Преглед на файлове

Merge branch 'master' of http://182.92.126.35:3000/hrx/mky-vent-base

lxh преди 6 дни
родител
ревизия
47f1101bbc

BIN
src/assets/images/home-container/configurable/tashanhome/workFace.png


+ 162 - 158
src/views/vent/deviceManager/comment/DeviceModal.vue

@@ -41,9 +41,12 @@
           @delete="deletePointById"
         />
       </a-tab-pane>
-      <a-tab-pane key="3" tab="设备关联" v-if="deviceType == 'managesys'">
+      <a-tab-pane key="3" tab="关联设备" v-if="deviceType == 'managesys'">
         <WorkFacePointTable :columns="linkColumns" :deviceId="deviceData.id" @save="savePointData" @delete="deletePointById" />
       </a-tab-pane>
+      <a-tab-pane key="12" tab="关联报表" v-if="deviceType == 'managesys'">
+        <WorkFaceReportTable :columns="reportColumns" :device="deviceData" />
+      </a-tab-pane>
       <a-tab-pane v-if="deviceType == 'managesys'" key="4" tab="预警条目管理">
         <ManagerWarningDeviceTable v-if="activeKey == '4'" :deviceId="deviceData.id" />
       </a-tab-pane>
@@ -85,174 +88,175 @@
   </BasicModal>
 </template>
 <script lang="ts" setup>
-import { computed, unref, inject, reactive, ref, watch } from 'vue';
-import { BasicModal, useModalInner } from '/@/components/Modal';
-import EditRowTable from '../../comment/EditRowTable.vue';
-import PointTable from './pointTabel/PointTable.vue';
-import WarningTable from './warningTabel/index.vue';
-import ManagerWarningTable from './warningTabel/index1.vue';
-import ManagerWarningDeviceTable from './warningTabel/index2.vue';
-import BackWindDeviceTable from './warningTabel/index3.vue';
-import AccidentPlanTable from './warningTabel/index4.vue';
-import LEDPlaylistTable from './warningTabel/index5.vue';
-import WorkFacePointTable from './pointTabel/WorkFacePointTable.vue';
-import DeviceReportInfo from './DeviceReportInfo.vue';
-// import editWarnTable from './editWarnTable/index.vue'
-import FanLineModal from './FanLineModal .vue';
-import FormModal from './FormModal.vue';
-import { cloneDeep } from 'lodash-es';
-import { columns as pointColumns, workFaceColumns, simulationColumns } from './pointTabel/point.data';
-import { saveOrUpdate as pointSaveOrUpdate, deleteById as pointDeleteById } from './pointTabel/point.api';
-import { columns as cameraColumns } from './cameraTabel/camera.data';
+  import { computed, unref, inject, reactive, ref, watch } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import EditRowTable from '../../comment/EditRowTable.vue';
+  import PointTable from './pointTabel/PointTable.vue';
+  import WarningTable from './warningTabel/index.vue';
+  import ManagerWarningTable from './warningTabel/index1.vue';
+  import ManagerWarningDeviceTable from './warningTabel/index2.vue';
+  import BackWindDeviceTable from './warningTabel/index3.vue';
+  import AccidentPlanTable from './warningTabel/index4.vue';
+  import LEDPlaylistTable from './warningTabel/index5.vue';
+  import WorkFacePointTable from './pointTabel/WorkFacePointTable.vue';
+  import WorkFaceReportTable from './pointTabel/WorkFaceReportTable.vue';
+  import DeviceReportInfo from './DeviceReportInfo.vue';
+  // import editWarnTable from './editWarnTable/index.vue'
+  import FanLineModal from './FanLineModal .vue';
+  import FormModal from './FormModal.vue';
+  import { cloneDeep } from 'lodash-es';
+  import { columns as pointColumns, workFaceColumns, simulationColumns, reportColumns } from './pointTabel/point.data';
+  import { saveOrUpdate as pointSaveOrUpdate, deleteById as pointDeleteById } from './pointTabel/point.api';
+  import { columns as cameraColumns } from './cameraTabel/camera.data';
 
-import { list as cameraList, saveOrUpdate as cameraSaveOrUpdate, deleteById as cameraDeleteById } from './cameraTabel/camera.api';
+  import { list as cameraList, saveOrUpdate as cameraSaveOrUpdate, deleteById as cameraDeleteById } from './cameraTabel/camera.api';
 
-const props = defineProps({
-  showTab: { type: Boolean, required: true },
-  // deviceType: { type: String },
-});
-// 声明Emits
-const emit = defineEmits(['saveOrUpdate', 'register', 'closeModal']);
-const isUpdate = inject('isUpdate');
-const deviceData = inject('formData') as any;
-const deviceType = inject('deviceType') as any;
-const record = reactive({});
-const activeKey = ref('1');
-const linkColumns = ref<any[]>([]);
+  const props = defineProps({
+    showTab: { type: Boolean, required: true },
+    // deviceType: { type: String },
+  });
+  // 声明Emits
+  const emit = defineEmits(['saveOrUpdate', 'register', 'closeModal']);
+  const isUpdate = inject('isUpdate');
+  const deviceData = inject('formData') as any;
+  const deviceType = inject('deviceType') as any;
+  const record = reactive({});
+  const activeKey = ref('1');
+  const linkColumns = ref<any[]>([]);
 
-//表单赋值
-const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
-  //重置表单
-  setModalProps({ confirmLoading: false });
-  Object.assign(deviceData, data.record);
-  // 判断是否是关键阻力路线
-});
+  //表单赋值
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+    //重置表单
+    setModalProps({ confirmLoading: false });
+    Object.assign(deviceData, data.record);
+    // 判断是否是关键阻力路线
+  });
 
-//设置标题
-const title = computed(() => {
-  if (!unref(isUpdate)) {
-    if (deviceData.strname || deviceData.systemname) {
-      return `新增(${deviceData.strname || deviceData.systemname})`;
-    }
-    return `新增`;
-  } else {
-    if (deviceData['strtype'] == 'sys_majorpath') {
-      linkColumns.value = [
-        ...workFaceColumns,
-        ...[
-          {
-            title: '是否在关键通风路线上',
-            width: 100,
-            dataIndex: 'pathflag',
-            edit: true,
-            editComponent: 'Switch',
-            editValueMap: (value) => {
-              return value ? '是' : '否';
+  //设置标题
+  const title = computed(() => {
+    if (!unref(isUpdate)) {
+      if (deviceData.strname || deviceData.systemname) {
+        return `新增(${deviceData.strname || deviceData.systemname})`;
+      }
+      return `新增`;
+    } else {
+      if (deviceData['strtype'] == 'sys_majorpath') {
+        linkColumns.value = [
+          ...workFaceColumns,
+          ...[
+            {
+              title: '是否在关键通风路线上',
+              width: 100,
+              dataIndex: 'pathflag',
+              edit: true,
+              editComponent: 'Switch',
+              editValueMap: (value) => {
+                return value ? '是' : '否';
+              },
             },
-          },
-          {
-            title: '传感器类型',
-            width: 100,
-            dataIndex: 'sensorType',
-            edit: true,
-            editComponent: 'Select',
-            editComponentProps: {
-              options: [
-                {
-                  label: '多参',
-                  value: '1',
-                },
-                {
-                  label: '测风',
-                  value: '2',
-                },
-              ],
+            {
+              title: '传感器类型',
+              width: 100,
+              dataIndex: 'sensorType',
+              edit: true,
+              editComponent: 'Select',
+              editComponentProps: {
+                options: [
+                  {
+                    label: '多参',
+                    value: '1',
+                  },
+                  {
+                    label: '测风',
+                    value: '2',
+                  },
+                ],
+              },
             },
-          },
-          {
-            title: '风向',
-            width: 100,
-            dataIndex: 'winddir',
-            edit: true,
-            editComponent: 'Select',
-            editComponentProps: {
-              options: [
-                {
-                  label: '进风',
-                  value: '1',
-                },
-                {
-                  label: '用风',
-                  value: '2',
-                },
-                {
-                  label: '回风',
-                  value: '3',
-                },
-              ],
+            {
+              title: '风向',
+              width: 100,
+              dataIndex: 'winddir',
+              edit: true,
+              editComponent: 'Select',
+              editComponentProps: {
+                options: [
+                  {
+                    label: '进风',
+                    value: '1',
+                  },
+                  {
+                    label: '用风',
+                    value: '2',
+                  },
+                  {
+                    label: '回风',
+                    value: '3',
+                  },
+                ],
+              },
             },
-          },
-          {
-            title: '是否总风量',
-            width: 100,
-            dataIndex: 'windflag',
-            edit: true,
-            editComponent: 'Switch',
-            editValueMap: (value) => {
-              return value ? '是' : '否';
+            {
+              title: '是否总风量',
+              width: 100,
+              dataIndex: 'windflag',
+              edit: true,
+              editComponent: 'Switch',
+              editValueMap: (value) => {
+                return value ? '是' : '否';
+              },
             },
-          },
-          {
-            title: '路线名称',
-            width: 100,
-            dataIndex: 'des',
-            edit: true,
-            editComponent: 'Input',
-          },
-          {
-            title: ' 阻力值',
-            width: 100,
-            dataIndex: 'testDrag',
-            edit: true,
-            editComponent: 'InputNumber',
-          },
-        ],
-      ];
-    } else {
-      linkColumns.value = [...workFaceColumns];
-    }
-    if (deviceData.strname || deviceData.systemname) {
-      return `编辑(${deviceData.strname || deviceData.systemname})`;
+            {
+              title: '路线名称',
+              width: 100,
+              dataIndex: 'des',
+              edit: true,
+              editComponent: 'Input',
+            },
+            {
+              title: ' 阻力值',
+              width: 100,
+              dataIndex: 'testDrag',
+              edit: true,
+              editComponent: 'InputNumber',
+            },
+          ],
+        ];
+      } else {
+        linkColumns.value = [...workFaceColumns];
+      }
+      if (deviceData.strname || deviceData.systemname) {
+        return `编辑(${deviceData.strname || deviceData.systemname})`;
+      }
+      return `编辑`;
     }
-    return `编辑`;
-  }
-});
+  });
 
-const closeModalFn = () => {
-  activeKey.value = '1';
-  closeModal();
-  emit('closeModal');
-};
+  const closeModalFn = () => {
+    activeKey.value = '1';
+    closeModal();
+    emit('closeModal');
+  };
 
-const savePointData = (data) => {
-  const record = cloneDeep(data.editValueRefs);
-  pointSaveOrUpdate(Object.assign(record, { id: data.id, deviceId: deviceData.id }), data.id);
-};
-const saveCameraData = (data: any, reload: Function) => {
-  cameraSaveOrUpdate(Object.assign({ ...data }, { id: data.id, deviceid: deviceData.id }), data.id);
-};
-const deletePointById = (id, reload) => {
-  pointDeleteById({ id: id }, reload);
-};
-const deleteCameraById = (id, reload) => {
-  cameraDeleteById({ id: id }, reload);
-};
+  const savePointData = (data) => {
+    const record = cloneDeep(data.editValueRefs);
+    pointSaveOrUpdate(Object.assign(record, { id: data.id, deviceId: deviceData.id }), data.id);
+  };
+  const saveCameraData = (data: any, reload: Function) => {
+    cameraSaveOrUpdate(Object.assign({ ...data }, { id: data.id, deviceid: deviceData.id }), data.id);
+  };
+  const deletePointById = (id, reload) => {
+    pointDeleteById({ id: id }, reload);
+  };
+  const deleteCameraById = (id, reload) => {
+    cameraDeleteById({ id: id }, reload);
+  };
 </script>
 <style scoped lang="less">
-::v-deep .suffix {
-  height: 32px;
-  line-height: 32px;
-  margin-left: 5px;
-  color: #fff;
-}
+  ::v-deep .suffix {
+    height: 32px;
+    line-height: 32px;
+    margin-left: 5px;
+    color: #fff;
+  }
 </style>

+ 0 - 224
src/views/vent/deviceManager/comment/pointTabel/WorkFacePointTable copy.vue

@@ -1,224 +0,0 @@
-<template>
-  <div class="p-4">
-    <div class="btm-group vent-flex-row-between">
-      <div>
-        <label style="color: #fff">设备类型:</label>
-        <ApiTreeSelect
-          @change="handleChange"
-          :api="deviceList.bind(null, { devicetype: '' })"
-          :fieldNames="{ children: 'children', label: 'itemText', value: 'itemValue' }"
-          v-model:value="deviceKind"
-          style="width: 200px"
-        />
-        <a-button type="primary" @click="addRow"> 新增 </a-button>
-      </div>
-      <div>
-        <a-button type="primary" @click="handleSave"> 保存 </a-button>
-      </div>
-    </div>
-    <BasicTable @register="registerTable" :dataSource="dataSource" :columns="workFaceColumns" @edit-change="onEditChange">
-      <template #action="{ record, column }">
-        <TableAction :actions="createActions(record, column)" />
-      </template>
-    </BasicTable>
-    <DeviceModalTable
-      @register="registerModal"
-      :deviceType="deviceKind"
-      :deviceID="deviceId"
-      @reload="getWorkFaceList"
-      :selectionRowKeys="selectionRowKeys"
-    />
-  </div>
-</template>
-<script lang="ts">
-  import { defineComponent, ref, nextTick, inject, onMounted } from 'vue';
-  import { BasicTable, useTable, TableAction, BasicColumn, ActionItem, EditRecordRow } from '/@/components/Table';
-  import { useModal } from '/@/components/Modal';
-  import { ApiTreeSelect } from '/@/components/Form';
-  import DeviceModalTable from './DeviceModalTable.vue';
-  import { deviceId, workDeviceList, deviceList, list, edit } from './point.api';
-  import { workFaceColumns, deviceColumns } from './point.data';
-
-  export default defineComponent({
-    components: { BasicTable, TableAction, DeviceModalTable, ApiTreeSelect },
-    props: {
-      columns: {
-        type: Array,
-        requried: true,
-      },
-      deviceId: {
-        type: String || Number,
-        requried: true,
-      },
-      list: {
-        type: Function,
-        requried: true,
-      },
-      isAdd: {
-        type: Boolean,
-      },
-    },
-    emits: ['save', 'delete'],
-    setup(props, { emit }) {
-      const activeTab = ref('1');
-      const deviceKind = ref('');
-      const type = inject('deviceType') || '';
-
-      const currentEditKeyRef = ref('');
-      const options = ref([]);
-
-      const dataSource = ref<any>([]);
-      const selectionRowKeys = ref<any[]>([]);
-
-      const [registerModal, { openModal }] = useModal();
-
-      const [registerTable, { insertTableDataRecord, reload }] = useTable({
-        title: '',
-        showIndexColumn: true,
-        showTableSetting: false,
-        tableSetting: { fullScreen: true },
-        actionColumn: {
-          width: 160,
-          title: '操作',
-          dataIndex: 'action',
-          slots: { customRender: 'action' },
-        },
-      });
-
-      function addRow() {
-        openModal();
-      }
-
-      function handleEdit(record: EditRecordRow) {
-        currentEditKeyRef.value = record.key;
-        record.onEdit?.(true);
-      }
-
-      function handleCancel(record: EditRecordRow) {
-        currentEditKeyRef.value = '';
-        record.onEdit?.(false, false);
-      }
-
-      function handleDelete(record: EditRecordRow) {
-        emit('delete', record.id, reload);
-      }
-      async function getOptions() {
-        const res = await deviceList({ devicetype: '' });
-        options.value = res;
-        deviceKind.value = options.value[0]['itemValue'];
-        getWorkFaceList();
-      }
-
-      function getWorkFaceList() {
-        workDeviceList({ deviceKind: deviceKind.value, sysId: props.deviceId }).then((res) => {
-          dataSource.value = res['records'];
-          selectionRowKeys.value = dataSource.value.map((item) => item.deviceId) || [];
-        });
-      }
-
-      function handleChange(id) {
-        deviceKind.value = id;
-        getWorkFaceList();
-      }
-
-      async function handleSave(record: EditRecordRow) {
-        dataSource.value.filter((item) => {
-          if (record.id && record.id === item.id) {
-            Object.assign(item, record.editValueRefs);
-          }
-        });
-        console.log('[ dataSource ] >', dataSource.value, record);
-        // 校验
-        await edit(dataSource.value);
-        record.editable = false;
-      }
-
-      function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
-        if (!record.editable) {
-          if (props.isAdd) {
-            return [
-              {
-                label: '编辑',
-                disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-                onClick: handleEdit.bind(null, record),
-              },
-              {
-                label: '删除',
-                disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-                onClick: handleDelete.bind(null, record),
-              },
-            ];
-          } else {
-            return [
-              {
-                label: '编辑',
-                disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-                onClick: handleEdit.bind(null, record),
-              },
-            ];
-          }
-        }
-        return [
-          {
-            label: '保存',
-            onClick: handleSave.bind(null, record, column),
-          },
-          {
-            label: '取消',
-            popConfirm: {
-              title: '是否取消编辑',
-              confirm: handleCancel.bind(null, record, column),
-            },
-          },
-        ];
-      }
-
-      function onEditChange({ column, value, record }) {
-        // 本例
-        if (column.dataIndex === 'devicetype') {
-          // record.editValueRefs.name4.value = `${value}`;
-        }
-        // console.log(column, value, record);
-      }
-
-      onMounted(async () => {
-        await getOptions();
-        getWorkFaceList();
-      });
-
-      return {
-        activeTab,
-        registerTable,
-        handleEdit,
-        createActions,
-        onEditChange,
-        addRow,
-        workFaceColumns,
-        deviceColumns,
-        getOptions,
-        options,
-        deviceList,
-        dataSource,
-        deviceKind,
-        handleChange,
-        registerModal,
-        handleSave,
-        selectionRowKeys,
-        getWorkFaceList,
-        // handleChangeDeviceType,
-        // handleChangeLinkCode,
-        // monitorParamsOptions,
-      };
-    },
-  });
-</script>
-<style scoped lang="less">
-  @ventSpace: zxm;
-  
-  :deep(.@{ventSpace}-table-body) {
-    height: auto !important;
-  }
-  .btm-group {
-    padding-bottom: 2px;
-  }
-</style>

+ 278 - 0
src/views/vent/deviceManager/comment/pointTabel/WorkFaceReportTable.vue

@@ -0,0 +1,278 @@
+<template>
+  <div class="p-4">
+    <div class="btm-group vent-flex-row-between">
+      <div class="mb-10px">
+        <JDictSelectTag v-model:value="deviceKind" placeholder="请输入设备类型" dictCode="analyReportType" />
+        <a-button class="ml-5px mr-5px" type="primary" @click="handleAddDevices"> 新增 </a-button>
+        <a-button type="primary" @click="handleAssoicate"> 自动关联 </a-button>
+      </div>
+      <!-- <a-button class="vent-margin-l-10" type="primary" @click="handleSave()"> 批量保存 </a-button> -->
+    </div>
+    <BasicTable ref="editTable" @register="registerTable">
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: '查看报表数据',
+              onClick: () => handlePreview(record),
+            },
+            {
+              label: '删除',
+              popConfirm: {
+                title: '确认删除?',
+                confirm: () => handleDelete(record),
+              },
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+    <BasicModal title="手动关联报表数据" width="800px" @register="registerModal">
+      <a-button type="primary" @click="handleSaveSelection"> 批量保存 </a-button>
+      <BasicTable @register="registerTable2">
+        <template #action="{ record }">
+          <TableAction
+            :actions="[
+              {
+                label: '保存',
+                onClick: () => handleSave(record),
+              },
+            ]"
+          />
+        </template>
+      </BasicTable>
+    </BasicModal>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, nextTick, watch } from 'vue';
+  import { BasicModal, useModal } from '/@/components/Modal';
+  import { BasicTable, useTable, TableAction } from '/@/components/Table';
+  import {
+    deviceList,
+    sceneReportAssociationList,
+    sceneReportAssociationDelete,
+    findPotentialAssociations,
+    autoAssociate,
+    manualAssociate,
+  } from './point.api';
+  import { reportColumns } from './point.data';
+  import { message, Modal } from 'ant-design-vue';
+  import { JDictSelectTag } from '/@/components/Form';
+  import { JsonPreview } from '/@/components/CodeEditor';
+  import { h } from 'vue';
+
+  export default defineComponent({
+    components: { BasicTable, TableAction, BasicModal, JDictSelectTag },
+    props: {
+      columns: {
+        type: Array<any>,
+        requried: true,
+      },
+      device: {
+        type: Object,
+        requried: true,
+        default: () => ({}),
+      },
+    },
+    emits: ['save', 'delete'],
+    setup(props) {
+      const deviceKind = ref('');
+
+      const [registerModal, { openModal }] = useModal();
+
+      const [registerTable, tableCtx] = useTable({
+        columns: props.columns,
+        title: '',
+        api: ({ pageNo, pageSize }) => {
+          return sceneReportAssociationList({
+            pageNo,
+            pageSize,
+            sceneId: props.device.id,
+          });
+        },
+        showIndexColumn: true,
+        showTableSetting: false,
+        tableSetting: { fullScreen: true },
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+        },
+      });
+
+      const [registerTable2, tableCtx2] = useTable({
+        columns: reportColumns,
+        api() {
+          return findPotentialAssociations({ sceneName: props.device.systemname, reportType: deviceKind.value });
+        },
+        pagination: false,
+        rowSelection: { type: 'checkbox' },
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+        },
+      });
+
+      function handleSave(record) {
+        return manualAssociate([
+          {
+            ...record,
+            sceneId: props.device.id,
+          },
+        ])
+          .then((res) => {
+            message.success(res);
+            tableCtx.reload();
+            tableCtx2.reload();
+          })
+          .catch((res) => {
+            message.error(res.message);
+          });
+      }
+      function handleSaveSelection() {
+        return manualAssociate(
+          tableCtx2.getSelectRows().map((e) => ({
+            ...e,
+            sceneId: props.device.id,
+          }))
+        )
+          .then((res) => {
+            message.success(res);
+            tableCtx.reload();
+            tableCtx2.reload();
+          })
+          .catch((res) => {
+            message.error(res.message);
+          });
+      }
+      function handleDelete(record) {
+        return sceneReportAssociationDelete({
+          id: record.id,
+        })
+          .then((res) => {
+            message.success(res);
+            tableCtx.reload();
+          })
+          .catch((res) => {
+            message.error(res.message);
+          });
+      }
+      function handleAssoicate() {
+        if (!deviceKind.value) return message.info('请选择设备类型');
+        return autoAssociate({
+          reportType: deviceKind.value,
+        })
+          .then((res) => {
+            message.success(res);
+            tableCtx.reload();
+          })
+          .catch((res) => {
+            message.error(res.message);
+          });
+      }
+      function handlePreview(record) {
+        Modal.info({
+          title: record.reportPointName,
+          width: 700,
+          content: h(JsonPreview, {
+            data: record.reportJsonData,
+            style: { backgroundColor: '#333', marginRight: '38px' },
+          }),
+        });
+      }
+
+      function handleAddDevices() {
+        if (!deviceKind.value) return message.info('请选择设备类型');
+        openModal();
+        nextTick(() => tableCtx2.reload());
+      }
+
+      watch(
+        () => props.columns,
+        (columns = []) => {
+          // linkColumns.value = columns
+          // reload()
+          tableCtx.setColumns(columns);
+        }
+      );
+
+      return {
+        registerTable,
+        registerTable2,
+        deviceKind,
+        deviceList,
+        registerModal,
+        handleAddDevices,
+        handleSave,
+        handleAssoicate,
+        handleDelete,
+        handleSaveSelection,
+        handlePreview,
+      };
+    },
+  });
+</script>
+<style scoped lang="less">
+  @ventSpace: zxm;
+
+  :deep(.@{ventSpace}-table-body) {
+    height: auto !important;
+  }
+  .btm-group {
+    padding-bottom: 2px;
+  }
+  .device-button-group {
+    // margin: 0 20px;
+    display: flex;
+    flex-wrap: wrap;
+    pointer-events: auto;
+    position: relative;
+    margin-top: 10px;
+    margin-bottom: 5px;
+    &::after {
+      position: absolute;
+      content: '';
+      width: calc(100% + 10px);
+      height: 2px;
+      top: 30px;
+      left: -10px;
+      border-bottom: 1px solid #0efcff;
+    }
+    .device-button {
+      padding: 4px 10px;
+      position: relative;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      font-size: 14px;
+
+      color: #fff;
+      cursor: pointer;
+      margin: 0 1px;
+
+      &::before {
+        content: '';
+        position: absolute;
+        top: 0;
+        right: 0;
+        bottom: 0;
+        left: 0;
+        border: 1px solid #6176af;
+        // transform: skewX(-38deg);
+        background-color: rgba(0, 77, 103, 85%);
+        z-index: -1;
+      }
+    }
+    .device-active {
+      // color: #0efcff;
+      &::before {
+        border-color: #0efcff;
+        box-shadow: 1px 1px 3px 1px #0efcff inset;
+      }
+    }
+  }
+</style>

+ 21 - 0
src/views/vent/deviceManager/comment/pointTabel/point.api.ts

@@ -27,6 +27,16 @@ enum Api {
 
   workRelevanceDeviceTypes = '/safety/managesysDevice/typelist',
   workRelevanceDeviceDelete = '/safety/managesysDevice/delete',
+
+  autoAssociate = '/safety/sceneReportAssociation/autoAssociate',
+  sceneReportAssociationDelete = '/safety/sceneReportAssociation/delete',
+  sceneReportAssociationDeleteBatch = '/safety/sceneReportAssociation/deleteBatch',
+  sceneReportAssociationEdit = '/safety/sceneReportAssociation/edit',
+  findPotentialAssociations = '/safety/sceneReportAssociation/findPotentialAssociations',
+  sceneReportAssociationList = '/safety/sceneReportAssociation/list',
+  manualAssociate = '/safety/sceneReportAssociation/manualAssociate',
+  queryReportData = '/safety/sceneReportAssociation/queryReportData',
+  queryPageList = '/safety/sceneReportAssociation/queryPageList',
 }
 /**
  * 导出api
@@ -144,3 +154,14 @@ export const workRelevanceDeviceDelete = (params, handleSuccess) => {
     handleSuccess();
   });
 };
+
+export const autoAssociate = (params) => defHttp.post({ url: Api.autoAssociate, params });
+export const sceneReportAssociationDelete = (params) => defHttp.delete({ url: Api.sceneReportAssociationDelete, params }, { joinParamsToUrl: true });
+export const sceneReportAssociationDeleteBatch = (params) =>
+  defHttp.delete({ url: Api.sceneReportAssociationDeleteBatch, params }, { joinParamsToUrl: true });
+export const sceneReportAssociationEdit = (params) => defHttp.put({ url: Api.sceneReportAssociationEdit, params });
+export const findPotentialAssociations = (params) => defHttp.get({ url: Api.findPotentialAssociations, params });
+export const sceneReportAssociationList = (params) => defHttp.get({ url: Api.sceneReportAssociationList, params });
+export const manualAssociate = (params) => defHttp.post({ url: Api.manualAssociate, params });
+export const queryReportData = (params) => defHttp.get({ url: Api.queryReportData, params });
+export const queryPageList = (params) => defHttp.get({ url: Api.queryPageList, params });

+ 7 - 0
src/views/vent/deviceManager/comment/pointTabel/point.data.ts

@@ -201,3 +201,10 @@ export const workFaceColumns: BasicColumn[] = [
   //   },
   // },
 ];
+
+export const reportColumns: BasicColumn[] = [
+  {
+    title: '测点名称',
+    dataIndex: 'reportPointName',
+  },
+];

+ 24 - 4
src/views/vent/home/configurable/fireTS.vue

@@ -67,7 +67,11 @@
       :visible="true"
       :common-title="commonTitle"
     />
-    <Three3D :modal-name="modalName" />
+    <!-- <Three3D :modal-name="modalName" /> -->
+    <!-- 工作面二维图像 -->
+    <div class="workFace-content">
+      <div class="workFace-bg"></div>
+    </div>
   </div>
 </template>
 <script lang="ts" setup>
@@ -77,9 +81,9 @@
   // import { testConfigTSFire } from './configurable.data.tashan';
   import ModuleCommon from './components/ModuleCommon.vue';
   import ModuleCommonDual from './components/ModuleCommonDual.vue';
-  import Three3D from './components/three3D.vue';
+  // import Three3D from './components/three3D.vue';
 
-  const modalName = ref('workFace11');
+  // const modalName = ref('workFace11');
   const cfgs = computed(() => configs.value.filter((_, index) => index !== 6 && index !== 7 && index !== 8));
   const cfgA = computed<any>(() => configs.value[6]);
   const cfgB = computed<any>(() => configs.value[7]);
@@ -297,7 +301,7 @@
     }
     // 顶部中间样式块
     .center-info-bar {
-      position: relative;
+      position: absolute;
       top: 75px;
       left: 50%;
       transform: translateX(-50%);
@@ -439,5 +443,21 @@
     ::v-deep .table__content .table__content_label {
       width: 95%;
     }
+    .workFace-content {
+      width: 100%;
+      height: 100%;
+      position: relative;
+      .workFace-bg {
+        width: 1000px;
+        height: 320px;
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        background: url('/src/assets/images/home-container/configurable/tashanhome/workFace.png') no-repeat center;
+        background-size: 100% 100%;
+        z-index: 0;
+      }
+    }
   }
 </style>

+ 27 - 2
src/views/vent/monitorManager/deviceMonitor/components/device/device.data.ts

@@ -554,6 +554,9 @@ export const noWarningArr = [
   'gate_linkdlfm',
   'substation_normal',
   'safetymonitor',
+  'bundleReport',
+  'bundleSpyReport',
+  'dustReport',
 ]; // 无预警详情的
 export const haveSysDetailArr = ['forcFan', 'pulping']; //有场景详情的
 
@@ -569,5 +572,27 @@ export const noLocationArr = () => {
 };
 export const noHistoryArr = () =>
   History_Type['type'] == 'remote'
-    ? ['surface_history', 'gasDayReport', 'dustDayReport', 'bundleDayReport', 'bundleSpyDayReport', 'gasDay', 'gate_linkdlfm']
-    : ['gasDayReport', 'dustDayReport', 'bundleDayReport', 'bundleSpyDayReport', 'gate_linkdlfm', 'gasDay', 'substation_normal'];
+    ? [
+        'surface_history',
+        'gasDayReport',
+        'dustDayReport',
+        'bundleDayReport',
+        'bundleSpyDayReport',
+        'gasDay',
+        'gate_linkdlfm',
+        'bundleReport',
+        'bundleSpyReport',
+        'dustReport',
+      ]
+    : [
+        'gasDayReport',
+        'dustDayReport',
+        'bundleDayReport',
+        'bundleSpyDayReport',
+        'gate_linkdlfm',
+        'gasDay',
+        'substation_normal',
+        'bundleReport',
+        'bundleSpyReport',
+        'dustReport',
+      ];

+ 36 - 23
src/views/vent/monitorManager/deviceMonitor/components/device/index.vue

@@ -171,9 +171,11 @@
               deviceType.startsWith('gasDay_normal')
                 ? '当日巡检监测'
                 : deviceType.startsWith('dustDayReport') ||
-                  deviceType.startsWith('dustDayReport') ||
                   deviceType.startsWith('bundleDayReport') ||
-                  deviceType.startsWith('bundleSpyDayReport')
+                  deviceType.startsWith('bundleSpyDayReport') ||
+                  deviceType.startsWith('bundleReport') ||
+                  deviceType.startsWith('bundleSpyReport') ||
+                  deviceType.startsWith('dustReport')
                 ? '最新监测报表'
                 : '实时监测'
             "
@@ -670,7 +672,6 @@
     surfaceChartsColumns,
     noHistoryArr,
     getMonitorComponent,
-    vehicleFormConfig,
     noLocationArr,
     haveHistoryEcharts,
   } from './device.data';
@@ -809,7 +810,7 @@
 
   function tabChange(activeKeyVal) {
     activeKey.value = activeKeyVal;
-    // router.push({ path: route.path, query: { ...route.query, tabtype: activeKey.value } });
+    router.push({ path: route.path, query: { ...route.query, tabtype: activeKey.value } });
   }
 
   function showTree(flag, value) {
@@ -897,25 +898,38 @@
           const readData = data.readData;
           return Object.assign(data, readData);
         });
-        if (item.type != 'sys') {
-          if (item.type === 'majorpath') {
-            deviceArr.unshift({ deviceType: item.type, deviceName: item['typeName'], datalist: item['datalist'][0]['paths'] });
-            majorPathEchartsData.value = item['datalist'][0];
-          } else if (item.type.startsWith('surface_history')) {
-            surfaceEchartsData.value = item['datalist'][0];
-            deviceArr.unshift({
-              deviceType: item.type,
-              deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'],
-              datalist: data,
-            });
-          } else {
-            deviceArr.unshift({
-              deviceType: item.type,
-              deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'],
-              datalist: data,
-            });
-          }
+
+        // 如果查出的所有设备里,设备类型是sys的,标识其是系统总体,不应显示在设备列表中
+        if (item.type == 'sys') return;
+
+        // majorpath关键线路需要显示图表
+        if (item.type === 'majorpath') {
+          deviceArr.unshift({ deviceType: item.type, deviceName: item['typeName'], datalist: item['datalist'][0]['paths'] });
+          return (majorPathEchartsData.value = item['datalist'][0]);
         }
+        // 工作面历史数据需要显示图表
+        if (item.type.startsWith('surface_history')) {
+          surfaceEchartsData.value = item['datalist'][0];
+          return deviceArr.unshift({
+            deviceType: item.type,
+            deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'],
+            datalist: data,
+          });
+        }
+        // 其余的存在 subtype 的(一般为报表)仅需显示报表表格,同时它们一版都排在后面
+        if (item.subtype) {
+          return deviceArr.push({
+            deviceType: item.subtype,
+            deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'],
+            datalist: data,
+          });
+        }
+
+        deviceArr.unshift({
+          deviceType: item.type,
+          deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'],
+          datalist: data,
+        });
       });
 
       deviceList.value = deviceArr;
@@ -1350,7 +1364,6 @@
     if (activeKey.value == '4' && handlerHistoryTable.value) {
       handlerHistoryTable.value.setLoading(true);
     }
-    router.push({ path: route.path, query: { ...route.query, deviceActive: deviceActive.value } });
   }
   /**
    * 设置巷道设备定位图标的显示与隐藏

+ 9 - 5
src/views/vent/monitorManager/windrectMonitor/index.vue

@@ -149,7 +149,7 @@
 
 <script setup lang="ts">
   import DeviceEcharts from '../comment/DeviceEcharts.vue';
-  import { unref, onBeforeMount, ref, onMounted, onUnmounted, reactive, toRaw, nextTick, inject } from 'vue';
+  import { unref, onBeforeMount, ref, onMounted, onUnmounted, reactive, toRaw, nextTick, inject, shallowRef } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import MonitorTable from '../comment/MonitorTable.vue';
   import ModalTable from './components/modalTable.vue';
@@ -183,7 +183,7 @@
   const { currentRoute } = useRouter();
   const modelRef = ref();
   /** 模型对应的组件,根据实际情况分为二维三维 */
-  let modelComponent = getModelComponent(true, sysOrgCode);
+  let modelComponent = shallowRef(getModelComponent(globalConfig.is2DModel));
 
   const MonitorDataTable = ref();
   const scroll = reactive({
@@ -385,7 +385,7 @@
       const selectedData = toRaw(dataSource.value[selectRowIndex.value]);
       Object.assign(selectData, selectedData);
       addMonitorText(selectData);
-      palyAnimation(selectedData);
+      if (selectedData) palyAnimation(selectedData);
     }
   }
   let deviceRunState = '',
@@ -723,7 +723,7 @@
        * 模型对应的组件,根据实际情况分为二维三维
        * 这里传入类型type而不是sysOrgCode进行判断展示哪个装置
        * */
-      modelComponent = getModelComponent(true, type);
+      if (globalConfig.is2DModel) await setSVGModelType(type);
       await setModelType(type);
       loading.value = false;
       deviceRunState = '';
@@ -731,7 +731,11 @@
       await getCamera(selectRow.deviceID, playerRef.value);
     }
   }
-
+  // 设置模型类型
+  function setSVGModelType(type) {
+    modelComponent.value = getModelComponent(globalConfig.is2DModel, type);
+    return nextTick();
+  }
   /* 一键测风 */
   function handleOk() {
     modalType.value = 'multiple';

+ 9 - 5
src/views/vent/monitorManager/windrectMonitor/windrect.data.ts

@@ -428,16 +428,20 @@ export const option = {
     rotate: 40,
   },
 };
-export function getModelComponent(is2DModel: boolean = false, sysOrgCode?: string) {
+const componentsCaches = new Map<string, any>();
+export function getModelComponent(is2DModel: boolean = false, type: string = '') {
   // @ts-ignore
   return defineAsyncComponent(() => {
     if (!is2DModel) return import('./components/entryThree.vue');
-    switch (sysOrgCode) {
-      // 这里配置测风装置类型,也可通过sysOrgCode来进行判断
+    // 为了支持SVG组件切换时不闪烁,先行下载并缓存
+    if (!componentsCaches.has('scanSVG')) componentsCaches.set('scanSVG', import('./components/scanSVG.vue'));
+    if (!componentsCaches.has('fixedSVG')) componentsCaches.set('fixedSVG', import('./components/fixedSVG.vue'));
+    switch (type) {
+      // 这里配置测风装置类型和对应的组件
       case 'dsWindRect_move':
-        return import('./components/scanSVG.vue');
+        return componentsCaches.get('scanSVG');
       default:
-        return import('./components/fixedSVG.vue');
+        return componentsCaches.get('fixedSVG');
     }
   });
 }