Pārlūkot izejas kodu

pms 保养计划 功能迭代

zhangcl 3 mēneši atpakaļ
vecāks
revīzija
2949571019

+ 13 - 0
src/api/pms/device/index.ts

@@ -31,6 +31,9 @@ export interface IotDeviceVO {
   infoRemark: string // 资料备注
   infoUrl: string // 资料附件
   templateJson: string // 动态模板信息
+  bomNodeId: number // bom节点id
+  name: string // bom节点名称
+  code: string // bom节点编码
 }
 
 // 设备台账 API
@@ -40,6 +43,16 @@ export const IotDeviceApi = {
     return await request.get({ url: `/rq/iot-device/page`, params })
   },
 
+  // 查询 设备bom关联 列表分页
+  deviceAssociateBomPage: async (params: any) => {
+    return await request.get({ url: `/rq/iot-device/deviceAssociateBomPage`, params })
+  },
+
+  // 查询 设备 bom关联 列表
+  deviceAssociateBomList: async (params: any) => {
+    return await request.get({ url: `/rq/iot-device/deviceAssociateBomList`, params })
+  },
+
   // 查询设备台账详情
   getIotDevice: async (id: number) => {
     return await request.get({ url: `/rq/iot-device/get?id=` + id })

+ 70 - 61
src/api/pms/iotmaintenancebom/index.ts

@@ -1,61 +1,70 @@
-import request from '@/config/axios'
-
-// PMS 保养计划明细BOM VO
-export interface IotMaintenanceBomVO {
-  id: number // 主键
-  planId: number // 保养计划id
-  planDetailId: number // 保养计划明细id
-  deviceCategoryId: number // 所属设备分类
-  deviceId: number // 设备id
-  rule: string // 保养规则(量程 运行时间 自然日期) 可多选
-  lastRunningTime: number // 上次保养运行时长(小时)
-  nextRunningTime: number // 下次保养运行时长(小时)
-  lastRunningKilometers: number // 上次保养运行公里数(千米)
-  nextRunningKilometers: number // 下次保养运行公里数(千米)
-  lastNaturalDate: number // 上次保养自然日期(天)
-  nextNaturalDate: number // 下次保养自然日期(天)
-  name: string // BOM名称
-  code: string // BOM编码
-  parentId: number // 父BOM id 顶级为0
-  childIds: string // 子节点id 逗号分隔
-  level: number // 层级
-  leafFlag: number // 是否叶子节点 0是 1否
-  sort: number // 显示顺序
-  type: string // M维修 S保养 维修+保养
-  status: number // 状态 0启用  1停用
-  remark: string // 备注
-  version: number // 版本
-}
-
-// PMS 保养计划明细BOM API
-export const IotMaintenanceBomApi = {
-  // 查询PMS 保养计划明细BOM分页
-  getIotMaintenanceBomPage: async (params: any) => {
-    return await request.get({ url: `/rq/iot-maintenance-bom/page`, params })
-  },
-
-  // 查询PMS 保养计划明细BOM详情
-  getIotMaintenanceBom: async (id: number) => {
-    return await request.get({ url: `/rq/iot-maintenance-bom/get?id=` + id })
-  },
-
-  // 新增PMS 保养计划明细BOM
-  createIotMaintenanceBom: async (data: IotMaintenanceBomVO) => {
-    return await request.post({ url: `/rq/iot-maintenance-bom/create`, data })
-  },
-
-  // 修改PMS 保养计划明细BOM
-  updateIotMaintenanceBom: async (data: IotMaintenanceBomVO) => {
-    return await request.put({ url: `/rq/iot-maintenance-bom/update`, data })
-  },
-
-  // 删除PMS 保养计划明细BOM
-  deleteIotMaintenanceBom: async (id: number) => {
-    return await request.delete({ url: `/rq/iot-maintenance-bom/delete?id=` + id })
-  },
-
-  // 导出PMS 保养计划明细BOM Excel
-  exportIotMaintenanceBom: async (params) => {
-    return await request.download({ url: `/rq/iot-maintenance-bom/export-excel`, params })
-  },
-}
+import request from '@/config/axios'
+
+// PMS 保养计划明细BOM VO
+export interface IotMaintenanceBomVO {
+  id: number // 主键
+  planId: number // 保养计划id
+  planDetailId: number // 保养计划明细id
+  deviceCategoryId: number // 所属设备分类
+  deviceId: number // 设备id
+  rule: string // 保养规则(里程 运行时间 自然日期) 可多选
+  mileageRule: number       // 保养规则-里程(0启用 1停用)
+  naturalDateRule: number   // 保养规则-自然日期(0启用 1停用)
+  runningTimeRule: number   // 保养规则-运行时间(0启用 1停用)
+  lastRunningTime: number // 上次保养运行时长(小时)
+  nextRunningTime: number // 下次保养运行时长(小时)
+  lastRunningKilometers: number // 上次保养运行公里数(千米)
+  nextRunningKilometers: number // 下次保养运行公里数(千米)
+  lastNaturalDate: number // 上次保养自然日期(天)
+  nextNaturalDate: number // 下次保养自然日期(天)
+  bomNodeId: number // bom节点id
+  name: string // BOM名称
+  code: string // BOM编码
+  parentId: number // 父BOM id 顶级为0
+  childIds: string // 子节点id 逗号分隔
+  level: number // 层级
+  leafFlag: number // 是否叶子节点 0是 1否
+  sort: number // 显示顺序
+  type: string // 1维修 2保养 维修+保养
+  status: number // 状态 0启用  1停用
+  remark: string // 备注
+  version: number // 版本
+  // 扩展字段
+  deviceName: string  // 设备名称
+  deviceCode: string  // 设备编码
+  deviceStatus: string  // 设备状态
+  assetProperty: string //资产性质
+}
+
+// PMS 保养计划明细BOM API
+export const IotMaintenanceBomApi = {
+  // 查询PMS 保养计划明细BOM分页
+  getIotMaintenanceBomPage: async (params: any) => {
+    return await request.get({ url: `/rq/iot-maintenance-bom/page`, params })
+  },
+
+  // 查询PMS 保养计划明细BOM详情
+  getIotMaintenanceBom: async (id: number) => {
+    return await request.get({ url: `/rq/iot-maintenance-bom/get?id=` + id })
+  },
+
+  // 新增PMS 保养计划明细BOM
+  createIotMaintenanceBom: async (data: any) => {
+    return await request.post({ url: `/rq/iot-maintenance-bom/create`, data })
+  },
+
+  // 修改PMS 保养计划明细BOM
+  updateIotMaintenanceBom: async (data: IotMaintenanceBomVO) => {
+    return await request.put({ url: `/rq/iot-maintenance-bom/update`, data })
+  },
+
+  // 删除PMS 保养计划明细BOM
+  deleteIotMaintenanceBom: async (id: number) => {
+    return await request.delete({ url: `/rq/iot-maintenance-bom/delete?id=` + id })
+  },
+
+  // 导出PMS 保养计划明细BOM Excel
+  exportIotMaintenanceBom: async (params) => {
+    return await request.download({ url: `/rq/iot-maintenance-bom/export-excel`, params })
+  },
+}

+ 46 - 46
src/api/pms/maintenance/index.ts

@@ -1,46 +1,46 @@
-import request from '@/config/axios'
-
-// 保养计划 VO
-export interface IotMaintenancePlanVO {
-  id: number // 主键id
-  deptId: number // 组织id
-  serialNumber: string // 计划编号 自动生成
-  name: string // 计划名称 默认以队伍名称生成
-  responsiblePerson: string // 负责人id 多个以逗号分隔
-  responsiblePersonName: string // 负责人id 多个以逗号分隔
-  remark: string // 备注
-  status: number // 状态 0启用  1停用
-}
-
-// 保养计划 API
-export const IotMaintenancePlanApi = {
-  // 查询保养计划分页
-  getIotMaintenancePlanPage: async (params: any) => {
-    return await request.get({ url: `/rq/iot-maintenance-plan/page`, params })
-  },
-
-  // 查询保养计划详情
-  getIotMaintenancePlan: async (id: number) => {
-    return await request.get({ url: `/rq/iot-maintenance-plan/get?id=` + id })
-  },
-
-  // 新增保养计划
-  createIotMaintenancePlan: async (data: IotMaintenancePlanVO) => {
-    return await request.post({ url: `/rq/iot-maintenance-plan/create`, data })
-  },
-
-  // 修改保养计划
-  updateIotMaintenancePlan: async (data: IotMaintenancePlanVO) => {
-    return await request.put({ url: `/rq/iot-maintenance-plan/update`, data })
-  },
-
-  // 删除保养计划
-  deleteIotMaintenancePlan: async (id: number) => {
-    return await request.delete({ url: `/rq/iot-maintenance-plan/delete?id=` + id })
-  },
-
-  // 导出保养计划 Excel
-  exportIotMaintenancePlan: async (params) => {
-    return await request.download({ url: `/rq/iot-maintenance-plan/export-excel`, params })
-  },
-}
+import request from '@/config/axios'
+
+// 保养计划 VO
+export interface IotMaintenancePlanVO {
+  id: number // 主键id
+  deptId: number // 组织id
+  serialNumber: string // 计划编号 自动生成
+  name: string // 计划名称 默认以队伍名称生成
+  responsiblePerson: string // 负责人id 多个以逗号分隔
+  responsiblePersonName: string // 负责人id 多个以逗号分隔
+  remark: string // 备注
+  status: number // 状态 0启用  1停用
+}
+
+// 保养计划 API
+export const IotMaintenancePlanApi = {
+  // 查询保养计划分页
+  getIotMaintenancePlanPage: async (params: any) => {
+    return await request.get({ url: `/rq/iot-maintenance-plan/page`, params })
+  },
+
+  // 查询保养计划详情
+  getIotMaintenancePlan: async (id: number) => {
+    return await request.get({ url: `/rq/iot-maintenance-plan/get?id=` + id })
+  },
+
+  // 新增保养计划
+  createIotMaintenancePlan: async (data: any) => {
+    return await request.post({ url: `/rq/iot-maintenance-plan/create`, data })
+  },
+
+  // 修改保养计划
+  updateIotMaintenancePlan: async (data: IotMaintenancePlanVO) => {
+    return await request.put({ url: `/rq/iot-maintenance-plan/update`, data })
+  },
+
+  // 删除保养计划
+  deleteIotMaintenancePlan: async (id: number) => {
+    return await request.delete({ url: `/rq/iot-maintenance-plan/delete?id=` + id })
+  },
+
+  // 导出保养计划 Excel
+  exportIotMaintenancePlan: async (params) => {
+    return await request.download({ url: `/rq/iot-maintenance-plan/export-excel`, params })
+  },
+}

+ 269 - 52
src/views/pms/maintenance/IotMaintenancePlan.vue

@@ -63,32 +63,75 @@
       <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
         <el-table-column label="设备编码" align="center" prop="deviceCode" />
         <el-table-column label="设备名称" align="center" prop="deviceName" />
-        <el-table-column label="所属部门" align="center" prop="deptName" />
-        <el-table-column label="设备状态" align="center" prop="deviceStatus" >
+        <el-table-column label="运行时间(H)" align="center" prop="runningTime" :formatter="erpPriceTableColumnFormatter"/>
+        <el-table-column label="运行公里数(KM)" align="center" prop="runningKilometers" :formatter="erpPriceTableColumnFormatter"/>
+        <el-table-column label="BOM节点" align="center" prop="name" />
+        <el-table-column label="里程" key="mileageRule">
           <template #default="scope">
-            <dict-tag :type="DICT_TYPE.PMS_DEVICE_STATUS" :value="scope.row.deviceStatus" />
+            <el-switch
+              v-model="scope.row.mileageRule"
+              :active-value="0"
+              :inactive-value="1"
+            />
           </template>
         </el-table-column>
-        <el-table-column label="资产性质" align="center" prop="assetProperty" >
+        <el-table-column label="里程周期(H)" align="center" prop="nextRunningKilometers" :formatter="erpPriceTableColumnFormatter">
           <template #default="scope">
-            <dict-tag :type="DICT_TYPE.PMS_ASSET_PROPERTY" :value="scope.row.assetProperty" />
+            <el-input v-model="scope.row.nextRunningKilometers" />
+          </template>
+        </el-table-column>
+        <el-table-column label="运行时间" key="runningTimeRule">
+          <template #default="scope">
+            <el-switch
+              v-model="scope.row.runningTimeRule"
+              :active-value="0"
+              :inactive-value="1"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="时间周期(H)" align="center" prop="nextRunningTime" :formatter="erpPriceTableColumnFormatter">
+          <template #default="scope">
+            <el-input v-model="scope.row.nextRunningTime" />
+          </template>
+        </el-table-column>
+        <el-table-column label="自然日期" key="naturalDateRule">
+          <template #default="scope">
+            <el-switch
+              v-model="scope.row.naturalDateRule"
+              :active-value="0"
+              :inactive-value="1"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="自然日期(D)" align="center" prop="nextNaturalDate" :formatter="erpPriceTableColumnFormatter">
+          <template #default="scope">
+            <el-input v-model="scope.row.nextNaturalDate" />
           </template>
         </el-table-column>
-        <el-table-column label="备注" align="center" prop="remark" />
         <el-table-column label="操作" align="center" min-width="120px">
           <template #default="scope">
             <div style="display: flex; justify-content: center; align-items: center; width: 100%">
-              <div>
+                <div>
                 <Icon style="vertical-align: middle; color: #ea3434" icon="ep:zoom-out" />
                 <el-button
                   style="vertical-align: middle"
                   link
                   type="danger"
-                  @click="handleDelete(scope.row.id)"
+                  @click="handleDelete(scope.row.id+'-'+scope.row.bomNodeId)"
                 >
                   移除
                 </el-button>
               </div>
+              <!-- 新增配置按钮 -->
+              <div style="margin-left: 12px">
+                <el-button
+                  link
+                  type="primary"
+                  @click="openConfigDialog(scope.row)"
+                >
+                  配置
+                </el-button>
+              </div>
             </div>
           </template>
         </el-table-column>
@@ -104,17 +147,73 @@
     </el-form>
   </ContentWrap>
   <MainPlanDeviceList ref="deviceFormRef" @choose="deviceChoose" />
+  <!-- 新增配置对话框 -->
+  <el-dialog
+    v-model="configDialog.visible"
+    :title="`设备 ${configDialog.current?.deviceCode+'-'+configDialog.current?.name} 保养配置`"
+    width="600px"
+  >
+    <el-form :model="configDialog.form" label-width="160px">
+      <!-- 里程配置 -->
+      <el-form-item
+        v-if="configDialog.current?.mileageRule === 0"
+        label="上次保养里程数(KM)"
+        prop="lastRunningKilometers"
+      >
+        <el-input-number
+          v-model="configDialog.form.lastRunningKilometers"
+          :precision="2"
+          :min="0"
+          controls-position="right"
+        />
+      </el-form-item>
+      <!-- 运行时间配置 -->
+      <el-form-item
+        v-if="configDialog.current?.runningTimeRule === 0"
+        label="上次保养运行时间(H)"
+        prop="lastRunningTime"
+      >
+        <el-input-number
+          v-model="configDialog.form.lastRunningTime"
+          :precision="1"
+          :min="0"
+          controls-position="right"
+        />
+      </el-form-item>
+      <!-- 自然日期配置 -->
+      <el-form-item
+        v-if="configDialog.current?.naturalDateRule === 0"
+        label="上次保养自然日期(D)"
+        prop="lastNaturalDate"
+      >
+        <el-input-number
+          v-model="configDialog.form.lastNaturalDate"
+          :precision="1"
+          :min="0"
+          controls-position="right"
+        />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="configDialog.visible = false">取消</el-button>
+      <el-button type="primary" @click="saveConfig">保存</el-button>
+    </template>
+  </el-dialog>
+
 </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'
 import { ref } from 'vue'
-import { IotMaintainMaterialVO } from '@/api/pms/maintain/material'
+import { IotMaintenanceBomApi, IotMaintenanceBomVO } from '@/api/pms/iotmaintenancebom'
+import { IotMaintenancePlanApi, IotMaintenancePlanVO } from '@/api/pms/maintenance'
 import { useTagsViewStore } from '@/store/modules/tagsView'
 import {CACHE_KEY, useCache} from "@/hooks/web/useCache";
-import {DICT_TYPE} from "@/utils/dict";
 import MainPlanDeviceList from "@/views/pms/maintenance/MainPlanDeviceList.vue";
+import * as DeptApi from "@/api/system/dept";
+import {erpPriceTableColumnFormatter} from "@/utils";
 
 /** 保养计划 表单 */
 defineOptions({ name: 'IotAddMainPlan' })
@@ -124,37 +223,24 @@ const message = useMessage() // 消息弹窗
 const { delView } = useTagsViewStore() // 视图操作
 const { currentRoute, push } = useRouter()
 const deptUsers = ref<UserApi.UserVO[]>([]) // 用户列表
+const dept = ref() // 当前登录人所属部门对象
 const dialogTitle = ref('') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
 const deviceLabel = ref('') // 表单的类型:create - 新增;update - 修改
-const list = ref<IotMaintainMaterialVO[]>([]) // 列表的数据
+const list = ref<IotMaintenanceBomVO[]>([]) // 设备bom关联列表的数据
+const deviceIds = ref<number[]>([]) // 已经选择的设备id数组
 const { params, name } = useRoute() // 查询参数
 const id = params.id
 const formData = ref({
   id: undefined,
-  name: undefined,
+  deptId: undefined,
+  name: '',
   serialNumber: undefined,
+  responsiblePerson: undefined,
+  remark: undefined,
   failureName: undefined,
-  deviceId: undefined,
   status: undefined,
-  type: undefined,
-  ifStop: undefined,
-  failureTime: undefined,
-  failureInfluence: undefined,
-  failureSystem: undefined,
-  description: undefined,
-  pic: undefined,
-  solution: undefined,
-  maintainStartTime: undefined,
-  maintainEndTime: undefined,
-  remark: undefined,
-  deviceName: undefined,
-  processInstanceId: undefined,
-  auditStatus: undefined,
-  deptId: undefined,
-  responsiblePerson: undefined,
-  maintainDescription: undefined,
 })
 const formRules = reactive({
   name: [{ required: true, message: '计划名称不能为空', trigger: 'blur' }],
@@ -162,26 +248,85 @@ const formRules = reactive({
 })
 const formRef = ref() // 表单 Ref
 
-const deviceChoose = (selectedDevices) => {
-  // formData.value.deviceId = row.id
-  // formData.value.deviceName = row.deviceName
-  // formData.value.deptId = row.deptId
-  // deviceLabel.value = row.deviceName
+// 新增配置相关状态
+const configDialog = reactive({
+  visible: false,
+  current: null as IotMaintenanceBomVO | null,
+  form: {
+    lastRunningKilometers: 0,
+    lastRunningTime: 0,
+    lastNaturalDate: 0
+  }
+})
+
+// 打开配置对话框
+const openConfigDialog = (row: IotMaintenanceBomVO) => {
+  configDialog.current = row
+  configDialog.form = {
+    lastRunningKilometers: row.lastRunningKilometers || 0,
+    lastRunningTime: row.lastRunningTime || 0,
+    lastNaturalDate: row.lastNaturalDate || 0
+  }
+  configDialog.visible = true
+}
+
+// 保存配置
+const saveConfig = () => {
+  if (!configDialog.current) return
+  // 更新当前行的数据
+  Object.assign(configDialog.current, configDialog.form)
+  configDialog.visible = false
+}
+
+const queryParams = reactive({
+  deviceIds: undefined
+})
+
+const deviceChoose = async(selectedDevices) => {
+  const newIds = selectedDevices.map(device => device.id)
+  deviceIds.value = [...new Set([...deviceIds.value, ...newIds])]
+  const params = {
+    deviceIds: deviceIds.value.join(',') // 明确传递数组参数
+  }
+  // console.log('请求参数:', JSON.parse(JSON.stringify(params.deviceIds)))
+  queryParams.deviceIds = JSON.parse(JSON.stringify(params.deviceIds))
+  // 根据选择的设备筛选出设备关系的分类BOM中与保养相关的节点项
+  const res = await IotDeviceApi.deviceAssociateBomList(queryParams)
+  const rawData = res || []
+  if(rawData.length === 0){
+    message.error('选择的设备不存在待保养BOM项')
+  }
+  if (!Array.isArray(rawData)) {
+    console.error('接口返回数据结构异常:', rawData)
+    return
+  }
   // 转换数据结构(根据你的接口定义调整)
-  const newItems = selectedDevices.map(device => ({
+  const newItems = rawData.map(device => ({
+    assetClass: device.assetClass,
     deviceCode: device.deviceCode,
     deviceName: device.deviceName,
     deviceStatus: device.deviceStatus,
     deptName: device.deptName,
+    name: device.name,
+    code: device.code,
     assetProperty: device.assetProperty,
     remark: null,    // 初始化备注
-    id: device.id // 移除操作需要
+    deviceId: device.id, // 移除操作需要
+    bomNodeId: device.bomNodeId,
+    runningTime: 0,
+    runningKilometers: 0,
+    nextRunningKilometers: 0,
+    nextRunningTime: 0,
+    nextNaturalDate: 0,
   }))
-
+  // 获取选择的设备相关的id数组
+  newItems.forEach(item => {
+    deviceIds.value.push(item.deviceId)
+  })
   // 合并到现有列表(去重)
   newItems.forEach(item => {
     const exists = list.value.some(
-      existing => existing.id === item.id
+      existing => (existing.deviceId === item.deviceId && existing.bomNodeId === item.bomNodeId)
     )
     if (!exists) {
       list.value.push(item)
@@ -223,23 +368,19 @@ const emit = defineEmits(['success']) // 定义 success 事件,用于操作成
 const submitForm = async () => {
   // 校验表单
   await formRef.value.validate()
-  if (list.value.length > 0) {
-    const nullList = list.value.filter((item) => item.depleteCount===null)
-    if (nullList.length > 0) {
-      message.error('请填写消耗数量')
-      return
-    }
-  }
-
+  // 校验表格数据
+  const isValid = validateTableData()
+  if (!isValid) return
   // 提交请求
   formLoading.value = true
   try {
     const data = {
-      maintain: formData.value,
-      maintainMaterials: list.value
+      mainPlan: formData.value,
+      mainPlanBom: list.value
     }
+    // console.log('列表数据:'+data.mainPlanBom[0].lastRunningKilometers)
     if (formType.value === 'create') {
-      await IotMaintainApi.createIotMaintain(data)
+      await IotMaintenancePlanApi.createIotMaintenancePlan(data)
       message.success(t('common.createSuccess'))
       close()
     } else {
@@ -254,6 +395,76 @@ const submitForm = async () => {
   }
 }
 
+/** 校验表格数据 */
+const validateTableData = (): boolean => {
+  let isValid = true
+  const errorMessages: string[] = []
+  const noRulesErrorMessages: string[] = []  // 未设置任何保养项规则 的错误提示信息
+  const noRules: string[] = []  // 行记录中设置了保养规则的记录数量
+  const configErrors: string[] = []   // 保养规则配置弹出框
+  let shouldBreak = false;
+  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 || row.nextNaturalDate <= 0) {
+        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
+}
+
 /** 重置表单 */
 const resetForm = () => {
   formData.value = {
@@ -280,7 +491,12 @@ const resetForm = () => {
 }
 onMounted(async () => {
   const deptId = useUserStore().getUser.deptId
+  // 查询当前登录人所属部门名称
+  dept.value = await DeptApi.getDept(deptId)
+  // 根据当前登录人部门信息生成生成 保养计划 名称
+  formData.value.name = dept.value.name + '-保养计划'
   deptUsers.value = await UserApi.getDeptUsersByDeptId(deptId)
+  formData.value.deptId = deptId
   if (id){
     formType.value = 'update'
     const iotMaintain = await IotMaintainApi.getIotMaintain(id);
@@ -293,12 +509,13 @@ onMounted(async () => {
     formData.value.responsiblePerson = userInfo.user.id;
   }
 })
-const handleDelete = async (id: number) => {
+const handleDelete = async (str: string) => {
   try {
-    const index = list.value.findIndex((item) => item.code === id)
+    const index = list.value.findIndex((item) => (item.id+'-'+item.bomNodeId) === str)
     if (index !== -1) {
       // 通过 splice 删除元素
       list.value.splice(index, 1)
+      deviceIds.value = []
     }
   } catch {}
 }

+ 8 - 3
src/views/pms/maintenance/MainPlanDeviceList.vue

@@ -49,7 +49,7 @@
         <el-table-column label="所在部门" align="center" prop="deptName" />
         <el-table-column label="设备状态" align="center" prop="deviceStatus">
           <template #default="scope">
-            <dict-tag :type="DICT_TYPE.PMS_DEVICE_STATUS" :value="scope.row.status" />
+            <dict-tag :type="DICT_TYPE.PMS_DEVICE_STATUS" :value="scope.row.deviceStatus" />
           </template>
         </el-table-column>
         <el-table-column
@@ -98,7 +98,10 @@ const queryParams = reactive({
   status: undefined,
   deptId: undefined,
   assetClass: undefined,
-  deviceName: undefined
+  deviceName: undefined,
+  deviceCode: undefined,
+  name: undefined,
+  code: undefined
 })
 
 // 点击整行选中
@@ -156,7 +159,9 @@ const handleConfirm = () => {
     deviceName: row.deviceName,
     deviceStatus: row.deviceStatus,
     deptName: row.deptName,
-    assetProperty: row.assetProperty
+    assetProperty: row.assetProperty,
+    name: row.name,
+    code: row.code
   })))
   dialogVisible.value = false;
   handleClose()