Kaynağa Gözat

pms 瑞都日报 油耗

zhangcl 4 gün önce
ebeveyn
işleme
b96e5e4bc1

+ 457 - 7
src/views/pms/iotrddailyreport/FillDailyReportForm.vue

@@ -320,6 +320,21 @@
           </el-col>
         </el-row>
 
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="当日油耗(L)" prop="dailyFuel">
+              <el-input
+                v-model="formData.dailyFuel"
+                type="text"
+                :min="0"
+                placeholder="自动计算当日油耗"
+                :readonly="isReadonlyMode"
+                @blur="formatDailyFuel"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
         <!-- 第三行:当日生产动态 -->
         <el-row>
           <el-col :span="24">
@@ -444,6 +459,87 @@
       </el-form>
     </ContentWrap>
 
+    <!-- 油耗信息区域 - 当有油耗数据时显示 -->
+    <ContentWrap class="fuel-consumption-section" v-if="formData.reportFuels && formData.reportFuels.length > 0">
+      <h2 class="text-lg font-semibold mb-4">油耗信息</h2>
+
+      <div class="fuel-consumption-table">
+        <el-table
+          :data="formData.reportFuels"
+          border
+          style="width: 100%"
+          class="fuel-consumption-el-table"
+          table-layout="fixed"
+        >
+          <!-- 车辆编码 -->
+          <el-table-column
+            prop="deviceCode"
+            label="车辆编码"
+            align="center"
+            :show-overflow-tooltip="false"
+            width="120"
+          />
+
+          <!-- 车辆名称 -->
+          <el-table-column
+            prop="deviceName"
+            label="车辆名称"
+            align="center"
+            :show-overflow-tooltip="false"
+            width="150"
+          />
+
+          <!-- 发生日期 -->
+          <el-table-column
+            label="发生日期"
+            align="center"
+            :show-overflow-tooltip="false"
+            width="120"
+          >
+            <template #default="scope">
+              {{ formatDate(scope.row.queryDate) }}
+            </template>
+          </el-table-column>
+
+          <!-- 中航北斗油耗 -->
+          <el-table-column
+            label="中航北斗油耗(L)"
+            align="center"
+            width="140"
+          >
+            <template #default="scope">
+              {{ formatNumber(scope.row.zhbdFuel, 2) }}
+            </template>
+          </el-table-column>
+
+          <!-- 实际油耗 -->
+          <el-table-column
+            label="实际油耗(L)"
+            align="center"
+            width="140"
+          >
+            <template #default="scope">
+              <!-- 编辑模式下显示输入框 -->
+              <el-input
+                v-if="!isReadonlyMode"
+                v-model="scope.row.customFuel"
+                type="text"
+                :min="0"
+                placeholder="请输入实际油耗"
+                @blur="handleCustomFuelChange(scope.row)"
+                style="width: 100%"
+                size="small"
+              />
+              <!-- 只读模式下显示数值 -->
+              <span v-else>
+            {{ formatNumber(scope.row.customFuel, 2) }}
+          </span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </ContentWrap>
+
     <!-- 平台井工作量区域 - 只在平台井的详情或审批模式下显示 -->
     <ContentWrap class="platform-workload-section" v-if="(isDetailMode || isApprovalMode) && dailyReportData?.platformWell === 1">
       <h2 class="text-lg font-semibold mb-4">平台井工作量</h2>
@@ -618,9 +714,15 @@ const formLoading = ref(false)
 const formRef = ref()
 const id = params.id // 瑞都日报id
 
+// 添加一个新的响应式变量用于输入
+const dailyFuelInput = ref('')
+
 // 日报数据
 const dailyReportData = ref<any>({})
 
+// 修改 reportFuels 的 watch,添加标志位避免自动覆盖
+const dailyFuelManuallyModified = ref(false)
+
 // 添加模式判断计算属性
 const isApprovalMode = computed(() => params.mode === 'approval')
 const isDetailMode = computed(() => params.mode === 'detail')
@@ -840,6 +942,7 @@ const formData = ref({
   rdStatus: '', // 施工状态
   deviceIds: [] as number[], // 设备ID数组
   techniqueIds: [], // 施工工艺
+  dailyFuel: '', // 当日油耗
   productionStatus: '', // 当日生产动态
   nextPlan: '', // 下步工作计划
   externalRental: '', // 外租设备
@@ -848,7 +951,8 @@ const formData = ref({
   // 添加动态字段对象
   dynamicFields: {} as Record<string, any>,
   // 附件列表
-  attachments: [] as any[]
+  attachments: [] as any[],
+  reportFuels: [] as any[] // 油耗信息数组
 })
 
 // 添加上传成功处理函数
@@ -1061,6 +1165,34 @@ const openDeviceDialog = async () => {
   }
 }
 
+// 修改格式化函数,改为失去焦点时触发
+const formatDailyFuel = () => {
+  if (!dailyFuelInput.value || dailyFuelInput.value.trim() === '') {
+    formData.value.dailyFuel = ''
+    dailyFuelInput.value = ''
+    return
+  }
+
+  // 移除非数字字符(除了小数点)
+  const cleaned = dailyFuelInput.value.replace(/[^\d.]/g, '')
+
+  // 确保只有一个小数点
+  const parts = cleaned.split('.')
+  if (parts.length > 2) {
+    dailyFuelInput.value = parts[0] + '.' + parts.slice(1).join('')
+  }
+
+  const numValue = parseFloat(dailyFuelInput.value)
+  if (!isNaN(numValue)) {
+    // 限制到两位小数
+    formData.value.dailyFuel = formatNumber(numValue, 2)
+    dailyFuelInput.value = formData.value.dailyFuel
+  } else {
+    formData.value.dailyFuel = ''
+    dailyFuelInput.value = ''
+  }
+}
+
 // 处理穿梭框变化
 const handleTransferChange = (value: number[], direction: string, movedKeys: number[]) => {
   // 可以添加额外的处理逻辑
@@ -1114,7 +1246,27 @@ const formRules = computed(() => {
   // 基础校验规则(时间节点、当日生产动态始终必填)
   const rules = {
     timeRange: [{ required: true, message: '时间节点不能为空', trigger: 'change' }],
-    productionStatus: [{ required: true, message: '当日生产动态不能为空', trigger: 'blur' }]
+    productionStatus: [{ required: true, message: '当日生产动态不能为空', trigger: 'blur' }],
+    dailyFuel: [
+      {
+        validator: (rule: any, value: any, callback: any) => {
+          if (value === '' || value === null || value === undefined) {
+            callback()
+            return
+          }
+
+          const numValue = Number(value)
+          if (isNaN(numValue)) {
+            callback(new Error('当日油耗必须是数字'))
+          } else if (numValue < 0) {
+            callback(new Error('当日油耗不能小于0'))
+          } else {
+            callback()
+          }
+        },
+        trigger: 'blur'
+      }
+    ]
   }
 
   // 非虚拟项目时,添加施工状态、施工工艺的必填校验
@@ -1228,7 +1380,15 @@ const submitForm = async () => {
     extProperty: extProperties,
     deviceIds: formData.value.deviceIds, // 设备ID集合
     // 在填报模式下也提交审批意见字段
-    opinion: isEditMode.value ? approvalForm.opinion : undefined
+    opinion: isEditMode.value ? approvalForm.opinion : undefined,
+    // 将油耗数据格式化为后端需要的格式
+    reportFuels: formData.value.reportFuels.map(fuel => ({
+      ...fuel,
+      // 确保 customFuel 是数字格式
+      customFuel: fuel.customFuel ? parseFloat(fuel.customFuel) : null
+    })),
+    // 确保当日油耗是数字格式
+    dailyFuel: formData.value.dailyFuel ? parseFloat(formData.value.dailyFuel) : 0
   }
 
   // 删除不需要复制的字段
@@ -1482,6 +1642,25 @@ watch(() => formData.value.techniqueIds, async (newTechniqueIds, oldTechniqueIds
   }
 }, { deep: true })
 
+// 监听 formData.dailyFuel 变化,同步到输入变量
+watch(() => formData.value.dailyFuel, (newVal) => {
+  if (newVal !== null && newVal !== undefined && newVal !== '') {
+    // 将数字转换为字符串显示,但不干扰输入
+    dailyFuelInput.value = String(newVal)
+  } else {
+    dailyFuelInput.value = ''
+  }
+  dailyFuelManuallyModified.value = true
+}, { immediate: true })
+
+// 监听reportFuels的变化,自动更新当日油耗
+watch(() => formData.value.reportFuels, (newFuels) => {
+  // 只有在编辑模式且用户没有手动修改过当日油耗时才自动计算
+  if (!isReadonlyMode.value) {
+    calculateAndUpdateDailyFuel();
+  }
+}, { deep: true })
+
 // 更新当前平台井的 extProperty
 const updateCurrentPlatformExtProperty = () => {
   if (!currentPlatformId.value) return
@@ -1624,6 +1803,9 @@ const initFormData = (reportData: any) => {
     techniqueIds = reportData.techniqueIds.map((id: number) => id.toString())
   }
 
+  // 计算当日油耗默认值
+  const dailyFuelDefault = calculateDailyFuel(reportData)
+
   formData.value = {
     ...formData.value,
     id: reportData.id,
@@ -1632,6 +1814,7 @@ const initFormData = (reportData: any) => {
     platformWell: reportData.platformWell,
     rdStatus: reportData.rdStatus || '',
     techniqueIds: techniqueIds,
+    dailyFuel: dailyFuelDefault, // 设置当日油耗默认值
     productionStatus: reportData.productionStatus || '',
     nextPlan: reportData.nextPlan || '',
     externalRental: reportData.externalRental || '',
@@ -1670,10 +1853,35 @@ const initFormData = (reportData: any) => {
   // 初始化设备数据
   initDeviceData(reportData)
 
-  // 如果是平台井模式且有数据,初始化 platformWellPairs 中的第一个平台井数据
-  /* if (reportData.platformWell === 1 && formData.value.platformId) {
-    loadPlatformData(formData.value.platformId)
-  } */
+  // 初始化油耗数据
+  if (reportData.reportFuels && Array.isArray(reportData.reportFuels)) {
+    // 处理每个油耗数据项,设置 customFuel 的默认值并确保格式正确
+    const processedFuels = reportData.reportFuels.map((fuel: any) => {
+      let customFuelValue;
+
+      // 如果 customFuel 不为空,确保它是字符串格式并已正确格式化
+      if (fuel.customFuel !== null && fuel.customFuel !== undefined) {
+        const numValue = parseFloat(fuel.customFuel);
+        customFuelValue = !isNaN(numValue) ? formatNumber(numValue, 2) : '0.00';
+      } else {
+        // 如果 customFuel 为空,则使用 zhbdFuel 的值
+        const zhbdValue = parseFloat(fuel.zhbdFuel);
+        customFuelValue = !isNaN(zhbdValue) ? formatNumber(zhbdValue, 2) : '0.00';
+      }
+
+      return {
+        ...fuel,
+        customFuel: customFuelValue
+      };
+    });
+
+    formData.value.reportFuels = processedFuels;
+
+    // 计算初始的当日油耗
+    calculateTotalDailyFuel();
+  } else {
+    formData.value.reportFuels = []
+  }
 
 }
 
@@ -1724,6 +1932,142 @@ const getWorkloadColumns = () => {
   return columns;
 };
 
+// 计算当日油耗的默认值
+const calculateDailyFuel = (reportData: any) => {
+  let dailyFuelValue = 0
+
+  // 如果有接口返回的dailyFuel,优先使用
+  if (reportData.dailyFuel !== null && reportData.dailyFuel !== undefined) {
+    dailyFuelValue = Number(reportData.dailyFuel)
+  }
+
+  // 如果reportFuels有数据,累加zhbdFuel的值
+  if (reportData.reportFuels && Array.isArray(reportData.reportFuels) && reportData.reportFuels.length > 0) {
+    const totalZhbdFuel = reportData.reportFuels.reduce((sum: number, item: any) => {
+      const zhbdFuelValue = Number(item.zhbdFuel) || 0
+      return sum + zhbdFuelValue
+    }, 0)
+
+    // 只有当累计值大于0时才覆盖原有的dailyFuel值
+    if (totalZhbdFuel > 0) {
+      dailyFuelValue = totalZhbdFuel
+    }
+  }
+
+  return formatNumber(dailyFuelValue, 2)
+}
+
+// 处理当日油耗输入
+const handleDailyFuelInput = () => {
+  // 确保保留两位小数
+  if (formData.value.dailyFuel !== '') {
+    const numValue = parseFloat(formData.value.dailyFuel)
+    if (!isNaN(numValue)) {
+      formData.value.dailyFuel = numValue.toFixed(2)
+    }
+  }
+}
+
+// 添加数字格式化函数
+const formatNumber = (value: any, decimalPlaces: number = 2) => {
+  if (value === null || value === undefined || value === '' || value === 'NaN') {
+    return '0.00';
+  }
+
+  // 如果已经是字符串,尝试转换为数字
+  if (typeof value === 'string') {
+    // 移除可能的非数字字符
+    const cleaned = value.replace(/[^\d.-]/g, '');
+    const num = Number(cleaned);
+    if (isNaN(num)) {
+      return '0.00';
+    }
+    return num.toFixed(decimalPlaces);
+  }
+
+  const num = Number(value);
+  if (isNaN(num)) {
+    return '0.00';
+  }
+
+  return num.toFixed(decimalPlaces)
+}
+
+// 新增:计算并更新当日油耗的方法
+const calculateAndUpdateDailyFuel = () => {
+  if (!formData.value.reportFuels || !Array.isArray(formData.value.reportFuels)) {
+    return;
+  }
+
+  // 计算所有车辆的实际油耗总和
+  const totalCustomFuel = formData.value.reportFuels.reduce((sum: number, item: any) => {
+    const customFuelValue = Number(item.customFuel) || 0;
+    return sum + customFuelValue;
+  }, 0);
+
+  // 只有当累计的实际油耗大于0时,才更新当日油耗
+  if (totalCustomFuel > 0 && !isReadonlyMode.value) {
+    formData.value.dailyFuel = formatNumber(totalCustomFuel, 2);
+    // 更新输入框显示
+    if (dailyFuelInput.value) {
+      dailyFuelInput.value = formData.value.dailyFuel;
+    }
+  }
+}
+
+// 重新计算当日油耗const formatNumber
+const calculateTotalDailyFuel = () => {
+  if (!formData.value.reportFuels || !Array.isArray(formData.value.reportFuels)) {
+    return;
+  }
+
+  // 计算所有车辆的实际油耗总和
+  const totalCustomFuel = formData.value.reportFuels.reduce((sum: number, item: any) => {
+    const customFuelValue = Number(item.customFuel) || 0;
+    return sum + customFuelValue;
+  }, 0);
+
+  // 只有当累计的实际油耗大于0时,才自动更新当日油耗
+  if (totalCustomFuel > 0 && !isReadonlyMode.value) {
+    formData.value.dailyFuel = formatNumber(totalCustomFuel, 2);
+  }
+};
+
+// 处理实际油耗变化
+const handleCustomFuelChange = (fuelItem: any) => {
+  // 获取当前输入的值
+  let value = fuelItem.customFuel;
+
+  // 如果输入为空,则重置为zhbdFuel的值
+  if (value === '' || value === null || value === undefined) {
+    fuelItem.customFuel = formatNumber(fuelItem.zhbdFuel, 2);
+    return;
+  }
+
+  // 移除非数字字符(除了小数点)
+  const cleaned = value.toString().replace(/[^\d.]/g, '');
+
+  // 确保只有一个小数点
+  const parts = cleaned.split('.');
+  let formattedValue = cleaned;
+  if (parts.length > 2) {
+    formattedValue = parts[0] + '.' + parts.slice(1).join('');
+  }
+
+  // 转换为数字并格式化为两位小数
+  const numValue = parseFloat(formattedValue);
+  if (!isNaN(numValue)) {
+    // 限制到两位小数
+    fuelItem.customFuel = formatNumber(numValue, 2);
+  } else {
+    // 如果转换失败,设置为0.00
+    fuelItem.customFuel = '0.00';
+  }
+
+  // 手动触发当日油耗的重新计算
+  calculateAndUpdateDailyFuel();
+}
+
 // 详情 审批 平台井 获取工作量值
 const getWorkloadValue = (platform, identifier) => {
   if (!platform.extProperty) return '';
@@ -2195,4 +2539,110 @@ const handleApprove = async (action: 'pass' | 'reject') => {
   width: 100%;
 }
 
+/* 油耗信息区域样式 */
+.fuel-consumption-section {
+  padding-left: 0px;
+  padding-right: 0px;
+  margin-top: 20px;
+}
+
+/* 强制表格宽度为100% */
+:deep(.fuel-consumption-el-table) {
+  width: 100% !important;
+  min-width: 100% !important;
+}
+
+/* 确保表格内部元素也充满宽度 */
+:deep(.fuel-consumption-el-table .el-table) {
+  width: 100% !important;
+  min-width: 100% !important;
+}
+
+/* 强制设置表头宽度为100% */
+:deep(.fuel-consumption-el-table .el-table__header) {
+  width: 100% !important;
+  min-width: 100% !important;
+}
+
+/* 表头不换行 */
+:deep(.fuel-consumption-el-table .el-table__header-wrapper th) {
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  background-color: #f5f7fa;
+  color: #606266;
+  font-weight: bold;
+}
+
+/* 强制设置表格主体宽度为100% */
+:deep(.fuel-consumption-el-table .el-table__body) {
+  width: 100% !important;
+  min-width: 100% !important;
+}
+
+/* 表头和表体都设置为100%宽度 */
+:deep(.fuel-consumption-el-table .el-table__header-wrapper),
+:deep(.fuel-consumption-el-table .el-table__body-wrapper) {
+  width: 100% !important;
+}
+
+/* 单元格内容居中 */
+:deep(.fuel-consumption-el-table .el-table__body-wrapper td) {
+  text-align: center;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+
+/* 实际油耗输入框样式 */
+:deep(.fuel-consumption-el-table .el-input__inner) {
+  text-align: center;
+  padding: 0 5px;
+  height: 28px;
+  line-height: 28px;
+}
+
+/* 只读模式下的数值显示 */
+.fuel-consumption-el-table .readonly-value {
+  color: #606266;
+  font-weight: normal;
+}
+
+/* 强制设置表格宽度为100% */
+:deep(.fuel-consumption-el-table .el-table) {
+  width: 100% !important;
+}
+
+/* 表格容器填满父容器 */
+.fuel-consumption-table {
+  width: 100%;
+  overflow-x: auto;
+}
+
+/* 响应式调整 */
+@media (max-width: 768px) {
+  .fuel-consumption-section {
+    padding-left: 10px;
+    padding-right: 10px;
+  }
+
+  :deep(.fuel-consumption-el-table .el-table__header-wrapper th),
+  :deep(.fuel-consumption-el-table .el-table__body-wrapper td) {
+    padding: 8px 5px;
+    font-size: 12px;
+  }
+}
+
+/* 当日油耗输入框样式优化 */
+:deep(.el-form-item .el-input-number) {
+  width: 100%;
+}
+
+/* 当日油耗字段在只读模式下的样式 */
+:deep(.is-disabled .el-input__inner[type="number"]) {
+  background-color: #f5f7fa;
+  border-color: #e4e7ed;
+  color: #606266;
+  cursor: not-allowed;
+}
 </style>