feat: 🚀 角色分配权限,根据角色查询已经分配好的权限,其它缺陷修复

This commit is contained in:
bunny 2024-10-08 10:44:31 +08:00
parent f3e39db4ee
commit 3a115c82d1
15 changed files with 140 additions and 74 deletions

View File

@ -154,6 +154,7 @@ class PureHttp {
// 关闭进度条动画 // 关闭进度条动画
NProgress.done(); NProgress.done();
message(error.message, { type: 'error' });
return error; return error;
}, },
); );

View File

@ -12,7 +12,7 @@ export const fetchGetPowerList = (data: any) => {
* ---id获取权限内容 * ---id获取权限内容
*/ */
export const fetchGetPowerListByRoleId = (data: any) => { export const fetchGetPowerListByRoleId = (data: any) => {
return http.request<BaseResult<object>>('get', 'rolePower/getPowerListByRoleId', { data }); return http.request<BaseResult<object>>('get', 'rolePower/getPowerListByRoleId', { params: data });
}; };
/** /**

View File

@ -8,27 +8,6 @@ export const fetchGetRoleList = (data: any) => {
return http.request<BaseResult<ResultTable>>('get', `role/getRoleList/${data.currentPage}/${data.pageSize}`, { params: data }); return http.request<BaseResult<ResultTable>>('get', `role/getRoleList/${data.currentPage}/${data.pageSize}`, { params: data });
}; };
/**
* ---
*/
export const fetchAddRole = (data: any) => {
return http.request<BaseResult<object>>('post', 'role/addRole', { data });
};
/**
* ---
*/
export const fetchUpdateRole = (data: any) => {
return http.request<BaseResult<object>>('put', 'role/updateRole', { data });
};
/**
* ---
*/
export const fetchDeleteRole = (data: any) => {
return http.request<BaseResult<object>>('delete', 'role/deleteRole', { data });
};
/** /**
* *
*/ */
@ -42,3 +21,31 @@ export const fetchGetAllRoles = () => {
export const fetchGetRoleListByUserId = data => { export const fetchGetRoleListByUserId = data => {
return http.request<BaseResult<any>>('get', `userRole/getRoleListByUserId`, { params: data }); return http.request<BaseResult<any>>('get', `userRole/getRoleListByUserId`, { params: data });
}; };
/**
* ---
*/
export const fetchAddRole = (data: any) => {
return http.request<BaseResult<object>>('post', 'role/addRole', { data });
};
/**
* ---
*/
export const fetchAssignPowersToRole = (data: any) => {
return http.request<BaseResult<object>>('post', 'rolePower/assignPowersToRole', { data });
};
/**
* ---
*/
export const fetchUpdateRole = (data: any) => {
return http.request<BaseResult<object>>('put', 'role/updateRole', { data });
};
/**
* ---
*/
export const fetchDeleteRole = (data: any) => {
return http.request<BaseResult<object>>('delete', 'role/deleteRole', { data });
};

View File

@ -1,5 +1,5 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { fetchAddRole, fetchDeleteRole, fetchGetAllRoles, fetchGetRoleList, fetchUpdateRole } from '@/api/v1/role'; import { fetchAddRole, fetchAssignPowersToRole, fetchDeleteRole, fetchGetAllRoles, fetchGetRoleList, fetchUpdateRole } from '@/api/v1/role';
import { pageSizes } from '@/enums/baseConstant'; import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message'; import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination'; import { storePagination } from '@/store/useStorePagination';
@ -70,6 +70,15 @@ export const useRoleStore = defineStore('roleStore', {
return storeMessage(result); return storeMessage(result);
}, },
/**
* *
* @param data
*/
async assignPowersToRole(data: any) {
const result = await fetchAssignPowersToRole(data);
return storeMessage(result);
},
/** /**
* * * *
*/ */

View File

@ -31,15 +31,6 @@ interface MessageParams {
onClose?: Function | null; onClose?: Function | null;
} }
// 消息盒
interface MessageBox {
message: string | undefined;
title: string | undefined;
confirmMessage: any;
cancelMessage: any;
showMessage: boolean;
}
/** 用法非常简单,参考 src/views/components/message/index.vue 文件 */ /** 用法非常简单,参考 src/views/components/message/index.vue 文件 */
/** /**
@ -101,7 +92,7 @@ export const storeMessage = (result: BaseResult<any>) => {
return true; return true;
}; };
const defaultBoxOption: MessageBox = { const defaultBoxOption: any = {
showMessage: false, showMessage: false,
message: '', message: '',
title: '', title: '',
@ -114,7 +105,7 @@ const defaultBoxOption: MessageBox = {
* @param type * @param type
* @param option * @param option
*/ */
export const messageBox = async (option: MessageBox = defaultBoxOption, type: any = 'warning') => { export const messageBox = async (option: any = defaultBoxOption, type: any = 'warning') => {
return ElMessageBox.confirm(option.message, option.title, { return ElMessageBox.confirm(option.message, option.title, {
confirmButtonText: '确认', confirmButtonText: '确认',
cancelButtonText: '返回', cancelButtonText: '返回',

View File

@ -95,16 +95,14 @@ defineExpose({ formRef });
<!-- 用户简介 --> <!-- 用户简介 -->
<re-col :sm="24" :value="24" :xs="24"> <re-col :sm="24" :value="24" :xs="24">
<el-form-item :label="$t('adminUser_summary')" prop="summary"> <el-form-item :label="$t('adminUser_summary')" prop="summary">
<el-input v-model="form.summary" :placeholder="$t('adminUser_summary')" autocomplete="off" maxlength="600" show-word-limit type="textarea" /> <el-input v-model="form.summary" :placeholder="$t('adminUser_summary')" autocomplete="off" maxlength="200" show-word-limit type="textarea" />
</el-form-item> </el-form-item>
</re-col> </re-col>
<!-- 用户状态 --> <!-- 用户状态 -->
<re-col :sm="24" :value="12" :xs="24"> <re-col :sm="24" :value="12" :xs="24">
<el-form-item :label="$t('adminUser_status')" prop="status"> <el-form-item :label="$t('adminUser_status')" prop="status">
<el-switch v-model="form.status" active-text="禁用" class="ml-2" inactive-text="正常" inline-prompt style=" <el-switch v-model="form.status" active-text="禁用" class="ml-2" inactive-text="正常" inline-prompt style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66" />
--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66" />
</el-form-item> </el-form-item>
</re-col> </re-col>
</el-row> </el-row>

View File

@ -4,7 +4,19 @@ import { columns } from '@/views/system/adminUser/utils/columns';
import PureTableBar from '@/components/TableBar/src/bar'; import PureTableBar from '@/components/TableBar/src/bar';
import AddFill from '@iconify-icons/ri/add-circle-line'; import AddFill from '@iconify-icons/ri/add-circle-line';
import PureTable from '@pureadmin/table'; import PureTable from '@pureadmin/table';
import { onAdd, onAssignRolesToUser, onDelete, onForcedOffline, onResetPassword, onSearch, onUpdate, onUploadAvatar, updateUserStatus } from '@/views/system/adminUser/utils/hooks'; import {
deleteIds,
onAdd,
onAssignRolesToUser,
onDelete,
onDeleteBatch,
onForcedOffline,
onResetPassword,
onSearch,
onUpdate,
onUploadAvatar,
updateUserStatus,
} from '@/views/system/adminUser/utils/hooks';
import Delete from '@iconify-icons/ep/delete'; import Delete from '@iconify-icons/ep/delete';
import EditPen from '@iconify-icons/ep/edit-pen'; import EditPen from '@iconify-icons/ep/edit-pen';
import Refresh from '@iconify-icons/ep/refresh'; import Refresh from '@iconify-icons/ep/refresh';
@ -22,6 +34,7 @@ import { deviceDetection, handleTree } from '@pureadmin/utils';
import Tree from '@/views/system/adminUser/tree.vue'; import Tree from '@/views/system/adminUser/tree.vue';
import Airplane from '@/assets/svg/airplane.svg'; import Airplane from '@/assets/svg/airplane.svg';
import { useDeptStore } from '@/store/system/dept'; import { useDeptStore } from '@/store/system/dept';
import { FormInstance } from 'element-plus';
const tableRef = ref(); const tableRef = ref();
const formRef = ref(); const formRef = ref();
@ -29,6 +42,15 @@ const adminUserStore = useAdminUserStore();
const deptStore = useDeptStore(); const deptStore = useDeptStore();
const deptList = computed(() => handleTree(deptStore.allDeptList)); const deptList = computed(() => handleTree(deptStore.allDeptList));
/**
* * 加载部门列表
*/
const onSearchDept = async () => {
deptStore.loading = true;
await deptStore.getAllDeptList();
deptStore.loading = false;
};
/** /**
* * 当前页改变时 * * 当前页改变时
*/ */
@ -50,20 +72,18 @@ const onPageSizeChange = async (value: number) => {
* 重置表单 * 重置表单
* @param formEl * @param formEl
*/ */
const resetForm = async formEl => { const resetForm = async (formEl: FormInstance) => {
if (!formEl) return; if (!formEl) return;
formEl.resetFields(); formEl.resetFields();
await onSearch(); await onSearch();
}; };
/** /**
* * 加载部门列表 * * 选择多行
* @param deptName * @param rows
*/ */
const onSearchDept = async (deptName: string) => { const onSelectionChange = (rows: Array<any>) => {
deptStore.loading = true; deleteIds.value = rows.map((row: any) => row.id);
await deptStore.getAllDeptList();
deptStore.loading = false;
}; };
/** /**
@ -71,7 +91,7 @@ const onSearchDept = async (deptName: string) => {
* 搜索当前用户属于哪个部门 * 搜索当前用户属于哪个部门
* @param dept * @param dept
*/ */
const onTreeSelect = dept => { const onTreeSelect = (dept: any) => {
console.log(dept); console.log(dept);
}; };
@ -134,6 +154,11 @@ onMounted(() => {
<PureTableBar :columns="columns" title="用户信息" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch"> <PureTableBar :columns="columns" title="用户信息" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
<template #buttons> <template #buttons>
<el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> {{ $t('add_new') }}</el-button> <el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> {{ $t('add_new') }}</el-button>
<!-- 批量删除按钮 -->
<el-button v-show="deleteIds.length > 0" :icon="useRenderIcon(Delete)" type="danger" @click="onDeleteBatch">
{{ $t('delete_batches') }}
</el-button>
</template> </template>
<template v-slot="{ size, dynamicColumns }"> <template v-slot="{ size, dynamicColumns }">
@ -154,6 +179,7 @@ onMounted(() => {
showOverflowTooltip showOverflowTooltip
table-layout="auto" table-layout="auto"
@page-size-change="onPageSizeChange" @page-size-change="onPageSizeChange"
@selection-change="onSelectionChange"
@page-current-change="onCurrentPageChange" @page-current-change="onCurrentPageChange"
> >
<!-- 显示头像 --> <!-- 显示头像 -->
@ -169,10 +195,8 @@ onMounted(() => {
class="ml-2" class="ml-2"
inactive-text="正常" inactive-text="正常"
inline-prompt inline-prompt
style=" style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66"
@click="updateUserStatus(row)"
--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66"
@change="updateUserStatus(row)"
/> />
</template> </template>

View File

@ -8,13 +8,7 @@ import ExpandIcon from '@/assets/svg/expand.svg?component';
import UnExpandIcon from '@/assets/svg/unexpand.svg?component'; import UnExpandIcon from '@/assets/svg/unexpand.svg?component';
import { useRenderIcon } from '@/components/CommonIcon/src/hooks'; import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
import Reset from '@iconify-icons/ri/restart-line'; import Reset from '@iconify-icons/ri/restart-line';
import { Tree } from '@/views/system/adminUser/utils/types';
interface Tree {
id: number;
deptName: string;
highlight?: boolean;
children?: Tree[];
}
defineProps({ defineProps({
treeLoading: Boolean, treeLoading: Boolean,

View File

@ -6,6 +6,7 @@ export const isAddUserinfo = ref(false);
// 表格列 // 表格列
export const columns: TableColumnList = [ export const columns: TableColumnList = [
{ type: 'selection', align: 'left' },
{ type: 'index', index: (index: number) => index + 1, label: '序号', width: 60 }, { type: 'index', index: (index: number) => index + 1, label: '序号', width: 60 },
// 主键 // 主键
{ label: $t('id'), prop: 'id' }, { label: $t('id'), prop: 'id' },

View File

@ -1,6 +1,6 @@
import { addDialog } from '@/components/BaseDialog/index'; import { addDialog } from '@/components/BaseDialog/index';
import AdminUserDialog from '@/views/system/adminUser/admin-user-dialog.vue'; import AdminUserDialog from '@/views/system/adminUser/admin-user-dialog.vue';
import { useAdminUserStore } from '@/store/system/adminUser.ts'; import { useAdminUserStore } from '@/store/system/adminUser';
import { h, reactive, ref } from 'vue'; import { h, reactive, ref } from 'vue';
import { message, messageBox } from '@/utils/message'; import { message, messageBox } from '@/utils/message';
import type { FormItemProps } from '@/views/system/adminUser/utils/types'; import type { FormItemProps } from '@/views/system/adminUser/utils/types';
@ -16,8 +16,11 @@ import { useUserStore } from '@/store/system/user';
const adminUserStore = useAdminUserStore(); const adminUserStore = useAdminUserStore();
const userStore = useUserStore(); const userStore = useUserStore();
// 表单Ref
const formRef = ref(); const formRef = ref();
// 剪裁头像的Ref
const cropRef = ref(); const cropRef = ref();
// 分配角色的Ref
const assignRolesRef = ref(); const assignRolesRef = ref();
// 上传头像信息 // 上传头像信息
const avatarInfo = ref(); const avatarInfo = ref();
@ -28,6 +31,8 @@ const restPasswordForm = reactive({
userId: void 0, userId: void 0,
password: '', password: '',
}); });
// 批量删除id列表
export const deleteIds = ref([]);
/** /**
* * * *
@ -137,6 +142,23 @@ export const onDelete = async (row: any) => {
await onSearch(); await onSearch();
}; };
/**
* *
*/
export const onDeleteBatch = async () => {
// 是否确认删除
const result = await messageBox({
title: $t('confirm_delete'),
showMessage: false,
confirmMessage: undefined,
cancelMessage: $t('cancel_delete'),
});
if (!result) return;
// 删除数据
await adminUserStore.deleteAdminUser(deleteIds.value);
await onSearch();
};
/** /**
* * * *
* @param row * @param row

View File

@ -24,3 +24,11 @@ export interface FormItemProps {
export interface FormProps { export interface FormProps {
formInline: FormItemProps; formInline: FormItemProps;
} }
// 树形结构
export interface Tree {
id: number;
deptName: string;
highlight?: boolean;
children?: Tree[];
}

View File

@ -1,6 +1,6 @@
import { addDialog } from '@/components/BaseDialog/index'; import { addDialog } from '@/components/BaseDialog/index';
import DeptDialog from '@/views/system/dept/dept-dialog.vue'; import DeptDialog from '@/views/system/dept/dept-dialog.vue';
import { useDeptStore } from '@/store/system/dept.ts'; import { useDeptStore } from '@/store/system/dept';
import { h, ref } from 'vue'; import { h, ref } from 'vue';
import { messageBox } from '@/utils/message'; import { messageBox } from '@/utils/message';
import type { FormItemProps } from '@/views/system/dept/utils/types'; import type { FormItemProps } from '@/views/system/dept/utils/types';

View File

@ -27,8 +27,6 @@ export const rules = reactive({
powerCode: [{ required: true, message: `${$t('input')}${$t('power_powerCode')}`, trigger: 'blur' }], powerCode: [{ required: true, message: `${$t('input')}${$t('power_powerCode')}`, trigger: 'blur' }],
// 权限名称 // 权限名称
powerName: [{ required: true, message: `${$t('input')}${$t('power_powerName')}`, trigger: 'blur' }], powerName: [{ required: true, message: `${$t('input')}${$t('power_powerName')}`, trigger: 'blur' }],
// 请求路径
requestUrl: [{ required: true, message: `${$t('input')}${$t('power_requestUrl')}`, trigger: 'blur' }],
}); });
// 权限树形结构props // 权限树形结构props

View File

@ -5,22 +5,24 @@ import Check from '@iconify-icons/ep/check';
import { computed, nextTick, onMounted, ref, watch } from 'vue'; import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { delay, getKeyList, handleTree, subBefore, useResizeObserver } from '@pureadmin/utils'; import { delay, getKeyList, handleTree, subBefore, useResizeObserver } from '@pureadmin/utils';
import { contentRef, currentRow, onMenuPowerClick, powerTreeIsShow, powerTreeRef, tableRef } from '@/views/system/role/utils/hooks'; import { contentRef, currentRow, onMenuPowerClick, powerTreeIsShow, powerTreeRef, tableRef } from '@/views/system/role/utils/hooks';
import { message } from '@/utils/message';
import { usePowerStore } from '@/store/system/power'; import { usePowerStore } from '@/store/system/power';
import { powerCascadeProps } from '@/views/system/power/utils/columns'; import { powerCascadeProps } from '@/views/system/power/utils/columns';
import { useRoleStore } from '@/store/system/role';
const powerStore = usePowerStore();
const roleStore = useRoleStore();
// //
const isExpandAll = ref(false); const isExpandAll = ref(false);
// //
const isSelectAll = ref(false); const isSelectAll = ref(false);
const isLinkage = ref(false); const isLinkage = ref(true);
// //
const treeHeight = ref(); const treeHeight = ref();
// //
const treeSearchValue = ref(); const treeSearchValue = ref();
// id // id
const treeIds = ref([]); const treeIds = ref([]);
const powerStore = usePowerStore(); //
const datalist = computed(() => handleTree(powerStore.allPowerList)); const datalist = computed(() => handleTree(powerStore.allPowerList));
/** /**
@ -34,11 +36,17 @@ const getAllPowers = async () => {
/** /**
* 菜单权限-保存 * 菜单权限-保存
*/ */
const onSave = () => { const onSave = async () => {
//
const { id, description } = currentRow.value; const { id, description } = currentRow.value;
// id const powerIds = powerTreeRef.value.getCheckedKeys();
console.log(id, powerTreeRef.value.getCheckedKeys()); const data = { roleId: id, powerIds, description };
message(`${description} 权限修改成功`, { type: 'success' });
//
const result = await roleStore.assignPowersToRole(data);
if (!result) return;
currentRow.value = null;
powerTreeIsShow.value = false;
}; };
/** /**
@ -46,7 +54,7 @@ const onSave = () => {
* @param query * @param query
* @param node * @param node
*/ */
const filterMethod = (query: string, node) => node.powerName!.includes(query); const filterMethod = (query: string, node: any) => node.powerName!.includes(query);
/** /**
* * 菜单搜索 * * 菜单搜索

View File

@ -6,6 +6,7 @@ import { messageBox } from '@/utils/message';
import type { FormItemProps } from '@/views/system/role/utils/types'; import type { FormItemProps } from '@/views/system/role/utils/types';
import { $t } from '@/plugins/i18n'; import { $t } from '@/plugins/i18n';
import { fetchGetPowerListByRoleId } from '@/api/v1/power'; import { fetchGetPowerListByRoleId } from '@/api/v1/power';
import { isAllEmpty } from '@pureadmin/utils';
// 表格ref // 表格ref
export const tableRef = ref(); export const tableRef = ref();
@ -131,10 +132,14 @@ export const onDeleteBatch = async () => {
*/ */
export const onMenuPowerClick = async (row: any) => { export const onMenuPowerClick = async (row: any) => {
const { id } = row; const { id } = row;
if (isAllEmpty(id)) {
currentRow.value = null;
powerTreeIsShow.value = false;
} else {
currentRow.value = row; currentRow.value = row;
powerTreeIsShow.value = true; powerTreeIsShow.value = true;
const { data, code } = await fetchGetPowerListByRoleId({ id }); const { data } = await fetchGetPowerListByRoleId({ id });
if (code === 200) {
powerTreeRef.value.setCheckedKeys(data); powerTreeRef.value.setCheckedKeys(data);
} }
}; };