Преглед изворни кода

Merge branch 'dailyreport'

zhangcl пре 2 дана
родитељ
комит
126e8c9104

+ 5 - 0
src/api/system/dept/index.ts

@@ -20,6 +20,11 @@ export const getSimpleDeptList = async (): Promise<DeptVO[]> => {
   return await request.get({ url: '/system/dept/simple-list' })
 }
 
+// 获取指定部门精简信息列表
+export const specifiedSimpleDepts = async (deptId: number): Promise<DeptVO[]> => {
+  return await request.get({ url: '/system/dept/specifiedSimpleDepts?deptId=' + deptId  })
+}
+
 // 查询当前用户所属的公司级部门列表 项目 日报
 export const companyLevelDepts = async (): Promise<DeptVO[]> => {
   return await request.get({ url: '/system/dept/companyLevelDepts' })

+ 5 - 1
src/utils/dict.ts

@@ -287,7 +287,11 @@ export enum DICT_TYPE {
   PMS_PROJECT_WELL_TYPE = 'rq_iot_project_well_type',  // 日报 项目管理 井型
   PMS_PROJECT_WELL_CATEGORY = 'rq_iot_project_well_category',  // 日报 项目管理 井别
   PMS_PROJECT_TECHNOLOGY = 'rq_iot_project_technology',  // 日报 项目管理 施工工艺
+  PMS_PROJECT_RY_TECHNOLOGY = 'rq_iot_project_technology_ry', // 瑞鹰施工工艺
   PMS_PROJECT_WORKLOAD_UNIT = 'rq_iot_project_measure_unit',  // 日报 项目管理 工作量单位
   PMS_PROJECT_WORK_AREA = 'rq_iot_project_work_area',     // 日报 施工区域
-  PMS_PROJECT_NPT_REASON = 'nptReason'  // 日报 非生产时间原因
+  PMS_PROJECT_NPT_REASON = 'nptReason',    // 日报 非生产时间原因
+  PMS_PROJECT_RY_NPT_REASON = 'ryNptReason',  // 瑞鹰日报 非生产时间原因
+  PMS_PROJECT_WELL_CONTROL_LEVEL = 'rq_iot_well_control_level',  // 井控级别
+  PMS_PROJECT_casing_pipe_size = 'rq_iot_casing_pipe_size'  // 日报 套生段产管尺寸
 }

+ 145 - 0
src/views/pms/iotrhdailyreport/DeptTree2.vue

@@ -0,0 +1,145 @@
+<template>
+  <div class="head-container" style="display: flex;flex-direction: row;">
+    <el-input v-model="deptName" class="mb-18px" clearable placeholder="请输入部门名称">
+      <template #prefix>
+        <Icon icon="ep:search" />
+      </template>
+    </el-input>
+  </div>
+  <div ref="treeContainer" class="tree-container">
+    <el-tree
+      ref="treeRef"
+      :data="deptList"
+      :expand-on-click-node="false"
+      :filter-node-method="filterNode"
+      :props="defaultProps"
+      :default-expanded-keys="firstLevelKeys"
+      highlight-current
+      node-key="id"
+      @node-click="handleNodeClick"
+      @node-contextmenu="handleRightClick"
+      style="height: 52em"
+    />
+  </div>
+  <div
+    v-show="menuVisible"
+    class="custom-menu"
+    :style="{ left: menuX + 'px', top: menuY + 'px' }"
+  >
+    <ul>
+      <li @click="handleMenuClick('add')">新增子节点</li>
+      <li @click="handleMenuClick('edit')">重命名</li>
+      <li @click="handleMenuClick('delete')">删除</li>
+    </ul>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ElTree } from 'element-plus'
+import * as DeptApi from '@/api/system/dept'
+import { defaultProps, handleTree } from '@/utils/tree'
+import { useTreeStore } from '@/store/modules/usersTreeStore'
+import {specifiedSimpleDepts} from "@/api/system/dept";
+defineOptions({ name: 'DeptTree2' })
+
+const deptName = ref('')
+const deptList = ref<Tree[]>([]) // 树形结构
+const treeRef = ref<InstanceType<typeof ElTree>>()
+const menuVisible = ref(false);
+const menuX = ref(0);
+const menuY = ref(0);
+const firstLevelKeys = ref([])
+let selectedNode = null;
+const treeStore = useTreeStore();
+
+const handleRightClick = (event, { node, data }) => {
+  event.preventDefault();
+  menuX.value = event.clientX;
+  menuY.value = event.clientY;
+  selectedNode = data; // 存储当前操作的节点数据 ‌:ml-citation{ref="7" data="citationList"}
+  //menuVisible.value = true;
+};
+const treeContainer = ref(null)
+const setHeight = () => {
+  if (!treeContainer.value) return
+  const windowHeight = window.innerHeight
+  const containerTop = treeContainer.value.offsetTop
+  treeContainer.value.style.height = `${windowHeight * 0.78}px` // 60px 底部预留
+}
+const handleMenuClick = (action) => {
+  switch(action) {
+    case 'add':
+      // 调用新增节点逻辑 ‌:ml-citation{ref="4" data="citationList"}
+      break;
+    case 'edit':
+      // 调用编辑节点逻辑 ‌:ml-citation{ref="7" data="citationList"}
+      break;
+    case 'delete':
+      // 调用删除节点逻辑 ‌:ml-citation{ref="4" data="citationList"}
+      break;
+  }
+  menuVisible.value = false;
+};
+/** 获得部门树 */
+const getTree = async () => {
+  const res = await DeptApi.specifiedSimpleDepts(157)
+  deptList.value = []
+  deptList.value.push(...handleTree(res))
+  firstLevelKeys.value = deptList.value.map(node => node.id);
+}
+
+/** 基于名字过滤 */
+const filterNode = (name: string, data: Tree) => {
+  if (!name) return true
+  return data.name.includes(name)
+}
+
+/** 处理部门被点击 */
+const handleNodeClick = async (row: { [key: string]: any }) => {
+  emits('node-click', row)
+  treeStore.setSelectedId(row.id);
+}
+const emits = defineEmits(['node-click'])
+
+/** 监听deptName */
+watch(deptName, (val) => {
+  treeRef.value!.filter(val)
+})
+
+/** 初始化 */
+onMounted(async () => {
+  await getTree()
+  setHeight()
+  window.addEventListener('resize', setHeight)
+})
+onUnmounted(() => {
+  window.removeEventListener('resize', setHeight)
+})
+</script>
+<style lang="scss" scoped>
+.custom-menu {
+  position: fixed;
+  background: white;
+  border: 1px solid #ccc;
+  box-shadow: 2px 2px 5px rgba(0,0,0,0.1);
+  z-index: 1000;
+}
+.custom-menu ul {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+.custom-menu li {
+  padding: 8px 20px;
+  cursor: pointer;
+}
+.custom-menu li:hover {
+  background: #f5f5f5;
+}
+.tree-container {
+  overflow-y: auto;
+  min-width: 100%;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+}
+</style>

+ 23 - 6
src/views/pms/iotrhdailyreport/index.vue

@@ -2,7 +2,7 @@
   <el-row :gutter="20">
     <el-col :span="4" :xs="24">
       <ContentWrap class="h-1/1">
-        <DeptTree @node-click="handleDeptNodeClick" />
+        <DeptTree2 @node-click="handleDeptNodeClick" />
       </ContentWrap>
     </el-col>
     <el-col :span="20" :xs="24">
@@ -95,11 +95,12 @@
               label="日期"
               align="center"
               prop="createTime"
-              :formatter="dateFormatter2"
+              :formatter="dateFormatter"
               :width="columnWidths.createTime"
             />
             <el-table-column label="施工队伍" align="center" prop="deptName" :width="columnWidths.deptName"/>
-            <el-table-column label="项目" align="center" prop="contractName" :width="columnWidths.contractName"/>
+            <el-table-column label="项目" align="center" prop="contractName" :width="columnWidths.contractName"
+                             :show-overflow-tooltip="true" class-name="contract-name-column"/>
             <el-table-column label="任务" align="center" prop="taskName" :width="columnWidths.taskName"/>
             <!-- <el-table-column label="施工状态" align="center" prop="constructionStatus" /> -->
             <el-table-column :label="t('project.status')" align="center" prop="constructionStatus" :width="columnWidths.constructionStatus">
@@ -199,7 +200,7 @@ import { IotRhDailyReportApi, IotRhDailyReportVO } from '@/api/pms/iotrhdailyrep
 import IotRhDailyReportForm from './IotRhDailyReportForm.vue'
 import {DICT_TYPE, getDictLabel} from "@/utils/dict";
 import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue'
-import DeptTree from "@/views/system/user/DeptTree.vue";
+import DeptTree2 from "@/views/pms/iotrhdailyreport/DeptTree2.vue";
 
 /** 瑞恒日报 列表 */
 defineOptions({ name: 'IotRhDailyReport' })
@@ -260,7 +261,7 @@ const tableContainerRef = ref()
 // 列宽度配置
 const columnWidths = ref({
   deptName: '120px',
-  contractName: '150px',
+  contractName: '200px',
   taskName: '120px',
   constructionStatus: '110px',
   relocationDays: '120px',
@@ -316,7 +317,7 @@ const percentageFormatter = (row: any, column: any, cellValue: any, index: numbe
 };
 
 // 可伸缩列配置
-const FLEXIBLE_COLUMNS = ['deptName', 'contractName', 'taskName', 'constructionStatus', 'relocationDays', 'designInjection',
+const FLEXIBLE_COLUMNS = ['deptName', 'taskName', 'constructionStatus', 'relocationDays', 'designInjection',
   'transitTime', 'dailyGasInjection', 'dailyWaterInjection', 'dailyPowerUsage', 'dailyInjectGasTime',
   'dailyInjectWaterTime', 'nonProductionTime', 'nptReason', 'constructionStartDate',
   'constructionEndDate', 'productionStatus', 'totalGasInjection', 'totalWaterInjection',
@@ -409,6 +410,13 @@ const calculateColumnWidths = () => {
 
   // 计算列最小宽度的函数
   const calculateColumnMinWidth = (key: string, label: string, getValue: Function) => {
+    // 跳过 contractName 列的计算,使用固定宽度
+    if (key === 'contractName') {
+      minWidths[key] = 200; // 固定宽度
+      totalMinWidth += 200;
+      return 200;
+    }
+
     const headerWidth = getTextWidth(label) * 1.2;
     let contentMaxWidth = 0;
 
@@ -496,6 +504,9 @@ const calculateColumnWidths = () => {
     });
   }
 
+  // 确保 contractName 保持固定宽度
+  newWidths.contractName = '200px';
+
   // 3. 更新列宽配置
   columnWidths.value = newWidths;
 
@@ -645,6 +656,12 @@ watch(list, () => {
   text-overflow: clip !important;
 }
 
+:deep(.contract-name-column .cell) {
+  overflow: hidden !important;
+  text-overflow: ellipsis !important;
+  white-space: nowrap !important;
+}
+
 /* 颜色说明区域样式 */
 .color-legend {
   display: flex;

+ 2 - 2
src/views/pms/iotrydailyreport/IotRyDailyReportForm.vue

@@ -19,7 +19,7 @@
       <el-form-item :label="t('project.status')" prop="rigStatus">
         <el-select v-model="formData.rigStatus" placeholder="请选择" clearable>
           <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.PMS_PROJECT_TASK_RY_SCHEDULE)"
+            v-for="dict in getStrDictOptions(DICT_TYPE.PMS_PROJECT_TASK_RY_SCHEDULE)"
             :key="dict.id"
             :label="dict.label"
             :value="dict.value"
@@ -98,7 +98,7 @@
 </template>
 <script setup lang="ts">
 import { IotRyDailyReportApi, IotRyDailyReportVO } from '@/api/pms/iotrydailyreport'
-import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
+import {DICT_TYPE, getStrDictOptions} from "@/utils/dict";
 import { computed, ref, watch, nextTick, reactive } from 'vue'
 
 /** 瑞鹰日报 表单 */

+ 301 - 0
src/views/pms/iotrydailyreport/IotRyXjDailyReportForm.vue

@@ -0,0 +1,301 @@
+<template>
+  <Dialog :title="dialogTitle" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="120px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="施工队伍" prop="deptName">
+        <el-input v-model="displayData.deptName" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item label="项目" prop="contractName">
+        <el-input v-model="displayData.contractName" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item label="任务" prop="taskName">
+        <el-input v-model="displayData.taskName" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item :label="t('project.status')" prop="rigStatus">
+        <el-select v-model="formData.rigStatus" placeholder="请选择" clearable>
+          <el-option
+            v-for="dict in getStrDictOptions(DICT_TYPE.PMS_PROJECT_TASK_RY_SCHEDULE)"
+            :key="dict.id"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="上井次完井时间" prop="latestWellDoneTime">
+        <el-date-picker
+          v-model="formData.latestWellDoneTime"
+          type="date"
+          value-format="x"
+          placeholder=""
+          disabled
+        />
+      </el-form-item>
+      <el-form-item label="设计井深(m)" prop="designWellDepth">
+        <el-input v-model="displayData.designWellDepth" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item label="当前井深(m)" prop="currentDepth">
+        <el-input v-model="formData.currentDepth" placeholder="请输入当前井深(m)" />
+      </el-form-item>
+      <el-form-item label="日进尺(m)" prop="dailyFootage">
+        <el-input v-model="formData.dailyFootage" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item label="月进尺(m)" prop="monthlyFootage">
+        <el-input v-model="formData.monthlyFootage" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item label="年累计进尺(m)" prop="annualFootage">
+        <el-input v-model="formData.annualFootage" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item label="当日用电量(kWh)" prop="dailyPowerUsage">
+        <el-input v-model="formData.dailyPowerUsage" placeholder="请输入当日用电量(kWh)" />
+      </el-form-item>
+      <el-form-item label="当日油耗(吨)" prop="dailyFuel">
+        <el-input v-model="formData.dailyFuel" placeholder="请输入当日油耗(吨)" />
+      </el-form-item>
+      <el-form-item label="总施工井数" prop="monthlyFuel">
+        <el-input v-model="displayData.totalConstructionWells" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item label="完工井数" prop="completedWells">
+        <el-input v-model="displayData.completedWells" placeholder="" disabled/>
+      </el-form-item>
+      <el-form-item label="泥浆密度(g/cm³)" prop="mudDensity">
+        <el-input v-model="formData.mudDensity" placeholder="请输入泥浆性能-密度(g/cm³)" />
+      </el-form-item>
+      <el-form-item label="泥浆粘度(S)" prop="mudViscosity">
+        <el-input v-model="formData.mudViscosity" placeholder="请输入泥浆性能-粘度(S)" />
+      </el-form-item>
+      <el-form-item label="水平段长度(m)" prop="lateralLength">
+        <el-input v-model="formData.lateralLength" placeholder="请输入水平段长度(m)" />
+      </el-form-item>
+      <el-form-item label="井斜(°)" prop="wellInclination">
+        <el-input v-model="formData.wellInclination" placeholder="请输入井斜(°)" />
+      </el-form-item>
+      <el-form-item label="方位(°)" prop="azimuth">
+        <el-input v-model="formData.azimuth" placeholder="请输入方位(°)" />
+      </el-form-item>
+      <el-form-item label="设计井身结构" prop="designWellStruct">
+        <el-input v-model="displayData.designWellStruct" placeholder="" type="textarea" disabled/>
+      </el-form-item>
+      <el-form-item label="生产动态" prop="productionStatus">
+        <el-input v-model="formData.productionStatus" placeholder="请输入生产动态" type="textarea"/>
+      </el-form-item>
+      <el-form-item label="人员情况" prop="personnel">
+        <el-input v-model="formData.personnel" placeholder="请输入人员情况" type="textarea"/>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input v-model="formData.remark" placeholder="请输入备注" type="textarea"/>
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script setup lang="ts">
+import { IotRyDailyReportApi, IotRyDailyReportVO } from '@/api/pms/iotrydailyreport'
+import {DICT_TYPE, getStrDictOptions} from "@/utils/dict";
+import { computed, ref, watch, nextTick, reactive } from 'vue'
+
+/** 瑞鹰日报 表单 */
+defineOptions({ name: 'IotRyXjDailyReportForm' })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+// 添加 props 接收行数据
+const props = defineProps({
+  rowData: {
+    type: Object,
+    default: () => ({})
+  }
+})
+
+// 监听 props.rowData 的变化
+watch(() => props.rowData, (newVal) => {
+  if (newVal) {
+    displayData.value.deptName = newVal.deptName || ''
+    displayData.value.contractName = newVal.contractName || ''
+    displayData.value.taskName = newVal.taskName || ''
+    displayData.value.designWellDepth = newVal.designWellDepth || ''
+    displayData.value.designWellStruct = newVal.designWellStruct || ''
+    displayData.value.totalConstructionWells = newVal.totalConstructionWells || ''
+    displayData.value.completedWells = newVal.completedWells || ''
+  }
+}, { immediate: true })
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+
+// 添加显示数据对象
+const displayData = ref({
+  deptName: '',
+  contractName: '',
+  taskName: '',
+  designWellDepth: '',
+  designWellStruct: '',
+  totalConstructionWells: '',
+  completedWells: ''
+})
+
+const formData = ref({
+  id: undefined,
+  deptId: undefined,
+  projectId: undefined,
+  taskId: undefined,
+  projectClassification: undefined,
+  relocationDays: undefined,
+  latestWellDoneTime: undefined,
+  designWellDepth: undefined,
+  currentDepth: undefined,
+  dailyFootage: undefined,
+  monthlyFootage: undefined,
+  annualFootage: undefined,
+  totalConstructionWells: undefined,
+  completedWells: undefined,
+  dailyPowerUsage: undefined,
+  monthlyPowerUsage: undefined,
+  dailyFuel: undefined,
+  monthlyFuel: undefined,
+  nonProductionTime: undefined,
+  nptReason: undefined,
+  constructionStartDate: undefined,
+  constructionEndDate: undefined,
+  productionStatus: undefined,
+  nextPlan: undefined,
+  rigStatus: undefined,
+  personnel: undefined,
+  mudDensity: undefined,
+  mudViscosity: undefined,
+  lateralLength: undefined,
+  wellInclination: undefined,
+  azimuth: undefined,
+  designWellStruct: undefined,
+  extProperty: undefined,
+  sort: undefined,
+  remark: undefined,
+  status: undefined,
+  processInstanceId: undefined,
+  auditStatus: undefined,
+})
+const formRules = reactive({
+})
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const open = async (type: string, id?: number) => {
+  dialogVisible.value = true
+  dialogTitle.value = t('action.' + type)
+  formType.value = type
+  resetForm()
+
+  // 设置显示数据
+  if (props.rowData) {
+    displayData.value.deptName = props.rowData.deptName || ''
+    displayData.value.contractName = props.rowData.contractName || ''
+    displayData.value.taskName = props.rowData.taskName || ''
+    displayData.value.designWellDepth = props.rowData.designWellDepth || ''
+    displayData.value.designWellStruct = props.rowData.designWellStruct || ''
+    displayData.value.totalConstructionWells = props.rowData.totalConstructionWells || ''
+    displayData.value.completedWells = props.rowData.completedWells || ''
+  }
+
+  // 修改时,设置数据
+  if (id) {
+    formLoading.value = true
+    try {
+      formData.value = await IotRyDailyReportApi.getIotRyDailyReport(id)
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as IotRyDailyReportVO
+    if (formType.value === 'create') {
+      await IotRyDailyReportApi.createIotRyDailyReport(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await IotRyDailyReportApi.updateIotRyDailyReport(data)
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    id: undefined,
+    deptId: undefined,
+    projectId: undefined,
+    taskId: undefined,
+    projectClassification: undefined,
+    relocationDays: undefined,
+    latestWellDoneTime: undefined,
+    designWellDepth: undefined,
+    currentDepth: undefined,
+    dailyFootage: undefined,
+    monthlyFootage: undefined,
+    annualFootage: undefined,
+    totalConstructionWells: undefined,
+    completedWells: undefined,
+    dailyPowerUsage: undefined,
+    monthlyPowerUsage: undefined,
+    dailyFuel: undefined,
+    monthlyFuel: undefined,
+    nonProductionTime: undefined,
+    nptReason: undefined,
+    constructionStartDate: undefined,
+    constructionEndDate: undefined,
+    productionStatus: undefined,
+    nextPlan: undefined,
+    rigStatus: undefined,
+    personnel: undefined,
+    mudDensity: undefined,
+    mudViscosity: undefined,
+    lateralLength: undefined,
+    wellInclination: undefined,
+    azimuth: undefined,
+    designWellStruct: undefined,
+    extProperty: undefined,
+    sort: undefined,
+    remark: undefined,
+    status: undefined,
+    processInstanceId: undefined,
+    auditStatus: undefined,
+  }
+
+  displayData.value = {
+    deptName: '',
+    contractName: '',
+    taskName: '',
+    designWellDepth: '',
+    designWellStruct: '',
+    totalConstructionWells: '',
+    completedWells: ''
+  }
+
+  formRef.value?.resetFields()
+}
+</script>

+ 1 - 1
src/views/pms/iotrydailyreport/index.vue

@@ -224,7 +224,7 @@ const queryParams = reactive({
   projectId: undefined,
   taskName: undefined,
   taskId: undefined,
-  projectClassification: undefined,
+  projectClassification: '1',
   relocationDays: undefined,
   latestWellDoneTime: [],
   currentDepth: undefined,

+ 781 - 0
src/views/pms/iotrydailyreport/xjindex.vue

@@ -0,0 +1,781 @@
+<template>
+  <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"
+        />
+      </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="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>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap ref="tableContainerRef">
+    <div class="table-container">
+      <el-table ref="tableRef" v-loading="loading" :data="list" :stripe="true"
+                style="width: 100%" :cell-style="cellStyle">
+        <el-table-column :label="t('iotDevice.serial')" width="70" align="center">
+          <template #default="scope">
+            {{ scope.$index + 1 }}
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="日期"
+          align="center"
+          prop="createTime"
+          :formatter="dateFormatter2"
+          :width="columnWidths.createTime"
+        />
+        <el-table-column label="施工队伍" align="center" prop="deptName" :width="columnWidths.deptName"/>
+        <el-table-column label="项目" align="center" prop="contractName" :width="columnWidths.contractName"/>
+        <el-table-column label="任务" align="center" prop="taskName" :width="columnWidths.taskName"/>
+        <el-table-column :label="t('project.status')" align="center" prop="rigStatus" :width="columnWidths.rigStatus">
+          <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="latestWellDoneTime" :width="columnWidths.latestWellDoneTime" :formatter="dateFormatter2"/>
+        <el-table-column label="设计井深(m)" align="center" prop="designWellDepth" :width="columnWidths.designWellDepth"/>
+        <el-table-column label="当前井深(m)" align="center" prop="currentDepth" :width="columnWidths.currentDepth" />
+        <el-table-column label="日进尺(m)" align="center" prop="dailyFootage" :width="columnWidths.dailyFootage" />
+        <el-table-column label="月进尺(m)" align="center" prop="monthlyFootage" :width="columnWidths.monthlyFootage"/>
+        <el-table-column label="年累计进尺(m)" align="center" prop="annualFootage" :width="columnWidths.annualFootage"/> -->
+        <el-table-column label="总施工井数" align="center" prop="totalConstructionWells" :width="columnWidths.totalConstructionWells"/>
+        <el-table-column label="完工井数" align="center" prop="completedWells" :width="columnWidths.completedWells"/>
+        <el-table-column :label="t('project.technology')" align="center" prop="technique" :width="columnWidths.technique">
+          <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" :width="columnWidths.wellCategory"/>
+        <el-table-column label="井深(m)" align="center" prop="designWellDepth" :width="columnWidths.designWellDepth"/>
+        <el-table-column label="套生段产管尺寸(mm)" align="center" prop="casingPipeSize" :width="columnWidths.casingPipeSize"/>
+        <el-table-column label="井控级别" align="center" prop="wellControlLevel" :width="columnWidths.wellControlLevel"/>
+        <!--
+        <el-table-column label="泥浆性能-密度(g/cm³)" align="center" prop="mudDensity" :width="columnWidths.mudDensity"/>
+        <el-table-column label="泥浆性能-粘度(S)" align="center" prop="mudViscosity" :width="columnWidths.mudViscosity"/> -->
+        <el-table-column
+          label="施工开始日期"
+          align="center"
+          prop="constructionStartDate"
+          :formatter="dateFormatter"
+          :width="columnWidths.constructionStartDate"
+        />
+        <el-table-column
+          label="施工结束日期"
+          align="center"
+          prop="constructionEndDate"
+          :formatter="dateFormatter"
+          :width="columnWidths.constructionEndDate"
+        />
+        <!--
+        <el-table-column label="水平段长度(m)" align="center" prop="lateralLength" :width="columnWidths.lateralLength" />
+        <el-table-column label="井斜(°)" align="center" prop="wellInclination" :width="columnWidths.wellInclination"/>
+        <el-table-column label="方位(°)" align="center" prop="azimuth" :width="columnWidths.azimuth"/>
+        <el-table-column label="设计井身结构" align="center" :width="columnWidths.designWellStruct" fixed-width>
+          <template #default="scope">
+            <el-tooltip
+              effect="light"
+              :content="scope.row.designWellStruct"
+              placement="top"
+              popper-class="design-well-struct-tooltip"
+              :disabled="!scope.row.designWellStruct || scope.row.designWellStruct.length <= 30"
+            >
+              <span class="design-well-struct-text">{{ formatDesignWellStruct(scope.row.designWellStruct) }}</span>
+            </el-tooltip>
+          </template>
+        </el-table-column> -->
+        <el-table-column label="目前工序" align="center" prop="currentOperation" :width="columnWidths.currentOperation"/>
+        <el-table-column label="下部工序" align="center" prop="nextPlan" :width="columnWidths.nextPlan"/>
+        <el-table-column label="运行时效" align="center" prop="transitTime" :width="columnWidths.transitTime" :formatter="percentageFormatter"/>
+        <el-table-column label="额定生产时间(H)" align="center" prop="ratedProductionTime" :width="columnWidths.ratedProductionTime"/>
+        <el-table-column label="生产时间(H)" align="center" prop="productionTime" :width="columnWidths.productionTime"/>
+        <el-table-column label="非生产时间(H)" align="center" prop="nonProductionTime" :width="columnWidths.nonProductionTime"/>
+        <el-table-column :label="t('project.nptReason')" align="center" prop="ryNptReason" :width="columnWidths.ryNptReason">
+          <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" :width="columnWidths.productionStatus" fixed-width>
+          <template #default="scope">
+            <el-tooltip
+              effect="light"
+              :content="scope.row.productionStatus"
+              placement="top"
+              popper-class="design-well-struct-tooltip"
+              :disabled="!scope.row.productionStatus || scope.row.productionStatus.length <= 30"
+            >
+              <span class="design-well-struct-text">{{ formatDesignWellStruct(scope.row.productionStatus) }}</span>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" :width="columnWidths.operation" 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>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <IotRyDailyReportForm ref="formRef" @success="getList" :row-data="selectedRowData"/>
+</template>
+
+<script setup lang="ts">
+import {dateFormatter, dateFormatter2} from '@/utils/formatTime'
+import download from '@/utils/download'
+import { IotRyDailyReportApi, IotRyDailyReportVO } from '@/api/pms/iotrydailyreport'
+import IotRyDailyReportForm from './IotRyDailyReportForm.vue'
+import {DICT_TYPE, getDictLabel} from "@/utils/dict";
+import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue'
+
+/** 瑞鹰日报 列表 */
+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) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  deptId: undefined,
+  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: [],
+})
+const queryFormRef = ref() // 搜索的表单
+const exportLoading = ref(false) // 导出的加载中
+
+// 表格引用
+const tableRef = ref()
+// 表格容器引用
+const tableContainerRef = ref()
+
+// 列宽度配置
+const columnWidths = ref({
+  deptName: '120px',
+  contractName: '150px',
+  taskName: '120px',
+  technique: '120px',
+  rigStatus: '110px',
+  latestWellDoneTime: '120px',
+  designWellDepth: '120px',
+  wellCategory: '120px',
+  casingPipeSize: '120px',
+  wellControlLevel: '120px',
+  currentDepth: '100px',
+  dailyFootage: '150px',
+  monthlyFootage: '150px',
+  annualFootage: '150px',
+  totalConstructionWells: '150px',
+  completedWells: '150px',
+  mudDensity: '150px',
+  mudViscosity: '150px',
+  constructionStartDate: '180px',
+  constructionEndDate: '180px',
+  lateralLength: '150px',
+  wellInclination: '150px',
+  transitTime: '150px',
+  productionStatus: '200px',
+  currentOperation: '200px',
+  nextPlan: '200px',
+  ryNptReason: '150px',
+  azimuth: '150px',
+  designWellStruct: '200px',
+  ratedProductionTime: '150px',
+  productionTime: '150px',
+  nonProductionTime: '150px',
+  createTime: '180px',
+  operation: '120px'
+})
+
+// 格式化设计井身结构文本
+const formatDesignWellStruct = (text: string | null | undefined) => {
+  if (!text) return '-';
+  // 如果文本长度超过30个字符,显示前30个字符并添加省略号
+  return text.length > 30 ? text.substring(0, 30) + '...' : text;
+};
+
+// 检查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 }) => {
+  // 1. 检查三个时间字段:额定生产时间、生产时间、非生产时间
+  const timeFields = ['ratedProductionTime', 'productionTime', 'nonProductionTime'];
+  if (timeFields.includes(column.property)) {
+    const ratedTime = parseFloat(row.ratedProductionTime) || 0
+    const prodTime = parseFloat(row.productionTime) || 0
+    const nonProdTime = parseFloat(row.nonProductionTime) || 0
+
+    // 新增:检查三个字段是否有空值
+    const hasEmptyField =
+      row.ratedProductionTime === null || row.ratedProductionTime === undefined || row.ratedProductionTime === '' ||
+      row.productionTime === null || row.productionTime === undefined || row.productionTime === '' ||
+      row.nonProductionTime === null || row.nonProductionTime === undefined || row.nonProductionTime === ''
+
+    // 如果有空字段,应用警告样式
+    if (hasEmptyField) {
+      return {
+        backgroundColor: '#fff2f0', // 浅红色背景,表示数据不完整
+        color: '#d46b08', // 深红色文字
+        fontWeight: 'bold',
+        border: '1px solid #ffa39e' // 可选:添加边框突出显示
+      }
+    }
+
+    // 如果三个字段都有值,且不满足公式:额定生产时间 = 生产时间 + 非生产时间
+    // 使用容差比较,避免浮点数精度问题
+    if (Math.abs(ratedTime - (prodTime + nonProdTime)) > 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'
+      };
+    }
+  }
+  // 默认返回空对象,不应用特殊样式
+  return {};
+};
+
+// 计算文本宽度
+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 FLEXIBLE_COLUMNS = ['deptName', 'contractName', 'taskName', 'technique', 'rigStatus', 'latestWellDoneTime', 'designWellDepth',
+  'currentDepth', 'dailyFootage', 'monthlyFootage', 'annualFootage', 'totalConstructionWells',
+  'completedWells', 'mudDensity', 'mudViscosity', 'constructionStartDate', 'ryNptReason',
+  'constructionEndDate', 'lateralLength', 'wellInclination', 'casingPipeSize',
+  'azimuth', 'ratedProductionTime', 'productionTime', 'nonProductionTime', 'createTime'];
+
+/** 查询列表 */
+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 calculateColumnWidths = () => {
+  const MIN_WIDTH = 80; // 最小列宽
+  const PADDING = 25; // 列内边距
+
+  // 确保表格容器存在
+  if (!tableContainerRef.value?.$el) return;
+
+  const container = tableContainerRef.value.$el;
+  const containerWidth = container.clientWidth;
+
+  // 1. 计算所有列的最小宽度
+  const minWidths: Record<string, number> = {};
+  let totalMinWidth = 0;
+
+  // 计算列最小宽度的函数
+  const calculateColumnMinWidth = (key: string, label: string, getValue: Function) => {
+    const headerWidth = getTextWidth(label) * 1.2;
+    let contentMaxWidth = 0;
+
+    // 计算内容最大宽度
+    list.value.forEach((row, index) => {
+      let text = '';
+      if (key === 'rigStatus') {
+        // 特殊处理字典列
+        const dictValue = row[key];
+        // 这里需要根据实际情况获取字典标签,简化处理使用值本身
+        text = String(dictValue || '');
+      } 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);
+      if (textWidth > contentMaxWidth) contentMaxWidth = textWidth;
+    });
+
+    const minWidth = Math.max(headerWidth, contentMaxWidth, MIN_WIDTH) + PADDING;
+    minWidths[key] = minWidth;
+    totalMinWidth += minWidth;
+    return minWidth;
+  };
+
+  // 计算各列最小宽度
+  calculateColumnMinWidth('deptName', '施工队伍', (row: any) => row.deptName);
+  calculateColumnMinWidth('contractName', '项目', (row: any) => row.contractName);
+  calculateColumnMinWidth('taskName', '任务', (row: any) => row.taskName);
+  calculateColumnMinWidth('technique', '施工工艺', (row: any) => row.technique);
+  calculateColumnMinWidth('rigStatus', t('project.status'), (row: any) => {
+    // 这里可以获取字典标签,简化处理使用值本身
+    return String(row.rigStatus || '');
+  });
+  calculateColumnMinWidth('latestWellDoneTime', '上井次完井时间', (row: any) => row.latestWellDoneTime);
+  calculateColumnMinWidth('designWellDepth', '设计井深(m)', (row: any) => row.designWellDepth);
+  calculateColumnMinWidth('currentDepth', '当前井深(m)', (row: any) => row.currentDepth);
+  calculateColumnMinWidth('dailyFootage', '日进尺(m)', (row: any) => row.dailyFootage);
+  calculateColumnMinWidth('monthlyFootage', '月进尺(m)', (row: any) => row.monthlyFootage);
+  calculateColumnMinWidth('annualFootage', '年累计进尺(m)', (row: any) => row.annualFootage);
+  calculateColumnMinWidth('totalConstructionWells', '总施工井数', (row: any) => row.totalConstructionWells);
+  calculateColumnMinWidth('completedWells', '完工井数', (row: any) => row.completedWells);
+  calculateColumnMinWidth('casingPipeSize', '套生段产管尺寸', (row: any) => row.casingPipeSize);
+  calculateColumnMinWidth('mudDensity', '泥浆性能-密度(g/cm³)', (row: any) => row.mudDensity);
+  calculateColumnMinWidth('mudViscosity', '泥浆性能-粘度(S)', (row: any) => row.mudViscosity);
+  calculateColumnMinWidth('ryNptReason', t('project.nptReason'), (row: any) => row.ryNptReason);
+  calculateColumnMinWidth('constructionStartDate', '施工开始日期', (row: any) => dateFormatter(null, null, row.constructionStartDate));
+  calculateColumnMinWidth('constructionEndDate', '施工结束日期', (row: any) => dateFormatter(null, null, row.constructionEndDate));
+  calculateColumnMinWidth('lateralLength', '水平段长度(m)', (row: any) => row.lateralLength);
+  calculateColumnMinWidth('wellInclination', '井斜(°)', (row: any) => row.wellInclination);
+  calculateColumnMinWidth('azimuth', '方位(°)', (row: any) => row.azimuth);
+  calculateColumnMinWidth('designWellStruct', '设计井身结构', (row: any) => row.designWellStruct);
+  calculateColumnMinWidth('productionStatus', '生产动态', (row: any) => row.productionStatus);
+  calculateColumnMinWidth('ratedProductionTime', '额定生产时间(H)', (row: any) => row.ratedProductionTime);
+  calculateColumnMinWidth('productionTime', '生产时间(H)', (row: any) => row.productionTime);
+  calculateColumnMinWidth('nonProductionTime', '非生产时间(H)', (row: any) => row.nonProductionTime);
+  calculateColumnMinWidth('createTime', '创建时间', (row: any) => dateFormatter(null, null, row.createTime));
+
+  // 设计井身结构 生产动态 列使用固定宽度,不参与自动计算
+  minWidths.designWellStruct = 200; // 固定宽度200px
+  totalMinWidth += 200;
+
+  minWidths.productionStatus = 200; // 固定宽度200px
+  totalMinWidth += 200;
+
+  // 操作列固定宽度
+  minWidths.operation = 120;
+  totalMinWidth += 120;
+
+  // 2. 计算可伸缩列最终宽度
+  const newWidths: Record<string, string> = {};
+  const availableWidth = containerWidth - 17; // 减去滚动条宽度
+
+  // 应用最小宽度到所有列
+  Object.keys(minWidths).forEach(key => {
+    newWidths[key] = `${minWidths[key]}px`;
+  });
+
+  // 计算可伸缩列需要的宽度
+  if (totalMinWidth < availableWidth) {
+    // 有剩余空间:按比例分配给可伸缩列
+    const extraSpace = availableWidth - totalMinWidth;
+    const flexibleColumnCount = FLEXIBLE_COLUMNS.length;
+    const spacePerColumn = Math.floor(extraSpace / flexibleColumnCount);
+
+    FLEXIBLE_COLUMNS.forEach(key => {
+      newWidths[key] = `${minWidths[key] + spacePerColumn}px`;
+    });
+  }
+
+  // 3. 更新列宽配置
+  columnWidths.value = newWidths;
+
+  // 4. 触发表格重新布局
+  nextTick(() => {
+    tableRef.value?.doLayout();
+  });
+};
+
+// 百分比格式化函数
+const percentageFormatter = (row: any, column: any, cellValue: any, index: number) => {
+  if (cellValue === null || cellValue === undefined || cellValue === '') return '';
+  const value = parseFloat(cellValue)
+  if (isNaN(value)) return '-'
+  // 将小数转换为百分比,保留两位小数
+  return `${(value * 100).toFixed(2)}%`
+};
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  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,
+      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 handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await IotRyDailyReportApi.exportIotRyDailyReport(queryParams)
+    download.excel(data, '瑞鹰日报.xls')
+  } catch {
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+// 声明 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(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;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  line-height: 1.5;
+  max-height: 3em; /* 两行文本的高度 */
+}
+
+/* 确保设计井身结构列不参与自动调整 */
+: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;
+  flex-direction: column;
+  gap: 8px;
+  padding: 12px 16px;
+  background-color: #f8f9fa;
+  border-radius: 4px;
+  border-left: 4px solid #e6f7ff;
+}
+
+.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 {
+  white-space: pre-line;
+  max-width: 500px;
+  line-height: 1.5;
+}
+</style>