Browse Source

设备详情

zhangafei 3 months ago
parent
commit
e71ddef7c7

+ 12 - 0
src/App.vue

@@ -106,4 +106,16 @@
     display: inline-block;
   }
   // update-end--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
+  .zgztel-check-icon {
+    font-size: 24px;
+    font-weight: bolder;
+
+    &.checked {
+      color: #389e0d;
+    }
+
+    &.no-checked {
+      color: #ff4d4f;
+    }
+  }
 </style>

+ 1 - 0
src/assets/icons/el-device-allocate-transfer.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744705173441" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1119" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M768 1024H256C115.2 1024 0 908.8 0 768V256C0 115.2 115.2 0 256 0h512c140.8 0 256 115.2 256 256v512c0 140.8-115.2 256-256 256z" fill="#08979c" p-id="1120"></path><path d="M561.066667 672v64h-192v-64h-96v-64h96v-64h192v64h226.133333v64H561.066667z m-64-64h-64v64h64v-64z m194.133333-160v32h-192v-64H273.066667v-64h226.133333v-64h192v64h96v64h-96V448z m-64-96h-64v64h64v-64z" fill="#ffffff" p-id="1121"></path></svg>

+ 1 - 0
src/assets/icons/el-device-base-info.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744704552429" class="icon" viewBox="0 0 1026 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2880" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.390625" height="200"><path d="M768 1024h-512c-140.8 0-256-115.2-256-256V256c0-140.8 115.2-256 256-256h512c140.8 0 256 115.2 256 256v512c0 140.8-113.066667 256-256 256z" fill="#FF9A2E" p-id="2881"></path><path d="M516.266667 441.6c0-2.133333 0-2.133333 0 0 21.333333-23.466667 21.333333-57.6 0-78.933333s-49.066667-21.333333-70.4 0-21.333333 53.333333-2.133334 74.666666c19.2 23.466667 51.2 23.466667 72.533334 4.266667z" fill="#FFFFFF" p-id="2882"></path><path d="M706.133333 264.533333H307.2c-21.333333 0-38.4 14.933333-38.4 36.266667v405.333333c0 21.333333 17.066667 36.266667 38.4 36.266667H706.133333c21.333333 0 38.4-14.933333 38.4-36.266667v-405.333333c2.133333-21.333333-17.066667-36.266667-38.4-36.266667zM371.2 490.666667l46.933333-46.933334c-21.333333-29.866667-17.066667-72.533333 8.533334-96 27.733333-29.866667 74.666667-29.866667 104.533333-2.133333l2.133333 2.133333c29.866667 29.866667 29.866667 81.066667 0 110.933334-27.733333 23.466667-66.133333 27.733333-96 8.533333l-46.933333 46.933333c-6.4 6.4-14.933333 6.4-21.333333 0V512c-4.266667-6.4-4.266667-14.933333 2.133333-21.333333z m147.2 187.733333h-136.533333c-8.533333 0-17.066667-8.533333-17.066667-17.066667s8.533333-17.066667 17.066667-17.066666h136.533333c8.533333 0 17.066667 8.533333 17.066667 17.066666 2.133333 8.533333-4.266667 17.066667-17.066667 17.066667z m115.2-68.266667H381.866667c-8.533333 0-17.066667-8.533333-17.066667-17.066666s8.533333-17.066667 17.066667-17.066667h247.466666c8.533333 0 17.066667 8.533333 17.066667 17.066667 4.266667 8.533333-4.266667 17.066667-12.8 17.066666z" fill="#FFFFFF" p-id="2883"></path></svg>

+ 1 - 0
src/assets/icons/el-device-equipment-disposal.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744705245045" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1119" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M768 1024H256C115.2 1024 0 908.8 0 768V256C0 115.2 115.2 0 256 0h512c140.8 0 256 115.2 256 256v512c0 140.8-115.2 256-256 256z" fill="#87d068" p-id="1120"></path><path d="M426.666667 268.8c0 38.4 29.866667 68.266667 68.266666 68.266667s68.266667-29.866667 68.266667-68.266667-29.866667-68.266667-66.133333-68.266667-70.4 32-70.4 68.266667z m-198.4 394.666667c19.2 32 61.866667 44.8 93.866666 25.6 32-19.2 44.8-61.866667 25.6-93.866667-12.8-21.333333-34.133333-34.133333-59.733333-34.133333-23.466667 0-46.933333 12.8-59.733333 34.133333-12.8 21.333333-12.8 46.933333 0 68.266667z m441.6 25.6c21.333333 12.8 46.933333 12.8 68.266666 0s34.133333-34.133333 34.133334-59.733334-12.8-46.933333-34.133334-59.733333c-21.333333-12.8-46.933333-12.8-68.266666 0s-34.133333 34.133333-34.133334 59.733333 12.8 49.066667 34.133334 59.733334z m-260.266667-185.6c0 46.933333 38.4 85.333333 85.333333 85.333333s85.333333-38.4 85.333334-85.333333-38.4-85.333333-85.333334-85.333334-85.333333 38.4-85.333333 85.333334z m209.066667 76.8c23.466667-40.533333 70.4-57.6 115.2-42.666667 12.8-104.533333-44.8-204.8-142.933334-247.466667-10.666667 44.8-49.066667 76.8-96 76.8s-85.333333-32-96-76.8c-96 42.666667-155.733333 142.933333-142.933333 247.466667 42.666667-12.8 91.733333 4.266667 113.066667 44.8 23.466667 40.533333 14.933333 89.6-19.2 121.6 85.333333 64 200.533333 64 285.866666 0-32-32-40.533333-83.2-17.066666-123.733333z m-123.733334 44.8c-66.133333 0-121.6-53.333333-121.6-121.6s53.333333-121.6 121.6-121.6 121.6 53.333333 121.6 121.6-55.466667 121.6-121.6 121.6z" fill="#ffffff" p-id="1121"></path></svg>

+ 1 - 0
src/assets/icons/el-device-events.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744705386885" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3308" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M768 1024H256C115.2 1024 0 908.8 0 768V256C0 115.2 115.2 0 256 0h512c140.8 0 256 115.2 256 256v512c0 140.8-115.2 256-256 256z" fill="#FF9A2E" p-id="3309"></path><path d="M755.2 640h-192c-6.4 0-10.666667-4.266667-10.666667-10.666667v-23.466666c0-25.6-19.2-44.8-44.8-44.8h-44.8c-25.6 0-44.8 19.2-44.8 44.8v23.466666c0 6.4-4.266667 10.666667-10.666666 10.666667h-192C189.866667 640 170.666667 661.333333 170.666667 684.8v34.133333c0 25.6 19.2 44.8 44.8 44.8h539.733333c25.6 0 44.8-19.2 44.8-44.8v-34.133333c0-23.466667-19.2-44.8-44.8-44.8z" fill="#FFFFFF" p-id="3310"></path><path d="M507.733333 147.2l51.2 102.4c4.266667 6.4 10.666667 12.8 19.2 12.8l113.066667 17.066667c12.8 2.133333 23.466667 14.933333 21.333333 29.866666 0 4.266667-4.266667 10.666667-6.4 12.8l-81.066666 76.8c-6.4 6.4-8.533333 14.933333-6.4 23.466667l19.2 108.8c2.133333 12.8-6.4 25.6-19.2 29.866667-6.4 2.133333-10.666667 0-14.933334-2.133334l-102.4-53.333333c-6.4-4.266667-14.933333-4.266667-23.466666 0l-102.4 53.333333c-12.8 6.4-27.733333 2.133333-32-10.666666-2.133333-4.266667-2.133333-10.666667-2.133334-14.933334l19.2-108.8c2.133333-8.533333-2.133333-17.066667-6.4-23.466666l-78.933333-76.8c-10.666667-10.666667-10.666667-25.6 0-36.266667 4.266667-4.266667 8.533333-6.4 12.8-6.4l113.066667-17.066667c8.533333-2.133333 14.933333-6.4 19.2-12.8L471.466667 149.333333c6.4-12.8 19.2-17.066667 32-10.666666-2.133333 0 2.133333 4.266667 4.266666 8.533333z" fill="#FFFFFF" p-id="3311"></path></svg>

+ 1 - 0
src/assets/icons/el-device-information.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744704560214" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3043" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M768 1024H256C115.2 1024 0 908.8 0 768V256C0 115.2 115.2 0 256 0h512c140.8 0 256 115.2 256 256v512c0 140.8-115.2 256-256 256z" fill="#F85835" p-id="3044"></path><path d="M729.6 320v413.866667H347.733333c-29.866667 0-55.466667-21.333333-55.466666-46.933334 0-25.6 23.466667-46.933333 55.466666-46.933333h345.6V258.133333h-362.666666c-40.533333 0-72.533333 27.733333-72.533334 64V704c0 34.133333 32 64 72.533334 64H768V320h-38.4z m-362.666667 352h328.533334V704H366.933333v-32z" fill="#FFFFFF" p-id="3045"></path></svg>

+ 1 - 0
src/assets/icons/el-device-maintain.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744704742508" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3367" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M768 1024H256C115.2 1024 0 908.8 0 768V256C0 115.2 115.2 0 256 0h512c140.8 0 256 115.2 256 256v512c0 140.8-115.2 256-256 256z" fill="#25C251" p-id="3368"></path><path d="M742.4 684.8c-8.533333 0-14.933333-4.266667-17.066667-12.8l-83.2-247.466667-59.733333-179.2c-4.266667-14.933333-19.2-25.6-36.266667-25.6h-49.066666c-17.066667 0-29.866667 10.666667-36.266667 25.6l-142.933333 428.8c-2.133333 8.533333-10.666667 12.8-17.066667 12.8h-21.333333c-17.066667 0-32 14.933333-32 32s14.933333 32 32 32H746.666667c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32l-4.266667-2.133333zM505.6 266.666667h32c4.266667 0 8.533333 2.133333 8.533333 6.4 2.133333 6.4 0 10.666667-6.4 12.8l-36.266666 8.533333c-4.266667 2.133333-10.666667-2.133333-10.666667-6.4v-4.266667l4.266667-10.666666c0-4.266667 4.266667-6.4 8.533333-6.4z m-44.8 130.133333l102.4-27.733333c10.666667-2.133333 19.2 2.133333 23.466667 12.8l10.666666 34.133333c4.266667 10.666667-2.133333 21.333333-12.8 23.466667h-2.133333l-128 34.133333c-10.666667 2.133333-21.333333-4.266667-23.466667-12.8v-10.666667l12.8-40.533333c6.4-6.4 10.666667-10.666667 17.066667-12.8z m-64 192L618.666667 529.066667c10.666667-2.133333 19.2 2.133333 23.466666 12.8l17.066667 51.2c4.266667 10.666667-2.133333 21.333333-12.8 23.466666L396.8 682.666667H384c-10.666667 0-19.2-8.533333-19.2-19.2v-6.4L384 597.333333c2.133333-2.133333 8.533333-6.4 12.8-8.533333z" fill="#FFFFFF" p-id="3369"></path></svg>

+ 1 - 0
src/assets/icons/el-device-maintenance.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744704571275" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3205" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M768 1024H256C115.2 1024 0 908.8 0 768V256C0 115.2 115.2 0 256 0h512c140.8 0 256 115.2 256 256v512c0 140.8-115.2 256-256 256z" fill="#10C7C1" p-id="3206"></path><path d="M757.333333 364.8L725.333333 394.666667c-32 32-85.333333 32-117.333333 0s-32-85.333333 0-119.466667l29.866667-29.866667c17.066667-17.066667 6.4-36.266667-25.6-32-32 4.266667-61.866667 19.2-85.333334 42.666667-36.266667 36.266667-51.2 89.6-40.533333 140.8l-256 258.133333c-32 32-32 85.333333 0 119.466667 32 32 85.333333 32 117.333333 0l256-258.133333c83.2 17.066667 164.266667-34.133333 181.333334-117.333334 0-2.133333 2.133333-6.4 2.133333-8.533333 6.4-32-12.8-42.666667-29.866667-25.6z m-448 369.066667c-10.666667 10.666667-27.733333 10.666667-38.4 0s-10.666667-27.733333 0-40.533334c10.666667-10.666667 29.866667-10.666667 38.4 2.133334 10.666667 10.666667 10.666667 27.733333 0 38.4z m-27.733333-364.8l96 96 38.4-40.533334-96-96-21.333333-40.533333-68.266667-49.066667L192 279.466667l49.066667 68.266666 40.533333 21.333334zM605.866667 576c-6.4-6.4-14.933333-6.4-19.2 0l-59.733334 59.733333c-6.4 6.4-6.4 14.933333 0 19.2l138.666667 140.8c21.333333 21.333333 57.6 21.333333 78.933333 0s21.333333-57.6 0-78.933333c0-2.133333-138.666667-140.8-138.666666-140.8z" fill="#FFFFFF" p-id="3207"></path></svg>

File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/el-device-point-inspection.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/el-device-spare-parts.svg


+ 13 - 0
src/views/equipmentLifecycle/device/list/DeviceBaseInfo.api.ts

@@ -19,6 +19,10 @@ enum Api {
   saveSubDevice = '/deviceInfo/deviceBaseInfo/subAdd',
   // 设备物料关系
   saveDeviceMaterialRelation = '/deviceInfo/deviceBaseInfo/deviceMaterialRelationAdd',
+  // 已绑定的父子设备
+  queryDeviceBaseInfoByParentId = '/deviceInfo/deviceBaseInfo/parentOrSubDeviceList',
+  // 详情获取物料
+  materialList = '/deviceInfo/deviceMaterialRelation/listDeviceMaterialRelation',
 }
 /**
  * 导出api
@@ -89,3 +93,12 @@ export const saveSubDevice = (params) => {
 export const saveDeviceMaterialRelation = (params) => {
   return defHttp.post({ url: Api.saveDeviceMaterialRelation, params, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
 };
+
+// 已绑定的父子设备
+export const queryDeviceBaseInfoByParentId = (params) => {
+  return defHttp.get({ url: Api.queryDeviceBaseInfoByParentId, params });
+};
+
+export const materialList = (params) => {
+  return defHttp.get({ url: Api.materialList, params });
+};

+ 78 - 1
src/views/equipmentLifecycle/device/list/DeviceBaseInfo.data.ts

@@ -168,7 +168,7 @@ export const columns: BasicColumn[] = [
     dataIndex: 'departmentName',
   },
   {
-    title: '位置',
+    title: '功能位置',
     align: 'center',
     dataIndex: 'positionName',
   },
@@ -623,3 +623,80 @@ export function getBpmFormSchema(_formData): FormSchema[] {
   // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
   return formSchema;
 }
+
+// 设备详情子设备,主设备
+export const dtlColumns: BasicColumn[] = [
+  {
+    title: '设备编号',
+    align: 'center',
+    dataIndex: 'deviceNumber',
+    slots: { customRender: 'deviceNumber' },
+  },
+  {
+    title: '设备名称',
+    align: 'center',
+    dataIndex: 'deviceName',
+  },
+  {
+    title: '品牌',
+    align: 'center',
+    dataIndex: 'brand',
+    customRender(opt) {
+      return render.renderDict(opt.record.brand, 'brand_type');
+    },
+  },
+  {
+    title: '规格型号',
+    align: 'center',
+    dataIndex: 'specificationModel',
+  },
+  {
+    title: '类别',
+    align: 'center',
+    dataIndex: 'categoryName',
+  },
+  {
+    title: '负责人',
+    align: 'center',
+    dataIndex: 'personInCharge',
+  },
+];
+
+// 备件字段
+export const spareColumns: BasicColumn[] = [
+  {
+    title: '备件编号',
+    align: 'center',
+    dataIndex: 'materialNumber',
+  },
+  {
+    title: '备件名称',
+    align: 'center',
+    dataIndex: 'materialName',
+  },
+  {
+    title: '分类',
+    align: 'center',
+    dataIndex: 'classification',
+  },
+  {
+    title: '规格型号',
+    align: 'center',
+    dataIndex: 'materialSpecModel',
+  },
+  {
+    title: '单位',
+    align: 'center',
+    dataIndex: 'unit',
+  },
+  {
+    title: '更换周期',
+    align: 'center',
+    dataIndex: 'replacementCycle',
+  },
+  {
+    title: '需求量',
+    align: 'center',
+    dataIndex: 'demandAmount',
+  },
+];

+ 26 - 43
src/views/equipmentLifecycle/device/list/DeviceBaseInfoList.vue

@@ -61,20 +61,18 @@
       </div>
     </template>
     <template #isMeteringDevice="{ record }">
-      <Icon icon="ant-design:check-outlined" class="check-icon checked" v-if="record.isMeteringDevice === true" />
-      <Icon icon="ant-design:close-outlined" class="check-icon no-checked" v-else />
+      <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="record.isMeteringDevice === true" />
+      <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
     </template>
     <template #isDepreciation="{ record }">
-      <Icon icon="ant-design:check-outlined" class="check-icon checked" v-if="record.isDepreciation === true" />
-      <Icon icon="ant-design:close-outlined" class="check-icon no-checked" v-else />
+      <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="record.isDepreciation === true" />
+      <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
     </template>
   </BasicTable>
   <!-- 表单区域 -->
   <DeviceBaseInfoModal @register="registerModal" @success="handleSuccess" />
-  <!-- 父级设备 -->
-  <ParentDeviceModal @register="registerParentDeviceModal" @success="handleSuccess" />
-  <!-- 子级设备 -->
-  <SubDeviceModal @register="registerSubDeviceModal" @success="handleSuccess" />
+  <!-- 添加父、子级设备 -->
+  <AddDeviceModal @register="registerParentDeviceModal" @success="handleSuccess" />
   <!-- 详情 -->
   <DeviceBaseInfoDetailDrawer @register="registerDetailDrawer" @success="handleSuccess" />
 </template>
@@ -87,8 +85,7 @@
   import DeviceBaseInfoModal from './components/DeviceBaseInfoModal.vue';
   import { columns, searchFormSchema, superQuerySchema } from './DeviceBaseInfo.data';
   import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './DeviceBaseInfo.api';
-  import ParentDeviceModal from './components/ParentDeviceModal.vue';
-  import SubDeviceModal from './components/SubDeviceModal.vue';
+  import AddDeviceModal from './components/AddDeviceModal.vue';
   import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
   import DeviceBaseInfoDetailDrawer from './components/DeviceBaseInfoDetailDrawer.vue';
   import { useDrawer } from '/@/components/Drawer';
@@ -96,23 +93,15 @@
   const queryParam = reactive<any>({});
 
   const emits = defineEmits(['selection-change']);
-  const props = defineProps({
-    noOperate: {
-      type: Boolean,
-      default: false,
-    },
-    superQueryParams: {
-      type: Array,
-      default: () => [],
-    },
-  });
+  const props = defineProps<{
+    noOperate?: boolean;
+    superQueryParams?: any[];
+  }>();
 
   //注册model
   const [registerModal, { openModal }] = useModal();
-  // 添加父级设备
-  const [registerParentDeviceModal, { openModal: openParentDeviceModal }] = useModal();
-  // 添加子级设备
-  const [registerSubDeviceModal, { openModal: openSubDeviceModal }] = useModal();
+  // 添加父、子级设备
+  const [registerParentDeviceModal, { openModal: openAddDeviceModal }] = useModal();
   // 注册详情抽屉
   const [registerDetailDrawer, detailDrawer] = useDrawer();
   //注册table数据
@@ -137,7 +126,7 @@
       },
       beforeFetch: (params) => {
         if (props.noOperate === true) {
-          let superQueryParamsArr = [];
+          let superQueryParamsArr: any[] = [];
           if (queryParam['superQueryParams']) {
             superQueryParamsArr = JSON.parse(decodeURIComponent(queryParam['superQueryParams']));
           }
@@ -146,7 +135,7 @@
             queryParam['superQueryMatchType'] = 'and';
           }
 
-          props.superQueryParams.forEach((ele) => {
+          (props.superQueryParams || []).forEach((ele) => {
             const parentDeviceIdsIndex = superQueryParamsArr.findIndex((item) => {
               return item.field === ele.field;
             });
@@ -173,7 +162,7 @@
     },
   });
 
-  const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
+  const [registerTable, { reload, setSelectedRowKeys }, { rowSelection, selectedRowKeys }] = tableContext;
 
   // 高级查询配置
   const superQueryConfig = reactive(superQuerySchema);
@@ -250,10 +239,11 @@
       {
         label: '添加父设备',
         onClick: () => {
-          openParentDeviceModal(true, {
+          openAddDeviceModal(true, {
             device: record,
             isUpdate: false,
             showFooter: true,
+            addType: 1, // 父设备
           });
         },
         auth: 'deviceInfo:parent_device_info:add',
@@ -261,13 +251,14 @@
       {
         label: '添加子设备',
         onClick: () => {
-          openSubDeviceModal(true, {
+          openAddDeviceModal(true, {
             device: record,
             isUpdate: false,
             showFooter: true,
+            addType: 2, // 子设备
           });
         },
-        auth: 'deviceInfo:sub_device:add',
+        auth: 'deviceInfo:sub_device_info:add',
       },
       {
         label: '详情',
@@ -298,6 +289,11 @@
       emits('selection-change', selectedInfo);
     }
   };
+
+  // 暴露方法
+  defineExpose({
+    setSelectedRowKeys,
+  });
 </script>
 
 <style lang="less" scoped>
@@ -305,17 +301,4 @@
   :deep(.ant-input-number) {
     width: 100%;
   }
-
-  .check-icon {
-    font-size: 24px;
-    font-weight: bolder;
-
-    &.checked {
-      color: #389e0d;
-    }
-
-    &.no-checked {
-      color: #ff4d4f;
-    }
-  }
 </style>

+ 149 - 0
src/views/equipmentLifecycle/device/list/components/AddDeviceModal.vue

@@ -0,0 +1,149 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="registerModal"
+    destroyOnClose
+    :title="title"
+    :width="1400"
+    :height="900"
+    @ok="handleSubmit"
+    :bodyStyle="{ padding: 0 }"
+  >
+    <DeviceBaseInfoList
+      ref="deviceBaseInfoListRef"
+      :noOperate="true"
+      @selection-change="handleRowSelectionChange"
+      :superQueryParams="superQueryParams"
+    />
+    <a-divider orientation="left">已选{{ addType === 1 ? '父' : '子' }}设备:({{ selectedRows.length }})</a-divider>
+    <div class="selected-divider-rap">
+      <a-tag color="#3b5999" v-for="item in selectedRows" :key="item.id" closable @close="() => removeTag(item)">{{ item.deviceName }}</a-tag>
+    </div>
+  </BasicModal>
+</template>
+
+<script lang="ts" setup>
+  import { ref, computed, unref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import DeviceBaseInfoList from '../DeviceBaseInfoList.vue';
+  import { saveParentDevice, saveSubDevice, queryDeviceBaseInfoByParentId } from '../DeviceBaseInfo.api';
+  import { useMessage } from '/@/hooks/web/useMessage';
+
+  const { createMessage } = useMessage();
+  // Emits声明
+  const emit = defineEmits(['register', 'success']);
+  const isUpdate = ref(true);
+  const isDetail = ref(false);
+  const deviceBaseInfoListRef = ref();
+  const selectedRows = ref<any[]>([]);
+  const selectedKeys = ref<string[]>([]);
+  const deviceBaseInfoId = ref('');
+  const superQueryParams = ref<any[]>([]);
+  const orgPdata = ref<any[]>([]);
+  const addType = ref(1);
+
+  //表单赋值
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+    setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
+    isUpdate.value = !!data?.isUpdate;
+    isDetail.value = !!data?.showFooter;
+    if (!data?.device) {
+      closeModal();
+      return;
+    }
+
+    addType.value = data?.addType;
+    deviceBaseInfoId.value = data?.device?.id;
+    if (data?.addType === 2) {
+      superQueryParams.value = [
+        { field: 'id', rule: 'ne', val: data?.device?.id, type: 'text', dbType: 'string' },
+        // { field: 'subDeviceIds', rule: 'empty', val: '', type: 'text', dbType: 'string' },
+        { field: 'subDeviceIds', rule: 'ne', val: data?.device?.id, type: 'text', dbType: 'string' },
+      ];
+    } else {
+      superQueryParams.value = [
+        { field: 'parentDeviceIds', rule: 'empty', val: '', type: 'text', dbType: 'string' },
+        { field: 'id', rule: 'ne', val: data?.device?.id, type: 'text', dbType: 'string' },
+      ];
+    }
+
+    await queryParentDevice(data?.device?.id);
+  });
+  //设置标题
+  const title = computed(() => (!unref(isUpdate) ? `添加${addType.value === 1 ? '父' : '子'}设备` : !unref(isDetail) ? '详情' : '编辑'));
+  //表单提交事件
+  async function handleSubmit() {
+    try {
+      if (!selectedRows.value.length && !orgPdata.value.length) {
+        createMessage.warning(`请选择要添加的${addType.value === 1 ? '父' : '子'}设备`);
+        return;
+      }
+      setModalProps({ confirmLoading: true });
+      const fetchFn = addType.value === 1 ? saveParentDevice : saveSubDevice;
+
+      let params: { id: string; parentDeviceIds?: string; subDeviceIds?: string } = { id: deviceBaseInfoId.value };
+      if (addType.value === 2) {
+        params.subDeviceIds = selectedKeys.value.join(',');
+      } else {
+        params.parentDeviceIds = selectedKeys.value.join(',');
+      }
+
+      //提交表单
+      await fetchFn(params);
+      //关闭弹窗
+      selectedRows.value = [];
+      selectedKeys.value = [];
+      closeModal();
+      //刷新列表
+      emit('success');
+    } catch (error: any) {
+      return Promise.reject(error);
+    } finally {
+      setModalProps({ confirmLoading: false });
+    }
+  }
+
+  // 根据id 查询父设备
+  async function queryParentDevice(id) {
+    try {
+      const data = await queryDeviceBaseInfoByParentId({ deviceId: id, queryType: addType.value });
+      selectedRows.value = data;
+      selectedKeys.value = data.map((item) => item.id);
+      orgPdata.value = data;
+      deviceBaseInfoListRef.value.setSelectedRowKeys(selectedKeys.value);
+    } catch (error) {
+      console.log('error', error);
+    }
+  }
+
+  // 监听行选择
+  const handleRowSelectionChange = (selection) => {
+    if (selection.rows.length === selection.keys.length) {
+      console.log(selection);
+      selectedRows.value = selection.rows;
+      selectedKeys.value = selection.keys;
+    }
+  };
+
+  // 删除标签
+  const removeTag = (item) => {
+    selectedRows.value = selectedRows.value.filter((i) => i.id !== item.id);
+    selectedKeys.value = selectedKeys.value.filter((i) => i !== item.id);
+    deviceBaseInfoListRef.value.setSelectedRowKeys(selectedKeys.value);
+  };
+</script>
+
+<style lang="less" scoped>
+  /** 时间和数字输入框样式 */
+  :deep(.ant-input-number) {
+    width: 100%;
+  }
+
+  :deep(.ant-calendar-picker) {
+    width: 100%;
+  }
+
+  .selected-divider-rap {
+    padding: 0 30px;
+  }
+</style>

+ 85 - 7
src/views/equipmentLifecycle/device/list/components/DeviceBaseInfoDetailDrawer.vue

@@ -1,19 +1,97 @@
 <template>
-  <BasicDrawer v-bind="$attrs" @register="register" title="Drawer Title" width="80%">
-    Drawer Info.
-    <a-button type="primary" @click="closeDrawer">内部关闭drawer</a-button>
+  <BasicDrawer v-bind="$attrs" rootClassName="device-dtl-drawer-wrapper" @register="register" title="设备详情" width="90%">
+    <a-tabs class="device-dtl-tabs-wrapper" v-model:activeKey="activeKey">
+      <a-tab-pane :key="item.key" v-for="item in tabList" :disabled="item.disabled">
+        <template #tab>
+          <div class="flex flex-col items-center">
+            <div class="tab-icon" :class="{ 'el-disabled-icon': item.disabled }"><SvgIcon :name="item.icon" :size="item.size" /></div>
+            <div class="tab-text">{{ item.tab }}</div>
+          </div>
+        </template>
+        <component :is="item.component" :info="info" />
+      </a-tab-pane>
+    </a-tabs>
   </BasicDrawer>
 </template>
 <script lang="ts">
-  import { defineComponent } from 'vue';
+  import { defineComponent, ref } from 'vue';
   import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+  import { SvgIcon } from '/@/components/Icon';
+  import BaseInfo from './deviceDetail.vue/baseInfo.vue';
   export default defineComponent({
-    components: { BasicDrawer },
+    components: { SvgIcon, BasicDrawer, BaseInfo },
     setup() {
+      const activeKey = ref<string>('1');
+      const info = ref<Recordable>({});
+
+      // tab List
+      const tabList = [
+        { key: '1', tab: '基本信息', icon: 'el-device-base-info', disabled: false, component: 'BaseInfo', size: '32' },
+        { key: '2', tab: '资料', icon: 'el-device-information', disabled: true, component: 'BaseInfo', size: '32' },
+        { key: '3', tab: '维修', icon: 'el-device-maintenance', disabled: true, component: 'BaseInfo', size: '32' },
+        { key: '4', tab: '保养', icon: 'el-device-maintain', disabled: true, component: 'BaseInfo', size: '32' },
+        { key: '5', tab: '点巡检', icon: 'el-device-point-inspection', disabled: true, component: 'BaseInfo', size: '32' },
+        { key: '6', tab: '调拨', icon: 'el-device-allocate-transfer', disabled: true, component: 'BaseInfo', size: '32' },
+        { key: '7', tab: '设备处置', icon: 'el-device-equipment-disposal', disabled: true, component: 'BaseInfo', size: '32' },
+        { key: '8', tab: '备件', icon: 'el-device-spare-parts', disabled: false, component: 'BaseInfo', size: '32' },
+        { key: '9', tab: '事件', icon: 'el-device-events', disabled: false, component: 'BaseInfo', size: '32' },
+      ];
+
+      // 抽屉注册及关闭方法,用于openDrawer方法中
+      // 注册抽屉,用于openDrawer调用
       const [register, { closeDrawer }] = useDrawerInner((data) => {
-        console.log('11111111111111', data);
+        info.value = data;
       });
-      return { register, closeDrawer };
+
+      return { register, closeDrawer, activeKey, tabList, info };
     },
   });
 </script>
+<style lang="less" scoped>
+  .device-dtl-tabs-wrapper {
+    height: 100%;
+    overflow: hidden;
+
+    :deep(.scrollbar__view) {
+      height: 100%;
+    }
+
+    :deep(.ant-tabs-nav) {
+      margin-bottom: 10px;
+    }
+
+    :deep(.ant-tabs-content) {
+      height: 100%;
+      overflow: hidden;
+    }
+
+    .tab-icon {
+      width: 32px;
+      height: 32px;
+      margin-bottom: 10px;
+    }
+
+    .el-disabled-icon {
+      position: relative;
+
+      &::after {
+        content: '';
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        background-color: rgba(255, 255, 255, 0.25);
+        z-index: 1;
+      }
+    }
+  }
+</style>
+<style lang="less">
+  .device-dtl-drawer-wrapper {
+    .scrollbar__view {
+      height: 100%;
+      overflow: hidden;
+    }
+  }
+</style>

+ 0 - 92
src/views/equipmentLifecycle/device/list/components/ParentDeviceModal.vue

@@ -1,92 +0,0 @@
-<template>
-  <BasicModal
-    v-bind="$attrs"
-    @register="registerModal"
-    destroyOnClose
-    :title="title"
-    :width="1200"
-    :height="800"
-    @ok="handleSubmit"
-    :bodyStyle="{ padding: 0 }"
-  >
-    <DeviceBaseInfoList :noOperate="true" @selection-change="handleRowSelectionChange" :superQueryParams="superQueryParams" />
-  </BasicModal>
-</template>
-
-<script lang="ts" setup>
-  import { ref, computed, unref } from 'vue';
-  import { BasicModal, useModalInner } from '/@/components/Modal';
-  import DeviceBaseInfoList from '../DeviceBaseInfoList.vue';
-  import { saveParentDevice } from '../DeviceBaseInfo.api';
-  import { useMessage } from '/@/hooks/web/useMessage';
-
-  const { createMessage } = useMessage();
-  // Emits声明
-  const emit = defineEmits(['register', 'success']);
-  const isUpdate = ref(true);
-  const isDetail = ref(false);
-  const selectedRows = ref([]);
-  const deviceBaseInfoId = ref('');
-  const superQueryParams = ref([]);
-
-  //表单赋值
-  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
-    setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
-    isUpdate.value = !!data?.isUpdate;
-    isDetail.value = !!data?.showFooter;
-    if (!data?.device) {
-      closeModal();
-      return;
-    }
-
-    deviceBaseInfoId.value = data?.device?.id;
-    superQueryParams.value = [
-      { field: 'parentDeviceIds', rule: 'eq', val: null, type: 'text', dbType: 'string' },
-      { field: 'id', rule: 'ne', val: data?.device?.id, type: 'text', dbType: 'string' },
-    ];
-  });
-  //设置标题
-  const title = computed(() => (!unref(isUpdate) ? '添加父设备' : !unref(isDetail) ? '详情' : '编辑'));
-  //表单提交事件
-  async function handleSubmit() {
-    try {
-      if (!selectedRows.value.length) {
-        createMessage.warning('请选择要添加的父设备');
-        return;
-      }
-      setModalProps({ confirmLoading: true });
-      //提交表单
-      await saveParentDevice({ id: deviceBaseInfoId.value, parentDeviceIds: selectedRows.value.join(',') }, isUpdate.value);
-      //关闭弹窗
-      closeModal();
-      //刷新列表
-      emit('success');
-    } catch ({ errorFields }) {
-      if (errorFields) {
-        const firstField = errorFields[0];
-        if (firstField) {
-          scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
-        }
-      }
-      return Promise.reject(errorFields);
-    } finally {
-      setModalProps({ confirmLoading: false });
-    }
-  }
-
-  // 监听行选择
-  const handleRowSelectionChange = (selection) => {
-    selectedRows.value = selection.keys;
-  };
-</script>
-
-<style lang="less" scoped>
-  /** 时间和数字输入框样式 */
-  :deep(.ant-input-number) {
-    width: 100%;
-  }
-
-  :deep(.ant-calendar-picker) {
-    width: 100%;
-  }
-</style>

+ 0 - 80
src/views/equipmentLifecycle/device/list/components/SubDeviceModal.vue

@@ -1,80 +0,0 @@
-<template>
-  <BasicModal
-    v-bind="$attrs"
-    @register="registerModal"
-    destroyOnClose
-    :title="title"
-    :width="1200"
-    :height="800"
-    @ok="handleSubmit"
-    :bodyStyle="{ padding: 0 }"
-  >
-    <DeviceBaseInfoList :noOperate="true" @selection-change="handleRowSelectionChange" />
-  </BasicModal>
-</template>
-
-<script lang="ts" setup>
-  import { ref, computed, unref } from 'vue';
-  import { BasicModal, useModalInner } from '/@/components/Modal';
-  import DeviceBaseInfoList from '../../list/DeviceBaseInfoList.vue';
-  import { saveOrUpdate } from '../ParentDevice.api';
-  // Emits声明
-  const emit = defineEmits(['register', 'success']);
-  const isUpdate = ref(true);
-  const isDetail = ref(false);
-  const selectedRows = ref([]);
-  const deviceBaseInfoId = ref('');
-
-  //表单赋值
-  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
-    setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
-    isUpdate.value = !!data?.isUpdate;
-    isDetail.value = !!data?.showFooter;
-    if (!data?.device) {
-      closeModal();
-      return;
-    }
-
-    deviceBaseInfoId.value = data?.device?.id;
-  });
-  //设置标题
-  const title = computed(() => (!unref(isUpdate) ? '添加父设备' : !unref(isDetail) ? '详情' : '编辑'));
-  //表单提交事件
-  async function handleSubmit() {
-    try {
-      setModalProps({ confirmLoading: true });
-      //提交表单
-      // await saveOrUpdate(values, isUpdate.value);
-      //关闭弹窗
-      closeModal();
-      //刷新列表
-      emit('success');
-    } catch ({ errorFields }) {
-      if (errorFields) {
-        const firstField = errorFields[0];
-        if (firstField) {
-          scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
-        }
-      }
-      return Promise.reject(errorFields);
-    } finally {
-      setModalProps({ confirmLoading: false });
-    }
-  }
-
-  // 监听行选择
-  const handleRowSelectionChange = (selection) => {
-    selectedRows.value = selection.rows;
-  };
-</script>
-
-<style lang="less" scoped>
-  /** 时间和数字输入框样式 */
-  :deep(.ant-input-number) {
-    width: 100%;
-  }
-
-  :deep(.ant-calendar-picker) {
-    width: 100%;
-  }
-</style>

+ 253 - 0
src/views/equipmentLifecycle/device/list/components/deviceDetail.vue/baseInfo.vue

@@ -0,0 +1,253 @@
+<template>
+  <a-row class="device-dtl-baseinfo-wrapper" :gutter="20">
+    <a-col :span="10" class="device-dtl-baseinfo-col">
+      <div class="device-dtl-wrapper">
+        <div class="title">基本信息</div>
+        <a-descriptions bordered size="small">
+          <a-descriptions-item label="设备编号">{{ info.deviceNumber }}</a-descriptions-item>
+          <a-descriptions-item label="资产编号">{{ info.assetNumber }}</a-descriptions-item>
+          <a-descriptions-item label="序列号">{{ info.serialNumber }}</a-descriptions-item>
+          <a-descriptions-item label="设备名称">{{ info.deviceName }}</a-descriptions-item>
+          <a-descriptions-item label="电子标签码">{{ info.electronicTag }}</a-descriptions-item>
+          <a-descriptions-item label="单位">{{ info.unit_dictText }}</a-descriptions-item>
+          <a-descriptions-item label="类别">{{ info.categoryName }}</a-descriptions-item>
+          <a-descriptions-item label="规格型号">{{ info.specificationModel }}</a-descriptions-item>
+          <a-descriptions-item label="品牌">{{ info.brand_dictText }}</a-descriptions-item>
+          <a-descriptions-item label="入账方式">{{ info.entryMethod_dictText }}</a-descriptions-item>
+          <a-descriptions-item label="创建人">{{ info.createBy }}</a-descriptions-item>
+          <a-descriptions-item label="创建时间">
+            {{ !info.createTime ? '' : info.createTime.length > 10 ? info.createTime.substr(0, 10) : info.createTime }}
+          </a-descriptions-item>
+          <a-descriptions-item label="设备来源">{{ info.source_dictText }}</a-descriptions-item>
+          <a-descriptions-item label="供应商" :span="2">{{ info.supplier }}</a-descriptions-item>
+          <a-descriptions-item label="采购金额">{{ info.purchaseAmount }}</a-descriptions-item>
+          <a-descriptions-item label="购置日期">{{ info.purchaseDate }}</a-descriptions-item>
+          <a-descriptions-item label="保修期至">{{ info.warrantyExpiry }}</a-descriptions-item>
+          <a-descriptions-item label="启用日期">{{ info.启用日期 }}</a-descriptions-item>
+          <a-descriptions-item label="预计报废日期" :span="2">{{ info.expectedDiscardDate }}</a-descriptions-item>
+          <a-descriptions-item label="设备状态"><component :is="renderDictTag(info.deviceStatus, 'device_status')" /></a-descriptions-item>
+          <a-descriptions-item label="使用状态"><component :is="renderDictTag(info.usageStatus, 'use_status')" /></a-descriptions-item>
+          <a-descriptions-item label="设备等级"><component :is="renderDictTag(info.deviceLevel, 'device_level')" /></a-descriptions-item>
+          <a-descriptions-item label="负责人" :span="3">{{ info.personInCharge }}</a-descriptions-item>
+          <a-descriptions-item label="所属部门" :span="3">{{ info.departmentName }}</a-descriptions-item>
+          <a-descriptions-item label="功能位置" :span="3">{{ info.positionName }}</a-descriptions-item>
+          <a-descriptions-item label="特种设备">
+            <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="info.isSpecialEquip === true" />
+            <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
+          </a-descriptions-item>
+          <a-descriptions-item label="是否计量设备">
+            <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="info.isMeteringDevice === true" />
+            <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
+          </a-descriptions-item>
+          <a-descriptions-item label="是否开启折旧">
+            <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="info.isDepreciation === true" />
+            <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
+          </a-descriptions-item>
+          <a-descriptions-item label="技术参数" :span="3">{{ info.technicalParameters }}</a-descriptions-item>
+          <a-descriptions-item label="备注" :span="3">{{ info.remarks }}</a-descriptions-item>
+        </a-descriptions>
+      </div>
+
+      <div class="device-dtl-wrapper">
+        <div class="title">扩展属性</div>
+        <a-descriptions bordered size="small">
+          <!-- 扩展属性 -->
+        </a-descriptions>
+      </div>
+
+      <div class="device-dtl-wrapper">
+        <div class="title">专有属性</div>
+        <a-descriptions bordered size="small">
+          <!-- 专有属性 -->
+        </a-descriptions>
+      </div>
+
+      <div class="device-dtl-wrapper">
+        <div class="title">设备图片</div>
+        <a-card style="width: 100%" :bodyStyle="{ padding: '10px', minHeight: '40px' }">
+          <a-image-preview-group v-if="info.imageUrl">
+            <a-image :width="200" v-for="(img, index) in handleImage" :key="index" :src="img" />
+          </a-image-preview-group>
+        </a-card>
+      </div>
+    </a-col>
+    <a-col :span="14" class="device-dtl-baseinfo-col right-col">
+      <div class="device-dtl-wrapper">
+        <div class="title">验收信息</div>
+        <a-card style="width: 80%">
+          <a-steps
+            :current="4"
+            size="small"
+            label-placement="vertical"
+            :items="[
+              {
+                title: '到货验收',
+                subTitle: 'SBYS2020000118',
+                description: '2020-11-24',
+              },
+              {
+                title: '试运行验收',
+                subTitle: 'SBYS2020000119',
+                description: '2020-11-24',
+              },
+              {
+                title: '到货验收',
+                subTitle: 'SBYS2020000120',
+                description: '2020-11-24',
+              },
+              {
+                title: '到货验收',
+                subTitle: 'SBYS2020000121',
+                description: '2020-11-24',
+              },
+              {
+                title: '试运行验收',
+                subTitle: 'SBYS2020000122',
+                description: '2020-11-24',
+              },
+            ]"
+          />
+        </a-card>
+      </div>
+      <div class="device-dtl-wrapper">
+        <div class="title">子设备</div>
+        <BasicTable @register="registerSubTable" />
+      </div>
+      <div class="device-dtl-wrapper">
+        <div class="title">父设备</div>
+        <BasicTable @register="registerParentTable" />
+      </div>
+      <div class="device-dtl-wrapper">
+        <div class="title">设备关联备件</div>
+        <BasicTable @register="registerMaterialTable" />
+      </div>
+    </a-col>
+  </a-row>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { Image as AImage } from 'ant-design-vue';
+  import { render } from '/@/utils/common/renderUtils';
+  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
+  import { BasicTable } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { dtlColumns, spareColumns } from '../../DeviceBaseInfo.data';
+  import { queryDeviceBaseInfoByParentId, materialList } from '../../DeviceBaseInfo.api';
+  export default defineComponent({
+    components: { AImage, AImagePreviewGroup: AImage.PreviewGroup, BasicTable },
+    props: {
+      info: {
+        type: Object,
+        default: () => {},
+      },
+    },
+    setup(props) {
+      // 注册子设备table数据
+      const { tableContext: tableSubContext } = useListPage({
+        tableProps: {
+          title: '',
+          api: queryDeviceBaseInfoByParentId,
+          columns: dtlColumns,
+          size: 'small',
+          canResize: false,
+          showTableSetting: false,
+          showActionColumn: false,
+          beforeFetch: (params) => {
+            return Object.assign(params, { deviceId: props.info.id, queryType: 2 });
+          },
+        },
+      });
+
+      const [registerSubTable] = tableSubContext;
+
+      // 注册父设备table数据
+      const { tableContext: tableParentContext } = useListPage({
+        tableProps: {
+          title: '',
+          api: queryDeviceBaseInfoByParentId,
+          size: 'small',
+          columns: dtlColumns,
+          canResize: false,
+          showTableSetting: false,
+          showActionColumn: false,
+          beforeFetch: (params) => {
+            return Object.assign(params, { deviceId: props.info.id, queryType: 1 });
+          },
+        },
+      });
+      const [registerParentTable] = tableParentContext;
+
+      // 注册材料table数据
+      const { tableContext: tableMaterialContext } = useListPage({
+        tableProps: {
+          title: '',
+          api: materialList,
+          size: 'small',
+          columns: spareColumns,
+          canResize: false,
+          showTableSetting: false,
+          showActionColumn: false,
+          beforeFetch: (params) => {
+            return Object.assign(params, { deviceId: props.info.id });
+          },
+        },
+      });
+      const [registerMaterialTable] = tableMaterialContext;
+
+      // 渲染字典标签
+      const renderDictTag = (value: string, dictCode: string) => {
+        return render.renderDictTag(value, dictCode);
+      };
+
+      return { renderDictTag, registerSubTable, registerParentTable, registerMaterialTable };
+    },
+    computed: {
+      // 处理图片
+      handleImage() {
+        const { info } = this;
+        if (!info || !info.imageUrl) return [];
+        return info.imageUrl.split(',').map((item) => {
+          return getFileAccessHttpUrl(item);
+        });
+      },
+    },
+  });
+</script>
+<style scoped lang="less">
+  .device-dtl-baseinfo-wrapper {
+    overflow: hidden;
+    height: 100%;
+
+    .device-dtl-baseinfo-col {
+      height: 100%;
+      overflow: auto;
+    }
+
+    .ant-descriptions {
+      :deep(.ant-descriptions-view) {
+        min-height: 40px;
+      }
+    }
+
+    :deep(.ant-descriptions-item-label) {
+      min-width: 101px;
+    }
+
+    .device-dtl-wrapper {
+      margin-bottom: 10px;
+
+      .title {
+        font-size: 14px;
+        font-weight: bold;
+        margin-bottom: 10px;
+        color: var(--vxe-primary-color);
+      }
+    }
+
+    .right-col {
+      .jeecg-basic-table {
+        padding: 0;
+      }
+    }
+  }
+</style>

+ 2 - 14
src/views/equipmentLifecycle/supplier/list/index.vue

@@ -42,8 +42,8 @@
       <!--字段回显插槽-->
       <!-- <template v-slot:bodyCell="{ column, record, index, text }"> </template> -->
       <template #disable="{ record }">
-        <Icon icon="ant-design:check-outlined" class="check-icon no-checked" v-if="record.isMeteringDevice === true" />
-        <Icon icon="ant-design:close-outlined" class="check-icon checked" v-else />
+        <Icon icon="ant-design:check-outlined" class="zgztel-check-icon no-checked" v-if="record.isMeteringDevice === true" />
+        <Icon icon="ant-design:close-outlined" class="zgztel-check-icon checked" v-else />
       </template>
       <template #grade="{ record }">
         <a-rate :value="Number(record.grade)" :allowHalf="true" :disabled="true" />
@@ -202,16 +202,4 @@
   :deep(.ant-input-number) {
     width: 100%;
   }
-  .check-icon {
-    font-size: 24px;
-    font-weight: bolder;
-
-    &.checked {
-      color: #389e0d;
-    }
-
-    &.no-checked {
-      color: #ff4d4f;
-    }
-  }
 </style>

Some files were not shown because too many files changed in this diff