|
@@ -3,8 +3,7 @@ import { QhseMonthReportSummaryApi } from '@/api/pms/qhse'
|
|
|
import type {
|
|
import type {
|
|
|
QhseMonthReportItem,
|
|
QhseMonthReportItem,
|
|
|
ReportCompanyColumn,
|
|
ReportCompanyColumn,
|
|
|
- ReportMetricRow,
|
|
|
|
|
- ReportMetricValue
|
|
|
|
|
|
|
+ ReportMetricRow
|
|
|
} from './types'
|
|
} from './types'
|
|
|
import dayjs from 'dayjs'
|
|
import dayjs from 'dayjs'
|
|
|
import { computed, ref, watch } from 'vue'
|
|
import { computed, ref, watch } from 'vue'
|
|
@@ -26,165 +25,181 @@ 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: '安全行驶里程数(公里)',
|
|
|
|
|
|
|
+ category: '\u4eba\u5de5\u65f6\u548c\u5b89\u5168\u884c\u9a76\u516c\u91cc\u6570',
|
|
|
|
|
+ label: '\u5458\u5de5\u4eba\u6570',
|
|
|
|
|
+ field: 'employee',
|
|
|
|
|
+ unit: '\u4eba'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: '\u4eba\u5de5\u65f6\u548c\u5b89\u5168\u884c\u9a76\u516c\u91cc\u6570',
|
|
|
|
|
+ label: '\u5206\u5305\u5546\u4eba\u6570',
|
|
|
|
|
+ field: 'subcontractors',
|
|
|
|
|
+ unit: '\u4eba'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: '\u4eba\u5de5\u65f6\u548c\u5b89\u5168\u884c\u9a76\u516c\u91cc\u6570',
|
|
|
|
|
+ label: '\u5b89\u5168\u884c\u9a76\u91cc\u7a0b\u6570\uff08\u516c\u91cc\uff09',
|
|
|
field: 'drivingMileage',
|
|
field: 'drivingMileage',
|
|
|
- unit: '公里'
|
|
|
|
|
|
|
+ unit: '\u516c\u91cc'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: '\u4eba\u5de5\u65f6\u548c\u5b89\u5168\u884c\u9a76\u516c\u91cc\u6570',
|
|
|
|
|
+ label: '\u603b\u4eba\u5de5\u65f6\u6570\uff08\u5c0f\u65f6\uff09',
|
|
|
|
|
+ field: 'totalManHours',
|
|
|
|
|
+ unit: '\u5c0f\u65f6'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u65e0\u4e8b\u6545\u7d2f\u8ba1\u5929\u6570',
|
|
|
|
|
+ field: 'withoutAccident',
|
|
|
|
|
+ unit: '\u5929'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1', label: '\u6b7b\u4ea1\u4e8b\u6545\uff08\u8d77\uff09', field: 'fatality', unit: '\u8d77' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u635f\u5931\u5de5\u65f6\u4e8b\u6545\uff08\u8d77\uff09',
|
|
|
|
|
+ field: 'injury',
|
|
|
|
|
+ unit: '\u8d77'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u5de5\u4f5c\u53d7\u9650\u4e8b\u4ef6\uff08\u8d77\uff09',
|
|
|
|
|
+ field: 'restrictedCase',
|
|
|
|
|
+ unit: '\u8d77'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u533b\u7597\u5904\u7406\u4e8b\u4ef6\uff08\u8d77\uff09',
|
|
|
|
|
+ field: 'medicalCase',
|
|
|
|
|
+ unit: '\u8d77'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u6025\u6551\u7bb1\u4e8b\u4ef6\uff08\u8d77\uff09',
|
|
|
|
|
+ field: 'firstAidCase',
|
|
|
|
|
+ unit: '\u8d77'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u4ea4\u901a\u4e8b\u6545\uff08\u8d77\uff09',
|
|
|
|
|
+ field: 'vehicleAccident',
|
|
|
|
|
+ unit: '\u8d77'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u672a\u9042\u4e8b\u4ef6\uff08\u8d77\uff09',
|
|
|
|
|
+ field: 'nearMiss',
|
|
|
|
|
+ unit: '\u8d77'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u6cc4\u6f0f\u4e8b\u4ef6\uff08\u8d77\uff09',
|
|
|
|
|
+ field: 'spill',
|
|
|
|
|
+ unit: '\u8d77'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u88ab\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u8fdd\u53cd\u4fdd\u547d\u89c4\u5219\u7684\u6b21\u6570\uff08\u6b21\uff09',
|
|
|
|
|
+ field: 'lifeSavingRules',
|
|
|
|
|
+ unit: '\u6b21'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1', label: '\u73ed\u524d\u4f1a\uff08\u6b21\uff09', field: 'toolboxTalk', unit: '\u6b21' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: 'QHSE\u7ba1\u7406\u59d4\u5458\u4f1a\u4f1a\u8bae\uff08\u6b21\uff09',
|
|
|
|
|
+ field: 'committeeMeeting',
|
|
|
|
|
+ unit: '\u6b21'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: 'QHSE\u6708\u5ea6\u4f8b\u4f1a\uff08\u6b21\uff09',
|
|
|
|
|
+ field: 'monthlyMeeting',
|
|
|
|
|
+ unit: '\u6b21'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u516c\u53f8\u7ea7\u9690\u60a3\u6392\u67e5\uff08\u6b21\uff09',
|
|
|
|
|
+ field: 'companyHazard',
|
|
|
|
|
+ unit: '\u6b21'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1', label: 'QHSE\u68c0\u67e5\uff08\u6b21\uff09', field: 'qhseInspection', unit: '\u6b21' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u5b89\u5168\u89c2\u5bdf\u5361\uff08\u5f20\uff09',
|
|
|
|
|
+ field: 'socCards',
|
|
|
|
|
+ unit: '\u5f20'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u5de5\u4f5c\u8bb8\u53ef\u5ba1\u6838\uff08\u4efd\uff09',
|
|
|
|
|
+ field: 'ptwAudit',
|
|
|
|
|
+ unit: '\u4efd'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: '\u5de5\u4f5c\u5b89\u5168\u5206\u6790\uff08\u6b21\uff09',
|
|
|
|
|
+ field: 'jsa',
|
|
|
|
|
+ unit: '\u6b21'
|
|
|
},
|
|
},
|
|
|
- { 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: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1', label: '\u6f14\u7ec3\u6b21\u6570', field: 'drills', unit: '\u6b21' },
|
|
|
|
|
+ { category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1', label: 'QHSE\u57f9\u8bad\u6b21\u6570', field: 'training', unit: '\u6b21' },
|
|
|
|
|
+ { category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1', label: 'QHSE\u57f9\u8bad\u4eba\u6b21', field: 'participantsTraining', unit: '\u4eba\u6b21' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: 'QHSE\u4e3b\u52a8\u6027\u6307\u6807\u7edf\u8ba1',
|
|
|
|
|
+ label: 'QHSE\u57f9\u8bad\u5b66\u65f6\u6570\uff08\u5c0f\u65f6\uff09',
|
|
|
|
|
+ field: 'trainingsHours',
|
|
|
|
|
+ unit: '\u5c0f\u65f6'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: '\u73af\u5883\u6570\u636e', label: '\u6c34\u6d88\u8017\uff08\u5428\uff09', field: 'waterConsumption', unit: '\u5428' },
|
|
|
|
|
+ { category: '\u73af\u5883\u6570\u636e', label: '\u67f4\u6cb9\u6d88\u8017\uff08\u5347\uff09', field: 'dieselConsumption', unit: '\u5347' },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: '\u73af\u5883\u6570\u636e',
|
|
|
|
|
+ label: '\u7528\u7535\u91cf\uff08\u5343\u74e6\u65f6\uff09',
|
|
|
|
|
+ field: 'electricityConsumption',
|
|
|
|
|
+ unit: '\u5343\u74e6\u65f6'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ category: '\u73af\u5883\u6570\u636e',
|
|
|
|
|
+ label: '\u5929\u7136\u6c14\u6d88\u8017\u91cf\uff08\u7acb\u65b9\u7c73\uff09',
|
|
|
|
|
+ field: 'naturalGasConsumption',
|
|
|
|
|
+ unit: '\u7acb\u65b9\u7c73'
|
|
|
|
|
+ },
|
|
|
|
|
+ { category: '\u5176\u4ed6\u4fe1\u606f', label: '\u5907\u6ce8', 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 || `Company ${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,7 +210,7 @@ const tableRows = computed<TableRow[]>(() => {
|
|
|
...companyValues
|
|
...companyValues
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
-})
|
|
|
|
|
|
|
+)
|
|
|
|
|
|
|
|
async function loadDetail() {
|
|
async function loadDetail() {
|
|
|
loading.value = true
|
|
loading.value = true
|
|
@@ -203,8 +218,7 @@ async function loadDetail() {
|
|
|
const res = await QhseMonthReportSummaryApi.getQhseMonthReportSummary({
|
|
const res = await QhseMonthReportSummaryApi.getQhseMonthReportSummary({
|
|
|
yearMonths: props.yearMonths
|
|
yearMonths: props.yearMonths
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
- report.value = ((res as any)?.data ?? res ?? {}) as QhseMonthReportItem
|
|
|
|
|
|
|
+ reportList.value = ((res as any)?.data?.list ?? (res as any)?.list ?? []) as QhseMonthReportItem[]
|
|
|
} finally {
|
|
} finally {
|
|
|
loading.value = false
|
|
loading.value = false
|
|
|
}
|
|
}
|
|
@@ -212,39 +226,45 @@ async function loadDetail() {
|
|
|
|
|
|
|
|
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 getCompanyKey(index: number) {
|
|
|
|
|
+ return `company_${index}`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function formatDisplayValue(field: keyof QhseMonthReportItem) {
|
|
|
|
|
- const value = report.value?.[field]
|
|
|
|
|
|
|
+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('; ')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function tableSpanMethod({
|
|
function tableSpanMethod({
|
|
@@ -262,9 +282,21 @@ 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.yearMonths] as const,
|
|
() => [props.visible, props.yearMonths] as const,
|
|
|
- async ([visible, yearMonths], [previousVisible, previousYearMonths]) => {
|
|
|
|
|
|
|
+ async ([visible, yearMonths], previous = [false, undefined] as const) => {
|
|
|
|
|
+ const [previousVisible, previousYearMonths] = previous
|
|
|
if (!visible || !yearMonths) return
|
|
if (!visible || !yearMonths) return
|
|
|
if (visible === previousVisible && yearMonths === previousYearMonths) return
|
|
if (visible === previousVisible && yearMonths === previousYearMonths) return
|
|
|
await loadDetail()
|
|
await loadDetail()
|
|
@@ -285,9 +317,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>年月:{{ props.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">
|
|
@@ -300,11 +332,11 @@ watch(
|
|
|
class="qhse-report-preview__el-table">
|
|
class="qhse-report-preview__el-table">
|
|
|
<el-table-column
|
|
<el-table-column
|
|
|
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"
|