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-09-02 17:35:37 +08:00
|
|
|
|
<el-form-item label="类型" prop="type">
|
|
|
|
|
<el-select v-model="form.type" placeholder="请选择类型">
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in options"
|
|
|
|
|
:key="item.value"
|
|
|
|
|
:label="item.label"
|
|
|
|
|
:value="item.value"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item
|
|
|
|
|
v-show="form.type === 2 || form.type === 3"
|
|
|
|
|
label="服务平台"
|
|
|
|
|
prop="servicePlatformId"
|
|
|
|
|
>
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="form.servicePlatformId"
|
|
|
|
|
placeholder="请选择服务平台"
|
|
|
|
|
multiple
|
|
|
|
|
@change="fnGetCompanyOptions"
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in servicePlatformOptions"
|
|
|
|
|
:key="item.id"
|
|
|
|
|
:label="item.serviceName"
|
|
|
|
|
:value="item.id"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item v-show="form.type === 3" label="企业" prop="companyId">
|
|
|
|
|
<el-select v-model="form.companyId" multiple placeholder="请选择类型">
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in companyOptions"
|
|
|
|
|
:key="item.id"
|
|
|
|
|
:label="`${item.companyName}(${item.servicePlatformName})`"
|
|
|
|
|
:value="item.id"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</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";
|
2025-09-02 17:35:37 +08:00
|
|
|
|
import { nextTick, ref, watchEffect, watch } from "vue";
|
2025-06-10 09:31:15 +08:00
|
|
|
|
import {
|
|
|
|
|
getRouteList,
|
|
|
|
|
setRoleAdd,
|
|
|
|
|
setRoleEdit,
|
2025-09-02 17:35:37 +08:00
|
|
|
|
getBusServicePlatformListAllName,
|
|
|
|
|
getBusCompanyInfoListAllName,
|
2025-06-10 09:31:15 +08:00
|
|
|
|
} 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" },
|
|
|
|
|
],
|
2025-09-02 17:35:37 +08:00
|
|
|
|
type: [{ required: true, message: "类型不能为空", trigger: "change" }],
|
|
|
|
|
};
|
|
|
|
|
const options = [
|
|
|
|
|
{ label: "系统角色", value: 1 },
|
|
|
|
|
{ label: "服务平台角色", value: 2 },
|
|
|
|
|
{ label: "企业角色", value: 3 },
|
|
|
|
|
];
|
|
|
|
|
const servicePlatformOptions = ref([]);
|
|
|
|
|
const companyOptions = ref([]);
|
|
|
|
|
watch(
|
|
|
|
|
() => form.value.type,
|
|
|
|
|
async (val) => {
|
|
|
|
|
if (val !== 1) await fnGetServicePlatformOptions();
|
|
|
|
|
if (val === 3) await fnGetCompanyOptions();
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
const fnGetServicePlatformOptions = async () => {
|
|
|
|
|
if (servicePlatformOptions.value.length === 0) {
|
|
|
|
|
const { data } = await getBusServicePlatformListAllName();
|
|
|
|
|
servicePlatformOptions.value = data;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const fnGetCompanyOptions = async () => {
|
|
|
|
|
if (form.value.type !== 3 || form.value.servicePlatformId.length === 0)
|
|
|
|
|
return;
|
|
|
|
|
const { data } = await getBusCompanyInfoListAllName({
|
|
|
|
|
servicePlatformIds: form.value.servicePlatformId.join(","),
|
|
|
|
|
});
|
|
|
|
|
companyOptions.value = data;
|
2025-06-10 09:31:15 +08:00
|
|
|
|
};
|
|
|
|
|
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-09-02 17:35:37 +08:00
|
|
|
|
const servicePlatformId = form.value.servicePlatformId.join(",");
|
|
|
|
|
const companyId = form.value.companyId.join(",");
|
2025-06-10 09:31:15 +08:00
|
|
|
|
if (props.type === "add") {
|
|
|
|
|
await setRoleAdd({
|
|
|
|
|
...form.value,
|
|
|
|
|
menuIdList: [...checkedKeys, ...halfCheckedKeys],
|
|
|
|
|
roleId: undefined,
|
2025-09-02 17:35:37 +08:00
|
|
|
|
servicePlatformId,
|
|
|
|
|
companyId,
|
2025-06-10 09:31:15 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
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>
|