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();
message(error.message, { type: 'error' });
return error;
},
);

View File

@ -12,7 +12,7 @@ export const fetchGetPowerList = (data: any) => {
* ---id获取权限内容
*/
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 });
};
/**
* ---
*/
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 => {
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 { 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 { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';
@ -70,6 +70,15 @@ export const useRoleStore = defineStore('roleStore', {
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;
}
// 消息盒
interface MessageBox {
message: string | undefined;
title: string | undefined;
confirmMessage: any;
cancelMessage: any;
showMessage: boolean;
}
/** 用法非常简单,参考 src/views/components/message/index.vue 文件 */
/**
@ -101,7 +92,7 @@ export const storeMessage = (result: BaseResult<any>) => {
return true;
};
const defaultBoxOption: MessageBox = {
const defaultBoxOption: any = {
showMessage: false,
message: '',
title: '',
@ -114,7 +105,7 @@ const defaultBoxOption: MessageBox = {
* @param type
* @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, {
confirmButtonText: '确认',
cancelButtonText: '返回',

View File

@ -95,16 +95,14 @@ defineExpose({ formRef });
<!-- 用户简介 -->
<re-col :sm="24" :value="24" :xs="24">
<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>
</re-col>
<!-- 用户状态 -->
<re-col :sm="24" :value="12" :xs="24">
<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-on-color: #ff4949; --el-switch-off-color: #13ce66" />
<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-form-item>
</re-col>
</el-row>

View File

@ -4,7 +4,19 @@ import { columns } from '@/views/system/adminUser/utils/columns';
import PureTableBar from '@/components/TableBar/src/bar';
import AddFill from '@iconify-icons/ri/add-circle-line';
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 EditPen from '@iconify-icons/ep/edit-pen';
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 Airplane from '@/assets/svg/airplane.svg';
import { useDeptStore } from '@/store/system/dept';
import { FormInstance } from 'element-plus';
const tableRef = ref();
const formRef = ref();
@ -29,6 +42,15 @@ const adminUserStore = useAdminUserStore();
const deptStore = useDeptStore();
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
*/
const resetForm = async formEl => {
const resetForm = async (formEl: FormInstance) => {
if (!formEl) return;
formEl.resetFields();
await onSearch();
};
/**
* * 加载部门列表
* @param deptName
* * 选择多行
* @param rows
*/
const onSearchDept = async (deptName: string) => {
deptStore.loading = true;
await deptStore.getAllDeptList();
deptStore.loading = false;
const onSelectionChange = (rows: Array<any>) => {
deleteIds.value = rows.map((row: any) => row.id);
};
/**
@ -71,7 +91,7 @@ const onSearchDept = async (deptName: string) => {
* 搜索当前用户属于哪个部门
* @param dept
*/
const onTreeSelect = dept => {
const onTreeSelect = (dept: any) => {
console.log(dept);
};
@ -134,6 +154,11 @@ onMounted(() => {
<PureTableBar :columns="columns" title="用户信息" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
<template #buttons>
<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 v-slot="{ size, dynamicColumns }">
@ -154,6 +179,7 @@ onMounted(() => {
showOverflowTooltip
table-layout="auto"
@page-size-change="onPageSizeChange"
@selection-change="onSelectionChange"
@page-current-change="onCurrentPageChange"
>
<!-- 显示头像 -->
@ -169,10 +195,8 @@ onMounted(() => {
class="ml-2"
inactive-text="正常"
inline-prompt
style="
--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66"
@change="updateUserStatus(row)"
style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66"
@click="updateUserStatus(row)"
/>
</template>

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import { addDialog } from '@/components/BaseDialog/index';
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 { message, messageBox } from '@/utils/message';
import type { FormItemProps } from '@/views/system/adminUser/utils/types';
@ -16,8 +16,11 @@ import { useUserStore } from '@/store/system/user';
const adminUserStore = useAdminUserStore();
const userStore = useUserStore();
// 表单Ref
const formRef = ref();
// 剪裁头像的Ref
const cropRef = ref();
// 分配角色的Ref
const assignRolesRef = ref();
// 上传头像信息
const avatarInfo = ref();
@ -28,6 +31,8 @@ const restPasswordForm = reactive({
userId: void 0,
password: '',
});
// 批量删除id列表
export const deleteIds = ref([]);
/**
* *
@ -137,6 +142,23 @@ export const onDelete = async (row: any) => {
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

View File

@ -24,3 +24,11 @@ export interface FormItemProps {
export interface FormProps {
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 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 { messageBox } from '@/utils/message';
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' }],
// 权限名称
powerName: [{ required: true, message: `${$t('input')}${$t('power_powerName')}`, trigger: 'blur' }],
// 请求路径
requestUrl: [{ required: true, message: `${$t('input')}${$t('power_requestUrl')}`, trigger: 'blur' }],
});
// 权限树形结构props

View File

@ -5,22 +5,24 @@ import Check from '@iconify-icons/ep/check';
import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { delay, getKeyList, handleTree, subBefore, useResizeObserver } from '@pureadmin/utils';
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 { powerCascadeProps } from '@/views/system/power/utils/columns';
import { useRoleStore } from '@/store/system/role';
const powerStore = usePowerStore();
const roleStore = useRoleStore();
//
const isExpandAll = ref(false);
//
const isSelectAll = ref(false);
const isLinkage = ref(false);
const isLinkage = ref(true);
//
const treeHeight = ref();
//
const treeSearchValue = ref();
// id
const treeIds = ref([]);
const powerStore = usePowerStore();
//
const datalist = computed(() => handleTree(powerStore.allPowerList));
/**
@ -34,11 +36,17 @@ const getAllPowers = async () => {
/**
* 菜单权限-保存
*/
const onSave = () => {
const onSave = async () => {
//
const { id, description } = currentRow.value;
// id
console.log(id, powerTreeRef.value.getCheckedKeys());
message(`${description} 权限修改成功`, { type: 'success' });
const powerIds = powerTreeRef.value.getCheckedKeys();
const data = { roleId: id, powerIds, description };
//
const result = await roleStore.assignPowersToRole(data);
if (!result) return;
currentRow.value = null;
powerTreeIsShow.value = false;
};
/**
@ -46,7 +54,7 @@ const onSave = () => {
* @param query
* @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 { $t } from '@/plugins/i18n';
import { fetchGetPowerListByRoleId } from '@/api/v1/power';
import { isAllEmpty } from '@pureadmin/utils';
// 表格ref
export const tableRef = ref();
@ -131,10 +132,14 @@ export const onDeleteBatch = async () => {
*/
export const onMenuPowerClick = async (row: any) => {
const { id } = row;
if (isAllEmpty(id)) {
currentRow.value = null;
powerTreeIsShow.value = false;
} else {
currentRow.value = row;
powerTreeIsShow.value = true;
const { data, code } = await fetchGetPowerListByRoleId({ id });
if (code === 200) {
const { data } = await fetchGetPowerListByRoleId({ id });
powerTreeRef.value.setCheckedKeys(data);
}
};