Sfoglia il codice sorgente

fix: 修复设备搬迁日报明细校验下标异常

- 为施工动态明细行增加前端临时 key
- 根据明细行 key 回查真实数组下标,不再依赖表格插槽的 $index
- 修复校验字段生成 improveReportDetails.-1 导致提交报错的问题
- 删除明细时按行 key 定位数据,并保留至少一条明细
- 提交新增或修改时剔除前端临时 key,避免传给后端
- 保留修改模式保存时传递 modifyFlag: "Y" 的逻辑
Zimo 2 giorni fa
parent
commit
ac51674fe5
1 ha cambiato i file con 45 aggiunte e 11 eliminazioni
  1. 45 11
      src/views/pms/iotrydailyreport/components/equipment-form.vue

+ 45 - 11
src/views/pms/iotrydailyreport/components/equipment-form.vue

@@ -23,6 +23,7 @@ interface EquipmentReportForm {
 }
 
 interface ImproveReportDetail {
+  detailKey?: string
   projectName: string
   constructionDetail: string
   nextPlan: string
@@ -70,6 +71,8 @@ const auditStatusMap = {
   40: { label: '已取消', type: 'info' }
 } as const
 
+let detailKeySeed = 0
+
 const rules: FormRules = {
   title: [{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }],
   createTime: [{ required: true, message: '请选择汇报时间', trigger: ['blur', 'change'] }],
@@ -103,12 +106,18 @@ function getAuditStatus(status?: number) {
 
 function createDefaultDetail(): ImproveReportDetail {
   return {
+    detailKey: createDetailKey(),
     projectName: '',
     constructionDetail: '',
     nextPlan: ''
   }
 }
 
+function createDetailKey() {
+  detailKeySeed += 1
+  return `detail-${Date.now()}-${detailKeySeed}`
+}
+
 function getDefaultDetails() {
   return [createDefaultDetail()]
 }
@@ -119,12 +128,32 @@ function normalizeDetails(details?: ImproveReportDetail[]) {
   }
 
   return details.map((item) => ({
+    detailKey: item.detailKey || createDetailKey(),
     projectName: item.projectName || '',
     constructionDetail: item.constructionDetail || '',
     nextPlan: item.nextPlan || ''
   }))
 }
 
+function resolveDetailIndex(row: ImproveReportDetail) {
+  const index = form.value.improveReportDetails.findIndex(
+    (item) => item.detailKey === row.detailKey
+  )
+  return index >= 0 ? index : 0
+}
+
+function getDetailFieldProp(row: ImproveReportDetail, field: keyof ImproveReportDetail) {
+  return `improveReportDetails.${resolveDetailIndex(row)}.${field}`
+}
+
+function getDetailRowKey(row: ImproveReportDetail) {
+  return row.detailKey || ''
+}
+
+function getSubmitDetails(details: ImproveReportDetail[]) {
+  return details.map(({ detailKey: _detailKey, ...item }) => item)
+}
+
 function toFormData(row?: any): EquipmentReportForm {
   if (!row) return { ...defaultForm, improveReportDetails: getDefaultDetails() }
 
@@ -173,12 +202,12 @@ function addImproveReportDetail() {
   form.value.improveReportDetails.push(createDefaultDetail())
 }
 
-function removeImproveReportDetail(index: number) {
+function removeImproveReportDetail(row: ImproveReportDetail) {
   if (form.value.improveReportDetails.length <= 1) {
     return
   }
 
-  form.value.improveReportDetails.splice(index, 1)
+  form.value.improveReportDetails.splice(resolveDetailIndex(row), 1)
 }
 
 async function submitForm() {
@@ -188,7 +217,11 @@ async function submitForm() {
     formLoading.value = true
     await formRef.value.validate()
 
-    const data = { ...form.value, createTime: Number(form.value.createTime) }
+    const data = {
+      ...form.value,
+      createTime: Number(form.value.createTime),
+      improveReportDetails: getSubmitDetails(form.value.improveReportDetails)
+    }
 
     if (data.id) {
       await IotRyImproveDailyReportApi.updateIotRyImproveDailyReport({
@@ -355,14 +388,15 @@ defineExpose({ handleOpenForm })
               :data="form.improveReportDetails"
               :loading="false"
               class="detail-table"
+              :row-key="getDetailRowKey"
               :show-border="true"
               :show-overflow-tooltip="false">
               <ZmTableColumn label="项目名称" prop="projectName" :width="220">
-                <template #default="{ row, $index }">
+                <template #default="{ row }">
                   <el-form-item
                     class="mb-0!"
                     :show-message="false"
-                    :prop="`improveReportDetails.${$index}.projectName`"
+                    :prop="getDetailFieldProp(row, 'projectName')"
                     :rules="{
                       required: true,
                       message: '请输入项目名称',
@@ -378,11 +412,11 @@ defineExpose({ handleOpenForm })
               </ZmTableColumn>
 
               <ZmTableColumn label="施工动态" min-width="280">
-                <template #default="{ row, $index }">
+                <template #default="{ row }">
                   <el-form-item
                     class="mb-0!"
                     :show-message="false"
-                    :prop="`improveReportDetails.${$index}.constructionDetail`"
+                    :prop="getDetailFieldProp(row, 'constructionDetail')"
                     :rules="{
                       required: true,
                       message: '请输入施工动态',
@@ -401,11 +435,11 @@ defineExpose({ handleOpenForm })
               </ZmTableColumn>
 
               <ZmTableColumn label="下步计划" min-width="240">
-                <template #default="{ row, $index }">
+                <template #default="{ row }">
                   <el-form-item
                     class="mb-0!"
                     :show-message="false"
-                    :prop="`improveReportDetails.${$index}.nextPlan`"
+                    :prop="getDetailFieldProp(row, 'nextPlan')"
                     :rules="{
                       required: true,
                       message: '请输入下步计划',
@@ -424,12 +458,12 @@ defineExpose({ handleOpenForm })
               </ZmTableColumn>
 
               <ZmTableColumn label="操作" width="90" fixed="right">
-                <template #default="{ $index }">
+                <template #default="{ row }">
                   <el-button
                     link
                     type="danger"
                     :icon="Delete"
-                    @click="removeImproveReportDetail($index)"
+                    @click="removeImproveReportDetail(row)"
                     :disabled="mainFieldDisabled || form.improveReportDetails.length <= 1">
                     删除
                   </el-button>