|
|
@@ -2,7 +2,7 @@
|
|
|
<div class="page-container">
|
|
|
<el-row :gutter="16" class="summary">
|
|
|
<!-- 原有的统计卡片部分保持不变 -->
|
|
|
- <el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
+ <el-col v-loading="loading" :sm="3" :xs="24">
|
|
|
<SummaryCard
|
|
|
:value="device.total || 0"
|
|
|
icon="fa-solid:project-diagram"
|
|
|
@@ -11,7 +11,7 @@
|
|
|
:title="t('stat.deviceCount')"
|
|
|
/>
|
|
|
</el-col>
|
|
|
- <el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
+ <el-col v-loading="loading" :sm="3" :xs="24">
|
|
|
<SummaryCard
|
|
|
:value="maintain.total || 0"
|
|
|
icon="fa-solid:list"
|
|
|
@@ -20,7 +20,7 @@
|
|
|
:title="t('stat.repairOrder')"
|
|
|
/>
|
|
|
</el-col>
|
|
|
- <el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
+ <el-col v-loading="loading" :sm="3" :xs="24">
|
|
|
<SummaryCard
|
|
|
:value="fill.unfilledCount || 0"
|
|
|
icon="fa-solid:times-circle"
|
|
|
@@ -29,7 +29,7 @@
|
|
|
:title="t('stat.operationNotFilled')"
|
|
|
/>
|
|
|
</el-col>
|
|
|
- <el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
+ <el-col v-loading="loading" :sm="3" :xs="24">
|
|
|
<SummaryCard
|
|
|
:value="fill.filledCount || 0"
|
|
|
icon="fa-solid:award"
|
|
|
@@ -38,7 +38,7 @@
|
|
|
:title="t('stat.operationFilled')"
|
|
|
/>
|
|
|
</el-col>
|
|
|
- <el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
+ <el-col v-loading="loading" :sm="3" :xs="24">
|
|
|
<SummaryCard
|
|
|
:value="by.todo || 0"
|
|
|
icon="fa-solid:times-circle"
|
|
|
@@ -47,7 +47,7 @@
|
|
|
:title="t('stat.notMaintained')"
|
|
|
/>
|
|
|
</el-col>
|
|
|
- <el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
+ <el-col v-loading="loading" :sm="3" :xs="24">
|
|
|
<SummaryCard
|
|
|
:value="by.finished || 0"
|
|
|
icon="fa-solid:award"
|
|
|
@@ -56,7 +56,7 @@
|
|
|
:title="t('stat.maintained')"
|
|
|
/>
|
|
|
</el-col>
|
|
|
- <el-col v-loading="loading" :sm="3" :xs="12">
|
|
|
+ <el-col v-loading="loading" :sm="3" :xs="24">
|
|
|
<SummaryCard
|
|
|
:value="inspect.todo || 0"
|
|
|
icon="fa-solid:times-circle"
|
|
|
@@ -77,17 +77,58 @@
|
|
|
</el-row>
|
|
|
<el-row :gutter="16" class="mb-4">
|
|
|
<!-- 设备状态统计和工单数量情况图表部分保持不变 -->
|
|
|
- <el-col :span="10">
|
|
|
+ <el-col :span="6" :xs="24">
|
|
|
<el-card class="chart-card" shadow="never">
|
|
|
<template #header>
|
|
|
<div class="flex items-center">
|
|
|
<span class="text-base font-medium " style="color: #b6c8da">{{t('stat.deviceStatus')}}</span>
|
|
|
</div>
|
|
|
</template>
|
|
|
- <div ref="statusChartRef" class="h-[290px]"></div>
|
|
|
+ <div style="display:flex; align-items:center;min-height: 292px;">
|
|
|
+ <div ref="statusChartRef" style="width:100%; max-width:250px; height:250px;"></div>
|
|
|
+ <div class="text-[12px]" style="width:100%; display:flex; flex-wrap:wrap; justify-content:center; gap:8px; color:#fff;margin-top: -50px;">
|
|
|
+ <div v-for="item in legendData" :key="item.name" style="display:flex; align-items:center; gap:12px; padding:0; min-width:160px; justify-content:space-between;">
|
|
|
+ <div style="display:flex; align-items:center; gap:8px;">
|
|
|
+ <span :style="{display:'inline-block', width:'12px', height:'12px', 'border-radius':'50%', background:item.color}"></span>
|
|
|
+ <span>{{ item.name }}</span>
|
|
|
+ </div>
|
|
|
+ <div style="display:flex; align-items:center; gap:10px; color:#fff;">
|
|
|
+ <span style="font-weight:700">{{ item.value }} 台</span>
|
|
|
+ <span>{{ item.percent }}%</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="10" :xs="24">
|
|
|
+ <el-card class="chart-card" shadow="never">
|
|
|
+ <template #header>
|
|
|
+ <div class="flex items-center justify-between">
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">国内设备分布及价值(国内RMB)</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="overflow-auto">
|
|
|
+ <el-table
|
|
|
+ :data="projectData"
|
|
|
+ border
|
|
|
+ @row-click="projectDataRowClick"
|
|
|
+ :header-cell-style="{color:'#fff'}"
|
|
|
+ :cell-style="{ color: '#fff', height: '65px' }"
|
|
|
+ style="width:100%"
|
|
|
+
|
|
|
+ >
|
|
|
+
|
|
|
+ <el-table-column prop="dept" label="地区" width="120" align="center" fixed="left" />
|
|
|
+ <el-table-column prop="count" label="设备数量" min-width="100" align="center" />
|
|
|
+ <el-table-column prop="orig_value" label="原值(万元)" min-width="100" align="center" />
|
|
|
+ <el-table-column prop="net_value" label="净值(万元)" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="orig_ratio" label="原值占比" min-width="100" align="center" />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
- <el-col :span="14">
|
|
|
+ <el-col :span="8" :xs="24">
|
|
|
<el-card class="chart-card" shadow="never">
|
|
|
<template #header>
|
|
|
<div class="flex items-center justify-between">
|
|
|
@@ -98,9 +139,10 @@
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
+
|
|
|
<el-row :gutter="16" class="mb-4">
|
|
|
<!-- 备件更换情况部分保持不变 -->
|
|
|
- <el-col :span="10">
|
|
|
+ <el-col :span="10" :xs="24">
|
|
|
<el-card class="chart-card" shadow="never">
|
|
|
<template #header>
|
|
|
<div style="display: flex; flex-direction: row; justify-content: space-between">
|
|
|
@@ -193,68 +235,53 @@
|
|
|
</div>
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
- <el-col :span="14">
|
|
|
- <div class="flex flex-col justify-between">
|
|
|
- <el-card class="chart-card" shadow="never">
|
|
|
- <template #header>
|
|
|
- <div class="flex items-center justify-between">
|
|
|
- <span class="text-base font-medium " style="color: #b6c8da">{{t('stat.maintenanceStatus')}}</span>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <div class="flex mr-3">
|
|
|
- <div ref="maintenanceChartRef" class="h-[167px] w-2/5"></div>
|
|
|
- <div class="w-3/5 p-4 flex flex-col mt-5">
|
|
|
- <div class="flex justify-between">
|
|
|
- <div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:list" size="30" color="#f1d209" />
|
|
|
- <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.totalOrder')}}</p>
|
|
|
- <span style="font-size: 20px;color: white">{{ (by.finished?by.finished:0) + (by.todo?by.todo:0) }}</span>
|
|
|
- </div>
|
|
|
- <div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:check-circle" size="30" color="green" />
|
|
|
- <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.finishedOrder')}}</p>
|
|
|
- <span style="font-size: 20px;color: white">{{ by.finished?by.finished:0 }}</span>
|
|
|
- </div>
|
|
|
- <div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:hourglass-half" size="30" color="#e14f0f" />
|
|
|
- <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.pendingOrder')}} </p>
|
|
|
- <span style="font-size: 20px;color: white">{{ by.todo?by.todo:0 }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-card>
|
|
|
- <el-card class="chart-card mt-2" shadow="never">
|
|
|
- <template #header>
|
|
|
- <div class="flex items-center justify-between">
|
|
|
- <span class="text-base font-medium " style="color: #b6c8da">{{t('stat.inspectStatus')}}</span>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <div class="flex mr-3">
|
|
|
- <div ref="inspectChartRef" class="h-[167px] w-2/5"></div>
|
|
|
- <div class="w-3/5 p-4 flex flex-col mt-5">
|
|
|
- <div class="flex justify-between">
|
|
|
- <div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:list" size="30" color="#f1d209" />
|
|
|
- <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.totalOrder')}}</p>
|
|
|
- <span style="font-size: 20px;color: white">{{ inspect.todo + inspect.finished }}</span>
|
|
|
- </div>
|
|
|
- <div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:check-circle" size="30" color="green" />
|
|
|
- <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.finishedOrder')}}</p>
|
|
|
- <span style="font-size: 20px;color: white">{{ inspect.finished }}</span>
|
|
|
- </div>
|
|
|
- <div class="flex flex-col items-center">
|
|
|
- <Icon icon="fa-solid:hourglass-half" size="30" color="#e14f0f" />
|
|
|
- <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.pendingOrder')}}</p>
|
|
|
- <span style="font-size: 20px;color: white">{{ inspect.todo }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <!-- 月度工作量表 -->
|
|
|
+ <el-col :span="14" :xs="24">
|
|
|
+ <el-card class="chart-card" shadow="never">
|
|
|
+ <template #header>
|
|
|
+ <div class="flex items-center justify-between">
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">月度工作量表</span>
|
|
|
</div>
|
|
|
- </el-card>
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
+ <div class="overflow-auto">
|
|
|
+ <el-table
|
|
|
+ :data="monthData"
|
|
|
+ border
|
|
|
+ height="420px"
|
|
|
+ :disabled-affix="true"
|
|
|
+ style="width:100%"
|
|
|
+ :header-cell-style="{color:'#fff'}"
|
|
|
+ :cell-style="{ color: '#fff' }"
|
|
|
+ :summary-method="tableSummary"
|
|
|
+
|
|
|
+ show-summary>
|
|
|
+ <el-table-column prop="month" label="月份" width="80" fixed="left" align="center" />
|
|
|
+
|
|
|
+ <el-table-column label="2025年" align="center">
|
|
|
+ <el-table-column prop="y2025_fractures" label="压裂井数" align="center" width="110" />
|
|
|
+ <el-table-column prop="y2025_layers" label="压裂层数" width="110" align="center" />
|
|
|
+ <el-table-column prop="y2025_pump_trips" label="泵车台次" width="110" align="center" />
|
|
|
+ <el-table-column prop="y2025_oil_wells" label="连油井数" width="110" align="center" />
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column label="2024年" align="center">
|
|
|
+ <el-table-column prop="y2024_fractures" label="压裂井数" width="110" align="center" />
|
|
|
+ <el-table-column prop="y2024_layers" label="压裂层数" width="110" align="center" />
|
|
|
+ <el-table-column prop="y2024_pump_trips" label="泵车台次" width="110" align="center" />
|
|
|
+ <el-table-column prop="y2024_oil_wells" label="连油井数" width="110" align="center" />
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column label="同比增长量" align="center">
|
|
|
+ <el-table-column prop="diff_fractures" label="压裂井数" width="110" align="center" />
|
|
|
+ <el-table-column prop="diff_layers" label="压裂层数" width="110" align="center" />
|
|
|
+ <el-table-column prop="diff_pump_trips" label="泵车台次" width="110" align="center" />
|
|
|
+ <el-table-column prop="diff_oil_wells" label="连油井数" width="110" align="center" />
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
</el-col>
|
|
|
+ <!-- 月度工作量表结束 -->
|
|
|
</el-row>
|
|
|
</div>
|
|
|
<el-dialog
|
|
|
@@ -303,6 +330,111 @@
|
|
|
</el-table>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <el-dialog
|
|
|
+ v-model="projectDataDialog"
|
|
|
+
|
|
|
+ width="45vw"
|
|
|
+
|
|
|
+ class="custom-scroll-dialog"
|
|
|
+ >
|
|
|
+ <div class="dialog-scroll-content">
|
|
|
+ <el-card class="bg-[#284d72]!" shadow="never">
|
|
|
+ <template #header>
|
|
|
+ <div class="flex items-center justify-between">
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">国内设备分布及价值(国内RMB)</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="overflow-auto" style="min-height:260px;">
|
|
|
+ <el-table
|
|
|
+ :data="domesticData"
|
|
|
+ border
|
|
|
+ :header-cell-style="{color:'#fff'}"
|
|
|
+ :cell-style="{ color: '#fff' }"
|
|
|
+ style="width:100%"
|
|
|
+ :summary-method="tableSummary"
|
|
|
+ show-summary>
|
|
|
+ <el-table-column prop="index" label="序号" width="60" align="center" fixed="left" />
|
|
|
+ <el-table-column prop="dept" label="项目部" width="120" align="center" fixed="left" />
|
|
|
+ <el-table-column prop="count" label="设备数量" min-width="100" align="center" />
|
|
|
+ <el-table-column prop="orig_value" label="原值(万元)" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="net_value" label="净值(万元)" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="orig_ratio" label="原值占比" min-width="100" align="center" />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ <el-dialog
|
|
|
+ v-model="projectDataDialog2"
|
|
|
+
|
|
|
+ width="45vw"
|
|
|
+
|
|
|
+ class="custom-scroll-dialog"
|
|
|
+ >
|
|
|
+ <div class="dialog-scroll-content">
|
|
|
+ <el-card class="bg-[#284d72]!" shadow="never">
|
|
|
+ <template #header>
|
|
|
+ <div class="flex items-center justify-between">
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">伊拉克设备分布及价值(美元)</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="overflow-auto" style="min-height:260px;">
|
|
|
+ <el-table
|
|
|
+ :data="iraqTableData"
|
|
|
+ border
|
|
|
+ :header-cell-style="{color:'#fff'}"
|
|
|
+ :cell-style="{ color: '#fff' }"
|
|
|
+ style="width:100%"
|
|
|
+
|
|
|
+ >
|
|
|
+ <el-table-column prop="index" label="序号" width="60" align="center" fixed="left" />
|
|
|
+ <el-table-column prop="dept" label="项目部" width="120" align="center" fixed="left" />
|
|
|
+ <el-table-column prop="count" label="设备数量" min-width="100" align="center" />
|
|
|
+ <el-table-column prop="orig_value_usd" label="原值(万元)" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="net_value_usd" label="净值(万元)" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="orig_ratio" label="原值占比" min-width="100" align="center" />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <el-dialog
|
|
|
+ v-model="projectDataDialog3"
|
|
|
+
|
|
|
+ width="45vw"
|
|
|
+
|
|
|
+ class="custom-scroll-dialog"
|
|
|
+ >
|
|
|
+ <div class="dialog-scroll-content">
|
|
|
+ <el-card class="bg-[#284d72]!" shadow="never">
|
|
|
+ <template #header>
|
|
|
+ <div class="flex items-center justify-between">
|
|
|
+ <span class="text-base font-medium " style="color: #b6c8da">利比亚设备分布及价值(第纳尔)</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="overflow-auto" style="min-height:260px;">
|
|
|
+ <el-table
|
|
|
+ :data="libyaTableData"
|
|
|
+ border
|
|
|
+ :header-cell-style="{color:'#fff'}"
|
|
|
+ :cell-style="{ color: '#fff' }"
|
|
|
+ :row-class-name="tableRowClass"
|
|
|
+ style="width:100%"
|
|
|
+ :summary-method="tableSummary"
|
|
|
+ >
|
|
|
+ <el-table-column prop="index" label="序号" width="60" align="center" fixed="left" />
|
|
|
+ <el-table-column prop="dept" label="项目部" width="120" align="center" fixed="left" />
|
|
|
+ <el-table-column prop="count" label="设备数量" min-width="100" align="center" />
|
|
|
+ <el-table-column prop="orig_value" label="原值(万元)" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="net_value" label="净值(万元)" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="orig_ratio" label="原值占比" min-width="100" align="center" />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
</template>
|
|
|
<script lang="ts" setup>
|
|
|
import { MemberSummaryRespVO } from '@/api/mall/statistics/member'
|
|
|
@@ -358,6 +490,7 @@ const handleDialogClose = () => {
|
|
|
teamDialogVisible.value = false
|
|
|
teamTableData.value = [] // 清空表格数据
|
|
|
}
|
|
|
+
|
|
|
// 格式化利用率为百分比
|
|
|
const formatRate = (row) => {
|
|
|
return (row.utilizationRate * 100).toFixed(2) + '%'
|
|
|
@@ -383,6 +516,7 @@ const handleRowClick = (row, column, event) => {
|
|
|
const dateRange = ref<[Date, Date] | null>(null)
|
|
|
const summary = ref<MemberSummaryRespVO>() // 会员统计数据
|
|
|
const statusChartRef = ref() // 设备数量统计的图表
|
|
|
+let statusChartInstance = null
|
|
|
const qxRef = ref(null)
|
|
|
let qxInstance = null
|
|
|
const sparePartRef = ref(null)
|
|
|
@@ -396,7 +530,20 @@ let inspectionChartInstance = null
|
|
|
const { t } = useI18n() // 国际化
|
|
|
const maintenanceChartRef1 = ref(null)
|
|
|
|
|
|
-const typeData = ref({})
|
|
|
+const typeData = ref([])
|
|
|
+// 配色(与图表保持一致)
|
|
|
+const statusColors = ['#2ed3df', '#34d399', '#ff6b95', '#4aa3ff', '#f59e0b', '#ef4444', '#7dd3fc']
|
|
|
+
|
|
|
+const legendData = computed(() => {
|
|
|
+ const arr = Array.isArray(typeData.value) ? typeData.value : []
|
|
|
+ const total = arr.reduce((s, it) => s + (Number(it.value) || 0), 0)
|
|
|
+ return arr.map((it, idx) => ({
|
|
|
+ name: it.name,
|
|
|
+ value: it.value || 0,
|
|
|
+ percent: total ? ((Number(it.value) / total) * 100).toFixed(2) : '0.00',
|
|
|
+ color: statusColors[idx % statusColors.length]
|
|
|
+ }))
|
|
|
+})
|
|
|
const orderSevenData = ref({})
|
|
|
const device = ref({
|
|
|
total: undefined,
|
|
|
@@ -878,45 +1025,187 @@ const initInspectionChart = () => {
|
|
|
|
|
|
/** 初始化图表 */
|
|
|
const initDeviceStatusCharts = () => {
|
|
|
- // 设备数量统计
|
|
|
- echarts.init(statusChartRef.value).setOption({
|
|
|
+ if (!statusChartRef.value) return
|
|
|
+ // dispose old instance
|
|
|
+ try {
|
|
|
+ if (statusChartInstance) {
|
|
|
+ statusChartInstance.dispose()
|
|
|
+ statusChartInstance = null
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+ statusChartInstance = echarts.init(statusChartRef.value)
|
|
|
+ const data = Array.isArray(typeData.value) ? typeData.value : []
|
|
|
+ const option = {
|
|
|
+ color: statusColors,
|
|
|
tooltip: {
|
|
|
- trigger: 'item'
|
|
|
- },
|
|
|
- legend: {
|
|
|
- orient: 'horizontal', // 水平排列图例项
|
|
|
- bottom: '0%', // 放置在底部
|
|
|
- icon: 'circle',
|
|
|
- textStyle: {
|
|
|
- color: '#B6C8DA'
|
|
|
- }
|
|
|
+ trigger: 'item',
|
|
|
+ formatter: '{b}: {c} ({d}%)'
|
|
|
},
|
|
|
series: [
|
|
|
{
|
|
|
name: '',
|
|
|
type: 'pie',
|
|
|
- radius: ['50%', '80%'],
|
|
|
+ radius: ['45%', '65%'],
|
|
|
+ center: ['50%', '36%'],
|
|
|
avoidLabelOverlap: false,
|
|
|
- center: ['50%', '44%'],
|
|
|
- label: {
|
|
|
- show: false,
|
|
|
- position: 'outside'
|
|
|
- },
|
|
|
- emphasis: {
|
|
|
- label: {
|
|
|
- show: true,
|
|
|
- fontSize: 15,
|
|
|
- fontWeight: 'bold',
|
|
|
- color: 'white'
|
|
|
- }
|
|
|
- },
|
|
|
- labelLine: {
|
|
|
- show: false
|
|
|
- },
|
|
|
- data: typeData.value
|
|
|
+ label: { show: false },
|
|
|
+ labelLine: { show: false },
|
|
|
+ data: data.map((it) => ({ name: it.name, value: it.value }))
|
|
|
}
|
|
|
]
|
|
|
+ }
|
|
|
+ statusChartInstance.setOption(option)
|
|
|
+}
|
|
|
+
|
|
|
+// 月度工作量表数据
|
|
|
+const monthData = ref<any[]>([
|
|
|
+ { month: '1月', y2025_fractures: 49, y2025_layers: 102, y2025_pump_trips: 621, y2025_oil_wells: 17, y2024_fractures: 23, y2024_layers: 42, y2024_pump_trips: 347, y2024_oil_wells: 9 },
|
|
|
+ { month: '2月', y2025_fractures: 30, y2025_layers: 52, y2025_pump_trips: 438, y2025_oil_wells: 15, y2024_fractures: 14, y2024_layers: 41, y2024_pump_trips: 46, y2024_oil_wells: 11 },
|
|
|
+ { month: '3月', y2025_fractures: 48, y2025_layers: 127, y2025_pump_trips: 326, y2025_oil_wells: 30, y2024_fractures: 42, y2024_layers: 58, y2024_pump_trips: 321, y2024_oil_wells: 17 },
|
|
|
+ { month: '4月', y2025_fractures: 49, y2025_layers: 130, y2025_pump_trips: 1203, y2025_oil_wells: 45, y2024_fractures: 32, y2024_layers: 184, y2024_pump_trips: 1046, y2024_oil_wells: 30 },
|
|
|
+ { month: '5月', y2025_fractures: 13, y2025_layers: 76, y2025_pump_trips: 701, y2025_oil_wells: 18, y2024_fractures: 73, y2024_layers: 133, y2024_pump_trips: 414, y2024_oil_wells: 24 },
|
|
|
+ { month: '6月', y2025_fractures: 34, y2025_layers: 187, y2025_pump_trips: 831, y2025_oil_wells: 30, y2024_fractures: 29, y2024_layers: 113, y2024_pump_trips: 750, y2024_oil_wells: 35 },
|
|
|
+ { month: '7月', y2025_fractures: 30, y2025_layers: 230, y2025_pump_trips: 1157, y2025_oil_wells: 51, y2024_fractures: 24, y2024_layers: 47, y2024_pump_trips: 326, y2024_oil_wells: 17 },
|
|
|
+ { month: '8月', y2025_fractures: 59, y2025_layers: 218, y2025_pump_trips: 1163, y2025_oil_wells: 12, y2024_fractures: 36, y2024_layers: 121, y2024_pump_trips: 1107, y2024_oil_wells: 26 },
|
|
|
+ { month: '9月', y2025_fractures: 48, y2025_layers: 80, y2025_pump_trips: 440, y2025_oil_wells: 39, y2024_fractures: 35, y2024_layers: 162, y2024_pump_trips: 928, y2024_oil_wells: 36 },
|
|
|
+ { month: '10月', y2025_fractures: 45, y2025_layers: 99, y2025_pump_trips: 697, y2025_oil_wells: 49, y2024_fractures: 36, y2024_layers: 116, y2024_pump_trips: 891, y2024_oil_wells: 33 },
|
|
|
+ { month: '11月', y2025_fractures: null, y2025_layers: null, y2025_pump_trips: null, y2025_oil_wells: null, y2024_fractures: 19, y2024_layers: 102, y2024_pump_trips: 582, y2024_oil_wells: 36 },
|
|
|
+ { month: '12月', y2025_fractures: null, y2025_layers: null, y2025_pump_trips: null, y2025_oil_wells: null, y2024_fractures: 51, y2024_layers: 186, y2024_pump_trips: 971, y2024_oil_wells: 32 }
|
|
|
+])
|
|
|
+
|
|
|
+// 计算同比差值(2025 - 2024),保留 null 的情况
|
|
|
+monthData.value.forEach((row) => {
|
|
|
+ const f2025 = row.y2025_fractures
|
|
|
+ const f2024 = row.y2024_fractures
|
|
|
+ row.diff_fractures = (f2025 == null || f2024 == null) ? null : (f2025 - f2024)
|
|
|
+
|
|
|
+ const l2025 = row.y2025_layers
|
|
|
+ const l2024 = row.y2024_layers
|
|
|
+ row.diff_layers = (l2025 == null || l2024 == null) ? null : (l2025 - l2024)
|
|
|
+
|
|
|
+ const p2025 = row.y2025_pump_trips
|
|
|
+ const p2024 = row.y2024_pump_trips
|
|
|
+ row.diff_pump_trips = (p2025 == null || p2024 == null) ? null : (p2025 - p2024)
|
|
|
+
|
|
|
+ const o2025 = row.y2025_oil_wells
|
|
|
+ const o2024 = row.y2024_oil_wells
|
|
|
+ row.diff_oil_wells = (o2025 == null || o2024 == null) ? null : (o2025 - o2024)
|
|
|
+})
|
|
|
+
|
|
|
+// 表格合计方法
|
|
|
+const tableSummary = ({ columns, data }: any) => {
|
|
|
+ const sums: any[] = []
|
|
|
+ columns.forEach((column: any, index: number) => {
|
|
|
+ if (index === 0) {
|
|
|
+ sums[index] = '合计'
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const property = column.property
|
|
|
+ if (!property) {
|
|
|
+ sums[index] = ''
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let total = 0
|
|
|
+ let hasValue = false
|
|
|
+ data.forEach((row: any) => {
|
|
|
+ const val = row[property]
|
|
|
+ if (val != null && !isNaN(Number(val))) {
|
|
|
+ total += Number(val)
|
|
|
+ hasValue = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // 针对国内表的 "原值占比" 列,按 全局合计 计算百分比
|
|
|
+ if (data === domesticData.value && property === 'orig_ratio') {
|
|
|
+ const domesticOrig = data.reduce((acc: number, r: any) => acc + (r.orig_value ? Number(r.orig_value) : 0), 0)
|
|
|
+ const overall = domesticOrig + Number(iraqRmbTotal.value || 0) + Number(libyaRmbTotal.value || 0)
|
|
|
+ sums[index] = overall > 0 ? ( (domesticOrig / overall) * 100 ).toFixed(2) + '%' : ''
|
|
|
+ } else {
|
|
|
+ sums[index] = hasValue ? total : ''
|
|
|
+ }
|
|
|
})
|
|
|
+ return sums
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const projectData = ref<any[]>([
|
|
|
+ { index: 1, dept: '国内', count: 224, orig_value: 44653.40, net_value: 9938.77, orig_ratio: '72.52%' },
|
|
|
+ { index: 2, dept: '伊拉克', count: 279, orig_value: 14279.83, net_value: 5760.03, orig_ratio: '23.19%' },
|
|
|
+ { index: 3, dept: '利比亚', count: 22, orig_value: 2641.07, net_value: 2557.84, orig_ratio: '4.29%' },
|
|
|
+ { index: 4, dept: '合计', count: 525, orig_value: 61574.30, net_value: 18256.63, orig_ratio: '' }
|
|
|
+])
|
|
|
+
|
|
|
+let projectDataDialog = ref(false)
|
|
|
+let projectDataDialog2 = ref(false)
|
|
|
+let projectDataDialog3 = ref(false)
|
|
|
+
|
|
|
+// projectDataRowClick
|
|
|
+const projectDataRowClick = (row, column, event) => {
|
|
|
+ console.log('点击的行数据:', row);
|
|
|
+
|
|
|
+
|
|
|
+ if(row.dept === '国内') {
|
|
|
+ // 显示国内表格
|
|
|
+ projectDataDialog.value = true
|
|
|
+ } else if (row.dept === '伊拉克') {
|
|
|
+ // 显示伊拉克表格
|
|
|
+ projectDataDialog2.value = true
|
|
|
+ } else if (row.dept === '利比亚') {
|
|
|
+ // 显示利比亚表格
|
|
|
+ projectDataDialog3.value = true
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+// 三张表的数据
|
|
|
+const domesticData = ref<any[]>([
|
|
|
+ { index: 1, dept: '公滩', count: 13, orig_value: 1506.88, net_value: 559.95, orig_ratio: '2.45%' },
|
|
|
+ { index: 2, dept: '新疆项目部', count: 58, orig_value: 5118.1, net_value: 1182.91, orig_ratio: '8.31%' },
|
|
|
+ { index: 3, dept: '青海项目', count: 33, orig_value: 14082.33, net_value: 736.94, orig_ratio: '22.87%' },
|
|
|
+ { index: 4, dept: '东部项目部', count: 49, orig_value: 5273.54, net_value: 683.58, orig_ratio: '8.56%' },
|
|
|
+ { index: 5, dept: '西南连油项目部', count: 24, orig_value: 4070.12, net_value: 743.99, orig_ratio: '6.61%' },
|
|
|
+ { index: 6, dept: '西南压裂项目部', count: 47, orig_value: 14602.44, net_value: 6031.39, orig_ratio: '23.72%' }
|
|
|
+])
|
|
|
+
|
|
|
+const iraqData = ref<any[]>([
|
|
|
+ { index: 1, dept: '伊拉克 哈法亚连油', count: 120, orig_value_usd: 694.78, net_value_usd: 94.44, orig_ratio: '8.02%' },
|
|
|
+ { index: 2, dept: '伊拉克 哈法亚压裂', count: 132, orig_value_usd: 1008.92, net_value_usd: 587.07, orig_ratio: '11.65%' },
|
|
|
+ { index: 3, dept: '伊拉克 B9增产', count: 27, orig_value_usd: 304.72, net_value_usd: 128.62, orig_ratio: '3.52%' }
|
|
|
+])
|
|
|
+
|
|
|
+const iraqTableData = computed(() => {
|
|
|
+ const base = iraqData.value.slice()
|
|
|
+ base.push({ index: '', dept: '合计', count: 279, orig_value: Number(279), orig_value_usd: Number(2008.41), net_value_usd: Number(810.13), orig_ratio: '' })
|
|
|
+ base.push({ index: '', dept: '折算RMB合计', count: '', orig_value: Number(61574.30), orig_value_usd: Number(14279.83), net_value_usd: Number(5760.03), orig_ratio: '23.19%' })
|
|
|
+ return base
|
|
|
+})
|
|
|
+
|
|
|
+// 折算RMB合计(数值)
|
|
|
+const iraqRmbTotal = ref(14279.83)
|
|
|
+
|
|
|
+const libyaData = ref<any[]>([
|
|
|
+ { index: 1, dept: '利比亚 连油8队', count: 22, orig_value: 2025.52, net_value: 1961.69, orig_ratio: '' }
|
|
|
+])
|
|
|
+
|
|
|
+const libyaRmbTotal = ref(2641.07)
|
|
|
+const libyaRmbNet = ref(2557.84)
|
|
|
+
|
|
|
+const libyaTableData = computed(() => {
|
|
|
+ const base = libyaData.value.slice()
|
|
|
+ base.push({ index: '', dept: '折算RMB合计', count: '', orig_value: Number(libyaRmbTotal.value), net_value: Number(libyaRmbNet.value), orig_ratio: '4.29%' })
|
|
|
+ base.push({ index: '', dept: '国内外合计', count: 525, orig_value: Number(61574.30), net_value: Number(18256.63), orig_ratio: '' })
|
|
|
+ return base
|
|
|
+})
|
|
|
+
|
|
|
+// 行样式:合计行与折算RMB合计高亮
|
|
|
+const tableRowClass = (row: any) => {
|
|
|
+ if (!row) return ''
|
|
|
+ if (row.dept === '合计') return 'summary-row'
|
|
|
+ if (row.dept && typeof row.dept === 'string' && row.dept.indexOf('折算') !== -1) return 'rmb-row'
|
|
|
+ return ''
|
|
|
}
|
|
|
|
|
|
/** 初始化 **/
|
|
|
@@ -927,6 +1216,45 @@ onMounted(async () => {
|
|
|
})
|
|
|
</script>
|
|
|
<style lang="scss" scoped>
|
|
|
+/*最外层透明*/
|
|
|
+::v-deep .el-table,
|
|
|
+::v-deep .el-table__expanded-cell {
|
|
|
+ background-color: transparent !important;
|
|
|
+}
|
|
|
+/* 表格内背景颜色 */
|
|
|
+
|
|
|
+::v-deep .el-table tr,
|
|
|
+::v-deep .el-table td {
|
|
|
+ background-color: transparent !important;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+::v-deep .el-table th {
|
|
|
+ background-color: #2196df !important;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .el-table__footer {
|
|
|
+ color: #fff !important;
|
|
|
+}
|
|
|
+::v-deep .el-table__footer-wrapper {
|
|
|
+ color: #fff !important;
|
|
|
+ background-color: #42c5f9 !important;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep th.el-table-fixed-column--left {
|
|
|
+ background-color: #3fc1f7 !important;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+::v-deep .el-table__footer-wrapper .is-leaf {
|
|
|
+ color: #fff !important;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep td.el-table-fixed-column--left {
|
|
|
+ background-color: #3fc1f7 !important;
|
|
|
+}
|
|
|
+
|
|
|
.summary {
|
|
|
.el-col {
|
|
|
margin-bottom: 1rem;
|