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. 79
      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<{ const props = defineProps<{
type: string type: string
formulaNameVisible: boolean formulaNameVisible: boolean
editable?: boolean
}>() }>()
const homeStore = useHomeStore() const homeStore = useHomeStore()
@ -415,6 +416,19 @@ const addFormula = async () => {
defineExpose({ defineExpose({
addFormula, 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> </script>
<template> <template>
@ -422,7 +436,7 @@ defineExpose({
<div v-if="isFlip" class="formula-form"> <div v-if="isFlip" class="formula-form">
<el-form <el-form
ref="formRef" ref="formRef"
:disabled="type === 'home'"
:disabled="isDisabled"
:model="formData" :model="formData"
label-width="auto" label-width="auto"
label-position="right" label-position="right"
@ -440,7 +454,7 @@ defineExpose({
name="name" name="name"
prop="name" prop="name"
placeholder="配方名称" placeholder="配方名称"
:disabled="type === 'home'"
:disabled="isDisabled"
@focus="openKeyboard" @focus="openKeyboard"
/> />
</el-form-item> </el-form-item>

4
src/components/formula/FormulaTable.vue

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

6
src/components/setting/User.vue

@ -78,7 +78,7 @@ const handleSelectionChange = (users: User.UserItem[]) => {
<template> <template>
<div class="user"> <div class="user">
<div class="add-user">
<div v-if="userInfo.roleType === 'admin'" class="add-user">
<bt-button type="primary" button-text="新增用户" @click="onAddUser" /> <bt-button type="primary" button-text="新增用户" @click="onAddUser" />
</div> </div>
<div class="user-table"> <div class="user-table">
@ -94,10 +94,10 @@ const handleSelectionChange = (users: User.UserItem[]) => {
<el-table-column prop="detail" label="操作" width="250"> <el-table-column prop="detail" label="操作" width="250">
<template #default="scoped"> <template #default="scoped">
<div class="user-opera"> <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>
<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> </el-button>
</div> </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 ErrorEventsModal from 'components/system/ErrorEventsModal.vue'
import NetReconnection from 'components/system/NetReconnection.vue' import NetReconnection from 'components/system/NetReconnection.vue'
import { formatDateTime, openFullscreen } from 'libs/utils' import { formatDateTime, openFullscreen } from 'libs/utils'
import { authRoutes } from 'router/routes'
import { useDeviceStore } from 'stores/deviceStore' import { useDeviceStore } from 'stores/deviceStore'
import { computed, onMounted, onUnmounted, ref, watch, watchEffect } from 'vue' import { computed, onMounted, onUnmounted, ref, watch, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@ -12,11 +11,14 @@ import { useRouter } from 'vue-router'
import { getDeviceStatus } from '@/libs/deviceComm' import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessageBox } from '@/libs/messageBox' import { FtMessageBox } from '@/libs/messageBox'
import { generateRoutes } from '@/router/routes'
import { useHomeStore } from '@/stores/homeStore' import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore' import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore' import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore' import { useSystemStore } from '@/stores/systemStore'
const routes = generateRoutes()
const childrenRoutes = routes.find(r => r.path === '/')?.children || []
const { locale } = useI18n() const { locale } = useI18n()
const router = useRouter() const router = useRouter()
const liquidStore = useLiquidStore() const liquidStore = useLiquidStore()
@ -181,7 +183,7 @@ const deviceType = computed(() => {
<div class="header-menu"> <div class="header-menu">
<div class="aside"> <div class="aside">
<el-tag <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" :key="item.path"
class="menu-tag" class="menu-tag"
:class="{ 'aside-item-active': router.currentRoute.value.path.includes(item.path) }" :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 { getToken } from '@/libs/token'
import routes from './routes'
import { generateRoutes } from './routes'
const wsClient = createWebSocket() const wsClient = createWebSocket()
const router = createRouter({ const router = createRouter({
history: createWebHashHistory(), history: createWebHashHistory(),
routes,
routes: generateRoutes(),
}) })
router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => { router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
@ -18,7 +18,6 @@ router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, n
next() next()
} }
else { else {
// 未登录
if (to.name === 'login') { if (to.name === 'login') {
next() next()
} }

79
src/router/routes.ts

@ -1,3 +1,4 @@
// router/routes.ts
import n_audit from 'assets/images/menuIcon/n-audit.svg' import n_audit from 'assets/images/menuIcon/n-audit.svg'
import n_debug from 'assets/images/menuIcon/n-debug.svg' import n_debug from 'assets/images/menuIcon/n-debug.svg'
import n_disinfect from 'assets/images/menuIcon/n-disinfect.svg' import n_disinfect from 'assets/images/menuIcon/n-disinfect.svg'
@ -14,11 +15,16 @@ import s_seal from 'assets/images/menuIcon/s-seal.svg'
import s_setting from 'assets/images/menuIcon/s-setting.svg' import s_setting from 'assets/images/menuIcon/s-setting.svg'
import { useDeviceStore } from 'stores/deviceStore' import { useDeviceStore } from 'stores/deviceStore'
import pinia from 'stores/index' import pinia from 'stores/index'
import type { Ref } from 'vue'
import { ref, watchEffect } from 'vue'
import type { RouteRecordRaw } from 'vue-router' import type { RouteRecordRaw } from 'vue-router'
const authRoutes: Ref<RouteRecordRaw[]> = ref<RouteRecordRaw[]>([
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', path: '/home',
name: 'home', name: 'home',
@ -109,61 +115,34 @@ const authRoutes: Ref<RouteRecordRaw[]> = ref<RouteRecordRaw[]>([
activeIcon: s_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'),
},
return [
{ {
path: '/', path: '/',
component: () => import('../layouts/default.vue'), component: () => import('../layouts/default.vue'),
redirect: '/home', redirect: '/home',
children: authRoutes.value,
children: filteredRoutes,
},
{
path: '/login',
name: 'login',
component: () => import('../views/login/index.vue'),
}, },
] ]
export { authRoutes }
export default routes
}

2
src/stores/settingStore.ts

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

8
src/views/audit/index.vue

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

6
src/views/formula/index.vue

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

8
src/views/setting/index.vue

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

Loading…
Cancel
Save