Commit 85287e1f7f0dc402135e8bae317583e158469377
1 parent
72db9341
feat: 完善用户权限
Showing
8 changed files
with
210 additions
and
40 deletions
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java
| @@ -12,8 +12,8 @@ import java.util.Set; | @@ -12,8 +12,8 @@ import java.util.Set; | ||
| 12 | @Data | 12 | @Data |
| 13 | public class PermissionAssignUserRoleReqVO { | 13 | public class PermissionAssignUserRoleReqVO { |
| 14 | 14 | ||
| 15 | - @ApiModelProperty(value = "角色编号", required = true, example = "1") | ||
| 16 | - @NotNull(message = "角色编号不能为空") | 15 | + @ApiModelProperty(value = "用户编号", required = true, example = "1") |
| 16 | + @NotNull(message = "用户编号不能为空") | ||
| 17 | private Long userId; | 17 | private Long userId; |
| 18 | 18 | ||
| 19 | @ApiModelProperty(value = "角色编号列表", example = "1,3,5") | 19 | @ApiModelProperty(value = "角色编号列表", example = "1,3,5") |
yudao-ui-admin-vue3/src/api/system/permission/index.ts
0 → 100644
| 1 | +import { useAxios } from '@/hooks/web/useAxios' | ||
| 2 | +import type { | ||
| 3 | + PermissionAssignRoleDataScopeReqVO, | ||
| 4 | + PermissionAssignRoleMenuReqVO, | ||
| 5 | + PermissionAssignUserRoleReqVO | ||
| 6 | +} from './types' | ||
| 7 | + | ||
| 8 | +const request = useAxios() | ||
| 9 | + | ||
| 10 | +// 查询角色拥有的菜单权限 | ||
| 11 | +export const listRoleMenusApi = async (roleId: number) => { | ||
| 12 | + return await request.get({ url: '/system/permission/list-role-resources?roleId=' + roleId }) | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +// 赋予角色菜单权限 | ||
| 16 | +export const assignRoleMenuApi = async (data: PermissionAssignRoleMenuReqVO) => { | ||
| 17 | + return await request.post({ url: '/system/permission/assign-role-menu', data }) | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +// 赋予角色数据权限 | ||
| 21 | +export const assignRoleDataScopeApi = async (data: PermissionAssignRoleDataScopeReqVO) => { | ||
| 22 | + return await request.post({ url: '/system/permission/assign-role-data-scope', data }) | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +// 查询用户拥有的角色数组 | ||
| 26 | +export const listUserRolesApi = async (userId: number) => { | ||
| 27 | + return await request.get({ url: '/system/permission/list-user-roles?userId=' + userId }) | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +// 赋予用户角色 | ||
| 31 | +export const aassignUserRoleApi = async (data: PermissionAssignUserRoleReqVO) => { | ||
| 32 | + return await request.post({ url: '/system/permission/assign-user-role', data }) | ||
| 33 | +} |
yudao-ui-admin-vue3/src/api/system/permission/types.ts
0 → 100644
| 1 | +export type PermissionAssignUserRoleReqVO = { | ||
| 2 | + userId: number | ||
| 3 | + roleIds: number[] | ||
| 4 | +} | ||
| 5 | + | ||
| 6 | +export type PermissionAssignRoleMenuReqVO = { | ||
| 7 | + roleId: number | ||
| 8 | + menuIds: number[] | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +export type PermissionAssignRoleDataScopeReqVO = { | ||
| 12 | + roleId: number | ||
| 13 | + dataScope: number | ||
| 14 | + dataScopeDeptIds: number[] | ||
| 15 | +} |
yudao-ui-admin-vue3/src/api/system/role/index.ts
| @@ -4,31 +4,36 @@ import type { RoleVO } from './types' | @@ -4,31 +4,36 @@ import type { RoleVO } from './types' | ||
| 4 | const request = useAxios() | 4 | const request = useAxios() |
| 5 | 5 | ||
| 6 | // 查询角色列表 | 6 | // 查询角色列表 |
| 7 | -export const getRolePageApi = (params) => { | ||
| 8 | - return request.get({ url: '/system/role/page', params }) | 7 | +export const getRolePageApi = async (params) => { |
| 8 | + return await request.get({ url: '/system/role/page', params }) | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +// 查询角色(精简)列表 | ||
| 12 | +export const listSimpleRolesApi = async () => { | ||
| 13 | + return await request.get({ url: '/system/role/list-all-simple' }) | ||
| 9 | } | 14 | } |
| 10 | 15 | ||
| 11 | // 查询角色详情 | 16 | // 查询角色详情 |
| 12 | -export const getRoleApi = (id: number) => { | ||
| 13 | - return request.get({ url: '/system/role/get?id=' + id }) | 17 | +export const getRoleApi = async (id: number) => { |
| 18 | + return await request.get({ url: '/system/role/get?id=' + id }) | ||
| 14 | } | 19 | } |
| 15 | 20 | ||
| 16 | // 新增角色 | 21 | // 新增角色 |
| 17 | -export const createRoleApi = (data: RoleVO) => { | ||
| 18 | - return request.post({ url: '/system/role/create', data }) | 22 | +export const createRoleApi = async (data: RoleVO) => { |
| 23 | + return await request.post({ url: '/system/role/create', data }) | ||
| 19 | } | 24 | } |
| 20 | 25 | ||
| 21 | // 修改角色 | 26 | // 修改角色 |
| 22 | -export const updateRoleApi = (data: RoleVO) => { | ||
| 23 | - return request.put({ url: '/system/role/update', data }) | 27 | +export const updateRoleApi = async (data: RoleVO) => { |
| 28 | + return await request.put({ url: '/system/role/update', data }) | ||
| 24 | } | 29 | } |
| 25 | 30 | ||
| 26 | // 修改角色状态 | 31 | // 修改角色状态 |
| 27 | -export const updateRoleStatusApi = (data: RoleVO) => { | ||
| 28 | - return request.put({ url: '/system/role/update-status', data }) | 32 | +export const updateRoleStatusApi = async (data: RoleVO) => { |
| 33 | + return await request.put({ url: '/system/role/update-status', data }) | ||
| 29 | } | 34 | } |
| 30 | 35 | ||
| 31 | // 删除角色 | 36 | // 删除角色 |
| 32 | -export const deleteRoleApi = (id: number) => { | ||
| 33 | - return request.delete({ url: '/system/role/delete?id=' + id }) | 37 | +export const deleteRoleApi = async (id: number) => { |
| 38 | + return await request.delete({ url: '/system/role/delete?id=' + id }) | ||
| 34 | } | 39 | } |
yudao-ui-admin-vue3/src/components/CountTo/src/CountTo.vue
| @@ -157,7 +157,7 @@ const count = (timestamp: number) => { | @@ -157,7 +157,7 @@ const count = (timestamp: number) => { | ||
| 157 | } else { | 157 | } else { |
| 158 | state.printVal = state.printVal > endVal ? endVal : state.printVal | 158 | state.printVal = state.printVal > endVal ? endVal : state.printVal |
| 159 | } | 159 | } |
| 160 | - state.displayValue = formatNumber(state.printVal) | 160 | + state.displayValue = formatNumber(state.printVal!) |
| 161 | if (progress < (state.localDuration as number)) { | 161 | if (progress < (state.localDuration as number)) { |
| 162 | state.rAF = requestAnimationFrame(count) | 162 | state.rAF = requestAnimationFrame(count) |
| 163 | } else { | 163 | } else { |
yudao-ui-admin-vue3/src/views/system/role/index.vue
| 1 | <script setup lang="ts"> | 1 | <script setup lang="ts"> |
| 2 | import { onMounted, reactive, ref, unref } from 'vue' | 2 | import { onMounted, reactive, ref, unref } from 'vue' |
| 3 | import dayjs from 'dayjs' | 3 | import dayjs from 'dayjs' |
| 4 | -import { DICT_TYPE, getDictOptions } from '@/utils/dict' | ||
| 5 | -import { useTable } from '@/hooks/web/useTable' | ||
| 6 | -import { useI18n } from '@/hooks/web/useI18n' | ||
| 7 | -import { FormExpose } from '@/components/Form' | ||
| 8 | -import type { RoleVO } from '@/api/system/role/types' | ||
| 9 | -import { rules, allSchemas } from './role.data' | ||
| 10 | -import * as RoleApi from '@/api/system/role' | ||
| 11 | -import Dialog from '@/components/Dialog/src/Dialog.vue' | ||
| 12 | import { | 4 | import { |
| 13 | ElForm, | 5 | ElForm, |
| 14 | ElFormItem, | 6 | ElFormItem, |
| @@ -20,6 +12,18 @@ import { | @@ -20,6 +12,18 @@ import { | ||
| 20 | ElCard, | 12 | ElCard, |
| 21 | ElSwitch | 13 | ElSwitch |
| 22 | } from 'element-plus' | 14 | } from 'element-plus' |
| 15 | +import { DICT_TYPE, getDictOptions } from '@/utils/dict' | ||
| 16 | +import { useTable } from '@/hooks/web/useTable' | ||
| 17 | +import { useI18n } from '@/hooks/web/useI18n' | ||
| 18 | +import { FormExpose } from '@/components/Form' | ||
| 19 | +import { rules, allSchemas } from './role.data' | ||
| 20 | +import type { RoleVO } from '@/api/system/role/types' | ||
| 21 | +import type { | ||
| 22 | + PermissionAssignRoleDataScopeReqVO, | ||
| 23 | + PermissionAssignRoleMenuReqVO | ||
| 24 | +} from '@/api/system/permission/types' | ||
| 25 | +import * as RoleApi from '@/api/system/role' | ||
| 26 | +import * as PermissionApi from '@/api/system/permission' | ||
| 23 | import { listSimpleMenusApi } from '@/api/system/menu' | 27 | import { listSimpleMenusApi } from '@/api/system/menu' |
| 24 | import { listSimpleDeptApi } from '@/api/system/dept' | 28 | import { listSimpleDeptApi } from '@/api/system/dept' |
| 25 | import { handleTree } from '@/utils/tree' | 29 | import { handleTree } from '@/utils/tree' |
| @@ -95,6 +99,7 @@ const handleDetail = async (row: RoleVO) => { | @@ -95,6 +99,7 @@ const handleDetail = async (row: RoleVO) => { | ||
| 95 | 99 | ||
| 96 | // ========== 数据权限 ========== | 100 | // ========== 数据权限 ========== |
| 97 | const dataScopeForm = reactive({ | 101 | const dataScopeForm = reactive({ |
| 102 | + id: 0, | ||
| 98 | name: '', | 103 | name: '', |
| 99 | code: '', | 104 | code: '', |
| 100 | dataScope: 0, | 105 | dataScope: 0, |
| @@ -111,33 +116,62 @@ const dialogScopeVisible = ref(false) | @@ -111,33 +116,62 @@ const dialogScopeVisible = ref(false) | ||
| 111 | const dialogScopeTitle = ref('数据权限') | 116 | const dialogScopeTitle = ref('数据权限') |
| 112 | const actionScopeType = ref('') | 117 | const actionScopeType = ref('') |
| 113 | const dataScopeDictDatas = ref() | 118 | const dataScopeDictDatas = ref() |
| 119 | +const defaultCheckedKeys = ref() | ||
| 114 | // 选项 | 120 | // 选项 |
| 115 | const checkStrictly = ref(true) | 121 | const checkStrictly = ref(true) |
| 116 | const treeNodeAll = ref(false) | 122 | const treeNodeAll = ref(false) |
| 123 | +// 全选/全不选 | ||
| 124 | +const handleCheckedTreeNodeAll = () => { | ||
| 125 | + treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : []) | ||
| 126 | +} | ||
| 117 | // 权限操作 | 127 | // 权限操作 |
| 118 | const handleScope = async (type: string, row: RoleVO) => { | 128 | const handleScope = async (type: string, row: RoleVO) => { |
| 119 | - checkStrictly.value = true | ||
| 120 | - treeNodeAll.value = false | ||
| 121 | - dataScopeForm.dataScope = 0 | 129 | + dataScopeForm.id = row.id |
| 122 | dataScopeForm.name = row.name | 130 | dataScopeForm.name = row.name |
| 123 | dataScopeForm.code = row.code | 131 | dataScopeForm.code = row.code |
| 124 | if (type === 'menu') { | 132 | if (type === 'menu') { |
| 125 | const menuRes = await listSimpleMenusApi() | 133 | const menuRes = await listSimpleMenusApi() |
| 126 | treeOptions.value = handleTree(menuRes) | 134 | treeOptions.value = handleTree(menuRes) |
| 127 | - } else if (type === 'dept') { | 135 | + const role = await PermissionApi.listRoleMenusApi(row.id) |
| 136 | + console.info(role) | ||
| 137 | + if (role) { | ||
| 138 | + // treeRef.value!.setCheckedKeys(role as unknown as Array<number>) | ||
| 139 | + defaultCheckedKeys.value = role | ||
| 140 | + } | ||
| 141 | + } else if (type === 'data') { | ||
| 128 | const deptRes = await listSimpleDeptApi() | 142 | const deptRes = await listSimpleDeptApi() |
| 129 | treeOptions.value = handleTree(deptRes) | 143 | treeOptions.value = handleTree(deptRes) |
| 144 | + const role = await RoleApi.getRoleApi(row.id) | ||
| 145 | + console.info(role) | ||
| 146 | + dataScopeForm.dataScope = role.dataScope | ||
| 147 | + if (role.dataScopeDeptIds) { | ||
| 148 | + // treeRef.value!.setCheckedKeys(role.dataScopeDeptIds as unknown as Array<number>, false) | ||
| 149 | + defaultCheckedKeys.value = role.dataScopeDeptIds | ||
| 150 | + } | ||
| 130 | } | 151 | } |
| 131 | actionScopeType.value = type | 152 | actionScopeType.value = type |
| 132 | dialogScopeVisible.value = true | 153 | dialogScopeVisible.value = true |
| 133 | } | 154 | } |
| 134 | -// 全选/全不选 | ||
| 135 | -const handleCheckedTreeNodeAll = () => { | ||
| 136 | - treeRef.value?.setCheckedNodes(treeNodeAll.value ? treeOptions.value : []) | ||
| 137 | -} | ||
| 138 | -// TODO:保存 | ||
| 139 | -const submitScope = () => { | ||
| 140 | - console.info() | 155 | +// 保存权限 |
| 156 | +const submitScope = async () => { | ||
| 157 | + const keys = treeRef.value!.getCheckedKeys(false) as unknown as Array<number> | ||
| 158 | + console.info(keys) | ||
| 159 | + if ('data' === actionScopeType.value) { | ||
| 160 | + const data = ref<PermissionAssignRoleDataScopeReqVO>({ | ||
| 161 | + roleId: dataScopeForm.id, | ||
| 162 | + dataScope: dataScopeForm.dataScope, | ||
| 163 | + dataScopeDeptIds: dataScopeForm.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM ? [] : keys | ||
| 164 | + }) | ||
| 165 | + await PermissionApi.assignRoleDataScopeApi(data.value) | ||
| 166 | + } else if ('menu' === actionScopeType.value) { | ||
| 167 | + const data = ref<PermissionAssignRoleMenuReqVO>({ | ||
| 168 | + roleId: dataScopeForm.id, | ||
| 169 | + menuIds: keys | ||
| 170 | + }) | ||
| 171 | + await PermissionApi.assignRoleMenuApi(data.value) | ||
| 172 | + } | ||
| 173 | + ElMessage.success(t('common.updateSuccess')) | ||
| 174 | + dialogScopeVisible.value = false | ||
| 141 | } | 175 | } |
| 142 | const init = () => { | 176 | const init = () => { |
| 143 | dataScopeDictDatas.value = getDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE) | 177 | dataScopeDictDatas.value = getDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE) |
| @@ -308,7 +342,7 @@ onMounted(() => { | @@ -308,7 +342,7 @@ onMounted(() => { | ||
| 308 | ref="treeRef" | 342 | ref="treeRef" |
| 309 | node-key="id" | 343 | node-key="id" |
| 310 | show-checkbox | 344 | show-checkbox |
| 311 | - default-expand-all | 345 | + :default-checked-keys="defaultCheckedKeys" |
| 312 | :check-strictly="!checkStrictly" | 346 | :check-strictly="!checkStrictly" |
| 313 | :props="defaultProps" | 347 | :props="defaultProps" |
| 314 | :data="treeOptions" | 348 | :data="treeOptions" |
yudao-ui-admin-vue3/src/views/system/user/index.vue
| 1 | <script setup lang="ts"> | 1 | <script setup lang="ts"> |
| 2 | -import { onMounted, ref, unref, watch } from 'vue' | 2 | +import { onMounted, reactive, ref, unref, watch } from 'vue' |
| 3 | import dayjs from 'dayjs' | 3 | import dayjs from 'dayjs' |
| 4 | import { | 4 | import { |
| 5 | + ElTag, | ||
| 5 | ElInput, | 6 | ElInput, |
| 6 | ElCard, | 7 | ElCard, |
| 7 | ElTree, | 8 | ElTree, |
| @@ -23,14 +24,19 @@ import { useTable } from '@/hooks/web/useTable' | @@ -23,14 +24,19 @@ import { useTable } from '@/hooks/web/useTable' | ||
| 23 | import { FormExpose } from '@/components/Form' | 24 | import { FormExpose } from '@/components/Form' |
| 24 | import type { UserVO } from '@/api/system/user/types' | 25 | import type { UserVO } from '@/api/system/user/types' |
| 25 | import type { PostVO } from '@/api/system/post/types' | 26 | import type { PostVO } from '@/api/system/post/types' |
| 27 | +import type { PermissionAssignUserRoleReqVO } from '@/api/system/permission/types' | ||
| 26 | import { listSimpleDeptApi } from '@/api/system/dept' | 28 | import { listSimpleDeptApi } from '@/api/system/dept' |
| 27 | import { listSimplePostsApi } from '@/api/system/post' | 29 | import { listSimplePostsApi } from '@/api/system/post' |
| 30 | +import { listSimpleRolesApi } from '@/api/system/role' | ||
| 31 | +import { aassignUserRoleApi, listUserRolesApi } from '@/api/system/permission' | ||
| 28 | import { rules, allSchemas } from './user.data' | 32 | import { rules, allSchemas } from './user.data' |
| 29 | import * as UserApi from '@/api/system/user' | 33 | import * as UserApi from '@/api/system/user' |
| 30 | import download from '@/utils/download' | 34 | import download from '@/utils/download' |
| 35 | +import { useRouter } from 'vue-router' | ||
| 31 | import { CommonStatusEnum } from '@/utils/constants' | 36 | import { CommonStatusEnum } from '@/utils/constants' |
| 32 | import { getAccessToken, getTenantId } from '@/utils/auth' | 37 | import { getAccessToken, getTenantId } from '@/utils/auth' |
| 33 | import { useMessage } from '@/hooks/web/useMessage' | 38 | import { useMessage } from '@/hooks/web/useMessage' |
| 39 | + | ||
| 34 | const message = useMessage() | 40 | const message = useMessage() |
| 35 | interface Tree { | 41 | interface Tree { |
| 36 | id: number | 42 | id: number |
| @@ -74,6 +80,10 @@ const handleDeptNodeClick = (data: { [key: string]: any }) => { | @@ -74,6 +80,10 @@ const handleDeptNodeClick = (data: { [key: string]: any }) => { | ||
| 74 | tableTitle.value = data.name | 80 | tableTitle.value = data.name |
| 75 | methods.getList() | 81 | methods.getList() |
| 76 | } | 82 | } |
| 83 | +const { push } = useRouter() | ||
| 84 | +const handleDeptEdit = () => { | ||
| 85 | + push('/system/dept') | ||
| 86 | +} | ||
| 77 | watch(filterText, (val) => { | 87 | watch(filterText, (val) => { |
| 78 | treeRef.value!.filter(val) | 88 | treeRef.value!.filter(val) |
| 79 | }) | 89 | }) |
| @@ -164,7 +174,37 @@ const handleResetPwd = (row: UserVO) => { | @@ -164,7 +174,37 @@ const handleResetPwd = (row: UserVO) => { | ||
| 164 | }) | 174 | }) |
| 165 | }) | 175 | }) |
| 166 | } | 176 | } |
| 167 | - | 177 | +// 分配角色 |
| 178 | +const roleDialogVisible = ref(false) | ||
| 179 | +const roleOptions = ref() | ||
| 180 | +const userRole = reactive({ | ||
| 181 | + id: 0, | ||
| 182 | + username: '', | ||
| 183 | + nickname: '', | ||
| 184 | + roleIds: [] | ||
| 185 | +}) | ||
| 186 | +const handleRole = async (row: UserVO) => { | ||
| 187 | + userRole.id = row.id | ||
| 188 | + userRole.username = row.username | ||
| 189 | + userRole.nickname = row.nickname | ||
| 190 | + // 获得角色拥有的权限集合 | ||
| 191 | + const roles = await listUserRolesApi(row.id) | ||
| 192 | + userRole.roleIds = roles | ||
| 193 | + // 获取角色列表 | ||
| 194 | + const roleOpt = await listSimpleRolesApi() | ||
| 195 | + roleOptions.value = roleOpt | ||
| 196 | + roleDialogVisible.value = true | ||
| 197 | +} | ||
| 198 | +// 提交 | ||
| 199 | +const submitRole = async () => { | ||
| 200 | + const data = ref<PermissionAssignUserRoleReqVO>({ | ||
| 201 | + userId: userRole.id, | ||
| 202 | + roleIds: userRole.roleIds | ||
| 203 | + }) | ||
| 204 | + await aassignUserRoleApi(data.value) | ||
| 205 | + message.success(t('common.updateSuccess')) | ||
| 206 | + roleDialogVisible.value = false | ||
| 207 | +} | ||
| 168 | // ========== 详情相关 ========== | 208 | // ========== 详情相关 ========== |
| 169 | const detailRef = ref() | 209 | const detailRef = ref() |
| 170 | 210 | ||
| @@ -251,6 +291,9 @@ getList() | @@ -251,6 +291,9 @@ getList() | ||
| 251 | <template #header> | 291 | <template #header> |
| 252 | <div class="card-header"> | 292 | <div class="card-header"> |
| 253 | <span>部门列表</span> | 293 | <span>部门列表</span> |
| 294 | + <el-button link class="button" type="primary" @click="handleDeptEdit"> | ||
| 295 | + 修改部门 | ||
| 296 | + </el-button> | ||
| 254 | </div> | 297 | </div> |
| 255 | </template> | 298 | </template> |
| 256 | <el-input v-model="filterText" placeholder="搜索部门" /> | 299 | <el-input v-model="filterText" placeholder="搜索部门" /> |
| @@ -354,6 +397,14 @@ getList() | @@ -354,6 +397,14 @@ getList() | ||
| 354 | <el-button | 397 | <el-button |
| 355 | link | 398 | link |
| 356 | type="primary" | 399 | type="primary" |
| 400 | + v-hasPermi="['system:permission:assign-user-role']" | ||
| 401 | + @click="handleRole(row)" | ||
| 402 | + > | ||
| 403 | + <Icon icon="ep:key" class="mr-1px" /> 分配角色 | ||
| 404 | + </el-button> | ||
| 405 | + <el-button | ||
| 406 | + link | ||
| 407 | + type="primary" | ||
| 357 | v-hasPermi="['system:user:delete']" | 408 | v-hasPermi="['system:user:delete']" |
| 358 | @click="delList(row.id, false)" | 409 | @click="delList(row.id, false)" |
| 359 | > | 410 | > |
| @@ -398,10 +449,14 @@ getList() | @@ -398,10 +449,14 @@ getList() | ||
| 398 | :data="detailRef" | 449 | :data="detailRef" |
| 399 | > | 450 | > |
| 400 | <template #deptId="{ row }"> | 451 | <template #deptId="{ row }"> |
| 401 | - <span>{{ row.dept.name }}</span> | 452 | + <span>{{ row.dept?.name }}</span> |
| 402 | </template> | 453 | </template> |
| 403 | <template #postIds="{ row }"> | 454 | <template #postIds="{ row }"> |
| 404 | - <span>{{ row.dept.name }}</span> | 455 | + <el-tag v-for="(post, index) in row.postIds" :key="index" index=""> |
| 456 | + <template v-for="postObj in postOptions"> | ||
| 457 | + {{ post === postObj.id ? postObj.name : '' }} | ||
| 458 | + </template> | ||
| 459 | + </el-tag> | ||
| 405 | </template> | 460 | </template> |
| 406 | <template #sex="{ row }"> | 461 | <template #sex="{ row }"> |
| 407 | <DictTag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="row.sex" /> | 462 | <DictTag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="row.sex" /> |
| @@ -426,6 +481,34 @@ getList() | @@ -426,6 +481,34 @@ getList() | ||
| 426 | <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button> | 481 | <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button> |
| 427 | </template> | 482 | </template> |
| 428 | </Dialog> | 483 | </Dialog> |
| 484 | + <!-- 分配用户角色 --> | ||
| 485 | + <Dialog v-model="roleDialogVisible" title="分配角色"> | ||
| 486 | + <el-form :model="userRole" label-width="80px"> | ||
| 487 | + <el-form-item label="用户名称"> | ||
| 488 | + <el-input v-model="userRole.username" :disabled="true" /> | ||
| 489 | + </el-form-item> | ||
| 490 | + <el-form-item label="用户昵称"> | ||
| 491 | + <el-input v-model="userRole.nickname" :disabled="true" /> | ||
| 492 | + </el-form-item> | ||
| 493 | + <el-form-item label="角色"> | ||
| 494 | + <el-select v-model="userRole.roleIds" multiple> | ||
| 495 | + <el-option | ||
| 496 | + v-for="item in roleOptions" | ||
| 497 | + :key="parseInt(item.id)" | ||
| 498 | + :label="item.name" | ||
| 499 | + :value="parseInt(item.id)" | ||
| 500 | + /> | ||
| 501 | + </el-select> | ||
| 502 | + </el-form-item> | ||
| 503 | + </el-form> | ||
| 504 | + <!-- 操作按钮 --> | ||
| 505 | + <template #footer> | ||
| 506 | + <el-button type="primary" :loading="loading" @click="submitRole"> | ||
| 507 | + {{ t('action.save') }} | ||
| 508 | + </el-button> | ||
| 509 | + <el-button @click="roleDialogVisible = false">{{ t('dialog.close') }}</el-button> | ||
| 510 | + </template> | ||
| 511 | + </Dialog> | ||
| 429 | <!-- 导入 --> | 512 | <!-- 导入 --> |
| 430 | <Dialog | 513 | <Dialog |
| 431 | v-model="importDialogVisible" | 514 | v-model="importDialogVisible" |
yudao-ui-admin-vue3/src/views/system/user/user.data.ts
| @@ -152,7 +152,7 @@ const crudSchemas = reactive<CrudSchema[]>([ | @@ -152,7 +152,7 @@ const crudSchemas = reactive<CrudSchema[]>([ | ||
| 152 | }, | 152 | }, |
| 153 | { | 153 | { |
| 154 | field: 'action', | 154 | field: 'action', |
| 155 | - width: '340px', | 155 | + width: '400px', |
| 156 | label: t('table.action'), | 156 | label: t('table.action'), |
| 157 | form: { | 157 | form: { |
| 158 | show: false | 158 | show: false |