Эх сурвалжийг харах

Merge remote-tracking branch 'origin/master'

lipenghui 3 сар өмнө
parent
commit
25cea8222b

+ 6 - 0
src/api/pms/iotdeviceperson/index.ts

@@ -5,6 +5,7 @@ export interface IotDevicePersonVO {
   id: number // 主键id
   deviceId: number // 设备id
   personId: number // 负责人id
+  personName: string  // 负责人姓名
   status: number // 开启状态 0启用  1停用
   remark: string // 备注
 }
@@ -16,6 +17,11 @@ export const IotDevicePersonApi = {
     return await request.get({ url: `/pms/iot-device-person/page`, params })
   },
 
+  // 根据设备id集合查询设备的负责人列表
+  getPersonsByDeviceIds: async (params: any) => {
+    return await request.get({ url: `/pms/iot-device-person/getPersonsByDeviceIds`, params })
+  },
+
   // 查询设备负责人分配详情
   getIotDevicePerson: async (id: number) => {
     return await request.get({ url: `/pms/iot-device-person/get?id=` + id })

+ 9 - 1
src/views/pms/bom/index.vue

@@ -58,6 +58,7 @@
             <el-button type="danger" plain @click="toggleExpandAll">
               <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
             </el-button>
+            <el-button @click="handleAllQuery"><Icon icon="ep:search" class="mr-5px" /> 查询所有</el-button>
           </el-form-item>
         </el-form>
       </ContentWrap>
@@ -87,7 +88,7 @@
               </el-tooltip>
             </template>
           </el-table-column>
-          <!-- <el-table-column prop="deviceCategoryName" label="设备分类" /> -->
+          <el-table-column prop="deviceCategoryName" label="设备分类" />
           <el-table-column prop="sort" label="排序" />
           <el-table-column prop="status" label="状态" >
             <template #default="scope">
@@ -254,6 +255,13 @@ const handleQuery = () => {
   getList()
 }
 
+/** 查询所有数据 */
+const handleAllQuery = () => {
+  queryParams.pageNo = 1
+  queryParams.deviceCategoryId = ''
+  getList()
+}
+
 /** 重置按钮操作 */
 const resetQuery = () => {
   queryFormRef.value?.resetFields()

+ 8 - 0
src/views/pms/devicetemplate/index.vue

@@ -74,6 +74,7 @@
             >
               <Icon icon="ep:plus" /> 新增
             </el-button>
+            <el-button @click="handleAllQuery"><Icon icon="ep:search" />查询所有</el-button>
           </el-form-item>
         </el-form>
       </ContentWrap>
@@ -226,6 +227,13 @@ const handleQuery = () => {
   getList()
 }
 
+/** 搜索按钮操作 */
+const handleAllQuery = () => {
+  queryParams.pageNo = 1
+  queryParams.deviceCategoryId = ''
+  getList()
+}
+
 /** 重置按钮操作 */
 const resetQuery = () => {
   queryFormRef.value?.resetFields()

+ 1 - 90
src/views/pms/iotmainworkorder/IotMainWorkOrderAdd.vue

@@ -22,7 +22,7 @@
           </el-col>
           <el-col :span="8">
             <el-form-item label="责任人" prop="responsiblePerson">
-              <el-select v-model="formData.responsiblePerson" filterable clearable style="width: 100%">
+              <el-select v-model="formData.responsiblePerson" filterable clearable style="width: 100%" disabled>
                 <el-option
                   v-for="item in deptUsers"
                   :key="item.id"
@@ -402,7 +402,6 @@
   />
 </template>
 <script setup lang="ts">
-import { IotMaintainApi, IotMaintainVO } from '@/api/pms/maintain'
 import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
 import * as UserApi from '@/api/system/user'
 import { useUserStore } from '@/store/modules/user'
@@ -411,7 +410,6 @@ import type { ComponentPublicInstance } from 'vue'
 import { IotMaintenanceBomApi, IotMaintenanceBomVO } from '@/api/pms/iotmaintenancebom'
 import { IotMainWorkOrderBomApi, IotMainWorkOrderBomVO } from '@/api/pms/iotmainworkorderbom'
 import { IotMainWorkOrderBomMaterialApi, IotMainWorkOrderBomMaterialVO } from '@/api/pms/iotmainworkorderbommaterial'
-import { IotMaintenancePlanApi, IotMaintenancePlanVO } from '@/api/pms/maintenance'
 import { IotMainWorkOrderApi, IotMainWorkOrderVO } from '@/api/pms/iotmainworkorder'
 import { useTagsViewStore } from '@/store/modules/tagsView'
 import {CACHE_KEY, useCache} from "@/hooks/web/useCache";
@@ -760,15 +758,6 @@ const submitForm = async () => {
     message.success(t('common.createSuccess'))
     close()
 
-    /* if (formType.value === 'create') {
-      await IotMaintenancePlanApi.createIotMaintenancePlan(data)
-      message.success(t('common.createSuccess'))
-      close()
-    } else {
-      await IotMaintainApi.updateIotMaintain(data)
-      message.success(t('common.updateSuccess'))
-      close()
-    } */
     // 发送操作成功的事件
     emit('success')
   } finally {
@@ -826,66 +815,6 @@ const validateTableData = (): boolean => {
     message.error('请至少添加一条设备保养明细')
     return isValid
   }
-
-  /* list.value.forEach((row, index) => {
-    if (shouldBreak) return;
-    const rowNumber = index + 1 // 用户可见的行号从1开始
-    const deviceIdentifier = `${row.deviceCode}-${row.name}` // 设备标识
-    // 校验逻辑
-    const checkConfig = (ruleName: string, ruleValue: number, configField: keyof typeof row) => {
-      if (ruleValue === 0) { // 规则开启
-        if (!row[configField] || row[configField] <= 0) {
-          configErrors.push(`第 ${rowNumber} 行(${deviceIdentifier}):请点击【配置】维护${ruleName}上次保养值`)
-          isValid = false
-        }
-      }
-    }
-    // 里程校验逻辑
-    if (row.mileageRule === 0) { // 假设 0 表示开启状态
-      if (!row.nextRunningKilometers || row.nextRunningKilometers <= 0) {
-        errorMessages.push(`第 ${rowNumber} 行:开启里程规则必须填写有效的里程周期`)
-        isValid = false
-      }
-      // 再校验配置值
-      checkConfig('里程', row.mileageRule, 'lastRunningKilometers')
-    } else {
-      noRules.push(`第 ${rowNumber} 行:未设置里程规则`)
-    }
-    // 运行时间校验逻辑
-    if (row.runningTimeRule === 0) {
-      if (!row.nextRunningTime || row.nextRunningTime <= 0) {
-        errorMessages.push(`第 ${rowNumber} 行:开启运行时间规则必须填写有效的时间周期`)
-        isValid = false
-      }
-      checkConfig('运行时间', row.runningTimeRule, 'lastRunningTime')
-    } else {
-      noRules.push(`第 ${rowNumber} 行:未设置运行时间规则`)
-    }
-    // 自然日期校验逻辑
-    if (row.naturalDateRule === 0) {
-      if (!row.nextNaturalDate) {
-        errorMessages.push(`第 ${rowNumber} 行:开启自然日期规则必须填写有效的自然日期周期`)
-        isValid = false
-      }
-      checkConfig('自然日期', row.naturalDateRule, 'lastNaturalDate')
-    } else {
-      noRules.push(`第 ${rowNumber} 行:未设置自然日期规则`)
-    }
-    // 如果选中的一行记录未设置任何保养规则 提示 ‘保养项未设置任何保养规则’
-    if (noRules.length === 3) {
-      isValid = false
-      shouldBreak = true; // 设置标志变量为true,退出循环
-      noRulesErrorMessages.push('保养项至少设置1个保养规则')
-    }
-    noRules.length = 0;
-  })
-  if (errorMessages.length > 0) {
-    message.error('设置保养规则后,请维护对应的周期值')
-  } else if (noRulesErrorMessages.length > 0) {
-    message.error(noRulesErrorMessages.pop())
-  } else if (configErrors.length > 0) {
-    message.error(configErrors.pop())
-  } */
   return isValid
 }
 
@@ -920,24 +849,6 @@ onMounted(async () => {
     const { wsCache } = useCache()
     const userInfo = wsCache.get(CACHE_KEY.USER)
     formData.value.responsiblePerson = userInfo.user.id;
-    // 查询保养工单 主表数据
-    // const workOrder = await IotMainWorkOrderApi.getIotMainWorkOrder(id);
-    // formData.value = workOrder
-    // 查询保养责任人
-    /* const personId = formData.value.responsiblePerson ? Number(formData.value.responsiblePerson) : 0;
-    UserApi.getUser(personId).then((res) => {
-      formData.value.responsiblePerson = res.nickname;
-    }) */
-    // 查询保养工单 明细数据
-    /* const data = await IotMainWorkOrderBomApi.getWorkOrderBOMs(queryParams);
-    list.value = []
-    if (Array.isArray(data)) {
-      list.value = data.map(item => ({
-        ...item,
-        // 这里可以添加必要的字段转换(如果有日期等需要格式化的字段)
-        lastNaturalDate: item.lastNaturalDate ? dayjs(item.lastNaturalDate).format('YYYY-MM-DD') : null
-      }))
-    } */
   } catch (error) {
     console.error('数据加载失败:', error)
     message.error('数据加载失败,请重试')

+ 3 - 1
src/views/pms/iotmainworkorder/index.vue

@@ -75,13 +75,15 @@
           {{ scope.$index + 1 }}
         </template>
       </el-table-column>
-      <el-table-column label="工单号" align="center" prop="orderNumber" />
+      <!--
+      <el-table-column label="工单号" align="center" prop="orderNumber" /> -->
       <el-table-column label="工单名称" align="center" prop="name" />
       <el-table-column label="保养状态" align="center" prop="result" >
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT" :value="scope.row.result" />
         </template>
       </el-table-column>
+      <el-table-column label="距离保养" align="center" prop="maintenanceInterval" />
       <el-table-column label="工单类型" align="center" prop="type" >
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE" :value="scope.row.type" />

+ 105 - 4
src/views/pms/maintenance/IotMaintenancePlan.vue

@@ -32,11 +32,16 @@
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="16">
             <el-form-item label="备注" prop="remark">
               <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
             </el-form-item>
           </el-col>
+          <el-col :span="8">
+            <el-form-item label="设备责任人" prop="devicePersons">
+              <el-input type="text" v-model="formData.devicePersons"  disabled/>
+            </el-form-item>
+          </el-col>
         </el-row>
       </div>
     </el-form>
@@ -68,6 +73,7 @@
           width="60"
           align="center"
         />
+        <el-table-column label="设备id" align="center" prop="deviceId" v-if="false"/>
         <el-table-column label="设备编码" align="center" prop="deviceCode" />
         <el-table-column label="设备名称" align="center" prop="deviceName" />
         <el-table-column label="累计运行时间(H)" align="center" prop="totalRunTime" :formatter="erpPriceTableColumnFormatter"/>
@@ -130,7 +136,7 @@
                   style="vertical-align: middle"
                   link
                   type="danger"
-                  @click="handleDelete(scope.row.id+'-'+scope.row.bomNodeId)"
+                  @click="handleDelete(scope.row.deviceId+'-'+scope.row.bomNodeId)"
                 >
                   移除
                 </el-button>
@@ -285,6 +291,14 @@
     </template>
   </el-dialog>
 
+  <div class="temp-list card" v-if="false">
+    <h3>已经选择的设备关联的负责人列表</h3>
+    <el-table :data="tempDevicePersons" style="width: 100%" >
+      <el-table-column prop="tempDeviceIds" label="设备id" width="200" />
+      <el-table-column prop="tempPersonNames" label="责任人姓名" />
+    </el-table>
+  </div>
+
 </template>
 <script setup lang="ts">
 import { IotMaintainApi, IotMaintainVO } from '@/api/pms/maintain'
@@ -293,6 +307,7 @@ import * as UserApi from '@/api/system/user'
 import { useUserStore } from '@/store/modules/user'
 import { ref } from 'vue'
 import { IotMaintenanceBomApi, IotMaintenanceBomVO } from '@/api/pms/iotmaintenancebom'
+import { IotDevicePersonApi, IotDevicePersonVO } from '@/api/pms/iotdeviceperson'
 import { IotMaintenancePlanApi, IotMaintenancePlanVO } from '@/api/pms/maintenance'
 import { useTagsViewStore } from '@/store/modules/tagsView'
 import {CACHE_KEY, useCache} from "@/hooks/web/useCache";
@@ -316,7 +331,21 @@ const formLoading = ref(false) // 表单的加载中:1)修改时的数据加
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
 const deviceLabel = ref('') // 表单的类型:create - 新增;update - 修改
 const list = ref<IotMaintenanceBomVO[]>([]) // 设备bom关联列表的数据
+const devicePersonsMap = ref<Map<number, Set<string>>>(new Map()) // 存储设备-责任人映射
+const tempDevicePersons = ref<Array<{
+  tempDeviceIds: number[]
+  tempDeviceNames: string
+  tempPersonIds: number[]
+  tempPersonNames: string
+}>>([])
 const deviceIds = ref<number[]>([]) // 已经选择的设备id数组
+const totalDeviceIds = ref<number[]>([]) // 列表区域暂存的设备id数组 包括之前选择的+当前选择的
+
+/** 获取当前所有设备ID集合 */
+const getCurrentDeviceIds = (): number[] => {
+  return [...new Set(list.value.map(item => item.deviceId))]
+}
+
 const { params, name } = useRoute() // 查询参数
 const id = params.id
 const formData = ref({
@@ -328,13 +357,20 @@ const formData = ref({
   remark: undefined,
   failureName: undefined,
   status: undefined,
+  devicePersons: '',
 })
+
 const formRules = reactive({
   name: [{ required: true, message: '计划名称不能为空', trigger: 'blur' }],
   responsiblePerson: [{ required: true, message: '责任人不能为空', trigger: 'blur' }],
 })
 const formRef = ref() // 表单 Ref
 
+interface DevicePerson {
+  deviceId: number
+  personName: string
+}
+
 // 新增配置相关状态
 const configDialog = reactive({
   visible: false,
@@ -445,6 +481,48 @@ const queryParams = reactive({
   planId: id
 })
 
+/**
+ * 根据选择的设备查询所有设备关联的 责任人姓名 逗号分隔
+ */
+async function getDevicePersons() {
+  // 获取当前已经选择的设备ID集合
+  const existDeviceIds = getCurrentDeviceIds()
+  if (existDeviceIds.length === 0) {
+    formData.value.devicePersons = ''
+    return
+  }
+  try {
+    // 调用接口获取数据
+    const params = {
+      deviceIds: existDeviceIds.join(',') // 明确传递数组参数
+    }
+    const res = await IotDevicePersonApi.getPersonsByDeviceIds(params)
+    const personsData = res || []
+    // 清空旧数据
+    devicePersonsMap.value.clear()
+    // 处理接口数据
+    personsData.forEach((item: { deviceId: number; personName: string }) => {
+      if (!devicePersonsMap.value.has(item.deviceId)) {
+        devicePersonsMap.value.set(item.deviceId, new Set())
+      }
+      devicePersonsMap.value.get(item.deviceId)?.add(item.personName)
+    })
+    // 生成展示字符串
+    updateDevicePersonsDisplay()
+  } catch (error) {
+    console.error('获取设备责任人失败:', error)
+  }
+}
+
+/** 更新责任人显示 */
+function updateDevicePersonsDisplay() {
+  const allNames = new Set<string>()
+  devicePersonsMap.value.forEach(names => {
+    names.forEach(name => allNames.add(name))
+  })
+  formData.value.devicePersons = Array.from(allNames).join(', ')
+}
+
 const deviceChoose = async(selectedDevices) => {
   const newIds = selectedDevices.map(device => device.id)
   deviceIds.value = [...new Set([...deviceIds.value, ...newIds])]
@@ -499,6 +577,8 @@ const deviceChoose = async(selectedDevices) => {
       list.value.push(item)
     }
   })
+  // 新增完设备后 查询现有设备-bom明细中 所有设备配置的负责人姓名 逗号分隔
+  await getDevicePersons();
 }
 
 const deviceFormRef = ref<InstanceType<typeof MainPlanDeviceList>>()
@@ -715,14 +795,35 @@ onMounted(async () => {
   }
 })
 const handleDelete = async (str: string) => {
-  try {
+  /* try {
     const index = list.value.findIndex((item) => (item.id+'-'+item.bomNodeId) === str)
     if (index !== -1) {
       // 通过 splice 删除元素
       list.value.splice(index, 1)
       deviceIds.value = []
     }
-  } catch {}
+  } catch {} */
+  try {
+    const [deviceIdStr, bomNodeId] = str.split('-')
+    const deviceId = parseInt(deviceIdStr)
+    // 删除列表项
+    const index = list.value.findIndex((item) => (item.deviceId+'-'+item.bomNodeId) === str)
+    if (index !== -1) {
+      list.value.splice(index, 1)
+      deviceIds.value = []
+    }
+    // 更新设备ID列表(需要检查是否还有该设备的其他项)
+    const hasOtherItems = list.value.some(item => item.deviceId === deviceId)
+    if (!hasOtherItems) {
+      deviceIds.value = deviceIds.value.filter(id => id !== deviceId)
+      devicePersonsMap.value.delete(deviceId) // 移除对应设备的责任人
+      updateDevicePersonsDisplay() // 立即更新显示
+    }
+    // message.success('移除成功')
+  } catch (error) {
+    console.error('移除失败:', error)
+    message.error('移除失败')
+  }
 }
 </script>
 <style scoped>