docking-vue/src/views/system_management/role/components/add.vue

149 lines
4.0 KiB
Vue
Raw Normal View History

2025-06-10 09:31:15 +08:00
<template>
<el-dialog
v-model="visible"
:title="type === 'edit' ? '修改' : '新增'"
:before-close="fnClose"
>
<el-form ref="formRef" :rules="rules" :model="form" label-width="110px">
<el-form-item label="名称" prop="roleName">
<el-input v-model="form.roleName" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
type="textarea"
:autosize="{ minRows: 1 }"
placeholder="请输入备注"
/>
</el-form-item>
2025-06-27 14:01:42 +08:00
<el-form-item v-if="form.parentId !== '0'" label="菜单" prop="menuIdList">
2025-06-10 09:31:15 +08:00
<el-tree
ref="treeRef"
node-key="menuId"
:data="menusAll"
:props="{
label: 'name',
children: 'list',
}"
show-checkbox
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"></el-button>
</template>
</el-dialog>
</template>
<script setup>
import { debounce } from "throttle-debounce";
2025-06-27 14:01:42 +08:00
import useForm from "@/hooks/useForm.js";
2025-06-10 09:31:15 +08:00
import { ElMessage } from "element-plus";
import { nextTick, ref, watchEffect } from "vue";
import {
getRouteList,
setRoleAdd,
setRoleEdit,
} from "@/request/system_management.js";
const props = defineProps({
type: {
type: String,
required: true,
},
});
const emits = defineEmits(["getData"]);
const visible = defineModel("visible", { type: Boolean, required: true });
const form = defineModel("form", { type: Object, required: true });
2025-06-27 14:01:42 +08:00
const { formRef, validate, reset } = useForm();
2025-06-10 09:31:15 +08:00
const treeRef = ref(null);
const menusAll = ref([]);
const rules = {
roleName: [
{ required: true, message: "名称不能为空", trigger: "blur" },
{ min: 2, max: 30, message: "长度在2到30个字符", trigger: "blur" },
],
};
const fnGetData = async () => {
const resData = await getRouteList({ parentId: 0 });
menusAll.value = fnConversion(resData.menuList);
};
const fnConversion = (menuList) => {
for (let i = 0; i < menuList.length; i++) {
menuList[i].meta = JSON.parse(menuList[i].meta);
if (menuList[i].type === 1) {
2025-06-27 14:01:42 +08:00
menuList[i].name = (menuList[i].name || "首页") + "(页面)";
2025-06-10 09:31:15 +08:00
}
if (menuList[i].type === 2) {
menuList[i].name = menuList[i].name + "(按钮)";
}
if (menuList[i].list.length > 0) {
fnConversion(menuList[i].list);
}
}
return menuList;
};
const fnClose = () => {
2025-06-27 14:01:42 +08:00
reset();
2025-06-10 09:31:15 +08:00
visible.value = false;
2025-06-27 14:01:42 +08:00
treeRef.value?.setCheckedKeys([]);
2025-06-10 09:31:15 +08:00
};
watchEffect(async () => {
if (visible.value) {
await fnGetData();
await nextTick();
let checkedKeys = [];
form.value.menuIdList.forEach((item) => {
checkedKeys = fnGetChecked(item, menusAll.value, checkedKeys);
});
2025-06-27 14:01:42 +08:00
treeRef.value?.setCheckedKeys(checkedKeys);
2025-06-10 09:31:15 +08:00
}
});
const fnGetChecked = (menuId, menusAll, checkedKeys) => {
for (let i = 0; i < menusAll.length; i++) {
if (menuId === menusAll[i].menuId) {
if (menusAll[i].list.length === 0) {
checkedKeys.push(menusAll[i].menuId);
break;
}
} else {
if (menusAll[i].list.length > 0) {
fnGetChecked(menuId, menusAll[i].list, checkedKeys);
}
}
}
return checkedKeys;
};
const fnSubmit = debounce(
1000,
async () => {
await validate();
2025-06-27 14:01:42 +08:00
const checkedKeys = treeRef.value?.getCheckedKeys() || [];
const halfCheckedKeys = treeRef.value?.getHalfCheckedKeys() || [];
2025-06-10 09:31:15 +08:00
if (props.type === "add") {
await setRoleAdd({
...form.value,
menuIdList: [...checkedKeys, ...halfCheckedKeys],
roleId: undefined,
});
}
if (props.type === "edit")
await setRoleEdit({
...form.value,
menuIdList: [...checkedKeys, ...halfCheckedKeys],
});
ElMessage.success("操作成功");
fnClose();
emits("getData");
},
{ atBegin: true }
);
</script>
<style lang="scss" scoped>
:deep(.el-tree) {
width: 100%;
}
</style>