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