|
@@ -1,17 +1,12 @@
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
|
-import { QhseMonthReportApi } from '@/api/pms/qhse'
|
|
|
|
|
-import type {
|
|
|
|
|
- QhseMonthReportItem,
|
|
|
|
|
- ReportCompanyColumn,
|
|
|
|
|
- ReportMetricRow,
|
|
|
|
|
- ReportMetricValue
|
|
|
|
|
-} from './types'
|
|
|
|
|
|
|
+import { QhseMonthReportSummaryApi } from '@/api/pms/qhse'
|
|
|
|
|
+import type { QhseMonthReportItem, ReportCompanyColumn, ReportMetricRow } from './types'
|
|
|
import dayjs from 'dayjs'
|
|
import dayjs from 'dayjs'
|
|
|
import { computed, ref, watch } from 'vue'
|
|
import { computed, ref, watch } from 'vue'
|
|
|
|
|
|
|
|
interface Props {
|
|
interface Props {
|
|
|
visible: boolean
|
|
visible: boolean
|
|
|
- id?: number
|
|
|
|
|
|
|
+ yearMonths: string | undefined
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
interface TableRow {
|
|
interface TableRow {
|
|
@@ -26,165 +21,129 @@ const props = defineProps<Props>()
|
|
|
const emits = defineEmits(['update:visible'])
|
|
const emits = defineEmits(['update:visible'])
|
|
|
|
|
|
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
|
-const report = ref<QhseMonthReportItem>()
|
|
|
|
|
-
|
|
|
|
|
-const companyColumns: ReportCompanyColumn[] = [
|
|
|
|
|
- { key: 'rhxy', label: '瑞恒兴域' },
|
|
|
|
|
- { key: 'scrd', label: '四川瑞都' },
|
|
|
|
|
- { key: 'sxty', label: '陕西瑞鹰' },
|
|
|
|
|
- { key: 'eys', label: '俄油服' },
|
|
|
|
|
- { key: 'rqny', label: '瑞气能源' },
|
|
|
|
|
- { key: 'rljs', label: '瑞霖技术' },
|
|
|
|
|
- { key: 'bjhq', label: '北京总部' }
|
|
|
|
|
-]
|
|
|
|
|
|
|
+const reportList = ref<QhseMonthReportItem[]>([])
|
|
|
|
|
|
|
|
const metricRows: ReportMetricRow[] = [
|
|
const metricRows: ReportMetricRow[] = [
|
|
|
- { category: '人工时与里程', label: '员工人数', field: 'employee', unit: '人' },
|
|
|
|
|
- { category: '人工时与里程', label: '分包商人数', field: 'subcontractors', unit: '人' },
|
|
|
|
|
|
|
+ { category: '人工时和安全行驶公里数', label: '员工人数', field: 'employee', unit: '人' },
|
|
|
|
|
+ { category: '人工时和安全行驶公里数', label: '分包商人数', field: 'subcontractors', unit: '人' },
|
|
|
{
|
|
{
|
|
|
- category: '人工时与里程',
|
|
|
|
|
- label: '安全行驶里程数(公里)',
|
|
|
|
|
|
|
+ category: '人工时和安全行驶公里数',
|
|
|
|
|
+ label: '安全行驶里程数(公里)',
|
|
|
field: 'drivingMileage',
|
|
field: 'drivingMileage',
|
|
|
unit: '公里'
|
|
unit: '公里'
|
|
|
},
|
|
},
|
|
|
- { category: '人工时与里程', label: '总人工时数(小时)', field: 'totalManHours', unit: '小时' },
|
|
|
|
|
- { category: '被动性指标', label: '无事故累计天数(天)', field: 'withoutAccident', unit: '天' },
|
|
|
|
|
- { category: '被动性指标', label: '死亡事故(起)', field: 'fatality', unit: '起' },
|
|
|
|
|
- { category: '被动性指标', label: '损失工时事故(起)', field: 'injury', unit: '起' },
|
|
|
|
|
- { category: '被动性指标', label: '工作受限事件(起)', field: 'restrictedCase', unit: '起' },
|
|
|
|
|
- { category: '被动性指标', label: '医疗处理事件(起)', field: 'medicalCase', unit: '起' },
|
|
|
|
|
- { category: '被动性指标', label: '急救箱事件(起)', field: 'firstAidCase', unit: '起' },
|
|
|
|
|
- { category: '被动性指标', label: '交通事故(起)', field: 'vehicleAccident', unit: '起' },
|
|
|
|
|
- { category: '被动性指标', label: '未遂事件(起)', field: 'nearMiss', unit: '起' },
|
|
|
|
|
- { category: '被动性指标', label: '泄漏事件(起)', field: 'spill', unit: '起' },
|
|
|
|
|
- { category: '被动性指标', label: '违反保命规则的次数(次)', field: 'lifeSavingRules', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: '班前会(次)', field: 'toolboxTalk', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: 'QHSE管理委员会会议', field: 'committeeMeeting', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: 'QHSE月度例会', field: 'monthlyMeeting', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: '公司级隐患排查', field: 'companyHazard', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: 'QHSE检查', field: 'qhseInspection', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: '安全观察卡', field: 'socCards', unit: '张' },
|
|
|
|
|
- { category: '主动性指标', label: '工作许可审核', field: 'ptwAudit', unit: '份' },
|
|
|
|
|
- { category: '主动性指标', label: '工作安全分析', field: 'jsa', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: '演练次数', field: 'drills', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: 'QHSE培训次数', field: 'training', unit: '次' },
|
|
|
|
|
- { category: '主动性指标', label: 'QHSE培训人次', field: 'participantsTraining', unit: '人次' },
|
|
|
|
|
- { category: '主动性指标', label: 'QHSE培训学时数', field: 'trainingsHours', unit: '小时' },
|
|
|
|
|
- { category: '环境数据', label: '水消耗', field: 'waterConsumption', unit: '吨' },
|
|
|
|
|
- { category: '环境数据', label: '柴油消耗', field: 'dieselConsumption', unit: '升' },
|
|
|
|
|
- { category: '环境数据', label: '用电量', field: 'electricityConsumption', unit: '千瓦·小时' },
|
|
|
|
|
- { category: '环境数据', label: '天然气消耗量', field: 'naturalGasConsumption', unit: '立方米' },
|
|
|
|
|
- { category: '其他信息', label: '备注', field: 'remark', unit: '/' }
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ category: '人工时和安全行驶公里数',
|
|
|
|
|
+ label: '总人工时数(小时)',
|
|
|
|
|
+ field: 'totalManHours',
|
|
|
|
|
+ unit: '小时'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: 'QHSE被动性指标统计', label: '无事故累计天数', field: 'withoutAccident', unit: '天' },
|
|
|
|
|
+ { category: 'QHSE被动性指标统计', label: '死亡事故(起)', field: 'fatality', unit: '起' },
|
|
|
|
|
+ { category: 'QHSE被动性指标统计', label: '损失工时事故(起)', field: 'injury', unit: '起' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE被动性指标统计',
|
|
|
|
|
+ label: '工作受限事件(起)',
|
|
|
|
|
+ field: 'restrictedCase',
|
|
|
|
|
+ unit: '起'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: 'QHSE被动性指标统计', label: '医疗处理事件(起)', field: 'medicalCase', unit: '起' },
|
|
|
|
|
+ { category: 'QHSE被动性指标统计', label: '急救箱事件(起)', field: 'firstAidCase', unit: '起' },
|
|
|
|
|
+ { category: 'QHSE被动性指标统计', label: '交通事故(起)', field: 'vehicleAccident', unit: '起' },
|
|
|
|
|
+ { category: 'QHSE被动性指标统计', label: '未遂事件(起)', field: 'nearMiss', unit: '起' },
|
|
|
|
|
+ { category: 'QHSE被动性指标统计', label: '泄漏事件(起)', field: 'spill', unit: '起' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE被动性指标统计',
|
|
|
|
|
+ label: '违反保命规则的次数(次)',
|
|
|
|
|
+ field: 'lifeSavingRules',
|
|
|
|
|
+ unit: '次'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: 'QHSE主动性指标统计', label: '班前会(次)', field: 'toolboxTalk', unit: '次' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE主动性指标统计',
|
|
|
|
|
+ label: 'QHSE管理委员会会议(次)',
|
|
|
|
|
+ field: 'committeeMeeting',
|
|
|
|
|
+ unit: '次'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE主动性指标统计',
|
|
|
|
|
+ label: 'QHSE月度例会(次)',
|
|
|
|
|
+ field: 'monthlyMeeting',
|
|
|
|
|
+ unit: '次'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE主动性指标统计',
|
|
|
|
|
+ label: '公司级隐患排查(次)',
|
|
|
|
|
+ field: 'companyHazard',
|
|
|
|
|
+ unit: '次'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: 'QHSE主动性指标统计', label: 'QHSE检查(次)', field: 'qhseInspection', unit: '次' },
|
|
|
|
|
+ { category: 'QHSE主动性指标统计', label: '安全观察卡(张)', field: 'socCards', unit: '张' },
|
|
|
|
|
+ { category: 'QHSE主动性指标统计', label: '工作许可审核(份)', field: 'ptwAudit', unit: '份' },
|
|
|
|
|
+ { category: 'QHSE主动性指标统计', label: '工作安全分析(次)', field: 'jsa', unit: '次' },
|
|
|
|
|
+ { category: 'QHSE主动性指标统计', label: '演练次数', field: 'drills', unit: '次' },
|
|
|
|
|
+ { category: 'QHSE主动性指标统计', label: 'QHSE培训次数', field: 'training', unit: '次' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE主动性指标统计',
|
|
|
|
|
+ label: 'QHSE培训人次',
|
|
|
|
|
+ field: 'participantsTraining',
|
|
|
|
|
+ unit: '人次'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE主动性指标统计',
|
|
|
|
|
+ label: 'QHSE培训学时数(小时)',
|
|
|
|
|
+ field: 'trainingsHours',
|
|
|
|
|
+ unit: '小时'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: '环境数据', label: '水消耗(吨)', field: 'waterConsumption', unit: '吨' },
|
|
|
|
|
+ { category: '环境数据', label: '柴油消耗(升)', field: 'dieselConsumption', unit: '升' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: '环境数据',
|
|
|
|
|
+ label: '用电量(千瓦时)',
|
|
|
|
|
+ field: 'electricityConsumption',
|
|
|
|
|
+ unit: '千瓦时'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: '环境数据',
|
|
|
|
|
+ label: '天然气消耗量(立方米)',
|
|
|
|
|
+ field: 'naturalGasConsumption',
|
|
|
|
|
+ unit: '立方米'
|
|
|
|
|
+ }
|
|
|
|
|
+ // { category: '其他信息', label: '备注', field: 'remark', unit: '/' }
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
-const categoryRowSpanMap = computed(() => {
|
|
|
|
|
- return metricRows.reduce<Record<string, number>>((acc, item) => {
|
|
|
|
|
|
|
+const companyColumns = computed<ReportCompanyColumn[]>(() =>
|
|
|
|
|
+ reportList.value.map((item, index) => ({
|
|
|
|
|
+ key: getCompanyKey(index),
|
|
|
|
|
+ label: item.deptName || `公司${index + 1}`
|
|
|
|
|
+ }))
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const companyRowMap = computed<Record<string, QhseMonthReportItem>>(() =>
|
|
|
|
|
+ Object.fromEntries(reportList.value.map((item, index) => [getCompanyKey(index), item]))
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const categoryRowSpanMap = computed(() =>
|
|
|
|
|
+ metricRows.reduce<Record<string, number>>((acc, item) => {
|
|
|
acc[item.category] = (acc[item.category] || 0) + 1
|
|
acc[item.category] = (acc[item.category] || 0) + 1
|
|
|
return acc
|
|
return acc
|
|
|
}, {})
|
|
}, {})
|
|
|
-})
|
|
|
|
|
|
|
+)
|
|
|
|
|
|
|
|
-const firstRowIndexByCategory = computed(() => {
|
|
|
|
|
- return metricRows.reduce<Record<string, number>>((acc, item, index) => {
|
|
|
|
|
|
|
+const firstRowIndexByCategory = computed(() =>
|
|
|
|
|
+ metricRows.reduce<Record<string, number>>((acc, item, index) => {
|
|
|
if (acc[item.category] === undefined) acc[item.category] = index
|
|
if (acc[item.category] === undefined) acc[item.category] = index
|
|
|
return acc
|
|
return acc
|
|
|
}, {})
|
|
}, {})
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-const mockMetricValueMap = computed<Record<string, Record<string, ReportMetricValue>>>(() => ({
|
|
|
|
|
- employee: { rhxy: 32, scrd: 28, sxty: 25, eys: 18, rqny: 20, rljs: 14, bjhq: 12 },
|
|
|
|
|
- subcontractors: { rhxy: 15, scrd: 12, sxty: 9, eys: 7, rqny: 6, rljs: 5, bjhq: 0 },
|
|
|
|
|
- drivingMileage: {
|
|
|
|
|
- rhxy: 12680.5,
|
|
|
|
|
- scrd: 11024.2,
|
|
|
|
|
- sxty: 9480.8,
|
|
|
|
|
- eys: 6855.6,
|
|
|
|
|
- rqny: 7742.4,
|
|
|
|
|
- rljs: 4136.5,
|
|
|
|
|
- bjhq: 980.2
|
|
|
|
|
- },
|
|
|
|
|
- totalManHours: {
|
|
|
|
|
- rhxy: 3824,
|
|
|
|
|
- scrd: 3416,
|
|
|
|
|
- sxty: 2988,
|
|
|
|
|
- eys: 2210,
|
|
|
|
|
- rqny: 2456,
|
|
|
|
|
- rljs: 1768,
|
|
|
|
|
- bjhq: 960
|
|
|
|
|
- },
|
|
|
|
|
- withoutAccident: { rhxy: 186, scrd: 186, sxty: 186, eys: 132, rqny: 186, rljs: 186, bjhq: 186 },
|
|
|
|
|
- fatality: { rhxy: 0, scrd: 0, sxty: 0, eys: 0, rqny: 0, rljs: 0, bjhq: 0 },
|
|
|
|
|
- injury: { rhxy: 0, scrd: 1, sxty: 0, eys: 0, rqny: 0, rljs: 0, bjhq: 0 },
|
|
|
|
|
- restrictedCase: { rhxy: 1, scrd: 0, sxty: 0, eys: 0, rqny: 1, rljs: 0, bjhq: 0 },
|
|
|
|
|
- medicalCase: { rhxy: 1, scrd: 1, sxty: 0, eys: 0, rqny: 0, rljs: 0, bjhq: 0 },
|
|
|
|
|
- firstAidCase: { rhxy: 2, scrd: 1, sxty: 1, eys: 0, rqny: 1, rljs: 0, bjhq: 0 },
|
|
|
|
|
- vehicleAccident: { rhxy: 0, scrd: 0, sxty: 0, eys: 1, rqny: 0, rljs: 0, bjhq: 0 },
|
|
|
|
|
- nearMiss: { rhxy: 3, scrd: 2, sxty: 1, eys: 1, rqny: 2, rljs: 1, bjhq: 0 },
|
|
|
|
|
- spill: { rhxy: 0, scrd: 0, sxty: 0, eys: 0, rqny: 1, rljs: 0, bjhq: 0 },
|
|
|
|
|
- lifeSavingRules: { rhxy: 0, scrd: 1, sxty: 0, eys: 0, rqny: 0, rljs: 0, bjhq: 0 },
|
|
|
|
|
- toolboxTalk: { rhxy: 28, scrd: 24, sxty: 22, eys: 18, rqny: 20, rljs: 16, bjhq: 6 },
|
|
|
|
|
- committeeMeeting: { rhxy: 1, scrd: 1, sxty: 1, eys: 1, rqny: 1, rljs: 1, bjhq: 1 },
|
|
|
|
|
- monthlyMeeting: { rhxy: 1, scrd: 1, sxty: 1, eys: 1, rqny: 1, rljs: 1, bjhq: 1 },
|
|
|
|
|
- companyHazard: { rhxy: 6, scrd: 5, sxty: 4, eys: 3, rqny: 4, rljs: 2, bjhq: 1 },
|
|
|
|
|
- qhseInspection: { rhxy: 10, scrd: 9, sxty: 8, eys: 6, rqny: 7, rljs: 5, bjhq: 3 },
|
|
|
|
|
- socCards: { rhxy: 42, scrd: 38, sxty: 31, eys: 22, rqny: 27, rljs: 18, bjhq: 12 },
|
|
|
|
|
- ptwAudit: { rhxy: 18, scrd: 15, sxty: 13, eys: 8, rqny: 9, rljs: 6, bjhq: 2 },
|
|
|
|
|
- jsa: { rhxy: 21, scrd: 18, sxty: 16, eys: 10, rqny: 12, rljs: 8, bjhq: 3 },
|
|
|
|
|
- drills: { rhxy: 2, scrd: 2, sxty: 1, eys: 1, rqny: 1, rljs: 1, bjhq: 1 },
|
|
|
|
|
- training: { rhxy: 5, scrd: 4, sxty: 4, eys: 3, rqny: 3, rljs: 2, bjhq: 2 },
|
|
|
|
|
- participantsTraining: { rhxy: 96, scrd: 82, sxty: 74, eys: 48, rqny: 56, rljs: 35, bjhq: 24 },
|
|
|
|
|
- trainingsHours: { rhxy: 64, scrd: 56, sxty: 48, eys: 32, rqny: 36, rljs: 24, bjhq: 16 },
|
|
|
|
|
- waterConsumption: {
|
|
|
|
|
- rhxy: 82.5,
|
|
|
|
|
- scrd: 74.2,
|
|
|
|
|
- sxty: 65.8,
|
|
|
|
|
- eys: 48.6,
|
|
|
|
|
- rqny: 53.4,
|
|
|
|
|
- rljs: 31.8,
|
|
|
|
|
- bjhq: 12.2
|
|
|
|
|
- },
|
|
|
|
|
- dieselConsumption: {
|
|
|
|
|
- rhxy: 2680,
|
|
|
|
|
- scrd: 2410,
|
|
|
|
|
- sxty: 2085,
|
|
|
|
|
- eys: 1530,
|
|
|
|
|
- rqny: 1695,
|
|
|
|
|
- rljs: 980,
|
|
|
|
|
- bjhq: 220
|
|
|
|
|
- },
|
|
|
|
|
- electricityConsumption: {
|
|
|
|
|
- rhxy: 4250,
|
|
|
|
|
- scrd: 3980,
|
|
|
|
|
- sxty: 3650,
|
|
|
|
|
- eys: 2420,
|
|
|
|
|
- rqny: 2860,
|
|
|
|
|
- rljs: 1680,
|
|
|
|
|
- bjhq: 920
|
|
|
|
|
- },
|
|
|
|
|
- naturalGasConsumption: {
|
|
|
|
|
- rhxy: 1260,
|
|
|
|
|
- scrd: 1140,
|
|
|
|
|
- sxty: 980,
|
|
|
|
|
- eys: 660,
|
|
|
|
|
- rqny: 720,
|
|
|
|
|
- rljs: 450,
|
|
|
|
|
- bjhq: 180
|
|
|
|
|
- },
|
|
|
|
|
- remark: {
|
|
|
|
|
- rhxy: '现场管理平稳',
|
|
|
|
|
- scrd: '专项培训已完成',
|
|
|
|
|
- sxty: '持续推进隐患整改',
|
|
|
|
|
- eys: '强化车辆安全检查',
|
|
|
|
|
- rqny: '开展环保专项复盘',
|
|
|
|
|
- rljs: '重点盯控作业许可',
|
|
|
|
|
- bjhq: '推进体系宣贯'
|
|
|
|
|
- }
|
|
|
|
|
-}))
|
|
|
|
|
|
|
+)
|
|
|
|
|
|
|
|
-const tableRows = computed<TableRow[]>(() => {
|
|
|
|
|
- return metricRows.map((row) => {
|
|
|
|
|
|
|
+const tableRows = computed<TableRow[]>(() =>
|
|
|
|
|
+ metricRows.map((row) => {
|
|
|
const companyValues = Object.fromEntries(
|
|
const companyValues = Object.fromEntries(
|
|
|
- companyColumns.map((company) => [company.key, getMetricCompanyValue(row.field, company.key)])
|
|
|
|
|
|
|
+ companyColumns.value.map((company) => [
|
|
|
|
|
+ company.key,
|
|
|
|
|
+ getMetricCompanyValue(row.field, company.key)
|
|
|
|
|
+ ])
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
@@ -195,13 +154,17 @@ const tableRows = computed<TableRow[]>(() => {
|
|
|
...companyValues
|
|
...companyValues
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
-})
|
|
|
|
|
|
|
+)
|
|
|
|
|
|
|
|
-async function loadDetail(id: number) {
|
|
|
|
|
|
|
+async function loadDetail() {
|
|
|
loading.value = true
|
|
loading.value = true
|
|
|
try {
|
|
try {
|
|
|
- const res = await QhseMonthReportApi.getQhseMonthReport(id)
|
|
|
|
|
- report.value = ((res as any)?.data ?? res ?? {}) as QhseMonthReportItem
|
|
|
|
|
|
|
+ const res = await QhseMonthReportSummaryApi.getQhseMonthReportSummary({
|
|
|
|
|
+ yearMonths: props.yearMonths
|
|
|
|
|
+ })
|
|
|
|
|
+ reportList.value = ((res as any)?.data?.list ??
|
|
|
|
|
+ (res as any)?.list ??
|
|
|
|
|
+ []) as QhseMonthReportItem[]
|
|
|
} finally {
|
|
} finally {
|
|
|
loading.value = false
|
|
loading.value = false
|
|
|
}
|
|
}
|
|
@@ -209,38 +172,44 @@ async function loadDetail(id: number) {
|
|
|
|
|
|
|
|
function handleVisibleChange(visible: boolean) {
|
|
function handleVisibleChange(visible: boolean) {
|
|
|
emits('update:visible', visible)
|
|
emits('update:visible', visible)
|
|
|
- if (!visible) report.value = undefined
|
|
|
|
|
|
|
+ if (!visible) reportList.value = []
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function formatDisplayValue(field: keyof QhseMonthReportItem) {
|
|
|
|
|
- const value = report.value?.[field]
|
|
|
|
|
|
|
+function getCompanyKey(index: number) {
|
|
|
|
|
+ return `company_${index}`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function formatMetricValue(value: QhseMonthReportItem[keyof QhseMonthReportItem]) {
|
|
|
if (value === undefined || value === null || value === '') return '-'
|
|
if (value === undefined || value === null || value === '') return '-'
|
|
|
- if (field === 'createTime') {
|
|
|
|
|
- const date = dayjs(value)
|
|
|
|
|
- return date.isValid() ? date.format('YYYY-MM-DD') : String(value)
|
|
|
|
|
|
|
+ const numericValue = Number(value)
|
|
|
|
|
+ if (!Number.isNaN(numericValue) && String(value).trim() !== '') {
|
|
|
|
|
+ return Number.isInteger(numericValue) ? String(numericValue) : numericValue.toFixed(2)
|
|
|
}
|
|
}
|
|
|
return String(value)
|
|
return String(value)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function getMetricCompanyValue(field: keyof QhseMonthReportItem, companyKey: string) {
|
|
function getMetricCompanyValue(field: keyof QhseMonthReportItem, companyKey: string) {
|
|
|
- const rowData = mockMetricValueMap.value[String(field)] || {}
|
|
|
|
|
- const value = rowData[companyKey]
|
|
|
|
|
- if (value === undefined || value === null || value === '') return '-'
|
|
|
|
|
- if (typeof value === 'number' && !Number.isInteger(value)) return value.toFixed(2)
|
|
|
|
|
- return String(value)
|
|
|
|
|
|
|
+ const rowData = companyRowMap.value[companyKey]
|
|
|
|
|
+ return formatMetricValue(rowData?.[field])
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function getMetricSummaryValue(field: keyof QhseMonthReportItem) {
|
|
function getMetricSummaryValue(field: keyof QhseMonthReportItem) {
|
|
|
- const rowData = mockMetricValueMap.value[String(field)] || {}
|
|
|
|
|
- const values = companyColumns
|
|
|
|
|
- .map((company) => rowData[company.key])
|
|
|
|
|
|
|
+ const values = reportList.value
|
|
|
|
|
+ .map((item) => item[field])
|
|
|
.filter((value) => value !== undefined && value !== null && value !== '')
|
|
.filter((value) => value !== undefined && value !== null && value !== '')
|
|
|
|
|
|
|
|
if (!values.length) return '-'
|
|
if (!values.length) return '-'
|
|
|
- if (values.every((value) => typeof value === 'number')) {
|
|
|
|
|
- const total = values.reduce((sum, value) => sum + Number(value), 0)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (field === 'remark') {
|
|
|
|
|
+ return values.map((value) => String(value)).join(';')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const numericValues = values.map((value) => Number(value))
|
|
|
|
|
+ if (numericValues.every((value) => !Number.isNaN(value))) {
|
|
|
|
|
+ const total = numericValues.reduce((sum, value) => sum + value, 0)
|
|
|
return Number.isInteger(total) ? String(total) : total.toFixed(2)
|
|
return Number.isInteger(total) ? String(total) : total.toFixed(2)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
return values.map((value) => String(value)).join(';')
|
|
return values.map((value) => String(value)).join(';')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -259,11 +228,24 @@ function tableSpanMethod({
|
|
|
return { rowspan: categoryRowSpanMap.value[row.category], colspan: 1 }
|
|
return { rowspan: categoryRowSpanMap.value[row.category], colspan: 1 }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const previewMeta = computed(() => {
|
|
|
|
|
+ const firstItem = reportList.value[0]
|
|
|
|
|
+ if (!firstItem) return { personName: '-', createTime: '-' }
|
|
|
|
|
+
|
|
|
|
|
+ const date = dayjs(firstItem.createTime)
|
|
|
|
|
+ return {
|
|
|
|
|
+ personName: firstItem.personName || '-',
|
|
|
|
|
+ createTime: date.isValid() ? date.format('YYYY-MM-DD') : '-'
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
watch(
|
|
watch(
|
|
|
- () => [props.visible, props.id] as const,
|
|
|
|
|
- ([visible, id]) => {
|
|
|
|
|
- if (!visible || !id) return
|
|
|
|
|
- loadDetail(id)
|
|
|
|
|
|
|
+ () => [props.visible, props.yearMonths] as const,
|
|
|
|
|
+ async ([visible, yearMonths], previous = [false, undefined] as const) => {
|
|
|
|
|
+ const [previousVisible, previousYearMonths] = previous
|
|
|
|
|
+ if (!visible || !yearMonths) return
|
|
|
|
|
+ if (visible === previousVisible && yearMonths === previousYearMonths) return
|
|
|
|
|
+ await loadDetail()
|
|
|
},
|
|
},
|
|
|
{ immediate: true }
|
|
{ immediate: true }
|
|
|
)
|
|
)
|
|
@@ -281,9 +263,9 @@ watch(
|
|
|
<div class="qhse-report-preview__sheet">
|
|
<div class="qhse-report-preview__sheet">
|
|
|
<div class="qhse-report-preview__sheet-title">QHSE 月度报告</div>
|
|
<div class="qhse-report-preview__sheet-title">QHSE 月度报告</div>
|
|
|
<div class="qhse-report-preview__meta">
|
|
<div class="qhse-report-preview__meta">
|
|
|
- <span>年月:{{ formatDisplayValue('yearMonths') }}</span>
|
|
|
|
|
- <span>填报人:{{ formatDisplayValue('personName') }}</span>
|
|
|
|
|
- <span>创建日期:{{ formatDisplayValue('createTime') }}</span>
|
|
|
|
|
|
|
+ <span>年月:{{ props.yearMonths || '-' }}</span>
|
|
|
|
|
+ <!-- <span>填报人:{{ previewMeta.personName }}</span>
|
|
|
|
|
+ <span>创建日期:{{ previewMeta.createTime }}</span> -->
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="qhse-report-preview__table-wrap">
|
|
<div class="qhse-report-preview__table-wrap">
|
|
@@ -298,9 +280,9 @@ watch(
|
|
|
prop="category"
|
|
prop="category"
|
|
|
label="基本信息"
|
|
label="基本信息"
|
|
|
fixed="left"
|
|
fixed="left"
|
|
|
- width="140"
|
|
|
|
|
|
|
+ width="170"
|
|
|
align="center" />
|
|
align="center" />
|
|
|
- <el-table-column prop="label" label="单位" fixed="left" width="220" align="center" />
|
|
|
|
|
|
|
+ <el-table-column prop="label" label="单位" fixed="left" width="240" align="center" />
|
|
|
<el-table-column
|
|
<el-table-column
|
|
|
v-for="company in companyColumns"
|
|
v-for="company in companyColumns"
|
|
|
:key="company.key"
|
|
:key="company.key"
|