85 lines
3.0 KiB
Vue
85 lines
3.0 KiB
Vue
<template>
|
|||
|
|
<el-container class="layout" style="min-height:100vh">
|
||
|
|
<el-aside width="210px" class="aside">
|
||
|
|
<div class="logo">MES 产线控制</div>
|
||
|
|
<el-menu :default-active="$route.path" router background-color="#001529"
|
||
|
|
text-color="#a6adb4" active-text-color="#409eff" style="border-right:none">
|
||
|
|
<el-menu-item v-for="m in menus" :key="m.path" :index="m.path">
|
||
|
|
<span>{{ m.name }}</span>
|
||
|
|
</el-menu-item>
|
||
|
|
</el-menu>
|
||
|
|
</el-aside>
|
||
|
|
<el-container>
|
||
|
|
<el-header class="header">
|
||
|
|
<div @click="drawer=true" style="cursor:pointer">☰ 菜单</div>
|
||
|
|
<div>
|
||
|
|
<span style="margin-right:16px">{{ userName }}</span>
|
||
|
|
<el-button size="small" @click="doLogout">退出</el-button>
|
||
|
|
</div>
|
||
|
|
</el-header>
|
||
|
|
<el-main style="padding:14px">
|
||
|
|
<router-view />
|
||
|
|
</el-main>
|
||
|
|
</el-container>
|
||
|
|
</el-container>
|
||
|
|
|
||
|
|
<el-drawer v-model="drawer" direction="ltr" size="200px">
|
||
|
|
<el-menu :default-active="$route.path" router>
|
||
|
|
<el-menu-item v-for="m in menus" :key="m.path" :index="m.path">{{ m.name }}</el-menu-item>
|
||
|
|
</el-menu>
|
||
|
|
</el-drawer>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup>
|
||
|
|
import { ref, computed, onMounted } from 'vue'
|
||
|
|
import { useRouter } from 'vue-router'
|
||
|
|
import { getUser, logout } from '../utils/auth'
|
||
|
|
import request from '../utils/request'
|
||
|
|
|
||
|
|
const router = useRouter()
|
||
|
|
const drawer = ref(false)
|
||
|
|
|
||
|
|
const menus = computed(() => {
|
||
|
|
const me = getUser()
|
||
|
|
if (!me) return defaultMenus
|
||
|
|
const owned = me.permissionCodes || []
|
||
|
|
const ok = (c) => me.roleCode === 'SUPER_ADMIN' || owned.includes('*') || owned.includes(c)
|
||
|
|
return defaultMenus.filter((m) => ok(m.code))
|
||
|
|
})
|
||
|
|
|
||
|
|
const defaultMenus = [
|
||
|
|
{ code: 'produce.workorder', name: '工单管理', path: '/work-order' },
|
||
|
|
{ code: 'produce.bom', name: 'BOM', path: '/bom' },
|
||
|
|
{ code: 'produce.material', name: '备料单', path: '/material-request' },
|
||
|
|
{ code: 'produce.plc', name: 'PLC工序下发', path: '/plc-send' },
|
||
|
|
{ code: 'produce.torque', name: '拧紧查询', path: '/torque' },
|
||
|
|
{ code: 'produce.scan', name: '扫码报工', path: '/scan' },
|
||
|
|
{ code: 'produce.trace', name: '工件追溯', path: '/trace' },
|
||
|
|
{ code: 'produce.product', name: '产品类型', path: '/product-type' },
|
||
|
|
{ code: 'sys.eventlog', name: '操作日志', path: '/event-log' },
|
||
|
|
{ code: 'sys.rbac', name: '角色权限管理', path: '/rbac' }
|
||
|
|
]
|
||
|
|
|
||
|
|
const userName = computed(() => {
|
||
|
|
const me = getUser()
|
||
|
|
return me ? (me.name || me.username) : '未登录'
|
||
|
|
})
|
||
|
|
|
||
|
|
onMounted(async () => {
|
||
|
|
try {
|
||
|
|
const u = await request.get('/userinfo')
|
||
|
|
localStorage.setItem('user', JSON.stringify(u))
|
||
|
|
} catch { /* ignore */ }
|
||
|
|
})
|
||
|
|
|
||
|
|
function doLogout() {
|
||
|
|
logout()
|
||
|
|
router.replace('/login')
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.aside { background: #001529; }
|
||
|
|
.logo { color: #fff; font-size: 17px; font-weight: 600; text-align: center; line-height: 60px; height: 60px; }
|
||
|
|
.header { display: flex; align-items: center; justify-content: space-between; background: #fff; border-bottom: 1px solid #eee; }
|
||
|
|
</style>
|