فهرست منبع

Merge branch 'stable' of http://39.98.153.250:9080/yudao/yudao-admin-yiqun into stable

yangguanjin 1 روز پیش
والد
کامیت
ddb86f4629
15فایلهای تغییر یافته به همراه204 افزوده شده و 214 حذف شده
  1. 13 6
      yudao-ui-admin-vue3/src/views/pressure2/acceptorder/boilerDetail.vue
  2. 8 7
      yudao-ui-admin-vue3/src/views/pressure2/acceptorder/pipeDetail.vue
  3. 15 4
      yudao-ui-admin-vue3/src/views/pressure2/boilerchecker/components/StatusOperationPanel.vue
  4. 8 1
      yudao-ui-admin-vue3/src/views/pressure2/boilertaskorder/detail.vue
  5. 23 12
      yudao-ui-admin-vue3/src/views/pressure2/equipboilerscheduling/components/BoilerPlanScheduleDialog.vue
  6. 8 4
      yudao-ui-admin-vue3/src/views/pressure2/equipboilerscheduling/components/BoilerPlanScheduleEquipDialog.vue
  7. 28 62
      yudao-ui-admin-vue3/src/views/pressure2/inspectionOpinion/indexBoilerTab.vue
  8. 28 62
      yudao-ui-admin-vue3/src/views/pressure2/inspectionOpinion/indexPipeTab.vue
  9. 15 4
      yudao-ui-admin-vue3/src/views/pressure2/pipechecker/components/StatusOperationPanel.vue
  10. 15 13
      yudao-ui-admin-vue3/src/views/pressure2/pipescheduling/components/PipePlanScheduleDialog.vue
  11. 11 13
      yudao-ui-admin-vue3/src/views/pressure2/pipescheduling/components/PipePlanScheduleEquipDialog.vue
  12. 9 1
      yudao-ui-admin-vue3/src/views/pressure2/pipetaskorder/detail.vue
  13. 10 16
      yudao-ui-admin-vue3/src/views/pressure2/planNew/components/PipePlanScheduleDialog.vue
  14. 12 8
      yudao-ui-admin-vue3/src/views/pressure2/planNew/components/PlanScheduleEquipBoilerDialog.vue
  15. 1 1
      yudao-ui-admin-vue3/src/views/pressure2/planNew/pipeDetail.vue

+ 13 - 6
yudao-ui-admin-vue3/src/views/pressure2/acceptorder/boilerDetail.vue

@@ -724,7 +724,7 @@
     <!-- 页面底部按钮 -->
     <div class="flex justify-center pb-4 footer-btn-box">
       <el-button @click="handleClose">关闭</el-button>
-      <el-button :disabled="pageType === 'detail'" type="primary" @click="handleGenerateAcceptance">
+      <el-button :disabled="pageType === 'detail'" type="primary" :loading="submitLoading" @click="handleGenerateAcceptance">
         重新提交
       </el-button>
       <!-- <el-button type="primary" plain @click="handlePrintPDF">打印受理单PDF</el-button> -->
@@ -838,6 +838,7 @@ const formData = ref<Record<string, any>>({
 })
 
 const loading = ref(false)
+const submitLoading = ref(false) // 提交按钮 loading
 
 const userList = ref<any[]>([])
 
@@ -1315,33 +1316,37 @@ const handleAddEquipSuccess = (selectedEquips) => {
 /** 生成受理单 */
 const handleGenerateAcceptance = () => {
   console.log('开始验证表单', formRef.value)
-  
+
   // 表单验证
   if (!formRef.value) {
     ElMessage.warning('表单引用获取失败')
     return
   }
 
+  submitLoading.value = true
   // 手动触发表单验证
   formRef.value.validate((valid, fields) => {
-    
+
     if (!valid) {
       ElMessage.warning('请完善必填信息')
       console.log('验证失败的字段:', fields)
+      submitLoading.value = false
       return
     }
-    
+
     // 检查排期时间和检验员
     if (!formData.value.appointmentDate) {
       ElMessage.warning('请选择排期时间')
+      submitLoading.value = false
       return
     }
-    
+
     if (selectedCheckers.value.length === 0) {
       ElMessage.warning('请选择检验员')
+      submitLoading.value = false
       return
     }
-    
+
     // 二次确认
     ElMessageBox.confirm(
       '确认重新提交受理单吗?',
@@ -1360,6 +1365,7 @@ const handleGenerateAcceptance = () => {
     }).catch(() => {
       // 用户取消操作
       console.log('用户取消操作')
+      submitLoading.value = false
     })
   })
 }
@@ -1433,6 +1439,7 @@ const submitAcceptance = async () => {
     ElMessage.error('提交失败')
   } finally {
     loading.value = false
+    submitLoading.value = false
   }
 }
 

+ 8 - 7
yudao-ui-admin-vue3/src/views/pressure2/acceptorder/pipeDetail.vue

@@ -660,7 +660,7 @@
     <!-- 页面底部按钮 -->
     <div class="flex justify-center pb-4 footer-btn-box">
       <el-button @click="handleClose">关闭</el-button>
-      <el-button :disabled="pageType === 'detail'" type="primary" @click="handleGenerateAcceptance">
+      <el-button :disabled="pageType === 'detail'" type="primary" :loading="submitLoading" @click="handleGenerateAcceptance">
         重新提交
       </el-button>
       <!-- <el-button type="primary" plain @click="handlePrintPDF">打印受理单PDF</el-button> -->
@@ -790,6 +790,7 @@ const checkerSelectRef = ref()
 const selectedCheckers = ref<CheckerItem[]>([])
 
 const loading = ref(false)
+const submitLoading = ref(false) // 提交按钮 loading
 
 // 记录每个区域下已选择的街道
 const areaStreetMap = ref(new Map<number, number[]>())
@@ -1391,23 +1392,21 @@ const handleGenerateAcceptance = () => {
     return
   }
 
+  submitLoading.value = true
   // 手动触发表单验证
   formRef.value.validate((valid, fields) => {
 
     if (!valid) {
       ElMessage.warning('请完善必填信息')
       console.log('验证失败的字段:', fields)
+      submitLoading.value = false
       return
     }
 
-    // 检查排期时间和检验员
+    // 检查排期时间(检验员改为非必选,任务单阶段才必选)
     if (!formData.value.appointmentDate) {
       ElMessage.warning('请选择排期时间')
-      return
-    }
-
-    if (selectedCheckers.value.length === 0) {
-      ElMessage.warning('请选择检验员')
+      submitLoading.value = false
       return
     }
 
@@ -1429,6 +1428,7 @@ const handleGenerateAcceptance = () => {
     }).catch(() => {
       // 用户取消操作
       console.log('用户取消操作')
+      submitLoading.value = false
     })
   })
 }
@@ -1503,6 +1503,7 @@ const submitAcceptance = async () => {
     ElMessage.error('提交失败')
   } finally {
     loading.value = false
+    submitLoading.value = false
   }
 }
 

+ 15 - 4
yudao-ui-admin-vue3/src/views/pressure2/boilerchecker/components/StatusOperationPanel.vue

@@ -1462,6 +1462,7 @@ const ectificationMaterialsVisible = ref(false)
 
 const handleRectificationMaterials = () => {
   ectificationMaterialsVisible.value = true
+  checkBookDetail.value.id =  props.selectedItem?.id
 }
 
 // 获取检验员名称
@@ -1509,7 +1510,8 @@ const isCanSubmitRecheck = computed(() => {
   else
     return (
       props.selectedItem &&
-      props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT']
+      props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT'] &&
+      !isSingleReportWithoutInstruction.value
       // && props.selectedItem.reportUrl
     )
 })
@@ -1540,19 +1542,28 @@ const isCanSubmitToAudit = computed(() => {
     )
 })
 
+// 独审报告未关联操作指导书时不可编辑
+const isSingleReportWithoutInstruction = computed(
+  () =>
+    props.selectedItem?.reportType === PressureReportType.SINGLE &&
+    !props.selectedItem?.instructionId
+)
+
 // 判断“填写记录”按钮是否显示
 const isCanEditTestRecord = computed(
   () =>
     props.selectedItem &&
     (props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT'] ||
-      props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['CONFIRMED']) && props.selectedItem.reportType !== PressureReportType['SUBCONTRACT']
+      props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['CONFIRMED']) && props.selectedItem.reportType !== PressureReportType['SUBCONTRACT'] &&
+    !isSingleReportWithoutInstruction.value
 )
 
 // 判断“编制报告”按钮是否显示
 const isCanEditReport = computed(
   () =>
     props.selectedItem &&
-    props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['REPORT_INPUT']
+    props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['REPORT_INPUT'] &&
+    !isSingleReportWithoutInstruction.value
 )
 
 // 判断"撤销流程"按钮是否显示:报告审核或审批阶段,且有OA流程ID,且当前用户是发起人
@@ -2583,7 +2594,7 @@ const initPreview=()=>{
   initData.value.templateId = templateId;
   initData.value.refId = refId;
   initData.value.refName =  props.selectedItem?.reportName;
-  initData.value.opType = (props.selectedItem.taskStatus == 510 || props.selectedItem.taskStatus >= 600 || (showReportPdfType.value === 'record' && props.selectedItem.taskStatus > 500) ||  props?.selectedItem?.checkUsers?.[0]?.id != userStore?.user?.id) ? 1 : 0;
+  initData.value.opType = (props.selectedItem.taskStatus == 510 || props.selectedItem.taskStatus >= 600 || (showReportPdfType.value === 'record' && props.selectedItem.taskStatus > 500) ||  props?.selectedItem?.checkUsers?.[0]?.id != userStore?.user?.id || isSingleReportWithoutInstruction.value) ? 1 : 0;
   if (props.selectedItem.reportType === PressureReportType['INSPECTIONPLAN'] && props.selectedItem.manualUrl){
     initData.value.manualUrl = props.selectedItem.manualUrl;
   }else{

+ 8 - 1
yudao-ui-admin-vue3/src/views/pressure2/boilertaskorder/detail.vue

@@ -490,7 +490,7 @@
     <!-- 页面底部按钮 -->
     <div class="flex justify-center pb-4 footer-btn-box">
       <el-button @click="handleClose">关闭</el-button>
-      <el-button type="primary" @click="handleGenerateAcceptance">
+      <el-button type="primary" :loading="submitLoading" @click="handleGenerateAcceptance">
         确认修改
       </el-button>
     </div>
@@ -609,6 +609,7 @@ const batchEditFormRef = ref()
 const boilerTypeOptions = getStrDictOptions(DICT_TYPE.SYSTEM_EQUIP_BOILER_TYPE)
 
 const loading = ref(false)
+const submitLoading = ref(false) // 提交按钮 loading
 
 // 检验员组件引用
 const checkerSelectRef = ref()
@@ -1102,23 +1103,27 @@ const handleGenerateAcceptance = () => {
     return
   }
 
+  submitLoading.value = true
   // 手动触发表单验证
   formRef.value.validate((valid, fields) => {
 
     if (!valid) {
       ElMessage.warning('请完善必填信息')
       console.log('验证失败的字段:', fields)
+      submitLoading.value = false
       return
     }
 
     // 检查排期时间和检验员
     if (!formData.value.checkDate) {
       ElMessage.warning('请选择排期时间')
+      submitLoading.value = false
       return
     }
 
     if (selectedCheckers.value.length === 0) {
       ElMessage.warning('请选择检验员')
+      submitLoading.value = false
       return
     }
 
@@ -1144,6 +1149,7 @@ const handleGenerateAcceptance = () => {
     }).catch(() => {
       // 用户取消操作
       console.log('用户取消操作')
+      submitLoading.value = false
     })
   })
 }
@@ -1246,6 +1252,7 @@ const submitAcceptance = async (reason: string) => {
     ElMessage.error('任务单修改请求提交失败')
   } finally {
     loading.value = false
+    submitLoading.value = false
   }
 }
 

+ 23 - 12
yudao-ui-admin-vue3/src/views/pressure2/equipboilerscheduling/components/BoilerPlanScheduleDialog.vue

@@ -50,6 +50,7 @@
                 class="!w-240px"
               />
               <el-checkbox
+                v-if="!isFrontDesk"
                 v-model="formData.inIsOrderConfirm"
                 class="ml-4"
                 :disabled="inEquipCount === 0"
@@ -106,6 +107,7 @@
                 class="!w-240px"
               />
               <el-checkbox
+                v-if="!isFrontDesk"
                 v-model="formData.outIsOrderConfirm"
                 class="ml-4"
                 :disabled="outEquipCount === 0"
@@ -163,6 +165,7 @@
                 class="!w-240px"
               />
               <el-checkbox
+                v-if="!isFrontDesk"
                 v-model="formData.pressureIsOrderConfirm"
                 class="ml-4"
                 :disabled="preEquipCount == 0"
@@ -265,6 +268,7 @@
           type="primary" 
           @click="handleConfirm"
           :disabled="isConfirmDisabled"
+          :loading="submitLoading"
         >
           确定
         </el-button>
@@ -334,9 +338,13 @@ const props = defineProps({
   }
 })
 
+// 是否前台约检来源:前台约检跳过计划表提交+约检确认,直接生成受理单
+const isFrontDesk = computed(() => props.source === 'plan')
+
 const emit = defineEmits(['success', 'close', 'clear-selected-rows'])
 const dialogVisible = ref(false)
 const formRef = ref<FormInstance>()
+const submitLoading = ref(false) // 提交按钮 loading
 const isBatch = ref(false)
 const title = computed(() => props.selectedRows.length > 1 ? '批量计划排期' : '计划排期')
 
@@ -1038,16 +1046,17 @@ const handleConfirm = async () => {
   const form = unref(formRef)
   if (!form) return
 
-  // 验证日期
-  await form.validate()
-  // 验证检验员必填
-  const validations: boolean[] = []
-  if (inEquipCount.value > 0) validations.push(checkerInRef.value?.validate())
-  if (outEquipCount.value > 0) validations.push(checkerOutRef.value?.validate())
-  if (preEquipCount.value !== 0) validations.push(checkerPreRef.value?.validate())
-  if (validations.some(v => v === false)) return
-
+  submitLoading.value = true
   try {
+    // 验证日期
+    await form.validate()
+    // 验证检验员必填
+    const validations: boolean[] = []
+    if (inEquipCount.value > 0) validations.push(checkerInRef.value?.validate())
+    if (outEquipCount.value > 0) validations.push(checkerOutRef.value?.validate())
+    if (preEquipCount.value !== 0) validations.push(checkerPreRef.value?.validate())
+    if (validations.some(v => v === false)) return
+
     // 组装新的数据结构
     const submitData: { taskList: any[]; source: number } = {
       taskList: [],
@@ -1092,7 +1101,7 @@ const handleConfirm = async () => {
           submitData.taskList.push({
             equipIds: item.map(item => item.id).join(','),
             type: '100',
-            hasOrderConfirm: formData.value.inIsOrderConfirm,
+            hasOrderConfirm: isFrontDesk.value ? false : formData.value.inIsOrderConfirm,
             date: formData.value.inDate,
             teamList: formData.value.inTeamList,
             chargeType: formData.value.inChargeType,
@@ -1143,7 +1152,7 @@ const handleConfirm = async () => {
           submitData.taskList.push({
             equipIds: item.map(item => item.id).join(','),
             type: '200',
-            hasOrderConfirm: formData.value.outIsOrderConfirm,
+            hasOrderConfirm: isFrontDesk.value ? false : formData.value.outIsOrderConfirm,
             date: formData.value.outDate,
             teamList: formData.value.outTeamList,
             chargeType: formData.value.outChargeType,
@@ -1195,7 +1204,7 @@ const handleConfirm = async () => {
           submitData.taskList.push({
             equipIds: item.map(item => item.id).join(','),
             type: '300',
-            hasOrderConfirm: formData.value.pressureIsOrderConfirm,
+            hasOrderConfirm: isFrontDesk.value ? false : formData.value.pressureIsOrderConfirm,
             date: formData.value.preDate,
             teamList: formData.value.preTeamList,
             chargeType: formData.value.preChargeType,
@@ -1245,6 +1254,8 @@ const handleConfirm = async () => {
     (error) {
     console.error( error)
     message.error('保存失败')
+  } finally {
+    submitLoading.value = false
   }
 }
 

+ 8 - 4
yudao-ui-admin-vue3/src/views/pressure2/equipboilerscheduling/components/BoilerPlanScheduleEquipDialog.vue

@@ -258,7 +258,7 @@
     <template #footer>
       <div class="flex justify-end">
         <el-button @click="handleCancel">取消</el-button>
-        <el-button type="primary" @click="handleConfirm">确定</el-button>
+        <el-button type="primary" :loading="submitLoading" @click="handleConfirm">确定</el-button>
       </div>
     </template>
     <!-- 费用计算弹窗 -->
@@ -347,6 +347,7 @@ const emit = defineEmits(['success', 'close'])
 
 const dialogVisible = ref(false)
 const formRef = ref<FormInstance>()
+const submitLoading = ref(false) // 提交按钮 loading
 
 const title = computed(() => props.isBatch ? '批量计划排期' : '计划排期')
 
@@ -826,10 +827,11 @@ const handleCancel = () => {
 const handleConfirm = async () => {
   const form = unref(formRef)
   if (!form) return
-  
-  await form.validate()
-  
+
+  submitLoading.value = true
   try {
+    await form.validate()
+
     // 组装新的数据结构
     const submitData: { taskList: any[] } = {
       taskList: []
@@ -931,6 +933,8 @@ const handleConfirm = async () => {
     emit('success')
   } catch (error) {
     message.error('保存失败')
+  } finally {
+    submitLoading.value = false
   }
 }
 

+ 28 - 62
yudao-ui-admin-vue3/src/views/pressure2/inspectionOpinion/indexBoilerTab.vue

@@ -214,11 +214,10 @@
         <template #default="{ row }">
           <div class="flex justify-center">
 <!--            <el-button link type="primary" v-if="filerFileUrlShowFn(row)" @click="handleFilePreview(row)"> 查看附件 </el-button>-->
-            <el-button link type="primary" @click="fiePreviewEmitFn(row)"> 消息推送 </el-button>
+            <el-button link type="primary" @click="handleRePush(row)"> 消息推送 </el-button>
             <el-button link type="primary" @click="() => handleFollowRecord(row)">
               跟进记录
             </el-button>
-            <el-button link type="primary" @click="handleViewPdf(row)"> 预览 </el-button>
             <el-button
               link
               type="primary"
@@ -657,11 +656,16 @@
 
  <unitContainerForm ref="unitContainerFormRef" />
 
-  <!-- PDF预览弹窗 -->
-  <PdfPreviewDialog
-    v-model="pdfPreviewVisible"
-    :pdfBlob="currentPdfBlob"
-    @close="handlePdfPreviewClose"
+  <!-- PDF预览 + 消息推送弹窗 -->
+  <FilePreview
+    v-if="previewVisible"
+    v-model="previewVisible"
+    :id="currentPreviewId"
+    :reportId="currentReportId"
+    :filename="currentFilename"
+    :title="'检验意见通知书'"
+    @close="handlePreviewClose"
+    @sbmit="fiePreviewEmitFn"
   />
 
 </template>
@@ -698,7 +702,6 @@ import { cloneDeep } from 'lodash-es'
 import { useUserStoreWithOut } from '@/store/modules/user'
 import { buildFileUrl } from '@/utils'
 import {PipeInputApi} from "@/api/pressure2/pipeInput";
-import PdfPreviewDialog from "@/views/pressure2/boilertaskorder/PdfPreviewDialog.vue";
 
 const currentPreviewId = ref<string>('')
 const currentFilename = ref<string>('')
@@ -891,17 +894,24 @@ const handleRePush = async (row) => {
   recipientType.value = 'single'
   currentReportId.value = row.opinionReportedUrl
   currentPreviewId.value = row.id
-  recipientDialogVisible.value = true
-
+  currentFilename.value = '检验意见通知书.pdf'
+  // 重置上次推送的接收人信息
+  recipientFormData.recipient = ''
+  recipientFormData.recipientPhone = ''
+  previewVisible.value = true
 }
-const fiePreviewEmitFn = (row) => {
-  recipientRow.value = row
-  recipientType.value = 'single'
-  currentReportId.value = row.opinionReportedUrl
-  currentPreviewId.value = row.id
-
-  recipientFormData.recipient = row.defaultRecipient || ''
-  recipientFormData.recipientPhone = row.defaultRecipientPhone || ''
+const fiePreviewEmitFn = async () => {
+  try {
+    recipientFormData.recipient = (recipientRow.value as any).recipient || (recipientRow.value as any).defaultRecipient || ''
+    recipientFormData.recipientPhone = (recipientRow.value as any).recipientPhone || (recipientRow.value as any).defaultRecipientPhone || ''
+  } catch (e) {
+    console.warn('获取推送接收人信息失败,使用默认值', e)
+  }
+  // 兜底使用行数据中的默认值
+  if (!recipientFormData.recipient) {
+    recipientFormData.recipient = (recipientRow.value as any).defaultRecipient || ''
+    recipientFormData.recipientPhone = (recipientRow.value as any).defaultRecipientPhone || ''
+  }
   recipientDialogVisible.value = true
 }
 const handleFilePreview = (row) => {
@@ -1236,50 +1246,6 @@ const downloadFile = async (blob, filename) => {
   }
 }
 
-// PDF预览相关
-const pdfPreviewVisible = ref(false)
-const currentPdfBlob = ref<Blob | null>(null)
-const handleViewPdf = async (row) => {
-
-  let data: any[] = []
-  data.push({
-    taskStatus: 100,
-    resultTemplateId: '',
-    templateId: row.templateId,
-    id: row.reportId,
-  })
-
-  const loadingInstance = ElLoading.service({
-    fullscreen: true,
-    text: '正在生成...'
-  })
-
-  try {
-    // 调用 API 获取 ZIP blob
-    const pdfBlob = await PipeInputApi.handlePrint(data)
-
-    if (pdfBlob) {
-
-      currentPdfBlob.value = pdfBlob
-      pdfPreviewVisible.value = true
-
-    } else {
-      ElMessage.error('获取文件失败')
-    }
-  } catch (error) {
-    console.error('预览失败:', error)
-    ElMessage.error('预览失败')
-  } finally {
-    loadingInstance.close()
-  }
-
-}
-
-// PDF预览关闭处理
-const handlePdfPreviewClose = () => {
-  currentPdfBlob.value = null
-}
-
 const handleRowDownload = async (row) => {
 
   let data: any[] = []

+ 28 - 62
yudao-ui-admin-vue3/src/views/pressure2/inspectionOpinion/indexPipeTab.vue

@@ -214,11 +214,10 @@
         <template #default="{ row }">
           <div class="flex justify-center">
 <!--            <el-button link type="primary" v-if="filerFileUrlShowFn(row)" @click="handleFilePreview(row)"> 查看附件 </el-button>-->
-            <el-button link type="primary" @click="fiePreviewEmitFn(row)"> 消息推送 </el-button>
+            <el-button link type="primary" @click="handleRePush(row)"> 消息推送 </el-button>
             <el-button link type="primary" @click="() => handleFollowRecord(row)">
               跟进记录
             </el-button>
-            <el-button link type="primary" @click="handleViewPdf(row)"> 预览 </el-button>
             <el-button
               link
               type="primary"
@@ -657,11 +656,16 @@
 
  <unitContainerForm ref="unitContainerFormRef" />
 
-  <!-- PDF预览弹窗 -->
-  <PdfPreviewDialog
-    v-model="pdfPreviewVisible"
-    :pdfBlob="currentPdfBlob"
-    @close="handlePdfPreviewClose"
+  <!-- PDF预览 + 消息推送弹窗 -->
+  <FilePreview
+    v-if="previewVisible"
+    v-model="previewVisible"
+    :id="currentPreviewId"
+    :reportId="currentReportId"
+    :filename="currentFilename"
+    :title="'检验意见通知书'"
+    @close="handlePreviewClose"
+    @sbmit="fiePreviewEmitFn"
   />
 
 </template>
@@ -698,7 +702,6 @@ import { cloneDeep } from 'lodash-es'
 import { useUserStoreWithOut } from '@/store/modules/user'
 import { buildFileUrl } from '@/utils'
 import {PipeInputApi} from "@/api/pressure2/pipeInput";
-import PdfPreviewDialog from "@/views/pressure2/boilertaskorder/PdfPreviewDialog.vue";
 
 const currentPreviewId = ref<string>('')
 const currentFilename = ref<string>('')
@@ -891,17 +894,24 @@ const handleRePush = async (row) => {
   recipientType.value = 'single'
   currentReportId.value = row.opinionReportedUrl
   currentPreviewId.value = row.id
-  recipientDialogVisible.value = true
-
+  currentFilename.value = '检验意见通知书.pdf'
+  // 重置上次推送的接收人信息
+  recipientFormData.recipient = ''
+  recipientFormData.recipientPhone = ''
+  previewVisible.value = true
 }
-const fiePreviewEmitFn = (row) => {
-  recipientRow.value = row
-  recipientType.value = 'single'
-  currentReportId.value = row.opinionReportedUrl
-  currentPreviewId.value = row.id
-
-  recipientFormData.recipient = row.defaultRecipient || ''
-  recipientFormData.recipientPhone = row.defaultRecipientPhone || ''
+const fiePreviewEmitFn = async () => {
+  try {
+    recipientFormData.recipient = (recipientRow.value as any).recipient || (recipientRow.value as any).defaultRecipient || ''
+    recipientFormData.recipientPhone = (recipientRow.value as any).recipientPhone || (recipientRow.value as any).defaultRecipientPhone || ''
+  } catch (e) {
+    console.warn('获取推送接收人信息失败,使用默认值', e)
+  }
+  // 兜底使用行数据中的默认值
+  if (!recipientFormData.recipient) {
+    recipientFormData.recipient = (recipientRow.value as any).defaultRecipient || ''
+    recipientFormData.recipientPhone = (recipientRow.value as any).defaultRecipientPhone || ''
+  }
   recipientDialogVisible.value = true
 }
 const handleFilePreview = (row) => {
@@ -1236,50 +1246,6 @@ const downloadFile = async (blob, filename) => {
   }
 }
 
-// PDF预览相关
-const pdfPreviewVisible = ref(false)
-const currentPdfBlob = ref<Blob | null>(null)
-const handleViewPdf = async (row) => {
-
-  let data: any[] = []
-  data.push({
-    taskStatus: 100,
-    resultTemplateId: '',
-    templateId: row.templateId,
-    id: row.reportId,
-  })
-
-  const loadingInstance = ElLoading.service({
-    fullscreen: true,
-    text: '正在生成...'
-  })
-
-  try {
-    // 调用 API 获取 ZIP blob
-    const pdfBlob = await PipeInputApi.handlePrint(data)
-
-    if (pdfBlob) {
-
-      currentPdfBlob.value = pdfBlob
-      pdfPreviewVisible.value = true
-
-    } else {
-      ElMessage.error('获取文件失败')
-    }
-  } catch (error) {
-    console.error('预览失败:', error)
-    ElMessage.error('预览失败')
-  } finally {
-    loadingInstance.close()
-  }
-
-}
-
-// PDF预览关闭处理
-const handlePdfPreviewClose = () => {
-  currentPdfBlob.value = null
-}
-
 const handleRowDownload = async (row) => {
 
   let data: any[] = []

+ 15 - 4
yudao-ui-admin-vue3/src/views/pressure2/pipechecker/components/StatusOperationPanel.vue

@@ -1416,6 +1416,7 @@ const ectificationMaterialsVisible = ref(false)
 
 const handleRectificationMaterials = () => {
   ectificationMaterialsVisible.value = true
+  checkBookDetail.value.id =  props.selectedItem?.id
 }
 
 // 获取检验员名称
@@ -1463,7 +1464,8 @@ const isCanSubmitRecheck = computed(() => {
   else
     return (
       props.selectedItem &&
-      props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT']
+      props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT'] &&
+      !isSingleReportWithoutInstruction.value
       // && props.selectedItem.reportUrl
     )
 })
@@ -1494,19 +1496,28 @@ const isCanSubmitToAudit = computed(() => {
     )
 })
 
+// 独审报告未关联操作指导书时不可编辑
+const isSingleReportWithoutInstruction = computed(
+  () =>
+    props.selectedItem?.reportType === PressureReportType.SINGLE &&
+    !props.selectedItem?.instructionId
+)
+
 // 判断“填写记录”按钮是否显示
 const isCanEditTestRecord = computed(
   () =>
     props.selectedItem &&
     (props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['RECORD_INPUT'] ||
-      props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['CONFIRMED']) && props.selectedItem.reportType !== PressureReportType['SUBCONTRACT']
+      props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['CONFIRMED']) && props.selectedItem.reportType !== PressureReportType['SUBCONTRACT'] &&
+    !isSingleReportWithoutInstruction.value
 )
 
 // 判断“编制报告”按钮是否显示
 const isCanEditReport = computed(
   () =>
     props.selectedItem &&
-    props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['REPORT_INPUT']
+    props.selectedItem.taskStatus === PressureCheckerMyTaskStatus['REPORT_INPUT'] &&
+    !isSingleReportWithoutInstruction.value
 )
 
 // 判断"撤销流程"按钮是否显示:报告审核或审批阶段,且有OA流程ID,且当前用户是发起人
@@ -2453,7 +2464,7 @@ const initPreview=()=>{
   initData.value.templateId = templateId;
   initData.value.refId = refId;
   initData.value.refName =  props.selectedItem?.reportName;
-  initData.value.opType = (props.selectedItem.taskStatus == 510 || props.selectedItem.taskStatus >= 600 || (showReportPdfType.value === 'record' && props.selectedItem.taskStatus > 500) ||  props?.selectedItem?.checkUsers?.[0]?.id != userStore?.user?.id) ? 1 : 0;
+  initData.value.opType = (props.selectedItem.taskStatus == 510 || props.selectedItem.taskStatus >= 600 || (showReportPdfType.value === 'record' && props.selectedItem.taskStatus > 500) ||  props?.selectedItem?.checkUsers?.[0]?.id != userStore?.user?.id || isSingleReportWithoutInstruction.value) ? 1 : 0;
 
   if (props.selectedItem.reportType === PressureReportType['INSPECTIONPLAN'] && props.selectedItem.manualUrl){
     initData.value.manualUrl = props.selectedItem.manualUrl;

+ 15 - 13
yudao-ui-admin-vue3/src/views/pressure2/pipescheduling/components/PipePlanScheduleDialog.vue

@@ -47,6 +47,7 @@
                 class="!w-240px"
               />
               <el-checkbox
+                v-if="!isFrontDesk"
                 v-model="formData.legalIsOrderConfirm"
                 class="ml-4"
                 :disabled="legalEquipCount === 0"
@@ -58,7 +59,6 @@
             <el-form-item label="检验员">
               <CheckerSelect
                 ref="checkerLegalRef"
-                required
                 v-model="legalSelectedCheckers"
                 @change="(v: CheckerItem[]) => handleCheckerSelectChange('legal', v)"
               />
@@ -101,6 +101,7 @@
                 class="!w-240px"
               />
               <el-checkbox
+                v-if="!isFrontDesk"
                 v-model="formData.yearIsOrderConfirm"
                 class="ml-4"
                 :disabled="yearEquipCount === 0"
@@ -112,7 +113,6 @@
             <el-form-item label="检验员">
               <CheckerSelect
                 ref="checkerYearRef"
-                required
                 v-model="yearSelectedCheckers"
                 @change="(v: CheckerItem[]) => handleCheckerSelectChange('year', v)"
               />
@@ -193,7 +193,7 @@
     <template #footer>
       <div class="flex justify-end">
         <el-button @click="handleCancel">取消</el-button>
-        <el-button type="primary" @click="handleConfirm">确定</el-button>
+        <el-button type="primary" :loading="submitLoading" @click="handleConfirm">确定</el-button>
       </div>
     </template>
     <!-- 费用计算弹窗 -->
@@ -251,9 +251,13 @@ const props = defineProps({
   }
 })
 
+// 是否前台约检来源:前台约检跳过计划表提交+约检确认,直接生成受理单
+const isFrontDesk = computed(() => props.source === 'plan')
+
 const emit = defineEmits(['success', 'close'])
 const dialogVisible = ref(false)
 const formRef = ref<FormInstance>()
+const submitLoading = ref(false) // 提交按钮 loading
 const checkerLegalRef = ref()
 const checkerYearRef = ref()
 
@@ -724,15 +728,11 @@ const handleConfirm = async () => {
   const form = unref(formRef)
   if (!form) return
 
-  //验证
-  await form.validate()
-
-  const validations: boolean[] = []
-  validations.push(checkerLegalRef.value?.validate())
-  validations.push(checkerYearRef.value?.validate())
-  if (validations.some(v => v === false)) return
-
+  submitLoading.value = true
   try {
+    //验证(检验员改为非必选,任务单阶段才必选,故移除 CheckerSelect 的 validate 校验)
+    await form.validate()
+
     // 组装新的数据结构
     const submitData: { taskList: any[]; source: number } = {
       taskList: [],
@@ -774,7 +774,7 @@ const handleConfirm = async () => {
           submitData.taskList.push({
             equipIds: item.map(item => item.equipPipeId).join(','),
             type: '100',
-            hasOrderConfirm: formData.value.legalIsOrderConfirm,
+            hasOrderConfirm: isFrontDesk.value ? false : formData.value.legalIsOrderConfirm,
             date: formData.value.legalDate,
             teamList: formData.value.legalTeamList,
             pipeDetailList: item,
@@ -824,7 +824,7 @@ const handleConfirm = async () => {
           submitData.taskList.push({
             equipIds: item.map(item => item.equipPipeId).join(','),
             type: '200',
-            hasOrderConfirm: formData.value.yearIsOrderConfirm,
+            hasOrderConfirm: isFrontDesk.value ? false : formData.value.yearIsOrderConfirm,
             date: formData.value.yearDate,
             teamList: formData.value.yearTeamList,
             pipeDetailList: item,
@@ -873,6 +873,8 @@ const handleConfirm = async () => {
   } catch (error) {
     console.log(error)
     message.error('保存失败')
+  } finally {
+    submitLoading.value = false
   }
 }
 

+ 11 - 13
yudao-ui-admin-vue3/src/views/pressure2/pipescheduling/components/PipePlanScheduleEquipDialog.vue

@@ -258,7 +258,7 @@
     <template #footer>
       <div class="flex justify-end">
         <el-button @click="handleCancel">取消</el-button>
-        <el-button type="primary" @click="handleConfirm">确定</el-button>
+        <el-button type="primary" :loading="submitLoading" @click="handleConfirm">确定</el-button>
       </div>
     </template>
 
@@ -317,6 +317,7 @@ const emit = defineEmits(['success', 'close'])
 const { queryCheckItemList } = BoilerTaskOrderApi
 const dialogVisible = ref(false)
 const formRef = ref<FormInstance>()
+const submitLoading = ref(false) // 提交按钮 loading
 // 是否批量
 const isBatch = ref(false)
 
@@ -386,11 +387,8 @@ const formRules = {
   }],
   regularCheckTeamList: [{
     validator: (_rule, value, callback) => {
-      if (!formData.value.regularNoSchedule && (!value || value.length === 0)) {
-        callback(new Error('请选择检验员'))
-      } else {
-        callback()
-      }
+      // 检验员改为非必选(任务单阶段才必选)
+      callback()
     },
     trigger: 'change'
   }],
@@ -406,11 +404,8 @@ const formRules = {
   }],
   annualCheckTeamList: [{
     validator: (_rule, value, callback) => {
-      if (!formData.value.annualNoSchedule && (!value || value.length === 0)) {
-        callback(new Error('请选择检验员'))
-      } else {
-        callback()
-      }
+      // 检验员改为非必选(任务单阶段才必选)
+      callback()
     },
     trigger: 'change'
   }]
@@ -716,9 +711,10 @@ const handleConfirm = async () => {
   const form = unref(formRef)
   if (!form) return
 
-  await form.validate()
-
+  submitLoading.value = true
   try {
+    await form.validate()
+
     // 组装新的数据结构
     const submitData: { source: number; taskList: any[] } = {
       source: 200,
@@ -784,6 +780,8 @@ const handleConfirm = async () => {
     emit('success')
   } catch (error) {
     message.error('保存失败')
+  } finally {
+    submitLoading.value = false
   }
 }
 

+ 9 - 1
yudao-ui-admin-vue3/src/views/pressure2/pipetaskorder/detail.vue

@@ -157,6 +157,7 @@
                 v-model="selectedCheckers"
                 :disabled="false"
                 :has-data="true"
+                :required="true"
                 empty-text="暂无检验员数据"
                 :multiple="true"
                 @change="handleCheckerChange"
@@ -553,7 +554,7 @@
     <!-- 页面底部按钮 -->
     <div class="flex justify-center pb-4 footer-btn-box">
       <el-button @click="handleClose">关闭</el-button>
-      <el-button type="primary" @click="handleGenerateAcceptance">
+      <el-button type="primary" :loading="submitLoading" @click="handleGenerateAcceptance">
         确认修改
       </el-button>
     </div>
@@ -657,6 +658,7 @@ const batchEditFormRef = ref()
 const pipeTypeOptions = getStrDictOptions(DICT_TYPE.PIPE_TYPE)
 
 const loading = ref(false)
+const submitLoading = ref(false) // 提交按钮 loading
 
 // 检验员组件引用
 const checkerSelectRef = ref()
@@ -1295,23 +1297,27 @@ const handleGenerateAcceptance = () => {
     return
   }
 
+  submitLoading.value = true
   // 手动触发表单验证
   formRef.value.validate((valid, fields) => {
 
     if (!valid) {
       ElMessage.warning('请完善必填信息')
       console.log('验证失败的字段:', fields)
+      submitLoading.value = false
       return
     }
 
     // 检查排期时间和检验员
     if (!formData.value.checkDate) {
       ElMessage.warning('请选择排期时间')
+      submitLoading.value = false
       return
     }
 
     if (selectedCheckers.value.length === 0) {
       ElMessage.warning('请选择检验员')
+      submitLoading.value = false
       return
     }
     ElMessageBox.prompt(
@@ -1335,6 +1341,7 @@ const handleGenerateAcceptance = () => {
     }).catch(() => {
       // 用户取消操作
       console.log('用户取消操作')
+      submitLoading.value = false
     })
   })
 }
@@ -1439,6 +1446,7 @@ const submitAcceptance = async (reason: string) => {
     ElMessage.error('任务单修改请求提交失败')
   } finally {
     loading.value = false
+    submitLoading.value = false
   }
 }
 

+ 10 - 16
yudao-ui-admin-vue3/src/views/pressure2/planNew/components/PipePlanScheduleDialog.vue

@@ -277,17 +277,14 @@ const formRules = {
     },
     trigger: 'change' 
   }],
-  regularUserIds: [{ 
+  regularUserIds: [{
     validator: (rule, value, callback) => {
-      if (!formData.value.regularNoSchedule && (!value || value.length === 0)) {
-        callback(new Error('请选择检验员'))
-      } else {
-        callback()
-      }
+      // 检验员改为非必选(任务单阶段才必选)
+      callback()
     },
-    trigger: 'change' 
+    trigger: 'change'
   }],
-  yearDate: [{ 
+  yearDate: [{
     validator: (rule, value, callback) => {
       if (!formData.value.yearNoSchedule && !value) {
         callback(new Error('请选择年检日期'))
@@ -295,17 +292,14 @@ const formRules = {
         callback()
       }
     },
-    trigger: 'change' 
+    trigger: 'change'
   }],
-  yearUserIds: [{ 
+  yearUserIds: [{
     validator: (rule, value, callback) => {
-      if (!formData.value.yearNoSchedule && (!value || value.length === 0)) {
-        callback(new Error('请选择检验员'))
-      } else {
-        callback()
-      }
+      // 检验员改为非必选(任务单阶段才必选)
+      callback()
     },
-    trigger: 'change' 
+    trigger: 'change'
   }]
 }
 

+ 12 - 8
yudao-ui-admin-vue3/src/views/pressure2/planNew/components/PlanScheduleEquipBoilerDialog.vue

@@ -274,7 +274,7 @@
     <template #footer>
       <div class="flex justify-end">
         <el-button @click="handleCancel">取消</el-button>
-        <el-button type="primary" @click="handleConfirm">确定</el-button>
+        <el-button type="primary" :loading="submitLoading" @click="handleConfirm">确定</el-button>
       </div>
     </template>
     <!-- 费用计算弹窗 -->
@@ -342,6 +342,7 @@ const emit = defineEmits(['success', 'close'])
 const { queryCheckItemList,querySchedulingCheckItemList } = BoilerTaskOrderApi
 const dialogVisible = ref(false)
 const formRef = ref<FormInstance>()
+const submitLoading = ref(false) // 提交按钮 loading
 const checkerInRef = ref()
 const checkerOutRef = ref()
 const checkerPressureRef = ref()
@@ -779,15 +780,16 @@ const handleConfirm = async () => {
   const form = unref(formRef)
   if (!form) return
 
-  await form.validate()
+  submitLoading.value = true
+  try {
+    await form.validate()
 
-  const validations: boolean[] = []
-  validations.push(checkerInRef.value?.validate())
-  validations.push(checkerOutRef.value?.validate())
-  validations.push(checkerPressureRef.value?.validate())
-  if (validations.some(v => v === false)) return
+    const validations: boolean[] = []
+    validations.push(checkerInRef.value?.validate())
+    validations.push(checkerOutRef.value?.validate())
+    validations.push(checkerPressureRef.value?.validate())
+    if (validations.some(v => v === false)) return
 
-  try {
     // 组装新的数据结构
     const submitData: { source: number; taskList: any[] } = {
       source: 200,
@@ -881,6 +883,8 @@ const handleConfirm = async () => {
   } catch (error) {
     message.error('保存失败')
     console.error( error)
+  } finally {
+    submitLoading.value = false
   }
 }
 

+ 1 - 1
yudao-ui-admin-vue3/src/views/pressure2/planNew/pipeDetail.vue

@@ -490,7 +490,7 @@
     :selected-pipe-rows="selectedDetailRows"
     :selected-legal-list="selectedLegalList"
     :selected-year-list="selectedYearList"
-    :source="'pressure'"
+    :source="'plan'"
     @success="handleScheduleSuccess"
   />
   <PipeBatchEditForm ref="formRef" @success="handleScheduleSuccess" />