瀏覽代碼

维保新增修改、补录,添加停机操作

HD_wangm 3 月之前
父節點
當前提交
830d385e2c

+ 13 - 4
ygtx-gxt/src/main/java/com/ygtx/gxt/controller/GxtWorkOrderController.java

@@ -9,8 +9,7 @@ import com.github.pagehelper.util.StringUtil;
 import com.ygtx.common.constant.HttpStatus;
 import com.ygtx.common.core.page.PageDomain;
 import com.ygtx.common.core.page.TableSupport;
-import com.ygtx.gxt.domain.GxtOrderData;
-import com.ygtx.gxt.domain.GxtWorkOrderAttachment;
+import com.ygtx.gxt.domain.*;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -27,8 +26,6 @@ import com.ygtx.common.annotation.Log;
 import com.ygtx.common.core.controller.BaseController;
 import com.ygtx.common.core.domain.AjaxResult;
 import com.ygtx.common.enums.BusinessType;
-import com.ygtx.gxt.domain.GxtWorkOrder;
-import com.ygtx.gxt.domain.GxtWorkOrderFlow;
 import com.ygtx.gxt.service.IGxtWorkOrderService;
 import com.ygtx.common.utils.poi.ExcelUtil;
 import com.ygtx.common.core.page.TableDataInfo;
@@ -498,4 +495,16 @@ public class GxtWorkOrderController extends BaseController
         ExcelUtil<GxtWorkOrder> util = new ExcelUtil<GxtWorkOrder>(GxtWorkOrder.class);
         return success(util.getExportFields());
     }
+
+    /**
+     * 停机(工单停机)
+     */
+    @PreAuthorize("@ss.hasPermi('gxt:maintenance:order:shutdown')")
+    @Log(title = "维保工单", businessType = BusinessType.UPDATE)
+    @PutMapping("/shutdown")
+    @ApiOperation("停机")
+    public AjaxResult shutdown(@RequestBody GxtWorkOrder gxtWorkOrder)
+    {
+        return toAjax(gxtWorkOrderService.shutdownOrder(gxtWorkOrder));
+    }
 }

+ 11 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/domain/GxtRepairOrder.java

@@ -256,6 +256,9 @@ public class GxtRepairOrder extends BaseEntity
     @Excel(name = "工作票编号")
     private String workPermitNum;
     
+    /** 结单方式(1系统自动匹配,2工作票) */
+    private String finalizeMethod;
+    
     /** 评分退回理由 */
     private String scoreReturnReason;
 
@@ -900,6 +903,14 @@ public class GxtRepairOrder extends BaseEntity
         this.workPermitNum = workPermitNum;
     }
     
+    public String getFinalizeMethod() {
+        return finalizeMethod;
+    }
+    
+    public void setFinalizeMethod(String finalizeMethod) {
+        this.finalizeMethod = finalizeMethod;
+    }
+    
     public String getScoreReturnReason() {
         return scoreReturnReason;
     }

+ 11 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/domain/GxtWorkOrder.java

@@ -231,6 +231,9 @@ public class GxtWorkOrder extends BaseEntity
 
     /** 结单附件原始文件名 */
     private String attachmentOriginalNames;
+    
+    /** 结单方式(1系统自动匹配,2工作票) */
+    private String finalizeMethod;
 
     /** 分项完成系数 */
     private BigDecimal itemCompletionFactor;
@@ -837,6 +840,14 @@ public class GxtWorkOrder extends BaseEntity
     public void setInvalidReason(String invalidReason) {
         this.invalidReason = invalidReason;
     }
+    
+    public String getFinalizeMethod() {
+        return finalizeMethod;
+    }
+    
+    public void setFinalizeMethod(String finalizeMethod) {
+        this.finalizeMethod = finalizeMethod;
+    }
 
     public String getModifyReason() {
         return modifyReason;

+ 7 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/service/IGxtWorkOrderService.java

@@ -239,4 +239,11 @@ public interface IGxtWorkOrderService {
      * @return 结果
      */
     public int invalidateGxtWorkOrder(GxtWorkOrder gxtWorkOrder);
+
+    /**
+     * 停机
+     * @param gxtWorkOrder
+     * @return
+     */
+    public int shutdownOrder(GxtWorkOrder gxtWorkOrder);
 }

+ 14 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtWorkOrderServiceImpl.java

@@ -2141,4 +2141,18 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
         return result;
     }
 
+    @Override
+    @Transactional
+    public int shutdownOrder(GxtWorkOrder gxtWorkOrder) {
+        int result = gxtWorkOrderMapper.updateGxtWorkOrder(gxtWorkOrder);
+        if (result > 0)
+        {
+            // 记录流转
+            recordWorkOrderFlow(gxtWorkOrder.getId(), gxtWorkOrder.getWorkOrderProjectNo(), "shutdown", gxtWorkOrder.getWorkOrderStatus(),gxtWorkOrder.getWorkOrderStatus(),
+                    null);
+        }
+
+        return result;
+    }
+
 }

+ 5 - 1
ygtx-gxt/src/main/resources/mapper/gxt/GxtRepairOrderMapper.xml

@@ -74,6 +74,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="realFailureReason"    column="real_failure_reason"    />
         <result property="lostPower"    column="lost_power"    />
         <result property="workPermitNum"    column="work_permit_num"    />
+        <result property="finalizeMethod"    column="finalize_method"    />
         <result property="appealUserName"    column="appeal_user_name"    />
         <result property="appealUserId"    column="appeal_user_id"    />
         <result property="appealTime"    column="appeal_time"    />
@@ -145,7 +146,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                review_content, maintenance_type, occur_time, fault_barcode, suspend_reason, suspend_description, approval_status,
                rejection_reason, modify_reason, finalization_remark, related_order_code, related_order_content, mis_order_no, restart_time,
                scoring_status, pcs_station_pid, attachment_urls, review_score_num, final_coefficient, order_type, repair_method, reset_method, invalid_reason, return_type, return_reason, feedback_reason, confirm_status,
-                wwry_num, wlry_num, work_area, info_entry, real_failure_reason, lost_power, work_permit_num, appeal_user_name, appeal_user_id, appeal_time, appeal_reason, suspend_explain, order_entry_type, order_attachment, extra_work, accept_return_type, accept_return_reason, score_return_reason from gxt_repair_order t
+                wwry_num, wlry_num, work_area, info_entry, real_failure_reason, lost_power, work_permit_num, finalize_method, appeal_user_name, appeal_user_id, appeal_time, appeal_reason, suspend_explain, order_entry_type, order_attachment, extra_work, accept_return_type, accept_return_reason, score_return_reason from gxt_repair_order t
         left join sys_user u on u.user_name = t.create_by
         left join sys_dept d on u.dept_id = d.dept_id
     </sql>
@@ -315,6 +316,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="acceptReturnType != null and acceptReturnType != ''">accept_return_type,</if>
             <if test="acceptReturnReason != null and acceptReturnReason != ''">accept_return_reason,</if>
             <if test="scoreReturnReason != null and scoreReturnReason != ''">score_return_reason,</if>
+            <if test="finalizeMethod != null and finalizeMethod != ''">finalize_method,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="workOrderProjectNo != null and workOrderProjectNo != ''">#{workOrderProjectNo},</if>
@@ -395,6 +397,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="acceptReturnType != null and acceptReturnType != ''">#{acceptReturnType},</if>
             <if test="acceptReturnReason != null and acceptReturnReason != ''">#{acceptReturnReason},</if>
             <if test="scoreReturnReason != null and scoreReturnReason != ''">#{scoreReturnReason},</if>
+            <if test="finalizeMethod != null and finalizeMethod != ''">#{finalizeMethod},</if>
         </trim>
     </insert>
 
@@ -483,6 +486,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 accept_return_reason = #{acceptReturnReason},
             </if>
             <if test="scoreReturnReason != null and scoreReturnReason != ''">score_return_reason = #{scoreReturnReason},</if>
+            <if test="finalizeMethod != null and finalizeMethod != ''">finalize_method = #{finalizeMethod},</if>
         </trim>
         where id = #{id}
     </update>

+ 5 - 1
ygtx-gxt/src/main/resources/mapper/gxt/GxtWorkOrderMapper.xml

@@ -75,6 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="infoEntry"    column="info_entry"    />
         <result property="lostPower"    column="lost_power"    />
         <result property="workPermitNum"    column="work_permit_num"    />
+        <result property="finalizeMethod"    column="finalize_method"    />
         <result property="appealUserId"    column="appeal_user_id"    />
         <result property="appealUserName"    column="appeal_user_name"    />
         <result property="appealTime"    column="appeal_time"    />
@@ -119,7 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                content, real_content, fault_code, fault_desc, order_type, priority_type, score, review_content, issuer_name,
                permitter_name, scoring_status, t.create_by, t.create_time, t.update_by, t.update_time, t.remark, t.attachment_urls,
                item_completion_factor, item_completion_factor_sum, review_score_num, final_coefficient, is_deferred, invalid_reason, feedback_reason, confirm_status,
-               wwry_num, wlry_num, info_entry, lost_power, work_permit_num, appeal_user_id, appeal_user_name, appeal_time, appeal_reason, suspend_explain, order_entry_type, score_return_reason
+               wwry_num, wlry_num, info_entry, lost_power, work_permit_num, finalize_method, appeal_user_id, appeal_user_name, appeal_time, appeal_reason, suspend_explain, order_entry_type, score_return_reason
         from gxt_work_order t
          left join sys_user u on u.user_name = t.create_by
          left join sys_dept d on u.dept_id = d.dept_id
@@ -264,6 +265,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="suspendExplain != null and suspendExplain != ''">suspend_explain,</if>
             <if test="orderEntryType != null and orderEntryType != ''">order_entry_type,</if>
             <if test="scoreReturnReason != null and scoreReturnReason != ''">score_return_reason,</if>
+            <if test="finalizeMethod != null and finalizeMethod != ''">finalize_method,</if>
             </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="workOrderProjectNo != null and workOrderProjectNo != ''">#{workOrderProjectNo},</if>
@@ -339,6 +341,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="suspendExplain != null and suspendExplain != ''">#{suspendExplain},</if>
             <if test="orderEntryType != null and orderEntryType != ''">#{orderEntryType},</if>
             <if test="scoreReturnReason != null and scoreReturnReason != ''">#{scoreReturnReason},</if>
+            <if test="finalizeMethod != null and finalizeMethod != ''">#{finalizeMethod},</if>
         </trim>
     </insert>
 
@@ -438,6 +441,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="suspendExplain != null and suspendExplain != ''">suspend_explain = #{suspendExplain},</if>
             <if test="orderEntryType != null and orderEntryType != ''">order_entry_type = #{orderEntryType},</if>
             <if test="scoreReturnReason != null and scoreReturnReason != ''">score_return_reason = #{scoreReturnReason},</if>
+            <if test="finalizeMethod != null and finalizeMethod != ''">finalize_method = #{finalizeMethod},</if>
         </trim>
         where id = #{id}
     </update>

+ 4 - 2
ygtx-gxt/src/main/resources/mapper/gxt/source/GxtMisInfoMapper.xml

@@ -37,6 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="userName"    column="person_id"    />
         <result property="createTime"    column="create_time"    />
         <result property="updateTime"    column="update_time"    />
+        <result property="isLeader"    column="is_charge_user"    />
     </resultMap>
 
     <sql id="selectGxtMisInfoVo">
@@ -47,7 +48,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </sql>
 
     <sql id="selectGxtWorkOrderPersonVo">
-        select person_name, work_order_project_code, person_id, create_time, update_time
+        select person_name, work_order_project_code, person_id, create_time, update_time, is_charge_user
         from fujian_wo_new_internal_team_members
     </sql>
 
@@ -74,7 +75,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <where>
             <if test="nickName != null and nickName != ''"> and person_name = #{nickName}</if>
             <if test="misNo != null and misNo != ''"> and work_order_project_code = #{misNo}</if>
-            <if test="userName != null and userName != ''"> and person_id = #{isLeader}</if>
+            <if test="userName != null and userName != ''"> and person_id = #{userName}</if>
+            <if test="isLeader != null and isLeader != ''"> and is_charge_user = #{isLeader}</if>
         </where>
         order by create_time desc
     </select>

+ 9 - 1
ygtx-ui/src/api/gxt/gxtOrder.js

@@ -250,4 +250,12 @@ export function getExportFields() {
     url: '/gxt/order/exportFields',
     method: 'get'
   })
-}
+}
+
+export function shutdownOrder(data) {
+  return request({
+    url: '/gxt/order/shutdown',
+    method: 'put',
+    data: data
+  })
+}

+ 709 - 0
ygtx-ui/src/components/gxtOrder/backfillFinalize.vue

@@ -0,0 +1,709 @@
+<template>
+  <el-dialog title="结单" v-model="visible" width="800px" append-to-body @close="handleClose">
+    <el-alert type="info" :closable="false" style="border-color: #14b8a6; background-color: #f0fdfa; color: #0d9488; height: 35px;">
+      <template #default>
+        <i class="fa fa-file-text-o mr-2" style="color: #0d9488;"> 请输入相关作业信息,请上传附件完成结单。</i>
+      </template>
+    </el-alert>
+    <el-form ref="finishRef" :model="formData" :rules="finishRules" label-width="120px" label-position="top">
+      <!-- 工单信息 -->
+      <h4 class="text-sm font-medium text-gray-800 mb-3"></h4>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="工单编码">
+            <el-input v-model="formData.workOrderProjectNo" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="工单状态" prop="workOrderStatus">
+            <el-select v-model="formData.workOrderStatus" disabled>
+              <el-option
+                v-for="dict in workOrderStatusOptions"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="风机编号">
+            <el-input v-model="formData.pcsDeviceName" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="维保中心">
+            <el-input v-model="formData.gxtCenter" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="场站">
+            <el-input v-model="formData.pcsStationName" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="品牌">
+            <el-input v-model="formData.brand" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="机型">
+            <el-input v-model="formData.model" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="formData.infoEntry == '1'">
+          <el-form-item label="MIS工单编码">
+            <el-input v-model="formData.misNo" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="formData.infoEntry == '2'">
+          <el-form-item label="工作票编号">
+            <el-input v-model="formData.workPermitNum" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="接单人">
+            <el-input v-model="formData.acceptUserName" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="接单时间">
+            <el-input v-model="formData.acceptTime" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="开始时间" prop="realStartTime">
+            <el-date-picker
+              v-model="formData.realStartTime"
+              type="datetime"
+              format="YYYY-MM-DD HH:mm"
+              value-format="YYYY-MM-DD HH:mm"
+              placeholder="请选择开始时间"
+              style="width: 100%"
+              :disabled-date="disabledStartDate"
+              @change="handleStartTimeChange"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="结束时间" prop="realEndTime">
+            <el-date-picker
+              v-model="formData.realEndTime"
+              type="datetime"
+              format="YYYY-MM-DD HH:mm"
+              value-format="YYYY-MM-DD HH:mm"
+              placeholder="请选择结束时间"
+              style="width: 100%"
+              :disabled-date="disabledEndDate"
+              @change="handleEndTimeChange"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="resumeInfo && resumeShow">
+          <el-form-item label="挂起结束时间" prop="resumeTime">
+            <el-date-picker
+                v-model="formData.resumeTime"
+                type="datetime"
+                format="YYYY-MM-DD HH:mm"
+                value-format="YYYY-MM-DD HH:mm"
+                placeholder="请选择挂起结束时间"
+                style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="外委人员数(人)" prop="wwryNum">
+            <el-input-number
+              v-model="formData.wwryNum"
+              placeholder="请输入外委人员数"
+              controls-position="right"
+              style="width: 100%"
+              class="input-number-left"
+              :min="0"
+              :step="1"
+              :precision="0"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="外来人员数(人)" prop="wlryNum">
+            <el-input-number
+              v-model="formData.wlryNum"
+              placeholder="请输入外来人员数"
+              controls-position="right"
+              style="width: 100%"
+              class="input-number-left"
+              :min="0"
+              :step="1"
+              :precision="0"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <!-- 维保详情 -->
+      <el-row :gutter="20">
+        <el-col :span="24">
+          <el-form-item label="维保内容" prop="content">
+            <el-input v-model="formData.content" type="textarea" :rows="3" maxlength="500" show-word-limit />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="工作负责人">
+            <el-input v-model="formData.teamLeaderName" disabled />
+          </el-form-item>
+        </el-col>
+<!--      </el-row>-->
+<!--      <el-row>-->
+        <el-col :span="12">
+          <el-form-item label="检修人员" prop="workGroupMemberName">
+            <el-input
+                v-model="formData.workGroupMemberName"
+                placeholder="请选择检修人员"
+                :readonly="formData.infoEntry == '1'"
+            >
+              <template #append v-if="formData.infoEntry == '2'">
+                <el-button @click="userSelectVisible = true" icon="User"></el-button>
+              </template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="附件(可选)">
+            <preview :limit="8" v-model="formData.attachmentUrls" :filesize="5"></preview>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="handleCancel">取 消</el-button>
+        <el-button type="primary" @click="handleSubmit" :loading="submitLoading">确认结单</el-button>
+      </div>
+    </template>
+  </el-dialog>
+
+  <!-- 人员选择组件 -->
+  <UserSelectMulti
+      v-model="userSelectVisible"
+      :pre-selected-users="selectedUsers"
+      @onSelected="onUserSelected"
+  />
+</template>
+
+<script setup>
+import { ref, defineProps, defineEmits, getCurrentInstance, watch } from 'vue'
+import preview from '@/components/FileUpload/preview.vue'
+import UserSelectMulti from "@/components/userSelect/multi.vue";
+import {ElMessageBox} from "element-plus";
+
+// 获取当前实例
+const { proxy } = getCurrentInstance()
+
+// 定义属性
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  data: {
+    type: Object,
+    default: () => ({})
+  },
+  workOrderStatusOptions: {
+    type: Array,
+    default: () => ([])
+  },
+  listUserData: {
+    type: Function,
+    default: null
+  },
+  onSubmit: {
+    type: Function,
+    default: null
+  }
+})
+// 定义事件
+const emit = defineEmits(['update:modelValue', 'success'])
+
+// 响应式数据
+const visible = ref(false)
+const formData = ref({})
+const finishRef = ref()
+const submitLoading = ref(false)
+const userSelectVisible = ref(false) // 添加人员选择组件可见性
+const selectedUsers = ref([]) // 存储选中的用户
+const inputUsers = ref([]) // 存储选中的用户
+const flowList = ref([])
+const suspendInfo = ref(null)
+const resumeInfo = ref(null)
+const resumeShow = ref(false)
+
+
+// 表单验证规则
+const finishRules = ref({
+  realStartTime: [
+    { required: true, message: "开始时间不能为空", trigger: "change" },
+    {
+      validator: (rule, value, callback) => {
+        if (value && new Date(value) > new Date()) {
+          callback(new Error('开始时间不能大于当前时间'));
+        // } else if(value && new Date(value) < new Date(formData.value.acceptTime) && formData.value.infoEntry == '2') {
+        //   callback(new Error('开始时间不能小于接单时间'));
+        } else {
+          callback();
+        }
+      },
+      trigger: 'change'
+    }
+  ],
+  realEndTime: [
+    { required: true, message: "结束时间不能为空", trigger: "change" },
+    {
+      validator: (rule, value, callback) => {
+        if (value && new Date(value) > new Date() && formData.value.infoEntry == '2') {
+          callback(new Error('结束时间不能大于当前时间'));
+        } else if(value && new Date(value) < new Date(formData.value.realStartTime) && formData.value.infoEntry == '2') {
+          callback(new Error('结束时间不能小于开始时间'));
+        } else {
+          callback();
+        }
+      },
+      trigger: 'change'
+    }
+  ],
+  workGroupMemberName: [
+    { required: false, message: "请输入检修人员", trigger: "change" },
+    {
+      validator: async (rule, value, callback) => {
+        // 如果值为空、关联MIS,直接通过验证
+        if (!value || formData.value.infoEntry == '1') {
+          selectedUsers.value = [];
+          return callback();
+        }
+        try {
+          inputUsers.value = []
+          // 将输入的检修人员姓名按逗号分割
+          const names = value.split(',').map(name => name.trim());
+          // 验证每个检修人员是否存在于组织架构中
+          for (const name of names) {
+            if (name.length > 0) {
+              // 检查输入中重复
+              if (inputUsers.value.some(u => u.nickName === name)) {
+                return callback(new Error(`检修人员"${name}"重复,请重新输入`));
+              }
+              // 使用从属性传入的listUserData方法(如果有的话)
+              if (props.listUserData) {
+                const response = await props.listUserData({nickName: name});
+                if (!response.rows || response.rows.length === 0) {
+                  return callback(new Error(`检修人员"${name}"非系统内人员,请重新输入`));
+                }else{
+                  inputUsers.value.push(response.rows[0]);
+                }
+              }
+            } else {
+              return callback(new Error(`请正确输入检修人员名单`));
+            }
+          }
+          selectedUsers.value = inputUsers.value;
+          callback();
+        } catch (error) {
+          callback(new Error('验证检修人员时发生错误'));
+        }
+      },
+      trigger: 'change'
+    }
+  ],
+  content: [
+    { required: true, message: "请输入维保内容", trigger: "change" }
+  ],
+  resumeTime: [
+    { required: true, message: "挂起结束时间不能为空", trigger: "change" },
+    {
+      validator: (rule, value, callback) => {
+        const realStartTime = formData.value.realStartTime
+        const realEndTime = formData.value.realEndTime
+        const suspendTime = suspendInfo.value.actionTime
+        debugger
+        if (suspendTime && realStartTime && new Date(suspendTime) < new Date(realStartTime)) { // 开工前挂起
+          if (value && new Date(value) > new Date(realStartTime)) {
+            callback(new Error('开工前挂起结束时间晚于实际开始时间,请调整'));
+          } else if(realEndTime && value && new Date(value) > new Date(realEndTime)) {
+            callback(new Error('开工前挂起结束时间晚于实际结束时间,请调整'));
+          } else {
+            callback();
+          }
+
+        } else if(suspendTime && realStartTime && new Date(suspendTime) >= new Date(realStartTime)) { // 作业中挂起
+          if (value && new Date(value) < new Date(realStartTime)) {
+            callback(new Error('作业中挂起结束时间早于实际开始时间,请调整'));
+          } else if(realEndTime && value && new Date(value) > new Date(realEndTime)) {
+            callback(new Error('作业中挂起结束时间晚于实际结束时间,请调整'));
+          } else {
+            callback();
+          }
+        } else {
+          callback();
+        }
+      },
+      trigger: 'change'
+    }
+  ],
+})
+// 时间禁用函数
+const disabledStartDate = (time) => {
+  const getYYYYMMDD = (date) => {
+    const y = date.getFullYear();
+    const m = String(date.getMonth() + 1).padStart(2, '0');
+    const d = String(date.getDate()).padStart(2, '0');
+    return `${y}-${m}-${d}`;
+  };
+
+  const today = getYYYYMMDD(new Date());
+
+  let acceptDateStr = null;
+  const acceptStr = formData.value.acceptTime;
+  if (acceptStr) {
+    acceptDateStr = acceptStr.split(' ')[0];
+  }
+
+  const selectedDateStr = getYYYYMMDD(time);
+
+  // 如果没有 acceptTime,只禁用未来日期
+  if (!acceptDateStr) {
+    return selectedDateStr > today;
+  }
+
+  // 要用:早于 acceptDate 或 晚于今天
+  // return selectedDateStr < acceptDateStr || selectedDateStr > today;
+  return selectedDateStr > today;
+
+};
+
+const disabledEndDate = (time) => {
+  const getYYYYMMDD = (date) => {
+    const y = date.getFullYear();
+    const m = String(date.getMonth() + 1).padStart(2, '0');
+    const d = String(date.getDate()).padStart(2, '0');
+    return `${y}-${m}-${d}`;
+  };
+
+  const today = getYYYYMMDD(new Date());
+
+  let acceptDateStr = null;
+  const acceptStr = formData.value.acceptTime;
+  const startStr = formData.value.realStartTime;
+  if (startStr) {
+    acceptDateStr = startStr.split(' ')[0];
+  } else if(acceptStr) {
+    acceptDateStr = acceptStr.split(' ')[0];
+  }
+
+  const selectedDateStr = getYYYYMMDD(time);
+
+  // 如果没有 acceptTime,只禁用未来日期
+  if (!acceptDateStr) {
+    return selectedDateStr > today;
+  }
+
+  // 要用:早于 acceptDate 或 晚于今天
+  return selectedDateStr < acceptDateStr || selectedDateStr > today;
+};
+
+// 监听modelValue变化
+watch(() => props.modelValue, (val) => {
+  visible.value = val
+  if (val) {
+    // 初始化表单数据
+    formData.value = { ...props.data }
+    flowList.value = formData.value.workOrderFlowList || []
+    debugger
+    if (formData.value.suspendReason && flowList.value.length > 0) {
+      // 获取最后一个 actionType 等于 'resume' 的项
+      const lastResumeItem = flowList.value.findLast(item => item.actionType === 'resume')
+      if (lastResumeItem) {
+        // 做你想做的事,比如记录时间、设置状态等
+        console.log('最后一个 resume 项:', lastResumeItem)
+        resumeInfo.value = lastResumeItem
+        formData.value.resumeTime = lastResumeItem.actionTime
+      }
+
+      const lastSuspendItem = flowList.value.findLast(item => item.actionType === 'to_approve')
+      if (lastSuspendItem) {
+        // 做你想做的事,比如记录时间、设置状态等
+        console.log('最后一个 to_approve 项:', lastSuspendItem)
+        suspendInfo.value = lastSuspendItem
+      }
+      handleStartTimeChange(formData.value.realStartTime)
+    }
+  }
+})
+
+// 监听props.data变化
+watch(() => props.data, (newData) => {
+  if (visible.value) {
+    // 只有在对话框打开时才更新数据
+    formData.value = { ...newData }
+
+    flowList.value = formData.value.workOrderFlowList || []
+    debugger
+    if (formData.value.suspendReason && flowList.value.length > 0) {
+      // 获取最后一个 actionType 等于 'resume' 的项
+      const lastResumeItem = flowList.value.findLast(item => item.actionType === 'resume')
+      if (lastResumeItem) {
+        // 做你想做的事,比如记录时间、设置状态等
+        console.log('最后一个 resume 项:', lastResumeItem)
+        resumeInfo.value = lastResumeItem
+        formData.value.resumeTime = lastResumeItem.actionTime
+      }
+
+      const lastSuspendItem = flowList.value.findLast(item => item.actionType === 'to_approve')
+      if (lastSuspendItem) {
+        // 做你想做的事,比如记录时间、设置状态等
+        console.log('最后一个 to_approve 项:', lastSuspendItem)
+        suspendInfo.value = lastSuspendItem
+      }
+      handleStartTimeChange(formData.value.realStartTime)
+    }
+  }
+}, { deep: true })
+
+// 监听visible变化
+watch(visible, (val) => {
+  emit('update:modelValue', val)
+  if (val) {
+    // 打开对话框后重置表单验证错误
+    proxy.$nextTick(() => {
+      if (finishRef.value) {
+        finishRef.value.clearValidate()
+      }
+    })
+  }
+})
+
+watch(
+    () => props.data?.realStartTime, // 只监听 realStartTime
+    (newStartTime, oldStartTime) => {
+      // 判断是否真的变化了(避免 undefined === undefined 误判)
+      debugger
+      if (resumeInfo.value && newStartTime && newStartTime !== oldStartTime) {
+        // 注意:此时对话框可能未打开,根据你的需求决定是否加 visible 判断
+        if (visible.value) {
+          handleStartTimeChange(newStartTime);
+        }
+      }
+    },
+    { immediate: true } // 如果需要初始化时也触发一次,可加;否则去掉
+);
+
+watch(
+    () => props.data?.realEndTime, // 只监听 realEndTime
+    (newEndTime, oldEndTime) => {
+      // 判断是否真的变化了(避免 undefined === undefined 误判)
+      debugger
+      if (resumeInfo.value && newEndTime && oldEndTime !== oldEndTime) {
+        // 注意:此时对话框可能未打开,根据你的需求决定是否加 visible 判断
+        if (visible.value) {
+          handleEndTimeChange(newEndTime);
+        }
+      }
+    },
+    { immediate: true } // 如果需要初始化时也触发一次,可加;否则去掉
+);
+
+// 关闭对话框
+const handleClose = () => {
+  visible.value = false
+  selectedUsers.value = []
+  resumeInfo.value = null
+  suspendInfo.value = null
+  resumeShow.value = false
+}
+
+// 取消操作
+const handleCancel = () => {
+  visible.value = false
+  selectedUsers.value = []
+  resumeInfo.value = null
+  suspendInfo.value = null
+  resumeShow.value = false
+}
+
+// 用户选择回调函数
+const onUserSelected = (users) => {
+  if (users && users.length > 0) {
+    // 合并用户,避免重复
+    const existingNames = selectedUsers.value.map(u => u.nickName);
+    const newUsers = users.filter(u => !existingNames.includes(u.nickName));
+    selectedUsers.value = [...selectedUsers.value, ...newUsers];
+    // 构建用户姓名列表
+    const userNames = selectedUsers.value.map(user => user.nickName).join(',');
+    formData.value.workGroupMemberName = userNames;
+  } else {
+    selectedUsers.value = [];
+    formData.value.workGroupMemberName = '';
+  }
+  formData.value.workOrderPersonList = selectedUsers.value.map(user => ({
+    userId: user.userId,
+    nickName: user.nickName,
+    orderId: formData.value.id,
+    orderCode: formData.value.workOrderProjectNo,
+    status: 1
+  }));
+};
+
+// 提交操作
+const handleSubmit = async () => {
+  if (!finishRef.value) return
+
+  await finishRef.value.validate(async (valid) => {
+    if (valid) {
+      const { realStartTime, acceptTime } = formData.value;
+      debugger
+      if (realStartTime && acceptTime && (new Date(realStartTime) < new Date(acceptTime))) { //开始时间早于接单时间,为补录工单
+        formData.value.orderEntryType = '2'
+        // try {
+        //   debugger
+        //   await ElMessageBox.confirm(
+        //       '检测到开始时间早于接单时间,系统将按“补录工单”处理,准备工时为0。是否继续?',
+        //       '提示',
+        //       {
+        //         confirmButtonText: '是',
+        //         cancelButtonText: '否',
+        //         type: 'warning',
+        //         distinguishCancelAndClose: true
+        //       }
+        //   );
+        //   formData.value.orderEntryType = '2'
+        //   // 用户点击“是”,继续提交
+        // } catch (error) {
+        //   // 用户点击“否”或关闭弹窗
+        //   finalizeFormRef.value?.validateField('realStartTime');
+        //   return;
+        // }
+      }
+
+
+      try {
+        if (!formData.value.realEndTime) {
+          proxy.$modal.msgError("该工单未结束,无法结单!")
+          return
+        }
+        submitLoading.value = true
+
+        // 调用父组件传入的提交函数
+        if (props.onSubmit && typeof props.onSubmit === 'function') {
+          flowList.value = []
+          if (formData.value.resumeTime && formData.value.resumeTime != resumeInfo.value.actionTime) { //存入新的挂起结束时间
+            resumeInfo.value.actionTime = formData.value.resumeTime
+            flowList.value.push(resumeInfo.value)
+          }
+          formData.value.workOrderFlowList = flowList.value
+          await props.onSubmit(formData.value)
+        } else {
+          throw new Error("未提供提交方法")
+        }
+
+        proxy.$modal.msgSuccess("结单成功")
+        visible.value = false
+        emit('success')
+      } catch (error) {
+        proxy.$modal.msgError("操作失败: " + (error.message || "未知错误"))
+      } finally {
+        submitLoading.value = false
+      }
+    }
+  })
+}
+
+
+// 开始时间变化处理
+const handleStartTimeChange = (value) => {
+  debugger
+  if (resumeInfo.value && value) {
+    const realStartTime = formData.value.realStartTime
+    const realEndTime = formData.value.realEndTime
+    const suspendTime = suspendInfo.value.actionTime
+    const resumeTime = formData.value.resumeTime
+    if (suspendTime && value && new Date(suspendTime) < new Date(value)) { // 开工前挂起
+      if (value && resumeTime > new Date(value)) {
+        resumeShow.value = true
+      } else if(realEndTime && resumeTime && new Date(resumeTime) > new Date(realEndTime)) {
+        resumeShow.value = true
+      } else {
+        resumeShow.value = false
+      }
+
+    } else if(suspendTime && value && new Date(suspendTime) >= new Date(value)) { // 作业中挂起
+      if (value && new Date(resumeTime) < new Date(value)) {
+        resumeShow.value = true
+      } else if(realEndTime && resumeTime && new Date(resumeTime) > new Date(realEndTime)) {
+        resumeShow.value = true
+      } else {
+        resumeShow.value = false
+      }
+    } else {
+      resumeShow.value = false
+    }
+  }
+}
+
+// 结束时间变化处理
+const handleEndTimeChange = (value) => {
+  debugger
+  if (resumeInfo.value && value) {
+    const realStartTime = formData.value.realStartTime
+    const realEndTime = formData.value.realEndTime
+    const suspendTime = suspendInfo.value.actionTime
+    const resumeTime = formData.value.resumeTime
+    if (suspendTime && realStartTime && new Date(suspendTime) < new Date(realStartTime)) { // 开工前挂起
+      if (value && resumeTime > new Date(realStartTime)) {
+        resumeShow.value = true
+      } else if(value && resumeTime && new Date(resumeTime) > new Date(value)) {
+        resumeShow.value = true
+      } else {
+        resumeShow.value = false
+      }
+
+    } else if(suspendTime && realStartTime && new Date(suspendTime) >= new Date(realStartTime)) { // 作业中挂起
+      if (realStartTime && new Date(resumeTime) < new Date(realStartTime)) {
+        resumeShow.value = true
+      } else if(value && resumeTime && new Date(resumeTime) > new Date(value)) {
+        resumeShow.value = true
+      } else {
+        resumeShow.value = false
+      }
+    } else {
+      resumeShow.value = false
+    }
+  }
+}
+</script>
+
+<style scoped>
+/* 表单中的列间距调整 */
+:deep(.el-col) {
+  padding-left: 5px;
+  padding-right: 5px;
+}
+
+/* 穿透修改组件内部输入框的对齐方式(关键) */
+:deep(.input-number-left .el-input__inner) {
+  text-align: left !important; /* !important 覆盖组件默认的居中 */
+}
+</style>

+ 184 - 15
ygtx-ui/src/components/gxtOrder/finalize.vue

@@ -57,16 +57,16 @@
             <el-input v-model="formData.model" disabled />
           </el-form-item>
         </el-col>
-        <el-col :span="12" v-if="formData.infoEntry == '1'">
-          <el-form-item label="MIS工单编码">
-            <el-input v-model="formData.misNo" disabled />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12" v-if="formData.infoEntry == '2'">
-          <el-form-item label="工作票编号">
-            <el-input v-model="formData.workPermitNum" disabled />
-          </el-form-item>
-        </el-col>
+<!--        <el-col :span="12" v-if="formData.infoEntry == '1'">-->
+<!--          <el-form-item label="MIS工单编码">-->
+<!--            <el-input v-model="formData.misNo" disabled />-->
+<!--          </el-form-item>-->
+<!--        </el-col>-->
+<!--        <el-col :span="12" v-if="formData.infoEntry == '2'">-->
+<!--          <el-form-item label="工作票编号">-->
+<!--            <el-input v-model="formData.workPermitNum" disabled />-->
+<!--          </el-form-item>-->
+<!--        </el-col>-->
       </el-row>
       <el-row>
         <el-col :span="12">
@@ -81,6 +81,56 @@
         </el-col>
       </el-row>
       <el-row>
+        <el-col :span="12">
+          <el-form-item label="信息录入" prop="infoEntry">
+            <el-radio-group v-model="formData.infoEntry" @change="handleInfoEntryChange">
+              <el-radio
+                  v-for="dict in infoEntryOptions"
+                  :key="dict.value"
+                  :label="dict.value"
+              >
+                {{ dict.label }}
+              </el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="formData.infoEntry == 1">
+          <el-form-item label="MIS工单编码" prop="misNo" >
+            <el-input
+                v-model="formData.misNo"
+                placeholder="请输入MIS工单编码或点击搜索选择"
+                clearable
+                @focus="handleMisNoInputFocus"
+                @blur="handleMisNoInputBlur"
+                @input="handleMisNoInput"
+                @clear="handleMisNoClear"
+            >
+              <template #append>
+                <el-button @click="handleSelectMisInfo" icon="Search"></el-button>
+              </template>
+            </el-input>
+            <!-- 快速检索下拉框 -->
+            <div class="quick-select-dropdown" v-show="showMisNoQuickSelect && quickMisNoList.length > 0">
+              <div
+                  v-for="item in quickMisNoList"
+                  :key="item.misNo"
+                  class="quick-select-item"
+                  @click="handleMisNoQuickSelect(item)">
+                <span class="mis-no">{{ item.misNo }}</span>
+              </div>
+            </div>
+            <div class="quick-select-dropdown no-data" v-show="showMisNoQuickSelect && quickMisNoList.length === 0 && formData.misNo">
+              <div>未找到匹配的MIS工单</div>
+            </div>
+          </el-form-item>
+        </el-col>
+        <!-- MIS选择组件 -->
+        <slot name="mis-info-select"></slot>
+        <el-col :span="12" v-if="formData.infoEntry == 2">
+          <el-form-item label="工作票编号" prop="workPermitNum">
+            <el-input v-model="workPermitNumProxy" maxlength="20" show-word-limit />
+          </el-form-item>
+        </el-col>
         <el-col :span="12">
           <el-form-item label="开始时间" prop="realStartTime">
             <el-date-picker
@@ -236,10 +286,22 @@ const props = defineProps({
   onSubmit: {
     type: Function,
     default: null
-  }
+  },
+  infoEntryOptions: {
+    type: Array,
+    default: () => ([])
+  },
+  listMisInfo: {
+    type: Function,
+    default: null
+  },
+  listWorkPerson: {
+    type: Function,
+    default: null
+  },
 })
 // 定义事件
-const emit = defineEmits(['update:modelValue', 'success'])
+const emit = defineEmits(['update:modelValue', 'success', 'select-mis-info'])
 
 // 响应式数据
 const visible = ref(false)
@@ -253,6 +315,18 @@ const flowList = ref([])
 const suspendInfo = ref(null)
 const resumeInfo = ref(null)
 const resumeShow = ref(false)
+const showMisNoQuickSelect = ref(false)
+const quickMisNoList = ref([])
+
+// 计算属性
+const workPermitNumProxy = computed({
+  get() {
+    return formData.value.workPermitNum
+  },
+  set(val) {
+    formData.value.workPermitNum = val
+  }
+})
 
 
 // 表单验证规则
@@ -364,6 +438,9 @@ const finishRules = ref({
       trigger: 'change'
     }
   ],
+  misNo: [
+    { required: true, message: "MIS工单编码不能为空", trigger: "change" }
+  ],
 })
 // 时间禁用函数
 const disabledStartDate = (time) => {
@@ -575,8 +652,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(
@@ -596,7 +673,7 @@ const handleSubmit = async () => {
         //   finalizeFormRef.value?.validateField('realStartTime');
         //   return;
         // }
-      }
+      // }
 
 
       try {
@@ -693,6 +770,98 @@ const handleEndTimeChange = (value) => {
     }
   }
 }
+
+// MIS工单相关处理函数
+const handleMisNoInputFocus = () => {
+  // showMisNoQuickSelect.value = true
+  showMisNoQuickSelect.value = true
+  // 如果已有输入内容,立即搜索
+  if (formData.value.misNo && formData.value.misNo.trim()) {
+    handleMisNoInput(formData.value.misNo)
+  }
+}
+
+const handleMisNoInputBlur = () => {
+  // 延迟隐藏下拉框,确保点击选项能触发
+  setTimeout(() => {
+    showMisNoQuickSelect.value = false
+  }, 200)
+}
+
+const handleMisNoInput = (value) => {
+  const searchText = value.trim()
+  // 这里应该调用搜索函数
+  if (!searchText) {
+    quickMisNoList.value = []
+    showMisNoQuickSelect.value = false
+    return
+  }
+  showMisNoQuickSelect.value = true
+  // 清除之前的定时器
+  if (misNoSearchTimer.value) {
+    clearTimeout(misNoSearchTimer.value)
+  }
+  // 设置新的定时器,防抖处理(500ms)
+  misNoSearchTimer.value = setTimeout(() => {
+    searchMisNoList(searchText)
+  }, 500)
+}
+
+const handleMisNoClear = () => {
+  formData.value.misNo = undefined
+}
+
+const handleSelectMisInfo = () => {
+  emit('select-mis-info')
+}
+
+const handleMisNoQuickSelect = (item) => {
+  formData.value.misNo = item.misNo
+  showMisNoQuickSelect.value = false
+}
+
+/** 搜索MIS工单列表 */
+const searchMisNoList = async (keyword) => {
+  if (!keyword) {
+    quickMisNoList.value = []
+    return
+  }
+  debugger
+  // 检查是否提供了listMisInfo函数
+  if (!props.listMisInfo || typeof props.listMisInfo !== 'function') {
+    console.error('未提供listMisInfo函数')
+    quickMisNoList.value = []
+    return
+  }
+
+  try {
+    const response = await props.listMisInfo({
+      pageNum: 1,
+      misNo: keyword
+    })
+
+    quickMisNoList.value = response.rows || []
+  } catch (error) {
+    console.error('搜索MIS工单失败:', error)
+    proxy.$modal.msgError('搜索失败,请重试')
+    quickMisNoList.value = []
+  }
+}
+
+// 信息录入方式变化处理
+const handleInfoEntryChange = (val) => {
+  // 选中2工作票编号时修改其他值
+  if (val === '2') {
+    formData.value.misNo = undefined;
+    formData.value.realStartTime = undefined;
+    formData.value.realEndTime = undefined;
+    formData.value.workGroupMemberName = undefined;
+    formData.value.repairOrderPersonList = [];
+    selectedUsers.value = [];
+  } else {
+    formData.value.workPermitNum = undefined;
+  }
+}
 </script>
 
 <style scoped>

+ 206 - 0
ygtx-ui/src/components/gxtOrder/shutdown.vue

@@ -0,0 +1,206 @@
+<template>
+  <el-dialog title="停机" v-model="visible" width="800px" append-to-body @close="handleClose">
+    <el-alert type="info" :closable="false" style="border-color: #0ea5e9; background-color: #ecf7ff; color: #0369a1; height: 35px;">
+      <template #default>
+        <i class="fa fa-refresh mr-2" style="color: #0369a1;"> 请填写停机相关信息,完成工单停机。</i>
+      </template>
+    </el-alert>
+    <!-- 工单信息 -->
+    <h3 class="text-sm font-medium text-gray-800 mb-3"></h3>
+    <el-form ref="shutdownRef" :model="formData" :rules="restartRules" label-width="120px" label-position="top">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="工单编码">
+            <el-input v-model="formData.workOrderProjectNo" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="风机编号">
+            <el-input v-model="formData.pcsDeviceName" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="维保中心">
+            <el-input v-model="formData.gxtCenter" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="场站">
+            <el-input v-model="formData.pcsStationName" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="品牌">
+            <el-input v-model="formData.brand" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="开始时间"><el-input v-model="formData.realStartTime" disabled /> </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="formData.infoEntry == '1'">
+          <el-form-item label="MIS工单编码">
+            <el-input v-model="formData.misNo" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="formData.infoEntry == '2'">
+          <el-form-item label="工作票编号">
+            <el-input v-model="formData.workPermitNum" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="停机时间" prop="pauseTime">
+            <el-date-picker
+                v-model="formData.pauseTime"
+                type="datetime"
+                placeholder="请选择停机时间"
+                format="YYYY-MM-DD HH:mm"
+                value-format="YYYY-MM-DD HH:mm"
+                style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <!--      </div>-->
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="visible = false">取 消</el-button>
+        <el-button type="primary" @click="handleSubmit">确认停机</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, defineProps, defineEmits, getCurrentInstance, watch, onMounted } from 'vue'
+// 获取当前实例
+const { proxy } = getCurrentInstance()
+
+// 定义属性
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  data: {
+    type: Object,
+    default: () => ({})
+  },
+  workOrderStatusOptions: {
+    type: Array,
+    default: () => ([])
+  },
+  suspendReasonOptions: {
+    type: Array,
+    default: () => ([])
+  },
+  onSubmit: {
+    type: Function,
+    default: null
+  }
+})
+
+// 定义事件
+const emit = defineEmits(['update:modelValue', 'success'])
+
+// 响应式数据
+const visible = ref(false)
+const formData = ref({})
+const shutdownRef = ref()
+
+// 表单验证规则
+const restartRules = ref({
+  pauseTime: [
+    { required: true, message: "请选择停机时间", trigger: "change" },
+    // {
+    //   validator: (rule, value, callback) => {
+    //     debugger
+    //     if (value && new Date(value) > new Date()) {
+    //       callback(new Error('停机时间不能大于当前时间'));
+    //     // } else if(value && new Date(value) < new Date(formData.value.realEndTime)) {
+    //     //   callback(new Error('停机时间不能小于结束时间'));
+    //     } else {
+    //       callback();
+    //     }
+    //   },
+    //   trigger: 'change'
+    // }
+  ]
+})
+
+// 监听modelValue变化
+watch(() => props.modelValue, (val) => {
+  visible.value = val
+  if (val) {
+    // 初始化表单数据
+    formData.value = { ...props.data }
+  }
+})
+
+// 监听props.data变化
+watch(() => props.data, (newData) => {
+  if (visible.value) {
+    // 只有在对话框打开时才更新数据
+    formData.value = { ...newData }
+  }
+}, { deep: true })
+
+// 监听visible变化
+watch(visible, (val) => {
+  emit('update:modelValue', val)
+  if (val) {
+    // 打开对话框后重置表单验证错误
+    proxy.$nextTick(() => {
+      if (shutdownRef.value) {
+        shutdownRef.value.clearValidate()
+      }
+    })
+  }
+})
+
+// 关闭对话框
+const handleClose = () => {
+  visible.value = false
+}
+
+// 取消操作
+const handleCancel = () => {
+  visible.value = false
+}
+
+// 提交操作
+const handleSubmit = async () => {
+  if (!shutdownRef.value) return
+
+  debugger
+  await shutdownRef.value.validate(async (valid) => {
+    if (valid) {
+      try {
+        // 调用父组件传入的提交函数
+        if (props.onSubmit && typeof props.onSubmit === 'function') {
+          // 清除时间字段避免冲突
+          const submitData = { ...formData.value }
+          submitData.createTime = null
+          submitData.updateTime = null
+          await props.onSubmit(submitData)
+        } else {
+          throw new Error("未提供提交方法")
+        }
+
+        proxy.$modal.msgSuccess("停机成功")
+        visible.value = false
+        emit('success')
+      } catch (error) {
+        proxy.$modal.msgError("操作失败: " + (error.message || "未知错误"))
+      }
+    }
+  })
+}</script>
+
+<style scoped>
+/* 表单中的列间距调整 */
+:deep(.el-col) {
+  padding-left: 5px;
+  padding-right: 5px;
+}
+</style>

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

@@ -30,6 +30,12 @@
                 <el-col :span="24">
                   <el-form-item label="机型">{{ formData.model || '-' }}</el-form-item>
                 </el-col>
+                <el-col :span="24">
+                  <el-form-item label="维保类型">{{ formattedInspectionType }}</el-form-item>
+                </el-col>
+                <el-col :span="24">
+                  <el-form-item label="停机时间">{{ formData.pauseTime || '-' }}</el-form-item>
+                </el-col>
 
                 <!--                  <el-col :span="24">-->
                 <!--                    <el-form-item label="维保内容">{{ formData.content || '-' }}</el-form-item>-->
@@ -166,6 +172,10 @@ const props = defineProps({
   repairOrderFlowActionTypeOptions: {
     type: Array,
     default: () => ([])
+  },
+  inspectionTypeOptions: {
+    type: Array,
+    default: () => ([])
   }
 })
 
@@ -217,6 +227,30 @@ const parseTime = (time, pattern) => {
   if (!time) return ''
   return proxy.parseTime(time, pattern)
 }
+
+// 维保类型
+const formattedInspectionType = computed(() => {
+  debugger
+  const { inspectionType } = formData.value;
+  if (!inspectionType) return '-';
+
+  let values = [];
+  if (typeof inspectionType === 'string') {
+    values = inspectionType.split(',').filter(v => v.trim()); // 去空
+  } else if (Array.isArray(inspectionType)) {
+    values = inspectionType;
+  } else {
+    values = [inspectionType]; // 单个值
+  }
+  const options = props.inspectionTypeOptions || [];
+  return values
+      .map(v => {
+        // 注意:v 可能是字符串,确保类型一致(建议都转字符串比较)
+        const opt = options.find(o => String(o.value) === String(v));
+        return opt ? opt.label : v;
+      })
+      .join(',');
+})
 </script>
 
 <style scoped>

+ 346 - 303
ygtx-ui/src/views/gxt/gxtOrder/index.vue

@@ -113,6 +113,15 @@
             v-hasPermi="['gxt:maintenance:order:add']"
         >新建工单</el-button>
       </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="primary"
+            plain
+            icon="Plus"
+            @click="handleBackFilling"
+            v-hasPermi="['gxt:maintenance:order:add']"
+        >补录工单</el-button>
+      </el-col>
 <!--      <el-col :span="1.5">-->
 <!--        <el-button-->
 <!--          type="info"-->
@@ -164,6 +173,11 @@
           <dict-tag :options="gxt_work_order_status" :value="scope.row.workOrderStatus"/>
         </template>
       </el-table-column>
+      <el-table-column label="录入类别" align="center" prop="workOrderStatus" min-width="100">
+        <template #default="scope">
+          {{ scope.row.orderEntryType == '1' ? '默认' : '补录工单' }}
+        </template>
+      </el-table-column>
       <el-table-column label="维保中心" align="center" prop="gxtCenter" min-width="140" :show-overflow-tooltip="true">
         <template #default="scope">
           {{ scope.row.gxtCenter || '-' }}
@@ -260,10 +274,21 @@
           </el-button>
 
           <!-- 待结单状态:显示结单按钮 -->
-          <el-button link type="success" @click="handleFinish(scope.row)" v-if="(scope.row.workOrderStatus === 'processing' || scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))" v-hasPermi="['gxt:maintenance:order:complete']">
+          <el-button link type="success" @click="handleFinish(scope.row)" v-if="(scope.row.workOrderStatus === 'processing' || scope.row.workOrderStatus === 'to_finish') && scope.row.orderEntryType == '1'" v-hasPermi="['gxt:maintenance:order:complete']">
+            <i class="fa fa-check"></i>结单
+          </el-button>
+
+          <!-- 补录结单-->
+          <el-button link type="success" @click="handleBackfillingFinish(scope.row)" v-if="(scope.row.workOrderStatus === 'processing' || scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin') && scope.row.orderEntryType == '2')" v-hasPermi="['gxt:maintenance:order:complete']">
             <i class="fa fa-check"></i>结单
           </el-button>
 
+          <el-button link type="danger" @click="handleShutdown(scope.row)"
+                     v-if="scope.row.pauseTime == null && scope.row.workOrderStatus != 'to_issue' && scope.row.workOrderStatus != 'auto_suspend' && scope.row.workOrderStatus != 'completed' && scope.row.workOrderStatus != 'archived' && scope.row.workOrderStatus != 'invalid'"
+                     v-hasPermi="['gxt:maintenance:order:shutdown']">
+            <i class="fa fa-stop"></i>停机
+          </el-button>
+
 <!--          &lt;!&ndash; 已完成状态:显示评分按钮 &ndash;&gt;-->
 <!--          <el-button link type="warning" @click="handleRate(scope.row)" v-if="scope.row.workOrderStatus === 'completed' && scope.row.score === null" v-hasPermi="['gxt:maintenance:order:rating']">-->
 <!--            <i class="fa fa-star"></i>评分-->
@@ -309,6 +334,138 @@
 
     <!-- 新增对话框 -->
     <el-dialog :title="title" v-model="open" width="800px" append-to-body>
+      <div style="max-height: 500px; overflow-y: auto; padding-right: 10px;">
+        <el-form ref="orderRef" :model="form" :rules="rules" label-width="120px" label-position="top">
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="工单编码" prop="workOrderProjectNo">
+                <el-input v-model="form.workOrderProjectNo" placeholder="自动生成" maxlength="50" show-word-limit v-chinese-limit readonly/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="风机编号" prop="pcsDeviceName">
+                <el-input v-model="form.pcsDeviceName" readonly>
+                  <template #append>
+                    <el-button @click="handleSelectEquipment" icon="Search"></el-button>
+                  </template>
+                </el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="维保中心" prop="gxtCenter">
+                <el-input v-model="form.gxtCenter" readonly />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="场站" prop="pcsStationName">
+                <el-input v-model="form.pcsStationName" readonly />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="品牌" prop="brand">
+                <el-input v-model="form.brand" readonly />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="机型" prop="model">
+                <el-input v-model="form.model" readonly />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="维保类型" prop="inspectionType">
+                <el-select v-model="form.inspectionType" multiple placeholder="请选择维保类型" clearable>
+                  <el-option
+                      v-for="dict in gxt_inspection_type"
+                      :key="dict.value"
+                      :label="dict.label"
+                      :value="dict.value"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+<!--          <el-row :gutter="20">-->
+<!--            <el-col :span="12">-->
+<!--              <el-form-item label="信息录入" prop="infoEntry">-->
+<!--                <el-radio-group v-model="form.infoEntry" @change="handleInfoEntryChange">-->
+<!--                  <el-radio-->
+<!--                      v-for="dict in gxt_info_entry"-->
+<!--                      :key="dict.value"-->
+<!--                      :label="dict.value"-->
+<!--                  >-->
+<!--                    {{ dict.label }}-->
+<!--                  </el-radio>-->
+<!--                </el-radio-group>-->
+<!--              </el-form-item>-->
+<!--            </el-col>-->
+<!--            <el-col :span="12" v-if="form.infoEntry == '1'">-->
+<!--              <el-form-item label="MIS工单编码" prop="misNo">-->
+<!--                <el-input v-model="form.misNo"-->
+<!--                          placeholder="请输入MIS工单编码或点击搜索选择"-->
+<!--                          clearable-->
+<!--                          @focus="handleMisNoInputFocus"-->
+<!--                          @blur="handleMisNoInputBlur"-->
+<!--                          @input="handleMisNoInput"-->
+<!--                          @clear="handleMisNoClear"-->
+<!--                >-->
+<!--                  <template #append>-->
+<!--                    <el-button @click="handleSelectMisInfo" icon="Search"></el-button>-->
+<!--                  </template>-->
+<!--                </el-input>-->
+<!--                &lt;!&ndash; 快速检索下拉框 &ndash;&gt;-->
+<!--                <div class="quick-select-dropdown" v-show="showMisNoQuickSelect && quickMisNoList.length > 0">-->
+<!--                  <div-->
+<!--                      v-for="item in quickMisNoList"-->
+<!--                      :key="item.misNo"-->
+<!--                      class="quick-select-item"-->
+<!--                      @click="handleMisNoQuickSelect(item)">-->
+<!--                    <span class="mis-no">{{ item.misNo }}</span>-->
+<!--                    &lt;!&ndash;                    <span class="mis-info">&ndash;&gt;-->
+<!--                    &lt;!&ndash;                    <span class="device">{{ item.pcsDeviceName }}</span>&ndash;&gt;-->
+<!--                    &lt;!&ndash;                    <span class="station">{{ item.pcsStationName }}</span>&ndash;&gt;-->
+<!--                    &lt;!&ndash;                    </span>&ndash;&gt;-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--                <div class="quick-select-dropdown no-data" v-show="showMisNoQuickSelect && quickMisNoList.length === 0 && form.misNo">-->
+<!--                  <div>未找到匹配的MIS工单</div>-->
+<!--                </div>-->
+<!--              </el-form-item>-->
+<!--            </el-col>-->
+<!--            <el-col :span="12" v-if="form.infoEntry == 2">-->
+<!--              <el-form-item label="工作票编号" prop="workPermitNum">-->
+<!--                <el-input v-model="workPermitNumProxy"  maxlength="20" show-word-limit />-->
+<!--              </el-form-item>-->
+<!--            </el-col>-->
+<!--          </el-row>-->
+
+          <el-row :gutter="20">
+            <el-col :span="24">
+              <el-form-item label="维保内容" prop="content">
+                <el-input v-model="form.content" type="textarea" :rows="3" maxlength="500" show-word-limit />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+<!--          <el-button type="primary" @click="submitAccept">确 认</el-button>-->
+          <el-button @click="open = false">取 消</el-button>
+          <el-button type="primary" @click="submitForm('to_issue')" v-if="optType == 'add'">保 存</el-button>
+          <el-button type="primary" @click="submitForm('assigned')" v-if="optType == 'add'">保存并下发</el-button>
+          <el-button type="primary" @click="submitForm('assigned')" v-if="optType == 'edit'">确认下发</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 补录对话框 -->
+    <el-dialog :title="title" v-model="backfillDialogVisible" width="800px" append-to-body>
       <div style="max-height: 500px; overflow-y: auto; padding-right: 10px;">
         <el-form ref="orderRef" :model="form" :rules="rules" label-width="120px" label-position="top">
           <el-row :gutter="20">
@@ -398,7 +555,7 @@
                 </div>
               </el-form-item>
             </el-col>
-            <el-col :span="12" v-if="form.infoEntry == 2">
+            <el-col :span="12">
               <el-form-item label="工作票编号" prop="workPermitNum">
                 <el-input v-model="workPermitNumProxy"  maxlength="20" show-word-limit />
               </el-form-item>
@@ -412,26 +569,12 @@
               </el-form-item>
             </el-col>
           </el-row>
-<!--          <el-row :gutter="20">-->
-<!--            <el-col :span="24">-->
-<!--              <el-form-item label="工作负责人" prop="teamLeaderId">-->
-<!--                <el-select v-model="acceptForm.teamLeaderId" placeholder="请选择工作负责人" style="width: 100%" @change="(userId) => acceptForm.teamLeaderName = userList.find(u => u.userId === userId)?.nickName">-->
-<!--                  <el-option-->
-<!--                      v-for="user in userList"-->
-<!--                      :key="user.userId"-->
-<!--                      :label="user.nickName"-->
-<!--                      :value="user.userId"-->
-<!--                  />-->
-<!--                </el-select>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
         </el-form>
       </div>
       <template #footer>
         <div class="dialog-footer">
-<!--          <el-button type="primary" @click="submitAccept">确 认</el-button>-->
-          <el-button @click="open = false">取 消</el-button>
+          <!--          <el-button type="primary" @click="submitAccept">确 认</el-button>-->
+          <el-button @click="backfillDialogVisible = false">取 消</el-button>
           <el-button type="primary" @click="submitForm('to_issue')" v-if="optType == 'add'">保 存</el-button>
           <el-button type="primary" @click="submitForm('assigned')" v-if="optType == 'add'">保存并下发</el-button>
           <el-button type="primary" @click="submitForm('assigned')" v-if="optType == 'edit'">确认下发</el-button>
@@ -439,60 +582,6 @@
       </template>
     </el-dialog>
 
-<!--    &lt;!&ndash; 挂起对话框 &ndash;&gt;-->
-<!--    <el-dialog title="申请挂起工单" v-model="suspendDialogVisible" width="800px" append-to-body>-->
-<!--      <el-form ref="suspendRef" :model="suspendForm" :rules="suspendRules" label-width="120px" label-position="top">-->
-<!--        <el-row style="margin-bottom: 20px;">-->
-<!--          <el-col :span="24">-->
-<!--            <el-alert type="warning" :closable="false">-->
-<!--              <template #default>-->
-<!--                <i class="fa fa-exclamation-circle mr-2"></i>-->
-<!--                请选择挂起原因,提交后需等待班长审批。-->
-<!--              </template>-->
-<!--            </el-alert>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-<!--        <el-row>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="工单编码">-->
-<!--              <el-input v-model="suspendForm.workOrderProjectNo" disabled />-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="风机编号">-->
-<!--              <el-input v-model="suspendForm.pcsDeviceName" disabled />-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-<!--        <el-row v-if="suspendForm.content">-->
-<!--          <el-col :span="24">-->
-<!--            <el-form-item label="维保内容" prop="content">-->
-<!--              <el-input v-model="suspendForm.content" type="textarea" :rows="3" disabled />-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-<!--        <el-row>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="挂起原因" prop="suspendReason">-->
-<!--              <el-select v-model="suspendForm.suspendReason" placeholder="请选择挂起原因" style="width: 100%">-->
-<!--                <el-option-->
-<!--                    v-for="dict in gxt_order_suspend_reason"-->
-<!--                    :key="dict.value"-->
-<!--                    :label="dict.label"-->
-<!--                    :value="dict.value"-->
-<!--                />-->
-<!--              </el-select>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-<!--      </el-form>-->
-<!--      <template #footer>-->
-<!--        <div class="dialog-footer">-->
-<!--          <el-button @click="suspendDialogVisible = false">取 消</el-button>-->
-<!--          <el-button type="primary" @click="submitSuspend">提交申请</el-button>-->
-<!--        </div>-->
-<!--      </template>-->
-<!--    </el-dialog>-->
     <!-- 接单对话框 -->
     <el-dialog :title="'接单'" v-model="acceptDialogVisible" width="800px" append-to-body>
 <!--      <div style="max-height: 500px; overflow-y: auto; padding-right: 10px;">-->
@@ -678,7 +767,26 @@
       :list-user-data="listUserData"
       :on-submit="submitFinishFromParent"
       @success="handleFinishSuccess"
-    />
+      @select-mis-info="handleSelectMisInfo2"
+    >
+      <template #mis-info-select>
+        <MisInfoSelectSingle :key="commonKey" v-model="misInfoSelectVisible2" @onSelected="onMisInfoSelected2" :pcsStationName="finishForm.pcsStationName" :pcsDeviceName="finishForm.pcsDeviceName"></MisInfoSelectSingle>
+      </template>
+    </FinalizeDialog>
+
+    <!-- 补录结单对话框组件 -->
+    <BackfillFinalizeDialog
+        v-model="backfillFinishDialogVisible"
+        :data="finishForm"
+        :work-order-status-options="gxt_work_order_status"
+        :list-user-data="listUserData"
+        :on-submit="submitFinishFromParent"
+        @success="handleFinishSuccess"
+    >
+<!--      <template #mis-info-select>-->
+<!--        <MisInfoSelectSingle :key="commonKey" v-model="misInfoSelectVisible" @onSelected="onMisInfoSelected" :pcsStationName="finishForm.pcsStationName" :pcsDeviceName="finishForm.pcsDeviceName"></MisInfoSelectSingle>-->
+<!--      </template>-->
+    </BackfillFinalizeDialog>
 
     <!-- 维保挂起对话框 -->
     <SuspendDialog
@@ -762,59 +870,6 @@
                 <el-input v-model="restartForm.workPermitNum" disabled />
               </el-form-item>
             </el-col>
-<!--          </el-row>-->
-          <!-- 处理信息 -->
-<!--          <h4 class="text-sm font-medium text-gray-800 mb-3">处理信息</h4>-->
-<!--          <el-row>-->
-<!--            <el-col :span="12">-->
-<!--              <el-form-item label="工作负责人">-->
-<!--                <el-input v-model="restartForm.teamLeaderName" disabled />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--            <el-col :span="12">-->
-<!--              <el-form-item label="检修人员">-->
-<!--                <el-input v-model="restartForm.workGroupMemberName" disabled />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-          <!-- 维保内容 -->
-<!--          <el-row>-->
-<!--            <el-col :span="24">-->
-<!--              <el-form-item label="维保内容">-->
-<!--                <el-input v-model="restartForm.content" type="textarea" :rows="3" disabled />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-<!--          <el-row>-->
-<!--            <el-col :span="24">-->
-<!--              <el-form-item label="实际维保内容">-->
-<!--                <el-input v-model="restartForm.realContent" type="textarea" :rows="3" disabled />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-<!--          <el-row>-->
-<!--            <el-col :span="24">-->
-<!--              <el-form-item label="附件">-->
-<!--                <preview :limit="8" v-model="restartForm.attachmentUrls" :filesize="5" disabled></preview>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-<!--          <el-row>-->
-<!--            <el-col :span="12">-->
-<!--              <el-form-item label="评分" prop="score">-->
-<!--                <el-input v-model="restartForm.score" disabled />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-<!--          <el-row>-->
-<!--            <el-col :span="24">-->
-<!--              <el-form-item label="点评" prop="reviewContent">-->
-<!--                <el-input v-model="restartForm.reviewContent" disabled />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-          <!-- 复运信息 -->
-<!--          <el-row>-->
             <el-col :span="12">
               <el-form-item label="恢复运行时间" prop="restartTime">
                 <el-date-picker
@@ -939,13 +994,6 @@
               </el-form-item>
             </el-col>
           </el-row>
-<!--          <el-row :gutter="20">-->
-<!--            <el-col :span="24">-->
-<!--              <el-form-item label="实际维保内容">-->
-<!--                <el-input v-model="rateForm.realContent" type="textarea" :rows="3" disabled />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
           <el-row>
             <el-col :span="24">
               <el-form-item label="附件">
@@ -1009,6 +1057,14 @@
         @success="handleApproveSuccess"
     />
 
+    <!-- 停机对话框组件 -->
+    <ShutdownDialog
+        v-model="shutdownDialogVisible"
+        :data="shutdownForm"
+        :on-submit="submitShutdownFormParent"
+        @success="handleShutdownSuccess"
+    />
+
     <!-- 流转记录对话框 -->
     <el-dialog title="工单流转记录" v-model="flowDialogVisible" width="900px" append-to-body>
       <el-timeline>
@@ -1034,148 +1090,8 @@
         :data="detailData"
         :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"
     />
-<!--    <el-dialog title="查看工单详情" v-model="detailDialogVisible" width="1000px" append-to-body>-->
-<!--      <el-row :gutter="20">-->
-<!--        &lt;!&ndash; 工单信息 &ndash;&gt;-->
-<!--        <el-col :span="8">-->
-<!--          <div class="info-section">-->
-<!--            <h3 class="section-title">工单信息</h3>-->
-<!--            <div class="info-content">-->
-<!--              <el-form label-width="100px" label-position="top">-->
-<!--                <el-row :gutter="20">-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="工单编码">{{ detailData.workOrderProjectNo || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="工单状态">-->
-<!--                      <dict-tag :options="gxt_work_order_status" :value="detailData.workOrderStatus" />-->
-<!--                    </el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="风机编号">{{ detailData.pcsDeviceName || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="维保中心">{{ detailData.gxtCenter || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="场站">{{ detailData.pcsStationName || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="品牌">{{ detailData.brand || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="机型">{{ detailData.model || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-
-<!--&lt;!&ndash;                  <el-col :span="24">&ndash;&gt;-->
-<!--&lt;!&ndash;                    <el-form-item label="维保内容">{{ detailData.content || '-' }}</el-form-item>&ndash;&gt;-->
-<!--&lt;!&ndash;                  </el-col>&ndash;&gt;-->
-<!--                </el-row>-->
-<!--              </el-form>-->
-<!--            </div>-->
-<!--          </div>-->
-<!--        </el-col>-->
-
-<!--        &lt;!&ndash; 处理信息 &ndash;&gt;-->
-<!--        <el-col :span="8">-->
-<!--          <div class="info-section">-->
-<!--            <h3 class="section-title">处理信息</h3>-->
-<!--            <div class="info-content">-->
-<!--              <el-form label-width="100px" label-position="top">-->
-<!--                <el-row :gutter="20">-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="接单人">{{ detailData.acceptUserName || '-'}}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="接单时间">{{ parseTime(detailData.acceptTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="工作负责人">{{ detailData.teamLeaderName || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="检修人员">{{ detailData.workGroupMemberName || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24" v-if="detailData.infoEntry == '1'">-->
-<!--                    <el-form-item label="MIS工单编码">{{ detailData.misNo || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24" v-if="detailData.infoEntry == '2'">-->
-<!--                    <el-form-item label="工作票编号">{{ detailData.workPermitNum|| '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="开始时间">{{ parseTime(detailData.realStartTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="结束时间">{{ parseTime(detailData.realEndTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="外委人员数(人)">{{ detailData.wwryNum || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="外来人员数(人)">{{ detailData.wlryNum || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="恢复运行时间">{{ parseTime(detailData.restartTime,'{y}-{m}-{d} {h}:{i}') || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="24">-->
-<!--                    <el-form-item label="损失电量(kWh)">{{ detailData.lostPower || '-' }}</el-form-item>-->
-<!--                  </el-col>-->
-<!--                </el-row>-->
-<!--              </el-form>-->
-<!--            </div>-->
-<!--          </div>-->
-<!--        </el-col>-->
-
-<!--        &lt;!&ndash; 工单流转记录 &ndash;&gt;-->
-<!--        <el-col :span="8">-->
-<!--          <div class="info-section">-->
-<!--            <h3 class="section-title">工单流转</h3>-->
-<!--            <div class="flow-history">-->
-<!--              <el-timeline>-->
-<!--                <el-timeline-item type="primary"-->
-<!--                                  v-for="(flow, index) in flowList"-->
-<!--                                  :key="index"-->
-<!--                                  :timestamp="parseTime(flow.actionTime, '{y}-{m}-{d} {h}:{i}')"-->
-<!--                >-->
-<!--                  <div class="flow-item">-->
-<!--                    <h4><dict-tag :options="gxt_repair_order_flow_action_type" :value="flow.actionType" /></h4>-->
-<!--                    <p>-->
-<!--                      &lt;!&ndash;                      {{ flow.actionRemark }}<br>&ndash;&gt;-->
-<!--                      {{ flow.operatorName }}-->
-<!--                    </p>-->
-<!--                  </div>-->
-<!--                </el-timeline-item>-->
-<!--              </el-timeline>-->
-<!--            </div>-->
-<!--          </div>-->
-<!--        </el-col>-->
-<!--      </el-row>-->
-<!--      <el-form label-position="top">-->
-<!--        <el-row>-->
-<!--          <el-col :span="24">-->
-<!--            <el-form-item label="维保内容">-->
-<!--              <div class="content-text">{{ detailData.content || '-' }}</div>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-<!--      </el-form>-->
-<!--      &lt;!&ndash; 附件信息 &ndash;&gt;-->
-<!--      <div class="info-section" v-if="detailData.attachmentUrls">-->
-<!--        <h3 class="section-title">结单附件</h3>-->
-<!--        <el-row>-->
-<!--          <el-col :span="24">-->
-<!--            <el-form-item label="附件">-->
-<!--              <preview :limit="8" v-model="detailData.attachmentUrls" :filesize="5" disabled></preview>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-<!--      </div>-->
-<!--      <template #footer>-->
-<!--        <div class="dialog-footer">-->
-<!--          <el-button @click="detailDialogVisible = false">关 闭</el-button>-->
-<!--        </div>-->
-<!--      </template>-->
-<!--    </el-dialog>-->
 
     <!-- 作废工单对话框 -->
     <el-dialog title="作废工单" v-model="invalidateDialogVisible" width="800px" append-to-body>
@@ -1313,7 +1229,7 @@ import {
   importGxtWorkOrderPersonFromExcel,
   // importTemplate
   invalidateGxtOrder,
-  getExportFields
+  getExportFields, shutdownOrder
 } from "@/api/gxt/gxtOrder"
 import {listUserData, listUserNoPermi, listLeader} from "@/api/system/user"
 import {getToken} from "@/utils/auth.js";
@@ -1328,6 +1244,8 @@ import useUserStore from '@/store/modules/user'
 import SuspendDialog from "@/components/gxtOrder/suspend.vue";
 import ViewDialog from "@/components/gxtOrder/view.vue";
 import ApproveDialog from "@/components/gxtOrder/approve.vue";
+import ShutdownDialog from "@/components/gxtOrder/shutdown.vue";
+import BackfillFinalizeDialog from '@/components/gxtOrder/backfillFinalize.vue'
 
 // 工作负责人快速检索相关响应式数据
 const showTeamLeaderQuickSelect = ref(false)
@@ -1561,13 +1479,14 @@ const handleMisNoQuickSelect = (item) => {
 const handleMisNoClear = () => {
   // 清空与MIS工单相关的字段
   form.value.misNo = null
-  form.value.pcsDeviceName = null
-  form.value.pcsStationName = null
   form.value.content = null
-  form.value.pcsDeviceId = null
-  form.value.gxtCenter = null
-  form.value.brand = null
-  form.value.model = null
+  form.value.workPermitNum = null
+  // form.value.pcsDeviceName = null
+  // form.value.pcsStationName = null
+  // form.value.pcsDeviceId = null
+  // form.value.gxtCenter = null
+  // form.value.brand = null
+  // form.value.model = null
   quickMisNoList.value = []
   showMisNoQuickSelect.value = false
 }
@@ -1612,6 +1531,9 @@ const acceptDialogVisible = ref(false)
 const restartDialogVisible = ref(false)
 const equipmentSelectVisible = ref(false)
 const invalidateDialogVisible = ref(false)
+const shutdownDialogVisible = ref(false)
+const backfillDialogVisible = ref(false)
+const backfillFinishDialogVisible = ref(false)
 const userList = ref([])
 const flowList = ref([])
 const detailData = ref({})
@@ -1623,6 +1545,7 @@ const fileUploadRef = ref(null)
 
 const tableHeight = ref(window.innerHeight - 300)
 const misInfoSelectVisible = ref(false)
+const misInfoSelectVisible2 = ref(false)
 let commonKey = 0
 const optType = ref("")
 
@@ -1670,9 +1593,11 @@ const data = reactive({
     orderSource: undefined
   },
   rules: {
+
     // workOrderProjectNo: [{ required: true, message: "工单编码不能为空", trigger: "blur" }],
     misNo: [{ required: true, message: "MIS编码不能为空", trigger: "change" }],
     pcsDeviceName: [{ required: true, message: "风机编号不能为空", trigger: "change" }],
+    inspectionType: [{ required: true, message: "维保类型不能为空", trigger: "change" }],
     // workOrderStatus: [{ required: true, message: "工单状态不能为空", trigger: "change" }],
     // gxtCenter: [{ required: true, message: "维保中心不能为空", trigger: "blur" }],
     // pcsStationName: [{ required: true, message: "风电场不能为空", trigger: "blur" }],
@@ -1722,22 +1647,22 @@ const data = reactive({
     ],    // 动态控制 content 是否必填
     content: [
       { required: true, message: "维保内容不能为空", trigger: "change" },
-      {
-        validator: (rule, value, callback) => {
-          // 当 infoEntry == 2 时才校验必填
-          if (form.value.infoEntry == '2') {
-            if (!value || value.trim() === '') {
-              callback(new Error('维保内容不能为空'));
-            } else {
-              callback();
-            }
-          } else {
-            // 不是 infoEntry=2 时,不校验,直接通过
-            callback();
-          }
-        },
-        trigger: 'blur'
-      }
+      // {
+      //   validator: (rule, value, callback) => {
+      //     // 当 infoEntry == 2 时才校验必填
+      //     if (form.value.infoEntry == '2') {
+      //       if (!value || value.trim() === '') {
+      //         callback(new Error('维保内容不能为空'));
+      //       } else {
+      //         callback();
+      //       }
+      //     } else {
+      //       // 不是 infoEntry=2 时,不校验,直接通过
+      //       callback();
+      //     }
+      //   },
+      //   trigger: 'blur'
+      // }
     ]
   },
   assignForm: {
@@ -1841,6 +1766,8 @@ const data = reactive({
     workOrderStatus: 'suspended',
     rejectionReason: undefined
   },
+  shutdownForm: {
+  },
   rateRules: {
     score: [{ required: true, message: "请选择评分", trigger: "change" }],
     reviewContent: [{ required: false, message: "请输入点评", trigger: "blur" }]
@@ -2000,7 +1927,7 @@ const exportFieldsData = ref([])
 const exportFieldsSelected = ref([])
 
 const { queryParams, form, rules, assignForm, assignRules, suspendForm, suspendRules, pauseForm, pauseRules, startForm,
-  resumeForm, completeForm, finishForm, rateForm, rateRules, approveForm, approveRules, acceptForm, acceptRules, finishRules, restartForm, restartRules, invalidateForm, invalidateRules } = toRefs(data)
+  resumeForm, completeForm, finishForm, rateForm, rateRules, approveForm, approveRules, acceptForm, acceptRules, finishRules, restartForm, restartRules, invalidateForm, invalidateRules, shutdownForm } = toRefs(data)
 
 onMounted(() => {
   getList()
@@ -2096,20 +2023,39 @@ function handleSelectionChange(selection) {
 /** 新增按钮操作 */
 function handleAdd() {
   reset()
-  form.value.infoEntry = "1"
+  // form.value.infoEntry = "1"
   open.value = true
   title.value = "新建维保工单"
   optType.value = "add"
   commonKey++
 }
 
+/**
+ *
+ *
+ * 补录按钮操作
+ */
+function handleBackFilling() {
+  reset()
+  form.value.infoEntry = "1"
+  form.value.orderEntryType = "2"
+  backfillDialogVisible.value = true
+  title.value = "补录维保工单"
+  optType.value = "add"
+  commonKey++
+}
+
 /** 修改按钮操作 */
 function handleUpdate(row) {
   reset()
   const id = row.id || ids.value
   getGxtOrder(id).then(response => {
     form.value = response.data
-    open.value = true
+    if (form.value.orderEntryType == '2') {
+      backfillDialogVisible.value = true
+    } else {
+      open.value = true
+    }
     title.value = "下发"
     optType.value = "edit"
     commonKey++
@@ -2121,16 +2067,20 @@ function submitForm(status) {
   proxy.$refs["orderRef"].validate(valid => {
     if (valid) {
       form.value.workOrderStatus = status
+      form.value.inspectionType = Array.isArray(form.value.inspectionType) ? form.value.inspectionType.join(',')
+          : form.value.inspectionType || ''
       if (form.value.id != undefined) {
         updateGxtOrder(form.value).then(response => {
           proxy.$modal.msgSuccess("下发成功")
           open.value = false
+          backfillDialogVisible.value = false
           getList()
         })
       } else {
         addGxtOrder(form.value).then(response => {
           proxy.$modal.msgSuccess("新建成功")
           open.value = false
+          backfillDialogVisible.value = false
           getList()
         })
       }
@@ -2190,6 +2140,7 @@ function handleFinish(row) {
   getGxtOrder(row.id).then(response => {
     finishForm.value = response.data
     finishForm.value.orderId = row.id
+    finishForm.value.infoEntry = '1'
     if (finishForm.value.infoEntry != null && finishForm.value.infoEntry == '1') {
       if (row.misNo != null) {
         listMisInfo({misNo: row.misNo}).then(response => {
@@ -2223,6 +2174,42 @@ function handleFinish(row) {
   })
 }
 
+function handleBackfillingFinish(row) {
+  getGxtOrder(row.id).then(response => {
+    finishForm.value = response.data
+    finishForm.value.orderId = row.id
+    if (finishForm.value.infoEntry != null && finishForm.value.infoEntry == '1') {
+      if (row.misNo != null) {
+        listMisInfo({misNo: row.misNo}).then(response => {
+          const misInfo = response.rows
+          if (misInfo.length > 0) {
+            finishForm.value.realStartTime = misInfo[0].realStartTime
+            finishForm.value.realEndTime = misInfo[0].realEndTime
+          }
+        })
+      }
+      listWorkPerson({misNo: row.misNo}).then(response => {
+        finishForm.value.workOrderPersonList = response.rows;
+        if (finishForm.value.workOrderPersonList) {
+          const nickNames = finishForm.value.workOrderPersonList
+              .map(person => person.nickName)
+              .join(',');
+          finishForm.value.workGroupMemberName = nickNames
+          backfillFinishDialogVisible.value = true
+        }
+      })
+    } else {
+      finishForm.value.realStartTime = null
+      finishForm.value.realEndTime = null
+      backfillFinishDialogVisible.value = true
+    }
+    // 打开对话框后重置表单验证错误
+    proxy.$nextTick(() => {
+      proxy.$refs["finishRef"]?.clearValidate()
+    })
+  })
+}
+
 /** 提交结单 */
 function submitFinish() {
   proxy.$refs["finishRef"].validate(valid => {
@@ -2259,6 +2246,7 @@ async function submitFinishFromParent(data) {
 // 在提交结单成功后的回调函数
 function handleFinishSuccess() {
   finishDialogVisible.value = false
+  backfillFinishDialogVisible.value = false
   getList()
 }
 
@@ -2278,13 +2266,14 @@ async function submitApproveFromParent(data) {
   await approveWorkOrder(data.id, data)
 }
 
+
 // 在提交审批成功后的回调函数
 function handleApproveSuccess() {
   approveDialogVisible.value = false
   getList()
 }
 
-/** 复运 */
+// 复运
 function handleRestart(row) {
   getGxtOrder(row.id).then(response => {
     restartForm.value = response.data
@@ -2295,6 +2284,28 @@ function handleRestart(row) {
   })
 }
 
+/** 停机 */
+function handleShutdown(row) {
+  getGxtOrder(row.id).then(response => {
+    shutdownForm.value = response.data
+    shutdownForm.value.orderId = row.id
+    shutdownDialogVisible.value = true
+    // 打开对话框后重置表单验证错误
+    proxy.resetForm("shutdownRef")
+  })
+}
+
+// 提交停机
+async function submitShutdownFormParent(data) {
+  await shutdownOrder(data)
+}
+
+// 在提交停机成功后的回调函数
+function handleShutdownSuccess() {
+  shutdownDialogVisible.value = false
+  getList()
+}
+
 /** 提交评分 */
 function submitRate() {
   proxy.$refs["rateRef"].validate(valid => {
@@ -2798,12 +2809,17 @@ function handleSelectMisInfo() {
   misInfoSelectVisible.value = true
 }
 
+function handleSelectMisInfo2() {
+  misInfoSelectVisible2.value = true
+}
+
 /** 设备MIS信息回调 */
 function onMisInfoSelected(row) {
   if (row) {
     listGxtOrder({pageNum: 1, pageSize: 10, misNo: row.misNo }).then(response => {
       const  gxtOrders= response.rows
       debugger
+      const targetForm = isForFinishForm ? finishForm : form; // 确定赋值目标
       if (gxtOrders.length > 0) {
         if (form.value.id == null) {
           proxy.$modal.msgWarning('选择工单已存在!请重新选择!')
@@ -2819,8 +2835,9 @@ function onMisInfoSelected(row) {
       form.value.content = row.content
       form.value.realStartTime = row.realStartTime
       form.value.realEndTime = row.realEndTime
-      form.value.planStartTime = row.planStartTime
-      form.value.planEndTime = row.planEndTime
+      form.value.workPermitNum = row.workPermitNum
+      // form.value.planStartTime = row.planStartTime
+      // form.value.planEndTime = row.planEndTime
       if (!form.value.pcsDeviceId) {
         form.value.pcsDeviceName = row.pcsDeviceName
         form.value.pcsStationName = row.pcsStationName
@@ -2839,6 +2856,32 @@ function onMisInfoSelected(row) {
   }
 }
 
+function onMisInfoSelected2(row) {
+  if (row) {
+    listGxtOrder({pageNum: 1, pageSize: 10, misNo: row.misNo }).then(response => {
+      const  gxtOrders= response.rows
+      debugger
+      if (gxtOrders.length > 0) {
+        if (finishForm.value.id == null) {
+          proxy.$modal.msgWarning('选择工单已存在!请重新选择!')
+          return
+        } else {
+          if (gxtOrders[0].id != form.value.id) {
+            proxy.$modal.msgWarning('选择工单已存在!请重新选择!')
+            return
+          }
+        }
+      }
+      finishForm.value.misNo = row.misNo
+      finishForm.value.content = row.content
+      finishForm.value.realStartTime = row.realStartTime
+      finishForm.value.realEndTime = row.realEndTime
+      finishForm.value.workPermitNum = row.workPermitNum
+      misInfoSelectVisible2.value = false
+    })
+  }
+}
+
 //自动编码生成
 function handleAutoGenChange(){
   genPostCode('WORK_ORDER_CODE', form.value).then(response =>{

+ 8 - 7
ygtx-ui/src/views/gxt/orderMyTodo/index.vue

@@ -174,13 +174,13 @@
                 @click="handleRepairSuspend(scope.row)"
                 v-hasPermi="['gxt:repairOrder:suspend']"
             ><i class="fa fa-stop"></i>挂起</el-button>
-            <el-button
-                v-if="(scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
-                type="warning"
-                link
-                @click="handleReturn(scope.row)"
-                v-hasPermi="['gxt:repairOrder:return']"
-            ><i class="fa fa-sign-in"></i>退回</el-button> <!--结单退回,负责人退回至班长 -->
+<!--            <el-button-->
+<!--                v-if="(scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"-->
+<!--                type="warning"-->
+<!--                link-->
+<!--                @click="handleReturn(scope.row)"-->
+<!--                v-hasPermi="['gxt:repairOrder:return']"-->
+<!--            ><i class="fa fa-sign-in"></i>退回</el-button> &lt;!&ndash;结单退回,负责人退回至班长 &ndash;&gt;-->
             <el-button
                 v-if="scope.row.workOrderStatus === 'return'|| scope.row.workOrderStatus === 'assigned'"
                 type="warning"
@@ -305,6 +305,7 @@
         :data="detailData"
         :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"
     />
 
     <!-- 接单对话框 (维修工单) -->

+ 7 - 150
ygtx-ui/src/views/gxt/repairOrder/index.vue

@@ -295,13 +295,13 @@
               @click="handleSuspend(scope.row)"
               v-hasPermi="['gxt:repairOrder:suspend']"
           ><i class="fa fa-stop"></i>挂起</el-button>
-          <el-button
-              v-if="scope.row.workOrderStatus === 'to_finish'&& (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
-              type="warning"
-              link
-              @click="handleReturn(scope.row)"
-              v-hasPermi="['gxt:repairOrder:return']"
-          ><i class="fa fa-sign-in"></i>退回</el-button> <!--结单退回,负责人退回至班长 -->
+<!--          <el-button-->
+<!--              v-if="scope.row.workOrderStatus === 'to_finish'&& (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"-->
+<!--              type="warning"-->
+<!--              link-->
+<!--              @click="handleReturn(scope.row)"-->
+<!--              v-hasPermi="['gxt:repairOrder:return']"-->
+<!--          ><i class="fa fa-sign-in"></i>退回</el-button> &lt;!&ndash;结单退回,负责人退回至班长 &ndash;&gt;-->
           <el-button
               v-if="scope.row.workOrderStatus === 'return'|| scope.row.workOrderStatus === 'assigned'"
               type="warning"
@@ -740,69 +740,6 @@
       </template>
     </el-dialog>
 
-    <!-- 挂起对话框 -->
-<!--    <el-dialog title="申请挂起工单" v-model="suspendDialogVisible" width="800px" append-to-body @close="closeSuspendDialog">-->
-<!--      <el-form ref="suspendFormRef" :model="suspendForm" :rules="suspendRules" label-width="120px" label-position="top">-->
-<!--        <el-alert type="warning" :closable="false" title="请选择挂起原因,提交后需等待班长审批。" show-icon />-->
-<!--        <el-row>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="工单编码">-->
-<!--              <el-input v-model="suspendForm.workOrderProjectNo" disabled />-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="风机编号">-->
-<!--              <el-input v-model="suspendForm.pcsDeviceName" disabled />-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="24" v-if="suspendForm.faultBarcode">-->
-<!--            <el-form-item label="故障信息">-->
-<!--              <el-input v-model="suspendForm.faultBarcode" type="textarea" :rows="3" disabled />-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--&lt;!&ndash;            <el-form-item label="挂起原因" prop="suspendReason">-->
-<!--              <el-input-->
-<!--                  v-model="suspendForm.suspendReason"-->
-<!--                  type="textarea"-->
-<!--                  placeholder="请输入挂起原因"-->
-<!--                  maxlength="100"-->
-<!--                  show-word-limit-->
-<!--                  :rows="3"-->
-<!--              />-->
-<!--            </el-form-item>&ndash;&gt;-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="挂起原因" prop="suspendReason">-->
-<!--              <el-select v-model="suspendForm.suspendReason" placeholder="请选择挂起原因" style="width: 100%">-->
-<!--                <el-option-->
-<!--                    v-for="dict in gxt_order_suspend_reason"-->
-<!--                    :key="dict.value"-->
-<!--                    :label="dict.label"-->
-<!--                    :value="dict.value"-->
-<!--                />-->
-<!--              </el-select>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-<!--        &lt;!&ndash;-->
-<!--                <el-form-item label="详细说明" prop="suspendDescription">-->
-<!--                  <el-input-->
-<!--                    v-model="suspendForm.suspendDescription"-->
-<!--                    type="textarea"-->
-<!--                    placeholder="请输入详细说明"-->
-<!--                    maxlength="100"-->
-<!--                    show-word-limit-->
-<!--                    :rows="3"-->
-<!--                  />-->
-<!--                </el-form-item>&ndash;&gt;-->
-<!--      </el-form>-->
-<!--      <template #footer>-->
-<!--        <div class="dialog-footer">-->
-<!--          <el-button @click="closeSuspendDialog">取 消</el-button>-->
-<!--          <el-button type="primary" @click="submitSuspend">提交申请</el-button>-->
-<!--        </div>-->
-<!--      </template>-->
-<!--    </el-dialog>-->
-
     <!-- 结单对话框组件 -->
     <FinalizeDialog
       v-model="finalizeDialogVisible"
@@ -1158,86 +1095,6 @@
       </template>
     </el-dialog>
 
-    <!-- 审批对话框 -->
-<!--    <el-dialog title="退回" v-model="returnDialogVisible" width="800px" append-to-body @close="closeReturnDialog">-->
-<!--      <el-alert type="info" :closable="false" style="border-color: #a855f7; background-color: #f8f5ff; color: #6d28d9; height: 35px;">-->
-<!--        <template #default>-->
-<!--          <i class="fa fa-sign-in mr-2" style="color: #6d28d9;"> 请选择退回类型,填写退回原因,完成工单退回。</i>-->
-<!--        </template>-->
-<!--      </el-alert>-->
-<!--      &lt;!&ndash; 工单信息 &ndash;&gt;-->
-<!--      <h3 class="text-sm font-medium text-gray-800 mb-3"></h3>-->
-<!--      <el-form ref="returnFormRef" :model="returnForm" :rules="returnRules" label-width="120px" label-position="top">-->
-<!--        <el-row>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="工单编码"><el-input v-model="returnForm.workOrderProjectNo" disabled /></el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="风机编号"><el-input v-model="returnForm.pcsDeviceName" disabled /> </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="工单状态">-->
-<!--              <el-select v-model="returnForm.workOrderStatus" style="width: 100%" disabled>-->
-<!--                <el-option-->
-<!--                    v-for="dict in gxt_work_order_status"-->
-<!--                    :key="dict.value"-->
-<!--                    :label="dict.label"-->
-<!--                    :value="dict.value"-->
-<!--                />-->
-<!--              </el-select>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="维保中心"><el-input v-model="returnForm.gxtCenter" disabled /> </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="场站"><el-input v-model="returnForm.pcsStationName" disabled /> </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="品牌"><el-input v-model="returnForm.brand" disabled /> </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="工作负责人"><el-input v-model="returnForm.teamLeaderName" disabled /> </el-form-item>-->
-<!--          </el-col>-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="退回类型" prop="returnType">-->
-<!--              <el-select v-model="returnForm.returnType" style="width: 100%" :disabled="returnForm.workOrderStatus === 'return'">-->
-<!--                <el-option-->
-<!--                    v-for="dict in gxt_return_type"-->
-<!--                    :key="dict.value"-->
-<!--                    :label="dict.label"-->
-<!--                    :value="dict.value"-->
-<!--                />-->
-<!--              </el-select>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-<!--        &lt;!&ndash;        <el-form-item label="审批决定" prop="approvalStatus">-->
-<!--                  <el-radio-group v-model="returnForm.approvalStatus" @change="toggleRejectionReason">-->
-<!--                    <el-radio label="approved">通过</el-radio>-->
-<!--                    <el-radio label="rejected">驳回</el-radio>-->
-<!--                  </el-radio-group>-->
-<!--                </el-form-item>&ndash;&gt;-->
-<!--        <el-form-item label="退回原因" prop="returnReason">-->
-<!--          <el-input-->
-<!--              v-model="returnForm.returnReason"-->
-<!--              type="textarea"-->
-<!--              placeholder="请输入退回原因"-->
-<!--              maxlength="100"-->
-<!--              show-word-limit-->
-<!--              :rows="3"-->
-<!--              :disabled="returnForm.workOrderStatus === 'return'"-->
-<!--          />-->
-<!--        </el-form-item>-->
-<!--      </el-form>-->
-<!--      <template #footer>-->
-<!--        <div class="dialog-footer">-->
-<!--          <el-button @click="closeReturnDialog">取 消</el-button>-->
-<!--          <el-button type="primary" @click="submitReturn()">退 回</el-button>-->
-<!--        </div>-->
-<!--      </template>-->
-<!--    </el-dialog>-->
-
     <!-- 查看工单详情对话框 -->
     <ViewDialog
         v-model="viewDialogVisible"