Explorar el Código

维保结单组件

HD_wangm hace 4 meses
padre
commit
9d704172cc

+ 438 - 0
ygtx-ui/src/components/gxtOrder/finalize.vue

@@ -0,0 +1,438 @@
+<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%"
+              :readonly="formData.infoEntry == '1'"
+              :disabled-date="disabledStartDate"
+            />
+          </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%"
+              :readonly="formData.infoEntry == '1'"
+              :disabled-date="disabledEndDate"
+            />
+          </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="24">
+          <el-form-item label="检修人员" prop="workGroupMemberName">
+            <el-input
+              v-model="formData.workGroupMemberName"
+              maxlength="200"
+              show-word-limit
+              :readonly="formData.infoEntry == '1'"
+            />
+          </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>
+</template>
+
+<script setup>
+import { ref, defineProps, defineEmits, getCurrentInstance, watch } from 'vue'
+import preview from '@/components/FileUpload/preview.vue'
+
+// 获取当前实例
+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 finishRules = ref({
+  realStartTime: [
+    { 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.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: "blur" },
+    {
+      validator: async (rule, value, callback) => {
+        // 如果值为空、关联MIS,直接通过验证
+        if (!value || formData.value.infoEntry == '1') {
+          return callback();
+        }
+        try {
+          // 将输入的检修人员姓名按逗号分割
+          const names = value.split(',').map(name => name.trim());
+
+          // 验证每个检修人员是否存在于组织架构中
+          for (const name of names) {
+            if (name.length > 0) {
+              // 使用从属性传入的listUserData方法(如果有的话)
+              if (props.listUserData) {
+                const response = await props.listUserData({nickName: name});
+                if (!response.rows || response.rows.length === 0) {
+                  return callback(new Error(`检修人员"${name}"非系统内人员,请重新输入`));
+                }
+              }
+            } else {
+              return callback(new Error(`请正确输入检修人员名单`));
+            }
+          }
+          callback();
+        } catch (error) {
+          callback(new Error('验证检修人员时发生错误'));
+        }
+      },
+      trigger: 'blur'
+    }
+  ],
+  content: [
+    { required: true, message: "请输入维保内容", trigger: "blur" }
+  ]
+})
+// 时间禁用函数
+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;
+};
+
+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 }
+  }
+})
+
+// 监听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 (finishRef.value) {
+        finishRef.value.clearValidate()
+      }
+    })
+  }
+})
+
+// 关闭对话框
+const handleClose = () => {
+  visible.value = false
+}
+
+// 取消操作
+const handleCancel = () => {
+  visible.value = false
+}
+
+// 提交操作
+const handleSubmit = async () => {
+  if (!finishRef.value) return
+
+  await finishRef.value.validate(async (valid) => {
+    if (valid) {
+      try {
+        if (!formData.value.realEndTime) {
+          proxy.$modal.msgError("该工单未结束,无法结单!")
+          return
+        }
+        submitLoading.value = true
+
+        // 调用父组件传入的提交函数
+        if (props.onSubmit && typeof props.onSubmit === 'function') {
+          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
+      }
+    }
+  })
+}
+</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>

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

@@ -640,7 +640,7 @@ const handleSubmit = async () => {
           throw new Error("未提供提交方法")
         }
 
-        proxy.$modal.msgSuccess("工单结单成功")
+        proxy.$modal.msgSuccess("结单成功")
         visible.value = false
         emit('success')
       } catch (error) {

+ 34 - 227
ygtx-ui/src/views/gxt/gxtOrder/index.vue

@@ -656,223 +656,19 @@
         </div>
       </template>
     </el-dialog>
-    <!-- 结单对话框 -->
-    <el-dialog title="结单" v-model="finishDialogVisible" width="800px" append-to-body>
-      <div class="space-y-4">
-        <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="finishForm" :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="finishForm.workOrderProjectNo" disabled />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="工单状态" prop="workOrderStatus">
-                  <!--                <el-input v-model="finishForm.workOrderStatus" disabled />-->
-                  <el-select v-model="finishForm.workOrderStatus" 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-row>
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="风机编号">
-                  <el-input v-model="finishForm.pcsDeviceName" disabled />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="维保中心">
-                  <el-input v-model="finishForm.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="finishForm.pcsStationName" disabled />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="品牌">
-                  <el-input v-model="finishForm.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="finishForm.model" disabled />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12" v-if="finishForm.infoEntry == '1'">
-                <el-form-item label="MIS工单编码">
-                  <el-input v-model="finishForm.misNo" disabled />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12" v-if="finishForm.infoEntry == '2'">
-                <el-form-item label="工作票编号">
-                  <el-input v-model="finishForm.workPermitNum" disabled />
-                </el-form-item>
-              </el-col>
-            </el-row>
-          <el-row>
-            <el-col :span="12">
-              <el-form-item label="接单人"><el-input v-model="finishForm.acceptUserName" disabled /> </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="接单时间"><el-input v-model="finishForm.acceptTime" disabled /> </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row>
-            <el-col :span="12">
-              <!--            <el-form-item label="开始时间">{{ parseTime(finalizeForm.realStartTime, '{y}-{m}-{d} {h}:{i}') }}</el-form-item>-->
-              <el-form-item label="开始时间" prop="realStartTime">
-                <el-date-picker
-                    v-model="finishForm.realStartTime"
-                    type="datetime"
-                    format="YYYY-MM-DD HH:mm"
-                    value-format="YYYY-MM-DD HH:mm"
-                    placeholder="请选择开始时间"
-                    style="width: 100%"
-                    :readonly="finishForm.infoEntry == '1'"
-                    :disabled-date="disabledStartDate"
-                />
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <!--            <el-form-item label="结束时间">{{ parseTime(finalizeForm.realEndTime, '{y}-{m}-{d} {h}:{i}') }}</el-form-item>-->
-              <el-form-item label="结束时间" prop="realEndTime">
-                <el-date-picker
-                    v-model="finishForm.realEndTime"
-                    type="datetime"
-                    format="YYYY-MM-DD HH:mm"
-                    value-format="YYYY-MM-DD HH:mm"
-                    placeholder="请选择结束时间"
-                    style="width: 100%"
-                    :readonly="finishForm.infoEntry == '1'"
-                    :disabled-date="disabledEndDate"
-                />
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row>
-            <el-col :span="12">
-              <el-form-item label="外委人员数(人)" prop="wwryNum">
-                <el-input-number
-                    v-model="finishForm.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="finishForm.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="finishForm.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="finishForm.teamLeaderName" disabled />
-                </el-form-item>
-              </el-col>
-<!--              <el-col :span="12">-->
-<!--                <el-form-item label="维保类型" prop="inspectionType">-->
-<!--                  <el-select v-model="finishForm.inspectionType" placeholder="请选择维保类型">-->
-<!--                    <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="24">-->
-<!--                <el-form-item label="维保总结" prop="realContent">-->
-<!--                  <el-input v-model="finishForm.realContent"-->
-<!--                    type="textarea"-->
-<!--                    placeholder="请输入点评内容,最多100字"-->
-<!--                    maxlength="100"-->
-<!--                    :rows="3"-->
-<!--                    show-word-limit />-->
-<!--                </el-form-item>-->
-<!--              </el-col>-->
-<!--            </el-row>-->
-            <el-row>
-              <el-col :span="24">
-                <el-form-item label="检修人员" prop="workGroupMemberName">
-                  <el-input v-model="finishForm.workGroupMemberName"
-                            maxlength="200"
-                            show-word-limit
-                            :readonly="finishForm.infoEntry == '1'" />
-                </el-form-item>
-<!--                <el-form-item label="检修人员" prop="memberIds">-->
-<!--                  <el-checkbox-group v-model="finishForm.memberIds" style="width: 100%" @change="handleMembersChange">-->
-<!--                    <el-row :gutter="10">-->
-<!--                      <el-col :span="8" v-for="user in userList" :key="user.userId">-->
-<!--                        <el-checkbox :label="user.userId">{{ user.nickName }}</el-checkbox>-->
-<!--                      </el-col>-->
-<!--                    </el-row>-->
-<!--                  </el-checkbox-group>-->
-<!--                </el-form-item>-->
-              </el-col>
-            </el-row>
-            <el-row>
-              <el-col :span="24">
-                <el-form-item label="附件(可选)">
-                  <preview :limit="8" v-model="finishForm.attachmentUrls" :filesize="5"></preview>
-                </el-form-item>
-              </el-col>
-            </el-row>
-        </el-form>
-      </div>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="finishDialogVisible = false">取 消</el-button>
-          <el-button type="primary" @click="submitFinish">确认结单</el-button>
-        </div>
-      </template>
-    </el-dialog>
-
+    <!-- 结单对话框组件 -->
+    <FinalizeDialog
+      v-model="finishDialogVisible"
+      :data="finishForm"
+      :work-order-status-options="gxt_work_order_status"
+      :info-entry-options="gxt_info_entry"
+      :list-gxt-order="listGxtOrder"
+      :list-work-person="listWorkPerson"
+      :list-mis-info="listMisInfo"
+      :list-user-data="listUserData"
+      :on-submit="submitFinishFromParent"
+      @success="handleFinishSuccess"
+    />
     <!-- 复运对话框 -->
     <el-dialog title="复运" v-model="restartDialogVisible" width="800px" append-to-body>
       <div class="space-y-4">
@@ -1612,9 +1408,9 @@ import {
 } from "@/api/gxt/gxtOrder"
 import {listUserData, listUserNoPermi, listLeader} from "@/api/system/user"
 import {getToken} from "@/utils/auth.js";
-import {getRepairOrder, startRepairOrder} from "@/api/gxt/repairOrder.js";
-import {listEquipment, listMaintenanceCenters, listStationsByMaintenanceCenter} from "@/api/gxt/equipment.js";
-import MisInfoSelectSingle from "@/components/misInfoSelect/single.vue";
+import {getRepairOrder, listRepairOrder, startRepairOrder} from "@/api/gxt/repairOrder.js";
+import FinalizeDialog from '@/components/gxtOrder/finalize.vue'
+import {listEquipment, listMaintenanceCenters, listStationsByMaintenanceCenter} from "@/api/gxt/equipment.js";import MisInfoSelectSingle from "@/components/misInfoSelect/single.vue";
 import {genCode} from "@/api/system/autocode/rule.js";
 import {listMisInfo, listWorkPerson} from "@/api/gxt/misInfo.js";
 import {ElMessageBox} from "element-plus";
@@ -2526,22 +2322,34 @@ function submitFinish() {
 
 /** 保存结单工单 */
 function saveFinishWorkOrder() {
-  if (!finishForm.value.realEndTime) {
-    proxy.$modal.msgError("该工单未结束,无法结单!")
-    return
-  }
+  // if (!finishForm.value.realEndTime) {
+  //   proxy.$modal.msgError("该工单未结束,无法结单!")
+  //   return
+  // }
   finishForm.value.workOrderStatus = 'completed'
   completeWorkOrder(finishForm.value.orderId, finishForm.value).then(response => {
     finishDialogVisible.value = false
     // 清空附件列表
     finishForm.value.attachmentUrls = undefined
-    proxy.$modal.msgSuccess("结单成功")
+    // proxy.$modal.msgSuccess("结单成功")
     getList()
   }).catch(error => {
     console.log("操作失败: " + error.message)
   })
 }
 
+// 用于传递给结单组件的提交方法
+async function submitFinishFromParent(data) {
+  finishForm.value = data
+  await saveFinishWorkOrder()
+}
+
+// 在提交结单成功后的回调函数
+function handleFinishSuccess() {
+  finishDialogVisible.value = false
+  getList()
+}
+
 /** 复运 */
 function handleRestart(row) {
   getGxtOrder(row.id).then(response => {
@@ -3510,5 +3318,4 @@ getList()
 /* 穿透修改组件内部输入框的对齐方式(关键) */
 :deep(.input-number-left .el-input__inner) {
   text-align: left !important; /* !important 覆盖组件默认的居中 */
-}
-</style>
+}</style>

+ 93 - 1
ygtx-ui/src/views/gxt/orderMyTodo/index.vue

@@ -231,7 +231,7 @@
                 v-if="(scope.row.workOrderStatus === 'processing' || scope.row.workOrderStatus === 'to_finish') && (scope.row.teamLeaderId == userStore.id || userStore.roles.includes('admin'))"
                 type="success"
                 link
-                @click="handleFinalize(scope.row)"
+                @click="handleFinish(scope.row)"
                 v-hasPermi="['gxt:maintenance:order:complete']"
             ><i class="fa fa-check"></i>结单</el-button>
 
@@ -1611,6 +1611,20 @@
         :on-submit="submitReturnFromParent"
         @success="handleReturnSuccess"
     />
+
+    <!-- 维保结单对话框组件 -->
+    <FinishDialog
+        v-model="finishDialogVisible"
+        :data="finishForm"
+        :work-order-status-options="gxt_work_order_status"
+        :info-entry-options="gxt_info_entry"
+        :list-gxt-order="listGxtOrder"
+        :list-work-person="listWorkPerson"
+        :list-mis-info="listMisInfo"
+        :list-user-data="listUserData"
+        :on-submit="submitFinishFromParent"
+        @success="handleFinishSuccess"
+    />
   </div>
 </template>
 
@@ -1643,10 +1657,13 @@ import ResetDialog from '@/components/repairOrder/reset.vue'
 import {
   listGxtOrder,
   updateGxtOrder,
+  completeWorkOrder,
+  getGxtOrder
 } from "@/api/gxt/gxtOrder"
 import EquipmentSelectSingle from "@/components/equipmentSelect/single.vue"
 import FinalizeDialog from "@/components/repairOrder/finalize.vue";
 import ReturnDialog from "@/components/repairOrder/return.vue";
+import FinishDialog from "@/components/gxtOrder/finalize.vue";
 
 const { proxy } = getCurrentInstance();
 const userStore = useUserStore();
@@ -1678,6 +1695,8 @@ const finalizeRepairDialogVisible = ref(false);
 const finalizeWorkDialogVisible = ref(false);
 // 维修结单组件对话框可见性
 const finalizeDialogVisible = ref(false)
+// 维保结单组件对话框可见性
+const finishDialogVisible = ref(false)
 
 // 审批对话框可见性
 const approveRepairDialogVisible = ref(false);
@@ -1720,6 +1739,9 @@ const acceptWorkForm = ref({});
 const finalizeRepairForm = ref({workArea: []});
 const finalizeWorkForm = ref({});
 
+// 维保结单表单数据
+const finishForm = ref({})
+
 // 控制结单表单中字段是否可编辑
 const getMisDataConfig = ref("0"); // 默认值为"0",表示可以手动输入
 
@@ -2968,6 +2990,76 @@ function handleReturnSuccess() {
   returnDialogVisible.value = false
   getList()
 }
+
+/** 待结单状态:结单按钮 */
+function handleFinish(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
+          debugger
+          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
+          finishDialogVisible.value = true
+        }
+      })
+    } else {
+      finishForm.value.realStartTime = null
+      finishForm.value.realEndTime = null
+      finishDialogVisible.value = true
+    }
+    // 打开对话框后重置表单验证错误
+    proxy.$nextTick(() => {
+      proxy.$refs["finishRef"]?.clearValidate()
+    })
+  })
+}
+
+/** 保存结单工单 */
+function saveFinishWorkOrder() {
+  // if (!finishForm.value.realEndTime) {
+  //   proxy.$modal.msgError("该工单未结束,无法结单!")
+  //   return
+  // }
+  finishForm.value.workOrderStatus = 'completed'
+  completeWorkOrder(finishForm.value.orderId, finishForm.value).then(response => {
+    finishDialogVisible.value = false
+    // 清空附件列表
+    finishForm.value.attachmentUrls = undefined
+    // proxy.$modal.msgSuccess("结单成功")
+    getList()
+  }).catch(error => {
+    console.log("操作失败: " + error.message)
+  })
+}
+
+// 用于传递给结单组件的提交方法
+async function submitFinishFromParent(data) {
+  finishForm.value = data
+  await saveFinishWorkOrder()
+}
+
+// 在提交结单成功后的回调函数
+function handleFinishSuccess() {
+  finishDialogVisible.value = false
+  getList()
+}
+
+
 </script>
 
 <style scoped>