Bläddra i källkod

pms 瑞恒日报 汇总页面等功能优化

zhangcl 2 veckor sedan
förälder
incheckning
1a63a3cfbf

+ 56 - 6
src/views/pms/iotprojecttask/IotProjectTaskForm.vue

@@ -1075,14 +1075,36 @@ const taskFormRules = computed(() => {
     workloadUnit: [{ required: currentTask.value.platformWell !== '1', message: '工作量单位不能为空', trigger: 'change' }],
     deptIds: [{ required: true, message: '施工队伍不能为空', trigger: 'change' }],
     deviceIds: [{ required: true, message: '施工设备不能为空', trigger: 'change' }],
-    responsiblePerson: [{ required: true, message: '责任人不能为空', trigger: 'change' }]
+    responsiblePerson: [
+      {
+        required: true,
+        message: isSpecialDept.value ? '带班干部不能为空' : '责任人不能为空',
+        trigger: 'change',
+        validator: (rule, value, callback) => {
+          if (!value || value.length === 0) {
+            callback(new Error(isSpecialDept.value ? '带班干部不能为空' : '责任人不能为空'));
+          } else {
+            callback();
+          }
+        }
+      }
+    ],
+    submitter: [
+      {
+        required: isSpecialDept.value,
+        message: '填报人不能为空',
+        trigger: 'change',
+        validator: (rule, value, callback) => {
+          if (isSpecialDept.value && (!value || value.length === 0)) {
+            callback(new Error('填报人不能为空'));
+          } else {
+            callback();
+          }
+        }
+      }
+    ]
   };
 
-  // 如果是特殊部门,添加填报人必填规则
-  if (isSpecialDept.value) {
-    rules.submitter = [{ required: true, message: '填报人不能为空', trigger: 'change' }];
-  }
-
   return rules;
 });
 
@@ -1368,12 +1390,22 @@ const confirmDeviceSelection = () => {
 const confirmResponsiblePersonSelection = () => {
   currentTask.value.responsiblePerson = [...selectedResponsiblePersonIds.value];
   responsiblePersonDialogVisible.value = false;
+
+  // 立即触发责任人字段验证
+  nextTick(() => {
+    taskFormRef.value.validateField('responsiblePerson');
+  });
 };
 
 // 确认填报人选择(用于表单)
 const confirmSubmitterSelection = () => {
   currentTask.value.submitter = [...selectedSubmitterIds.value];
   submitterDialogVisible.value = false;
+
+  // 立即触发填报人字段验证
+  nextTick(() => {
+    taskFormRef.value.validateField('submitter');
+  });
 };
 
 // 关闭设备选择对话框
@@ -1648,6 +1680,11 @@ const resetTaskForm = () => {
 
   isNewTask.value = false;
   taskFormRef.value?.resetFields();
+
+  // 清除表单验证状态
+  nextTick(() => {
+    taskFormRef.value?.clearValidate();
+  });
 };
 
 // 获取已选的工作量单位(排除当前行) ==========
@@ -2648,6 +2685,19 @@ watch(() => currentTask.value.deptIds, (newVal) => {
   if (newVal && newVal.length > 0) {
     defaultExpandedKeys.value = [...newVal];
   }
+  if (!newVal || newVal.length === 0) {
+    // 清空施工队伍时,同时清空相关人员和设备
+    currentTask.value.responsiblePerson = [];
+    currentTask.value.submitter = [];
+    currentTask.value.deviceIds = [];
+
+    // 清除相关字段的验证状态
+    nextTick(() => {
+      taskFormRef.value?.validateField('responsiblePerson');
+      taskFormRef.value?.validateField('submitter');
+      taskFormRef.value?.validateField('deviceIds');
+    });
+  }
 }, { immediate: true, deep: true });
 
 // 监听部门列表加载完成

+ 26 - 26
src/views/pms/iotrddailyreport/fillDailyReport.vue

@@ -72,6 +72,27 @@
       <ContentWrap>
         <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
           <el-table-column label="主键id" align="center" prop="id" v-if="false"/>
+          <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>
+            </template>
+          </el-table-column>
           <el-table-column
             label="创建时间"
             align="center"
@@ -79,16 +100,16 @@
             :formatter="dateFormatter"
             width="180px"
           />
-          <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" prop="responsiblePersonNames" />
-          <el-table-column label="填报人" align="center" prop="submitterNames" />
           <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="deptName" />
+          <el-table-column label="项目" align="center" prop="contractName" />
+          <el-table-column label="任务" align="center" prop="taskName" />
+          <el-table-column label="带班干部" align="center" prop="responsiblePersonNames" />
+          <el-table-column label="填报人" align="center" prop="submitterNames" />
           <!--
           <el-table-column label="项目类别(钻井 修井 注氮 酸化压裂... )" align="center" prop="projectClassification" /> -->
           <!--
@@ -107,27 +128,6 @@
             :formatter="dateFormatter"
             width="180px"
           /> -->
-          <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>
-            </template>
-          </el-table-column>
         </el-table>
         <!-- 分页 -->
         <Pagination

+ 71 - 2
src/views/pms/iotrddailyreport/index.vue

@@ -118,8 +118,32 @@
             :formatter="dateFormatter"
             :width="columnWidths.constructionEndDate"
           /> -->
-          <el-table-column label="当日生产动态" align="center" prop="productionStatus" :width="columnWidths.productionStatus"/>
-          <el-table-column label="下步工作计划" align="center" prop="nextPlan" :width="columnWidths.nextPlan"/>
+          <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="long-text-tooltip"
+                :disabled="!scope.row.productionStatus || scope.row.productionStatus.length <= 30"
+              >
+                <span class="long-text">{{ formatLongText(scope.row.productionStatus) }}</span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column label="下步工作计划" align="center" :width="columnWidths.nextPlan" fixed-width>
+            <template #default="scope">
+              <el-tooltip
+                effect="light"
+                :content="scope.row.nextPlan"
+                placement="top"
+                popper-class="long-text-tooltip"
+                :disabled="!scope.row.nextPlan || scope.row.nextPlan.length <= 30"
+              >
+                <span class="long-text">{{ formatLongText(scope.row.nextPlan) }}</span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
           <el-table-column label="外租设备" align="center" prop="externalRental" :width="columnWidths.externalRental"/>
           <el-table-column label="故障情况" align="center" prop="malfunction" :width="columnWidths.malfunction"/>
           <el-table-column label="故障误工H" align="center" prop="faultDowntime" :width="columnWidths.faultDowntime"/>
@@ -266,6 +290,13 @@ const columnWidths = ref({
   operation: '120px'
 })
 
+// 添加长文本格式化函数
+const formatLongText = (text: string | null | undefined) => {
+  if (!text) return '-';
+  // 如果文本长度超过30个字符,显示前30个字符并添加省略号
+  return text.length > 30 ? text.substring(0, 30) + '...' : text;
+};
+
 // 计算文本宽度
 const getTextWidth = (text: string, fontSize = 14) => {
   const span = document.createElement('span');
@@ -295,6 +326,11 @@ const calculateColumnWidths = () => {
 
   // 计算各列宽度的函数
   const calculateColumnWidth = (key: string, label: string, getValue: Function) => {
+    // 如果是需要固定宽度的列,跳过计算
+    if (key === 'productionStatus' || key === 'nextPlan') {
+      return;
+    }
+
     const headerWidth = getTextWidth(label) + PADDING;
     let contentMaxWidth = MIN_WIDTH;
 
@@ -343,6 +379,10 @@ const calculateColumnWidths = () => {
   calculateColumnWidth('faultDowntime', '故障误工H', (row: any) => row.faultDowntime);
   calculateColumnWidth('createTime', '创建时间', (row: any) => dateFormatter(null, null, row.createTime));
 
+  // 为固定宽度的列设置固定值
+  newWidths.productionStatus = '200px';
+  newWidths.nextPlan = '200px';
+
   // 操作列固定宽度
   newWidths.operation = '120px';
   // id列固定宽度(虽然隐藏)
@@ -470,6 +510,9 @@ onMounted(() => {
   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) {
@@ -518,4 +561,30 @@ white-space: nowrap;
 :deep(.el-table) {
 min-width: 100%;
 }
+
+/* 长文本样式 - 多行显示并添加省略号 */
+.long-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;
+}
+</style>
+
+<style>
+/* 长文本 tooltip 样式 - 保留换行符 */
+.long-text-tooltip {
+  white-space: pre-line;
+  max-width: 500px;
+  line-height: 1.5;
+}
 </style>

+ 58 - 11
src/views/pms/iotrddailyreport/statistics.vue

@@ -71,14 +71,20 @@
       <!-- 列表 -->
       <ContentWrap ref="tableContainerRef">
         <el-table ref="tableRef" v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
+          <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="projectDeptName" :width="columnWidths.projectDeptName"/>
           <el-table-column label="队伍" align="center" prop="deptName" :width="columnWidths.deptName"/>
-          <el-table-column label="甲方" align="center" prop="manufactureName" :width="columnWidths.manufactureName"/>
+
           <el-table-column label="井号" align="center" prop="wellName" :width="columnWidths.wellName">
             <template #default="scope">
               <el-link
                 type="primary"
-                @click="handleWellNameClick(scope.row.wellName)"
+                @click="handleWellNameClick(scope.row.taskId)"
                 :underline="false"
               >
                 {{ scope.row.wellName }}
@@ -103,7 +109,7 @@
               </template>
             </el-table-column>
           </el-table-column>
-
+          <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">
@@ -132,7 +138,7 @@
           :total="total"
           v-model:page="queryParams.pageNo"
           v-model:limit="queryParams.pageSize"
-          @pagination="getList"
+          @pagination="handlePagination"
         />
       </ContentWrap>
 
@@ -148,7 +154,7 @@ import { dateFormatter } from '@/utils/formatTime'
 import download from '@/utils/download'
 import { IotRdDailyReportApi, IotRdDailyReportVO } from '@/api/pms/iotrddailyreport'
 import IotRdDailyReportForm from './IotRdDailyReportForm.vue'
-import {DICT_TYPE} from "@/utils/dict";
+import {DICT_TYPE, getDictLabel} from "@/utils/dict";
 import { ref, reactive, onMounted, computed } from 'vue'
 import DeptTree2 from "@/views/pms/iotrhdailyreport/DeptTree2.vue";
 
@@ -159,7 +165,6 @@ const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 const { push } = useRouter() // 路由跳转
 const loading = ref(true) // 列表的加载中
-const list = ref<IotRdDailyReportVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
 const queryParams = reactive({
   pageNo: 1,
@@ -211,6 +216,10 @@ const exportLoading = ref(false) // 导出的加载中
 
 const rootDeptId = ref(163)
 
+// 响应式数据
+const allList = ref<IotRdDailyReportVO[]>([]) // 存储所有数据
+const list = ref<IotRdDailyReportVO[]>([]) // 存储当前页数据
+
 // 表格引用
 const tableRef = ref()
 // 表格容器引用
@@ -239,6 +248,7 @@ const getWorkloadByUnit = (items, unit) => {
 // 列宽度配置
 const columnWidths = ref({
   id: '80px',
+  rdStatus: '120px', // 施工状态列默认宽度
   projectDeptName: '120px',
   contractName: '120px',
   deptName: '120px',
@@ -303,6 +313,12 @@ const calculateColumnWidths = () => {
     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);
@@ -330,8 +346,12 @@ const getList = async () => {
   loading.value = true
   try {
     const data = await IotRdDailyReportApi.statistics(queryParams)
-    list.value = data
-    // total.value = data.total
+    // 存储所有数据
+    allList.value = data
+    // 计算总条数
+    total.value = data.length
+    // 执行前端分页
+    handleFrontendPagination()
     // 获取数据后计算列宽
     nextTick(() => {
       calculateColumnWidths();
@@ -342,14 +362,15 @@ const getList = async () => {
 }
 
 /** 井号点击操作 */
-const handleWellNameClick = (wellName: string) => {
-  if (!wellName) return
+const handleWellNameClick = (taskId: number) => {
+  if (!taskId) return
 
   // 跳转到日报列表页面,传递井号参数
   push({
     name: 'IotRdDailyReport',
     query: {
-      wellName: wellName
+      // wellName: wellName
+      taskId: taskId
     }
   })
 }
@@ -364,6 +385,16 @@ const handleDeptNodeClick = async (row) => {
   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
@@ -376,6 +407,14 @@ const resetQuery = () => {
   handleQuery()
 }
 
+/** 分页事件处理 */
+const handlePagination = (pagination: any) => {
+  queryParams.pageNo = pagination.page
+  queryParams.pageSize = pagination.limit
+  // 使用前端分页,不重新调用接口
+  handleFrontendPagination()
+}
+
 /** 添加/修改操作 */
 const formRef = ref()
 const openForm = (type: string, id?: number) => {
@@ -458,6 +497,14 @@ onUnmounted(() => {
   }
 })
 
+// 监听查询参数变化,实现前端分页
+watch(
+  [() => queryParams.pageNo, () => queryParams.pageSize],
+  () => {
+    handleFrontendPagination()
+  }
+)
+
 // 监听列表数据变化重新计算列宽
 watch(list, () => {
   nextTick(calculateColumnWidths)