Преглед изворни кода

[Feat 0000] 对接煤矿级联选择器

houzekong пре 2 месеци
родитељ
комит
d90e6458a4
2 измењених фајлова са 202 додато и 201 уклоњено
  1. 183 184
      src/components/Container/src/AdaptiveContainer.vue
  2. 19 17
      src/store/modules/mine.ts

+ 183 - 184
src/components/Container/src/AdaptiveContainer.vue

@@ -6,201 +6,200 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
-import { debounce } from 'lodash-es';
-import { useAppStore } from '/@/store/modules/app';
-import { computed } from 'vue';
-
-// 类型定义
-interface AdaptiveOptions {
-  width?: number;
-  height?: number;
-  baseWidth?: number; // 设计稿基准宽度,用于REM计算
-  minScale?: number; // 最小缩放比例
-  maxScale?: number; // 最大缩放比例
-  debounceTime?: number; // 防抖时间(ms)
-  ratio?: number; // 宽高比
-  tolerance?: number; // 宽高比容忍度
-}
-
-interface ScaleInfo {
-  widthScale: number;
-  heightScale: number;
-  scale: number;
-}
-
-export default defineComponent({
-  name: 'AdaptiveContainer',
-  props: {
-    options: {
-      type: Object as () => AdaptiveOptions,
-      default: () => ({}),
+  import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
+  import { debounce } from 'lodash-es';
+  import { useAppStore } from '/@/store/modules/app';
+  import { computed } from 'vue';
+
+  // 类型定义
+  interface AdaptiveOptions {
+    width?: number;
+    height?: number;
+    baseWidth?: number; // 设计稿基准宽度,用于REM计算
+    minScale?: number; // 最小缩放比例
+    maxScale?: number; // 最大缩放比例
+    debounceTime?: number; // 防抖时间(ms)
+    ratio?: number; // 宽高比
+    tolerance?: number; // 宽高比容忍度
+  }
+
+  interface ScaleInfo {
+    widthScale: number;
+    heightScale: number;
+    scale: number;
+  }
+
+  export default defineComponent({
+    name: 'AdaptiveContainer',
+    props: {
+      options: {
+        type: Object as () => AdaptiveOptions,
+        default: () => ({}),
+      },
     },
-  },
-  setup(props) {
-    const appStore = useAppStore();
-    const containerRef = ref<HTMLElement | null>(null);
-    // const isReady = ref(false);
-
-    // 默认配置
-    const defaultOptions = ref<Required<AdaptiveOptions>>({
-      width: 1920,
-      height: 948,
-      baseWidth: 1920,
-      minScale: 0.5,
-      maxScale: 2,
-      debounceTime: 100,
-      ratio: 16 / 9,
-      tolerance: 0.1,
-    });
-
-    // 合并配置
-    const config = computed(() => {
-      return {
-        ...defaultOptions.value,
-        ...props.options,
+    setup(props) {
+      const appStore = useAppStore();
+      const containerRef = ref<HTMLElement | null>(null);
+      // const isReady = ref(false);
+
+      // 默认配置
+      const defaultOptions = ref<Required<AdaptiveOptions>>({
+        width: 1920,
+        height: 948,
+        baseWidth: 1920,
+        minScale: 0.5,
+        maxScale: 2,
+        debounceTime: 100,
+        ratio: 16 / 9,
+        tolerance: 0.1,
+      });
+
+      // 合并配置
+      const config = computed(() => {
+        return {
+          ...defaultOptions.value,
+          ...props.options,
+        };
+      });
+
+      // 设计稿尺寸
+      const designSize = computed(() => {
+        return {
+          width: config.value.width,
+          height: config.value.height,
+        };
+      });
+
+      /**
+       * 设置REM基准值
+       * @param baseSize 基准大小,默认18px
+       */
+      const setRem = (baseSize: number = 18): void => {
+        try {
+          const baseVal = baseSize / config.value.baseWidth;
+          const vW = window.innerWidth;
+          const rem = vW * baseVal;
+
+          // 设置全局缩放比例(如果有需要)
+          if (typeof window['$size'] !== 'number') {
+            Object.defineProperty(window, '$size', {
+              value: rem / 100,
+              writable: true,
+            });
+          } else {
+            window['$size'] = rem / 100;
+          }
+
+          // document.documentElement.style.fontSize = `${rem}px`;
+        } catch (error) {
+          console.error('设置REM失败:', error);
+          // 回退方案:使用固定REM
+          document.documentElement.style.fontSize = `${baseSize}px`;
+        }
       };
-    });
 
-    // 设计稿尺寸
-    const designSize = computed(() => {
-      return {
-        width: config.value.width,
-        height: config.value.height,
+      /**
+       * 计算缩放比例
+       */
+      const calculateScale = (): ScaleInfo => {
+        const { width: designWidth, height: designHeight } = designSize.value;
+        const { innerWidth: currentWidth, innerHeight: currentHeight } = window;
+        const { minScale, maxScale } = config.value;
+
+        // 计算原始比例
+        const rawWidthScale = currentWidth / designWidth;
+        const rawHeightScale = currentHeight / designHeight;
+
+        // 应用比例限制
+        const widthScale = Math.max(minScale, Math.min(maxScale, rawWidthScale));
+        const heightScale = Math.max(minScale, Math.min(maxScale, rawHeightScale));
+
+        // 选择最小比例保持内容完整显示
+        const scale = Math.min(widthScale, heightScale);
+
+        return { widthScale, heightScale, scale };
       };
-    });
-
-    /**
-     * 设置REM基准值
-     * @param baseSize 基准大小,默认18px
-     */
-    const setRem = (baseSize: number = 18): void => {
-      try {
-        const baseVal = baseSize / config.value.baseWidth;
-        const vW = window.innerWidth;
-        const rem = vW * baseVal;
-
-        // 设置全局缩放比例(如果有需要)
-        if (typeof window['$size'] !== 'number') {
-          Object.defineProperty(window, '$size', {
-            value: rem / 100,
-            writable: true,
-          });
-        } else {
-          window['$size'] = rem / 100;
-        }
 
-        // document.documentElement.style.fontSize = `${rem}px`;
-      } catch (error) {
-        console.error('设置REM失败:', error);
-        // 回退方案:使用固定REM
-        document.documentElement.style.fontSize = `${baseSize}px`;
-      }
-    };
-
-    /**
-     * 计算缩放比例
-     */
-    const calculateScale = (): ScaleInfo => {
-      const { width: designWidth, height: designHeight } = designSize.value;
-      const { innerWidth: currentWidth, innerHeight: currentHeight } = window;
-      const { minScale, maxScale } = config.value;
-
-      // 计算原始比例
-      const rawWidthScale = currentWidth / designWidth;
-      const rawHeightScale = currentHeight / designHeight;
-
-      // 应用比例限制
-      const widthScale = Math.max(minScale, Math.min(maxScale, rawWidthScale));
-      const heightScale = Math.max(minScale, Math.min(maxScale, rawHeightScale));
-
-      // 选择最小比例保持内容完整显示
-      const scale = Math.min(widthScale, heightScale);
-
-      return { widthScale, heightScale, scale };
-    };
-
-    /**
-     * 应用缩放变换
-     */
-    const applyScale = (): void => {
-      if (!containerRef.value) return;
-
-      const container = containerRef.value;
-      const { widthScale, heightScale } = calculateScale();
-
-      // 应用缩放
-      container.style.transform = `scale(${widthScale}, ${heightScale})`;
-      // container.style.transformOrigin = 'top left';
-
-      // 更新store中的比例信息(如果需要)
-      debugger;
-      appStore.setWidthScale(widthScale);
-      appStore.setHeightScale(heightScale);
-    };
-
-    /**
-     * 处理窗口大小变化
-     */
-    const handleResize = debounce((): void => {
-      // 更新缩放和REM
-      applyScale();
-      setRem();
-    }, config.value.debounceTime);
-
-    onMounted(async () => {
-      // 生命周期
-      try {
-        if (!containerRef.value) {
-          // if (!document.getElementById('app')) {
-          throw new Error('容器元素未找到');
-        }
+      /**
+       * 应用缩放变换
+       */
+      const applyScale = (): void => {
+        if (!containerRef.value) return;
+
         const container = containerRef.value;
-        const { ratio, tolerance } = config.value;
-        const normalRatio = Math.abs(ratio - container.clientWidth / container.clientHeight) < ratio * tolerance;
-        // const container = document.getElementById('app')!;
-        if (normalRatio) {
-          defaultOptions.value.width = container.clientWidth;
-          defaultOptions.value.height = container.clientHeight;
-        }
+        const { widthScale, heightScale } = calculateScale();
+
+        // 应用缩放
+        container.style.transform = `scale(${widthScale}, ${heightScale})`;
+        // container.style.transformOrigin = 'top left';
 
-        const { width, height } = designSize.value;
-        container.style.width = `${width}px`;
-        container.style.height = `${height}px`;
+        // 更新store中的比例信息(如果需要)
+        appStore.setWidthScale(widthScale);
+        appStore.setHeightScale(heightScale);
+      };
 
+      /**
+       * 处理窗口大小变化
+       */
+      const handleResize = debounce((): void => {
+        // 更新缩放和REM
         applyScale();
         setRem();
-      } catch (error) {
-        console.error('初始化自适应容器失败:', error);
-      }
-
-      window.addEventListener('resize', handleResize);
-    });
-
-    onUnmounted(() => {
-      window.removeEventListener('resize', handleResize);
-    });
-
-    return {
-      containerRef,
-      // isReady,
-    };
-  },
-});
+      }, config.value.debounceTime);
+
+      onMounted(async () => {
+        // 生命周期
+        try {
+          if (!containerRef.value) {
+            // if (!document.getElementById('app')) {
+            throw new Error('容器元素未找到');
+          }
+          const container = containerRef.value;
+          const { ratio, tolerance } = config.value;
+          const normalRatio = Math.abs(ratio - container.clientWidth / container.clientHeight) < ratio * tolerance;
+          // const container = document.getElementById('app')!;
+          if (normalRatio) {
+            defaultOptions.value.width = container.clientWidth;
+            defaultOptions.value.height = container.clientHeight;
+          }
+
+          const { width, height } = designSize.value;
+          container.style.width = `${width}px`;
+          container.style.height = `${height}px`;
+
+          applyScale();
+          setRem();
+        } catch (error) {
+          console.error('初始化自适应容器失败:', error);
+        }
+
+        window.addEventListener('resize', handleResize);
+      });
+
+      onUnmounted(() => {
+        window.removeEventListener('resize', handleResize);
+      });
+
+      return {
+        containerRef,
+        // isReady,
+      };
+    },
+  });
 </script>
 
 <style lang="less" scoped>
-.adaptive-container {
-  // position: relative;
-  // top: 0;
-  // left: 0;
-  overflow: hidden;
-  height: 100%;
-  width: 100%;
-  transform-origin: left top;
-  // z-index: 0;
-  // 防止缩放导致的模糊(开启GPU加速)
-  backface-visibility: hidden;
-  // -webkit-font-smoothing: antialiased;
-}
+  .adaptive-container {
+    // position: relative;
+    // top: 0;
+    // left: 0;
+    overflow: hidden;
+    height: 100%;
+    width: 100%;
+    transform-origin: left top;
+    // z-index: 0;
+    // 防止缩放导致的模糊(开启GPU加速)
+    backface-visibility: hidden;
+    // -webkit-font-smoothing: antialiased;
+  }
 </style>

+ 19 - 17
src/store/modules/mine.ts

@@ -25,6 +25,8 @@ export interface MineDepartment {
   disabled?: boolean;
 }
 
+const TOP_LEVEL_ORG = '1';
+const LEAF_LEVEL_ORG = '4';
 const DEFAULT_CONFIG = {
   id: 'id',
   pid: 'parentId',
@@ -92,31 +94,32 @@ export const useMineDepartmentStore = defineStore('mine-department-store', () =>
 
   /**
    * 获取组织树数据(异步)
-   * 从两个接口获取数据:
-   * 1. getEnfMineTree: 获取执法处、区等非叶子节点
    * 2. getUserMinePermissionData: 获取矿井(叶子节点)数据
    */
   async function fetchDepartTree() {
     try {
       // 并行请求两个接口
-      const [r1, r2] = await Promise.all([
-        getEnfMineTree(), // 非叶子节点(执法处、区)
-        getUserMinePermissionData({}), // 叶子节点(矿井)
-      ]);
-
-      // 标记节点类型
-      r1.forEach((node: any) => {
-        // node.id = ''
-        node.isLeaf = false;
-      }); // 非叶子节点
+      const r2 = await getUserMinePermissionData({});
       r2.forEach((node) => {
-        node.rawid = node.id;
-        node.id = node.fax; // 使用矿井编码作为ID
-        node.isLeaf = true; // 叶子节点(矿井)
+        const isLeaf = node.orgType === LEAF_LEVEL_ORG;
+        node.isLeaf = isLeaf;
+
+        if (isLeaf) {
+          node.rawid = node.id;
+          node.id = node.fax; // 使用矿井编码作为ID
+        }
       });
 
       // 合并数据并转换为树形结构
-      const tree = listToTree([...r1, ...r2], DEFAULT_CONFIG);
+      const tree: any[] = [];
+      listToTree(r2, DEFAULT_CONFIG).some((node: any) => {
+        if (node.orgType === TOP_LEVEL_ORG) {
+          tree.push(...node[DEFAULT_CONFIG.children]);
+          return true;
+        }
+        return false;
+      });
+
       forEach(
         tree,
         (node) => {
@@ -128,7 +131,6 @@ export const useMineDepartmentStore = defineStore('mine-department-store', () =>
         },
         DEFAULT_CONFIG
       );
-
       departTree.value = tree;
       // 深拷贝保存原始数据,用于过滤后恢复
       // rawTree.value = JSON.parse(JSON.stringify(tree));