|
|
@ -1,118 +1,37 @@ |
|
|
|
<script setup> |
|
|
|
// 导航栏在这 |
|
|
|
import {onMounted, ref} from 'vue' |
|
|
|
import {useRoute, useRouter} from 'vue-router' |
|
|
|
import {ref} from 'vue' |
|
|
|
import {useRouter} from 'vue-router' |
|
|
|
import {ElMessage} from 'element-plus' |
|
|
|
import API from '@/util/http' |
|
|
|
import dmmn from '../assets/link.png' |
|
|
|
import moment from 'moment' |
|
|
|
import ChangePassword from '@/components/changePassword.vue' |
|
|
|
|
|
|
|
// 获取当前路由实例 |
|
|
|
const route = useRoute() |
|
|
|
import {useAdminStore} from '@/store' |
|
|
|
import {storeToRefs} from 'pinia' |
|
|
|
import {filterMenu, getRoutePath} from "@/utils/menuUtils.js"; |
|
|
|
|
|
|
|
// 存储接口返回的菜单数据 |
|
|
|
const menuList = ref([]) |
|
|
|
|
|
|
|
// 获取仓库实例 |
|
|
|
const adminStore = useAdminStore() |
|
|
|
// 解构状态(保持响应式) 获得 adminData(用户信息) 和 menuTree(菜单树) |
|
|
|
const {adminData, menuTree} = storeToRefs(adminStore) |
|
|
|
|
|
|
|
// 筛选权限菜单 ,menuTree 是组件通信拿的 |
|
|
|
menuList.value = filterMenu(menuTree.value) |
|
|
|
|
|
|
|
/** |
|
|
|
* 调用 /menu/tree 接口获取菜单数据 |
|
|
|
*/ |
|
|
|
const fetchMenuTree = async function() { |
|
|
|
try { |
|
|
|
const result = await API({ url: '/menu/tree', data: {id: adminData.value.roleId} }) |
|
|
|
|
|
|
|
return result.data // 直接返回接口响应数据 |
|
|
|
} catch (error) { |
|
|
|
console.error('菜单数据请求失败:', error) |
|
|
|
return { code: 500, msg: '获取菜单失败' } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function filterMenu(menuList) { |
|
|
|
return menuList |
|
|
|
.filter(menu => menu.menuType !== 4) |
|
|
|
.map(menu => ({ |
|
|
|
...menu, |
|
|
|
children: menu.children ? filterMenu(menu.children) : [] |
|
|
|
})) |
|
|
|
.sort((a, b) => a.priority - b.priority); // 按 id 升序 |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 映射菜单名称到路由路径 |
|
|
|
*/ |
|
|
|
const getRoutePath = (menu) => { |
|
|
|
// 路由映射表:key为接口menuName,value为对应路由路径 |
|
|
|
const routeMap = { |
|
|
|
'工作台': '/workspace', |
|
|
|
|
|
|
|
'审核页面': '/audit', |
|
|
|
'财务审核': '/audit', |
|
|
|
|
|
|
|
'充值审核': '/rechargeAudit', |
|
|
|
'退款审核': '/refundAudit', |
|
|
|
|
|
|
|
'汇率管理': '/rate', |
|
|
|
|
|
|
|
'消耗管理': '/coinConsume', |
|
|
|
'消耗页面': '/coinConsume', |
|
|
|
|
|
|
|
'权限管理': '/permissions', |
|
|
|
|
|
|
|
'充值管理': '/coinRecharge', |
|
|
|
'充值页面': '/coinRecharge', |
|
|
|
|
|
|
|
'退款管理': '/coinRefund', |
|
|
|
'退款页面': '/coinRefund', |
|
|
|
|
|
|
|
'客户账户明细': '/usergold', |
|
|
|
}; |
|
|
|
|
|
|
|
// 未匹配的菜单默认使用id作为路由(可根据实际需求调整) |
|
|
|
return routeMap[menu.menuName] || '/workspace' |
|
|
|
} |
|
|
|
console.log("menuList", menuList.value) |
|
|
|
|
|
|
|
const router = useRouter() |
|
|
|
const imgrule1 = dmmn |
|
|
|
const messageVisible = ref(false) |
|
|
|
|
|
|
|
// 这是获取用户信息的接口 |
|
|
|
const adminData = ref({ |
|
|
|
name: '' |
|
|
|
}) |
|
|
|
|
|
|
|
const getAdminData = async function () { |
|
|
|
try { |
|
|
|
const result = await API({ url: '/admin/userinfo', data: {} }) |
|
|
|
adminData.value = result |
|
|
|
console.log('请求成功', result) |
|
|
|
console.log('用户信息', adminData.value) |
|
|
|
} catch (error) { |
|
|
|
console.log('请求失败', error) |
|
|
|
} |
|
|
|
} |
|
|
|
// 获取地区 |
|
|
|
const areas = ref([]) |
|
|
|
|
|
|
|
const currentArea = ref('全部') |
|
|
|
|
|
|
|
const getAreas = async function () { |
|
|
|
try { |
|
|
|
const result = await API({ url: '/general/adminMarkets', data: { |
|
|
|
account: adminData.value.account, |
|
|
|
} }) |
|
|
|
areas.value = result.data |
|
|
|
console.log('请求成功', result) |
|
|
|
} catch (error) { |
|
|
|
console.log('请求失败', error) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 查看个人信息弹出框 |
|
|
|
const openMessage = function () { |
|
|
|
messageVisible.value = true |
|
|
|
} |
|
|
|
// 关闭个人信息 |
|
|
|
const closeMessage = function () { |
|
|
|
messageVisible.value = false |
|
|
|
} |
|
|
@ -120,93 +39,23 @@ const message = function () { |
|
|
|
openMessage() |
|
|
|
} |
|
|
|
|
|
|
|
// 导出列表数据 |
|
|
|
const exportList = ref([]) |
|
|
|
// 导出列表加载状态 |
|
|
|
const exportListLoading = ref(false) |
|
|
|
|
|
|
|
//根据状态返回对应的标签类型 |
|
|
|
const getTagType = (state) => { |
|
|
|
switch (state) { |
|
|
|
case 0: |
|
|
|
return 'info'; |
|
|
|
case 1: |
|
|
|
return 'primary'; |
|
|
|
case 2: |
|
|
|
return'success'; |
|
|
|
case 3: |
|
|
|
return 'danger'; |
|
|
|
default: |
|
|
|
return 'info'; |
|
|
|
} |
|
|
|
} |
|
|
|
//根据状态返回对应的标签文案 |
|
|
|
const getTagText = (state) => { |
|
|
|
switch (state) { |
|
|
|
case 0: |
|
|
|
return '待执行'; |
|
|
|
case 1: |
|
|
|
return '执行中'; |
|
|
|
case 2: |
|
|
|
return'执行完成'; |
|
|
|
case 3: |
|
|
|
return '执行出错'; |
|
|
|
default: |
|
|
|
return '未知状态'; |
|
|
|
} |
|
|
|
} |
|
|
|
// 显示修改密码弹窗 |
|
|
|
const showPasswordDialog = ref(false) |
|
|
|
|
|
|
|
// 下载导出文件 |
|
|
|
const downloadExportFile = (item) => { |
|
|
|
if (item.state === 2) { |
|
|
|
const link = document.createElement('a') |
|
|
|
link.href = item.url |
|
|
|
link.download = item.fileName |
|
|
|
link.click() |
|
|
|
} else { |
|
|
|
ElMessage.warning('文件还在导出中,请稍后再试') |
|
|
|
} |
|
|
|
//打开修改密码弹窗 |
|
|
|
const openChangePassword = () => { |
|
|
|
showPasswordDialog.value = true |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function logout() { |
|
|
|
const machineId = localStorage.getItem('machineId') |
|
|
|
localStorage.removeItem('token') |
|
|
|
adminStore.clearState() |
|
|
|
router.push('/login?machineId=' + machineId) |
|
|
|
ElMessage.success('退出成功') |
|
|
|
} |
|
|
|
|
|
|
|
// 挂载 |
|
|
|
onMounted(async function () { |
|
|
|
// 获取用户信息 |
|
|
|
|
|
|
|
await getAdminData() |
|
|
|
|
|
|
|
const menus = await fetchMenuTree() |
|
|
|
menuList.value = filterMenu(menus) |
|
|
|
}) |
|
|
|
// 处理地区点击事件,直接在组件内更新当前地区,包老师改的,直接传参 |
|
|
|
const changeDataByArea = (item) => { |
|
|
|
currentArea.value = item |
|
|
|
} |
|
|
|
|
|
|
|
// 控制导出列表弹窗显示状态 |
|
|
|
const exportListVisible = ref(false) |
|
|
|
// 显示修改密码弹窗 |
|
|
|
const showPasswordDialog = ref(false) |
|
|
|
// 打开导出列表弹窗 |
|
|
|
const openExportList = () => { |
|
|
|
getExportList() |
|
|
|
exportListVisible.value = true |
|
|
|
} |
|
|
|
//打开修改密码弹窗 |
|
|
|
const openChangePassword = () => { |
|
|
|
showPasswordDialog.value = true |
|
|
|
} |
|
|
|
// 關閉修改密碼的清空邏輯 |
|
|
|
const changePasswordRef = ref(null) |
|
|
|
const handleClosePasswordDialog = () => { |
|
|
|
changePasswordRef.value?.resetFields() |
|
|
|
} |
|
|
|
|
|
|
|
</script> |
|
|
|
|
|
|
@ -224,31 +73,44 @@ const handleClosePasswordDialog = () => { |
|
|
|
z-index: 100; /* 确保侧边栏在其他元素之上 */ |
|
|
|
"> |
|
|
|
<div class="logo"> |
|
|
|
<img src="../assets/新logo.png" alt="logo" style="width: 80px; height: 80px" /> |
|
|
|
<img src="../assets/新logo.png" alt="logo" style="width: 80px; height: 80px"/> |
|
|
|
<!-- <div style="font-size: 16px; font-weight: bold; color: black; text-align: center;" ><h1>海外金币管理系统</h1></div> --> |
|
|
|
</div> |
|
|
|
<el-card style="min-height: 90%;"> |
|
|
|
|
|
|
|
<el-menu :router="true" class="el-menu-vertical-demo" :default-active="$route.path"> |
|
|
|
<el-menu |
|
|
|
:router="true" |
|
|
|
class="el-menu-vertical-demo" |
|
|
|
:default-active="$route.path" |
|
|
|
> |
|
|
|
<!-- 递归渲染菜单层级 --> |
|
|
|
<template v-for="menu in menuList" :key="menu.id"> |
|
|
|
<!-- 有子菜单的父级菜单(menuType=2 且存在children) --> |
|
|
|
<el-sub-menu v-if="menu.children && menu.children.length > 0" :index="menu.id.toString()"> |
|
|
|
<el-sub-menu |
|
|
|
v-if="menu.children && menu.children.length > 0" |
|
|
|
:index="menu.id.toString()" |
|
|
|
> |
|
|
|
<template #title> |
|
|
|
<el-icon> |
|
|
|
<Folder /> |
|
|
|
<Folder/> |
|
|
|
</el-icon> |
|
|
|
<span>{{ menu.menuName }}</span> |
|
|
|
</template> |
|
|
|
<!-- 子菜单 --> |
|
|
|
<template v-for="child in menu.children" :key="child.id"> |
|
|
|
<!-- 子菜单为叶子节点(无children) --> |
|
|
|
<el-menu-item v-if="!child.children || child.children.length === 0" :index="getRoutePath(child)"> |
|
|
|
<el-menu-item |
|
|
|
v-if="!child.children || child.children.length === 0" |
|
|
|
:index="getRoutePath(child)" |
|
|
|
> |
|
|
|
<span>{{ child.menuName }}</span> |
|
|
|
</el-menu-item> |
|
|
|
|
|
|
|
<!-- 子菜单有下级 --> |
|
|
|
<el-sub-menu v-else :index="child.id.toString()"> |
|
|
|
<el-sub-menu |
|
|
|
v-else |
|
|
|
:index="child.id.toString()" |
|
|
|
> |
|
|
|
<template #title> |
|
|
|
<span>{{ child.menuName }}</span> |
|
|
|
</template> |
|
|
@ -263,9 +125,12 @@ const handleClosePasswordDialog = () => { |
|
|
|
</el-sub-menu> |
|
|
|
|
|
|
|
<!-- 无子菜单的一级菜单 --> |
|
|
|
<el-menu-item v-else :index="getRoutePath(menu)"> |
|
|
|
<el-menu-item |
|
|
|
v-else |
|
|
|
:index="getRoutePath(menu)" |
|
|
|
> |
|
|
|
<el-icon> |
|
|
|
<Folder /> |
|
|
|
<Folder/> |
|
|
|
</el-icon> |
|
|
|
<span>{{ menu.menuName }}</span> |
|
|
|
</el-menu-item> |
|
|
@ -290,7 +155,7 @@ const handleClosePasswordDialog = () => { |
|
|
|
|
|
|
|
<el-sub-menu index="1" class="admin"> |
|
|
|
<template #title> |
|
|
|
<el-image :src="imgrule1" alt="错误" style="width: 50px; height: 50px" /> |
|
|
|
<el-image :src="imgrule1" alt="错误" style="width: 50px; height: 50px"/> |
|
|
|
<span style="margin-left: 10px">{{ adminData.name }}</span> |
|
|
|
</template> |
|
|
|
<el-menu-item @click="message()">查看个人信息</el-menu-item> |
|
|
@ -331,11 +196,16 @@ const handleClosePasswordDialog = () => { |
|
|
|
</template> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
<!-- 自定义密码修改弹窗组件 父組件和子組件通信--> |
|
|
|
<el-dialog v-model="showPasswordDialog" :center="true" width="470px" @close="handleClosePasswordDialog"> |
|
|
|
<ChangePassword ref="changePasswordRef" @confirm="showPasswordDialog = false" /> |
|
|
|
<!-- 自定义密码修改弹窗组件 --> |
|
|
|
<el-dialog |
|
|
|
v-model="showPasswordDialog" |
|
|
|
:center="true" |
|
|
|
width="470px" |
|
|
|
> |
|
|
|
<ChangePassword @confirm="showPasswordDialog = false"/> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|