系统管理完善
This commit is contained in:
527
rc_autoplc_front/src/views/user-role/index.vue
Normal file
527
rc_autoplc_front/src/views/user-role/index.vue
Normal file
@@ -0,0 +1,527 @@
|
||||
<template>
|
||||
<div class="user-role-page">
|
||||
<el-card class="search-card" shadow="never">
|
||||
<div class="search-bar">
|
||||
<el-form :inline="true" :model="queryForm" label-width="80px">
|
||||
<el-form-item label="用户">
|
||||
<el-select
|
||||
v-model="queryForm.userId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择用户"
|
||||
style="width: 200px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in userOptions"
|
||||
:key="item.id"
|
||||
:label="item.userName || item.nicke || item.nickName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色">
|
||||
<el-select
|
||||
v-model="queryForm.roleId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择角色"
|
||||
style="width: 200px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in roleOptions"
|
||||
:key="item.id"
|
||||
:label="item.roleName || item.roleCode"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="toolbar">
|
||||
<el-button type="primary" @click="openDrawer('create')">新增用户角色关联</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
style="width: 100%"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="70" />
|
||||
<el-table-column
|
||||
prop="userId"
|
||||
label="用户名"
|
||||
min-width="150"
|
||||
>
|
||||
<template #default="scope">
|
||||
{{ getUserName(scope.row.userId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="roleId"
|
||||
label="角色名"
|
||||
min-width="150"
|
||||
>
|
||||
<template #default="scope">
|
||||
{{ getRoleName(scope.row.roleId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="remark"
|
||||
label="备注"
|
||||
min-width="200"
|
||||
:formatter="formatCell"
|
||||
/>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.pageNum"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
background
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-drawer
|
||||
v-model="drawerVisible"
|
||||
title="新增用户角色关联"
|
||||
direction="rtl"
|
||||
:size="500"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
class="drawer-form"
|
||||
>
|
||||
<el-form-item label="用户" prop="userId">
|
||||
<el-select
|
||||
v-model="form.userId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择用户"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in userOptions"
|
||||
:key="item.id"
|
||||
:label="item.userName || item.nicke || item.nickName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色" prop="roleId">
|
||||
<el-select
|
||||
v-model="form.roleId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择角色"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in roleOptions"
|
||||
:key="item.id"
|
||||
:label="item.roleName || item.roleCode"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
placeholder="请输入备注"
|
||||
:rows="3"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="drawer-footer">
|
||||
<el-button @click="drawerVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitForm">
|
||||
保存
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { userRoleAdd, userRoleDel, userRoleList, userRoleByUserId } from '@/api/system/user-role'
|
||||
import { userselect } from '@/api/system/user'
|
||||
import { rleselect } from '@/api/system/role'
|
||||
|
||||
interface UserRoleItem {
|
||||
id?: number | string
|
||||
userId: number | string
|
||||
roleId: number | string
|
||||
remark?: string
|
||||
}
|
||||
|
||||
interface UserItem {
|
||||
id: number | string
|
||||
userName?: string
|
||||
nicke?: string
|
||||
nickName?: string
|
||||
}
|
||||
|
||||
interface RoleItem {
|
||||
id: number | string
|
||||
roleName?: string
|
||||
roleCode?: string
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const tableData = ref<UserRoleItem[]>([])
|
||||
const total = ref(0)
|
||||
const userOptions = ref<UserItem[]>([])
|
||||
const roleOptions = ref<RoleItem[]>([])
|
||||
const userMap = ref<Map<number | string, string>>(new Map())
|
||||
const roleMap = ref<Map<number | string, string>>(new Map())
|
||||
|
||||
const queryForm = reactive({
|
||||
userId: null as number | string | null,
|
||||
roleId: null as number | string | null,
|
||||
})
|
||||
|
||||
const pagination = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
})
|
||||
|
||||
const drawerVisible = ref(false)
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const form = reactive<UserRoleItem>({
|
||||
userId: '',
|
||||
roleId: '',
|
||||
remark: '',
|
||||
})
|
||||
|
||||
const rules: FormRules = {
|
||||
userId: [{ required: true, message: '请选择用户', trigger: 'change' }],
|
||||
roleId: [{ required: true, message: '请选择角色', trigger: 'change' }],
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
form.userId = ''
|
||||
form.roleId = ''
|
||||
form.remark = ''
|
||||
formRef.value?.clearValidate()
|
||||
}
|
||||
|
||||
const formatCell = (_row: any, _column: any, value: any) => {
|
||||
if (value === 0) return 0
|
||||
return value === undefined || value === null || value === '' ? '暂无' : value
|
||||
}
|
||||
|
||||
// 获取用户名
|
||||
const getUserName = (userId: number | string | null | undefined) => {
|
||||
if (!userId) return '暂无'
|
||||
return userMap.value.get(userId) || '暂无'
|
||||
}
|
||||
|
||||
// 获取角色名
|
||||
const getRoleName = (roleId: number | string | null | undefined) => {
|
||||
if (!roleId) return '暂无'
|
||||
return roleMap.value.get(roleId) || '暂无'
|
||||
}
|
||||
|
||||
// 加载用户列表
|
||||
const loadUsers = async () => {
|
||||
try {
|
||||
const res: any = await userselect({})
|
||||
const data = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : []
|
||||
userOptions.value = data
|
||||
userMap.value.clear()
|
||||
data.forEach((user: UserItem) => {
|
||||
if (user.id) {
|
||||
const userName = user.userName || user.nicke || user.nickName || ''
|
||||
userMap.value.set(user.id, userName)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('load user list error', error)
|
||||
ElMessage.error('加载用户列表失败')
|
||||
userOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 加载角色列表
|
||||
const loadRoles = async () => {
|
||||
try {
|
||||
const res: any = await rleselect({})
|
||||
const data = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : []
|
||||
roleOptions.value = data
|
||||
roleMap.value.clear()
|
||||
data.forEach((role: RoleItem) => {
|
||||
if (role.id) {
|
||||
const roleName = role.roleName || role.roleCode || ''
|
||||
roleMap.value.set(role.id, roleName)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('load role list error', error)
|
||||
ElMessage.error('加载角色列表失败')
|
||||
roleOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 加载用户角色关联列表
|
||||
const loadList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
// 确保用户和角色列表已加载
|
||||
if (userOptions.value.length === 0) {
|
||||
await loadUsers()
|
||||
}
|
||||
if (roleOptions.value.length === 0) {
|
||||
await loadRoles()
|
||||
}
|
||||
|
||||
const params: any = {
|
||||
pageNum: pagination.pageNum,
|
||||
pageSize: pagination.pageSize,
|
||||
}
|
||||
if (queryForm.userId) {
|
||||
params.userId = queryForm.userId
|
||||
}
|
||||
if (queryForm.roleId) {
|
||||
params.roleId = queryForm.roleId
|
||||
}
|
||||
|
||||
const res: any = await userRoleList(params)
|
||||
|
||||
console.log('用户角色关联列表API返回数据:', res)
|
||||
|
||||
let pageData = res?.data
|
||||
|
||||
if (!pageData && (res?.records || res?.total !== undefined)) {
|
||||
pageData = res
|
||||
}
|
||||
|
||||
const recordsFromData =
|
||||
pageData?.records ||
|
||||
pageData?.list ||
|
||||
pageData?.rows ||
|
||||
pageData?.items ||
|
||||
(Array.isArray(pageData?.data) ? pageData.data : undefined)
|
||||
|
||||
const records = Array.isArray(recordsFromData)
|
||||
? recordsFromData
|
||||
: Array.isArray(pageData)
|
||||
? pageData
|
||||
: Array.isArray(res?.data)
|
||||
? res.data
|
||||
: []
|
||||
|
||||
const totalValue =
|
||||
pageData?.total ??
|
||||
pageData?.count ??
|
||||
pageData?.totalCount ??
|
||||
res?.total ??
|
||||
(Array.isArray(records) ? records.length : 0)
|
||||
|
||||
tableData.value = records
|
||||
total.value = Number(totalValue) || 0
|
||||
|
||||
console.log('解析后的数据:', {
|
||||
records: records.length,
|
||||
total: total.value,
|
||||
firstRecord: records[0],
|
||||
})
|
||||
} catch (error: any) {
|
||||
console.error('load user role list error', error)
|
||||
const errorMsg = error?.message || error?.msg || '加载用户角色关联列表失败'
|
||||
ElMessage.error(errorMsg)
|
||||
tableData.value = []
|
||||
total.value = 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
pagination.pageNum = 1
|
||||
loadList()
|
||||
}
|
||||
|
||||
const resetSearch = () => {
|
||||
queryForm.userId = null
|
||||
queryForm.roleId = null
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
const handleSizeChange = (size: number) => {
|
||||
pagination.pageSize = size
|
||||
loadList()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (page: number) => {
|
||||
pagination.pageNum = page
|
||||
loadList()
|
||||
}
|
||||
|
||||
const openDrawer = async (mode: 'create') => {
|
||||
resetForm()
|
||||
drawerVisible.value = true
|
||||
|
||||
// 加载用户和角色数据
|
||||
await Promise.all([loadUsers(), loadRoles()])
|
||||
}
|
||||
|
||||
const submitForm = () => {
|
||||
formRef.value?.validate(async (valid) => {
|
||||
if (!valid) return
|
||||
|
||||
// 检查用户是否已拥有该角色
|
||||
try {
|
||||
const res: any = await userRoleByUserId(form.userId)
|
||||
const data = res?.data ?? res ?? {}
|
||||
|
||||
// 兼容多种返回格式
|
||||
const userRoles = Array.isArray(data)
|
||||
? data
|
||||
: Array.isArray(data.data)
|
||||
? data.data
|
||||
: Array.isArray(data.records)
|
||||
? data.records
|
||||
: Array.isArray(data.list)
|
||||
? data.list
|
||||
: []
|
||||
|
||||
// 检查是否已存在该角色关联
|
||||
const existingRole = userRoles.find((item: any) => item.roleId === form.roleId)
|
||||
|
||||
if (existingRole) {
|
||||
// 获取用户名和角色名
|
||||
const userName = getUserName(form.userId)
|
||||
const roleName = getRoleName(form.roleId)
|
||||
ElMessage.warning(`用户【${userName}】已拥有【${roleName}】角色,无需重复分配`)
|
||||
return
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('check user role error', error)
|
||||
// 如果检查失败,继续执行新增操作,让后端处理重复情况
|
||||
}
|
||||
|
||||
submitLoading.value = true
|
||||
try {
|
||||
const payload: any = {
|
||||
userId: form.userId,
|
||||
roleId: form.roleId,
|
||||
remark: form.remark || '',
|
||||
}
|
||||
|
||||
await userRoleAdd(payload)
|
||||
ElMessage.success('新增成功')
|
||||
drawerVisible.value = false
|
||||
loadList()
|
||||
} catch (error: any) {
|
||||
console.error('submit user role error', error)
|
||||
const errorMsg = error?.message || error?.msg || '新增失败'
|
||||
ElMessage.error(errorMsg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleDelete = (row: UserRoleItem) => {
|
||||
if (!row.id) {
|
||||
ElMessage.warning('缺少关联ID')
|
||||
return
|
||||
}
|
||||
const userName = getUserName(row.userId)
|
||||
const roleName = getRoleName(row.roleId)
|
||||
ElMessageBox.confirm(`确认删除用户「${userName}」与角色「${roleName}」的关联吗?`, '提示', {
|
||||
type: 'warning',
|
||||
})
|
||||
.then(async () => {
|
||||
if (row.id == null) {
|
||||
ElMessage.warning('缺少关联ID,无法删除')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await userRoleDel(row.id)
|
||||
ElMessage.success('删除成功')
|
||||
loadList()
|
||||
} catch (error: any) {
|
||||
console.error('delete user role error', error)
|
||||
const errorMsg = error?.message || error?.msg || '删除失败'
|
||||
ElMessage.error(errorMsg)
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadUsers()
|
||||
loadRoles()
|
||||
loadList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-role-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.search-card {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.drawer-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user