|
|
@@ -1,17 +1,608 @@
|
|
1
|
1
|
<script lang="ts" setup>
|
|
|
2
|
+// 导入部分
|
|
|
3
|
+import type { EchartsUIType } from '@vben/plugins/echarts';
|
|
|
4
|
+import type { VxeGridProps } from '#/adapter/vxe-table';
|
|
|
5
|
+import { ref, watch, onMounted } from 'vue';
|
|
2
|
6
|
import { Page } from '@vben/common-ui';
|
|
|
7
|
+import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
|
|
8
|
+import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
|
|
9
|
+import { ElSelect, ElOption, ElButton, ElSpace, ElRadioGroup, ElRadioButton } from 'element-plus';
|
|
|
10
|
+
|
|
|
11
|
+// 类型定义
|
|
|
12
|
+interface TabOption {
|
|
|
13
|
+ label: string;
|
|
|
14
|
+ value: 'station' | 'area' | 'stationManage' | 'stationStaff' | 'areaStaff' | 'headStaff';
|
|
|
15
|
+}
|
|
|
16
|
+
|
|
|
17
|
+interface StationOption {
|
|
|
18
|
+ label: string;
|
|
|
19
|
+ value: string;
|
|
|
20
|
+}
|
|
|
21
|
+
|
|
|
22
|
+interface EvaluationItem {
|
|
|
23
|
+ id: number;
|
|
|
24
|
+ dimension: string;
|
|
|
25
|
+ indicator: string;
|
|
|
26
|
+ currentScore: number;
|
|
|
27
|
+ currentValue: string;
|
|
|
28
|
+ lastValue: string;
|
|
|
29
|
+ comparison: '进步' | '持平' | '退步';
|
|
|
30
|
+ maxValue: string;
|
|
|
31
|
+ standard: string;
|
|
|
32
|
+}
|
|
|
33
|
+
|
|
|
34
|
+// 响应式数据
|
|
|
35
|
+// Tab切换数据
|
|
|
36
|
+const activeTab = ref<'station' | 'area' | 'stationManage' | 'stationStaff' | 'areaStaff' | 'headStaff'>('station');
|
|
|
37
|
+const tabOptions: TabOption[] = [
|
|
|
38
|
+ { label: '油站', value: 'station' },
|
|
|
39
|
+ { label: '片区', value: 'area' },
|
|
|
40
|
+ { label: '油站管理', value: 'stationManage' },
|
|
|
41
|
+ { label: '油站员工', value: 'stationStaff' },
|
|
|
42
|
+ { label: '片区人员', value: 'areaStaff' },
|
|
|
43
|
+ { label: '总部人员', value: 'headStaff' },
|
|
|
44
|
+];
|
|
|
45
|
+
|
|
|
46
|
+// 搜索相关数据
|
|
|
47
|
+const periodType = ref<'week' | 'month'>('week');
|
|
|
48
|
+const currentPeriod = ref('12月4日-12月11日');
|
|
|
49
|
+const selectedStation = ref('');
|
|
|
50
|
+const stationOptions: StationOption[] = [
|
|
|
51
|
+ { label: '油站1', value: 'station1' },
|
|
|
52
|
+ { label: '油站2', value: 'station2' },
|
|
|
53
|
+ { label: '油站3', value: 'station3' },
|
|
|
54
|
+];
|
|
|
55
|
+
|
|
|
56
|
+// 图表相关数据
|
|
|
57
|
+const radarChartRef = ref<EchartsUIType>();
|
|
|
58
|
+const trendChartRef = ref<EchartsUIType>();
|
|
|
59
|
+const { renderEcharts: renderRadarEcharts } = useEcharts(radarChartRef);
|
|
|
60
|
+const { renderEcharts: renderTrendEcharts } = useEcharts(trendChartRef);
|
|
|
61
|
+
|
|
|
62
|
+// 辅助函数
|
|
|
63
|
+// 格式化日期为中文格式(MM月dd日)
|
|
|
64
|
+const formatDate = (date: Date): string => {
|
|
|
65
|
+ const month = date.getMonth() + 1;
|
|
|
66
|
+ const day = date.getDate();
|
|
|
67
|
+ return `${month}月${day}日`;
|
|
|
68
|
+};
|
|
|
69
|
+
|
|
|
70
|
+// 将十六进制颜色转换为带透明度的rgba颜色
|
|
|
71
|
+const hexToRgba = (hex: string, opacity: number): string => {
|
|
|
72
|
+ const r = parseInt(hex.slice(1, 3), 16);
|
|
|
73
|
+ const g = parseInt(hex.slice(3, 5), 16);
|
|
|
74
|
+ const b = parseInt(hex.slice(5, 7), 16);
|
|
|
75
|
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
|
76
|
+};
|
|
|
77
|
+
|
|
|
78
|
+// 更新时间范围的函数
|
|
|
79
|
+const updateTimeRange = (type: 'week' | 'month'): void => {
|
|
|
80
|
+ const today = new Date();
|
|
|
81
|
+ const endDate = today;
|
|
|
82
|
+ let startDate: Date;
|
|
|
83
|
+
|
|
|
84
|
+ if (type === 'week') {
|
|
|
85
|
+ // 计算最近一周(今天往前推7天)
|
|
|
86
|
+ startDate = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
|
87
|
+ } else {
|
|
|
88
|
+ // 计算最近一个月(上个月的今天到今天)
|
|
|
89
|
+ startDate = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
|
|
|
90
|
+ }
|
|
|
91
|
+
|
|
|
92
|
+ currentPeriod.value = `${formatDate(startDate)}-${formatDate(endDate)}`;
|
|
|
93
|
+};
|
|
|
94
|
+
|
|
|
95
|
+// 图表和数据配置
|
|
|
96
|
+// 统一的图表颜色配置 - 确保图表颜色风格一致
|
|
|
97
|
+const CHART_COLORS = {
|
|
|
98
|
+ THIS_WEEK: '#5ab1ef', // 本周数据颜色
|
|
|
99
|
+ LAST_WEEK: '#faad14', // 上周数据颜色
|
|
|
100
|
+ LAST_MONTH: '#52c41a', // 上月同期数据颜色
|
|
|
101
|
+ TASK_COMPLETION: '#5ab1ef', // 任务完成率颜色
|
|
|
102
|
+ TASK_QUALITY: '#52c41a', // 任务质量颜色
|
|
|
103
|
+ PERFORMANCE_SCORE: '#faad14', // 绩效得分颜色
|
|
|
104
|
+ AVERAGE_SCORE: '#faad14', // 平均得分颜色
|
|
|
105
|
+ AUTHORIZATION: '#52c41a', // 授权完成率颜色
|
|
|
106
|
+ REVIEW_RATE: '#faad14', // 点评完成率颜色
|
|
|
107
|
+ EFFICIENCY: '#faad14', // 效率颜色
|
|
|
108
|
+};
|
|
|
109
|
+
|
|
|
110
|
+// Mock数据配置 - 为不同标签页提供模拟评估数据
|
|
|
111
|
+const MOCK_DATA_CONFIG: Record<string, EvaluationItem[]> = {
|
|
|
112
|
+ station: [
|
|
|
113
|
+ // 油站列表维度:总分,任务数量,任务质量,查阅情况,绩效,逾期
|
|
|
114
|
+ { id: 1, dimension: '总分', indicator: '总分值', currentScore: 95, currentValue: '95.62%', lastValue: '82.67%', comparison: '进步', maxValue: '95.62%', standard: '' },
|
|
|
115
|
+ { id: 2, dimension: '任务数量', indicator: '任务完成数', currentScore: 88, currentValue: '120个', lastValue: '105个', comparison: '进步', maxValue: '150个', standard: '' },
|
|
|
116
|
+ { id: 3, dimension: '任务质量', indicator: '任务达标率', currentScore: 92, currentValue: '98.5%', lastValue: '96.2%', comparison: '进步', maxValue: '99.0%', standard: '' },
|
|
|
117
|
+ { id: 4, dimension: '查阅情况', indicator: '查阅完成率', currentScore: 76, currentValue: '85.0%', lastValue: '80.0%', comparison: '进步', maxValue: '95.0%', standard: '' },
|
|
|
118
|
+ { id: 5, dimension: '绩效', indicator: '绩效得分', currentScore: 89, currentValue: '89分', lastValue: '85分', comparison: '进步', maxValue: '95分', standard: '' },
|
|
|
119
|
+ { id: 6, dimension: '逾期', indicator: '逾期率', currentScore: 72, currentValue: '5.2%', lastValue: '8.7%', comparison: '进步', maxValue: '3.0%', standard: '' },
|
|
|
120
|
+ ],
|
|
|
121
|
+ area: [
|
|
|
122
|
+ // 片区列表维度:总分,任务数量,任务质量,查阅情况,绩效
|
|
|
123
|
+ { id: 1, dimension: '总分', indicator: '总分值', currentScore: 92, currentValue: '92.35%', lastValue: '88.42%', comparison: '进步', maxValue: '95.62%', standard: '' },
|
|
|
124
|
+ { id: 2, dimension: '任务数量', indicator: '任务完成数', currentScore: 85, currentValue: '850个', lastValue: '780个', comparison: '进步', maxValue: '1000个', standard: '' },
|
|
|
125
|
+ { id: 3, dimension: '任务质量', indicator: '任务达标率', currentScore: 90, currentValue: '97.2%', lastValue: '95.8%', comparison: '进步', maxValue: '99.0%', standard: '' },
|
|
|
126
|
+ { id: 4, dimension: '查阅情况', indicator: '查阅完成率', currentScore: 78, currentValue: '82.5%', lastValue: '79.0%', comparison: '进步', maxValue: '95.0%', standard: '' },
|
|
|
127
|
+ { id: 5, dimension: '绩效', indicator: '绩效得分', currentScore: 87, currentValue: '87分', lastValue: '83分', comparison: '进步', maxValue: '95分', standard: '' },
|
|
|
128
|
+ ],
|
|
|
129
|
+ stationManage: [
|
|
|
130
|
+ // 油站管理列表维度:总分,任务数量,任务质量,查阅情况,授权
|
|
|
131
|
+ { id: 1, dimension: '总分', indicator: '总分值', currentScore: 90, currentValue: '90.45%', lastValue: '86.72%', comparison: '进步', maxValue: '95.62%', standard: '' },
|
|
|
132
|
+ { id: 2, dimension: '任务数量', indicator: '任务完成数', currentScore: 82, currentValue: '450个', lastValue: '420个', comparison: '进步', maxValue: '500个', standard: '' },
|
|
|
133
|
+ { id: 3, dimension: '任务质量', indicator: '任务达标率', currentScore: 88, currentValue: '96.8%', lastValue: '94.5%', comparison: '进步', maxValue: '99.0%', standard: '' },
|
|
|
134
|
+ { id: 4, dimension: '查阅情况', indicator: '查阅完成率', currentScore: 74, currentValue: '80.0%', lastValue: '76.5%', comparison: '进步', maxValue: '95.0%', standard: '' },
|
|
|
135
|
+ { id: 5, dimension: '授权', indicator: '授权完成率', currentScore: 85, currentValue: '92.5%', lastValue: '88.0%', comparison: '进步', maxValue: '98.0%', standard: '' },
|
|
|
136
|
+ ],
|
|
|
137
|
+ stationStaff: [
|
|
|
138
|
+ // 油站员工列表维度:总分,任务数量,任务质量
|
|
|
139
|
+ { id: 1, dimension: '总分', indicator: '总分值', currentScore: 88, currentValue: '88.72%', lastValue: '84.36%', comparison: '进步', maxValue: '95.62%', standard: '' },
|
|
|
140
|
+ { id: 2, dimension: '任务数量', indicator: '任务完成数', currentScore: 84, currentValue: '95个', lastValue: '88个', comparison: '进步', maxValue: '120个', standard: '' },
|
|
|
141
|
+ { id: 3, dimension: '任务质量', indicator: '任务达标率', currentScore: 91, currentValue: '97.8%', lastValue: '95.2%', comparison: '进步', maxValue: '99.0%', standard: '' },
|
|
|
142
|
+ ],
|
|
|
143
|
+ areaStaff: [
|
|
|
144
|
+ // 片区人员列表维度:总分,任务数量,任务质量,点评,逾期
|
|
|
145
|
+ { id: 1, dimension: '总分', indicator: '总分值', currentScore: 89, currentValue: '89.25%', lastValue: '85.68%', comparison: '进步', maxValue: '95.62%', standard: '' },
|
|
|
146
|
+ { id: 2, dimension: '任务数量', indicator: '任务完成数', currentScore: 86, currentValue: '780个', lastValue: '720个', comparison: '进步', maxValue: '900个', standard: '' },
|
|
|
147
|
+ { id: 3, dimension: '任务质量', indicator: '任务达标率', currentScore: 90, currentValue: '97.0%', lastValue: '94.8%', comparison: '进步', maxValue: '99.0%', standard: '' },
|
|
|
148
|
+ { id: 4, dimension: '点评', indicator: '点评完成率', currentScore: 79, currentValue: '85.5%', lastValue: '81.2%', comparison: '进步', maxValue: '95.0%', standard: '' },
|
|
|
149
|
+ { id: 5, dimension: '逾期', indicator: '逾期率', currentScore: 74, currentValue: '6.8%', lastValue: '9.3%', comparison: '进步', maxValue: '3.0%', standard: '' },
|
|
|
150
|
+ ],
|
|
|
151
|
+ headStaff: [
|
|
|
152
|
+ // 总部人员列表维度:总分,任务数量,任务质量,点评
|
|
|
153
|
+ { id: 1, dimension: '总分', indicator: '总分值', currentScore: 93, currentValue: '93.48%', lastValue: '89.75%', comparison: '进步', maxValue: '95.62%', standard: '' },
|
|
|
154
|
+ { id: 2, dimension: '任务数量', indicator: '任务完成数', currentScore: 87, currentValue: '420个', lastValue: '390个', comparison: '进步', maxValue: '500个', standard: '' },
|
|
|
155
|
+ { id: 3, dimension: '任务质量', indicator: '任务达标率', currentScore: 94, currentValue: '98.2%', lastValue: '96.5%', comparison: '进步', maxValue: '99.0%', standard: '' },
|
|
|
156
|
+ { id: 4, dimension: '点评', indicator: '点评完成率', currentScore: 83, currentValue: '89.0%', lastValue: '84.5%', comparison: '进步', maxValue: '95.0%', standard: '' },
|
|
|
157
|
+ ],
|
|
|
158
|
+};
|
|
|
159
|
+
|
|
|
160
|
+// 雷达图配置 - 定义不同标签页的雷达图维度和数据
|
|
|
161
|
+const RADAR_CHART_CONFIG: Record<string, { indicator: Array<{ name: string; max: number }>; radarData: number[] }> = {
|
|
|
162
|
+ station: {
|
|
|
163
|
+ indicator: [
|
|
|
164
|
+ { name: '任务数量', max: 100 },
|
|
|
165
|
+ { name: '任务质量', max: 100 },
|
|
|
166
|
+ { name: '查阅情况', max: 100 },
|
|
|
167
|
+ { name: '绩效', max: 100 },
|
|
|
168
|
+ { name: '逾期', max: 100 },
|
|
|
169
|
+ ],
|
|
|
170
|
+ radarData: [95, 92, 76, 89, 72],
|
|
|
171
|
+ },
|
|
|
172
|
+ area: {
|
|
|
173
|
+ indicator: [
|
|
|
174
|
+ { name: '任务数量', max: 100 },
|
|
|
175
|
+ { name: '任务质量', max: 100 },
|
|
|
176
|
+ { name: '查阅情况', max: 100 },
|
|
|
177
|
+ { name: '绩效', max: 100 },
|
|
|
178
|
+ { name: '平均得分', max: 100 },
|
|
|
179
|
+ ],
|
|
|
180
|
+ radarData: [92, 90, 78, 87, 85],
|
|
|
181
|
+ },
|
|
|
182
|
+ stationManage: {
|
|
|
183
|
+ indicator: [
|
|
|
184
|
+ { name: '任务数量', max: 100 },
|
|
|
185
|
+ { name: '任务质量', max: 100 },
|
|
|
186
|
+ { name: '查阅情况', max: 100 },
|
|
|
187
|
+ { name: '授权', max: 100 },
|
|
|
188
|
+ { name: '平均得分', max: 100 },
|
|
|
189
|
+ ],
|
|
|
190
|
+ radarData: [90, 88, 74, 85, 83],
|
|
|
191
|
+ },
|
|
|
192
|
+ stationStaff: {
|
|
|
193
|
+ indicator: [
|
|
|
194
|
+ { name: '任务数量', max: 100 },
|
|
|
195
|
+ { name: '任务质量', max: 100 },
|
|
|
196
|
+ { name: '平均得分', max: 100 },
|
|
|
197
|
+ { name: '效率', max: 100 },
|
|
|
198
|
+ { name: '合规性', max: 100 },
|
|
|
199
|
+ ],
|
|
|
200
|
+ radarData: [88, 91, 87, 82, 78],
|
|
|
201
|
+ },
|
|
|
202
|
+ areaStaff: {
|
|
|
203
|
+ indicator: [
|
|
|
204
|
+ { name: '任务数量', max: 100 },
|
|
|
205
|
+ { name: '任务质量', max: 100 },
|
|
|
206
|
+ { name: '点评', max: 100 },
|
|
|
207
|
+ { name: '逾期', max: 100 },
|
|
|
208
|
+ { name: '平均得分', max: 100 },
|
|
|
209
|
+ ],
|
|
|
210
|
+ radarData: [89, 90, 79, 74, 83],
|
|
|
211
|
+ },
|
|
|
212
|
+ headStaff: {
|
|
|
213
|
+ indicator: [
|
|
|
214
|
+ { name: '任务数量', max: 100 },
|
|
|
215
|
+ { name: '任务质量', max: 100 },
|
|
|
216
|
+ { name: '点评', max: 100 },
|
|
|
217
|
+ { name: '平均得分', max: 100 },
|
|
|
218
|
+ { name: '效率', max: 100 },
|
|
|
219
|
+ ],
|
|
|
220
|
+ radarData: [93, 94, 83, 88, 90],
|
|
|
221
|
+ },
|
|
|
222
|
+ default: {
|
|
|
223
|
+ indicator: [
|
|
|
224
|
+ { name: '任务完成率', max: 100 },
|
|
|
225
|
+ { name: '问题解决率', max: 100 },
|
|
|
226
|
+ { name: '效率提升', max: 100 },
|
|
|
227
|
+ { name: '合规性', max: 100 },
|
|
|
228
|
+ { name: '满意度', max: 100 },
|
|
|
229
|
+ ],
|
|
|
230
|
+ radarData: [95, 88, 76, 92, 85],
|
|
|
231
|
+ },
|
|
|
232
|
+};
|
|
|
233
|
+
|
|
|
234
|
+// 趋势图配置 - 定义不同标签页的趋势图数据和图例
|
|
|
235
|
+const TREND_CHART_CONFIG: Record<string, { series: any[]; legendData: string[] }> = {
|
|
|
236
|
+ station: {
|
|
|
237
|
+ series: [
|
|
|
238
|
+ { name: '任务完成率', type: 'line', data: [85, 88, 90, 87, 92, 95], itemStyle: { color: CHART_COLORS.TASK_COMPLETION } },
|
|
|
239
|
+ { name: '任务质量', type: 'line', data: [88, 90, 92, 91, 93, 95], itemStyle: { color: CHART_COLORS.TASK_QUALITY } },
|
|
|
240
|
+ { name: '绩效得分', type: 'line', data: [82, 84, 86, 85, 88, 89], itemStyle: { color: CHART_COLORS.PERFORMANCE_SCORE } },
|
|
|
241
|
+ ],
|
|
|
242
|
+ legendData: ['任务完成率', '任务质量', '绩效得分'],
|
|
|
243
|
+ },
|
|
|
244
|
+ area: {
|
|
|
245
|
+ series: [
|
|
|
246
|
+ { name: '任务完成率', type: 'line', data: [82, 85, 88, 86, 90, 92], itemStyle: { color: CHART_COLORS.TASK_COMPLETION } },
|
|
|
247
|
+ { name: '任务质量', type: 'line', data: [86, 88, 90, 89, 91, 93], itemStyle: { color: CHART_COLORS.TASK_QUALITY } },
|
|
|
248
|
+ { name: '平均得分', type: 'line', data: [80, 82, 85, 84, 86, 87], itemStyle: { color: CHART_COLORS.AVERAGE_SCORE } },
|
|
|
249
|
+ ],
|
|
|
250
|
+ legendData: ['任务完成率', '任务质量', '平均得分'],
|
|
|
251
|
+ },
|
|
|
252
|
+ stationManage: {
|
|
|
253
|
+ series: [
|
|
|
254
|
+ { name: '任务完成率', type: 'line', data: [80, 83, 85, 84, 88, 90], itemStyle: { color: CHART_COLORS.TASK_COMPLETION } },
|
|
|
255
|
+ { name: '授权完成率', type: 'line', data: [85, 87, 89, 88, 91, 93], itemStyle: { color: CHART_COLORS.AUTHORIZATION } },
|
|
|
256
|
+ { name: '平均得分', type: 'line', data: [78, 81, 83, 82, 85, 86], itemStyle: { color: CHART_COLORS.AVERAGE_SCORE } },
|
|
|
257
|
+ ],
|
|
|
258
|
+ legendData: ['任务完成率', '授权完成率', '平均得分'],
|
|
|
259
|
+ },
|
|
|
260
|
+ stationStaff: {
|
|
|
261
|
+ series: [
|
|
|
262
|
+ { name: '任务完成率', type: 'line', data: [78, 81, 83, 82, 86, 88], itemStyle: { color: CHART_COLORS.TASK_COMPLETION } },
|
|
|
263
|
+ { name: '任务质量', type: 'line', data: [88, 90, 92, 91, 94, 95], itemStyle: { color: CHART_COLORS.TASK_QUALITY } },
|
|
|
264
|
+ { name: '效率', type: 'line', data: [75, 78, 80, 79, 82, 84], itemStyle: { color: CHART_COLORS.EFFICIENCY } },
|
|
|
265
|
+ ],
|
|
|
266
|
+ legendData: ['任务完成率', '任务质量', '效率'],
|
|
|
267
|
+ },
|
|
|
268
|
+ areaStaff: {
|
|
|
269
|
+ series: [
|
|
|
270
|
+ { name: '任务完成率', type: 'line', data: [80, 83, 85, 84, 88, 89], itemStyle: { color: CHART_COLORS.TASK_COMPLETION } },
|
|
|
271
|
+ { name: '任务质量', type: 'line', data: [86, 88, 90, 89, 92, 94], itemStyle: { color: CHART_COLORS.TASK_QUALITY } },
|
|
|
272
|
+ { name: '点评完成率', type: 'line', data: [75, 78, 80, 79, 82, 84], itemStyle: { color: CHART_COLORS.REVIEW_RATE } },
|
|
|
273
|
+ ],
|
|
|
274
|
+ legendData: ['任务完成率', '任务质量', '点评完成率'],
|
|
|
275
|
+ },
|
|
|
276
|
+ headStaff: {
|
|
|
277
|
+ series: [
|
|
|
278
|
+ { name: '任务完成率', type: 'line', data: [85, 88, 90, 89, 93, 95], itemStyle: { color: CHART_COLORS.TASK_COMPLETION } },
|
|
|
279
|
+ { name: '任务质量', type: 'line', data: [90, 92, 94, 93, 95, 97], itemStyle: { color: CHART_COLORS.TASK_QUALITY } },
|
|
|
280
|
+ { name: '点评完成率', type: 'line', data: [78, 81, 83, 82, 86, 88], itemStyle: { color: CHART_COLORS.REVIEW_RATE } },
|
|
|
281
|
+ ],
|
|
|
282
|
+ legendData: ['任务完成率', '任务质量', '点评完成率'],
|
|
|
283
|
+ },
|
|
|
284
|
+ default: {
|
|
|
285
|
+ series: [
|
|
|
286
|
+ { name: '任务完成率', type: 'line', data: [85, 88, 90, 87, 92, 95], itemStyle: { color: CHART_COLORS.TASK_COMPLETION } },
|
|
|
287
|
+ { name: '问题解决率', type: 'line', data: [80, 82, 85, 83, 86, 88], itemStyle: { color: CHART_COLORS.TASK_QUALITY } },
|
|
|
288
|
+ { name: '效率提升', type: 'line', data: [70, 72, 75, 73, 76, 78], itemStyle: { color: CHART_COLORS.EFFICIENCY } },
|
|
|
289
|
+ ],
|
|
|
290
|
+ legendData: ['任务完成率', '问题解决率', '效率提升'],
|
|
|
291
|
+ },
|
|
|
292
|
+};
|
|
|
293
|
+
|
|
|
294
|
+// 数据生成函数
|
|
|
295
|
+// 根据标签页类型生成不同的mock数据 - 实现数据与视图的解耦
|
|
|
296
|
+const generateMockData = (tabType: string): EvaluationItem[] => {
|
|
|
297
|
+ return MOCK_DATA_CONFIG[tabType] || [];
|
|
|
298
|
+};
|
|
|
299
|
+
|
|
|
300
|
+// 表格配置
|
|
|
301
|
+const evaluationColumns: VxeGridProps['columns'] = [
|
|
|
302
|
+ { title: '维度', width: 100, field: 'dimension' },
|
|
|
303
|
+ { title: '指标', field: 'indicator' },
|
|
|
304
|
+ { title: '本周得分', width: 120, field: 'currentScore' },
|
|
|
305
|
+ { title: '本周数值', width: 120, field: 'currentValue' },
|
|
|
306
|
+ { title: '上周数值', width: 120, field: 'lastValue' },
|
|
|
307
|
+ { title: '对比结果', width: 120, field: 'comparison', scopedSlots: { default: 'comparison' } },
|
|
|
308
|
+ { title: '全网最高数值', width: 150, field: 'maxValue' },
|
|
|
309
|
+ { title: '评分标准', width: 100, field: 'standard', scopedSlots: { default: 'standard' } },
|
|
|
310
|
+];
|
|
|
311
|
+
|
|
|
312
|
+const evaluationGridOptions: VxeGridProps = {
|
|
|
313
|
+ columns: evaluationColumns,
|
|
|
314
|
+ size: 'medium',
|
|
|
315
|
+ height: '400px',
|
|
|
316
|
+ useSearchForm: false,
|
|
|
317
|
+ proxyConfig: {
|
|
|
318
|
+ enabled: true,
|
|
|
319
|
+ autoLoad: true,
|
|
|
320
|
+ ajax: {
|
|
|
321
|
+ query: async () => {
|
|
|
322
|
+ // 根据当前激活的标签页返回对应的数据
|
|
|
323
|
+ const mockData = generateMockData(activeTab.value);
|
|
|
324
|
+ return { items: mockData, total: mockData.length };
|
|
|
325
|
+ },
|
|
|
326
|
+ },
|
|
|
327
|
+ },
|
|
|
328
|
+ rowConfig: { keyField: 'id' },
|
|
|
329
|
+ toolbarConfig: {},
|
|
|
330
|
+ id: 'task-evaluation-report',
|
|
|
331
|
+};
|
|
|
332
|
+
|
|
|
333
|
+// 创建表格实例 - 使用封装的表格组件
|
|
|
334
|
+const [EvaluationTable, {}] = useVbenVxeGrid({
|
|
|
335
|
+ gridOptions: evaluationGridOptions,
|
|
|
336
|
+});
|
|
|
337
|
+
|
|
|
338
|
+// 图表更新函数
|
|
|
339
|
+// 更新雷达图 - 根据当前激活的标签页动态生成雷达图
|
|
|
340
|
+const updateRadarChart = () => {
|
|
|
341
|
+ // 获取当前标签页的雷达图配置,默认使用default配置
|
|
|
342
|
+ const { indicator, radarData } = RADAR_CHART_CONFIG[activeTab.value] || RADAR_CHART_CONFIG.default;
|
|
|
343
|
+
|
|
|
344
|
+ renderRadarEcharts({
|
|
|
345
|
+ radar: {
|
|
|
346
|
+ indicator,
|
|
|
347
|
+ radius: '70%',
|
|
|
348
|
+ },
|
|
|
349
|
+ series: [
|
|
|
350
|
+ {
|
|
|
351
|
+ type: 'radar',
|
|
|
352
|
+ data: [
|
|
|
353
|
+ {
|
|
|
354
|
+ value: radarData,
|
|
|
355
|
+ name: '本周',
|
|
|
356
|
+ itemStyle: { color: CHART_COLORS.THIS_WEEK },
|
|
|
357
|
+ areaStyle: { color: hexToRgba(CHART_COLORS.THIS_WEEK, 0.3) },
|
|
|
358
|
+ },
|
|
|
359
|
+ {
|
|
|
360
|
+ value: radarData.map(v => v - Math.floor(Math.random() * 10) - 3),
|
|
|
361
|
+ name: '上周',
|
|
|
362
|
+ itemStyle: { color: CHART_COLORS.LAST_WEEK },
|
|
|
363
|
+ areaStyle: { color: hexToRgba(CHART_COLORS.LAST_WEEK, 0.3) },
|
|
|
364
|
+ },
|
|
|
365
|
+ {
|
|
|
366
|
+ value: radarData.map(v => v - Math.floor(Math.random() * 15) - 5),
|
|
|
367
|
+ name: '上月同期',
|
|
|
368
|
+ itemStyle: { color: CHART_COLORS.LAST_MONTH },
|
|
|
369
|
+ areaStyle: { color: hexToRgba(CHART_COLORS.LAST_MONTH, 0.3) },
|
|
|
370
|
+ },
|
|
|
371
|
+ ],
|
|
|
372
|
+ },
|
|
|
373
|
+ ],
|
|
|
374
|
+ tooltip: {
|
|
|
375
|
+ trigger: 'item',
|
|
|
376
|
+ },
|
|
|
377
|
+ });
|
|
|
378
|
+};
|
|
|
379
|
+// 处理标签页点击事件 - 切换当前激活的标签页
|
|
|
380
|
+const handleTabClick = (tab: string) => {
|
|
|
381
|
+ activeTab.value = tab.paneName;
|
|
|
382
|
+};
|
|
|
383
|
+// 更新趋势图 - 根据当前激活的标签页动态生成趋势图
|
|
|
384
|
+const updateTrendChart = () => {
|
|
|
385
|
+ // 获取当前标签页的趋势图配置,默认使用default配置
|
|
|
386
|
+ const { series, legendData } = TREND_CHART_CONFIG[activeTab.value] || TREND_CHART_CONFIG.default;
|
|
|
387
|
+
|
|
|
388
|
+ renderTrendEcharts({
|
|
|
389
|
+ xAxis: {
|
|
|
390
|
+ type: 'category',
|
|
|
391
|
+ data: ['11/04', '11/11', '11/18', '11/25', '12/02', '12/09'],
|
|
|
392
|
+ },
|
|
|
393
|
+ yAxis: {
|
|
|
394
|
+ type: 'value',
|
|
|
395
|
+ name: '得分',
|
|
|
396
|
+ max: 100,
|
|
|
397
|
+ },
|
|
|
398
|
+ series,
|
|
|
399
|
+ tooltip: {
|
|
|
400
|
+ trigger: 'axis',
|
|
|
401
|
+ },
|
|
|
402
|
+ legend: {
|
|
|
403
|
+ data: legendData,
|
|
|
404
|
+ bottom: 0,
|
|
|
405
|
+ },
|
|
|
406
|
+ });
|
|
|
407
|
+};
|
|
|
408
|
+
|
|
|
409
|
+// 事件处理函数
|
|
|
410
|
+// 查询按钮点击事件 - 处理用户查询请求
|
|
|
411
|
+const handleQuery = () => {
|
|
|
412
|
+ console.log('查询条件:', {
|
|
|
413
|
+ tab: activeTab.value,
|
|
|
414
|
+ station: selectedStation.value,
|
|
|
415
|
+ periodType: periodType.value,
|
|
|
416
|
+ period: currentPeriod.value,
|
|
|
417
|
+ });
|
|
|
418
|
+ // TODO: 这里可以添加实际的查询逻辑,调用API获取真实数据
|
|
|
419
|
+ // refreshGrid(); // 刷新表格数据
|
|
|
420
|
+ updateRadarChart(); // 更新雷达图
|
|
|
421
|
+ updateTrendChart(); // 更新趋势图
|
|
|
422
|
+};
|
|
|
423
|
+
|
|
|
424
|
+// 指标说明点击事件 - 显示指标说明信息
|
|
|
425
|
+const handleIndicatorExplain = () => {
|
|
|
426
|
+ console.log('指标说明');
|
|
|
427
|
+ // TODO: 这里可以添加指标说明的逻辑,如显示弹窗或跳转到说明页面
|
|
|
428
|
+};
|
|
|
429
|
+
|
|
|
430
|
+// 生命周期钩子和监听
|
|
|
431
|
+// 监听时间类型变化 - 更新当前时段显示
|
|
|
432
|
+watch(periodType, (newType) => {
|
|
|
433
|
+ updateTimeRange(newType);
|
|
|
434
|
+});
|
|
|
435
|
+
|
|
|
436
|
+// 监听标签页变化 - 重新加载数据和图表
|
|
|
437
|
+watch(activeTab, () => {
|
|
|
438
|
+ // refreshGrid(); // 刷新表格数据
|
|
|
439
|
+ updateRadarChart(); // 更新雷达图
|
|
|
440
|
+ updateTrendChart(); // 更新趋势图
|
|
|
441
|
+});
|
|
|
442
|
+
|
|
|
443
|
+// 组件初始化 - 设置默认数据和图表
|
|
|
444
|
+onMounted(() => {
|
|
|
445
|
+ updateTimeRange(periodType.value); // 初始化时间范围
|
|
|
446
|
+ updateRadarChart(); // 初始化雷达图
|
|
|
447
|
+ updateTrendChart(); // 初始化趋势图
|
|
|
448
|
+});
|
|
3
|
449
|
</script>
|
|
|
450
|
+
|
|
4
|
451
|
<template>
|
|
5
|
|
-<Page>
|
|
6
|
|
-<div class="wrap">
|
|
7
|
|
- 空空如也
|
|
8
|
|
-</div>
|
|
9
|
|
-</Page>
|
|
|
452
|
+ <Page :auto-content-height="true">
|
|
|
453
|
+ <div class="task-evaluation-report">
|
|
|
454
|
+ <!-- Tab切换区域 - 根据不同标签页展示不同维度的数据 -->
|
|
|
455
|
+ <div class="tab-container">
|
|
|
456
|
+ <el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
|
|
457
|
+ <el-tab-pane v-for="tab in tabOptions" :key="tab.value" :label="tab.label" :name="tab.value">
|
|
|
458
|
+ </el-tab-pane>
|
|
|
459
|
+ </el-tabs>
|
|
|
460
|
+ </div>
|
|
|
461
|
+
|
|
|
462
|
+ <!-- 搜索栏区域 - 提供油站选择和时间范围筛选功能 -->
|
|
|
463
|
+ <div class="search-container">
|
|
|
464
|
+ <ElSpace>
|
|
|
465
|
+ <div class="search-item">
|
|
|
466
|
+ <label>油站:</label>
|
|
|
467
|
+ <ElSelect v-model="selectedStation" placeholder="请选择油站" style="width: 150px;">
|
|
|
468
|
+ <ElOption v-for="station in stationOptions" :key="station.value" :label="station.label" :value="station.value" />
|
|
|
469
|
+ </ElSelect>
|
|
|
470
|
+ </div>
|
|
|
471
|
+ <div class="search-item">
|
|
|
472
|
+ <label>时间:</label>
|
|
|
473
|
+ <ElRadioGroup v-model="periodType" size="large">
|
|
|
474
|
+ <ElRadioButton label="week" value="week">周</ElRadioButton>
|
|
|
475
|
+ <ElRadioButton label="month" value="month">月</ElRadioButton>
|
|
|
476
|
+ </ElRadioGroup>
|
|
|
477
|
+ </div>
|
|
|
478
|
+ <div class="search-item">
|
|
|
479
|
+ <label>当前时段:</label>
|
|
|
480
|
+ <span>{{ currentPeriod }}</span>
|
|
|
481
|
+ </div>
|
|
|
482
|
+ </ElSpace>
|
|
|
483
|
+ </div>
|
|
|
484
|
+
|
|
|
485
|
+ <!-- 操作按钮区域 - 提供查询和指标说明功能 -->
|
|
|
486
|
+ <div class="button-container">
|
|
|
487
|
+ <ElSpace>
|
|
|
488
|
+ <ElButton type="primary" @click="handleQuery">查询</ElButton>
|
|
|
489
|
+ <ElButton @click="handleIndicatorExplain">指标说明</ElButton>
|
|
|
490
|
+ </ElSpace>
|
|
|
491
|
+ </div>
|
|
|
492
|
+
|
|
|
493
|
+ <!-- 任务评估报告区域 - 包含雷达图和详细数据表格 -->
|
|
|
494
|
+ <div class="evaluation-container">
|
|
|
495
|
+ <h3>任务评估报告</h3>
|
|
|
496
|
+ <div class="evaluation-content">
|
|
|
497
|
+ <!-- 雷达图区域 - 展示多维度评估指标的综合分析 -->
|
|
|
498
|
+ <div class="radar-chart">
|
|
|
499
|
+ <EchartsUI ref="radarChartRef" style="width: 100%; height: 400px;" />
|
|
|
500
|
+ </div>
|
|
|
501
|
+ <!-- 数据表格区域 - 展示各项评估指标的详细数值和对比结果 -->
|
|
|
502
|
+ <div class="evaluation-table">
|
|
|
503
|
+ <EvaluationTable>
|
|
|
504
|
+ <!-- 对比结果插槽 - 根据进步/持平/退步显示不同颜色 -->
|
|
|
505
|
+ <template #comparison="{ row }">
|
|
|
506
|
+ <span :style="{
|
|
|
507
|
+ color: row.comparison === '进步' ? '#52c41a' :
|
|
|
508
|
+ row.comparison === '持平' ? '#faad14' : '#f5222d'
|
|
|
509
|
+ }">{{ row.comparison }}</span>
|
|
|
510
|
+ </template>
|
|
|
511
|
+ <!-- 评分标准插槽 - 提供查看详细评分标准的入口 -->
|
|
|
512
|
+ <template #standard>
|
|
|
513
|
+ <el-button type="text" size="small">查看</el-button>
|
|
|
514
|
+ </template>
|
|
|
515
|
+ </EvaluationTable>
|
|
|
516
|
+ </div>
|
|
|
517
|
+ </div>
|
|
|
518
|
+ </div>
|
|
|
519
|
+
|
|
|
520
|
+ <!-- 总体趋势分析区域 - 展示评估指标的历史变化趋势 -->
|
|
|
521
|
+ <div class="trend-container">
|
|
|
522
|
+ <h3>总体趋势分析</h3>
|
|
|
523
|
+ <div class="trend-chart">
|
|
|
524
|
+ <EchartsUI ref="trendChartRef" style="width: 100%; height: 400px;" />
|
|
|
525
|
+ </div>
|
|
|
526
|
+ </div>
|
|
|
527
|
+ </div>
|
|
|
528
|
+ </Page>
|
|
10
|
529
|
</template>
|
|
11
|
|
-<style lang="scss" scoped>
|
|
12
|
|
-.wrap {
|
|
13
|
|
-padding: 16px;
|
|
14
|
|
-background-color: #fff;
|
|
15
|
|
-border-radius: 6px;
|
|
|
530
|
+
|
|
|
531
|
+<style scoped lang="scss">
|
|
|
532
|
+.task-evaluation-report {
|
|
|
533
|
+ min-height: 100vh;
|
|
|
534
|
+ padding: 16px;
|
|
|
535
|
+ background-color: #fff;
|
|
|
536
|
+
|
|
|
537
|
+ .tab-container {
|
|
|
538
|
+ margin-bottom: 16px;
|
|
|
539
|
+ }
|
|
|
540
|
+
|
|
|
541
|
+ .search-container {
|
|
|
542
|
+ display: flex;
|
|
|
543
|
+ align-items: center;
|
|
|
544
|
+ padding: 16px;
|
|
|
545
|
+ margin-bottom: 16px;
|
|
|
546
|
+ background-color: #fff;
|
|
|
547
|
+ border-radius: 6px;
|
|
|
548
|
+
|
|
|
549
|
+ .search-item {
|
|
|
550
|
+ display: flex;
|
|
|
551
|
+ align-items: center;
|
|
|
552
|
+
|
|
|
553
|
+ label {
|
|
|
554
|
+ margin-right: 8px;
|
|
|
555
|
+ font-weight: 500;
|
|
|
556
|
+ }
|
|
|
557
|
+ }
|
|
|
558
|
+ }
|
|
|
559
|
+
|
|
|
560
|
+ .button-container {
|
|
|
561
|
+ margin-bottom: 16px;
|
|
|
562
|
+ }
|
|
|
563
|
+
|
|
|
564
|
+ .evaluation-container {
|
|
|
565
|
+ padding: 16px;
|
|
|
566
|
+ margin-bottom: 16px;
|
|
|
567
|
+ background-color: #fff;
|
|
|
568
|
+ border-radius: 6px;
|
|
|
569
|
+
|
|
|
570
|
+ h3 {
|
|
|
571
|
+ margin-bottom: 16px;
|
|
|
572
|
+ font-size: 16px;
|
|
|
573
|
+ font-weight: 600;
|
|
|
574
|
+ }
|
|
|
575
|
+
|
|
|
576
|
+ .evaluation-content {
|
|
|
577
|
+ display: flex;
|
|
|
578
|
+ gap: 16px;
|
|
|
579
|
+
|
|
|
580
|
+ .radar-chart {
|
|
|
581
|
+ flex: 0.4; /* 雷达图占40%宽度 */
|
|
|
582
|
+ min-width: 300px;
|
|
|
583
|
+ }
|
|
|
584
|
+
|
|
|
585
|
+ .evaluation-table {
|
|
|
586
|
+ flex: 0.6; /* 列表占60%宽度 */
|
|
|
587
|
+ min-width: 400px;
|
|
|
588
|
+ }
|
|
|
589
|
+ }
|
|
|
590
|
+ }
|
|
|
591
|
+
|
|
|
592
|
+ .trend-container {
|
|
|
593
|
+ padding: 16px;
|
|
|
594
|
+ background-color: #fff;
|
|
|
595
|
+ border-radius: 6px;
|
|
|
596
|
+
|
|
|
597
|
+ h3 {
|
|
|
598
|
+ margin-bottom: 16px;
|
|
|
599
|
+ font-size: 16px;
|
|
|
600
|
+ font-weight: 600;
|
|
|
601
|
+ }
|
|
|
602
|
+
|
|
|
603
|
+ .trend-chart {
|
|
|
604
|
+ width: 100%;
|
|
|
605
|
+ }
|
|
|
606
|
+ }
|
|
16
|
607
|
}
|
|
17
|
608
|
</style>
|