ソースを参照

pms 物料消耗 保养工单 校验必填项

zhangcl 1 週間 前
コミット
c52c5e85bb
1 ファイル変更114 行追加17 行削除
  1. 114 17
      src/views/pms/iotmainworkorder/IotMainWorkOrderOptimize.vue

+ 114 - 17
src/views/pms/iotmainworkorder/IotMainWorkOrderOptimize.vue

@@ -152,6 +152,24 @@
           </template>
         </el-table-column>
 
+        <el-table-column :label="t('mainPlan.mainStatus')" align="center" width="140">
+          <template #default="scope">
+            <div class="status-container">
+              <el-switch
+                v-model="scope.row.status"
+                :active-value="1"
+                :inactive-value="0"
+                :disabled="scope.row.initialStatus === 1"
+                @change="handleStatusChange(scope.row)"
+                class="status-switch"
+              />
+              <span class="status-text">
+                {{ getStatusText(scope.row) }}
+              </span>
+            </div>
+          </template>
+        </el-table-column>
+
         <el-table-column :label="t('main.mileage')" key="mileageRule" align="center"
                          :width="columnWidths.mileageRule" v-if="false">
           <template #default="scope">
@@ -294,23 +312,6 @@
           </el-table-column>
         </el-table-column>
 
-        <el-table-column :label="t('mainPlan.mainStatus')" align="center" width="140">
-          <template #default="scope">
-            <div class="status-container">
-              <el-switch
-                v-model="scope.row.status"
-                :active-value="1"
-                :inactive-value="0"
-                :disabled="scope.row.initialStatus === 1"
-                @change="handleStatusChange(scope.row)"
-                class="status-switch"
-              />
-              <span class="status-text">
-                {{ getStatusText(scope.row) }}
-              </span>
-            </div>
-          </template>
-        </el-table-column>
         <!--
         <el-table-column :label="t('iotMaintain.numberOfMaterials')" align="center" width="90">
           <template #default="scope">
@@ -1263,6 +1264,31 @@ const handleSizeChange = (newSize: number) => {
 
 // 处理状态变化
 const handleStatusChange = (row: IotMainWorkOrderBomVO) => {
+  // 如果是从未完成(0)切换到完成(1)
+  if (row.status === 1 && row.initialStatus === 0) {
+    // 检查消耗物料规则:如果设置为不消耗物料(rule=1),则跳过物料校验
+    if (row.rule === 1) {
+      console.log(`保养项 ${row.name} 设置为不消耗物料,跳过物料校验`);
+      message.success(`${row.deviceCode}-${formatMaintItemName(row.name)} 已标记为完成`);
+      return;
+    }
+
+    // 校验物料数据
+    const isValid = validateBomItemMaterials(row.bomNodeId);
+
+    if (!isValid) {
+      // 获取无效物料信息用于提示
+      const invalidMaterials = getInvalidMaterialsInfo(row.bomNodeId);
+      const errorMessage = `请填写物料必填项\n无效物料:\n${invalidMaterials.join('\n')}`;
+
+      message.error(errorMessage);
+
+      // 重置状态为未完成
+      row.status = 0;
+      return;
+    }
+  }
+
   console.log(`保养项 ${row.name} 状态改为: ${row.status === 1 ? '完成' : '未完成'}`);
 
   // 这里可以添加状态变化后的业务逻辑
@@ -1597,6 +1623,45 @@ const getMaterialCount = (bomNodeId: number) => {
   return materialList.value.filter(item => item.bomNodeId === bomNodeId).length
 }
 
+// 校验保养项下物料数据的方法
+const validateBomItemMaterials = (bomNodeId: number): boolean => {
+  const uniqueKey = `${bomNodeId}`;
+  const materials = bomMaterialsMap.value[uniqueKey] || [];
+
+  // 如果没有物料数据,直接返回true(允许完成)
+  if (materials.length === 0) {
+    return true;
+  }
+
+  // 检查所有物料的单价和消耗数量是否都大于0
+  const hasInvalidMaterial = materials.some(material => {
+    const unitPrice = Number(material.unitPrice) || 0;
+    const quantity = Number(material.quantity) || 0;
+
+    return unitPrice <= 0 || quantity <= 0;
+  });
+
+  return !hasInvalidMaterial;
+};
+
+// 获取校验失败的物料信息(用于错误提示)
+const getInvalidMaterialsInfo = (bomNodeId: number): string[] => {
+  const uniqueKey = `${bomNodeId}`;
+  const materials = bomMaterialsMap.value[uniqueKey] || [];
+  const invalidMaterials = [];
+
+  materials.forEach(material => {
+    const unitPrice = Number(material.unitPrice) || 0;
+    const quantity = Number(material.quantity) || 0;
+
+    if (unitPrice <= 0 || quantity <= 0) {
+      invalidMaterials.push(`${material.materialName || material.materialCode} (单价: ${unitPrice}, 数量: ${quantity})`);
+    }
+  });
+
+  return invalidMaterials;
+};
+
 // 删除物料(在表格中)
 const handleDeleteMaterialInTable = (material) => {
   // 确认删除对话框
@@ -1672,6 +1737,38 @@ const submitForm = async () => {
     return; // 校验失败则终止提交
   }
 
+  // 校验所有设置为完成状态的保养项的物料数据
+  const invalidBomItems = [];
+
+  list.value.forEach(row => {
+    // 只校验状态为完成(1)且消耗物料规则为消耗(0)的保养项
+    if (row.status === 1 && row.rule === '0') {
+      const isValid = validateBomItemMaterials(row.bomNodeId);
+      if (!isValid) {
+        invalidBomItems.push({
+          name: `${row.deviceCode}-${formatMaintItemName(row.name)}`,
+          invalidMaterials: getInvalidMaterialsInfo(row.bomNodeId)
+        });
+      }
+    }
+  });
+
+  // 如果有校验失败的保养项,显示错误信息并终止提交
+  if (invalidBomItems.length > 0) {
+    let errorMessage = '请填写物料必填项\n\n';
+
+    invalidBomItems.forEach((item, index) => {
+      errorMessage += `${index + 1}. ${item.name}:\n`;
+      item.invalidMaterials.forEach(material => {
+        errorMessage += `   - ${material}\n`;
+      });
+      errorMessage += '\n';
+    });
+
+    message.error(errorMessage);
+    return;
+  }
+
   // 校验表格数据
   const isValid = validateTableData()
   if (!isValid) return