Kaynağa Gözat

Merge remote-tracking branch 'origin/master'

ouyj 3 ay önce
ebeveyn
işleme
654de4e6a0

+ 1 - 1
ygtx-admin/src/main/resources/application-test.yml

@@ -22,7 +22,7 @@ spring:
                 password:
             # 源数据库数据源(用于设备同步)
             source:
-                url: jdbc:mysql://192.168.254.253:9906/equipment_source?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                url: jdbc:mysql://192.168.254.253:9906/work_order?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 username: root
                 password: 11rrRRvv90)*9&FuuI}{
                 initialSize: 5

+ 35 - 5
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtRepairOrderServiceImpl.java

@@ -804,6 +804,21 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
         gxtRepairOrder.setWorkOrderStatus("to_approve");
         gxtRepairOrder.setUpdateBy(SecurityUtils.getUsername());
         gxtRepairOrder.setUpdateTime(DateUtils.getNowDate());
+        // 负责人为空
+        if (null == gxtRepairOrder.getTeamLeaderName() && StringUtils.isEmpty(gxtRepairOrder.getTeamLeaderName())) {
+            gxtRepairOrder.setTeamLeaderId(SecurityUtils.getUserId());
+            gxtRepairOrder.setTeamLeaderName(SecurityUtils.getLoginUser().getUser().getNickName());
+            GxtRepairOrderPerson person = new GxtRepairOrderPerson();
+            person.setUserId(SecurityUtils.getUserId());
+            person.setNickName(SecurityUtils.getLoginUser().getUser().getNickName());
+            person.setIsLeader(1);
+            person.setOrderId(gxtRepairOrder.getId());
+            person.setOrderCode(gxtRepairOrder.getWorkOrderProjectNo());
+            person.setStatus(1);
+            person.setCreateBy(SecurityUtils.getUsername());
+            gxtRepairOrderPersonMapper.insertGxtRepairOrderPerson(person);
+        }
+
         int result = gxtRepairOrderMapper.updateGxtRepairOrder(gxtRepairOrder);
 
         // 记录挂起流转信息
@@ -917,6 +932,21 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
         }
         gxtRepairOrder.setUpdateBy(SecurityUtils.getUsername());
         gxtRepairOrder.setUpdateTime(DateUtils.getNowDate());
+        // 负责人为空
+        if (null == gxtRepairOrder.getTeamLeaderName() && StringUtils.isEmpty(gxtRepairOrder.getTeamLeaderName())) {
+            gxtRepairOrder.setTeamLeaderId(SecurityUtils.getUserId());
+            gxtRepairOrder.setTeamLeaderName(SecurityUtils.getLoginUser().getUser().getNickName());
+            GxtRepairOrderPerson person = new GxtRepairOrderPerson();
+            person.setUserId(SecurityUtils.getUserId());
+            person.setNickName(SecurityUtils.getLoginUser().getUser().getNickName());
+            person.setIsLeader(1);
+            person.setOrderId(gxtRepairOrder.getId());
+            person.setOrderCode(gxtRepairOrder.getWorkOrderProjectNo());
+            person.setStatus(1);
+            person.setCreateBy(SecurityUtils.getUsername());
+//                    person.setCreateTime(DateUtils.getNowDate());
+            gxtRepairOrderPersonMapper.insertGxtRepairOrderPerson(person);
+        }
         int result = gxtRepairOrderMapper.updateGxtRepairOrder(gxtRepairOrder);
 
         // 记录结单流转信息
@@ -985,11 +1015,11 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
 //                        }
 //                        if(sysUser == null) continue;
                         person.setUserId(sysUser.getUserId());
-//                        if (Objects.equals(sysUser.getUserId(), gxtRepairOrder.getTeamLeaderId())) {
-//                            person.setIsLeader(1);
-//                        } else {
-//                            person.setIsLeader(0);
-//                        }
+                        if (Objects.equals(sysUser.getUserId(), gxtRepairOrder.getTeamLeaderId())) {
+                            person.setIsLeader(1);
+                        } else {
+                            person.setIsLeader(0);
+                        }
                         person.setUserId(sysUser.getUserId());
                         person.setOrderId(gxtRepairOrder.getId());
                         person.setOrderCode(gxtRepairOrder.getWorkOrderProjectNo());

+ 32 - 8
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtWorkOrderServiceImpl.java

@@ -575,6 +575,19 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
         order.setSuspendExplain(gxtWorkOrder.getSuspendExplain());
         order.setUpdateTime(DateUtils.getNowDate());
         order.setUpdateBy(SecurityUtils.getUsername());
+        if (null == order.getTeamLeaderName() && StringUtils.isEmpty(order.getTeamLeaderName())) {
+            order.setTeamLeaderId(SecurityUtils.getUserId());
+            order.setTeamLeaderName(SecurityUtils.getLoginUser().getUser().getNickName());
+            GxtWorkOrderPerson person = new GxtWorkOrderPerson();
+            person.setUserId(SecurityUtils.getUserId());
+            person.setNickName(SecurityUtils.getLoginUser().getUser().getNickName());
+            person.setIsLeader(1);
+            person.setOrderId(order.getId());
+            person.setOrderCode(order.getWorkOrderProjectNo());
+            person.setStatus(1);
+            person.setCreateBy(SecurityUtils.getUsername());
+            gxtWorkOrderPersonMapper.insertGxtWorkOrderPerson(person);
+        }
 
         int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
 
@@ -765,9 +778,20 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
             order.setWorkPermitNum(gxtWorkOrder.getWorkPermitNum());
             order.setMisNo(gxtWorkOrder.getMisNo());
             order.setInfoEntry(gxtWorkOrder.getInfoEntry());
-//            if (null != gxtWorkOrder.getTeamLeaderName() && order.getTeamLeaderName() != gxtWorkOrder.getTeamLeaderName()) {
-//                order.setTeamLeaderName(gxtWorkOrder.getTeamLeaderName());
-//            }
+            order.setFinalizeMethod(gxtWorkOrder.getFinalizeMethod());
+            if (null == order.getTeamLeaderName() && StringUtils.isEmpty(order.getTeamLeaderName())) {
+                order.setTeamLeaderId(SecurityUtils.getUserId());
+                order.setTeamLeaderName(SecurityUtils.getLoginUser().getUser().getNickName());
+                GxtWorkOrderPerson person = new GxtWorkOrderPerson();
+                person.setUserId(SecurityUtils.getUserId());
+                person.setNickName(SecurityUtils.getLoginUser().getUser().getNickName());
+                person.setIsLeader(1);
+                person.setOrderId(order.getId());
+                person.setOrderCode(order.getWorkOrderProjectNo());
+                person.setStatus(1);
+                person.setCreateBy(SecurityUtils.getUsername());
+                gxtWorkOrderPersonMapper.insertGxtWorkOrderPerson(person);
+            }
 
 
             int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
@@ -830,11 +854,11 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
 //                    }
 //                    if(sysUser == null) continue;
                             person.setUserId(sysUser.getUserId());
-//                        if (sysUser.getUserId() == order.getTeamLeaderId()) {
-//                            person.setIsLeader(1);
-//                        } else {
-//                            person.setIsLeader(0);
-//                        }
+                            if (sysUser.getUserId() == order.getTeamLeaderId()) {
+                                person.setIsLeader(1);
+                            } else {
+                                person.setIsLeader(0);
+                            }
                             person.setOrderId(id);
                             person.setOrderCode(order.getWorkOrderProjectNo());
                             person.setStatus(1);

+ 76 - 33
ygtx-gxt/src/main/java/com/ygtx/gxt/task/OrderAutoFinalizeTask.java

@@ -86,25 +86,30 @@ public class OrderAutoFinalizeTask {
             if (misInfoList != null && misInfoList.size() == 1) {
                 GxtMisInfo mis = misInfoList.get(0);
                 if (mis.getWorkPermitNum() != null && !mis.getWorkPermitNum().isEmpty()) {
-                    // 查询工作负责人和工作组成员信息
-                    GxtWorkOrderPerson workOrderPerson = new GxtWorkOrderPerson();
-                    workOrderPerson.setMisNo(mis.getMisNo());
-                    personList = misInfoMapper.selectGxtWorkOrderPersonList(workOrderPerson);
+                    // 检查该MIS工单是否已在维修工单或维保工单中存在
+                    boolean misExistsInOrders = checkMisExistsInOrders(mis.getMisNo());
                     
-                    if (personList != null && !personList.isEmpty()) {
-                        boolean hasLeader = false;
-                        boolean hasMembers = false;
+                    if (!misExistsInOrders) {
+                        // 查询工作负责人和工作组成员信息
+                        GxtWorkOrderPerson workOrderPerson = new GxtWorkOrderPerson();
+                        workOrderPerson.setMisNo(mis.getMisNo());
+                        personList = misInfoMapper.selectGxtWorkOrderPersonList(workOrderPerson);
                         
-                        for (GxtWorkOrderPerson person : personList) {
-                            if (person.getIsLeader() != null && 1 == person.getIsLeader()) {
-                                hasLeader = true;
-                            } else {
-                                hasMembers = true;
+                        if (personList != null && !personList.isEmpty()) {
+                            boolean hasLeader = false;
+                            boolean hasMembers = false;
+                            
+                            for (GxtWorkOrderPerson person : personList) {
+                                if (person.getIsLeader() != null && 1 == person.getIsLeader()) {
+                                    hasLeader = true;
+                                } else {
+                                    hasMembers = true;
+                                }
+                            }
+                            
+                            if (hasLeader && hasMembers) {
+                                validMisInfo = mis;
                             }
-                        }
-                        
-                        if (hasLeader && hasMembers) {
-                            validMisInfo = mis;
                         }
                     }
                 }
@@ -157,7 +162,8 @@ public class OrderAutoFinalizeTask {
                     updateRepairOrder.setRealEndTime(validMisInfo.getRealEndTime());
                     updateRepairOrder.setInfoEntry("1");
                     updateRepairOrder.setFinalizeMethod("1");
-                    
+                    updateRepairOrder.setScoringStatus("to_self");
+
                     gxtRepairOrderMapper.updateGxtRepairOrder(updateRepairOrder);
                     
                     // 将工作负责人和工作组成员存入GxtWorkOrderPersonMapper
@@ -235,25 +241,30 @@ public class OrderAutoFinalizeTask {
             if (misInfoList != null && misInfoList.size() == 1) {
                 GxtMisInfo mis = misInfoList.get(0);
                 if (mis.getWorkPermitNum() != null && !mis.getWorkPermitNum().isEmpty()) {
-                    // 查询工作负责人和工作组成员信息
-                    GxtWorkOrderPerson workOrderPerson = new GxtWorkOrderPerson();
-                    workOrderPerson.setMisNo(mis.getMisNo());
-                    personList = misInfoMapper.selectGxtWorkOrderPersonList(workOrderPerson);
+                    // 检查该MIS工单是否已在维修工单或维保工单中存在
+                    boolean misExistsInOrders = checkMisExistsInOrders(mis.getMisNo());
                     
-                    if (personList != null && !personList.isEmpty()) {
-                        boolean hasLeader = false;
-                        boolean hasMembers = false;
+                    if (!misExistsInOrders) {
+                        // 查询工作负责人和工作组成员信息
+                        GxtWorkOrderPerson workOrderPerson = new GxtWorkOrderPerson();
+                        workOrderPerson.setMisNo(mis.getMisNo());
+                        personList = misInfoMapper.selectGxtWorkOrderPersonList(workOrderPerson);
                         
-                        for (GxtWorkOrderPerson person : personList) {
-                            if (person.getIsLeader() != null && 1 == person.getIsLeader()) {
-                                hasLeader = true;
-                            } else {
-                                hasMembers = true;
+                        if (personList != null && !personList.isEmpty()) {
+                            boolean hasLeader = false;
+                            boolean hasMembers = false;
+                            
+                            for (GxtWorkOrderPerson person : personList) {
+                                if (person.getIsLeader() != null && 1 == person.getIsLeader()) {
+                                    hasLeader = true;
+                                } else {
+                                    hasMembers = true;
+                                }
+                            }
+                            
+                            if (hasLeader && hasMembers) {
+                                validMisInfo = mis;
                             }
-                        }
-                        
-                        if (hasLeader && hasMembers) {
-                            validMisInfo = mis;
                         }
                     }
                 }
@@ -306,6 +317,8 @@ public class OrderAutoFinalizeTask {
                     updateWorkOrder.setRealEndTime(validMisInfo.getRealEndTime());
                     updateWorkOrder.setInfoEntry("1");
                     updateWorkOrder.setFinalizeMethod("1");
+                    updateWorkOrder.setScoringStatus("to_self");
+                    updateWorkOrder.setCompleteTime(DateUtils.getNowDate());
                     
                     gxtWorkOrderMapper.updateGxtWorkOrder(updateWorkOrder);
                     
@@ -357,4 +370,34 @@ public class OrderAutoFinalizeTask {
             }
         }
     }
+    
+    /**
+     * 检查MIS工单是否已在维修工单或维保工单中存在
+     * @param misNo MIS工单编号
+     * @return 如果MIS工单已存在返回true,否则返回false
+     */
+    private boolean checkMisExistsInOrders(String misNo) {
+        // 检查维修工单中是否已存在该MIS工单号(排除当前工单)
+        GxtRepairOrder repairOrderCriteria = new GxtRepairOrder();
+        repairOrderCriteria.setMisOrderNo(misNo);
+        List<GxtRepairOrder> existingRepairOrders = gxtRepairOrderMapper.selectGxtRepairOrderList(repairOrderCriteria);
+        
+        // 如果查询到结果,且存在非排除ID的记录,则返回true
+        if (existingRepairOrders != null && !existingRepairOrders.isEmpty()) {
+            return true;
+        }
+        
+        // 检查维保工单中是否已存在该MIS工单号(排除当前工单)
+        GxtWorkOrder workOrderCriteria = new GxtWorkOrder();
+        workOrderCriteria.setMisNo(misNo);
+        List<GxtWorkOrder> existingWorkOrders = gxtWorkOrderMapper.selectGxtWorkOrderList(workOrderCriteria);
+        
+        // 如果查询到结果,且存在非排除ID的记录,则返回true
+        if (existingWorkOrders != null && !existingWorkOrders.isEmpty()) {
+            return true;
+        }
+        
+        // 如果都没有找到符合条件的记录,则返回false
+        return false;
+    }
 }

+ 10 - 0
ygtx-ui/src/components/gxtOrder/view.vue

@@ -89,6 +89,12 @@
                 <el-col :span="24">
                   <el-form-item label="损失电量(kWh)">{{ formData.lostPower || '-' }}</el-form-item>
                 </el-col>
+                <el-col :span="24">
+                  <el-form-item label="结单方式">
+                    <dict-tag :options="finalizeMethodOptions" :value="formData.finalizeMethod" />
+                  </el-form-item>
+                </el-col>
+
               </el-row>
             </el-form>
           </div>
@@ -176,6 +182,10 @@ const props = defineProps({
   inspectionTypeOptions: {
     type: Array,
     default: () => ([])
+  },
+  finalizeMethodOptions: {
+    type: Array,
+    default: () => ([])
   }
 })
 

+ 4 - 4
ygtx-ui/src/components/repairOrder/finalize.vue

@@ -839,8 +839,8 @@ const handleSubmit = async () => {
     if (valid) {
       const { realStartTime, acceptTime } = formData.value;
       debugger
-      if (realStartTime && acceptTime && (new Date(realStartTime) < new Date(acceptTime))) {
-        formData.value.orderEntryType = '2'
+      // if (realStartTime && acceptTime && (new Date(realStartTime) < new Date(acceptTime))) {
+      //   formData.value.orderEntryType = '2'
         // try {
         //   debugger
         //   await ElMessageBox.confirm(
@@ -860,7 +860,7 @@ const handleSubmit = async () => {
         //   finalizeFormRef.value?.validateField('realStartTime');
         //   return;
         // }
-      }
+      // }
 
       try {
         debugger
@@ -892,7 +892,7 @@ const handleSubmit = async () => {
             flowList.value.push(resumeInfo.value)
           }
           formData.value.repairOrderFlowList = flowList.value
-
+          formData.value.finalizeMethod = '2'
           await props.onSubmit(formData.value)
         } else {
           throw new Error("未提供提交方法")

+ 17 - 2
ygtx-ui/src/components/repairOrder/view.vue

@@ -37,6 +37,12 @@
                 <el-col :span="24">
                   <el-form-item label="故障代码">{{ formData.faultCode || '-' }}</el-form-item>
                 </el-col>
+                <el-col :span="24">
+                  <el-form-item label="故障条纹">{{ formData.faultBarcode || '-' }}</el-form-item>
+                </el-col>
+<!--                <el-col :span="24">-->
+<!--                  <el-form-item label="故障描述">{{ formData.faultDesc || '-' }}</el-form-item>-->
+<!--                </el-col>-->
               </el-row>
             </el-form>
           </div>
@@ -123,6 +129,11 @@
                 <el-col :span="24">
                   <el-form-item label="损失电量(kWh)">{{ formData.lostPower || '-' }}</el-form-item>
                 </el-col>
+                <el-col :span="24">
+                  <el-form-item label="结单方式">
+                    <dict-tag :options="finalizeMethodOptions" :value="formData.finalizeMethod" />
+                  </el-form-item>
+                </el-col>
               </el-row>
             </el-form>
           </div>
@@ -155,8 +166,8 @@
     <el-form label-position="top">
       <el-row>
         <el-col :span="24">
-          <el-form-item label="故障信息">
-            <div class="content-text">{{ formData.faultBarcode || '-' }}</div>
+          <el-form-item label="故障描述">
+            <div class="content-text">{{ formData.faultDesc || '-' }}</div>
           </el-form-item>
         </el-col>
         <el-col :span="24">
@@ -238,6 +249,10 @@ const props = defineProps({
     type: Array,
     default: () => ([])
   },
+  finalizeMethodOptions: {
+    type: Array,
+    default: () => ([])
+  }
 })
 
 // 定义事件

+ 43 - 26
ygtx-ui/src/views/gxt/gxtOrder/index.vue

@@ -314,7 +314,7 @@
             <i class="fa fa-eye"></i>查看
           </el-button>
           <el-button
-              v-if="scope.row.workOrderStatus === 'draft'"
+              v-if="scope.row.workOrderStatus === 'to_issue'"
               type="danger"
               link
               @click="handleDelete(scope.row)"
@@ -1092,6 +1092,7 @@
         :work-order-status-options="gxt_work_order_status"
         :repair-order-flow-action-type-options="gxt_repair_order_flow_action_type"
         :inspection-type-options="gxt_inspection_type"
+        :finalize-method-options="gxt_finalize_method"
     />
 
     <!-- 作废工单对话框 -->
@@ -1501,14 +1502,16 @@ const {
   gxt_pause_reasons,
   gxt_repair_order_flow_action_type,
   gxt_order_suspend_reason,
-  gxt_info_entry
+  gxt_info_entry,
+  gxt_finalize_method
 } = proxy.useDict(
     "gxt_work_order_status",
     "gxt_inspection_type",
     "gxt_pause_reasons",
     "gxt_repair_order_flow_action_type",
     "gxt_order_suspend_reason",
-    "gxt_info_entry"
+    "gxt_info_entry",
+    "gxt_finalize_method"
 )
 const orderList = ref([])
 const open = ref(false)
@@ -2159,29 +2162,43 @@ function handleFinish(row) {
         if (misInfo.length > 0 && misInfo.length == 1) {
           // 有工作票号提示
           if (misInfo[0].workPermitNum) {
-              finishForm.value.misNo = misInfo[0].misNo
-              finishForm.value.realStartTime = misInfo[0].realStartTime
-              finishForm.value.realEndTime = misInfo[0].realEndTime
-              finishForm.value.workPermitNum = misInfo[0].workPermitNum
-              listWorkPerson({misNo: misInfo[0].misNo}).then(response => {
-                finishForm.value.workOrderPersonList = response.rows;
-                if (finishForm.value.workOrderPersonList) {
-                  // 查询负责人信息并回填
-                  for (const person of finishForm.value.workOrderPersonList) {
-                    // 严格判断isLeader为1(兼容数字/字符串类型)
-                    if (person.isLeader === 1 || person.isLeader === '1') {
-                      finishForm.value.teamLeaderName = person.nickName;
-                      break; // 找到后立即停止循环
+            listGxtOrder({pageNum: 1, pageSize: 10, misNo: row.misNo }).then(response => {
+              const gxtOrders = response.rows
+              if (gxtOrders.length == 0) {
+                finishForm.value.misNo = misInfo[0].misNo
+                finishForm.value.realStartTime = misInfo[0].realStartTime
+                finishForm.value.realEndTime = misInfo[0].realEndTime
+                finishForm.value.workPermitNum = misInfo[0].workPermitNum
+                listWorkPerson({misNo: misInfo[0].misNo}).then(response => {
+                  finishForm.value.workOrderPersonList = response.rows;
+                  if (finishForm.value.workOrderPersonList) {
+                    // 查询负责人信息并回填
+                    for (const person of finishForm.value.workOrderPersonList) {
+                      // 严格判断isLeader为1(兼容数字/字符串类型)
+                      if (person.isLeader === 1 || person.isLeader === '1') {
+                        finishForm.value.teamLeaderName = person.nickName;
+                        break; // 找到后立即停止循环
+                      }
                     }
+                    const nickNames = finishForm.value.workOrderPersonList
+                        .map(person => person.nickName)
+                        .join(',');
+                    finishForm.value.workGroupMemberName = nickNames
+                    // finishDialogVisible.value = true
                   }
-                  const nickNames = finishForm.value.workOrderPersonList
-                      .map(person => person.nickName)
-                      .join(',');
-                  finishForm.value.workGroupMemberName = nickNames
-                  // finishDialogVisible.value = true
-                }
-              })
-
+                })
+              } else {
+                ElMessageBox.confirm('未找到匹配的MIS工单,请确认风机停复机时间是否已录入工效通系统或请进入工作票录入方式。', '提示', {
+                  confirmButtonText: '确定',
+                  showCancelButton: false,
+                  type: 'warning'
+                }).then(function() {
+                  finishForm.value.infoEntry = '2'
+                  infoEntryDisabled.value = true
+                }).then(() => {
+                }).catch(() => {})
+              }
+            })
           } else {  // 无工作票号提示
             ElMessageBox.confirm('已匹配到MIS工单,但未关联工作票号,系统无法自动结单,请进入工作票录入方式。', '提示', {
               confirmButtonText: '确定',
@@ -2335,12 +2352,12 @@ function handleFinishSuccess() {
   getList()
 }
 
-// 用于传递给退回组件的提交方法
+// 用于传递给挂起组件的提交方法
 async function submitSuspendFromParent(data) {
   await suspendWorkOrder(data.id, data)
 }
 
-// 在提交退回成功后的回调函数
+// 在提交挂起成功后的回调函数
 function handleSuspendSuccess() {
   suspendDialogVisible.value = false
   getList()

+ 417 - 37
ygtx-ui/src/views/gxt/repairOrder/index.vue

@@ -336,7 +336,7 @@
               v-hasPermi="['gxt:repairOrder:finalize']"
           ><i class="fa fa-check"></i>结单</el-button>
           <el-button
-              v-if="scope.row.workOrderStatus === 'to_finish' && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
+              v-if="scope.row.workOrderStatus === 'to_finish'"
               type="primary"
               link
               @click="handleReset(scope.row)"
@@ -463,24 +463,110 @@
             <el-form-item label="故障代码" prop="faultCode">
               <el-input
                   v-model="form.faultCode"
-                  placeholder="请输入故障代码"
+                  placeholder="请输入故障代码或点击选择"
                   maxlength="20"
                   show-word-limit
+                  clearable
+                  @focus="handleFaultCodeInputFocus"
+                  @blur="handleFaultCodeInputBlur"
+                  @input="handleFaultCodeInput"
+                  @clear="handleFaultCodeClear"
               />
+              <!-- 故障代码快速检索下拉框 -->
+              <div class="quick-select-dropdown" v-show="showFaultCodeQuickSelect && quickFaultInfoList.length > 0">
+                <div
+                    v-for="item in quickFaultInfoList"
+                    :key="item.id"
+                    class="quick-select-item"
+                    @click="handleFaultCodeQuickSelect(item)">
+                  <span class="user-name">{{ item.faultCode }}</span>
+                  <span class="user-name">{{ item.faultBarcode }} | {{ item.faultDescription }}</span>
+                </div>
+              </div>
+              <div class="quick-select-dropdown no-data" v-show="showFaultCodeQuickSelect && quickFaultInfoList.length === 0 && form.faultCode && !faultInfoLoading">
+                <div>未找到匹配的故障代码</div>
+              </div>
+              <div class="quick-select-dropdown no-data" v-show="showFaultCodeQuickSelect && faultInfoLoading">
+                <div>
+                  <i class="el-icon-loading"></i>
+                  搜索中...
+                </div>
+              </div>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row>
           <el-col :span="24">
-            <el-form-item label="故障信息" prop="faultBarcode">
+            <el-form-item label="故障条纹" prop="faultBarcode">
               <el-input
                   v-model="form.faultBarcode"
+                  placeholder="请输入故障条纹或点击选择"
+                  show-word-limit
+                  clearable
+                  @focus="handleFaultBarcodeInputFocus"
+                  @blur="handleFaultBarcodeInputBlur"
+                  @input="handleFaultBarcodeInput"
+                  @clear="handleFaultBarcodeClear"
+              />
+              <!-- 故障条纹快速检索下拉框 -->
+              <div class="quick-select-dropdown" v-show="showFaultBarcodeQuickSelect && quickFaultBarcodeList.length > 0">
+                <div
+                    v-for="item in quickFaultBarcodeList"
+                    :key="item.id"
+                    class="quick-select-item"
+                    @click="handleFaultBarcodeQuickSelect(item)">
+                  <span class="user-name">{{ item.faultBarcode }}</span>
+                  <span class="user-name">{{ item.faultCode }} | {{ item.faultDescription }}</span>
+                </div>
+              </div>
+              <div class="quick-select-dropdown no-data" v-show="showFaultBarcodeQuickSelect && quickFaultBarcodeList.length === 0 && form.faultBarcode && !faultBarcodeLoading">
+                <div>未找到匹配的故障条纹</div>
+              </div>
+              <div class="quick-select-dropdown no-data" v-show="showFaultBarcodeQuickSelect && faultBarcodeLoading">
+                <div>
+                  <i class="el-icon-loading"></i>
+                  搜索中...
+                </div>
+              </div>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="故障描述" prop="faultDesc">
+              <el-input
+                  v-model="form.faultDesc"
                   type="textarea"
-                  placeholder="请输入故障信息"
+                  placeholder="请输入故障描述或点击选择"
                   maxlength="100"
                   show-word-limit
                   :rows="3"
+                  clearable
+                  @focus="handleFaultDescInputFocus"
+                  @blur="handleFaultDescInputBlur"
+                  @input="handleFaultDescInput"
+                  @clear="handleFaultDescClear"
               />
+              <!-- 故障描述快速检索下拉框 -->
+              <div class="quick-select-dropdown" v-show="showFaultDescQuickSelect && quickFaultDescList.length > 0">
+                <div
+                    v-for="item in quickFaultDescList"
+                    :key="item.id"
+                    class="quick-select-item"
+                    @click="handleFaultDescQuickSelect(item)">
+                  <span class="user-name">{{ item.faultDescription }}</span>
+                  <span class="user-name">{{ item.faultCode }} | {{ item.faultBarcode }}</span>
+                </div>
+              </div>
+              <div class="quick-select-dropdown no-data" v-show="showFaultDescQuickSelect && quickFaultDescList.length === 0 && form.faultDesc && !faultDescLoading">
+                <div>未找到匹配的故障描述</div>
+              </div>
+              <div class="quick-select-dropdown no-data" v-show="showFaultDescQuickSelect && faultDescLoading">
+                <div>
+                  <i class="el-icon-loading"></i>
+                  搜索中...
+                </div>
+              </div>
             </el-form-item>
           </el-col>
         </el-row>
@@ -561,11 +647,11 @@
             <el-form-item label="故障代码"><el-input v-model="assignForm.faultCode" disabled /></el-form-item>
           </el-col>
           <el-col :span="24">
-            <el-form-item label="故障信息">
+            <el-form-item label="故障条纹">
               <el-input
                 v-model="assignForm.faultBarcode"
                 type="textarea"
-                placeholder="请输入故障信息"
+                placeholder="请输入故障条纹"
                 maxlength="100"
                 show-word-limit
                 :rows="3"
@@ -681,11 +767,11 @@
             <el-form-item label="故障代码"><el-input v-model="acceptForm.faultCode" disabled /></el-form-item>
           </el-col>
           <el-col :span="24">
-            <el-form-item label="故障信息">
+            <el-form-item label="故障条纹">
               <el-input
                   v-model="acceptForm.faultBarcode"
                   type="textarea"
-                  placeholder="请输入故障信息"
+                  placeholder="请输入故障条纹"
                   maxlength="100"
                   show-word-limit
                   :rows="3"
@@ -830,11 +916,11 @@
             <el-form-item label="故障代码"><el-input v-model="ratingForm.faultCode" disabled /> </el-form-item>
           </el-col>
           <el-col :span="24">
-            <el-form-item label="故障信息">
+            <el-form-item label="故障条纹">
               <el-input
                 v-model="ratingForm.faultBarcode"
                 type="textarea"
-                placeholder="请输入故障信息"
+                placeholder="请输入故障条纹"
                 maxlength="100"
                 show-word-limit
                 :rows="3"
@@ -1068,11 +1154,11 @@
             <el-form-item label="故障代码"><el-input v-model="invalidateForm.faultCode" disabled /></el-form-item>
           </el-col>
           <el-col :span="24">
-            <el-form-item label="故障信息">
+            <el-form-item label="故障条纹">
               <el-input
                 v-model="invalidateForm.faultBarcode"
                 type="textarea"
-                placeholder="请输入故障信息"
+                placeholder="请输入故障条纹"
                 maxlength="100"
                 show-word-limit
                 :rows="3"
@@ -1112,6 +1198,7 @@
         :work-area-options="gxt_work_area"
         :return-type-options="gxt_return_type"
         :accept-return-type-options="gxt_accept_return_type"
+        :finalize-method-options="gxt_finalize_method"
     />
 
     <!-- 审批对话框组件 -->
@@ -1224,9 +1311,9 @@ import ViewDialog from '@/components/repairOrder/view.vue'
 import ApproveDialog from '@/components/repairOrder/approve.vue'
 const { proxy } = getCurrentInstance()
 const { gxt_maintenance_type, gxt_work_order_status, gxt_order_priority_type,gxt_repair_order_flow_action_type,
-  gxt_order_suspend_reason,gxt_repair_method,gxt_reset_method,gxt_return_type,gxt_info_entry,gxt_work_area, gxt_accept_return_type }
+  gxt_order_suspend_reason,gxt_repair_method,gxt_reset_method,gxt_return_type,gxt_info_entry,gxt_work_area, gxt_accept_return_type,gxt_finalize_method }
     = proxy.useDict("gxt_maintenance_type", "gxt_work_order_status", "gxt_order_priority_type","gxt_repair_order_flow_action_type",
-    "gxt_order_suspend_reason","gxt_repair_method","gxt_reset_method","gxt_return_type","gxt_info_entry","gxt_work_area","gxt_accept_return_type")
+    "gxt_order_suspend_reason","gxt_repair_method","gxt_reset_method","gxt_return_type","gxt_info_entry","gxt_work_area","gxt_accept_return_type","gxt_finalize_method")
 
 // 数据列表相关
 const repairOrderList = ref([])
@@ -1350,6 +1437,21 @@ const teamLeaderSearchTimer = ref(null)
 const allUserList = ref([]) // 存储所有设备数据用于快速检索
 const lastLoadedCenterId = ref(null) // Track last loaded maintenance center ID
 
+// 故障代码快速检索相关响应式数据
+const showFaultCodeQuickSelect = ref(false)
+const showFaultBarcodeQuickSelect = ref(false)
+const showFaultDescQuickSelect = ref(false)
+const quickFaultInfoList = ref([])
+const quickFaultBarcodeList = ref([])
+const quickFaultDescList = ref([])
+const faultInfoLoading = ref(false)
+const faultBarcodeLoading = ref(false)
+const faultDescLoading = ref(false)
+const faultInfoSearchTimer = ref(null)
+const faultBarcodeSearchTimer = ref(null)
+const faultDescSearchTimer = ref(null)
+const allFaultInfoList = ref([]) // 存储所有故障数据用于快速检索
+
 const forceKey = ref(0)
 
 const userStore = useUserStore();
@@ -1625,6 +1727,252 @@ const handleMisNoInput = (value) => {
   }, 500)
 }
 
+/** 加载所有故障信息列表 */
+const loadAllFaultInfoList = async () => {
+  try {
+    // 构建查询参数,包含风机编号和场站信息
+    const queryParams = {
+      pageNum: 1,
+      pageSize: 1000, // 获取所有故障代码
+      isActive: 0
+    };
+
+    // 如果表单中有风机编号和场站信息,则添加到查询参数中
+    if (form.value.pcsDeviceName) {
+      queryParams.model = form.value.model;
+    }
+    if (form.value.pcsStationName) {
+      queryParams.station = form.value.pcsStationName;
+    }
+
+    // 加载故障代码数据
+    const response = await listFaultCodes(queryParams);
+    allFaultInfoList.value = response.rows || [];
+  } catch (error) {
+    console.error('加载故障信息列表失败:', error);
+    allFaultInfoList.value = [];
+  }
+}
+
+// 故障代码快速检索方法
+/** 故障代码输入框获取焦点 */
+const handleFaultCodeInputFocus = async () => {
+  showFaultCodeQuickSelect.value = true;
+
+  // 加载所有故障信息
+  await loadAllFaultInfoList();
+
+  // 如果已有输入内容,立即搜索
+  if (form.value.faultCode && form.value.faultCode.trim()) {
+    handleFaultCodeInput(form.value.faultCode);
+  } else {
+    // 如果没有输入内容,显示所有故障信息
+    quickFaultInfoList.value = allFaultInfoList.value;
+  }
+};
+
+/** 故障代码输入框失去焦点 */
+const handleFaultCodeInputBlur = () => {
+  // 延迟隐藏下拉框,确保点击选项能触发
+  setTimeout(() => {
+    showFaultCodeQuickSelect.value = false;
+  }, 200);
+};
+
+/** 故障代码输入事件 - 实时搜索 */
+const handleFaultCodeInput = (value) => {
+  const searchText = value.trim();
+
+  if (!searchText) {
+    quickFaultInfoList.value = [];
+    showFaultCodeQuickSelect.value = false;
+    return;
+  }
+
+  showFaultCodeQuickSelect.value = true;
+
+  // 清除之前的定时器
+  if (faultInfoSearchTimer.value) {
+    clearTimeout(faultInfoSearchTimer.value);
+  }
+
+  // 过滤故障信息列表
+  const lowerKeyword = searchText.toLowerCase();
+  quickFaultInfoList.value = allFaultInfoList.value.filter(item =>
+    (item.faultCode && item.faultCode.toLowerCase().includes(lowerKeyword)) ||
+    (item.faultBarcode && item.faultBarcode.toLowerCase().includes(lowerKeyword)) ||
+    (item.faultDescription && item.faultDescription.toLowerCase().includes(lowerKeyword))
+  );
+
+  // 设置新的定时器,防抖处理(500ms)
+  faultInfoSearchTimer.value = setTimeout(() => {
+    // 由于我们已经在上面过滤了,这里不需要额外的API调用
+  }, 500);
+};
+
+/** 快速选择故障代码 */
+const handleFaultCodeQuickSelect = (item) => {
+  form.value.faultCode = item.faultCode;
+  form.value.faultBarcode = item.faultBarcode;
+  form.value.faultDesc = item.faultDescription;
+  showFaultCodeQuickSelect.value = false;
+};
+
+/** 清空故障代码 */
+const handleFaultCodeClear = () => {
+  form.value.faultCode = '';
+  form.value.faultBarcode = '';
+  form.value.faultDesc = '';
+  quickFaultInfoList.value = [];
+  showFaultCodeQuickSelect.value = false;
+};
+
+// 故障条纹快速检索方法
+/** 故障条纹输入框获取焦点 */
+const handleFaultBarcodeInputFocus = async () => {
+  showFaultBarcodeQuickSelect.value = true;
+
+  // 加载所有故障信息
+  await loadAllFaultInfoList();
+
+  // 如果已有输入内容,立即搜索
+  if (form.value.faultBarcode && form.value.faultBarcode.trim()) {
+    handleFaultBarcodeInput(form.value.faultBarcode);
+  } else {
+    // 如果没有输入内容,显示所有故障信息
+    quickFaultBarcodeList.value = allFaultInfoList.value;
+  }
+};
+
+/** 故障条纹输入框失去焦点 */
+const handleFaultBarcodeInputBlur = () => {
+  // 延迟隐藏下拉框,确保点击选项能触发
+  setTimeout(() => {
+    showFaultBarcodeQuickSelect.value = false;
+  }, 200);
+};
+
+/** 故障条纹输入事件 - 实时搜索 */
+const handleFaultBarcodeInput = (value) => {
+  const searchText = value.trim();
+
+  if (!searchText) {
+    quickFaultBarcodeList.value = [];
+    showFaultBarcodeQuickSelect.value = false;
+    return;
+  }
+
+  showFaultBarcodeQuickSelect.value = true;
+
+  // 清除之前的定时器
+  if (faultBarcodeSearchTimer.value) {
+    clearTimeout(faultBarcodeSearchTimer.value);
+  }
+
+  // 过滤故障信息列表
+  const lowerKeyword = searchText.toLowerCase();
+  quickFaultBarcodeList.value = allFaultInfoList.value.filter(item =>
+    (item.faultCode && item.faultCode.toLowerCase().includes(lowerKeyword)) ||
+    (item.faultBarcode && item.faultBarcode.toLowerCase().includes(lowerKeyword)) ||
+    (item.faultDescription && item.faultDescription.toLowerCase().includes(lowerKeyword))
+  );
+
+  // 设置新的定时器,防抖处理(500ms)
+  faultBarcodeSearchTimer.value = setTimeout(() => {
+    // 由于我们已经在上面过滤了,这里不需要额外的API调用
+  }, 500);
+};
+
+/** 快速选择故障条纹 */
+const handleFaultBarcodeQuickSelect = (item) => {
+  form.value.faultCode = item.faultCode;
+  form.value.faultBarcode = item.faultBarcode;
+  form.value.faultDesc = item.faultDescription;
+  showFaultBarcodeQuickSelect.value = false;
+};
+
+/** 清空故障条纹 */
+const handleFaultBarcodeClear = () => {
+  form.value.faultCode = '';
+  form.value.faultBarcode = '';
+  form.value.faultDesc = '';
+  quickFaultBarcodeList.value = [];
+  showFaultBarcodeQuickSelect.value = false;
+};
+
+// 故障描述快速检索方法
+/** 故障描述输入框获取焦点 */
+const handleFaultDescInputFocus = async () => {
+  showFaultDescQuickSelect.value = true;
+
+  // 加载所有故障信息
+  await loadAllFaultInfoList();
+
+  // 如果已有输入内容,立即搜索
+  if (form.value.faultDesc && form.value.faultDesc.trim()) {
+    handleFaultDescInput(form.value.faultDesc);
+  } else {
+    // 如果没有输入内容,显示所有故障信息
+    quickFaultDescList.value = allFaultInfoList.value;
+  }
+};
+
+/** 故障描述输入框失去焦点 */
+const handleFaultDescInputBlur = () => {
+  // 延迟隐藏下拉框,确保点击选项能触发
+  setTimeout(() => {
+    showFaultDescQuickSelect.value = false;
+  }, 200);
+};
+
+/** 故障描述输入事件 - 实时搜索 */
+const handleFaultDescInput = (value) => {
+  const searchText = value.trim();
+
+  if (!searchText) {
+    quickFaultDescList.value = [];
+    showFaultDescQuickSelect.value = false;
+    return;
+  }
+
+  showFaultDescQuickSelect.value = true;
+
+  // 清除之前的定时器
+  if (faultDescSearchTimer.value) {
+    clearTimeout(faultDescSearchTimer.value);
+  }
+
+  // 过滤故障信息列表
+  const lowerKeyword = searchText.toLowerCase();
+  quickFaultDescList.value = allFaultInfoList.value.filter(item =>
+    (item.faultCode && item.faultCode.toLowerCase().includes(lowerKeyword)) ||
+    (item.faultBarcode && item.faultBarcode.toLowerCase().includes(lowerKeyword)) ||
+    (item.faultDescription && item.faultDescription.toLowerCase().includes(lowerKeyword))
+  );
+
+  // 设置新的定时器,防抖处理(500ms)
+  faultDescSearchTimer.value = setTimeout(() => {
+    // 由于我们已经在上面过滤了,这里不需要额外的API调用
+  }, 500);
+};
+
+/** 快速选择故障描述 */
+const handleFaultDescQuickSelect = (item) => {
+  form.value.faultCode = item.faultCode;
+  form.value.faultBarcode = item.faultBarcode;
+  form.value.faultDesc = item.faultDescription;
+  showFaultDescQuickSelect.value = false;
+};
+
+/** 清空故障描述 */
+const handleFaultDescClear = () => {
+  form.value.faultCode = '';
+  form.value.faultBarcode = '';
+  form.value.faultDesc = '';
+  quickFaultDescList.value = [];
+  showFaultDescQuickSelect.value = false;
+};
+
 /** 搜索MIS工单列表 */
 const searchMisNoList = async (keyword) => {
   if (!keyword) {
@@ -1759,7 +2107,10 @@ const rules = ref({
      { required: true, message: "请选择优先级", trigger: "change" }
    ],*/
   faultBarcode: [
-    { required: true, message: "故障信息不能为空", trigger: "change" }
+    { required: true, message: "故障条纹不能为空", trigger: "change" }
+  ],
+  faultCode: [
+    { required: true, message: "故障代码不能为空", trigger: "change" }
   ],
 })
 
@@ -2102,6 +2453,20 @@ onMounted(() => {
   window.addEventListener('resize', handleResize)
 })
 
+// 监听风机编号和场站变化,自动刷新故障信息列表
+// 监听风机编号变化,清空故障相关字段
+watch(() => form.value.pcsDeviceName, (newDeviceName, oldDeviceName) => {
+  if (newDeviceName !== oldDeviceName) {
+    // 清空故障相关字段,因为新设备可能需要选择不同的故障信息
+    form.value.faultCode = '';
+    form.value.faultBarcode = '';
+    form.value.faultDesc = '';
+
+    // 同时清空故障信息列表,以便下次获取焦点时使用新的设备信息重新加载
+    allFaultInfoList.value = [];
+  }
+}, { immediate: false });
+
 // 监听路由变化,当从其他路由跳转到当前路由时重新解析参数
 const route = useRoute();
 watch(() => route.query, (newQuery, oldQuery) => {
@@ -2493,10 +2858,10 @@ function confirmExport() {
 /** 故障代码变化处理 */
 function handleFaultCodeChange(value) {
   if (value === '无') {
-    // 当选择"无"时,故障信息设置为"-"并允许手动输入
+    // 当选择"无"时,故障条纹设置为"-"并允许手动输入
     form.value.faultBarcode = "-";
   } else {
-    // 当选择具体的故障代码时,自动填充故障信息并设为只读
+    // 当选择具体的故障代码时,自动填充故障条纹并设为只读
     const selectedFaultCode = faultCodeOptions.value.find(item => item.faultCode === value);
     if (selectedFaultCode) {
       form.value.faultBarcode = selectedFaultCode.faultBarcode || "";
@@ -3009,29 +3374,44 @@ function handleFinalize(row, method) {
       if (misInfo.length > 0 && misInfo.length == 1) {
         // 有工作票号提示
         if (misInfo[0].workPermitNum) {
-          finalizeFormData.value.misOrderNo = misInfo[0].misNo
-          finalizeFormData.value.realStartTime = misInfo[0].realStartTime
-          finalizeFormData.value.realEndTime = misInfo[0].realEndTime
-          finalizeFormData.value.workPermitNum = misInfo[0].workPermitNum
-          listWorkPerson({misNo: misInfo[0].misNo}).then(response => {
-            finalizeFormData.value.repairOrderPersonList = response.rows;
-            if (finalizeFormData.value.repairOrderPersonList) {
-              // 查询负责人信息并回填
-              for (const person of finalizeFormData.value.repairOrderPersonList) {
-                // 严格判断isLeader为1(兼容数字/字符串类型)
-                if (person.isLeader === 1 || person.isLeader === '1') {
-                  finalizeFormData.value.teamLeaderName = person.nickName;
-                  break; // 找到后立即停止循环
+          // 查询MIS工单是否已存在
+          listRepairOrder({pageNum: 1, pageSize: 10, misOrderNo: misInfo[0].misNo }).then(response => {
+            const gxtOrders = response.rows
+            if (gxtOrders.length == 0) {
+              finalizeFormData.value.misOrderNo = misInfo[0].misNo
+              finalizeFormData.value.realStartTime = misInfo[0].realStartTime
+              finalizeFormData.value.realEndTime = misInfo[0].realEndTime
+              finalizeFormData.value.workPermitNum = misInfo[0].workPermitNum
+              listWorkPerson({misNo: misInfo[0].misNo}).then(response => {
+                finalizeFormData.value.repairOrderPersonList = response.rows;
+                if (finalizeFormData.value.repairOrderPersonList) {
+                  // 查询负责人信息并回填
+                  for (const person of finalizeFormData.value.repairOrderPersonList) {
+                    // 严格判断isLeader为1(兼容数字/字符串类型)
+                    if (person.isLeader === 1 || person.isLeader === '1') {
+                      finalizeFormData.value.teamLeaderName = person.nickName;
+                      break; // 找到后立即停止循环
+                    }
+                  }
+                  const nickNames = finalizeFormData.value.repairOrderPersonList
+                      .map(person => person.nickName)
+                      .join(',');
+                  finalizeFormData.value.workGroupMemberName = nickNames
+                  // finishDialogVisible.value = true
                 }
-              }
-              const nickNames = finalizeFormData.value.repairOrderPersonList
-                  .map(person => person.nickName)
-                  .join(',');
-              finalizeFormData.value.workGroupMemberName = nickNames
-              // finishDialogVisible.value = true
+              })
+            } else {
+              ElMessageBox.confirm('未找到匹配的MIS工单,请确认风机停复机时间是否已录入工效通系统或请进入工作票录入方式。', '提示', {
+                confirmButtonText: '确定',
+                showCancelButton: false,
+                type: 'warning'
+              }).then(function() {
+                finalizeFormData.value.infoEntry = '2'
+                infoEntryDisabled.value = true
+              }).then(() => {
+              }).catch(() => {})
             }
           })
-
         } else {  // 无工作票号提示
           ElMessageBox.confirm('已匹配到MIS工单,但未关联工作票号,系统无法自动结单,请进入工作票录入方式。', '提示', {
             confirmButtonText: '确定',