Files
orico-officialWebsite-ts-admin/src/views/userManagement/role/index1.vue

317 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="table-box">
<div style="padding-bottom: 16px">
<el-button type="primary" @click="handleAdd"> 添加 </el-button>
</div>
<ProTable
ref="proTableRef"
:formData="dataStore.formData"
:columns="dataStore.columns"
:request-api="getRoleListApi"
:init-param="dataStore.initParam"
>
<template #operation="scope">
<el-button size="small" type="primary" @click="handleBtnClick('编辑', scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleBtnClick('删除', scope.row)">删除</el-button>
</template>
</ProTable>
<el-drawer
v-model="dataStore.visible"
:show-close="true"
:size="600"
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="handleBeforeClone"
destroy-on-close
>
<template #header="{ titleId, titleClass }">
<h4 :id="titleId" :class="titleClass">{{ dataStore.title }}</h4>
</template>
<div>
<rulesForm
:ruleForm="dataStore.editRuleForm"
:formData="dataStore.editFormData"
:rules="dataStore.rules"
:indeterminate="dataStore.isIndeterminate"
ref="formRef"
>
</rulesForm>
<div style="margin-left: 65px; font-size: 14px; color: #606266">
<div style="display: flex; align-items: center; margin-bottom: 10px">
<span style="margin-right: 10px">权限分配:</span>
<el-checkbox v-model="dataStore.allCheck" @change="handleAllCheckChange" label="全选" size="large" />
<!-- <el-checkbox v-model="dataStore.allCheck" @change="handleAllCheckChange" label="全选" size="large" /> -->
</div>
<el-tree
ref="treeRef"
style="max-width: 600px"
:data="dataStore.treeData"
show-checkbox
node-key="id"
highlight-current
:props="defaultProps"
@check-change="handleTreeCheckChange"
/>
</div>
</div>
<template #footer>
<div style="flex: auto">
<el-button @click="handleResetClick">重置</el-button>
<el-button type="primary" @click="handleConfirmClick">确认</el-button>
</div>
</template>
</el-drawer>
</div>
</template>
<script setup lang="ts" name="roleListIndex">
import ProTable from "@/components/ProTable/index.vue";
import rulesForm from "@/components/rulesForm/index.vue";
import { messageBox } from "@/utils/messageBox";
import { nextTick } from "vue";
import { useMsg } from "@/hooks/useMsg";
//列表接口
import {
getRoleListApi,
getRoleListDetailsApi,
getRoleListDelApi,
getRoleListEditUpApi,
getRoleListSaveApi
} from "@/api/modules/roleList";
//权限列表接口
import { getRoleMenusListApi } from "@/api/modules/webMenusList";
//深拷贝方法
import { cloneDeep } from "lodash-es";
//表格和搜索条件
import { RULE_FORM, FORM_DATA, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES } from "./constant/index";
// 组件引用
const proTableRef = ref<any>(null);
const formRef: any = ref(null);
const treeRef: any = ref(null);
const defaultProps = {
children: "children",
label: "title"
};
// 数据源
const dataStore = reactive<any>({
treeData: [], //权限树数据
allCheck: false, //全选框状态
title: "添加角色", //抽屉标题
columns: COLUMNS, //列表配置项
rules: cloneDeep(RULES), //表单验证规则
editRuleForm: cloneDeep(EDIT_RULE_FORM), //编辑表单数据
editFormData: cloneDeep(EDIT_FORM_DATA), //表单配置项
initParam: cloneDeep(RULE_FORM), //初始化搜索条件
ruleForm: cloneDeep(RULE_FORM), //搜索参数
formData: FORM_DATA, //搜索配置项
selectedMenuIds: [], //选中的菜单ID含全选和半选
isIndeterminate: false, //全选框半选样式
visible: false, //抽屉显示状态
selectRow: {} //当前选中行数据
});
// 处理全选框状态变化
const handleAllCheckChange = (checked: any) => {
const allNodeKeys = getAllNodeKeys(dataStore.treeData);
if (checked) {
// 全选时选中所有节点(包括父节点)
treeRef.value.setCheckedKeys(allNodeKeys);
} else {
// 取消全选时清空所有选中
treeRef.value.setCheckedKeys([]);
}
};
// 获取所有节点的ID
const getAllNodeKeys = (data: any[]) => {
let keys: number[] = [];
data.forEach(item => {
keys.push(item.id);
if (item.children && item.children.length > 0) {
keys = keys.concat(getAllNodeKeys(item.children));
}
});
return keys;
};
// 处理树节点选中状态变化
const handleTreeCheckChange = () => {
const allNodeKeys = getAllNodeKeys(dataStore.treeData);
// 获取全选节点ID包括父节点全选和叶子节点选中
const checkedKeys = treeRef.value.getCheckedKeys();
// 获取半选节点ID父节点部分子节点选中
const halfCheckedKeys = treeRef.value.getHalfCheckedKeys();
// 合并全选和半选ID并去重
const allSelectedKeys = [...new Set([...checkedKeys, ...halfCheckedKeys])];
// 更新全选框状态
if (allSelectedKeys.length === allNodeKeys.length) {
dataStore.allCheck = true;
dataStore.isIndeterminate = false;
} else if (allSelectedKeys.length === 0) {
dataStore.allCheck = false;
dataStore.isIndeterminate = false;
} else {
dataStore.allCheck = false;
dataStore.isIndeterminate = true;
}
// 保存所有选中的菜单ID含半选父节点
dataStore.selectedMenuIds = allSelectedKeys.map((id: number) => ({ menu_id: id }));
};
// 抽屉确认按钮
const handleConfirmClick = () => {
if (!formRef.value?.ruleFormRef) return;
formRef.value.ruleFormRef.validate((valid: boolean) => {
if (valid) {
dataStore.title === "添加角色" ? getRoleListSave() : getRoleListEditUp();
} else {
console.log("表单验证失败");
return false;
}
});
};
// 重置表单验证状态
const resetFields = () => {
if (formRef.value?.ruleFormRef) {
formRef.value.ruleFormRef.resetFields();
}
};
// 抽屉重置按钮
const handleResetClick = () => {
if (dataStore.title === "添加角色") {
resetFields();
// 重置树选择状态
treeRef.value?.setCheckedKeys([]);
dataStore.selectedMenuIds = [];
} else {
// 编辑时重新获取详情数据
getRoleListDetails(dataStore.editRuleForm.id);
}
};
// 打开添加抽屉
const handleAdd = () => {
dataStore.title = "添加角色";
dataStore.visible = true;
// 重置表单和树状态
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
resetFields();
nextTick(() => {
treeRef.value?.setCheckedKeys([]);
});
};
// 抽屉关闭前处理
const handleBeforeClone = () => {
dataStore.selectedMenuIds = [];
treeRef.value?.setCheckedKeys([]);
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
resetFields();
dataStore.visible = false;
};
// 编辑/删除按钮点击
const handleBtnClick = (type: string, row: any) => {
dataStore.selectRow = row;
if (type === "编辑") {
dataStore.visible = true;
dataStore.title = "编辑角色";
getRoleListDetails(row.id);
} else if (type === "删除") {
getRoleListDel(row.id);
}
};
// 删除角色
const getRoleListDel = (id: number) => {
messageBox("你确定要删除?", async () => {
const result = await getRoleListDelApi(id);
if (result?.code === 0) {
useMsg("success", result.msg);
proTableRef.value?.getTableList();
}
});
};
// 获取角色详情并回显
const getRoleListDetails = async (id: number) => {
const result = await getRoleListDetailsApi(id);
if (result?.code === 0) {
dataStore.editRuleForm = result.data;
// 提取后台返回的权限ID列表
const savedMenuIds = dataStore.editRuleForm.authorities.map((item: any) => item.menu_id);
nextTick(() => {
if (treeRef.value) {
// 筛选出所有叶子节点ID用于正确触发父节点半选状态
const leafIds: number[] = [];
const findLeafNodes = (nodes: any[]) => {
nodes.forEach(node => {
if (!node.children || node.children.length === 0) {
// 叶子节点且在保存的ID中才选中
if (savedMenuIds.includes(node.id)) {
leafIds.push(node.id);
}
} else {
findLeafNodes(node.children);
}
});
};
findLeafNodes(dataStore.treeData);
// 设置叶子节点选中状态,父节点会自动计算半选/全选
treeRef.value.setCheckedKeys(leafIds);
// 触发状态更新
handleTreeCheckChange();
}
});
}
};
// 保存新角色
const getRoleListSave = async () => {
const result = await getRoleListSaveApi({
...dataStore.editRuleForm,
menu_permission: JSON.stringify(dataStore.selectedMenuIds)
});
if (result?.code === 0) {
useMsg("success", result.msg);
dataStore.visible = false;
proTableRef.value?.getTableList();
}
};
// 更新角色信息
const getRoleListEditUp = async () => {
const result = await getRoleListEditUpApi({
...dataStore.editRuleForm,
menu_permission: JSON.stringify(dataStore.selectedMenuIds)
});
if (result?.code === 0) {
useMsg("success", result.msg);
dataStore.visible = false;
proTableRef.value?.getTableList();
}
};
// 获取权限树数据
const getMenusList = async () => {
const result = await getRoleMenusListApi();
if (result?.code === 0) {
dataStore.treeData = result.data;
console.log(result.data, "==============data===============");
}
};
// 初始化加载权限树
getMenusList();
</script>
<style scoped></style>