Przeglądaj źródła

[Feat 0000]控制点位关联功能开发

bobo04052021@163.com 2 dni temu
rodzic
commit
620f32d8f1

+ 3 - 8
src/views/vent/deviceManager/comment/DeviceModal.vue

@@ -31,14 +31,8 @@
           @delete="deletePointById"
         />
       </a-tab-pane>
-      <a-tab-pane v-if="deviceType === 'gate'" key="15" tab="控制点位关联">
-        <PointTable
-          :columns="pointColumns"
-          :pointType="deviceData.strtype"
-          :deviceId="deviceData.id"
-          @save="savePointData"
-          @delete="deletePointById"
-        />
+      <a-tab-pane key="15" tab="控制点位关联">
+        <CtrlTable :deviceId="deviceData.id" :deviceType="deviceData.strtype" />
       </a-tab-pane>
       <a-tab-pane key="8" tab="虚拟点表配置">
         <PointTable
@@ -118,6 +112,7 @@ 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 CtrlTable from './warningTabel/ctrlTable.vue';
 import WorkFaceReportTable from './pointTabel/WorkFaceReportTable.vue';
 import DeviceReportInfo from './DeviceReportInfo.vue';
 import FaultConfigTable from './faultConfigTable/index.vue';

+ 195 - 195
src/views/vent/deviceManager/comment/pointTabel/PointTable.vue

@@ -43,219 +43,219 @@
   </div>
 </template>
 <script lang="ts">
-  import { defineComponent, ref, nextTick, inject, onMounted } from 'vue';
-  import { BasicTable, useTable, TableAction, BasicColumn, ActionItem, EditRecordRow } from '/@/components/Table';
-  import { Select } from 'ant-design-vue';
-  import { ApiTreeSelect } from '/@/components/Form';
-  import { deviceId, getDeviceId, deviceList, list, pointEdit } from './point.api';
-  // import { nextTick } from 'process';
+import { defineComponent, ref, nextTick, inject, onMounted } from 'vue';
+import { BasicTable, useTable, TableAction, BasicColumn, ActionItem, EditRecordRow } from '/@/components/Table';
+import { Select } from 'ant-design-vue';
+import { ApiTreeSelect } from '/@/components/Form';
+import { deviceId, getDeviceId, deviceList, list, pointEdit } from './point.api';
+// import { nextTick } from 'process';
 
-  export default defineComponent({
-    components: { BasicTable, TableAction, Select, ApiTreeSelect },
-    props: {
-      columns: {
-        type: Array,
-        requried: true,
-      },
-      deviceId: {
-        type: String || Number,
-        requried: true,
-      },
-      valuetype: {
-        type: Number,
-        requried: true,
-      },
-      pointType: {
-        type: String,
-        requried: true,
-      },
-      list: {
-        type: Function,
-        requried: true,
-      },
-      isAdd: {
-        type: Boolean,
-      },
+export default defineComponent({
+  components: { BasicTable, TableAction, Select, ApiTreeSelect },
+  props: {
+    columns: {
+      type: Array,
+      requried: true,
     },
-    emits: ['save', 'delete'],
-    setup(props, { emit }) {
-      const deviceType = inject('deviceType');
-      const options = ref([]);
-      const monitorParamsOptions = ref([]);
-      const currentEditKeyRef = ref('');
-      const dataSource = ref<any>([]);
-      const [registerTable, { insertTableDataRecord, reload }] = useTable({
-        title: '',
-        columns: props.columns as BasicColumn[],
-        showIndexColumn: false,
-        showTableSetting: false,
-        tableSetting: { fullScreen: true },
-        actionColumn: {
-          width: 160,
-          title: '操作',
-          dataIndex: 'action',
-          slots: { customRender: 'action' },
-        },
+    deviceId: {
+      type: String || Number,
+      requried: true,
+    },
+    valuetype: {
+      type: Number,
+      requried: true,
+    },
+    pointType: {
+      type: String,
+      requried: true,
+    },
+    list: {
+      type: Function,
+      requried: true,
+    },
+    isAdd: {
+      type: Boolean,
+    },
+  },
+  emits: ['save', 'delete'],
+  setup(props, { emit }) {
+    const deviceType = inject('deviceType');
+    const options = ref([]);
+    const monitorParamsOptions = ref([]);
+    const currentEditKeyRef = ref('');
+    const dataSource = ref<any>([]);
+    const [registerTable, { insertTableDataRecord, reload }] = useTable({
+      title: '',
+      columns: props.columns as BasicColumn[],
+      showIndexColumn: false,
+      showTableSetting: false,
+      tableSetting: { fullScreen: true },
+      actionColumn: {
+        width: 160,
+        title: '操作',
+        dataIndex: 'action',
+        slots: { customRender: 'action' },
+      },
+    });
+    const filterOption = (input: string, option: any) => {
+      return option.deviceName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
+    };
+    function addRow() {
+      const record = {} as EditRecordRow;
+      insertTableDataRecord(record);
+      nextTick(() => {
+        handleEdit(record);
       });
-      const filterOption = (input: string, option: any) => {
-        return option.deviceName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
-      };
-      function addRow() {
-        const record = {} as EditRecordRow;
-        insertTableDataRecord(record);
-        nextTick(() => {
-          handleEdit(record);
-        });
-      }
-      function handleEdit(record: EditRecordRow) {
-        currentEditKeyRef.value = record.key;
-        record.onEdit?.(true);
-        handleChange(record['link_id']);
-        handleChangeDeviceType(record['link_devicetype']);
-      }
-
-      function handleCancel(record: EditRecordRow) {
-        currentEditKeyRef.value = '';
-        record.onEdit?.(false, false);
-      }
+    }
+    function handleEdit(record: EditRecordRow) {
+      currentEditKeyRef.value = record.key;
+      record.onEdit?.(true);
+      handleChange(record['link_id']);
+      handleChangeDeviceType(record['link_devicetype']);
+    }
 
-      function handleDelete(record: EditRecordRow) {
-        emit('delete', record.id, reload);
-      }
-      function getOptions(value) {
-        console.log(value);
-      }
+    function handleCancel(record: EditRecordRow) {
+      currentEditKeyRef.value = '';
+      record.onEdit?.(false, false);
+    }
 
-      function handleChange(id, index?) {
-        if (!id) return;
-        if (index !== undefined) dataSource['value'][index]['link_id'] = id;
+    function handleDelete(record: EditRecordRow) {
+      emit('delete', record.id, reload);
+    }
+    function getOptions(value) {
+      console.log(value);
+    }
 
-        deviceId({ id: id }).then((res) => {
-          monitorParamsOptions.value = res;
-          console.log(res);
-        });
-      }
-      function handleSearch(val: string) {
-        return options.value.map((item) => {
-          return (item['deviceName'] as string).includes(val);
-        });
-      }
+    function handleChange(id, index?) {
+      if (!id) return;
+      if (index !== undefined) dataSource['value'][index]['link_id'] = id;
 
-      function handleChangeDeviceType(e, index?) {
-        if (!e) return;
-        if (index !== undefined) dataSource['value'][index]['link_devicetype'] = e;
-        getDeviceId({ devicetype: e }).then((res) => {
-          options.value = res;
-        });
-      }
+      deviceId({ id: id }).then((res) => {
+        monitorParamsOptions.value = res;
+        console.log(res);
+      });
+    }
+    function handleSearch(val: string) {
+      return options.value.map((item) => {
+        return (item['deviceName'] as string).includes(val);
+      });
+    }
 
-      function handleChangeLinkCode(e, index?) {
-        if (!e) return;
-        if (index !== undefined) dataSource['value'][index]['link_code'] = e;
-      }
+    function handleChangeDeviceType(e, index?) {
+      if (!e) return;
+      if (index !== undefined) dataSource['value'][index]['link_devicetype'] = e;
+      getDeviceId({ devicetype: e }).then((res) => {
+        options.value = res;
+      });
+    }
 
-      async function handleSave(record: EditRecordRow) {
-        dataSource.value.filter((item) => {
-          if (record.id && record.id === item.id) {
-            console.log(111);
-            Object.assign(item, record.editValueRefs);
-            item['test'] = '1212';
-            console.log(222, item, record.editValueRefs);
-          }
-        });
-        // await edit(dataSource.value);
-        await pointEdit({ deviceid: props.deviceId, linklist: dataSource.value });
-        currentEditKeyRef.value = '';
-        record.onEdit?.(false, false);
-        await getDataSource(props.pointType);
-      }
+    function handleChangeLinkCode(e, index?) {
+      if (!e) return;
+      if (index !== undefined) dataSource['value'][index]['link_code'] = e;
+    }
 
-      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),
-              },
-            ];
-          }
+    async function handleSave(record: EditRecordRow) {
+      dataSource.value.filter((item) => {
+        if (record.id && record.id === item.id) {
+          console.log(111);
+          Object.assign(item, record.editValueRefs);
+          item['test'] = '1212';
+          console.log(222, item, record.editValueRefs);
         }
-        return [
-          {
-            label: '保存',
-            onClick: handleSave.bind(null, record, column),
-          },
-          {
-            label: '取消',
-            popConfirm: {
-              title: '是否取消编辑',
-              confirm: handleCancel.bind(null, record, column),
+      });
+      // await edit(dataSource.value);
+      await pointEdit({ deviceid: props.deviceId, linklist: dataSource.value });
+      currentEditKeyRef.value = '';
+      record.onEdit?.(false, false);
+      await getDataSource(props.pointType);
+    }
+
+    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);
+    function onEditChange({ column, value, record }) {
+      // 本例
+      if (column.dataIndex === 'devicetype') {
+        // record.editValueRefs.name4.value = `${value}`;
       }
+      // console.log(column, value, record);
+    }
 
-      // watch(() => props.pointType, async(pointType) => {
-      //   await getDataSource(pointType)
-      // })
+    // watch(() => props.pointType, async(pointType) => {
+    //   await getDataSource(pointType)
+    // })
 
-      async function getDataSource(pointType) {
-        const result = await list({ devicetype: pointType, valuetype: props.valuetype, deviceid: props.deviceId });
-        dataSource.value = result.records;
-      }
-      onMounted(async () => {
-        await getDataSource(props.pointType);
-      });
+    async function getDataSource(pointType) {
+      const result = await list({ devicetype: pointType, valuetype: props.valuetype, deviceid: props.deviceId });
+      dataSource.value = result.records;
+    }
+    onMounted(async () => {
+      await getDataSource(props.pointType);
+    });
 
-      return {
-        registerTable,
-        handleEdit,
-        createActions,
-        onEditChange,
-        addRow,
-        handleChange,
-        handleSearch,
-        handleChangeDeviceType,
-        handleChangeLinkCode,
-        getOptions,
-        options,
-        monitorParamsOptions,
-        deviceList,
-        dataSource,
-        filterOption,
-      };
-    },
-  });
+    return {
+      registerTable,
+      handleEdit,
+      createActions,
+      onEditChange,
+      addRow,
+      handleChange,
+      handleSearch,
+      handleChangeDeviceType,
+      handleChangeLinkCode,
+      getOptions,
+      options,
+      monitorParamsOptions,
+      deviceList,
+      dataSource,
+      filterOption,
+    };
+  },
+});
 </script>
 <style scoped lang="less">
-  @ventSpace: zxm;
-  :deep(.@{ventSpace}-table-body) {
-    height: auto !important;
-  }
-  .@{ventSpace}-dropdown-menu-item {
-    color: black;
-  }
+@ventSpace: zxm;
+:deep(.@{ventSpace}-table-body) {
+  height: auto !important;
+}
+.@{ventSpace}-dropdown-menu-item {
+  color: black;
+}
 </style>

+ 218 - 0
src/views/vent/deviceManager/comment/pointTabel/ctrlTable.vue

@@ -0,0 +1,218 @@
+<template>
+  <!-- 配置预警设备 -->
+  <div class="warning-device-box">
+    <div class="device-box">
+      <a-button class="vent-margin-b-5" type="primary" @click="handleOpen(true, {})"> 新增 </a-button>
+      <a-table :columns="MonitorColumns" :data-source="dataSource" bordered :scroll="{ y: 500 }" :pagination="false">
+        <template v-if="show" #bodyCell="{ column, record }">
+          <template v-if="column.dataIndex === 'operation'">
+            <a class="action-link" @click="handleOpen('update', record)">编辑</a>
+            <a class="action-link vent-margin-l-10" @click="handleDelete(record)">删除</a>
+          </template>
+          <template v-if="column.dataIndex === 'operation1'">
+            <a class="action-link" @click="handleOpen('add', record)">新增</a>
+          </template>
+        </template>
+      </a-table>
+    </div>
+  </div>
+  <BaseModal @register="register" @add="onSubmit" @update="onSubmit" :form-schemas="formSchemas" :monitor-type="'2,3,9,202,203,209'" />
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted } from 'vue';
+import { rowOrColSpanMap, MonitorColumns, monitorWarningFormSchemas } from './warning.data';
+import { warningLogList, workFaceWarningList, workFaceWarningAdd, workFaceWarningEdit, workFaceWarningDelete } from './warning.api';
+import BaseModal from './BaseModal.vue';
+import { useModal } from '/@/components/Modal';
+import { message } from 'ant-design-vue';
+
+const emit = defineEmits(['register']);
+
+const props = defineProps({
+  deviceId: { type: String },
+});
+
+const show = ref(false);
+const formSchemas = monitorWarningFormSchemas({ id: props.deviceId });
+const activeID = ref('');
+const dataSource = ref<any[]>([]);
+
+function selectWarning(id) {
+  activeID.value = id;
+  // 查询该条目的下预警设备列表
+  getDataSource();
+}
+async function getDataSource() {
+  show.value = false;
+  rowOrColSpanMap.clear();
+  const result = await workFaceWarningList({ sysId: props.deviceId, monitorType: 2, alarmId: activeID.value, pageSize: 100000 });
+  let flag = 0;
+  let groupNum = 0;
+  let resultDataSource: any[] = [];
+  const value1 = [
+    {
+      code: 'key',
+      rowSpan: 0,
+      colSpan: 1,
+    },
+    {
+      code: 'alarmName',
+      rowSpan: 0,
+      colSpan: 1,
+    },
+    {
+      code: 'operation1',
+      rowSpan: 0,
+      colSpan: 1,
+    },
+  ];
+  // 根据relId 排序
+
+  for (let i = 0; i < result.records.length; i++) {
+    const item = result.records[i];
+    if (!item.relId) {
+      groupNum++;
+      resultDataSource.push(item);
+      let itemChildArr: any[] = [];
+      for (let j = 0; j < result.records.length; j++) {
+        const itemChild = result.records[j];
+        if (itemChild.relId == item.id) {
+          resultDataSource.push(itemChild);
+          itemChildArr.push(itemChild);
+        }
+      }
+      const value0 = [
+        {
+          code: 'key',
+          rowSpan: itemChildArr.length + 1,
+          colSpan: 1,
+        },
+        {
+          code: 'alarmName',
+          rowSpan: itemChildArr.length + 1,
+          colSpan: 1,
+        },
+        {
+          code: 'operation1',
+          rowSpan: itemChildArr.length + 1,
+          colSpan: 1,
+        },
+      ];
+      rowOrColSpanMap.set(item['id'], value0);
+      item['key'] = `${groupNum}`;
+      for (let m = 0; m < itemChildArr.length; m++) {
+        rowOrColSpanMap.set(itemChildArr[m]['id'], value1);
+      }
+    }
+  }
+  show.value = true;
+  dataSource.value = resultDataSource;
+}
+
+async function handleDelete(record) {
+  await workFaceWarningDelete({ id: record.id });
+  getDataSource();
+}
+
+const [register, { openModal, closeModal }] = useModal();
+
+function handleOpen(flag?, record?) {
+  if (record) {
+    if (flag == 'update') {
+      openModal(true, {
+        isUpdate: true,
+        record,
+      });
+    } else {
+      if (!activeID.value) {
+        message.warning('请先选择预警条目!');
+        return;
+      }
+      // 新增并关系数据
+      openModal(true, {
+        isUpdate: false,
+        record,
+      });
+    }
+  } else {
+    if (!activeID.value) {
+      message.warning('请先选择预警条目!');
+      return;
+    }
+    openModal(true, {
+      isUpdate: false,
+    });
+  }
+}
+
+async function onSubmit(flag, values) {
+  if (activeID.value) {
+    // 提交数据弹窗
+    if (flag == 'update') {
+      await workFaceWarningEdit({ ...values });
+    } else {
+      await workFaceWarningAdd({ ...values, monitorType: 2, sysId: props.deviceId, alarmId: activeID.value });
+    }
+    getDataSource();
+  }
+  closeModal();
+}
+
+onMounted(async () => {
+  await getWarningList();
+  await getDataSource();
+});
+</script>
+
+<style lang="less" scoped>
+@ventSpace: zxm;
+
+.warning-device-box {
+  width: 100%;
+  height: 600px;
+  overflow-y: auto;
+  display: flex;
+  .warning-box {
+    width: 200px;
+    height: 100%;
+    overflow-y: auto;
+    background: #ffffff11;
+    padding: 5px;
+    border-radius: 5px;
+
+    .link-item {
+      position: relative;
+      cursor: pointer;
+      line-height: 30px;
+      padding-left: 30px;
+      color: #fff;
+      span:hover {
+        color: #89ffff;
+      }
+      &::after {
+        content: '';
+        position: absolute;
+        display: block;
+        width: 8px;
+        height: 8px;
+        top: 12px;
+        left: 10px;
+        transform: rotateZ(45deg) skew(10deg, 10deg);
+        background: #45d3fd;
+      }
+    }
+    .active-device-title {
+      color: aqua;
+    }
+  }
+  .device-box {
+    flex: 1;
+    margin-left: 10px;
+  }
+
+  .action-link {
+    color: #00e7ff;
+  }
+}
+</style>

+ 145 - 0
src/views/vent/deviceManager/comment/warningTabel/BaseModalCtrl.vue

@@ -0,0 +1,145 @@
+<template>
+  <BasicModal @register="register" :title="title" :width="800" :min-height="400" v-bind="$attrs" @ok="onSubmit">
+    <BasicForm @register="registerForm">
+      <template #monitor="{ model, field }">
+        <div class="vent-flex-row-between">
+          <Select ref="selectRef" disabled v-model:value="pointData" :options="option" style="width: calc(100% - 65px)" />
+          <a-button class="vent-margin-b-5" type="primary" @click="selectPoint" style="position: absolute; right: 0; top: 1px">选择</a-button>
+        </div>
+      </template>
+    </BasicForm>
+  </BasicModal>
+  <DevicePointTable @register="registerModal" :data-source="devicePointList" :selection-row-keys="pointData" @reload="setPoint" />
+</template>
+<script lang="ts" setup>
+import { onMounted, ref, unref, nextTick } from 'vue';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { BasicModal, useModalInner, useModal } from '/@/components/Modal';
+import type { FormSchema } from '/@/components/Form/src/types/form';
+import { Select, message } from 'ant-design-vue';
+import { workFacePointList } from './warning.api';
+import DevicePointTable from './DeviceCtrlPointTable.vue';
+
+const props = defineProps({
+  formSchemas: {
+    type: Array as PropType<FormSchema[]>,
+    default: () => [],
+  },
+  deviceId: { type: String },
+  monitorType: {
+    type: String,
+    default: '2',
+  },
+  deviceType: { type: String },
+});
+const emit = defineEmits(['add', 'update', 'register']);
+const option = ref<any[]>([]);
+const devicePointList = ref<any[]>([]);
+const pointData = ref<String[]>([]);
+const selectedPoint = ref<any>(null);
+const selectedDevice = ref<any>(null);
+const title = ref('');
+const isUpdate = ref(false);
+// 注册 form
+const [registerForm, { resetFields, setFieldsValue, validate, getFieldsValue }] = useForm({
+  schemas: props.formSchemas,
+  showActionButtonGroup: false,
+});
+
+// 注册 modal
+const [register, { setModalProps }] = useModalInner(async (data) => {
+  isUpdate.value = unref(data.isUpdate);
+  title.value = unref(data.title);
+  await resetFields();
+  pointData.value = [];
+  selectedPoint.value = null;
+  selectedDevice.value = null;
+  option.value = [];
+  await resetFields();
+  if (data.isUpdate) {
+    await setFieldsValue({ ...data.record });
+    pointData.value = [data.record['linkMonitorCode']];
+
+    await getDevicePointList(data.record['deviceId'] || data.record['linkDeviceId']);
+    const matchItem = devicePointList.value.find((item) => item['id'] == pointData.value[0] || item['valuecode'] == pointData.value[0]);
+    if (matchItem) {
+      setPoint([matchItem]);
+    }
+  } else if (data.record) {
+    await getDevicePointList(data.record['linkDeviceType']);
+    devicePointList.value.forEach((item) => {
+      if (item['id'] == data.record['linkMonitorCode'] || item['valuecode'] == data.record['linkMonitorCode']) {
+        setPoint([item]);
+      }
+    });
+    pointData.value = [data.record['linkMonitorCode']];
+    await setFieldsValue({ linkMonitorCode: '' });
+  }
+});
+
+const [registerModal, { openModal }] = useModal();
+
+async function getDevicePointList(strtype) {
+  try {
+    const result = await workFacePointList({ deviceType: strtype, valueTypes: '1' });
+    devicePointList.value = result;
+  } catch (error) {
+    devicePointList.value = [];
+  }
+}
+
+async function onSubmit() {
+  try {
+    const data = await getFieldsValue();
+    await setFieldsValue({ ...data, linkMonitorCode: pointData.value[0] });
+    const values = await validate();
+    values.deviceId = props.deviceId;
+    if (selectedPoint.value) {
+      values.linkMonitorCode = selectedPoint.value.valuecode;
+      values.linkMonitorId = String(selectedPoint.value.id);
+      values.linkMonitorName = selectedPoint.value.valuename;
+    }
+    console.log(values, 'values');
+    setModalProps({ confirmLoading: true });
+    if (!isUpdate.value) {
+      emit('add', 'add', values);
+    } else {
+      emit('update', 'update', values);
+    }
+  } finally {
+    setModalProps({ confirmLoading: false });
+  }
+}
+
+async function selectPoint() {
+  const values = await getFieldsValue();
+  const strtype = values.linkDeviceType || props.deviceType;
+  if (!strtype) {
+    message.info('请先选择设备类型!');
+    return;
+  }
+  if (!values.linkDeviceId) {
+    message.info('请先选择关联设备!');
+    return;
+  }
+  await getDevicePointList(strtype);
+  openModal();
+}
+
+function setPoint(value) {
+  const data = value[0];
+  selectedPoint.value = data;
+  option.value = [
+    {
+      value: data.id,
+      label: data.valuename,
+    },
+  ];
+  nextTick(() => {
+    pointData.value = [data.id];
+  });
+}
+
+onMounted(async () => {});
+</script>
+<style scoped lang="less"></style>

+ 76 - 0
src/views/vent/deviceManager/comment/warningTabel/DeviceCtrlPointTable.vue

@@ -0,0 +1,76 @@
+<template>
+  <BasicModal
+    ref="DeviceModalTable"
+    v-bind="$attrs"
+    @register="registerModal"
+    title="选择控制点位"
+    width="1000px"
+    :showCancelBtn="false"
+    :showOkBtn="false"
+    :footer="null"
+    :destroy-on-close="true"
+  >
+    <div>
+      <a-button type="primary" @click="saveData"> 确定 </a-button>
+    </div>
+    <a-table
+      v-if="refresh"
+      :row-selection="{ type: 'radio', selectedRowKeys: selectedRowKeys, onSelect: onSelectChange }"
+      :columns="columns"
+      :dataSource="dataSource"
+      :row-key="(record) => record.id"
+      size="small"
+    />
+  </BasicModal>
+</template>
+<script lang="ts" setup>
+import { onMounted, ref, defineEmits, watch, nextTick } from 'vue';
+import { columns } from '../../pointTabel/point.data';
+import { BasicModal, useModalInner } from '/@/components/Modal';
+
+const DeviceModalTable = ref();
+const props = defineProps({
+  dataSource: { type: Array, default: () => [] },
+  selectionRowKeys: { type: Array, default: () => [] },
+});
+const emit = defineEmits(['reload', 'register']);
+
+const refresh = ref(true);
+const selectedRowKeys = ref<any[]>([]);
+const selectionRows = ref<any[]>([]);
+
+const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+  //重置表单
+  setModalProps({ confirmLoading: false });
+});
+
+/**
+ * 复选框选中事件
+ * @param rowKeys
+ * @param rows
+ */
+function onSelectChange(record) {
+  selectedRowKeys.value = [record['id']];
+  selectionRows.value = [record];
+}
+
+const saveData = async () => {
+  emit('reload', selectionRows.value);
+
+  closeModal();
+};
+
+watch(
+  () => props.selectionRowKeys,
+  (newVal: any[]) => {
+    selectedRowKeys.value = newVal;
+    refresh.value = false;
+    nextTick(() => {
+      refresh.value = true;
+    });
+  }
+);
+
+onMounted(async () => {});
+</script>
+<style scoped lang="less"></style>

+ 186 - 0
src/views/vent/deviceManager/comment/warningTabel/ctrlTable.vue

@@ -0,0 +1,186 @@
+<template>
+  <!-- 配置预警设备 -->
+  <div class="warning-device-box">
+    <div class="warning-box">
+      <div v-for="item in ctrlList" class="link-item" :class="{ 'active-device-title': item.id == activeID }" :key="item.id">
+        <span class="" @click="selectWarning(item.id)">{{ item.valuename }}</span>
+      </div>
+    </div>
+    <div class="device-box">
+      <a-button class="vent-margin-b-5" type="primary" @click="handleOpen(true, {})"> 新增 </a-button>
+      <a-table :columns="ctrlColumns" :data-source="dataSource" bordered :scroll="{ y: 500 }" :pagination="false">
+        <template #bodyCell="{ column, record }">
+          <template v-if="column.dataIndex === 'operation'">
+            <a class="action-link" @click="handleOpen('update', record)">编辑</a>
+            <a-popconfirm title="确定删除?" @confirm="handleDelete(record)">
+              <a class="table-action-link">删除</a>
+            </a-popconfirm>
+          </template>
+        </template>
+      </a-table>
+    </div>
+  </div>
+  <BaseModal
+    @register="register"
+    @add="onSubmit"
+    @update="onSubmit"
+    :device-type="props.deviceType"
+    :device-id="props.deviceId"
+    :form-schemas="formSchemas"
+    :monitor-type="''"
+  />
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted } from 'vue';
+import { ctrlColumns, ctrlFormSchemas } from './warning.data';
+import { getCtrlDevicePointList, addCtrlDevicePoint, editCtrlDevicePoint, getCtrlDevicePointPage, deleteDevicePonit } from './warning.api';
+import BaseModal from './BaseModalCtrl.vue';
+import { useModal } from '/@/components/Modal';
+
+const emit = defineEmits(['register']);
+
+const props = defineProps({
+  deviceId: { type: String },
+  deviceType: { type: String },
+});
+
+const formSchemas = ctrlFormSchemas;
+const activeID = ref('');
+const dataSource = ref<any[]>([]);
+const ctrlList = ref<any[]>([]);
+const deviceType = ref('');
+const editRecord = ref<any>(null);
+function selectWarning(id) {
+  activeID.value = id;
+  getTableData(id);
+}
+async function getControlDevicePointList() {
+  const param = {
+    pageNo: 1,
+    pageSize: 1000,
+    devicetype: props.deviceType,
+    valuetype: 10,
+  };
+  const res = await getCtrlDevicePointList(param);
+  ctrlList.value = res.records || [];
+}
+const [register, { openModal, closeModal }] = useModal();
+
+function handleOpen(flag?, record?) {
+  console.log(record, 'record');
+  deviceType.value = props.deviceType;
+  editRecord.value = flag == 'update' ? record : null;
+  if (record) {
+    if (flag == 'update') {
+      openModal(true, {
+        isUpdate: true,
+        record,
+      });
+    } else {
+      openModal(true, {
+        isUpdate: false,
+        record,
+      });
+    }
+  } else {
+    openModal(true, {
+      isUpdate: false,
+      record,
+    });
+  }
+}
+
+async function onSubmit(flag, values) {
+  const currentItem = ctrlList.value.find((item) => item.id == activeID.value);
+  if (currentItem) {
+    values.monitorCode = currentItem.valuecode;
+    values.monitorId = currentItem.id;
+    values.monitorName = currentItem.valuename;
+  }
+  if (flag == 'update') {
+    await editCtrlDevicePoint({ id: editRecord.value?.id, ...editRecord.value, ...values });
+  } else {
+    await addCtrlDevicePoint({ ...values });
+  }
+  editRecord.value = null;
+  closeModal();
+  await getTableData(activeID.value);
+}
+
+async function handleDelete(record) {
+  await deleteDevicePonit({ id: record.id });
+  getTableData(activeID.value);
+}
+
+async function getTableData(id?: string) {
+  const param = {
+    pageNo: 1,
+    pageSize: 1000,
+    monitorId: id,
+    deviceId: props.deviceId,
+  };
+  const res = await getCtrlDevicePointPage(param);
+  dataSource.value = res.records || [];
+}
+
+onMounted(async () => {
+  await getControlDevicePointList();
+  if (ctrlList.value.length > 0) {
+    activeID.value = ctrlList.value[0].id;
+  }
+  await getTableData(activeID.value);
+});
+</script>
+
+<style lang="less" scoped>
+@ventSpace: zxm;
+
+.warning-device-box {
+  width: 100%;
+  height: 600px;
+  overflow-y: auto;
+  display: flex;
+  .warning-box {
+    width: 200px;
+    height: 100%;
+    overflow-y: auto;
+    background: #ffffff11;
+    padding: 5px;
+    border-radius: 5px;
+
+    .link-item {
+      position: relative;
+      cursor: pointer;
+      line-height: 30px;
+      padding-left: 30px;
+      color: #fff;
+      span:hover {
+        color: #89ffff;
+      }
+      &::after {
+        content: '';
+        position: absolute;
+        display: block;
+        width: 8px;
+        height: 8px;
+        top: 12px;
+        left: 10px;
+        transform: rotateZ(45deg) skew(10deg, 10deg);
+        background: #45d3fd;
+      }
+    }
+    .active-device-title {
+      color: aqua;
+    }
+  }
+  .device-box {
+    flex: 1;
+    margin-left: 10px;
+  }
+
+  .action-link {
+    color: #00e7ff;
+  }
+}
+</style>

+ 26 - 0
src/views/vent/deviceManager/comment/warningTabel/warning.api.ts

@@ -1,3 +1,4 @@
+import { getAllPostList } from './../../../../system/user/user.api';
 import { defHttp } from '/@/utils/http/axios';
 import { Modal } from 'ant-design-vue';
 
@@ -50,6 +51,19 @@ enum Api {
   addProgram = '/monitor/voice-alarm/addProgram',
   updateProgram = '/monitor/voice-alarm/updateProgram',
   deleteProgram = '/monitor/voice-alarm/deleteProgram',
+
+  // 获取控制点位列表
+  getCtrlDevicePointList = '/safety/ventanalyMonitorParams/list',
+  // 新增控制点位关联
+  addCtrlDevicePoint = '/ventanaly-device/safety/deviceLink/add',
+  // 编辑控制点位关联
+  editCtrlDevicePoint = '/ventanaly-device/safety/deviceLink/edit',
+  // 设备联动控制管理-分页查询
+  ctrlDevicePointPage = '/ventanaly-device/safety/deviceLink/list',
+  // 设备联动控制管理-删除
+  deleteDevicePonit = '/ventanaly-device/safety/deviceLink/delete',
+  // 获取设备下的设备数据
+  getDeviceList = '/safety/ventanalyDeviceInfo/list',
 }
 /**
  * 导出api
@@ -157,3 +171,15 @@ export const modelAlarmAutoEdit = (params) => defHttp.post({ url: Api.modelAlarm
 export const addProgram = (params) => defHttp.post({ url: Api.addProgram, params });
 export const updateProgram = (params) => defHttp.post({ url: Api.updateProgram, params });
 export const deleteProgram = (params) => defHttp.post({ url: Api.deleteProgram, params });
+// 控制点位关联
+export const getCtrlDevicePointList = (params) => defHttp.get({ url: Api.getCtrlDevicePointList, params });
+// 新增控制点位关联
+export const addCtrlDevicePoint = (params) => defHttp.post({ url: Api.addCtrlDevicePoint, params });
+// 编辑控制点位关联
+export const editCtrlDevicePoint = (params) => defHttp.post({ url: Api.editCtrlDevicePoint, params });
+// 设备联动控制管理-分页查询
+export const getCtrlDevicePointPage = (params) => defHttp.get({ url: Api.ctrlDevicePointPage, params });
+// 设备联动控制管理-删除
+export const deleteDevicePonit = (params) => defHttp.delete({ url: Api.deleteDevicePonit, params }, { joinParamsToUrl: true });
+// 获取设备下的设备数据
+export const getDeviceList = (params) => defHttp.get({ url: Api.getDeviceList, params });

+ 137 - 2
src/views/vent/deviceManager/comment/warningTabel/warning.data.ts

@@ -1,7 +1,7 @@
 import { BasicColumn, FormSchema } from '/@/components/Table';
 import { initDictOptions } from '/@/utils/dict';
 import type { TableColumnType } from 'ant-design-vue';
-import { workFaceDeviceList } from './warning.api';
+import { workFaceDeviceList, getDeviceList } from './warning.api';
 import { render } from '/@/utils/common/renderUtils';
 
 export const levelColumns: BasicColumn[] = [
@@ -909,7 +909,6 @@ export const controlColumns: TableColumnType[] = [
     align: 'center',
   },
 ];
-
 export const testData = [
   {
     key: '1',
@@ -1236,3 +1235,139 @@ export const ledPlaylistFormSchemas = () =>
       },
     },
   ];
+
+// 控制点位关联
+export const ctrlColumns: TableColumnType[] = [
+  {
+    title: '点位名称',
+    dataIndex: 'monitorName',
+    align: 'center',
+  },
+  {
+    title: '关联设备名称',
+    dataIndex: 'linkDeviceName',
+    align: 'center',
+  },
+  {
+    title: '关联设备安装位置',
+    dataIndex: 'linkDevicePos',
+    align: 'center',
+  },
+  {
+    title: '设备值',
+    dataIndex: 'value',
+    align: 'center',
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark',
+    align: 'center',
+  },
+  {
+    title: '创建人',
+    dataIndex: 'createBy',
+    align: 'center',
+  },
+  {
+    title: '创建日期',
+    dataIndex: 'createTime',
+    align: 'center',
+  },
+  {
+    title: '执行顺序',
+    dataIndex: 'orderNum',
+    align: 'center',
+  },
+  {
+    title: '操作',
+    colSpan: 2,
+    dataIndex: 'operation',
+    width: 120,
+    align: 'center',
+  },
+];
+// 新增/编辑 表单部分
+export const ctrlFormSchemas: FormSchema[] = [
+  {
+    label: '关联设备类型',
+    field: 'linkDeviceType',
+    component: 'MTreeSelect',
+    componentProps: ({ formModel }) => ({
+      isSearch: false,
+      onChange: () => {
+        formModel['linkDeviceId'] = undefined;
+        formModel['linkDevicePos'] = undefined;
+        formModel['linkDeviceName'] = undefined;
+        formModel['linkDeviceKind'] = undefined;
+      },
+    }),
+    required: true,
+  },
+  {
+    label: '关联设备',
+    field: 'linkDeviceId',
+    component: 'ApiSelect',
+    componentProps: ({ formModel }) => ({
+      api: (params) =>
+        getDeviceList({
+          pageNo: 1,
+          pageSize: 1000,
+          strtype: formModel.linkDeviceType,
+          ...params,
+        }),
+      resultField: 'records',
+      labelField: 'strname',
+      valueField: 'id',
+      onChange: (e, option) => {
+        if (option) {
+          formModel['linkDeviceType'] = option.strtype;
+          formModel['linkDevicePos'] = option.strinstallpos;
+          formModel['linkDeviceName'] = option.strname;
+          formModel['linkDeviceKind'] = option.devicekind;
+        }
+        formModel['linkMonitorCode'] = undefined;
+      },
+    }),
+    required: true,
+  },
+  {
+    label: '关联点位code',
+    field: 'linkMonitorCode',
+    component: 'Select',
+    slot: 'monitor',
+    required: true,
+  },
+  {
+    label: '执行顺序',
+    field: 'orderNum',
+    component: 'InputNumber',
+  },
+  {
+    label: '设置值',
+    field: 'value',
+    component: 'InputNumber',
+  },
+  {
+    label: '备注',
+    field: 'remark',
+    component: 'Input',
+  },
+  {
+    label: '',
+    field: 'linkDevicePos',
+    component: 'Input',
+    show: false,
+  },
+  {
+    label: '',
+    field: 'linkDeviceName',
+    component: 'Input',
+    show: false,
+  },
+  {
+    label: '',
+    field: 'linkDeviceKind',
+    component: 'Input',
+    show: false,
+  },
+];