yanghao 1 giorno fa
parent
commit
54f1313e1d
29 ha cambiato i file con 717 aggiunte e 13981 eliminazioni
  1. 1 0
      package.json
  2. 30 0
      pnpm-lock.yaml
  3. 2 1
      src/layout/components/Menu/src/components/useRenderMenuItem.tsx
  4. 6 0
      src/views/pms/iotrddailyreport/FillDailyReportForm.vue
  5. 0 3271
      src/views/pms/iotrddailyreport/FillDailyReportForm1.vue
  6. 9 1
      src/views/pms/iotrddailyreport/create-rd-form.vue
  7. 0 544
      src/views/pms/iotrddailyreport/fillDailyReport1.vue
  8. 1 7
      src/views/pms/iotrddailyreport/index.vue
  9. 0 996
      src/views/pms/iotrddailyreport/index1.vue
  10. 0 782
      src/views/pms/iotrddailyreport/statistics1.vue
  11. 0 669
      src/views/pms/iotrhdailyreport/approval1.vue
  12. 0 674
      src/views/pms/iotrhdailyreport/fill1.vue
  13. 11 10
      src/views/pms/iotrhdailyreport/index.vue
  14. 0 1339
      src/views/pms/iotrhdailyreport/index1.vue
  15. 127 71
      src/views/pms/iotrhdailyreport/summary.vue
  16. 0 724
      src/views/pms/iotrydailyreport/approval1.vue
  17. 0 724
      src/views/pms/iotrydailyreport/fill1.vue
  18. 18 17
      src/views/pms/iotrydailyreport/index.vue
  19. 0 1169
      src/views/pms/iotrydailyreport/index1.vue
  20. 2 2
      src/views/pms/iotrydailyreport/ry-form.vue
  21. 1 7
      src/views/pms/iotrydailyreport/ry-table.vue
  22. 1 7
      src/views/pms/iotrydailyreport/ry-xj-table.vue
  23. 128 73
      src/views/pms/iotrydailyreport/summary.vue
  24. 0 723
      src/views/pms/iotrydailyreport/xapproval1.vue
  25. 0 730
      src/views/pms/iotrydailyreport/xfill1.vue
  26. 25 24
      src/views/pms/iotrydailyreport/xjindex.vue
  27. 0 1265
      src/views/pms/iotrydailyreport/xjindex1.vue
  28. 127 71
      src/views/pms/iotrydailyreport/xsummary.vue
  29. 228 80
      src/views/test/index.vue

+ 1 - 0
package.json

@@ -25,6 +25,7 @@
     "lint:lint-staged": "lint-staged -c "
   },
   "dependencies": {
+    "@antv/x6": "^3.1.6",
     "@element-plus/icons-vue": "^2.1.0",
     "@form-create/designer": "^3.2.6",
     "@form-create/element-ui": "^3.2.11",

+ 30 - 0
pnpm-lock.yaml

@@ -8,6 +8,9 @@ importers:
 
   .:
     dependencies:
+      '@antv/x6':
+        specifier: ^3.1.6
+        version: 3.1.6
       '@element-plus/icons-vue':
         specifier: ^2.1.0
         version: 2.3.1(vue@3.5.12(typescript@5.3.3))
@@ -433,6 +436,10 @@ packages:
   '@antfu/utils@0.7.10':
     resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
 
+  '@antv/x6@3.1.6':
+    resolution: {integrity: sha512-M/kWetMQ+0CbozONh6OQg5UgbN7SZ4GnNWiNxZQXBHfxjYCDk/rfXPD+CfZeePSvUDabTpRxGOu3obGu/vu06g==}
+    engines: {node: '>=20.0.0'}
+
   '@babel/code-frame@7.26.2':
     resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
     engines: {node: '>=6.9.0'}
@@ -3196,6 +3203,9 @@ packages:
     resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
     engines: {node: '>=6.0.0'}
 
+  dom-align@1.12.4:
+    resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==}
+
   dom-serializer@2.0.0:
     resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
 
@@ -4292,6 +4302,9 @@ packages:
       '@vueuse/core': '>=10.0.0'
       vue: '>=3.0.0'
 
+  mousetrap@1.6.5:
+    resolution: {integrity: sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==}
+
   mpd-parser@0.22.1:
     resolution: {integrity: sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==}
     hasBin: true
@@ -5274,6 +5287,10 @@ packages:
   util-deprecate@1.0.2:
     resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
 
+  utility-types@3.11.0:
+    resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==}
+    engines: {node: '>= 4'}
+
   uuid@10.0.0:
     resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
     hasBin: true
@@ -5628,6 +5645,13 @@ snapshots:
 
   '@antfu/utils@0.7.10': {}
 
+  '@antv/x6@3.1.6':
+    dependencies:
+      dom-align: 1.12.4
+      lodash-es: 4.17.21
+      mousetrap: 1.6.5
+      utility-types: 3.11.0
+
   '@babel/code-frame@7.26.2':
     dependencies:
       '@babel/helper-validator-identifier': 7.25.9
@@ -8886,6 +8910,8 @@ snapshots:
     dependencies:
       esutils: 2.0.3
 
+  dom-align@1.12.4: {}
+
   dom-serializer@2.0.0:
     dependencies:
       domelementtype: 2.3.0
@@ -10021,6 +10047,8 @@ snapshots:
       - react
       - react-dom
 
+  mousetrap@1.6.5: {}
+
   mpd-parser@0.22.1:
     dependencies:
       '@babel/runtime': 7.26.0
@@ -11025,6 +11053,8 @@ snapshots:
 
   util-deprecate@1.0.2: {}
 
+  utility-types@3.11.0: {}
+
   uuid@10.0.0: {}
 
   v3-jsoneditor@0.0.6:

+ 2 - 1
src/layout/components/Menu/src/components/useRenderMenuItem.tsx

@@ -47,7 +47,8 @@ export const useRenderMenuItem = () =>
                 '台账管理',
                 '证书管理',
                 '危险源管理',
-                '环境因素识别'
+                '环境因素识别',
+                '事故事件上报'
               ].includes(v.meta?.title)
             )
           } else {

+ 6 - 0
src/views/pms/iotrddailyreport/FillDailyReportForm.vue

@@ -72,6 +72,7 @@ interface Data {
   finishedPlatforms: Platform[]
   taskId: number
   wellName: string
+  submitterNames: string
   constructionStartDate: number
   manufactureName: string
   contractName: string
@@ -898,6 +899,11 @@ const inContent = async (attachment) => {
         <div>{{ data.responsiblePersonNames || '-' }}</div>
       </div>
 
+      <div class="info-item">
+        <label>填报人</label>
+        <div>{{ data.submitterNames || '-' }}</div>
+      </div>
+
       <div class="info-item col-span-3">
         <label>设备配置</label>
         <div>{{ data.deviceNames || '-' }}</div>

+ 0 - 3271
src/views/pms/iotrddailyreport/FillDailyReportForm1.vue

@@ -1,3271 +0,0 @@
-<template>
-  <ContentWrap v-loading="formLoading">
-    <!-- 第一部分:日报标题 -->
-    <div class="daily-report-title">
-      <h2>{{ pageTitle }}</h2>
-      <!-- 在审批模式下显示审批状态提示 -->
-      <div v-if="isReadonlyMode" class="approval-notice">
-        <el-alert :title="modeNotice" type="info" :closable="false" />
-      </div>
-    </div>
-
-    <!-- 第二部分:项目/任务信息 -->
-    <ContentWrap>
-      <div class="info-table" style="margin-top: 1em">
-        <!-- 表格行 -->
-        <div class="table-row">
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">甲方:</span>
-              <!-- 甲方字段:添加 single-line-ellipsis 类 + title 绑定完整内容 -->
-              <span
-                class="cell-value single-line-ellipsis"
-                :title="dailyReportData.manufactureName || '-'"
-              >
-                {{ dailyReportData.manufactureName || '-' }}
-              </span>
-            </div>
-          </div>
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">合同号:</span>
-              <span class="cell-value">{{ dailyReportData.contractName || '-' }}</span>
-            </div>
-          </div>
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">井号:</span>
-              <span class="cell-value">{{
-                displayWellName || dailyReportData.taskName || '-'
-              }}</span>
-            </div>
-          </div>
-        </div>
-
-        <div class="table-row">
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">施工队伍:</span>
-              <span class="cell-value">{{ dailyReportData.deptName || '-' }}</span>
-            </div>
-          </div>
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">施工地点:</span>
-              <span class="cell-value">{{ dailyReportData.location || '-' }}</span>
-            </div>
-          </div>
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">工艺:</span>
-              <span class="cell-value">{{ dailyReportData.techniqueNames || '-' }}</span>
-            </div>
-          </div>
-        </div>
-
-        <div class="table-row">
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">设计工作量:</span>
-              <span class="cell-value">{{ dailyReportData.workloadDesign || '-' }}</span>
-            </div>
-          </div>
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">开工日期:</span>
-              <span class="cell-value">{{ dailyReportData.commencementDate || '-' }}</span>
-            </div>
-          </div>
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">完工日期:</span>
-              <span class="cell-value">{{ dailyReportData.completionDate || '-' }}</span>
-            </div>
-          </div>
-        </div>
-
-        <div class="table-row">
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">施工周期D:</span>
-              <span class="cell-value">{{ dailyReportData.constructionPeriod || '' }}</span>
-            </div>
-          </div>
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">停待时间D:</span>
-              <span class="cell-value">{{ dailyReportData.idleTime || '' }}</span>
-            </div>
-          </div>
-          <div class="table-cell">
-            <div class="cell-content">
-              <span class="cell-label">带班干部:</span>
-              <span class="cell-value">{{ dailyReportData.responsiblePersonNames || '-' }}</span>
-            </div>
-          </div>
-        </div>
-
-        <!-- 第五行:设备配置(单独一行) -->
-        <div class="table-row">
-          <div class="table-cell full-width">
-            <div class="cell-content">
-              <span class="cell-label">设备配置:</span>
-              <span class="cell-value indent-multiline">{{
-                dailyReportData.deviceNames || '-'
-              }}</span>
-            </div>
-          </div>
-        </div>
-      </div>
-    </ContentWrap>
-
-    <!-- 实际进度显示区域(新增) -->
-    <ContentWrap class="section-padding" v-if="showActualProgress">
-      <h3 class="progress-title">任务进度</h3>
-      <div class="actual-progress-container">
-        <div v-if="actualProgressData.length > 0">
-          <el-steps
-            direction="horizontal"
-            :active="actualProgressData.length - 1"
-            finish-status="success"
-          >
-            <el-step
-              v-for="(step, index) in actualProgressData"
-              :key="index"
-              :title="step.title"
-              :description="step.description"
-              :status="step.status"
-            />
-          </el-steps>
-        </div>
-        <div v-else class="no-progress-data"> 暂无实际进度数据 </div>
-      </div>
-    </ContentWrap>
-
-    <!-- 第三部分:日报填报表单 -->
-    <ContentWrap class="section-padding">
-      <el-form
-        ref="formRef"
-        :model="formData"
-        :rules="isReadonlyMode ? {} : formRules"
-        v-loading="formLoading"
-        style="margin-top: 1em"
-        label-width="200px"
-        :disabled="isReadonlyMode"
-      >
-        <!-- 第一行:时间节点、施工状态 -->
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="时间节点" prop="timeRange">
-              <el-time-picker
-                is-range
-                v-model="formData.timeRange"
-                range-separator="至"
-                start-placeholder="开始时间"
-                end-placeholder="结束时间"
-                placeholder="选择时间范围"
-                style="width: 100%"
-                :readonly="isReadonlyMode"
-                :disabled="isReadonlyMode"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="施工状态" prop="rdStatus">
-              <el-select
-                v-model="formData.rdStatus"
-                placeholder="请选择施工状态"
-                style="width: 100%"
-                :disabled="isReadonlyMode"
-              >
-                <el-option
-                  v-for="dict in rdStatusOptions"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 平台井 -->
-        <el-row v-if="showPlatformField">
-          <el-col :span="24">
-            <el-form-item label="平台井" prop="platformId">
-              <el-select
-                v-model="formData.platformId"
-                placeholder="请选择平台井"
-                style="width: 100%"
-                :disabled="isReadonlyMode && query.istime !== 'true'"
-              >
-                <el-option
-                  v-for="platform in platformOptions"
-                  :key="platform.id"
-                  :label="platform.wellName"
-                  :value="platform.id"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 施工设备字段 -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="施工设备" prop="deviceIds">
-              <!-- 编辑模式:显示选择按钮 -->
-              <template v-if="isEditMode">
-                <el-button
-                  @click="openDeviceDialog"
-                  type="primary"
-                  size="small"
-                  :disabled="formLoading || isReadonlyMode"
-                >
-                  选择设备
-                </el-button>
-                <el-tooltip
-                  v-if="formData.deviceIds && formData.deviceIds.length > 0"
-                  :content="getAllDeviceNamesForDisplay"
-                  placement="top"
-                >
-                  <span class="device-display-container">
-                    {{ formatDevicesForDisplay }}
-                  </span>
-                </el-tooltip>
-                <span v-else class="no-device"> 未选择设备 </span>
-              </template>
-
-              <!-- 只读模式:只显示设备信息 -->
-              <template v-else>
-                <el-tooltip
-                  v-if="formData.deviceIds && formData.deviceIds.length > 0"
-                  :content="getAllDeviceNamesForDisplay"
-                  placement="top"
-                >
-                  <span class="device-display-container">
-                    {{ formatDevicesForDisplay }}
-                  </span>
-                </el-tooltip>
-                <span v-else class="no-device">-</span>
-              </template>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 未施工设备 -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="未施工设备" prop="unSelectedDeviceNames">
-              <el-input
-                v-model="unSelectedDeviceNames"
-                type="textarea"
-                :rows="2"
-                placeholder="未施工的设备将显示在这里"
-                :readonly="true"
-                class="unselected-device"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 第二行:施工工艺 -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="施工工艺" prop="techniqueIds">
-              <el-select
-                v-model="formData.techniqueIds"
-                placeholder="请选择施工工艺"
-                style="width: 100%"
-                multiple
-                :disabled="isReadonlyMode"
-              >
-                <el-option
-                  v-for="dict in techniqueOptions"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 动态属性区域:施工工艺与当日生产动态之间 -->
-        <el-row v-if="dynamicAttrs.length > 0" :gutter="30">
-          <el-col
-            v-for="attr in dynamicAttrs"
-            :key="attr.id"
-            :span="attr.dataType === 'textarea' ? 24 : 12"
-          >
-            <el-form-item
-              :label="attr.name + (attr.unit ? `(${attr.unit})` : '')"
-              :prop="'dynamicFields.' + attr.identifier"
-              :rules="isReadonlyMode ? [] : getDynamicAttrRules(attr)"
-            >
-              <!-- 文本类型 -->
-              <el-input
-                v-if="attr.dataType === 'text'"
-                v-model="formData.dynamicFields[attr.identifier]"
-                :placeholder="`请输入${attr.name}`"
-                :readonly="isReadonlyMode"
-              />
-
-              <!-- 文本域类型 -->
-              <el-input
-                v-else-if="attr.dataType === 'textarea'"
-                v-model="formData.dynamicFields[attr.identifier]"
-                :placeholder="`请输入${attr.name}`"
-                type="textarea"
-                :rows="3"
-                :readonly="isReadonlyMode"
-              />
-
-              <!-- 数字类型 -->
-              <el-input
-                v-else-if="attr.dataType === 'double'"
-                v-model="formData.dynamicFields[attr.identifier]"
-                :placeholder="`请输入${attr.name}`"
-                type="number"
-                :min="attr.minValue || undefined"
-                :max="attr.maxValue || undefined"
-                :readonly="isReadonlyMode"
-              />
-
-              <!-- 日期类型 -->
-              <el-date-picker
-                v-else-if="attr.dataType === 'date'"
-                v-model="formData.dynamicFields[attr.identifier]"
-                type="date"
-                value-format="x"
-                :placeholder="`选择${attr.name}`"
-                style="width: 100%"
-                :readonly="isReadonlyMode"
-              />
-
-              <!-- 默认文本输入 -->
-              <el-input
-                v-else
-                v-model="formData.dynamicFields[attr.identifier]"
-                :placeholder="`请输入${attr.name}`"
-                :readonly="isReadonlyMode"
-              />
-            </el-form-item>
-          </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">
-            <el-form-item label="当日生产动态" prop="productionStatus">
-              <el-input
-                v-model="formData.productionStatus"
-                type="textarea"
-                :rows="3"
-                placeholder="请输入当日生产动态"
-                :readonly="isReadonlyMode"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 第四行:下步工作计划 -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="下步工作计划" prop="nextPlan">
-              <el-input
-                v-model="formData.nextPlan"
-                type="textarea"
-                :rows="3"
-                placeholder="请输入下步工作计划"
-                :readonly="isReadonlyMode"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 第五行:外租设备 -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="外租设备" prop="externalRental">
-              <el-input
-                v-model="formData.externalRental"
-                type="textarea"
-                :rows="3"
-                placeholder="请输入外租设备信息"
-                :readonly="isReadonlyMode"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 故障情况 -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="故障情况" prop="malfunction">
-              <el-input
-                v-model="formData.malfunction"
-                type="textarea"
-                :rows="3"
-                placeholder="请输入故障情况"
-                :readonly="isReadonlyMode"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 故障误工H -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="故障误工H" prop="faultDowntime">
-              <el-input
-                v-model="formData.faultDowntime"
-                type="number"
-                :rows="3"
-                placeholder="请输入故障误工H"
-                :readonly="isReadonlyMode"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <div class="grid grid-cols-3 gao-4">
-          <el-form-item
-            v-for="field in NON_PROD_FIELDS"
-            :key="field.key"
-            :label="field.label + '(H)'"
-            :prop="field.key"
-          >
-            <el-input-number
-              class="!w-full"
-              :min="0"
-              :max="24"
-              v-model="formData[field.key]"
-              :controls="false"
-              align="left"
-              :disabled="query.istime !== 'true'"
-            />
-          </el-form-item>
-        </div>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="其他非生产原因" prop="otherNptReason">
-              <el-input
-                v-model="formData.otherNptReason"
-                placeholder="请输入其他非生产原因"
-                :disabled="query.istime !== 'true'"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <!-- 第六行:上传附件 -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="附件">
-              <!-- 文件上传组件 -->
-              <FileUpload
-                v-if="!isReadonlyMode"
-                ref="fileUploadRef"
-                :device-id="deviceId"
-                :show-folder-button="false"
-                @upload-success="handleUploadSuccess"
-              />
-
-              <!-- 已上传附件列表显示 -->
-              <div
-                v-if="formData.attachments && formData.attachments.length > 0"
-                class="attachment-container"
-              >
-                <div class="attachment-list">
-                  <div
-                    v-for="(attachment, index) in formData.attachments"
-                    :key="attachment.id || index"
-                    class="attachment-item"
-                  >
-                    <!-- 为附件名称添加点击事件,传递整个附件对象 -->
-                    <a class="attachment-name" @click="inContent(attachment)">
-                      {{ attachment.filename }}
-                    </a>
-                    <el-button
-                      v-if="!isReadonlyMode"
-                      type="danger"
-                      link
-                      size="small"
-                      @click="removeAttachment(index)"
-                    >
-                      删除
-                    </el-button>
-                  </div>
-                </div>
-              </div>
-
-              <!-- 审批模式下只显示附件列表 -->
-              <div
-                v-else-if="
-                  isApprovalMode && (!formData.attachments || formData.attachments.length === 0)
-                "
-                class="no-attachment"
-              >
-                无附件
-              </div>
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-    </ContentWrap>
-
-    <!-- 油耗信息区域 - 当有油耗数据时显示 -->
-    <ContentWrap class="fuel-consumption-section" v-if="showFuelConsumption">
-      <h2 class="text-lg font-semibold mb-4">油耗信息</h2>
-
-      <div class="fuel-consumption-table">
-        <el-table
-          :data="fuelConsumptionData"
-          border
-          style="width: 100%"
-          class="fuel-consumption-el-table"
-          table-layout="fixed"
-          :key="fuelTableKey"
-          row-key="deviceId"
-        >
-          <!-- 车辆编码 -->
-          <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"
-                @focus="handleFuelInputFocus(scope.row)"
-                :key="scope.row.deviceId"
-              />
-              <!-- 只读模式下显示数值 -->
-              <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>
-
-      <div
-        class="platform-workload-table"
-        v-if="platformWorkloadData && platformWorkloadData.length > 0"
-      >
-        <el-table
-          :data="platformWorkloadData"
-          border
-          style="width: 100%"
-          class="platform-workload-el-table"
-          table-layout="fixed"
-        >
-          <!-- 固定列 -->
-          <el-table-column
-            prop="wellName"
-            label="井号"
-            align="center"
-            :show-overflow-tooltip="true"
-          />
-          <el-table-column label="施工状态" align="center" :show-overflow-tooltip="true">
-            <template #default="scope">
-              {{ scope.row.rdStatusLabel || '' }}
-            </template>
-          </el-table-column>
-          <el-table-column label="施工工艺" align="center" :show-overflow-tooltip="true">
-            <template #default="scope">
-              {{ scope.row.techniqueNames || '' }}
-            </template>
-          </el-table-column>
-
-          <!-- 动态工作量列 -->
-          <el-table-column
-            v-for="workloadColumn in getWorkloadColumns()"
-            :key="workloadColumn.key"
-            :label="workloadColumn.label"
-            align="center"
-            :show-overflow-tooltip="true"
-          >
-            <template #default="scope">
-              {{ getWorkloadValue(scope.row, workloadColumn.identifier) }}
-            </template>
-          </el-table-column>
-        </el-table>
-      </div>
-
-      <div v-else class="text-center text-gray-500 py-4"> 暂无平台井工作量数据 </div>
-    </ContentWrap>
-
-    <!-- 第四部分:审批意见 - 只在审批模式下显示 -->
-    <ContentWrap class="section-padding" v-if="isApprovalMode || isEditMode || isDetailMode">
-      <el-form
-        ref="approvalFormRef"
-        :model="approvalForm"
-        style="margin-top: 1em"
-        label-width="200px"
-      >
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="审批意见" prop="opinion">
-              <el-input
-                v-model="approvalForm.opinion"
-                type="textarea"
-                :rows="4"
-                placeholder="请输入审批意见"
-                maxlength="500"
-                show-word-limit
-                :readonly="!isApprovalMode"
-                :disabled="!isApprovalMode"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-    </ContentWrap>
-
-    <!-- 操作按钮 -->
-    <ContentWrap class="section-padding" v-if="isEditMode">
-      <el-form>
-        <el-form-item style="float: right">
-          <el-button @click="submitForm" type="primary" :disabled="formLoading">
-            {{ t('common.save') }}
-          </el-button>
-          <el-button @click="close">{{ t('common.cancel') }}</el-button>
-        </el-form-item>
-      </el-form>
-    </ContentWrap>
-
-    <!-- 审批模式下的操作按钮 -->
-    <ContentWrap class="section-padding" v-if="isApprovalMode">
-      <el-form>
-        <el-form-item style="float: right">
-          <el-button @click="handleApprove('pass')" type="success"> 审批通过 </el-button>
-          <el-button @click="handleApprove('reject')" type="danger"> 审批驳回 </el-button>
-          <el-button @click="close">{{ t('common.close') }}</el-button>
-        </el-form-item>
-      </el-form>
-    </ContentWrap>
-
-    <!-- 详情模式下的操作按钮 - 只有关闭按钮 -->
-    <ContentWrap class="section-padding" v-if="isDetailMode">
-      <el-form>
-        <el-form-item style="float: right">
-          <el-button @click="close">{{ t('common.close') }}</el-button>
-        </el-form-item>
-      </el-form>
-    </ContentWrap>
-  </ContentWrap>
-
-  <!-- 设备选择对话框 -->
-  <el-dialog
-    v-model="deviceDialogVisible"
-    title="选择施工设备"
-    width="1000px"
-    :before-close="handleDeviceDialogClose"
-    class="device-select-dialog"
-  >
-    <div class="transfer-container">
-      <el-transfer
-        v-model="selectedDeviceIds"
-        :data="filteredDeviceList"
-        :titles="['可选设备', '已选设备']"
-        :props="{ key: 'id', label: 'deviceCode' }"
-        filterable
-        class="transfer-component"
-        @change="handleTransferChange"
-      >
-        <template #default="{ option }">
-          <el-tooltip
-            effect="dark"
-            placement="top"
-            :content="`${option.deviceCode || ''} - ${option.deviceName || ''}`"
-            :disabled="!option.deviceCode && !option.deviceName"
-            transition="fade-in-linear"
-          >
-            <span class="transfer-option-text">
-              {{ option.deviceCode }} - {{ option.deviceName }}
-            </span>
-          </el-tooltip>
-        </template>
-      </el-transfer>
-    </div>
-    <template #footer>
-      <span class="dialog-footer">
-        <el-button @click="handleDeviceDialogClose">取消</el-button>
-        <el-button type="primary" @click="confirmDeviceSelection">确定</el-button>
-      </span>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup lang="ts">
-import { ref, reactive, computed, onMounted, nextTick, watch } from 'vue'
-import { useI18n } from '@/hooks/web/useI18n'
-import { useMessage } from '@/hooks/web/useMessage'
-import { useTagsViewStore } from '@/store/modules/tagsView'
-import { useRouter } from 'vue-router'
-import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
-import { IotRdDailyReportApi } from '@/api/pms/iotrddailyreport'
-import { IotDailyReportAttrsApi } from '@/api/pms/iotdailyreportattrs'
-import * as DeptApi from '@/api/system/dept'
-import { useUserStore } from '@/store/modules/user'
-import dayjs from 'dayjs'
-import FileUpload from '@/components/UploadFile/src/FileUpload.vue'
-
-const NON_PROD_FIELDS = [
-  { key: 'repairTime', label: '设备故障' },
-  { key: 'selfStopTime', label: '设备保养' },
-  { key: 'accidentTime', label: '工程质量' },
-  { key: 'complexityTime', label: '技术受限' },
-  { key: 'rectificationTime', label: '生产组织' },
-  { key: 'waitingStopTime', label: '不可抗力' },
-  { key: 'partyaDesign', label: '甲方设计' },
-  { key: 'partyaPrepare', label: '甲方准备' },
-  { key: 'partyaResource', label: '甲方资源' },
-  { key: 'relocationTime', label: '生产配合' },
-  { key: 'winterBreakTime', label: '待命' },
-  { key: 'otherNptTime', label: '其他非生产时间' }
-] as const
-
-const { t } = useI18n()
-const message = useMessage()
-const { delView } = useTagsViewStore()
-const { push, currentRoute } = useRouter()
-const { params, query } = useRoute()
-const userStore = useUserStore()
-
-/** 填报日报 表单 */
-defineOptions({ name: 'FillDailyReportForm' })
-
-const formLoading = ref(false)
-const formRef = ref()
-const id = params.id // 瑞都日报id
-
-const fuelTableKey = ref(0) // 用于强制重新渲染表格
-
-// 添加一个新的响应式变量用于输入
-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')
-const isEditMode = computed(() => params.mode === 'fill' || !params.mode) // 默认为编辑模式
-
-// 只读模式判断:审批模式或详情模式都为只读
-const isReadonlyMode = computed(
-  () => isApprovalMode.value || isDetailMode.value || formData.value.auditStatus === 20
-)
-
-// 在表单数据定义附近添加
-const platformWellPairs = ref<any[]>([]) // 存储各平台井的工作量数据
-const currentPlatformId = ref<number>() // 当前选中的平台井ID
-
-// 计算属性:显示井名(统一处理主井和平台井逻辑)
-const displayWellName = computed(() => {
-  // 如果是平台井模式
-  if (dailyReportData.value.platformWell === 1) {
-    // 确定平台井数据源:优先使用 platforms,不存在则使用 finishedPlatforms
-    const platformSource =
-      dailyReportData.value.platforms || dailyReportData.value.finishedPlatforms
-
-    // 如果有平台井数据
-    if (platformSource && platformSource.length > 0) {
-      // 检查主井是否在平台井列表中
-      const isMainWellInPlatforms = platformSource.some(
-        (platform: any) => platform.id === dailyReportData.value.taskId
-      )
-
-      // 如果主井不在平台井列表中(说明主井已施工完成),使用第一个平台井的名称
-      if (!isMainWellInPlatforms) {
-        const firstPlatformWellName = platformSource[0].wellName
-        console.log(`主井已施工完成,井号显示使用平台井名称: ${firstPlatformWellName}`)
-        return firstPlatformWellName
-      }
-    }
-  }
-
-  // 其他情况使用原来的井名
-  return dailyReportData.value.wellName
-})
-
-// 页面标题计算
-const pageTitle = computed(() => {
-  const displayWellNameValue = displayWellName.value
-  const constructionDate = dailyReportData.value.constructionStartDate
-
-  if (isApprovalMode.value) {
-    return displayWellNameValue && constructionDate
-      ? `${displayWellNameValue} - ${formatDate(constructionDate)} 日报审批`
-      : '日报审批'
-  } else if (isDetailMode.value) {
-    return displayWellNameValue && constructionDate
-      ? `${displayWellNameValue} - ${formatDate(constructionDate)} 日报详情`
-      : '日报详情'
-  } else {
-    return displayWellNameValue && constructionDate
-      ? `${displayWellNameValue} - ${formatDate(constructionDate)} 生产日报`
-      : '日报填报'
-  }
-})
-
-// 处理输入框获取焦点事件
-const handleFuelInputFocus = (fuelItem: any) => {
-  // 如果 customFuel 是空的,确保它显示默认值
-  if (!fuelItem.customFuel || fuelItem.customFuel === '') {
-    const zhbdValue = parseFloat(fuelItem.zhbdFuel)
-    fuelItem.customFuel = !isNaN(zhbdValue) ? formatNumber(zhbdValue, 2) : '0.00'
-  }
-}
-
-// 模式提示信息
-const modeNotice = computed(() => {
-  if (isApprovalMode.value) {
-    return '审批模式:所有字段均为只读'
-  } else if (isDetailMode.value) {
-    return '详情模式:所有字段均为只读'
-  }
-  return ''
-})
-
-// 动态属性相关变量
-const dynamicAttrs = ref<any[]>([]) // 存储动态属性列表
-
-// 添加设备选择相关变量
-const deviceDialogVisible = ref(false)
-const filteredDeviceList = ref<any[]>([])
-const selectedDeviceIds = ref<number[]>([])
-const deviceMap = ref<Record<number, any>>({})
-
-// 添加平台井相关响应式数据
-const platformOptions = ref<any[]>([]) // 平台井下拉选项
-const showPlatformField = ref(false) // 是否显示平台井字段
-
-// 计算属性:是否显示平台井字段
-const shouldShowPlatformField = computed(() => {
-  return dailyReportData.value.platformWell === 1
-})
-
-// 初始化平台井数据
-const initPlatformData = (reportData: any) => {
-  // 设置是否显示平台井字段
-  showPlatformField.value = reportData.platformWell === 1
-
-  // 设置平台井下拉选项 - 修改后的逻辑
-  let platformSource = reportData.platforms
-
-  // 在详情或审批模式下,如果 platforms 不存在,则使用 finishedPlatforms
-  if (
-    (isDetailMode.value || isApprovalMode.value) &&
-    (!platformSource || platformSource.length === 0)
-  ) {
-    platformSource = reportData.finishedPlatforms
-  }
-
-  // 设置平台井下拉选项
-  if (platformSource && Array.isArray(platformSource)) {
-    platformOptions.value = platformSource
-
-    // 初始化 platformWellPairs,确保包含所有平台井的完整数据
-    if (reportData.platformWell === 1) {
-      // 初始化 platformWellPairs,包含所有平台井的完整数据
-      platformWellPairs.value = platformSource.map((platform: any) => {
-        // 查找是否已有该平台井的数据
-        const existingData = reportData.platformWellPairs?.find(
-          (p: any) => p.taskId === platform.id
-        )
-
-        // 确保 techniqueIds 是字符串数组格式
-        let techniqueIds = []
-        if (existingData && existingData.techniqueIds) {
-          techniqueIds = existingData.techniqueIds.map((id: any) => id.toString())
-        } else if (platform.techniqueIds) {
-          techniqueIds = platform.techniqueIds.map((id: any) => id.toString())
-        }
-
-        return (
-          existingData || {
-            taskId: platform.id,
-            dailyFuel: platform.dailyFuel || '',
-            reportId: platform.reportId, // 使用接口返回的 reportId
-            wellName: platform.wellName,
-            rdStatus: platform.rdStatus || '', // 初始为空
-            techniqueIds: techniqueIds, // 初始为空数组
-            extProperty: platform.extProperty || [], // 初始为空数组
-            repairTime: platform.repairTime ?? 0,
-            selfStopTime: platform.selfStopTime ?? 0,
-            accidentTime: platform.accidentTime ?? 0,
-            complexityTime: platform.complexityTime ?? 0,
-            rectificationTime: platform.rectificationTime ?? 0,
-            waitingStopTime: platform.waitingStopTime ?? 0,
-            partyaDesign: platform.partyaDesign ?? 0,
-            partyaPrepare: platform.partyaPrepare ?? 0,
-            partyaResource: platform.partyaResource ?? 0,
-            relocationTime: platform.relocationTime ?? 0,
-            winterBreakTime: platform.winterBreakTime ?? 0,
-            otherNptTime: platform.otherNptTime ?? 0,
-            otherNptReason: platform.otherNptReason || ''
-          }
-        )
-      })
-    }
-  } else {
-    platformOptions.value = []
-    platformWellPairs.value = []
-  }
-
-  // 设置默认选中的平台井 - 修改后的逻辑
-  if (platformOptions.value.length > 0) {
-    let selectedPlatform = null
-
-    // 首先尝试查找与 taskId 匹配的平台井
-    if (reportData.taskId) {
-      selectedPlatform = platformOptions.value.find(
-        (platform: any) => platform.id === reportData.taskId
-      )
-    }
-
-    // 如果没有找到匹配的平台井,选择第一个平台井
-    if (!selectedPlatform) {
-      selectedPlatform = platformOptions.value[0]
-    }
-
-    // 设置选中的平台井
-    if (selectedPlatform) {
-      formData.value.platformId = selectedPlatform.id
-      currentPlatformId.value = selectedPlatform.id
-      // 加载平台井的数据到表单
-      loadPlatformData(selectedPlatform.id)
-
-      // 可选:在控制台输出提示信息
-      if (reportData.taskId && selectedPlatform.id !== reportData.taskId) {
-        console.log(`主井已施工完成,已自动选择第一个平台井: ${selectedPlatform.wellName}`)
-      }
-    }
-  }
-}
-
-// 添加审批表单相关变量
-const approvalFormRef = ref()
-const approvalForm = reactive({
-  opinion: '' // 审批意见
-})
-
-// 审批表单验证规则(可选,根据需求添加)
-const approvalFormRules = reactive({
-  opinion: [
-    { required: false, message: '请输入审批意见', trigger: 'blur' },
-    { min: 0, max: 500, message: '审批意见长度不能超过500个字符', trigger: 'blur' }
-  ]
-})
-
-// 将时分秒数组转换为Date对象(基于constructionStartDate的日期)
-const parseTimeArrayToDate = (timeArray: number[], baseDate: number) => {
-  if (!Array.isArray(timeArray) || !baseDate) {
-    return null
-  }
-  const hour = timeArray[0] || 0
-  const minute = timeArray[1] || 0
-  const second = timeArray[2] || 0
-  // 基于日报日期(constructionStartDate)设置时分秒
-  return dayjs(baseDate).hour(hour).minute(minute).second(second).toDate()
-}
-
-// 添加文件上传组件的引用
-const fileUploadRef = ref()
-
-// 表单数据
-const formData = ref<any>({
-  id: undefined,
-  deptId: undefined,
-  taskId: undefined,
-  platformWell: undefined,
-  companyId: undefined,
-  deptName: undefined,
-  constructionStartDate: undefined,
-  contractName: undefined,
-  projectDepartment: '',
-  costCenterId: undefined,
-  costCenter: '',
-  platformId: undefined, // 平台井ID
-  // 日报填报字段
-  timeRange: [
-    // 设置默认时间范围 8:00 - 8:00
-    dayjs().hour(8).minute(0).second(0).toDate(),
-    dayjs().hour(8).minute(0).second(0).toDate()
-  ],
-  startTime: undefined, // 开始时间
-  endTime: undefined, // 结束时间
-  rdStatus: '', // 施工状态
-  deviceIds: [] as number[], // 设备ID数组
-  techniqueIds: [], // 施工工艺
-  dailyFuel: '', // 当日油耗
-  productionStatus: '', // 当日生产动态
-  nextPlan: '', // 下步工作计划
-  externalRental: '', // 外租设备
-  malfunction: '', // 故障情况
-  faultDowntime: '', // 故障误工
-  // 添加动态字段对象
-  dynamicFields: {} as Record<string, any>,
-  // 附件列表
-  attachments: [] as any[],
-  reportFuels: [] as any[], // 油耗信息数组
-  repairTime: 0,
-  selfStopTime: 0,
-  accidentTime: 0,
-  complexityTime: 0,
-  rectificationTime: 0,
-  waitingStopTime: 0,
-  partyaDesign: 0,
-  partyaPrepare: 0,
-  partyaResource: 0,
-  relocationTime: 0,
-  winterBreakTime: 0,
-  otherNptTime: 0,
-  otherNptReason: ''
-})
-
-// 添加上传成功处理函数
-const handleUploadSuccess = (result: any) => {
-  console.log('上传成功', result)
-
-  try {
-    // 检查响应是否成功
-    if (!result.response) {
-      message.error('上传响应数据异常')
-      return
-    }
-
-    if (result.response.code !== 0) {
-      message.error(result.response.msg || '文件上传失败')
-      return
-    }
-
-    const responseData = result.response.data
-
-    if (!responseData) {
-      message.error('上传数据为空')
-      return
-    }
-
-    // 处理返回的文件列表
-    if (responseData.files && Array.isArray(responseData.files) && responseData.files.length > 0) {
-      responseData.files.forEach((file: any) => {
-        if (!file.filePath) {
-          console.warn('文件缺少 filePath:', file)
-          return
-        }
-
-        // 根据后端返回的数据结构构建附件对象
-        const attachment = {
-          id: undefined,
-          category: 'daily_report',
-          bizId: formData.value.id,
-          type: 'attachment',
-          filename: file.name || '未知文件',
-          fileType: getFileType(file.name),
-          filePath: file.filePath, //使用正确的 filePath
-          fileSize: formatFileSize(file.size || 0),
-          remark: ''
-        }
-
-        // 添加到附件列表
-        if (!formData.value.attachments) {
-          formData.value.attachments = []
-        }
-        formData.value.attachments.push(attachment)
-      })
-
-      message.success(`成功上传 ${responseData.files.length} 个文件`)
-    } else {
-      console.warn('上传成功但没有返回文件信息')
-      message.warning('上传成功但未获取到文件信息')
-    }
-  } catch (error) {
-    console.error('处理上传结果时发生错误:', error)
-    message.error('处理上传结果失败')
-  }
-}
-
-// 删除附件
-const removeAttachment = (index: number) => {
-  if (formData.value.attachments && formData.value.attachments.length > index) {
-    formData.value.attachments.splice(index, 1)
-  }
-}
-
-// 计算属性:未施工设备名称
-const unSelectedDeviceNames = computed(() => {
-  const selectedDevices = dailyReportData.value.selectedDevices || []
-  const selectedDeviceIds = formData.value.deviceIds || []
-
-  if (selectedDevices.length === 0) {
-    return '无可用设备'
-  }
-
-  // 筛选出未选择的设备
-  const unselectedDevices = selectedDevices.filter(
-    (device: any) => !selectedDeviceIds.includes(device.id)
-  )
-
-  if (unselectedDevices.length === 0) {
-    return '所有设备都已施工'
-  }
-
-  // 提取设备名称并用逗号分隔
-  const deviceNames = unselectedDevices
-    .map((device: any) => device.deviceName || device.deviceCode || '未知设备')
-    .filter((name: string) => name !== '未知设备')
-
-  return deviceNames.join(', ') || '无未选择设备'
-})
-
-// 附件名称点击事件
-const inContent = async (attachment) => {
-  if (!attachment || !attachment.filePath) {
-    message.error('附件路径不存在')
-    return
-  }
-
-  try {
-    // 直接使用 attachment.filePath
-    const filePath = attachment.filePath
-    // 确保 filePath 是编码后的格式
-    const encodedPath = encodeURIComponent(Base64.encode(filePath))
-
-    // 打开预览窗口
-    window.open(`http://doc.deepoil.cc:8012/onlinePreview?url=${encodedPath}`)
-  } catch (error) {
-    console.error('预览附件失败:', error)
-    message.error('预览附件失败')
-  }
-}
-
-// 获取文件类型辅助函数
-const getFileType = (filename: string) => {
-  const ext = filename.split('.').pop()?.toLowerCase()
-  if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(ext || '')) {
-    return 'image'
-  } else if (['pdf'].includes(ext || '')) {
-    return 'pdf'
-  } else if (['doc', 'docx'].includes(ext || '')) {
-    return 'word'
-  } else if (['xls', 'xlsx'].includes(ext || '')) {
-    return 'excel'
-  } else {
-    return 'other'
-  }
-}
-
-// 格式化文件大小辅助函数
-const formatFileSize = (bytes: number) => {
-  if (bytes === 0) return '0 Bytes'
-  const k = 1024
-  const sizes = ['Bytes', 'KB', 'MB', 'GB']
-  const i = Math.floor(Math.log(bytes) / Math.log(k))
-  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
-}
-
-// 计算属性:格式化设备显示
-const formatDevicesForDisplay = computed(() => {
-  const deviceIds = formData.value.deviceIds
-  if (!deviceIds || deviceIds.length === 0) {
-    return '无设备'
-  }
-
-  const deviceNames = deviceIds
-    .map((id) => deviceMap.value[id]?.deviceName)
-    .filter((name) => name !== undefined && name !== '')
-
-  if (deviceNames.length === 0) return '无设备'
-
-  // 如果设备数量超过2个,显示前两个加省略号
-  /* if (deviceNames.length > 2) {
-    return `${deviceNames[0]}, ${deviceNames[1]}...`
-  } */
-
-  return deviceNames.join(', ')
-})
-
-// 计算属性:获取所有设备名称(用于tooltip)
-const getAllDeviceNamesForDisplay = computed(() => {
-  const deviceIds = formData.value.deviceIds
-  if (!deviceIds || deviceIds.length === 0) {
-    return '无设备'
-  }
-
-  const deviceNames = deviceIds
-    .map((id) => deviceMap.value[id]?.deviceCode || '未知设备')
-    .filter((name) => name !== '未知设备')
-
-  return deviceNames.join(', ') || '无有效设备'
-})
-
-// 打开设备选择对话框
-const openDeviceDialog = async () => {
-  if (!dailyReportData.value.deptId) {
-    message.error('请先加载项目信息')
-    return
-  }
-
-  try {
-    formLoading.value = true
-    selectedDeviceIds.value = [...(formData.value.deviceIds || [])]
-
-    // 直接从日报数据的 selectedDevices 中获取设备列表
-    const selectedDevices = dailyReportData.value.selectedDevices || []
-
-    // 更新设备映射表
-    const newDeviceMap = { ...deviceMap.value }
-    selectedDevices.forEach((device: any) => {
-      if (device.id) {
-        newDeviceMap[device.id] = device
-      }
-    })
-    deviceMap.value = newDeviceMap
-
-    filteredDeviceList.value = selectedDevices
-    deviceDialogVisible.value = true
-  } catch (error) {
-    console.error('获取设备列表失败:', error)
-    message.error('获取设备列表失败')
-  } finally {
-    formLoading.value = false
-  }
-}
-
-// 修改格式化函数,改为失去焦点时触发
-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[]) => {
-  // 可以添加额外的处理逻辑
-}
-
-// 确认设备选择
-const confirmDeviceSelection = () => {
-  formData.value.deviceIds = [...selectedDeviceIds.value]
-  deviceDialogVisible.value = false
-  message.success(`已选择 ${selectedDeviceIds.value.length} 台设备`)
-}
-
-// 关闭设备选择对话框
-const handleDeviceDialogClose = () => {
-  deviceDialogVisible.value = false
-}
-
-// 初始化设备数据
-const initDeviceData = (reportData: any) => {
-  // 初始化设备ID
-  if (reportData.deviceIds && Array.isArray(reportData.deviceIds)) {
-    formData.value.deviceIds = [...reportData.deviceIds]
-  } else {
-    formData.value.deviceIds = []
-  }
-
-  // 初始化设备映射表(用于显示设备名称)
-  if (reportData.selectedDevices && Array.isArray(reportData.selectedDevices)) {
-    const newDeviceMap = { ...deviceMap.value }
-    reportData.selectedDevices.forEach((device: any) => {
-      if (device.id) {
-        newDeviceMap[device.id] = device
-      }
-    })
-    deviceMap.value = newDeviceMap
-  }
-}
-
-// const validateOtherReason = (_rule: any, value: any, callback: any) => {
-//   const time = formData.value.otherNptTime || 0
-//   if (time > 0 && !value) {
-//     callback(new Error('填写了其他时间,必须说明原因'))
-//   } else {
-//     callback()
-//   }
-// }
-
-const formRules = computed(() => {
-  // 判断是否为虚拟项目
-  const isVirtualProject = dailyReportData.value.virtualProject === 'Y'
-
-  // 基础校验规则(时间节点、当日生产动态始终必填)
-  const rules = {
-    timeRange: [{ required: true, message: '时间节点不能为空', trigger: 'change' }],
-    productionStatus: [{ required: true, message: '当日生产动态不能为空', trigger: 'blur' }],
-    nextPlan: [{ required: true, message: '下步工作计划不能为空', trigger: 'blur' }],
-    // otherNptReason: [{ validator: validateOtherReason, trigger: ['blur', 'change'] }],
-    dailyFuel: [
-      {
-        required: true,
-        message: '当日油耗不能为空',
-        trigger: 'blur'
-      },
-      {
-        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'
-      }
-    ]
-  }
-
-  // 非虚拟项目时,添加施工状态、施工工艺的必填校验
-  if (!isVirtualProject) {
-    rules.rdStatus = [{ required: true, message: '施工状态不能为空', trigger: 'change' }]
-    rules.techniqueIds = [{ required: true, message: '施工工艺不能为空', trigger: 'change' }]
-  }
-
-  return rules
-})
-
-const queryParams = reactive({
-  deptId: undefined,
-  techniqueIds: []
-})
-
-// 下拉选项
-const rdStatusOptions = getStrDictOptions(DICT_TYPE.PMS_PROJECT_RD_STATUS) // 施工状态
-const techniqueOptions = getStrDictOptions(DICT_TYPE.PMS_PROJECT_RD_TECHNOLOGY) // 瑞都施工工艺
-
-// 计算属性:日报标题
-const dailyReportTitle = computed(() => {
-  if (!dailyReportData.value.wellName || !dailyReportData.value.constructionStartDate) {
-    return '日报填报'
-  }
-  const dateStr = formatDate(dailyReportData.value.constructionStartDate)
-  return `${dailyReportData.value.wellName} - ${dateStr} 生产日报`
-})
-
-// 日报审批:日报标题
-const dailyReportApprovalTitle = computed(() => {
-  if (!dailyReportData.value.wellName || !dailyReportData.value.constructionStartDate) {
-    return '日报审批'
-  }
-  const dateStr = formatDate(dailyReportData.value.constructionStartDate)
-  return `${dailyReportData.value.wellName} - ${dateStr} 日报审批`
-})
-
-// 计算属性:施工周期
-const constructionPeriod = computed(() => {
-  const start = dailyReportData.value.constructionStartDate
-  const end = dailyReportData.value.constructionEndDate
-  if (!start || !end) return 0
-
-  const startDate = dayjs(start)
-  const endDate = dayjs(end)
-  return endDate.diff(startDate, 'day')
-})
-
-// 日期格式化函数
-const formatDate = (timestamp: number) => {
-  if (!timestamp) return ''
-  return dayjs(timestamp).format('YYYY-MM-DD')
-}
-
-const close = () => {
-  delView(unref(currentRoute))
-  push({ name: 'FillDailyReport', params: {} })
-}
-
-/** 提交表单 */
-const emit = defineEmits(['success'])
-const submitForm = async () => {
-  // 验证表单
-  try {
-    await formRef.value.validate()
-  } catch (error) {
-    return
-  }
-
-  // 保存当前平台井的数据
-  if (currentPlatformId.value) {
-    saveCurrentPlatformData(currentPlatformId.value)
-  }
-
-  let validationPassed = true
-  const validationErrors: string[] = []
-
-  // 检查所有平台井数据
-  for (const pair of platformWellPairs.value) {
-    // 计算所有时间字段的总和
-    const totalTime =
-      (pair.repairTime || 0) +
-      (pair.selfStopTime || 0) +
-      (pair.accidentTime || 0) +
-      (pair.complexityTime || 0) +
-      (pair.rectificationTime || 0) +
-      (pair.waitingStopTime || 0) +
-      (pair.partyaDesign || 0) +
-      (pair.partyaPrepare || 0) +
-      (pair.partyaResource || 0) +
-      (pair.relocationTime || 0) +
-      (pair.winterBreakTime || 0) +
-      (pair.otherNptTime || 0)
-
-    // 检查总和是否超过24小时
-    if (totalTime > 24) {
-      validationPassed = false
-      validationErrors.push(`${pair.wellName || '平台井'}的时间总和不能超过24小时`)
-    }
-
-    // 检查otherNptTime>0时是否填写了otherNptReason
-    if ((pair.otherNptTime || 0) > 0 && !pair.otherNptReason) {
-      validationPassed = false
-      validationErrors.push(`${pair.wellName || '平台井'}的其他时间大于0时必须填写原因`)
-    }
-  }
-
-  // 检查非平台井模式
-  if (dailyReportData.value.platformWell !== 1) {
-    // 计算所有时间字段的总和
-    const totalTime =
-      (formData.value.repairTime || 0) +
-      (formData.value.selfStopTime || 0) +
-      (formData.value.accidentTime || 0) +
-      (formData.value.complexityTime || 0) +
-      (formData.value.rectificationTime || 0) +
-      (formData.value.waitingStopTime || 0) +
-      (formData.value.partyaDesign || 0) +
-      (formData.value.partyaPrepare || 0) +
-      (formData.value.partyaResource || 0) +
-      (formData.value.relocationTime || 0) +
-      (formData.value.winterBreakTime || 0) +
-      (formData.value.otherNptTime || 0)
-
-    // 检查总和是否超过24小时
-    if (totalTime > 24) {
-      validationPassed = false
-      validationErrors.push('时间总和不能超过24小时')
-    }
-  }
-
-  // 如果验证失败,显示错误信息
-  if (!validationPassed) {
-    validationErrors.forEach((error) => {
-      message.error(error)
-    })
-    return
-  }
-
-  // 打印 platformWellPairs
-  console.log('platformWellPairs:', JSON.stringify(platformWellPairs.value, null, 2))
-
-  // 处理时间范围数据
-  if (formData.value.timeRange && formData.value.timeRange.length === 2) {
-    // 将时间范围转换为 LocalTime 格式的字符串
-    const startDate = dayjs(formData.value.timeRange[0])
-    const endDate = dayjs(formData.value.timeRange[1])
-
-    // 格式化为 HH:mm:ss 字符串,后端会自动转换为 LocalTime
-    formData.value.startTime = startDate.format('HH:mm:ss')
-    formData.value.endTime = endDate.format('HH:mm:ss')
-  }
-
-  // 构建动态属性 extProperty 数组
-  const extProperties = dynamicAttrs.value.map((attr) => {
-    return {
-      name: attr.name,
-      sort: attr.sort,
-      unit: attr.unit,
-      actualValue: formData.value.dynamicFields[attr.identifier] || '', // 从 dynamicFields 中获取用户填写的值
-      dataType: attr.dataType,
-      maxValue: attr.maxValue,
-      minValue: attr.minValue,
-      required: attr.required,
-      accessMode: attr.accessMode,
-      identifier: attr.identifier,
-      defaultValue: attr.defaultValue
-    }
-  })
-
-  // 准备提交数据,包含动态字段
-  const baseSubmitData = {
-    ...formData.value,
-    // 将动态字段组装成 extProperty 数组
-    extProperty: extProperties,
-    deviceIds: formData.value.deviceIds, // 设备ID集合
-    // 在填报模式下也提交审批意见字段
-    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,
-    nonProduct: query.istime === 'true' ? 'Y' : ''
-  }
-
-  console.log('baseSubmitData:', baseSubmitData)
-
-  // 删除不需要复制的字段
-  const {
-    id: currentId,
-    platformId,
-    platformWell,
-    taskId,
-    rdStatus,
-    techniqueIds,
-    extProperty,
-    ...baseData
-  } = baseSubmitData
-
-  const submitDatas: any[] = []
-
-  if (dailyReportData.value.platformWell === 1 && platformWellPairs.value.length > 0) {
-    // 平台井模式:处理所有平台井数据
-    platformWellPairs.value.forEach((pair) => {
-      console.log('pair:', pair)
-      // 复制基础数据
-      const platformData: any = { ...baseData }
-
-      // 设置平台井特定字段
-      platformData.id = pair.reportId // 使用 platformWellPairs 中的 reportId
-      platformData.platformId = pair.taskId // 使用 platformWellPairs 中的 taskId
-      platformData.rdStatus = pair.rdStatus || ''
-      platformData.techniqueIds = pair.techniqueIds || []
-      platformData.extProperty = pair.extProperty || []
-
-      platformData.repairTime = pair.repairTime || 0
-      platformData.selfStopTime = pair.selfStopTime || 0
-      platformData.accidentTime = pair.accidentTime || 0
-      platformData.complexityTime = pair.complexityTime || 0
-      platformData.rectificationTime = pair.rectificationTime || 0
-      platformData.waitingStopTime = pair.waitingStopTime || 0
-      platformData.partyaDesign = pair.partyaDesign || 0
-      platformData.partyaPrepare = pair.partyaPrepare || 0
-      platformData.partyaResource = pair.partyaResource || 0
-      platformData.relocationTime = pair.relocationTime || 0
-      platformData.winterBreakTime = pair.winterBreakTime || 0
-      platformData.otherNptTime = pair.otherNptTime || 0
-      platformData.otherNptReason = pair.otherNptReason || ''
-
-      // 处理附件:复制并修改 bizId 为当前 pair 的 reportId
-      platformData.attachments = (baseData.attachments || []).map((attachment) => ({
-        ...attachment, // 深拷贝单个附件
-        bizId: pair.reportId // 替换 bizId 为当前平台井的 reportId
-      }))
-
-      // 车辆油耗:复制并修改 reportId 为当前 pair 的 reportId
-      platformData.reportFuels = (baseData.reportFuels || []).map((reportFuel) => ({
-        ...reportFuel, // 深拷贝单个油耗
-        reportId: pair.reportId // 替换 reportId 为当前平台井的 reportId
-      }))
-
-      // 重新构建 dynamicFields(如果需要)
-      const dynamicFields = {}
-      if (platformData.extProperty && platformData.extProperty.length > 0) {
-        platformData.extProperty.forEach((prop) => {
-          if (prop.identifier) {
-            dynamicFields[prop.identifier] = prop.actualValue || ''
-          }
-        })
-      }
-      platformData.dynamicFields = dynamicFields
-
-      submitDatas.push(platformData)
-    })
-
-    console.log('平台井模式提交数据:', JSON.stringify(submitDatas, null, 2))
-  } else {
-    // 非平台井模式:只提交当前数据
-    submitDatas.push(baseSubmitData)
-  }
-
-  // 提交请求
-  formLoading.value = true
-  try {
-    // 调用更新接口
-    await IotRdDailyReportApi.saveBatch(submitDatas)
-    message.success(t('common.updateSuccess'))
-    close()
-    // 发送操作成功的事件
-    emit('success')
-  } catch (error) {
-    console.error('提交失败:', error)
-  } finally {
-    formLoading.value = false
-  }
-}
-
-/** 重置表单 */
-const resetForm = () => {
-  formRef.value?.resetFields()
-}
-
-// 初始化动态属性
-const initDynamicAttrs = (reportData: any) => {
-  if (reportData.dailyReportAttrs && reportData.dailyReportAttrs.length > 0) {
-    dynamicAttrs.value = reportData.dailyReportAttrs
-
-    // 初始化动态字段的值
-    const initialDynamicFields: Record<string, any> = {}
-
-    // 优先从 extProperty 中获取实际值(编辑时)
-    if (reportData.extProperty && reportData.extProperty.length > 0) {
-      reportData.extProperty.forEach((extProp: any) => {
-        if (extProp.identifier) {
-          initialDynamicFields[extProp.identifier] = extProp.actualValue || ''
-        }
-      })
-    }
-
-    reportData.dailyReportAttrs.forEach((attr: any) => {
-      if (!initialDynamicFields.hasOwnProperty(attr.identifier)) {
-        // 优先使用实际值,如果没有则使用默认值
-        const value =
-          attr.extProperty &&
-          attr.extProperty.actualValue !== undefined &&
-          attr.extProperty.actualValue !== null &&
-          attr.extProperty.actualValue !== ''
-            ? attr.extProperty.actualValue
-            : attr.defaultValue || attr.extProperty?.defaultValue || ''
-
-        initialDynamicFields[attr.identifier] = value
-      }
-    })
-
-    formData.value.dynamicFields = initialDynamicFields
-  }
-}
-
-// 获取动态字段的验证规则
-const getDynamicAttrRules = (attr: any) => {
-  const rules = []
-  if (attr.required === 1) {
-    rules.push({
-      required: true,
-      message: `${attr.name}不能为空`,
-      trigger: 'blur'
-    })
-  }
-
-  // 数字类型验证
-  if (attr.dataType === 'double') {
-    rules.push({
-      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(`${attr.name}必须是数字`))
-        } else if (attr.minValue && numValue < Number(attr.minValue)) {
-          callback(new Error(`${attr.name}不能小于${attr.minValue}`))
-        } else if (attr.maxValue && numValue > Number(attr.maxValue)) {
-          callback(new Error(`${attr.name}不能大于${attr.maxValue}`))
-        } else {
-          callback()
-        }
-      },
-      trigger: 'blur'
-    })
-  }
-
-  return rules
-}
-
-// 更新动态属性(处理交集、新增和删除)
-const updateDynamicAttrs = async (
-  newAttrs: any[],
-  newTechniqueIds: string[],
-  oldTechniqueIds?: string[]
-) => {
-  const oldAttrs = [...dynamicAttrs.value]
-  const oldDynamicFields = { ...formData.value.dynamicFields }
-
-  // 计算需要保留的字段(交集)
-  const commonAttrs = oldAttrs.filter((oldAttr) =>
-    newAttrs.some((newAttr) => newAttr.identifier === oldAttr.identifier)
-  )
-
-  // 计算需要新增的字段
-  const addedAttrs = newAttrs.filter(
-    (newAttr) => !oldAttrs.some((oldAttr) => oldAttr.identifier === newAttr.identifier)
-  )
-
-  // 计算需要删除的字段
-  const removedAttrs = oldAttrs.filter(
-    (oldAttr) => !newAttrs.some((newAttr) => newAttr.identifier === oldAttr.identifier)
-  )
-
-  // 构建新的动态属性数组
-  const updatedAttrs = [...commonAttrs, ...addedAttrs]
-
-  // 构建新的动态字段对象
-  const updatedDynamicFields = { ...oldDynamicFields }
-
-  // 移除已删除的字段
-  removedAttrs.forEach((attr) => {
-    delete updatedDynamicFields[attr.identifier]
-  })
-
-  // 初始化新增字段的值
-  addedAttrs.forEach((attr) => {
-    if (!updatedDynamicFields[attr.identifier]) {
-      // 如果有默认值使用默认值,否则为空
-      updatedDynamicFields[attr.identifier] =
-        attr.defaultValue || attr.extProperty?.defaultValue || ''
-    }
-  })
-
-  // 更新响应式数据
-  dynamicAttrs.value = updatedAttrs
-  formData.value.dynamicFields = updatedDynamicFields
-}
-
-// 加载动态属性
-const loadDynamicAttrs = async (newTechniqueIds: string[], oldTechniqueIds?: string[]) => {
-  try {
-    formLoading.value = true
-
-    const queryParams = {
-      techniqueIds: newTechniqueIds.join(',')
-    }
-
-    const response = await IotDailyReportAttrsApi.dailyReportAttrs(queryParams)
-    const newAttrs = response || []
-
-    // 处理动态属性更新
-    await updateDynamicAttrs(newAttrs, newTechniqueIds, oldTechniqueIds)
-  } catch (error) {
-    console.error('加载动态属性失败:', error)
-    message.error('加载动态属性失败')
-  } finally {
-    formLoading.value = false
-  }
-}
-
-// 计算属性:获取平台井工作量数据(在详情/审批模式下优先使用 platforms,不存在则使用 finishedPlatforms)
-const platformWorkloadData = computed(() => {
-  if (!dailyReportData.value) return []
-
-  // 在详情或审批模式下
-  if (isDetailMode.value || isApprovalMode.value) {
-    // 优先使用 platforms,如果不存在则使用 finishedPlatforms
-    return dailyReportData.value.platforms || dailyReportData.value.finishedPlatforms || []
-  }
-
-  // 其他模式只使用 platforms
-  return dailyReportData.value.platforms || []
-})
-
-// 在 watch 监听平台井选择变化的部分附近,添加施工工艺转换函数
-// 添加施工工艺数值到标签的转换函数
-const convertTechniqueIdsToLabels = (techniqueIds: number[]): string[] => {
-  if (!techniqueIds || !Array.isArray(techniqueIds)) {
-    return []
-  }
-
-  return techniqueIds.map((id) => {
-    const dict = techniqueOptions.value.find((option) => option.value === id.toString())
-    return dict ? dict.label : id.toString()
-  })
-}
-
-// 监听施工工艺变化
-watch(
-  () => formData.value.techniqueIds,
-  async (newTechniqueIds, oldTechniqueIds) => {
-    if (newTechniqueIds && newTechniqueIds.length > 0) {
-      await loadDynamicAttrs(newTechniqueIds, oldTechniqueIds)
-
-      // 动态属性加载完成后,更新当前平台井的 extProperty
-      if (currentPlatformId.value) {
-        updateCurrentPlatformExtProperty()
-      }
-    } else {
-      dynamicAttrs.value = []
-      formData.value.dynamicFields = {}
-
-      // 清空当前平台井的 extProperty
-      if (currentPlatformId.value) {
-        updateCurrentPlatformExtProperty()
-      }
-    }
-  },
-  { 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
-
-  const index = platformWellPairs.value.findIndex((item) => item.taskId === currentPlatformId.value)
-  if (index !== -1) {
-    platformWellPairs.value[index].extProperty = getCurrentExtProperties()
-  }
-}
-
-// 监听平台井选择变化
-watch(
-  () => formData.value.platformId,
-  (newPlatformId, oldPlatformId) => {
-    if (newPlatformId && newPlatformId !== oldPlatformId) {
-      // 保存当前平台井的数据到 platformWellPairs
-      if (oldPlatformId) {
-        saveCurrentPlatformData(oldPlatformId)
-      }
-
-      // 加载新平台井的数据到表单
-      loadPlatformData(newPlatformId)
-      currentPlatformId.value = newPlatformId
-    }
-  }
-)
-
-// 监听动态字段变化,实时更新到 platformWellPairs
-watch(
-  () => formData.value.dynamicFields,
-  (newFields) => {
-    if (currentPlatformId.value) {
-      updateCurrentPlatformExtProperty()
-    }
-  },
-  { deep: true }
-)
-
-// 监听施工状态变化
-watch(
-  () => formData.value.rdStatus,
-  (newStatus) => {
-    if (currentPlatformId.value) {
-      const index = platformWellPairs.value.findIndex(
-        (item) => item.taskId === currentPlatformId.value
-      )
-      if (index !== -1) {
-        platformWellPairs.value[index].rdStatus = newStatus
-      }
-    }
-  }
-)
-
-// 保存当前平台井数据到 platformWellPairs
-const saveCurrentPlatformData = (platformId: number) => {
-  const index = platformWellPairs.value.findIndex((item) => item.taskId === platformId)
-  if (index !== -1) {
-    platformWellPairs.value[index] = {
-      ...platformWellPairs.value[index],
-      rdStatus: formData.value.rdStatus,
-      techniqueIds: [...formData.value.techniqueIds],
-      extProperty: getCurrentExtProperties(),
-      repairTime: formData.value.repairTime ?? 0,
-      selfStopTime: formData.value.selfStopTime ?? 0,
-      accidentTime: formData.value.accidentTime ?? 0,
-      complexityTime: formData.value.complexityTime ?? 0,
-      rectificationTime: formData.value.rectificationTime ?? 0,
-      waitingStopTime: formData.value.waitingStopTime ?? 0,
-      partyaDesign: formData.value.partyaDesign ?? 0,
-      partyaPrepare: formData.value.partyaPrepare ?? 0,
-      partyaResource: formData.value.partyaResource ?? 0,
-      relocationTime: formData.value.relocationTime ?? 0,
-      winterBreakTime: formData.value.winterBreakTime ?? 0,
-      otherNptTime: formData.value.otherNptTime ?? 0,
-      otherNptReason: formData.value.otherNptReason || ''
-    }
-  } else {
-    // 如果找不到对应的平台井,添加新的记录
-    const platform = platformOptions.value.find((p) => p.id === platformId)
-    if (platform) {
-      platformWellPairs.value.push({
-        taskId: platformId,
-        reportId: undefined, // 新记录没有 reportId
-        wellName: platform.wellName,
-        rdStatus: formData.value.rdStatus,
-        techniqueIds: [...formData.value.techniqueIds],
-        extProperty: getCurrentExtProperties(),
-        repairTime: formData.value.repairTime ?? 0,
-        selfStopTime: formData.value.selfStopTime ?? 0,
-        accidentTime: formData.value.accidentTime ?? 0,
-        complexityTime: formData.value.complexityTime ?? 0,
-        rectificationTime: formData.value.rectificationTime ?? 0,
-        waitingStopTime: formData.value.waitingStopTime ?? 0,
-        partyaDesign: formData.value.partyaDesign ?? 0,
-        partyaPrepare: formData.value.partyaPrepare ?? 0,
-        partyaResource: formData.value.partyaResource ?? 0,
-        relocationTime: formData.value.relocationTime ?? 0,
-        winterBreakTime: formData.value.winterBreakTime ?? 0,
-        otherNptTime: formData.value.otherNptTime ?? 0,
-        otherNptReason: formData.value.otherNptReason || ''
-      })
-    }
-  }
-}
-
-// 从 platformWellPairs 加载平台井数据到表单
-const loadPlatformData = (platformId: number) => {
-  console.log('11 :>> ', 11)
-  const platformData = platformWellPairs.value.find((item) => item.taskId === platformId)
-  if (platformData) {
-    // 更新表单字段
-    formData.value.rdStatus = platformData.rdStatus || ''
-    // formData.value.dailyFuel = platformData.dailyFuel ? [...platformData.dailyFuel] : []
-    // 将施工工艺数值转换为对应的标签
-    if (platformData.techniqueIds && Array.isArray(platformData.techniqueIds)) {
-      // 如果是数字数组,转换为字符串数组(与数据字典格式匹配)
-      formData.value.techniqueIds = platformData.techniqueIds.map((id) => id.toString())
-    } else {
-      formData.value.techniqueIds = platformData.techniqueIds ? [...platformData.techniqueIds] : []
-    }
-
-    // 在详情或审批模式下,更新 dailyFuel 为当前平台井的值
-    if (isDetailMode.value || isApprovalMode.value) {
-      // 使用平台井的 dailyFuel 值
-      const platformDailyFuel = platformData.dailyFuel || ''
-      formData.value.dailyFuel = platformDailyFuel ? formatNumber(platformDailyFuel, 2) : ''
-      // 同步更新输入框
-      dailyFuelInput.value = formData.value.dailyFuel
-    }
-
-    // 更新动态属性
-    if (platformData.extProperty && platformData.extProperty.length > 0) {
-      const dynamicFields: Record<string, any> = {}
-      platformData.extProperty.forEach((prop: any) => {
-        if (prop.identifier) {
-          dynamicFields[prop.identifier] = prop.actualValue || ''
-        }
-      })
-      formData.value.dynamicFields = dynamicFields
-    } else {
-      formData.value.dynamicFields = {}
-    }
-
-    formData.value.repairTime = platformData.repairTime ?? 0
-    formData.value.selfStopTime = platformData.selfStopTime ?? 0
-    formData.value.accidentTime = platformData.accidentTime ?? 0
-    formData.value.complexityTime = platformData.complexityTime ?? 0
-    formData.value.rectificationTime = platformData.rectificationTime ?? 0
-    formData.value.waitingStopTime = platformData.waitingStopTime ?? 0
-    formData.value.partyaDesign = platformData.partyaDesign ?? 0
-    formData.value.partyaPrepare = platformData.partyaPrepare ?? 0
-    formData.value.partyaResource = platformData.partyaResource ?? 0
-    formData.value.relocationTime = platformData.relocationTime ?? 0
-    formData.value.winterBreakTime = platformData.winterBreakTime ?? 0
-    formData.value.otherNptTime = platformData.otherNptTime ?? 0
-    formData.value.otherNptReason = platformData.otherNptReason || ''
-  } else {
-    // 如果没有找到数据,初始化默认值
-    formData.value.rdStatus = ''
-    formData.value.techniqueIds = []
-    formData.value.dynamicFields = {}
-    // 初始化其他时间字段
-    formData.value.repairTime = 0
-    formData.value.selfStopTime = 0
-    formData.value.accidentTime = 0
-    formData.value.complexityTime = 0
-    formData.value.rectificationTime = 0
-    formData.value.waitingStopTime = 0
-    formData.value.partyaDesign = 0
-    formData.value.partyaPrepare = 0
-    formData.value.partyaResource = 0
-    formData.value.relocationTime = 0
-    formData.value.winterBreakTime = 0
-    formData.value.otherNptTime = 0
-    formData.value.otherNptReason = ''
-
-    // 在详情或审批模式下,清空 dailyFuel
-    if (isDetailMode.value || isApprovalMode.value) {
-      formData.value.dailyFuel = ''
-      dailyFuelInput.value = ''
-    }
-  }
-}
-
-// 获取当前动态属性数据
-const getCurrentExtProperties = () => {
-  return dynamicAttrs.value.map((attr) => {
-    return {
-      name: attr.name,
-      sort: attr.sort,
-      unit: attr.unit,
-      actualValue: formData.value.dynamicFields[attr.identifier] || '',
-      dataType: attr.dataType,
-      maxValue: attr.maxValue,
-      minValue: attr.minValue,
-      required: attr.required,
-      accessMode: attr.accessMode,
-      identifier: attr.identifier,
-      defaultValue: attr.defaultValue
-    }
-  })
-}
-
-// 是否显示实际进度
-const showActualProgress = computed(() => {
-  // 在所有模式下都显示,如果有数据就显示
-  return dailyReportData.value?.taskProgresses && dailyReportData.value.taskProgresses.length > 0
-})
-
-// 实际进度数据
-const actualProgressData = computed(() => {
-  if (
-    !dailyReportData.value?.taskProgresses ||
-    !Array.isArray(dailyReportData.value.taskProgresses)
-  ) {
-    return []
-  }
-
-  // 将 taskProgresses 转换为 el-steps 需要的格式
-  return dailyReportData.value.taskProgresses.map((progress: any, index: number) => {
-    // 格式化日期:如果只有日期部分,使用日期格式;如果有时间,使用日期时间格式
-    let formattedDate = ''
-    if (progress.createTime) {
-      // 判断日期格式,如果包含时间则显示完整时间,否则只显示日期
-      if (progress.createTime.includes(' ')) {
-        // 已经是完整的日期时间格式
-        formattedDate = progress.createTime
-      } else {
-        // 只有日期部分
-        formattedDate = progress.createTime
-      }
-    }
-
-    // 构建标题:日期 + 状态
-    const title =
-      formattedDate && progress.rdStatusLabel
-        ? `${formattedDate} ${progress.rdStatusLabel}`
-        : progress.rdStatusLabel || '未知状态'
-
-    return {
-      title: title,
-      description: '', // 可以根据需要添加描述信息
-      status: undefined, // el-steps 会自动计算状态
-      // 保留原始数据,便于调试
-      rawData: progress
-    }
-  })
-})
-
-// 初始化表单数据
-const initFormData = (reportData: any) => {
-  // 处理附件数据格式转换
-  const formattedAttachments = (reportData.attachments || []).map((attachment: any) => ({
-    id: attachment.id,
-    category: attachment.category?.toLowerCase() || 'daily_report',
-    bizId: attachment.bizId,
-    type: attachment.type?.toLowerCase() || 'attachment',
-    filename: attachment.filename,
-    fileType: attachment.fileType, // 使用辅助函数获取文件类型
-    filePath: attachment.filePath,
-    fileSize: attachment.fileSize,
-    remark: attachment.remark || ''
-  }))
-
-  // 确保 techniqueIds 是字符串数组格式
-  let techniqueIds = []
-  if (reportData.techniqueIds && Array.isArray(reportData.techniqueIds)) {
-    techniqueIds = reportData.techniqueIds.map((id: number) => id.toString())
-  }
-
-  formData.value = {
-    ...formData.value,
-    id: reportData.id,
-    deptId: reportData.deptId,
-    taskId: reportData.taskId,
-    platformWell: reportData.platformWell,
-    rdStatus: reportData.rdStatus || '',
-    techniqueIds: techniqueIds,
-    dailyFuel: reportData.dailyFuel, // 当日油耗默认值
-    productionStatus: reportData.productionStatus || '',
-    nextPlan: reportData.nextPlan || '',
-    externalRental: reportData.externalRental || '',
-    malfunction: reportData.malfunction || '',
-    faultDowntime: reportData.faultDowntime || '',
-    startTime: reportData.startTime || undefined,
-    endTime: reportData.endTime || undefined,
-    companyId: reportData.companyId || '',
-    dynamicFields: {}, // 确保有初始值
-    auditStatus: reportData.auditStatus,
-    // 初始化附件数据
-    attachments: formattedAttachments,
-    repairTime: reportData.repairTime ?? 0,
-    selfStopTime: reportData.selfStopTime ?? 0,
-    accidentTime: reportData.accidentTime ?? 0,
-    complexityTime: reportData.complexityTime ?? 0,
-    rectificationTime: reportData.rectificationTime ?? 0,
-    waitingStopTime: reportData.waitingStopTime ?? 0,
-    partyaDesign: reportData.partyaDesign ?? 0,
-    partyaPrepare: reportData.partyaPrepare ?? 0,
-    partyaResource: reportData.partyaResource ?? 0,
-    relocationTime: reportData.relocationTime ?? 0,
-    winterBreakTime: reportData.winterBreakTime ?? 0,
-    otherNptTime: reportData.otherNptTime ?? 0,
-    otherNptReason: reportData.otherNptReason || ''
-  }
-
-  // 初始化审批意见数据
-  approvalForm.opinion = reportData.auditOpinion || reportData.opinion || ''
-
-  queryParams.deptId = reportData.companyId
-  // 设置时间范围选择器
-  if (
-    reportData.startTime &&
-    Array.isArray(reportData.startTime) &&
-    reportData.endTime &&
-    Array.isArray(reportData.endTime)
-  ) {
-    // 基于日报的施工开始日期作为基准日期
-    const baseDate = reportData.constructionStartDate || Date.now()
-    const startTime = parseTimeArrayToDate(reportData.startTime, baseDate)
-    const endTime = parseTimeArrayToDate(reportData.endTime, baseDate)
-
-    if (startTime && endTime) {
-      formData.value.timeRange = [startTime, endTime]
-    }
-  }
-
-  // 初始化平台井数据
-  initPlatformData(reportData)
-
-  // 初始化动态属性
-  initDynamicAttrs(reportData)
-
-  // 初始化设备数据
-  initDeviceData(reportData)
-
-  // 初始化油耗数据 - 根据模式选择数据源
-  if (isDetailMode.value || isApprovalMode.value) {
-    // 详情或审批模式:优先使用 reportedFuels
-    let fuelSource = reportData.reportedFuels
-
-    if (fuelSource && Array.isArray(fuelSource) && fuelSource.length > 0) {
-      // 处理每个油耗数据项,设置 customFuel 的默认值并确保格式正确
-      const processedFuels = fuelSource.map((fuel: any) => {
-        // 创建全新的对象,避免引用共享
-        const newFuel = {
-          ...fuel, // 使用展开运算符创建浅拷贝
-          // 确保每个字段都有独立的值
-          createTime: fuel.createTime,
-          updateTime: fuel.updateTime,
-          creator: fuel.creator,
-          updater: fuel.updater,
-          deleted: fuel.deleted,
-          id: fuel.id,
-          type: fuel.type,
-          reportId: fuel.reportId,
-          deviceId: fuel.deviceId,
-          deviceCode: fuel.deviceCode,
-          yfDeviceCode: fuel.yfDeviceCode,
-          deviceName: fuel.deviceName,
-          carId: fuel.carId,
-          zhbdFuel: fuel.zhbdFuel,
-          customFuel: null, // 初始化为null
-          queryDate: fuel.queryDate,
-          remark: fuel.remark
-        }
-
-        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 {
-          ...newFuel,
-          customFuel: customFuelValue
-        }
-      })
-
-      formData.value.reportFuels = processedFuels
-
-      // 计算初始的当日油耗
-      calculateTotalDailyFuel()
-    } else {
-      // 如果 reportedFuels 不存在或为空,设置空数组
-      formData.value.reportFuels = []
-    }
-  } else {
-    // 编辑模式:优先使用 reportedFuels,不存在则使用 reportFuels
-    let fuelSource = reportData.reportedFuels || reportData.reportFuels || []
-
-    if (fuelSource && Array.isArray(fuelSource) && fuelSource.length > 0) {
-      // 处理每个油耗数据项,设置 customFuel 的默认值并确保格式正确
-      const processedFuels = fuelSource.map((fuel: any) => {
-        // 创建全新的对象,避免引用共享
-        const newFuel = {
-          ...fuel, // 使用展开运算符创建浅拷贝
-          // 确保每个字段都有独立的值
-          createTime: fuel.createTime,
-          updateTime: fuel.updateTime,
-          creator: fuel.creator,
-          updater: fuel.updater,
-          deleted: fuel.deleted,
-          id: fuel.id,
-          type: fuel.type,
-          reportId: fuel.reportId,
-          deviceId: fuel.deviceId,
-          deviceCode: fuel.deviceCode,
-          yfDeviceCode: fuel.yfDeviceCode,
-          deviceName: fuel.deviceName,
-          carId: fuel.carId,
-          zhbdFuel: fuel.zhbdFuel,
-          customFuel: null, // 初始化为null
-          queryDate: fuel.queryDate,
-          remark: fuel.remark
-        }
-
-        let customFuelValue
-
-        // 如果 customFuel 不为空,确保它是字符串格式并已正确格式化
-        if (fuel.customFuel !== null && fuel.customFuel !== undefined && fuel.customFuel !== '') {
-          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 {
-          ...newFuel,
-          customFuel: customFuelValue
-        }
-      })
-
-      formData.value.reportFuels = processedFuels
-
-      // 计算初始的当日油耗
-      calculateTotalDailyFuel()
-    } else {
-      formData.value.reportFuels = []
-    }
-  }
-}
-
-onMounted(async () => {
-  formLoading.value = true
-  try {
-    // 加载当前登录人所属部门
-    const deptId = userStore.getUser.deptId
-    const dept = await DeptApi.getDept(deptId)
-
-    // 查询瑞都日报详情
-    if (id) {
-      const response = await IotRdDailyReportApi.getIotRdDailyReport(id)
-      console.log('response :>> ', response)
-      dailyReportData.value = response || {}
-      initFormData(dailyReportData.value)
-
-      // 确保油耗数据在初始化后立即渲染
-      await nextTick()
-      // 强制更新油耗数据
-      if (formData.value.reportFuels && formData.value.reportFuels.length > 0) {
-        formData.value.reportFuels = [...formData.value.reportFuels]
-      }
-    }
-  } catch (error) {
-    console.error('初始化数据失败:', error)
-    message.error('数据加载失败')
-  } finally {
-    formLoading.value = false
-  }
-})
-
-// 详细 审批 平台井 获取工作量列配置
-const getWorkloadColumns = () => {
-  const dataSource = platformWorkloadData.value
-  if (!dataSource || dataSource.length === 0) return []
-
-  const columns = []
-  const addedIdentifiers = new Set()
-
-  dataSource.forEach((platform) => {
-    if (platform.extProperty && Array.isArray(platform.extProperty)) {
-      platform.extProperty.forEach((extProp) => {
-        if (!addedIdentifiers.has(extProp.identifier)) {
-          columns.push({
-            key: extProp.identifier,
-            identifier: extProp.identifier,
-            label: `${extProp.name}(${extProp.unit})`
-          })
-          addedIdentifiers.add(extProp.identifier)
-        }
-      })
-    }
-  })
-
-  return columns
-}
-
-// 添加一个深拷贝油耗数据的辅助函数
-const deepCopyFuelData = (fuelData: any) => {
-  if (!fuelData) return null
-
-  return {
-    createTime: fuelData.createTime,
-    updateTime: fuelData.updateTime,
-    creator: fuelData.creator,
-    updater: fuelData.updater,
-    deleted: fuelData.deleted,
-    id: fuelData.id,
-    type: fuelData.type,
-    reportId: fuelData.reportId,
-    deviceId: fuelData.deviceId,
-    deviceCode: fuelData.deviceCode,
-    yfDeviceCode: fuelData.yfDeviceCode,
-    deviceName: fuelData.deviceName,
-    carId: fuelData.carId,
-    zhbdFuel: fuelData.zhbdFuel,
-    customFuel: fuelData.customFuel,
-    queryDate: fuelData.queryDate,
-    remark: fuelData.remark
-  }
-}
-
-// 强制刷新表格
-const refreshFuelTable = () => {
-  fuelTableKey.value += 1
-}
-
-// 计算当日油耗的默认值
-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 fuelConsumptionData = computed(() => {
-  // 所有模式都统一使用 formData.value.reportFuels 作为数据源
-  // 因为 formData.value.reportFuels 在 initFormData 中已经正确处理了所有情况
-  return formData.value.reportFuels || []
-})
-
-// 判断是否显示油耗信息区域
-const showFuelConsumption = computed(() => {
-  const data = fuelConsumptionData.value
-  return data && Array.isArray(data) && data.length > 0
-})
-
-// 重新计算当日油耗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'
-  }
-
-  // 同步更新 formData.reportFuels 中的数据
-  // 确保通过 deviceId 正确找到并更新对应的记录
-  if (formData.value.reportFuels && fuelItem.deviceId) {
-    const index = formData.value.reportFuels.findIndex(
-      (item) => item.deviceId === fuelItem.deviceId
-    )
-
-    if (index !== -1) {
-      // 创建新对象,避免引用问题
-      const updatedFuel = {
-        ...formData.value.reportFuels[index],
-        customFuel: fuelItem.customFuel
-      }
-
-      // 使用 Vue.set 或直接赋值确保响应性
-      formData.value.reportFuels[index] = updatedFuel
-
-      // 强制刷新表格
-      fuelTableKey.value += 1
-    }
-  }
-
-  // 手动触发当日油耗的重新计算
-  calculateAndUpdateDailyFuel()
-}
-
-// 详情 审批 平台井 获取工作量值
-const getWorkloadValue = (platform, identifier) => {
-  if (!platform.extProperty) return ''
-  const prop = platform.extProperty.find((item) => item.identifier === identifier)
-  return prop ? prop.actualValue || '' : ''
-}
-
-/** 审批操作 */
-const handleApprove = async (action: 'pass' | 'reject') => {
-  // 只有在审批模式下才执行审批操作
-  if (!isApprovalMode.value) {
-    message.warning('当前不是审批模式')
-    return
-  }
-  try {
-    // 验证审批表单(如果需要)
-    // await approvalFormRef.value.validate()
-
-    formLoading.value = true
-
-    // 处理时间范围数据
-    if (formData.value.timeRange && formData.value.timeRange.length === 2) {
-      // 将时间范围转换为 LocalTime 格式的字符串
-      const startDate = dayjs(formData.value.timeRange[0])
-      const endDate = dayjs(formData.value.timeRange[1])
-
-      // 格式化为 HH:mm:ss 字符串,后端会自动转换为 LocalTime
-      formData.value.startTime = startDate.format('HH:mm:ss')
-      formData.value.endTime = endDate.format('HH:mm:ss')
-    }
-
-    // 构建审批数据,包含审批意见
-    const approveData = {
-      ...formData.value,
-      id: Number(id),
-      opinion: approvalForm.opinion,
-      auditStatus: action === 'pass' ? 20 : 30
-    }
-
-    // 这里可以调用审批API
-    if (action === 'pass') {
-      // 审批通过逻辑
-      await IotRdDailyReportApi.approveRdDailyReport(approveData)
-      message.success('审批通过')
-    } else {
-      // 审批驳回逻辑
-      await IotRdDailyReportApi.approveRdDailyReport(approveData)
-      message.success('审批驳回')
-    }
-    close()
-  } catch (error) {
-    console.error('审批操作失败:', error)
-    message.error('审批操作失败')
-  } finally {
-    formLoading.value = false
-  }
-}
-</script>
-
-<style scoped>
-.info-table {
-  border: 1px solid #e0e0e0;
-  border-radius: 4px;
-  overflow: hidden;
-}
-
-.table-row {
-  display: flex;
-  border-bottom: 1px solid #e0e0e0;
-}
-
-.table-row:last-child {
-  border-bottom: none;
-}
-
-.table-cell {
-  flex: 1;
-  border-right: 1px solid #e0e0e0;
-  padding: 12px 8px;
-  min-height: 44px;
-  display: flex;
-  align-items: center;
-}
-
-.table-cell:last-child {
-  border-right: none;
-}
-
-.table-cell.full-width {
-  flex: 1;
-  border-right: none;
-}
-
-.cell-content {
-  display: flex;
-  align-items: center;
-  width: 100%;
-}
-
-.cell-label {
-  font-weight: 500;
-  /* 统一字体大小为 14px(Element 表单默认) */
-  font-size: 14px;
-  color: #606266;
-  min-width: 80px;
-  margin-right: 8px;
-  flex-shrink: 0;
-}
-
-.cell-value {
-  /* 统一字体大小为 14px(Element 输入框默认) */
-  font-size: 14px;
-  color: #303133;
-  /* 统一行高为 1.5(Element 组件默认行高) */
-  line-height: 1.5;
-  flex: 1;
-  word-break: break-all;
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-  .table-row {
-    flex-direction: column;
-  }
-
-  .table-cell {
-    border-right: none;
-    border-bottom: 1px solid #e0e0e0;
-  }
-
-  .table-cell:last-child {
-    border-bottom: none;
-  }
-}
-
-.daily-report-title {
-  text-align: center;
-  margin: 20px 0;
-  padding: 10px;
-  border-bottom: 2px solid #409eff;
-}
-
-.daily-report-title h2 {
-  margin: 0;
-  color: #303133;
-  font-size: 16px;
-  font-weight: bold;
-}
-
-/* 为第二、三部分增加左右留白 */
-.section-padding {
-  padding-left: 0px;
-  padding-right: 40px;
-}
-
-.project-info-section {
-  margin: 20px 0;
-  padding: 20px;
-  background-color: #f8f9fa;
-  border-radius: 4px;
-  border: 1px solid #e9ecef;
-}
-
-.info-row {
-  padding: 12px 0;
-  border-bottom: 1px solid #e9ecef;
-}
-
-.info-row:last-child {
-  border-bottom: none;
-}
-
-.info-label {
-  font-weight: bold;
-  color: #495057;
-  margin-right: 8px;
-}
-
-.info-value {
-  color: #212529;
-}
-
-:deep(.el-textarea .el-textarea__inner) {
-  min-height: 80px;
-}
-
-/* 确保表单label不换行 */
-:deep(.el-form-item__label) {
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  overflow: hidden;
-}
-
-/* 甲方字段:单行显示+超出省略 */
-.single-line-ellipsis {
-  /* 强制文本单行显示 */
-  white-space: nowrap;
-  /* 超出容器部分隐藏 */
-  overflow: hidden;
-  /* 超出部分显示省略号 */
-  text-overflow: ellipsis;
-  /* 避免文本被截断(可选,根据需求调整) */
-  word-break: normal;
-}
-
-/* 设备配置字段:换行缩进(与首行对齐) */
-.indent-multiline {
-  /* 首行及换行后缩进 2em(与 label 宽度匹配,可根据需求调整) */
-  text-indent: 0em;
-  /* 允许长文本换行(覆盖原有 cell-value 的 break-all,确保中文换行正常) */
-  word-break: break-word;
-  /* 保证换行后文本正常显示(可选,清除可能的 nowrap 影响) */
-  white-space: normal;
-}
-
-/* 添加审批模式下的样式 */
-.approval-notice {
-  margin-top: 10px;
-}
-
-/* 审批模式下表单字段的只读样式 */
-:deep(.el-form-item.is-disabled .el-input__inner),
-:deep(.el-form-item.is-disabled .el-textarea__inner) {
-  background-color: #f5f7fa;
-  border-color: #e4e7ed;
-  color: #c0c4cc;
-  cursor: not-allowed;
-}
-
-:deep(.el-form-item.is-disabled .el-select .el-input__inner) {
-  background-color: #f5f7fa;
-  border-color: #e4e7ed;
-  color: #c0c4cc;
-  cursor: not-allowed;
-}
-
-:deep(.el-form-item.is-disabled .el-date-editor .el-input__inner) {
-  background-color: #f5f7fa;
-  border-color: #e4e7ed;
-  color: #c0c4cc;
-  cursor: not-allowed;
-}
-
-/* 只读模式下表单字段的样式 */
-:deep(.el-form-item.is-disabled .el-input__inner),
-:deep(.el-form-item.is-disabled .el-textarea__inner),
-:deep(.el-form-item.is-disabled .el-select .el-input__inner),
-:deep(.el-form-item.is-disabled .el-date-editor .el-input__inner) {
-  background-color: #f5f7fa;
-  border-color: #e4e7ed;
-  color: #606266; /* 保持文字可读性 */
-  cursor: not-allowed;
-}
-
-/* 详情模式下的特殊样式 */
-.detail-mode .cell-value {
-  color: #303133;
-  font-weight: normal;
-}
-
-/* 添加审批意见区域的样式 */
-.approval-opinion-section {
-  margin-top: 20px;
-  border-top: 2px solid #f0f0f0;
-  padding-top: 20px;
-}
-
-/* 审批意见文本域样式 */
-:deep(.approval-opinion .el-textarea__inner) {
-  min-height: 100px;
-  resize: vertical;
-}
-
-/* 审批意见标签样式 */
-:deep(.approval-opinion .el-form-item__label) {
-  font-weight: bold;
-  color: #606266;
-}
-
-/* 附件列表样式 */
-.attachment-list {
-  width: 100%;
-  margin-top: 5px;
-  border: 1px solid #e0e0e0;
-  border-radius: 4px;
-  padding: 10px;
-  background-color: #fafafa;
-  box-sizing: border-box;
-}
-
-.attachment-item {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding: 8px 12px;
-  border-bottom: 1px solid #f0f0f0;
-}
-
-.attachment-item:last-child {
-  border-bottom: none;
-}
-
-.attachment-name {
-  flex: 1;
-  color: #606266;
-  font-size: 11px;
-}
-
-.no-attachment {
-  color: #909399;
-  font-style: italic;
-  margin-top: 5px;
-  padding: 10px;
-}
-
-/* 附件名称链接样式 */
-.attachment-name {
-  color: #409eff;
-  text-decoration: underline;
-  cursor: pointer;
-}
-
-.attachment-name:hover {
-  color: #66b1ff;
-}
-
-/* 只读模式下的设备显示样式 */
-.device-display-readonly {
-  color: #606266;
-  font-size: 11px;
-  line-height: 1.5;
-  background-color: #f5f7fa;
-  padding: 8px 12px;
-  border-radius: 4px;
-  border: 1px solid #e4e7ed;
-  display: inline-block;
-  min-width: 200px;
-}
-
-.no-device {
-  margin-left: 10px;
-  color: #909399;
-  font-style: italic;
-}
-
-/* 设备选择对话框样式 */
-.transfer-container {
-  text-align: center;
-  padding: 0px;
-}
-
-.transfer-component {
-  width: 100%;
-  min-width: 600px;
-}
-
-:deep(.el-transfer-panel) {
-  width: 40% !important;
-}
-
-:deep(.el-transfer-panel__item) {
-  display: flex !important;
-  align-items: center !important;
-  height: 32px !important;
-  line-height: 32px !important;
-  padding: 0 8px !important;
-  margin: 0 !important;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-.transfer-option-text {
-  display: inline-block;
-  max-width: 100%;
-}
-
-:deep(.el-transfer-panel__list) {
-  width: 100% !important;
-}
-
-.device-display-container {
-  /* 与其他文本域保持相同的宽度和样式 */
-  display: inline-block;
-  width: 100%; /* 减去按钮宽度 */
-  min-height: 32px;
-  line-height: 32px;
-  padding: 0 12px;
-  margin-left: 0px;
-  border-radius: 4px;
-  border: 1px solid #e4e7ed;
-  background-color: #fff;
-  font-size: 11px;
-  /* 文本溢出处理 */
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-/* 只读模式下的设备显示样式 */
-:deep(.is-disabled) .device-display-container {
-  background-color: #f5f7fa;
-  color: #606266;
-  cursor: not-allowed;
-}
-
-/* 附件容器样式调整 */
-.attachment-container {
-  /* 与其他文本域保持相同的宽度和边距 */
-  width: 100%;
-  margin-top: 10px;
-}
-
-/* 未选择设备字段的只读样式 */
-:deep(.unselected-device .el-textarea__inner) {
-  background-color: #f5f7fa;
-  border-color: #e4e7ed;
-  color: #909399;
-  cursor: not-allowed;
-  resize: none;
-}
-
-/* 平台井工作量区域专用样式 */
-.platform-workload-section {
-  padding-left: 0px;
-  padding-right: 0px; /* 去掉右侧间距 */
-}
-
-/* 表格样式优化 */
-.platform-workload-el-table {
-  width: 100%;
-}
-
-/* 表头不换行 */
-:deep(.platform-workload-el-table .el-table__header-wrapper th) {
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  overflow: hidden;
-}
-
-/* 单元格内容不换行 */
-:deep(.platform-workload-el-table .el-table__body-wrapper td) {
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  overflow: hidden;
-}
-
-/* 强制设置表头宽度为100% */
-:deep(.platform-workload-el-table .el-table__header) {
-  width: 100% !important;
-  min-width: 100% !important;
-}
-
-/* 强制设置表格主体宽度为100% */
-:deep(.platform-workload-el-table .el-table__body) {
-  width: 100% !important;
-  min-width: 100% !important;
-}
-
-/* 确保表格填满容器 */
-:deep(.platform-workload-el-table .el-table) {
-  width: 100% !important;
-}
-
-/* 表格容器填满父容器 */
-.platform-workload-table {
-  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;
-}
-
-/* 实际进度区域样式 */
-.actual-progress-container {
-  margin-top: 10px;
-  padding: 20px;
-  border: 1px solid #e6e6e6;
-  border-radius: 8px;
-  background-color: #fafafa;
-}
-
-.progress-title {
-  margin: 0 0 16px 0;
-  font-size: 16px;
-  font-weight: bold;
-  color: #67c23a; /* 实际进度使用绿色标题 */
-}
-
-.no-progress-data {
-  text-align: center;
-  padding: 20px 0;
-  color: #909399;
-  font-style: italic;
-}
-
-/* 调整步骤组件样式以适应水平布局 */
-:deep(.actual-progress-container .el-steps--horizontal) {
-  flex-wrap: nowrap;
-  overflow-x: auto;
-  padding-bottom: 10px;
-}
-
-:deep(.actual-progress-container .el-step__title) {
-  font-size: 12px;
-  line-height: 1.4;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  max-width: 120px;
-}
-
-/* 确保步骤容器有足够空间 */
-:deep(.actual-progress-container .el-step) {
-  flex-basis: auto;
-  flex-shrink: 0;
-}
-
-/* 响应式调整 */
-@media (max-width: 768px) {
-  :deep(.actual-progress-container .el-step__title) {
-    font-size: 11px;
-    max-width: 100px;
-  }
-
-  .actual-progress-container {
-    padding: 15px;
-  }
-}
-</style>

+ 9 - 1
src/views/pms/iotrddailyreport/create-rd-form.vue

@@ -8,7 +8,9 @@ import * as DeptApi from '@/api/system/dept'
 import { IotRdDailyReportApi } from '@/api/pms/iotrddailyreport'
 import { formatT } from '@/utils/formatTime'
 
-const deptId = useUserStore().getUser.deptId
+const user = useUserStore().getUser
+
+const deptId = user.deptId
 
 interface Props {
   visible: boolean
@@ -120,6 +122,8 @@ const userOptions = ref<UserOptions[]>([])
 
 const deptName = ref('')
 
+const submitterNames = ref('')
+
 async function loadDept() {
   const res = await DeptApi.getDept(deptId)
   deptName.value = res.name
@@ -141,9 +145,12 @@ async function load() {
 
   await loadUserOptions()
 
+  submitterNames.value = user.nickname
+
   if (props.isview && props.id) {
     const res = await IotRdDailyReportApi.getIotRdDailyReport(props.id)
     deptName.value = res.deptName
+    submitterNames.value = res.submitterNames
     form.value = {
       deptId: res.deptId,
       location: res.location,
@@ -256,6 +263,7 @@ async function submitForm() {
               placeholder="请选择带班干部"
             />
           </el-form-item>
+          <el-form-item label="填报人" prop="submitterNames"> {{ submitterNames }} </el-form-item>
           <el-form-item label="时间节点" prop="timeRange">
             <el-time-picker
               v-model="form.timeRange"

+ 0 - 544
src/views/pms/iotrddailyreport/fillDailyReport1.vue

@@ -1,544 +0,0 @@
-<template>
-  <el-row :gutter="20">
-    <el-col :span="4" :xs="24">
-      <ContentWrap class="h-1/1">
-        <DeptTree2 :deptId="rootDeptId" @node-click="handleDeptNodeClick" />
-      </ContentWrap>
-    </el-col>
-    <el-col :span="20" :xs="24">
-      <ContentWrap>
-        <!-- 搜索工作栏 -->
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="68px"
-        >
-          <el-form-item label="项目" prop="contractName">
-            <el-input
-              v-model="queryParams.contractName"
-              placeholder="请输入项目"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="任务" prop="taskName">
-            <el-input
-              v-model="queryParams.taskName"
-              placeholder="请输入任务"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="创建时间" prop="createTime">
-            <el-date-picker
-              v-model="queryParams.createTime"
-              value-format="YYYY-MM-DD HH:mm:ss"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              class="!w-220px"
-              :shortcuts="rangeShortcuts"
-            />
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="handleQuery"
-              ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
-            >
-            <el-button @click="resetQuery"
-              ><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
-            >
-            <el-button
-              type="primary"
-              plain
-              @click="openForm('create')"
-              v-hasPermi="['pms:iot-rd-daily-report:create']"
-            >
-              <Icon icon="ep:plus" class="mr-5px" /> 新增
-            </el-button>
-            <!-- <el-button type="success" plain @click="handleExport" :loading="exportLoading">
-              <Icon icon="ep:download" class="mr-5px" /> 导出
-            </el-button> -->
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-
-      <!-- 列表 -->
-      <ContentWrap>
-        <el-table
-          v-loading="loading"
-          :data="list"
-          :stripe="true"
-          :style="{ width: '100%' }"
-          max-height="600"
-          show-overflow-tooltip
-          border
-        >
-          <el-table-column label="操作" align="center" min-width="120px">
-            <template #default="scope">
-              <el-button
-                link
-                type="primary"
-                @click="openForm('fill', scope.row.id)"
-                v-hasPermi="['pms:iot-rd-daily-report:update']"
-                v-if="scope.row.status === 0"
-              >
-                填报
-              </el-button>
-              <el-button
-                link
-                type="success"
-                @click="handleDetail(scope.row.id)"
-                v-hasPermi="['pms:iot-rd-daily-report:query']"
-              >
-                查看
-              </el-button>
-              <el-button
-                link
-                :type="
-                  scope.row.nonProductFlag || scope.row.processInstanceId === '2'
-                    ? 'success'
-                    : 'warning'
-                "
-                @click="openForm('fill', scope.row.id, 'true')"
-                v-hasPermi="['pms:iot-rd-daily-report:non-productive']"
-                v-if="scope.row.auditStatus === 20"
-              >
-                时效
-              </el-button>
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="创建时间"
-            align="center"
-            prop="createTime"
-            :formatter="dateFormatter2"
-            width="180px"
-          />
-          <el-table-column label="日报状态" align="center" prop="status">
-            <template #default="scope">
-              <dict-tag :type="DICT_TYPE.OPERATION_FILL_ORDER_STATUS" :value="scope.row.status" />
-            </template>
-          </el-table-column>
-          <el-table-column label="审批状态" align="center" prop="auditStatus" :min-width="84">
-            <template #default="scope">
-              <el-tag v-if="scope.row.auditStatus === 0" type="info">
-                {{ '待提交' }}
-              </el-tag>
-              <el-tag v-else-if="scope.row.auditStatus === 10">
-                {{ '待审批' }}
-              </el-tag>
-              <el-tag v-else-if="scope.row.auditStatus === 20" type="success">
-                {{ '审批通过' }}
-              </el-tag>
-              <el-tag v-else-if="scope.row.auditStatus === 30" type="danger">
-                {{ '审批拒绝' }}
-              </el-tag>
-            </template>
-          </el-table-column>
-          <el-table-column label="施工队伍" align="center" prop="deptName" />
-          <el-table-column label="项目" align="center" prop="contractName" />
-          <el-table-column label="任务" align="center" prop="taskName" />
-          <el-table-column label="非生产时间" align="center">
-            <el-table-column
-              label="工程质量"
-              align="center"
-              prop="accidentTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="设备故障"
-              align="center"
-              prop="repairTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="设备保养"
-              align="center"
-              prop="selfStopTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="技术受限"
-              align="center"
-              prop="complexityTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="生产配合"
-              align="center"
-              prop="relocationTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="生产组织"
-              align="center"
-              prop="rectificationTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="不可抗力"
-              align="center"
-              prop="waitingStopTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="待命"
-              align="center"
-              prop="winterBreakTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="甲方设计"
-              align="center"
-              prop="partyaDesign"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="甲方准备"
-              align="center"
-              prop="partyaPrepare"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="甲方资源"
-              align="center"
-              prop="partyaResource"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="其它非生产时间"
-              align="center"
-              prop="otherNptTime"
-              :min-width="110"
-              resizable
-            />
-          </el-table-column>
-          <el-table-column
-            label="其他非生产时间原因"
-            align="center"
-            prop="otherNptReason"
-            :min-width="140"
-            resizable
-          />
-          <!-- <el-table-column
-            label="非生产时间填写"
-            align="center"
-            prop="nonProductFlag"
-            :min-width="110"
-          >
-            <template #default="scope">
-              <el-tag
-                :type="
-                  scope.row.nonProductFlag || scope.row.processInstanceId === '2'
-                    ? 'success'
-                    : 'danger'
-                "
-              >
-                {{
-                  scope.row.nonProductFlag || scope.row.processInstanceId === '2'
-                    ? '已填写'
-                    : '未填写'
-                }}
-              </el-tag>
-            </template>
-          </el-table-column> -->
-          <el-table-column
-            label="非生产时效"
-            align="center"
-            prop="nonProductionRate"
-            :min-width="80"
-            resizable
-            :formatter="(row) => (Number(row.nonProductionRate ?? 0) * 100).toFixed(2) + '%'"
-          />
-          <el-table-column label="带班干部" align="center" prop="responsiblePersonNames" />
-          <el-table-column label="填报人" align="center" prop="submitterNames" />
-          <!--
-          <el-table-column label="项目类别(钻井 修井 注氮 酸化压裂... )" align="center" prop="projectClassification" /> -->
-          <!--
-          <el-table-column label="时间节点-结束" align="center" prop="endTime" />
-          <el-table-column
-            label="施工开始日期"
-            align="center"
-            prop="constructionStartDate"
-            :formatter="dateFormatter"
-            width="180px"
-          />
-          <el-table-column
-            label="施工结束日期"
-            align="center"
-            prop="constructionEndDate"
-            :formatter="dateFormatter"
-            width="180px"
-          /> -->
-        </el-table>
-        <!-- 分页 -->
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
-        />
-      </ContentWrap>
-    </el-col>
-  </el-row>
-
-  <!-- 表单弹窗:添加/修改
-  <IotRdDailyReportForm ref="formRef" @success="getList" /> -->
-</template>
-
-<script setup lang="ts">
-import { dateFormatter2 } from '@/utils/formatTime'
-import { IotRdDailyReportApi, IotRdDailyReportVO } from '@/api/pms/iotrddailyreport'
-import { DICT_TYPE } from '@/utils/dict'
-import DeptTree2 from '@/views/pms/iotrhdailyreport/DeptTree2.vue'
-
-import dayjs from 'dayjs'
-import quarterOfYear from 'dayjs/plugin/quarterOfYear'
-
-dayjs.extend(quarterOfYear)
-
-const rangeShortcuts = [
-  {
-    text: '今天',
-    value: () => {
-      const today = dayjs()
-      return [today.startOf('day').toDate(), today.endOf('day').toDate()]
-    }
-  },
-  {
-    text: '昨天',
-    value: () => {
-      const yesterday = dayjs().subtract(1, 'day')
-      return [yesterday.startOf('day').toDate(), yesterday.endOf('day').toDate()]
-    }
-  },
-  {
-    text: '本周',
-    value: () => {
-      return [dayjs().startOf('week').toDate(), dayjs().endOf('week').toDate()]
-    }
-  },
-  {
-    text: '上周',
-    value: () => {
-      const lastWeek = dayjs().subtract(1, 'week')
-      return [lastWeek.startOf('week').toDate(), lastWeek.endOf('week').toDate()]
-    }
-  },
-  {
-    text: '本月',
-    value: () => {
-      return [dayjs().startOf('month').toDate(), dayjs().endOf('month').toDate()]
-    }
-  },
-  {
-    text: '上月',
-    value: () => {
-      const lastMonth = dayjs().subtract(1, 'month')
-      return [lastMonth.startOf('month').toDate(), lastMonth.endOf('month').toDate()]
-    }
-  },
-  {
-    text: '本季度',
-    value: () => {
-      return [dayjs().startOf('quarter').toDate(), dayjs().endOf('quarter').toDate()]
-    }
-  },
-  {
-    text: '上季度',
-    value: () => {
-      const lastQuarter = dayjs().subtract(1, 'quarter')
-      return [lastQuarter.startOf('quarter').toDate(), lastQuarter.endOf('quarter').toDate()]
-    }
-  },
-  {
-    text: '今年',
-    value: () => {
-      return [dayjs().startOf('year').toDate(), dayjs().endOf('year').toDate()]
-    }
-  },
-  {
-    text: '去年',
-    value: () => {
-      const lastYear = dayjs().subtract(1, 'year')
-      return [lastYear.startOf('year').toDate(), lastYear.endOf('year').toDate()]
-    }
-  },
-  {
-    text: '最近7天',
-    value: () => {
-      return [dayjs().subtract(6, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近30天',
-    value: () => {
-      return [dayjs().subtract(29, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近90天',
-    value: () => {
-      return [dayjs().subtract(89, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近一年',
-    value: () => {
-      return [dayjs().subtract(1, 'year').toDate(), dayjs().toDate()]
-    }
-  }
-]
-
-/** 瑞都日报 填报 列表 */
-defineOptions({ name: 'FillDailyReport' })
-
-const message = useMessage() // 消息弹窗
-const { t } = useI18n() // 国际化
-const { push } = useRouter() // 路由跳转
-const loading = ref(true) // 列表的加载中
-const list = ref<IotRdDailyReportVO[]>([]) // 列表的数据
-const total = ref(0) // 列表的总页数
-
-const rootDeptId = ref(163)
-
-const queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: undefined,
-  projectId: undefined,
-  contractName: undefined,
-  taskId: undefined,
-  taskName: undefined,
-  projectClassification: undefined,
-  techniqueIds: undefined,
-  deviceIds: undefined,
-  startTime: [],
-  endTime: [],
-  cumulativeWorkingWell: undefined,
-  cumulativeWorkingLayers: undefined,
-  dailyPumpTrips: undefined,
-  dailyToolsSand: undefined,
-  runCount: undefined,
-  bridgePlug: undefined,
-  waterVolume: undefined,
-  hourCount: undefined,
-  dailyFuel: undefined,
-  dailyPowerUsage: undefined,
-  productionTime: [],
-  nonProductionTime: [],
-  rdNptReason: undefined,
-  constructionStartDate: [],
-  constructionEndDate: [],
-  productionStatus: undefined,
-  externalRental: undefined,
-  nextPlan: undefined,
-  rdStatus: undefined,
-  malfunction: undefined,
-  faultDowntime: [],
-  personnel: undefined,
-  totalStaffNum: undefined,
-  leaveStaffNum: undefined,
-  extProperty: undefined,
-  sort: undefined,
-  remark: undefined,
-  status: undefined,
-  processInstanceId: undefined,
-  auditStatus: undefined,
-  createTime: []
-})
-const queryFormRef = ref() // 搜索的表单
-
-/** 查询列表 */
-const getList = async () => {
-  loading.value = true
-  try {
-    const data = await IotRdDailyReportApi.getIotRdDailyReportPage(queryParams)
-    list.value = data.list
-    total.value = data.total
-  } finally {
-    loading.value = false
-  }
-}
-
-// 响应式变量存储选中的部门
-const selectedDept = ref<{ id: number; name: string }>()
-/** 处理部门被点击 */
-const handleDeptNodeClick = async (row) => {
-  // 记录选中的部门信息
-  selectedDept.value = { id: row.id, name: row.name }
-  queryParams.deptId = row.id
-  await getList()
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.pageNo = 1
-  getList()
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  handleQuery()
-}
-
-/** 添加/修改操作 */
-const formRef = ref()
-const openForm = (type: string, id?: number, istime: string = 'false') => {
-  push({ name: 'FillDailyReportForm', params: { id: id, mode: 'fill' }, query: { istime: istime } })
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (id: number) => {
-  try {
-    // 删除的二次确认
-    await message.delConfirm()
-    // 发起删除
-    await IotRdDailyReportApi.deleteIotRdDailyReport(id)
-    message.success(t('common.delSuccess'))
-    // 刷新列表
-    await getList()
-  } catch {}
-}
-
-/** 查看日报详情 */
-const handleDetail = async (id: number) => {
-  try {
-    // 跳转到 FillDailyReportForm 页面,传递审批模式和ID
-    push({
-      name: 'FillDailyReportForm',
-      params: {
-        id: id.toString(),
-        mode: 'detail' // 添加详情模式标识
-      }
-    })
-  } catch (error) {
-    console.error('跳转详情页面失败:', error)
-  }
-}
-
-const exportLoading = ref(false)
-const handleExport = async () => {}
-
-/** 初始化 **/
-onMounted(() => {
-  getList()
-})
-</script>

+ 1 - 7
src/views/pms/iotrddailyreport/index.vue

@@ -338,13 +338,7 @@ onMounted(() => {
               >
                 <template #default="{ row }">
                   <div v-if="row.reportDetails && row.reportDetails.length > 0" class="py-2">
-                    <el-popover
-                      placement="right"
-                      trigger="hover"
-                      width="320"
-                      popper-class="!p-0"
-                      :disabled="row.reportDetails.length <= 1"
-                    >
+                    <el-popover placement="right" trigger="hover" width="320" popper-class="!p-0">
                       <template #reference>
                         <el-badge
                           :value="row.reportDetails.length"

+ 0 - 996
src/views/pms/iotrddailyreport/index1.vue

@@ -1,996 +0,0 @@
-<template>
-  <el-row :gutter="20">
-    <el-col :span="4" :xs="24">
-      <ContentWrap class="h-1/1">
-        <DeptTree2 :deptId="rootDeptId" @node-click="handleDeptNodeClick" />
-      </ContentWrap>
-    </el-col>
-    <el-col :span="20" :xs="24">
-      <ContentWrap>
-        <!-- 搜索工作栏 -->
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="68px"
-        >
-          <el-form-item label="项目" prop="contractName">
-            <el-input
-              v-model="queryParams.contractName"
-              placeholder="请输入项目"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="任务" prop="taskName">
-            <el-input
-              v-model="queryParams.taskName"
-              placeholder="请输入任务"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="创建时间" prop="createTime">
-            <el-date-picker
-              v-model="queryParams.createTime"
-              value-format="YYYY-MM-DD HH:mm:ss"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              class="!w-220px"
-              :shortcuts="rangeShortcuts"
-            />
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="handleQuery"
-              ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
-            >
-            <el-button @click="resetQuery"
-              ><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
-            >
-            <el-button
-              type="primary"
-              plain
-              @click="openForm('create')"
-              v-hasPermi="['pms:iot-rd-daily-report:create']"
-            >
-              <Icon icon="ep:plus" class="mr-5px" /> 新增
-            </el-button>
-            <el-button type="success" plain @click="handleExport" :loading="exportLoading">
-              <Icon icon="ep:download" class="mr-5px" /> 导出
-            </el-button>
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-      <!-- 列表 -->
-      <ContentWrap ref="tableContainerRef">
-        <el-table
-          ref="tableRef"
-          v-loading="loading"
-          :data="list"
-          :stripe="true"
-          :style="{ width: '100%' }"
-          max-height="600"
-          show-overflow-tooltip
-          border
-        >
-          <el-table-column
-            label="创建时间"
-            align="center"
-            prop="createTime"
-            :formatter="dateFormatter2"
-            :min-width="columnWidths.createTime.width"
-            resizable
-          />
-          <el-table-column
-            label="施工队伍"
-            align="center"
-            prop="deptName"
-            :min-width="columnWidths.deptName.width"
-            resizable
-          />
-
-          <el-table-column
-            label="任务"
-            align="center"
-            prop="taskName"
-            :min-width="columnWidths.taskName.width"
-            resizable
-          />
-
-          <el-table-column
-            :label="t('project.status')"
-            align="center"
-            prop="rdStatus"
-            :min-width="columnWidths.rdStatus.width"
-            resizable
-          >
-            <template #default="scope">
-              <dict-tag :type="DICT_TYPE.PMS_PROJECT_RD_STATUS" :value="scope.row.rdStatus" />
-            </template>
-          </el-table-column>
-
-          <el-table-column
-            label="当日生产动态"
-            align="center"
-            prop="productionStatus"
-            :min-width="columnWidths.productionStatus.width"
-            resizable
-          />
-          <el-table-column
-            label="下步工作计划"
-            align="center"
-            prop="nextPlan"
-            :min-width="columnWidths.nextPlan.width"
-            fixed-width
-          />
-
-          <!--
-          <el-table-column label="项目类别(钻井 修井 注氮 酸化压裂... )" align="center" prop="projectClassification" />
-          <el-table-column label="施工工艺" align="center" prop="techniqueIds" /> -->
-          <!--
-          <el-table-column label="施工设备" align="center" prop="deviceIds" /> -->
-          <!--
-          <el-table-column label="时间节点-结束" align="center" prop="endTime" /> -->
-          <el-table-column align="center" label="当日">
-            <el-table-column
-              label="施工井"
-              align="center"
-              prop="cumulativeWorkingWell"
-              :min-width="columnWidths.cumulativeWorkingWell.width"
-              resizable
-            />
-            <el-table-column
-              label="施工层"
-              align="center"
-              prop="cumulativeWorkingLayers"
-              :min-width="columnWidths.cumulativeWorkingLayers.width"
-              resizable
-            />
-            <el-table-column
-              label="泵车台次"
-              align="center"
-              prop="dailyPumpTrips"
-              :min-width="columnWidths.dailyPumpTrips.width"
-              resizable
-            />
-            <el-table-column
-              label="仪表/混砂"
-              align="center"
-              prop="dailyToolsSand"
-              :min-width="columnWidths.dailyToolsSand.width"
-              resizable
-            />
-          </el-table-column>
-          <el-table-column
-            label="趟数"
-            align="center"
-            prop="runCount"
-            :min-width="columnWidths.runCount.width"
-            resizable
-          />
-          <el-table-column
-            label="桥塞"
-            align="center"
-            prop="bridgePlug"
-            :min-width="columnWidths.bridgePlug.width"
-            resizable
-          />
-          <el-table-column
-            label="水方量"
-            align="center"
-            prop="waterVolume"
-            :min-width="columnWidths.waterVolume.width"
-            resizable
-          />
-          <el-table-column
-            label="时间H"
-            align="center"
-            prop="hourCount"
-            :min-width="columnWidths.hourCount.width"
-            resizable
-          />
-          <el-table-column
-            label="油耗(L)"
-            align="center"
-            prop="dailyFuel"
-            :min-width="columnWidths.dailyFuel.width"
-            resizable
-          />
-
-          <el-table-column
-            label="外租设备"
-            align="center"
-            prop="externalRental"
-            :min-width="columnWidths.externalRental.width"
-            resizable
-          />
-          <el-table-column
-            label="故障情况"
-            align="center"
-            prop="malfunction"
-            :min-width="columnWidths.malfunction.width"
-            resizable
-          />
-          <el-table-column
-            label="故障误工H"
-            align="center"
-            prop="faultDowntime"
-            :min-width="columnWidths.faultDowntime.width"
-            resizable
-          />
-          <el-table-column label="非生产时间" align="center">
-            <el-table-column
-              label="工程质量"
-              align="center"
-              prop="accidentTime"
-              :min-width="columnWidths.accidentTime.width"
-              resizable
-            />
-            <el-table-column
-              label="设备故障"
-              align="center"
-              prop="repairTime"
-              :min-width="columnWidths.repairTime.width"
-              resizable
-            />
-            <el-table-column
-              label="设备保养"
-              align="center"
-              prop="selfStopTime"
-              :min-width="columnWidths.selfStopTime.width"
-              resizable
-            />
-            <el-table-column
-              label="技术受限"
-              align="center"
-              prop="complexityTime"
-              :min-width="columnWidths.complexityTime.width"
-              resizable
-            />
-            <el-table-column
-              label="生产配合"
-              align="center"
-              prop="relocationTime"
-              :min-width="columnWidths.relocationTime.width"
-              resizable
-            />
-            <el-table-column
-              label="生产组织"
-              align="center"
-              prop="rectificationTime"
-              :min-width="columnWidths.rectificationTime.width"
-              resizable
-            />
-            <el-table-column
-              label="不可抗力"
-              align="center"
-              prop="waitingStopTime"
-              :min-width="columnWidths.waitingStopTime.width"
-              resizable
-            />
-            <el-table-column
-              label="待命"
-              align="center"
-              prop="winterBreakTime"
-              :min-width="columnWidths.winterBreakTime.width"
-              resizable
-            />
-            <el-table-column
-              label="甲方设计"
-              align="center"
-              prop="partyaDesign"
-              :min-width="columnWidths.partyaDesign.width"
-              resizable
-            />
-            <el-table-column
-              label="甲方准备"
-              align="center"
-              prop="partyaPrepare"
-              :min-width="columnWidths.partyaPrepare.width"
-              resizable
-            />
-            <el-table-column
-              label="甲方资源"
-              align="center"
-              prop="partyaResource"
-              :min-width="columnWidths.partyaResource.width"
-              resizable
-            />
-            <el-table-column
-              label="其它非生产时间"
-              align="center"
-              prop="otherNptTime"
-              :min-width="columnWidths.otherNptTime.width"
-              resizable
-            />
-          </el-table-column>
-          <el-table-column
-            label="其他非生产时间原因"
-            align="center"
-            prop="otherNptReason"
-            :min-width="columnWidths.otherNptReason.width"
-            resizable
-          />
-          <el-table-column
-            label="非生产时间填写"
-            align="center"
-            prop="nonProductFlag"
-            :min-width="110"
-          >
-            <template #default="scope">
-              <el-tag
-                :type="
-                  scope.row.nonProductFlag || scope.row.processInstanceId === '2'
-                    ? 'success'
-                    : 'danger'
-                "
-              >
-                {{
-                  scope.row.nonProductFlag || scope.row.processInstanceId === '2'
-                    ? '已填写'
-                    : '未填写'
-                }}
-              </el-tag>
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="非生产时效"
-            align="center"
-            prop="nonProductionRate"
-            :min-width="80"
-            resizable
-            :formatter="(row) => (Number(row.nonProductionRate ?? 0) * 100).toFixed(2) + '%'"
-          />
-          <el-table-column
-            label="项目"
-            align="center"
-            prop="contractName"
-            :min-width="columnWidths.contractName.width"
-            resizable
-          />
-          <el-table-column
-            label="时间节点"
-            align="center"
-            prop="timeRange"
-            :min-width="columnWidths.timeRange.width"
-            resizable
-          />
-          <el-table-column label="审批状态" align="center" prop="auditStatus" :min-width="84">
-            <template #default="scope">
-              <el-tag v-if="scope.row.auditStatus === 0" type="info">
-                {{ '待提交' }}
-              </el-tag>
-              <el-tag v-else-if="scope.row.auditStatus === 10">
-                {{ '待审批' }}
-              </el-tag>
-              <el-tag v-else-if="scope.row.auditStatus === 20" type="success">
-                {{ '审批通过' }}
-              </el-tag>
-              <el-tag v-else-if="scope.row.auditStatus === 30" type="danger">
-                {{ '审批拒绝' }}
-              </el-tag>
-            </template>
-          </el-table-column>
-
-          <el-table-column label="操作" align="center" min-width="120px" fixed="right">
-            <template #default="scope">
-              <el-button
-                link
-                type="success"
-                @click="handleDetail(scope.row.id)"
-                v-hasPermi="['pms:iot-rd-daily-report:query']"
-              >
-                查看
-              </el-button>
-              <el-button
-                link
-                type="warning"
-                @click="handleApprove(scope.row.id)"
-                v-hasPermi="['pms:iot-rd-daily-report:update']"
-                v-if="scope.row.auditStatus === 10"
-              >
-                审批
-              </el-button>
-            </template>
-          </el-table-column>
-        </el-table>
-        <!-- 分页 -->
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
-        />
-      </ContentWrap>
-
-      <!-- 表单弹窗:添加/修改 -->
-      <IotRdDailyReportForm ref="formRef" @success="getList" />
-    </el-col>
-  </el-row>
-</template>
-
-<script setup lang="ts">
-import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
-import { IotRdDailyReportApi, IotRdDailyReportVO } from '@/api/pms/iotrddailyreport'
-import IotRdDailyReportForm from './IotRdDailyReportForm.vue'
-import { DICT_TYPE } from '@/utils/dict'
-import { useRoute } from 'vue-router'
-import DeptTree2 from '@/views/pms/iotrhdailyreport/DeptTree2.vue'
-import { useDebounceFn } from '@vueuse/core'
-
-import dayjs from 'dayjs'
-import quarterOfYear from 'dayjs/plugin/quarterOfYear'
-import download from '@/utils/download'
-
-dayjs.extend(quarterOfYear)
-
-const rangeShortcuts = [
-  {
-    text: '今天',
-    value: () => {
-      const today = dayjs()
-      return [today.startOf('day').toDate(), today.endOf('day').toDate()]
-    }
-  },
-  {
-    text: '昨天',
-    value: () => {
-      const yesterday = dayjs().subtract(1, 'day')
-      return [yesterday.startOf('day').toDate(), yesterday.endOf('day').toDate()]
-    }
-  },
-  {
-    text: '本周',
-    value: () => {
-      return [dayjs().startOf('week').toDate(), dayjs().endOf('week').toDate()]
-    }
-  },
-  {
-    text: '上周',
-    value: () => {
-      const lastWeek = dayjs().subtract(1, 'week')
-      return [lastWeek.startOf('week').toDate(), lastWeek.endOf('week').toDate()]
-    }
-  },
-  {
-    text: '本月',
-    value: () => {
-      return [dayjs().startOf('month').toDate(), dayjs().endOf('month').toDate()]
-    }
-  },
-  {
-    text: '上月',
-    value: () => {
-      const lastMonth = dayjs().subtract(1, 'month')
-      return [lastMonth.startOf('month').toDate(), lastMonth.endOf('month').toDate()]
-    }
-  },
-  {
-    text: '本季度',
-    value: () => {
-      return [dayjs().startOf('quarter').toDate(), dayjs().endOf('quarter').toDate()]
-    }
-  },
-  {
-    text: '上季度',
-    value: () => {
-      const lastQuarter = dayjs().subtract(1, 'quarter')
-      return [lastQuarter.startOf('quarter').toDate(), lastQuarter.endOf('quarter').toDate()]
-    }
-  },
-  {
-    text: '今年',
-    value: () => {
-      return [dayjs().startOf('year').toDate(), dayjs().endOf('year').toDate()]
-    }
-  },
-  {
-    text: '去年',
-    value: () => {
-      const lastYear = dayjs().subtract(1, 'year')
-      return [lastYear.startOf('year').toDate(), lastYear.endOf('year').toDate()]
-    }
-  },
-  {
-    text: '最近7天',
-    value: () => {
-      return [dayjs().subtract(6, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近30天',
-    value: () => {
-      return [dayjs().subtract(29, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近90天',
-    value: () => {
-      return [dayjs().subtract(89, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近一年',
-    value: () => {
-      return [dayjs().subtract(1, 'year').toDate(), dayjs().toDate()]
-    }
-  }
-]
-
-/** 瑞都日报 列表 */
-defineOptions({ name: 'IotRdDailyReport' })
-
-const message = useMessage() // 消息弹窗
-const { t } = useI18n() // 国际化
-const { push } = useRouter() // 路由跳转
-const loading = ref(true) // 列表的加载中
-const list = ref<IotRdDailyReportVO[]>([]) // 列表的数据
-const total = ref(0) // 列表的总页数
-
-const route = useRoute() // 路由信息
-
-const queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: undefined,
-  projectId: undefined,
-  contractName: undefined,
-  taskId: undefined,
-  taskName: undefined,
-  projectClassification: undefined,
-  techniqueIds: undefined,
-  deviceIds: undefined,
-  startTime: [],
-  endTime: [],
-  cumulativeWorkingWell: undefined,
-  cumulativeWorkingLayers: undefined,
-  dailyPumpTrips: undefined,
-  dailyToolsSand: undefined,
-  runCount: undefined,
-  bridgePlug: undefined,
-  waterVolume: undefined,
-  hourCount: undefined,
-  dailyFuel: undefined,
-  dailyPowerUsage: undefined,
-  productionTime: [],
-  nonProductionTime: [],
-  rdNptReason: undefined,
-  constructionStartDate: [],
-  constructionEndDate: [],
-  productionStatus: undefined,
-  externalRental: undefined,
-  nextPlan: undefined,
-  rdStatus: undefined,
-  malfunction: undefined,
-  faultDowntime: [],
-  personnel: undefined,
-  totalStaffNum: undefined,
-  leaveStaffNum: undefined,
-  extProperty: undefined,
-  sort: undefined,
-  remark: undefined,
-  status: undefined,
-  processInstanceId: undefined,
-  auditStatus: undefined,
-  createTime: []
-})
-const queryFormRef = ref() // 搜索的表单
-
-const rootDeptId = ref(163)
-
-// 表格引用
-const tableRef = ref()
-// 表格容器引用
-const tableContainerRef = ref()
-
-const columnWidths = ref<
-  Record<
-    string,
-    { label: string; prop: string; width: string; fn?: (row: IotRdDailyReportVO) => string }
-  >
->({
-  createTime: {
-    label: '创建时间',
-    prop: 'createTime',
-    width: '120px',
-    fn: (row: IotRdDailyReportVO) => dateFormatter(null, null, row.createTime)
-  },
-  deptName: {
-    label: '施工队伍',
-    prop: 'deptName',
-    width: '120px'
-  },
-  contractName: {
-    label: '项目',
-    prop: 'contractName',
-    width: '120px'
-  },
-  taskName: {
-    label: '任务',
-    prop: 'taskName',
-    width: '120px'
-  },
-  timeRange: {
-    label: '时间节点',
-    prop: 'timeRange',
-    width: '120px'
-  },
-  rdStatus: {
-    label: '施工状态',
-    prop: 'rdStatus',
-    width: '120px'
-  },
-  cumulativeWorkingWell: {
-    label: '施工井',
-    prop: 'cumulativeWorkingWell',
-    width: '120px'
-  },
-  cumulativeWorkingLayers: {
-    label: '施工层',
-    prop: 'cumulativeWorkingLayers',
-    width: '120px'
-  },
-  dailyPumpTrips: {
-    label: '泵车台次',
-    prop: 'dailyPumpTrips',
-    width: '120px'
-  },
-  dailyToolsSand: {
-    label: '仪表/混砂',
-    prop: 'dailyToolsSand',
-    width: '120px'
-  },
-  runCount: {
-    label: '趟数',
-    prop: 'runCount',
-    width: '120px'
-  },
-  bridgePlug: {
-    label: '桥塞',
-    prop: 'bridgePlug',
-    width: '120px'
-  },
-  waterVolume: {
-    label: '水方量',
-    prop: 'waterVolume',
-    width: '120px'
-  },
-  hourCount: {
-    label: '时间H',
-    prop: 'hourCount',
-    width: '120px'
-  },
-  dailyFuel: {
-    label: '油耗(L)',
-    prop: 'dailyFuel',
-    width: '120px'
-  },
-  productionStatus: {
-    label: '当日生产动态',
-    prop: 'productionStatus',
-    width: '120px'
-  },
-  nextPlan: {
-    label: '下步工作计划',
-    prop: 'nextPlan',
-    width: '120px'
-  },
-  externalRental: {
-    label: '外租设备',
-    prop: 'externalRental',
-    width: '120px'
-  },
-  malfunction: {
-    label: '故障情况',
-    prop: 'malfunction',
-    width: '120px'
-  },
-  faultDowntime: {
-    label: '故障误工H',
-    prop: 'faultDowntime',
-    width: '120px'
-  },
-  accidentTime: {
-    label: '工程质量',
-    prop: 'accidentTime',
-    width: '120px'
-  },
-  repairTime: {
-    label: '设备故障',
-    prop: 'repairTime',
-    width: '120px'
-  },
-  selfStopTime: {
-    label: '设备保养',
-    prop: 'selfStopTime',
-    width: '120px'
-  },
-  complexityTime: {
-    label: '技术受限',
-    prop: 'complexityTime',
-    width: '120px'
-  },
-  relocationTime: {
-    label: '生产配合',
-    prop: 'relocationTime',
-    width: '120px'
-  },
-  rectificationTime: {
-    label: '生产组织',
-    prop: 'rectificationTime',
-    width: '120px'
-  },
-  waitingStopTime: {
-    label: '不可抗力',
-    prop: 'waitingStopTime',
-    width: '120px'
-  },
-  winterBreakTime: {
-    label: '待命',
-    prop: 'winterBreakTime',
-    width: '120px'
-  },
-  partyaDesign: {
-    label: '甲方设计',
-    prop: 'partyaDesign',
-    width: '120px'
-  },
-  partyaPrepare: {
-    label: '甲方资源',
-    prop: 'partyaPrepare',
-    width: '120px'
-  },
-  partyaResource: {
-    label: '甲方准备',
-    prop: 'partyaResource',
-    width: '120px'
-  },
-  otherNptTime: {
-    label: '其它非生产时间',
-    prop: 'otherNptTime',
-    width: '120px'
-  },
-  otherNptReason: {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    width: '120px'
-  }
-})
-
-// 计算文本宽度
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = useDebounceFn(() => {
-  if (!tableContainerRef.value?.$el) return
-  Object.values(columnWidths.value).forEach(({ fn, prop, label, width }) => {
-    width =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(fn ? fn(v) : v[prop])
-              })
-            ]
-          ) + (label === '施工状态' ? 35 : 20),
-          200
-        ]
-      ) + 'px'
-
-    console.log('width :>> ', width)
-
-    columnWidths.value[prop].width = width
-  })
-}, 1000)
-
-/** 查询列表 */
-const getList = async () => {
-  loading.value = true
-  try {
-    const data = await IotRdDailyReportApi.getIotRdDailyReportPage(queryParams)
-    list.value = data.list
-    total.value = data.total
-    // 获取数据后计算列宽
-    nextTick(() => {
-      calculateColumnWidths()
-    })
-  } finally {
-    loading.value = false
-  }
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.pageNo = 1
-  getList()
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  handleQuery()
-}
-
-/** 添加/修改操作 */
-const formRef = ref()
-const openForm = (type: string, id?: number) => {
-  formRef.value.open(type, id)
-}
-
-/** 查看日报详情 */
-const handleDetail = async (id: number) => {
-  try {
-    // 跳转到 FillDailyReportForm 页面,传递审批模式和ID
-    push({
-      name: 'FillDailyReportForm',
-      params: {
-        id: id.toString(),
-        mode: 'detail' // 添加详情模式标识
-      }
-    })
-  } catch (error) {
-    console.error('跳转详情页面失败:', error)
-  }
-}
-
-// 响应式变量存储选中的部门
-const selectedDept = ref<{ id: number; name: string }>()
-/** 处理部门被点击 */
-const handleDeptNodeClick = async (row) => {
-  // 记录选中的部门信息
-  selectedDept.value = { id: row.id, name: row.name }
-  queryParams.deptId = row.id
-  await getList()
-}
-
-/** 审批按钮操作 */
-const handleApprove = async (id: number) => {
-  try {
-    // 跳转到 FillDailyReportForm 页面,传递审批模式和ID
-    push({
-      name: 'FillDailyReportForm',
-      params: {
-        id: id.toString(),
-        mode: 'approval' // 添加审批模式标识
-      }
-    })
-  } catch (error) {
-    console.error('跳转审批页面失败:', error)
-  }
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (id: number) => {
-  try {
-    // 删除的二次确认
-    await message.delConfirm()
-    // 发起删除
-    await IotRdDailyReportApi.deleteIotRdDailyReport(id)
-    message.success(t('common.delSuccess'))
-    // 刷新列表
-    await getList()
-  } catch {}
-}
-
-const exportLoading = ref(false)
-
-const handleExport = async () => {
-  const res = await IotRdDailyReportApi.exportIotRdDailyReportDetails(queryParams)
-
-  download.excel(res, '瑞都日报明细.xlsx')
-}
-
-// 声明 ResizeObserver 实例
-let resizeObserver: ResizeObserver | null = null
-
-/** 初始化 **/
-onMounted(() => {
-  // 检查是否有路由参数传递过来的 wellName
-  if (route.query.wellName) {
-    queryParams.taskName = route.query.wellName as string
-  }
-  if (route.query.taskId) {
-    queryParams.taskId = route.query.taskId as number
-  }
-  getList()
-  // 创建 ResizeObserver 监听表格容器尺寸变化
-  if (tableContainerRef.value?.$el) {
-    resizeObserver = new ResizeObserver(() => {
-      // 使用防抖避免频繁触发
-      clearTimeout((window as any).resizeTimer)
-      ;(window as any).resizeTimer = setTimeout(() => {
-        calculateColumnWidths()
-      }, 100)
-    })
-    resizeObserver.observe(tableContainerRef.value.$el)
-  }
-})
-
-onUnmounted(() => {
-  // 清除 ResizeObserver
-  if (resizeObserver && tableContainerRef.value?.$el) {
-    resizeObserver.unobserve(tableContainerRef.value.$el)
-    resizeObserver = null
-  }
-
-  // 清除定时器
-  if ((window as any).resizeTimer) {
-    clearTimeout((window as any).resizeTimer)
-  }
-})
-
-// 监听列表数据变化重新计算列宽
-watch(
-  list,
-  () => {
-    nextTick(calculateColumnWidths)
-  },
-  { deep: true }
-)
-</script>
-
-<style scoped>
-/* 确保表格单元格内容不换行 */
-
-/* :deep(.el-table .cell) {
-  white-space: nowrap;
-} */
-
-/* 确保表格列标题不换行 */
-
-/* :deep(.el-table th > .cell) {
-  white-space: nowrap;
-} */
-
-/* 调整表格最小宽度,确保内容完全显示 */
-:deep(.el-table) {
-  min-width: 100%;
-}
-
-/* 长文本样式 - 多行显示并添加省略号 */
-.long-text {
-  display: -webkit-box;
-  max-height: 3em; /* 两行文本的高度 */
-  overflow: hidden;
-  line-height: 1.5;
-  text-overflow: ellipsis;
-  -webkit-box-orient: vertical;
-  -webkit-line-clamp: 2;
-}
-
-/* 确保固定宽度列不参与自动调整 */
-:deep(.el-table__header-wrapper .el-table__cell.fixed-width),
-:deep(.el-table__body-wrapper .el-table__cell.fixed-width) {
-  flex-shrink: 0;
-  flex-grow: 0;
-}
-</style>
-
-<style>
-/* 长文本 tooltip 样式 - 保留换行符 */
-.long-text-tooltip {
-  max-width: 500px;
-  line-height: 1.5;
-  white-space: pre-line;
-}
-</style>

+ 0 - 782
src/views/pms/iotrddailyreport/statistics1.vue

@@ -1,782 +0,0 @@
-<template>
-  <el-row :gutter="20">
-    <el-col :span="4" :xs="24">
-      <ContentWrap class="h-1/1">
-        <DeptTree2 :deptId="rootDeptId" @node-click="handleDeptNodeClick" />
-      </ContentWrap>
-    </el-col>
-    <el-col :span="20" :xs="24">
-      <ContentWrap>
-        <!-- 搜索工作栏 -->
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="68px"
-        >
-          <el-form-item label="项目" prop="contractName">
-            <el-input
-              v-model="queryParams.contractName"
-              placeholder="请输入项目"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="任务" prop="taskName">
-            <el-input
-              v-model="queryParams.taskName"
-              placeholder="请输入任务"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="创建时间" prop="createTime">
-            <el-date-picker
-              v-model="queryParams.createTime"
-              value-format="YYYY-MM-DD HH:mm:ss"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              class="!w-220px"
-              :shortcuts="rangeShortcuts"
-            />
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="handleQuery">
-              <Icon icon="ep:search" class="mr-5px" /> 搜索
-            </el-button>
-            <el-button @click="resetQuery">
-              <Icon icon="ep:refresh" class="mr-5px" /> 重置
-            </el-button>
-            <el-button
-              type="primary"
-              plain
-              @click="openForm('create')"
-              v-hasPermi="['pms:iot-rd-daily-report:create']"
-            >
-              <Icon icon="ep:plus" class="mr-5px" /> 新增
-            </el-button>
-            <el-button type="success" plain @click="handleExport" :loading="exportLoading">
-              <Icon icon="ep:download" class="mr-5px" /> 导出
-            </el-button>
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-
-      <!-- 列表 -->
-      <ContentWrap ref="tableContainerRef">
-        <el-table
-          ref="tableRef"
-          v-loading="loading"
-          :data="list"
-          :stripe="true"
-          :style="{ width: '100%' }"
-          max-height="600"
-          show-overflow-tooltip
-          border
-        >
-          <el-table-column
-            label="施工状态"
-            align="center"
-            prop="rdStatus"
-            :width="columnWidths.rdStatus"
-          >
-            <template #default="scope">
-              <dict-tag :type="DICT_TYPE.PMS_PROJECT_RD_STATUS" :value="scope.row.rdStatus" />
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="施工周期(D)"
-            align="center"
-            prop="period"
-            :width="columnWidths.projectDeptName"
-          />
-          <el-table-column
-            label="任务开始日期"
-            align="center"
-            prop="taskStartDate"
-            :width="columnWidths.projectDeptName"
-          />
-          <el-table-column
-            label="项目部"
-            align="center"
-            prop="projectDeptName"
-            :width="columnWidths.projectDeptName"
-          />
-          <el-table-column
-            label="队伍"
-            align="center"
-            prop="deptName"
-            :width="columnWidths.deptName"
-          />
-
-          <el-table-column
-            label="井号"
-            align="center"
-            prop="wellName"
-            :width="columnWidths.wellName"
-          >
-            <template #default="scope">
-              <el-link
-                type="primary"
-                @click="handleWellNameClick(scope.row.taskId)"
-                :underline="false"
-              >
-                {{ scope.row.wellName }}
-              </el-link>
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="工艺"
-            align="center"
-            prop="techniques"
-            :width="columnWidths.techniques"
-          />
-          <el-table-column
-            label="总工作量"
-            align="center"
-            prop="workloadDesign"
-            :width="columnWidths.workloadDesign"
-          />
-          <el-table-column
-            label="油耗(L)"
-            align="center"
-            prop="totalDailyFuel"
-            :width="columnWidths.totalDailyFuel"
-          />
-          <!-- 已完成工作量分组列 -->
-          <el-table-column label="已完成工作量" align="center">
-            <!-- 动态生成列 -->
-            <el-table-column
-              v-for="column in dynamicColumns"
-              :key="column"
-              :label="column"
-              :prop="column"
-              align="center"
-              min-width="120"
-            >
-              <template #default="scope">
-                {{ getWorkloadByUnit(scope.row.items, column) }}
-              </template>
-            </el-table-column>
-          </el-table-column>
-          <!-- <el-table-column label="非生产时间" align="center">
-            <el-table-column
-              label="工程质量"
-              align="center"
-              prop="accidentTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="设备故障"
-              align="center"
-              prop="repairTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="设备保养"
-              align="center"
-              prop="selfStopTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="技术受限"
-              align="center"
-              prop="complexityTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="生产配合"
-              align="center"
-              prop="relocationTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="生产组织"
-              align="center"
-              prop="rectificationTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="不可抗力"
-              align="center"
-              prop="waitingStopTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="待命"
-              align="center"
-              prop="winterBreakTime"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="甲方设计"
-              align="center"
-              prop="partyaDesign"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="甲方准备"
-              align="center"
-              prop="partyaPrepare"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="甲方资源"
-              align="center"
-              prop="partyaResource"
-              :min-width="80"
-              resizable
-            />
-            <el-table-column
-              label="其它非生产时间"
-              align="center"
-              prop="otherNptTime"
-              :min-width="120"
-              resizable
-            />
-          </el-table-column> -->
-          <el-table-column
-            label="非生产时效"
-            align="center"
-            prop="nonProductionRate"
-            :min-width="80"
-            resizable
-            :formatter="(row) => (Number(row.nonProductionRate ?? 0) * 100).toFixed(2) + '%'"
-          />
-          <el-table-column
-            label="甲方"
-            align="center"
-            prop="manufactureName"
-            :width="columnWidths.manufactureName"
-          />
-          <!--
-          <el-table-column label="操作" align="center" min-width="120px" fixed="right">
-            <template #default="scope">
-
-              <el-button
-                link
-                type="primary"
-                @click="openForm('update', scope.row.id)"
-                v-hasPermi="['pms:iot-rd-daily-report:update']"
-              >
-                编辑
-              </el-button>
-              <el-button
-                link
-                type="warning"
-                @click="handleApprove(scope.row.id)"
-                v-hasPermi="['pms:iot-rd-daily-report:update']"
-              >
-                审批
-              </el-button>
-            </template>
-          </el-table-column> -->
-        </el-table>
-        <!-- 分页 -->
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="handlePagination"
-        />
-      </ContentWrap>
-
-      <!-- 表单弹窗:添加/修改 -->
-      <IotRdDailyReportForm ref="formRef" @success="getList" />
-    </el-col>
-  </el-row>
-</template>
-
-<script setup lang="ts">
-import { dateFormatter } from '@/utils/formatTime'
-import { IotRdDailyReportApi, IotRdDailyReportVO } from '@/api/pms/iotrddailyreport'
-import IotRdDailyReportForm from './IotRdDailyReportForm.vue'
-import { DICT_TYPE, getDictLabel } from '@/utils/dict'
-import { ref, reactive, onMounted, computed } from 'vue'
-import DeptTree2 from '@/views/pms/iotrhdailyreport/DeptTree2.vue'
-
-import dayjs from 'dayjs'
-import quarterOfYear from 'dayjs/plugin/quarterOfYear'
-import download from '@/utils/download'
-
-dayjs.extend(quarterOfYear)
-
-const rangeShortcuts = [
-  {
-    text: '今天',
-    value: () => {
-      const today = dayjs()
-      return [today.startOf('day').toDate(), today.endOf('day').toDate()]
-    }
-  },
-  {
-    text: '昨天',
-    value: () => {
-      const yesterday = dayjs().subtract(1, 'day')
-      return [yesterday.startOf('day').toDate(), yesterday.endOf('day').toDate()]
-    }
-  },
-  {
-    text: '本周',
-    value: () => {
-      return [dayjs().startOf('week').toDate(), dayjs().endOf('week').toDate()]
-    }
-  },
-  {
-    text: '上周',
-    value: () => {
-      const lastWeek = dayjs().subtract(1, 'week')
-      return [lastWeek.startOf('week').toDate(), lastWeek.endOf('week').toDate()]
-    }
-  },
-  {
-    text: '本月',
-    value: () => {
-      return [dayjs().startOf('month').toDate(), dayjs().endOf('month').toDate()]
-    }
-  },
-  {
-    text: '上月',
-    value: () => {
-      const lastMonth = dayjs().subtract(1, 'month')
-      return [lastMonth.startOf('month').toDate(), lastMonth.endOf('month').toDate()]
-    }
-  },
-  {
-    text: '本季度',
-    value: () => {
-      return [dayjs().startOf('quarter').toDate(), dayjs().endOf('quarter').toDate()]
-    }
-  },
-  {
-    text: '上季度',
-    value: () => {
-      const lastQuarter = dayjs().subtract(1, 'quarter')
-      return [lastQuarter.startOf('quarter').toDate(), lastQuarter.endOf('quarter').toDate()]
-    }
-  },
-  {
-    text: '今年',
-    value: () => {
-      return [dayjs().startOf('year').toDate(), dayjs().endOf('year').toDate()]
-    }
-  },
-  {
-    text: '去年',
-    value: () => {
-      const lastYear = dayjs().subtract(1, 'year')
-      return [lastYear.startOf('year').toDate(), lastYear.endOf('year').toDate()]
-    }
-  },
-  {
-    text: '最近7天',
-    value: () => {
-      return [dayjs().subtract(6, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近30天',
-    value: () => {
-      return [dayjs().subtract(29, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近90天',
-    value: () => {
-      return [dayjs().subtract(89, 'day').toDate(), dayjs().toDate()]
-    }
-  },
-  {
-    text: '最近一年',
-    value: () => {
-      return [dayjs().subtract(1, 'year').toDate(), dayjs().toDate()]
-    }
-  }
-]
-
-/** 瑞都日报 汇总统计 */
-defineOptions({ name: 'IotRdDailyReportStatistics' })
-
-const message = useMessage() // 消息弹窗
-const { t } = useI18n() // 国际化
-const { push } = useRouter() // 路由跳转
-const loading = ref(true) // 列表的加载中
-const total = ref(0) // 列表的总页数
-const queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: undefined,
-  projectId: undefined,
-  contractName: undefined,
-  taskId: undefined,
-  taskName: undefined,
-  projectClassification: undefined,
-  techniqueIds: undefined,
-  deviceIds: undefined,
-  startTime: [],
-  endTime: [],
-  cumulativeWorkingWell: undefined,
-  cumulativeWorkingLayers: undefined,
-  dailyPumpTrips: undefined,
-  dailyToolsSand: undefined,
-  runCount: undefined,
-  bridgePlug: undefined,
-  waterVolume: undefined,
-  hourCount: undefined,
-  dailyFuel: undefined,
-  dailyPowerUsage: undefined,
-  productionTime: [],
-  nonProductionTime: [],
-  rdNptReason: undefined,
-  constructionStartDate: [],
-  constructionEndDate: [],
-  productionStatus: undefined,
-  externalRental: undefined,
-  nextPlan: undefined,
-  rdStatus: undefined,
-  malfunction: undefined,
-  faultDowntime: [],
-  personnel: undefined,
-  totalStaffNum: undefined,
-  leaveStaffNum: undefined,
-  extProperty: undefined,
-  sort: undefined,
-  remark: undefined,
-  status: undefined,
-  processInstanceId: undefined,
-  auditStatus: undefined,
-  createTime: []
-})
-const queryFormRef = ref() // 搜索的表单
-// 导出的加载中
-
-const rootDeptId = ref(163)
-
-// 响应式数据
-const allList = ref<IotRdDailyReportVO[]>([]) // 存储所有数据
-const list = ref<IotRdDailyReportVO[]>([]) // 存储当前页数据
-
-// 表格引用
-const tableRef = ref()
-// 表格容器引用
-const tableContainerRef = ref()
-
-// 计算属性:获取所有动态列(去重的unit)
-const dynamicColumns = computed(() => {
-  const units = new Set()
-  list.value.forEach((item) => {
-    item.items.forEach((subItem) => {
-      if (subItem.unit) {
-        units.add(subItem.unit)
-      }
-    })
-  })
-  return Array.from(units)
-})
-
-// 根据unit获取对应workload
-const getWorkloadByUnit = (items, unit) => {
-  if (!items || !Array.isArray(items)) return ''
-  const targetItem = items.find((item) => item.unit === unit)
-  return targetItem ? targetItem.workload : ''
-}
-
-// 列宽度配置
-const columnWidths = ref({
-  id: '80px',
-  rdStatus: '120px', // 施工状态列默认宽度
-  projectDeptName: '120px',
-  contractName: '120px',
-  deptName: '120px',
-  manufactureName: '200px',
-  wellName: '120px',
-  techniques: '120px',
-  workloadDesign: '120px',
-  totalDailyFuel: '120px',
-  operation: '120px'
-})
-
-// 计算文本宽度
-const getTextWidth = (text: string, fontSize = 14) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'inherit'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-// 计算列宽度
-const calculateColumnWidths = () => {
-  const MIN_WIDTH = 80 // 最小列宽
-  const PADDING = 25 // 列内边距
-
-  // 确保表格容器存在
-  if (!tableContainerRef.value?.$el) return
-
-  const newWidths: Record<string, string> = {}
-
-  // 计算各列宽度的函数
-  const calculateColumnWidth = (key: string, label: string, getValue: Function) => {
-    const headerWidth = getTextWidth(label) + PADDING
-    let contentMaxWidth = MIN_WIDTH
-
-    // 计算内容最大宽度
-    list.value.forEach((row, index) => {
-      let text = ''
-      if (key === 'rdStatus') {
-        // 特殊处理字典列,这里简化处理,实际应该获取字典标签
-        text = String(row[key] || '')
-      } else if (key.includes('Date') || key === 'createTime') {
-        // 日期列使用格式化后的值
-        text = dateFormatter(null, null, row[key]) || ''
-      } else {
-        text = String(getValue ? getValue(row, index) : row[key] || '')
-      }
-
-      const textWidth = getTextWidth(text) + PADDING
-      if (textWidth > contentMaxWidth) contentMaxWidth = textWidth
-    })
-
-    // 取标题宽度和内容最大宽度的较大值
-    const finalWidth = Math.max(headerWidth, contentMaxWidth, MIN_WIDTH)
-    newWidths[key] = `${finalWidth}px`
-  }
-
-  // 计算施工状态列宽度(使用字典标签文本计算)
-  calculateColumnWidth('rdStatus', '施工状态', (row: any) => {
-    // 用字典标签(如"完工")而非原始编码(如"wg")计算宽度
-    return getDictLabel(DICT_TYPE.PMS_PROJECT_RD_STATUS, row.rdStatus) || row.rdStatus
-  })
-
-  // 计算各列宽度
-  calculateColumnWidth('projectDeptName', '项目部', (row: any) => row.projectDeptName)
-  calculateColumnWidth('deptName', '队伍', (row: any) => row.deptName)
-  calculateColumnWidth('manufactureName', '甲方', (row: any) => row.manufactureName)
-  calculateColumnWidth('wellName', '井号', (row: any) => row.wellName)
-  calculateColumnWidth('techniques', '工艺', (row: any) => row.techniques)
-  calculateColumnWidth('workloadDesign', '总工作量', (row: any) => row.workloadDesign)
-  calculateColumnWidth('totalDailyFuel', '油耗(L)', (row: any) => row.totalDailyFuel)
-
-  // 操作列固定宽度
-  newWidths.operation = '120px'
-  // id列固定宽度(虽然隐藏)
-  newWidths.id = '80px'
-
-  // 更新列宽配置
-  columnWidths.value = newWidths
-
-  // 触发表格重新布局
-  nextTick(() => {
-    tableRef.value?.doLayout()
-  })
-}
-
-/** 查询列表 */
-const getList = async () => {
-  loading.value = true
-  try {
-    const data = await IotRdDailyReportApi.statistics(queryParams)
-    // 存储所有数据
-    allList.value = data
-    // 计算总条数
-    total.value = data.length
-    // 执行前端分页
-    handleFrontendPagination()
-    // 获取数据后计算列宽
-    nextTick(() => {
-      calculateColumnWidths()
-    })
-  } finally {
-    loading.value = false
-  }
-}
-
-/** 井号点击操作 */
-const handleWellNameClick = (taskId: number) => {
-  if (!taskId) return
-
-  // 跳转到日报列表页面,传递井号参数
-  push({
-    name: 'IotRdDailyReport',
-    query: {
-      // wellName: wellName
-      taskId: taskId
-    }
-  })
-}
-
-// 响应式变量存储选中的部门
-const selectedDept = ref<{ id: number; name: string }>()
-/** 处理部门被点击 */
-const handleDeptNodeClick = async (row) => {
-  // 记录选中的部门信息
-  selectedDept.value = { id: row.id, name: row.name }
-  queryParams.deptId = row.id
-  await getList()
-}
-
-/** 前端分页处理 */
-const handleFrontendPagination = () => {
-  const { pageNo, pageSize } = queryParams
-  const startIndex = (pageNo - 1) * pageSize
-  const endIndex = startIndex + pageSize
-
-  // 对全部数据进行分页切片
-  list.value = allList.value.slice(startIndex, endIndex)
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.pageNo = 1
-  getList()
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  handleQuery()
-}
-
-/** 分页事件处理 */
-const handlePagination = (pagination: any) => {
-  queryParams.pageNo = pagination.page
-  queryParams.pageSize = pagination.limit
-  // 使用前端分页,不重新调用接口
-  handleFrontendPagination()
-}
-
-/** 添加/修改操作 */
-const formRef = ref()
-const openForm = (type: string, id?: number) => {
-  formRef.value.open(type, id)
-}
-
-/** 审批按钮操作 */
-const handleApprove = async (id: number) => {
-  try {
-    // 跳转到 FillDailyReportForm 页面,传递审批模式和ID
-    push({
-      name: 'FillDailyReportForm',
-      params: {
-        id: id.toString(),
-        mode: 'approval' // 添加审批模式标识
-      }
-    })
-  } catch (error) {
-    console.error('跳转审批页面失败:', error)
-  }
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (id: number) => {
-  try {
-    // 删除的二次确认
-    await message.delConfirm()
-    // 发起删除
-    await IotRdDailyReportApi.deleteIotRdDailyReport(id)
-    message.success(t('common.delSuccess'))
-    // 刷新列表
-    await getList()
-  } catch {}
-}
-
-const exportLoading = ref(false)
-const handleExport = async () => {
-  const res = await IotRdDailyReportApi.exportIotRdDailyReport({
-    createTime: queryParams.createTime,
-    contractName: queryParams.contractName,
-    taskName: queryParams.taskName,
-    // pageNo: queryParams.pageNo,
-    // pageSize: queryParams.pageSize,
-    deptId: queryParams.deptId
-  })
-
-  download.excel(res, '瑞都日报汇总.xlsx')
-}
-
-// 声明 ResizeObserver 实例
-let resizeObserver: ResizeObserver | null = null
-
-/** 初始化 **/
-onMounted(() => {
-  getList()
-  // 创建 ResizeObserver 监听表格容器尺寸变化
-  if (tableContainerRef.value?.$el) {
-    resizeObserver = new ResizeObserver(() => {
-      // 使用防抖避免频繁触发
-      clearTimeout((window as any).resizeTimer)
-      ;(window as any).resizeTimer = setTimeout(() => {
-        calculateColumnWidths()
-      }, 100)
-    })
-    resizeObserver.observe(tableContainerRef.value.$el)
-  }
-})
-
-onUnmounted(() => {
-  // 清除 ResizeObserver
-  if (resizeObserver && tableContainerRef.value?.$el) {
-    resizeObserver.unobserve(tableContainerRef.value.$el)
-    resizeObserver = null
-  }
-
-  // 清除定时器
-  if ((window as any).resizeTimer) {
-    clearTimeout((window as any).resizeTimer)
-  }
-})
-
-// 监听查询参数变化,实现前端分页
-watch([() => queryParams.pageNo, () => queryParams.pageSize], () => {
-  handleFrontendPagination()
-})
-
-// 监听列表数据变化重新计算列宽
-watch(
-  list,
-  () => {
-    nextTick(calculateColumnWidths)
-  },
-  { deep: true }
-)
-</script>
-
-<style scoped>
-/* 确保表格单元格内容不换行 */
-:deep(.el-table .cell) {
-  white-space: nowrap;
-}
-
-/* 确保表格列标题不换行 */
-:deep(.el-table th > .cell) {
-  white-space: nowrap;
-}
-
-/* 调整表格最小宽度,确保内容完全显示 */
-:deep(.el-table) {
-  min-width: 100%;
-}
-</style>

+ 0 - 669
src/views/pms/iotrhdailyreport/approval1.vue

@@ -1,669 +0,0 @@
-<script lang="ts" setup>
-import { IotRhDailyReportApi } from '@/api/pms/iotrhdailyreport'
-import { rangeShortcuts } from '@/utils/formatTime'
-import { useDebounceFn } from '@vueuse/core'
-import dayjs from 'dayjs'
-import { DICT_TYPE } from '@/utils/dict'
-import { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
-import { useUserStore } from '@/store/modules/user'
-import rhForm from './rh-form.vue'
-
-interface List {
-  createTime: number // 日期
-  deptName: string // 施工队伍
-  contractName: string // 项目
-  taskName: string // 任务
-  id: number
-  deptId: number
-  projectId: number
-  taskId: number
-  relocationDays: number // 搬迁安装天数
-  designInjection: string // 设计注气量(万方)
-  transitTime: number // 运行时效
-  dailyGasInjection: number // 注气量(万方)
-  dailyWaterInjection: number // 注水量(方)
-  dailyInjectGasTime: number // 注气时间(H)
-  dailyInjectWaterTime: number // 注水时间(H)
-  dailyPowerUsage: number // 日耗电量(度)
-  dailyOilUsage: number // 日耗油量(升)
-  accidentTime: number
-  repairTime: number
-  selfStopTime: number
-  complexityTime: number
-  relocationTime: number
-  rectificationTime: number
-  waitingStopTime: number
-  winterBreakTime: number
-  partyaDesign: number
-  partyaPrepare: number
-  partyaResource: number
-  otherNptTime: number
-  otherNptReason: string // 其他非生产时间原因
-  nptReason: string // 非生产时间原因
-  constructionStartDate: number // 施工开始日期
-  constructionEndDate: number // 施工结束日期
-  productionStatus: string // 生产动态
-  constructionStatus: string // 施工状态
-  totalGasInjection: number // 注气量(万方)
-  totalWaterInjection: number // 注水量(方)
-  cumulativeCompletion: number // 完工井次
-  capacity: number // 产能(万方)
-  remark: string // 备注
-  auditStatus: number // 审核状态
-  status: number // 状态
-  opinion: string // 审核意见
-  gasElectricityRatio: number // 气电比
-  nonProductionRate: number // 非生产时效
-}
-
-interface Column {
-  prop?: keyof List
-  label: string
-  'min-width'?: string
-  isTag?: boolean
-  fixed?: 'left' | 'right'
-  formatter?: (row: List) => any
-  children?: Column[]
-  dictType?: string
-}
-
-const columns = ref<Column[]>([
-  {
-    label: '日期',
-    prop: 'createTime',
-    'min-width': '120px',
-    fixed: 'left',
-    formatter: (row: List) => dayjs(row.createTime).format('YYYY-MM-DD')
-  },
-  {
-    label: '施工队伍',
-    prop: 'deptName',
-    fixed: 'left',
-    'min-width': '120px'
-  },
-  {
-    label: '任务',
-    prop: 'taskName',
-    fixed: 'left',
-    'min-width': '120px'
-  },
-  {
-    label: '施工状态',
-    prop: 'constructionStatus',
-    fixed: 'left',
-    'min-width': '120px',
-    isTag: true,
-    dictType: DICT_TYPE.PMS_PROJECT_TASK_SCHEDULE
-  },
-  {
-    label: '审批状态',
-    prop: 'auditStatus',
-    'min-width': '120px',
-    isTag: true,
-    formatter: (row: List) => {
-      switch (row.auditStatus) {
-        case 0:
-          return '待提交'
-        case 10:
-          return '待审批'
-        case 20:
-          return '审批通过'
-        case 30:
-          return '审批拒绝'
-        default:
-          return ''
-      }
-    }
-  },
-  {
-    label: '搬迁安装天数',
-    prop: 'relocationDays',
-    'min-width': '120px',
-    formatter: (row: List) => (row.relocationDays < 0 ? '0' : String(row.relocationDays))
-  },
-  {
-    label: '设计注气量(万方)',
-    prop: 'designInjection',
-    'min-width': '120px',
-    formatter: (row: List) => row.designInjection || '0'
-  },
-  {
-    label: '运行时效',
-    prop: 'transitTime',
-    'min-width': '120px',
-    formatter: (row: List) => {
-      const capacity = Number(row?.capacity)
-      const dailyGasInjection = Number(row?.dailyGasInjection)
-
-      if (!capacity || !dailyGasInjection) {
-        return '0.00%'
-      }
-
-      return ((dailyGasInjection / capacity) * 100).toFixed(2) + '%'
-    }
-  },
-  {
-    label: '当日',
-    children: [
-      {
-        label: '注气量(万方)',
-        prop: 'dailyGasInjection',
-        'min-width': '120px',
-        formatter: (row: List) => (row.dailyGasInjection / 10000).toFixed(2)
-      },
-      {
-        label: '注水量(方)',
-        prop: 'dailyWaterInjection',
-        'min-width': '120px'
-      },
-      {
-        label: '注气时间(H)',
-        prop: 'dailyInjectGasTime',
-        'min-width': '120px'
-      },
-      {
-        label: '注水时间(H)',
-        prop: 'dailyInjectWaterTime',
-        'min-width': '120px'
-      },
-      {
-        label: '用电量(kWh)',
-        prop: 'dailyPowerUsage',
-        'min-width': '120px'
-      },
-      {
-        label: '油耗(L)',
-        prop: 'dailyOilUsage',
-        'min-width': '120px'
-      },
-      {
-        label: '气电比',
-        prop: 'gasElectricityRatio',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    'min-width': '120px',
-    formatter: (row: List) => {
-      const nonProductionRate = row?.nonProductionRate ?? 0
-
-      return (nonProductionRate * 100).toFixed(2) + '%'
-    }
-  },
-  {
-    label: '非生产时间',
-    children: [
-      {
-        label: '工程质量',
-        prop: 'accidentTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备故障',
-        prop: 'repairTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备保养',
-        prop: 'selfStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '技术受限',
-        prop: 'complexityTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产配合',
-        prop: 'relocationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产组织',
-        prop: 'rectificationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '不可抗力',
-        prop: 'waitingStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '待命',
-        prop: 'winterBreakTime',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方设计',
-        prop: 'partyaDesign',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方准备',
-        prop: 'partyaPrepare',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方资源',
-        prop: 'partyaResource',
-        'min-width': '120px'
-      },
-      {
-        label: '其它非生产时间',
-        prop: 'otherNptTime',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    'min-width': '120px'
-  },
-
-  // {
-  //   label: '非生产时间原因',
-  //   prop: 'nptReason',
-  //   'min-width': '120px',
-  //   isTag: true,
-  //   dictType: DICT_TYPE.PMS_PROJECT_NPT_REASON
-  // },
-  // {
-  //   label: '施工开始日期',
-  //   prop: 'constructionStartDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionStartDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  // {
-  //   label: '施工结束日期',
-  //   prop: 'constructionEndDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionEndDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  {
-    label: '生产动态',
-    prop: 'productionStatus',
-    'min-width': '120px'
-  },
-  {
-    label: '项目',
-    prop: 'contractName',
-    'min-width': '120px'
-  },
-  {
-    label: '累计',
-    children: [
-      {
-        label: '注气量(万方)',
-        prop: 'totalGasInjection',
-        'min-width': '120px',
-        formatter: (row: List) => (row.totalGasInjection / 10000).toFixed(2)
-      },
-      {
-        label: '注水量(方)',
-        prop: 'totalWaterInjection',
-        'min-width': '120px'
-      },
-      {
-        label: '完工井次',
-        prop: 'cumulativeCompletion',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '产能(万方)',
-    prop: 'capacity',
-    'min-width': '120px',
-    formatter: (row: List) => (row.capacity / 10000).toFixed(2)
-  }
-])
-
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = (colums: Column[]) => {
-  for (const col of colums) {
-    let { formatter, prop, label, 'min-width': minWidth, isTag, children } = col
-
-    if (children && children.length > 0) {
-      calculateColumnWidths(children)
-      continue
-    }
-
-    minWidth =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(formatter ? formatter(v) : v[prop!])
-              })
-            ]
-          ) + (isTag ? 40 : 20),
-          200
-        ]
-      ) + 'px'
-
-    col['min-width'] = minWidth
-  }
-}
-
-// function checkTimeSumEquals24(row: List) {
-//   // 获取三个字段的值,转换为数字,如果为空则视为0
-//   const gasTime = row.dailyInjectGasTime || 0
-//   const waterTime = row.dailyInjectWaterTime || 0
-//   const nonProdTime = row.nonProductionTime || 0
-
-//   // 计算总和
-//   const sum = gasTime + waterTime + nonProdTime
-
-//   // 返回是否等于24(允许一定的浮点数误差)
-//   return Math.abs(sum - 24) < 0.01 // 使用0.01作为误差范围
-// }
-
-function cellStyle(data: {
-  row: List
-  column: TableColumnCtx<List>
-  rowIndex: number
-  columnIndex: number
-}) {
-  const { row, column } = data
-
-  if (column.property === 'transitTime') {
-    // 1. 获取参与计算的字段,逻辑与 formatter 保持一致
-    const capacity = Number(row?.capacity)
-    const dailyGasInjection = Number(row?.dailyGasInjection)
-
-    // 2. 只有当两个值都有效(且 capacity 不为 0)时才进行计算
-    // 对应 formatter 中的 if (!capacity || !dailyGasInjection) 返回 '0.00%' 的情况
-    if (capacity && dailyGasInjection) {
-      const ratio = dailyGasInjection / capacity
-
-      // 3. 判断计算结果是否大于 1.2 (即 120%)
-      if (ratio > 1.2) {
-        return {
-          color: 'red',
-          fontWeight: 'bold'
-        }
-      }
-    }
-  }
-  // const timeFields = ['dailyInjectGasTime', 'dailyInjectWaterTime', 'nonProductionTime']
-  // if (timeFields.includes(column.property)) {
-  //   if (!checkTimeSumEquals24(row)) {
-  //     return {
-  //       color: 'orange',
-  //       fontWeight: 'bold'
-  //     }
-  //   }
-  // }
-
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-const id = useUserStore().getUser.deptId
-
-const deptId = id
-
-interface Query {
-  pageNo: number
-  pageSize: number
-  deptId: number
-  contractName?: string
-  taskName?: string
-  createTime: string[]
-}
-
-const query = ref<Query>({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: id,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ]
-})
-
-function handleSizeChange(val: number) {
-  query.value.pageSize = val
-  handleQuery()
-}
-
-function handleCurrentChange(val: number) {
-  query.value.pageNo = val
-  loadList()
-}
-
-const loading = ref(false)
-
-const list = ref<List[]>([])
-const total = ref(0)
-
-const loadList = useDebounceFn(async function () {
-  loading.value = true
-  try {
-    const data = await IotRhDailyReportApi.getIotRhDailyReportPage(query.value)
-    list.value = data.list
-    total.value = data.total
-
-    nextTick(() => {
-      calculateColumnWidths(columns.value)
-    })
-  } finally {
-    loading.value = false
-  }
-}, 500)
-
-function handleQuery(setPage = true) {
-  if (setPage) {
-    query.value.pageNo = 1
-  }
-  loadList()
-}
-
-function resetQuery() {
-  query.value = {
-    pageNo: 1,
-    pageSize: 10,
-    deptId: 157,
-    contractName: '',
-    taskName: '',
-    createTime: [
-      ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-    ]
-  }
-  handleQuery()
-}
-
-watch(
-  [
-    () => query.value.createTime,
-    () => query.value.deptId,
-    () => query.value.taskName,
-    () => query.value.contractName
-  ],
-  () => {
-    handleQuery()
-  },
-  { immediate: true }
-)
-
-const visible = ref(false)
-
-const formRef = ref()
-
-function handleOpenForm(id: number, type: 'edit' | 'readonly') {
-  if (formRef.value) {
-    formRef.value.handleOpenForm(id, type)
-  }
-}
-
-const route = useRoute()
-
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    handleOpenForm(Number(route.query.id), 'edit')
-  }
-})
-</script>
-
-<template>
-  <div
-    class="h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
-  >
-    <div class="grid grid-cols-[15%_1fr] gap-4 h-full">
-      <div class="flex flex-col p-4 gap-2 bg-white dark:bg-[#1d1e1f] shadow rounded-lg h-full">
-        <DeptTreeSelect :deptId="deptId" :topId="157" v-model="query.deptId" />
-      </div>
-      <div class="grid grid-rows-[62px_1fr] h-full gap-4">
-        <el-form
-          size="default"
-          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
-        >
-          <div class="flex items-center gap-8">
-            <el-form-item label="项目">
-              <el-input
-                v-model="query.contractName"
-                placeholder="请输入项目"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="任务">
-              <el-input
-                v-model="query.taskName"
-                placeholder="请输入任务"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="创建时间">
-              <el-date-picker
-                v-model="query.createTime"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                type="daterange"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-                :shortcuts="rangeShortcuts"
-                class="!w-220px"
-                :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              />
-            </el-form-item>
-          </div>
-          <el-form-item>
-            <el-button type="primary" @click="handleQuery()">
-              <Icon icon="ep:search" class="mr-5px" /> 搜索
-            </el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
-          </el-form-item>
-        </el-form>
-        <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg p-4 flex flex-col">
-          <div class="flex-1 relative">
-            <el-auto-resizer class="absolute">
-              <template #default="{ width, height }">
-                <el-table
-                  :data="list"
-                  v-loading="loading"
-                  stripe
-                  class="absolute"
-                  :max-height="height"
-                  show-overflow-tooltip
-                  :width="width"
-                  :cell-style="cellStyle"
-                  border
-                >
-                  <DailyTableColumn :columns="columns" />
-                  <el-table-column label="操作" width="120px" align="center" fixed="right">
-                    <template #default="{ row }">
-                      <el-button
-                        link
-                        type="success"
-                        @click="handleOpenForm(row.id, 'readonly')"
-                        v-hasPermi="['pms:iot-rh-daily-report:update']"
-                      >
-                        查看
-                      </el-button>
-                      <el-button
-                        v-show="row.auditStatus === 10"
-                        link
-                        type="primary"
-                        @click="handleOpenForm(row.id, 'edit')"
-                        v-hasPermi="['pms:iot-rh-daily-report:update']"
-                      >
-                        审批
-                      </el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </template>
-            </el-auto-resizer>
-          </div>
-          <div class="h-10 mt-4 flex items-center justify-end">
-            <el-pagination
-              size="default"
-              v-show="total > 0"
-              v-model:current-page="query.pageNo"
-              v-model:page-size="query.pageSize"
-              :background="true"
-              :page-sizes="[10, 20, 30, 50, 100]"
-              :total="total"
-              layout="total, sizes, prev, pager, next, jumper"
-              @size-change="handleSizeChange"
-              @current-change="handleCurrentChange"
-            />
-          </div>
-        </div>
-      </div>
-    </div>
-    <rh-form v-model:visible="visible" type="approval" ref="formRef" :load-list="loadList" />
-  </div>
-</template>
-
-<style scoped>
-:deep(.el-form-item) {
-  margin-bottom: 0;
-}
-
-:deep(.el-table) {
-  border-top-right-radius: 8px;
-  border-top-left-radius: 8px;
-
-  .el-table__cell {
-    height: 40px;
-  }
-
-  .el-table__header-wrapper {
-    .el-table__cell {
-      background: var(--el-fill-color-light);
-    }
-  }
-}
-
-:deep(.el-input-number__decrease) {
-  display: none !important;
-}
-
-:deep(.el-input-number__increase) {
-  display: none !important;
-}
-</style>

+ 0 - 674
src/views/pms/iotrhdailyreport/fill1.vue

@@ -1,674 +0,0 @@
-<script lang="ts" setup>
-import { IotRhDailyReportApi } from '@/api/pms/iotrhdailyreport'
-import { rangeShortcuts } from '@/utils/formatTime'
-import { useDebounceFn } from '@vueuse/core'
-import dayjs from 'dayjs'
-import { DICT_TYPE } from '@/utils/dict'
-import { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
-import { useUserStore } from '@/store/modules/user'
-import rhForm from './rh-form.vue'
-
-interface List {
-  createTime: number // 日期
-  deptName: string // 施工队伍
-  contractName: string // 项目
-  taskName: string // 任务
-  id: number
-  deptId: number
-  projectId: number
-  taskId: number
-  relocationDays: number // 搬迁安装天数
-  designInjection: string // 设计注气量(万方)
-  transitTime: number // 运行时效
-  dailyGasInjection: number // 注气量(万方)
-  dailyWaterInjection: number // 注水量(方)
-  dailyInjectGasTime: number // 注气时间(H)
-  dailyInjectWaterTime: number // 注水时间(H)
-  dailyPowerUsage: number // 日耗电量(度)
-  dailyOilUsage: number // 日耗油量(升)
-  accidentTime: number
-  repairTime: number
-  selfStopTime: number
-  complexityTime: number
-  relocationTime: number
-  rectificationTime: number
-  waitingStopTime: number
-  winterBreakTime: number
-  partyaDesign: number
-  partyaPrepare: number
-  partyaResource: number
-  otherNptTime: number
-  otherNptReason: string // 其他非生产时间原因
-  nptReason: string // 非生产时间原因
-  constructionStartDate: number // 施工开始日期
-  constructionEndDate: number // 施工结束日期
-  productionStatus: string // 生产动态
-  constructionStatus: string // 施工状态
-  totalGasInjection: number // 注气量(万方)
-  totalWaterInjection: number // 注水量(方)
-  cumulativeCompletion: number // 完工井次
-  capacity: number // 产能(万方)
-  remark: string // 备注
-  auditStatus: number // 审核状态
-  status: number // 状态
-  opinion: string // 审核意见
-  gasElectricityRatio: number // 气电比
-  nonProductionRate: number // 非生产时效
-}
-
-interface Column {
-  prop?: keyof List
-  label: string
-  'min-width'?: string
-  isTag?: boolean
-  fixed?: 'left' | 'right'
-  formatter?: (row: List) => any
-  children?: Column[]
-  dictType?: string
-}
-
-const columns = ref<Column[]>([
-  {
-    label: '日期',
-    prop: 'createTime',
-    'min-width': '120px',
-    fixed: 'left',
-    formatter: (row: List) => dayjs(row.createTime).format('YYYY-MM-DD')
-  },
-  {
-    label: '施工队伍',
-    prop: 'deptName',
-    fixed: 'left',
-    'min-width': '120px'
-  },
-  {
-    label: '任务',
-    prop: 'taskName',
-    fixed: 'left',
-    'min-width': '120px'
-  },
-  {
-    label: '施工状态',
-    prop: 'constructionStatus',
-    fixed: 'left',
-    'min-width': '120px',
-    isTag: true,
-    dictType: DICT_TYPE.PMS_PROJECT_TASK_SCHEDULE
-  },
-  {
-    label: '审批状态',
-    prop: 'auditStatus',
-    'min-width': '120px',
-    isTag: true,
-    formatter: (row: List) => {
-      switch (row.auditStatus) {
-        case 0:
-          return '待提交'
-        case 10:
-          return '待审批'
-        case 20:
-          return '审批通过'
-        case 30:
-          return '审批拒绝'
-        default:
-          return ''
-      }
-    }
-  },
-  {
-    label: '搬迁安装天数',
-    prop: 'relocationDays',
-    'min-width': '120px',
-    formatter: (row: List) => (row.relocationDays < 0 ? '0' : String(row.relocationDays))
-  },
-  {
-    label: '设计注气量(万方)',
-    prop: 'designInjection',
-    'min-width': '120px',
-    formatter: (row: List) => row.designInjection || '0'
-  },
-  {
-    label: '运行时效',
-    prop: 'transitTime',
-    'min-width': '120px',
-    formatter: (row: List) => {
-      const capacity = Number(row?.capacity)
-      const dailyGasInjection = Number(row?.dailyGasInjection)
-
-      if (!capacity || !dailyGasInjection) {
-        return '0.00%'
-      }
-
-      return ((dailyGasInjection / capacity) * 100).toFixed(2) + '%'
-    }
-  },
-  {
-    label: '当日',
-    children: [
-      {
-        label: '注气量(万方)',
-        prop: 'dailyGasInjection',
-        'min-width': '120px',
-        formatter: (row: List) => (row.dailyGasInjection / 10000).toFixed(2)
-      },
-      {
-        label: '注水量(方)',
-        prop: 'dailyWaterInjection',
-        'min-width': '120px'
-      },
-      {
-        label: '注气时间(H)',
-        prop: 'dailyInjectGasTime',
-        'min-width': '120px'
-      },
-      {
-        label: '注水时间(H)',
-        prop: 'dailyInjectWaterTime',
-        'min-width': '120px'
-      },
-      {
-        label: '用电量(kWh)',
-        prop: 'dailyPowerUsage',
-        'min-width': '120px'
-      },
-      {
-        label: '油耗(L)',
-        prop: 'dailyOilUsage',
-        'min-width': '120px'
-      },
-      {
-        label: '气电比',
-        prop: 'gasElectricityRatio',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    'min-width': '120px',
-    formatter: (row: List) => {
-      const nonProductionRate = row?.nonProductionRate ?? 0
-
-      return (nonProductionRate * 100).toFixed(2) + '%'
-    }
-  },
-  {
-    label: '非生产时间',
-    children: [
-      {
-        label: '工程质量',
-        prop: 'accidentTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备故障',
-        prop: 'repairTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备保养',
-        prop: 'selfStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '技术受限',
-        prop: 'complexityTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产配合',
-        prop: 'relocationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产组织',
-        prop: 'rectificationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '不可抗力',
-        prop: 'waitingStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '待命',
-        prop: 'winterBreakTime',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方设计',
-        prop: 'partyaDesign',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方准备',
-        prop: 'partyaPrepare',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方资源',
-        prop: 'partyaResource',
-        'min-width': '120px'
-      },
-      {
-        label: '其它非生产时间',
-        prop: 'otherNptTime',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    'min-width': '120px'
-  },
-
-  // {
-  //   label: '非生产时间原因',
-  //   prop: 'nptReason',
-  //   'min-width': '120px',
-  //   isTag: true,
-  //   dictType: DICT_TYPE.PMS_PROJECT_NPT_REASON
-  // },
-  // {
-  //   label: '施工开始日期',
-  //   prop: 'constructionStartDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionStartDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  // {
-  //   label: '施工结束日期',
-  //   prop: 'constructionEndDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionEndDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  {
-    label: '生产动态',
-    prop: 'productionStatus',
-    'min-width': '120px'
-  },
-  {
-    label: '项目',
-    prop: 'contractName',
-    'min-width': '120px'
-  },
-  {
-    label: '累计',
-    children: [
-      {
-        label: '注气量(万方)',
-        prop: 'totalGasInjection',
-        'min-width': '120px',
-        formatter: (row: List) => (row.totalGasInjection / 10000).toFixed(2)
-      },
-      {
-        label: '注水量(方)',
-        prop: 'totalWaterInjection',
-        'min-width': '120px'
-      },
-      {
-        label: '完工井次',
-        prop: 'cumulativeCompletion',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '产能(万方)',
-    prop: 'capacity',
-    'min-width': '120px',
-    formatter: (row: List) => (row.capacity / 10000).toFixed(2)
-  }
-])
-
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = (colums: Column[]) => {
-  for (const col of colums) {
-    let { formatter, prop, label, 'min-width': minWidth, isTag, children } = col
-
-    if (children && children.length > 0) {
-      calculateColumnWidths(children)
-      continue
-    }
-
-    minWidth =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(formatter ? formatter(v) : v[prop!])
-              })
-            ]
-          ) + (isTag ? 40 : 20),
-          200
-        ]
-      ) + 'px'
-
-    col['min-width'] = minWidth
-  }
-}
-
-// function checkTimeSumEquals24(row: List) {
-//   // 获取三个字段的值,转换为数字,如果为空则视为0
-//   const gasTime = row.dailyInjectGasTime || 0
-//   const waterTime = row.dailyInjectWaterTime || 0
-//   const nonProdTime = row.nonProductionTime || 0
-
-//   // 计算总和
-//   const sum = gasTime + waterTime + nonProdTime
-
-//   // 返回是否等于24(允许一定的浮点数误差)
-//   return Math.abs(sum - 24) < 0.01 // 使用0.01作为误差范围
-// }
-
-function cellStyle(data: {
-  row: List
-  column: TableColumnCtx<List>
-  rowIndex: number
-  columnIndex: number
-}) {
-  const { row, column } = data
-
-  if (column.property === 'transitTime') {
-    // 1. 获取参与计算的字段,逻辑与 formatter 保持一致
-    const capacity = Number(row?.capacity)
-    const dailyGasInjection = Number(row?.dailyGasInjection)
-
-    // 2. 只有当两个值都有效(且 capacity 不为 0)时才进行计算
-    // 对应 formatter 中的 if (!capacity || !dailyGasInjection) 返回 '0.00%' 的情况
-    if (capacity && dailyGasInjection) {
-      const ratio = dailyGasInjection / capacity
-
-      // 3. 判断计算结果是否大于 1.2 (即 120%)
-      if (ratio > 1.2) {
-        return {
-          color: 'red',
-          fontWeight: 'bold'
-        }
-      }
-    }
-  }
-
-  // const timeFields = ['dailyInjectGasTime', 'dailyInjectWaterTime', 'nonProductionTime']
-  // if (timeFields.includes(column.property)) {
-  //   if (!checkTimeSumEquals24(row)) {
-  //     return {
-  //       color: 'orange',
-  //       fontWeight: 'bold'
-  //     }
-  //   }
-  // }
-
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-const id = useUserStore().getUser.deptId ?? 157
-
-const deptId = id
-
-interface Query {
-  pageNo: number
-  pageSize: number
-  deptId: number
-  contractName?: string
-  taskName?: string
-  createTime: string[]
-}
-
-const query = ref<Query>({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: id,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ]
-})
-
-function handleSizeChange(val: number) {
-  query.value.pageSize = val
-  handleQuery()
-}
-
-function handleCurrentChange(val: number) {
-  query.value.pageNo = val
-  loadList()
-}
-
-const loading = ref(false)
-
-const list = ref<List[]>([])
-const total = ref(0)
-
-const loadList = useDebounceFn(async function () {
-  loading.value = true
-  try {
-    const data = await IotRhDailyReportApi.getIotRhDailyReportPage(query.value)
-    list.value = data.list
-    total.value = data.total
-
-    nextTick(() => {
-      calculateColumnWidths(columns.value)
-    })
-  } finally {
-    loading.value = false
-  }
-}, 500)
-
-function handleQuery(setPage = true) {
-  if (setPage) {
-    query.value.pageNo = 1
-  }
-  loadList()
-}
-
-function resetQuery() {
-  query.value = {
-    pageNo: 1,
-    pageSize: 10,
-    deptId: 157,
-    contractName: '',
-    taskName: '',
-    createTime: [
-      ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-    ]
-  }
-  handleQuery()
-}
-
-watch(
-  [
-    () => query.value.createTime,
-    () => query.value.deptId,
-    () => query.value.taskName,
-    () => query.value.contractName
-  ],
-  () => {
-    handleQuery()
-  },
-  { immediate: true }
-)
-
-const visible = ref(false)
-
-const formRef = ref()
-
-function handleOpenForm(id: number, type: 'edit' | 'readonly') {
-  if (formRef.value) {
-    formRef.value.handleOpenForm(id, type)
-  }
-}
-
-const route = useRoute()
-
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    handleOpenForm(Number(route.query.id), 'edit')
-  }
-})
-</script>
-
-<template>
-  <div
-    class="h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
-  >
-    <div class="grid grid-cols-[15%_1fr] gap-4 h-full">
-      <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg h-full">
-        <DeptTreeSelect :top-id="157" :deptId="deptId" v-model="query.deptId" />
-      </div>
-      <div class="grid grid-rows-[62px_1fr] h-full gap-4">
-        <el-form
-          size="default"
-          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
-        >
-          <div class="flex items-center gap-8">
-            <el-form-item label="项目">
-              <el-input
-                v-model="query.contractName"
-                placeholder="请输入项目"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="任务">
-              <el-input
-                v-model="query.taskName"
-                placeholder="请输入任务"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="创建时间">
-              <el-date-picker
-                v-model="query.createTime"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                type="daterange"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-                :shortcuts="rangeShortcuts"
-                :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-                class="!w-220px"
-              />
-            </el-form-item>
-          </div>
-          <el-form-item>
-            <el-button type="primary" @click="handleQuery()">
-              <Icon icon="ep:search" class="mr-5px" /> 搜索
-            </el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
-          </el-form-item>
-        </el-form>
-        <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg p-4 flex flex-col">
-          <div class="flex-1 relative">
-            <el-auto-resizer class="absolute">
-              <template #default="{ width, height }">
-                <el-table
-                  :data="list"
-                  v-loading="loading"
-                  stripe
-                  class="absolute"
-                  :max-height="height"
-                  show-overflow-tooltip
-                  :width="width"
-                  :cell-style="cellStyle"
-                  border
-                >
-                  <DailyTableColumn :columns="columns" />
-                  <el-table-column label="操作" width="120px" align="center" fixed="right">
-                    <template #default="{ row }">
-                      <el-button
-                        link
-                        type="success"
-                        @click="handleOpenForm(row.id, 'readonly')"
-                        v-hasPermi="['pms:iot-rh-daily-report:query']"
-                      >
-                        查看
-                      </el-button>
-                      <el-button
-                        v-show="row.status === 0"
-                        link
-                        type="primary"
-                        @click="handleOpenForm(row.id, 'edit')"
-                        v-hasPermi="['pms:iot-rh-daily-report:create']"
-                      >
-                        编辑
-                      </el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </template>
-            </el-auto-resizer>
-          </div>
-          <div class="h-10 mt-4 flex items-center justify-end">
-            <el-pagination
-              size="default"
-              v-show="total > 0"
-              v-model:current-page="query.pageNo"
-              v-model:page-size="query.pageSize"
-              :background="true"
-              :page-sizes="[10, 20, 30, 50, 100]"
-              :total="total"
-              layout="total, sizes, prev, pager, next, jumper"
-              @size-change="handleSizeChange"
-              @current-change="handleCurrentChange"
-            />
-          </div>
-        </div>
-      </div>
-    </div>
-    <rh-form v-model:visible="visible" type="edit" ref="formRef" :load-list="loadList" />
-  </div>
-</template>
-
-<style scoped>
-:deep(.el-form-item) {
-  margin-bottom: 0;
-}
-
-:deep(.el-table) {
-  border-top-right-radius: 8px;
-  border-top-left-radius: 8px;
-
-  .el-table__cell {
-    height: 40px;
-  }
-
-  .el-table__header-wrapper {
-    .el-table__cell {
-      background: var(--el-fill-color-light);
-    }
-  }
-}
-
-:deep(.el-input-number) {
-  width: 100%;
-}
-
-:deep(.el-input-number__decrease) {
-  display: none !important;
-}
-
-:deep(.el-input-number__increase) {
-  display: none !important;
-}
-</style>

+ 11 - 10
src/views/pms/iotrhdailyreport/index.vue

@@ -233,7 +233,7 @@ const openUnfilledDialog = () => {
 
 <template>
   <div
-    class="grid grid-cols-[15%_1fr] grid-rows-[48px_auto_auto_1fr] gap-x-4 gap-y-3 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
+    class="grid grid-cols-[15%_1fr] grid-rows-[48px_auto_1fr_auto] gap-x-4 gap-y-3 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
   >
     <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg row-span-4">
       <DeptTreeSelect :top-id="157" :deptId="deptId" v-model="query.deptId" :show-title="false" />
@@ -335,15 +335,7 @@ const openUnfilledDialog = () => {
         </div>
       </div>
     </div>
-    <div class="p-2 bg-white dark:bg-[#1d1e1f] rounded-lg shadow">
-      <el-alert
-        class="h-8!"
-        title="运行时效=当日注气量/产能&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;超过120%红色预警"
-        type="error"
-        show-icon
-        :closable="false"
-      />
-    </div>
+
     <rh-table
       :list="list"
       :total="total"
@@ -355,6 +347,15 @@ const openUnfilledDialog = () => {
       @current-change="handleCurrentChange"
       @size-change="handleSizeChange"
     />
+    <div class="p-2 bg-white dark:bg-[#1d1e1f] rounded-lg shadow">
+      <el-alert
+        class="h-8!"
+        title="运行时效=当日注气量/产能&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;超过120%红色预警"
+        type="error"
+        show-icon
+        :closable="false"
+      />
+    </div>
   </div>
 
   <UnfilledReportDialog ref="unfilledDialogRef" :query-params="query" />

+ 0 - 1339
src/views/pms/iotrhdailyreport/index1.vue

@@ -1,1339 +0,0 @@
-<template>
-  <el-row :gutter="20" class="h-full">
-    <el-col :span="4" :xs="24">
-      <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-4 h-full">
-        <DeptTreeSelect
-          :deptId="rootDeptId"
-          :top-id="157"
-          v-model="queryParams.deptId"
-          @node-click="handleDeptNodeClick"
-        />
-      </div>
-
-      <!-- <DeptTree2 :deptId="rootDeptId" @node-click="handleDeptNodeClick" /> -->
-
-      <!-- </ContentWrap> -->
-    </el-col>
-    <el-col :span="20" :xs="24">
-      <ContentWrap>
-        <!-- 搜索工作栏 -->
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="80px"
-        >
-          <el-form-item label="项目" prop="contractName">
-            <el-input
-              v-model="queryParams.contractName"
-              placeholder="请输入项目"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="任务" prop="taskName">
-            <el-input
-              v-model="queryParams.taskName"
-              placeholder="请输入任务"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="创建时间" prop="createTime">
-            <el-date-picker
-              v-model="queryParams.createTime"
-              value-format="YYYY-MM-DD HH:mm:ss"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              :shortcuts="rangeShortcuts"
-              class="!w-220px"
-            />
-          </el-form-item>
-          <el-form-item label="非生产时效" prop="nonProductFlag">
-            <el-switch v-model="queryParams.nonProductFlag" active-value="Y" inactive-value="N" />
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="handleQuery"
-              ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
-            >
-            <el-button @click="resetQuery"
-              ><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
-            >
-            <el-button
-              type="primary"
-              plain
-              @click="openForm('create')"
-              v-hasPermi="['pms:iot-rh-daily-report:create']"
-            >
-              <Icon icon="ep:plus" class="mr-5px" /> 新增
-            </el-button>
-            <el-button
-              type="success"
-              plain
-              @click="handleExport"
-              :loading="exportLoading"
-              v-hasPermi="['pms:iot-rh-daily-report:export']"
-            >
-              <Icon icon="ep:download" class="mr-5px" /> 导出
-            </el-button>
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-
-      <!-- 数据统计区域 -->
-      <ContentWrap class="mb-15px">
-        <div class="statistics-container">
-          <div class="stat-item" :style="{ color: totalColor }">
-            <span>总数:</span>
-            <span>{{ statistics.total || '-' }}</span>
-          </div>
-          <div class="stat-item" :style="{ color: filledColor }">
-            <span>已填报:</span>
-            <span>{{ statistics.filled || '-' }}</span>
-          </div>
-          <div class="stat-item" :style="{ color: unFilledColor }">
-            <span>未填报:</span>
-            <span
-              class="unfilled-link"
-              @click="openUnfilledDialog"
-              :class="{ disabled: !queryParams.createTime || queryParams.createTime.length === 0 }"
-            >
-              {{ statistics.unFilled || '-' }}
-            </span>
-          </div>
-          <div class="stat-item" :style="{ color: '#0099CC' }">
-            <span>累计注水量(方):</span>
-            <span>{{ statistics.totalWaterInjection || '-' }}</span>
-          </div>
-          <div class="stat-item" :style="{ color: '#FF9900' }">
-            <span>累计注气量(万方):</span>
-            <span>{{ statistics.totalGasInjection || '-' }}</span>
-          </div>
-        </div>
-      </ContentWrap>
-
-      <ContentWrap class="mb-15px">
-        <div class="color-legend">
-          <div class="legend-item">
-            <span class="color-indicator red"></span>
-            <span
-              >运行时效=当日注气量/产能&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;超过120%红色预警</span
-            >
-          </div>
-          <!-- <div class="legend-item">
-            <span class="color-indicator orange"></span>
-            <span
-              >当日注气时间+当日注水时间+非生产时间=24H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;否则橙色预警</span
-            >
-          </div> -->
-        </div>
-      </ContentWrap>
-
-      <!-- 列表 -->
-      <ContentWrap ref="tableContainerRef">
-        <div class="table-container">
-          <el-table
-            ref="tableRef"
-            v-loading="loading"
-            :data="list"
-            :stripe="true"
-            :style="{ width: '100%' }"
-            max-height="600"
-            :cell-style="cellStyle"
-            show-overflow-tooltip
-            border
-          >
-            <el-table-column
-              :label="t('iotDevice.serial')"
-              width="56px"
-              align="center"
-              fixed="left"
-            >
-              <template #default="scope">
-                {{ scope.$index + 1 }}
-              </template>
-            </el-table-column>
-            <el-table-column
-              label="日期"
-              align="center"
-              prop="createTime"
-              :formatter="dateFormatter2"
-              :min-width="columnWidths.createTime.width"
-              resizable
-              fixed="left"
-            />
-            <el-table-column
-              label="施工队伍"
-              align="center"
-              prop="deptName"
-              :min-width="columnWidths.deptName.width"
-              resizable
-              fixed="left"
-            />
-            <el-table-column
-              label="任务"
-              align="center"
-              prop="taskName"
-              :min-width="columnWidths.taskName.width"
-              resizable
-              fixed="left"
-            />
-            <!-- <el-table-column label="施工状态" align="center" prop="constructionStatus" /> -->
-            <el-table-column
-              :label="t('project.status')"
-              align="center"
-              prop="constructionStatus"
-              :min-width="columnWidths.constructionStatus.width"
-              resizable
-              fixed="left"
-            >
-              <template #default="scope">
-                <dict-tag
-                  :type="DICT_TYPE.PMS_PROJECT_TASK_SCHEDULE"
-                  :value="scope.row.constructionStatus"
-                />
-              </template>
-            </el-table-column>
-            <el-table-column
-              label="搬迁安装天数"
-              align="center"
-              prop="relocationDays"
-              :formatter="relocationDaysFormatter"
-              :min-width="columnWidths.relocationDays.width"
-              resizable
-            />
-            <el-table-column
-              label="设计注气量(万方)"
-              align="center"
-              prop="designInjection"
-              :min-width="columnWidths.designInjection.width"
-              resizable
-            />
-            <el-table-column
-              label="运行时效"
-              align="center"
-              prop="transitTime"
-              :formatter="percentageFormatter"
-              :min-width="columnWidths.transitTime.width"
-              resizable
-            />
-            <el-table-column label="当日" align="center">
-              <el-table-column
-                label="注气量(万方)"
-                align="center"
-                prop="dailyGasInjection"
-                :formatter="gasInjectionFormatter"
-                :min-width="columnWidths.dailyGasInjection.width"
-                resizable
-              />
-              <el-table-column
-                label="注水量(方)"
-                align="center"
-                prop="dailyWaterInjection"
-                :min-width="columnWidths.dailyWaterInjection.width"
-                resizable
-              />
-              <el-table-column
-                label="注气时间(H)"
-                align="center"
-                prop="dailyInjectGasTime"
-                :min-width="columnWidths.dailyInjectGasTime.width"
-                resizable
-              />
-              <el-table-column
-                label="注水时间(H)"
-                align="center"
-                prop="dailyInjectWaterTime"
-                :min-width="columnWidths.dailyInjectWaterTime.width"
-                resizable
-              />
-              <el-table-column
-                label="用电量(kWh)"
-                align="center"
-                prop="dailyPowerUsage"
-                :min-width="columnWidths.dailyPowerUsage.width"
-                resizable
-              />
-              <el-table-column
-                label="油耗(L)"
-                align="center"
-                prop="dailyOilUsage"
-                :min-width="columnWidths.dailyOilUsage.width"
-                resizable
-              />
-              <el-table-column
-                label="气电比"
-                align="center"
-                prop="gasElectricityRatio"
-                :min-width="columnWidths.gasElectricityRatio.width"
-                resizable
-              />
-            </el-table-column>
-            <el-table-column
-              label="非生产时效"
-              align="center"
-              prop="nonProductionRate"
-              :formatter="nonProductionRateFormatter"
-              :min-width="columnWidths.nonProductionRate.width"
-              resizable
-            />
-            <el-table-column label="非生产时间" align="center">
-              <el-table-column
-                label="工程质量"
-                align="center"
-                prop="accidentTime"
-                :min-width="columnWidths.accidentTime.width"
-                resizable
-              />
-              <el-table-column
-                label="设备故障"
-                align="center"
-                prop="repairTime"
-                :min-width="columnWidths.repairTime.width"
-                resizable
-              />
-              <el-table-column
-                label="设备保养"
-                align="center"
-                prop="selfStopTime"
-                :min-width="columnWidths.selfStopTime.width"
-                resizable
-              />
-              <el-table-column
-                label="技术受限"
-                align="center"
-                prop="complexityTime"
-                :min-width="columnWidths.complexityTime.width"
-                resizable
-              />
-              <el-table-column
-                label="生产配合"
-                align="center"
-                prop="relocationTime"
-                :min-width="columnWidths.relocationTime.width"
-                resizable
-              />
-              <el-table-column
-                label="生产组织"
-                align="center"
-                prop="rectificationTime"
-                :min-width="columnWidths.rectificationTime.width"
-                resizable
-              />
-              <el-table-column
-                label="不可抗力"
-                align="center"
-                prop="waitingStopTime"
-                :min-width="columnWidths.waitingStopTime.width"
-                resizable
-              />
-              <el-table-column
-                label="待命"
-                align="center"
-                prop="winterBreakTime"
-                :min-width="columnWidths.winterBreakTime.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方设计"
-                align="center"
-                prop="partyaDesign"
-                :min-width="columnWidths.partyaDesign.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方准备"
-                align="center"
-                prop="partyaPrepare"
-                :min-width="columnWidths.partyaPrepare.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方资源"
-                align="center"
-                prop="partyaResource"
-                :min-width="columnWidths.partyaResource.width"
-                resizable
-              />
-              <el-table-column
-                label="其它非生产时间"
-                align="center"
-                prop="otherNptTime"
-                :min-width="columnWidths.otherNptTime.width"
-                resizable
-              />
-            </el-table-column>
-            <el-table-column
-              label="其他非生产时间原因"
-              align="center"
-              prop="otherNptReason"
-              :min-width="columnWidths.otherNptReason.width"
-              resizable
-            />
-
-            <!-- <el-table-column
-              :label="t('project.nptReason')"
-              align="center"
-              prop="nptReason"
-              :min-width="columnWidths.nptReason.width"
-              resizable
-            >
-              <template #default="scope">
-                <dict-tag :type="DICT_TYPE.PMS_PROJECT_NPT_REASON" :value="scope.row.nptReason" />
-              </template>
-            </el-table-column> -->
-            <!-- <el-table-column
-              label="施工开始日期"
-              align="center"
-              prop="constructionStartDate"
-              :formatter="dateFormatter"
-              :min-width="columnWidths.constructionStartDate.width"
-              resizable
-            />
-            <el-table-column
-              label="施工结束日期"
-              align="center"
-              prop="constructionEndDate"
-              :formatter="dateFormatter"
-              :min-width="columnWidths.constructionEndDate.width"
-              resizable
-            /> -->
-            <el-table-column
-              label="生产动态"
-              align="center"
-              :min-width="columnWidths.productionStatus.width"
-              prop="productionStatus"
-              resizable
-            />
-            <el-table-column
-              label="项目"
-              align="center"
-              prop="contractName"
-              class-name="contract-name-column"
-              :min-width="columnWidths.contractName.width"
-              resizable
-            />
-            <el-table-column label="井累计" align="center">
-              <el-table-column
-                label="注气量(万方)"
-                align="center"
-                prop="wellTotalGasInjection"
-                :formatter="gasInjectionFormatter"
-                :min-width="columnWidths.totalGasInjection.width"
-                resizable
-              />
-              <el-table-column
-                label="注水量(方)"
-                align="center"
-                prop="wellTotalWaterInjection"
-                :min-width="columnWidths.totalWaterInjection.width"
-                resizable
-              />
-              <el-table-column
-                label="用电量(MWh)"
-                align="center"
-                prop="wellTotalPower"
-                :formatter="gasInjectionFormatter"
-                :min-width="columnWidths.yearTotalPower.width"
-                resizable
-              />
-              <el-table-column
-                label="油耗(L)"
-                align="center"
-                prop="wellTotalFuel"
-                :min-width="columnWidths.cumulativeCompletion.width"
-                resizable
-              />
-            </el-table-column>
-            <el-table-column label="年累计" align="center">
-              <el-table-column
-                label="注气量(万方)"
-                align="center"
-                prop="yearTotalGasInjection"
-                :formatter="gasInjectionFormatter"
-                :min-width="columnWidths.totalGasInjection.width"
-                resizable
-              />
-              <el-table-column
-                label="注水量(方)"
-                align="center"
-                prop="yearTotalWaterInjection"
-                :min-width="columnWidths.totalWaterInjection.width"
-                resizable
-              />
-              <el-table-column
-                label="用电量(MWh)"
-                align="center"
-                prop="yearTotalPower"
-                :formatter="gasInjectionFormatter"
-                :min-width="columnWidths.yearTotalPower.width"
-                resizable
-              />
-              <el-table-column
-                label="油耗(L)"
-                align="center"
-                prop="yearTotalFuel"
-                :min-width="columnWidths.cumulativeCompletion.width"
-                resizable
-              />
-            </el-table-column>
-            <el-table-column
-              label="产能(万方)"
-              align="center"
-              prop="capacity"
-              :formatter="gasInjectionFormatter"
-              :min-width="columnWidths.capacity.width"
-              resizable
-            />
-
-            <!-- <el-table-column label="操作" align="center" fixed="right">
-              <template #default="scope">
-                <el-button
-                  link
-                  type="primary"
-                  @click="openForm('update', scope.row.id, scope.row)"
-                  v-hasPermi="['pms:iot-rh-daily-report:update']"
-                >
-                  编辑
-                </el-button>
-                <el-button
-                  link
-                  type="danger"
-                  @click="handleDelete(scope.row.id)"
-                  v-hasPermi="['pms:iot-rh-daily-report:delete']"
-                >
-                  删除
-                </el-button>
-              </template>
-            </el-table-column> -->
-          </el-table>
-        </div>
-        <!-- 分页 -->
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
-        />
-      </ContentWrap>
-
-      <!-- 表单弹窗:添加/修改 -->
-      <IotRhDailyReportForm ref="formRef" @success="getList" :row-data="selectedRowData" />
-
-      <UnfilledReportDialog
-        ref="unfilledDialogRef"
-        :query-params="queryParams"
-        @close="handleUnfilledDialogClose"
-      />
-    </el-col>
-  </el-row>
-</template>
-
-<script setup lang="ts">
-import { dateFormatter, dateFormatter2, rangeShortcuts } from '@/utils/formatTime'
-import download from '@/utils/download'
-import { IotRhDailyReportApi, IotRhDailyReportVO } from '@/api/pms/iotrhdailyreport'
-import IotRhDailyReportForm from './IotRhDailyReportForm.vue'
-import UnfilledReportDialog from './UnfilledReportDialog.vue'
-import { DICT_TYPE } from '@/utils/dict'
-import { ref, reactive, onMounted, onUnmounted } from 'vue'
-import { useDebounceFn } from '@vueuse/core'
-import quarterOfYear from 'dayjs/plugin/quarterOfYear'
-import dayjs from 'dayjs'
-
-import { useUserStore } from '@/store/modules/user'
-
-dayjs.extend(quarterOfYear)
-
-/** 瑞恒日报 列表 */
-defineOptions({ name: 'IotRhDailyReport' })
-
-const message = useMessage() // 消息弹窗
-const { t } = useI18n() // 国际化
-
-// 添加 selectedRowData 响应式变量
-const selectedRowData = ref<Record<string, any> | null>(null)
-
-const loading = ref(true) // 列表的加载中
-const list = ref<IotRhDailyReportVO[]>([]) // 列表的数据
-const total = ref(0) // 列表的总页数
-let queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: useUserStore().getUser.deptId,
-  contractName: undefined,
-  projectId: undefined,
-  taskName: undefined,
-  taskId: undefined,
-  projectClassification: undefined,
-  relocationDays: undefined,
-  transitTime: [],
-  dailyGasInjection: undefined,
-  dailyWaterInjection: undefined,
-  dailyPowerUsage: undefined,
-  dailyInjectGasTime: [],
-  dailyInjectWaterTime: [],
-  nonProductionTime: [],
-  nptReason: undefined,
-  constructionStartDate: [],
-  constructionEndDate: [],
-  productionStatus: undefined,
-  nextPlan: undefined,
-  constructionStatus: undefined,
-  personnel: undefined,
-  totalGasInjection: undefined,
-  totalWaterInjection: undefined,
-  cumulativeCompletion: undefined,
-  extProperty: undefined,
-  sort: undefined,
-  remark: undefined,
-  status: undefined,
-  processInstanceId: undefined,
-  auditStatus: undefined,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ],
-  nonProductFlag: 'N'
-})
-const queryFormRef = ref() // 搜索的表单
-const exportLoading = ref(false) // 导出的加载中
-// 添加弹窗引用
-const unfilledDialogRef = ref()
-
-const rootDeptId = ref(useUserStore().getUser.deptId)
-
-// 新增统计相关变量
-const statistics = ref({
-  total: '-',
-  filled: '-',
-  unFilled: '-',
-  totalWaterInjection: '-', // 新增累计注水量
-  totalGasInjection: '-' // 新增累计注气量
-})
-
-const totalColor = '#00DD99'
-const filledColor = '#0055BB'
-const unFilledColor = '#FF5500'
-
-// 表格引用
-const tableRef = ref()
-// 表格容器引用
-const tableContainerRef = ref()
-
-// 工作量统计相关变量
-const workloadStatistics = ref({
-  totalWaterInjection: '-',
-  totalGasInjection: '-'
-})
-
-// 列宽度配置
-const columnWidths = ref<
-  Record<
-    string,
-    { label: string; prop: string; width: string; fn?: (row: IotRhDailyReportVO) => string }
-  >
->({
-  createTime: {
-    label: '日期',
-    prop: 'createTime',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => dateFormatter2(null, null, row.createTime)
-  },
-  deptName: {
-    label: '施工队伍',
-    prop: 'deptName',
-    width: '120px'
-  },
-  contractName: {
-    label: '项目',
-    prop: 'contractName',
-    width: '120px'
-  },
-  taskName: {
-    label: '任务',
-    prop: 'taskName',
-    width: '120px'
-  },
-  constructionStatus: {
-    label: '施工状态',
-    prop: 'constructionStatus',
-    width: '120px'
-  },
-  relocationDays: {
-    label: '搬迁安装天数',
-    prop: 'relocationDays',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => relocationDaysFormatter(null, null, row.relocationDays, null)
-  },
-  designInjection: {
-    label: '设计注气量(万方)',
-    prop: 'designInjection',
-    width: '120px'
-  },
-  transitTime: {
-    label: '运行时效',
-    prop: 'transitTime',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => percentageFormatter(null, null, row.transitTime, null)
-  },
-  dailyGasInjection: {
-    label: '注气量(万方)',
-    prop: 'dailyGasInjection',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => gasInjectionFormatter(null, null, row.dailyGasInjection, null)
-  },
-  dailyWaterInjection: {
-    label: '注水量(方)',
-    prop: 'dailyWaterInjection',
-    width: '120px'
-  },
-  dailyInjectGasTime: {
-    label: '注气时间(H)',
-    prop: 'dailyInjectGasTime',
-    width: '120px'
-  },
-  dailyInjectWaterTime: {
-    label: '注水时间(H)',
-    prop: 'dailyInjectWaterTime',
-    width: '120px'
-  },
-  dailyPowerUsage: {
-    label: '用电量(kWh)',
-    prop: 'dailyPowerUsage',
-    width: '120px'
-  },
-  dailyOilUsage: {
-    label: '油耗(L)',
-    prop: 'dailyOilUsage',
-    width: '120px'
-  },
-  gasElectricityRatio: {
-    label: '气电比',
-    prop: 'gasElectricityRatio',
-    width: '120px'
-  },
-  accidentTime: {
-    label: '工程质量',
-    prop: 'accidentTime',
-    width: '120px'
-  },
-  repairTime: {
-    label: '设备故障',
-    prop: 'repairTime',
-    width: '120px'
-  },
-  selfStopTime: {
-    label: '设备保养',
-    prop: 'selfStopTime',
-    width: '120px'
-  },
-  complexityTime: {
-    label: '技术受限',
-    prop: 'complexityTime',
-    width: '120px'
-  },
-  relocationTime: {
-    label: '生产配合',
-    prop: 'relocationTime',
-    width: '120px'
-  },
-  rectificationTime: {
-    label: '生产组织',
-    prop: 'rectificationTime',
-    width: '120px'
-  },
-  waitingStopTime: {
-    label: '不可抗力',
-    prop: 'waitingStopTime',
-    width: '120px'
-  },
-  winterBreakTime: {
-    label: '待命',
-    prop: 'winterBreakTime',
-    width: '120px'
-  },
-  partyaDesign: {
-    label: '甲方设计',
-    prop: 'partyaDesign',
-    width: '120px'
-  },
-  partyaPrepare: {
-    label: '甲方资源',
-    prop: 'partyaPrepare',
-    width: '120px'
-  },
-  partyaResource: {
-    label: '甲方准备',
-    prop: 'partyaResource',
-    width: '120px'
-  },
-  otherNptTime: {
-    label: '其它非生产时间',
-    prop: 'otherNptTime',
-    width: '120px'
-  },
-  otherNptReason: {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    width: '120px'
-  },
-  constructionStartDate: {
-    label: '施工开始日期',
-    prop: 'constructionStartDate',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => dateFormatter(null, null, row.constructionStartDate)
-  },
-  constructionEndDate: {
-    label: '施工结束日期',
-    prop: 'constructionEndDate',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => dateFormatter(null, null, row.constructionEndDate)
-  },
-  productionStatus: {
-    label: '生产动态',
-    prop: 'productionStatus',
-    width: '120px'
-  },
-  totalGasInjection: {
-    label: '注气量(万方)',
-    prop: 'totalGasInjection',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => gasInjectionFormatter(null, null, row.totalGasInjection, null)
-  },
-  totalWaterInjection: {
-    label: '注水量(方)',
-    prop: 'totalWaterInjection',
-    width: '120px'
-  },
-  yearTotalPower: {
-    label: '用电量(万千瓦时)',
-    prop: 'yearTotalPower',
-    width: '120px'
-  },
-  cumulativeCompletion: {
-    label: '完工井次',
-    prop: 'cumulativeCompletion',
-    width: '120px'
-  },
-  capacity: {
-    label: '产能(万方)',
-    prop: 'capacity',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => gasInjectionFormatter(null, null, row.capacity, null)
-  },
-  nonProductionRate: {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    width: '120px',
-    fn: (row: IotRhDailyReportVO) => nonProductionRateFormatter(row)
-  }
-})
-
-const nonProductionRateFormatter = (row: any) => {
-  const nonProductionRate = row?.nonProductionRate ?? 0
-
-  return (nonProductionRate * 100).toFixed(2) + '%'
-}
-
-// 计算文本宽度
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = useDebounceFn(() => {
-  if (!tableContainerRef.value?.$el) return
-  Object.values(columnWidths.value).forEach(({ fn, prop, label, width }) => {
-    width =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(fn ? fn(v) : v[prop])
-              })
-            ]
-          ) +
-            (label === '施工状态' || label === '非生产时间原因'
-              ? 30
-              : label === '气电比'
-                ? 40
-                : 20),
-          200
-        ]
-      ) + 'px'
-
-    columnWidths.value[prop].width = width
-  })
-}, 1000)
-// 计算列宽度
-
-// 格式化设计井身结构文本
-const formatDesignWellStruct = (text: string | null | undefined) => {
-  if (!text) return '-'
-  // 如果文本长度超过30个字符,显示前30个字符并添加省略号
-  return text.length > 30 ? text.substring(0, 30) + '...' : text
-}
-
-// 百分比格式化函数
-const percentageFormatter = (row: any, column: any, cellValue: any, index: number | null) => {
-  const capacity = Number(row?.capacity)
-  const dailyGasInjection = Number(row?.dailyGasInjection)
-
-  if (!capacity || !dailyGasInjection) {
-    return '0.00%'
-  }
-
-  return ((dailyGasInjection / capacity) * 100).toFixed(2) + '%'
-
-  // if (cellValue === null || cellValue === undefined) return ''
-  // // 将小数转换为百分比,保留两位小数
-  // return `${(parseFloat(cellValue) * 100).toFixed(2)}%`
-}
-
-// 添加打开未填报弹窗的方法
-const openUnfilledDialog = () => {
-  // 检查是否选择了创建时间
-  if (!queryParams.createTime || queryParams.createTime.length === 0) {
-    message.warning('请先选择创建时间范围')
-    return
-  }
-
-  // 打开弹窗
-  unfilledDialogRef.value.open()
-}
-
-// 弹窗关闭回调
-const handleUnfilledDialogClose = () => {
-  // 可以在这里处理弹窗关闭后的逻辑
-  console.log('未填报弹窗已关闭')
-}
-
-// 新增获取统计数据的方法
-const getStatistics = async () => {
-  // 重置统计数据
-  statistics.value = {
-    total: '-',
-    filled: '-',
-    unFilled: '-'
-  }
-
-  // 如果没有选择时间范围,不调用接口
-  if (!queryParams.createTime || queryParams.createTime.length === 0) {
-    return
-  }
-
-  try {
-    const res = await IotRhDailyReportApi.rhDailyReportStatistics({
-      createTime: queryParams.createTime
-    })
-
-    // 处理统计数据
-    const statsMap = {}
-    res.forEach((item) => {
-      statsMap[item.groupName] = item.count
-    })
-
-    statistics.value = {
-      total: statsMap['总数'] || '-',
-      filled: statsMap['已填报'] || '-',
-      unFilled: statsMap['未填报'] || '-'
-    }
-  } catch (error) {
-    console.error('获取统计数据失败', error)
-  }
-}
-
-/** 查询列表 */
-const getList = async () => {
-  loading.value = true
-  try {
-    console.log('22 :>> ', 11)
-    const data = await IotRhDailyReportApi.getIotRhDailyReportPage(queryParams)
-    list.value = data.list
-    total.value = data.total
-
-    // 获取统计数据
-    await getStatistics()
-
-    // 获取工作量统计数据
-    await getWorkloadStatistics()
-
-    // 获取数据后计算列宽
-    nextTick(() => {
-      calculateColumnWidths()
-    })
-  } finally {
-    loading.value = false
-  }
-}
-
-// 搬迁安装天数格式化函数
-const relocationDaysFormatter = (row: any, column: any, cellValue: any, index: number | null) => {
-  if (cellValue === null || cellValue === undefined || cellValue === '') return ''
-
-  const value = parseFloat(cellValue)
-  // 如果值为负数,显示0,否则显示原值
-  return value < 0 ? '0' : String(value)
-}
-
-// 注气量格式化函数(单位转换:方 -> 万方)
-const gasInjectionFormatter = (row: any, column: any, cellValue: any, index: number | null) => {
-  if (cellValue === null || cellValue === undefined || cellValue === '') return ''
-  // 将方转换为万方,保留两位小数
-  const value = parseFloat(cellValue)
-  return (value / 10000).toFixed(2)
-}
-
-// 检查三个时间字段之和是否为24
-const checkTimeSumEquals24 = (row: any) => {
-  // 获取三个字段的值,转换为数字,如果为空则视为0
-  const gasTime = parseFloat(row.dailyInjectGasTime) || 0
-  const waterTime = parseFloat(row.dailyInjectWaterTime) || 0
-  const nonProdTime = parseFloat(row.nonProductionTime) || 0
-
-  // 计算总和
-  const sum = gasTime + waterTime + nonProdTime
-
-  // 返回是否等于24(允许一定的浮点数误差)
-  return Math.abs(sum - 24) < 0.01 // 使用0.01作为误差范围
-}
-
-// 单元格样式函数
-const cellStyle = ({
-  row,
-  column,
-  rowIndex,
-  columnIndex
-}: {
-  row: any
-  column: any
-  rowIndex: number
-  columnIndex: number
-}) => {
-  // 只针对 transitTime 列进行处理
-  if (column.property === 'transitTime') {
-    // 1. 获取参与计算的字段,逻辑与 formatter 保持一致
-    const capacity = Number(row?.capacity)
-    const dailyGasInjection = Number(row?.dailyGasInjection)
-
-    // 2. 只有当两个值都有效(且 capacity 不为 0)时才进行计算
-    // 对应 formatter 中的 if (!capacity || !dailyGasInjection) 返回 '0.00%' 的情况
-    if (capacity && dailyGasInjection) {
-      const ratio = dailyGasInjection / capacity
-
-      // 3. 判断计算结果是否大于 1.2 (即 120%)
-      if (ratio > 1.2) {
-        return {
-          color: 'red',
-          fontWeight: 'bold'
-        }
-      }
-    }
-  }
-
-  // 处理三个时间字段:当日注气时间、当日注水时间、非生产时间
-  // const timeFields = ['dailyInjectGasTime', 'dailyInjectWaterTime', 'nonProductionTime']
-  // if (timeFields.includes(column.property)) {
-  //   // 检查三个时间字段之和是否不等于24
-  //   if (!checkTimeSumEquals24(row)) {
-  //     return {
-  //       color: 'orange',
-  //       fontWeight: 'bold'
-  //     }
-  //   }
-  // }
-
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-// 获取工作量统计数据的方法
-const getWorkloadStatistics = async () => {
-  // 重置工作量统计数据
-  statistics.value.totalWaterInjection = '-'
-  statistics.value.totalGasInjection = '-'
-
-  try {
-    const res = await IotRhDailyReportApi.totalWorkload(queryParams)
-
-    // 处理工作量统计数据
-    if (res) {
-      // 累计注水量直接显示,单位:方
-      statistics.value.totalWaterInjection = res.totalWaterInjection || '-'
-
-      // 累计注气量需要转换:方 -> 万方 (除以10000)
-      if (res.totalGasInjection) {
-        const gasInjection = parseFloat(res.totalGasInjection)
-        statistics.value.totalGasInjection = (gasInjection / 10000).toFixed(2)
-      } else {
-        statistics.value.totalGasInjection = '-'
-      }
-    }
-  } catch (error) {
-    console.error('获取工作量统计数据失败', error)
-  }
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.pageNo = 1
-  getList()
-}
-
-const route = useRoute()
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  queryParams.deptId = useUserStore().getUser.deptId
-  // 重置后需要重新获取统计数据
-  getStatistics()
-  // 重新获取工作量统计数据
-  getWorkloadStatistics()
-  handleQuery()
-}
-
-/** 添加/修改操作 */
-const formRef = ref()
-const openForm = (type: string, id?: number, row?: any) => {
-  // 保存当前行数据
-  if (row) {
-    selectedRowData.value = {
-      deptName: row.deptName,
-      contractName: row.contractName,
-      taskName: row.taskName,
-      relocationDays: row.relocationDays
-    }
-  } else {
-    selectedRowData.value = null
-  }
-
-  formRef.value.open(type, id)
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (id: number) => {
-  try {
-    // 删除的二次确认
-    await message.delConfirm()
-    // 发起删除
-    await IotRhDailyReportApi.deleteIotRhDailyReport(id)
-    message.success(t('common.delSuccess'))
-    // 刷新列表
-    await getList()
-  } catch {}
-}
-
-// 响应式变量存储选中的部门
-const selectedDept = ref<{ id: number; name: string }>()
-/** 处理部门被点击 */
-const handleDeptNodeClick = async (row) => {
-  // 记录选中的部门信息
-  selectedDept.value = { id: row.id, name: row.name }
-  // queryParams.deptId = row.id
-  await getList()
-}
-
-/** 导出按钮操作 */
-const handleExport = async () => {
-  try {
-    // 导出的二次确认
-    await message.exportConfirm()
-    // 发起导出
-    exportLoading.value = true
-    const data = await IotRhDailyReportApi.exportIotRhDailyReport(queryParams)
-    download.excel(data, '瑞恒日报.xls')
-  } catch {
-  } finally {
-    exportLoading.value = false
-  }
-}
-
-// 声明 ResizeObserver 实例
-let resizeObserver: ResizeObserver | null = null
-
-/** 初始化 **/
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    nextTick(() => {
-      queryParams.deptId = Number(route.query.deptId) as any
-      queryParams.createTime = route.query.createTime as string[]
-      queryParams.nonProductFlag = route.query.nonProductFlag as string
-      handleQuery()
-    })
-  } else getList()
-  // 创建 ResizeObserver 监听表格容器尺寸变化
-  if (tableContainerRef.value?.$el) {
-    resizeObserver = new ResizeObserver(() => {
-      // 使用防抖避免频繁触发
-      clearTimeout((window as any).resizeTimer)
-      ;(window as any).resizeTimer = setTimeout(() => {
-        calculateColumnWidths()
-      }, 100)
-    })
-    resizeObserver.observe(tableContainerRef.value.$el)
-  }
-})
-
-onUnmounted(() => {
-  // 清除 ResizeObserver
-  if (resizeObserver && tableContainerRef.value?.$el) {
-    resizeObserver.unobserve(tableContainerRef.value.$el)
-    resizeObserver = null
-  }
-
-  // 清除定时器
-  if ((window as any).resizeTimer) {
-    clearTimeout((window as any).resizeTimer)
-  }
-})
-
-// 监听列表数据变化重新计算列宽
-watch(
-  list,
-  () => {
-    nextTick(() => calculateColumnWidths())
-  },
-  { deep: true }
-)
-</script>
-
-<style scoped>
-/* 表格容器样式,确保水平滚动 */
-.table-container {
-  width: 100%;
-  overflow-x: auto;
-}
-
-/* 确保表格单元格内容不换行 */
-
-/* :deep(.el-table .cell) {
-  white-space: nowrap;
-} */
-
-/* 确保表格列标题不换行 */
-
-/* :deep(.el-table th > .cell) {
-  white-space: nowrap;
-} */
-
-/* 调整表格最小宽度,确保内容完全显示 */
-:deep(.el-table) {
-  min-width: 100%;
-}
-
-/* 强制显示所有内容,防止省略号 */
-
-/* :deep(.el-table td.el-table__cell),
-:deep(.el-table th.el-table__cell) {
-  overflow: visible !important;
-} */
-
-/* :deep(.el-table .cell) {
-  overflow: visible !important;
-  text-overflow: clip !important;
-} */
-
-/* :deep(.contract-name-column .cell) {
-  overflow: hidden !important;
-  text-overflow: ellipsis !important;
-  white-space: nowrap !important;
-} */
-
-/* 颜色说明区域样式 */
-.color-legend {
-  display: flex;
-  padding: 12px 16px;
-  background-color: #f8f9fa;
-  border-left: 4px solid #e6f7ff;
-  border-radius: 4px;
-  flex-direction: column;
-  gap: 8px;
-}
-
-.legend-item {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  font-size: 14px;
-}
-
-.color-indicator {
-  display: inline-block;
-  width: 12px;
-  height: 12px;
-  border-radius: 50%;
-}
-
-.color-indicator.red {
-  background-color: red;
-}
-
-.color-indicator.orange {
-  background-color: orange;
-}
-
-/* 统计区域未填报链接样式 */
-.unfilled-link {
-  color: #f50;
-  text-decoration: underline;
-  cursor: pointer;
-}
-
-.unfilled-link:hover {
-  color: #f73;
-}
-
-.unfilled-link.disabled {
-  color: #ccc;
-  text-decoration: none;
-  cursor: not-allowed;
-}
-</style>
-
-<style>
-/* 设计井身结构 tooltip 样式 - 保留换行符 */
-.design-well-struct-tooltip {
-  max-width: 500px;
-  line-height: 1.5;
-  white-space: pre-line;
-}
-
-/* 统计区域样式 */
-.statistics-container {
-  display: flex;
-  justify-content: space-around;
-  padding: 10px 0;
-}
-
-.stat-item {
-  min-width: 0; /* 防止内容溢出 */
-  font-size: 16px;
-  font-weight: 500;
-  text-align: center;
-  flex: 1;
-}
-
-/* 确保统计项内容不换行 */
-.stat-item span {
-  white-space: nowrap;
-}
-</style>

+ 127 - 71
src/views/pms/iotrhdailyreport/summary.vue

@@ -328,95 +328,151 @@ onUnmounted(() => {
   window.removeEventListener('resize', resizer)
 })
 
-const render = () => {
-  if (!chartRef.value) return
-
-  chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })
-
-  window.addEventListener('resize', resizer)
-
-  const values: number[] = []
-
-  for (const [_name, key] of legend.value) {
-    values.push(...(chartData.value[key] || []))
+const selectedLegends = ref<Record<string, boolean>>({})
+const intervalArr = ref<number[]>([])
+const maxInterval = ref(0)
+const minInterval = ref(0)
+
+const calcIntervals = () => {
+  let maxVal = -Infinity
+  let minVal = Infinity
+  let hasData = false
+
+  for (const [name, key] of legend.value) {
+    if (selectedLegends.value[name] !== false) {
+      const dataset = chartData.value[key] || []
+      if (dataset.length > 0) {
+        hasData = true
+        for (const val of dataset) {
+          if (val > maxVal) maxVal = val
+          if (val < minVal) minVal = val
+        }
+      }
+    }
   }
 
-  const maxVal = values.length === 0 ? 10000 : Math.max(...values)
-  const minVal = values.length === 0 ? 0 : Math.min(...values) > 0 ? 0 : Math.min(...values)
+  if (!hasData) {
+    maxVal = 10000
+    minVal = 0
+  } else {
+    minVal = minVal > 0 ? 0 : minVal
+  }
 
   const maxDigits = (Math.floor(maxVal) + '').length
   const minDigits = minVal === 0 ? 0 : (Math.floor(Math.abs(minVal)) + '').length
   const interval = Math.max(maxDigits, minDigits)
 
-  const maxInterval = interval
-  const minInterval = minDigits
+  maxInterval.value = interval
+  minInterval.value = minDigits
 
-  const intervalArr = [0]
+  const arr = [0]
   for (let i = 1; i <= interval; i++) {
-    intervalArr.push(Math.pow(10, i))
+    arr.push(Math.pow(10, i))
   }
+  intervalArr.value = arr
+}
 
-  chart.setOption({
-    tooltip: {
-      trigger: 'axis',
-      axisPointer: {
-        type: 'line'
-      },
-      formatter: (params) => {
-        let d = `${params[0].axisValueLabel}<br>`
-        let item = params.map((el) => {
-          return `<div class="flex items-center justify-between mt-1 gap-1">
-            <span>${el.marker} ${el.seriesName}</span>
-            <span>${chartData.value[legend.value[el.componentIndex][1]][el.dataIndex].toFixed(2)} ${el.seriesName.split(' ')[1]}</span>
-          </div>`
-        })
+const mapDataValue = (value: number) => {
+  if (value === 0) return 0
 
-        return d + item.join('')
-      }
-    },
-    legend: {
-      data: legend.value.map(([name]) => name),
-      show: true
-    },
-    xAxis: {
-      type: 'category',
-      data: xAxisData.value
-    },
-    yAxis: {
-      type: 'value',
-      min: -minInterval,
-      max: maxInterval,
-      interval: 1,
-      axisLabel: {
-        formatter: (v) => {
-          const num = v === 0 ? 0 : v > 0 ? Math.pow(10, v) : -Math.pow(10, -v)
-
-          return num.toLocaleString()
-        }
-      }
-    },
-    series: legend.value.map(([name, key]) => ({
-      name,
-      type: 'line',
-      smooth: true,
-      showSymbol: true,
-      data: chartData.value[key].map((value) => {
-        // return value
-        if (value === 0) return 0
+  const isPositive = value > 0
+  const absItem = Math.abs(value)
+
+  if (!intervalArr.value.length) return value
+
+  const min_value = Math.max(...intervalArr.value.filter((v) => v <= absItem))
+  const min_index = intervalArr.value.findIndex((v) => v === min_value)
+
+  const denominator =
+    min_index < intervalArr.value.length - 1
+      ? intervalArr.value[min_index + 1] - intervalArr.value[min_index]
+      : intervalArr.value[min_index] || 1
 
-        const isPositive = value > 0
-        const absItem = Math.abs(value)
+  const new_value = (absItem - min_value) / denominator + min_index
 
-        const min_value = Math.max(...intervalArr.filter((v) => v <= absItem))
-        const min_index = intervalArr.findIndex((v) => v === min_value)
+  return isPositive ? new_value : -new_value
+}
+
+const getSeries = () => {
+  return legend.value.map(([name, key]) => ({
+    name,
+    type: 'line',
+    smooth: true,
+    showSymbol: true,
+    data: chartData.value[key].map((value) => mapDataValue(value))
+  }))
+}
+
+const render = () => {
+  if (!chartRef.value) return
 
-        const new_value =
-          (absItem - min_value) / (intervalArr[min_index + 1] - intervalArr[min_index]) + min_index
+  if (!chart) {
+    chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })
+    window.addEventListener('resize', resizer)
 
-        return isPositive ? new_value : -new_value
+    chart.on('legendselectchanged', (params: any) => {
+      selectedLegends.value = params.selected
+
+      calcIntervals()
+
+      chart?.setOption({
+        yAxis: {
+          min: -minInterval.value,
+          max: maxInterval.value
+        },
+        series: getSeries()
       })
-    }))
+    })
+  }
+
+  legend.value.forEach(([name]) => {
+    selectedLegends.value[name] = true
   })
+
+  calcIntervals()
+
+  chart.setOption(
+    {
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: { type: 'line' },
+        formatter: (params: any) => {
+          let d = `${params[0].axisValueLabel}<br>`
+          let item = params.map((el: any) => {
+            const realValue = chartData.value[legend.value[el.componentIndex][1]][el.dataIndex]
+            return `<div class="flex items-center justify-between mt-1 gap-1">
+            <span>${el.marker} ${el.seriesName}</span>
+            <span>${realValue.toFixed(2)} ${el.seriesName.split(' ')[1] || ''}</span>
+          </div>`
+          })
+          return d + item.join('')
+        }
+      },
+      legend: {
+        data: legend.value.map(([name]) => name),
+        selected: selectedLegends.value,
+        show: true
+      },
+      xAxis: {
+        type: 'category',
+        data: xAxisData.value
+      },
+      yAxis: {
+        type: 'value',
+        min: -minInterval.value,
+        max: maxInterval.value,
+        interval: 1,
+        axisLabel: {
+          formatter: (v: number) => {
+            const num = v === 0 ? 0 : v > 0 ? Math.pow(10, v) : -Math.pow(10, -v)
+            return num.toLocaleString()
+          }
+        }
+      },
+      series: getSeries()
+    },
+    true
+  )
 }
 
 const handleDeptNodeClick = (node: any) => {

+ 0 - 724
src/views/pms/iotrydailyreport/approval1.vue

@@ -1,724 +0,0 @@
-<script lang="ts" setup>
-import { rangeShortcuts } from '@/utils/formatTime'
-import { useDebounceFn } from '@vueuse/core'
-import dayjs from 'dayjs'
-import { DICT_TYPE } from '@/utils/dict'
-import { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
-import { useUserStore } from '@/store/modules/user'
-import { IotRyDailyReportApi } from '@/api/pms/iotrydailyreport'
-import ryForm from './ry-form.vue'
-
-interface List {
-  id: number
-  deptId: number
-  projectId: number
-  taskId: number
-  projectClassification: string
-  relocationDays: number
-  latestWellDoneTime: number
-  currentDepth: number
-  dailyFootage: number
-  monthlyFootage: number
-  annualFootage: number
-  dailyPowerUsage: number
-  monthlyPowerUsage: number
-  dailyFuel: number
-  monthlyFuel: number
-  dailyOilVolume: number
-  remainDieselVolume: number
-  productionTime: number
-  nonProductionTime: number
-  ryNptReason: string
-  drillingWorkingTime: number
-  otherProductionTime: number
-  accidentTime: number
-  repairTime: number
-  selfStopTime: number
-  complexityTime: number
-  relocationTime: number
-  rectificationTime: number
-  waitingStopTime: number
-  winterBreakTime: number
-  partyaDesign: number
-  partyaPrepare: number
-  partyaResource: number
-  otherNptTime: number
-  otherNptReason: string // 其他非生产时间原因
-  constructionStartDate: number
-  constructionEndDate: number
-  productionStatus: string
-  currentOperation: string
-  nextPlan: string
-  rigStatus: string
-  repairStatus: string
-  personnel: string
-  totalStaffNum: number
-  leaveStaffNum: number
-  mudDensity: number
-  mudViscosity: number
-  lateralLength: number
-  wellInclination: number
-  azimuth: number
-  remark: string
-  status: number
-  processInstanceId: string
-  auditStatus: number
-  opinion: string
-  createTime: number
-  deptName: string
-  contractName: string
-  taskName: string
-  designWellDepth: number
-  designWellStruct: number
-  totalConstructionWells: number
-  completedWells: number
-  equipmentType: string
-  transitTime: number
-  lastCurrentDepth: number
-  nonProductionRate: number
-}
-
-interface Column {
-  prop?: keyof List
-  label: string
-  'min-width'?: string
-  isTag?: boolean
-  fixed?: 'left' | 'right'
-  formatter?: (row: List) => any
-  children?: Column[]
-  dictType?: string
-}
-
-const columns = ref<Column[]>([
-  {
-    label: '日期',
-    prop: 'createTime',
-    'min-width': '120px',
-    formatter: (row: List) => dayjs(row.createTime).format('YYYY-MM-DD'),
-    fixed: 'left'
-  },
-  {
-    label: '施工队伍',
-    prop: 'deptName',
-    'min-width': '120px',
-    fixed: 'left'
-  },
-  {
-    label: '任务',
-    prop: 'taskName',
-    'min-width': '120px',
-    fixed: 'left'
-  },
-  {
-    label: '施工状态',
-    prop: 'rigStatus',
-    'min-width': '120px',
-    isTag: true,
-    dictType: DICT_TYPE.PMS_PROJECT_TASK_RY_SCHEDULE,
-    fixed: 'left'
-  },
-  {
-    label: '审批状态',
-    prop: 'auditStatus',
-    'min-width': '120px',
-    isTag: true,
-    formatter: (row: List) => {
-      switch (row.auditStatus) {
-        case 0:
-          return '待提交'
-        case 10:
-          return '待审批'
-        case 20:
-          return '审批通过'
-        case 30:
-          return '审批拒绝'
-        default:
-          return ''
-      }
-    }
-  },
-  {
-    label: '设备型号',
-    prop: 'equipmentType',
-    'min-width': '120px'
-  },
-  {
-    label: '上井次完井时间',
-    prop: 'latestWellDoneTime',
-    'min-width': '120px',
-    formatter: (row: List) =>
-      row.latestWellDoneTime ? dayjs(row.latestWellDoneTime).format('YYYY-MM-DD') : ''
-  },
-  {
-    label: '井深(m)',
-    children: [
-      {
-        label: '设计',
-        prop: 'designWellDepth',
-        'min-width': '120px'
-      },
-      {
-        label: '当前',
-        prop: 'currentDepth',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '进尺(m)',
-    children: [
-      {
-        label: '日',
-        prop: 'dailyFootage',
-        'min-width': '120px'
-      },
-      {
-        label: '月',
-        prop: 'monthlyFootage',
-        'min-width': '120px'
-      },
-      {
-        label: '年累计',
-        prop: 'annualFootage',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '总施工井数',
-    prop: 'totalConstructionWells',
-    'min-width': '120px'
-  },
-  {
-    label: '完工井数',
-    prop: 'completedWells',
-    'min-width': '120px'
-  },
-  {
-    label: '泥浆性能',
-    children: [
-      {
-        label: '密度(g/cm³)',
-        prop: 'mudDensity',
-        'min-width': '120px'
-      },
-      {
-        label: '粘度(S)',
-        prop: 'mudViscosity',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '当日',
-    children: [
-      {
-        label: '用电量(kWh)',
-        prop: 'dailyPowerUsage',
-        'min-width': '120px'
-      },
-      {
-        label: '油耗(升)',
-        prop: 'dailyFuel',
-        'min-width': '120px'
-      }
-    ]
-  },
-  // {
-  //   label: '施工开始日期',
-  //   prop: 'constructionStartDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionStartDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  // {
-  //   label: '施工结束日期',
-  //   prop: 'constructionEndDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionEndDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  {
-    label: '水平段长度(m)',
-    prop: 'lateralLength',
-    'min-width': '120px'
-  },
-  {
-    label: '井斜(°)',
-    prop: 'wellInclination',
-    'min-width': '120px'
-  },
-  {
-    label: '方位(°)',
-    prop: 'azimuth',
-    'min-width': '120px'
-  },
-  {
-    label: '设计井身结构',
-    prop: 'designWellStruct',
-    'min-width': '120px'
-  },
-  {
-    label: '生产动态',
-    prop: 'productionStatus',
-    'min-width': '120px'
-  },
-  {
-    label: '项目',
-    prop: 'contractName',
-    'min-width': '120px'
-  },
-  {
-    label: '进尺工作时间(H)',
-    prop: 'drillingWorkingTime',
-    'min-width': '120px'
-  },
-  {
-    label: '其它生产时间(H)',
-    prop: 'otherProductionTime',
-    'min-width': '120px'
-  },
-  {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    'min-width': '120px',
-    formatter: (row: List) => {
-      const nonProductionRate = row?.nonProductionRate ?? 0
-
-      return (nonProductionRate * 100).toFixed(2) + '%'
-    }
-  },
-  {
-    label: '非生产时间',
-    children: [
-      {
-        label: '工程质量',
-        prop: 'accidentTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备故障',
-        prop: 'repairTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备保养',
-        prop: 'selfStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '技术受限',
-        prop: 'complexityTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产配合',
-        prop: 'relocationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产组织',
-        prop: 'rectificationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '不可抗力',
-        prop: 'waitingStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '待命',
-        prop: 'winterBreakTime',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方设计',
-        prop: 'partyaDesign',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方准备',
-        prop: 'partyaPrepare',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方资源',
-        prop: 'partyaResource',
-        'min-width': '120px'
-      },
-      {
-        label: '其它非生产时间',
-        prop: 'otherNptTime',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    'min-width': '120px'
-  }
-])
-
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = (colums: Column[]) => {
-  for (const col of colums) {
-    let { formatter, prop, label, 'min-width': minWidth, isTag, children } = col
-
-    if (children && children.length > 0) {
-      calculateColumnWidths(children)
-      continue
-    }
-
-    minWidth =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(formatter ? formatter(v) : v[prop!])
-              })
-            ]
-          ) + (isTag ? 40 : 20),
-          200
-        ]
-      ) + 'px'
-
-    col['min-width'] = minWidth
-  }
-}
-
-const nptFields = [
-  'accidentTime', // 工程质量
-  'repairTime', // 设备故障
-  'selfStopTime', // 设备保养
-  'complexityTime', // 技术受限
-  // 'relocationTime', // 生产配合
-  'rectificationTime', // 生产组织
-  'waitingStopTime', // 不可抗力
-  'winterBreakTime', // 待命
-  'partyaDesign', // 甲方设计
-  'partyaPrepare', // 甲方资源
-  'partyaResource', // 甲方准备
-  'otherNptTime' // 其它非生产时间
-]
-
-function checkTimeSumEquals24(row: List) {
-  const gasTime = parseFloat(row.drillingWorkingTime + '') || 0
-  // 对应你代码中的 waterTime
-  const waterTime = parseFloat(row.otherProductionTime + '') || 0
-
-  // 3. 计算所有非生产时间之和
-  const nonProdTime = nptFields.reduce((sum, field) => {
-    const val = parseFloat(row[field])
-    // 如果值是数字则累加,如果是 NaN 或 null/undefined 则加 0
-    return sum + (isNaN(val) ? 0 : val)
-  }, 0)
-
-  // 4. 计算总和:纯钻进 + 其他生产 + 所有非生产时间
-  const totalSum = gasTime + waterTime + nonProdTime
-
-  // 5. 返回是否等于 24(允许 0.01 的浮点数误差)
-  return Math.abs(totalSum - 24) < 0.01
-}
-
-function cellStyle(data: {
-  row: List
-  column: TableColumnCtx<List>
-  rowIndex: number
-  columnIndex: number
-}) {
-  const { row, column } = data
-
-  if (column.property === 'dailyFuel') {
-    const originalValue = row.dailyFuel ?? 0
-
-    if (originalValue > 9000)
-      return {
-        color: 'red',
-        fontWeight: 'bold'
-      }
-  }
-
-  const timeFields = ['drillingWorkingTime', 'otherProductionTime', ...nptFields]
-  if (timeFields.includes(column.property)) {
-    if (!checkTimeSumEquals24(row)) {
-      return {
-        color: 'orange',
-        fontWeight: 'bold'
-      }
-    }
-  }
-
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-const id = useUserStore().getUser.deptId
-
-const deptId = id
-
-interface Query {
-  pageNo: number
-  pageSize: number
-  deptId: number
-  contractName?: string
-  taskName?: string
-  createTime: string[]
-  projectClassification: '1' | '2'
-}
-
-const query = ref<Query>({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: id,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ],
-  projectClassification: '1'
-})
-
-function handleSizeChange(val: number) {
-  query.value.pageSize = val
-  handleQuery()
-}
-
-function handleCurrentChange(val: number) {
-  query.value.pageNo = val
-  loadList()
-}
-
-const loading = ref(false)
-
-const list = ref<List[]>([])
-const total = ref(0)
-
-const loadList = useDebounceFn(async function () {
-  loading.value = true
-  try {
-    const data = await IotRyDailyReportApi.getIotRyDailyReportPage(query.value)
-    list.value = data.list
-    total.value = data.total
-
-    nextTick(() => {
-      calculateColumnWidths(columns.value)
-    })
-  } finally {
-    loading.value = false
-  }
-}, 500)
-
-function handleQuery(setPage = true) {
-  if (setPage) {
-    query.value.pageNo = 1
-  }
-  loadList()
-}
-
-function resetQuery() {
-  query.value = {
-    pageNo: 1,
-    pageSize: 10,
-    deptId: 157,
-    contractName: '',
-    taskName: '',
-    createTime: [
-      ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-    ],
-    projectClassification: '1'
-  }
-  handleQuery()
-}
-
-watch(
-  [
-    () => query.value.createTime,
-    () => query.value.deptId,
-    () => query.value.taskName,
-    () => query.value.contractName
-  ],
-  () => {
-    handleQuery()
-  },
-  { immediate: true }
-)
-
-const visible = ref(false)
-
-const formRef = ref()
-
-function handleOpenForm(id: number, type: 'edit' | 'readonly') {
-  if (formRef.value) {
-    formRef.value.handleOpenForm(id, type)
-  }
-}
-
-const route = useRoute()
-
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    handleOpenForm(Number(route.query.id), 'edit')
-  }
-})
-</script>
-
-<template>
-  <div
-    class="h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))] >"
-  >
-    <div class="grid grid-cols-[15%_1fr] gap-4 h-full">
-      <div class="flex flex-col p-4 gap-2 bg-white dark:bg-[#1d1e1f] shadow rounded-lg h-full">
-        <DeptTreeSelect :deptId="deptId" :topId="158" v-model="query.deptId" />
-      </div>
-      <div class="grid grid-rows-[62px_1fr] h-full gap-4">
-        <el-form
-          size="default"
-          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
-        >
-          <div class="flex items-center gap-8">
-            <el-form-item label="项目">
-              <el-input
-                v-model="query.contractName"
-                placeholder="请输入项目"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="任务">
-              <el-input
-                v-model="query.taskName"
-                placeholder="请输入任务"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="创建时间">
-              <el-date-picker
-                v-model="query.createTime"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                type="daterange"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-                :shortcuts="rangeShortcuts"
-                class="!w-220px"
-                :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              />
-            </el-form-item>
-          </div>
-          <el-form-item>
-            <el-button type="primary" @click="handleQuery()">
-              <Icon icon="ep:search" class="mr-5px" /> 搜索
-            </el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
-          </el-form-item>
-        </el-form>
-        <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg p-4 flex flex-col">
-          <div class="flex-1 relative">
-            <el-auto-resizer class="absolute">
-              <template #default="{ width, height }">
-                <el-table
-                  :data="list"
-                  v-loading="loading"
-                  stripe
-                  class="absolute"
-                  :max-height="height"
-                  show-overflow-tooltip
-                  :width="width"
-                  :cell-style="cellStyle"
-                  border
-                >
-                  <DailyTableColumn :columns="columns" />
-                  <el-table-column label="操作" width="120px" align="center" fixed="right">
-                    <template #default="{ row }">
-                      <el-button
-                        link
-                        type="success"
-                        @click="handleOpenForm(row.id, 'readonly')"
-                        v-hasPermi="['pms:iot-ry-daily-report:update']"
-                      >
-                        查看
-                      </el-button>
-                      <el-button
-                        v-show="row.auditStatus === 10"
-                        link
-                        type="primary"
-                        @click="handleOpenForm(row.id, 'edit')"
-                        v-hasPermi="['pms:iot-ry-daily-report:update']"
-                      >
-                        审批
-                      </el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </template>
-            </el-auto-resizer>
-          </div>
-          <div class="h-10 mt-4 flex items-center justify-end">
-            <el-pagination
-              size="default"
-              v-show="total > 0"
-              v-model:current-page="query.pageNo"
-              v-model:page-size="query.pageSize"
-              :background="true"
-              :page-sizes="[10, 20, 30, 50, 100]"
-              :total="total"
-              layout="total, sizes, prev, pager, next, jumper"
-              @size-change="handleSizeChange"
-              @current-change="handleCurrentChange"
-            />
-          </div>
-        </div>
-      </div>
-    </div>
-    <ry-form v-model:visible="visible" type="approval" ref="formRef" :load-list="loadList" />
-  </div>
-</template>
-
-<style scoped>
-:deep(.el-form-item) {
-  margin-bottom: 0;
-}
-
-:deep(.el-table) {
-  border-top-right-radius: 8px;
-  border-top-left-radius: 8px;
-
-  .el-table__cell {
-    height: 40px;
-  }
-
-  .el-table__header-wrapper {
-    .el-table__cell {
-      background: var(--el-fill-color-light);
-    }
-  }
-}
-
-:deep(.el-input-number) {
-  width: 100%;
-}
-
-:deep(.el-input-number__decrease) {
-  display: none !important;
-}
-
-:deep(.el-input-number__increase) {
-  display: none !important;
-}
-</style>

+ 0 - 724
src/views/pms/iotrydailyreport/fill1.vue

@@ -1,724 +0,0 @@
-<script lang="ts" setup>
-import { rangeShortcuts } from '@/utils/formatTime'
-import { useDebounceFn } from '@vueuse/core'
-import dayjs from 'dayjs'
-import { DICT_TYPE } from '@/utils/dict'
-import { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
-import { useUserStore } from '@/store/modules/user'
-import { IotRyDailyReportApi } from '@/api/pms/iotrydailyreport'
-import ryForm from './ry-form.vue'
-
-interface List {
-  id: number
-  deptId: number
-  projectId: number
-  taskId: number
-  projectClassification: string
-  relocationDays: number
-  latestWellDoneTime: number
-  currentDepth: number
-  dailyFootage: number
-  monthlyFootage: number
-  annualFootage: number
-  dailyPowerUsage: number
-  monthlyPowerUsage: number
-  dailyFuel: number
-  monthlyFuel: number
-  dailyOilVolume: number
-  remainDieselVolume: number
-  productionTime: number
-  nonProductionTime: number
-  ryNptReason: string
-  drillingWorkingTime: number
-  otherProductionTime: number
-  accidentTime: number
-  repairTime: number
-  selfStopTime: number
-  complexityTime: number
-  relocationTime: number
-  rectificationTime: number
-  waitingStopTime: number
-  winterBreakTime: number
-  partyaDesign: number
-  partyaPrepare: number
-  partyaResource: number
-  otherNptTime: number
-  otherNptReason: string
-  constructionStartDate: number
-  constructionEndDate: number
-  productionStatus: string
-  currentOperation: string
-  nextPlan: string
-  rigStatus: string
-  repairStatus: string
-  personnel: string
-  totalStaffNum: number
-  leaveStaffNum: number
-  mudDensity: number
-  mudViscosity: number
-  lateralLength: number
-  wellInclination: number
-  azimuth: number
-  remark: string
-  status: number
-  processInstanceId: string
-  auditStatus: number
-  opinion: string
-  createTime: number
-  deptName: string
-  contractName: string
-  taskName: string
-  designWellDepth: number
-  designWellStruct: number
-  totalConstructionWells: number
-  completedWells: number
-  equipmentType: string
-  transitTime: number
-  lastCurrentDepth: number
-  nonProductionRate: number
-}
-
-interface Column {
-  prop?: keyof List
-  label: string
-  'min-width'?: string
-  isTag?: boolean
-  fixed?: 'left' | 'right'
-  formatter?: (row: List) => any
-  children?: Column[]
-  dictType?: string
-}
-
-const columns = ref<Column[]>([
-  {
-    label: '日期',
-    prop: 'createTime',
-    'min-width': '120px',
-    formatter: (row: List) => dayjs(row.createTime).format('YYYY-MM-DD'),
-    fixed: 'left'
-  },
-  {
-    label: '施工队伍',
-    prop: 'deptName',
-    'min-width': '120px',
-    fixed: 'left'
-  },
-  {
-    label: '任务',
-    prop: 'taskName',
-    'min-width': '120px',
-    fixed: 'left'
-  },
-  {
-    label: '施工状态',
-    prop: 'rigStatus',
-    'min-width': '120px',
-    isTag: true,
-    dictType: DICT_TYPE.PMS_PROJECT_TASK_RY_SCHEDULE,
-    fixed: 'left'
-  },
-  {
-    label: '审批状态',
-    prop: 'auditStatus',
-    'min-width': '120px',
-    isTag: true,
-    formatter: (row: List) => {
-      switch (row.auditStatus) {
-        case 0:
-          return '待提交'
-        case 10:
-          return '待审批'
-        case 20:
-          return '审批通过'
-        case 30:
-          return '审批拒绝'
-        default:
-          return ''
-      }
-    }
-  },
-  {
-    label: '设备型号',
-    prop: 'equipmentType',
-    'min-width': '120px'
-  },
-  {
-    label: '上井次完井时间',
-    prop: 'latestWellDoneTime',
-    'min-width': '120px',
-    formatter: (row: List) =>
-      row.latestWellDoneTime ? dayjs(row.latestWellDoneTime).format('YYYY-MM-DD') : ''
-  },
-  {
-    label: '井深(m)',
-    children: [
-      {
-        label: '设计',
-        prop: 'designWellDepth',
-        'min-width': '120px'
-      },
-      {
-        label: '当前',
-        prop: 'currentDepth',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '进尺(m)',
-    children: [
-      {
-        label: '日',
-        prop: 'dailyFootage',
-        'min-width': '120px'
-      },
-      {
-        label: '月',
-        prop: 'monthlyFootage',
-        'min-width': '120px'
-      },
-      {
-        label: '年累计',
-        prop: 'annualFootage',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '总施工井数',
-    prop: 'totalConstructionWells',
-    'min-width': '120px'
-  },
-  {
-    label: '完工井数',
-    prop: 'completedWells',
-    'min-width': '120px'
-  },
-  {
-    label: '泥浆性能',
-    children: [
-      {
-        label: '密度(g/cm³)',
-        prop: 'mudDensity',
-        'min-width': '120px'
-      },
-      {
-        label: '粘度(S)',
-        prop: 'mudViscosity',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '当日',
-    children: [
-      {
-        label: '用电量(kWh)',
-        prop: 'dailyPowerUsage',
-        'min-width': '120px'
-      },
-      {
-        label: '油耗(升)',
-        prop: 'dailyFuel',
-        'min-width': '120px'
-      }
-    ]
-  },
-  // {
-  //   label: '施工开始日期',
-  //   prop: 'constructionStartDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionStartDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  // {
-  //   label: '施工结束日期',
-  //   prop: 'constructionEndDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionEndDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  {
-    label: '水平段长度(m)',
-    prop: 'lateralLength',
-    'min-width': '120px'
-  },
-  {
-    label: '井斜(°)',
-    prop: 'wellInclination',
-    'min-width': '120px'
-  },
-  {
-    label: '方位(°)',
-    prop: 'azimuth',
-    'min-width': '120px'
-  },
-  {
-    label: '设计井身结构',
-    prop: 'designWellStruct',
-    'min-width': '120px'
-  },
-  {
-    label: '生产动态',
-    prop: 'productionStatus',
-    'min-width': '120px'
-  },
-  {
-    label: '项目',
-    prop: 'contractName',
-    'min-width': '120px'
-  },
-  {
-    label: '进尺工作时间(H)',
-    prop: 'drillingWorkingTime',
-    'min-width': '120px'
-  },
-  {
-    label: '其它生产时间(H)',
-    prop: 'otherProductionTime',
-    'min-width': '120px'
-  },
-  {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    'min-width': '120px',
-    formatter: (row: List) => {
-      const nonProductionRate = row?.nonProductionRate ?? 0
-
-      return (nonProductionRate * 100).toFixed(2) + '%'
-    }
-  },
-  {
-    label: '非生产时间',
-    children: [
-      {
-        label: '工程质量',
-        prop: 'accidentTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备故障',
-        prop: 'repairTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备保养',
-        prop: 'selfStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '技术受限',
-        prop: 'complexityTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产配合',
-        prop: 'relocationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产组织',
-        prop: 'rectificationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '不可抗力',
-        prop: 'waitingStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '待命',
-        prop: 'winterBreakTime',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方设计',
-        prop: 'partyaDesign',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方准备',
-        prop: 'partyaPrepare',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方资源',
-        prop: 'partyaResource',
-        'min-width': '120px'
-      },
-      {
-        label: '其它非生产时间',
-        prop: 'otherNptTime',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    'min-width': '120px'
-  }
-])
-
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = (colums: Column[]) => {
-  for (const col of colums) {
-    let { formatter, prop, label, 'min-width': minWidth, isTag, children } = col
-
-    if (children && children.length > 0) {
-      calculateColumnWidths(children)
-      continue
-    }
-
-    minWidth =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(formatter ? formatter(v) : v[prop!])
-              })
-            ]
-          ) + (isTag ? 40 : 20),
-          200
-        ]
-      ) + 'px'
-
-    col['min-width'] = minWidth
-  }
-}
-
-const nptFields = [
-  'accidentTime', // 工程质量
-  'repairTime', // 设备故障
-  'selfStopTime', // 设备保养
-  'complexityTime', // 技术受限
-  // 'relocationTime', // 生产配合
-  'rectificationTime', // 生产组织
-  'waitingStopTime', // 不可抗力
-  'winterBreakTime', // 待命
-  'partyaDesign', // 甲方设计
-  'partyaPrepare', // 甲方资源
-  'partyaResource', // 甲方准备
-  'otherNptTime' // 其它非生产时间
-]
-
-function checkTimeSumEquals24(row: List) {
-  const gasTime = parseFloat(row.drillingWorkingTime + '') || 0
-  // 对应你代码中的 waterTime
-  const waterTime = parseFloat(row.otherProductionTime + '') || 0
-
-  // 3. 计算所有非生产时间之和
-  const nonProdTime = nptFields.reduce((sum, field) => {
-    const val = parseFloat(row[field])
-    // 如果值是数字则累加,如果是 NaN 或 null/undefined 则加 0
-    return sum + (isNaN(val) ? 0 : val)
-  }, 0)
-
-  // 4. 计算总和:纯钻进 + 其他生产 + 所有非生产时间
-  const totalSum = gasTime + waterTime + nonProdTime
-
-  // 5. 返回是否等于 24(允许 0.01 的浮点数误差)
-  return Math.abs(totalSum - 24) < 0.01
-}
-
-function cellStyle(data: {
-  row: List
-  column: TableColumnCtx<List>
-  rowIndex: number
-  columnIndex: number
-}) {
-  const { row, column } = data
-
-  if (column.property === 'dailyFuel') {
-    const originalValue = row.dailyFuel ?? 0
-
-    if (originalValue > 9000)
-      return {
-        color: 'red',
-        fontWeight: 'bold'
-      }
-  }
-
-  const timeFields = ['drillingWorkingTime', 'otherProductionTime', ...nptFields]
-  if (timeFields.includes(column.property)) {
-    if (!checkTimeSumEquals24(row)) {
-      return {
-        color: 'orange',
-        fontWeight: 'bold'
-      }
-    }
-  }
-
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-const id = useUserStore().getUser.deptId
-
-const deptId = id
-
-interface Query {
-  pageNo: number
-  pageSize: number
-  deptId: number
-  contractName?: string
-  taskName?: string
-  createTime: string[]
-  projectClassification: '1' | '2'
-}
-
-const query = ref<Query>({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: id,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ],
-  projectClassification: '1'
-})
-
-function handleSizeChange(val: number) {
-  query.value.pageSize = val
-  handleQuery()
-}
-
-function handleCurrentChange(val: number) {
-  query.value.pageNo = val
-  loadList()
-}
-
-const loading = ref(false)
-
-const list = ref<List[]>([])
-const total = ref(0)
-
-const loadList = useDebounceFn(async function () {
-  loading.value = true
-  try {
-    const data = await IotRyDailyReportApi.getIotRyDailyReportPage(query.value)
-    list.value = data.list
-    total.value = data.total
-
-    nextTick(() => {
-      calculateColumnWidths(columns.value)
-    })
-  } finally {
-    loading.value = false
-  }
-}, 500)
-
-function handleQuery(setPage = true) {
-  if (setPage) {
-    query.value.pageNo = 1
-  }
-  loadList()
-}
-
-function resetQuery() {
-  query.value = {
-    pageNo: 1,
-    pageSize: 10,
-    deptId: 157,
-    contractName: '',
-    taskName: '',
-    createTime: [
-      ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-    ],
-    projectClassification: '1'
-  }
-  handleQuery()
-}
-
-watch(
-  [
-    () => query.value.createTime,
-    () => query.value.deptId,
-    () => query.value.taskName,
-    () => query.value.contractName
-  ],
-  () => {
-    handleQuery()
-  },
-  { immediate: true }
-)
-
-const visible = ref(false)
-
-const formRef = ref()
-
-function handleOpenForm(id: number, type: 'edit' | 'readonly') {
-  if (formRef.value) {
-    formRef.value.handleOpenForm(id, type)
-  }
-}
-
-const route = useRoute()
-
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    handleOpenForm(Number(route.query.id), 'edit')
-  }
-})
-</script>
-
-<template>
-  <div
-    class="h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
-  >
-    <div class="grid grid-cols-[15%_1fr] gap-4 h-full">
-      <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg h-full">
-        <DeptTreeSelect :top-id="158" :deptId="deptId" v-model="query.deptId" />
-      </div>
-      <div class="grid grid-rows-[62px_1fr] h-full gap-4">
-        <el-form
-          size="default"
-          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
-        >
-          <div class="flex items-center gap-8">
-            <el-form-item label="项目">
-              <el-input
-                v-model="query.contractName"
-                placeholder="请输入项目"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="任务">
-              <el-input
-                v-model="query.taskName"
-                placeholder="请输入任务"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="创建时间">
-              <el-date-picker
-                v-model="query.createTime"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                type="daterange"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-                :shortcuts="rangeShortcuts"
-                class="!w-220px"
-                :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              />
-            </el-form-item>
-          </div>
-          <el-form-item>
-            <el-button type="primary" @click="handleQuery()">
-              <Icon icon="ep:search" class="mr-5px" /> 搜索
-            </el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
-          </el-form-item>
-        </el-form>
-        <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg p-4 flex flex-col">
-          <div class="flex-1 relative">
-            <el-auto-resizer class="absolute">
-              <template #default="{ width, height }">
-                <el-table
-                  :data="list"
-                  v-loading="loading"
-                  stripe
-                  class="absolute"
-                  :max-height="height"
-                  show-overflow-tooltip
-                  :width="width"
-                  :cell-style="cellStyle"
-                  border
-                >
-                  <DailyTableColumn :columns="columns" />
-                  <el-table-column label="操作" width="120px" align="center" fixed="right">
-                    <template #default="{ row }">
-                      <el-button
-                        link
-                        type="success"
-                        @click="handleOpenForm(row.id, 'readonly')"
-                        v-hasPermi="['pms:iot-ry-daily-report:query']"
-                      >
-                        查看
-                      </el-button>
-                      <el-button
-                        v-show="row.status === 0"
-                        link
-                        type="primary"
-                        @click="handleOpenForm(row.id, 'edit')"
-                        v-hasPermi="['pms:iot-ry-daily-report:create']"
-                      >
-                        编辑
-                      </el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </template>
-            </el-auto-resizer>
-          </div>
-          <div class="h-10 mt-4 flex items-center justify-end">
-            <el-pagination
-              size="default"
-              v-show="total > 0"
-              v-model:current-page="query.pageNo"
-              v-model:page-size="query.pageSize"
-              :background="true"
-              :page-sizes="[10, 20, 30, 50, 100]"
-              :total="total"
-              layout="total, sizes, prev, pager, next, jumper"
-              @size-change="handleSizeChange"
-              @current-change="handleCurrentChange"
-            />
-          </div>
-        </div>
-      </div>
-    </div>
-    <ry-form v-model:visible="visible" type="edit" ref="formRef" :load-list="loadList" />
-  </div>
-</template>
-
-<style scoped>
-:deep(.el-form-item) {
-  margin-bottom: 0;
-}
-
-:deep(.el-table) {
-  border-top-right-radius: 8px;
-  border-top-left-radius: 8px;
-
-  .el-table__cell {
-    height: 40px;
-  }
-
-  .el-table__header-wrapper {
-    .el-table__cell {
-      background: var(--el-fill-color-light);
-    }
-  }
-}
-
-:deep(.el-input-number) {
-  width: 100%;
-}
-
-:deep(.el-input-number__decrease) {
-  display: none !important;
-}
-
-:deep(.el-input-number__increase) {
-  display: none !important;
-}
-</style>

+ 18 - 17
src/views/pms/iotrydailyreport/index.vue

@@ -134,7 +134,7 @@ function handleOpenForm(id: number, type: 'edit' | 'readonly') {
 
 <template>
   <div
-    class="grid grid-cols-[15%_1fr] grid-rows-[48px_auto_1fr] gap-x-4 gap-y-3 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
+    class="grid grid-cols-[15%_1fr] grid-rows-[48px_1fr_auto] gap-x-4 gap-y-3 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
   >
     <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg row-span-3">
       <DeptTreeSelect :top-id="158" :deptId="deptId" v-model="query.deptId" :show-title="false" />
@@ -203,22 +203,6 @@ function handleOpenForm(id: number, type: 'edit' | 'readonly') {
       </el-form-item>
     </el-form>
 
-    <div class="p-2 bg-white dark:bg-[#1d1e1f] rounded-lg shadow flex flex-col gap-2">
-      <el-alert
-        class="h-8!"
-        title="当日油耗大于9000升&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;红色预警"
-        type="error"
-        show-icon
-        :closable="false"
-      />
-      <el-alert
-        class="h-8!"
-        title="进尺工作时间+其它生产时间+非生产时间=24H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;否则橙色预警"
-        type="warning"
-        show-icon
-        :closable="false"
-      />
-    </div>
     <ry-table
       :list="list"
       :total="total"
@@ -248,6 +232,23 @@ function handleOpenForm(id: number, type: 'edit' | 'readonly') {
         </el-button>
       </template>
     </ry-table>
+
+    <div class="p-2 bg-white dark:bg-[#1d1e1f] rounded-lg shadow flex flex-col gap-2">
+      <el-alert
+        class="h-8!"
+        title="当日油耗大于9000升&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;红色预警"
+        type="error"
+        show-icon
+        :closable="false"
+      />
+      <el-alert
+        class="h-8!"
+        title="进尺工作时间+其它生产时间+非生产时间=24H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;否则橙色预警"
+        type="warning"
+        show-icon
+        :closable="false"
+      />
+    </div>
   </div>
 
   <ry-form

+ 0 - 1169
src/views/pms/iotrydailyreport/index1.vue

@@ -1,1169 +0,0 @@
-<template>
-  <el-row :gutter="20">
-    <el-col :span="4" :xs="24">
-      <!-- <ContentWrap class="h-1/1">
-        <DeptTree2 :deptId="rootDeptId" @node-click="handleDeptNodeClick" />
-      </ContentWrap> -->
-      <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-4 h-full">
-        <DeptTreeSelect
-          :deptId="rootDeptId"
-          :top-id="158"
-          v-model="queryParams.deptId"
-          @node-click="handleDeptNodeClick"
-        />
-      </div>
-    </el-col>
-    <el-col :span="20" :xs="24">
-      <ContentWrap>
-        <!-- 搜索工作栏 -->
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="80px"
-        >
-          <el-form-item label="项目" prop="contractName">
-            <el-input
-              v-model="queryParams.contractName"
-              placeholder="请输入项目"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="任务" prop="taskName">
-            <el-input
-              v-model="queryParams.taskName"
-              placeholder="请输入任务"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="创建时间" prop="createTime">
-            <el-date-picker
-              v-model="queryParams.createTime"
-              value-format="YYYY-MM-DD HH:mm:ss"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              class="!w-220px"
-              :shortcuts="rangeShortcuts"
-            />
-          </el-form-item>
-          <el-form-item label="非生产时效" prop="nonProductFlag">
-            <el-switch v-model="queryParams.nonProductFlag" active-value="Y" inactive-value="N" />
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="handleQuery"
-              ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
-            >
-            <el-button @click="resetQuery"
-              ><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
-            >
-            <!-- <el-button
-              type="primary"
-              plain
-              @click="openForm('create')"
-              v-hasPermi="['pms:iot-ry-daily-report:create']"
-            >
-              <Icon icon="ep:plus" class="mr-5px" /> 新增
-            </el-button> -->
-            <el-button type="success" plain @click="handleExport" :loading="exportLoading">
-              <Icon icon="ep:download" class="mr-5px" /> 导出
-            </el-button>
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-
-      <ContentWrap class="mb-15px">
-        <div class="color-legend">
-          <div class="legend-item">
-            <span class="color-indicator red"></span>
-            <span>当日油耗大于9000升&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;红色预警</span>
-          </div>
-          <div class="legend-item">
-            <span class="color-indicator orange"></span>
-            <span
-              >进尺工作时间+其它生产时间+非生产时间=24H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;否则橙色预警</span
-            >
-          </div>
-        </div>
-      </ContentWrap>
-
-      <!-- 列表 -->
-      <ContentWrap ref="tableContainerRef">
-        <div class="table-container">
-          <el-table
-            ref="tableRef"
-            v-loading="loading"
-            :data="list"
-            :stripe="true"
-            :style="{ width: '100%' }"
-            max-height="600"
-            :cell-style="cellStyle"
-            show-overflow-tooltip
-            border
-          >
-            <el-table-column
-              :label="t('iotDevice.serial')"
-              width="56px"
-              align="center"
-              fixed="left"
-            >
-              <template #default="scope">
-                {{ scope.$index + 1 }}
-              </template>
-            </el-table-column>
-            <el-table-column
-              label="日期"
-              align="center"
-              prop="createTime"
-              :formatter="dateFormatter2"
-              :min-width="columnWidths.createTime.width"
-              resizable
-              fixed="left"
-            />
-            <el-table-column
-              label="施工队伍"
-              align="center"
-              prop="deptName"
-              :min-width="columnWidths.deptName.width"
-              resizable
-              fixed="left"
-            />
-
-            <el-table-column
-              label="任务"
-              align="center"
-              prop="taskName"
-              :min-width="columnWidths.taskName.width"
-              resizable
-              fixed="left"
-            />
-
-            <el-table-column
-              :label="t('project.status')"
-              align="center"
-              prop="rigStatus"
-              :min-width="columnWidths.rigStatus.width"
-              resizable
-              fixed="left"
-            >
-              <template #default="scope">
-                <dict-tag
-                  :type="DICT_TYPE.PMS_PROJECT_TASK_RY_SCHEDULE"
-                  :value="scope.row.rigStatus"
-                />
-              </template>
-            </el-table-column>
-            <el-table-column
-              label="设备型号"
-              align="center"
-              prop="equipmentType"
-              :min-width="columnWidths.equipmentType.width"
-              resizable
-            />
-            <el-table-column
-              label="上井次完井时间"
-              align="center"
-              prop="latestWellDoneTime"
-              :min-width="columnWidths.latestWellDoneTime.width"
-              :formatter="dateFormatter2"
-              resizable
-            />
-            <el-table-column align="center" label="井深(m)">
-              <el-table-column
-                label="设计"
-                align="center"
-                prop="designWellDepth"
-                :min-width="columnWidths.designWellDepth.width"
-                resizable
-              />
-              <el-table-column
-                label="当前"
-                align="center"
-                prop="currentDepth"
-                :min-width="columnWidths.currentDepth.width"
-                resizable
-              />
-            </el-table-column>
-            <el-table-column align="center" label="进尺(m)">
-              <el-table-column
-                label="日"
-                align="center"
-                prop="dailyFootage"
-                :min-width="columnWidths.dailyFootage.width"
-                resizable
-              />
-              <el-table-column
-                label="月"
-                align="center"
-                prop="monthlyFootage"
-                :min-width="columnWidths.monthlyFootage.width"
-                resizable
-              />
-              <el-table-column
-                label="年累计"
-                align="center"
-                prop="annualFootage"
-                :min-width="columnWidths.annualFootage.width"
-                resizable
-              />
-            </el-table-column>
-
-            <el-table-column
-              label="总施工井数"
-              align="center"
-              prop="totalConstructionWells"
-              :min-width="columnWidths.totalConstructionWells.width"
-              resizable
-            />
-            <el-table-column
-              label="完工井数"
-              align="center"
-              prop="completedWells"
-              :min-width="columnWidths.completedWells.width"
-              resizable
-            />
-            <el-table-column align="center" label="泥浆性能">
-              <el-table-column
-                label="密度(g/cm³)"
-                align="center"
-                prop="mudDensity"
-                :min-width="columnWidths.mudDensity.width"
-                resizable
-              />
-              <el-table-column
-                label="粘度(S)"
-                align="center"
-                prop="mudViscosity"
-                :min-width="columnWidths.mudViscosity.width"
-                resizable
-              />
-            </el-table-column>
-            <el-table-column align="center" label="当日">
-              <el-table-column
-                label="用电量(kWh)"
-                align="center"
-                prop="dailyPowerUsage"
-                :min-width="columnWidths.dailyPowerUsage.width"
-                resizable
-              />
-              <el-table-column
-                label="油耗(升)"
-                align="center"
-                prop="dailyFuel"
-                :min-width="columnWidths.dailyFuel.width"
-                resizable
-              >
-                <template #default="scope">
-                  <span :class="{ 'fuel-warning': shouldShowFuelWarning(scope.row) }">
-                    {{ scope.row.dailyFuel }}
-                  </span>
-                </template>
-              </el-table-column>
-            </el-table-column>
-
-            <!-- <el-table-column
-              label="施工开始日期"
-              align="center"
-              prop="constructionStartDate"
-              :formatter="dateFormatter"
-              :min-width="columnWidths.constructionStartDate.width"
-              resizable
-            />
-            <el-table-column
-              label="施工结束日期"
-              align="center"
-              prop="constructionEndDate"
-              :formatter="dateFormatter"
-              :min-width="columnWidths.constructionEndDate.width"
-              resizable
-            /> -->
-            <el-table-column
-              label="水平段长度(m)"
-              align="center"
-              prop="lateralLength"
-              :min-width="columnWidths.lateralLength.width"
-              resizable
-            />
-            <el-table-column
-              label="井斜(°)"
-              align="center"
-              prop="wellInclination"
-              :min-width="columnWidths.wellInclination.width"
-              resizable
-            />
-            <el-table-column
-              label="方位(°)"
-              align="center"
-              prop="azimuth"
-              :min-width="columnWidths.azimuth.width"
-              resizable
-            />
-            <el-table-column
-              label="设计井身结构"
-              align="center"
-              prop="designWellStruct"
-              :min-width="columnWidths.designWellStruct.width"
-              resizable
-            />
-            <el-table-column
-              label="生产动态"
-              align="center"
-              prop="productionStatus"
-              :width="columnWidths.productionStatus.width"
-            />
-            <el-table-column
-              label="项目"
-              align="center"
-              prop="contractName"
-              :min-width="columnWidths.contractName.width"
-              resizable
-            />
-            <el-table-column
-              label="进尺工作时间(H)"
-              align="center"
-              prop="drillingWorkingTime"
-              :min-width="columnWidths.drillingWorkingTime.width"
-              resizable
-            />
-            <el-table-column
-              label="其它生产时间(H)"
-              align="center"
-              prop="otherProductionTime"
-              :min-width="columnWidths.otherProductionTime.width"
-              resizable
-            />
-            <el-table-column
-              label="非生产时效"
-              align="center"
-              prop="nonProductionRate"
-              :formatter="nonProductionRateFormatter"
-              :min-width="columnWidths.nonProductionRate.width"
-              resizable
-            />
-            <el-table-column label="非生产时间" align="center">
-              <el-table-column
-                label="工程质量"
-                align="center"
-                prop="accidentTime"
-                :min-width="columnWidths.accidentTime.width"
-                resizable
-              />
-              <el-table-column
-                label="设备故障"
-                align="center"
-                prop="repairTime"
-                :min-width="columnWidths.repairTime.width"
-                resizable
-              />
-              <el-table-column
-                label="设备保养"
-                align="center"
-                prop="selfStopTime"
-                :min-width="columnWidths.selfStopTime.width"
-                resizable
-              />
-              <el-table-column
-                label="技术受限"
-                align="center"
-                prop="complexityTime"
-                :min-width="columnWidths.complexityTime.width"
-                resizable
-              />
-              <el-table-column
-                label="生产配合"
-                align="center"
-                prop="relocationTime"
-                :min-width="columnWidths.relocationTime.width"
-                resizable
-              />
-              <el-table-column
-                label="生产组织"
-                align="center"
-                prop="rectificationTime"
-                :min-width="columnWidths.rectificationTime.width"
-                resizable
-              />
-              <el-table-column
-                label="不可抗力"
-                align="center"
-                prop="waitingStopTime"
-                :min-width="columnWidths.waitingStopTime.width"
-                resizable
-              />
-              <el-table-column
-                label="待命"
-                align="center"
-                prop="winterBreakTime"
-                :min-width="columnWidths.winterBreakTime.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方设计"
-                align="center"
-                prop="partyaDesign"
-                :min-width="columnWidths.partyaDesign.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方准备"
-                align="center"
-                prop="partyaPrepare"
-                :min-width="columnWidths.partyaPrepare.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方资源"
-                align="center"
-                prop="partyaResource"
-                :min-width="columnWidths.partyaResource.width"
-                resizable
-              />
-              <el-table-column
-                label="其它非生产时间"
-                align="center"
-                prop="otherNptTime"
-                :min-width="columnWidths.otherNptTime.width"
-                resizable
-              />
-            </el-table-column>
-            <el-table-column
-              label="其他非生产时间原因"
-              align="center"
-              prop="otherNptReason"
-              :min-width="columnWidths.otherNptReason.width"
-              resizable
-            />
-
-            <el-table-column label="操作" align="center" fixed="right">
-              <template #default="scope">
-                <el-button
-                  link
-                  type="primary"
-                  @click="handleOpenForm(scope.row.id, 'edit')"
-                  v-hasPermi="['pms:iot-ry-daily-report:update']"
-                >
-                  编辑
-                </el-button>
-                <el-button
-                  link
-                  type="danger"
-                  @click="handleDelete(scope.row.id)"
-                  v-hasPermi="['pms:iot-ry-daily-report:delete']"
-                >
-                  删除
-                </el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-        <!-- 分页 -->
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
-        />
-      </ContentWrap>
-
-      <!-- 表单弹窗:添加/修改 -->
-      <ry-form
-        v-model:visible="visible"
-        type="edit"
-        ref="formRef"
-        :load-list="getList"
-        no-validate-status
-      />
-    </el-col>
-  </el-row>
-</template>
-
-<script setup lang="ts">
-import ryForm from './ry-form.vue'
-import { dateFormatter, dateFormatter2, rangeShortcuts } from '@/utils/formatTime'
-import { IotRyDailyReportApi, IotRyDailyReportVO } from '@/api/pms/iotrydailyreport'
-import { DICT_TYPE } from '@/utils/dict'
-import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue'
-
-import dayjs from 'dayjs'
-import quarterOfYear from 'dayjs/plugin/quarterOfYear'
-import { useDebounceFn } from '@vueuse/core'
-
-import { useUserStore } from '@/store/modules/user'
-import download from '@/utils/download'
-
-dayjs.extend(quarterOfYear)
-
-/** 瑞鹰日报 列表 */
-defineOptions({ name: 'IotRyDailyReport' })
-
-const message = useMessage() // 消息弹窗
-const { t } = useI18n() // 国际化
-
-// 添加 selectedRowData 响应式变量
-const selectedRowData = ref<Record<string, any> | null>(null)
-
-const rootDeptId = ref(useUserStore().getUser.deptId)
-
-const loading = ref(true) // 列表的加载中
-const list = ref<IotRyDailyReportVO[]>([]) // 列表的数据
-const total = ref(0) // 列表的总页数
-let queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: useUserStore().getUser.deptId,
-  contractName: undefined,
-  projectId: undefined,
-  taskName: undefined,
-  taskId: undefined,
-  projectClassification: '1',
-  relocationDays: undefined,
-  latestWellDoneTime: [],
-  currentDepth: undefined,
-  dailyFootage: undefined,
-  monthlyFootage: undefined,
-  annualFootage: undefined,
-  dailyPowerUsage: undefined,
-  monthlyPowerUsage: undefined,
-  dailyFuel: undefined,
-  monthlyFuel: undefined,
-  nonProductionTime: [],
-  nptReason: undefined,
-  constructionStartDate: [],
-  constructionEndDate: [],
-  productionStatus: undefined,
-  nextPlan: undefined,
-  rigStatus: undefined,
-  personnel: undefined,
-  mudDensity: undefined,
-  mudViscosity: undefined,
-  lateralLength: undefined,
-  wellInclination: undefined,
-  azimuth: undefined,
-  extProperty: undefined,
-  sort: undefined,
-  remark: undefined,
-  status: undefined,
-  processInstanceId: undefined,
-  auditStatus: undefined,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ],
-  nonProductFlag: 'N'
-})
-const queryFormRef = ref() // 搜索的表单
-
-// 表格引用
-const tableRef = ref()
-// 表格容器引用
-const tableContainerRef = ref()
-
-const columnWidths = ref<
-  Record<
-    string,
-    { label: string; prop: string; width: string; fn?: (row: IotRyDailyReportVO) => string }
-  >
->({
-  createTime: {
-    label: '日期',
-    prop: 'createTime',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) => dateFormatter2(null, null, row.createTime)
-  },
-  deptName: {
-    label: '施工队伍',
-    prop: 'deptName',
-    width: '120px'
-  },
-  contractName: {
-    label: '项目',
-    prop: 'contractName',
-    width: '120px'
-  },
-  taskName: {
-    label: '任务',
-    prop: 'taskName',
-    width: '120px'
-  },
-  equipmentType: {
-    label: '设备型号',
-    prop: 'equipmentType',
-    width: '120px'
-  },
-  rigStatus: {
-    label: '施工状态',
-    prop: 'rigStatus',
-    width: '120px'
-  },
-  latestWellDoneTime: {
-    label: '上井次完井时间',
-    prop: 'latestWellDoneTime',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) => dateFormatter2(null, null, row.latestWellDoneTime)
-  },
-  designWellDepth: {
-    label: '设计',
-    prop: 'designWellDepth',
-    width: '120px'
-  },
-  currentDepth: {
-    label: '当前',
-    prop: 'currentDepth',
-    width: '120px'
-  },
-  dailyFootage: {
-    label: '日',
-    prop: 'dailyFootage',
-    width: '120px'
-  },
-  monthlyFootage: {
-    label: '月',
-    prop: 'monthlyFootage',
-    width: '120px'
-  },
-  annualFootage: {
-    label: '年累计',
-    prop: 'annualFootage',
-    width: '120px'
-  },
-  totalConstructionWells: {
-    label: '总施工井数',
-    prop: 'totalConstructionWells',
-    width: '120px'
-  },
-  completedWells: {
-    label: '完工井数',
-    prop: 'completedWells',
-    width: '120px'
-  },
-  mudDensity: {
-    label: '密度(g/cm³)',
-    prop: 'mudDensity',
-    width: '120px'
-  },
-  mudViscosity: {
-    label: '粘度(S)',
-    prop: 'mudViscosity',
-    width: '120px'
-  },
-  dailyPowerUsage: {
-    label: '用电量(kWh)',
-    prop: 'dailyPowerUsage',
-    width: '120px'
-  },
-  dailyFuel: {
-    label: '油耗(升)',
-    prop: 'dailyFuel',
-    width: '120px'
-  },
-  constructionStartDate: {
-    label: '施工开始日期',
-    prop: 'constructionStartDate',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) => dateFormatter(null, null, row.constructionStartDate)
-  },
-  constructionEndDate: {
-    label: '施工结束日期',
-    prop: 'constructionEndDate',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) => dateFormatter(null, null, row.constructionEndDate)
-  },
-  lateralLength: {
-    label: '水平段长度(m)',
-    prop: 'lateralLength',
-    width: '120px'
-  },
-  wellInclination: {
-    label: '井斜(°)',
-    prop: 'wellInclination',
-    width: '120px'
-  },
-  azimuth: {
-    label: '方位(°)',
-    prop: 'azimuth',
-    width: '120px'
-  },
-  designWellStruct: {
-    label: '设计井身结构',
-    prop: 'designWellStruct',
-    width: '120px'
-  },
-  productionStatus: {
-    label: '生产动态',
-    prop: 'productionStatus',
-    width: '120px'
-  },
-  drillingWorkingTime: {
-    label: '进尺工作时间(H)',
-    prop: 'drillingWorkingTime',
-    width: '120px'
-  },
-  otherProductionTime: {
-    label: '其它生产时间(H)',
-    prop: 'otherProductionTime',
-    width: '120px'
-  },
-  accidentTime: {
-    label: '工程质量',
-    prop: 'accidentTime',
-    width: '120px'
-  },
-  repairTime: {
-    label: '设备故障',
-    prop: 'repairTime',
-    width: '120px'
-  },
-  selfStopTime: {
-    label: '设备保养',
-    prop: 'selfStopTime',
-    width: '120px'
-  },
-  complexityTime: {
-    label: '技术受限',
-    prop: 'complexityTime',
-    width: '120px'
-  },
-  relocationTime: {
-    label: '生产配合',
-    prop: 'relocationTime',
-    width: '120px'
-  },
-  rectificationTime: {
-    label: '生产组织',
-    prop: 'rectificationTime',
-    width: '120px'
-  },
-  waitingStopTime: {
-    label: '不可抗力',
-    prop: 'waitingStopTime',
-    width: '120px'
-  },
-  winterBreakTime: {
-    label: '待命',
-    prop: 'winterBreakTime',
-    width: '120px'
-  },
-  partyaDesign: {
-    label: '甲方设计',
-    prop: 'partyaDesign',
-    width: '120px'
-  },
-  partyaPrepare: {
-    label: '甲方资源',
-    prop: 'partyaPrepare',
-    width: '120px'
-  },
-  partyaResource: {
-    label: '甲方准备',
-    prop: 'partyaResource',
-    width: '120px'
-  },
-  otherNptTime: {
-    label: '其它非生产时间',
-    prop: 'otherNptTime',
-    width: '120px'
-  },
-  otherNptReason: {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    width: '120px'
-  },
-  nonProductionRate: {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    width: '120px',
-    fn: (row: any) => nonProductionRateFormatter(row)
-  }
-})
-
-const nonProductionRateFormatter = (row: any) => {
-  const nonProductionRate = row?.nonProductionRate ?? 0
-
-  return (nonProductionRate * 100).toFixed(2) + '%'
-}
-
-// 计算文本宽度
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = useDebounceFn(() => {
-  if (!tableContainerRef.value?.$el) return
-  Object.values(columnWidths.value).forEach(({ fn, prop, label, width }) => {
-    width =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(fn ? fn(v) : v[prop])
-              })
-            ]
-          ) + (label === '施工状态' ? 30 : 20),
-          200
-        ]
-      ) + 'px'
-
-    columnWidths.value[prop].width = width
-  })
-}, 1000)
-
-const nptFields = [
-  'accidentTime', // 工程质量
-  'repairTime', // 设备故障
-  'selfStopTime', // 设备保养
-  'complexityTime', // 技术受限
-  // 'relocationTime', // 生产配合
-  'rectificationTime', // 生产组织
-  'waitingStopTime', // 不可抗力
-  'winterBreakTime', // 待命
-  'partyaDesign', // 甲方设计
-  'partyaPrepare', // 甲方资源
-  'partyaResource', // 甲方准备
-  'otherNptTime' // 其它非生产时间
-]
-
-function checkTimeSumEquals24(row) {
-  const gasTime = parseFloat(row.drillingWorkingTime + '') || 0
-  // 对应你代码中的 waterTime
-  const waterTime = parseFloat(row.otherProductionTime + '') || 0
-
-  // 3. 计算所有非生产时间之和
-  const nonProdTime = nptFields.reduce((sum, field) => {
-    const val = parseFloat(row[field])
-    // 如果值是数字则累加,如果是 NaN 或 null/undefined 则加 0
-    return sum + (isNaN(val) ? 0 : val)
-  }, 0)
-
-  // 4. 计算总和:纯钻进 + 其他生产 + 所有非生产时间
-  const totalSum = gasTime + waterTime + nonProdTime
-
-  // 5. 返回是否等于 24(允许 0.01 的浮点数误差)
-  return Math.abs(totalSum - 24) < 0.01
-}
-
-// 单元格样式函数
-const cellStyle = ({
-  row,
-  column,
-  rowIndex,
-  columnIndex
-}: {
-  row: any
-  column: any
-  rowIndex: number
-  columnIndex: number
-}) => {
-  // 处理当日油耗预警
-  if (column.property === 'dailyFuel') {
-    if (shouldShowFuelWarning(row)) {
-      return {
-        color: 'red',
-        fontWeight: 'bold',
-        backgroundColor: '#fff5f5' // 可选:添加背景色突出显示
-      }
-    }
-  }
-
-  // 处理三个时间字段:当日注气时间、当日注水时间、非生产时间
-  const timeFields = ['drillingWorkingTime', 'otherProductionTime', ...nptFields]
-  if (timeFields.includes(column.property)) {
-    if (!checkTimeSumEquals24(row)) {
-      return {
-        color: 'orange',
-        fontWeight: 'bold'
-      }
-    }
-  }
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-// 可伸缩列配置
-
-/** 查询列表 */
-const getList = async () => {
-  loading.value = true
-  try {
-    const data = await IotRyDailyReportApi.getIotRyDailyReportPage(queryParams)
-    list.value = data.list
-    total.value = data.total
-    // 获取数据后计算列宽
-    nextTick(() => {
-      calculateColumnWidths()
-    })
-  } finally {
-    loading.value = false
-  }
-}
-
-// 在 cellStyle 函数附近添加油耗预警判断函数
-const shouldShowFuelWarning = (row: any): boolean => {
-  const dailyFuel = parseFloat(row.dailyFuel)
-  return !isNaN(dailyFuel) && dailyFuel > 9000
-}
-
-// 计算列宽度
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.pageNo = 1
-  getList()
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  queryParams.deptId = useUserStore().getUser.deptId
-  handleQuery()
-}
-
-const visible = ref(false)
-
-const formRef = ref()
-
-function handleOpenForm(id: number, type: 'edit' | 'readonly') {
-  if (formRef.value) {
-    formRef.value.handleOpenForm(id, type)
-  }
-}
-
-/** 添加/修改操作 */
-// const formRef = ref()
-// const openForm = (type: string, id?: number, row?: any) => {
-//   // 保存当前行数据
-//   if (row) {
-//     selectedRowData.value = {
-//       deptName: row.deptName,
-//       contractName: row.contractName,
-//       taskName: row.taskName,
-//       designWellDepth: row.designWellDepth,
-//       designWellStruct: row.designWellStruct,
-//       totalConstructionWells: row.totalConstructionWells,
-//       completedWells: row.completedWells
-//     }
-//   } else {
-//     selectedRowData.value = null
-//   }
-
-//   formRef.value.open(type, id)
-// }
-
-/** 删除按钮操作 */
-const handleDelete = async (id: number) => {
-  try {
-    // 删除的二次确认
-    await message.delConfirm()
-    // 发起删除
-    await IotRyDailyReportApi.deleteIotRyDailyReport(id)
-    message.success(t('common.delSuccess'))
-    // 刷新列表
-    await getList()
-  } catch {}
-}
-
-// 响应式变量存储选中的部门
-const selectedDept = ref<{ id: number; name: string }>()
-/** 处理部门被点击 */
-const handleDeptNodeClick = async (row) => {
-  // 记录选中的部门信息
-  selectedDept.value = { id: row.id, name: row.name }
-  // queryParams.deptId = row.id
-  await getList()
-}
-
-const exportLoading = ref(false)
-const handleExport = async () => {
-  const res = await IotRyDailyReportApi.exportIotRyDailyReport({
-    createTime: queryParams.createTime,
-    contractName: queryParams.contractName,
-    taskName: queryParams.taskName,
-    // pageNo: queryParams.pageNo,
-    // pageSize: queryParams.pageSize,
-    deptId: queryParams.deptId,
-    projectClassification: queryParams.projectClassification
-  })
-
-  download.excel(res, '瑞鹰钻井日报.xlsx')
-}
-// 声明 ResizeObserver 实例
-let resizeObserver: ResizeObserver | null = null
-
-const route = useRoute()
-
-/** 初始化 **/
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    nextTick(() => {
-      queryParams.deptId = Number(route.query.deptId) as any
-      queryParams.createTime = route.query.createTime as string[]
-      queryParams.nonProductFlag = route.query.nonProductFlag as string
-      handleQuery()
-    })
-  } else getList()
-  // 创建 ResizeObserver 监听表格容器尺寸变化
-  if (tableContainerRef.value?.$el) {
-    resizeObserver = new ResizeObserver(() => {
-      // 使用防抖避免频繁触发
-      clearTimeout((window as any).resizeTimer)
-      ;(window as any).resizeTimer = setTimeout(() => {
-        calculateColumnWidths()
-      }, 100)
-    })
-    resizeObserver.observe(tableContainerRef.value.$el)
-  }
-})
-
-onUnmounted(() => {
-  // 清除 ResizeObserver
-  if (resizeObserver && tableContainerRef.value?.$el) {
-    resizeObserver.unobserve(tableContainerRef.value.$el)
-    resizeObserver = null
-  }
-
-  // 清除定时器
-  if ((window as any).resizeTimer) {
-    clearTimeout((window as any).resizeTimer)
-  }
-})
-
-// 监听列表数据变化重新计算列宽
-watch(
-  list,
-  () => {
-    nextTick(calculateColumnWidths)
-  },
-  { deep: true }
-)
-</script>
-
-<style scoped>
-/* 表格容器样式,确保水平滚动 */
-.table-container {
-  width: 100%;
-  overflow-x: auto;
-}
-
-/* 确保表格单元格内容不换行 */
-
-/* :deep(.el-table .cell) {
-  white-space: nowrap;
-} */
-
-/* 确保表格列标题不换行 */
-
-/* :deep(.el-table th > .cell) {
-  white-space: nowrap;
-} */
-
-/* 调整表格最小宽度,确保内容完全显示 */
-:deep(.el-table) {
-  min-width: 100%;
-}
-
-/* 强制显示所有内容,防止省略号 */
-
-/* :deep(.el-table td.el-table__cell),
-:deep(.el-table th.el-table__cell) {
-  overflow: visible !important;
-} */
-
-/* :deep(.el-table .cell) {
-  overflow: visible !important;
-  text-overflow: clip !important;
-} */
-
-/* 设计井身结构文本样式 - 多行显示并添加省略号 */
-.design-well-struct-text {
-  display: -webkit-box;
-  max-height: 3em; /* 两行文本的高度 */
-  overflow: hidden;
-  line-height: 1.5;
-  text-overflow: ellipsis;
-  -webkit-box-orient: vertical;
-  -webkit-line-clamp: 2;
-}
-
-/* 确保设计井身结构列不参与自动调整 */
-:deep(.el-table__header-wrapper .el-table__cell.fixed-width),
-:deep(.el-table__body-wrapper .el-table__cell.fixed-width) {
-  flex-shrink: 0;
-  flex-grow: 0;
-}
-
-/* 颜色说明区域样式 */
-.color-legend {
-  display: flex;
-  padding: 12px 16px;
-  background-color: #f8f9fa;
-  border-left: 4px solid #e6f7ff;
-  border-radius: 4px;
-  flex-direction: column;
-  gap: 8px;
-}
-
-.legend-item {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  font-size: 14px;
-}
-
-.color-indicator {
-  display: inline-block;
-  width: 12px;
-  height: 12px;
-  border-radius: 50%;
-}
-
-.color-indicator.red {
-  background-color: red;
-}
-
-.color-indicator.orange {
-  background-color: orange;
-}
-</style>
-
-<style>
-/* 设计井身结构 tooltip 样式 - 保留换行符 */
-.design-well-struct-tooltip {
-  max-width: 500px;
-  line-height: 1.5;
-  white-space: pre-line;
-}
-.color-indicator.red {
-  background-color: red;
-}
-
-/* 当日油耗预警样式 */
-.fuel-warning {
-  color: red !important;
-  font-weight: bold;
-  animation: pulse 1.5s infinite;
-}
-
-/* 确保表格中的预警样式不被覆盖 */
-:deep(.el-table .cell .fuel-warning) {
-  color: red !important;
-  font-weight: bold !important;
-}
-</style>

+ 2 - 2
src/views/pms/iotrydailyreport/ry-form.vue

@@ -909,8 +909,8 @@ const inputCurrentDepth = useDebounceFn(function inputCurrentDepth() {
             show-word-limit
             resize="none"
             :maxlength="1000"
-            placeholder="请输入当日施工简报"
-            :disabled="!isApproval"
+            placeholder="请输入下步计划"
+            :disabled="isMainFieldDisabled"
           />
         </el-form-item>
 

+ 1 - 7
src/views/pms/iotrydailyreport/ry-table.vue

@@ -253,13 +253,7 @@ function handleCurrentChange(val: number) {
             >
               <template #default="{ row }">
                 <div v-if="row.reportDetails && row.reportDetails.length > 0" class="py-2">
-                  <el-popover
-                    placement="right"
-                    trigger="hover"
-                    width="320"
-                    popper-class="!p-0"
-                    :disabled="row.reportDetails.length <= 1"
-                  >
+                  <el-popover placement="right" trigger="hover" width="320" popper-class="!p-0">
                     <template #reference>
                       <el-badge :value="row.reportDetails.length" type="primary" class="max-w-full">
                         <div

+ 1 - 7
src/views/pms/iotrydailyreport/ry-xj-table.vue

@@ -314,13 +314,7 @@ function handleCurrentChange(val: number) {
             >
               <template #default="{ row }">
                 <div v-if="row.reportDetails && row.reportDetails.length > 0" class="py-2">
-                  <el-popover
-                    placement="right"
-                    trigger="hover"
-                    width="320"
-                    popper-class="p-0!"
-                    :disabled="row.reportDetails.length <= 1"
-                  >
+                  <el-popover placement="right" trigger="hover" width="320" popper-class="p-0!">
                     <template #reference>
                       <el-badge :value="row.reportDetails.length" type="primary" class="max-w-full">
                         <div

+ 128 - 73
src/views/pms/iotrydailyreport/summary.vue

@@ -257,7 +257,7 @@ const chartData = ref<Record<string, number[]>>({
   cumulativeFootage: [],
   cumulativePowerConsumption: [],
   transitTime: [],
-    utilizationRate: []
+  utilizationRate: []
 })
 
 let chartLoading = ref(false)
@@ -303,96 +303,151 @@ onUnmounted(() => {
   window.removeEventListener('resize', resizer)
 })
 
-const render = () => {
-  if (!chartRef.value) return
-
-  chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })
-
-  window.addEventListener('resize', resizer)
-
-  const values: number[] = []
-
-  for (const [_name, key] of legend.value) {
-    values.push(...(chartData.value[key] || []))
+const selectedLegends = ref<Record<string, boolean>>({})
+const intervalArr = ref<number[]>([])
+const maxInterval = ref(0)
+const minInterval = ref(0)
+
+const calcIntervals = () => {
+  let maxVal = -Infinity
+  let minVal = Infinity
+  let hasData = false
+
+  for (const [name, key] of legend.value) {
+    if (selectedLegends.value[name] !== false) {
+      const dataset = chartData.value[key] || []
+      if (dataset.length > 0) {
+        hasData = true
+        for (const val of dataset) {
+          if (val > maxVal) maxVal = val
+          if (val < minVal) minVal = val
+        }
+      }
+    }
   }
 
-  const maxVal = values.length === 0 ? 10000 : Math.max(...values)
-  const minVal = values.length === 0 ? 0 : Math.min(...values) > 0 ? 0 : Math.min(...values)
+  if (!hasData) {
+    maxVal = 10000
+    minVal = 0
+  } else {
+    minVal = minVal > 0 ? 0 : minVal
+  }
 
   const maxDigits = (Math.floor(maxVal) + '').length
   const minDigits = minVal === 0 ? 0 : (Math.floor(Math.abs(minVal)) + '').length
-
   const interval = Math.max(maxDigits, minDigits)
 
-  const maxInterval = interval
-  const minInterval = minDigits
+  maxInterval.value = interval
+  minInterval.value = minDigits
 
-  const intervalArr = [0]
+  const arr = [0]
   for (let i = 1; i <= interval; i++) {
-    intervalArr.push(Math.pow(10, i))
+    arr.push(Math.pow(10, i))
   }
+  intervalArr.value = arr
+}
 
-  chart.setOption({
-    tooltip: {
-      trigger: 'axis',
-      axisPointer: {
-        type: 'line'
-      },
-      formatter: (params) => {
-        let d = `${params[0].axisValueLabel}<br>`
-        let item = params.map((el) => {
-          return `<div class="flex items-center justify-between mt-1 gap-1">
-            <span>${el.marker} ${el.seriesName}</span>
-            <span>${chartData.value[legend.value[el.componentIndex][1]][el.dataIndex].toFixed(2)} ${el.seriesName.split(' ')[1]}</span>
-          </div>`
-        })
+const mapDataValue = (value: number) => {
+  if (value === 0) return 0
 
-        return d + item.join('')
-      }
-    },
-    legend: {
-      data: legend.value.map(([name]) => name),
-      show: true
-    },
-    xAxis: {
-      type: 'category',
-      data: xAxisData.value
-    },
-    yAxis: {
-      type: 'value',
-      min: -minInterval,
-      max: maxInterval,
-      interval: 1,
-      axisLabel: {
-        formatter: (v) => {
-          const num = v === 0 ? 0 : v > 0 ? Math.pow(10, v) : -Math.pow(10, -v)
-
-          return num.toLocaleString()
-        }
-      }
-    },
-    series: legend.value.map(([name, key]) => ({
-      name,
-      type: 'line',
-      smooth: true,
-      showSymbol: true,
-      data: chartData.value[key].map((value) => {
-        // return value
-        if (value === 0) return 0
+  const isPositive = value > 0
+  const absItem = Math.abs(value)
+
+  if (!intervalArr.value.length) return value
+
+  const min_value = Math.max(...intervalArr.value.filter((v) => v <= absItem))
+  const min_index = intervalArr.value.findIndex((v) => v === min_value)
 
-        const isPositive = value > 0
-        const absItem = Math.abs(value)
+  const denominator =
+    min_index < intervalArr.value.length - 1
+      ? intervalArr.value[min_index + 1] - intervalArr.value[min_index]
+      : intervalArr.value[min_index] || 1
 
-        const min_value = Math.max(...intervalArr.filter((v) => v <= absItem))
-        const min_index = intervalArr.findIndex((v) => v === min_value)
+  const new_value = (absItem - min_value) / denominator + min_index
 
-        const new_value =
-          (absItem - min_value) / (intervalArr[min_index + 1] - intervalArr[min_index]) + min_index
+  return isPositive ? new_value : -new_value
+}
+
+const getSeries = () => {
+  return legend.value.map(([name, key]) => ({
+    name,
+    type: 'line',
+    smooth: true,
+    showSymbol: true,
+    data: chartData.value[key].map((value) => mapDataValue(value))
+  }))
+}
+
+const render = () => {
+  if (!chartRef.value) return
 
-        return isPositive ? new_value : -new_value
+  if (!chart) {
+    chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })
+    window.addEventListener('resize', resizer)
+
+    chart.on('legendselectchanged', (params: any) => {
+      selectedLegends.value = params.selected
+
+      calcIntervals()
+
+      chart?.setOption({
+        yAxis: {
+          min: -minInterval.value,
+          max: maxInterval.value
+        },
+        series: getSeries()
       })
-    }))
+    })
+  }
+
+  legend.value.forEach(([name]) => {
+    selectedLegends.value[name] = true
   })
+
+  calcIntervals()
+
+  chart.setOption(
+    {
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: { type: 'line' },
+        formatter: (params: any) => {
+          let d = `${params[0].axisValueLabel}<br>`
+          let item = params.map((el: any) => {
+            const realValue = chartData.value[legend.value[el.componentIndex][1]][el.dataIndex]
+            return `<div class="flex items-center justify-between mt-1 gap-1">
+            <span>${el.marker} ${el.seriesName}</span>
+            <span>${realValue.toFixed(2)} ${el.seriesName.split(' ')[1] || ''}</span>
+          </div>`
+          })
+          return d + item.join('')
+        }
+      },
+      legend: {
+        data: legend.value.map(([name]) => name),
+        selected: selectedLegends.value,
+        show: true
+      },
+      xAxis: {
+        type: 'category',
+        data: xAxisData.value
+      },
+      yAxis: {
+        type: 'value',
+        min: -minInterval.value,
+        max: maxInterval.value,
+        interval: 1,
+        axisLabel: {
+          formatter: (v: number) => {
+            const num = v === 0 ? 0 : v > 0 ? Math.pow(10, v) : -Math.pow(10, -v)
+            return num.toLocaleString()
+          }
+        }
+      },
+      series: getSeries()
+    },
+    true
+  )
 }
 
 const handleDeptNodeClick = (node: any) => {

+ 0 - 723
src/views/pms/iotrydailyreport/xapproval1.vue

@@ -1,723 +0,0 @@
-<script lang="ts" setup>
-import { rangeShortcuts } from '@/utils/formatTime'
-import { useDebounceFn } from '@vueuse/core'
-import dayjs from 'dayjs'
-import { DICT_TYPE } from '@/utils/dict'
-import { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
-import { useUserStore } from '@/store/modules/user'
-import { IotRyDailyReportApi } from '@/api/pms/iotrydailyreport'
-import ryXjForm from './ry-xj-form.vue'
-
-interface List {
-  id: number
-  deptId: number
-  projectId: number
-  taskId: number
-  createTime: number
-  deptName: string
-  contractName: string
-  taskName: string
-  repairStatus: string
-  totalConstructionWells: number
-  completedWells: number
-  technique: string
-  wellCategory: string
-  designWellDepth: number
-  casingPipeSize: string
-  wellControlLevel: string
-  dailyPowerUsage: number
-  dailyFuel: number
-  constructionStartDate: number
-  constructionEndDate: number
-  currentOperation: string
-  nextPlan: string
-  transitTime: number
-  ratedProductionTime: number
-  productionTime: number
-  accidentTime: number
-  repairTime: number
-  selfStopTime: number
-  complexityTime: number
-  relocationTime: number
-  rectificationTime: number
-  waitingStopTime: number
-  winterBreakTime: number
-  partyaDesign: number
-  partyaPrepare: number
-  partyaResource: number
-  otherNptTime: number
-  otherNptReason: string
-  ryNptReason: string
-  productionStatus: string
-  totalStaffNum: number
-  onDutyStaffNum: number
-  leaveStaffNum: number
-  status: number
-  auditStatus: number
-  opinion: string
-  offDutyStaffNum: number
-  remark: string
-  nonProductionRate: number
-}
-
-interface Column {
-  prop?: keyof List
-  label: string
-  'min-width'?: string
-  isTag?: boolean
-  fixed?: 'left' | 'right'
-  formatter?: (row: List) => any
-  children?: Column[]
-  dictType?: string
-}
-
-const columns = ref<Column[]>([
-  {
-    label: '日期',
-    prop: 'createTime',
-    'min-width': '120px',
-    formatter: (row: List) => dayjs(row.createTime).format('YYYY-MM-DD'),
-    fixed: 'left'
-  },
-  {
-    label: '施工队伍',
-    prop: 'deptName',
-    'min-width': '120px',
-    fixed: 'left'
-  },
-
-  {
-    label: '任务',
-    prop: 'taskName',
-    'min-width': '120px',
-    fixed: 'left'
-  },
-  {
-    label: '施工状态',
-    prop: 'repairStatus',
-    'min-width': '120px',
-    isTag: true,
-    dictType: DICT_TYPE.PMS_PROJECT_TASK_RY_REPAIR_SCHEDULE,
-    fixed: 'left'
-  },
-  {
-    label: '审批状态',
-    prop: 'auditStatus',
-    'min-width': '120px',
-    isTag: true,
-    formatter: (row: List) => {
-      switch (row.auditStatus) {
-        case 0:
-          return '待提交'
-        case 10:
-          return '待审批'
-        case 20:
-          return '审批通过'
-        case 30:
-          return '审批拒绝'
-        default:
-          return ''
-      }
-    }
-  },
-  {
-    label: '总施工井数',
-    prop: 'totalConstructionWells',
-    'min-width': '120px'
-  },
-  {
-    label: '完工井数',
-    prop: 'completedWells',
-    'min-width': '120px'
-  },
-  {
-    label: '施工工艺',
-    prop: 'technique',
-    'min-width': '120px',
-    isTag: true,
-    dictType: DICT_TYPE.PMS_PROJECT_RY_TECHNOLOGY
-  },
-  {
-    label: '井别',
-    prop: 'wellCategory',
-    'min-width': '120px'
-  },
-  {
-    label: '井深(m)',
-    prop: 'designWellDepth',
-    'min-width': '120px'
-  },
-  {
-    label: '套生段产管尺寸(mm)',
-    prop: 'casingPipeSize',
-    'min-width': '120px'
-  },
-  {
-    label: '井控级别',
-    prop: 'wellControlLevel',
-    'min-width': '120px'
-  },
-  {
-    label: '当日',
-    children: [
-      {
-        label: '用电量(kWh)',
-        prop: 'dailyPowerUsage',
-        'min-width': '120px'
-      },
-      {
-        label: '油耗(升)',
-        prop: 'dailyFuel',
-        'min-width': '120px'
-      }
-    ]
-  },
-  // {
-  //   label: '施工开始日期',
-  //   prop: 'constructionStartDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionStartDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  // {
-  //   label: '施工结束日期',
-  //   prop: 'constructionEndDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionEndDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  {
-    label: '目前工序',
-    prop: 'currentOperation',
-    'min-width': '120px'
-  },
-  {
-    label: '下步工序',
-    prop: 'nextPlan',
-    'min-width': '120px'
-  },
-  {
-    label: '运行时效',
-    prop: 'transitTime',
-    'min-width': '120px',
-    formatter: (row: List) => (row.transitTime * 100).toFixed(2) + '%'
-  },
-  {
-    label: '额定生产时间(H)',
-    prop: 'ratedProductionTime',
-    'min-width': '120px'
-  },
-  {
-    label: '生产时间(H)',
-    prop: 'productionTime',
-    'min-width': '120px'
-  },
-  {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    'min-width': '120px',
-    formatter: (row: List) => {
-      const nonProductionRate = row?.nonProductionRate ?? 0
-
-      return (nonProductionRate * 100).toFixed(2) + '%'
-    }
-  },
-  {
-    label: '非生产时间',
-    children: [
-      {
-        label: '工程质量',
-        prop: 'accidentTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备故障',
-        prop: 'repairTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备保养',
-        prop: 'selfStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '技术受限',
-        prop: 'complexityTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产配合',
-        prop: 'relocationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产组织',
-        prop: 'rectificationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '不可抗力',
-        prop: 'waitingStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '待命',
-        prop: 'winterBreakTime',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方设计',
-        prop: 'partyaDesign',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方准备',
-        prop: 'partyaPrepare',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方资源',
-        prop: 'partyaResource',
-        'min-width': '120px'
-      },
-      {
-        label: '其它非生产时间',
-        prop: 'otherNptTime',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    'min-width': '120px'
-  },
-
-  {
-    label: '生产动态',
-    prop: 'productionStatus',
-    'min-width': '120px'
-  },
-  {
-    label: '项目',
-    prop: 'contractName',
-    'min-width': '120px'
-  },
-  {
-    label: '全员数量',
-    prop: 'totalStaffNum',
-    'min-width': '120px'
-  },
-  {
-    label: '在岗人数',
-    prop: 'onDutyStaffNum',
-    'min-width': '120px',
-    formatter: (row: List) => (Number(row.totalStaffNum) || 0) - (Number(row.offDutyStaffNum) || 0)
-  },
-  {
-    label: '休假人员数量',
-    prop: 'leaveStaffNum',
-    'min-width': '120px'
-  }
-])
-
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = (colums: Column[]) => {
-  for (const col of colums) {
-    let { formatter, prop, label, 'min-width': minWidth, isTag, children } = col
-
-    if (children && children.length > 0) {
-      calculateColumnWidths(children)
-      continue
-    }
-
-    minWidth =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(formatter ? formatter(v) : v[prop!])
-              })
-            ]
-          ) + (isTag ? 40 : 20),
-          200
-        ]
-      ) + 'px'
-
-    col['min-width'] = minWidth
-  }
-}
-
-const nptFields = [
-  'accidentTime', // 工程质量
-  'repairTime', // 设备故障
-  'selfStopTime', // 设备保养
-  'complexityTime', // 技术受限
-  'relocationTime', // 生产配合
-  'rectificationTime', // 生产组织
-  'waitingStopTime', // 不可抗力
-  'winterBreakTime', // 待命
-  'partyaDesign', // 甲方设计
-  'partyaPrepare', // 甲方资源
-  'partyaResource', // 甲方准备
-  'otherNptTime' // 其它非生产时间
-]
-
-function checkTimeSumEquals24(row: List) {
-  const ratedProductionTime = parseFloat(row.ratedProductionTime + '') || 0
-  const productionTime = parseFloat(row.productionTime + '') || 0
-
-  // 3. 计算所有非生产时间细项的总和
-  const totalNonProductionTime = nptFields.reduce((sum, field) => {
-    // 获取字段值,转为浮点数,如果是 NaN 则视为 0
-    const val = parseFloat(row[field])
-    return sum + (isNaN(val) ? 0 : val)
-  }, 0)
-
-  // 4. 计算实际总投入时间:生产时间 + 所有非生产时间之和
-  const currentSum = productionTime + totalNonProductionTime
-
-  // 5. 校验逻辑:判断 (生产时间 + 非生产时间总和) 是否等于 额定生产时间
-  // 允许 0.01 的浮点数误差
-  return Math.abs(currentSum - ratedProductionTime) < 0.01
-}
-
-function cellStyle(data: {
-  row: List
-  column: TableColumnCtx<List>
-  rowIndex: number
-  columnIndex: number
-}) {
-  const { row, column } = data
-
-  if (column.property === 'transitTime') {
-    const originalValue = Number(row.transitTime ?? 0)
-
-    if (originalValue >= 1)
-      return {
-        color: 'red',
-        fontWeight: 'bold'
-      }
-  }
-
-  if (column.property === 'dailyFuel') {
-    const originalValue = row.dailyFuel ?? 0
-
-    if (originalValue > 3500)
-      return {
-        color: 'blue',
-        fontWeight: 'bold'
-      }
-  }
-
-  const timeFields = ['ratedProductionTime', 'productionTime', ...nptFields]
-  if (timeFields.includes(column.property)) {
-    if (!checkTimeSumEquals24(row)) {
-      return {
-        color: 'orange',
-        fontWeight: 'bold'
-      }
-    }
-  }
-
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-const id = useUserStore().getUser.deptId
-
-const deptId = id
-
-interface Query {
-  pageNo: number
-  pageSize: number
-  deptId: number
-  contractName?: string
-  taskName?: string
-  createTime: string[]
-  projectClassification: '1' | '2'
-}
-
-const query = ref<Query>({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: id,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ],
-  projectClassification: '2'
-})
-
-function handleSizeChange(val: number) {
-  query.value.pageSize = val
-  handleQuery()
-}
-
-function handleCurrentChange(val: number) {
-  query.value.pageNo = val
-  loadList()
-}
-
-const loading = ref(false)
-
-const list = ref<List[]>([])
-const total = ref(0)
-
-const loadList = useDebounceFn(async function () {
-  loading.value = true
-  try {
-    const data = await IotRyDailyReportApi.getIotRyDailyReportPage(query.value)
-
-    data.list.forEach((v) => {
-      const { ratedProductionTime = 0, productionTime = 0 } = v
-
-      v.transitTime = ratedProductionTime === 0 ? 0 : productionTime / ratedProductionTime
-    })
-
-    list.value = data.list
-    total.value = data.total
-
-    nextTick(() => {
-      calculateColumnWidths(columns.value)
-    })
-  } finally {
-    loading.value = false
-  }
-}, 500)
-
-function handleQuery(setPage = true) {
-  if (setPage) {
-    query.value.pageNo = 1
-  }
-  loadList()
-}
-
-function resetQuery() {
-  query.value = {
-    pageNo: 1,
-    pageSize: 10,
-    deptId: 157,
-    contractName: '',
-    taskName: '',
-    createTime: [
-      ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-    ],
-    projectClassification: '2'
-  }
-  handleQuery()
-}
-
-watch(
-  [
-    () => query.value.createTime,
-    () => query.value.deptId,
-    () => query.value.taskName,
-    () => query.value.contractName
-  ],
-  () => {
-    handleQuery()
-  },
-  { immediate: true }
-)
-
-const visible = ref(false)
-
-const formRef = ref()
-
-function handleOpenForm(id: number, type: 'edit' | 'readonly') {
-  if (formRef.value) {
-    formRef.value.handleOpenForm(id, type)
-  }
-}
-
-const route = useRoute()
-
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    handleOpenForm(Number(route.query.id), 'edit')
-  }
-})
-</script>
-
-<template>
-  <div
-    class="h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
-  >
-    <div class="grid grid-cols-[15%_1fr] gap-4 h-full">
-      <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg h-full">
-        <DeptTreeSelect :top-id="158" :deptId="deptId" v-model="query.deptId" />
-      </div>
-      <div class="grid grid-rows-[62px_1fr] h-full gap-4">
-        <el-form
-          size="default"
-          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
-        >
-          <div class="flex items-center gap-8">
-            <el-form-item label="项目">
-              <el-input
-                v-model="query.contractName"
-                placeholder="请输入项目"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="任务">
-              <el-input
-                v-model="query.taskName"
-                placeholder="请输入任务"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="创建时间">
-              <el-date-picker
-                v-model="query.createTime"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                type="daterange"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-                :shortcuts="rangeShortcuts"
-                class="!w-220px"
-                :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              />
-            </el-form-item>
-          </div>
-          <el-form-item>
-            <el-button type="primary" @click="handleQuery()">
-              <Icon icon="ep:search" class="mr-5px" /> 搜索
-            </el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
-          </el-form-item>
-        </el-form>
-        <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg p-4 flex flex-col">
-          <div class="flex-1 relative">
-            <el-auto-resizer class="absolute">
-              <template #default="{ width, height }">
-                <el-table
-                  :data="list"
-                  v-loading="loading"
-                  stripe
-                  class="absolute"
-                  :max-height="height"
-                  show-overflow-tooltip
-                  :width="width"
-                  :cell-style="cellStyle"
-                  border
-                >
-                  <DailyTableColumn :columns="columns" />
-                  <el-table-column label="操作" width="120px" align="center" fixed="right">
-                    <template #default="{ row }">
-                      <el-button
-                        link
-                        type="success"
-                        @click="handleOpenForm(row.id, 'readonly')"
-                        v-hasPermi="['pms:iot-ry-daily-report:query']"
-                      >
-                        查看
-                      </el-button>
-                      <el-button
-                        v-show="row.auditStatus === 10"
-                        link
-                        type="primary"
-                        @click="handleOpenForm(row.id, 'edit')"
-                        v-hasPermi="['pms:iot-ry-daily-report:update']"
-                      >
-                        审批
-                      </el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </template>
-            </el-auto-resizer>
-          </div>
-          <div class="h-10 mt-4 flex items-center justify-end">
-            <el-pagination
-              size="default"
-              v-show="total > 0"
-              v-model:current-page="query.pageNo"
-              v-model:page-size="query.pageSize"
-              :background="true"
-              :page-sizes="[10, 20, 30, 50, 100]"
-              :total="total"
-              layout="total, sizes, prev, pager, next, jumper"
-              @size-change="handleSizeChange"
-              @current-change="handleCurrentChange"
-            />
-          </div>
-        </div>
-      </div>
-    </div>
-    <ry-xj-form v-model:visible="visible" type="approval" ref="formRef" :load-list="loadList" />
-  </div>
-</template>
-
-<style scoped>
-:deep(.el-form-item) {
-  margin-bottom: 0;
-}
-
-:deep(.el-table) {
-  border-top-right-radius: 8px;
-  border-top-left-radius: 8px;
-
-  .el-table__cell {
-    height: 40px;
-  }
-
-  .el-table__header-wrapper {
-    .el-table__cell {
-      background: var(--el-fill-color-light);
-    }
-  }
-}
-
-:deep(.warning-input) {
-  .el-input__inner {
-    color: red !important;
-    -webkit-text-fill-color: red !important;
-  }
-}
-
-:deep(.blue-input) {
-  .el-input__inner {
-    color: blue !important;
-    -webkit-text-fill-color: blue !important;
-  }
-}
-
-:deep(.orange-input) {
-  .el-input__inner {
-    color: orange !important;
-    -webkit-text-fill-color: orange !important;
-  }
-}
-
-:deep(.el-input-number) {
-  width: 100%;
-}
-
-:deep(.el-input-number__decrease) {
-  display: none !important;
-}
-
-:deep(.el-input-number__increase) {
-  display: none !important;
-}
-</style>

+ 0 - 730
src/views/pms/iotrydailyreport/xfill1.vue

@@ -1,730 +0,0 @@
-<script lang="ts" setup>
-import { rangeShortcuts } from '@/utils/formatTime'
-import { useDebounceFn } from '@vueuse/core'
-import dayjs from 'dayjs'
-import { DICT_TYPE } from '@/utils/dict'
-import { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
-import { useUserStore } from '@/store/modules/user'
-import { IotRyDailyReportApi } from '@/api/pms/iotrydailyreport'
-import ryXjForm from './ry-xj-form.vue'
-
-interface List {
-  id: number
-  deptId: number
-  projectId: number
-  taskId: number
-  createTime: number
-  deptName: string
-  contractName: string
-  taskName: string
-  repairStatus: string
-  totalConstructionWells: number
-  completedWells: number
-  technique: string
-  wellCategory: string
-  designWellDepth: number
-  casingPipeSize: string
-  wellControlLevel: string
-  dailyPowerUsage: number
-  dailyFuel: number
-  constructionStartDate: number
-  constructionEndDate: number
-  currentOperation: string
-  nextPlan: string
-  transitTime: number
-  ratedProductionTime: number
-  productionTime: number
-  accidentTime: number
-  repairTime: number
-  selfStopTime: number
-  complexityTime: number
-  relocationTime: number
-  rectificationTime: number
-  waitingStopTime: number
-  winterBreakTime: number
-  partyaDesign: number
-  partyaPrepare: number
-  partyaResource: number
-  otherNptTime: number
-  otherNptReason: string
-  ryNptReason: string
-  productionStatus: string
-  totalStaffNum: number
-  onDutyStaffNum: number
-  leaveStaffNum: number
-  status: number
-  auditStatus: number
-  opinion: string
-  offDutyStaffNum: number
-  remark: string
-  nonProductionRate: number
-}
-
-interface Column {
-  prop?: keyof List
-  label: string
-  'min-width'?: string
-  isTag?: boolean
-  fixed?: 'left' | 'right'
-  formatter?: (row: List) => any
-  children?: Column[]
-  dictType?: string
-}
-
-const columns = ref<Column[]>([
-  {
-    label: '日期',
-    prop: 'createTime',
-    'min-width': '120px',
-    formatter: (row: List) => dayjs(row.createTime).format('YYYY-MM-DD'),
-    fixed: 'left'
-  },
-  {
-    label: '施工队伍',
-    prop: 'deptName',
-    'min-width': '120px',
-    fixed: 'left'
-  },
-
-  {
-    label: '任务',
-    prop: 'taskName',
-    'min-width': '120px',
-    fixed: 'left'
-  },
-  {
-    label: '施工状态',
-    prop: 'repairStatus',
-    'min-width': '120px',
-    isTag: true,
-    dictType: DICT_TYPE.PMS_PROJECT_TASK_RY_REPAIR_SCHEDULE,
-    fixed: 'left'
-  },
-  {
-    label: '审批状态',
-    prop: 'auditStatus',
-    'min-width': '120px',
-    isTag: true,
-    formatter: (row: List) => {
-      switch (row.auditStatus) {
-        case 0:
-          return '待提交'
-        case 10:
-          return '待审批'
-        case 20:
-          return '审批通过'
-        case 30:
-          return '审批拒绝'
-        default:
-          return ''
-      }
-    }
-  },
-  {
-    label: '总施工井数',
-    prop: 'totalConstructionWells',
-    'min-width': '120px'
-  },
-  {
-    label: '完工井数',
-    prop: 'completedWells',
-    'min-width': '120px'
-  },
-  {
-    label: '施工工艺',
-    prop: 'technique',
-    'min-width': '120px',
-    isTag: true,
-    dictType: DICT_TYPE.PMS_PROJECT_RY_TECHNOLOGY
-  },
-  {
-    label: '井别',
-    prop: 'wellCategory',
-    'min-width': '120px'
-  },
-  {
-    label: '井深(m)',
-    prop: 'designWellDepth',
-    'min-width': '120px'
-  },
-  {
-    label: '套生段产管尺寸(mm)',
-    prop: 'casingPipeSize',
-    'min-width': '120px'
-  },
-  {
-    label: '井控级别',
-    prop: 'wellControlLevel',
-    'min-width': '120px'
-  },
-  {
-    label: '当日',
-    children: [
-      {
-        label: '用电量(kWh)',
-        prop: 'dailyPowerUsage',
-        'min-width': '120px'
-      },
-      {
-        label: '油耗(升)',
-        prop: 'dailyFuel',
-        'min-width': '120px'
-      }
-    ]
-  },
-  // {
-  //   label: '施工开始日期',
-  //   prop: 'constructionStartDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionStartDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  // {
-  //   label: '施工结束日期',
-  //   prop: 'constructionEndDate',
-  //   'min-width': '120px',
-  //   formatter: (row: List) => dayjs(row.constructionEndDate).format('YYYY-MM-DD HH:mm:ss')
-  // },
-  {
-    label: '目前工序',
-    prop: 'currentOperation',
-    'min-width': '120px'
-  },
-  {
-    label: '下步工序',
-    prop: 'nextPlan',
-    'min-width': '120px'
-  },
-  {
-    label: '运行时效',
-    prop: 'transitTime',
-    'min-width': '120px',
-    formatter: (row: List) => (row.transitTime * 100).toFixed(2) + '%'
-  },
-  {
-    label: '额定生产时间(H)',
-    prop: 'ratedProductionTime',
-    'min-width': '120px'
-  },
-  {
-    label: '生产时间(H)',
-    prop: 'productionTime',
-    'min-width': '120px'
-  },
-  {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    'min-width': '120px',
-    formatter: (row: List) => {
-      const nonProductionRate = row?.nonProductionRate ?? 0
-
-      return (nonProductionRate * 100).toFixed(2) + '%'
-    }
-  },
-  {
-    label: '非生产时间',
-    children: [
-      {
-        label: '工程质量',
-        prop: 'accidentTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备故障',
-        prop: 'repairTime',
-        'min-width': '120px'
-      },
-      {
-        label: '设备保养',
-        prop: 'selfStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '技术受限',
-        prop: 'complexityTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产配合',
-        prop: 'relocationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '生产组织',
-        prop: 'rectificationTime',
-        'min-width': '120px'
-      },
-      {
-        label: '不可抗力',
-        prop: 'waitingStopTime',
-        'min-width': '120px'
-      },
-      {
-        label: '待命',
-        prop: 'winterBreakTime',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方设计',
-        prop: 'partyaDesign',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方准备',
-        prop: 'partyaPrepare',
-        'min-width': '120px'
-      },
-      {
-        label: '甲方资源',
-        prop: 'partyaResource',
-        'min-width': '120px'
-      },
-      {
-        label: '其它非生产时间',
-        prop: 'otherNptTime',
-        'min-width': '120px'
-      }
-    ]
-  },
-  {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    'min-width': '120px'
-  },
-
-  // {
-  //   label: '非生产时间原因',
-  //   prop: 'ryNptReason',
-  //   'min-width': '120px',
-  //   isTag: true,
-  //   dictType: DICT_TYPE.PMS_PROJECT_RY_NPT_REASON
-  // },
-  {
-    label: '生产动态',
-    prop: 'productionStatus',
-    'min-width': '120px'
-  },
-  {
-    label: '项目',
-    prop: 'contractName',
-    'min-width': '120px'
-  },
-  {
-    label: '全员数量',
-    prop: 'totalStaffNum',
-    'min-width': '120px'
-  },
-  {
-    label: '在岗人数',
-    prop: 'onDutyStaffNum',
-    'min-width': '120px',
-    formatter: (row: List) => (Number(row.totalStaffNum) || 0) - (Number(row.offDutyStaffNum) || 0)
-  },
-  {
-    label: '休假人员数量',
-    prop: 'leaveStaffNum',
-    'min-width': '120px'
-  }
-])
-
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = (colums: Column[]) => {
-  for (const col of colums) {
-    let { formatter, prop, label, 'min-width': minWidth, isTag, children } = col
-
-    if (children && children.length > 0) {
-      calculateColumnWidths(children)
-      continue
-    }
-
-    minWidth =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(formatter ? formatter(v) : v[prop!])
-              })
-            ]
-          ) + (isTag ? 40 : 20),
-          200
-        ]
-      ) + 'px'
-
-    col['min-width'] = minWidth
-  }
-}
-
-const nptFields = [
-  'accidentTime', // 工程质量
-  'repairTime', // 设备故障
-  'selfStopTime', // 设备保养
-  'complexityTime', // 技术受限
-  'relocationTime', // 生产配合
-  'rectificationTime', // 生产组织
-  'waitingStopTime', // 不可抗力
-  'winterBreakTime', // 待命
-  'partyaDesign', // 甲方设计
-  'partyaPrepare', // 甲方资源
-  'partyaResource', // 甲方准备
-  'otherNptTime' // 其它非生产时间
-]
-
-function checkTimeSumEquals24(row: List) {
-  const ratedProductionTime = parseFloat(row.ratedProductionTime + '') || 0
-  const productionTime = parseFloat(row.productionTime + '') || 0
-
-  // 3. 计算所有非生产时间细项的总和
-  const totalNonProductionTime = nptFields.reduce((sum, field) => {
-    // 获取字段值,转为浮点数,如果是 NaN 则视为 0
-    const val = parseFloat(row[field])
-    return sum + (isNaN(val) ? 0 : val)
-  }, 0)
-
-  // 4. 计算实际总投入时间:生产时间 + 所有非生产时间之和
-  const currentSum = productionTime + totalNonProductionTime
-
-  // 5. 校验逻辑:判断 (生产时间 + 非生产时间总和) 是否等于 额定生产时间
-  // 允许 0.01 的浮点数误差
-  return Math.abs(currentSum - ratedProductionTime) < 0.01
-}
-
-function cellStyle(data: {
-  row: List
-  column: TableColumnCtx<List>
-  rowIndex: number
-  columnIndex: number
-}) {
-  const { row, column } = data
-
-  if (column.property === 'transitTime') {
-    const originalValue = Number(row.transitTime ?? 0)
-
-    if (originalValue >= 1)
-      return {
-        color: 'red',
-        fontWeight: 'bold'
-      }
-  }
-
-  if (column.property === 'dailyFuel') {
-    const originalValue = row.dailyFuel ?? 0
-
-    if (originalValue > 3500)
-      return {
-        color: 'blue',
-        fontWeight: 'bold'
-      }
-  }
-
-  const timeFields = ['ratedProductionTime', 'productionTime', ...nptFields]
-  if (timeFields.includes(column.property)) {
-    if (!checkTimeSumEquals24(row)) {
-      return {
-        color: 'orange',
-        fontWeight: 'bold'
-      }
-    }
-  }
-
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-const id = useUserStore().getUser.deptId
-
-const deptId = id
-
-interface Query {
-  pageNo: number
-  pageSize: number
-  deptId: number
-  contractName?: string
-  taskName?: string
-  createTime: string[]
-  projectClassification: '1' | '2'
-}
-
-const query = ref<Query>({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: id,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ],
-  projectClassification: '2'
-})
-
-function handleSizeChange(val: number) {
-  query.value.pageSize = val
-  handleQuery()
-}
-
-function handleCurrentChange(val: number) {
-  query.value.pageNo = val
-  loadList()
-}
-
-const loading = ref(false)
-
-const list = ref<List[]>([])
-const total = ref(0)
-
-const loadList = useDebounceFn(async function () {
-  loading.value = true
-  try {
-    const data = await IotRyDailyReportApi.getIotRyDailyReportPage(query.value)
-
-    data.list.forEach((v) => {
-      const { ratedProductionTime = 0, productionTime = 0 } = v
-
-      v.transitTime = ratedProductionTime === 0 ? 0 : productionTime / ratedProductionTime
-    })
-
-    list.value = data.list
-    total.value = data.total
-
-    nextTick(() => {
-      calculateColumnWidths(columns.value)
-    })
-  } finally {
-    loading.value = false
-  }
-}, 500)
-
-function handleQuery(setPage = true) {
-  if (setPage) {
-    query.value.pageNo = 1
-  }
-  loadList()
-}
-
-function resetQuery() {
-  query.value = {
-    pageNo: 1,
-    pageSize: 10,
-    deptId: 157,
-    contractName: '',
-    taskName: '',
-    createTime: [
-      ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-    ],
-    projectClassification: '2'
-  }
-  handleQuery()
-}
-
-watch(
-  [
-    () => query.value.createTime,
-    () => query.value.deptId,
-    () => query.value.taskName,
-    () => query.value.contractName
-  ],
-  () => {
-    handleQuery()
-  },
-  { immediate: true }
-)
-
-const visible = ref(false)
-
-const formRef = ref()
-
-function handleOpenForm(id: number, type: 'edit' | 'readonly') {
-  if (formRef.value) {
-    formRef.value.handleOpenForm(id, type)
-  }
-}
-
-const route = useRoute()
-
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    handleOpenForm(Number(route.query.id), 'edit')
-  }
-})
-</script>
-
-<template>
-  <div
-    class="h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
-  >
-    <div class="grid grid-cols-[15%_1fr] gap-4 h-full">
-      <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg h-full">
-        <DeptTreeSelect :top-id="158" :deptId="deptId" v-model="query.deptId" />
-      </div>
-      <div class="grid grid-rows-[62px_1fr] h-full gap-4">
-        <el-form
-          size="default"
-          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
-        >
-          <div class="flex items-center gap-8">
-            <el-form-item label="项目">
-              <el-input
-                v-model="query.contractName"
-                placeholder="请输入项目"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="任务">
-              <el-input
-                v-model="query.taskName"
-                placeholder="请输入任务"
-                clearable
-                @keyup.enter="handleQuery()"
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="创建时间">
-              <el-date-picker
-                v-model="query.createTime"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                type="daterange"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-                :shortcuts="rangeShortcuts"
-                class="!w-220px"
-                :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              />
-            </el-form-item>
-          </div>
-          <el-form-item>
-            <el-button type="primary" @click="handleQuery()">
-              <Icon icon="ep:search" class="mr-5px" /> 搜索
-            </el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
-          </el-form-item>
-        </el-form>
-        <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg p-4 flex flex-col">
-          <div class="flex-1 relative">
-            <el-auto-resizer class="absolute">
-              <template #default="{ width, height }">
-                <el-table
-                  :data="list"
-                  v-loading="loading"
-                  stripe
-                  class="absolute"
-                  :max-height="height"
-                  show-overflow-tooltip
-                  :width="width"
-                  :cell-style="cellStyle"
-                  border
-                >
-                  <DailyTableColumn :columns="columns" />
-                  <el-table-column label="操作" width="120px" align="center" fixed="right">
-                    <template #default="{ row }">
-                      <el-button
-                        link
-                        type="success"
-                        @click="handleOpenForm(row.id, 'readonly')"
-                        v-hasPermi="['pms:iot-ry-daily-report:query']"
-                      >
-                        查看
-                      </el-button>
-                      <el-button
-                        v-show="row.status === 0"
-                        link
-                        type="primary"
-                        @click="handleOpenForm(row.id, 'edit')"
-                        v-hasPermi="['pms:iot-ry-daily-report:create']"
-                      >
-                        编辑
-                      </el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </template>
-            </el-auto-resizer>
-          </div>
-          <div class="h-10 mt-4 flex items-center justify-end">
-            <el-pagination
-              size="default"
-              v-show="total > 0"
-              v-model:current-page="query.pageNo"
-              v-model:page-size="query.pageSize"
-              :background="true"
-              :page-sizes="[10, 20, 30, 50, 100]"
-              :total="total"
-              layout="total, sizes, prev, pager, next, jumper"
-              @size-change="handleSizeChange"
-              @current-change="handleCurrentChange"
-            />
-          </div>
-        </div>
-      </div>
-    </div>
-    <ry-xj-form v-model:visible="visible" type="edit" ref="formRef" :load-list="loadList" />
-  </div>
-</template>
-
-<style scoped>
-:deep(.el-form-item) {
-  margin-bottom: 0;
-}
-
-:deep(.el-table) {
-  border-top-right-radius: 8px;
-  border-top-left-radius: 8px;
-
-  .el-table__cell {
-    height: 40px;
-  }
-
-  .el-table__header-wrapper {
-    .el-table__cell {
-      background: var(--el-fill-color-light);
-    }
-  }
-}
-
-:deep(.warning-input) {
-  .el-input__inner {
-    color: red !important;
-    -webkit-text-fill-color: red !important;
-  }
-}
-
-:deep(.blue-input) {
-  .el-input__inner {
-    color: blue !important;
-    -webkit-text-fill-color: blue !important;
-  }
-}
-
-:deep(.orange-input) {
-  .el-input__inner {
-    color: orange !important;
-    -webkit-text-fill-color: orange !important;
-  }
-}
-
-:deep(.el-input-number) {
-  width: 100%;
-}
-
-:deep(.el-input-number__decrease) {
-  display: none !important;
-}
-
-:deep(.el-input-number__increase) {
-  display: none !important;
-}
-</style>

+ 25 - 24
src/views/pms/iotrydailyreport/xjindex.vue

@@ -133,7 +133,7 @@ function handleOpenForm(id: number, type: 'edit' | 'readonly') {
 
 <template>
   <div
-    class="grid grid-cols-[15%_1fr] grid-rows-[48px_auto_1fr] gap-x-4 gap-y-3 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
+    class="grid grid-cols-[15%_1fr] grid-rows-[48px_1fr_auto] gap-x-4 gap-y-3 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
   >
     <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg row-span-3">
       <DeptTreeSelect :top-id="158" :deptId="deptId" v-model="query.deptId" :show-title="false" />
@@ -202,29 +202,6 @@ function handleOpenForm(id: number, type: 'edit' | 'readonly') {
       </el-form-item>
     </el-form>
 
-    <div class="p-2 bg-white dark:bg-[#1d1e1f] rounded-lg shadow flex flex-col gap-2">
-      <el-alert
-        class="h-8!"
-        title="运行时效=生产时间/额定生产时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;超过100%红色预警"
-        type="error"
-        show-icon
-        :closable="false"
-      />
-      <el-alert
-        class="h-8!"
-        title="生产时间+非生产时间=额定生产时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;否则橙色预警"
-        type="warning"
-        show-icon
-        :closable="false"
-      />
-      <el-alert
-        class="h-8!"
-        title="当日油耗大于3500升&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;蓝色预警"
-        type="primary"
-        show-icon
-        :closable="false"
-      />
-    </div>
     <ry-xj-table
       :list="list"
       :total="total"
@@ -254,6 +231,30 @@ function handleOpenForm(id: number, type: 'edit' | 'readonly') {
         </el-button>
       </template>
     </ry-xj-table>
+
+    <div class="p-2 bg-white dark:bg-[#1d1e1f] rounded-lg shadow flex flex-col gap-2">
+      <el-alert
+        class="h-8!"
+        title="运行时效=生产时间/额定生产时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;超过100%红色预警"
+        type="error"
+        show-icon
+        :closable="false"
+      />
+      <el-alert
+        class="h-8!"
+        title="生产时间+非生产时间=额定生产时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;否则橙色预警"
+        type="warning"
+        show-icon
+        :closable="false"
+      />
+      <el-alert
+        class="h-8!"
+        title="当日油耗大于3500升&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;蓝色预警"
+        type="primary"
+        show-icon
+        :closable="false"
+      />
+    </div>
   </div>
 
   <ry-xj-form

+ 0 - 1265
src/views/pms/iotrydailyreport/xjindex1.vue

@@ -1,1265 +0,0 @@
-<template>
-  <el-row :gutter="20">
-    <el-col :span="4" :xs="24">
-      <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-4 h-full">
-        <DeptTreeSelect
-          :deptId="rootDeptId"
-          :top-id="158"
-          v-model="queryParams.deptId"
-          @node-click="handleDeptNodeClick"
-        />
-      </div>
-      <!-- <ContentWrap class="h-1/1">
-        <DeptTree2 :deptId="rootDeptId" @node-click="handleDeptNodeClick" />
-      </ContentWrap> -->
-    </el-col>
-    <el-col :span="20" :xs="24">
-      <ContentWrap>
-        <!-- 搜索工作栏 -->
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="80px"
-        >
-          <el-form-item label="项目" prop="contractName">
-            <el-input
-              v-model="queryParams.contractName"
-              placeholder="请输入项目"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="任务" prop="taskName">
-            <el-input
-              v-model="queryParams.taskName"
-              placeholder="请输入任务"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="创建时间" prop="createTime">
-            <el-date-picker
-              v-model="queryParams.createTime"
-              value-format="YYYY-MM-DD HH:mm:ss"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
-              class="!w-220px"
-              :shortcuts="rangeShortcuts"
-            />
-          </el-form-item>
-          <el-form-item label="非生产时效" prop="nonProductFlag">
-            <el-switch v-model="queryParams.nonProductFlag" active-value="Y" inactive-value="N" />
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="handleQuery"
-              ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
-            >
-            <el-button @click="resetQuery"
-              ><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
-            >
-            <!-- <el-button
-              type="primary"
-              plain
-              @click="openForm('create')"
-              v-hasPermi="['pms:iot-rh-daily-report:create']"
-            >
-              <Icon icon="ep:plus" class="mr-5px" /> 新增
-            </el-button> -->
-            <el-button type="success" plain @click="handleExport" :loading="exportLoading">
-              <Icon icon="ep:download" class="mr-5px" /> 导出
-            </el-button>
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-
-      <ContentWrap class="mb-15px">
-        <div class="color-legend">
-          <div class="legend-item">
-            <span class="color-indicator red"></span>
-            <span
-              >运行时效=生产时间/额定生产时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;超过100%红色预警</span
-            >
-          </div>
-          <div class="legend-item">
-            <span class="color-indicator orange"></span>
-            <span
-              >生产时间+非生产时间=额定生产时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;否则橙色预警</span
-            >
-          </div>
-          <div class="legend-item">
-            <span class="color-indicator yellow"></span>
-            <span>当日油耗大于3500升&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;蓝色预警</span>
-          </div>
-        </div>
-      </ContentWrap>
-
-      <!-- 列表 -->
-      <ContentWrap ref="tableContainerRef">
-        <div class="table-container">
-          <el-table
-            ref="tableRef"
-            v-loading="loading"
-            :data="list"
-            :stripe="true"
-            :style="{ width: '100%' }"
-            max-height="600"
-            :cell-style="cellStyle"
-            show-overflow-tooltip
-            border
-          >
-            <el-table-column
-              :label="t('iotDevice.serial')"
-              width="56px"
-              align="center"
-              fixed="left"
-            >
-              <template #default="scope">
-                {{ scope.$index + 1 }}
-              </template>
-            </el-table-column>
-            <el-table-column
-              label="日期"
-              align="center"
-              prop="createTime"
-              :formatter="dateFormatter2"
-              :min-width="columnWidths.createTime.width"
-              resizable
-              fixed="left"
-            />
-            <el-table-column
-              label="施工队伍"
-              align="center"
-              prop="deptName"
-              :min-width="columnWidths.deptName.width"
-              resizable
-              fixed="left"
-            />
-
-            <el-table-column
-              label="任务"
-              align="center"
-              prop="taskName"
-              :min-width="columnWidths.taskName.width"
-              resizable
-              fixed="left"
-            />
-            <el-table-column
-              :label="t('project.status')"
-              align="center"
-              prop="repairStatus"
-              :min-width="columnWidths.repairStatus.width"
-              resizable
-              fixed="left"
-            >
-              <template #default="scope">
-                <dict-tag
-                  :type="DICT_TYPE.PMS_PROJECT_TASK_RY_REPAIR_SCHEDULE"
-                  :value="scope.row.repairStatus"
-                />
-              </template>
-            </el-table-column>
-            <el-table-column
-              label="总施工井数"
-              align="center"
-              prop="totalConstructionWells"
-              :min-width="columnWidths.totalConstructionWells.width"
-              resizable
-            />
-            <el-table-column
-              label="完工井数"
-              align="center"
-              prop="completedWells"
-              :min-width="columnWidths.completedWells.width"
-              resizable
-            />
-            <el-table-column
-              :label="t('project.technology')"
-              align="center"
-              prop="technique"
-              :min-width="columnWidths.technique.width"
-              resizable
-            >
-              <template #default="scope">
-                <dict-tag
-                  :type="DICT_TYPE.PMS_PROJECT_RY_TECHNOLOGY"
-                  :value="scope.row.technique"
-                />
-              </template>
-            </el-table-column>
-            <el-table-column
-              label="井别"
-              align="center"
-              prop="wellCategory"
-              :min-width="columnWidths.wellCategory.width"
-              resizable
-            />
-            <el-table-column
-              label="井深(m)"
-              align="center"
-              prop="designWellDepth"
-              :min-width="columnWidths.designWellDepth.width"
-              resizable
-            />
-            <el-table-column
-              label="套生段产管尺寸(mm)"
-              align="center"
-              prop="casingPipeSize"
-              :min-width="columnWidths.casingPipeSize.width"
-              resizable
-            />
-            <el-table-column
-              label="井控级别"
-              align="center"
-              prop="wellControlLevel"
-              :min-width="columnWidths.wellControlLevel.width"
-              resizable
-            />
-            <el-table-column align="center" label="当日">
-              <el-table-column
-                label="用电量(kWh)"
-                align="center"
-                prop="dailyPowerUsage"
-                :min-width="columnWidths.dailyPowerUsage.width"
-                resizable
-              />
-              <el-table-column
-                label="油耗(升)"
-                align="center"
-                prop="dailyFuel"
-                :min-width="columnWidths.dailyFuel.width"
-                resizable
-              />
-            </el-table-column>
-
-            <el-table-column
-              label="施工开始日期"
-              align="center"
-              prop="constructionStartDate"
-              :formatter="dateFormatter"
-              :min-width="columnWidths.constructionStartDate.width"
-              resizable
-            />
-            <el-table-column
-              label="施工结束日期"
-              align="center"
-              prop="constructionEndDate"
-              :formatter="dateFormatter"
-              :min-width="columnWidths.constructionEndDate.width"
-              resizable
-            />
-
-            <el-table-column
-              :label="t('project.currentOperation')"
-              align="center"
-              prop="currentOperation"
-              :min-width="columnWidths.currentOperation.width"
-              resizable
-            />
-            <el-table-column
-              :label="t('project.nextPlan')"
-              align="center"
-              prop="nextPlan"
-              :min-width="columnWidths.nextPlan.width"
-              resizable
-            />
-            <el-table-column
-              :label="t('project.transitTime')"
-              align="center"
-              prop="transitTime"
-              :min-width="columnWidths.transitTime.width"
-              resizable
-              :formatter="percentageFormatter"
-            />
-            <el-table-column
-              label="额定生产时间(H)"
-              align="center"
-              prop="ratedProductionTime"
-              :min-width="columnWidths.ratedProductionTime.width"
-              resizable
-            />
-            <el-table-column
-              label="生产时间(H)"
-              align="center"
-              prop="productionTime"
-              :min-width="columnWidths.productionTime.width"
-              resizable
-            />
-            <el-table-column
-              label="非生产时效"
-              align="center"
-              prop="nonProductionRate"
-              :formatter="nonProductionRateFormatter"
-              :min-width="columnWidths.nonProductionRate.width"
-              resizable
-            />
-            <el-table-column label="非生产时间" align="center">
-              <el-table-column
-                label="工程质量"
-                align="center"
-                prop="accidentTime"
-                :min-width="columnWidths.accidentTime.width"
-                resizable
-              />
-              <el-table-column
-                label="设备故障"
-                align="center"
-                prop="repairTime"
-                :min-width="columnWidths.repairTime.width"
-                resizable
-              />
-              <el-table-column
-                label="设备保养"
-                align="center"
-                prop="selfStopTime"
-                :min-width="columnWidths.selfStopTime.width"
-                resizable
-              />
-              <el-table-column
-                label="技术受限"
-                align="center"
-                prop="complexityTime"
-                :min-width="columnWidths.complexityTime.width"
-                resizable
-              />
-              <el-table-column
-                label="生产配合"
-                align="center"
-                prop="relocationTime"
-                :min-width="columnWidths.relocationTime.width"
-                resizable
-              />
-              <el-table-column
-                label="生产组织"
-                align="center"
-                prop="rectificationTime"
-                :min-width="columnWidths.rectificationTime.width"
-                resizable
-              />
-              <el-table-column
-                label="不可抗力"
-                align="center"
-                prop="waitingStopTime"
-                :min-width="columnWidths.waitingStopTime.width"
-                resizable
-              />
-              <el-table-column
-                label="待命"
-                align="center"
-                prop="winterBreakTime"
-                :min-width="columnWidths.winterBreakTime.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方设计"
-                align="center"
-                prop="partyaDesign"
-                :min-width="columnWidths.partyaDesign.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方准备"
-                align="center"
-                prop="partyaPrepare"
-                :min-width="columnWidths.partyaPrepare.width"
-                resizable
-              />
-              <el-table-column
-                label="甲方资源"
-                align="center"
-                prop="partyaResource"
-                :min-width="columnWidths.partyaResource.width"
-                resizable
-              />
-              <el-table-column
-                label="其它非生产时间"
-                align="center"
-                prop="otherNptTime"
-                :min-width="columnWidths.otherNptTime.width"
-                resizable
-              />
-            </el-table-column>
-            <el-table-column
-              label="其他非生产时间原因"
-              align="center"
-              prop="otherNptReason"
-              :min-width="columnWidths.otherNptReason.width"
-              resizable
-            />
-
-            <!-- <el-table-column
-              :label="t('project.nptReason')"
-              align="center"
-              prop="ryNptReason"
-              :min-width="columnWidths.ryNptReason.width"
-              resizable
-            >
-              <template #default="scope">
-                <dict-tag
-                  :type="DICT_TYPE.PMS_PROJECT_RY_NPT_REASON"
-                  :value="scope.row.ryNptReason"
-                />
-              </template>
-            </el-table-column> -->
-            <el-table-column
-              label="生产动态"
-              align="center"
-              prop="productionStatus"
-              :min-width="columnWidths.productionStatus.width"
-              resizable
-            />
-            <el-table-column
-              label="项目"
-              align="center"
-              prop="contractName"
-              :min-width="columnWidths.contractName.width"
-              resizable
-            />
-            <el-table-column
-              label="全员数量"
-              align="center"
-              prop="totalStaffNum"
-              :min-width="columnWidths.totalStaffNum.width"
-              resizable
-            />
-            <!--
-            <el-table-column label="在岗人数" align="center" prop="onDutyStaffNum" :min-width="columnWidths.onDutyStaffNum"/> -->
-            <el-table-column
-              label="在岗人数"
-              align="center"
-              prop="onDutyStaffNum"
-              :min-width="columnWidths.onDutyStaffNum.width"
-              resizable
-            >
-              <template #default="scope">
-                <!-- 动态计算:在岗人数 = 全员数量 - 休假人员数量 -->
-                {{
-                  (Number(scope.row.totalStaffNum) || 0) - (Number(scope.row.leaveStaffNum) || 0)
-                }}
-              </template>
-            </el-table-column>
-            <el-table-column
-              label="休假人员数量"
-              align="center"
-              prop="leaveStaffNum"
-              :min-width="columnWidths.leaveStaffNum.width"
-              resizable
-            />
-            <el-table-column label="操作" align="center" fixed="right">
-              <template #default="scope">
-                <el-button
-                  link
-                  type="primary"
-                  @click="handleOpenForm(scope.row.id, 'edit')"
-                  v-hasPermi="['pms:iot-ry-daily-report:update']"
-                >
-                  编辑
-                </el-button>
-                <el-button
-                  link
-                  type="danger"
-                  @click="handleDelete(scope.row.id)"
-                  v-hasPermi="['pms:iot-ry-daily-report:delete']"
-                >
-                  删除
-                </el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-        <!-- 分页 -->
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
-        />
-      </ContentWrap>
-
-      <!-- 表单弹窗:添加/修改 -->
-      <ry-xj-form
-        v-model:visible="visible"
-        type="edit"
-        ref="formRef"
-        :load-list="getList"
-        no-validate-status
-      />
-    </el-col>
-  </el-row>
-</template>
-
-<script setup lang="ts">
-import ryXjForm from './ry-xj-form.vue'
-import { dateFormatter, dateFormatter2, rangeShortcuts } from '@/utils/formatTime'
-import download from '@/utils/download'
-import { IotRyDailyReportApi, IotRyDailyReportVO } from '@/api/pms/iotrydailyreport'
-import { DICT_TYPE } from '@/utils/dict'
-import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue'
-import { useDebounceFn } from '@vueuse/core'
-
-import { useUserStore } from '@/store/modules/user'
-
-import dayjs from 'dayjs'
-import quarterOfYear from 'dayjs/plugin/quarterOfYear'
-
-dayjs.extend(quarterOfYear)
-
-/** 瑞鹰日报 列表 */
-defineOptions({ name: 'IotRyXjDailyReport' })
-
-const message = useMessage() // 消息弹窗
-const { t } = useI18n() // 国际化
-
-// 添加 selectedRowData 响应式变量
-const selectedRowData = ref<Record<string, any> | null>(null)
-
-const loading = ref(true) // 列表的加载中
-const list = ref<IotRyDailyReportVO[]>([]) // 列表的数据
-const total = ref(0) // 列表的总页数
-let queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  deptId: useUserStore().getUser.deptId,
-  contractName: undefined,
-  projectId: undefined,
-  taskName: undefined,
-  taskId: undefined,
-  projectClassification: '2',
-  relocationDays: undefined,
-  latestWellDoneTime: [],
-  currentDepth: undefined,
-  dailyFootage: undefined,
-  monthlyFootage: undefined,
-  annualFootage: undefined,
-  dailyPowerUsage: undefined,
-  monthlyPowerUsage: undefined,
-  dailyFuel: undefined,
-  monthlyFuel: undefined,
-  nonProductionTime: [],
-  nptReason: undefined,
-  constructionStartDate: [],
-  constructionEndDate: [],
-  productionStatus: undefined,
-  nextPlan: undefined,
-  rigStatus: undefined,
-  personnel: undefined,
-  mudDensity: undefined,
-  mudViscosity: undefined,
-  lateralLength: undefined,
-  wellInclination: undefined,
-  azimuth: undefined,
-  extProperty: undefined,
-  sort: undefined,
-  remark: undefined,
-  status: undefined,
-  processInstanceId: undefined,
-  auditStatus: undefined,
-  createTime: [
-    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
-  ],
-  nonProductFlag: 'N'
-})
-const queryFormRef = ref() // 搜索的表单
-
-const rootDeptId = ref(useUserStore().getUser.deptId)
-
-// 表格引用
-const tableRef = ref()
-// 表格容器引用
-const tableContainerRef = ref()
-
-// 列宽度配置
-const columnWidths = ref<
-  Record<
-    string,
-    {
-      label: string
-      prop: string
-      width: string
-      fn?: (row: IotRyDailyReportVO) => string | number
-    }
-  >
->({
-  createTime: {
-    label: '日期',
-    prop: 'createTime',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) => dateFormatter2(null, null, row.createTime)
-  },
-  deptName: {
-    label: '施工队伍',
-    prop: 'deptName',
-    width: '120px'
-  },
-  contractName: {
-    label: '项目',
-    prop: 'contractName',
-    width: '120px'
-  },
-  taskName: {
-    label: '任务',
-    prop: 'taskName',
-    width: '120px'
-  },
-  equipmentType: {
-    label: '设备型号',
-    prop: 'equipmentType',
-    width: '120px'
-  },
-  repairStatus: {
-    label: '施工状态',
-    prop: 'repairStatus',
-    width: '120px'
-  },
-  totalConstructionWells: {
-    label: '总施工井数',
-    prop: 'totalConstructionWells',
-    width: '120px'
-  },
-  completedWells: {
-    label: '完工井数',
-    prop: 'completedWells',
-    width: '120px'
-  },
-  technique: {
-    label: '施工工艺',
-    prop: 'technique',
-    width: '120px'
-  },
-  wellCategory: {
-    label: '井别',
-    prop: 'wellCategory',
-    width: '120px'
-  },
-  designWellDepth: {
-    label: '井深(m)',
-    prop: 'designWellDepth',
-    width: '120px'
-  },
-  casingPipeSize: {
-    label: '套生段产管尺寸(mm)',
-    prop: 'casingPipeSize',
-    width: '120px'
-  },
-  wellControlLevel: {
-    label: '井控级别',
-    prop: 'wellControlLevel',
-    width: '120px'
-  },
-  dailyPowerUsage: {
-    label: '用电量(kWh)',
-    prop: 'dailyPowerUsage',
-    width: '120px'
-  },
-  dailyFuel: {
-    label: '油耗(升)',
-    prop: 'dailyFuel',
-    width: '120px'
-  },
-  constructionStartDate: {
-    label: '施工开始日期',
-    prop: 'constructionStartDate',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) => dateFormatter(null, null, row.constructionStartDate)
-  },
-  constructionEndDate: {
-    label: '施工结束日期',
-    prop: 'constructionEndDate',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) => dateFormatter(null, null, row.constructionEndDate)
-  },
-  currentOperation: {
-    label: '目前',
-    prop: 'currentOperation',
-    width: '120px'
-  },
-  nextPlan: {
-    label: '下步',
-    prop: 'nextPlan',
-    width: '120px'
-  },
-  transitTime: {
-    label: '运行时效',
-    prop: 'transitTime',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) => percentageFormatter(null, null, row.transitTime, null)
-  },
-  ratedProductionTime: {
-    label: '额定生产时间(H)',
-    prop: 'ratedProductionTime',
-    width: '120px'
-  },
-  productionTime: {
-    label: '生产时间(H)',
-    prop: 'productionTime',
-    width: '120px'
-  },
-  accidentTime: {
-    label: '工程质量',
-    prop: 'accidentTime',
-    width: '120px'
-  },
-  repairTime: {
-    label: '设备故障',
-    prop: 'repairTime',
-    width: '120px'
-  },
-  selfStopTime: {
-    label: '设备保养',
-    prop: 'selfStopTime',
-    width: '120px'
-  },
-  complexityTime: {
-    label: '技术受限',
-    prop: 'complexityTime',
-    width: '120px'
-  },
-  relocationTime: {
-    label: '生产配合',
-    prop: 'relocationTime',
-    width: '120px'
-  },
-  rectificationTime: {
-    label: '生产组织',
-    prop: 'rectificationTime',
-    width: '120px'
-  },
-  waitingStopTime: {
-    label: '不可抗力',
-    prop: 'waitingStopTime',
-    width: '120px'
-  },
-  winterBreakTime: {
-    label: '待命',
-    prop: 'winterBreakTime',
-    width: '120px'
-  },
-  partyaDesign: {
-    label: '甲方设计',
-    prop: 'partyaDesign',
-    width: '120px'
-  },
-  partyaPrepare: {
-    label: '甲方资源',
-    prop: 'partyaPrepare',
-    width: '120px'
-  },
-  partyaResource: {
-    label: '甲方准备',
-    prop: 'partyaResource',
-    width: '120px'
-  },
-  otherNptTime: {
-    label: '其它非生产时间',
-    prop: 'otherNptTime',
-    width: '120px'
-  },
-  otherNptReason: {
-    label: '其他非生产时间原因',
-    prop: 'otherNptReason',
-    width: '120px'
-  },
-  ryNptReason: {
-    label: '非生产时间原因',
-    prop: 'ryNptReason',
-    width: '120px'
-  },
-  drillingWorkingTime: {
-    label: '进尺工作时间(H)',
-    prop: 'drillingWorkingTime',
-    width: '120px'
-  },
-  otherProductionTime: {
-    label: '其它生产时间(H)',
-    prop: 'otherProductionTime',
-    width: '120px'
-  },
-  productionStatus: {
-    label: '生产动态',
-    prop: 'productionStatus',
-    width: '120px'
-  },
-  totalStaffNum: {
-    label: '全员数量',
-    prop: 'totalStaffNum',
-    width: '120px'
-  },
-  onDutyStaffNum: {
-    label: '在岗人数',
-    prop: 'onDutyStaffNum',
-    width: '120px',
-    fn: (row: IotRyDailyReportVO) =>
-      (Number(row.totalStaffNum) || 0) - (Number(row.offDutyStaffNum) || 0)
-  },
-  leaveStaffNum: {
-    label: '休假人员数量',
-    prop: 'leaveStaffNum',
-    width: '120px'
-  },
-  nonProductionRate: {
-    label: '非生产时效',
-    prop: 'nonProductionRate',
-    width: '120px',
-    fn: (row: any) => nonProductionRateFormatter(row)
-  }
-})
-
-const nonProductionRateFormatter = (row: any) => {
-  const nonProductionRate = row?.nonProductionRate ?? 0
-
-  return (nonProductionRate * 100).toFixed(2) + '%'
-}
-
-// 计算文本宽度
-const getTextWidth = (text: string, fontSize = 12) => {
-  const span = document.createElement('span')
-  span.style.visibility = 'hidden'
-  span.style.position = 'absolute'
-  span.style.whiteSpace = 'nowrap'
-  span.style.fontSize = `${fontSize}px`
-  span.style.fontFamily = 'PingFang SC'
-  span.innerText = text
-
-  document.body.appendChild(span)
-  const width = span.offsetWidth
-  document.body.removeChild(span)
-
-  return width
-}
-
-const calculateColumnWidths = useDebounceFn(() => {
-  if (!tableContainerRef.value?.$el) return
-  Object.values(columnWidths.value).forEach(({ fn, prop, label, width }) => {
-    width =
-      Math.min(
-        ...[
-          Math.max(
-            ...[
-              getTextWidth(label),
-              ...list.value.map((v) => {
-                return getTextWidth(fn ? fn(v) : v[prop])
-              })
-            ]
-          ) +
-            (label === '施工状态' || label === '施工工艺' || label === '非生产时间原因' ? 35 : 20),
-          200
-        ]
-      ) + 'px'
-
-    columnWidths.value[prop].width = width
-  })
-}, 1000)
-
-// 检查10个时间字段之和是否为24H
-const checkTimeSumEquals24 = (row: any) => {
-  // 获取三个字段的值,转换为数字,如果为空则视为0
-  const drillingWorkingTime = parseFloat(row.drillingWorkingTime) || 0
-  const otherProductionTime = parseFloat(row.otherProductionTime) || 0
-  const accidentTime = parseFloat(row.accidentTime) || 0
-  const repairTime = parseFloat(row.repairTime) || 0
-  const selfStopTime = parseFloat(row.selfStopTime) || 0
-  const complexityTime = parseFloat(row.complexityTime) || 0
-  const relocationTime = parseFloat(row.relocationTime) || 0
-  const rectificationTime = parseFloat(row.rectificationTime) || 0
-  const waitingStopTime = parseFloat(row.waitingStopTime) || 0
-  const winterBreakTime = parseFloat(row.winterBreakTime) || 0
-
-  // 计算总和
-  const sum =
-    drillingWorkingTime +
-    otherProductionTime +
-    accidentTime +
-    repairTime +
-    selfStopTime +
-    complexityTime +
-    relocationTime +
-    rectificationTime +
-    waitingStopTime +
-    winterBreakTime
-
-  // 返回是否等于24(允许一定的浮点数误差)
-  return Math.abs(sum - 24) < 0.01 // 使用0.01作为误差范围
-}
-
-// 单元格样式函数
-const cellStyle = ({
-  row,
-  column,
-  rowIndex,
-  columnIndex
-}: {
-  row: any
-  column: any
-  rowIndex: number
-  columnIndex: number
-}) => {
-  // 当日油耗预警逻辑
-  if (column.property === 'dailyFuel') {
-    const dailyFuel = parseFloat(row.dailyFuel) || 0
-    if (dailyFuel > 3500) {
-      return {
-        backgroundColor: '#e6f8ff', // 浅黄色背景
-        color: '#0a35c4', // 橙色文字
-        fontWeight: 'bold',
-        border: '1px solid #ffd591' // 可选:添加边框突出显示
-      }
-    }
-  }
-
-  const nptFields = [
-    'accidentTime', // 工程质量
-    'repairTime', // 设备故障
-    'selfStopTime', // 设备保养
-    'complexityTime', // 技术受限
-    'relocationTime', // 生产配合
-    'rectificationTime', // 生产组织
-    'waitingStopTime', // 不可抗力
-    'winterBreakTime', // 待命
-    'partyaDesign', // 甲方设计
-    'partyaPrepare', // 甲方资源
-    'partyaResource', // 甲方准备
-    'otherNptTime' // 其它非生产时间
-  ]
-
-  // 定义所有涉及校验的列(额定、生产 + 所有非生产细分字段)
-  const timeFields = ['ratedProductionTime', 'productionTime', ...nptFields]
-
-  if (timeFields.includes(column.property)) {
-    // 辅助函数:判断值是否为空
-    const isEmpty = (val) => val === null || val === undefined || val === ''
-
-    // 1. 检查是否有空值
-    // 先检查额定时间和生产时间
-    let hasEmptyField = isEmpty(row.ratedProductionTime) || isEmpty(row.productionTime)
-
-    // 如果主要字段不为空,继续检查所有非生产时间细分字段
-    if (!hasEmptyField) {
-      hasEmptyField = nptFields.some((field) => isEmpty(row[field]))
-    }
-
-    // 如果有空字段,应用警告样式(红色)
-    if (hasEmptyField) {
-      return {
-        backgroundColor: '#fff2f0', // 浅红色背景
-        color: '#d46b08', // 深红色文字
-        fontWeight: 'bold',
-        border: '1px solid #ffa39e'
-      }
-    }
-
-    // 2. 获取数值进行计算
-    const ratedTime = parseFloat(row.ratedProductionTime) || 0
-    const prodTime = parseFloat(row.productionTime) || 0
-
-    // 计算所有非生产时间细分字段的总和
-    const totalNonProdTime = nptFields.reduce((sum, field) => {
-      return sum + (parseFloat(row[field]) || 0)
-    }, 0)
-
-    // 3. 校验逻辑:额定生产时间 = 生产时间 + 所有非生产时间细项之和
-    // 使用容差比较,避免浮点数精度问题
-    if (Math.abs(ratedTime - (prodTime + totalNonProdTime)) > 0.01) {
-      return {
-        backgroundColor: '#fffbe6', // 浅黄色背景
-        color: '#d46b08', // 橙色文字
-        fontWeight: 'bold'
-      }
-    }
-  }
-
-  // 2. 处理运行时效字段的颜色
-  if (column.property === 'transitTime') {
-    const transitTime = row.transitTime
-    // 将运行时效转为数字(处理原逻辑中 toFixed(4) 生成的字符串)
-    const transitTimeNum = parseFloat(transitTime)
-    if (
-      transitTime === null ||
-      transitTime === undefined ||
-      isNaN(transitTimeNum) ||
-      transitTimeNum === 0 ||
-      transitTimeNum >= 1
-    ) {
-      return {
-        backgroundColor: '#fff2f0', // 浅红色背景(与数据不完整警告样式统一)
-        color: '#ff4d4f', // 红色文字
-        fontWeight: 'bold'
-      }
-    }
-  }
-
-  // 3. 处理“在岗人数”列:动态计算 + 负数黄色背景
-  if (column.label === '在岗人数') {
-    // 按列名匹配(避免prop绑定问题)
-    // 步骤1:计算在岗人数(处理空值/非数字情况,默认设为0)
-    const totalStaff = Number(row.totalStaffNum) || 0
-    const leaveStaff = Number(row.leaveStaffNum) || 0
-    const onDutyStaff = totalStaff - leaveStaff
-
-    // 步骤2:若计算值为负数,设置黄色提醒样式
-    if (onDutyStaff < 0) {
-      return {
-        backgroundColor: '#fff9e6', // 浅黄色背景
-        fontWeight: 'bold'
-      }
-    }
-  }
-
-  // 默认返回空对象,不应用特殊样式
-  return {}
-}
-
-/** 查询列表 */
-const getList = async () => {
-  loading.value = true
-  try {
-    const data = await IotRyDailyReportApi.getIotRyDailyReportPage(queryParams)
-    // 计算运行时效
-    data.list.forEach((item: any) => {
-      const ratedTime = parseFloat(item.ratedProductionTime) || 0
-      const productionTime = parseFloat(item.productionTime) || 0
-
-      if (ratedTime > 0 && !isNaN(productionTime)) {
-        // 计算运行时效并保留4位小数用于计算
-        item.transitTime = (productionTime / ratedTime).toFixed(4)
-      } else {
-        item.transitTime = null
-      }
-    })
-    list.value = data.list
-    total.value = data.total
-    // 获取数据后计算列宽
-    nextTick(() => {
-      calculateColumnWidths()
-    })
-  } finally {
-    loading.value = false
-  }
-}
-
-// 百分比格式化函数
-const percentageFormatter = (row: any, column: any, cellValue: any, index: number | null) => {
-  if (cellValue === null || cellValue === undefined || cellValue === '') return ''
-  console.log('cellValue :>> ', cellValue)
-  const value = parseFloat(cellValue)
-  if (isNaN(value)) return '-'
-  // 将小数转换为百分比,保留两位小数
-  return `${(value * 100).toFixed(2)}%`
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.pageNo = 1
-  getList()
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  queryParams.deptId = useUserStore().getUser.deptId
-  handleQuery()
-}
-
-const visible = ref(false)
-
-const formRef = ref()
-
-function handleOpenForm(id: number, type: 'edit' | 'readonly') {
-  if (formRef.value) {
-    formRef.value.handleOpenForm(id, type)
-  }
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (id: number) => {
-  try {
-    // 删除的二次确认
-    await message.delConfirm()
-    // 发起删除
-    await IotRyDailyReportApi.deleteIotRyDailyReport(id)
-    message.success(t('common.delSuccess'))
-    // 刷新列表
-    await getList()
-  } catch {}
-}
-
-// 响应式变量存储选中的部门
-const selectedDept = ref<{ id: number; name: string }>()
-/** 处理部门被点击 */
-const handleDeptNodeClick = async (row) => {
-  // 记录选中的部门信息
-  selectedDept.value = { id: row.id, name: row.name }
-  queryParams.deptId = row.id
-  await getList()
-}
-
-const exportLoading = ref(false)
-const handleExport = async () => {
-  const res = await IotRyDailyReportApi.exportIotRyDailyReport({
-    createTime: queryParams.createTime,
-    contractName: queryParams.contractName,
-    taskName: queryParams.taskName,
-    // pageNo: queryParams.pageNo,
-    // pageSize: queryParams.pageSize,
-    deptId: queryParams.deptId,
-    projectClassification: queryParams.projectClassification
-  })
-
-  download.excel(res, '瑞鹰修井日报.xlsx')
-}
-// 声明 ResizeObserver 实例
-let resizeObserver: ResizeObserver | null = null
-
-const route = useRoute()
-
-/** 初始化 **/
-onMounted(() => {
-  if (Object.keys(route.query).length > 0) {
-    nextTick(() => {
-      queryParams.deptId = Number(route.query.deptId) as any
-      queryParams.createTime = route.query.createTime as string[]
-      queryParams.nonProductFlag = route.query.nonProductFlag as string
-      handleQuery()
-    })
-  } else getList()
-  // 创建 ResizeObserver 监听表格容器尺寸变化
-  if (tableContainerRef.value?.$el) {
-    resizeObserver = new ResizeObserver(() => {
-      // 使用防抖避免频繁触发
-      clearTimeout((window as any).resizeTimer)
-      ;(window as any).resizeTimer = setTimeout(() => {
-        calculateColumnWidths()
-      }, 100)
-    })
-    resizeObserver.observe(tableContainerRef.value.$el)
-  }
-})
-
-onUnmounted(() => {
-  // 清除 ResizeObserver
-  if (resizeObserver && tableContainerRef.value?.$el) {
-    resizeObserver.unobserve(tableContainerRef.value.$el)
-    resizeObserver = null
-  }
-
-  // 清除定时器
-  if ((window as any).resizeTimer) {
-    clearTimeout((window as any).resizeTimer)
-  }
-})
-
-// 监听列表数据变化重新计算列宽
-watch(
-  list,
-  () => {
-    nextTick(calculateColumnWidths)
-  },
-  { deep: true }
-)
-</script>
-
-<style scoped>
-/* 表格容器样式,确保水平滚动 */
-.table-container {
-  width: 100%;
-  overflow-x: auto;
-}
-
-/* 确保表格单元格内容不换行 */
-
-/* :deep(.el-table .cell) {
-  white-space: nowrap;
-} */
-
-/* 确保表格列标题不换行 */
-
-/* :deep(.el-table th > .cell) {
-  white-space: nowrap;
-} */
-
-/* 调整表格最小宽度,确保内容完全显示 */
-:deep(.el-table) {
-  min-width: 100%;
-}
-
-/* 强制显示所有内容,防止省略号 */
-
-/* :deep(.el-table td.el-table__cell),
-:deep(.el-table th.el-table__cell) {
-  overflow: visible !important;
-} */
-
-/* :deep(.el-table .cell) {
-  overflow: visible !important;
-  text-overflow: clip !important;
-} */
-
-/* 设计井身结构文本样式 - 多行显示并添加省略号 */
-.design-well-struct-text {
-  display: -webkit-box;
-  max-height: 3em; /* 两行文本的高度 */
-  overflow: hidden;
-  line-height: 1.5;
-  text-overflow: ellipsis;
-  -webkit-box-orient: vertical;
-  -webkit-line-clamp: 2;
-}
-
-/* 确保设计井身结构列不参与自动调整 */
-:deep(.el-table__header-wrapper .el-table__cell.fixed-width),
-:deep(.el-table__body-wrapper .el-table__cell.fixed-width) {
-  flex-shrink: 0;
-  flex-grow: 0;
-}
-
-/* 颜色说明区域样式 */
-.color-legend {
-  display: flex;
-  padding: 12px 16px;
-  background-color: #f8f9fa;
-  border-left: 4px solid #e6f7ff;
-  border-radius: 4px;
-  flex-direction: column;
-  gap: 8px;
-}
-
-.legend-item {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  font-size: 14px;
-}
-
-.color-indicator {
-  display: inline-block;
-  width: 12px;
-  height: 12px;
-  border-radius: 50%;
-}
-
-.color-indicator.red {
-  background-color: red;
-}
-
-.color-indicator.orange {
-  background-color: orange;
-}
-
-/* 在原有样式基础上添加黄色指示器 */
-.color-indicator.yellow {
-  background-color: #0a35c4; /* 黄色,与警告颜色一致 */
-}
-</style>
-
-<style>
-/* 设计井身结构 tooltip 样式 - 保留换行符 */
-.design-well-struct-tooltip {
-  max-width: 500px;
-  line-height: 1.5;
-  white-space: pre-line;
-}
-</style>

+ 127 - 71
src/views/pms/iotrydailyreport/xsummary.vue

@@ -301,95 +301,151 @@ onUnmounted(() => {
   window.removeEventListener('resize', resizer)
 })
 
-const render = () => {
-  if (!chartRef.value) return
-
-  chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })
-
-  window.addEventListener('resize', resizer)
-
-  const values: number[] = []
-
-  for (const [_name, key] of legend.value) {
-    values.push(...(chartData.value[key] || []))
+const selectedLegends = ref<Record<string, boolean>>({})
+const intervalArr = ref<number[]>([])
+const maxInterval = ref(0)
+const minInterval = ref(0)
+
+const calcIntervals = () => {
+  let maxVal = -Infinity
+  let minVal = Infinity
+  let hasData = false
+
+  for (const [name, key] of legend.value) {
+    if (selectedLegends.value[name] !== false) {
+      const dataset = chartData.value[key] || []
+      if (dataset.length > 0) {
+        hasData = true
+        for (const val of dataset) {
+          if (val > maxVal) maxVal = val
+          if (val < minVal) minVal = val
+        }
+      }
+    }
   }
 
-  const maxVal = values.length === 0 ? 10000 : Math.max(...values)
-  const minVal = values.length === 0 ? 0 : Math.min(...values) > 0 ? 0 : Math.min(...values)
+  if (!hasData) {
+    maxVal = 10000
+    minVal = 0
+  } else {
+    minVal = minVal > 0 ? 0 : minVal
+  }
 
   const maxDigits = (Math.floor(maxVal) + '').length
   const minDigits = minVal === 0 ? 0 : (Math.floor(Math.abs(minVal)) + '').length
   const interval = Math.max(maxDigits, minDigits)
 
-  const maxInterval = interval
-  const minInterval = minDigits
+  maxInterval.value = interval
+  minInterval.value = minDigits
 
-  const intervalArr = [0]
+  const arr = [0]
   for (let i = 1; i <= interval; i++) {
-    intervalArr.push(Math.pow(10, i))
+    arr.push(Math.pow(10, i))
   }
+  intervalArr.value = arr
+}
 
-  chart.setOption({
-    tooltip: {
-      trigger: 'axis',
-      axisPointer: {
-        type: 'line'
-      },
-      formatter: (params) => {
-        let d = `${params[0].axisValueLabel}<br>`
-        let item = params.map((el) => {
-          return `<div class="flex items-center justify-between mt-1 gap-1">
-            <span>${el.marker} ${el.seriesName}</span>
-            <span>${chartData.value[legend.value[el.componentIndex][1]][el.dataIndex].toFixed(2)} ${el.seriesName.split(' ')[1]}</span>
-          </div>`
-        })
+const mapDataValue = (value: number) => {
+  if (value === 0) return 0
 
-        return d + item.join('')
-      }
-    },
-    legend: {
-      data: legend.value.map(([name]) => name),
-      show: true
-    },
-    xAxis: {
-      type: 'category',
-      data: xAxisData.value
-    },
-    yAxis: {
-      type: 'value',
-      min: -minInterval,
-      max: maxInterval,
-      interval: 1,
-      axisLabel: {
-        formatter: (v) => {
-          const num = v === 0 ? 0 : v > 0 ? Math.pow(10, v) : -Math.pow(10, -v)
-
-          return num.toLocaleString()
-        }
-      }
-    },
-    series: legend.value.map(([name, key]) => ({
-      name,
-      type: 'line',
-      smooth: true,
-      showSymbol: true,
-      data: chartData.value[key].map((value) => {
-        // return value
-        if (value === 0) return 0
+  const isPositive = value > 0
+  const absItem = Math.abs(value)
 
-        const isPositive = value > 0
-        const absItem = Math.abs(value)
+  if (!intervalArr.value.length) return value
 
-        const min_value = Math.max(...intervalArr.filter((v) => v <= absItem))
-        const min_index = intervalArr.findIndex((v) => v === min_value)
+  const min_value = Math.max(...intervalArr.value.filter((v) => v <= absItem))
+  const min_index = intervalArr.value.findIndex((v) => v === min_value)
 
-        const new_value =
-          (absItem - min_value) / (intervalArr[min_index + 1] - intervalArr[min_index]) + min_index
+  const denominator =
+    min_index < intervalArr.value.length - 1
+      ? intervalArr.value[min_index + 1] - intervalArr.value[min_index]
+      : intervalArr.value[min_index] || 1
+
+  const new_value = (absItem - min_value) / denominator + min_index
+
+  return isPositive ? new_value : -new_value
+}
 
-        return isPositive ? new_value : -new_value
+const getSeries = () => {
+  return legend.value.map(([name, key]) => ({
+    name,
+    type: 'line',
+    smooth: true,
+    showSymbol: true,
+    data: chartData.value[key].map((value) => mapDataValue(value))
+  }))
+}
+
+const render = () => {
+  if (!chartRef.value) return
+
+  if (!chart) {
+    chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })
+    window.addEventListener('resize', resizer)
+
+    chart.on('legendselectchanged', (params: any) => {
+      selectedLegends.value = params.selected
+
+      calcIntervals()
+
+      chart?.setOption({
+        yAxis: {
+          min: -minInterval.value,
+          max: maxInterval.value
+        },
+        series: getSeries()
       })
-    }))
+    })
+  }
+
+  legend.value.forEach(([name]) => {
+    selectedLegends.value[name] = true
   })
+
+  calcIntervals()
+
+  chart.setOption(
+    {
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: { type: 'line' },
+        formatter: (params: any) => {
+          let d = `${params[0].axisValueLabel}<br>`
+          let item = params.map((el: any) => {
+            const realValue = chartData.value[legend.value[el.componentIndex][1]][el.dataIndex]
+            return `<div class="flex items-center justify-between mt-1 gap-1">
+            <span>${el.marker} ${el.seriesName}</span>
+            <span>${realValue.toFixed(2)} ${el.seriesName.split(' ')[1] || ''}</span>
+          </div>`
+          })
+          return d + item.join('')
+        }
+      },
+      legend: {
+        data: legend.value.map(([name]) => name),
+        selected: selectedLegends.value,
+        show: true
+      },
+      xAxis: {
+        type: 'category',
+        data: xAxisData.value
+      },
+      yAxis: {
+        type: 'value',
+        min: -minInterval.value,
+        max: maxInterval.value,
+        interval: 1,
+        axisLabel: {
+          formatter: (v: number) => {
+            const num = v === 0 ? 0 : v > 0 ? Math.pow(10, v) : -Math.pow(10, -v)
+            return num.toLocaleString()
+          }
+        }
+      },
+      series: getSeries()
+    },
+    true
+  )
 }
 
 const handleDeptNodeClick = (node: any) => {

+ 228 - 80
src/views/test/index.vue

@@ -1,96 +1,244 @@
 <script lang="ts" setup>
-import { IotDeviceApi } from '@/api/pms/device'
-import { SortField } from '@/components/ZmTable/token'
-import { useTableComponents } from '@/components/ZmTable/useTableComponents'
-import { DICT_TYPE, getDictOptions } from '@/utils/dict'
-
-interface List {
-  id: number
-  yfDeviceCode: string // 油服编码
-  deviceCode: string // 历史编码
-  deviceName: string // 设备名称
-  deptName: string // 所在部门
-  deviceStatus: string // 设备状态
-  assetProperty: string // 资产性质
-  assetClassName: string // 资产类别
-  manufacturer: string // 制造商
-  brandName: string // 品牌
-  model: string // 规格型号
-  chargeName: string // 负责人
-  useProject: string // 使用项目
-  assetOwnership: string // 资产归属
-}
+import { ref, onMounted, onUnmounted } from 'vue'
+import { Graph } from '@antv/x6'
 
-const loading = ref(false)
-const list = ref<List[]>([])
-const total = ref(0)
+const containerRef = ref<HTMLDivElement>()
+let graph: Graph | null = null
 
-const query = ref<Partial<List> & { pageNo: number; pageSize: number; sortingFields: SortField[] }>(
+// 1. 注册自定义节点
+Graph.registerNode(
+  'custom-node',
   {
-    pageNo: 1,
-    pageSize: 10,
-    sortingFields: []
-  }
+    attrs: {
+      body: { refWidth: 1, refHeight: 1, rx: 4 }
+    },
+    markup: [
+      { tagName: 'rect', selector: 'body' },
+      { tagName: 'path', selector: 'icon' },
+      { tagName: 'text', selector: 'title' }
+    ]
+  },
+  true
 )
 
-const getList = async () => {
-  loading.value = true
-  try {
-    const data = await IotDeviceApi.getIotDevicePage(query.value)
-    list.value = data.list
-    total.value = data.total
-  } finally {
-    loading.value = false
+// 2. 抽离通用样式配置 (DRY原则,消除重复)
+const commonNodeAttrs = {
+  body: {
+    fill: {
+      type: 'linearGradient',
+      stops: [
+        { offset: '0%', color: 'rgba(10, 30, 60, 0.9)' },
+        { offset: '100%', color: 'rgba(4, 10, 25, 0.9)' }
+      ]
+    },
+    stroke: '#00EAFF',
+    strokeWidth: 2,
+    rx: 6,
+    filter: {
+      name: 'dropShadow',
+      args: { dx: 0, dy: 0, blur: 15, color: '#00EAFF' }
+    }
+  },
+  icon: {
+    fill: '#00EAFF',
+    refX: 0.5,
+    refY: 0.4,
+    xAlign: 'middle',
+    yAlign: 'middle',
+    transform: 'scale(3)'
+  },
+  title: {
+    fill: '#FFFFFF',
+    fontSize: 18,
+    fontWeight: 'bold',
+    letterSpacing: 4,
+    refX: 0.5,
+    refY: 0.8,
+    textAnchor: 'middle',
+    textVerticalAnchor: 'middle'
   }
 }
 
-getList()
+// 3. 集中管理节点数据和 SVG 图标路径
+const ICONS = {
+  compressor:
+    'M10.6 22q-1.275 0-1.937-.763T8 19.5q0-.65.288-1.263t.887-1.012q.55-.35.888-.9t.462-1.175l-.3-.15q-.15-.075-.275-.175l-2.3.825q-.425.15-.825.25T6 16q-1.575 0-2.788-1.375T2 10.6q0-1.275.763-1.937T4.475 8q.65 0 1.275.288t1.025.887q.35.55.9.887t1.175.463l.15-.3q.075-.15.175-.275l-.825-2.3q-.15-.425-.25-.825t-.1-.8q0-1.6 1.375-2.813T13.4 2q1.275 0 1.938.763T16 4.475q0 .65-.288 1.275t-.887 1.025q-.55.35-.887.9t-.463 1.175l.3.15q.15.075.275.175l2.3-.85q.425-.15.813-.237T17.975 8Q20 8 21 9.675t1 3.725q0 1.275-.8 1.938T19.425 16q-.625 0-1.213-.288t-.987-.887q-.35-.55-.9-.887t-1.175-.463l-.15.3q-.075.15-.175.275l.825 2.3q.15.4.25.763t.1.762q.025 1.625-1.35 2.875T10.6 22m1.4-8.5q.625 0 1.062-.437T13.5 12t-.437-1.062T12 10.5t-1.062.438T10.5 12t.438 1.063T12 13.5',
+  airSkid:
+    'M14.5 17c0 1.65-1.35 3-3 3s-3-1.35-3-3h2c0 .55.45 1 1 1s1-.45 1-1s-.45-1-1-1H2v-2h9.5c1.65 0 3 1.35 3 3M19 6.5C19 4.57 17.43 3 15.5 3S12 4.57 12 6.5h2c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5S16.33 8 15.5 8H2v2h13.5c1.93 0 3.5-1.57 3.5-3.5m-.5 4.5H2v2h16.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5v2c1.93 0 3.5-1.57 3.5-3.5S20.43 11 18.5 11',
+  psa: 'M3 21q-.825 0-1.412-.587T1 19v-5q0-.825.588-1.412T3 12V7.725q-.45-.275-.725-.712T2 6V5q0-.825.588-1.412T4 3h5q.825 0 1.413.588T11 5v1q0 .575-.275 1.013T10 7.725V12h4V7.725q-.45-.275-.725-.712T13 6V5q0-.825.588-1.412T15 3h5q.825 0 1.413.588T22 5v1q0 .575-.275 1.013T21 7.725V12q.825 0 1.413.588T23 14v5q0 .825-.587 1.413T21 21zm13-9h3V8h-3zM5 12h3V8H5z',
+  supercharger:
+    'M11.25 16.95V13.8l-2.225 2.225q.5.35 1.063.575t1.162.35m1.5-.025q.6-.1 1.163-.325t1.062-.575L12.75 13.8zm3.275-1.95q.35-.5.563-1.062t.337-1.163H13.8zM13.8 11.25h3.125q-.125-.575-.338-1.137t-.562-1.063zm-1.05-1.05l2.225-2.225q-.5-.35-1.063-.575t-1.162-.35zm-.038 2.513Q13 12.425 13 12t-.288-.712T12 11t-.712.288T11 12t.288.713T12 13t.713-.288M11.25 10.2V7.075q-.6.1-1.162.325t-1.063.575zm-4.175 1.05H10.2l-2.225-2.2q-.35.5-.575 1.05t-.325 1.15m.9 3.725L10.2 12.75H7.05q.125.6.35 1.163t.575 1.062M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h14q.825 0 1.413.588T21 5v14q0 .825-.587 1.413T19 21z',
+  waterPump:
+    'm12 9l-.85 1.25q-.675 1.05-.913 1.613T10 13q0 .825.588 1.413T12 15t1.413-.587T14 13q0-.575-.238-1.137t-.912-1.613zm-4.425 7.425Q5.75 14.6 5.75 12t1.825-4.425T12 5.75t4.425 1.825T18.25 12t-1.825 4.425T12 18.25t-4.425-1.825M21 12v-1h-1.325q-.275-2-1.437-3.588T15.325 5H21V4h2v8zM1 20v-8h2v1h1.325q.275 2 1.438 3.588T8.675 19H3v1z',
+  pipe: 'M16 9v2H8V9h2V8H4v2H2V2h2v2h8a2 2 0 0 1 2 2v3zm-6 6v3a2 2 0 0 0 2 2h8v2h2v-8h-2v2h-6v-1h2v-2H8v2z'
+}
 
-const { ZmTable, ZmTableColumn } = useTableComponents<List>()
+const nodesData = [
+  { id: 'ac1', title: '空压机', x: 40, y: 40, icon: ICONS.compressor },
+  { id: 'ac2', title: '空压机', x: 40, y: 280, icon: ICONS.compressor },
+  { id: 'ac3', title: '空压机', x: 40, y: 520, icon: ICONS.compressor },
+  { id: 'Air', title: '空气处理橇', x: 280, y: 280, icon: ICONS.airSkid },
+  { id: 'PSA', title: 'PSA', x: 520, y: 280, icon: ICONS.psa }, // 注意:原代码这里标题写的是空气处理橇,但图标是PSA,请确认是否需改名
+  { id: 'supercharger', title: '增压机', x: 760, y: 280, icon: ICONS.supercharger },
+  { id: 'waterpump1', title: '注水泵', x: 520, y: 680, icon: ICONS.waterPump },
+  { id: 'waterpump2', title: '注水泵', x: 520, y: 920, icon: ICONS.waterPump },
+  { id: 'casing', title: '套管', x: 1220, y: 680, icon: ICONS.pipe },
+  { id: 'olitube', title: '油管', x: 1220, y: 920, icon: ICONS.pipe }
+]
 
-const realValue = (value: string) => {
-  const option = getDictOptions(DICT_TYPE.PMS_ASSET_PROPERTY).find((item) => item.value === value)
-  return option?.label || value
-}
+const edgesData = [
+  // 三个空压机流向空气处理橇
+  { source: 'ac1', target: 'Air' },
+  { source: 'ac2', target: 'Air' },
+  { source: 'ac3', target: 'Air' },
+
+  // 空气处理橇 -> PSA -> 增压机
+  { source: 'Air', target: 'PSA' },
+  { source: 'PSA', target: 'supercharger' },
+
+  { source: 'supercharger', target: 'casing' },
+  { source: 'supercharger', target: 'olitube' },
+
+  { source: 'waterpump1', target: 'casing' },
+  { source: 'waterpump2', target: 'olitube' }
+]
+
+onMounted(() => {
+  if (!containerRef.value) return
+
+  graph = new Graph({
+    container: containerRef.value,
+    autoResize: true,
+    background: { color: '#0B1120' }, // 建议配合高科技风格改为暗色背景
+    grid: {
+      visible: true,
+      type: 'dot',
+      size: 20,
+      args: { color: '#1F3A5F', thickness: 2 } // 网格也调整为暗色系
+    },
+    mousewheel: false
+  })
+
+  // 4. 遍历数据批量生成节点
+  nodesData.forEach((node) => {
+    graph!.addNode({
+      id: node.id,
+      shape: 'custom-node',
+      x: node.x,
+      y: node.y,
+      width: 150,
+      height: 160,
+      attrs: {
+        body: commonNodeAttrs.body,
+        icon: { ...commonNodeAttrs.icon, d: node.icon },
+        title: { ...commonNodeAttrs.title, text: node.title }
+      }
+    })
+  })
+  edgesData.forEach((edge) => {
+    graph!.addEdge({
+      // 1. 核心优化:固定线条的起点和终点位置
+      source: {
+        cell: edge.source,
+        anchor: 'right' // 强制从右侧出
+      },
+      target: {
+        cell: edge.target,
+        anchor: 'left' // 强制从左侧入
+      },
+
+      // 2. 核心优化:使用曼哈顿路由规划线条走向,避免斜线穿插
+      router: {
+        name: 'manhattan',
+        args: {
+          padding: 30, // 线条拐弯处距离节点的缓冲间距
+          startDirections: ['right'], // 限制首段线条向右
+          endDirections: ['left'] // 限制末段线条向左
+        }
+      },
+
+      // 3. 连接器:在直角拐弯处增加大圆角,完美代替原先的 smooth,保留流体感
+      connector: {
+        name: 'rounded',
+        args: { radius: 24 } // 圆角半径可以根据喜好调大调小
+      },
+      markup: [
+        {
+          tagName: 'path',
+          selector: 'line'
+        }
+      ],
+      attrs: {
+        line: {
+          connection: true,
+          strokeWidth: 5,
+          strokeLinecap: 'round',
+
+          targetMarker: {
+            name: 'classic',
+            size: 16,
+            fill: '#00EAFF',
+            stroke: 'none',
+            offset: -4
+          },
+
+          strokeDasharray: '10, 20',
+          fill: 'none',
+
+          stroke: {
+            type: 'linearGradient',
+            stops: [
+              { offset: '0%', color: '#0A1E3C', opacity: 0.8 }, // 起点:与节点背景融合的暗色
+              { offset: '50%', color: '#0077FF', opacity: 0.8 }, // 中段:纯正科技蓝
+              { offset: '100%', color: '#00EAFF', opacity: 1 } // 终点:高亮青色,能量注入箭头
+            ]
+          }
+        }
+      },
+
+      animation: [
+        [
+          {
+            'attrs/line/opacity': [0.7, 1]
+          },
+          {
+            duration: 1000,
+            fill: 'forwards',
+            direction: 'alternate',
+            iterations: Infinity
+          }
+        ],
+        [
+          {
+            'attrs/line/strokeDashoffset': [30, 0]
+          },
+          {
+            duration: 500, // 800ms 匀速流动,不会太晃眼
+            iterations: Infinity
+          }
+        ]
+      ]
+    })
+  })
+})
+
+// 5. 页面销毁时清理画布,释放内存
+onUnmounted(() => {
+  if (graph) {
+    graph.dispose()
+  }
+})
 </script>
 
 <template>
-  <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg p-4 flex flex-col mt-4">
-    <zm-table
-      :data="list"
-      :loading="loading"
-      :handle-query="getList"
-      v-model:sorting-fields="query.sortingFields"
-    >
-      <zm-table-column
-        zm-filterable
-        v-model:filter-model-value="query.yfDeviceCode"
-        zm-sortable
-        prop="yfDeviceCode"
-        label="油服编码"
-      />
-      <zm-table-column zm-filterable zm-sortable prop="deviceCode" label="历史编码" />
-      <zm-table-column zm-filterable zm-sortable prop="deviceName" label="设备名称" />
-      <zm-table-column zm-filterable zm-sortable prop="deptName" label="所在部门" />
-      <zm-table-column zm-filterable zm-sortable prop="deviceStatus" label="设备状态" />
-      <zm-table-column
-        zm-filterable
-        zm-sortable
-        prop="assetProperty"
-        label="资产性质"
-        :real-value="realValue"
-      >
-        <template #default="scope">
-          <dict-tag :type="DICT_TYPE.PMS_ASSET_PROPERTY" :value="scope.row.assetProperty" />
-        </template>
-      </zm-table-column>
-      <zm-table-column zm-filterable zm-sortable prop="assetClassName" label="资产类别" />
-      <zm-table-column zm-filterable zm-sortable prop="manufacturer" label="制造商" />
-      <zm-table-column zm-filterable zm-sortable prop="brandName" label="品牌" />
-      <zm-table-column zm-filterable zm-sortable prop="model" label="规格型号" />
-      <zm-table-column zm-filterable zm-sortable prop="chargeName" label="负责人" />
-      <zm-table-column zm-filterable zm-sortable prop="useProject" label="使用项目" />
-      <zm-table-column zm-filterable zm-sortable prop="assetOwnership" label="资产归属" />
-    </zm-table>
+  <div
+    class="h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
+  >
+    <div
+      class="w-full h-full border-1 border-solid border-gray-300 rounded-lg shadow"
+      ref="containerRef"
+    ></div>
   </div>
 </template>
+
+<style scoped></style>