From d01af540b961aaaa17f68e70374f78a6695219cc Mon Sep 17 00:00:00 2001
From: wupengfei <834520024@qq.com>
Date: 星期一, 17 十一月 2025 10:25:32 +0800
Subject: [PATCH] fix: bug
---
src/views/Permission/components/dialogAuthorizeV2.vue | 357 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 357 insertions(+), 0 deletions(-)
diff --git a/src/views/Permission/components/dialogAuthorizeV2.vue b/src/views/Permission/components/dialogAuthorizeV2.vue
new file mode 100644
index 0000000..aad24be
--- /dev/null
+++ b/src/views/Permission/components/dialogAuthorizeV2.vue
@@ -0,0 +1,357 @@
+<template>
+ <ProDialog
+ class="custom-dialog"
+ width="55%"
+ :title="dialogTitle"
+ v-model="visible"
+ :top="'10vh'"
+ :close-on-click-modal="false"
+ :close-on-press-escape="false"
+ >
+ <div class="authorize-wrapper">
+ <div class="container-wrapper left-wrapper">
+ <el-scrollbar>
+ <el-tree
+ class="companyTree"
+ :data="menusTree"
+ :props="{
+ children: 'children',
+ label: 'name',
+ }"
+ node-key="id"
+ :expand-on-click-node="false"
+ :highlight-current="true"
+ check-strictly
+ default-expand-all
+ show-checkbox
+ ref="moduleTree"
+ :default-checked-keys="defaultCheckedKeys"
+ @check="handleModuleCheck"
+ >
+ <template #default="{ node }">
+ <div class="custom-tree-node">
+ <type-tip :isMenu="node.data.type === EnumMenuType.Menu" />
+ <div class="node-text" @click="handleSelectModule(node.data)">
+ {{ node.label }}
+ </div>
+ </div>
+ </template>
+ </el-tree>
+ </el-scrollbar>
+ </div>
+
+ <div class="container-wrapper">
+ <div class="type-wrapper">
+ {{ SubModuleTitle[SubModuleType.PageButton] }}
+ </div>
+ <el-scrollbar>
+ <el-tree
+ v-show="!!state.currentMenuId"
+ :data="[
+ {
+ name: '鍏ㄩ��',
+ id: 'pageButtonAll',
+ children: menuPageButtons,
+ },
+ ]"
+ :props="{
+ children: 'children',
+ label: 'name',
+ }"
+ node-key="id"
+ :expand-on-click-node="false"
+ :highlight-current="true"
+ default-expand-all
+ show-checkbox
+ ref="pageButtonTree"
+ :default-checked-keys="defaultCheckedKeys"
+ @check="handlePageButtonCheck"
+ >
+ <template #default="{ node }">
+ <div class="custom-tree-node">
+ <span>{{ node.label }}</span>
+ </div>
+ </template>
+ </el-tree>
+ </el-scrollbar>
+ </div>
+
+ <div class="container-wrapper">
+ <div class="type-wrapper">
+ {{ SubModuleTitle[SubModuleType.DataButton] }}
+ </div>
+ <el-scrollbar>
+ <el-tree
+ v-show="!!state.currentMenuId"
+ :data="[
+ {
+ name: '鍏ㄩ��',
+ id: 'dataButtonAll',
+ children: menuDataButtons,
+ },
+ ]"
+ :props="{
+ children: 'children',
+ label: 'name',
+ }"
+ node-key="id"
+ :expand-on-click-node="false"
+ :highlight-current="true"
+ default-expand-all
+ show-checkbox
+ ref="dataButtonTree"
+ :default-checked-keys="defaultCheckedKeys"
+ @check="handleDataButtonCheck"
+ >
+ <template #default="{ node }">
+ <div class="custom-tree-node">
+ <span>{{ node.label }}</span>
+ </div>
+ </template>
+ </el-tree>
+ </el-scrollbar>
+ </div>
+
+ <div class="container-wrapper">
+ <div class="type-wrapper">
+ {{ SubModuleTitle[SubModuleType.Column] }}
+ </div>
+ <el-scrollbar>
+ <el-tree
+ v-show="!!state.currentMenuId"
+ :data="[
+ {
+ name: '鍏ㄩ��',
+ id: 'dataColumnAll',
+ children: menuFields,
+ },
+ ]"
+ :props="{
+ children: 'children',
+ label: 'name',
+ }"
+ node-key="id"
+ :expand-on-click-node="false"
+ :highlight-current="true"
+ default-expand-all
+ show-checkbox
+ ref="dataColumnTree"
+ :default-checked-keys="defaultCheckedKeys"
+ @check="handleDataColumnCheck"
+ >
+ <template #default="{ node }">
+ <div class="custom-tree-node">
+ <span>{{ node.label }}</span>
+ </div>
+ </template>
+ </el-tree>
+ </el-scrollbar>
+ </div>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="visible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleConfirm" class="btn-submit"> 纭畾 </el-button>
+ </span>
+ </template>
+ </ProDialog>
+</template>
+
+<script setup lang="ts">
+import { Message } from '@bole-core/core';
+import { SubModuleType, SubModuleTitle, EnumMenuType } from '@/constants';
+import { getTree, treeEach } from '@/utils';
+import { TreeInstance } from 'element-plus';
+import { ProDialog } from '@bole-core/components';
+import { useMenus, useMenu } from '@/hooks';
+import data from '@iconify-icons/ep/tickets';
+
+const TypeTip = defineComponent({
+ name: 'TypeTip',
+ props: ['isMenu'],
+ render() {
+ const { isMenu } = this;
+ const tipText = isMenu ? `鑿滃崟` : '椤甸潰';
+ return h(
+ 'span',
+ {
+ class: 'tip-text',
+ style: {
+ color: '#EB6100',
+ },
+ },
+ '[' + tipText + ']'
+ );
+ },
+});
+
+type Props = {
+ authorizeType: 'Role' | 'User';
+};
+
+const props = withDefaults(defineProps<Props>(), {});
+
+const visible = defineModel({ type: Boolean });
+
+type Form = {
+ title?: string;
+ detail: API.GetRoleQueryResult;
+};
+
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+ (e: 'onConfirm', selectedMenuIds: string[]): void;
+ (e: 'onCancel'): void;
+}>();
+
+type CheckedResourceItem = {
+ resourceId: string;
+ menuId: string;
+ resourceType: SubModuleType;
+};
+
+const state = reactive({
+ currentMenuId: '',
+ selectedMenuIds: [] as string[],
+});
+
+const defaultCheckedKeys = computed(() => Array.from(state.selectedMenuIds));
+
+watch(visible, (newVal) => {
+ if (newVal) {
+ state.currentMenuId = '';
+ const menuIds = form.value.detail?.menuIds ?? [];
+ // menuIds.forEach((id) => state.selectedMenuIds.add(id));
+ state.selectedMenuIds = [...menuIds];
+ }
+});
+
+const dialogTitle = computed(() =>
+ props.authorizeType === 'Role' ? '瑙掕壊鍔熻兘鎺堟潈' : '璐﹀彿鍔熻兘鎺堟潈'
+);
+
+const moduleTree = useTemplateRef<TreeInstance>('moduleTree');
+const pageButtonTree = useTemplateRef<TreeInstance>('pageButtonTree');
+const dataButtonTree = useTemplateRef<TreeInstance>('dataButtonTree');
+const dataColumnTree = useTemplateRef<TreeInstance>('dataColumnTree');
+
+type TreeRef = ReturnType<typeof useTemplateRef<TreeInstance>>;
+
+const { menusTree, getMenuById } = useMenus({
+ params: computed(() => ({
+ userType: form.value.detail?.userType,
+ clientType: form.value.detail?.clientType,
+ enterpriseType: form.value.detail?.enterpriseType,
+ roleId: form.value.detail?.id,
+ })),
+ enabled: computed(() => !!form.value.detail?.id),
+});
+
+const { menuFields, menuPageButtons, menuDataButtons } = useMenu({
+ params: computed(() => ({
+ id: state.currentMenuId,
+ roleId: form.value.detail?.id,
+ })),
+ enabled: computed(() => !!state.currentMenuId),
+});
+
+function handleSelectModule(menu: API.GetMenusQueryResultItem) {
+ state.currentMenuId = menu.id;
+}
+
+function handleModuleCheck(data, params) {
+ handleCheck(data, params, moduleTree);
+}
+
+function handlePageButtonCheck(data, params) {
+ handleCheck(data, params, pageButtonTree);
+}
+
+function handleDataButtonCheck(data, params) {
+ handleCheck(data, params, dataButtonTree);
+}
+
+function handleDataColumnCheck(data, params) {
+ handleCheck(data, params, dataColumnTree);
+}
+
+function handleCheck(data, params, treeRef: TreeRef) {
+ const dataMap = {};
+ treeEach(
+ [treeRef.value.store.root],
+ (node) => (dataMap[node.key] = node),
+ (node) => node.childNodes
+ );
+
+ const uncachedCheckedKeys = params.checkedKeys.filter(
+ (item) => !['pageButtonAll', 'dataButtonAll', 'dataColumnAll'].includes(item)
+ );
+ const cachedKeys = state.selectedMenuIds.filter(
+ (item) => !(item in dataMap) && !uncachedCheckedKeys.includes(item)
+ );
+ state.selectedMenuIds = cachedKeys.concat(uncachedCheckedKeys);
+}
+
+function handleConfirm() {
+ emit('onConfirm', state.selectedMenuIds);
+}
+</script>
+
+<style lang="scss" scoped>
+:deep(.custom-dialog) {
+ min-width: 900px;
+}
+
+.authorize-wrapper {
+ display: flex;
+
+ height: 500px;
+ border-bottom: 2px solid #f5f5f5;
+ background: #dddddd;
+
+ .container-wrapper {
+ width: calc(25%);
+ border-right: 2px solid #f5f5f5;
+ // margin-right: 7px;
+ background: #ffffff;
+
+ .type-wrapper {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ padding: 10px 16px;
+ border-bottom: 2px solid #f5f5f5;
+ color: #333333;
+ }
+
+ &:last-of-type {
+ margin-right: 0px;
+ }
+
+ &.left-wrapper {
+ margin-right: 7px;
+ padding-top: 10px;
+ width: calc(35% - 7px);
+
+ :deep(.el-scrollbar) {
+ width: 100%;
+ height: 98%;
+ }
+ }
+
+ :deep(.el-scrollbar) {
+ width: 100%;
+ height: calc(98% - 43px);
+
+ .el-scrollbar__wrap {
+ overflow: auto;
+
+ .custom-tree-node {
+ display: flex;
+ }
+ }
+ }
+ }
+}
+</style>
--
Gitblit v1.9.1