diff --git a/src/api/v1/menu.ts b/src/api/v1/menu.ts new file mode 100644 index 0000000..a0e1c26 --- /dev/null +++ b/src/api/v1/menu.ts @@ -0,0 +1,34 @@ +import { http } from '@/api/service/request'; +import type { BaseResult, ResultTable } from '@/api/service/types'; + +/** 菜单管理-列表 */ +export const fetchGetMenusList = (data?: any) => { + return http.request>('get', `router/getMenusList`, { params: data }); +}; + +/** 菜单管理-添加菜单 */ +export const fetchAddMenu = (data?: any) => { + return http.request>('post', `router/addMenu`, { data }); +}; + +/** 菜单管理-更新菜单 */ +export const fetchUpdateMenu = (data?: any) => { + return http.request>('put', `router/updateMenu`, { data }); +}; + +/** 菜单管理-删除菜单 */ +export const fetchDeletedMenuByIds = (data?: any) => { + return http.request>('delete', `router/deletedMenuByIds`, { data }); +}; + +/** 菜单管理-为菜单分配角色 */ +export const fetchAssignRolesToRouter = (data: any) => { + return http.request>('post', `routerRole/assignRolesToRouter`, { data }); +}; + +/** + * 根据路由id获取所有角色 + */ +export const fetchGetRoleListByRouterId = data => { + return http.request>('get', `routerRole/getRoleListByRouterId`, { params: data }); +}; diff --git a/src/api/v1/power.ts b/src/api/v1/power.ts index c9dfd91..5c83a41 100644 --- a/src/api/v1/power.ts +++ b/src/api/v1/power.ts @@ -28,3 +28,10 @@ export const fetchUpdatePower = (data: any) => { export const fetchDeletePower = (data: any) => { return http.request>('delete', 'power/deletePower', { data }); }; + +/** + * 获取所有权限 + */ +export const fetchGetAllPowers = () => { + return http.request>('get', `power/getAllPowers`); +}; diff --git a/src/api/v1/role.ts b/src/api/v1/role.ts index bdd050b..ec276ab 100644 --- a/src/api/v1/role.ts +++ b/src/api/v1/role.ts @@ -28,3 +28,17 @@ export const fetchUpdateRole = (data: any) => { export const fetchDeleteRole = (data: any) => { return http.request>('delete', 'role/deleteRole', { data }); }; + +/** + * 获取所有角色 + */ +export const fetchGetAllRoles = () => { + return http.request>('get', `role/getAllRoles`); +}; + +/** + * 根据用户id获取所有角色 + */ +export const fetchGetRoleListByUserId = data => { + return http.request>('get', `userRole/getRoleListByUserId`, { params: data }); +}; diff --git a/src/api/v1/system.ts b/src/api/v1/system.ts index 6348f1c..225badf 100644 --- a/src/api/v1/system.ts +++ b/src/api/v1/system.ts @@ -1,31 +1,11 @@ import { http } from '@/api/service/request'; -import type { BaseResult, ResultTable } from '@/api/service/types'; +import type { BaseResult } from '@/api/service/types'; /** 系统管理-用户路由获取 */ export const getRouterAsync = () => { return http.request>('get', 'router/getRouterAsync'); }; -/** 菜单管理-列表 */ -export const getMenusList = (data?: any) => { - return http.request>('get', `router/getMenusList`, { params: data }); -}; - -/** 菜单管理-添加菜单 */ -export const addMenu = (data?: any) => { - return http.request>('post', `router/addMenu`, { data }); -}; - -/** 菜单管理-更新菜单 */ -export const updateMenu = (data?: any) => { - return http.request>('put', `router/updateMenu`, { data }); -}; - -/** 菜单管理-删除菜单 */ -export const deletedMenuByIds = (data?: any) => { - return http.request>('delete', `router/deletedMenuByIds`, { data }); -}; - /** 上传文件 */ export const fetchUploadFile = (data: any) => { return http.post>('/files/upload', { data }, { headers: { 'Content-Type': 'multipart/form-data' } }); diff --git a/src/api/v1/user.ts b/src/api/v1/user.ts index 8072c6e..6405193 100644 --- a/src/api/v1/user.ts +++ b/src/api/v1/user.ts @@ -87,3 +87,11 @@ export const fetchUploadAvatarByAdmin = (data: any) => { export const fetchForcedOffline = (data: any) => { return http.request>('put', 'user/forcedOffline', { data }); }; + +/** + * 为用户分配角色 + * @param data + */ +export const fetchAssignRolesToUsers = (data: object) => { + return http.request>('post', 'userRole/assignRolesToUsers', { data }); +}; diff --git a/src/enums/baseConstant.ts b/src/enums/baseConstant.ts index 9e6e92e..cc3fdc5 100644 --- a/src/enums/baseConstant.ts +++ b/src/enums/baseConstant.ts @@ -1,3 +1,5 @@ +import { computed } from 'vue'; + /** * * 是否默认 */ @@ -34,3 +36,4 @@ export const userStatus = [ * * 分页默认数组个数 */ export const pageSizes: number[] = [15, 30, 50, 100, 150, 200, 300]; +export const tableSelectButtonClass = computed(() => ['!h-[20px]', 'reset-margin', '!text-gray-500', 'dark:!text-white', 'dark:hover:!text-primary']); diff --git a/src/store/system/router.ts b/src/store/system/menu.ts similarity index 51% rename from src/store/system/router.ts rename to src/store/system/menu.ts index 8e74ce4..2abe9b9 100644 --- a/src/store/system/router.ts +++ b/src/store/system/menu.ts @@ -1,9 +1,9 @@ import { defineStore } from 'pinia'; -import { addMenu, deletedMenuByIds, getMenusList, updateMenu } from '@/api/v1/system'; import { storeMessage } from '@/utils/message'; import { handleTree } from '@/utils/tree'; +import { fetchAddMenu, fetchAssignRolesToRouter, fetchDeletedMenuByIds, fetchGetMenusList, fetchGetRoleListByRouterId, fetchUpdateMenu } from '@/api/v1/menu'; -export const userRouterStore = defineStore('routerStore', { +export const userMenuStore = defineStore('menuStore', { state() { return { datalist: [], @@ -18,7 +18,7 @@ export const userRouterStore = defineStore('routerStore', { */ async getMenuList() { const data = { ...this.pagination, ...this.form }; - const result = await getMenusList(data); + const result = await fetchGetMenusList(data); if (result.code === 200) { this.datalist = handleTree(result.data as any); @@ -32,7 +32,7 @@ export const userRouterStore = defineStore('routerStore', { * @param data */ async addMenu(data: object) { - const result = await addMenu(data); + const result = await fetchAddMenu(data); return storeMessage(result); }, @@ -41,7 +41,7 @@ export const userRouterStore = defineStore('routerStore', { * @param data */ async updateMenu(data: object) { - const result = await updateMenu(data); + const result = await fetchUpdateMenu(data); return storeMessage(result); }, @@ -50,7 +50,26 @@ export const userRouterStore = defineStore('routerStore', { * @param data */ async deletedMenuByIds(data: object) { - const result = await deletedMenuByIds(data); + const result = await fetchDeletedMenuByIds(data); + return storeMessage(result); + }, + + /** + * * 根据路由id获取角色列表 + * @param data + */ + async getRoleListByRouterId(data: any) { + const result = await fetchGetRoleListByRouterId(data); + if (result.code !== 200) return; + return result.data; + }, + + /** + * * 为路由分配角色 + * @param data + */ + async assignRolesToRouter(data: any) { + const result = await fetchAssignRolesToRouter(data); return storeMessage(result); }, }, diff --git a/src/store/system/power.ts b/src/store/system/power.ts index 764b99f..1de36d3 100644 --- a/src/store/system/power.ts +++ b/src/store/system/power.ts @@ -1,5 +1,5 @@ import { defineStore } from 'pinia'; -import { fetchAddPower, fetchDeletePower, fetchGetPowerList, fetchUpdatePower } from '@/api/v1/power'; +import { fetchAddPower, fetchDeletePower, fetchGetAllPowers, fetchGetPowerList, fetchUpdatePower } from '@/api/v1/power'; import { pageSizes } from '@/enums/baseConstant'; import { storeMessage } from '@/utils/message'; import { storePagination } from '@/store/useStorePagination'; @@ -12,6 +12,8 @@ export const usePowerStore = defineStore('powerStore', { return { // 权限列表 datalist: [], + // 权限树形结构 + treeList: [], // 查询表单 form: { // 权限编码 @@ -75,5 +77,14 @@ export const usePowerStore = defineStore('powerStore', { const result = await fetchDeletePower(data); return storeMessage(result); }, + + /** + * 获取所有权限 + */ + async getAllPowers() { + const result = await fetchGetAllPowers(); + if (result.code !== 200) return; + this.treeList = result.data; + }, }, }); diff --git a/src/store/system/role.ts b/src/store/system/role.ts index a89df70..3558ce6 100644 --- a/src/store/system/role.ts +++ b/src/store/system/role.ts @@ -1,5 +1,5 @@ import { defineStore } from 'pinia'; -import { fetchAddRole, fetchDeleteRole, fetchGetRoleList, fetchUpdateRole } from '@/api/v1/role'; +import { fetchAddRole, fetchDeleteRole, fetchGetAllRoles, fetchGetRoleList, fetchUpdateRole } from '@/api/v1/role'; import { pageSizes } from '@/enums/baseConstant'; import { storeMessage } from '@/utils/message'; import { storePagination } from '@/store/useStorePagination'; @@ -52,6 +52,16 @@ export const useRoleStore = defineStore('roleStore', { return pagination(result); }, + /** + * * 获取所有角色 + */ + async getAllRoles() { + const result = await fetchGetAllRoles(); + if (result.code !== 200) return; + + this.allRoleList = result.data.map(role => ({ key: role.id, label: role.description })); + }, + /** * * 添加角色 */ @@ -75,21 +85,5 @@ export const useRoleStore = defineStore('roleStore', { const result = await fetchDeleteRole(data); return storeMessage(result); }, - - /** - * * 根据用户id获取角色列表 - * @param data - */ - async getRoleListByUserId(data: any) { - console.log(data); - }, - - /** - * * 为用户分配角色 - * @param data - */ - async assignRolesToUsers(data: any) { - console.log(data); - }, }, }); diff --git a/src/store/system/user.ts b/src/store/system/user.ts index 97403f2..63c48af 100644 --- a/src/store/system/user.ts +++ b/src/store/system/user.ts @@ -1,9 +1,10 @@ import { defineStore } from 'pinia'; import { resetRouter, router, routerArrays, storageLocal, store, type userType } from '../utils'; -import { fetchLogin, fetchLogout, fetchPostEmailCode, refreshTokenApi } from '@/api/v1/user'; +import { fetchAssignRolesToUsers, fetchLogin, fetchLogout, fetchPostEmailCode, refreshTokenApi } from '@/api/v1/user'; import { useMultiTagsStoreHook } from '../multiTags'; import { type DataInfo, removeToken, setToken, userKey } from '@/utils/auth'; -import { message } from '@/utils/message'; +import { message, storeMessage } from '@/utils/message'; +import { fetchGetRoleListByUserId } from '@/api/v1/role'; export const useUserStore = defineStore({ id: 'system-user', @@ -84,6 +85,25 @@ export const useUserStore = defineStore({ message(result.message, { type: 'error' }); return false; }, + + /** + * * 根据用户id获取角色列表 + * @param data + */ + async getRoleListByUserId(data: any) { + const result = await fetchGetRoleListByUserId(data); + if (result.code !== 200) return; + return result.data; + }, + + /** + * * 为用户分配角色 + * @param data + */ + async assignRolesToUsers(data: any) { + const result = await fetchAssignRolesToUsers(data); + return storeMessage(result); + }, }, }); diff --git a/src/utils/message.ts b/src/utils/message.ts index 98316be..e841e2a 100644 --- a/src/utils/message.ts +++ b/src/utils/message.ts @@ -127,7 +127,7 @@ export const messageBox = async (option: MessageBox = defaultBoxOption, type: an return true; }) .catch(() => { - message(option.cancelMessage, { type: 'warning' }); + message(option.cancelMessage, { type: 'info' }); return false; }); }; diff --git a/src/views/system/adminUser/assign-user-to-role.vue b/src/views/system/adminUser/assign-user-to-role.vue index e4f13a7..c62f568 100644 --- a/src/views/system/adminUser/assign-user-to-role.vue +++ b/src/views/system/adminUser/assign-user-to-role.vue @@ -1,12 +1,14 @@ + + diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue index a580270..f6ac879 100644 --- a/src/views/system/menu/index.vue +++ b/src/views/system/menu/index.vue @@ -6,30 +6,46 @@ import Delete from '@iconify-icons/ep/delete'; import EditPen from '@iconify-icons/ep/edit-pen'; import Refresh from '@iconify-icons/ep/refresh'; import AddFill from '@iconify-icons/ri/add-circle-line'; -import { handleDelete, onAdd, onSearch, onUpdate, resetForm } from '@/views/system/menu/utils/hooks'; +import { assignRolesToRouter, handleDelete, onAdd, onSearch, onUpdate, resetForm } from '@/views/system/menu/utils/hooks'; import form from '@/views/system/menu/form.vue'; import PureTable from '@pureadmin/table'; import { columns } from '@/views/system/menu/utils/columns'; -import { userRouterStore } from '@/store/system/router'; +import { userMenuStore } from '@/store/system/menu'; import { useRenderIcon } from '@/components/CommonIcon/src/hooks'; import { selectUserinfo } from '@/components/Table/Userinfo/columns'; +import More from '@iconify-icons/ep/more-filled'; +import { tableSelectButtonClass } from '@/enums/baseConstant'; +import Upload from '@iconify-icons/ri/upload-line'; +import { messageBox } from '@/utils/message'; const formRef = ref(); const tableRef = ref(); -const routerStore = userRouterStore(); +const routerStore = userMenuStore(); /** * * 修改菜单是否显示 - * @param val + * @param row */ -const onchangeVisible = async (val: boolean) => { +const onchangeVisible = async (row: any) => { + // 是否确认修改显示状态 + const confirm = await messageBox({ + title: $t('confirm_update_status'), + showMessage: false, + confirmMessage: undefined, + cancelMessage: $t('cancel'), + }); + if (!confirm) { + row.visible = !row.visible; + return; + } + const data = { - id: val.id, - visible: val.visible, - menuType: val.menuType, - title: val.title, - name: val.name, - path: val.path, + id: row.id, + visible: row.visible, + menuType: row.menuType, + title: row.title, + name: row.name, + path: row.path, }; await routerStore.updateMenu(data); await onSearch(); @@ -106,13 +122,26 @@ onMounted(() => { diff --git a/src/views/system/menu/utils/columns.tsx b/src/views/system/menu/utils/columns.tsx index 5142664..4fec62b 100644 --- a/src/views/system/menu/utils/columns.tsx +++ b/src/views/system/menu/utils/columns.tsx @@ -43,7 +43,7 @@ export const columns: TableColumnList = [ { label: $t('table.createTime'), prop: 'createTime', sortable: true }, { label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 90 }, { label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser', width: 90 }, - { label: '操作', fixed: 'right', width: 210, slot: 'operation' }, + { label: '操作', fixed: 'right', width: 210, slot: 'operation', width: 240 }, ]; /** 自定义表单规则校验 */ diff --git a/src/views/system/menu/utils/hooks.tsx b/src/views/system/menu/utils/hooks.tsx index 3cd7887..b1167c9 100644 --- a/src/views/system/menu/utils/hooks.tsx +++ b/src/views/system/menu/utils/hooks.tsx @@ -1,16 +1,15 @@ import editForm from '../form.vue'; import { $t } from '@/plugins/i18n'; import { addDialog } from '@/components/BaseDialog/index'; -import { h, reactive, ref } from 'vue'; +import { h, ref } from 'vue'; import type { FormItemProps } from './types'; import { cloneDeep, deviceDetection } from '@pureadmin/utils'; -import { userRouterStore } from '@/store/system/router'; +import { userMenuStore } from '@/store/system/menu'; +import AssignRouterToRole from '@/views/system/menu/assign-router-to-role.vue'; -const routerStore = userRouterStore(); -export const form = reactive({ - title: '', -}); +const menuStore = userMenuStore(); +const assignRouterToRolesRef = ref(); export const formRef = ref(); /** @@ -33,9 +32,9 @@ export const getMenuType = (type, text = false) => { * * 获取菜单数据 */ export const onSearch = async () => { - routerStore.loading = true; - await routerStore.getMenuList(); - routerStore.loading = false; + menuStore.loading = true; + await menuStore.getMenuList(); + menuStore.loading = false; }; export const formatHigherMenuOptions = (treeList: any) => { @@ -58,7 +57,7 @@ export function onAdd(parentId: any = 0) { props: { formInline: { menuType: 0, - higherMenuOptions: formatHigherMenuOptions(cloneDeep(routerStore.datalist)), + higherMenuOptions: formatHigherMenuOptions(cloneDeep(menuStore.datalist)), parentId, title: '', name: '', @@ -82,7 +81,7 @@ export function onAdd(parentId: any = 0) { if (!valid) return; delete curData.higherMenuOptions; - const result = await routerStore.addMenu(curData); + const result = await menuStore.addMenu(curData); // 刷新表格数据 if (result) { done(); @@ -103,7 +102,7 @@ export const onUpdate = (row?: FormItemProps) => { props: { formInline: { menuType: row?.menuType, - higherMenuOptions: formatHigherMenuOptions(cloneDeep(routerStore.datalist)), + higherMenuOptions: formatHigherMenuOptions(cloneDeep(menuStore.datalist)), parentId: row?.parentId, title: row?.title, name: row?.name, @@ -129,7 +128,7 @@ export const onUpdate = (row?: FormItemProps) => { delete curData.higherMenuOptions; curData.id = row.id; - const result = await routerStore.updateMenu(curData); + const result = await menuStore.updateMenu(curData); // 刷新表格数据 if (result) { done(); @@ -145,6 +144,30 @@ export const onUpdate = (row?: FormItemProps) => { * @param row */ export const handleDelete = async row => { - await routerStore.deletedMenuByIds([row.id]); + await menuStore.deletedMenuByIds([row.id]); await onSearch(); }; + +/** + * 为路由分配角色 + * @param row + */ +export const assignRolesToRouter = (row: any) => { + addDialog({ + title: `为 ${row.name} 分配角色`, + width: '45%', + draggable: true, + closeOnClickModal: false, + fullscreenIcon: true, + contentRenderer: () => , + beforeSure: async (done: any) => { + // 分配用户角色 + const data = { routerId: row.id, roleIds: assignRouterToRolesRef.value.assignRoles }; + const result = await menuStore.assignRolesToRouter(data); + + // 更新成功关闭弹窗 + if (!result) return; + done(); + }, + }); +};