1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
| <template>
| <div class="category-ratio">
| <div class="card">
| <div class="card__header">
| <span class="label">销售类别占比</span>
|
| <el-icon class="more" @click="router.push('/goods/category')">
| <arrow-right-bold />
| </el-icon>
| </div>
|
| <div class="card__container">
| <v-chart :option="chartOption" autoresize />
| </div>
| </div>
| </div>
| </template>
|
| <script lang="ts" setup>
| import { onMounted, reactive, ref } from "vue";
| import { useCool } from "/@/cool";
| import { ArrowRightBold } from "@element-plus/icons-vue";
| import { orderBy } from "lodash-es";
|
| const { service, router } = useCool();
|
| const list = ref<{ typeName: string; total: number }[]>([]);
|
| const chartOption = reactive({
| legend: {
| top: 50,
| left: 15,
| orient: "vertical",
| icon: "circle",
| data: [] as string[],
| formatter(name: string) {
| const d = list.value.find((e) => e.typeName === name);
|
| return `${d?.typeName}(${d?.total})`;
| }
| },
|
| series: [
| {
| type: "pie",
| padAngle: 5,
| radius: ["45%", "60%"],
| center: ["75%", "55%"],
| avoidLabelOverlap: false,
| label: {
| show: false,
| position: "center"
| },
| emphasis: {
| label: {
| show: true,
| fontSize: "15",
| fontWeight: "bold"
| }
| },
| labelLine: {
| show: false
| },
| data: [] as any[],
| itemStyle: {
| borderColor: "#fff",
| borderWidth: 2,
| borderRadius: 4
| }
| }
| ]
| });
|
| onMounted(() => {
| service.count.home
| .goodsCategory({
| type: "count"
| })
| .then((res: any[]) => {
| // 倒序
| const arr = orderBy(res, "total", "desc").map((e) => {
| return {
| ...e,
| total: Number(e.total)
| };
| });
|
| // 前5个先
| const rank = arr.filter((_, i) => i < 5);
|
| // 合并其他
| const other = {
| typeName: "其他",
| total: arr.splice(5).reduce((a, b) => a + b.total, 0)
| };
|
| list.value = [...rank, other];
|
| // 设置图例
| chartOption.legend.data = list.value.map((e) => e.typeName);
|
| // 设置数据
| chartOption.series[0].data = list.value.map((e) => {
| return {
| value: e.total,
| name: e.typeName
| };
| });
| });
| });
| </script>
|
| <style lang="scss" scoped>
| .category-ratio {
| position: relative;
|
| .echarts {
| height: 150px;
| position: absolute;
| right: 0;
| top: 0;
| }
|
| .card__container {
| height: 100px;
| }
| }
| </style>
|
|