Просмотр исходного кода

运营模块-任务评估,台账异常,任务报表-油站报表

miaofuhao 1 месяц назад
Родитель
Сommit
1b0e535a5b

+ 505 - 10
apps/web-ele/src/views/operationRadar/accountAnalysis/index.vue

@@ -1,17 +1,512 @@
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';
15
+}
16
+
17
+interface StationOption {
18
+  label: string;
19
+  value: string;
20
+}
21
+
22
+interface AccountOption {
23
+  label: string;
24
+  value: 'operation' | 'hidden';
25
+}
26
+
27
+interface ExceptionType {
28
+  id: number;
29
+  name: string;
30
+  count: number;
31
+  percentage: string;
32
+}
33
+
34
+interface StationException {
35
+  id: number;
36
+  station: string;
37
+  area: string;
38
+  total: number;
39
+  transferred: number;
40
+  completed: number;
41
+  pending: number;
42
+  unhandled: number;
43
+  equipment: number;
44
+  none: number;
45
+  hygiene: number;
46
+  compliance: number;
47
+}
48
+
49
+// 响应式数据
50
+// Tab切换数据
51
+const activeTab = ref<'station' | 'area'>('station');
52
+const tabOptions: TabOption[] = [
53
+  { label: '油站', value: 'station' },
54
+  { label: '片区', value: 'area' },
55
+];
56
+
57
+// 搜索相关数据
58
+const periodType = ref<'week' | 'month'>('week');
59
+const currentPeriod = ref('12月4日-12月11日');
60
+const selectedStation = ref('');
61
+const selectedAccount = ref('operation');
62
+
63
+const stationOptions: StationOption[] = [
64
+  { label: '油站1', value: 'station1' },
65
+  { label: '油站2', value: 'station2' },
66
+  { label: '油站3', value: 'station3' },
67
+  { label: '油站4', value: 'station4' },
68
+  { label: '油站5', value: 'station5' },
69
+];
70
+
71
+const accountOptions: AccountOption[] = [
72
+  { label: '运营台账', value: 'operation' },
73
+  { label: '隐患台账', value: 'hidden' },
74
+];
75
+
76
+// 图表相关数据
77
+const pieChartRef = ref<EchartsUIType>();
78
+const barChartRef = ref<EchartsUIType>();
79
+const { renderEcharts: renderPieEcharts } = useEcharts(pieChartRef);
80
+const { renderEcharts: renderBarEcharts } = useEcharts(barChartRef);
81
+
82
+// 辅助函数
83
+// 格式化日期为中文格式(MM月dd日)
84
+const formatDate = (date: Date): string => {
85
+  const month = date.getMonth() + 1;
86
+  const day = date.getDate();
87
+  return `${month}月${day}日`;
88
+};
89
+
90
+// 更新时间范围的函数
91
+const updateTimeRange = (type: 'week' | 'month'): void => {
92
+  const today = new Date();
93
+  const endDate = today;
94
+  let startDate: Date;
95
+
96
+  if (type === 'week') {
97
+    // 计算最近一周(今天往前推7天)
98
+    startDate = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
99
+  } else {
100
+    // 计算最近一个月(上个月的今天到今天)
101
+    startDate = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
102
+  }
103
+
104
+  currentPeriod.value = `${formatDate(startDate)}-${formatDate(endDate)}`;
105
+};
106
+
107
+// 图表和数据配置
108
+// 统一的图表颜色配置 - 确保图表颜色风格一致
109
+const CHART_COLORS = {
110
+  EQUIPMENT: '#5ab1ef', // 设备设施异常颜色
111
+  HYGIENE: '#52c41a', // 卫生异常颜色
112
+  COMPLIANCE: '#faad14', // 合规异常颜色
113
+  OTHER: '#f5222d', // 其他异常颜色
114
+  NONE: '#722ed1', // 无异常颜色
115
+  TRANSFERRED: '#5ab1ef', // 转任务颜色
116
+  COMPLETED: '#52c41a', // 已完成颜色
117
+  PENDING: '#faad14', // 待处理颜色
118
+  UNHANDLED: '#f5222d', // 未处理颜色
119
+};
120
+
121
+// Mock数据配置
122
+// 异常类型数据
123
+const MOCK_EXCEPTION_TYPES: ExceptionType[] = [
124
+  { id: 1, name: '设备设施', count: 120, percentage: '35%' },
125
+  { id: 2, name: '卫生', count: 80, percentage: '23%' },
126
+  { id: 3, name: '合规', count: 60, percentage: '17%' },
127
+  { id: 4, name: '其他', count: 50, percentage: '15%' },
128
+  { id: 5, name: '无', count: 35, percentage: '10%' },
129
+];
130
+
131
+// 油站异常数据
132
+const MOCK_STATION_EXCEPTIONS: StationException[] = [
133
+  { id: 1, station: '油站1', area: '片区1', total: 150, transferred: 80, completed: 40, pending: 20, unhandled: 10, equipment: 60, none: 20, hygiene: 40, compliance: 30 },
134
+  { id: 2, station: '油站2', area: '片区1', total: 120, transferred: 70, completed: 30, pending: 15, unhandled: 5, equipment: 50, none: 15, hygiene: 30, compliance: 25 },
135
+  { id: 3, station: '油站3', area: '片区2', total: 180, transferred: 90, completed: 50, pending: 30, unhandled: 10, equipment: 70, none: 25, hygiene: 50, compliance: 35 },
136
+  { id: 4, station: '油站4', area: '片区2', total: 90, transferred: 50, completed: 25, pending: 10, unhandled: 5, equipment: 35, none: 10, hygiene: 25, compliance: 20 },
137
+  { id: 5, station: '油站5', area: '片区3', total: 200, transferred: 100, completed: 60, pending: 30, unhandled: 10, equipment: 80, none: 30, hygiene: 55, compliance: 35 },
138
+];
139
+
140
+// 表格配置
141
+// 异常类型表格配置
142
+const exceptionColumns: VxeGridProps['columns'] = [
143
+  { title: '标签名', field: 'name' },
144
+  { title: '数量', field: 'count' },
145
+  { title: '占比', field: 'percentage' },
146
+];
147
+
148
+const exceptionGridOptions: VxeGridProps = {
149
+  columns: exceptionColumns,
150
+  size: 'medium',
151
+  height: '250px',
152
+  useSearchForm: false,
153
+  proxyConfig: {
154
+    enabled: true,
155
+    autoLoad: true,
156
+    ajax: {
157
+      query: async () => {
158
+        return { items: MOCK_EXCEPTION_TYPES, total: MOCK_EXCEPTION_TYPES.length };
159
+      },
160
+    },
161
+  },
162
+  rowConfig: { keyField: 'id' },
163
+  toolbarConfig: {},
164
+  id: 'exception-type-table',
165
+};
166
+
167
+// 油站异常表格配置
168
+const stationExceptionColumns: VxeGridProps['columns'] = [
169
+  { title: '油站', minWidth: 120, field: 'station' },
170
+  { title: '片区', minWidth: 120, field: 'area' },
171
+  { title: '总数', minWidth: 100, field: 'total' },
172
+  { title: '转任务', minWidth: 100, field: 'transferred' },
173
+  { title: '已完成', minWidth: 100, field: 'completed' },
174
+  { title: '未处理', minWidth: 100, field: 'unhandled' },
175
+  { title: '待处理', minWidth: 100, field: 'pending' },
176
+  { title: '设备设施', minWidth: 120, field: 'equipment' },
177
+  { title: '无', minWidth: 80, field: 'none' },
178
+  { title: '卫生', minWidth: 80, field: 'hygiene' },
179
+  { title: '合规', minWidth: 80, field: 'compliance' },
180
+];
181
+
182
+const stationExceptionGridOptions: VxeGridProps = {
183
+  columns: stationExceptionColumns,
184
+  size: 'medium',
185
+  height: '400px',
186
+  useSearchForm: false,
187
+  proxyConfig: {
188
+    enabled: true,
189
+    autoLoad: true,
190
+    ajax: {
191
+      query: async () => {
192
+        return { items: MOCK_STATION_EXCEPTIONS, total: MOCK_STATION_EXCEPTIONS.length };
193
+      },
194
+    },
195
+  },
196
+  rowConfig: { keyField: 'id' },
197
+  toolbarConfig: {},
198
+  id: 'station-exception-table',
199
+};
200
+
201
+// 创建表格实例
202
+const [ExceptionTable] = useVbenVxeGrid({ gridOptions: exceptionGridOptions });
203
+const [StationExceptionTable] = useVbenVxeGrid({ gridOptions: stationExceptionGridOptions });
204
+
205
+// 图表更新函数
206
+// 更新饼图 - 各类异常占比
207
+const updatePieChart = () => {
208
+  const pieData = MOCK_EXCEPTION_TYPES.map(item => ({
209
+    name: item.name,
210
+    value: item.count,
211
+  }));
212
+
213
+  renderPieEcharts({
214
+    tooltip: {
215
+      trigger: 'item',
216
+      formatter: '{a} <br/>{b}: {c} ({d}%)',
217
+    },
218
+    legend: {
219
+      orient: 'vertical',
220
+      right: 10,
221
+      top: 'center',
222
+    },
223
+    series: [
224
+      {
225
+        name: '异常类型',
226
+        type: 'pie',
227
+        radius: ['40%', '70%'],
228
+        avoidLabelOverlap: false,
229
+        itemStyle: {
230
+          borderRadius: 10,
231
+          borderColor: '#fff',
232
+          borderWidth: 2,
233
+        },
234
+        label: {
235
+          show: false,
236
+          position: 'center',
237
+        },
238
+        emphasis: {
239
+          label: {
240
+            show: true,
241
+            fontSize: 20,
242
+            fontWeight: 'bold',
243
+          },
244
+        },
245
+        labelLine: {
246
+          show: false,
247
+        },
248
+        data: pieData,
249
+        color: [CHART_COLORS.EQUIPMENT, CHART_COLORS.HYGIENE, CHART_COLORS.COMPLIANCE, CHART_COLORS.OTHER, CHART_COLORS.NONE],
250
+      },
251
+    ],
252
+  });
253
+};
254
+
255
+// 更新柱状图 - 油站异常数量
256
+const updateBarChart = () => {
257
+  const stationNames = MOCK_STATION_EXCEPTIONS.map(item => item.station);
258
+  const exceptionData = MOCK_STATION_EXCEPTIONS.map(item => item.total);
259
+
260
+  renderBarEcharts({
261
+    tooltip: {
262
+      trigger: 'axis',
263
+      axisPointer: {
264
+        type: 'shadow',
265
+      },
266
+    },
267
+    grid: {
268
+      left: '3%',
269
+      right: '4%',
270
+      bottom: '3%',
271
+      containLabel: true,
272
+    },
273
+    xAxis: [
274
+      {
275
+        type: 'category',
276
+        data: stationNames,
277
+        axisTick: {
278
+          alignWithLabel: true,
279
+        },
280
+      },
281
+    ],
282
+    yAxis: [
283
+      {
284
+        type: 'value',
285
+        name: '异常数量',
286
+      },
287
+    ],
288
+    series: [
289
+      {
290
+        name: '异常总数',
291
+        type: 'bar',
292
+        barWidth: '10%',
293
+        data: exceptionData,
294
+        itemStyle: {
295
+          color: CHART_COLORS.TRANSFERRED,
296
+        },
297
+      },
298
+    ],
299
+  });
300
+};
301
+
302
+// 事件处理函数
303
+// 查询按钮点击事件
304
+const handleQuery = () => {
305
+  console.log('查询条件:', {
306
+    tab: activeTab.value,
307
+    station: selectedStation.value,
308
+    account: selectedAccount.value,
309
+    periodType: periodType.value,
310
+    period: currentPeriod.value,
311
+  });
312
+  // TODO: 这里可以添加实际的查询逻辑,调用API获取真实数据
313
+  updatePieChart();
314
+  updateBarChart();
315
+};
316
+
317
+// 导出按钮点击事件
318
+const handleExport = () => {
319
+  console.log('导出数据');
320
+  // TODO: 这里可以添加导出逻辑
321
+};
322
+
323
+// 生命周期钩子和监听
324
+// 监听时间类型变化 - 更新当前时段显示
325
+watch(periodType, (newType) => {
326
+  updateTimeRange(newType);
327
+});
328
+
329
+// 监听标签页变化 - 重新加载数据和图表
330
+watch(activeTab, () => {
331
+  updatePieChart();
332
+  updateBarChart();
333
+});
334
+
335
+// 组件初始化 - 设置默认数据和图表
336
+onMounted(() => {
337
+  updateTimeRange(periodType.value); // 初始化时间范围
338
+  updatePieChart(); // 初始化饼图
339
+  updateBarChart(); // 初始化柱状图
340
+});
3 341
 </script>
342
+
4 343
 <template>
5
-<Page>
6
-<div class="wrap">
7
-         空空如也
8
-</div>
9
-</Page>
344
+  <Page :auto-content-height="true">
345
+    <div class="account-analysis">
346
+      <!-- Tab切换区域 -->
347
+      <div class="tab-container">
348
+        <el-tabs v-model="activeTab">
349
+          <el-tab-pane v-for="tab in tabOptions" :key="tab.value" :label="tab.label" :name="tab.value">
350
+          </el-tab-pane>
351
+        </el-tabs>
352
+      </div>
353
+
354
+      <!-- 搜索栏区域 -->
355
+      <div class="search-container">
356
+        <ElSpace>
357
+          <div class="search-item">
358
+            <label>油站:</label>
359
+            <ElSelect v-model="selectedStation" placeholder="请选择油站" style="width: 150px;">
360
+              <ElOption v-for="station in stationOptions" :key="station.value" :label="station.label" :value="station.value" />
361
+            </ElSelect>
362
+          </div>
363
+          <div class="search-item">
364
+            <label>运营台账:</label>
365
+            <ElSelect v-model="selectedAccount" placeholder="请选择台账" style="width: 150px;">
366
+              <ElOption v-for="account in accountOptions" :key="account.value" :label="account.label" :value="account.value" />
367
+            </ElSelect>
368
+          </div>
369
+          <div class="search-item">
370
+            <label>时间:</label>
371
+            <ElRadioGroup v-model="periodType" size="large">
372
+              <ElRadioButton label="week" value="week">周</ElRadioButton>
373
+              <ElRadioButton label="month" value="month">月</ElRadioButton>
374
+            </ElRadioGroup>
375
+          </div>
376
+          <div class="search-item">
377
+            <label>当前时段:</label>
378
+            <span>{{ currentPeriod }}</span>
379
+          </div>
380
+        </ElSpace>
381
+      </div>
382
+
383
+      <!-- 操作按钮区域 -->
384
+      <div class="button-container">
385
+        <ElSpace>
386
+          <ElButton type="primary" @click="handleQuery">查询</ElButton>
387
+        </ElSpace>
388
+      </div>
389
+
390
+      <!-- 各类异常占比模块 -->
391
+      <div class="exception-type-container">
392
+        <h3>各类异常占比</h3>
393
+        <div class="exception-type-content">
394
+          <!-- 饼图区域 -->
395
+          <div class="pie-chart">
396
+            <EchartsUI ref="pieChartRef" style="width: 100%; height: 300px;" />
397
+          </div>
398
+          <!-- 异常类型表格 -->
399
+          <div class="exception-type-table">
400
+            <ExceptionTable />
401
+          </div>
402
+        </div>
403
+      </div>
404
+
405
+      <!-- 油站异常报表模块 -->
406
+      <div class="station-exception-container">
407
+        <div class="station-exception-header">
408
+          <h3>油站异常报表</h3>
409
+          <ElButton @click="handleExport">导出</ElButton>
410
+        </div>
411
+        <!-- 柱状图区域 -->
412
+        <div class="bar-chart">
413
+          <EchartsUI ref="barChartRef" style="width: 100%; height: 300px;" />
414
+        </div>
415
+        <!-- 油站异常表格 -->
416
+        <div class="station-exception-table">
417
+          <StationExceptionTable />
418
+        </div>
419
+      </div>
420
+    </div>
421
+  </Page>
10 422
 </template>
11
-<style lang="scss" scoped>
12
-.wrap {
13
-padding: 16px;
14
-background-color: #fff;
15
-border-radius: 6px;
423
+
424
+<style scoped lang="scss">
425
+.account-analysis {
426
+  min-height: 100vh;
427
+  padding: 16px;
428
+  background-color: #fff;
429
+
430
+  .tab-container {
431
+    margin-bottom: 16px;
432
+  }
433
+
434
+  .search-container {
435
+    display: flex;
436
+    align-items: center;
437
+    padding: 16px;
438
+    margin-bottom: 16px;
439
+    background-color: #fff;
440
+    border-radius: 6px;
441
+
442
+    .search-item {
443
+      display: flex;
444
+      align-items: center;
445
+
446
+      label {
447
+        margin-right: 8px;
448
+        font-weight: 500;
449
+      }
450
+    }
451
+  }
452
+
453
+  .button-container {
454
+    margin-bottom: 16px;
455
+  }
456
+
457
+  .exception-type-container {
458
+    padding: 16px;
459
+    margin-bottom: 16px;
460
+    background-color: #fff;
461
+    border-radius: 6px;
462
+
463
+    h3 {
464
+      margin-bottom: 16px;
465
+      font-size: 16px;
466
+      font-weight: 600;
467
+    }
468
+
469
+    .exception-type-content {
470
+      display: flex;
471
+      gap: 16px;
472
+
473
+      .pie-chart {
474
+        flex: 0.4;
475
+        min-width: 300px;
476
+      }
477
+
478
+      .exception-type-table {
479
+        flex: 0.6;
480
+        min-width: 300px;
481
+      }
482
+    }
483
+  }
484
+
485
+  .station-exception-container {
486
+    padding: 16px;
487
+    background-color: #fff;
488
+    border-radius: 6px;
489
+
490
+    .station-exception-header {
491
+      display: flex;
492
+      align-items: center;
493
+      justify-content: space-between;
494
+      margin-bottom: 16px;
495
+
496
+      h3 {
497
+        font-size: 16px;
498
+        font-weight: 600;
499
+      }
500
+    }
501
+
502
+    .bar-chart {
503
+      width: 100%;
504
+      margin-bottom: 16px;
505
+    }
506
+
507
+    .station-exception-table {
508
+      width: 100%;
509
+    }
510
+  }
16 511
 }
17 512
 </style>

+ 601 - 10
apps/web-ele/src/views/operationRadar/taskEvaluationReport/index.vue

@@ -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>

+ 738 - 10
apps/web-ele/src/views/operationRadar/taskReport/gasStationReport/index.vue

@@ -1,17 +1,745 @@
1 1
 <script lang="ts" setup>
2
+// 导入部分
3
+import type { VxeGridProps } from '#/adapter/vxe-table';
4
+import { ref, watch, onMounted } from 'vue';
2 5
 import { Page } from '@vben/common-ui';
6
+import { useVbenVxeGrid } from '#/adapter/vxe-table';
7
+import { ElSelect, ElOption, ElButton, ElSpace, ElRadioGroup, ElRadioButton } from 'element-plus';
8
+
9
+// 类型定义
10
+interface ReportTypeOption {
11
+  label: string;
12
+  value: 'evaluation' | 'full-indicator';
13
+}
14
+
15
+interface PeriodTypeOption {
16
+  label: string;
17
+  value: 'week' | 'month';
18
+}
19
+
20
+interface StationOption {
21
+  label: string;
22
+  value: string;
23
+}
24
+
25
+interface AreaOption {
26
+  label: string;
27
+  value: string;
28
+}
29
+
30
+interface TaskReportData {
31
+  id: number;
32
+  station: string;
33
+  manager: string;
34
+  area: string;
35
+  totalScore: number;
36
+  completionRate: {
37
+    ratio: string;
38
+    score: number;
39
+  };
40
+  taskScore: {
41
+    score: number;
42
+    obtainedScore: number;
43
+  };
44
+  readRate: {
45
+    ratio: string;
46
+    score: number;
47
+  };
48
+  maxSameScoreRate: {
49
+    ratio: string;
50
+    score: number;
51
+  };
52
+  overdueCount: {
53
+    count: number;
54
+    score: number;
55
+  };
56
+}
57
+
58
+// 全指标报表数据类型
59
+interface FullIndicatorReportData {
60
+  id: number;
61
+  station: string;
62
+  manager: string;
63
+  area: string;
64
+  // 任务数量
65
+  taskQuantity: {
66
+    totalTasks: number;
67
+    completedOnTime: number;
68
+    completedOverdue: number;
69
+    notCompleted: number;
70
+    totalCompletionRate: string;
71
+    overdueRate: string;
72
+    authorizedRate: string;
73
+    newTaskRate: string;
74
+  };
75
+  // 任务质量
76
+  taskQuality: {
77
+    commentCount: number;
78
+    taskScore: number;
79
+    ledgerAverage: number;
80
+  };
81
+  // 授权
82
+  authorization: {
83
+    authorizedCount: number;
84
+    authorizedRate: string;
85
+    authorizationComments: number;
86
+  };
87
+  // 查阅
88
+ 查阅: {
89
+    readableCount: number;
90
+    readCount: number;
91
+    readRate: string;
92
+   查阅Count: number;
93
+  };
94
+  // 绩效
95
+  performance: {
96
+    maxSameScoreRate: string;
97
+    performanceCommentRate: string;
98
+  };
99
+}
100
+
101
+// 响应式数据
102
+// 报表类型切换
103
+const reportType = ref<'evaluation' | 'full-indicator'>('evaluation');
104
+const reportTypeOptions: ReportTypeOption[] = [
105
+  { label: '任务评估报表', value: 'evaluation' },
106
+  { label: '任务全指标报表', value: 'full-indicator' },
107
+];
108
+
109
+// 时间类型切换
110
+const periodType = ref<'week' | 'month'>('week');
111
+const periodTypeOptions: PeriodTypeOption[] = [
112
+  { label: '周', value: 'week' },
113
+  { label: '月', value: 'month' },
114
+];
115
+const currentPeriod = ref('11月13日-11月19日');
116
+
117
+// 搜索条件
118
+const selectedStation = ref('');
119
+const selectedArea = ref('');
120
+
121
+// 下拉选项数据
122
+const stationOptions: StationOption[] = [
123
+  { label: '机场油站', value: 'station1' },
124
+  { label: '北京东加油站', value: 'station2' },
125
+  { label: '北京西加油站', value: 'station3' },
126
+  { label: '北京南加油站', value: 'station4' },
127
+  { label: '北京北加油站', value: 'station5' },
128
+];
129
+
130
+const areaOptions: AreaOption[] = [
131
+  { label: '默认片区', value: 'area1' },
132
+  { label: '片区1', value: 'area2' },
133
+  { label: '片区2', value: 'area3' },
134
+  { label: '片区3', value: 'area4' },
135
+];
136
+
137
+// 辅助函数
138
+// 格式化日期为中文格式(MM月dd日)
139
+const formatDate = (date: Date): string => {
140
+  const month = date.getMonth() + 1;
141
+  const day = date.getDate();
142
+  return `${month}月${day}日`;
143
+};
144
+
145
+// 更新时间范围的函数
146
+const updateTimeRange = (type: 'week' | 'month'): void => {
147
+  const today = new Date();
148
+  let startDate: Date;
149
+  let endDate = today;
150
+
151
+  if (type === 'week') {
152
+    // 计算最近一周(今天往前推7天)
153
+    startDate = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
154
+    currentPeriod.value = `${formatDate(startDate)}-${formatDate(endDate)}`;
155
+  } else {
156
+    // 计算最近一个月(上个月的今天到今天)
157
+    startDate = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
158
+    currentPeriod.value = `${formatDate(startDate)}-${formatDate(endDate)}`;
159
+  }
160
+};
161
+
162
+// 重置搜索条件
163
+const resetSearch = () => {
164
+  selectedStation.value = '';
165
+  selectedArea.value = '';
166
+  periodType.value = 'week';
167
+  updateTimeRange(periodType.value);
168
+};
169
+
170
+// 虚拟数据
171
+const MOCK_DATA: TaskReportData[] = [
172
+  { 
173
+    id: 1, 
174
+    station: '北京东加油站', 
175
+    manager: '李经理', 
176
+    area: '默认片区', 
177
+    totalScore: 44, 
178
+    completionRate: { ratio: '95.52%', score: 24 }, 
179
+    taskScore: { score: 0, obtainedScore: 0 }, 
180
+    readRate: { ratio: '0.00%', score: 0 }, 
181
+    maxSameScoreRate: { ratio: '56.11%', score: 8 }, 
182
+    overdueCount: { count: 3, score: 12 }
183
+  },
184
+  { 
185
+    id: 2, 
186
+    station: '北京西加油站', 
187
+    manager: '王经理', 
188
+    area: '默认片区', 
189
+    totalScore: 8, 
190
+    completionRate: { ratio: '77.14%', score: 0 }, 
191
+    taskScore: { score: 0, obtainedScore: 0 }, 
192
+    readRate: { ratio: '0.00%', score: 0 }, 
193
+    maxSameScoreRate: { ratio: '25%', score: 8 }, 
194
+    overdueCount: { count: 16, score: 0 }
195
+  },
196
+  { 
197
+    id: 3, 
198
+    station: '机场油站', 
199
+    manager: '张经理', 
200
+    area: '片区1', 
201
+    totalScore: 50, 
202
+    completionRate: { ratio: '100%', score: 25 }, 
203
+    taskScore: { score: 0, obtainedScore: 0 }, 
204
+    readRate: { ratio: '50.00%', score: 0 }, 
205
+    maxSameScoreRate: { ratio: '33.33%', score: 10 }, 
206
+    overdueCount: { count: 0, score: 15 }
207
+  },
208
+  { 
209
+    id: 4, 
210
+    station: '北京南加油站', 
211
+    manager: '刘经理', 
212
+    area: '片区2', 
213
+    totalScore: 38, 
214
+    completionRate: { ratio: '90.00%', score: 22 }, 
215
+    taskScore: { score: 0, obtainedScore: 0 }, 
216
+    readRate: { ratio: '33.33%', score: 0 }, 
217
+    maxSameScoreRate: { ratio: '66.67%', score: 6 }, 
218
+    overdueCount: { count: 2, score: 10 }
219
+  },
220
+  { 
221
+    id: 5, 
222
+    station: '北京北加油站', 
223
+    manager: '陈经理', 
224
+    area: '片区3', 
225
+    totalScore: 42, 
226
+    completionRate: { ratio: '93.33%', score: 23 }, 
227
+    taskScore: { score: 0, obtainedScore: 0 }, 
228
+    readRate: { ratio: '25.00%', score: 0 }, 
229
+    maxSameScoreRate: { ratio: '40.00%', score: 8 }, 
230
+    overdueCount: { count: 1, score: 11 }
231
+  },
232
+];
233
+
234
+// 任务全指标报表虚拟数据
235
+const FULL_INDICATOR_MOCK_DATA: FullIndicatorReportData[] = [
236
+  {
237
+    id: 1,
238
+    station: '未来路加油',
239
+    manager: '李玫琳',
240
+    area: '默认片区',
241
+    taskQuantity: {
242
+      totalTasks: 52,
243
+      completedOnTime: 48,
244
+      completedOverdue: 3,
245
+      notCompleted: 1,
246
+      totalCompletionRate: '98.08%',
247
+      overdueRate: '5.77%',
248
+      authorizedRate: '2.5%',
249
+      newTaskRate: '1.92%'
250
+    },
251
+    taskQuality: {
252
+      commentCount: 12,
253
+      taskScore: 4.5,
254
+      ledgerAverage: 85.5
255
+    },
256
+    authorization: {
257
+      authorizedCount: 1,
258
+      authorizedRate: '1.92%',
259
+      authorizationComments: 0
260
+    },
261
+    查阅: {
262
+      readableCount: 51,
263
+      readCount: 0,
264
+      readRate: '0.00%',
265
+      查阅Count: 2
266
+    },
267
+    performance: {
268
+      maxSameScoreRate: '25%',
269
+      performanceCommentRate: '16.67%'
270
+    }
271
+  },
272
+  {
273
+    id: 2,
274
+    station: '龙飞虎加',
275
+    manager: '安宁',
276
+    area: '默认片区',
277
+    taskQuantity: {
278
+      totalTasks: 67,
279
+      completedOnTime: 58,
280
+      completedOverdue: 8,
281
+      notCompleted: 1,
282
+      totalCompletionRate: '98.51%',
283
+      overdueRate: '11.94%',
284
+      authorizedRate: '33.33%',
285
+      newTaskRate: '1.49%'
286
+    },
287
+    taskQuality: {
288
+      commentCount: 8,
289
+      taskScore: 4.2,
290
+      ledgerAverage: 88.2
291
+    },
292
+    authorization: {
293
+      authorizedCount: 11,
294
+      authorizedRate: '16.42%',
295
+      authorizationComments: 3
296
+    },
297
+    查阅: {
298
+      readableCount: 80,
299
+      readCount: 0,
300
+      readRate: '0.00%',
301
+      查阅Count: 1
302
+    },
303
+    performance: {
304
+      maxSameScoreRate: '36.11%',
305
+      performanceCommentRate: '8.33%'
306
+    }
307
+  },
308
+  {
309
+    id: 3,
310
+    station: '法站',
311
+    manager: '张磊',
312
+    area: '默认片区',
313
+    taskQuantity: {
314
+      totalTasks: 125,
315
+      completedOnTime: 112,
316
+      completedOverdue: 12,
317
+      notCompleted: 1,
318
+      totalCompletionRate: '99.20%',
319
+      overdueRate: '9.60%',
320
+      authorizedRate: '16.44%',
321
+      newTaskRate: '0.80%'
322
+    },
323
+    taskQuality: {
324
+      commentCount: 15,
325
+      taskScore: 4.7,
326
+      ledgerAverage: 90.5
327
+    },
328
+    authorization: {
329
+      authorizedCount: 12,
330
+      authorizedRate: '9.60%',
331
+      authorizationComments: 5
332
+    },
333
+    查阅: {
334
+      readableCount: 131,
335
+      readCount: 0,
336
+      readRate: '0.00%',
337
+      查阅Count: 3
338
+    },
339
+    performance: {
340
+      maxSameScoreRate: '31.67%',
341
+      performanceCommentRate: '11.67%'
342
+    }
343
+  },
344
+  {
345
+    id: 4,
346
+    station: '机场油站',
347
+    manager: '王经理',
348
+    area: '片区1',
349
+    taskQuantity: {
350
+      totalTasks: 89,
351
+      completedOnTime: 78,
352
+      completedOverdue: 10,
353
+      notCompleted: 1,
354
+      totalCompletionRate: '98.88%',
355
+      overdueRate: '11.24%',
356
+      authorizedRate: '22.47%',
357
+      newTaskRate: '1.12%'
358
+    },
359
+    taskQuality: {
360
+      commentCount: 20,
361
+      taskScore: 4.3,
362
+      ledgerAverage: 87.8
363
+    },
364
+    authorization: {
365
+      authorizedCount: 10,
366
+      authorizedRate: '11.24%',
367
+      authorizationComments: 4
368
+    },
369
+    查阅: {
370
+      readableCount: 95,
371
+      readCount: 5,
372
+      readRate: '5.26%',
373
+      查阅Count: 2
374
+    },
375
+    performance: {
376
+      maxSameScoreRate: '38.33%',
377
+      performanceCommentRate: '13.33%'
378
+    }
379
+  },
380
+  {
381
+    id: 5,
382
+    station: '北京南加油',
383
+    manager: '刘经理',
384
+    area: '片区2',
385
+    taskQuantity: {
386
+      totalTasks: 45,
387
+      completedOnTime: 39,
388
+      completedOverdue: 5,
389
+      notCompleted: 1,
390
+      totalCompletionRate: '97.78%',
391
+      overdueRate: '11.11%',
392
+      authorizedRate: '15.56%',
393
+      newTaskRate: '2.22%'
394
+    },
395
+    taskQuality: {
396
+      commentCount: 7,
397
+      taskScore: 4.1,
398
+      ledgerAverage: 84.2
399
+    },
400
+    authorization: {
401
+      authorizedCount: 6,
402
+      authorizedRate: '13.33%',
403
+      authorizationComments: 2
404
+    },
405
+    查阅: {
406
+      readableCount: 48,
407
+      readCount: 3,
408
+      readRate: '6.25%',
409
+      查阅Count: 1
410
+    },
411
+    performance: {
412
+      maxSameScoreRate: '28.33%',
413
+      performanceCommentRate: '10.00%'
414
+    }
415
+  }
416
+];
417
+
418
+// 任务评估报表表格配置
419
+const taskReportColumns: VxeGridProps['columns'] = [
420
+  { title: '油站', field: 'station', minWidth: 150, align: 'center' },
421
+  { title: '油站经理', field: 'manager', minWidth: 120, align: 'center' },
422
+  { title: '片区', field: 'area', minWidth: 120, align: 'center' },
423
+  { title: '总分', field: 'totalScore', minWidth: 80, align: 'center' },
424
+  { 
425
+    title: '完成率', 
426
+    minWidth: 150, 
427
+    align: 'center', 
428
+    children: [
429
+      { title: '比例', field: 'completionRate.ratio', minWidth: 80, align: 'center' },
430
+      { title: '得分', field: 'completionRate.score', minWidth: 70, align: 'center' },
431
+    ]
432
+  },
433
+  { 
434
+    title: '任务得分', 
435
+    minWidth: 150, 
436
+    align: 'center', 
437
+    children: [
438
+      { title: '分数', field: 'taskScore.score', minWidth: 80, align: 'center' },
439
+      { title: '得分', field: 'taskScore.obtainedScore', minWidth: 70, align: 'center' },
440
+    ]
441
+  },
442
+  { 
443
+    title: '已阅比例', 
444
+    minWidth: 150, 
445
+    align: 'center', 
446
+    children: [
447
+      { title: '比例', field: 'readRate.ratio', minWidth: 80, align: 'center' },
448
+      { title: '得分', field: 'readRate.score', minWidth: 70, align: 'center' },
449
+    ]
450
+  },
451
+  { 
452
+    title: '最多相同分数率', 
453
+    minWidth: 180, 
454
+    align: 'center', 
455
+    children: [
456
+      { title: '比例', field: 'maxSameScoreRate.ratio', minWidth: 100, align: 'center' },
457
+      { title: '得分', field: 'maxSameScoreRate.score', minWidth: 80, align: 'center' },
458
+    ]
459
+  },
460
+  { 
461
+    title: '逾期未完成数', 
462
+    minWidth: 180, 
463
+    align: 'center', 
464
+    children: [
465
+      { title: '过期数量', field: 'overdueCount.count', minWidth: 100, align: 'center' },
466
+      { title: '过期分数', field: 'overdueCount.score', minWidth: 80, align: 'center' },
467
+    ]
468
+  },
469
+];
470
+
471
+const taskReportGridOptions: VxeGridProps = {
472
+  columns: taskReportColumns,
473
+  size: 'medium',
474
+  height: '500px',
475
+  useSearchForm: false,
476
+  proxyConfig: {
477
+    enabled: true,
478
+    autoLoad: true,
479
+    ajax: {
480
+      query: async () => {
481
+        return { items: MOCK_DATA, total: MOCK_DATA.length };
482
+      },
483
+    },
484
+  },
485
+  rowConfig: { keyField: 'id' },
486
+  toolbarConfig: {},
487
+  id: 'task-report-table',
488
+};
489
+
490
+// 任务全指标报表表格配置
491
+const fullIndicatorReportColumns: VxeGridProps['columns'] = [
492
+  { title: '油站', field: 'station', minWidth: 150, align: 'center', fixed: 'left' },
493
+  { title: '油站经理', field: 'manager', minWidth: 120, align: 'center', fixed: 'left' },
494
+  { title: '片区', field: 'area', minWidth: 120, align: 'center', fixed: 'left' },
495
+  { 
496
+    title: '任务数量', 
497
+    minWidth: 400, 
498
+    align: 'center', 
499
+    children: [
500
+      { title: '任务数', field: 'taskQuantity.totalTasks', minWidth: 80, align: 'center' },
501
+      { title: '按时完成', field: 'taskQuantity.completedOnTime', minWidth: 80, align: 'center' },
502
+      { title: '逾期完成', field: 'taskQuantity.completedOverdue', minWidth: 80, align: 'center' },
503
+      { title: '过期未完成', field: 'taskQuantity.notCompleted', minWidth: 90, align: 'center' },
504
+      { title: '总完成率', field: 'taskQuantity.totalCompletionRate', minWidth: 80, align: 'center' },
505
+      { title: '逾期率', field: 'taskQuantity.overdueRate', minWidth: 80, align: 'center' },
506
+      { title: '被授权率', field: 'taskQuantity.authorizedRate', minWidth: 80, align: 'center' },
507
+      { title: '新增任务率', field: 'taskQuantity.newTaskRate', minWidth: 80, align: 'center' },
508
+    ]
509
+  },
510
+  { 
511
+    title: '任务质量', 
512
+    minWidth: 250, 
513
+    align: 'center', 
514
+    children: [
515
+      { title: '收到的点评数', field: 'taskQuality.commentCount', minWidth: 100, align: 'center' },
516
+      { title: '任务得分', field: 'taskQuality.taskScore', minWidth: 80, align: 'center' },
517
+      { title: '台账平均数', field: 'taskQuality.ledgerAverage', minWidth: 80, align: 'center' },
518
+    ]
519
+  },
520
+  { 
521
+    title: '授权', 
522
+    minWidth: 250, 
523
+    align: 'center', 
524
+    children: [
525
+      { title: '已授权', field: 'authorization.authorizedCount', minWidth: 80, align: 'center' },
526
+      { title: '已授权率', field: 'authorization.authorizedRate', minWidth: 80, align: 'center' },
527
+      { title: '授权点评', field: 'authorization.authorizationComments', minWidth: 80, align: 'center' },
528
+    ]
529
+  },
530
+  { 
531
+    title: '查阅', 
532
+    minWidth: 300, 
533
+    align: 'center', 
534
+    children: [
535
+      { title: '可阅读', field: '查阅.readableCount', minWidth: 80, align: 'center' },
536
+      { title: '已阅读', field: '查阅.readCount', minWidth: 80, align: 'center' },
537
+      { title: '已阅读率', field: '查阅.readRate', minWidth: 80, align: 'center' },
538
+      { title: '被查阅数', field: '查阅.查阅Count', minWidth: 80, align: 'center' },
539
+    ]
540
+  },
541
+  { 
542
+    title: '绩效', 
543
+    minWidth: 250, 
544
+    align: 'center', 
545
+    children: [
546
+      { title: '最多相同分数率', field: 'performance.maxSameScoreRate', minWidth: 100, align: 'center' },
547
+      { title: '绩效评语率', field: 'performance.performanceCommentRate', minWidth: 100, align: 'center' },
548
+    ]
549
+  },
550
+];
551
+
552
+const fullIndicatorReportGridOptions: VxeGridProps = {
553
+  columns: fullIndicatorReportColumns,
554
+  size: 'medium',
555
+  height: '500px',
556
+  useSearchForm: false,
557
+  proxyConfig: {
558
+    enabled: true,
559
+    autoLoad: true,
560
+    ajax: {
561
+      query: async () => {
562
+        return { items: FULL_INDICATOR_MOCK_DATA, total: FULL_INDICATOR_MOCK_DATA.length };
563
+      },
564
+    },
565
+  },
566
+  rowConfig: { keyField: 'id' },
567
+  toolbarConfig: {},
568
+  id: 'full-indicator-report-table',
569
+  scrollX: true,
570
+  scrollY: true,
571
+};
572
+
573
+// 创建表格实例
574
+const [TaskReportTable] = useVbenVxeGrid({ gridOptions: taskReportGridOptions });
575
+const [FullIndicatorReportTable] = useVbenVxeGrid({ gridOptions: fullIndicatorReportGridOptions });
576
+
577
+// 事件处理函数
578
+// 查询按钮点击事件
579
+const handleQuery = () => {
580
+  console.log('查询条件:', {
581
+    reportType: reportType.value,
582
+    station: selectedStation.value,
583
+    area: selectedArea.value,
584
+    periodType: periodType.value,
585
+    period: currentPeriod.value,
586
+  });
587
+  // TODO: 这里可以添加实际的查询逻辑,调用API获取真实数据
588
+};
589
+
590
+// 重置按钮点击事件
591
+const handleReset = () => {
592
+  resetSearch();
593
+  console.log('重置搜索条件');
594
+};
595
+
596
+// 导出按钮点击事件
597
+const handleExport = () => {
598
+  console.log('导出数据');
599
+  // TODO: 这里可以添加导出逻辑
600
+};
601
+
602
+// 生命周期钩子和监听
603
+// 监听时间类型变化 - 更新当前时段显示
604
+watch(periodType, (newType) => {
605
+  updateTimeRange(newType);
606
+});
607
+
608
+// 组件初始化 - 设置默认时间范围
609
+onMounted(() => {
610
+  updateTimeRange(periodType.value);
611
+});
3 612
 </script>
613
+
4 614
 <template>
5
-<Page>
6
-<div class="wrap">
7
-         空空如也
8
-</div>
9
-</Page>
615
+  <Page :auto-content-height="true">
616
+    <div class="task-report-container">
617
+      <!-- 报表类型切换 -->
618
+      <div class="report-type-container">
619
+        <ElRadioGroup v-model="reportType" size="large">
620
+          <ElRadioButton 
621
+            v-for="option in reportTypeOptions" 
622
+            :key="option.value" 
623
+            :label="option.value"
624
+          >
625
+            {{ option.label }}
626
+          </ElRadioButton>
627
+        </ElRadioGroup>
628
+      </div>
629
+
630
+      <!-- 搜索区域 -->
631
+      <div class="search-container">
632
+        <ElSpace>
633
+          <div class="search-item">
634
+            <label>油站:</label>
635
+            <ElSelect v-model="selectedStation" placeholder="请选择油站" style="width: 180px;">
636
+              <ElOption 
637
+                v-for="option in stationOptions" 
638
+                :key="option.value" 
639
+                :label="option.label" 
640
+                :value="option.value" 
641
+              />
642
+            </ElSelect>
643
+          </div>
644
+          <div class="search-item">
645
+            <label>片区:</label>
646
+            <ElSelect v-model="selectedArea" placeholder="请选择片区" style="width: 180px;">
647
+              <ElOption 
648
+                v-for="option in areaOptions" 
649
+                :key="option.value" 
650
+                :label="option.label" 
651
+                :value="option.value" 
652
+              />
653
+            </ElSelect>
654
+          </div>
655
+          <div class="search-item">
656
+            <ElRadioGroup v-model="periodType" size="large">
657
+              <ElRadioButton 
658
+                v-for="option in periodTypeOptions" 
659
+                :key="option.value" 
660
+                :label="option.value"
661
+              >
662
+                {{ option.label }}
663
+              </ElRadioButton>
664
+            </ElRadioGroup>
665
+          </div>
666
+          <div class="search-item">
667
+            <span>{{ currentPeriod }}</span>
668
+          </div>
669
+        </ElSpace>
670
+      </div>
671
+
672
+      <!-- 操作按钮区域 -->
673
+      <div class="button-container">
674
+        <ElSpace>
675
+          <ElButton type="primary" @click="handleQuery">查询</ElButton>
676
+          <ElButton @click="handleReset">重置</ElButton>
677
+          <ElButton @click="handleExport">导出</ElButton>
678
+        </ElSpace>
679
+      </div>
680
+
681
+      <!-- 报表提示语 -->
682
+      <div class="notice-container">
683
+        <p>数据周期:次周周三早9点自动生成,按周切片,次周日早9点自动生成。</p>
684
+      </div>
685
+
686
+      <!-- 报表数据表格 -->
687
+      <div class="table-container">
688
+        <TaskReportTable v-if="reportType === 'evaluation'" />
689
+        <FullIndicatorReportTable v-else />
690
+      </div>
691
+    </div>
692
+  </Page>
10 693
 </template>
11
-<style lang="scss" scoped>
12
-.wrap {
13
-padding: 16px;
14
-background-color: #fff;
15
-border-radius: 6px;
694
+
695
+<style scoped lang="scss">
696
+.task-report-container {
697
+  min-height: calc(100vh - 120px);
698
+  padding: 16px;
699
+  background-color: #fff;
700
+
701
+  .report-type-container {
702
+    margin-bottom: 16px;
703
+  }
704
+
705
+  .search-container {
706
+    display: flex;
707
+    align-items: center;
708
+    padding: 16px;
709
+    margin-bottom: 16px;
710
+    border-radius: 6px;
711
+
712
+    .search-item {
713
+      display: flex;
714
+      align-items: center;
715
+
716
+      label {
717
+        margin-right: 8px;
718
+        font-weight: 500;
719
+      }
720
+    }
721
+  }
722
+
723
+  .button-container {
724
+    margin-bottom: 16px;
725
+  }
726
+
727
+  .notice-container {
728
+    padding: 12px 16px;
729
+    margin-bottom: 16px;
730
+    font-size: 14px;
731
+    color: #606266;
732
+    background-color: #f0f5ff;
733
+    border-left: 4px solid #409eff;
734
+    border-radius: 4px;
735
+
736
+    p {
737
+      margin: 0;
738
+    }
739
+  }
740
+
741
+  .table-container {
742
+    width: 100%;
743
+  }
16 744
 }
17 745
 </style>