mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2025-12-14 19:52:48 +00:00
update admin
This commit is contained in:
parent
634d0105de
commit
9c5cd006fb
BIN
admin/src/app/assets/images/app_store/developer.png
Normal file
BIN
admin/src/app/assets/images/app_store/developer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
BIN
admin/src/app/assets/images/tools/developer.png
Normal file
BIN
admin/src/app/assets/images/tools/developer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
@ -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": "请输入授权秘钥",
|
||||
|
||||
@ -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]">您在官方应用市场购买任意一款应用,即可获得授权码。输入正确授权码认证通过后,即可支持在线升级和其它相关服务
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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 => {
|
||||
|
||||
@ -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>
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -132,7 +132,7 @@ const toggleMenuCollapse = () => {
|
||||
}
|
||||
|
||||
const changeApp = ()=>{
|
||||
router.push({ path: '/app_manage' })
|
||||
router.push({ path: '/app_manage/app_store' })
|
||||
}
|
||||
// 刷新路由
|
||||
const refreshRouter = () => {
|
||||
|
||||
@ -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>
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -120,7 +120,7 @@ watch(screenWidth, () => {
|
||||
})
|
||||
|
||||
const changeApp = ()=>{
|
||||
router.push({ path: '/app_manage' })
|
||||
router.push({ path: '/app_manage/app_store' })
|
||||
}
|
||||
// 菜单栏展开折叠
|
||||
const toggleMenuCollapse = () => {
|
||||
|
||||
@ -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>
|
||||
@ -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'){
|
||||
|
||||
@ -163,7 +163,7 @@ const checkIndexList = () => {
|
||||
}
|
||||
|
||||
const changeApp = ()=>{
|
||||
router.push({ path: '/app_manage' })
|
||||
router.push({ path: '/app_manage/app_store' })
|
||||
}
|
||||
|
||||
const index_path = ref('')
|
||||
|
||||
@ -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 => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user