update admin

This commit is contained in:
全栈小学生 2023-11-15 15:53:39 +08:00
parent 634d0105de
commit 9c5cd006fb
18 changed files with 425 additions and 128 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@ -37,6 +37,8 @@
"process": "启动进程",
"open": "开启",
"down": "下载",
"installDown":"未安装(重新下载)",
"unloadDown":"已安装(重新下载)",
"addonVersion": "插件版本",
"versionCode": "版本号",
"createTime": "发布时间",
@ -54,7 +56,7 @@
"descriptionLeft": "暂无任何应用,马上去",
"link": "官方应用市场",
"descriptionRight": "逛逛",
"installed-empty": "暂未安装任何应用,请先安装",
"installed-empty": "暂未安装任何应用",
"siteAddressTips": "授权域名不匹配",
"authCodePlaceholder": "请输入授权码",
"authSecretPlaceholder": "请输入授权秘钥",

View File

@ -35,12 +35,12 @@
<Hide />
</el-icon>
</span>
</div>
</div>
</div>
<div class="flex flex-1 flex-wrap justify-end relative">
<el-button class="w-[154px] !h-[48px] mt-[8px]" type="primary"
@click="authCodeApproveFn">授权码认证</el-button>
<el-popover ref="getAuthCodeDialog" placement="bottom" :width="478" trigger="click"
<el-popover ref="getAuthCodeDialog" placement="bottom-start" :width="478" trigger="click"
class="mt-[8px]">
<div class="px-[18px] py-[8px]">
<p class="leading-[32px] text-[14px]">您在官方应用市场购买任意一款应用即可获得授权码输入正确授权码认证通过后即可支持在线升级和其它相关服务

View File

@ -14,9 +14,8 @@
</div>
<div class="flex flex-wrap mt-[40px]">
<template v-for="(item, index) in detail.appList" :key="index">
<div class="app-item w-[280px] box-border py-[42px] px-[32px] bg-[#fff] rounded-[8px] cursor-pointer mr-[20px] mb-[20px] "
@click="itemPath(item)">
<div class="flex items-center">
<div class="app-item w-[280px] box-border !bg-[#fff] rounded-[6px] cursor-pointer mr-[20px] mb-[20px] overflow-hidden" @click="itemPath(item)">
<div class="bg-[#F7FAFB] py-[18px] px-[24px] flex items-center app-item-head">
<el-image class="w-[44px] h-[44px] rounded-[8px]" :src="img(item.icon)" fit="contain">
<template #error>
<div class="image-slot">
@ -25,15 +24,14 @@
</div>
</template>
</el-image>
<div class="ml-[12px] flex-1">
<div class="font-[600] text-[14px] text-[#222] leading-[20px]">{{ item.title }}</div>
<el-tooltip class="box-item" effect="light" :content="item.desc" placement="bottom-start">
<div
class="font-[500] text-[13px] text-[#6D7278] leading-[18px] mt-[6px] w-[160px] truncate">
{{
item.desc }}</div>
</el-tooltip>
</div>
</div>
<div class="py-[18px] px-[24px]">
<div class="font-[600] leading-[1] text-[14px] text-[#222]">{{ item.title }}</div>
<el-tooltip class="box-item" effect="light" :content="item.desc" placement="bottom-start">
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[6px] truncate">
{{ item.desc }}
</div>
</el-tooltip>
</div>
</div>
</template>
@ -157,6 +155,10 @@ getVersionsInfo()
.app-item {
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.18);
}
.app-item:hover .app-item-head{
background-color: #FDF4EF;
}
</style>
<style>
.overview-empty .el-empty__image {

View File

@ -1,8 +1,8 @@
<template>
<div class="pt-[64px] px-[90px] app-store" v-loading="loading">
<div v-if="info[activeName] && !loading">
<div class="pt-[64px] px-[90px] app-store" v-loading="authLoading">
<div v-if="info[activeName] && !loading && !authLoading">
<div class="flex justify-between items-center h-[32px] mb-4">
<span class="text-[26px] text-[#222] font-600">{{ t('localAppText') }}</span>
<span class="text-[22px] text-[#222] font-600">{{ t('localAppText') }}</span>
<el-input class="w-[247px]" :placeholder="t('search')" v-model="search_name" @keyup.enter="query">
<template #suffix>
<el-icon class="el-input__icon cursor-pointer" size="14px" @click="query">
@ -13,18 +13,18 @@
</div>
<div class="flex mt-[24px]">
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'installed' }"
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
@click="activeName = 'installed'">
class="w-[78px] h-[32rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[32px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
@click="activeNameTabFn('installed')">
{{ t('installLabel') }}
</div>
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'uninstalled' }"
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
@click="activeName = 'uninstalled'">
class="w-[78px] h-[32rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[32px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
@click="activeNameTabFn('uninstalled')">
{{ t('uninstalledLabel') }}
</div>
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'all' }"
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
@click="activeName = 'all'">
class="w-[78px] h-[32rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[32px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
@click="activeNameTabFn('all')">
{{ t('buyLabel') }}
</div>
</div>
@ -81,17 +81,20 @@
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" align="right" width="150">
<template #default="{ row }">
<el-button class="!text-[13px]" type="primary" link @click="getAddonDetialFn(row)">{{
t('detail') }}</el-button>
<el-button class="!text-[13px]" v-if="row.install_info && Object.keys(row.install_info)?.length"
<el-button v-if="row.install_info && Object.keys(row.install_info)?.length && activeName != 'all'" class="!text-[13px]" type="primary" link title="启动应用" @click="itemPath(row)">
<span class="iconfont iconicon_huojian"></span>
</el-button>
<el-button class="!text-[13px]" type="primary" link @click="getAddonDetialFn(row)">{{ t('detail') }}</el-button>
<el-button class="!text-[13px]" v-if="row.install_info && Object.keys(row.install_info)?.length && activeName != 'all'"
type="primary" link @click="uninstallAddonFn(row.key)">{{ t('unload') }}</el-button>
<el-button class="!text-[13px]" v-else-if="row.is_download && row.install_info <= 0"
type="primary" link @click="installAddonFn(row.key)">{{ t('install')
}}</el-button>
<el-button class="!text-[13px]" v-else :loading="downloading == row.key"
:disabled="downloading != ''" type="primary" link @click.stop="downEvent(row)">{{
t('down') }}</el-button>
<el-button class="!text-[13px]" v-else-if="row.is_download && row.install_info <= 0 && activeName != 'all'"
type="primary" link @click="installAddonFn(row.key)">{{ t('install') }}</el-button>
<el-button class="!text-[13px]" v-else :loading="downloading == row.key"
:disabled="downloading != ''" type="primary" link @click.stop="downEvent(row)">
<span v-if="row.install_info && Object.keys(row.install_info)?.length">{{t('unloadDown')}}</span>
<span v-else-if="row.is_download && row.install_info <= 0">{{t('installDown')}}</span>
<span v-else>{{ t('down') }}</span>
</el-button>
</template>
</el-table-column>
</el-table>
@ -344,6 +347,17 @@
</div>
</el-scrollbar>
</el-dialog>
<!-- 下载提示 -->
<el-dialog v-model="unloadHintDialog" title="下载提示" width="30%" :before-close="handleClose">
<span>本地已经存在该插件/应用再次下载会覆盖该插件/应用</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="unloadHintDialog = false">取消</el-button>
<el-button type="primary" @click="downEventHintFn">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</div>
</template>
@ -362,17 +376,35 @@ import { useRouter } from 'vue-router'
import useUserStore from '@/stores/modules/user'
const router = useRouter()
const activeName = ref('installed')
const activeName = ref(storage.get('storeActiveName') || 'installed')
const loading = ref<Boolean>(true)
const downloading = ref('')
const installAfterTips = ref<string[]>([])
const userStore = useUserStore()
let unloadHintDialog = ref(false)
let currDownData = ref()
const downEventHintFn = ()=>{
downEvent(currDownData.value, true);
}
const activeNameTabFn = (data)=>{
activeName.value = data
storage.set({key: 'storeActiveName', data: data});
}
const downEvent = (param: Record<string, any>, isDown = false) => {
if(param.is_download && activeName.value == 'all' && !isDown){
unloadHintDialog.value = true;
currDownData.value = param;
return false;
}
const downEvent = (param: Record<string, any>) => {
if (downloading.value) return
downloading.value = param.key
downloadVersion({ addon: param.key, version: param.version }).then(() => {
unloadHintDialog.value = false;
installAddonFn(param.key)
localListFn()
downloading.value = ''
@ -453,7 +485,6 @@ const localListFn = () => {
localListFn()
//
const appLink: any = ref({})
const itemPath = (data: any) => {
if (data.type == 'app' && Object.keys(data.install_info).length) {
@ -598,7 +629,8 @@ const authElMessageBox = () => {
cancelButtonText: t('toNiucloud')
}
).then(() => {
router.push({ path: '/app/authorize' })
authCodeApproveFn();
// router.push({ path: '/app/authorize' })
}).catch((action: string) => {
if (action === 'cancel') {
window.open('https://www.niucloud.com/app')
@ -682,6 +714,9 @@ const installShowDialogClose = (done: () => {}) => {
cancelInstall(currAddon.value)
done()
}).catch(() => { })
} else if(installStep.value == 3){
activeNameTabFn('installed');
location.reload()
} else done()
}
@ -698,14 +733,18 @@ const authCodeApproveDialog = ref(false)
const authinfo = ref('')
const getAuthCodeDialog = ref(null)
const saveLoading = ref(false)
let authLoading = ref(true);
const checkAppMange = () => {
authLoading.value = true;
getAuthinfo()
.then((res) => {
if (res.data.data && res.data.data.length != 0) {
authinfo.value = res.data.data
}
authLoading.value = false;
})
.catch(() => {
authLoading.value = false;
authCodeApproveDialog.value = false
})
}

View File

@ -2,69 +2,113 @@
<div class="box-border px-[64px] pt-[64px]">
<div class="font-600 text-[22px] text-[#222] mb-[32px] pl-[14px]">工具管理</div>
<div class="flex flex-wrap mt-[28px]">
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/addon')">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/tools/addon')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">插件开发</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">点击新建插件生成插件后系统会生成对应插</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
点击新建插件生成插件后系统会生成对应插
</div>
</div>
<img src="@/app/assets/images/tools/addon_develop.png" class="w-[256px] h-[148px]" />
<img src="@/app/assets/images/tools/addon_develop.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/code')">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/tools/code')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">代码生成</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">代码生成</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
代码生成
</div>
</div>
<img src="@/app/assets/images/tools/code.png" class="w-[256px] h-[148px]" />
<img src="@/app/assets/images/tools/code.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/list')">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/tools/list')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">数据字典</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">数据字典</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
数据字典
</div>
</div>
<img src="@/app/assets/images/tools/sys_dict_list.png" class="w-[256px] h-[148px]" />
<img src="@/app/assets/images/tools/sys_dict_list.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/update')">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/tools/update')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">更新缓存</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">更新缓存</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
更新缓存
</div>
</div>
<img src="@/app/assets/images/tools/tools_Update_cache.png" class="w-[256px] h-[148px]" />
<img src="@/app/assets/images/tools/tools_Update_cache.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/detection')">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/tools/detection')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">环境监测</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">环境监测</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
环境监测
</div>
</div>
<img src="@/app/assets/images/tools/tools_check_environment.png" class="w-[256px] h-[148px] cursor-pointer" />
<img src="@/app/assets/images/tools/tools_check_environment.png" class="w-[256px] h-[128px] cursor-pointer" />
</div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/schedule')">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/tools/schedule')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">计划任务</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">计划任务</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
计划任务
</div>
</div>
<img src="@/app/assets/images/tools/tools_schedule.png" class="w-[256px] h-[148px]" />
<img src="@/app/assets/images/tools/tools_schedule.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/menu')">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/tools/menu')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">菜单管理</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">菜单管理</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
菜单管理
</div>
</div>
<img src="@/app/assets/images/tools/auth_menu.png" class="w-[256px] h-[148px]" />
<img src="@/app/assets/images/tools/auth_menu.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/authorize')">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/tools/authorize')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">授权信息</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">查看授权信息及重新认证授权</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
查看授权信息及重新认证授权
</div>
</div>
<img src="@/app/assets/images/tools/app_auth.png" class="w-[256px] h-[148px]" />
<img src="@/app/assets/images/tools/app_auth.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="goRouter">
<div class="flex-1 py-[19px] px-[24px] flex flex-col">
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="developerDialogVisible = true">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">开发模式</span>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
开发环境和生产环境说明
</div>
</div>
<img src="@/app/assets/images/tools/developer.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="goRouter">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">官方市场</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">官方市场</p>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
官方市场
</div>
</div>
<img src="@/app/assets/images/tools/official_market.png" class="w-[256px] h-[148px]" />
<img src="@/app/assets/images/tools/official_market.png" class="w-[256px] h-[128px]" />
</div>
<el-dialog v-model="developerDialogVisible" class="developer-dialog-wrap" title="开发人员模式说明" width="30%" :before-close="handleClose">
<div>
<p class="text-[16px] mb-[4px] text-[#333]">开发模式</p>
<div class="text-[14px] indent-[2em]">
开发人员模式即软件开发环境指框架开启了开发模式(DEBUG=TRUE) 开发模式时会出现开发选项卡仅用于开发人员使用包括应用及插件的安装卸载系统升级等等本菜单及子项功能均不受系统管理和权限控制
</div>
<p class="text-[16px] mt-[15px] mb-[4px] text-[#333]">生产模式</p>
<div class="text-[14px] indent-[2em]">
生产模式即软件生产环境指框架关闭了调试开发模式(DEBUG=FALSE) 软件正式部署运营开发选项卡隐藏一般来说开发人员开发或者部署好环境后要关闭开发模式
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="developerDialogVisible = false">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</div>
</template>
@ -80,6 +124,7 @@
import {UserFilled} from '@element-plus/icons-vue'
const router = useRouter()
let developerDialogVisible = ref(false)
const toLink = (link)=>{
router.push(link)
@ -89,7 +134,8 @@
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>
<style>
.tools-item-shadow{
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
@ -103,4 +149,7 @@
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.developer-dialog-wrap .el-dialog__body{
padding: 15px 20px;
}
</style>

View File

@ -69,7 +69,7 @@ const router = useRouter()
let app_debug = ref(false)
const goAppManage = () => {
router.push('/app_manage')
router.push({ path: '/app_manage/app_store' })
}
const getEnvFn = () => {
getEnv().then(res => {

View File

@ -1,20 +1,69 @@
<template>
<div :class="[{'group-hover:flex': props.isShowHover},'hidden fixed left-0 top-[65px] z-[5555] bg-[#fff] w-[640px] px-[28px] py-[20px] flex-wrap box-border shadow-lg ']">
<div v-for="(item, index) in data" :key="index" @click="toLink(item, props.hoverType)" class="flex items-center cursor-pointer text-[#6d7278] hover:bg-[#f1f2f6] whitespace-nowrap py-[10px] px-[15px] box-border w-[165px]">
<img :src="img(item.icon)" class="w-[44px] h-[44px] rounded-full mr-[5px]" alt="" :title="item.title">
<span>{{ item.title }}</span>
<div v-if="data.length > 1 || app_debug " :class="[{'group-hover:flex': props.isShowHover},'hidden fixed left-0 top-[65px] z-[5555] bg-[#fff] w-[1076px] px-[28px] py-[20px] flex-wrap box-border shadow-lg ']">
<div :class="['app-item w-[240px] box-border !bg-[#fff] rounded-[6px] cursor-pointer mb-[20px] overflow-hidden',{'mr-[20px]': (index+1)%4 != 0}]" v-for="(item, index) in data" :key="index" @click="toLink(item, props.hoverType)">
<div class="bg-[#F7FAFB] py-[15px] px-[22px] flex items-center app-item-head">
<el-image class="w-[44px] h-[44px] rounded-[8px]" :src="img(item.icon)" fit="contain">
<template #error>
<div class="image-slot">
<img class="w-[40px] h-[40px] rounded-[8px]"
src="@/app/assets/images/app_store/app_store_default.png" />
</div>
</template>
</el-image>
</div>
<div class="py-[15px] px-[22px]">
<div class="font-[600] leading-[1] text-[14px] text-[#222]">{{ item.title }}</div>
<el-tooltip class="box-item" effect="light" :content="item.desc" placement="bottom-start">
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[6px] truncate">
{{ item.desc }}
</div>
</el-tooltip>
</div>
</div>
<div v-if="!data.length" class="flex-1 flex flex-col justify-center items-center pb-[30px]">
<div class="w-[130px]"><img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt=""></div>
<div class="text-[14px] text-[#909399]">暂无安装任何应用或插件马上去<a href="https://www.niucloud.com/app" target="_blank" class="text-[var(--el-color-primary)]">官方应用市场</a>逛逛</div>
<div v-if="app_debug" :class="['app-item w-[240px] box-border !bg-[#fff] rounded-[6px] cursor-pointer mb-[20px] overflow-hidden',{'mr-[20px]': (data.length+1)%4 != 0}]" @click="toDeveloperLink()">
<div class="bg-[#F7FAFB] py-[15px] px-[22px] flex items-center app-item-head developer">
<img class="w-[40px] h-[40px] rounded-[8px]" src="@/app/assets/images/app_store/developer.png" />
</div>
<div class="py-[15px] px-[22px]">
<div class="font-[600] leading-[1] text-[14px] text-[#222]">开发人员模式</div>
<el-tooltip class="box-item" effect="light" content="开发人员模式" placement="bottom-start">
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[6px] truncate">
开发人员模式
</div>
</el-tooltip>
</div>
</div>
<el-empty class="mx-auto overview-empty" v-if="!data.length">
<template #image>
<div class="w-[230px] mx-auto">
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
</div>
</template>
<template #description>
<p class="flex items-center">
<span>暂无安装任何应用,请点击</span>
<el-link type="primary" @click="toAppStore" class="mx-[5px]">安装应用</el-link>
<span>安装使用</span>
</p>
</template>
</el-empty>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, computed } from 'vue'
import { img } from '@/utils/common'
import { useRouter } from 'vue-router'
import {getEnv} from '@/app/api/sys'
let app_debug = ref(false)
const getEnvFn = () => {
getEnv().then(res => {
app_debug.value = res.data.app_debug;
}).catch(() => {})
}
getEnvFn();
const router = useRouter()
const props = defineProps(['isShowHover','data','hoverType'])
let data = ref([]);
if(props.data){
@ -28,6 +77,26 @@ const emit = defineEmits(['child-click'])
const toLink = (data,type)=>{
emit('child-click',data,type)
}
//
const toAppStore = () => {
router.push('/app_manage/app_store')
}
//
const toDeveloperLink = () =>{
router.push('/app_manage/tools')
}
</script>
<style lang="scss"></style>
<style lang="scss">
.app-item {
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.18);
}
.app-item:hover .app-item-head{
background-color: var(--el-color-primary-light-8);
}
.app-item:hover .app-item-head.developer{
background-color: #eee;
}
</style>

View File

@ -3,10 +3,9 @@
<div class="w-[124px] overflow-hidden">
<!-- , { 'bright': !dark } -->
<el-aside :class="['h-screen layout-aside w-[124px] pb-[30px] px-[8px] bg-[#282c34] ease-in duration-200']">
<div class="h-full flex flex-col relative">
<div class="h-full flex flex-col relative">
<div class="group flex items-center justify-center h-[64px] cursor-pointer" v-if="!globalAppKey" @mouseenter="threefloatMenuHover">
<span class="iconfont iconyun1 !text-[32px] !w-auto text-[#fff]"></span>
<!-- <app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>-->
</div>
<template v-for="(item, index) in menus" :key="index">
@ -16,7 +15,7 @@
<div class="flex items-center justify-center w-[30px] h-[30px]" v-else>
<icon v-if="item.meta.icon" :name="item.meta.icon" class="!w-auto" size="24px" />
</div>
<!-- <app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>-->
<app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>
</div>
<div v-for="(appItem, appIndex) in item.children" :key="appIndex" @click="toLink(appItem)"
:class="['rounded-sm flex items-center px-[8px] mb-[4px] h-[40px] cursor-pointer text-[#b9b9bf] hover:bg-[var(--el-color-primary)] hover:!text-[#fff] menu-item hover:text-color whitespace-nowrap', { 'bg-[var(--el-color-primary)] !text-[#fff] menu-item-active ': localMenuKey == appItem.meta.key}]">
@ -25,9 +24,9 @@
</div>
</template>
</template>
<template v-for="(item, index) in menus" :key="index">
<div v-if="!item.meta.app && (item.meta.attr == 'common' || item.meta.attr == 'system')" @click="toLink(item)"
<div v-if="!item.meta.app && item.meta.attr != 'tools' && item.meta.show" @click="toLink(item)"
:class="['rounded-sm flex items-center px-[8px] mb-[4px] h-[40px] cursor-pointer text-[#b9b9bf] hover:bg-[var(--el-color-primary)] hover:!text-[#fff] menu-item hover:text-color whitespace-nowrap', { 'bg-[var(--el-color-primary)] !text-[#fff] menu-item-active ': (item.path == currentRoute.path || (currentRoute.path == '/admin' && item.path == '/index') || (currentRoute.meta.app && item.path == '/index')) }]">
<icon v-if="item.meta.icon" :name="item.meta.icon" class="!w-auto" size="20px" :title="item.meta.title" />
<span class="text-[14px] ml-[8px]">{{item.meta.shortTitle}}</span>
@ -36,7 +35,7 @@
</div>
</el-aside>
</div>
<template v-for="(item, index) in menus" :key="index">
<div v-if="isTwoMenuFn(item)" class="w-[155px] box-border border-r-[1px] border-solid second-menu">
<div class="group flex flex-col items-center justify-center h-[64px] border-b-[1px] border-solid second-head cursor-pointer relative" @mouseenter="twofloatMenuHover">
@ -218,7 +217,7 @@ const menus = computed(() => {
menus.push(item)
}
})
if(appList.value && appList.value.length){
appList.value.forEach((item,index) =>{
menus.forEach((menuItem,menuIndex)=>{
@ -275,7 +274,7 @@ watch(route, () => {
const data = route.matched[1]
currentRoute.value = route.matched[1]
if(route.meta.app && route.meta.app == globalAppKey.value){
menus.value.forEach((item,index)=>{
if(item.children && item.name != route.name){
@ -331,7 +330,7 @@ const toLink = (data, type) => {
const getLinkName = (res)=>{
if(res.children && res.children.length){
return getLinkName(res.children[0])
}
}
return res.name
}

View File

@ -132,7 +132,7 @@ const toggleMenuCollapse = () => {
}
const changeApp = ()=>{
router.push({ path: '/app_manage' })
router.push({ path: '/app_manage/app_store' })
}
//
const refreshRouter = () => {

View File

@ -1,20 +1,69 @@
<template>
<div :class="[{'group-hover:flex': props.isShowHover},'hidden fixed left-0 top-[65px] z-[5555] bg-[#fff] w-[640px] px-[28px] py-[20px] flex-wrap box-border shadow-lg ']">
<div v-for="(item, index) in data" :key="index" @click="toLink(item, props.hoverType)" class="flex items-center cursor-pointer text-[#6d7278] hover:bg-[#f1f2f6] whitespace-nowrap py-[10px] px-[15px] box-border w-[165px]">
<img :src="img(item.icon)" class="w-[44px] h-[44px] rounded-full mr-[5px]" alt="" :title="item.title">
<span>{{ item.title }}</span>
<div v-if="data.length > 1 || app_debug " :class="[{'group-hover:flex': props.isShowHover},'hidden fixed left-0 top-[65px] z-[5555] bg-[#fff] w-[1076px] px-[28px] py-[20px] flex-wrap box-border shadow-lg ']">
<div :class="['app-item w-[240px] box-border !bg-[#fff] rounded-[6px] cursor-pointer mb-[20px] overflow-hidden',{'mr-[20px]': (index+1)%4 != 0}]" v-for="(item, index) in data" :key="index" @click="toLink(item, props.hoverType)">
<div class="bg-[#F7FAFB] py-[15px] px-[22px] flex items-center app-item-head">
<el-image class="w-[44px] h-[44px] rounded-[8px]" :src="img(item.icon)" fit="contain">
<template #error>
<div class="image-slot">
<img class="w-[40px] h-[40px] rounded-[8px]"
src="@/app/assets/images/app_store/app_store_default.png" />
</div>
</template>
</el-image>
</div>
<div class="py-[15px] px-[22px]">
<div class="font-[600] leading-[1] text-[14px] text-[#222]">{{ item.title }}</div>
<el-tooltip class="box-item" effect="light" :content="item.desc" placement="bottom-start">
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[6px] truncate">
{{ item.desc }}
</div>
</el-tooltip>
</div>
</div>
<div v-if="!data.length" class="flex-1 flex flex-col justify-center items-center pb-[30px]">
<div class="w-[130px]"><img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt=""></div>
<div class="text-[14px] text-[#909399]">暂无安装任何应用或插件马上去<a href="https://www.niucloud.com/app" target="_blank" class="text-[var(--el-color-primary)]">官方应用市场</a>逛逛</div>
<div v-if="app_debug" :class="['app-item w-[240px] box-border !bg-[#fff] rounded-[6px] cursor-pointer mb-[20px] overflow-hidden',{'mr-[20px]': (data.length+1)%4 != 0}]" @click="toDeveloperLink()">
<div class="bg-[#F7FAFB] py-[15px] px-[22px] flex items-center app-item-head developer">
<img class="w-[40px] h-[40px] rounded-[8px]" src="@/app/assets/images/app_store/developer.png" />
</div>
<div class="py-[15px] px-[22px]">
<div class="font-[600] leading-[1] text-[14px] text-[#222]">开发人员模式</div>
<el-tooltip class="box-item" effect="light" content="开发人员模式" placement="bottom-start">
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[6px] truncate">
开发人员模式
</div>
</el-tooltip>
</div>
</div>
<el-empty class="mx-auto overview-empty" v-if="!data.length">
<template #image>
<div class="w-[230px] mx-auto">
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
</div>
</template>
<template #description>
<p class="flex items-center">
<span>暂无安装任何应用,请点击</span>
<el-link type="primary" @click="toAppStore" class="mx-[5px]">安装应用</el-link>
<span>安装使用</span>
</p>
</template>
</el-empty>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, computed } from 'vue'
import { img } from '@/utils/common'
import { useRouter } from 'vue-router'
import {getEnv} from '@/app/api/sys'
let app_debug = ref(false)
const getEnvFn = () => {
getEnv().then(res => {
app_debug.value = res.data.app_debug;
}).catch(() => {})
}
getEnvFn();
const router = useRouter()
const props = defineProps(['isShowHover','data','hoverType'])
let data = ref([]);
if(props.data){
@ -28,6 +77,26 @@ const emit = defineEmits(['child-click'])
const toLink = (data,type)=>{
emit('child-click',data,type)
}
//
const toAppStore = () => {
router.push('/app_manage/app_store')
}
//
const toDeveloperLink = () =>{
router.push('/app_manage/tools')
}
</script>
<style lang="scss"></style>
<style lang="scss">
.app-item {
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.18);
}
.app-item:hover .app-item-head{
background-color: var(--el-color-primary-light-8);
}
.app-item:hover .app-item-head.developer{
background-color: #eee;
}
</style>

View File

@ -3,10 +3,9 @@
<div class="w-[64px] overflow-hidden">
<!-- , { 'bright': !dark } -->
<el-aside :class="['h-screen layout-aside w-[64px] pb-[30px] bg-[#282c34] ease-in duration-200']">
<div class="h-full flex flex-col relative">
<div class="h-full flex flex-col relative">
<div class="group flex items-center justify-center h-[64px] cursor-pointer" v-if="!globalAppKey" @mouseenter="threefloatMenuHover">
<span class="iconfont iconyun1 !text-[32px] !w-auto text-[#fff]"></span>
<!-- <app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>-->
</div>
<template v-for="(item, index) in menus" :key="index">
@ -16,7 +15,7 @@
<div class="flex items-center justify-center w-[30px] h-[30px]" v-else>
<icon v-if="item.meta.icon" :name="item.meta.icon" class="!w-auto" size="24px" />
</div>
<!-- <app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>-->
<app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>
</div>
<div v-for="(appItem, appIndex) in item.children" :key="appIndex" @click="toLink(appItem)"
:class="['rounded-[5px] flex justify-center flex-col items-center h-[54px] w-[54px] m-[5px] cursor-pointer text-[#fff] hover:bg-[var(--el-color-primary)] hover:!text-[#fff] menu-item hover:text-color whitespace-nowrap', { 'bg-[var(--el-color-primary)] !text-[#fff] menu-item-active ': localMenuKey == appItem.meta.key}]">
@ -25,9 +24,9 @@
</div>
</template>
</template>
<template v-for="(item, index) in menus" :key="index">
<div v-if="!item.meta.app && (item.meta.attr == 'common' || item.meta.attr == 'system')" @click="toLink(item)"
<div v-if="!item.meta.app && item.meta.attr != 'tools' && item.meta.show" @click="toLink(item)"
:class="['rounded-[5px] flex justify-center flex-col items-center m-[5px] h-[54px] w-[54px] cursor-pointer text-[#fff] hover:bg-[var(--el-color-primary)] hover:!text-[#fff] menu-item hover:text-color whitespace-nowrap', { 'bg-[var(--el-color-primary)] !text-[#fff] menu-item-active ': (item.path == currentRoute.path || (currentRoute.path == '/admin' && item.path == '/index') || (currentRoute.meta.app && item.path == '/index')) }]">
<icon v-if="item.meta.icon" :name="item.meta.icon" class="!w-auto" size="16px" :title="item.meta.title" />
<span class="text-[14px] leading-1">{{item.meta.shortTitle}}</span>
@ -36,7 +35,7 @@
</div>
</el-aside>
</div>
<template v-for="(item, index) in menus" :key="index">
<div v-if="isTwoMenuFn(item)" class="w-[201px] box-border border-r-[1px] border-solid second-menu">
<div class="group flex flex-col items-center justify-center h-[60px] border-b-[1px] border-solid second-head cursor-pointer relative" @mouseenter="twofloatMenuHover">
@ -232,7 +231,7 @@ const menus = computed(() => {
menus.push(item)
}
})
if(appList.value && appList.value.length){
appList.value.forEach((item,index) =>{
menus.forEach((menuItem,menuIndex)=>{
@ -289,7 +288,7 @@ watch(route, () => {
const data = route.matched[1]
currentRoute.value = route.matched[1]
if(route.meta.app && route.meta.app == globalAppKey.value){
menus.value.forEach((item,index)=>{
if(item.children && item.name != route.name){
@ -345,7 +344,7 @@ const toLink = (data, type) => {
const getLinkName = (res)=>{
if(res.children && res.children.length){
return getLinkName(res.children[0])
}
}
return res.name
}

View File

@ -120,7 +120,7 @@ watch(screenWidth, () => {
})
const changeApp = ()=>{
router.push({ path: '/app_manage' })
router.push({ path: '/app_manage/app_store' })
}
//
const toggleMenuCollapse = () => {

View File

@ -1,20 +1,69 @@
<template>
<div :class="[{'group-hover:flex': props.isShowHover},'hidden fixed left-0 top-[65px] z-[5555] bg-[#fff] w-[640px] px-[28px] py-[20px] flex-wrap box-border shadow-lg ']">
<div v-for="(item, index) in data" :key="index" @click="toLink(item, props.hoverType)" class="flex items-center cursor-pointer text-[#6d7278] hover:bg-[#f1f2f6] whitespace-nowrap py-[10px] px-[15px] box-border w-[165px]">
<img :src="img(item.icon)" class="w-[44px] h-[44px] rounded-full mr-[5px]" alt="" :title="item.title">
<span>{{ item.title }}</span>
<div v-if="data.length > 1 || app_debug " :class="[{'group-hover:flex': props.isShowHover},'hidden fixed left-0 top-[65px] z-[5555] bg-[#fff] w-[1076px] px-[28px] py-[20px] flex-wrap box-border shadow-lg ']">
<div :class="['app-item w-[240px] box-border !bg-[#fff] rounded-[6px] cursor-pointer mb-[20px] overflow-hidden',{'mr-[20px]': (index+1)%4 != 0}]" v-for="(item, index) in data" :key="index" @click="toLink(item, props.hoverType)">
<div class="bg-[#F7FAFB] py-[15px] px-[22px] flex items-center app-item-head">
<el-image class="w-[44px] h-[44px] rounded-[8px]" :src="img(item.icon)" fit="contain">
<template #error>
<div class="image-slot">
<img class="w-[40px] h-[40px] rounded-[8px]"
src="@/app/assets/images/app_store/app_store_default.png" />
</div>
</template>
</el-image>
</div>
<div class="py-[15px] px-[22px]">
<div class="font-[600] leading-[1] text-[14px] text-[#222]">{{ item.title }}</div>
<el-tooltip class="box-item" effect="light" :content="item.desc" placement="bottom-start">
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[6px] truncate">
{{ item.desc }}
</div>
</el-tooltip>
</div>
</div>
<div v-if="!data.length" class="flex-1 flex flex-col justify-center items-center pb-[30px]">
<div class="w-[130px]"><img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt=""></div>
<div class="text-[14px] text-[#909399]">暂无安装任何应用或插件马上去<a href="https://www.niucloud.com/app" target="_blank" class="text-[var(--el-color-primary)]">官方应用市场</a>逛逛</div>
<div v-if="app_debug" :class="['app-item w-[240px] box-border !bg-[#fff] rounded-[6px] cursor-pointer mb-[20px] overflow-hidden',{'mr-[20px]': (data.length+1)%4 != 0}]" @click="toDeveloperLink()">
<div class="bg-[#F7FAFB] py-[15px] px-[22px] flex items-center app-item-head developer">
<img class="w-[40px] h-[40px] rounded-[8px]" src="@/app/assets/images/app_store/developer.png" />
</div>
<div class="py-[15px] px-[22px]">
<div class="font-[600] leading-[1] text-[14px] text-[#222]">开发人员模式</div>
<el-tooltip class="box-item" effect="light" content="开发人员模式" placement="bottom-start">
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[6px] truncate">
开发人员模式
</div>
</el-tooltip>
</div>
</div>
<el-empty class="mx-auto overview-empty" v-if="!data.length">
<template #image>
<div class="w-[230px] mx-auto">
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
</div>
</template>
<template #description>
<p class="flex items-center">
<span>暂无安装任何应用,请点击</span>
<el-link type="primary" @click="toAppStore" class="mx-[5px]">安装应用</el-link>
<span>安装使用</span>
</p>
</template>
</el-empty>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, computed } from 'vue'
import { img } from '@/utils/common'
import { useRouter } from 'vue-router'
import {getEnv} from '@/app/api/sys'
let app_debug = ref(false)
const getEnvFn = () => {
getEnv().then(res => {
app_debug.value = res.data.app_debug;
}).catch(() => {})
}
getEnvFn();
const router = useRouter()
const props = defineProps(['isShowHover','data','hoverType'])
let data = ref([]);
if(props.data){
@ -28,6 +77,26 @@ const emit = defineEmits(['child-click'])
const toLink = (data,type)=>{
emit('child-click',data,type)
}
//
const toAppStore = () => {
router.push('/app_manage/app_store')
}
//
const toDeveloperLink = () =>{
router.push('/app_manage/tools')
}
</script>
<style lang="scss"></style>
<style lang="scss">
.app-item {
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.18);
}
.app-item:hover .app-item-head{
background-color: var(--el-color-primary-light-8);
}
.app-item:hover .app-item-head.developer{
background-color: #eee;
}
</style>

View File

@ -11,7 +11,7 @@
</div>
<span>{{ item.meta.app ? item.meta.parentTitle : item.meta.title }}</span>
</div>
<!-- <app-menu :isShowHover="twofloatMenu" :data="appList" @child-click="toLink" hoverType='twofloatMenu'></app-menu>-->
<app-menu :isShowHover="twofloatMenu" :data="appList" @child-click="toLink" hoverType='twofloatMenu'></app-menu>
</div>
<el-scrollbar class="overflow-y-auto menus-wrap">
@ -243,7 +243,7 @@
</div>
<template v-for="(twoMenu, twoIndex) in menus">
<el-sub-menu :index="String(twoMenu.meta.title)"
v-if="twoMenu.meta.attr == 'common' && !twoMenu.meta.app && twoMenu.children">
v-if="twoMenu.meta.attr != 'tools' && twoMenu.meta.show && !twoMenu.meta.app && twoMenu.children">
<template #title>
<div class="w-[16px] h-[16px] relative flex items-center">
<icon v-if="twoMenu.meta.icon" :name="twoMenu.meta.icon"
@ -304,7 +304,7 @@
</div>
</template>
</el-sub-menu>
<el-menu-item v-else-if="twoMenu.meta.attr == 'common'" class="!pl-[35px] text-[#333]"
<el-menu-item v-else-if="twoMenu.meta.attr != 'tools' && twoMenu.meta.show" class="!pl-[35px] text-[#333]"
:index="String(twoMenu.name)" @click="toLink(twoMenu)">
<template #title>
<div v-if="twoMenu.meta.icon" class="w-[16px] h-[16px] relative flex items-center">
@ -378,7 +378,7 @@ const menus = computed(() => {
menus.push(item)
}
})
if(appList.value && appList.value.length){
appList.value.forEach((item,index) =>{
menus.forEach((menuItem,menuIndex)=>{
@ -395,7 +395,7 @@ const menus = computed(() => {
storage.set({ key: 'menuAppStorage', data: '' })
globalAppKey.value = ""
}
if(appList.value.length && !globalAppKey.value){
storage.set({ key: 'menuAppStorage', data: appTypeList.value[0] })
globalAppKey.value = appTypeList.value[0]
@ -437,7 +437,7 @@ const twofloatMenuHover = ()=>{
}
const toLink = (data, type) => {
if(type == 'twofloatMenu') twofloatMenu.value = false;
if (!data.meta && data.type == 'app' || data.meta.key != 'official_market') {
let name = data.name;
if(data.type == 'app'){

View File

@ -163,7 +163,7 @@ const checkIndexList = () => {
}
const changeApp = ()=>{
router.push({ path: '/app_manage' })
router.push({ path: '/app_manage/app_store' })
}
const index_path = ref('')

View File

@ -68,7 +68,7 @@ const router = useRouter()
let app_debug = ref(false)
const goAppManage = () => {
router.push('/app_manage')
router.push({ path: '/app_manage/app_store' })
}
const getEnvFn = () => {
getEnv().then(res => {