Quellcode durchsuchen

调整瑞都日报填报,日期选择

Zimo vor 2 Tagen
Ursprung
Commit
cedf368cab
1 geänderte Dateien mit 151 neuen und 120 gelöschten Zeilen
  1. 151 120
      src/views/pms/iotrddailyreport/FillDailyReportForm.vue

+ 151 - 120
src/views/pms/iotrddailyreport/FillDailyReportForm.vue

@@ -122,6 +122,8 @@ interface Data {
 }
 
 interface ReportDetail {
+  reportDate: number
+  endDateTime: number
   startTime: string
   endTime: string
   constructionDetail: string
@@ -277,12 +279,25 @@ async function loadDetail(id: number) {
     form.value.faultDowntime = data.value.faultDowntime || 0
     form.value.constructionBrief = data.value.constructionBrief || ''
 
-    form.value.reportDetails = (data.value.reportDetails || []).map((item) => ({
-      duration: item.duration || 0,
-      constructionDetail: item.constructionDetail || '',
-      startTime: formatT(item.startTime),
-      endTime: formatT(item.endTime)
-    }))
+    form.value.reportDetails = (data.value.reportDetails || []).map((item) => {
+      const startTime = formatT(item.startTime)
+      const endTime = formatT(item.endTime)
+      const reportDate = item.reportDate ?? data.value.createTime ?? dayjs().valueOf()
+      const endDateTime =
+        item.endDateTime ??
+        (startTime && endTime && dayjs(`1970-01-01 ${endTime}`).isBefore(dayjs(`1970-01-01 ${startTime}`))
+          ? dayjs(reportDate).add(1, 'day').valueOf()
+          : reportDate)
+
+      return {
+        reportDate,
+        endDateTime,
+        duration: item.duration || 0,
+        constructionDetail: item.constructionDetail || '',
+        startTime,
+        endTime
+      }
+    })
 
     if (!form.value.reportDetails.length) {
       addReportDetailRow()
@@ -611,7 +626,10 @@ const addReportDetailRow = () => {
   if (!form.value.reportDetails) {
     form.value.reportDetails = []
   }
+  const reportDate = data.value.createTime ?? dayjs().valueOf()
   form.value.reportDetails.push({
+    reportDate,
+    endDateTime: reportDate,
     startTime: '',
     endTime: '',
     duration: 0,
@@ -636,6 +654,32 @@ const handleListChange = useDebounceFn(() => {
   form.value.dailyFuel = total
 }, 500)
 
+const calculateReportDetailDuration = (row: ReportDetail) => {
+  if (!row.reportDate || !row.endDateTime || !row.startTime || !row.endTime) {
+    calculateDuration(row)
+    return
+  }
+
+  const start = dayjs(row.reportDate)
+    .hour(Number(row.startTime.split(':')[0]))
+    .minute(Number(row.startTime.split(':')[1]))
+    .second(0)
+    .millisecond(0)
+  const end = dayjs(row.endDateTime)
+    .hour(Number(row.endTime.split(':')[0]))
+    .minute(Number(row.endTime.split(':')[1]))
+    .second(0)
+    .millisecond(0)
+
+  let diffMinutes = end.diff(start, 'minute')
+
+  if (diffMinutes < 0) {
+    diffMinutes += 1440
+  }
+
+  row.duration = Number((diffMinutes / 60).toFixed(2))
+}
+
 const platformWorkloadData = computed(() => {
   if (!data.value) return []
   // 需要调整
@@ -780,8 +824,7 @@ const inContent = async (attachment) => {
 <template>
   <div
     class="bg-white rounded-xl shadow size-full flex flex-col gap-4 p-4 mb-12"
-    v-loading="loading"
-  >
+    v-loading="loading">
     <div class="flex justify-between items-start">
       <div class="flex flex-col gap-1">
         <div class="flex items-center gap-3">
@@ -791,8 +834,7 @@ const inContent = async (attachment) => {
           <div
             v-if="header.title"
             class="px-2 py-0.5 rounded text-xs font-medium border"
-            :class="statusClass"
-          >
+            :class="statusClass">
             {{ header.suffix }}
           </div>
         </div>
@@ -810,16 +852,14 @@ const inContent = async (attachment) => {
       v-if="formType !== 'edit'"
       :title="modeNotice"
       type="info"
-      :closable="false"
-    />
+      :closable="false" />
 
     <el-alert
       class="min-h-12"
       v-if="formType !== 'approval' && data.opinion"
       :title="data.opinion"
       type="warning"
-      :closable="false"
-    />
+      :closable="false" />
     <el-divider class="m-0! border-2! border-[var(--el-color-primary)]!" />
 
     <div class="grid grid-cols-3 gap-y-8 gap-x-4">
@@ -910,32 +950,26 @@ const inContent = async (attachment) => {
         <div
           v-for="(item, index) in progressList"
           :key="index"
-          class="group relative flex flex-col items-center flex-1 min-w-[160px] cursor-default select-none"
-        >
+          class="group relative flex flex-col items-center flex-1 min-w-[160px] cursor-default select-none">
           <div
             v-if="index !== progressList.length - 1"
-            class="absolute top-[34px] left-1/2 w-full h-[2px] bg-gray-100 group-hover:bg-blue-50 transition-colors duration-300"
-          >
+            class="absolute top-[34px] left-1/2 w-full h-[2px] bg-gray-100 group-hover:bg-blue-50 transition-colors duration-300">
           </div>
 
           <span
-            class="text-xs font-medium text-gray-400 mb-3 font-mono transition-colors duration-300 group-hover:text-blue-500"
-          >
+            class="text-xs font-medium text-gray-400 mb-3 font-mono transition-colors duration-300 group-hover:text-blue-500">
             {{ item.createTime || '--' }}
           </span>
 
           <div
-            class="relative z-10 mb-3 transition-transform duration-300 group-hover:-translate-y-0.5"
-          >
+            class="relative z-10 mb-3 transition-transform duration-300 group-hover:-translate-y-0.5">
             <div
-              class="w-4 h-4 rounded-full border-[3px] border-white shadow-[0_0_0_2px_rgba(229,231,235,1)] bg-blue-600 group-hover:shadow-[0_0_0_4px_rgba(219,234,254,1)] group-hover:bg-blue-500 transition-all duration-300"
-            >
+              class="w-4 h-4 rounded-full border-[3px] border-white shadow-[0_0_0_2px_rgba(229,231,235,1)] bg-blue-600 group-hover:shadow-[0_0_0_4px_rgba(219,234,254,1)] group-hover:bg-blue-500 transition-all duration-300">
             </div>
           </div>
 
           <span
-            class="text-sm font-bold text-gray-700 px-2 text-center leading-relaxed transition-colors duration-300 group-hover:text-blue-600"
-          >
+            class="text-sm font-bold text-gray-700 px-2 text-center leading-relaxed transition-colors duration-300 group-hover:text-blue-600">
             {{ item.rdStatusLabel || '未知状态' }}
           </span>
         </div>
@@ -952,15 +986,13 @@ const inContent = async (attachment) => {
       :model="form"
       require-asterisk-position="right"
       class="flex flex-col"
-      :disabled="formDisabled()"
-    >
+      :disabled="formDisabled()">
       <!-- <h3 class="text-lg font-bold text-gray-800 flex items-center gap-2">
         <div class="w-1 h-4 bg-blue-600 rounded-full"></div>
         基础信息
       </h3> -->
       <div
-        class="p-6 rounded-lg shadow border border-solid border-gray-100 grid grid-cols-2 gap-x-8"
-      >
+        class="p-6 rounded-lg shadow border border-solid border-gray-100 grid grid-cols-2 gap-x-8">
         <el-form-item label="时间节点" prop="timeRange">
           <el-time-picker
             v-model="form.timeRange"
@@ -971,8 +1003,7 @@ const inContent = async (attachment) => {
             placeholder="选择时间范围"
             clearable
             format="HH:mm"
-            value-format="HH:mm"
-          />
+            value-format="HH:mm" />
         </el-form-item>
         <el-form-item label="当日油耗(L)" prop="dailyFuel">
           <el-input-number
@@ -981,8 +1012,7 @@ const inContent = async (attachment) => {
             :controls="false"
             align="left"
             class="w-full!"
-            placeholder="请输入当日油耗"
-          >
+            placeholder="请输入当日油耗">
             <template #suffix>升(L)</template>
           </el-input-number>
         </el-form-item>
@@ -993,22 +1023,19 @@ const inContent = async (attachment) => {
             placeholder="请选择施工设备"
             clearable
             filterable
-            tag-type="primary"
-          >
+            tag-type="primary">
             <el-option
               v-for="item in deviceOptions"
               :key="item.id"
               :label="item.deviceName"
-              :value="item.id"
-            >
+              :value="item.id">
               <span class="font-medium">{{ item.deviceCode + ' - ' + item.deviceName }}</span>
             </el-option>
           </el-select>
         </el-form-item>
         <el-form-item class="col-span-2" label="闲置/未施工设备">
           <div
-            class="w-full min-h-[40px] p-3 rounded bg-gray-50 border border-gray-200 border-dashed transition-all"
-          >
+            class="w-full min-h-[40px] p-3 rounded bg-gray-50 border border-gray-200 border-dashed transition-all">
             <template v-if="noSelectedDevices.length > 0">
               <div class="flex flex-wrap gap-2">
                 <el-tag
@@ -1016,8 +1043,7 @@ const inContent = async (attachment) => {
                   :key="device.id"
                   type="info"
                   effect="plain"
-                  class="!border-gray-300"
-                >
+                  class="!border-gray-300">
                   {{ device.deviceName }}
                 </el-tag>
               </div>
@@ -1042,22 +1068,35 @@ const inContent = async (attachment) => {
 
         <el-form-item prop="reportDetails" class="col-span-2">
           <ZmTable :data="form.reportDetails" :loading="false" class="col-span-2">
-            <ZmTableColumn
-              :width="120"
-              label="日期"
-              cover-formatter
-              :real-value="
-                () => (data.createTime ? dayjs(data.createTime).format('YYYY-MM-DD') : '')
-              "
-            />
+            <ZmTableColumn :width="160" label="开始日期" prop="reportDate">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  v-if="$index >= 0"
+                  class="mb-0!"
+                  :prop="`reportDetails.${$index}.reportDate`"
+                  :rules="{
+                    required: true,
+                    message: '请选择开始日期',
+                    trigger: ['change', 'blur'],
+                    type: 'number'
+                  }">
+                  <el-date-picker
+                    v-model="row.reportDate"
+                    placeholder="选择开始日期"
+                    clearable
+                    value-format="x"
+                    class="w-full!"
+                    @change="calculateReportDetailDuration(row)" />
+                </el-form-item>
+              </template>
+            </ZmTableColumn>
             <ZmTableColumn :width="160" label="开始时间" prop="startTime">
               <template #default="{ row, $index }">
                 <el-form-item
                   v-if="$index >= 0"
                   class="mb-0!"
                   :prop="`reportDetails.${$index}.startTime`"
-                  :rules="{ required: true, message: '请选择开始时间', trigger: 'change' }"
-                >
+                  :rules="{ required: true, message: '请选择开始时间', trigger: 'change' }">
                   <el-time-picker
                     v-model="row.startTime"
                     placeholder="选择开始时间"
@@ -1065,8 +1104,29 @@ const inContent = async (attachment) => {
                     format="HH:mm"
                     value-format="HH:mm"
                     class="w-full!"
-                    @change="calculateDuration(row)"
-                  />
+                    @change="calculateReportDetailDuration(row)" />
+                </el-form-item>
+              </template>
+            </ZmTableColumn>
+            <ZmTableColumn :width="160" label="结束日期" prop="endDateTime">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  v-if="$index >= 0"
+                  class="mb-0!"
+                  :prop="`reportDetails.${$index}.endDateTime`"
+                  :rules="{
+                    required: true,
+                    message: '请选择结束日期',
+                    trigger: ['change', 'blur'],
+                    type: 'number'
+                  }">
+                  <el-date-picker
+                    v-model="row.endDateTime"
+                    placeholder="选择结束日期"
+                    clearable
+                    value-format="x"
+                    class="w-full!"
+                    @change="calculateReportDetailDuration(row)" />
                 </el-form-item>
               </template>
             </ZmTableColumn>
@@ -1076,8 +1136,7 @@ const inContent = async (attachment) => {
                   v-if="$index >= 0"
                   class="mb-0!"
                   :prop="`reportDetails.${$index}.endTime`"
-                  :rules="{ required: true, message: '请选择结束时间', trigger: 'change' }"
-                >
+                  :rules="{ required: true, message: '请选择结束时间', trigger: 'change' }">
                   <el-time-picker
                     v-model="row.endTime"
                     placeholder="选择结束时间"
@@ -1085,8 +1144,7 @@ const inContent = async (attachment) => {
                     format="HH:mm"
                     value-format="HH:mm"
                     class="w-full!"
-                    @change="calculateDuration(row)"
-                  />
+                    @change="calculateReportDetailDuration(row)" />
                 </el-form-item>
               </template>
             </ZmTableColumn>
@@ -1097,8 +1155,7 @@ const inContent = async (attachment) => {
                   v-if="$index >= 0"
                   class="mb-0!"
                   :prop="`reportDetails.${$index}.constructionDetail`"
-                  :rules="{ required: true, message: '请输入施工详情', trigger: 'change' }"
-                >
+                  :rules="{ required: true, message: '请输入施工详情', trigger: 'change' }">
                   <el-input
                     v-model="row.constructionDetail"
                     placeholder="输入施工详情"
@@ -1106,8 +1163,7 @@ const inContent = async (attachment) => {
                     :autosize="{ minRows: 1 }"
                     show-word-limit
                     :maxlength="2000"
-                    class="w-full!"
-                  />
+                    class="w-full!" />
                 </el-form-item>
               </template>
             </ZmTableColumn>
@@ -1129,8 +1185,7 @@ const inContent = async (attachment) => {
             resize="none"
             show-word-limit
             :maxlength="1000"
-            placeholder="请输入下步工作计划"
-          />
+            placeholder="请输入下步工作计划" />
         </el-form-item>
         <el-form-item class="col-span-2" label="外租设备" prop="externalRental">
           <el-input
@@ -1140,8 +1195,7 @@ const inContent = async (attachment) => {
             resize="none"
             show-word-limit
             :maxlength="1000"
-            placeholder="请输入外租设备"
-          />
+            placeholder="请输入外租设备" />
         </el-form-item>
         <el-form-item class="col-span-2" label="故障情况" prop="malfunction">
           <el-input
@@ -1151,8 +1205,7 @@ const inContent = async (attachment) => {
             show-word-limit
             resize="none"
             :maxlength="1000"
-            placeholder="请输入故障情况"
-          />
+            placeholder="请输入故障情况" />
         </el-form-item>
         <el-form-item label="故障误工(H)" prop="faultDowntime">
           <el-input-number
@@ -1160,8 +1213,7 @@ const inContent = async (attachment) => {
             :min="0"
             :controls="false"
             align="left"
-            class="w-full!"
-          >
+            class="w-full!">
             <template #suffix>小时(H)</template>
           </el-input-number>
         </el-form-item>
@@ -1172,16 +1224,14 @@ const inContent = async (attachment) => {
             ref="fileUploadRef"
             :device-id="undefined"
             :show-folder-button="false"
-            @upload-success="handleUploadSuccess"
-          />
+            @upload-success="handleUploadSuccess" />
 
           <div v-if="form.attachments && form.attachments.length > 0" class="attachment-container">
             <div class="attachment-list">
               <div
                 v-for="(attachment, index) in form.attachments"
                 :key="attachment.id || index"
-                class="attachment-item"
-              >
+                class="attachment-item">
                 <a class="attachment-name" @click="inContent(attachment)">
                   {{ attachment.filename }}
                 </a>
@@ -1190,8 +1240,7 @@ const inContent = async (attachment) => {
                   type="danger"
                   link
                   size="small"
-                  @click="removeAttachment(index)"
-                >
+                  @click="removeAttachment(index)">
                   删除
                 </el-button>
               </div>
@@ -1216,14 +1265,12 @@ const inContent = async (attachment) => {
           collapse-tags
           collapse-tags-tooltip
           :max-collapse-tags="5"
-          tag-type="primary"
-        />
+          tag-type="primary" />
       </el-form-item>
       <template v-for="(pid, pindex) in form.platformIds" :key="pid">
         <el-divider v-if="pindex !== 0" class="my-6 border-2! border-[var(--el-color-primary)]!" />
         <div
-          class="p-6 rounded-lg shadow border border-solid border-gray-100 grid grid-cols-4 gap-x-8"
-        >
+          class="p-6 rounded-lg shadow border border-solid border-gray-100 grid grid-cols-4 gap-x-8">
           <h3 class="text-lg font-bold text-gray-800 flex items-center gap-2 col-span-4 mb-6">
             <div class="w-1 h-4 bg-blue-600 rounded-full"></div>
             {{ wellOptions.find((item) => item.value === pid)?.label ?? data.wellName ?? '' }}
@@ -1232,15 +1279,13 @@ const inContent = async (attachment) => {
             label="施工状态"
             :prop="`${pid}.rdStatus`"
             :rules="{ required: true, message: '请选择施工状态', trigger: 'change' }"
-            class="col-span-2"
-          >
+            class="col-span-2">
             <el-select
               v-model="form[pid].rdStatus"
               :options="rdStatusOptions"
               placeholder="请选择"
               class="w-full"
-              clearable
-            />
+              clearable />
           </el-form-item>
 
           <el-form-item
@@ -1252,8 +1297,7 @@ const inContent = async (attachment) => {
               trigger: 'change',
               type: 'array'
             }"
-            class="col-span-2"
-          >
+            class="col-span-2">
             <el-select
               v-model="form[pid].techniqueIds"
               :options="techniqueOptions"
@@ -1263,8 +1307,7 @@ const inContent = async (attachment) => {
               placeholder="请选择"
               class="w-full"
               @change="(val) => handleTechniqueChange(val, pid)"
-              clearable
-            />
+              clearable />
           </el-form-item>
 
           <template v-if="form[pid] && form[pid].extProperty">
@@ -1277,16 +1320,14 @@ const inContent = async (attachment) => {
                 attr.required === 1
                   ? [{ required: true, message: `请输入${attr.name}`, trigger: 'blur' }]
                   : []
-              "
-            >
+              ">
               <el-input-number
                 v-if="attr.dataType === 'double'"
                 v-model="attr.actualValue"
                 :controls="false"
                 class="w-full!"
                 align="left"
-                placeholder="请输入"
-              />
+                placeholder="请输入" />
               <el-input type="textarea" v-else v-model="attr.actualValue" placeholder="请输入" />
             </el-form-item>
           </template>
@@ -1300,8 +1341,7 @@ const inContent = async (attachment) => {
             :key="field.key"
             :label="field.label"
             :prop="`${pid}.${field.key}`"
-            :rules="noProductionTimeRule(pid)"
-          >
+            :rules="noProductionTimeRule(pid)">
             <el-input-number
               v-model="form[pid][field.key]"
               :min="0"
@@ -1310,8 +1350,7 @@ const inContent = async (attachment) => {
               class="w-full!"
               align="left"
               @blur="handleRowValidate(pid, field.key)"
-              :disabled="formDisabled(field.key)"
-            >
+              :disabled="formDisabled(field.key)">
               <template #suffix>小时(H)</template>
             </el-input-number>
           </el-form-item>
@@ -1324,8 +1363,7 @@ const inContent = async (attachment) => {
               required: form[pid].otherNptTime > 0,
               message: '请填写原因',
               trigger: ['blur', 'change']
-            }"
-          >
+            }">
             <el-input
               v-model="form[pid].otherNptReason"
               type="textarea"
@@ -1334,8 +1372,7 @@ const inContent = async (attachment) => {
               show-word-limit
               :maxlength="1000"
               placeholder="当'其他非生产时间'大于0时必填"
-              :disabled="formDisabled('otherNptReason')"
-            />
+              :disabled="formDisabled('otherNptReason')" />
           </el-form-item>
         </div>
       </template>
@@ -1351,8 +1388,7 @@ const inContent = async (attachment) => {
             type: 'string',
             trigger: ['blur', 'change']
           }
-        ]"
-      >
+        ]">
         <el-input
           v-model="form.constructionBrief"
           type="textarea"
@@ -1361,8 +1397,7 @@ const inContent = async (attachment) => {
           resize="none"
           :maxlength="1000"
           placeholder="请输入当日施工简报"
-          :disabled="formDisabled('constructionBrief')"
-        />
+          :disabled="formDisabled('constructionBrief')" />
       </el-form-item>
 
       <el-divider class="my-6 border-2! border-[var(--el-color-primary)]!" />
@@ -1380,8 +1415,7 @@ const inContent = async (attachment) => {
           prop="queryDate"
           :width="110"
           cover-formatter
-          :real-value="(row) => (row.queryDate ? dayjs(row.queryDate).format('YYYY-MM-DD') : '')"
-        />
+          :real-value="(row) => (row.queryDate ? dayjs(row.queryDate).format('YYYY-MM-DD') : '')" />
         <ZmTableColumn label="中航北斗油耗(L)" :width="140" prop="zhbdFuel" />
         <ZmTableColumn label="实际油耗(L)" prop="customFuel">
           <template #default="{ row, $index }">
@@ -1392,8 +1426,7 @@ const inContent = async (attachment) => {
                 :controls="false"
                 class="w-full!"
                 align="left"
-                @input="handleListChange"
-              >
+                @input="handleListChange">
                 <template #suffix> L </template>
               </el-input-number>
             </el-form-item>
@@ -1418,8 +1451,7 @@ const inContent = async (attachment) => {
               :label="label"
               :prop="prop"
               cover-formatter
-              :real-value="(row) => getWorkloadValue(row, prop)"
-            />
+              :real-value="(row) => getWorkloadValue(row, prop)" />
           </template>
         </ZmTable>
       </template>
@@ -1436,24 +1468,21 @@ const inContent = async (attachment) => {
             show-word-limit
             :maxlength="1000"
             placeholder="请输入审批意见"
-            :disabled="formDisabled('opinion')"
-          />
+            :disabled="formDisabled('opinion')" />
         </el-form-item>
       </template>
     </el-form>
   </div>
 
   <div
-    class="h-16 z-10 flex items-center justify-end px-6 shadow bg-white absolute bottom-0 left-0 w-full border-solid border-0 border-t-1 border-gray-200"
-  >
+    class="h-16 z-10 flex items-center justify-end px-6 shadow bg-white absolute bottom-0 left-0 w-full border-solid border-0 border-t-1 border-gray-200">
     <div v-if="formType === 'edit' || formType === 'time'">
       <el-button
         size="default"
         type="primary"
         @click="submitForm"
         :disabled="formDisabled('button')"
-        :loading="formLoading"
-      >
+        :loading="formLoading">
         确 定
       </el-button>
       <el-button size="default" @click="handleCancel">取 消</el-button>
@@ -1465,8 +1494,7 @@ const inContent = async (attachment) => {
         type="primary"
         @click="submitApprovalForm(20)"
         :disabled="formDisabled('button')"
-        :loading="formLoading"
-      >
+        :loading="formLoading">
         审批通过
       </el-button>
       <el-button
@@ -1474,12 +1502,15 @@ const inContent = async (attachment) => {
         type="danger"
         @click="submitApprovalForm(30)"
         :disabled="formDisabled('button')"
-        :loading="formLoading"
-      >
+        :loading="formLoading">
         审批拒绝
       </el-button>
       <el-button size="default" @click="handleCancel">取 消</el-button>
     </div>
+
+    <div v-if="formType === 'detail'">
+      <el-button size="default" @click="handleCancel">返 回</el-button>
+    </div>
   </div>
 </template>