yanghao 3 روز پیش
والد
کامیت
c80c4a2be6
2فایلهای تغییر یافته به همراه113 افزوده شده و 9 حذف شده
  1. 106 9
      src/views/pms/qhse/reportSummary/preview-drawer.vue
  2. 7 0
      src/views/pms/qhse/reportSummary/types.ts

+ 106 - 9
src/views/pms/qhse/reportSummary/preview-drawer.vue

@@ -1,6 +1,11 @@
 <script lang="ts" setup>
 import { QhseMonthReportApi } from '@/api/pms/qhse'
-import type { QhseMonthReportItem, ReportMetricRow } from './types'
+import type {
+  QhseMonthReportItem,
+  ReportCompanyColumn,
+  ReportMetricRow,
+  ReportMetricValue
+} from './types'
 import dayjs from 'dayjs'
 
 interface Props {
@@ -14,6 +19,16 @@ const emits = defineEmits(['update:visible'])
 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 metricRows: ReportMetricRow[] = [
   { category: '人工时与里程', label: '员工人数', field: 'employee', unit: '人' },
   { category: '人工时与里程', label: '分包商人数', field: 'subcontractors', unit: '人' },
@@ -69,6 +84,56 @@ const firstRowIndexByCategory = computed(() => {
   }, {})
 })
 
+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: '推进体系宣贯'
+  }
+}))
+
 async function loadDetail(id: number) {
   loading.value = true
   try {
@@ -96,6 +161,31 @@ function formatDisplayValue(field: keyof QhseMonthReportItem) {
   return String(value)
 }
 
+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)
+}
+
+function getMetricSummaryValue(field: keyof QhseMonthReportItem) {
+  const rowData = mockMetricValueMap.value[String(field)] || {}
+  const values = companyColumns
+    .map((company) => rowData[company.key])
+    .filter((value) => value !== undefined && value !== null && value !== '')
+
+  if (!values.length) return '-'
+
+  if (values.every((value) => typeof value === 'number')) {
+    const total = values.reduce((sum, value) => sum + Number(value), 0)
+    return Number.isInteger(total) ? String(total) : total.toFixed(2)
+  }
+
+  return values.map((value) => String(value)).join(';')
+}
+
 watch(
   () => [props.visible, props.id] as const,
   ([visible, id]) => {
@@ -136,14 +226,9 @@ watch(
             <thead>
               <tr>
                 <th class="is-sticky-col">基本信息</th>
+                <th>指标项</th>
                 <th>单位</th>
-                <th>瑞恒兴域</th>
-                <th>四川瑞都</th>
-                <th>陕西瑞鹰</th>
-                <th>俄油服</th>
-                <th>瑞气能源</th>
-                <th>瑞霖技术</th>
-                <th>北京总部</th>
+                <th v-for="company in companyColumns" :key="company.key">{{ company.label }}</th>
                 <th>汇总</th>
               </tr>
             </thead>
@@ -157,7 +242,13 @@ watch(
                 </th>
                 <th class="is-label">{{ row.label }}</th>
                 <td>{{ row.unit }}</td>
-                <td class="is-value">{{ formatDisplayValue(row.field) }}</td>
+                <td
+                  v-for="company in companyColumns"
+                  :key="`${row.field}-${company.key}`"
+                  class="is-value">
+                  {{ getMetricCompanyValue(row.field, company.key) }}
+                </td>
+                <td class="is-summary">{{ getMetricSummaryValue(row.field) }}</td>
               </tr>
             </tbody>
           </table>
@@ -282,6 +373,12 @@ watch(
   color: #0f3f8f;
 }
 
+.is-summary {
+  background: #eef4ff !important;
+  font-weight: 700;
+  color: #14346b;
+}
+
 @media (width < 768px) {
   .qhse-report-preview {
     padding: 12px;

+ 7 - 0
src/views/pms/qhse/reportSummary/types.ts

@@ -42,6 +42,13 @@ export interface QhseMonthReportItem {
 
 export type QhseMonthReportListItem = QhseMonthReportItem
 
+export interface ReportCompanyColumn {
+  key: string
+  label: string
+}
+
+export type ReportMetricValue = string | number
+
 export interface ReportMetricRow {
   category: string
   label: string