Browse Source

fix:二、用户权限说明

管理员用户:具备系统内所有页面和操作权限。
    普通用户:
    2.1配方页
    只可预览配方、执行配方,不可新增、删除配方。
    2.2测试页
    无权限并隐藏。
    2.3审计页
    操作记录选项,可查看消毒记录、导出、打印、查看详情。
    消毒记录选项,无权限并隐藏。
    2.4设置页
    消毒默认配置选项:仅查看。
    用户管理选项:仅允许查看列表修改本人密码。
    日期设置选项:无权限并隐藏。
    设备信息选项:仅查看。
master
白凤吉 2 weeks ago
parent
commit
67aca76bc8
  1. 18
      src/components/formula/FormulaConfig.vue
  2. 4
      src/components/formula/FormulaTable.vue
  3. 6
      src/components/setting/User.vue
  4. 6
      src/layouts/default.vue
  5. 5
      src/router/index.ts
  6. 257
      src/router/routes.ts
  7. 2
      src/stores/settingStore.ts
  8. 8
      src/views/audit/index.vue
  9. 6
      src/views/formula/index.vue
  10. 8
      src/views/setting/index.vue

18
src/components/formula/FormulaConfig.vue

@ -22,6 +22,7 @@ import { useFormulaStore } from '@/stores/formulaStore'
const props = defineProps<{
type: string
formulaNameVisible: boolean
editable?: boolean
}>()
const homeStore = useHomeStore()
@ -415,6 +416,19 @@ const addFormula = async () => {
defineExpose({
addFormula,
})
const isDisabled = computed(() => {
console.log('112223344', props.editable)
// editablefalse
if (props.editable === false) {
return true
}
// editabletrue
if (props.editable === true) {
return false
}
// editable沿
return props.type === 'home'
})
</script>
<template>
@ -422,7 +436,7 @@ defineExpose({
<div v-if="isFlip" class="formula-form">
<el-form
ref="formRef"
:disabled="type === 'home'"
:disabled="isDisabled"
:model="formData"
label-width="auto"
label-position="right"
@ -440,7 +454,7 @@ defineExpose({
name="name"
prop="name"
placeholder="配方名称"
:disabled="type === 'home'"
:disabled="isDisabled"
@focus="openKeyboard"
/>
</el-form-item>

4
src/components/formula/FormulaTable.vue

@ -17,6 +17,8 @@ const selectedIndexRest = async () => {
formulaStore.updateSelectedIndex(null)
console.log('子组件方法被调用')
}
const userData = localStorage.getItem('user')
const userInfo = userData ? JSON.parse(userData) : {}
//
defineExpose({
@ -122,7 +124,7 @@ const deleteRecipe = (item: Formula.FormulaItem) => {
<el-button class="view-button" @click.stop="onStartFormula(item)">
执行配方
</el-button>
<el-button class="delete-button" @click.stop="deleteRecipe(item)">
<el-button v-if="userInfo.roleType === 'admin'" class="delete-button" @click.stop="deleteRecipe(item)">
删除
</el-button>
</div>

6
src/components/setting/User.vue

@ -78,7 +78,7 @@ const handleSelectionChange = (users: User.UserItem[]) => {
<template>
<div class="user">
<div class="add-user">
<div v-if="userInfo.roleType === 'admin'" class="add-user">
<bt-button type="primary" button-text="新增用户" @click="onAddUser" />
</div>
<div class="user-table">
@ -94,10 +94,10 @@ const handleSelectionChange = (users: User.UserItem[]) => {
<el-table-column prop="detail" label="操作" width="250">
<template #default="scoped">
<div class="user-opera">
<el-button class="view-button" @click.stop="updatePwd(scoped.row)">
<el-button v-if="scoped.row.id === userInfo.id || userInfo.roleType === 'admin'" class="view-button" @click.stop="updatePwd(scoped.row)">
修改密码
</el-button>
<el-button class="delete-button" @click.stop="onDelUser(scoped.row)">
<el-button v-if="userInfo.roleType === 'admin'" class="delete-button" @click.stop="onDelUser(scoped.row)">
</el-button>
</div>

6
src/layouts/default.vue

@ -4,7 +4,6 @@ import WifiUnconnSvg from 'assets/images/wifi-unconn.svg'
import ErrorEventsModal from 'components/system/ErrorEventsModal.vue'
import NetReconnection from 'components/system/NetReconnection.vue'
import { formatDateTime, openFullscreen } from 'libs/utils'
import { authRoutes } from 'router/routes'
import { useDeviceStore } from 'stores/deviceStore'
import { computed, onMounted, onUnmounted, ref, watch, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
@ -12,11 +11,14 @@ import { useRouter } from 'vue-router'
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessageBox } from '@/libs/messageBox'
import { generateRoutes } from '@/router/routes'
import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore'
const routes = generateRoutes()
const childrenRoutes = routes.find(r => r.path === '/')?.children || []
const { locale } = useI18n()
const router = useRouter()
const liquidStore = useLiquidStore()
@ -181,7 +183,7 @@ const deviceType = computed(() => {
<div class="header-menu">
<div class="aside">
<el-tag
v-for="item in authRoutes.filter(item => item.meta!.isDefault)"
v-for="item in childrenRoutes.filter(item => item.meta!.isDefault)"
:key="item.path"
class="menu-tag"
:class="{ 'aside-item-active': router.currentRoute.value.path.includes(item.path) }"

5
src/router/index.ts

@ -4,13 +4,13 @@ import { createRouter, createWebHashHistory } from 'vue-router'
import { getToken } from '@/libs/token'
import routes from './routes'
import { generateRoutes } from './routes'
const wsClient = createWebSocket()
const router = createRouter({
history: createWebHashHistory(),
routes,
routes: generateRoutes(),
})
router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
@ -18,7 +18,6 @@ router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, n
next()
}
else {
// 未登录
if (to.name === 'login') {
next()
}

257
src/router/routes.ts

@ -1,3 +1,4 @@
// router/routes.ts
import n_audit from 'assets/images/menuIcon/n-audit.svg'
import n_debug from 'assets/images/menuIcon/n-debug.svg'
import n_disinfect from 'assets/images/menuIcon/n-disinfect.svg'
@ -14,156 +15,134 @@ import s_seal from 'assets/images/menuIcon/s-seal.svg'
import s_setting from 'assets/images/menuIcon/s-setting.svg'
import { useDeviceStore } from 'stores/deviceStore'
import pinia from 'stores/index'
import type { Ref } from 'vue'
import { ref, watchEffect } from 'vue'
import type { RouteRecordRaw } from 'vue-router'
const authRoutes: Ref<RouteRecordRaw[]> = ref<RouteRecordRaw[]>([
{
path: '/home',
name: 'home',
component: () => import('views/home/index.vue'),
meta: {
isDefault: true,
title: '消毒',
icon: n_disinfect,
activeIcon: s_disinfect,
},
children: [
{
path: 'config',
name: 'config',
component: () => import('components/home/config.vue'),
export function generateRoutes(): RouteRecordRaw[] {
const deviceStore = useDeviceStore(pinia)
const userData = localStorage.getItem('user')
const userInfo = userData ? JSON.parse(userData) : {}
const userRole = userInfo.roleType || ''
const deviceType = __DEVICE_TYPE__
const allRoutes: RouteRecordRaw[] = [
{
path: '/home',
name: 'home',
component: () => import('views/home/index.vue'),
meta: {
isDefault: true,
title: '消毒',
icon: n_disinfect,
activeIcon: s_disinfect,
},
{
path: 'chart',
name: 'chart',
component: () => import('views/home/chart.vue'),
children: [
{
path: 'config',
name: 'config',
component: () => import('components/home/config.vue'),
},
{
path: 'chart',
name: 'chart',
component: () => import('views/home/chart.vue'),
},
],
},
{
path: '/liquid',
name: 'liquid',
component: () => import('views/liquid/index.vue'),
meta: {
isDefault: true,
title: '消毒液',
icon: n_liquid,
activeIcon: s_liquid,
keepAlive: true,
},
],
},
{
path: '/liquid',
name: 'liquid',
component: () => import('views/liquid/index.vue'),
meta: {
isDefault: true,
title: '消毒液',
icon: n_liquid,
activeIcon: s_liquid,
keepAlive: true,
},
},
{
path: '/seal',
name: 'seal',
component: () => import('views/seal/index.vue'),
meta: {
isDefault: true,
title: '密封测试',
icon: n_seal,
activeIcon: s_seal,
{
path: '/seal',
name: 'seal',
component: () => import('views/seal/index.vue'),
meta: {
isDefault: true,
title: '密封测试',
icon: n_seal,
activeIcon: s_seal,
},
},
},
{
path: '/formula',
name: 'formula',
component: () => import('views/formula/index.vue'),
meta: {
isDefault: true,
title: '配方',
icon: n_formula,
activeIcon: s_formula,
{
path: '/formula',
name: 'formula',
component: () => import('views/formula/index.vue'),
meta: {
isDefault: true,
title: '配方',
icon: n_formula,
activeIcon: s_formula,
},
},
},
{
path: '/debug',
name: 'debug',
component: () => import('views/debug/index.vue'),
meta: {
isDefault: true,
title: '测试',
icon: n_debug,
activeIcon: s_debug,
{
path: '/debug',
name: 'debug',
component: () => import('views/debug/index.vue'),
meta: {
isDefault: true,
title: '测试',
icon: n_debug,
activeIcon: s_debug,
},
},
},
{
path: '/audit',
name: 'audit',
component: () => import('views/audit/index.vue'),
meta: {
isDefault: true,
title: '审计',
icon: n_audit,
activeIcon: s_audit,
{
path: '/audit',
name: 'audit',
component: () => import('views/audit/index.vue'),
meta: {
isDefault: true,
title: '审计',
icon: n_audit,
activeIcon: s_audit,
},
},
},
{
path: '/setting',
name: 'setting',
component: () => import('views/setting/index.vue'),
meta: {
isDefault: true,
title: '设置',
icon: n_setting,
activeIcon: s_setting,
{
path: '/setting',
name: 'setting',
component: () => import('views/setting/index.vue'),
meta: {
isDefault: true,
title: '设置',
icon: n_setting,
activeIcon: s_setting,
},
},
},
])
]
watchEffect(() => {
const deviceStore = useDeviceStore(pinia)
setTimeout(() => {
if (__DEVICE_TYPE__ === deviceStore.deviceTypeMap.LargeSpaceDM_B) {
// 大空间标准版
authRoutes.value = authRoutes.value.filter((item) => {
return item.name !== 'seal' && item.name !== 'liquid'
})
}
else if (__DEVICE_TYPE__ === deviceStore.deviceTypeMap.LargeSpaceDM) {
// 大空间
authRoutes.value = authRoutes.value.filter((item) => {
return item.name !== 'seal'
})
}
else if (__DEVICE_TYPE__ === deviceStore.deviceTypeMap.SmallSpaceDM) {
// 小空间
authRoutes.value = authRoutes.value.filter((item) => {
return item.name !== 'seal'
})
const filteredRoutes = allRoutes.filter((item) => {
if (
(deviceType === deviceStore.deviceTypeMap.LargeSpaceDM_B && (item.name === 'seal' || item.name === 'liquid'))
|| (deviceType === deviceStore.deviceTypeMap.LargeSpaceDM && item.name === 'seal')
|| (deviceType === deviceStore.deviceTypeMap.SmallSpaceDM && item.name === 'seal')
|| (deviceType === deviceStore.deviceTypeMap.DrawBarDM && item.name === 'liquid')
) {
return false
}
else if (__DEVICE_TYPE__ === deviceStore.deviceTypeMap.DrawBarDM) {
// 拉杆箱
authRoutes.value = authRoutes.value.filter((item) => {
return item.name !== 'liquid'
})
if (item.name === 'debug' && userRole !== 'admin') {
return false
}
// if (!deviceStore.deviceState.loginUser.roleType.includes('admin')) { // 测试菜单
// authRoutes.value = authRoutes.value.filter((item) => {
// return item.name !== 'debug'
// })
// }
/* else { //
authRoutes.value = authRoutes.value.filter((item) => {
return item.name !== 'liquid'
})
} */
}, 2000)
})
return true
})
const routes: RouteRecordRaw[] = [
{
path: '/login',
name: 'login',
component: () => import('../views/login/index.vue'),
},
{
path: '/',
component: () => import('../layouts/default.vue'),
redirect: '/home',
children: authRoutes.value,
},
]
export { authRoutes }
export default routes
return [
{
path: '/',
component: () => import('../layouts/default.vue'),
redirect: '/home',
children: filteredRoutes,
},
{
path: '/login',
name: 'login',
component: () => import('../views/login/index.vue'),
},
]
}

2
src/stores/settingStore.ts

@ -14,7 +14,7 @@ export const useSettingStore = defineStore('setting', () => {
}, {
name: '用户管理',
code: 'user',
roleType: 'admin',
roleType: 'admin,maintainer',
}, {
name: '日期设置',
code: 'date',

8
src/views/audit/index.vue

@ -7,7 +7,7 @@ import { ref } from 'vue'
const auditStore = useAuditStore()
const currentUserRoleType = JSON.parse(localStorage.getItem('user') || '{}')?.roleType
const auditMenus = auditStore.auditMenus.filter((item): boolean => item.roleType.includes(currentUserRoleType))
const selectedMenuCode = ref('history')
const selectedMenuCode = ref('operationRecord')
//
const selectItem = (menuCode: string) => {
selectedMenuCode.value = menuCode
@ -33,9 +33,9 @@ const selectItem = (menuCode: string) => {
</div>
</div>
<div class="setting-right">
<History v-if="selectedMenuCode === 'history'" />
<div v-if="selectedMenuCode === 'operationRecord'">
<OperationRecord />
<OperationRecord v-if="selectedMenuCode === 'operationRecord'" />
<div v-if="selectedMenuCode === 'history'">
<History />
</div>
</div>
</main>

6
src/views/formula/index.vue

@ -14,13 +14,15 @@ const tableRef = ref()
const selectedIndexRest = () => {
tableRef.value?.selectedIndexRest() //
}
const userData = localStorage.getItem('user')
const userInfo = userData ? JSON.parse(userData) : {}
</script>
<template>
<div class="dashboard-container">
<main class="main-content">
<div class="formula-left">
<div class="formula-add">
<div v-if="userInfo.roleType === 'admin'" class="formula-add">
<bt-button
type="primary"
button-text="新增配方"
@ -40,7 +42,7 @@ const selectedIndexRest = () => {
</div>
</div>
<div class="formula-right">
<FormulaConfig ref="formRef" type="formula" :formula-name-visible="true" />
<FormulaConfig ref="formRef" type="formula" :formula-name-visible="true" :editable="userInfo.roleType === 'admin'" />
</div>
</main>
</div>

8
src/views/setting/index.vue

@ -11,6 +11,8 @@ const settingStore = useSettingStore()
const currentUserRoleType = JSON.parse(localStorage.getItem('user') || '{}')?.roleType
const settingMenus = settingStore.settingMenus.filter((item): boolean => item.roleType.includes(currentUserRoleType))
const selectedMenuCode = ref('defaultFormula')
const userData = localStorage.getItem('user')
const userInfo = userData ? JSON.parse(userData) : {}
//
const selectItem = (menuCode: string) => {
selectedMenuCode.value = menuCode
@ -37,7 +39,11 @@ const selectItem = (menuCode: string) => {
</div>
<div class="setting-right">
<div v-if="selectedMenuCode === 'defaultFormula'">
<FormulaConfig type="setting" :formula-name-visible="false" />
<FormulaConfig
:type="userInfo.roleType === 'admin' ? 'setting' : 'home'"
:formula-name-visible="false"
:editable="userInfo.roleType === 'admin'"
/>
</div>
<template v-if="selectedMenuCode === 'user'">
<User />

Loading…
Cancel
Save