Преглед изворни кода

feat(blockingData): 优化数据展示模块样式和图表功能

调整各模块的容器尺寸和内边距,统一图表样式
重构图表数据展示逻辑,支持多维度数据展示
更新图表配置项,增强数据可视化和交互体验
huoyi пре 1 месец
родитељ
комит
719c1ef45d

+ 106 - 34
src/views/blockingData/blockingDataScreen/components/ModuleBrigadeOne.vue

@@ -117,52 +117,69 @@ const fetchData = async () => {
117 117
     ])
118 118
 
119 119
     if (trendRes.value?.data) {
120
-      const trendData = trendRes.value.data.map(item => ({
121
-        name: item.date || item.name || '',
122
-        value: item.count || item.value || 0
123
-      }))
124
-      setOption1(lineChartOption(trendData.map(d => d.value), '#3b82f6'))
120
+      const dates = trendRes.value.data.map(item => item.statDate?.split('T')[0] || item.date || item.name || '')
121
+      const t1TravelData = trendRes.value.data.map(item => item.t1TravelBlockedCount || 0)
122
+      const t2TravelData = trendRes.value.data.map(item => item.t2TravelBlockedCount || 0)
123
+      const t1WalkData = trendRes.value.data.map(item => item.t1WalkBlockedCount || 0)
124
+      const t2WalkData = trendRes.value.data.map(item => item.t2WalkBlockedCount || 0)
125
+      setOption1(multiLineChartOption(dates, [
126
+        { name: 'T1旅检查堵件数', data: t1TravelData, color: '#3b82f6' },
127
+        { name: 'T2旅检查堵件数', data: t2TravelData, color: '#22c55e' },
128
+        { name: 'T1行检查堵件数', data: t1WalkData, color: '#f97316' },
129
+        { name: 'T2行检查堵件数', data: t2WalkData, color: '#ec4899' }
130
+      ]))
125 131
     }
126 132
 
127 133
     if (luggageRes.value?.data) {
128
-      const luggageData = luggageRes.value.data.map(item => ({
129
-        name: item.date || item.name || '',
130
-        value: item.count || item.value || 0
131
-      }))
132
-      setOption2(areaChartOption(luggageData.map(d => d.value), '#22c55e'))
134
+      const dates = luggageRes.value.data.map(item => item.statDate?.split('T')[0] || item.date || item.name || '')
135
+      const t1TravelData = luggageRes.value.data.map(item => item.t1TravelBagCount || 0)
136
+      const t2TravelData = luggageRes.value.data.map(item => item.t2TravelBagCount || 0)
137
+      const t1WalkData = luggageRes.value.data.map(item => item.t1WalkBagCount || 0)
138
+      const t2WalkData = luggageRes.value.data.map(item => item.t2WalkBagCount || 0)
139
+      setOption2(multiLineChartOption(dates, [
140
+        { name: 'T1旅检过检行李数', data: t1TravelData, color: '#3b82f6' },
141
+        { name: 'T2旅检过检行李数', data: t2TravelData, color: '#22c55e' },
142
+        { name: 'T1行检过检行李数', data: t1WalkData, color: '#f97316' },
143
+        { name: 'T2行检过检行李数', data: t2WalkData, color: '#ec4899' }
144
+      ]))
133 145
     }
134 146
 
135 147
     if (blockedRes.value?.data) {
136
-      const blockedData = blockedRes.value.data.map(item => ({
137
-        name: item.terminal || item.name || '',
138
-        value: item.count || item.value || 0
139
-      }))
148
+      const blockedData = [
149
+        { name: 'T1', value: blockedRes.value.data.t1BlockedCount || 0 },
150
+        { name: 'T2', value: blockedRes.value.data.t2BlockedCount || 0 }
151
+      ]
140 152
       setOption3(horizontalBarChartOption(blockedData, '#3b82f6'))
141
-      const total = blockedRes.value.data.reduce((sum, item) => sum + (item.count || item.value || 0), 0)
153
+      const total = blockedRes.value.data.totalBlockedCount || 0
142 154
       statValue.value = total
143 155
     }
144 156
 
145 157
     if (timeRes.value?.data) {
146
-      const timeData = timeRes.value.data.map(item => ({
147
-        name: item.timePeriod || item.name || '',
148
-        value: item.count || item.value || 0
149
-      }))
150
-      setOption4(barChartOption(timeData, '#3b82f6'))
158
+      const timePeriods = timeRes.value.data.map(item => item.timePeriod || '')
159
+      const avgLuggageData = timeRes.value.data.map(item => item.avgLuggageCount || 0)
160
+      const avgBlockedData = timeRes.value.data.map(item => item.avgBlockedCount || 0)
161
+      setOption4(barLineChartOption(timePeriods, avgLuggageData, avgBlockedData))
151 162
     }
152 163
 
153 164
     if (rateRes.value?.data) {
154
-      const rateData = rateRes.value.data.map(item => ({
155
-        name: item.date || item.name || '',
156
-        value: item.rate || item.value || 0
157
-      }))
158
-      setOption5(lineChartOption(rateData.map(d => d.value), '#ec4899'))
165
+      const dates = rateRes.value.data.map(item => item.statDate?.split('T')[0] || item.date || item.name || '')
166
+      const t1TravelRate = rateRes.value.data.map(item => item.t1TravelBlockRate || 0)
167
+      const t2TravelRate = rateRes.value.data.map(item => item.t2TravelBlockRate || 0)
168
+      const t1WalkRate = rateRes.value.data.map(item => item.t1WalkBlockRate || 0)
169
+      const t2WalkRate = rateRes.value.data.map(item => item.t2WalkBlockRate || 0)
170
+      setOption5(multiLineChartOption(dates, [
171
+        { name: 'T1旅检万分率', data: t1TravelRate, color: '#3b82f6' },
172
+        { name: 'T2旅检万分率', data: t2TravelRate, color: '#22c55e' },
173
+        { name: 'T1行检万分率', data: t1WalkRate, color: '#f97316' },
174
+        { name: 'T2行检万分率', data: t2WalkRate, color: '#ec4899' }
175
+      ]))
159 176
     }
160 177
 
161 178
     if (itemRes.value?.data) {
162
-      const colors = ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6']
179
+      const colors = ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6', '#10b981', '#f59e0b', '#ef4444']
163 180
       const itemData = itemRes.value.data.map((item, index) => ({
164
-        name: item.itemName || item.name || '',
165
-        value: item.percentage || item.value || 0
181
+        name: item.missCheckItem ,
182
+        value: item.count 
166 183
       }))
167 184
       setOption6(pieChartOption(itemData, colors))
168 185
     }
@@ -187,6 +204,27 @@ const generateData = (count, min, max) => {
187 204
   return data
188 205
 }
189 206
 
207
+const multiLineChartOption = (xAxisData, series) => ({
208
+  grid: { left: '10%', top: '15%', right: '5%', bottom: '15%', containLabel: true },
209
+  xAxis: { type: 'category', data: xAxisData, axisLine: { lineStyle: { color: '#999' } }, axisLabel: { fontSize: 10, color: '#666' } },
210
+  yAxis: { type: 'value', axisLine: { lineStyle: { color: '#999' } }, axisLabel: { fontSize: 10, color: '#666' }, splitLine: { lineStyle: { color: '#eee' } } },
211
+  legend: { 
212
+    data: series.map(s => s.name),
213
+    top: '0%',
214
+    textStyle: { fontSize: 10 }
215
+  },
216
+  series: series.map(s => ({
217
+    name: s.name,
218
+    type: 'line',
219
+    smooth: true,
220
+    symbol: 'circle',
221
+    symbolSize: 6,
222
+    data: s.data,
223
+    itemStyle: { color: s.color },
224
+    lineStyle: { color: s.color }
225
+  }))
226
+})
227
+
190 228
 const lineChartOption = (data, color, title) => ({
191 229
   grid: { left: '10%', top: '15%', right: '5%', bottom: '15%', containLabel: true },
192 230
   xAxis: { type: 'category', data: xAxisData, axisLine: { lineStyle: { color: '#999' } }, axisLabel: { fontSize: 10, color: '#666' } },
@@ -215,14 +253,49 @@ const horizontalBarChartOption = (data, color) => ({
215 253
   series: [{ type: 'bar', data: data.map(d => d.value), itemStyle: { color: color }, barWidth: 15 }]
216 254
 })
217 255
 
256
+const barLineChartOption = (xAxisData, barData, lineData) => ({
257
+  grid: { left: '10%', top: '15%', right: '5%', bottom: '15%', containLabel: true },
258
+  xAxis: { type: 'category', data: xAxisData, axisLine: { lineStyle: { color: '#999' } }, axisLabel: { fontSize: 10, color: '#666' } },
259
+  yAxis: { type: 'value', axisLine: { lineStyle: { color: '#999' } }, axisLabel: { fontSize: 10, color: '#666' }, splitLine: { lineStyle: { color: '#eee' } } },
260
+  legend: { 
261
+    data: ['平均过检行李数', '平均查堵件数'],
262
+    top: '0%',
263
+    textStyle: { fontSize: 10 }
264
+  },
265
+  series: [
266
+    {
267
+      name: '平均过检行李数',
268
+      type: 'bar',
269
+      data: barData,
270
+      itemStyle: { color: '#3b82f6' },
271
+      barWidth: 20
272
+    },
273
+    {
274
+      name: '平均查堵件数',
275
+      type: 'line',
276
+      smooth: true,
277
+      symbol: 'circle',
278
+      symbolSize: 6,
279
+      data: lineData,
280
+      itemStyle: { color: '#ec4899' },
281
+      lineStyle: { color: '#ec4899' }
282
+    }
283
+  ]
284
+})
285
+
218 286
 const pieChartOption = (data, colors) => ({
219 287
   color: colors,
288
+  legend: { 
289
+    show: true,
290
+    textStyle: { fontSize: 10 }
291
+  },
292
+  tooltip: { trigger: 'item' },
220 293
   series: [{
221 294
     type: 'pie',
222 295
     radius: '65%',
223 296
     center: ['50%', '55%'],
224 297
     data: data,
225
-    label: { show: true, formatter: '{b}\n{c}%', fontSize: 10 }
298
+    label: { show: true, formatter: '{b}', fontSize: 10 }
226 299
   }]
227 300
 })
228 301
 
@@ -313,20 +386,19 @@ onMounted(() => {
313 386
   flex: 1;
314 387
   background: #fff;
315 388
   border-radius: 6px;
316
-  padding: 10px;
389
+  padding: 15px;
317 390
   border: 1px solid #eee;
318 391
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
319 392
   display: flex;
320 393
   flex-direction: column;
321
-  min-height: 200px;
394
+  min-height: 280px;
322 395
 }
323 396
 
324 397
 .chart-title {
325
-  font-size: 14px;
326
-  color: #333;
398
+ font-size: 17px;
399
+  color: black;
327 400
   margin-bottom: 5px;
328 401
   text-align: left;
329
-  font-weight: 500;
330 402
 }
331 403
 
332 404
 .echarts {

+ 17 - 20
src/views/blockingData/blockingDataScreen/components/ModuleBrigadeThree.vue

@@ -71,8 +71,8 @@ const fetchData = async () => {
71 71
     if (missCheckRes.data) {
72 72
       const colors = ['#22c55e', '#3b82f6', '#f97316']
73 73
       const missCheckData = missCheckRes.data.map(item => ({
74
-        name: item.range || item.name || '',
75
-        value: item.percentage || item.value || 0
74
+        name: item.name || item.level || '未知',
75
+        value: item.total || item.count || 0
76 76
       }))
77 77
       setOption1(ringChartOption(missCheckData, colors))
78 78
     }
@@ -81,7 +81,7 @@ const fetchData = async () => {
81 81
       const colors = ['#22c55e', '#3b82f6', '#fbbf24', '#ef4444']
82 82
       const assessmentData = assessmentRes.data.map(item => ({
83 83
         name: item.level || item.name || '',
84
-        value: item.percentage || item.value || 0
84
+        value: item.total || 0
85 85
       }))
86 86
       setOption2(ringChartOption(assessmentData, colors))
87 87
     }
@@ -98,29 +98,27 @@ watch(() => props.filterParams, () => {
98 98
 
99 99
 const ringChartOption = (data, colors) => ({
100 100
   color: colors,
101
+  tooltip: { trigger: 'item', formatter: '{b}: {c}' },
101 102
   series: [{
102 103
     type: 'pie',
103 104
     radius: ['40%', '65%'],
104 105
     center: ['50%', '55%'],
105 106
     data: data,
106
-    label: { show: true, formatter: '{b}\n{c}%', fontSize: 10 }
107
+    label: {
108
+      show: true,
109
+      formatter: (params) => {
110
+        const total = data.reduce((sum, item) => sum + item.value, 0)
111
+        const percentage = ((params.value / total) * 100).toFixed(2)
112
+        return `${params.name}\n${params.value}(${percentage}%)`
113
+      },
114
+      fontSize: 10
115
+    }
107 116
   }]
108 117
 })
109 118
 
110 119
 onMounted(() => {
111 120
   fetchData()
112
-  setOption1(ringChartOption([
113
-    { name: '漏检次数≤3次', value: 65.2 },
114
-    { name: '漏检次数4-6次', value: 22.8 },
115
-    { name: '漏检次数≥7次', value: 12.0 }
116
-  ], ['#22c55e', '#3b82f6', '#f97316']))
117
-
118
-  setOption2(ringChartOption([
119
-    { name: '优秀(90-100分)', value: 35.4 },
120
-    { name: '良好(80-89分)', value: 42.1 },
121
-    { name: '合格(70-79分)', value: 18.3 },
122
-    { name: '不合格(<70分)', value: 4.2 }
123
-  ], ['#22c55e', '#3b82f6', '#fbbf24', '#ef4444']))
121
+
124 122
 })
125 123
 </script>
126 124
 
@@ -148,15 +146,14 @@ onMounted(() => {
148 146
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
149 147
   display: flex;
150 148
   flex-direction: column;
151
-  min-height: 200px;
149
+  min-height: 280px;
152 150
 }
153 151
 
154 152
 .chart-title {
155
-  font-size: 14px;
156
-  color: #333;
153
+  font-size: 17px;
154
+  color: black;
157 155
   margin-bottom: 5px;
158 156
   text-align: left;
159
-  font-weight: 500;
160 157
 }
161 158
 
162 159
 .echarts {

+ 126 - 114
src/views/blockingData/blockingDataScreen/components/ModuleBrigadeTwo.vue

@@ -95,7 +95,8 @@ import {
95 95
   brigadeDifficultyDistribution,
96 96
   brigadeSupervisorDistribution,
97 97
   brigadeMissCheckReasonDistribution,
98
-  brigadeOperatingYearsDistribution
98
+  brigadeOperatingYearsDistribution,
99
+  tenureListAll
99 100
 } from '@/api/blockingData/blockingDataScreen'
100 101
 
101 102
 const props = defineProps({
@@ -152,7 +153,7 @@ const fetchData = async () => {
152 153
   loading.value = true
153 154
   try {
154 155
     const processedParams = processFilterParams(props.filterParams)
155
-    const [supervisorRes, teamRes, userRes, genderRes, certDetailRes, certBaseRes, locationRes, difficultyRes, supervisorDistRes, reasonRes, yearsRes] = await Promise.all([
156
+    const [supervisorRes, teamRes, userRes, genderRes, certDetailRes, certBaseRes, locationRes, difficultyRes, supervisorDistRes, reasonRes, yearsRes, tenureRes] = await Promise.allSettled([
156 157
       brigadeSupervisorRanking(processedParams),
157 158
       brigadeTeamLeaderRanking(processedParams),
158 159
       brigadeReviewedUserRanking(processedParams),
@@ -163,12 +164,13 @@ const fetchData = async () => {
163 164
       brigadeDifficultyDistribution(processedParams),
164 165
       brigadeSupervisorDistribution(processedParams),
165 166
       brigadeMissCheckReasonDistribution(processedParams),
166
-      brigadeOperatingYearsDistribution(processedParams)
167
+      brigadeOperatingYearsDistribution(processedParams),
168
+      tenureListAll(processedParams)
167 169
     ])
168 170
 
169
-    if (supervisorRes.data) {
171
+    if (supervisorRes.value?.data) {
170 172
       rankData1.length = 0
171
-      supervisorRes.data.slice(0, 10).forEach(item => {
173
+      supervisorRes.value.data.slice(0, 10).forEach(item => {
172 174
         rankData1.push({
173 175
           name: item.supervisorName || item.name || '',
174 176
           value: item.count || item.value || 0
@@ -176,9 +178,9 @@ const fetchData = async () => {
176 178
       })
177 179
     }
178 180
 
179
-    if (teamRes.data) {
181
+    if (teamRes.value?.data) {
180 182
       rankData2.length = 0
181
-      teamRes.data.slice(0, 10).forEach(item => {
183
+      teamRes.value.data.slice(0, 10).forEach(item => {
182 184
         rankData2.push({
183 185
           name: item.teamLeaderName || item.name || '',
184 186
           value: item.count || item.value || 0
@@ -186,9 +188,9 @@ const fetchData = async () => {
186 188
       })
187 189
     }
188 190
 
189
-    if (userRes.data) {
191
+    if (userRes.value?.data) {
190 192
       rankData3.length = 0
191
-      userRes.data.slice(0, 10).forEach(item => {
193
+      userRes.value.data.slice(0, 10).forEach(item => {
192 194
         rankData3.push({
193 195
           name: item.userName || item.name || '',
194 196
           value: item.count || item.value || 0
@@ -196,46 +198,46 @@ const fetchData = async () => {
196 198
       })
197 199
     }
198 200
 
199
-    if (genderRes.data) {
200
-      const genderData = genderRes.data.map(item => ({
201
+    if (genderRes.value?.data) {
202
+      const genderData = genderRes.value.data.map(item => ({
201 203
         name: item.gender || item.name || '',
202 204
         value: item.percentage || item.value || 0
203 205
       }))
204 206
       setOption4(pieChartOption(genderData, ['#ec4899', '#3b82f6']))
205 207
     }
206 208
 
207
-    if (certDetailRes.data) {
208
-      const certData = certDetailRes.data.map(item => ({
209
+    if (certDetailRes.value?.data) {
210
+      const certData = certDetailRes.value.data.map(item => ({
209 211
         name: item.certificateLevel || item.name || '',
210 212
         value: item.percentage || item.value || 0
211 213
       }))
212 214
       setOption5(pieChartOption(certData, ['#22c55e', '#3b82f6']))
213 215
     }
214 216
 
215
-    if (certBaseRes.data) {
216
-      const baseData = certBaseRes.data.map(item => ({
217
+    if (certBaseRes.value?.data) {
218
+      const baseData = certBaseRes.value.data.map(item => ({
217 219
         name: item.certificateLevel || item.name || '',
218 220
         value: item.percentage || item.value || 0
219 221
       }))
220 222
       setOption6(pieChartOption(baseData, ['#22c55e', '#3b82f6']))
221 223
     }
222 224
 
223
-    if (locationRes.data) {
225
+    if (locationRes.value?.data) {
224 226
       const colors = ['#8b5cf6', '#ec4899', '#f97316', '#22c55e', '#3b82f6', '#14b8a6', '#ef4444', '#fbbf24', '#6366f1', '#06b6d4', '#84cc16', '#e11d48']
225
-      const locationData = locationRes.data.map(item => ({
226
-        name: item.location || item.name || '',
227
+      const locationData = locationRes.value.data.map(item => ({
228
+        name: item.itemLocation || item.name || '',
227 229
         value: item.percentage || item.value || 0
228 230
       }))
229 231
       setOption7(donutChartOption(locationData, colors))
230 232
     }
231 233
 
232
-    if (difficultyRes.data) {
234
+    if (difficultyRes.value?.data) {
233 235
       let difficult = 0
234 236
       let simple = 0
235
-      difficultyRes.data.forEach(item => {
236
-        if (item.difficulty === 'difficult' || item.difficulty === '困难') {
237
+      difficultyRes.value.data.forEach(item => {
238
+        if (item.difficultyLevel === '难') {
237 239
           difficult = item.count || item.value || 0
238
-        } else if (item.difficulty === 'simple' || item.difficulty === '简单') {
240
+        } else if (item.difficultyLevel === '简单') {
239 241
           simple = item.count || item.value || 0
240 242
         }
241 243
       })
@@ -243,32 +245,69 @@ const fetchData = async () => {
243 245
       simpleValue.value = simple
244 246
     }
245 247
 
246
-    if (supervisorDistRes.data) {
248
+    if (supervisorDistRes.value?.data) {
247 249
       const colors = ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6', '#14b8a6', '#ef4444', '#fbbf24', '#6366f1', '#06b6d4', '#84cc16', '#e11d48', '#a855f7', '#f59e0b']
248
-      const supervisorData = supervisorDistRes.data.map(item => ({
250
+      const supervisorData = supervisorDistRes.value.data.map(item => ({
249 251
         name: item.supervisorName || item.name || '',
250 252
         value: item.percentage || item.value || 0
251 253
       }))
252 254
       setOption10(donutChartOption(supervisorData, colors))
253 255
     }
254 256
 
255
-    if (reasonRes.data) {
257
+    if (reasonRes.value?.data) {
256 258
       const colors = ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6', '#14b8a6', '#ef4444', '#fbbf24']
257
-      const reasonData = reasonRes.data.map(item => ({
258
-        name: item.reason || item.name || '',
259
-        value: item.percentage || item.value || 0
259
+      const reasonData = reasonRes.value.data.map(item => ({
260
+        name: item.missCheckReasonCategory || '',
261
+        value: item.count || 0
260 262
       }))
261 263
       setOption11(pieChartOption(reasonData, colors))
262 264
     }
263 265
 
264
-    if (yearsRes.data) {
266
+    if (yearsRes.value?.data) {
265 267
       const colors = ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6', '#14b8a6']
266
-      const yearsData = yearsRes.data.map(item => ({
267
-        name: item.yearsRange || item.name || '',
268
-        value: item.percentage || item.value || 0
268
+      const yearsData = yearsRes.value.data.map(item => ({
269
+        name: item.operatingYears || '',
270
+        value: item.count || 0
269 271
       }))
270 272
       setOption12(pieChartOption(yearsData, colors))
271 273
     }
274
+
275
+    if (tenureRes.value?.data) {
276
+      const xAxisData = tenureRes.value.data.map(item => item.brigadeName || '')
277
+      const seriesData = [
278
+        {
279
+          name: '5年及以上',
280
+          data: tenureRes.value.data.map(item => item.cntGe5Year || 0),
281
+          color: '#3b82f6'
282
+        },
283
+        {
284
+          name: '4年',
285
+          data: tenureRes.value.data.map(item => item.cnt4Years || 0),
286
+          color: '#22c55e'
287
+        },
288
+        {
289
+          name: '3年',
290
+          data: tenureRes.value.data.map(item => item.cnt3Years || 0),
291
+          color: '#f97316'
292
+        },
293
+        {
294
+          name: '2年',
295
+          data: tenureRes.value.data.map(item => item.cnt2Years || 0),
296
+          color: '#ec4899'
297
+        },
298
+        {
299
+          name: '1年',
300
+          data: tenureRes.value.data.map(item => item.cnt1Years || 0),
301
+          color: '#8b5cf6'
302
+        },
303
+        {
304
+          name: '不足1年',
305
+          data: tenureRes.value.data.map(item => item.cntLt1Year || 0),
306
+          color: '#14b8a6'
307
+        }
308
+      ]
309
+      setOption13(multiSeriesBarChartOption(xAxisData, seriesData))
310
+    }
272 311
   } catch (error) {
273 312
     console.error('获取数据失败:', error)
274 313
   } finally {
@@ -282,23 +321,42 @@ watch(() => props.filterParams, () => {
282 321
 
283 322
 const pieChartOption = (data, colors) => ({
284 323
   color: colors,
324
+  tooltip: { trigger: 'item', formatter: '{b}: {c}' },
285 325
   series: [{
286 326
     type: 'pie',
287 327
     radius: ['40%', '65%'],
288 328
     center: ['50%', '55%'],
289 329
     data: data,
290
-    label: { show: true, formatter: '{b}\n{c}%', fontSize: 10 }
330
+    label: {
331
+      show: true,
332
+      formatter: (params) => {
333
+        const total = data.reduce((sum, item) => sum + item.value, 0)
334
+        const percentage = ((params.value / total) * 100).toFixed(2)
335
+        return `${params.name}\n${params.value}(${percentage}%)`
336
+      },
337
+      fontSize: 10
338
+    }
291 339
   }]
292 340
 })
293 341
 
294 342
 const donutChartOption = (data, colors) => ({
295 343
   color: colors,
344
+  tooltip: { trigger: 'item', formatter: '{b}: {c}' },
296 345
   series: [{
297 346
     type: 'pie',
298 347
     radius: ['30%', '55%'],
299 348
     center: ['50%', '55%'],
300 349
     data: data,
301
-    label: { show: true, formatter: '{b}', fontSize: 10, position: 'outside' }
350
+    label: {
351
+      show: true,
352
+      position: 'outside',
353
+      formatter: (params) => {
354
+        const total = data.reduce((sum, item) => sum + item.value, 0)
355
+        const percentage = ((params.value / total) * 100).toFixed(2)
356
+        return `${params.name} ${params.value}(${percentage}%)`
357
+      },
358
+      fontSize: 10
359
+    }
302 360
   }]
303 361
 })
304 362
 
@@ -309,82 +367,37 @@ const multiBarChartOption = (data, color) => ({
309 367
   series: [{ type: 'bar', data: data.map(d => d.value), itemStyle: { color: color }, barWidth: 20 }]
310 368
 })
311 369
 
370
+const multiSeriesBarChartOption = (xAxisData, series) => ({
371
+  grid: { left: '10%', top: '15%', right: '5%', bottom: '15%', containLabel: true },
372
+  xAxis: {
373
+    type: 'category',
374
+    data: xAxisData,
375
+    axisLine: { lineStyle: { color: '#999' } },
376
+    axisLabel: { fontSize: 10, color: '#666' }
377
+  },
378
+  yAxis: {
379
+    type: 'value',
380
+    axisLine: { lineStyle: { color: '#999' } },
381
+    axisLabel: { fontSize: 10, color: '#666' },
382
+    splitLine: { lineStyle: { color: '#eee' } }
383
+  },
384
+  legend: {
385
+    data: series.map(s => s.name),
386
+    top: '0%',
387
+    textStyle: { fontSize: 10 }
388
+  },
389
+  series: series.map(s => ({
390
+    name: s.name,
391
+    type: 'bar',
392
+    data: s.data,
393
+    itemStyle: { color: s.color },
394
+    barWidth: 15
395
+  }))
396
+})
397
+
312 398
 onMounted(() => {
313 399
   fetchData()
314
-  setOption4(pieChartOption([
315
-    { name: '女', value: 52.26 },
316
-    { name: '男', value: 47.74 }
317
-  ], ['#ec4899', '#3b82f6']))
318
-
319
-  setOption5(pieChartOption([
320
-    { name: '高级', value: 49.81 },
321
-    { name: '中级', value: 50.19 }
322
-  ], ['#22c55e', '#3b82f6']))
323
-
324
-  setOption6(pieChartOption([
325
-    { name: '高级证书', value: 1.59 },
326
-    { name: '中级证书', value: 98.41 }
327
-  ], ['#22c55e', '#3b82f6']))
328
-
329
-  setOption7(donutChartOption([
330
-    { name: '中下', value: 6.35 },
331
-    { name: '中间', value: 11.85 },
332
-    { name: '右下', value: 7.74 },
333
-    { name: '右上', value: 7.56 },
334
-    { name: '左中', value: 7.26 },
335
-    { name: '左上', value: 6.61 },
336
-    { name: '左上', value: 11.16 },
337
-    { name: '右下', value: 6.45 },
338
-    { name: '右上', value: 12.42 },
339
-    { name: '中下', value: 7.41 },
340
-    { name: '右上', value: 6.11 },
341
-    { name: '左上', value: 10.24 }
342
-  ], ['#8b5cf6', '#ec4899', '#f97316', '#22c55e', '#3b82f6', '#14b8a6', '#ef4444', '#fbbf24', '#6366f1', '#06b6d4', '#84cc16', '#e11d48']))
343
-
344
-  setOption10(donutChartOption([
345
-    { name: '赵德峰', value: 12.46 },
346
-    { name: '刘佳', value: 7.94 },
347
-    { name: '郑晓华', value: 7.94 },
348
-    { name: '谢金艳', value: 7.82 },
349
-    { name: '潘仁芳', value: 7.33 },
350
-    { name: '张庆林', value: 7.2 },
351
-    { name: '陈颖', value: 7.2 },
352
-    { name: '李学芬', value: 7.2 },
353
-    { name: '李俊峰', value: 7.08 },
354
-    { name: '周雪梅', value: 7.08 },
355
-    { name: '刘旭', value: 6.46 },
356
-    { name: '李丽', value: 6.46 },
357
-    { name: '任静', value: 6.46 },
358
-    { name: '张静', value: 6.46 }
359
-  ], ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6', '#14b8a6', '#ef4444', '#fbbf24', '#6366f1', '#06b6d4', '#84cc16', '#e11d48', '#a855f7', '#f59e0b']))
360
-
361
-  setOption11(pieChartOption([
362
-    { name: '问题判断不清,未按规范检查导致漏检', value: 23.20 },
363
-    { name: '未按规范检查导致漏检', value: 7.04 },
364
-    { name: '判断不清,漏检', value: 6.48 },
365
-    { name: '未能辨别危险品', value: 5.92 },
366
-    { name: '未能辨别危险品', value: 5.92 },
367
-    { name: '未能辨别危险品', value: 2.88 },
368
-    { name: '简单漏检未能认真判断', value: 21.23 },
369
-    { name: '未能辨别危险品', value: 27.34 }
370
-  ], ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6', '#14b8a6', '#ef4444', '#fbbf24']))
371
-
372
-  setOption12(pieChartOption([
373
-    { name: '5年及5年以上', value: 30.71 },
374
-    { name: '4年人员数', value: 18.68 },
375
-    { name: '3年人员数', value: 22.47 },
376
-    { name: '2年人员数', value: 14.75 },
377
-    { name: '1年人员数', value: 6.76 },
378
-    { name: '不足1年人员数', value: 6.63 }
379
-  ], ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6', '#14b8a6']))
380
-
381
-  setOption13(multiBarChartOption([
382
-    { name: '安检一大队', value: 104 },
383
-    { name: '安检二大队', value: 39 },
384
-    { name: '安检三大队', value: 14 },
385
-    { name: '安检四大队', value: 13 },
386
-    { name: '安检五大队', value: 12 }
387
-  ], '#3b82f6'))
400
+
388 401
 })
389 402
 </script>
390 403
 
@@ -407,20 +420,19 @@ onMounted(() => {
407 420
   flex: 1;
408 421
   background: #fff;
409 422
   border-radius: 6px;
410
-  padding: 10px;
423
+  padding: 15px;
411 424
   border: 1px solid #eee;
412 425
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
413 426
   display: flex;
414 427
   flex-direction: column;
415
-  min-height: 200px;
428
+  min-height: 280px;
416 429
 }
417 430
 
418 431
 .chart-title {
419
-  font-size: 14px;
420
-  color: #333;
432
+  font-size: 17px;
433
+  color: black;
421 434
   margin-bottom: 5px;
422 435
   text-align: left;
423
-  font-weight: 500;
424 436
 }
425 437
 
426 438
 .echarts {
@@ -445,7 +457,7 @@ onMounted(() => {
445 457
 
446 458
 .number-unit {
447 459
   font-size: 14px;
448
-  color: #666;
460
+  color: #3b82f6;
449 461
   margin-top: 5px;
450 462
 }
451 463
 </style>

+ 6 - 6
src/views/blockingData/blockingDataScreen/components/ModuleFour.vue

@@ -386,8 +386,8 @@ onMounted(() => {
386 386
   flex: 1;
387 387
   display: flex;
388 388
   gap: 10px;
389
-  min-height: 350px;
390
-  height: 350px;
389
+  min-height: 400px;
390
+  height: 400px;
391 391
 }
392 392
 
393 393
 .chart-item {
@@ -396,10 +396,10 @@ onMounted(() => {
396 396
   flex-direction: column;
397 397
   background: #fff;
398 398
   border-radius: 6px;
399
-  padding: 8px;
399
+  padding: 15px;
400 400
   border: 1px solid #eee;
401 401
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
402
-  min-height: 300px;
402
+  min-height: 350px;
403 403
   height: 100%;
404 404
 }
405 405
 
@@ -413,7 +413,7 @@ onMounted(() => {
413 413
 .echarts {
414 414
   flex: 1;
415 415
   width: 100%;
416
-  min-height: 250px;
417
-  height: 250px;
416
+  min-height: 300px;
417
+  height: 300px;
418 418
 }
419 419
 </style>

+ 3 - 3
src/views/blockingData/blockingDataScreen/components/ModuleOne.vue

@@ -1388,17 +1388,17 @@ onMounted(() => {
1388 1388
   flex: 1;
1389 1389
   background: #fff;
1390 1390
   border-radius: 6px;
1391
-  padding: 10px;
1391
+  padding: 15px;
1392 1392
   border: 1px solid #eee;
1393 1393
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
1394 1394
   display: flex;
1395 1395
   flex-direction: column;
1396
-  min-height: 200px;
1396
+  min-height: 280px;
1397 1397
 }
1398 1398
 
1399 1399
 .chart-row.full-width .chart-item {
1400 1400
   flex: none;
1401
-  height: 200px;
1401
+  height: 280px;
1402 1402
 }
1403 1403
 
1404 1404
 .chart-title {

+ 4 - 4
src/views/blockingData/blockingDataScreen/components/ModuleThree.vue

@@ -137,12 +137,12 @@ onMounted(() => {
137 137
   flex: 1;
138 138
   background: #fff;
139 139
   border-radius: 6px;
140
-  padding: 10px;
140
+  padding: 15px;
141 141
   border: 1px solid #eee;
142 142
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
143 143
   display: flex;
144 144
   flex-direction: column;
145
-  min-height: 300px;
145
+  min-height: 350px;
146 146
   height: 100%;
147 147
 }
148 148
 
@@ -156,7 +156,7 @@ onMounted(() => {
156 156
 .echarts {
157 157
   flex: 1;
158 158
   width: 100%;
159
-  min-height: 250px;
160
-  height: 250px;
159
+  min-height: 300px;
160
+  height: 300px;
161 161
 }
162 162
 </style>

+ 3 - 3
src/views/blockingData/blockingDataScreen/components/ModuleTwo.vue

@@ -395,12 +395,12 @@ onMounted(() => {
395 395
   flex: 1;
396 396
   background: #fff;
397 397
   border-radius: 6px;
398
-  padding: 8px;
398
+  padding: 15px;
399 399
   border: 1px solid #eee;
400 400
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
401 401
   display: flex;
402 402
   flex-direction: column;
403
-  min-height: 120px;
403
+  min-height: 280px;
404 404
 }
405 405
 
406 406
 .chart-title {
@@ -457,6 +457,6 @@ onMounted(() => {
457 457
 .echarts {
458 458
   flex: 1;
459 459
   width: 100%;
460
-  min-height: 100px;
460
+  min-height: 250px;
461 461
 }
462 462
 </style>