Bladeren bron

瑞恒注气量添加tooltip,项目信息列表添加项目部搜索条件

Zimo 12 uur geleden
bovenliggende
commit
5b2b8d5f79

+ 11 - 1
src/api/pms/iotrhdailyreport/index.ts

@@ -36,6 +36,16 @@ export interface IotRhDailyReportVO {
   auditStatus: number // 审批状态 未提交、审批中、审批通过、审批不通过、已取消
 }
 
+export interface IotRhDailyReportTotalWorkloadVO {
+  totalFuelConsumption?: number
+  totalPowerConsumption?: number
+  totalWaterInjection?: number
+  totalGasInjection?: number
+  totalN2GasInjection?: number
+  totalNaturalGasInjection?: number
+  utilizationRate?: number
+}
+
 // 瑞恒日报 API
 export const IotRhDailyReportApi = {
   // 查询瑞恒日报分页
@@ -60,7 +70,7 @@ export const IotRhDailyReportApi = {
   },
 
   // 累计工作量统计
-  totalWorkload: async (params: any) => {
+  totalWorkload: async (params: any): Promise<IotRhDailyReportTotalWorkloadVO> => {
     return await request.get({ url: `/pms/iot-rh-daily-report/totalWorkload`, params })
   },
 

+ 62 - 5
src/views/pms/iotprojectinfo/index.vue

@@ -23,6 +23,24 @@
           />
         </el-select>
       </el-form-item>
+      <el-form-item label="项目部" prop="projectDeptId">
+        <el-select
+          v-model="queryParams.projectDeptId"
+          :placeholder="queryParams.companyDeptId ? '请选择项目部' : '请先选择公司'"
+          :disabled="!queryParams.companyDeptId"
+          :loading="projectDeptLoading"
+          clearable
+          filterable
+          class="!w-240px"
+        >
+          <el-option
+            v-for="item in projectDeptOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
       <!--
       <el-form-item label="客户名称" prop="manufactureName">
         <el-input
@@ -367,14 +385,14 @@ import { IotProjectInfoApi, IotProjectInfoVO } from '@/api/pms/iotprojectinfo'
 import { IotProjectTaskApi } from '@/api/pms/iotprojecttask'
 import { useUserStore } from '@/store/modules/user'
 import { DICT_TYPE, getIntDictOptions, getDictLabel, getStrDictOptions } from '@/utils/dict'
-import { IotDeviceApi } from '@/api/pms/device' // 引入设备API
-import * as UserApi from '@/api/system/user' // 引入用户API
-import * as DeptApi from '@/api/system/dept' // 引入部门API
-import { handleTree } from '@/utils/tree' // 引入树形处理工具
+import { IotDeviceApi } from '@/api/pms/device'; // 引入设备API
+import * as UserApi from '@/api/system/user'; // 引入用户API
+import * as DeptApi from '@/api/system/dept'; // 引入部门API
+import { handleTree } from '@/utils/tree'; // 引入树形处理工具
 import { IotProjectTaskScheduleApi } from '@/api/pms/iotprojecttaskschedule'
 import { IotRhDailyReportApi } from '@/api/pms/iotrhdailyreport'
 import { IotRdDailyReportApi } from '@/api/pms/iotrddailyreport'
-import dayjs from 'dayjs' // 引入 dayjs 用于时间格式化
+import dayjs from 'dayjs'; // 引入 dayjs 用于时间格式化
 import { ref, reactive, onMounted, computed, nextTick, watch } from 'vue'
 
 /** 项目信息 列表 */
@@ -389,6 +407,7 @@ const taskList = ref([]) // 任务列表的数据
 const selectedProject = ref(null) // 当前选中的项目
 const deptList = ref([]) // 部门列表
 const companyDeptList = ref<any[]>([]) // 在公司级部门列表
+const projectDeptOptions = ref<any[]>([]) // 项目部选项
 const deviceMap = ref({}) // 设备映射表
 const responsiblePersonList = ref([]) // 责任人列表
 
@@ -418,6 +437,7 @@ const queryParams = reactive({
   pageSize: 10,
   deptId: undefined,
   companyDeptId: undefined,
+  projectDeptId: undefined,
   deptName: undefined,
   contractName: undefined,
   contractCode: undefined,
@@ -434,6 +454,7 @@ const queryParams = reactive({
 })
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中
+const projectDeptLoading = ref(false)
 const { push } = useRouter() // 路由跳转
 
 // 列宽度配置
@@ -612,6 +633,29 @@ const resetQuery = () => {
   handleQuery()
 }
 
+const loadProjectDeptOptions = async (companyDeptId?: number) => {
+  if (!companyDeptId) {
+    projectDeptOptions.value = []
+    return
+  }
+
+  projectDeptLoading.value = true
+  try {
+    const res = await DeptApi.specifiedSimpleDepts(companyDeptId)
+    projectDeptOptions.value = res
+      .map((item: any) => ({
+        label: item.name,
+        value: item.id,
+        raw: item
+      }))
+      .filter((item) => item.raw.type === '2')
+  } catch (error) {
+    projectDeptOptions.value = []
+  } finally {
+    projectDeptLoading.value = false
+  }
+}
+
 // 加载施工工艺数据字典选项
 const loadTechnologyDictOptions = async (deptId: number) => {
   // 如果正在加载或已加载,直接返回
@@ -1037,6 +1081,9 @@ onMounted(async () => {
   companyDeptList.value = await DeptApi.companyLevelDepts()
 
   deptList.value = handleTree(await DeptApi.companyLevelChildrenDepts())
+  if (queryParams.companyDeptId) {
+    await loadProjectDeptOptions(queryParams.companyDeptId)
+  }
   getList()
   // 预加载任务进度字典
   // getTaskScheduleDictOptions()
@@ -1067,6 +1114,16 @@ onUnmounted(() => {
   }
 })
 
+watch(
+  () => queryParams.companyDeptId,
+  async (newVal, oldVal) => {
+    if (newVal === oldVal) return
+
+    queryParams.projectDeptId = undefined
+    await loadProjectDeptOptions(newVal)
+  }
+)
+
 // 监听列表数据变化重新计算列宽
 watch(
   list,

+ 65 - 32
src/views/pms/iotrhdailyreport/index.vue

@@ -1,5 +1,8 @@
 <script setup lang="ts">
-import { IotRhDailyReportApi } from '@/api/pms/iotrhdailyreport'
+import {
+  IotRhDailyReportApi,
+  type IotRhDailyReportTotalWorkloadVO
+} from '@/api/pms/iotrhdailyreport'
 import { useUserStore } from '@/store/modules/user'
 import download from '@/utils/download'
 import { rangeShortcuts } from '@/utils/formatTime'
@@ -95,6 +98,13 @@ const totalWork = ref({
 
 const totalLoading = ref(false)
 
+const totalWorkloadDetail = ref({
+  totalN2GasInjection: 0,
+  totalNaturalGasInjection: 0
+})
+
+const formatGasInjectionTooltipValue = (value?: number | null) => ((value || 0) / 10000).toFixed(2)
+
 const getTotal = useDebounceFn(async function () {
   totalLoading.value = true
 
@@ -113,7 +123,12 @@ const getTotal = useDebounceFn(async function () {
       totalWork.value.notReported = res1[2].count
     }
 
-    const res2 = await IotRhDailyReportApi.totalWorkload(other)
+    const res2: IotRhDailyReportTotalWorkloadVO = await IotRhDailyReportApi.totalWorkload(other)
+
+    totalWorkloadDetail.value = {
+      totalN2GasInjection: res2.totalN2GasInjection || 0,
+      totalNaturalGasInjection: res2.totalNaturalGasInjection || 0
+    }
 
     totalWork.value = {
       ...totalWork.value,
@@ -303,38 +318,56 @@ const openUnfilledDialog = () => {
       </el-form-item>
     </el-form>
     <div class="grid grid-cols-5 gap-3">
-      <div
-        v-for="info in totalWorkKeys"
-        :key="info[0]"
-        class="group relative bg-white dark:bg-[#1d1e1f] rounded-lg shadow-sm hover:shadow-md border border-gray-100 dark:border-gray-700 p-2.5 overflow-hidden transition-all duration-300"
-        :class="{
-          'cursor-pointer hover:border-blue-200 dark:hover:border-blue-800': info[2] === '未填报'
-        }"
-        @click="info[2] === '未填报' ? openUnfilledDialog() : ''"
-      >
-        <div class="relative z-10 flex flex-col h-full justify-center">
-          <span
-            class="text-[11px] text-gray-400 dark:text-gray-500 font-medium tracking-wide mb-0.5"
+      <template v-for="info in totalWorkKeys" :key="info[0]">
+        <el-tooltip :disabled="info[0] !== 'totalGasInjection'" placement="top">
+          <template #content>
+            <div>
+              累计氮气注气量:{{
+                formatGasInjectionTooltipValue(totalWorkloadDetail.totalN2GasInjection)
+              }}
+              万方
+            </div>
+            <div>
+              累计天然气注气量:{{
+                formatGasInjectionTooltipValue(totalWorkloadDetail.totalNaturalGasInjection)
+              }}
+              万方
+            </div>
+          </template>
+          <div
+            class="group relative bg-white dark:bg-[#1d1e1f] rounded-lg shadow-sm hover:shadow-md border border-gray-100 dark:border-gray-700 p-2.5 overflow-hidden transition-all duration-300"
+            :class="{
+              'cursor-pointer hover:border-blue-200 dark:hover:border-blue-800':
+                info[2] === '未填报',
+              'cursor-help': info[0] === 'totalGasInjection'
+            }"
+            @click="info[2] === '未填报' ? openUnfilledDialog() : ''"
           >
-            {{ info[2] }}
-          </span>
-          <div class="flex items-baseline gap-1">
-            <count-to
-              class="text-lg font-bold text-gray-800 dark:text-gray-100 leading-none tracking-tight font-sans"
-              :start-val="0"
-              :end-val="totalWork[info[0]]"
-              :decimals="info[4]"
-            />
-            <span class="text-[10px] text-gray-400 font-normal">{{ info[1] }}</span>
+            <div class="relative z-10 flex flex-col h-full justify-center">
+              <span
+                class="text-[11px] text-gray-400 dark:text-gray-500 font-medium tracking-wide mb-0.5"
+              >
+                {{ info[2] }}
+              </span>
+              <div class="flex items-baseline gap-1">
+                <count-to
+                  class="text-lg font-bold text-gray-800 dark:text-gray-100 leading-none tracking-tight font-sans"
+                  :start-val="0"
+                  :end-val="totalWork[info[0]]"
+                  :decimals="info[4]"
+                />
+                <span class="text-[10px] text-gray-400 font-normal">{{ info[1] }}</span>
+              </div>
+            </div>
+
+            <div
+              class="absolute -right-2 -bottom-3 opacity-40 dark:opacity-60 transform rotate-[-10deg] transition-transform duration-500 group-hover:scale-110 group-hover:rotate-0"
+            >
+              <div :class="info[3]" class="text-5xl"></div>
+            </div>
           </div>
-        </div>
-
-        <div
-          class="absolute -right-2 -bottom-3 opacity-40 dark:opacity-60 transform rotate-[-10deg] transition-transform duration-500 group-hover:scale-110 group-hover:rotate-0"
-        >
-          <div :class="info[3]" class="text-5xl"></div>
-        </div>
-      </div>
+        </el-tooltip>
+      </template>
     </div>
 
     <rh-table

+ 2 - 0
src/views/pms/iotrhdailyreport/rh-table.vue

@@ -45,6 +45,7 @@ interface ListItem {
   yearTotalPower: number
   yearTotalFuel: number
   capacity: number
+  techniqueNames: string
 }
 
 const props = defineProps({
@@ -196,6 +197,7 @@ function handleCurrentChange(val: number) {
               </template>
             </zm-table-column>
             <zm-table-column label="施工区域" prop="location" />
+            <zm-table-column label="施工工艺" prop="techniqueNames" />
             <zm-table-column label="搬迁安装天数" prop="relocationDays" />
             <zm-table-column label="设计注气量(万方)" prop="designInjection" />
             <zm-table-column

+ 56 - 20
src/views/pms/iotrhdailyreport/summary.vue

@@ -1,6 +1,9 @@
 <script setup lang="ts">
 import dayjs from 'dayjs'
-import { IotRhDailyReportApi } from '@/api/pms/iotrhdailyreport'
+import {
+  IotRhDailyReportApi,
+  type IotRhDailyReportTotalWorkloadVO
+} from '@/api/pms/iotrhdailyreport'
 import { useDebounceFn } from '@vueuse/core'
 import CountTo from '@/components/count-to1.vue'
 import * as echarts from 'echarts'
@@ -90,6 +93,13 @@ const totalWork = ref({
 
 const totalLoading = ref(false)
 
+const totalWorkloadDetail = ref({
+  totalN2GasInjection: 0,
+  totalNaturalGasInjection: 0
+})
+
+const formatGasInjectionTooltipValue = (value?: number | null) => ((value || 0) / 10000).toFixed(2)
+
 const getTotal = useDebounceFn(async () => {
   totalLoading.value = true
 
@@ -108,7 +118,12 @@ const getTotal = useDebounceFn(async () => {
       totalWork.value.notReported = res1[2].count
     }
 
-    const res2 = await IotRhDailyReportApi.totalWorkload(other)
+    const res2: IotRhDailyReportTotalWorkloadVO = await IotRhDailyReportApi.totalWorkload(other)
+
+    totalWorkloadDetail.value = {
+      totalN2GasInjection: res2.totalN2GasInjection || 0,
+      totalNaturalGasInjection: res2.totalNaturalGasInjection || 0
+    }
 
     totalWork.value = {
       ...totalWork.value,
@@ -653,24 +668,45 @@ const { ZmTable, ZmTableColumn } = useTableComponents()
       </el-form-item>
     </el-form>
     <div class="grid grid-cols-8 gap-8">
-      <div
-        v-for="info in totalWorkKeys"
-        :key="info[0]"
-        class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-1 flex flex-col items-center justify-center gap-1"
-      >
-        <div class="size-7.5" :class="info[3]"></div>
-        <count-to
-          class="text-2xl font-medium"
-          :start-val="0"
-          :end-val="totalWork[info[0]]"
-          :decimals="info[4]"
-          @click="info[2] === '未填报' ? openUnfilledDialog() : ''"
-        >
-          <span class="text-xs leading-8 text-[var(--el-text-color-regular)]">暂无数据</span>
-        </count-to>
-        <div class="text-xs font-medium text-[var(--el-text-color-regular)]">{{ info[1] }}</div>
-        <div class="text-sm font-medium text-[var(--el-text-color-regular)]">{{ info[2] }}</div>
-      </div>
+      <template v-for="info in totalWorkKeys" :key="info[0]">
+        <el-tooltip :disabled="info[0] !== 'totalGasInjection'" placement="top">
+          <template #content>
+            <div>
+              累计氮气注气量:{{
+                formatGasInjectionTooltipValue(totalWorkloadDetail.totalN2GasInjection)
+              }}
+              万方
+            </div>
+            <div>
+              累计天然气注气量:{{
+                formatGasInjectionTooltipValue(totalWorkloadDetail.totalNaturalGasInjection)
+              }}
+              万方
+            </div>
+          </template>
+          <div
+            class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-1 flex flex-col items-center justify-center gap-1"
+          >
+            <div class="size-7.5" :class="info[3]"></div>
+
+            <count-to
+              class="text-2xl font-medium"
+              :class="{ 'cursor-help': info[0] === 'totalGasInjection' }"
+              :start-val="0"
+              :end-val="totalWork[info[0]]"
+              :decimals="info[4]"
+              @click="info[2] === '未填报' ? openUnfilledDialog() : ''"
+            >
+              <span class="text-xs leading-8 text-[var(--el-text-color-regular)]">暂无数据</span>
+            </count-to>
+
+            <div class="text-xs font-medium text-[var(--el-text-color-regular)]">{{ info[1] }}</div>
+            <div class="text-sm font-medium text-[var(--el-text-color-regular)]">
+              {{ info[2] }}
+            </div>
+          </div>
+        </el-tooltip>
+      </template>
     </div>
 
     <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow flex flex-col p-4 gap-2">