update admin

This commit is contained in:
全栈小学生 2023-10-28 12:21:43 +08:00
parent 8eae9e7802
commit 00fbb9cbc6
54 changed files with 284 additions and 308 deletions

View File

@ -84,4 +84,13 @@ export function getAddonCloudInstallLog(addon: string) {
*/ */
export function preUninstallCheck(addon: string) { export function preUninstallCheck(addon: string) {
return request.get(`addon/uninstall/check/${addon}`, { timeout: 30 * 1000 }) return request.get(`addon/uninstall/check/${addon}`, { timeout: 30 * 1000 })
}
/**
*
* @param addon
* @returns
*/
export function cancelInstall(addon: string) {
return request.put(`addon/install/cancel/${addon}`, {}, { showErrorMessage: false })
} }

View File

@ -4,7 +4,7 @@ import request from '@/utils/request'
* *
* @returns * @returns
*/ */
export function getUserInfo(type: string) { export function getUserInfo() {
return request.get(`auth/get`) return request.get(`auth/get`)
} }

View File

@ -30,7 +30,7 @@
"installComplete": "安装完成", "installComplete": "安装完成",
"localAppText":"插件管理", "localAppText":"插件管理",
"marketAppText":"官方市场", "marketAppText":"官方市场",
"installShowDialogCloseTips": "安装任务尚未完成,关闭任务仍会执行,确定要继续关闭吗", "installShowDialogCloseTips": "安装任务尚未完成,关闭将取消安装任务,是否要继续关闭",
"marketDevelopMessage":"官方市场正在开发中!", "marketDevelopMessage":"官方市场正在开发中!",
"jobError": "任务队列未启动 请在服务端源码部署目录打开终端执行 php think queue:listen", "jobError": "任务队列未启动 请在服务端源码部署目录打开终端执行 php think queue:listen",
"conflictFiles": "冲突文件", "conflictFiles": "冲突文件",

View File

@ -8,7 +8,7 @@
</template> </template>
<div class="flex flex-wrap plug-list pb-10 plug-large"> <div class="flex flex-wrap plug-list pb-10 plug-large">
<div v-for="(item, index) in applyList.list" :key="index + 'b'" class="app-item cursor-pointer mr-4 mt-[20px] pb-2 bg-[#f7f7f7]" @click="toLink(item.key)"> <div v-for="(item, index) in appList.list" :key="index + 'b'" class="app-item cursor-pointer mr-4 mt-[20px] pb-2 bg-[#f7f7f7]" @click="toLink(item.key)">
<div class="flex justify-center items-center"> <div class="flex justify-center items-center">
<el-image class="w-[240px] h-[120px]" :src="img(item.icon)" fit="contain"> <el-image class="w-[240px] h-[120px]" :src="img(item.icon)" fit="contain">
<template #error> <template #error>
@ -41,15 +41,15 @@ import { useRouter } from 'vue-router'
const userStore = useUserStore() const userStore = useUserStore()
const router = useRouter() const router = useRouter()
const applyList = reactive({ const appList = reactive({
list: [] list: []
}) })
const getApplelist = async () => { const getAppList = async () => {
const res = await getApply({}) const res = await getApply({})
applyList.list = res.data appList.list = res.data
} }
getApplelist() getAppList()
const appLink = ref({}) const appLink = ref({})
const getAppLink = () => { const getAppLink = () => {

View File

@ -41,7 +41,7 @@
<el-form-item :label="t('authId')" prop="api_url" v-show="formData.menu_type != 0"> <el-form-item :label="t('authId')" prop="api_url" v-show="formData.menu_type != 0">
<el-input v-model="formData.api_url" :placeholder="t('authIdPlaceholder')" class="input-width"> <el-input v-model="formData.api_url" :placeholder="t('authIdPlaceholder')" class="input-width">
<template #append> <template #append>
<el-select class="w-[90px] border-none" v-model="method"> <el-select class="w-[90px] border-none" v-model="formData.methods">
<el-option label="POST" value="post" /> <el-option label="POST" value="post" />
<el-option label="GET" value="get" /> <el-option label="GET" value="get" />
<el-option label="PUT" value="put" /> <el-option label="PUT" value="put" />
@ -98,7 +98,6 @@ import { addMenu, editMenu, getMenuInfo, getSystemMenu,getAddonMenu } from '@/ap
import { getAddonDevelop } from '@/app/api/tools' import { getAddonDevelop } from '@/app/api/tools'
const showDialog = ref(false) const showDialog = ref(false)
const method = ref('post')
const loading = ref(false) const loading = ref(false)
let popTitle: string = ''; let popTitle: string = '';
@ -114,7 +113,7 @@ const initialFormData = {
api_url: '', api_url: '',
router_path: '', router_path: '',
view_path: '', view_path: '',
methods: '', methods: 'post',
sort: '', sort: '',
status: 1, status: 1,
is_show: 1, is_show: 1,
@ -219,7 +218,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
loading.value = true loading.value = true
const data = formData const data = formData
data.api_url = data.api_url ? `${data.api_url}/${method.value}` : '' data.api_url = data.api_url ? `${data.api_url}/${formData.methods}` : ''
save(data).then(res => { save(data).then(res => {
loading.value = false loading.value = false

View File

@ -1,121 +1,123 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<span class="text-[20px]">{{ pageName }}</span> <span class="text-[20px]">{{ pageName }}</span>
</div> </div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="sysUserLogTableData.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="sysUserLogTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('ip')" prop="ip"> <el-form-item :label="t('ip')" prop="ip">
<el-input v-model="sysUserLogTableData.searchParam.ip" :placeholder="t('ipPlaceholder')" /> <el-input v-model="sysUserLogTableData.searchParam.ip" :placeholder="t('ipPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('username')" prop="username"> <el-form-item :label="t('username')" prop="username">
<el-input v-model="sysUserLogTableData.searchParam.username" :placeholder="t('usernamePlaceholder')" /> <el-input v-model="sysUserLogTableData.searchParam.username"
</el-form-item> :placeholder="t('usernamePlaceholder')" />
</el-form-item>
<el-form-item :label="t('url')" prop="url"> <el-form-item :label="t('url')" prop="url">
<el-input v-model="sysUserLogTableData.searchParam.url" :placeholder="t('urlPlaceholder')" /> <el-input v-model="sysUserLogTableData.searchParam.url" :placeholder="t('urlPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="loadSysUserLogList()">{{ t('search') }}</el-button> <el-button type="primary" @click="loadSysUserLogList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> <el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
<div> <div>
<el-table :data="sysUserLogTableData.data" size="large" v-loading="sysUserLogTableData.loading"> <el-table :data="sysUserLogTableData.data" size="large" v-loading="sysUserLogTableData.loading">
<template #empty> <template #empty>
<span>{{ !sysUserLogTableData.loading ? t('emptyData') : '' }}</span> <span>{{ !sysUserLogTableData.loading ? t('emptyData') : '' }}</span>
</template> </template>
<el-table-column prop="username" :label="t('username')" min-width="120" /> <el-table-column prop="username" :label="t('username')" min-width="120" />
<el-table-column prop="ip" :label="t('ip')" min-width="100" align="left" /> <el-table-column prop="ip" :label="t('ip')" min-width="100" align="left" />
<el-table-column prop="url" :label="t('url')" min-width="180" /> <el-table-column prop="url" :label="t('url')" min-width="180" />
<el-table-column prop="type" :label="t('type')" min-width="100" align="center" /> <el-table-column prop="type" :label="t('type')" min-width="100" align="center" />
<el-table-column :label="t('createTime')" min-width="180" align="center"> <el-table-column :label="t('createTime')" min-width="180" align="center">
<template #default="{ row }"> <template #default="{ row }">
{{ row.create_time || '' }} {{ row.create_time || '' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="t('operation')" fixed="right" align="right" width="130"> <el-table-column :label="t('operation')" fixed="right" align="right" width="130">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="primary" link @click="detailEvent(row)">{{ t('detail') }}</el-button> <el-button type="primary" link @click="detailEvent(row)">{{ t('detail') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="mt-[16px] flex justify-end"> <div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="sysUserLogTableData.page" <el-pagination v-model:current-page="sysUserLogTableData.page"
v-model:page-size="sysUserLogTableData.limit" layout="total, sizes, prev, pager, next, jumper" v-model:page-size="sysUserLogTableData.limit"
:total="sysUserLogTableData.total" @size-change="loadSysUserLogList()" layout="total, sizes, prev, pager, next, jumper"
@current-change="loadSysUserLogList" /> :total="sysUserLogTableData.total" @size-change="loadSysUserLogList()"
</div> @current-change="loadSysUserLogList" />
<user-log-detail ref="userLogDetailDialog" @complete="loadSysUserLogList()" /> </div>
</div> <user-log-detail ref="userLogDetailDialog" @complete="loadSysUserLogList()" />
</el-card> </div>
</div> </el-card>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue' import {reactive, ref} from 'vue'
import { t } from '@/lang' import {t} from '@/lang'
import { getLogList } from '@/app/api/user' import {getLogList} from '@/app/api/user'
import UserLogDetail from '@/app/views/auth/components/user-log-detail.vue' import UserLogDetail from '@/app/views/auth/components/user-log-detail.vue'
import { useRoute } from 'vue-router' import {useRoute} from 'vue-router'
import { FormInstance } from 'element-plus' import {FormInstance} from 'element-plus'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title
const sysUserLogTableData = reactive({ const sysUserLogTableData = reactive({
page: 1, page: 1,
limit: 10, limit: 10,
total: 0, total: 0,
loading: true, loading: true,
data: [], data: [],
searchParam: { searchParam: {
ip: '', ip: '',
username: '' username: ''
} }
})
const searchFormRef = ref<FormInstance>()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadSysUserLogList()
}
/**
* 获取管理员操作记录表列表
*/
const loadSysUserLogList = (page: number = 1) => {
sysUserLogTableData.loading = true
sysUserLogTableData.page = page
getLogList({
page: sysUserLogTableData.page,
limit: sysUserLogTableData.limit,
...sysUserLogTableData.searchParam
}).then(res => {
sysUserLogTableData.loading = false
sysUserLogTableData.data = res.data.data
sysUserLogTableData.total = res.data.total
}).catch(() => {
sysUserLogTableData.loading = false
}) })
}
loadSysUserLogList() const searchFormRef = ref<FormInstance>()
const userLogDetailDialog: Record<string, any> | null = ref(null) const resetForm = (formEl: FormInstance | undefined) => {
/** if (!formEl) return
* 查看详情
* @param data formEl.resetFields()
*/ loadSysUserLogList()
const detailEvent = (data: any) => { }
userLogDetailDialog.value.setFormData(data) /**
userLogDetailDialog.value.showDialog = true * 获取管理员操作记录表列表
} */
const loadSysUserLogList = (page: number = 1) => {
sysUserLogTableData.loading = true
sysUserLogTableData.page = page
getLogList({
page: sysUserLogTableData.page,
limit: sysUserLogTableData.limit,
...sysUserLogTableData.searchParam
}).then(res => {
sysUserLogTableData.loading = false
sysUserLogTableData.data = res.data.data
sysUserLogTableData.total = res.data.total
}).catch(() => {
sysUserLogTableData.loading = false
})
}
loadSysUserLogList()
const userLogDetailDialog: Record<string, any> | null = ref(null)
/**
* 查看详情
* @param data
*/
const detailEvent = (data: any) => {
userLogDetailDialog.value.setFormData(data)
userLogDetailDialog.value.showDialog = true
}
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@ -98,7 +98,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
// import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import EditMenu from '@/app/views/auth/components/edit-menu.vue' import EditMenu from '@/app/views/auth/components/edit-menu.vue'
import { getSystem, getAddonList, deleteMenu, getMenus } from '@/app/api/sys' import { getSystem, getAddonList, deleteMenu, getMenus } from '@/app/api/sys'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'

View File

@ -26,8 +26,8 @@
<el-table-column prop="role_name" :label="t('roleName')" /> <el-table-column prop="role_name" :label="t('roleName')" />
<el-table-column :label="t('status')"> <el-table-column :label="t('status')">
<template #default="{ row }"> <template #default="{ row }">
<el-tag class="cursor-pointer" type="success" v-if="row.status == 1" @click="edstatusFn(row)">{{ row.status_name }}</el-tag> <el-tag class="cursor-pointer" type="success" v-if="row.status == 1" @click="edStatusFn(row)">{{ row.status_name }}</el-tag>
<el-tag class="cursor-pointer" type="error" v-if="row.status == 0" @click="edstatusFn(row)">{{ row.status_name }}</el-tag> <el-tag class="cursor-pointer" type="error" v-if="row.status == 0" @click="edStatusFn(row)">{{ row.status_name }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="create_time" :label="t('createTime')"></el-table-column> <el-table-column prop="create_time" :label="t('createTime')"></el-table-column>
@ -121,7 +121,7 @@ const editEvent = (role_id: any) => {
}) })
} }
// //
const edstatusFn=(row:any)=>{ const edStatusFn=(row:any)=>{
roleTableData.loading = true roleTableData.loading = true
let obj={ let obj={
role_id:row.role_id, role_id:row.role_id,

View File

@ -32,7 +32,6 @@
<div> <div>
<el-checkbox v-model="checkAll" :label="t('selectAll')" /> <el-checkbox v-model="checkAll" :label="t('selectAll')" />
</div> </div>
</div> </div>
<!-- :check-strictly="checkStrictly" --> <!-- :check-strictly="checkStrictly" -->
<el-tree :data="menusData" :props="{ label: 'menu_name' }" show-checkbox @check-change="handleCheckChange" :expand-on-click-node="false" node-key="menu_key" ref="treeRef" /> <el-tree :data="menusData" :props="{ label: 'menu_name' }" show-checkbox @check-change="handleCheckChange" :expand-on-click-node="false" node-key="menu_key" ref="treeRef" />
@ -106,13 +105,6 @@ onMounted(async () => {
if (route.query.role_id) { getRoleInfoFn(route.query.role_id) } else { loading.value = false } if (route.query.role_id) { getRoleInfoFn(route.query.role_id) } else { loading.value = false }
}) })
// const getSystemFn = () => {
// getSystem().then(res => {
// state.menusData = res.data
// if (route.query.role_id) getRoleInfoFn(route.query.role_id)
// })
// }
// getSystemFn()
// //
const getRoleInfoFn = (id: any) => { const getRoleInfoFn = (id: any) => {
getRoleInfo(id).then(res => { getRoleInfo(id).then(res => {

View File

@ -70,7 +70,7 @@ const menusTableData = reactive({
*/ */
const getMenuList = () => { const getMenuList = () => {
menusTableData.loading = true menusTableData.loading = true
getMenus('site').then(res => { getMenus().then(res => {
menusTableData.loading = false menusTableData.loading = false
menusTableData.data = res.data menusTableData.data = res.data
}).catch(() => { }).catch(() => {

View File

@ -125,7 +125,6 @@ const loadUserList = (page: number = 1) => {
page: userTableData.page, page: userTableData.page,
limit: userTableData.limit, limit: userTableData.limit,
username: userTableData.searchParam.seach username: userTableData.searchParam.seach
}).then(res => { }).then(res => {
userTableData.loading = false userTableData.loading = false
userTableData.data = res.data.data userTableData.data = res.data.data

View File

@ -49,7 +49,6 @@ const formData = reactive<Record<string, string | boolean>>({
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
/** /**
* 获取h5配置 * 获取h5配置
*/ */
@ -65,7 +64,6 @@ getH5Config().then(res => {
formData.request_url = res.data.wap_url + '/' formData.request_url = res.data.wap_url + '/'
}) })
/** /**
* 复制 * 复制
*/ */

View File

@ -34,7 +34,6 @@ import { useRouter, useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title
const loading = ref(true) const loading = ref(true)
const formData = reactive<Record<string, string | boolean>>({ const formData = reactive<Record<string, string | boolean>>({
@ -53,7 +52,6 @@ const router = useRouter()
loading.value = false; loading.value = false;
}) })
/** /**
* 复制 * 复制
*/ */

View File

@ -61,6 +61,7 @@ import { t } from '@/lang'
import { getWechatConfig } from '@/app/api/wechat' import { getWechatConfig } from '@/app/api/wechat'
import { img } from '@/utils/common' import { img } from '@/utils/common'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title
const router = useRouter() const router = useRouter()

View File

@ -83,6 +83,7 @@ import { ElMessageBox, ElMessage } from 'element-plus'
import { getWechatMenu, editWechatMenu } from '@/app/api/wechat' import { getWechatMenu, editWechatMenu } from '@/app/api/wechat'
import menuForm from './components/menu-form.vue' import menuForm from './components/menu-form.vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title
const router = useRouter() const router = useRouter()

View File

@ -69,6 +69,7 @@ import { t } from '@/lang'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { setDictData, getDictInfo } from '@/app/api/dict' import { setDictData, getDictInfo } from '@/app/api/dict'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
let showDialog = ref(false) let showDialog = ref(false)
const loading = ref(false) const loading = ref(false)
const dialogVisible = ref(false) const dialogVisible = ref(false)

View File

@ -51,21 +51,15 @@ const formRef = ref<FormInstance>()
// //
const formRules = computed(() => { const formRules = computed(() => {
return { return {
name: [ name: [
{ required: true, message: t('namePlaceholder'), trigger: 'blur' } {required: true, message: t('namePlaceholder'), trigger: 'blur'}
],
] key: [
, {required: true, message: t('keyPlaceholder'), trigger: 'blur'}
key: [ ],
{ required: true, message: t('keyPlaceholder'), trigger: 'blur' } data: [
{required: true, message: t('dataPlaceholder'), trigger: 'blur'}
] ]
,
data: [
{ required: true, message: t('dataPlaceholder'), trigger: 'blur' }
]
,
} }
}) })

View File

@ -65,6 +65,7 @@ import { ElMessageBox } from 'element-plus'
import Edit from '@/app/views/dict/components/edit.vue' import Edit from '@/app/views/dict/components/edit.vue'
import dict from '@/app/views/dict/components/dict.vue' import dict from '@/app/views/dict/components/dict.vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title; const pageName = route.meta.title;

View File

@ -200,7 +200,6 @@
bgColorStart: '#F83287', bgColorStart: '#F83287',
bgColorEnd: '#FE3423' bgColorEnd: '#FE3423'
} }
}) })
} }

View File

@ -72,8 +72,6 @@
const showDialog = ref(false) const showDialog = ref(false)
let iconSelect = ref('0')
const showStyle = () => { const showStyle = () => {
showDialog.value = true showDialog.value = true
} }

View File

@ -328,10 +328,6 @@
const selectImg = (url:string)=> { const selectImg = (url:string)=> {
handleHeight(true); handleHeight(true);
}; };
// //
const handleHeight = (isCalcHeight:boolean = false)=> { const handleHeight = (isCalcHeight:boolean = false)=> {
@ -346,9 +342,7 @@
} }
defineExpose({}) defineExpose({})
/** /**
* 魔方单行多个平分宽度 * 魔方单行多个平分宽度
* 公式 * 公式
@ -493,7 +487,6 @@
rubikCubeList.value.forEach((item, index) => { rubikCubeList.value.forEach((item, index) => {
item.imgWidth += 'px'; item.imgWidth += 'px';
item.imgHeight;
}); });
} }

View File

@ -89,7 +89,6 @@ import { useClipboard } from '@vueuse/core'
import { getUrl } from '@/app/api/sys' import { getUrl } from '@/app/api/sys'
const pageTemplate: any = reactive({}) const pageTemplate: any = reactive({})
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const pageName = route.meta.title; const pageName = route.meta.title;

View File

@ -274,7 +274,6 @@ const operationBtn = ref({
} }
}); });
const orderTableData = reactive({ const orderTableData = reactive({
page: 1, page: 1,
limit: 10, limit: 10,
@ -383,7 +382,6 @@ const transferFn = (data)=>{
* 详情 * 详情
* @param data * @param data
*/ */
let cashOutShowDialog = ref(false); let cashOutShowDialog = ref(false);
let cashOutInfo = ref({}); let cashOutInfo = ref({});
let cashOutLoading = ref(true); let cashOutLoading = ref(true);
@ -428,7 +426,6 @@ const infoEvent = (data: any) => {
router.push(`/finance/recharge/detail?order_id=${data.order_id}`) router.push(`/finance/recharge/detail?order_id=${data.order_id}`)
} }
/** /**
* 会员详情 * 会员详情
*/ */

View File

@ -67,8 +67,8 @@ import storage from '@/utils/storage'
import { findFirstValidRoute } from '@/router/routers' import { findFirstValidRoute } from '@/router/routers'
import { UserFilled } from '@element-plus/icons-vue' import { UserFilled } from '@element-plus/icons-vue'
import useUserStore from '@/stores/modules/user' import useUserStore from '@/stores/modules/user'
const router = useRouter()
const router = useRouter()
const userStore = useUserStore() const userStore = useUserStore()
const loading = ref(true) const loading = ref(true)
const detail = reactive({ const detail = reactive({
@ -102,15 +102,12 @@ const getAuthaddonFn = () => {
getAuthaddonFn() getAuthaddonFn()
const itemPath = (data: any) => { const itemPath = (data: any) => {
console.log(appLink.value)
storage.set({ key: 'menuAppStorage', data: data.key }) storage.set({ key: 'menuAppStorage', data: data.key })
storage.set({ key: 'plugMenuTypeStorage', data: '' }) storage.set({ key: 'plugMenuTypeStorage', data: '' })
const appMenuList = userStore.appMenuList const appMenuList = userStore.appMenuList
appMenuList.push(data.key) appMenuList.push(data.key)
userStore.setAppMenuList(appMenuList) userStore.setAppMenuList(appMenuList)
console.log(appLink.value)
let name: any = appLink.value[data.key] let name: any = appLink.value[data.key]
console.log(name)
router.push({ name: name }) router.push({ name: name })
} }

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="main-container w-full bg-white" v-loading="loading"> <div class="main-container w-full bg-white" v-loading="loading">
<el-card class="box-card !border-none" shadow="never" v-if="applyList.list.length"> <el-card class="box-card !border-none" shadow="never" v-if="appList.list.length">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<span class="text-[20px]">应用管理</span> <span class="text-[20px]">应用管理</span>
</div> </div>
<div class="flex flex-wrap plug-list pb-10 plug-large"> <div class="flex flex-wrap plug-list pb-10 plug-large">
<!-- <div v-for="(item, index) in applyList.list" :key="index + 'b'" <!-- <div v-for="(item, index) in appList.list" :key="index + 'b'"
class="app-item cursor-pointer mr-4 mt-[20px] pb-2 bg-[#f7f7f7]" @click="toLink(item.key)"> class="app-item cursor-pointer mr-4 mt-[20px] pb-2 bg-[#f7f7f7]" @click="toLink(item.key)">
<div class="flex justify-center items-center"> <div class="flex justify-center items-center">
<el-image class="w-[240px] h-[120px]" :src="img(item.icon)" fit="contain"> <el-image class="w-[240px] h-[120px]" :src="img(item.icon)" fit="contain">
@ -24,7 +24,7 @@
</div> </div>
</div> </div>
</div> --> </div> -->
<div v-for="(item, index) in applyList.list" :key="index + 'b'"> <div v-for="(item, index) in appList.list" :key="index + 'b'">
<div v-if="appLink[item.key]" class="relative app-item cursor-pointer px-4 mr-4 mt-[20px] bg-[#f7f7f7] border-[1px] hover:border-primary"> <div v-if="appLink[item.key]" class="relative app-item cursor-pointer px-4 mr-4 mt-[20px] bg-[#f7f7f7] border-[1px] hover:border-primary">
<div @click="toLink(item.key)"> <div @click="toLink(item.key)">
<div class="flex py-5 items-center"> <div class="flex py-5 items-center">
@ -53,7 +53,7 @@
</div> </div>
</div> </div>
</el-card> </el-card>
<div class="empty flex items-center justify-center" v-if="!loading && !applyList.list.length"> <div class="empty flex items-center justify-center" v-if="!loading && !appList.list.length">
<el-empty :description="t('emptyData')" /> <el-empty :description="t('emptyData')" />
</div> </div>
</div> </div>
@ -67,18 +67,19 @@ import { findFirstValidRoute } from "@/router/routers";
import useUserStore from "@/stores/modules/user"; import useUserStore from "@/stores/modules/user";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { t } from '@/lang' import { t } from '@/lang'
const userStore = useUserStore(); const userStore = useUserStore();
const router = useRouter(); const router = useRouter();
const applyList = reactive({ const appList = reactive({
list: [], list: [],
}); });
let loading = ref(true); let loading = ref(true);
const getApplelist = async () => { const getAppList = async () => {
const res = await getApply({ type: "tart" }); const res = await getApply({ type: "tart" });
applyList.list = res.data; appList.list = res.data;
loading.value = false; loading.value = false;
}; };
getApplelist(); getAppList();
const appLink = ref({}); const appLink = ref({});
const getAppLink = () => { const getAppLink = () => {

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="main-container w-full bg-white" v-loading="loading"> <div class="main-container w-full bg-white" v-loading="loading">
<el-card class="box-card !border-none" shadow="never" v-if="applyList.list.length"> <el-card class="box-card !border-none" shadow="never" v-if="appList.list.length">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<span class="text-[20px]">应用管理</span> <span class="text-[20px]">应用管理</span>
</div> </div>
<div class="flex flex-wrap plug-list pb-10 plug-large"> <div class="flex flex-wrap plug-list pb-10 plug-large">
<!-- <div v-for="(item, index) in applyList.list" :key="index + 'b'" <!-- <div v-for="(item, index) in appList.list" :key="index + 'b'"
class="app-item cursor-pointer mr-4 mt-[20px] pb-2 bg-[#f7f7f7]" @click="toLink(item.key)"> class="app-item cursor-pointer mr-4 mt-[20px] pb-2 bg-[#f7f7f7]" @click="toLink(item.key)">
<div class="flex justify-center items-center"> <div class="flex justify-center items-center">
<el-image class="w-[240px] h-[120px]" :src="img(item.icon)" fit="contain"> <el-image class="w-[240px] h-[120px]" :src="img(item.icon)" fit="contain">
@ -24,7 +24,7 @@
</div> </div>
</div> </div>
</div> --> </div> -->
<div v-for="(item, index) in applyList.list" :key="index + 'b'"> <div v-for="(item, index) in appList.list" :key="index + 'b'">
<div v-if="appLink[item.key]" <div v-if="appLink[item.key]"
class="relative app-item cursor-pointer px-4 mr-4 mt-[20px] bg-[#f7f7f7] border-[1px] hover:border-primary"> class="relative app-item cursor-pointer px-4 mr-4 mt-[20px] bg-[#f7f7f7] border-[1px] hover:border-primary">
<div @click="toLink(item.key)"> <div @click="toLink(item.key)">
@ -40,7 +40,6 @@
</div> </div>
<div class="flex flex-col justify-between text-left w-[190px]"> <div class="flex flex-col justify-between text-left w-[190px]">
<p class="app-text w-[190px] text-[17px] text-[#222] pl-3">{{ item.title }}</p> <p class="app-text w-[190px] text-[17px] text-[#222] pl-3">{{ item.title }}</p>
</div> </div>
</div> </div>
<div class="border-t-[1px] border-[#e8e9eb] py-3"> <div class="border-t-[1px] border-[#e8e9eb] py-3">
@ -51,7 +50,7 @@
</div> </div>
</div> </div>
</el-card> </el-card>
<div class="empty flex items-center justify-center" v-if="!loading&&!applyList.list.length" > <div class="empty flex items-center justify-center" v-if="!loading&&!appList.list.length" >
<el-empty :description="t('emptyData')" /> <el-empty :description="t('emptyData')" />
</div> </div>
</div> </div>
@ -65,21 +64,22 @@ import { findFirstValidRoute } from '@/router/routers'
import useUserStore from '@/stores/modules/user' import useUserStore from '@/stores/modules/user'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { t } from '@/lang' import { t } from '@/lang'
const userStore = useUserStore() const userStore = useUserStore()
const router = useRouter() const router = useRouter()
const applyList = reactive({ const appList = reactive({
list: [] list: []
}) })
let loading = ref(true) let loading = ref(true)
const getApplelist = async () => { const getAppList = async () => {
const res = await getApply({}) const res = await getApply({})
let data = userStore.appMenuList let data = userStore.appMenuList
applyList.list = res.data.filter(el=>{ appList.list = res.data.filter(el=>{
return data.includes(el.key) return data.includes(el.key)
}) })
loading.value = false loading.value = false
} }
getApplelist() getAppList()
const appLink = ref({}) const appLink = ref({})
const getAppLink = () => { const getAppLink = () => {

View File

@ -3,17 +3,17 @@
<el-card class="box-card !border-none" shadow="never" > <el-card class="box-card !border-none" shadow="never" >
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<span class="text-[20px]">应用管理</span> <span class="text-[20px]">应用管理</span>
<el-form :inline="true" :model="applyList.search" ref="searchFormRef"> <el-form :inline="true" :model="appList.search" ref="searchFormRef">
<el-form-item :label="t('appName')" prop="title"> <el-form-item :label="t('appName')" prop="title">
<el-input v-model="applyList.search.title" :placeholder="t('appNamePlaceholder')" /> <el-input v-model="appList.search.title" :placeholder="t('appNamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="getApplelist()">{{ t('search') }}</el-button> <el-button type="primary" @click="getAppList()">{{ t('search') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="flex flex-wrap plug-list pb-10 plug-large" v-if="applyList.list.length"> <div class="flex flex-wrap plug-list pb-10 plug-large" v-if="appList.list.length">
<div v-for="(item, index) in applyList.list" :key="index + 'b'"> <div v-for="(item, index) in appList.list" :key="index + 'b'">
<div class="relative app-item cursor-pointer px-4 mr-4 mt-[20px] bg-[#f7f7f7] border-[1px] hover:border-primary"> <div class="relative app-item cursor-pointer px-4 mr-4 mt-[20px] bg-[#f7f7f7] border-[1px] hover:border-primary">
<div @click="toLink(item.key)" class="flex py-5 items-center"> <div @click="toLink(item.key)" class="flex py-5 items-center">
<div class="flex justify-center items-center"> <div class="flex justify-center items-center">
@ -32,7 +32,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="empty flex items-center justify-center" v-if="!loading&&!applyList.list.length" > <div class="empty flex items-center justify-center" v-if="!loading&&!appList.list.length" >
<el-empty :description="t('emptyAppData')" /> <el-empty :description="t('emptyAppData')" />
</div> </div>
</el-card> </el-card>
@ -52,7 +52,7 @@ import storage from '@/utils/storage'
var key = storage.get('menuAppStorage') var key = storage.get('menuAppStorage')
const userStore = useUserStore() const userStore = useUserStore()
const router = useRouter() const router = useRouter()
const applyList = reactive({ const appList = reactive({
list: [], list: [],
search: { search: {
title: "", title: "",
@ -60,9 +60,9 @@ const applyList = reactive({
} }
}) })
let loading = ref(true) let loading = ref(true)
const getApplelist = async () => { const getAppList = async () => {
const res = await getApply({title: applyList.search.title,support_app:applyList.search.key}) const res = await getApply({title: appList.search.title,support_app:appList.search.key})
applyList.list = res.data.filter(el=>{ appList.list = res.data.filter(el=>{
return appLink.value[el.key] &&el.type == 'addon' return appLink.value[el.key] &&el.type == 'addon'
}) })
loading.value = false loading.value = false
@ -80,7 +80,7 @@ const getAppLink = () => {
} }
} }
}) })
getApplelist() getAppList()
} }
getAppLink() getAppLink()

View File

@ -30,7 +30,11 @@
<div class="w-[230px] mx-auto"><img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt=""></div> <div class="w-[230px] mx-auto"><img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt=""></div>
</template> </template>
<template #description> <template #description>
<p class="flex items-center"><span>{{ t('descriptionLeft') }}</span><el-link type="primary" @click="goRouter">{{ t('link') }}</el-link><span>{{ t('descriptionRight') }}</span></p> <p class="flex items-center">
<span>{{ t('descriptionLeft') }}</span>
<el-link type="primary" @click="goRouter">{{ t('link') }}</el-link>
<span>{{ t('descriptionRight') }}</span>
</p>
</template> </template>
</el-empty> </el-empty>
</div> </div>
@ -46,6 +50,7 @@ import { t } from '@/lang'
import { getAuthaddon } from '@/app/api/auth' import { getAuthaddon } from '@/app/api/auth'
import { img } from '@/utils/common' import { img } from '@/utils/common'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
import useUserStore from '@/stores/modules/user' import useUserStore from '@/stores/modules/user'
const userStore = useUserStore() const userStore = useUserStore()

View File

@ -37,13 +37,13 @@ import { useRoute, useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
// //
let saveInfo = reactive({ let saveInfo = reactive({
head_img: '', head_img: '',
real_name: '', real_name: '',
original_password: '', original_password: '',
password: '', password: '',
password_copy: '', password_copy: '',
username: '' username: ''
}); });
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
const loading = ref(true); const loading = ref(true);
@ -69,8 +69,7 @@ const getUserInfoFn = () => {
} }
getUserInfoFn(); getUserInfoFn();
//
//
const toEditPersonal = () => { const toEditPersonal = () => {
router.push('/user/edit_center') router.push('/user/edit_center')
} }

View File

@ -32,7 +32,9 @@
<el-table v-if="localList[activeName].length" :data="info[activeName]" size="large" class="pt-[5px]"> <el-table v-if="localList[activeName].length" :data="info[activeName]" size="large" class="pt-[5px]">
<el-table-column :label="t('appName')" align="left" width="320"> <el-table-column :label="t('appName')" align="left" width="320">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex items-center" :class="{'cursor-pointer': row.type == 'app' && Object.keys(row.install_info).length}" @click="itemPath(row)"> <div class="flex items-center"
:class="{ 'cursor-pointer': row.type == 'app' && Object.keys(row.install_info).length }"
@click="itemPath(row)">
<el-image class="w-[54px] h-[54px]" :src="row.icon" fit="contain"> <el-image class="w-[54px] h-[54px]" :src="row.icon" fit="contain">
<template #error> <template #error>
<img class="w-[54px] h-[54px]" src="@/app/assets/images/icon-addon.png" alt=""> <img class="w-[54px] h-[54px]" src="@/app/assets/images/icon-addon.png" alt="">
@ -349,7 +351,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive, watch, h } from 'vue' import { ref, reactive, watch, h } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck } from '@/app/api/addon' import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck, cancelInstall } from '@/app/api/addon'
import { downloadVersion, getAuthinfo, setAuthinfo } from '@/app/api/module' import { downloadVersion, getAuthinfo, setAuthinfo } from '@/app/api/module'
import { ElMessageBox, ElNotification, FormInstance, FormRules } from 'element-plus' import { ElMessageBox, ElNotification, FormInstance, FormRules } from 'element-plus'
import { img } from '@/utils/common' import { img } from '@/utils/common'
@ -358,6 +360,7 @@ import { findFirstValidRoute } from '@/router/routers'
import storage from '@/utils/storage' import storage from '@/utils/storage'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import useUserStore from '@/stores/modules/user' import useUserStore from '@/stores/modules/user'
const router = useRouter() const router = useRouter()
const activeName = ref('installed') const activeName = ref('installed')
const loading = ref<Boolean>(true) const loading = ref<Boolean>(true)
@ -389,9 +392,9 @@ getAuthinfo().then(res => {
/** /**
* 本地下载的插件列表 * 本地下载的插件列表
*/ */
//input // input
const search_name = ref('') const search_name = ref('')
// //
const info = ref({ const info = ref({
installed: [], installed: [],
uninstalled: [], uninstalled: [],
@ -459,8 +462,8 @@ const itemPath = (data: any) => {
const appMenuList = userStore.appMenuList const appMenuList = userStore.appMenuList
appMenuList.push(data.key) appMenuList.push(data.key)
userStore.setAppMenuList(appMenuList) userStore.setAppMenuList(appMenuList)
let name:any = appLink.value[data.key] const name: any = appLink.value[data.key]
router.push({ name: name }) router.push({ name })
} }
} }
@ -481,11 +484,11 @@ const installCheckResult = ref({})
*/ */
const installAddonFn = (key: string) => { const installAddonFn = (key: string) => {
currAddon.value = key currAddon.value = key
installStep.value = 1
installShowDialog.value = true
installAfterTips.value = []
preInstallCheck(key).then(res => { preInstallCheck(key).then(res => {
installStep.value = 1
installShowDialog.value = true
installAfterTips.value = []
installCheckResult.value = res.data installCheckResult.value = res.data
userStore.clearRouters() userStore.clearRouters()
}).catch(() => { }) }).catch(() => { })
@ -676,6 +679,7 @@ const installShowDialogClose = (done: () => {}) => {
type: 'warning' type: 'warning'
} }
).then(() => { ).then(() => {
cancelInstall(currAddon.value)
done() done()
}).catch(() => { }) }).catch(() => { })
} else done() } else done()
@ -737,8 +741,8 @@ const save = async (formEl: FormInstance | undefined) => {
.then(() => { .then(() => {
saveLoading.value = false saveLoading.value = false
setTimeout(() => { setTimeout(() => {
location.reload(); location.reload()
}, 1000); }, 1000)
}) })
.catch(() => { .catch(() => {
saveLoading.value = false saveLoading.value = false

View File

@ -80,7 +80,6 @@ const verifyRef = ref(null)
const success = (params) => { const success = (params) => {
loginFn({ captcha_code: params.captchaVerification }) loginFn({ captcha_code: params.captchaVerification })
} }
// - end
const form = reactive({ const form = reactive({
username: '', username: '',

View File

@ -162,7 +162,6 @@ let memberAccountLogTableData = reactive({
create_time:"", create_time:"",
mobile:"", mobile:"",
member_id, member_id,
}, },
balance_type: "" balance_type: ""
}) })

View File

@ -66,7 +66,6 @@ const formRules = computed(() => {
{ required: true, message: t('memberNoPlaceholder'), trigger: 'blur' }, { required: true, message: t('memberNoPlaceholder'), trigger: 'blur' },
{ validator: memberNoVerify, trigger: 'blur' } { validator: memberNoVerify, trigger: 'blur' }
], ],
mobile: [ mobile: [
{ required: true, message: t('mobilePlaceholder'), trigger: 'blur' }, { required: true, message: t('mobilePlaceholder'), trigger: 'blur' },
{ validator: mobileVerify, trigger: 'blur' } { validator: mobileVerify, trigger: 'blur' }

View File

@ -10,7 +10,6 @@
<el-form-item :label="t('sort')" prop="sort"> <el-form-item :label="t('sort')" prop="sort">
<el-input v-model="formData.sort" clearable :placeholder="t('sortPlaceholder')" class="input-width" type="number" /> <el-input v-model="formData.sort" clearable :placeholder="t('sortPlaceholder')" class="input-width" type="number" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -49,12 +48,12 @@ const formRef = ref<FormInstance>()
// //
const formRules = computed(() => { const formRules = computed(() => {
return { return {
label_name: [ label_name: [
{ required: true, message: t('labelNamePlaceholder'), trigger: 'blur' } {required: true, message: t('labelNamePlaceholder'), trigger: 'blur'}
], ],
sort:[ sort: [
{ validator: sortVerify, trigger: 'blur' } {validator: sortVerify, trigger: 'blur'}
] ]
} }
}) })

View File

@ -68,7 +68,6 @@ const initialFormData = {
nickname:'', nickname:'',
related_id:'', related_id:'',
username:'' username:''
} }
const formData: Record<string, any> = reactive({ ...initialFormData }) const formData: Record<string, any> = reactive({ ...initialFormData })

View File

@ -37,8 +37,6 @@
<el-date-picker v-model="memberTableData.searchParam.create_time" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')" /> <el-date-picker v-model="memberTableData.searchParam.create_time" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="loadMemberList()">{{ t('search') }}</el-button> <el-button type="primary" @click="loadMemberList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> <el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
@ -134,7 +132,7 @@
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
import { img } from '@/utils/common' import { img } from '@/utils/common'
import { addMember, getRegisterChannelType, getMemberList, getMemberLabelAll, editMemberStatus,deleteMember } from '@/app/api/member' import { getRegisterChannelType, getMemberList, getMemberLabelAll, editMemberStatus,deleteMember } from '@/app/api/member'
import { ElMessageBox, FormInstance } from 'element-plus' import { ElMessageBox, FormInstance } from 'element-plus'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import AddMember from '@/app/views/member/components/add-member.vue' import AddMember from '@/app/views/member/components/add-member.vue'
@ -176,7 +174,6 @@ const getMemberLabelAllFn = async () => {
} }
getMemberLabelAllFn(); getMemberLabelAllFn();
const resetForm = (formEl: FormInstance | undefined)=>{ const resetForm = (formEl: FormInstance | undefined)=>{
if (!formEl) return if (!formEl) return
formEl.resetFields(); formEl.resetFields();

View File

@ -249,8 +249,8 @@ import EditMember from '@/app/views/member/components/edit-member.vue'
import colorGradient from '../../../../uniapp/src/uni_modules/vk-uview-ui/libs/function/colorGradient' import colorGradient from '../../../../uniapp/src/uni_modules/vk-uview-ui/libs/function/colorGradient'
import useAppStore from '@/stores/modules/app' import useAppStore from '@/stores/modules/app'
import storage from '@/utils/storage' import storage from '@/utils/storage'
const theme = storage.get('theme') ?? {} const theme = storage.get('theme') ?? {}
console.log(theme)
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title

View File

@ -67,7 +67,6 @@ const setFormData = async (agreement_key: string = '') => {
} }
if (agreement_key) setFormData(agreement_key) if (agreement_key) setFormData(agreement_key)
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
// //

View File

@ -89,8 +89,6 @@ const setFormData = async (id: number = 0) => {
} }
setFormData() setFormData()
const minRules = (rule: any, value: any, callback: any) => { const minRules = (rule: any, value: any, callback: any) => {
if (Number(value) < 0.01) { if (Number(value) < 0.01) {
callback(new Error(t('cashWithdrawalAmountHint'))) callback(new Error(t('cashWithdrawalAmountHint')))

View File

@ -78,7 +78,6 @@ const formRules = computed(() => {
domain: [ domain: [
{ required: true, message: t('domainPlaceholder'), trigger: 'blur' } { required: true, message: t('domainPlaceholder'), trigger: 'blur' }
], ],
} }
}) })

View File

@ -95,7 +95,7 @@ const onSave = async (formEl: FormInstance | undefined) => {
if (valid) { if (valid) {
setMemberConfig(formData).then(() => { setMemberConfig(formData).then(() => {
loading.value = false loading.value = false
getMemberNo(); getMemberNo(formEl);
}).catch(() => { }).catch(() => {
loading.value = false loading.value = false
}) })

View File

@ -71,8 +71,8 @@ import { getNoticeList } from '@/app/api/notice'
import Sms from '@/app/views/setting/components/notice-sms.vue' import Sms from '@/app/views/setting/components/notice-sms.vue'
import Wechat from '@/app/views/setting/components/notice-wechat.vue' import Wechat from '@/app/views/setting/components/notice-wechat.vue'
import Weapp from '@/app/views/setting/components/notice-weapp.vue' import Weapp from '@/app/views/setting/components/notice-weapp.vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title

View File

@ -67,6 +67,7 @@ import { img } from '@/utils/common'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import Sortable, { SortableEvent } from 'sortablejs' import Sortable, { SortableEvent } from 'sortablejs'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title

View File

@ -100,6 +100,7 @@ import { getAddontype, addAddonDevelop, editAddonDevelop, getAddonDevelopInfo, g
import { getAddonList} from '@/app/api/sys' import { getAddonList} from '@/app/api/sys'
import { ElMessageBox, ElMessage } from 'element-plus' import { ElMessageBox, ElMessage } from 'element-plus'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const pageName = route.meta.title; const pageName = route.meta.title;

View File

@ -205,6 +205,7 @@ import { img } from '@/utils/common'
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const pageName = route.meta.title; const pageName = route.meta.title;

View File

@ -30,6 +30,7 @@ import { ref, reactive, computed } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
import { addGenerateTable, generateTable } from '@/app/api/tools' import { addGenerateTable, generateTable } from '@/app/api/tools'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
let showDialog = ref(false) let showDialog = ref(false)
const search = ref('') const search = ref('')

View File

@ -145,12 +145,10 @@ const confirm = async (formEl: FormInstance | undefined) => {
} }
const setFormData = async (row: any = null) => { const setFormData = async (row: any = null) => {
formData.value = cloneDeep(Object.assign(initialFormData, row)) formData.value = cloneDeep(Object.assign(initialFormData, row))
showDialog.value = true showDialog.value = true
} }
const beforeClose = (next: any) => { const beforeClose = (next: any) => {
formRef.value?.clearValidate() formRef.value?.clearValidate()
next() next()
} }

View File

@ -301,6 +301,7 @@ import { useRoute, useRouter } from 'vue-router'
import Sortable from 'sortablejs' import Sortable from 'sortablejs'
import { useTemplateRefsList } from '@vueuse/core' import { useTemplateRefsList } from '@vueuse/core'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const pageName = route.meta.title const pageName = route.meta.title

View File

@ -83,9 +83,7 @@ const getSystemService = () => {
getSystem().then(res => { getSystem().then(res => {
systemService.value = res.data systemService.value = res.data
loadingArr.server_load = false; loadingArr.server_load = false;
}).catch(()=>{
})
.catch(()=>{
loadingArr.server_load = false; loadingArr.server_load = false;
}) })
} }

View File

@ -44,7 +44,7 @@
</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-[148px]" />
</div> </div>
<div class="w-[256px] h-[260px] tools-item-shadow mb-[24px] mx-[14px] rounded-[8px] flex flex-col cursor-pointer" @click="toLink('/tools/admin')"> <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="flex-1 py-[19px] px-[24px] flex flex-col">
<span class="text-[16px] text-[#222] font-bold">菜单管理</span> <span class="text-[16px] text-[#222] font-bold">菜单管理</span>
<p class="text-[13px] text-[#666] mt-[8px] multi-hidden">菜单管理</p> <p class="text-[13px] text-[#666] mt-[8px] multi-hidden">菜单管理</p>
@ -78,6 +78,7 @@
import storage from '@/utils/storage' import storage from '@/utils/storage'
import {findFirstValidRoute} from '@/router/routers' import {findFirstValidRoute} from '@/router/routers'
import {UserFilled} from '@element-plus/icons-vue' import {UserFilled} from '@element-plus/icons-vue'
const router = useRouter() const router = useRouter()
const toLink = (link)=>{ const toLink = (link)=>{

View File

@ -6,7 +6,7 @@
<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"> <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> <span class="iconfont iconyun1 !text-[32px] !w-auto text-[#fff]"></span>
<!-- <app-menu :isShowHover="threefloatMenu" :data="applyList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>--> <!-- <app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>-->
</div> </div>
<template v-for="(item, index) in menus" :key="index"> <template v-for="(item, index) in menus" :key="index">
@ -16,7 +16,7 @@
<div class="flex items-center justify-center w-[30px] h-[30px]" v-else> <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" /> <icon v-if="item.meta.icon" :name="item.meta.icon" class="!w-auto" size="24px" />
</div> </div>
<!-- <app-menu :isShowHover="threefloatMenu" :data="applyList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>--> <!-- <app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>-->
</div> </div>
<div v-for="(appItem, appIndex) in item.children" :key="appIndex" @click="toLink(appItem)" <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}]"> :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}]">
@ -188,19 +188,19 @@ const isLoad = ref(false);
// start // start
const applyList = ref([]) const appList = ref([])
const applyTypeList = ref([]) const appTypeList = ref([])
const otherTypeList = ref([]) // \\ const otherTypeList = ref([]) // \\
const getApplelist = async () => { const getAppList = async () => {
const res = await getApply() const res = await getApply()
applyList.value = applyList.value.concat(res.data) appList.value = appList.value.concat(res.data)
applyList.value.forEach((item, index) => { appList.value.forEach((item, index) => {
if (item.type == 'app') { applyTypeList.value.push(item.key) } if (item.type == 'app') { appTypeList.value.push(item.key) }
if (item.type == 'addon') { otherTypeList.value.push(item.key) } if (item.type == 'addon') { otherTypeList.value.push(item.key) }
}) })
isLoad.value = true; isLoad.value = true;
} }
getApplelist() getAppList()
// end // end
@ -219,8 +219,8 @@ const menus = computed(() => {
} }
}) })
if(applyList.value && applyList.value.length){ if(appList.value && appList.value.length){
applyList.value.forEach((item,index) =>{ appList.value.forEach((item,index) =>{
menus.forEach((menuItem,menuIndex)=>{ menus.forEach((menuItem,menuIndex)=>{
if(item.key == menuItem.meta.key){ if(item.key == menuItem.meta.key){
menuItem.meta.parentTitle = item.title; menuItem.meta.parentTitle = item.title;
@ -231,13 +231,13 @@ const menus = computed(() => {
} }
// //
if(!applyList.value.length && !globalAppKey.value){ if(!appList.value.length && !globalAppKey.value){
storage.set({ key: 'menuAppStorage', data: '' }) storage.set({ key: 'menuAppStorage', data: '' })
globalAppKey.value = "" globalAppKey.value = ""
} }
if(applyList.value.length && !globalAppKey.value){ if(appList.value.length && !globalAppKey.value){
storage.set({ key: 'menuAppStorage', data: applyTypeList.value[0] }) storage.set({ key: 'menuAppStorage', data: appTypeList.value[0] })
globalAppKey.value = applyTypeList.value[0] globalAppKey.value = appTypeList.value[0]
} }
menus.forEach((item,index)=>{ menus.forEach((item,index)=>{
if(globalAppKey.value && item.meta.app == globalAppKey.value){ if(globalAppKey.value && item.meta.app == globalAppKey.value){
@ -262,7 +262,7 @@ const dark = computed(() => {
// //
watch(() =>userStore.globalAppKey, (val,old) => { watch(() =>userStore.globalAppKey, (val,old) => {
getApplelist(); getAppList();
},{deep: true}) },{deep: true})

View File

@ -6,7 +6,7 @@
<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"> <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> <span class="iconfont iconyun1 !text-[32px] !w-auto text-[#fff]"></span>
<!-- <app-menu :isShowHover="threefloatMenu" :data="applyList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>--> <!-- <app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>-->
</div> </div>
<template v-for="(item, index) in menus" :key="index"> <template v-for="(item, index) in menus" :key="index">
@ -16,7 +16,7 @@
<div class="flex items-center justify-center w-[30px] h-[30px]" v-else> <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" /> <icon v-if="item.meta.icon" :name="item.meta.icon" class="!w-auto" size="24px" />
</div> </div>
<!-- <app-menu :isShowHover="threefloatMenu" :data="applyList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>--> <!-- <app-menu :isShowHover="threefloatMenu" :data="appList" @child-click="toLink" hoverType='threefloatMenu'></app-menu>-->
</div> </div>
<div v-for="(appItem, appIndex) in item.children" :key="appIndex" @click="toLink(appItem)" <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}]"> :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}]">
@ -201,21 +201,20 @@ globalAppKey.value = storage.get('menuAppStorage')
localMenuKey.value = storage.get('menuAppStorage') localMenuKey.value = storage.get('menuAppStorage')
const isLoad = ref(false); const isLoad = ref(false);
// start // start
const applyList = ref([]) const appList = ref([])
const applyTypeList = ref([]) const appTypeList = ref([])
const otherTypeList = ref([]) // \\ const otherTypeList = ref([]) // \\
const getApplelist = async () => { const getAppList = async () => {
const res = await getApply() const res = await getApply()
applyList.value = applyList.value.concat(res.data) appList.value = appList.value.concat(res.data)
applyList.value.forEach((item, index) => { appList.value.forEach((item, index) => {
if (item.type == 'app') { applyTypeList.value.push(item.key) } if (item.type == 'app') { appTypeList.value.push(item.key) }
if (item.type == 'addon') { otherTypeList.value.push(item.key) } if (item.type == 'addon') { otherTypeList.value.push(item.key) }
}) })
isLoad.value = true; isLoad.value = true;
} }
getApplelist() getAppList()
// end // end
@ -234,8 +233,8 @@ const menus = computed(() => {
} }
}) })
if(applyList.value && applyList.value.length){ if(appList.value && appList.value.length){
applyList.value.forEach((item,index) =>{ appList.value.forEach((item,index) =>{
menus.forEach((menuItem,menuIndex)=>{ menus.forEach((menuItem,menuIndex)=>{
if(item.key == menuItem.meta.key){ if(item.key == menuItem.meta.key){
menuItem.meta.parentTitle = item.title; menuItem.meta.parentTitle = item.title;
@ -246,13 +245,13 @@ const menus = computed(() => {
} }
// //
if(!applyList.value.length && !globalAppKey.value){ if(!appList.value.length && !globalAppKey.value){
storage.set({ key: 'menuAppStorage', data: '' }) storage.set({ key: 'menuAppStorage', data: '' })
globalAppKey.value = "" globalAppKey.value = ""
} }
if(applyList.value.length && !globalAppKey.value){ if(appList.value.length && !globalAppKey.value){
storage.set({ key: 'menuAppStorage', data: applyTypeList.value[0] }) storage.set({ key: 'menuAppStorage', data: appTypeList.value[0] })
globalAppKey.value = applyTypeList.value[0] globalAppKey.value = appTypeList.value[0]
} }
menus.forEach((item,index)=>{ menus.forEach((item,index)=>{
if(globalAppKey.value && item.meta.app == globalAppKey.value){ if(globalAppKey.value && item.meta.app == globalAppKey.value){
@ -277,7 +276,7 @@ const dark = computed(() => {
// //
watch(() =>userStore.globalAppKey, (val,old) => { watch(() =>userStore.globalAppKey, (val,old) => {
getApplelist(); getAppList();
},{deep: true}) },{deep: true})

View File

@ -11,12 +11,12 @@
</div> </div>
<span>{{ item.meta.app ? item.meta.parentTitle : item.meta.title }}</span> <span>{{ item.meta.app ? item.meta.parentTitle : item.meta.title }}</span>
</div> </div>
<!-- <app-menu :isShowHover="twofloatMenu" :data="applyList" @child-click="toLink" hoverType='twofloatMenu'></app-menu>--> <!-- <app-menu :isShowHover="twofloatMenu" :data="appList" @child-click="toLink" hoverType='twofloatMenu'></app-menu>-->
</div> </div>
<el-scrollbar class="overflow-y-auto menus-wrap"> <el-scrollbar class="overflow-y-auto menus-wrap">
<el-menu class="apply-menu !border-0" :router="true" :unique-opened="true" :default-active="String(route.name)"> <el-menu class="apply-menu !border-0" :router="true" :unique-opened="true" :default-active="String(route.name)">
<template v-if="applyTypeList.length"> <template v-if="appTypeList.length">
<template v-for="(twoMenu, twoIndex) in item.children"> <template v-for="(twoMenu, twoIndex) in item.children">
<el-sub-menu :index="String(twoMenu.meta.title)" v-if="twoMenu.children && twoMenu.meta.show"> <el-sub-menu :index="String(twoMenu.meta.title)" v-if="twoMenu.children && twoMenu.meta.show">
<template #title> <template #title>
@ -100,7 +100,7 @@
<!-- 系统菜单 --> <!-- 系统菜单 -->
<template <template
v-if="applyTypeList.includes(localMenuKey) || otherTypeList.includes(localMenuKey)"> v-if="appTypeList.includes(localMenuKey) || otherTypeList.includes(localMenuKey)">
<div class="!border-0 !border-t-[1px] border-solid mx-[25px] bg-[#f7f7f7] my-[5px]"></div> <div class="!border-0 !border-t-[1px] border-solid mx-[25px] bg-[#f7f7f7] my-[5px]"></div>
<template v-for="(twoMenu, twoIndex) in menus"> <template v-for="(twoMenu, twoIndex) in menus">
<el-sub-menu :index="String(twoMenu.meta.title)" <el-sub-menu :index="String(twoMenu.meta.title)"
@ -239,7 +239,7 @@
</template> </template>
<!-- 浮动样式 --> <!-- 浮动样式 -->
<div <div
:class="['!border-0 border-solid mx-[25px] bg-[#f7f7f7] my-[5px]', !applyTypeList.length ? '' : '!border-t-[1px]']"> :class="['!border-0 border-solid mx-[25px] bg-[#f7f7f7] my-[5px]', !appTypeList.length ? '' : '!border-t-[1px]']">
</div> </div>
<template v-for="(twoMenu, twoIndex) in menus"> <template v-for="(twoMenu, twoIndex) in menus">
<el-sub-menu :index="String(twoMenu.meta.title)" <el-sub-menu :index="String(twoMenu.meta.title)"
@ -348,20 +348,20 @@ localMenuKey.value = storage.get('menuAppStorage')
const isLoad = ref(false); const isLoad = ref(false);
// start // start
const applyList = ref([]) const appList = ref([])
const applyTypeList = ref([]) const appTypeList = ref([])
const otherTypeList = ref([]) // \\ const otherTypeList = ref([]) // \\
const getApplelist = async () => { const getAppList = async () => {
const res = await getApply() const res = await getApply()
applyList.value = applyList.value.concat(res.data) appList.value = appList.value.concat(res.data)
applyList.value.forEach((item, index) => { appList.value.forEach((item, index) => {
if (item.type == 'app') { applyTypeList.value.push(item.key) } if (item.type == 'app') { appTypeList.value.push(item.key) }
if (item.type == 'addon') { otherTypeList.value.push(item.key) } if (item.type == 'addon') { otherTypeList.value.push(item.key) }
}) })
otherTypeList.value = otherTypeList.value.concat(['member', 'app_center']) otherTypeList.value = otherTypeList.value.concat(['member', 'app_center'])
isLoad.value = true; isLoad.value = true;
} }
getApplelist() getAppList()
// end // end
// //
@ -379,8 +379,8 @@ const menus = computed(() => {
} }
}) })
if(applyList.value && applyList.value.length){ if(appList.value && appList.value.length){
applyList.value.forEach((item,index) =>{ appList.value.forEach((item,index) =>{
menus.forEach((menuItem,menuIndex)=>{ menus.forEach((menuItem,menuIndex)=>{
if(item.key == menuItem.meta.key){ if(item.key == menuItem.meta.key){
menuItem.meta.parentTitle = item.title; menuItem.meta.parentTitle = item.title;
@ -391,14 +391,14 @@ const menus = computed(() => {
} }
// //
if(!applyList.value.length){ if(!appList.value.length){
storage.set({ key: 'menuAppStorage', data: '' }) storage.set({ key: 'menuAppStorage', data: '' })
globalAppKey.value = "" globalAppKey.value = ""
} }
if(applyList.value.length && !globalAppKey.value){ if(appList.value.length && !globalAppKey.value){
storage.set({ key: 'menuAppStorage', data: applyTypeList.value[0] }) storage.set({ key: 'menuAppStorage', data: appTypeList.value[0] })
globalAppKey.value = applyTypeList.value[0] globalAppKey.value = appTypeList.value[0]
} }
return menus return menus
}) })
@ -409,7 +409,7 @@ const dark = computed(() => {
// //
watch(() =>userStore.globalAppKey, (val,old) => { watch(() =>userStore.globalAppKey, (val,old) => {
getApplelist(); getAppList();
},{deep: true}) },{deep: true})
@ -467,9 +467,9 @@ const sidebar = computed(() => {
// //
const isTwoMenuFn = (item) => { const isTwoMenuFn = (item) => {
let bool = (otherTypeList.value.includes(localMenuKey.value) && globalAppKey.value == item.meta.app) let bool = (otherTypeList.value.includes(localMenuKey.value) && globalAppKey.value == item.meta.app)
|| (!applyTypeList.value.includes(localMenuKey.value) && !otherTypeList.value.includes(localMenuKey.value) && globalAppKey.value && globalAppKey.value == item.meta.app) || (!appTypeList.value.includes(localMenuKey.value) && !otherTypeList.value.includes(localMenuKey.value) && globalAppKey.value && globalAppKey.value == item.meta.app)
|| (applyTypeList.value.includes(localMenuKey.value) && (item.meta.key == localMenuKey.value || item.meta.app == localMenuKey.value)) || (appTypeList.value.includes(localMenuKey.value) && (item.meta.key == localMenuKey.value || item.meta.app == localMenuKey.value))
|| (!applyTypeList.value.length && (item.meta.key == localMenuKey.value || item.meta.app == localMenuKey.value)) || (!appTypeList.value.length && (item.meta.key == localMenuKey.value || item.meta.app == localMenuKey.value))
return bool; return bool;
} }

View File

@ -82,22 +82,22 @@ const useUserStore = defineStore('user', {
storage.set({ key: 'appMenuList' + (this.userInfo.username ? this.userInfo.username : ''), data }) storage.set({ key: 'appMenuList' + (this.userInfo.username ? this.userInfo.username : ''), data })
}, },
getAppList() { getAppList() {
let applyList = []; let appList:any = [];
let applyTypeList = []; let appTypeList:any = [];
let appKey = storage.get('menuAppStorage'); let appKey = storage.get('menuAppStorage');
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getApply() getApply()
.then((res) => { .then((res) => {
applyList = applyList.concat(res.data); appList = appList.concat(res.data);
applyList.forEach((item, index) => { appList.forEach((item, index) => {
if (item.type == 'app') { applyTypeList.push(item.key) } if (item.type == 'app') { appTypeList.push(item.key) }
}); });
// 用于插件的卸载或安装 // 用于插件的卸载或安装
if (!applyList.length) { if (!appList.length) {
this.globalAppKey = ''; this.globalAppKey = '';
} }
if (applyList.length && !appKey) { if (appList.length && !appKey) {
this.globalAppKey = applyTypeList[0]; this.globalAppKey = appTypeList[0];
} }
resolve(res) resolve(res)
}) })