Просмотр исходного кода

✨ feat(日报任务查看): 添加施工队伍搜索条件

Zimo 2 дней назад
Родитель
Сommit
a96d84544c
1 измененных файлов с 194 добавлено и 130 удалено
  1. 194 130
      src/views/pms/iotprojecttask/index.vue

+ 194 - 130
src/views/pms/iotprojecttask/index.vue

@@ -50,6 +50,15 @@
           class="!w-240px"
         />
       </el-form-item>
+      <el-form-item label="施工队伍" prop="deptName">
+        <el-input
+          v-model="queryParams.deptName"
+          placeholder="请输入施工队伍"
+          clearable
+          @keyup.enter="handleQuery"
+          class="!w-240px"
+        />
+      </el-form-item>
       <el-form-item label="井号" prop="wellName">
         <el-input
           v-model="queryParams.wellName"
@@ -109,26 +118,70 @@
   </ContentWrap>
 
   <!-- 列表 -->
-  <ContentWrap  ref="tableContainerRef">
+  <ContentWrap ref="tableContainerRef">
     <div class="table-container">
-      <el-table ref="tableRef" v-loading="loading" :data="list" :stripe="true" style="width: 100%" :cell-style="{padding: '5px'}">
-        <el-table-column :label="t('iotDevice.serial')" :width="columnWidths.serial" align="center" v-if="false">
+      <el-table
+        ref="tableRef"
+        v-loading="loading"
+        :data="list"
+        :stripe="true"
+        style="width: 100%"
+        :cell-style="{ padding: '5px' }"
+      >
+        <el-table-column
+          :label="t('iotDevice.serial')"
+          :width="columnWidths.serial"
+          align="center"
+          v-if="false"
+        >
           <template #default="scope">
             {{ scope.$index + 1 }}
           </template>
         </el-table-column>
-        <el-table-column label="客户名称" align="center" prop="manufactureName" :width="columnWidths.manufactureName" show-overflow-tooltip/>
-        <el-table-column label="合同名称" align="center" prop="contractName" :width="columnWidths.contractName" show-overflow-tooltip/>
-        <el-table-column label="合同编号" align="center" prop="contractCode" :width="columnWidths.contractCode" />
-        <el-table-column label="井号" align="center" prop="wellName" :width="columnWidths.wellName" />
+        <el-table-column
+          label="客户名称"
+          align="center"
+          prop="manufactureName"
+          :width="columnWidths.manufactureName"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="合同名称"
+          align="center"
+          prop="contractName"
+          :width="columnWidths.contractName"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="合同编号"
+          align="center"
+          prop="contractCode"
+          :width="columnWidths.contractCode"
+        />
+        <el-table-column
+          label="井号"
+          align="center"
+          prop="wellName"
+          :width="columnWidths.wellName"
+        />
         <!-- <el-table-column label="井型/井别" align="center" prop="wellType" />
         <el-table-column :label="t('project.wellType')" align="center" prop="wellType" :width="columnWidths.wellType">
           <template #default="scope">
             <dict-tag :type="DICT_TYPE.PMS_PROJECT_WELL_TYPE" :value="scope.row.wellType" />
           </template>
         </el-table-column> -->
-        <el-table-column label="施工地点" align="center" prop="location" :width="columnWidths.location" />
-        <el-table-column label="施工队伍" align="center" prop="deptNames" :width="columnWidths.deptNames" />
+        <el-table-column
+          label="施工地点"
+          align="center"
+          prop="location"
+          :width="columnWidths.location"
+        />
+        <el-table-column
+          label="施工队伍"
+          align="center"
+          prop="deptNames"
+          :width="columnWidths.deptNames"
+        />
         <!-- <el-table-column :label="t('project.technology')" align="center" prop="technique" :width="columnWidths.technique">
           <template #default="scope">
             <dict-tag :type="DICT_TYPE.PMS_PROJECT_TECHNOLOGY" :value="scope.row.technique" />
@@ -157,7 +210,7 @@
             <el-button
               link
               type="primary"
-              @click="openForm('update', scope.row.id,scope.row.projectId)"
+              @click="openForm('update', scope.row.id, scope.row.projectId)"
               v-hasPermi="['rq:iot-project-task:update']"
             >
               编辑
@@ -246,9 +299,7 @@
       </el-table-column>
       <el-table-column label="操作" width="100" align="center">
         <template #default="scope">
-          <el-button link type="danger" @click="removeRow(scope.$index)">
-            删除
-          </el-button>
+          <el-button link type="danger" @click="removeRow(scope.$index)"> 删除 </el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -256,25 +307,22 @@
     <template #footer>
       <span class="dialog-footer">
         <el-button @click="planDialogVisible = false">取消</el-button>
-        <el-button type="primary" @click="savePlan" :loading="saveLoading">
-          保存
-        </el-button>
+        <el-button type="primary" @click="savePlan" :loading="saveLoading"> 保存 </el-button>
       </span>
     </template>
   </el-dialog>
-
 </template>
 
 <script setup lang="ts">
 import { dateFormatter } from '@/utils/formatTime'
 import download from '@/utils/download'
 import { IotProjectTaskScheduleApi } from '@/api/pms/iotprojecttaskschedule'
-import { IotProjectTaskApi, IotProjectTaskVO} from '@/api/pms/iotprojecttask'
+import { IotProjectTaskApi, IotProjectTaskVO } from '@/api/pms/iotprojecttask'
 import dayjs from 'dayjs'
 import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
-import { ref, reactive, onMounted, computed, nextTick, watch, onUnmounted } from 'vue'
+import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue'
 import { useRouter } from 'vue-router'
-import * as DeptApi from "@/api/system/dept"; // 引入部门API
+import * as DeptApi from '@/api/system/dept' // 引入部门API
 
 /** 项目信息任务拆分 列表 */
 defineOptions({ name: 'IotProjectTask' })
@@ -301,6 +349,7 @@ const queryParams = reactive({
   manufactureName: '',
   platformFlag: '',
   remark: undefined,
+  deptName: undefined
 })
 
 const dictQueryParams = reactive({
@@ -315,7 +364,7 @@ const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中
 const { push } = useRouter() // 路由跳转
 
-const COMPLETED_STATUS = 'wg';
+const COMPLETED_STATUS = 'wg'
 
 // 表格引用
 const tableRef = ref()
@@ -340,29 +389,31 @@ const columnWidths = ref({
 
 // 计算文本宽度
 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 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 planDialogVisible = ref(false)
 // const planList = ref<Array<{name: string, value: string, startTime: string, endTime: string}>>([])
-const planList = ref<Array<{id?: number, status: string, startTime: string, endTime: string, showEndTime: boolean}>>([])
+const planList = ref<
+  Array<{ id?: number; status: string; startTime: string; endTime: string; showEndTime: boolean }>
+>([])
 const saveLoading = ref(false)
 const currentRow = ref<IotProjectTaskVO | null>(null)
 const workProgressDictOptions = ref<any[]>([]) // 施工进度字典选项
-const companyDeptList = ref<any[]>([])  // 在公司级部门列表
+const companyDeptList = ref<any[]>([]) // 在公司级部门列表
 const wellTypeDictOptions = ref<any[]>([]) // 井型字典选项
 const technologyDictOptions = ref<any[]>([]) // 施工工艺字典选项
 
@@ -389,19 +440,19 @@ const getTechnologyDictOptions = async () => {
 /** 时间戳转换为日期时间字符串(使用dayjs处理) */
 const timestampToDateTime = (timestamp: number | string | null | undefined): string => {
   if (timestamp === null || timestamp === undefined || timestamp === '') {
-    return '';
+    return ''
   }
   // 转换为数字
-  let ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp;
+  let ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp
 
   // 检查是否为有效数字
   if (isNaN(ts)) {
-    console.warn('无效的时间戳:', timestamp);
-    return '';
+    console.warn('无效的时间戳:', timestamp)
+    return ''
   }
   // 如果时间戳是秒级,转换为毫秒级
   if (ts < 1000000000000) {
-    ts *= 1000;
+    ts *= 1000
   }
   return dayjs(ts).format('YYYY-MM-DD HH:mm')
 }
@@ -425,12 +476,14 @@ const openPlanDialog = async (row: IotProjectTaskVO) => {
     await getWorkProgressDictOptions()
 
     // 获取已有计划数据
-    const taskSchedules = await IotProjectTaskScheduleApi.getIotProjectTaskSchedules({ taskId: row.id })
+    const taskSchedules = await IotProjectTaskScheduleApi.getIotProjectTaskSchedules({
+      taskId: row.id
+    })
 
     if (taskSchedules && taskSchedules.length > 0) {
       // 如果有数据,则使用接口返回的数据初始化表格
       planList.value = taskSchedules.map((plan: any) => {
-        const statusNum = plan.status;
+        const statusNum = plan.status
         return {
           id: plan.id,
           status: statusNum,
@@ -451,17 +504,17 @@ const openPlanDialog = async (row: IotProjectTaskVO) => {
 
 /** 判断某一行是否应该显示结束时间列 */
 const rowShowEndTime = (row) => {
-  return row.showEndTime;
+  return row.showEndTime
 }
 
 /** 处理施工状态变化 */
 const onStatusChange = (row) => {
   // 当状态变为“完工”时,隐藏结束时间列并清空结束时间;否则显示
   if (row.status === COMPLETED_STATUS) {
-    row.showEndTime = false;
-    row.endTime = ''; // 清空结束时间
+    row.showEndTime = false
+    row.endTime = '' // 清空结束时间
   } else {
-    row.showEndTime = true;
+    row.showEndTime = true
   }
 }
 
@@ -495,12 +548,13 @@ const savePlan = async () => {
     }
 
     // 准备提交数据
-    const submitData = planList.value.map(item => ({
+    const submitData = planList.value.map((item) => ({
       id: item.id, // 更新时使用
       taskId: currentRow.value?.id,
       status: item.status,
       startTime: item.startTime ? new Date(item.startTime).getTime() : null,
-      endTime: (item.status !== COMPLETED_STATUS && item.endTime) ? new Date(item.endTime).getTime() : null
+      endTime:
+        item.status !== COMPLETED_STATUS && item.endTime ? new Date(item.endTime).getTime() : null
     }))
 
     // 调用保存接口
@@ -526,8 +580,8 @@ const getList = async () => {
 
     // 获取数据后计算列宽
     nextTick(() => {
-      calculateColumnWidths();
-    });
+      calculateColumnWidths()
+    })
   } finally {
     loading.value = false
   }
@@ -535,111 +589,118 @@ const getList = async () => {
 
 // 计算列宽度
 const calculateColumnWidths = () => {
-  const MIN_WIDTH = 80; // 最小列宽
-  const PADDING = 25; // 列内边距
-  const FLEXIBLE_COLUMNS = ['contractCode', 'wellName', 'location']; // 可伸缩列
+  const MIN_WIDTH = 80 // 最小列宽
+  const PADDING = 25 // 列内边距
+  const FLEXIBLE_COLUMNS = ['contractCode', 'wellName', 'location'] // 可伸缩列
 
   // 确保表格容器存在
-  if (!tableContainerRef.value?.$el) return;
+  if (!tableContainerRef.value?.$el) return
 
-  const container = tableContainerRef.value.$el;
-  const containerWidth = container.clientWidth;
+  const container = tableContainerRef.value.$el
+  const containerWidth = container.clientWidth
 
   // 固定列的宽度
   const FIXED_COLUMNS = {
     manufactureName: 200,
     contractName: 200
-  };
+  }
 
   // 1. 计算所有列的最小宽度
-  const minWidths: Record<string, number> = {};
-  let totalMinWidth = 0;
+  const minWidths: Record<string, number> = {}
+  let totalMinWidth = 0
 
   // 设置固定列的宽度
-  Object.keys(FIXED_COLUMNS).forEach(key => {
-    minWidths[key] = FIXED_COLUMNS[key];
-    totalMinWidth += FIXED_COLUMNS[key];
-  });
+  Object.keys(FIXED_COLUMNS).forEach((key) => {
+    minWidths[key] = FIXED_COLUMNS[key]
+    totalMinWidth += FIXED_COLUMNS[key]
+  })
 
   // 计算列最小宽度的函数
   const calculateColumnMinWidth = (key: string, label: string, getValue: Function) => {
     // 如果是固定列,跳过计算
-    if (FIXED_COLUMNS[key]) return;
+    if (FIXED_COLUMNS[key]) return
 
-    const headerWidth = getTextWidth(label) * 1.2;
-    let contentMaxWidth = 0;
+    const headerWidth = getTextWidth(label) * 1.2
+    let contentMaxWidth = 0
 
     // 计算内容最大宽度
     list.value.forEach((row, index) => {
-      const 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;
-  };
+      const 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('serial', t('iotDevice.serial'), (row: any, index: number) => `${index + 1}`);
+  calculateColumnMinWidth(
+    'serial',
+    t('iotDevice.serial'),
+    (row: any, index: number) => `${index + 1}`
+  )
   // calculateColumnMinWidth('manufactureName', '客户名称', (row: any) => row.manufactureName);
   // calculateColumnMinWidth('contractName', '合同名称', (row: any) => row.contractName);
-  calculateColumnMinWidth('contractCode', '合同编号', (row: any) => row.contractCode);
-  calculateColumnMinWidth('wellName', '井号', (row: any) => row.wellName);
+  calculateColumnMinWidth('contractCode', '合同编号', (row: any) => row.contractCode)
+  calculateColumnMinWidth('wellName', '井号', (row: any) => row.wellName)
   calculateColumnMinWidth('wellType', t('project.wellType'), (row: any) => {
-    const dict = wellTypeDictOptions.value.find(d => d.value === row.wellType);
-    return dict ? dict.label : '';
-  });
-  calculateColumnMinWidth('location', '施工地点', (row: any) => row.location);
-  calculateColumnMinWidth('deptNames', '施工队伍', (row: any) => row.deptNames);
+    const dict = wellTypeDictOptions.value.find((d) => d.value === row.wellType)
+    return dict ? dict.label : ''
+  })
+  calculateColumnMinWidth('location', '施工地点', (row: any) => row.location)
+  calculateColumnMinWidth('deptNames', '施工队伍', (row: any) => row.deptNames)
   calculateColumnMinWidth('technique', t('project.technology'), (row: any) => {
-    const dict = technologyDictOptions.value.find(d => d.value === row.technique);
-    return dict ? dict.label : '';
-  });
-  calculateColumnMinWidth('workloadDesign', '设计工作量', (row: any) => row.workloadDesign);
-  calculateColumnMinWidth('createTime', '创建时间', (row: any) => dateFormatter(null, null, row.createTime));
+    const dict = technologyDictOptions.value.find((d) => d.value === row.technique)
+    return dict ? dict.label : ''
+  })
+  calculateColumnMinWidth('workloadDesign', '设计工作量', (row: any) => row.workloadDesign)
+  calculateColumnMinWidth('createTime', '创建时间', (row: any) =>
+    dateFormatter(null, null, row.createTime)
+  )
 
   // 操作列固定宽度
-  minWidths.operation = 200;
-  totalMinWidth += 200;
+  minWidths.operation = 200
+  totalMinWidth += 200
 
   // 2. 计算可伸缩列最终宽度
-  const newWidths: Record<string, string> = {};
-  const availableWidth = containerWidth - 17; // 减去滚动条宽度
+  const newWidths: Record<string, string> = {}
+  const availableWidth = containerWidth - 17 // 减去滚动条宽度
 
   // 应用最小宽度到所有列
-  Object.keys(minWidths).forEach(key => {
+  Object.keys(minWidths).forEach((key) => {
     if (FIXED_COLUMNS[key]) {
-      newWidths[key] = `${FIXED_COLUMNS[key]}px`;
+      newWidths[key] = `${FIXED_COLUMNS[key]}px`
     } else {
-      newWidths[key] = `${minWidths[key]}px`;
+      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 => {
-      if (!FIXED_COLUMNS[key]) { // 确保不是固定列
-        newWidths[key] = `${minWidths[key] + spacePerColumn}px`;
+    const extraSpace = availableWidth - totalMinWidth
+    const flexibleColumnCount = FLEXIBLE_COLUMNS.length
+    const spacePerColumn = Math.floor(extraSpace / flexibleColumnCount)
+
+    FLEXIBLE_COLUMNS.forEach((key) => {
+      if (!FIXED_COLUMNS[key]) {
+        // 确保不是固定列
+        newWidths[key] = `${minWidths[key] + spacePerColumn}px`
       }
-    });
+    })
   }
 
   // 3. 更新列宽配置
-  columnWidths.value = newWidths;
+  columnWidths.value = newWidths
 
   // 4. 触发表格重新布局
   nextTick(() => {
-    tableRef.value?.doLayout();
-  });
-};
+    tableRef.value?.doLayout()
+  })
+}
 
 /** 搜索按钮操作 */
 const handleQuery = () => {
@@ -655,11 +716,11 @@ const resetQuery = () => {
 
 /** 添加/修改操作 */
 const formRef = ref()
-const openForm = (type: string, id?: number,projectId?:number) => {
-  if(id===undefined){
-    push({ name: 'IotProjectTaskInfo', params: { type} })
-  }else{
-    push({ name: 'IotProjectTaskInfo', params: { type,id,projectId} })
+const openForm = (type: string, id?: number, projectId?: number) => {
+  if (id === undefined) {
+    push({ name: 'IotProjectTaskInfo', params: { type } })
+  } else {
+    push({ name: 'IotProjectTaskInfo', params: { type, id, projectId } })
   }
 }
 
@@ -692,7 +753,7 @@ const handleExport = async () => {
 }
 
 // 声明 ResizeObserver 实例
-let resizeObserver: ResizeObserver | null = null;
+let resizeObserver: ResizeObserver | null = null
 
 /** 初始化 **/
 onMounted(async () => {
@@ -709,33 +770,36 @@ onMounted(async () => {
   if (tableContainerRef.value?.$el) {
     resizeObserver = new ResizeObserver(() => {
       // 使用防抖避免频繁触发
-      clearTimeout((window as any).resizeTimer);
-      (window as any).resizeTimer = setTimeout(() => {
-        calculateColumnWidths();
-      }, 100);
-    });
-    resizeObserver.observe(tableContainerRef.value.$el);
+      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;
+    resizeObserver.unobserve(tableContainerRef.value.$el)
+    resizeObserver = null
   }
 
   // 清除定时器
   if ((window as any).resizeTimer) {
-    clearTimeout((window as any).resizeTimer);
+    clearTimeout((window as any).resizeTimer)
   }
 })
 
 // 监听列表数据变化重新计算列宽
-watch(list, () => {
-  nextTick(calculateColumnWidths)
-}, { deep: true })
-
+watch(
+  list,
+  () => {
+    nextTick(calculateColumnWidths)
+  },
+  { deep: true }
+)
 </script>
 
 <style scoped>