Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
N
nse-ui
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
吴超
nse-ui
Commits
6d3bc4e2
Commit
6d3bc4e2
authored
Aug 21, 2025
by
周海峰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
no message
parent
4b137e14
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
893 行增加
和
253 行删除
+893
-253
src/api/safetyManagement/roleConfig.js
+49
-0
src/views/safetyManagement/roleConfig/edit.vue
+247
-195
src/views/safetyManagement/roleConfig/edit.vue.new
+498
-0
src/views/safetyManagement/roleConfig/index.vue
+99
-58
没有找到文件。
src/api/safetyManagement/roleConfig.js
View file @
6d3bc4e2
...
...
@@ -14,3 +14,51 @@ export function queryAll(query) {
params
:
query
})
}
/*
* 角色列表查询
* @param {*} query
* @returns
*/
export
function
query
(
data
)
{
return
request
({
url
:
'/console/role/query'
,
method
:
'post'
,
data
:
data
})
}
export
function
initEdit
(
data
)
{
return
request
({
url
:
'/console/role/initEdit'
,
method
:
'post'
,
data
:
data
})
}
export
function
add
(
data
)
{
return
request
({
url
:
'/console/role/add'
,
method
:
'post'
,
data
:
data
})
}
export
function
modify
(
data
)
{
return
request
({
url
:
'/console/role/modify'
,
method
:
'post'
,
data
:
data
})
}
export
function
del
(
data
)
{
return
request
({
url
:
'/console/role/del'
,
method
:
'post'
,
data
:
data
})
}
\ No newline at end of file
src/views/safetyManagement/roleConfig/edit.vue
View file @
6d3bc4e2
...
...
@@ -22,8 +22,8 @@
<!-- 姓名和角色名 -->
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"角色名"
prop=
"role
N
ame"
>
<el-input
v-model=
"form.role
N
ame"
placeholder=
"请输入角色名"
/>
<el-form-item
label=
"角色名"
prop=
"role
n
ame"
>
<el-input
v-model=
"form.role
n
ame"
placeholder=
"请输入角色名"
/>
</el-form-item>
</el-col>
</el-row>
...
...
@@ -32,53 +32,18 @@
<el-form-item
label=
"备注"
prop=
"remark"
>
<el-input
v-model=
"form.remark"
type=
"textarea"
placeholder=
"请输入备注"
/>
</el-form-item>
<!-- 权限设置 -->
<el-form-item
label=
"权限设置"
>
<div
class=
"permission-area"
>
<div
class=
"all-select"
>
<el-checkbox
v-model=
"allPermissionsSelected"
@
change=
"handleAllPermissionsChange"
>
全选
</el-checkbox>
</div>
<div
class=
"permission-list"
>
<div
v-for=
"(item, index) in permissionList"
:key=
"index"
class=
"permission-item"
>
<!-- 父级权限项 -->
<div
class=
"permission-header"
@
click=
"toggleExpand(item)"
>
<div
class=
"left"
>
<el-icon
class=
"expand-icon"
:class=
"
{ expanded: item.expanded }">
<ArrowRight
/>
</el-icon>
<el-checkbox
v-model=
"item.selected"
:indeterminate=
"item.indeterminate"
@
change=
"(val) => handlePermissionChange(item, val)"
>
{{
item
.
name
}}
</el-checkbox>
</div>
<div
class=
"right"
>
<el-tag
size=
"small"
v-if=
"item.children"
>
{{
item
.
children
.
length
}}
</el-tag>
</div>
</div>
<!-- 子级权限列表 -->
<div
v-if=
"item.children"
class=
"sub-permissions"
v-show=
"item.expanded"
>
<el-checkbox
v-for=
"child in item.children"
:key=
"child.id"
v-model=
"child.selected"
@
change=
"(val) => handleSubPermissionChange(item, child, val)"
>
{{
child
.
name
}}
</el-checkbox>
</div>
</div>
</div>
</div>
</el-form-item>
</el-form>
<!-- 权限设置 -->
<PermissionArea
:permissionList=
"permissionList"
:allPermissionsSelected=
"allPermissionsSelected"
@
update:allPermissionsSelected=
"val => allPermissionsSelected = val"
@
permission-change=
"handlePermissionChange"
@
sub-permission-change=
"handleSubPermissionChange"
/>
</div>
<template
#
footer
>
<div
class=
"dialog-footer"
>
...
...
@@ -91,10 +56,19 @@
</el-dialog>
</template>
<
script
>
export
default
{
name
:
'RoleEdit'
,
props
:
{
<
script
setup
>
import
{
ref
,
reactive
,
computed
,
watch
,
nextTick
,
onMounted
}
from
'vue'
import
{
queryAll
as
queryAllMenu
}
from
'@/api/safetyManagement/menuConfig.js'
import
{
initEdit
,
add
,
modify
}
from
'@/api/safetyManagement/roleConfig.js'
import
{
ArrowRight
,
ArrowDown
}
from
'@element-plus/icons-vue'
import
PermissionArea
from
'@/components/PermissionArea/index.vue'
// 定义组件名称
defineOptions
({
name
:
'RoleEdit'
})
// 定义props
const
props
=
defineProps
({
visible
:
{
type
:
Boolean
,
default
:
false
...
...
@@ -103,44 +77,16 @@ export default {
type
:
Object
,
default
:
()
=>
null
}
},
emits
:
[
'update:visible'
,
'success'
],
watch
:
{
visible
(
val
)
{
if
(
val
&&
this
.
formData
)
{
this
.
form
=
{
...
this
.
formData
,
password
:
''
,
confirmPassword
:
''
}
}
}
},
data
()
{
// 密码验证
const
validatePassword
=
(
rule
,
value
,
callback
)
=>
{
if
(
value
===
''
)
{
callback
(
new
Error
(
'请输入密码'
))
}
else
{
if
(
this
.
form
.
confirmPassword
!==
''
)
{
this
.
$refs
.
formRef
.
validateField
(
'confirmPassword'
)
}
callback
()
}
}
// 确认密码验证
const
validateConfirmPassword
=
(
rule
,
value
,
callback
)
=>
{
if
(
value
===
''
)
{
callback
(
new
Error
(
'请再次输入密码'
))
}
else
if
(
value
!==
this
.
form
.
password
)
{
callback
(
new
Error
(
'两次输入密码不一致!'
))
}
else
{
callback
()
}
}
})
return
{
form
:
{
// 定义emits
const
emit
=
defineEmits
([
'update:visible'
,
'success'
])
// 表单引用
const
formRef
=
ref
(
null
)
// 表单数据
const
form
=
reactive
({
realname
:
''
,
roleName
:
''
,
password
:
''
,
...
...
@@ -149,77 +95,104 @@ export default {
userGroup
:
''
,
remark
:
''
,
isDisabled
:
false
},
rules
:
{
roleName
:
[
})
// 表单校验规则
const
rules
=
{
rolename
:
[
{
required
:
true
,
message
:
'请输入角色名'
,
trigger
:
'blur'
}
]
},
allSelected
:
false
,
searchRole
:
''
,
selectedRoles
:
[],
allPermissionsSelected
:
false
,
permissionList
:
[
{
id
:
1
,
name
:
'管理首页'
,
}
// 响应式数据
const
allSelected
=
ref
(
false
)
const
searchRole
=
ref
(
''
)
const
selectedRoles
=
ref
([])
const
allPermissionsSelected
=
ref
(
false
)
const
permissionList
=
ref
([])
// 用户当前具有的权限ID列表
const
menuIdList
=
ref
([])
// 获取菜单权限列表
const
fetchPermissionList
=
async
()
=>
{
try
{
const
res
=
await
queryAllMenu
()
if
(
res
.
code
===
'POP_00014'
)
{
permissionList
.
value
=
mapMenuToPermissions
(
res
.
data
||
[])
}
else
{
console
.
error
(
'获取权限菜单失败:'
,
res
.
msg
)
}
}
catch
(
error
)
{
console
.
error
(
'获取权限菜单异常:'
,
error
)
}
}
// 将菜单数据转换为权限列表格式
const
mapMenuToPermissions
=
(
menuArr
)
=>
{
return
menuArr
.
filter
(
item
=>
item
.
type
!==
'3'
||
item
.
type
===
1
).
map
(
item
=>
{
const
hasChildren
=
Array
.
isArray
(
item
.
children
)
&&
item
.
children
.
length
>
0
let
children
=
hasChildren
?
mapMenuToPermissions
(
item
.
children
)
:
null
return
{
id
:
item
.
id
,
name
:
item
.
type
===
'2'
?
'项目管理-'
+
item
.
name
:
item
.
name
,
selected
:
false
,
indeterminate
:
false
,
expanded
:
false
,
indeterminate
:
false
},
{
id
:
2
,
name
:
'项目管理'
,
selected
:
false
,
expanded
:
false
},
{
id
:
3
,
name
:
'规则管理'
,
selected
:
false
,
children
:
[
{
id
:
'3-1'
,
name
:
'规则管理子项1'
,
selected
:
false
},
{
id
:
'3-2'
,
name
:
'规则管理子项2'
,
selected
:
false
}
]
},
{
id
:
4
,
name
:
'资产库'
,
selected
:
false
},
{
id
:
5
,
name
:
'系统设置'
,
selected
:
false
,
children
:
[
{
id
:
'5-1'
,
name
:
'设置子项1'
,
selected
:
false
},
{
id
:
'5-2'
,
name
:
'设置子项2'
,
selected
:
false
}
]
},
{
id
:
6
,
name
:
'用户管理'
,
selected
:
false
,
children
:
[
{
id
:
'6-1'
,
name
:
'用户管理子项1'
,
selected
:
false
},
{
id
:
'6-2'
,
name
:
'用户管理子项2'
,
selected
:
false
}
]
children
}
]
})
}
// 计算属性
const
filteredRoles
=
computed
(()
=>
{
return
props
.
roles
?.
filter
(
role
=>
role
.
name
.
toLowerCase
().
includes
(
searchRole
.
value
.
toLowerCase
())
)
||
[]
})
// 监听props变化
watch
(()
=>
props
.
visible
,
async
(
val
)
=>
{
if
(
val
)
{
// 获取所有可选权限列表
const
menuRes
=
await
queryAllMenu
()
if
(
props
.
formData
&&
props
.
formData
.
id
)
{
try
{
// 调用接口获取角色详情
const
res
=
await
initEdit
({
roleid
:
props
.
formData
.
id
})
if
(
res
.
code
===
'POP_00014'
)
{
// 填充表单数据
Object
.
assign
(
form
,
{
...
res
.
data
.
roles
})
// 如果返回了权限列表,更新权限数据
permissionList
.
value
=
mapMenu
(
menuRes
.
data
,
res
.
data
.
menuIdList
?
res
.
data
.
menuIdList
.
map
(
m
=>
m
.
menuid
)
:
[])
}
else
{
console
.
error
(
'获取角色详情失败:'
,
res
.
msg
)
}
},
computed
:
{
filteredRoles
()
{
return
this
.
roles
.
filter
(
role
=>
role
.
name
.
toLowerCase
().
includes
(
this
.
searchRole
.
toLowerCase
())
)
}
catch
(
error
)
{
console
.
error
(
'获取角色详情异常:'
,
error
)
}
},
methods
:
{
handleClose
()
{
this
.
$emit
(
'update:visible'
,
false
)
this
.
$refs
.
formRef
?.
resetFields
()
this
.
form
=
{
}
else
{
// 新增角色时重置表单
resetForm
()
// 获取所有可选权限列表
const
menuRes
=
await
queryAllMenu
()
permissionList
.
value
=
mapMenu
(
menuRes
.
data
,
[])
}
}
})
// 方法
// 重置表单数据
const
resetForm
=
()
=>
{
nextTick
(()
=>
{
formRef
.
value
?.
resetFields
()
Object
.
assign
(
form
,
{
id
:
null
,
realname
:
''
,
roleName
:
''
,
password
:
''
,
...
...
@@ -228,62 +201,130 @@ export default {
userGroup
:
''
,
remark
:
''
,
isDisabled
:
false
})
})
}
// 权限
function
mapMenu
(
menuArr
,
selectedIds
=
[])
{
return
(
menuArr
||
[]).
filter
(
item
=>
item
.
type
!==
'3'
||
item
.
type
===
1
).
map
(
item
=>
{
const
hasChildren
=
Array
.
isArray
(
item
.
children
)
&&
item
.
children
.
length
>
0
let
children
=
hasChildren
?
mapMenu
(
item
.
children
,
selectedIds
)
:
null
let
selected
=
selectedIds
.
includes
(
item
.
id
)
let
indeterminate
=
false
if
(
hasChildren
)
{
const
selectedCount
=
children
.
filter
(
c
=>
c
.
selected
).
length
if
(
selectedCount
===
0
)
{
selected
=
false
indeterminate
=
false
}
else
if
(
selectedCount
===
children
.
length
)
{
selected
=
true
indeterminate
=
false
}
else
{
selected
=
false
indeterminate
=
true
}
},
handleSubmit
()
{
this
.
$refs
.
formRef
.
validate
((
valid
)
=>
{
}
return
{
id
:
item
.
id
,
name
:
item
.
type
===
'2'
?
'项目管理-'
+
item
.
name
:
item
.
name
,
selected
,
indeterminate
,
expanded
:
false
,
children
}
})
}
const
handleClose
=
()
=>
{
emit
(
'update:visible'
,
false
)
resetForm
()
}
const
handleSubmit
=
()
=>
{
formRef
.
value
.
validate
((
valid
)
=>
{
if
(
valid
)
{
// 提交表单逻辑
const
params
=
{
...
this
.
form
}
const
params
=
{
...
form
}
// 如果是编辑模式且没有修改密码,则不提交密码字段
if
(
this
.
formData
&&
!
params
.
password
)
{
if
(
props
.
formData
&&
props
.
formData
.
id
&&
!
params
.
password
)
{
delete
params
.
password
delete
params
.
confirmPassword
}
// 收集选中的菜单权限
const
selectedMenuIds
=
[]
const
collectSelectedMenus
=
(
menus
)
=>
{
menus
.
forEach
(
menu
=>
{
if
(
menu
.
selected
)
{
selectedMenuIds
.
push
(
menu
.
id
)
}
if
(
menu
.
children
&&
menu
.
children
.
length
>
0
)
{
collectSelectedMenus
(
menu
.
children
)
}
})
}
collectSelectedMenus
(
permissionList
.
value
)
params
.
menuList
=
selectedMenuIds
.
map
(
id
=>
({
id
}))
console
.
log
(
'submit form'
,
params
)
// 调用接口保存数据
this
.
$
emit
(
'success'
)
this
.
handleClose
()
emit
(
'success'
)
handleClose
()
}
})
},
handleSelectAll
(
val
)
{
this
.
roles
.
forEach
(
role
=>
{
}
const
handleSelectAll
=
(
val
)
=>
{
if
(
props
.
roles
)
{
props
.
roles
.
forEach
(
role
=>
{
role
.
selected
=
val
})
},
handleRoleSelect
(
role
,
val
)
{
}
}
const
handleRoleSelect
=
(
role
,
val
)
=>
{
role
.
selected
=
val
this
.
allSelected
=
this
.
roles
.
every
(
role
=>
role
.
selected
)
},
addSelected
()
{
const
selectedRoles
=
this
.
roles
.
filter
(
role
=>
role
.
selected
)
this
.
selectedRoles
=
[...
new
Set
([...
this
.
selectedRoles
,
...
selectedRoles
])]
this
.
roles
=
this
.
roles
.
filter
(
role
=>
!
role
.
selected
)
this
.
allSelected
=
false
},
removeSelected
()
{
this
.
roles
=
[...
this
.
roles
,
...
this
.
selectedRoles
]
this
.
selectedRoles
=
[]
},
clearSelected
()
{
this
.
roles
=
[...
this
.
roles
,
...
this
.
selectedRoles
]
this
.
selectedRoles
=
[]
},
// 权限相关方法
handleAllPermissionsChange
(
val
)
{
allSelected
.
value
=
props
.
roles
?.
every
(
role
=>
role
.
selected
)
||
false
}
const
addSelected
=
()
=>
{
const
selected
=
props
.
roles
?.
filter
(
role
=>
role
.
selected
)
||
[]
selectedRoles
.
value
=
[...
new
Set
([...
selectedRoles
.
value
,
...
selected
])]
// 这里应该更新props.roles,但由于是props,需要通过emit事件通知父组件更新
allSelected
.
value
=
false
}
const
removeSelected
=
()
=>
{
// 这里应该将selectedRoles添加回props.roles,但由于是props,需要通过emit事件通知父组件更新
selectedRoles
.
value
=
[]
}
const
clearSelected
=
()
=>
{
// 这里应该将selectedRoles添加回props.roles,但由于是props,需要通过emit事件通知父组件更新
selectedRoles
.
value
=
[]
}
// 权限相关方法
const
handleAllPermissionsChange
=
(
val
)
=>
{
// 处理全选
this
.
permissionList
.
forEach
(
item
=>
{
permissionList
.
value
.
forEach
(
item
=>
{
item
.
selected
=
val
if
(
item
.
children
)
{
item
.
children
.
forEach
(
child
=>
{
child
.
selected
=
val
})
}
item
.
indeterminate
=
false
})
},
handlePermissionChange
(
item
,
val
)
{
allPermissionsSelected
.
value
=
val
}
const
handlePermissionChange
=
(
item
,
val
)
=>
{
// 处理父级权限选择
item
.
selected
=
val
item
.
indeterminate
=
false
// 清除半选状态
...
...
@@ -292,9 +333,10 @@ export default {
child
.
selected
=
val
})
}
this
.
checkAllPermissionsStatus
()
},
handleSubPermissionChange
(
parent
,
child
,
val
)
{
checkAllPermissionsStatus
()
}
const
handleSubPermissionChange
=
(
parent
,
child
,
val
)
=>
{
// 处理子级权限选择
child
.
selected
=
val
// 检查父级状态
...
...
@@ -307,23 +349,29 @@ export default {
parent
.
selected
=
allSelected
parent
.
indeterminate
=
!
allSelected
&&
someSelected
}
this
.
checkAllPermissionsStatus
()
},
checkAllPermissionsStatus
()
{
checkAllPermissionsStatus
()
}
const
checkAllPermissionsStatus
=
()
=>
{
// 检查是否全部选中
this
.
allPermissionsSelected
=
this
.
permissionList
.
every
(
item
=>
{
allPermissionsSelected
.
value
=
permissionList
.
value
.
every
(
item
=>
{
if
(
item
.
children
)
{
return
item
.
selected
&&
item
.
children
.
every
(
child
=>
child
.
selected
)
}
return
item
.
selected
})
},
toggleExpand
(
item
)
{
}
const
toggleExpand
=
(
item
)
=>
{
// 展开/收起子菜单
item
.
expanded
=
!
item
.
expanded
}
}
}
// 组件挂载后初始化权限列表
onMounted
(()
=>
{
// 初始获取权限列表
fetchPermissionList
()
})
</
script
>
<
style
lang=
"scss"
scoped
>
...
...
@@ -379,11 +427,16 @@ export default {
width
:
100%
;
display
:
flex
;
flex-direction
:
column
;
max-height
:
400px
;
overflow-y
:
auto
;
.all-select
{
padding
:
8px
12px
;
background-color
:
#f5f7fa
;
border-bottom
:
1px
solid
#dcdfe6
;
position
:
sticky
;
top
:
0
;
z-index
:
1
;
}
.permission-list
{
...
...
@@ -475,5 +528,4 @@ export default {
justify-content
:
flex-end
;
}
}
</
style
>
src/views/safetyManagement/roleConfig/edit.vue.new
0 → 100644
View file @
6d3bc4e2
<template>
<el-dialog
title="编辑角色"
:model-value="visible"
@update:model-value="$emit('update:visible', $event)"
width="800px"
:close-on-click-modal="false"
append-to-body
destroy-on-close
:align-center="true"
:fullscreen="false"
@close="handleClose"
class="user-edit-dialog"
>
<div class="dialog-content" style="padding: 20px; padding-bottom: 80px;height: 700px;overflow-y: auto;">
<el-form
ref="formRef"
:model="form"
:rules="rules"
label-width="100px"
>
<!-- 姓名和角色名 -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="角色名" prop="roleName">
<el-input v-model="form.roleName" placeholder="请输入角色名" />
</el-form-item>
</el-col>
</el-row>
<!-- 备注 -->
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
type="textarea"
placeholder="请输入备注"
/>
</el-form-item>
<!-- 权限设置 -->
<el-form-item label="权限设置">
<div class="permission-area">
<div class="all-select">
<el-checkbox v-model="allPermissionsSelected" @change="handleAllPermissionsChange">全选</el-checkbox>
</div>
<div class="permission-list">
<div v-for="(item, index) in permissionList" :key="index" class="permission-item">
<!-- 父级权限项 -->
<div class="permission-header" @click="toggleExpand(item)">
<div class="left">
<el-icon class="expand-icon" :class="{ expanded: item.expanded }">
<component :is="item.expanded ? 'ArrowDown' : 'ArrowRight'" />
</el-icon>
<el-checkbox
v-model="item.selected"
:indeterminate="item.indeterminate"
@change="(val) => handlePermissionChange(item, val)"
>
{{ item.name }}
</el-checkbox>
</div>
<div class="right">
<el-tag size="small" v-if="item.children">{{ item.children.length }}</el-tag>
</div>
</div>
<!-- 子级权限列表 -->
<div v-if="item.children" class="sub-permissions" v-show="item.expanded">
<el-checkbox
v-for="child in item.children"
:key="child.id"
v-model="child.selected"
@change="(val) => handleSubPermissionChange(item, child, val)"
>
{{ child.name }}
</el-checkbox>
</div>
</div>
</div>
</div>
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer">
<div class="footer-buttons">
<el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="handleSubmit">确 定</el-button>
</div>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive, computed, watch, nextTick } from 'vue'
import { queryAll as queryAllMenu } from '@/api/safetyManagement/menuConfig.js'
import { ArrowRight, ArrowDown } from '@element-plus/icons-vue'
// 定义组件名称
defineOptions({
name: 'RoleEdit'
})
// 定义props
const props = defineProps({
visible: {
type: Boolean,
default: false
},
formData: {
type: Object,
default: () => null
}
})
// 定义emits
const emit = defineEmits(['update:visible', 'success'])
// 表单引用
const formRef = ref(null)
// 表单数据
const form = reactive({
realname: '',
roleName: '',
password: '',
confirmPassword: '',
email: '',
userGroup: '',
remark: '',
isDisabled: false
})
// 表单校验规则
const rules = {
roleName: [
{ required: true, message: '请输入角色名', trigger: 'blur' }
]
}
// 响应式数据
const allSelected = ref(false)
const searchRole = ref('')
const selectedRoles = ref([])
const allPermissionsSelected = ref(false)
const permissionList = ref([
{
id: 1,
name: '管理首页',
selected: false,
expanded: false,
indeterminate: false
},
{
id: 2,
name: '项目管理',
selected: false,
expanded: false
},
{
id: 3,
name: '规则管理',
selected: false,
expanded: false,
indeterminate: false,
children: [
{ id: '3-1', name: '规则管理子项1', selected: false },
{ id: '3-2', name: '规则管理子项2', selected: false }
]
},
{
id: 4,
name: '资产库',
selected: false
},
{
id: 5,
name: '系统设置',
selected: false,
expanded: false,
indeterminate: false,
children: [
{ id: '5-1', name: '设置子项1', selected: false },
{ id: '5-2', name: '设置子项2', selected: false }
]
},
{
id: 6,
name: '用户管理',
selected: false,
expanded: false,
indeterminate: false,
children: [
{ id: '6-1', name: '用户管理子项1', selected: false },
{ id: '6-2', name: '用户管理子项2', selected: false }
]
}
])
// 计算属性
const filteredRoles = computed(() => {
return props.roles?.filter(role =>
role.name.toLowerCase().includes(searchRole.value.toLowerCase())
) || []
})
// 监听props变化
watch(() => props.visible, (val) => {
if (val && props.formData) {
Object.assign(form, {
...props.formData,
password: '',
confirmPassword: ''
})
}
})
// 方法
const handleClose = () => {
emit('update:visible', false)
nextTick(() => {
formRef.value?.resetFields()
Object.assign(form, {
realname: '',
roleName: '',
password: '',
confirmPassword: '',
email: '',
userGroup: '',
remark: '',
isDisabled: false
})
})
}
const handleSubmit = () => {
formRef.value.validate((valid) => {
if (valid) {
// 提交表单逻辑
const params = { ...form }
// 如果是编辑模式且没有修改密码,则不提交密码字段
if (props.formData && !params.password) {
delete params.password
delete params.confirmPassword
}
console.log('submit form', params)
// 调用接口保存数据
emit('success')
handleClose()
}
})
}
const handleSelectAll = (val) => {
if (props.roles) {
props.roles.forEach(role => {
role.selected = val
})
}
}
const handleRoleSelect = (role, val) => {
role.selected = val
allSelected.value = props.roles?.every(role => role.selected) || false
}
const addSelected = () => {
const selected = props.roles?.filter(role => role.selected) || []
selectedRoles.value = [...new Set([...selectedRoles.value, ...selected])]
// 这里应该更新props.roles,但由于是props,需要通过emit事件通知父组件更新
allSelected.value = false
}
const removeSelected = () => {
// 这里应该将selectedRoles添加回props.roles,但由于是props,需要通过emit事件通知父组件更新
selectedRoles.value = []
}
const clearSelected = () => {
// 这里应该将selectedRoles添加回props.roles,但由于是props,需要通过emit事件通知父组件更新
selectedRoles.value = []
}
// 权限相关方法
const handleAllPermissionsChange = (val) => {
// 处理全选
permissionList.value.forEach(item => {
item.selected = val
if (item.children) {
item.children.forEach(child => {
child.selected = val
})
}
item.indeterminate = false
})
allPermissionsSelected.value = val
}
const handlePermissionChange = (item, val) => {
// 处理父级权限选择
item.selected = val
item.indeterminate = false // 清除半选状态
if (item.children) {
item.children.forEach(child => {
child.selected = val
})
}
checkAllPermissionsStatus()
}
const handleSubPermissionChange = (parent, child, val) => {
// 处理子级权限选择
child.selected = val
// 检查父级状态
if (parent.children) {
// 如果所有子项都选中,父级完全选中
const allSelected = parent.children.every(c => c.selected)
// 如果部分子项选中,父级半选
const someSelected = parent.children.some(c => c.selected)
parent.selected = allSelected
parent.indeterminate = !allSelected && someSelected
}
checkAllPermissionsStatus()
}
const checkAllPermissionsStatus = () => {
// 检查是否全部选中
allPermissionsSelected.value = permissionList.value.every(item => {
if (item.children) {
return item.selected && item.children.every(child => child.selected)
}
return item.selected
})
}
const toggleExpand = (item) => {
// 展开/收起子菜单
item.expanded = !item.expanded
}
</script>
<style lang="scss" scoped>
.role-transfer {
display: flex;
align-items: flex-start;
gap: 10px;
.transfer-list {
flex: 1;
border: 1px solid #dcdfe6;
border-radius: 4px;
height: 300px;
display: flex;
flex-direction: column;
.transfer-header {
padding: 8px 12px;
border-bottom: 1px solid #dcdfe6;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f5f7fa;
}
.role-list, .selected-list {
flex: 1;
overflow-y: auto;
padding: 6px 0;
}
.role-item {
padding: 6px 12px;
cursor: pointer;
&:hover {
background-color: #f5f7fa;
}
}
}
.transfer-operation {
display: flex;
flex-direction: column;
gap: 10px;
padding: 10px 0;
}
}
.permission-area {
border: 1px solid #dcdfe6;
border-radius: 4px;
width: 100%;
display: flex;
flex-direction: column;
max-height: 400px;
overflow-y: auto;
.all-select {
padding: 8px 12px;
background-color: #f5f7fa;
border-bottom: 1px solid #dcdfe6;
position: sticky;
top: 0;
z-index: 1;
}
.permission-list {
padding: 12px;
.permission-item {
border-bottom: 1px solid #ebeef5;
&:last-child {
border-bottom: none;
}
.permission-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 0;
cursor: pointer;
.left {
display: flex;
align-items: center;
gap: 8px;
.expand-icon {
transition: transform 0.3s;
font-size: 12px;
color: #909399;
&.expanded {
transform: rotate(90deg);
}
}
}
}
.sub-permissions {
padding: 8px 0 8px 32px;
display: flex;
flex-direction: column;
gap: 12px;
background-color: #f8f9fb;
border-top: 1px solid #ebeef5;
}
}
}
}
:deep(.el-transfer-panel) {
width: 100%;
}
.user-edit-dialog {
:deep(.el-dialog) {
display: flex;
flex-direction: column;
margin: 0 auto !important;
max-height: 90vh;
position: relative;
.el-dialog__body {
flex: 1;
overflow: hidden;
padding: 0;
}
.dialog-content {
height: 100%;
overflow-y: auto;
padding: 20px;
padding-bottom: 80px;
}
}
}
.dialog-footer {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 20px;
background-color: #fff;
border-top: 1px solid #dcdfe6;
z-index: 9999;
.footer-buttons {
display: flex;
gap: 10px;
justify-content: flex-end;
}
}
</style>
src/views/safetyManagement/roleConfig/index.vue
View file @
6d3bc4e2
...
...
@@ -11,10 +11,10 @@
<el-form
:inline=
"true"
:model=
"searchForm"
class=
"search-form"
>
<div
class=
"left-area"
>
<el-form-item
label=
"角色名:"
>
<el-input
v-model=
"searchForm.role
Name"
placeholder=
"请输入角色名"
></el-input>
<el-input
v-model=
"searchForm.role
name"
clearable
placeholder=
"请输入角色名"
></el-input>
</el-form-item>
<el-form-item
label=
"备注:"
>
<el-input
v-model=
"searchForm.remark"
placeholder=
"请输入备注"
></el-input>
<el-input
v-model=
"searchForm.remark"
clearable
placeholder=
"请输入备注"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
icon=
"Search"
@
click=
"handleSearch"
>
搜索
</el-button>
...
...
@@ -29,24 +29,24 @@
<!-- 列表 -->
<div
class=
"user-list"
>
<div
class=
"user-grid"
>
<div
v-for=
"(user, index) in
user
List"
:key=
"index"
class=
"user-card"
>
<div
v-for=
"(user, index) in
role
List"
:key=
"index"
class=
"user-card"
>
<div
class=
"user-info"
>
<div
class=
"avatar"
>
<el-avatar
:size=
"50"
icon=
"User"
></el-avatar>
</div>
<div
class=
"info"
>
<div
class=
"roleName"
>
角色名:
{{
user
.
role
N
ame
}}
</div>
<div
class=
"roleName"
>
角色名:
{{
user
.
role
n
ame
}}
</div>
<div
class=
"remark"
>
备注:
{{
user
.
remark
}}
</div>
</div>
<!-- 遮罩层和操作按钮 -->
<div
class=
"hover-mask"
>
<div
class=
"operation-buttons"
>
<div
class=
"operation-btn"
@
click=
"handleDelete(user)"
>
<
i
class=
"el-icon-delete"
></i
>
<
el-icon><Delete
/></el-icon
>
<span>
删除
</span>
</div>
<div
class=
"operation-btn"
@
click=
"handleEdit(user)"
>
<
i
class=
"el-icon-edit"
></i
>
<
el-icon><Edit
/></el-icon
>
<span>
编辑
</span>
</div>
</div>
...
...
@@ -58,12 +58,14 @@
<!-- 分页 -->
<div
class=
"pagination"
>
<div
class=
"pagination-info"
>
共有记录 1条,每页显示 8条,共 1页
</div>
<div
class=
"pagination-info"
>
共有记录
{{
total
}}
条,每页显示
{{
pageSize
}}
条,共
{{
Math
.
max
(
1
,
Math
.
ceil
(
total
/
pageSize
))
}}
页
</div>
<el-pagination
background
layout=
"prev, pager, next, jumper"
:total=
"total"
:current-page
.
sync
=
"currentPage"
:current-page=
"currentPage"
:page-size=
"pageSize"
@
current-change=
"handlePageChange"
>
</el-pagination>
...
...
@@ -78,72 +80,103 @@
</div>
</
template
>
<
script
>
<
script
setup
>
import
{
ref
,
reactive
,
onMounted
,
getCurrentInstance
}
from
'vue'
import
{
ElMessageBox
}
from
'element-plus'
import
{
User
,
Delete
,
Edit
}
from
'@element-plus/icons-vue'
import
RoleEdit
from
'./edit.vue'
import
{
query
as
queryRole
}
from
'@/api/safetyManagement/roleConfig.js'
// 定义组件名称
defineOptions
({
name
:
'RoleConfig'
})
export
default
{
name
:
'RoleConfig'
,
components
:
{
RoleEdit
},
data
()
{
return
{
searchForm
:
{
name
:
''
,
// 响应式数据
const
searchForm
=
reactive
({
roleName
:
''
,
remark
:
''
},
userList
:
[
})
const
roleList
=
ref
([
{
realname
:
'admin'
,
roleName
:
'admin'
,
remark
:
''
}
],
total
:
1
,
currentPage
:
1
,
pageSize
:
8
,
editVisible
:
false
,
editData
:
null
])
const
total
=
ref
(
1
)
const
currentPage
=
ref
(
1
)
const
pageSize
=
ref
(
8
)
const
editVisible
=
ref
(
false
)
const
editData
=
ref
(
null
)
const
instance
=
getCurrentInstance
()
// 获取角色列表
const
getList
=
async
()
=>
{
const
params
=
{
...
searchForm
,
page
:
currentPage
.
value
,
rows
:
pageSize
.
value
}
try
{
// 实际项目中这里应该调用接口获取数据
const
res
=
await
queryRole
(
params
)
console
.
log
(
'角色列表接口返回数据:'
,
res
)
roleList
.
value
=
res
.
data
.
list
||
[]
total
.
value
=
res
.
data
.
total
}
catch
(
error
)
{
const
modal
=
instance
?.
appContext
.
config
.
globalProperties
.
$modal
modal
&&
modal
.
msgError
?
modal
.
msgError
(
'查询异常'
)
:
console
.
error
(
'查询异常'
,
error
)
}
},
methods
:
{
handleSearch
()
{
// 实现搜索逻辑
},
handleAdd
()
{
// 打开新增角色弹窗
this
.
editData
=
null
this
.
editVisible
=
true
},
handlePageChange
(
page
)
{
// 实现分页逻辑
},
handleDelete
(
row
)
{
// 实现删除角色逻辑
this
.
$confirm
(
'确认删除该角色吗?'
,
'提示'
,
{
}
// 处理搜索
const
handleSearch
=
()
=>
{
currentPage
.
value
=
1
getList
()
}
// 添加角色
const
handleAdd
=
()
=>
{
editData
.
value
=
null
editVisible
.
value
=
true
}
// 分页变化
const
handlePageChange
=
(
page
)
=>
{
currentPage
.
value
=
page
getList
()
}
// 删除角色
const
handleDelete
=
(
row
)
=>
{
ElMessageBox
.
confirm
(
'确认删除该角色吗?'
,
'提示'
,
{
type
:
'warning'
}).
then
(()
=>
{
// 调用删除接口
console
.
log
(
'删除角色'
,
row
)
}).
catch
(()
=>
{})
},
handleEdit
(
row
)
{
// 打开编辑角色弹窗
this
.
editData
=
{
...
row
}
this
.
editVisible
=
true
},
handleEditSuccess
()
{
// 编辑成功后的回调
this
.
editVisible
=
false
}
// 编辑角色
const
handleEdit
=
(
row
)
=>
{
editData
.
value
=
{
...
row
}
editVisible
.
value
=
true
}
// 编辑成功回调
const
handleEditSuccess
=
()
=>
{
editVisible
.
value
=
false
// 刷新列表数据
this
.
getList
()
},
getList
()
{
// 获取角色列表数据
}
}
getList
()
}
// 页面挂载时获取数据
onMounted
(()
=>
{
getList
()
})
</
script
>
<
style
lang=
"scss"
scoped
>
...
...
@@ -205,6 +238,13 @@ export default {
border-radius
:
8px
;
box-shadow
:
0
2px
12px
0
rgba
(
0
,
0
,
0
,
0.1
);
overflow
:
hidden
;
border-left
:
4px
solid
#3498db
;
transition
:
all
0.3s
ease
;
&:hover
{
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.15
);
transform
:
translateY
(
-2px
);
}
}
.user-info
{
...
...
@@ -258,7 +298,7 @@ export default {
color
:
white
;
cursor
:
pointer
;
i
{
.el-icon
{
font-size
:
24px
;
margin-bottom
:
8px
;
}
...
...
@@ -269,6 +309,7 @@ export default {
&
:hover
{
color
:
#409EFF
;
transform
:
scale
(
1.1
);
}
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论