权限控制完善
This commit is contained in:
@@ -15,6 +15,7 @@ const TokenManager = {
|
||||
setToken(token: string) {
|
||||
const authStore = useAuthStore()
|
||||
authStore.setToken(token)
|
||||
isAuthExpired = false
|
||||
// 同时设置默认请求头
|
||||
request.defaults.headers.common['Authorization'] = `Bearer ${token}`
|
||||
},
|
||||
@@ -45,15 +46,23 @@ TokenManager.initToken()
|
||||
|
||||
// 登录过期提示防重复标志
|
||||
let isLoginExpiredShown = false
|
||||
let isAuthExpired = false
|
||||
|
||||
const isAuthExpiredRequest = (url: string) => {
|
||||
if (!isAuthExpired) return false
|
||||
if (!url) return true
|
||||
return !url.includes('/user/login') && !url.includes('/user/register')
|
||||
}
|
||||
|
||||
// 处理登录过期(防重复提示)
|
||||
const handleLoginExpired = () => {
|
||||
if (!isLoginExpiredShown) {
|
||||
isLoginExpiredShown = true
|
||||
isAuthExpired = true
|
||||
// 清除token
|
||||
TokenManager.removeToken()
|
||||
// 显示提示消息
|
||||
ElMessage.error('登录已过期,请重新登录')
|
||||
ElMessage.error('用户信息过期,请重新登录')
|
||||
// 跳转到登录页
|
||||
router.replace('/login').finally(() => {
|
||||
// 延迟重置标志位,确保跳转完成后再允许下次提示
|
||||
@@ -149,6 +158,11 @@ request.interceptors.response.use(
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// 如果是认证过期后的后续请求,静默处理业务错误,避免弹出部门加载失败等页面提示
|
||||
if (isAuthExpiredRequest(url) && errorMsg) {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// 网络错误或其他错误
|
||||
ElMessage.error(errorMsg)
|
||||
return Promise.reject(error)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
:rules="loginRules"
|
||||
class="login-form"
|
||||
label-width="0"
|
||||
@keyup.enter="handleLogin"
|
||||
@submit.prevent="handleLogin"
|
||||
>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
@@ -21,6 +21,7 @@
|
||||
size="large"
|
||||
:prefix-icon="User"
|
||||
clearable
|
||||
@keydown.enter.prevent="handleLogin"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
@@ -33,7 +34,7 @@
|
||||
:prefix-icon="Lock"
|
||||
show-password
|
||||
clearable
|
||||
@keyup.enter="handleLogin"
|
||||
@keydown.enter.prevent="handleLogin"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
@@ -191,10 +192,11 @@ const registerRules: FormRules = {
|
||||
|
||||
// 处理登录
|
||||
const handleLogin = async () => {
|
||||
if (!loginFormRef.value) return
|
||||
if (!loginFormRef.value || loginLoading.value) return
|
||||
|
||||
const valid = await loginFormRef.value.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
|
||||
await loginFormRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
loginLoading.value = true
|
||||
try {
|
||||
const response: any = await userlogin(loginForm.username, loginForm.password)
|
||||
@@ -226,7 +228,7 @@ const handleLogin = async () => {
|
||||
localStorage.setItem('token', token)
|
||||
localStorage.setItem('permissions', JSON.stringify(permissions))
|
||||
|
||||
ElMessage.success(response?.message || '登录成功')
|
||||
ElMessage.success('登录成功')
|
||||
router.push('/home')
|
||||
} else {
|
||||
ElMessage.error(response?.message || '登录失败,未获取到令牌')
|
||||
@@ -237,8 +239,6 @@ const handleLogin = async () => {
|
||||
} finally {
|
||||
loginLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 处理注册
|
||||
|
||||
@@ -86,8 +86,9 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="formType" label="表单控件" min-width="120" align="left">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.formType === 'select'">
|
||||
<el-button
|
||||
v-if="row.formType === 'select'"
|
||||
v-if="canConfigSelectOptions"
|
||||
type="success"
|
||||
size="small"
|
||||
link
|
||||
@@ -95,8 +96,11 @@
|
||||
>
|
||||
下拉框
|
||||
</el-button>
|
||||
<span v-else>下拉框</span>
|
||||
</span>
|
||||
<span v-else-if="row.formType === 'input' || row.formType === 'number'">
|
||||
<el-button
|
||||
v-else-if="row.formType === 'input' || row.formType === 'number'"
|
||||
v-if="canConfigRange"
|
||||
type="warning"
|
||||
size="small"
|
||||
link
|
||||
@@ -106,6 +110,8 @@
|
||||
{{ getFormTypeLabel(row.formType) || '暂无' }}
|
||||
</el-button>
|
||||
<span v-else>{{ getFormTypeLabel(row.formType) || '暂无' }}</span>
|
||||
</span>
|
||||
<span v-else>{{ getFormTypeLabel(row.formType) || '暂无' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="dicDataId" label="参数分类" min-width="120" align="left">
|
||||
@@ -236,12 +242,13 @@
|
||||
/>
|
||||
</el-select>
|
||||
<el-button
|
||||
v-if="formData.formType === 'select'"
|
||||
v-if="formData.formType === 'select' && canConfigSelectOptions"
|
||||
type="primary"
|
||||
@click="handleConfigFormTypeOptionsInDrawer"
|
||||
>
|
||||
配置
|
||||
</el-button>
|
||||
<span v-else-if="formData.formType === 'select'">配置</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="参数分类" prop="dicTypeId">
|
||||
@@ -259,11 +266,13 @@
|
||||
/>
|
||||
</el-select>
|
||||
<el-button
|
||||
v-if="canConfigSelectOptions"
|
||||
type="primary"
|
||||
@click="handleConfigCategoryOptionsInDrawer"
|
||||
>
|
||||
配置
|
||||
</el-button>
|
||||
<span v-else>配置</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="参数描述" prop="paramDesc">
|
||||
@@ -371,10 +380,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { computed, ref, reactive, onMounted } from 'vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus, Edit, Delete, Close } from '@element-plus/icons-vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import {
|
||||
devparamadd,
|
||||
devparamdel,
|
||||
@@ -390,6 +400,10 @@ const loading = ref(false)
|
||||
const submitting = ref(false)
|
||||
const rangeSubmitting = ref(false)
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const canConfigRange = computed(() => authStore.hasPermission('data:devparam:range'))
|
||||
const canConfigSelectOptions = computed(() => authStore.hasPermission('data:devparam:select'))
|
||||
|
||||
// 参数列表
|
||||
const paramList = ref<any[]>([])
|
||||
const total = ref(0)
|
||||
@@ -1031,6 +1045,10 @@ const resetRangeForm = () => {
|
||||
}
|
||||
|
||||
const handleConfigRange = async (row: any) => {
|
||||
if (!canConfigRange.value) {
|
||||
ElMessage.warning('您没有设置动作参数取值范围的权限')
|
||||
return
|
||||
}
|
||||
if (!row?.paramName) {
|
||||
ElMessage.warning('缺少参数名称,无法配置取值范围')
|
||||
return
|
||||
@@ -1158,11 +1176,19 @@ const isConfigFormType = ref(false) // 是否配置表单控件的下拉框选
|
||||
|
||||
// 打开表单控件下拉框选项配置对话框(从列表)
|
||||
const handleConfigFormTypeOptions = async (row: any) => {
|
||||
if (!canConfigSelectOptions.value) {
|
||||
ElMessage.warning('您没有设置动作参数下拉框选项列表的权限')
|
||||
return
|
||||
}
|
||||
await openSelectOptionsDialog(row, true)
|
||||
}
|
||||
|
||||
// 打开表单控件下拉框选项配置对话框(从抽屉)
|
||||
const handleConfigFormTypeOptionsInDrawer = async () => {
|
||||
if (!canConfigSelectOptions.value) {
|
||||
ElMessage.warning('您没有设置动作参数下拉框选项列表的权限')
|
||||
return
|
||||
}
|
||||
if (!formData.paramName) {
|
||||
ElMessage.warning('请先输入参数名称')
|
||||
return
|
||||
|
||||
@@ -95,12 +95,16 @@
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="canViewStatusRecord"
|
||||
:type="getStatusType(row.goodsStatus)"
|
||||
link
|
||||
@click="handleStatusClick(row)"
|
||||
>
|
||||
{{ getStatusText(row.goodsStatus) }}
|
||||
</el-button>
|
||||
<span v-else>
|
||||
{{ getStatusText(row.goodsStatus) }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
@@ -327,7 +331,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { computed, ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { goodsInfolist } from '@/api/tb/goodsinfo'
|
||||
import { flowInfobyid } from '@/api/tb/flowinfo'
|
||||
@@ -338,6 +342,7 @@ import { islandInfobyid } from '@/api/tb/islandinfo'
|
||||
import { devInfobyid } from '@/api/tb/devinfo'
|
||||
import { stepInfolist } from '@/api/tb/stepinfo'
|
||||
import { devparambyid } from '@/api/tb/devparam'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
interface GoodsInfoItem {
|
||||
id?: number | string
|
||||
@@ -379,6 +384,9 @@ const detailData = reactive<GoodsInfoItem>({})
|
||||
const detailStatusList = ref<any[]>([])
|
||||
const detailStatusLoading = ref(false)
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const canViewStatusRecord = computed(() => authStore.hasPermission('tb:goodrecord:record'))
|
||||
|
||||
// 样品流程状态列表相关
|
||||
const flowStatusDialogVisible = ref(false)
|
||||
const flowStatusDialogTitle = ref('样品流程状态列表')
|
||||
@@ -417,6 +425,10 @@ const getStatusText = (status: number | null | undefined) => {
|
||||
|
||||
// 样品状态点击事件处理
|
||||
const handleStatusClick = (row: GoodsInfoItem) => {
|
||||
if (!canViewStatusRecord.value) {
|
||||
ElMessage.warning('您没有样品状态记录的权限')
|
||||
return
|
||||
}
|
||||
const status = row.goodsStatus
|
||||
if (status === 0) {
|
||||
// 待处理 - 显示提示
|
||||
|
||||
Reference in New Issue
Block a user