6 Commity ed3e9e00e9 ... 107f64df11

Autor SHA1 Wiadomość Data
  houzekong 107f64df11 [Feat 0000] 风门详情页面适配缩略图功能 3 tygodni temu
  houzekong b7eed0d087 [Pref 0000] Debug代码去除 3 tygodni temu
  houzekong c2ef6fc00b [Feat 0000] ModelSelect模型选择器开发 3 tygodni temu
  houzekong 47cd7ed38e [Feat 0000] 模型缩略图选择器开发 3 tygodni temu
  houzekong 7f919a175f [Feat 0000] 新增模型文件信息Store 3 tygodni temu
  houzekong 1900bc9571 [Pref 0000] 依赖项优化,打包体积削减 3 tygodni temu

+ 4 - 0
build/vite/plugin/index.ts

@@ -16,6 +16,7 @@ import { configVisualizerConfig } from './visualizer';
 import { configThemePlugin } from './theme';
 import { configSvgIconsPlugin } from './svgSprite';
 import { configServerPlugin } from './serveStatic';
+import { configImageminPlugin } from './imagemin';
 // //预编译加载插件(不支持vite3作废)
 // import OptimizationPersist from 'vite-plugin-optimize-persist';
 import topLevelAwait from 'vite-plugin-top-level-await';
@@ -72,6 +73,9 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
   if (isBuild) {
     // rollup-plugin-gzip
     vitePlugins.push(configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE));
+
+    // vite-plugin-imagemin: 图片压缩 (仅生产环境)
+    vitePlugins.push(configImageminPlugin());
   }
 
   // //vite-plugin-theme【预编译加载插件,解决vite首次打开界面加载慢问题】

+ 1 - 18
package.json

@@ -30,7 +30,6 @@
     "@logicflow/core": "^1.2.12",
     "@logicflow/extension": "^1.2.13",
     "@qiaoqiaoyun/drag-free": "^1.1.4",
-    "@types/markdown-it": "^14.1.2",
     "@vue-office/docx": "^1.6.3",
     "@vue-office/excel": "^1.7.14",
     "@vue-office/pdf": "^2.0.10",
@@ -54,40 +53,29 @@
     "dom-align": "^1.12.4",
     "echarts": "^6.0.0",
     "emoji-mart-vue-fast": "^15.0.0",
-    "enquire.js": "^2.1.6",
     "gsap": "^3.11.3",
     "highlight.js": "^11.11.1",
     "hls.js": "^1.6.15",
     "html2canvas": "^1.4.1",
-    "intro.js": "^7.2.0",
     "katex": "^0.16.25",
     "lodash-es": "^4.17.21",
-    "lodash.get": "^4.4.2",
-    "markdown-it": "^14.3.0",
     "marked": "^17.0.1",
-    "md5": "^2.3.0",
     "mky-svg": "^1.0.2",
-    "moment": "^2.29.4",
     "nprogress": "^0.2.0",
     "path-to-regexp": "^6.2.1",
     "pinia": "2.1.6",
     "plyr": "^3.7.8",
-    "pnpm": "^10.32.1",
     "print-js": "^1.6.0",
     "qiankun": "^2.10.16",
     "qrcode": "^1.5.3",
-    "qrcodejs2": "0.0.2",
     "qs": "^6.11.2",
     "resize-observer-polyfill": "^1.5.1",
-    "showdown": "^2.1.0",
     "sortablejs": "^1.15.0",
     "three": "^0.162.0",
     "three.path": "^1.0.1",
     "tinymce": "^5.10.3",
     "vditor": "^3.9.5",
     "vue": "^3.2.0",
-    "vue-cropper": "^0.6.2",
-    "vue-cropperjs": "^5.0.0",
     "vue-draggable-resizable": "^3.0.0",
     "vue-i18n": "9.2.2",
     "vue-infinite-scroll": "^2.0.2",
@@ -117,7 +105,6 @@
     "@types/crypto-js": "^4.1.1",
     "@types/fs-extra": "^11.0.1",
     "@types/inquirer": "^9.0.3",
-    "@types/intro.js": "^5.1.1",
     "@types/jest": "^29.5.4",
     "@types/lodash-es": "^4.17.8",
     "@types/mockjs": "^1.0.7",
@@ -125,16 +112,12 @@
     "@types/nprogress": "^0.2.0",
     "@types/qrcode": "^1.5.1",
     "@types/qs": "^6.9.7",
-    "@types/showdown": "^2.0.1",
     "@types/sortablejs": "^1.15.1",
     "@types/three": "^0.162.0",
     "@typescript-eslint/eslint-plugin": "^6.4.1",
     "@typescript-eslint/parser": "^6.5.0",
-    "@vitejs/plugin-legacy": "^2.0.0",
     "@vitejs/plugin-vue": "^4.3.3",
     "@vitejs/plugin-vue-jsx": "^3.0.2",
-    "@vue-office/docx": "^1.6.3",
-    "@vue-office/pdf": "^2.0.10",
     "@vue/compiler-sfc": "^3.3.4",
     "@vue/test-utils": "^2.4.1",
     "autoprefixer": "^10.4.16",
@@ -182,10 +165,10 @@
     "typescript": "^4.9.5",
     "unocss": "^0.55.3",
     "video.js": "^8.23.4",
-    "videojs-flvjs-es6": "^1.0.1",
     "vite": "^4.4.9",
     "vite-plugin-compression": "^0.5.1",
     "vite-plugin-html": "^3.2.0",
+    "vite-plugin-imagemin": "^0.6.1",
     "vite-plugin-mkcert": "^1.16.0",
     "vite-plugin-mock": "^2.9.6",
     "vite-plugin-purge-icons": "^0.9.2",

Plik diff jest za duży
+ 575 - 150
pnpm-lock.yaml


+ 11 - 0
src/api/sys/modelFile.ts

@@ -0,0 +1,11 @@
+import { defHttp } from '/@/utils/http/axios';
+
+enum Api {
+  getAllModelFileJson = '/ventanaly-device/safety/modelAlarmInfo/getAllModelFileJson',
+}
+
+export const getAllModelFileJsonApi = () => {
+  return defHttp.get<Record<string, { fileName: string; filePath: string }[]>>({
+    url: Api.getAllModelFileJson,
+  });
+};

+ 1 - 1
src/components/AIChat/MiniChat.vue

@@ -476,7 +476,7 @@
   const parseMarkdownWithLatex = (mdStr) => {
     if (!mdStr) return '';
     try {
-      let html = marked(mdStr); // Markdown → HTML
+      let html = marked.parse(mdStr); // Markdown → HTML
       html = renderLatexInHtml(html); // 替换公式
       return html;
     } catch (error) {

+ 2 - 0
src/components/Form/src/componentMap.ts

@@ -61,6 +61,7 @@ import JSearchSelect from './jeecg/components/JSearchSelect.vue';
 import JAddInput from './jeecg/components/JAddInput.vue';
 import { Time } from '/@/components/Time';
 import JRangeNumber from './jeecg/components/JRangeNumber.vue';
+import ModelSelect from './jeecg/components/ModelSelect.vue';
 import UserSelect from './jeecg/components/userSelect/index.vue';
 import JRangeDate from './jeecg/components/JRangeDate.vue';
 import JRangeTime from './jeecg/components/JRangeTime.vue';
@@ -134,6 +135,7 @@ componentMap.set('JUpload', JUpload);
 componentMap.set('JSearchSelect', JSearchSelect);
 componentMap.set('JAddInput', JAddInput);
 componentMap.set('JRangeNumber', JRangeNumber);
+componentMap.set('ModelSelect', ModelSelect);
 componentMap.set('UserSelect', UserSelect);
 componentMap.set('RangeDate', JRangeDate);
 componentMap.set('RangeTime', JRangeTime);

+ 134 - 0
src/components/Form/src/jeecg/components/ModelSelect.vue

@@ -0,0 +1,134 @@
+<template>
+  <ASelect v-bind="attrs_" v-model:value="state" placeholder="请选择模型" @dropdown-visible-change="onDropdownVisibleChange">
+    <template #[item]="data" v-for="item in Object.keys($slots)">
+      <slot :name="item" v-bind="data || {}"></slot>
+    </template>
+    <template #dropdownRender>
+      <div v-if="getOptions.length" class="model-select-grid">
+        <div
+          v-for="opt in getOptions"
+          :key="opt.fileName"
+          class="model-select-grid-item"
+          :class="{ 'is-selected': state === opt.fileName }"
+          @click="handleSelect(opt)"
+        >
+          <div class="model-select-grid-thumb-wrap">
+            <AntImage v-if="hasOpened" :src="getFileAccessHttpUrl(opt.filePath)" :preview="true" width="64" class="model-select-thumb" />
+          </div>
+          <span class="model-select-name">{{ opt.fileName + deviceType }}</span>
+        </div>
+      </div>
+    </template>
+  </ASelect>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, computed, unref } from 'vue';
+  import { Select as ASelect, Image as AntImage } from 'ant-design-vue';
+  import { useRuleFormItem } from '/@/hooks/component/useFormItem';
+  import { useAttrs } from '/@/hooks/core/useAttrs';
+  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
+  import { propTypes } from '/@/utils/propTypes';
+  import { useModelFileStore } from '/@/store/modules/modelFile';
+  import { storeToRefs } from 'pinia';
+
+  type OptionsItem = { label: string; value: string; fileName: string; filePath: string };
+
+  export default defineComponent({
+    name: 'ModelSelect',
+    components: { ASelect, AntImage },
+    inheritAttrs: false,
+    props: {
+      value: propTypes.oneOfType([propTypes.string, propTypes.number]),
+      deviceType: propTypes.string.def(''),
+    },
+    emits: ['change', 'update:value'],
+    setup(props, { emit }) {
+      const emitData = ref<any[]>([]);
+      const attrs = useAttrs();
+      const hasOpened = ref(false);
+
+      const [state] = useRuleFormItem(props, 'value', 'change', emitData);
+
+      const modelFileStore = useModelFileStore();
+      const { modelFileData } = storeToRefs(modelFileStore);
+
+      const attrs_ = computed(() => {
+        const obj: any = { ...unref(attrs) };
+        if (obj && obj['onUpdate:value']) {
+          delete obj['onUpdate:value'];
+        }
+        return obj;
+      });
+
+      const getOptions = computed((): OptionsItem[] => {
+        const key = props.deviceType;
+        if (!key || !modelFileData.value) return [];
+        console.log('debug m', modelFileData.value);
+        const items = modelFileData.value[key.split('_')[0]];
+        if (!items) return [];
+        return items.map((item) => ({
+          label: item.fileName,
+          value: item.fileName,
+          fileName: item.fileName,
+          filePath: item.filePath,
+        }));
+      });
+
+      function onDropdownVisibleChange(visible: boolean) {
+        hasOpened.value = visible;
+      }
+
+      function handleSelect(opt: OptionsItem) {
+        state.value = opt.fileName;
+        emit('update:value', opt.fileName);
+      }
+
+      return { state, attrs_, getOptions, getFileAccessHttpUrl, hasOpened, onDropdownVisibleChange, handleSelect };
+    },
+  });
+</script>
+<style scoped>
+  .model-select-grid {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    gap: 8px;
+    padding: 8px;
+    max-height: 350px;
+    overflow-y: auto;
+  }
+  .model-select-grid-item {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 4px;
+    padding: 8px;
+    border: 1px solid #f0f0f0;
+    border-radius: 6px;
+    cursor: pointer;
+    transition:
+      border-color 0.2s,
+      box-shadow 0.2s;
+  }
+  .model-select-grid-item:hover {
+    border-color: #1890ff;
+    box-shadow: 0 2px 8px rgba(24, 144, 255, 0.15);
+  }
+  .model-select-grid-item.is-selected {
+    border-color: #1890ff;
+    background: #e6f7ff;
+  }
+  .model-select-grid-thumb-wrap {
+    line-height: 0;
+  }
+  .model-select-thumb {
+    border-radius: 4px;
+    border: 1px solid #f0f0f0;
+    cursor: pointer;
+  }
+  .model-select-name {
+    font-size: 12px;
+    color: #333;
+    text-align: center;
+    word-break: break-all;
+  }
+</style>

+ 1 - 0
src/components/Form/src/types/index.ts

@@ -154,4 +154,5 @@ export type ComponentType =
   | 'RangeNumber'
   | 'linkRecordSelect'
   | 'RangeTime'
+  | 'ModelSelect'
   | 'JRangeNumber';

+ 2 - 4
src/components/Markdown/src/MarkdownViewer.vue

@@ -4,15 +4,13 @@
 
 <script lang="ts" setup>
   import { computed } from 'vue';
-  import showdown from 'showdown';
+  import { marked } from 'marked';
 
-  const converter = new showdown.Converter();
-  converter.setOption('tables', true);
   const props = defineProps({
     value: { type: String },
     class: { type: String },
   });
-  const getHtmlData = computed(() => converter.makeHtml(props.value || ''));
+  const getHtmlData = computed(() => marked.parse(props.value || '', { gfm: true }));
 </script>
 
 <style scoped>

+ 5 - 0
src/router/guard/index.ts

@@ -2,6 +2,7 @@ import type { Router, RouteLocationNormalized } from 'vue-router';
 import { useAppStoreWithOut } from '/@/store/modules/app';
 import { useUserStoreWithOut } from '/@/store/modules/user';
 import { useVentStore } from '/@/store/modules/vent';
+import { useModelFileStore } from '/@/store/modules/modelFile';
 import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
 import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
 import { Modal, notification } from 'ant-design-vue';
@@ -64,6 +65,7 @@ function createPageGuard(router: Router) {
 // Used to handle page loading status
 function createPageLoadingGuard(router: Router) {
   const ventStore = useVentStore();
+  const modelFileStore = useModelFileStore();
   const userStore = useUserStoreWithOut();
   const appStore = useAppStoreWithOut();
   const { getOpenPageLoading } = useTransitionSetting();
@@ -77,6 +79,9 @@ function createPageLoadingGuard(router: Router) {
     if (!ventStore.allTableHeaderColumns) {
       await ventStore.setAllTableHeaderColumns();
     }
+    if (!modelFileStore.modelFileData) {
+      await modelFileStore.fetchModelFileData();
+    }
     if (unref(getOpenPageLoading)) {
       appStore.setPageLoadingAction(true);
       return true;

+ 38 - 0
src/store/modules/modelFile.ts

@@ -0,0 +1,38 @@
+import { defineStore } from 'pinia';
+import { getAllModelFileJsonApi } from '/@/api/sys/modelFile';
+
+interface ModelFileItem {
+  fileName: string;
+  filePath: string;
+}
+
+export const useModelFileStore = defineStore({
+  id: 'app-model-file',
+  state: () => ({
+    modelFileData: null as Record<string, ModelFileItem[]> | null,
+  }),
+  getters: {
+    getModelFileDataByKey(): (key: string) => ModelFileItem[] {
+      return (key: string) => {
+        if (!this.modelFileData || !this.modelFileData[key]) return [];
+        return this.modelFileData[key];
+      };
+    },
+    getAllModelFileData(): Record<string, ModelFileItem[]> | null {
+      return this.modelFileData;
+    },
+  },
+  actions: {
+    async fetchModelFileData() {
+      const raw = await getAllModelFileJsonApi();
+      const processed: Record<string, ModelFileItem[]> = {};
+      for (const [key, items] of Object.entries(raw)) {
+        processed[key] = items.map((item) => ({
+          fileName: item.fileName.replace(/\.[^.]+$/, ''),
+          filePath: item.filePath.replace(/^\/data\/file/, ''),
+        }));
+      }
+      this.modelFileData = processed;
+    },
+  },
+});

+ 4 - 2
src/utils/encryption/signMd5Utils.js

@@ -1,4 +1,4 @@
-import md5 from 'md5';
+import md5 from 'crypto-js/md5';
 import { fromEnvCharCodes } from '/@/utils/env';
 
 // 签名密钥串(前后端要一致,正式发布请自行修改,通过环境变量配置)
@@ -35,7 +35,9 @@ export default class signMd5Utils {
     let jsonObj = this.mergeObject(urlParams, requestParams);
     let requestBody = this.sortAsc(jsonObj);
     delete requestBody._t;
-    return md5(JSON.stringify(requestBody) + signatureSecret).toUpperCase();
+    return md5(JSON.stringify(requestBody) + signatureSecret)
+      .toString()
+      .toUpperCase();
   }
 
   /**

+ 1 - 1
src/views/monitor/trace/trace.data.ts

@@ -1,6 +1,6 @@
 import { BasicColumn } from '/@/components/Table';
 import dayjs from 'dayjs';
-import _get from 'lodash.get';
+import { get as _get } from 'lodash-es';
 import { h } from 'vue';
 import { Tag } from 'ant-design-vue';
 

+ 128 - 136
src/views/vent/deviceManager/comment/DeviceReportInfo.vue

@@ -8,81 +8,103 @@
   </div>
 </template>
 <script lang="ts" setup>
-import { onMounted, ref, defineEmits, onUnmounted, watch, PropType, nextTick, inject, onBeforeMount } from 'vue';
-import { BasicForm, useForm } from '/@/components/Form/index';
-import { FormSchema } from '/@/components/Form';
-import { getFormSchemaColumns } from '/@/hooks/web/useWebColumns';
-import { list as substationList } from '/@/views/vent/deviceManager/substationTabel/substation.api';
-import { list, updateReportInfo, sysList, sysInput } from '../../monitorManager/comment/comment.api';
-const deviceData = inject('formData') as any;
-const emit = defineEmits(['close', 'register']);
-const FormRef = ref();
-const tabType = ref('');
+  import { onMounted, ref, defineEmits, onUnmounted, watch, PropType, nextTick, inject, onBeforeMount } from 'vue';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { FormSchema } from '/@/components/Form';
+  import { getFormSchemaColumns } from '/@/hooks/web/useWebColumns';
+  import { list as substationList } from '/@/views/vent/deviceManager/substationTabel/substation.api';
+  import { list, updateReportInfo, sysList, sysInput } from '../../monitorManager/comment/comment.api';
+  const deviceData = inject('formData') as any;
+  const emit = defineEmits(['close', 'register']);
+  const FormRef = ref();
+  const tabType = ref('');
 
-const formSchema = ref<any[]>([]);
-const formData = ref(deviceData);
-const deviceTypeName = ref(deviceData.devicekind ? deviceData.devicekind : deviceData.strtype);
+  const formSchema = ref<any[]>([]);
+  const formData = ref(deviceData);
+  const deviceTypeName = ref(deviceData.devicekind ? deviceData.devicekind : deviceData.strtype);
 
-const arrToFormColumns = (tableHeaderColumns = [], devicetype) => {
-  const columnList: any[] = [];
-  tableHeaderColumns.forEach((item: any) => {
-    let columnsItem;
-    if (item.type == 1 || item.type == 10) {
-      columnsItem = {
-        label: item.des, //_dictText
-        field: item.monitorcode,
-        component: item.type == 1 ? 'Input' : item.type == 10 ? 'InputTextArea' : '',
-      };
-    } else {
-      if (item.type == 2 && item['monitorcode'] == 'nsubstationid') {
-        columnsItem = {
-          label: item.des, //_dictText
-          field: item.monitorcode,
-          component: 'ApiSelect',
-          componentProps: {
-            api: substationList,
-            labelField: 'strname',
-            valueField: 'id',
-          },
-        };
-      }
-      if (item.type == 3) {
-        columnsItem = {
-          label: item.des, //_dictText
-          field: item.monitorcode,
-          component: 'RadioGroup',
-          defaultValue: 1,
-          componentProps: () => {
-            return {
+  const arrToFormColumns = (tableHeaderColumns = [], devicetype) => {
+    const columnList: any[] = [];
+    tableHeaderColumns.forEach((item: any) => {
+      let columnsItem;
+      switch (item.type) {
+        case 1:
+          columnsItem = { label: item.des, field: item.monitorcode, component: 'Input' };
+          break;
+        case 10:
+          columnsItem = { label: item.des, field: item.monitorcode, component: 'InputTextArea' };
+          break;
+        case 2:
+          if (item.monitorcode !== 'nsubstationid') break;
+          columnsItem = {
+            label: item.des,
+            field: item.monitorcode,
+            component: 'ApiSelect',
+            componentProps: { api: substationList, labelField: 'strname', valueField: 'id' },
+          };
+          break;
+        case 3:
+          columnsItem = {
+            label: item.des,
+            field: item.monitorcode,
+            component: 'RadioGroup',
+            defaultValue: 1,
+            componentProps: () => ({
               options: [
                 { label: '是', value: 1, key: '1' },
                 { label: '否', value: 0, key: '2' },
               ],
               stringToNumber: true,
-            };
-          },
-        };
+            }),
+          };
+          break;
+        case 4:
+          columnsItem = {
+            label: item.des,
+            field: item.monitorcode,
+            component: 'JDictSelectTag',
+            componentProps: { dictCode: item.dict, placeholder: '请选择' },
+          };
+          break;
+      }
+      if (!!columnsItem) {
+        columnList.push(columnsItem);
       }
-      if (item.type == 4) {
-        columnsItem = {
-          label: item.des, //_dictText
-          field: item.monitorcode,
+    });
+    formSchema.value = columnList;
+    if (tabType.value === 'deviceInfo') {
+      formSchema.value.unshift(
+        {
+          label: '设备id', //_dictText
+          field: 'id',
+          component: 'Input',
+          componentProps: {
+            disabled: true,
+            show: false,
+          },
+        },
+        {
+          label: '点表',
+          field: 'strtype',
           component: 'JDictSelectTag',
           componentProps: {
-            dictCode: item.dict,
-            placeholder: '请选择',
-            // stringToNumber: false,
+            dictCode: `${devicetype.split('_')[0]}kind`,
+            placeholder: '请选择点表',
           },
-        };
-      }
-    }
-    columnList.push(columnsItem);
-  });
-  formSchema.value = columnList;
-  console.log(formSchema.value, 'sssssssssssssssssssss');
-  if (tabType.value === 'deviceInfo') {
-    formSchema.value.unshift(
-      {
+        }
+      );
+      formSchema.value.push({
+        label: '备用分站',
+        field: 'stationids',
+        component: 'ApiSelect',
+        componentProps: {
+          api: substationList,
+          labelField: 'strname',
+          valueField: 'id',
+        },
+      });
+    } else {
+      formSchema.value.unshift({
         label: '设备id', //_dictText
         field: 'id',
         component: 'Input',
@@ -90,87 +112,57 @@ const arrToFormColumns = (tableHeaderColumns = [], devicetype) => {
           disabled: true,
           show: false,
         },
-      },
-      {
-        label: '点表',
-        field: 'strtype',
-        component: 'JDictSelectTag',
-        componentProps: {
-          dictCode: `${devicetype.split('_')[0]}kind`,
-          placeholder: '请选择点表',
-        },
-      }
-    );
-    formSchema.value.push({
-      label: '备用分站',
-      field: 'stationids',
-      component: 'ApiSelect',
-      componentProps: {
-        api: substationList,
-        labelField: 'strname',
-        valueField: 'id',
-      },
-    });
-  } else {
-    formSchema.value.unshift({
-      label: '设备id', //_dictText
-      field: 'id',
-      component: 'Input',
-      componentProps: {
-        disabled: true,
-        show: false,
-      },
-    });
-  }
-};
+      });
+    }
+  };
 
-const [registerForm, { resetSchema, getFieldsValue, setFieldsValue, resetFields }] = useForm({
-  schemas: <FormSchema[]>formSchema.value,
-  showActionButtonGroup: false,
-});
+  const [registerForm, { resetSchema, getFieldsValue, setFieldsValue, resetFields }] = useForm({
+    schemas: <FormSchema[]>formSchema.value,
+    showActionButtonGroup: false,
+  });
 
-function getColumns() {
-  let formSchemaArr = getFormSchemaColumns(`${deviceData.devicekind ? deviceData.devicekind : deviceData.strtype}_input`) || [];
-  if (formSchemaArr && formSchemaArr.length < 1) {
-    const arr = deviceTypeName.value.split('_');
-    formSchemaArr = getFormSchemaColumns(arr[0] + '_input') || [];
+  function getColumns() {
+    let formSchemaArr = getFormSchemaColumns(`${deviceData.devicekind ? deviceData.devicekind : deviceData.strtype}_input`) || [];
+    if (formSchemaArr && formSchemaArr.length < 1) {
+      const arr = deviceTypeName.value.split('_');
+      formSchemaArr = getFormSchemaColumns(arr[0] + '_input') || [];
+    }
+    arrToFormColumns(formSchemaArr, deviceTypeName.value);
+    resetSchema(formSchema.value);
   }
-  arrToFormColumns(formSchemaArr, deviceTypeName.value);
-  resetSchema(formSchema.value);
-}
 
-async function onReset() {
-  await resetFields();
-  await setFieldsValue({ ...deviceData });
-}
+  async function onReset() {
+    await resetFields();
+    await setFieldsValue({ ...deviceData });
+  }
 
-async function handleSubmit() {
-  const data = await getFieldsValue();
-  if (!deviceData.devicekind) {
-    await sysInput(data);
-  } else {
-    await updateReportInfo(data);
+  async function handleSubmit() {
+    const data = await getFieldsValue();
+    if (!deviceData.devicekind) {
+      await sysInput(data);
+    } else {
+      await updateReportInfo(data);
+    }
   }
-}
 
-onBeforeMount(async () => {});
+  onBeforeMount(async () => {});
 
-onMounted(async () => {
-  getColumns();
-  let result;
-  if (!deviceData.devicekind) {
-    result = await sysList({ id: deviceData.id });
-  } else {
-    result = await list({ id: deviceData.id });
-  }
-  formData.value = result['records'][0] || [];
-  await setFieldsValue({
-    ...formData.value,
+  onMounted(async () => {
+    getColumns();
+    let result;
+    if (!deviceData.devicekind) {
+      result = await sysList({ id: deviceData.id });
+    } else {
+      result = await list({ id: deviceData.id });
+    }
+    formData.value = result['records'][0] || [];
+    await setFieldsValue({
+      ...formData.value,
+    });
   });
-});
-onUnmounted(() => {});
+  onUnmounted(() => {});
 </script>
 <style scoped lang="less">
-@import '/@/design/theme.less';
-@import '/@/design/vent/modal.less';
+  @import '/@/design/theme.less';
+  @import '/@/design/vent/modal.less';
 </style>

+ 44 - 54
src/views/vent/deviceManager/deviceTable/index.vue

@@ -44,82 +44,72 @@
     const columnList: any[] = [];
     tableHeaderColumns.forEach((item: any) => {
       let columnsItem;
-      if (item.type == 1 || item.type == 10) {
-        columnsItem = {
-          label: item.des, //_dictText
-          field: item.monitorcode,
-          component: item.type == 1 ? 'Input' : item.type == 10 ? 'InputTextArea' : '',
-        };
-      } else {
-        if (item.type == 2 && item['monitorcode'] == 'nsubstationid') {
+      switch (item.type) {
+        case 1:
+          columnsItem = { label: item.des, field: item.monitorcode, component: 'Input' };
+          break;
+        case 10:
+          columnsItem = { label: item.des, field: item.monitorcode, component: 'InputTextArea' };
+          break;
+        case 2:
+          if (item.monitorcode !== 'nsubstationid') break;
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'ApiSelect',
-            componentProps: {
-              api: substationList,
-              labelField: 'strname',
-              valueField: 'id',
-            },
+            componentProps: { api: substationList, labelField: 'strname', valueField: 'id' },
           };
-        }
-        if (item.type == 3) {
+          break;
+        case 3:
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'RadioGroup',
             defaultValue: 1,
-            componentProps: () => {
-              return {
-                options: [
-                  { label: '是', value: 1, key: '1' },
-                  { label: '否', value: 0, key: '2' },
-                ],
-                stringToNumber: true,
-              };
-            },
+            componentProps: () => ({
+              options: [
+                { label: '是', value: 1, key: '1' },
+                { label: '否', value: 0, key: '2' },
+              ],
+              stringToNumber: true,
+            }),
           };
-        }
-        if (item.type == 4) {
+          break;
+        case 4:
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'JDictSelectTag',
-            componentProps: {
-              dictCode: item.dict,
-              placeholder: '请选择',
-              // stringToNumber: true,
-            },
+            componentProps: { dictCode: item.dict, placeholder: '请选择' },
           };
-        }
-        // date日期
-        if (item.type == 8) {
+          break;
+        case 8:
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'DatePicker',
-            componentProps: {
-              showTime: false,
-              valueFormat: 'YYYY-MM-DD',
-              getPopupContainer: getAutoScrollContainer,
-            },
+            componentProps: { showTime: false, valueFormat: 'YYYY-MM-DD', getPopupContainer: getAutoScrollContainer },
           };
-        }
-        // 日期+时间
-        if (item.type == 9) {
+          break;
+        case 9:
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'DatePicker',
-            componentProps: {
-              showTime: true,
-              valueFormat: 'YYYY-MM-DD HH:mm:ss',
-              getPopupContainer: getAutoScrollContainer,
-            },
+            componentProps: { showTime: true, valueFormat: 'YYYY-MM-DD HH:mm:ss', getPopupContainer: getAutoScrollContainer },
           };
-        }
+          break;
+        case 11:
+          columnsItem = {
+            label: item.des,
+            field: item.monitorcode,
+            component: 'ModelSelect',
+            componentProps: { deviceType: deviceType.value },
+          };
+      }
+      if (!!columnsItem) {
+        columnList.push(columnsItem);
       }
-      columnList.push(columnsItem);
     });
     formSchema.value = columnList;
     formSchema.value.unshift(

+ 24 - 28
src/views/vent/deviceManager/workingFace/index.vue

@@ -36,44 +36,40 @@
     if (tableHeaderColumns.length > 0) {
       tableHeaderColumns.forEach((item: any) => {
         let columnsItem;
-        if (item.type == 1 || item.type == 10) {
-          columnsItem = {
-            label: item.des, //_dictText
-            field: item.monitorcode,
-            component: item.type == 1 ? 'Input' : item.type == 10 ? 'InputTextArea' : '',
-          };
-        } else {
-          if (item.type == 3) {
+        switch (item.type) {
+          case 1:
+            columnsItem = { label: item.des, field: item.monitorcode, component: 'Input' };
+            break;
+          case 10:
+            columnsItem = { label: item.des, field: item.monitorcode, component: 'InputTextArea' };
+            break;
+          case 3:
             columnsItem = {
-              label: item.des, //_dictText
+              label: item.des,
               field: item.monitorcode,
               component: 'RadioGroup',
               defaultValue: 1,
-              componentProps: () => {
-                return {
-                  options: [
-                    { label: '是', value: 1, key: '1' },
-                    { label: '否', value: 0, key: '2' },
-                  ],
-                  stringToNumber: true,
-                };
-              },
+              componentProps: () => ({
+                options: [
+                  { label: '是', value: 1, key: '1' },
+                  { label: '否', value: 0, key: '2' },
+                ],
+                stringToNumber: true,
+              }),
             };
-          }
-          if (item.type == 4) {
+            break;
+          case 4:
             columnsItem = {
-              label: item.des, //_dictText
+              label: item.des,
               field: item.monitorcode,
               component: 'JDictSelectTag',
-              componentProps: {
-                dictCode: item.dict,
-                placeholder: '请选择',
-                stringToNumber: true,
-              },
+              componentProps: { dictCode: item.dict, placeholder: '请选择', stringToNumber: true },
             };
-          }
+            break;
+        }
+        if (!!columnsItem) {
+          columnList.push(columnsItem);
         }
-        columnList.push(columnsItem);
         formSchema.value = [...commentFormSchema(strtype), ...columnList];
       });
     } else {

+ 4 - 4
src/views/vent/monitorManager/alarmMonitor/common/predictionCurve.vue

@@ -10,7 +10,7 @@
 </template>
 
 <script lang="ts" setup>
-  import moment from 'moment';
+  import dayjs from 'dayjs';
   import { ref, watch } from 'vue';
   import EchartLine3 from './echartLine3.vue';
 
@@ -87,14 +87,14 @@
         // indexMark为0表示还没插入过数据,初始化数据
         if (chartConfig.value.indexMark === 0) {
           const arr = new Array(20).fill(0);
-          const startFrom = moment(el.time);
+          const startFrom = dayjs(el.time);
           chartConfig.value = {
             // label: el.label,
             label: '',
             indexMark: 1,
             x: arr.map(() => {
               const str = startFrom.format('HH:mm:ss');
-              startFrom.add(props.timeout || 3000);
+              startFrom.add(props.timeout || 3000, 'millisecond');
               return str;
             }),
             y1: arr.map(() => {
@@ -123,7 +123,7 @@
             val.y4.shift();
             val.indexMark = 19;
           }
-          val.x[val.indexMark] = moment(el.time).format('HH:mm:ss');
+          val.x[val.indexMark] = dayjs(el.time).format('HH:mm:ss');
           val.y1[val.indexMark] = el.data[0];
           val.y2[val.indexMark] = el.data[1];
           val.y3[val.indexMark] = el.data[2];

+ 45 - 54
src/views/vent/monitorManager/comment/components/DeviceBaseInfo.vue

@@ -145,82 +145,73 @@
     const columnList: any[] = [];
     tableHeaderColumns.forEach((item: any) => {
       let columnsItem;
-      if (item.type == 1 || item.type == 10) {
-        columnsItem = {
-          label: item.des, //_dictText
-          field: item.monitorcode,
-          component: item.type == 1 ? 'Input' : item.type == 10 ? 'InputTextArea' : '',
-        };
-      } else {
-        if (item.type == 2 && item['monitorcode'] == 'nsubstationid') {
+      switch (item.type) {
+        case 1:
+          columnsItem = { label: item.des, field: item.monitorcode, component: 'Input' };
+          break;
+        case 10:
+          columnsItem = { label: item.des, field: item.monitorcode, component: 'InputTextArea' };
+          break;
+        case 2:
+          if (item.monitorcode !== 'nsubstationid') break;
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'ApiSelect',
-            componentProps: {
-              api: substationList,
-              labelField: 'strname',
-              valueField: 'id',
-            },
+            componentProps: { api: substationList, labelField: 'strname', valueField: 'id' },
           };
-        }
-        if (item.type == 3) {
+          break;
+        case 3:
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'RadioGroup',
             defaultValue: 1,
-            componentProps: () => {
-              return {
-                options: [
-                  { label: '是', value: 1, key: '1' },
-                  { label: '否', value: 0, key: '2' },
-                ],
-                stringToNumber: true,
-              };
-            },
+            componentProps: () => ({
+              options: [
+                { label: '是', value: 1, key: '1' },
+                { label: '否', value: 0, key: '2' },
+              ],
+              stringToNumber: true,
+            }),
           };
-        }
-        if (item.type == 4) {
+          break;
+        case 4:
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'JDictSelectTag',
-            componentProps: {
-              dictCode: item.dict,
-              placeholder: '请选择',
-              // stringToNumber: true,
-            },
+            componentProps: { dictCode: item.dict, placeholder: '请选择' },
           };
-        }
-        // date日期
-        if (item.type == 8) {
+          break;
+        case 8:
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'DatePicker',
-            componentProps: {
-              showTime: false,
-              valueFormat: 'YYYY-MM-DD',
-              getPopupContainer: getAutoScrollContainer,
-            },
+            componentProps: { showTime: false, valueFormat: 'YYYY-MM-DD', getPopupContainer: getAutoScrollContainer },
           };
-        }
-        // 日期+时间
-        if (item.type == 9) {
+          break;
+        case 9:
           columnsItem = {
-            label: item.des, //_dictText
+            label: item.des,
             field: item.monitorcode,
             component: 'DatePicker',
-            componentProps: {
-              showTime: true,
-              valueFormat: 'YYYY-MM-DD HH:mm:ss',
-              getPopupContainer: getAutoScrollContainer,
-            },
+            componentProps: { showTime: true, valueFormat: 'YYYY-MM-DD HH:mm:ss', getPopupContainer: getAutoScrollContainer },
           };
-        }
+          break;
+        case 11:
+          columnsItem = {
+            label: item.des,
+            field: item.monitorcode,
+            component: 'ModelSelect',
+            componentProps: { deviceType: props.deviceType },
+          };
+          break;
+      }
+      if (!!columnsItem) {
+        columnList.push(columnsItem);
       }
-      columnList.push(columnsItem);
     });
     formSchema.value = columnList;
     formSchema.value.unshift(

+ 0 - 2
src/views/vent/monitorManager/fireDoorMonitor/fireDoor.threejs.ymh.ts

@@ -87,7 +87,6 @@ class FireDoorYmh {
    */
   initAnimation() {
     const group = this.group.children[0];
-    console.log('debug rr', group.animations[0].tracks);
     /** 卷帘门的元素名称,pCude34-pCude73 */
     if (group) {
       const tracksA: THREE.KeyframeTrack[] = [];
@@ -136,7 +135,6 @@ class FireDoorYmh {
    * @param {number} [timeScale=0.01] - 动画时间缩放因子,控制动画播放速度
    */
   play(handlerState, timeScale = 0.01) {
-    console.log('debug ', handlerState);
     let handler = () => {};
     switch (handlerState) {
       case 1: // 打开门

+ 5 - 4
src/views/vent/monitorManager/gateMonitor/gate.threejs.ts

@@ -15,8 +15,8 @@ import FmXR from './gate.threejs.xr';
 // import FmSp1 from './gate.threejs.one.sp';
 import { animateCamera } from '/@/utils/threejs/util';
 import useEvent from '../../../../utils/threejs/useEvent';
-import { getDictItemsByCode } from '/@/utils/dict';
-import { useGlobSetting } from '/@/hooks/setting';
+import { useModelFileStore } from '/@/store/modules/modelFile';
+// import { useGlobSetting } from '/@/hooks/setting';
 
 // 模型对象、 文字对象
 let model,
@@ -868,11 +868,11 @@ export const mountedThree = () => {
     model.setEnvMap('test1.hdr');
     model.renderer.toneMappingExposure = 0.9;
     model.camera.position.set(100, 0, 1000);
-    const dictCodes = getDictItemsByCode('gateStyle');
+    const dictCodes = useModelFileStore().getModelFileDataByKey('gate');
     if (dictCodes && dictCodes.length > 0) {
       for (let i = 0; i < dictCodes.length; i++) {
         const dict = dictCodes[i];
-        switch (dict.value) {
+        switch (dict.fileName) {
           case 'fmXr':
             const FmXR = await loadModel('FmXR');
             fmXr = new FmXR(model);
@@ -981,6 +981,7 @@ export const mountedThree = () => {
     }
 
     model.animate();
+    // generateThumbnailsBySwitch();
     // startAnimation();
   });
 };

+ 0 - 9
src/views/vent/monitorManager/windowMonitor/components/windowDualAdjustSVG.vue

@@ -1701,15 +1701,6 @@
 
   /** 根据SVG的使用场景播放动画 */
   function animate(data: any, maxarea) {
-    console.log(
-      'debug animate',
-      data,
-      maxarea,
-      data.frontArea / maxarea,
-      data.rearArea / maxarea,
-      data.frontArea3 / maxarea,
-      data.frontArea4 / maxarea
-    );
     // 前门(画面左边的门)
     triggerAnimation([`auto_anim_0${props.identify}`], false, { progress: data.frontArea / maxarea || 0 });
     // 前门(画面左边的门)

+ 2 - 1
src/views/ventAI/dataPicker/components/DataPickerModal.vue

@@ -124,7 +124,8 @@
 
   const renderedText = computed(() => {
     if (!props.streamingText) return '';
-    return marked.parse(props.streamingText.replace(/<br\s*\/?>/gi, '  \n')) as string;
+    const processed = props.streamingText.replace(/<br\s*\/?>/gi, '  \n');
+    return marked.parse(processed);
   });
 </script>
 

+ 6 - 10
vite.config.ts

@@ -54,7 +54,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
           find: /@\//,
           replacement: pathResolve('src') + '/',
         },
-        // /#/xxxx => types/xxxx
+        // #/xxxx => types/xxxx
         {
           find: /#\//,
           replacement: pathResolve('types') + '/',
@@ -92,6 +92,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
             // 将 Lodash 库的代码单独打包 (lodash 已废弃,仅保留 lodash-es)
             'lodash-es-vendor': ['lodash-es'],
             'html2canvas-vendor': ['html2canvas'],
+            'd3-vendor': ['d3'],
+            'datav-vendor': ['@kjgl77/datav-vue3'],
             // vue vue-router合并打包
             vue: ['vue', 'vue-router'],
             'cron-parser-vendor': ['cron-parser'],
@@ -109,8 +111,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
 
       // 关闭brotliSize显示可以稍微减少打包时间
       reportCompressedSize: false,
-      // 提高超大静态资源警告大小
-      chunkSizeWarningLimit: 2500,
+      // 超大静态资源警告阈值
+      chunkSizeWarningLimit: 500,
     },
     esbuild: {
       //清除全局的console.log和debug
@@ -138,10 +140,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
       esbuildOptions: {
         target: 'es2020',
       },
-      exclude: [
-        //升级vite4后,需要排除online依赖
-        '@jeecg/online',
-      ],
+      exclude: [],
       // 提前预加载依赖,缩短首屏访问时间
       include: [
         '@vue/runtime-core',
@@ -193,9 +192,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
         'echarts/core',
         'echarts/renderers',
         'emoji-mart-vue-fast/src',
-        'intro.js',
         'lodash-es',
-        'md5',
         'nprogress',
         'path-to-regexp',
         'pinia',
@@ -203,7 +200,6 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
         'qrcode',
         'qs',
         'resize-observer-polyfill',
-        'showdown',
         'sortablejs',
         'tinymce/icons/default/icons',
         'tinymce/plugins/advlist',

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików