Showing
14 changed files
with
283 additions
and
94 deletions
... | ... | @@ -2,9 +2,10 @@ import { BasicPageParams } from './../model/baseModel'; |
2 | 2 | import { defHttp } from '/@/utils/http/axios'; |
3 | 3 | enum HomeEnum { |
4 | 4 | home = '/homepage/left/top', |
5 | - TenantExpireTimeList = '/homepage/right', | |
5 | + TenantExpireTimeList = '/homepage/right/overdue', | |
6 | 6 | EntitiesQueryFind = '/entitiesQuery/find', |
7 | 7 | TrendAPI = '/homepage/left/bottom', |
8 | + Top10 = '/homepage/right/top10', | |
8 | 9 | } |
9 | 10 | |
10 | 11 | export const getHomeData = () => { |
... | ... | @@ -21,6 +22,12 @@ export const getTenantExpireTimeList = (params: BasicPageParams) => { |
21 | 22 | }); |
22 | 23 | }; |
23 | 24 | |
25 | +export const getTenantTop10 = () => { | |
26 | + return defHttp.get<{ name: string; count: number }[]>({ | |
27 | + url: HomeEnum.Top10, | |
28 | + }); | |
29 | +}; | |
30 | + | |
24 | 31 | // 获取entities实体ID |
25 | 32 | export const getEntitiesId = () => { |
26 | 33 | return defHttp.post( | ... | ... |
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | @menuEvent="handleMenuEvent" |
12 | 12 | overlayClassName="app-locale-picker-overlay" |
13 | 13 | > |
14 | - <span class="cursor-pointer flex items-center" style="color: #fff"> | |
14 | + <span class="cursor-pointer flex items-center" :style="{ color: color }"> | |
15 | 15 | <Icon icon="ion:language" /> |
16 | 16 | <span v-if="showText" class="ml-1">{{ getLocaleText }}</span> |
17 | 17 | </span> |
... | ... | @@ -35,6 +35,10 @@ |
35 | 35 | * Whether to refresh the interface when changing |
36 | 36 | */ |
37 | 37 | reload: { type: Boolean }, |
38 | + color: { | |
39 | + type: String, | |
40 | + default: '#595959', | |
41 | + }, | |
38 | 42 | }); |
39 | 43 | |
40 | 44 | const selectedKeys = ref<string[]>([]); | ... | ... |
... | ... | @@ -42,3 +42,8 @@ const register_BAI_DU_MAP_URL = (ak: string) => { |
42 | 42 | }; |
43 | 43 | |
44 | 44 | export const BAI_DU_MAP_URL = register_BAI_DU_MAP_URL('7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa'); |
45 | + | |
46 | +// 数字加上每三位加上逗号 | |
47 | +export function toThousands(num) { | |
48 | + return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,'); | |
49 | +} | ... | ... |
... | ... | @@ -23,24 +23,50 @@ |
23 | 23 | tooltip: { |
24 | 24 | trigger: 'axis', |
25 | 25 | axisPointer: { |
26 | - type: 'shadow', | |
26 | + lineStyle: { | |
27 | + width: 1, | |
28 | + color: '#019680', | |
29 | + }, | |
27 | 30 | }, |
28 | 31 | }, |
29 | 32 | xAxis: { |
30 | 33 | type: 'time', |
34 | + splitLine: { | |
35 | + show: true, | |
36 | + lineStyle: { | |
37 | + width: 1, | |
38 | + type: 'solid', | |
39 | + color: 'rgba(226,226,226,0.5)', | |
40 | + }, | |
41 | + }, | |
42 | + axisTick: { | |
43 | + show: false, | |
44 | + }, | |
45 | + }, | |
46 | + yAxis: { | |
47 | + splitArea: { | |
48 | + show: true, | |
49 | + areaStyle: { | |
50 | + color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'], | |
51 | + }, | |
52 | + }, | |
31 | 53 | }, |
32 | - yAxis: {}, | |
33 | 54 | grid: { |
34 | - left: '3%', | |
35 | - right: '4%', | |
36 | - bottom: '3%', | |
55 | + left: '1%', | |
56 | + right: '2%', | |
57 | + bottom: 0, | |
37 | 58 | containLabel: true, |
38 | 59 | }, |
39 | 60 | series: [ |
40 | 61 | { |
62 | + smooth: true, | |
41 | 63 | name: '当前趋势', |
42 | 64 | type: 'line', |
43 | 65 | data: newValue, |
66 | + areaStyle: {}, | |
67 | + itemStyle: { | |
68 | + color: '#5ab1ef', | |
69 | + }, | |
44 | 70 | }, |
45 | 71 | ], |
46 | 72 | }); |
... | ... | @@ -57,33 +83,57 @@ |
57 | 83 | interval: 86400000, |
58 | 84 | trend: 'CUSTOMER_TREND', |
59 | 85 | }); |
60 | - const transferResult: [number, string][] = []; | |
61 | - res.map((item) => { | |
62 | - transferResult.push([item.ts, item.value]); | |
63 | - }); | |
64 | - console.log(transferResult); | |
86 | + | |
87 | + const transferResult = res.map((item) => [item.ts, item.value]); | |
65 | 88 | setOptions({ |
66 | 89 | tooltip: { |
67 | 90 | trigger: 'axis', |
68 | 91 | axisPointer: { |
69 | - type: 'shadow', | |
92 | + lineStyle: { | |
93 | + width: 1, | |
94 | + color: '#019680', | |
95 | + }, | |
70 | 96 | }, |
71 | 97 | }, |
72 | 98 | xAxis: { |
73 | 99 | type: 'time', |
100 | + splitLine: { | |
101 | + show: true, | |
102 | + lineStyle: { | |
103 | + width: 1, | |
104 | + type: 'solid', | |
105 | + color: 'rgba(226,226,226,0.5)', | |
106 | + }, | |
107 | + }, | |
108 | + axisTick: { | |
109 | + show: false, | |
110 | + }, | |
111 | + }, | |
112 | + | |
113 | + yAxis: { | |
114 | + splitArea: { | |
115 | + show: true, | |
116 | + areaStyle: { | |
117 | + color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'], | |
118 | + }, | |
119 | + }, | |
74 | 120 | }, |
75 | - yAxis: {}, | |
76 | 121 | grid: { |
77 | - left: '3%', | |
78 | - right: '4%', | |
79 | - bottom: '3%', | |
122 | + left: '1%', | |
123 | + right: '2%', | |
124 | + bottom: 0, | |
80 | 125 | containLabel: true, |
81 | 126 | }, |
82 | 127 | series: [ |
83 | 128 | { |
129 | + smooth: true, | |
84 | 130 | name: '当前趋势', |
85 | 131 | type: 'line', |
86 | 132 | data: transferResult, |
133 | + areaStyle: {}, | |
134 | + itemStyle: { | |
135 | + color: '#5ab1ef', | |
136 | + }, | |
87 | 137 | }, |
88 | 138 | ], |
89 | 139 | }); | ... | ... |
1 | 1 | <template> |
2 | 2 | <div class="md:flex"> |
3 | - <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"> | |
3 | + <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4" style="color: #666"> | |
4 | 4 | <div class="flex" style="height: 100px"> |
5 | 5 | <div class="mr-4" |
6 | 6 | ><img src="/src/assets/images/device-count.png" style="width: 5.625rem; height: 5.625rem" |
7 | 7 | /></div> |
8 | 8 | <div class="flex-auto"> |
9 | 9 | <div class="flex justify-between" style="align-items: center"> |
10 | - <div style="font-size: 1.625rem; color: #333">{{ | |
11 | - growCardList?.deviceInfo?.sumCount | |
10 | + <div style="font-size: 1.625rem; color: #333; font-weight: bold">{{ | |
11 | + toThousands(growCardList?.deviceInfo?.sumCount) | |
12 | 12 | }}</div> |
13 | 13 | <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" /> |
14 | 14 | </div> |
... | ... | @@ -30,10 +30,10 @@ |
30 | 30 | </div> |
31 | 31 | </div> |
32 | 32 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
33 | - 今日新增 {{ growCardList?.deviceInfo?.todayAdd }}</div | |
33 | + 今日新增 {{ toThousands(growCardList?.deviceInfo?.todayAdd) }}</div | |
34 | 34 | > |
35 | 35 | </Card> |
36 | - <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"> | |
36 | + <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4" style="color: #666"> | |
37 | 37 | <div class="flex" style="height: 100px"> |
38 | 38 | <div class="mr-4"> |
39 | 39 | <img |
... | ... | @@ -45,25 +45,27 @@ |
45 | 45 | </div> |
46 | 46 | <div class="flex-auto"> |
47 | 47 | <div class="flex justify-between" style="align-items: center"> |
48 | - <div v-if="!isAdmin(role)" style="font-size: 1.625rem; color: #333">{{ | |
49 | - growCardList?.alarmInfo?.sumCount | |
50 | - }}</div> | |
51 | - <div style="font-size: 1.625rem; color: #333">{{ | |
52 | - growCardList?.tenantInfo?.sumCount | |
53 | - }}</div> | |
48 | + <div | |
49 | + v-if="!isAdmin(role)" | |
50 | + style="font-size: 1.625rem; color: #333; font-weight: bold" | |
51 | + >{{ toThousands(growCardList?.alarmInfo?.sumCount) }}</div | |
52 | + > | |
53 | + <div style="font-size: 1.625rem; color: #333; font-weight: bold" v-else> | |
54 | + {{ toThousands(growCardList?.tenantInfo?.sumCount) }} | |
55 | + </div> | |
54 | 56 | <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" /> |
55 | 57 | </div> |
56 | 58 | <div> {{ !isAdmin(role) ? `${currentMonth}月告警数(条)` : '租户总量(个)' }}</div> |
57 | 59 | </div> |
58 | 60 | </div> |
59 | 61 | <div v-if="!isAdmin(role)" class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
60 | - 今日新增 {{ growCardList?.alarmInfo?.todayAdd }}</div | |
62 | + 今日新增 {{ toThousands(growCardList?.alarmInfo?.todayAdd) }}</div | |
61 | 63 | > |
62 | 64 | <div v-else class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
63 | - 今日新增 {{ growCardList?.tenantInfo?.todayAdd }}</div | |
65 | + 今日新增 {{ toThousands(growCardList?.tenantInfo?.todayAdd) }}</div | |
64 | 66 | > |
65 | 67 | </Card> |
66 | - <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4"> | |
68 | + <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4" style="color: #666"> | |
67 | 69 | <div class="flex" style="height: 100px"> |
68 | 70 | <div class="mr-4" |
69 | 71 | ><img |
... | ... | @@ -74,24 +76,24 @@ |
74 | 76 | </div> |
75 | 77 | <div v-if="!isAdmin(role)" style="display: flex; align-items: center"> |
76 | 78 | <div> |
77 | - <div class="flex" style="align-items: center"> | |
78 | - {{ `${currentMonth}月数据点(条)` }} | |
79 | - <span style="font-size: 1.625rem; color: #333"> | |
80 | - {{ growCardList?.messageInfo?.dataPointsCount }}</span | |
79 | + <div style="align-items: center"> | |
80 | + <div style="font-size: 1.625rem; color: #333; font-weight: bold"> | |
81 | + {{ toThousands(growCardList?.messageInfo?.messageCount) }}</div | |
81 | 82 | > |
82 | - </div> | |
83 | - <div class="flex" style="align-items: center"> | |
84 | 83 | {{ `${currentMonth}月消息量(条)` }} |
85 | - <span style="font-size: 1.625rem; color: #333"> | |
86 | - {{ growCardList?.messageInfo?.messageCount }}</span | |
84 | + </div> | |
85 | + <div> | |
86 | + <span class="mr-2">{{ `${currentMonth}月数据点` }}</span> | |
87 | + <span style="color: #333; font-weight: bold"> | |
88 | + {{ toThousands(growCardList?.messageInfo?.dataPointsCount) }}</span | |
87 | 89 | > |
88 | 90 | </div> |
89 | 91 | </div> |
90 | 92 | </div> |
91 | 93 | <div class="flex-auto" v-else> |
92 | 94 | <div class="flex justify-between" style="align-items: center"> |
93 | - <div style="font-size: 1.625rem; color: #333">{{ | |
94 | - growCardList?.customerInfo?.sumCount | |
95 | + <div style="font-size: 1.625rem; color: #333; font-weight: bold">{{ | |
96 | + toThousands(growCardList?.customerInfo?.sumCount) | |
95 | 97 | }}</div> |
96 | 98 | <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" /> |
97 | 99 | </div> |
... | ... | @@ -100,11 +102,15 @@ |
100 | 102 | </div> |
101 | 103 | <div v-if="!isAdmin(role)" class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
102 | 104 | 今日新增 |
103 | - <span class="ml-8">数据点 ({{ growCardList?.messageInfo?.todayDataPointsAdd }})</span> | |
104 | - <span class="ml-8">消息量 ({{ growCardList?.messageInfo?.todayMessageAdd }})</span> | |
105 | + <span class="ml-4" | |
106 | + >消息量 {{ toThousands(growCardList?.messageInfo?.todayMessageAdd) }}</span | |
107 | + > | |
108 | + <span class="ml-4" | |
109 | + >数据点 {{ toThousands(growCardList?.messageInfo?.todayDataPointsAdd) }}</span | |
110 | + > | |
105 | 111 | </div> |
106 | 112 | <div v-else class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
107 | - 今日新增 {{ growCardList?.customerInfo?.todayAdd }}</div | |
113 | + 今日新增 {{ toThousands(growCardList?.customerInfo?.todayAdd) }}</div | |
108 | 114 | > |
109 | 115 | </Card> |
110 | 116 | </div> |
... | ... | @@ -114,11 +120,13 @@ |
114 | 120 | import { Card } from 'ant-design-vue'; |
115 | 121 | import { getHomeData } from '/@/api/dashboard'; |
116 | 122 | import { isAdmin } from '/@/enums/roleEnum'; |
123 | + import { toThousands } from '/@/utils/fnUtils'; | |
117 | 124 | defineProps<{ |
118 | 125 | role: string; |
119 | 126 | }>(); |
120 | 127 | defineExpose({ |
121 | 128 | isAdmin, |
129 | + toThousands, | |
122 | 130 | }); |
123 | 131 | interface CardList { |
124 | 132 | deviceInfo: { | ... | ... |
... | ... | @@ -18,7 +18,7 @@ |
18 | 18 | <ListItem> |
19 | 19 | <ListItemMeta> |
20 | 20 | <template #avatar> |
21 | - <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" /> | |
21 | + <Avatar :src="item.user.avatar" size="large" /> | |
22 | 22 | </template> |
23 | 23 | <template #description> |
24 | 24 | <span |
... | ... | @@ -38,13 +38,7 @@ |
38 | 38 | </template> |
39 | 39 | </List> |
40 | 40 | </Card> |
41 | - <Card | |
42 | - hoverable | |
43 | - title="联系我们" | |
44 | - :bordered="false" | |
45 | - v-bind="$attrs" | |
46 | - :headStyle="{ padding: 0 }" | |
47 | - > | |
41 | + <Card title="联系我们" :bordered="false" v-bind="$attrs" :headStyle="{ padding: 0 }"> | |
48 | 42 | <template #cover> |
49 | 43 | <img :src="getQrCode" alt="" style="width: 150px; height: 150px; margin: 50px auto" /> |
50 | 44 | </template> |
... | ... | @@ -59,8 +53,12 @@ |
59 | 53 | </div> |
60 | 54 | |
61 | 55 | <Card v-else :bordered="false" :bodyStyle="{ padding: 0 }" v-bind="$attrs"> |
62 | - <Descriptions title="租户消息量TOP10" :column="1"> | |
63 | - <template v-for="index in 10" :key="index"> | |
56 | + <h1 style="color: rgba(0, 0, 0, 0.85); font-weight: bold; font-size: 16px"> | |
57 | + 租户消息量TOP10</h1 | |
58 | + > | |
59 | + <Empty v-if="!tenantTop10.length" /> | |
60 | + <Descriptions :column="1"> | |
61 | + <template v-for="(item, index) in tenantTop10" :key="item.name"> | |
64 | 62 | <DescriptionsItem> |
65 | 63 | <span |
66 | 64 | class="mr-2" |
... | ... | @@ -84,7 +82,7 @@ |
84 | 82 | ? '#e78739' |
85 | 83 | : '#4e84f5', |
86 | 84 | backgroundColor: |
87 | - index === 0 ? '#fed36a' : index === 1 ? '#CBCAC9' : index === 2 ? '#F1B889' : '', | |
85 | + index === 0 ? '#FAD672' : index === 1 ? '#CBCAC9' : index === 2 ? '#F1B889' : '', | |
88 | 86 | borderColor: |
89 | 87 | index === 0 |
90 | 88 | ? '#fdee7d' |
... | ... | @@ -94,12 +92,22 @@ |
94 | 92 | ? '#f8c296' |
95 | 93 | : '#0b55f1;', |
96 | 94 | }" |
97 | - >{{ index }}</span | |
98 | - >兰州天兆猪业</DescriptionsItem | |
99 | - > | |
95 | + >{{ index + 1 }}</span | |
96 | + > | |
97 | + <div class="flex justify-between" style="width: 100%"> | |
98 | + <span> | |
99 | + {{ item.name }} | |
100 | + </span> | |
101 | + <span :style="{ color: index === 0 ? '#EA5B42' : index === 2 ? '#E4751A' : '#666' }"> | |
102 | + {{ item.count }} | |
103 | + </span> | |
104 | + </div> | |
105 | + </DescriptionsItem> | |
100 | 106 | </template> |
101 | 107 | </Descriptions> |
102 | - <Descriptions title="本月即将过期租户" class="mt-6" /> | |
108 | + <h1 style="color: rgba(0, 0, 0, 0.85); font-weight: bold; font-size: 16px"> | |
109 | + 本月即将过期租户</h1 | |
110 | + > | |
103 | 111 | <BasicTable @register="registerTable" /> |
104 | 112 | </Card> |
105 | 113 | </div> |
... | ... | @@ -107,7 +115,7 @@ |
107 | 115 | |
108 | 116 | <script lang="ts"> |
109 | 117 | import { defineComponent, ref, computed, onMounted } from 'vue'; |
110 | - import { Card, Anchor, List, Avatar, Descriptions } from 'ant-design-vue'; | |
118 | + import { Card, Anchor, List, Avatar, Descriptions, Empty } from 'ant-design-vue'; | |
111 | 119 | import { useUserStore } from '/@/store/modules/user'; |
112 | 120 | import { getEnterPriseDetail } from '/@/api/oem'; |
113 | 121 | import { notifyMyGetrPageApi } from '/@/api/stationnotification/stationnotifyApi'; |
... | ... | @@ -115,10 +123,11 @@ |
115 | 123 | import { useGo } from '/@/hooks/web/usePage'; |
116 | 124 | import { BasicTable, useTable } from '/@/components/Table'; |
117 | 125 | import { isAdmin } from '/@/enums/roleEnum'; |
118 | - import { getTenantExpireTimeList } from '/@/api/dashboard'; | |
126 | + import { getTenantExpireTimeList, getTenantTop10 } from '/@/api/dashboard'; | |
119 | 127 | export default defineComponent({ |
120 | 128 | components: { |
121 | 129 | Card, |
130 | + Empty, | |
122 | 131 | CardMeta: Card.Meta, |
123 | 132 | AnchorLink: Anchor.Link, |
124 | 133 | List, |
... | ... | @@ -185,9 +194,14 @@ |
185 | 194 | width: 120, |
186 | 195 | }, |
187 | 196 | ], |
188 | - fetchSetting: { | |
189 | - listField: 'expireTenant.items', | |
190 | - totalField: 'expireTenant.total', | |
197 | + canResize: false, | |
198 | + maxHeight: 500, | |
199 | + resizeHeightOffset: 200, | |
200 | + pagination: { | |
201 | + showSizeChanger: false, | |
202 | + showQuickJumper: false, | |
203 | + | |
204 | + showTotal: () => ({ total: false }), | |
191 | 205 | }, |
192 | 206 | }); |
193 | 207 | |
... | ... | @@ -204,8 +218,12 @@ |
204 | 218 | const getQrCode = computed(() => { |
205 | 219 | return userStore.enterPriseInfo?.qrCode; |
206 | 220 | }); |
221 | + const tenantTop10 = ref<{ name: string; count: number }[]>([]); | |
207 | 222 | onMounted(async () => { |
208 | - if (isAdmin(props.role)) return; | |
223 | + if (isAdmin(props.role)) { | |
224 | + tenantTop10.value = await getTenantTop10(); | |
225 | + return; | |
226 | + } | |
209 | 227 | const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 }); |
210 | 228 | const res = await getEnterPriseDetail(); |
211 | 229 | dataSource.value = notice.items; |
... | ... | @@ -221,6 +239,7 @@ |
221 | 239 | getAddress, |
222 | 240 | getTel, |
223 | 241 | dataSource, |
242 | + tenantTop10, | |
224 | 243 | go, |
225 | 244 | registerTable, |
226 | 245 | isAdmin, |
... | ... | @@ -234,4 +253,7 @@ |
234 | 253 | .noticeTitle:hover { |
235 | 254 | border-bottom: 1px solid #ccc; |
236 | 255 | } |
256 | + :deep().ant-anchor-link-active > .ant-anchor-link-title { | |
257 | + color: #666; | |
258 | + } | |
237 | 259 | </style> | ... | ... |
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 | </template> |
48 | 48 | <TenantTrend :tenantTrendList="tenantTrendList" /> |
49 | 49 | </Card> |
50 | - <Card v-bind="$attrs" title="客户趋势"> | |
50 | + <Card v-bind="$attrs" title="客户趋势" style="height: 500px"> | |
51 | 51 | <template #extra> |
52 | 52 | <div class="extra-date"> |
53 | 53 | <template v-for="(item, index) in TenantOrCustomerDateList" :key="item.value"> |
... | ... | @@ -191,7 +191,6 @@ |
191 | 191 | }, |
192 | 192 | onMessage(_, e) { |
193 | 193 | const { data, update } = JSON.parse(e.data); |
194 | - console.log('来新消息了', data, update); | |
195 | 194 | if (activeKey.value === '1') { |
196 | 195 | if (data) { |
197 | 196 | const { createdAlarmsCountHourly } = data.data[0].latest.TIME_SERIES; |
... | ... | @@ -375,8 +374,6 @@ |
375 | 374 | ], |
376 | 375 | }); |
377 | 376 | send(sendValue); |
378 | - | |
379 | - console.log(JSON.parse(sendValue), '----interval', state.alarmList); | |
380 | 377 | } |
381 | 378 | |
382 | 379 | const { | ... | ... |
... | ... | @@ -25,24 +25,51 @@ |
25 | 25 | tooltip: { |
26 | 26 | trigger: 'axis', |
27 | 27 | axisPointer: { |
28 | - type: 'shadow', | |
28 | + lineStyle: { | |
29 | + width: 1, | |
30 | + color: '#019680', | |
31 | + }, | |
29 | 32 | }, |
30 | 33 | }, |
31 | 34 | xAxis: { |
32 | 35 | type: 'time', |
36 | + splitLine: { | |
37 | + show: true, | |
38 | + lineStyle: { | |
39 | + width: 1, | |
40 | + type: 'solid', | |
41 | + color: 'rgba(226,226,226,0.5)', | |
42 | + }, | |
43 | + }, | |
44 | + axisTick: { | |
45 | + show: false, | |
46 | + }, | |
47 | + }, | |
48 | + | |
49 | + yAxis: { | |
50 | + splitArea: { | |
51 | + show: true, | |
52 | + areaStyle: { | |
53 | + color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'], | |
54 | + }, | |
55 | + }, | |
33 | 56 | }, |
34 | - yAxis: {}, | |
35 | 57 | grid: { |
36 | - left: '3%', | |
37 | - right: '4%', | |
38 | - bottom: '3%', | |
58 | + left: '1%', | |
59 | + right: '2%', | |
60 | + bottom: 0, | |
39 | 61 | containLabel: true, |
40 | 62 | }, |
41 | 63 | series: [ |
42 | 64 | { |
65 | + smooth: true, | |
43 | 66 | name: '当前趋势', |
44 | 67 | type: 'line', |
45 | 68 | data: newValue, |
69 | + areaStyle: {}, | |
70 | + itemStyle: { | |
71 | + color: '#5ab1ef', | |
72 | + }, | |
46 | 73 | }, |
47 | 74 | ], |
48 | 75 | }); |
... | ... | @@ -59,31 +86,56 @@ |
59 | 86 | interval: 86400000, |
60 | 87 | trend: 'TENANT_TREND', |
61 | 88 | }); |
62 | - const transferResult = res.map((item) => { | |
63 | - return [item.ts, item.value]; | |
64 | - }); | |
89 | + const transferResult = res.map((item) => [item.ts, item.value]); | |
65 | 90 | setOptions({ |
66 | 91 | tooltip: { |
67 | 92 | trigger: 'axis', |
68 | 93 | axisPointer: { |
69 | - type: 'shadow', | |
94 | + lineStyle: { | |
95 | + width: 1, | |
96 | + color: '#019680', | |
97 | + }, | |
70 | 98 | }, |
71 | 99 | }, |
72 | 100 | xAxis: { |
73 | 101 | type: 'time', |
102 | + splitLine: { | |
103 | + show: true, | |
104 | + lineStyle: { | |
105 | + width: 1, | |
106 | + type: 'solid', | |
107 | + color: 'rgba(226,226,226,0.5)', | |
108 | + }, | |
109 | + }, | |
110 | + axisTick: { | |
111 | + show: false, | |
112 | + }, | |
113 | + }, | |
114 | + | |
115 | + yAxis: { | |
116 | + splitArea: { | |
117 | + show: true, | |
118 | + areaStyle: { | |
119 | + color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'], | |
120 | + }, | |
121 | + }, | |
74 | 122 | }, |
75 | - yAxis: {}, | |
76 | 123 | grid: { |
77 | - left: '3%', | |
78 | - right: '4%', | |
79 | - bottom: '3%', | |
124 | + left: '1%', | |
125 | + right: '2%', | |
126 | + bottom: 0, | |
80 | 127 | containLabel: true, |
81 | 128 | }, |
82 | 129 | series: [ |
83 | 130 | { |
131 | + smooth: true, | |
84 | 132 | name: '当前趋势', |
85 | 133 | type: 'line', |
86 | 134 | data: transferResult, |
135 | + areaStyle: {}, | |
136 | + itemStyle: { | |
137 | + color: '#5ab1ef', | |
138 | + }, | |
87 | 139 | }, |
88 | 140 | ], |
89 | 141 | }); | ... | ... |
1 | +import { formatToDateTime } from '/@/utils/dateUtil'; | |
1 | 2 | import { ref } from 'vue'; |
2 | 3 | import { getTrendData } from '/@/api/dashboard'; |
4 | + | |
3 | 5 | export function useDate() { |
4 | 6 | const tenantDateValue = ref([]); |
5 | 7 | const customerDateValue = ref([]); |
... | ... | @@ -44,15 +46,54 @@ export function useDate() { |
44 | 46 | customerTrendList.value = res.map((item) => [item.ts, item.value]); |
45 | 47 | } |
46 | 48 | } |
49 | + | |
50 | + // 获取选中的时间范围内的数据 | |
51 | + async function getDateData(startTs, endTs, trend: 'CUSTOMER_TREND' | 'TENANT_TREND', list) { | |
52 | + // 计算时间间隔 | |
53 | + function computedInterval(startTs: number, endTs: number) { | |
54 | + /** | |
55 | + * 选择的时间间隔 | |
56 | + * <=1 2h | |
57 | + * <=30 1day | |
58 | + * >30<90 2day | |
59 | + * >90 1month | |
60 | + */ | |
61 | + let interval = 86400000; | |
62 | + if (endTs - startTs <= 86400000) { | |
63 | + interval = 7200000; | |
64 | + } else if (endTs - startTs <= 2592000000) { | |
65 | + interval = 86400000; | |
66 | + } else if (endTs - startTs > 2592000000 && endTs - startTs < 7776000000) { | |
67 | + interval = 172800000; | |
68 | + } else if (endTs - startTs > 7776000000) { | |
69 | + interval = 2592000000; | |
70 | + } | |
71 | + return interval; | |
72 | + } | |
73 | + startTs = parseInt(formatToDateTime(startTs, 'x')) - 86400000; | |
74 | + endTs = parseInt(formatToDateTime(endTs, 'x')); | |
75 | + const res = await getTrendData({ | |
76 | + startTs, | |
77 | + endTs, | |
78 | + interval: computedInterval(startTs, endTs), | |
79 | + trend, | |
80 | + }); | |
81 | + list.value = res.map((item) => [item.ts, item.value]); | |
82 | + } | |
83 | + | |
47 | 84 | // 租户选择日期 |
48 | 85 | function onDateTenantChange(_, dateString) { |
86 | + if (!_.length) return; | |
87 | + const [startTs, endTs] = dateString; | |
49 | 88 | activeTenantIndex.value = -1; |
50 | - console.log(dateString); | |
89 | + getDateData(startTs, endTs, 'TENANT_TREND', tenantTrendList); | |
51 | 90 | } |
52 | 91 | // 客户趋势选择日期 |
53 | 92 | function onDateCustomerChange(_, dateString) { |
93 | + if (!_.length) return; | |
94 | + const [startTs, endTs] = dateString; | |
54 | 95 | activeCustomerIndex.value = -1; |
55 | - console.log(dateString); | |
96 | + getDateData(startTs, endTs, 'CUSTOMER_TREND', customerTrendList); | |
56 | 97 | } |
57 | 98 | return { |
58 | 99 | tenantDateValue, | ... | ... |
1 | 1 | <template> |
2 | - <div class="p-4 md:flex"> | |
2 | + <div class="p-4 md:flex" ref="homeRef"> | |
3 | 3 | <div class="md:w-7/10 w-full !mr-4 enter-y"> |
4 | 4 | <GrowCard :loading="loading" class="enter-y" :role="role" /> |
5 | 5 | <SiteAnalysis class="!my-4 enter-y" :loading="loading" :role="role" /> |
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | </div> |
12 | 12 | <div class="md:w-3/10 w-full enter-y"> |
13 | 13 | <Card |
14 | - :style="{ width: '100%', height: !isAdmin(role) ? '100%' : '98.5%' }" | |
14 | + :style="{ width: '100%', height: !isAdmin(role) ? '100%' : '98.4%' }" | |
15 | 15 | :title="!isAdmin(role) ? '帮助文档' : ''" |
16 | 16 | > |
17 | 17 | <HelpDoc :role="role" /> |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | </div> |
21 | 21 | </template> |
22 | 22 | <script lang="ts" setup> |
23 | - import { ref } from 'vue'; | |
23 | + import { ref, onMounted } from 'vue'; | |
24 | 24 | import GrowCard from './components/GrowCard.vue'; |
25 | 25 | import SiteAnalysis from './components/SiteAnalysis.vue'; |
26 | 26 | import { Card } from 'ant-design-vue'; |
... | ... | @@ -35,7 +35,10 @@ |
35 | 35 | const userInfo: any = getAuthCache(USER_INFO_KEY); |
36 | 36 | const role: string = userInfo?.roles[0]; |
37 | 37 | const loading = ref(true); |
38 | - | |
38 | + const homeRef = ref<HTMLDivElement>(); | |
39 | + onMounted(() => { | |
40 | + console.log(homeRef.value); | |
41 | + }); | |
39 | 42 | setTimeout(() => { |
40 | 43 | loading.value = false; |
41 | 44 | }, 1500); | ... | ... |
... | ... | @@ -51,10 +51,11 @@ export const columns: BasicColumn[] = [ |
51 | 51 | export const searchFormSchema: FormSchema[] = [ |
52 | 52 | { |
53 | 53 | field: 'type', |
54 | - label: '', | |
55 | - colProps: { span: 8 }, | |
54 | + label: '通知类型', | |
55 | + colProps: { span: 6 }, | |
56 | 56 | component: 'Select', |
57 | 57 | componentProps: { |
58 | + placeholder: '请选择类型', | |
58 | 59 | options: [ |
59 | 60 | { |
60 | 61 | label: '公告', | ... | ... |
1 | 1 | import { h } from 'vue'; |
2 | 2 | import { BasicColumn, FormSchema } from '/@/components/Table'; |
3 | 3 | import { Tinymce } from '/@/components/Tinymce/index'; |
4 | -// import { findDictItemByCode } from '/@/api/system/dict'; | |
5 | 4 | import { getOrganizationList } from '/@/api/system/system'; |
6 | 5 | import { copyTransFun } from '/@/utils/fnUtils'; |
7 | 6 | import { Tag } from 'ant-design-vue'; |
... | ... | @@ -158,8 +157,8 @@ export const formSchema: FormSchema[] = [ |
158 | 157 | export const searchFormSchema: FormSchema[] = [ |
159 | 158 | { |
160 | 159 | field: 'type', |
161 | - label: '', | |
162 | - colProps: { span: 4 }, | |
160 | + label: '通知类型', | |
161 | + colProps: { span: 6 }, | |
163 | 162 | component: 'Select', |
164 | 163 | componentProps: { |
165 | 164 | placeholder: '请选择类型', | ... | ... |