Commit 4fcb1b994d20151c90c97e75e61fc1dea7f962be

Authored by sqy
1 parent 8211eb25

'修改前端的一些样式,以及美化界面,首页系统管理员图表接口联调'

@@ -8,10 +8,10 @@ VITE_PUBLIC_PATH = / @@ -8,10 +8,10 @@ VITE_PUBLIC_PATH = /
8 # Please note that no line breaks 8 # Please note that no line breaks
9 9
10 # 本地 10 # 本地
11 -# VITE_PROXY = [["/api","http://localhost:8080/api"]] 11 +VITE_PROXY = [["/api","http://192.168.10.107:8080/api"]]
12 12
13 # 线上 13 # 线上
14 -VITE_PROXY = [["/api","http://101.133.234.90:8080/api"]] 14 +# VITE_PROXY = [["/api","http://101.133.234.90:8080/api"]]
15 15
16 # 实时数据的ws地址 16 # 实时数据的ws地址
17 VITE_WEB_SOCKET = ws://101.133.234.90:8080/api/ws/plugins/telemetry?token= 17 VITE_WEB_SOCKET = ws://101.133.234.90:8080/api/ws/plugins/telemetry?token=
@@ -4,6 +4,7 @@ enum HomeEnum { @@ -4,6 +4,7 @@ enum HomeEnum {
4 home = '/homepage/left/top', 4 home = '/homepage/left/top',
5 TenantExpireTimeList = '/homepage/right', 5 TenantExpireTimeList = '/homepage/right',
6 EntitiesQueryFind = '/entitiesQuery/find', 6 EntitiesQueryFind = '/entitiesQuery/find',
  7 + TrendAPI = '/homepage/left/bottom',
7 } 8 }
8 9
9 export const getHomeData = () => { 10 export const getHomeData = () => {
@@ -62,3 +63,17 @@ export const getEntitiesId = () => { @@ -62,3 +63,17 @@ export const getEntitiesId = () => {
62 } 63 }
63 ); 64 );
64 }; 65 };
  66 +
  67 +interface TrendParamsType {
  68 + startTs: number;
  69 + endTs: number;
  70 + interval: number;
  71 + trend: 'CUSTOMER_TREND' | 'TENANT_TREND';
  72 +}
  73 +// 获取租户趋势或者客户趋势数据
  74 +export const getTrendData = (params: TrendParamsType) => {
  75 + return defHttp.get({
  76 + url: HomeEnum.TrendAPI,
  77 + params,
  78 + });
  79 +};

417 KB | W: | H:

145 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
@@ -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"> 14 + <span class="cursor-pointer flex items-center" style="color: #fff">
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>
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 class="ml-2 md:opacity-100" 11 class="ml-2 md:opacity-100"
12 :class="getTitleClass" 12 :class="getTitleClass"
13 v-show="showTitle" 13 v-show="showTitle"
14 - style="white-space: nowrap; font-size: small" 14 + style="white-space: nowrap; font-size: small; color: #f3f4fb"
15 > 15 >
16 {{ getTitle }} 16 {{ getTitle }}
17 </span> 17 </span>
@@ -24,16 +24,20 @@ function itemRender({ page, type, originalElement }: ItemRender) { @@ -24,16 +24,20 @@ function itemRender({ page, type, originalElement }: ItemRender) {
24 export function usePagination(refProps: ComputedRef<BasicTableProps>) { 24 export function usePagination(refProps: ComputedRef<BasicTableProps>) {
25 const { t } = useI18n(); 25 const { t } = useI18n();
26 26
27 - const configRef = ref<PaginationProps>({}); 27 + const configRef = ref<PaginationProps>({
  28 + hideOnSinglePage:true
  29 + });
28 const show = ref(true); 30 const show = ref(true);
29 31
30 watchEffect(() => { 32 watchEffect(() => {
31 const { pagination } = unref(refProps); 33 const { pagination } = unref(refProps);
  34 +
32 if (!isBoolean(pagination) && pagination) { 35 if (!isBoolean(pagination) && pagination) {
33 configRef.value = { 36 configRef.value = {
34 ...unref(configRef), 37 ...unref(configRef),
35 ...(pagination ?? {}), 38 ...(pagination ?? {}),
36 - }; 39 + };
  40 +
37 } 41 }
38 }); 42 });
39 43
1 <template> 1 <template>
2 - 123  
3 <div ref="chartRef" :style="{ height, width }"></div> 2 <div ref="chartRef" :style="{ height, width }"></div>
4 </template> 3 </template>
5 <script lang="ts" setup> 4 <script lang="ts" setup>
6 - import { ref, Ref, withDefaults } from 'vue'; 5 + import { ref, Ref, withDefaults, onMounted, watch } from 'vue';
7 import { useECharts } from '/@/hooks/web/useECharts'; 6 import { useECharts } from '/@/hooks/web/useECharts';
  7 + import { getTrendData } from '/@/api/dashboard';
8 8
9 interface Props { 9 interface Props {
10 width?: string; 10 width?: string;
11 height?: string; 11 height?: string;
  12 + customerTrendList?: Array<[number, string]>;
12 } 13 }
13 - withDefaults(defineProps<Props>(), { 14 + const props = withDefaults(defineProps<Props>(), {
14 width: '100%', 15 width: '100%',
15 height: '280px', 16 height: '280px',
  17 + customerTrendList: () => [],
16 }); 18 });
  19 + watch(
  20 + () => props.customerTrendList,
  21 + (newValue) => {
  22 + setOptions({
  23 + tooltip: {
  24 + trigger: 'axis',
  25 + axisPointer: {
  26 + type: 'shadow',
  27 + },
  28 + },
  29 + xAxis: {
  30 + type: 'time',
  31 + },
  32 + yAxis: {},
  33 + grid: {
  34 + left: '3%',
  35 + right: '4%',
  36 + bottom: '3%',
  37 + containLabel: true,
  38 + },
  39 + series: [
  40 + {
  41 + name: '当前趋势',
  42 + type: 'line',
  43 + data: newValue,
  44 + },
  45 + ],
  46 + });
  47 + }
  48 + );
17 49
18 const chartRef = ref<HTMLDivElement | null>(null); 50 const chartRef = ref<HTMLDivElement | null>(null);
19 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); 51 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
  52 + onMounted(async () => {
  53 + const endTs = Date.now();
  54 + const res = await getTrendData({
  55 + startTs: endTs - 2592000000,
  56 + endTs,
  57 + interval: 86400000,
  58 + trend: 'CUSTOMER_TREND',
  59 + });
  60 + const transferResult: [number, string][] = [];
  61 + res.map((item) => {
  62 + transferResult.push([item.ts, item.value]);
  63 + });
  64 + console.log(transferResult);
  65 + setOptions({
  66 + tooltip: {
  67 + trigger: 'axis',
  68 + axisPointer: {
  69 + type: 'shadow',
  70 + },
  71 + },
  72 + xAxis: {
  73 + type: 'time',
  74 + },
  75 + yAxis: {},
  76 + grid: {
  77 + left: '3%',
  78 + right: '4%',
  79 + bottom: '3%',
  80 + containLabel: true,
  81 + },
  82 + series: [
  83 + {
  84 + name: '当前趋势',
  85 + type: 'line',
  86 + data: transferResult,
  87 + },
  88 + ],
  89 + });
  90 + });
20 </script> 91 </script>
@@ -3,26 +3,26 @@ @@ -3,26 +3,26 @@
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">
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: 5rem; height: 5rem" 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">{{ 10 <div style="font-size: 1.625rem; color: #333">{{
11 growCardList?.deviceInfo?.sumCount 11 growCardList?.deviceInfo?.sumCount
12 }}</div> 12 }}</div>
13 - <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> 13 + <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
14 </div> 14 </div>
15 <div> 设备数(个) </div> 15 <div> 设备数(个) </div>
16 - <div class="flex mt-2">  
17 - <div class="flex mr-1" style="align-items: center; font-size: 0.75rem" 16 + <div class="flex mt-2" style="font-size: 0.75rem">
  17 + <div class="flex mr-1" style="align-items: center"
18 ><img src="/src/assets/images/online.png" class="mr-1" /> 18 ><img src="/src/assets/images/online.png" class="mr-1" />
19 <span>在线{{ growCardList?.deviceInfo?.onLine }}</span> 19 <span>在线{{ growCardList?.deviceInfo?.onLine }}</span>
20 </div> 20 </div>
21 - <div class="flex mr-1" style="align-items: center; font-size: 0.75rem"> 21 + <div class="flex mr-1" style="align-items: center">
22 <img src="/src/assets/images/offline.png" class="mr-1" /> 22 <img src="/src/assets/images/offline.png" class="mr-1" />
23 <span> 离线{{ growCardList?.deviceInfo?.offLine }} </span> 23 <span> 离线{{ growCardList?.deviceInfo?.offLine }} </span>
24 </div> 24 </div>
25 - <div class="flex mr-1" style="align-items: center; font-size: 0.75rem"> 25 + <div class="flex mr-1" style="align-items: center">
26 <img src="/src/assets/images/inactive.png" class="mr-1" /> 26 <img src="/src/assets/images/inactive.png" class="mr-1" />
27 <span> 未激活{{ growCardList?.deviceInfo?.inActive }} </span> 27 <span> 未激活{{ growCardList?.deviceInfo?.inActive }} </span>
28 </div> 28 </div>
@@ -39,9 +39,9 @@ @@ -39,9 +39,9 @@
39 <img 39 <img
40 v-if="!isAdmin(role)" 40 v-if="!isAdmin(role)"
41 src="/src/assets/images/alarm-count.png" 41 src="/src/assets/images/alarm-count.png"
42 - style="width: 5rem; height: 5rem" 42 + style="width: 5.625rem; height: 5.625rem"
43 /> 43 />
44 - <img v-else src="/src/assets/images/zh.png" style="width: 5rem; height: 5rem" /> 44 + <img v-else src="/src/assets/images/zh.png" style="width: 5.625rem; height: 5.625rem" />
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">
@@ -51,7 +51,7 @@ @@ -51,7 +51,7 @@
51 <div style="font-size: 1.625rem; color: #333">{{ 51 <div style="font-size: 1.625rem; color: #333">{{
52 growCardList?.tenantInfo?.sumCount 52 growCardList?.tenantInfo?.sumCount
53 }}</div> 53 }}</div>
54 - <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> 54 + <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
55 </div> 55 </div>
56 <div> {{ !isAdmin(role) ? `${currentMonth}月告警数(条)` : '租户总量(个)' }}</div> 56 <div> {{ !isAdmin(role) ? `${currentMonth}月告警数(条)` : '租户总量(个)' }}</div>
57 </div> 57 </div>
@@ -69,8 +69,8 @@ @@ -69,8 +69,8 @@
69 ><img 69 ><img
70 v-if="!isAdmin(role)" 70 v-if="!isAdmin(role)"
71 src="/src/assets/images/msg-count.png" 71 src="/src/assets/images/msg-count.png"
72 - style="width: 5rem; height: 5rem"  
73 - /><img v-else src="/src/assets/images/kf.png" style="width: 5rem; height: 5rem" /> 72 + style="width: 5.625rem; height: 5.625rem"
  73 + /><img v-else src="/src/assets/images/kf.png" style="width: 5.625rem; height: 5.625rem" />
74 </div> 74 </div>
75 <div v-if="!isAdmin(role)" style="display: flex; align-items: center"> 75 <div v-if="!isAdmin(role)" style="display: flex; align-items: center">
76 <div> 76 <div>
@@ -93,7 +93,7 @@ @@ -93,7 +93,7 @@
93 <div style="font-size: 1.625rem; color: #333">{{ 93 <div style="font-size: 1.625rem; color: #333">{{
94 growCardList?.customerInfo?.sumCount 94 growCardList?.customerInfo?.sumCount
95 }}</div> 95 }}</div>
96 - <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> 96 + <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
97 </div> 97 </div>
98 <div>客户总量(个)</div> 98 <div>客户总量(个)</div>
99 </div> 99 </div>
1 <template> 1 <template>
2 <div> 2 <div>
3 - <Card title="帮助文档" v-if="!isAdmin(role)"> 3 + <div v-if="!isAdmin(role)">
4 <div> 4 <div>
5 <template v-for="item in helpDoc" :key="item.title"> 5 <template v-for="item in helpDoc" :key="item.title">
6 <AnchorLink v-bind="item" /> 6 <AnchorLink v-bind="item" />
7 </template> 7 </template>
8 </div> 8 </div>
9 <Card 9 <Card
10 - v-if="!isAdmin(role)"  
11 :tab-list="tabListTitle" 10 :tab-list="tabListTitle"
12 v-bind="$attrs" 11 v-bind="$attrs"
13 - :active-tab-key="activeKey"  
14 :bordered="false" 12 :bordered="false"
15 - @tabChange="onTabChange"  
16 :bodyStyle="{ padding: 0 }" 13 :bodyStyle="{ padding: 0 }"
  14 + :headStyle="{ padding: 0 }"
17 > 15 >
18 - <div v-if="activeKey === 'tab1'">  
19 - <List item-layout="horizontal" :dataSource="dataSource">  
20 - <template #renderItem="{ item }">  
21 - <ListItem>  
22 - <ListItemMeta>  
23 - <template #avatar>  
24 - <Avatar  
25 - src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"  
26 - />  
27 - </template>  
28 - <template #description>  
29 - <span  
30 - class="cursor-pointer noticeTitle"  
31 - @click="go('/stationnotification/mynotification')"  
32 - >{{ item.sysNotice.title }}  
33 - </span>  
34 - </template>  
35 - <template #title>  
36 - <span>{{ item.user.realName }}</span>  
37 - </template>  
38 - </ListItemMeta>  
39 - <template #extra>  
40 - <Time :value="item.sysNotice.senderDate" /> 16 + <List item-layout="horizontal" :dataSource="dataSource">
  17 + <template #renderItem="{ item }">
  18 + <ListItem>
  19 + <ListItemMeta>
  20 + <template #avatar>
  21 + <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
41 </template> 22 </template>
42 - </ListItem>  
43 - </template>  
44 - </List>  
45 - <Card hoverable title="联系我们" :bordered="false">  
46 - <template #cover>  
47 - <img :src="getQrCode" alt="" style="width: 150px; height: 150px; margin: 50px auto" />  
48 - </template>  
49 - <CardMeta>  
50 - <template #description>  
51 - <p>联系人: {{ getContacts }}</p>  
52 - <p>联系电话: {{ getTel }}</p>  
53 - <p>联系地址: {{ getAddress }} </p> 23 + <template #description>
  24 + <span
  25 + class="cursor-pointer noticeTitle"
  26 + @click="go('/stationnotification/mynotification')"
  27 + >{{ item.sysNotice.title }}
  28 + </span>
  29 + </template>
  30 + <template #title>
  31 + <span>{{ item.user.realName }}</span>
  32 + </template>
  33 + </ListItemMeta>
  34 + <template #extra>
  35 + <Time :value="item.sysNotice.senderDate" />
54 </template> 36 </template>
55 - </CardMeta>  
56 - </Card>  
57 - </div> 37 + </ListItem>
  38 + </template>
  39 + </List>
58 </Card> 40 </Card>
59 - </Card> 41 + <Card
  42 + hoverable
  43 + title="联系我们"
  44 + :bordered="false"
  45 + v-bind="$attrs"
  46 + :headStyle="{ padding: 0 }"
  47 + >
  48 + <template #cover>
  49 + <img :src="getQrCode" alt="" style="width: 150px; height: 150px; margin: 50px auto" />
  50 + </template>
  51 + <CardMeta>
  52 + <template #description>
  53 + <p>联系人: {{ getContacts }}</p>
  54 + <p>联系电话: {{ getTel }}</p>
  55 + <p>联系地址: {{ getAddress }} </p>
  56 + </template>
  57 + </CardMeta>
  58 + </Card>
  59 + </div>
60 60
61 - <Card v-if="isAdmin(role)"> 61 + <Card v-else :bordered="false" :bodyStyle="{ padding: 0 }" v-bind="$attrs">
62 <Descriptions title="租户消息量TOP10" :column="1"> 62 <Descriptions title="租户消息量TOP10" :column="1">
63 - <template v-for="(item, index) in 10" :key="index"> 63 + <template v-for="index in 10" :key="index">
64 <DescriptionsItem> 64 <DescriptionsItem>
65 <span 65 <span
66 class="mr-2" 66 class="mr-2"
@@ -94,13 +94,12 @@ @@ -94,13 +94,12 @@
94 ? '#f8c296' 94 ? '#f8c296'
95 : '#0b55f1;', 95 : '#0b55f1;',
96 }" 96 }"
97 - >{{ index + 1 }}</span 97 + >{{ index }}</span
98 >兰州天兆猪业</DescriptionsItem 98 >兰州天兆猪业</DescriptionsItem
99 > 99 >
100 </template> 100 </template>
101 </Descriptions> 101 </Descriptions>
102 - </Card>  
103 - <Card v-if="isAdmin(role)"> 102 + <Descriptions title="本月即将过期租户" class="mt-6" />
104 <BasicTable @register="registerTable" /> 103 <BasicTable @register="registerTable" />
105 </Card> 104 </Card>
106 </div> 105 </div>
@@ -115,7 +114,6 @@ @@ -115,7 +114,6 @@
115 import { Time } from '/@/components/Time'; 114 import { Time } from '/@/components/Time';
116 import { useGo } from '/@/hooks/web/usePage'; 115 import { useGo } from '/@/hooks/web/usePage';
117 import { BasicTable, useTable } from '/@/components/Table'; 116 import { BasicTable, useTable } from '/@/components/Table';
118 - import { columns } from './props';  
119 import { isAdmin } from '/@/enums/roleEnum'; 117 import { isAdmin } from '/@/enums/roleEnum';
120 import { getTenantExpireTimeList } from '/@/api/dashboard'; 118 import { getTenantExpireTimeList } from '/@/api/dashboard';
121 export default defineComponent({ 119 export default defineComponent({
@@ -169,16 +167,24 @@ @@ -169,16 +167,24 @@
169 tab: '我的通知', 167 tab: '我的通知',
170 }, 168 },
171 ]; 169 ];
172 - const onTabChange = (key) => {  
173 - activeKey.value = key;  
174 - };  
175 170
176 const [registerTable, { redoHeight }] = useTable({ 171 const [registerTable, { redoHeight }] = useTable({
177 api: getTenantExpireTimeList, 172 api: getTenantExpireTimeList,
178 - title: '本月即将过期租户',  
179 showIndexColumn: false, 173 showIndexColumn: false,
180 useSearchForm: false, 174 useSearchForm: false,
181 - columns, 175 + bordered: true,
  176 + columns: [
  177 + {
  178 + title: '租户名称',
  179 + dataIndex: 'name',
  180 + width: 120,
  181 + },
  182 + {
  183 + title: '过期时间',
  184 + dataIndex: 'tenantExpireTime',
  185 + width: 120,
  186 + },
  187 + ],
182 fetchSetting: { 188 fetchSetting: {
183 listField: 'expireTenant.items', 189 listField: 'expireTenant.items',
184 totalField: 'expireTenant.total', 190 totalField: 'expireTenant.total',
@@ -200,11 +206,10 @@ @@ -200,11 +206,10 @@
200 }); 206 });
201 onMounted(async () => { 207 onMounted(async () => {
202 if (isAdmin(props.role)) return; 208 if (isAdmin(props.role)) return;
203 -  
204 - const res = await getEnterPriseDetail();  
205 const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 }); 209 const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 });
206 - userStore.setEnterPriseInfo(res); 210 + const res = await getEnterPriseDetail();
207 dataSource.value = notice.items; 211 dataSource.value = notice.items;
  212 + userStore.setEnterPriseInfo(res);
208 }); 213 });
209 214
210 return { 215 return {
@@ -216,7 +221,6 @@ @@ -216,7 +221,6 @@
216 getAddress, 221 getAddress,
217 getTel, 222 getTel,
218 dataSource, 223 dataSource,
219 - onTabChange,  
220 go, 224 go,
221 registerTable, 225 registerTable,
222 isAdmin, 226 isAdmin,
@@ -45,7 +45,7 @@ @@ -45,7 +45,7 @@
45 /> 45 />
46 </div> 46 </div>
47 </template> 47 </template>
48 - <TenantTrend /> 48 + <TenantTrend :tenantTrendList="tenantTrendList" />
49 </Card> 49 </Card>
50 <Card v-bind="$attrs" title="客户趋势"> 50 <Card v-bind="$attrs" title="客户趋势">
51 <template #extra> 51 <template #extra>
@@ -64,7 +64,7 @@ @@ -64,7 +64,7 @@
64 /> 64 />
65 </div> 65 </div>
66 </template> 66 </template>
67 - <CustomerTrend /> 67 + <CustomerTrend :customerTrendList="customerTrendList" />
68 </Card> 68 </Card>
69 </div> 69 </div>
70 </template> 70 </template>
@@ -382,6 +382,8 @@ @@ -382,6 +382,8 @@
382 const { 382 const {
383 tenantDateValue, 383 tenantDateValue,
384 customerDateValue, 384 customerDateValue,
  385 + tenantTrendList,
  386 + customerTrendList,
385 activeTenantIndex, 387 activeTenantIndex,
386 activeCustomerIndex, 388 activeCustomerIndex,
387 TenantOrCustomerDateList, 389 TenantOrCustomerDateList,
@@ -3,18 +3,89 @@ @@ -3,18 +3,89 @@
3 <div ref="chartRef" :style="{ height, width }"></div> 3 <div ref="chartRef" :style="{ height, width }"></div>
4 </template> 4 </template>
5 <script lang="ts" setup> 5 <script lang="ts" setup>
6 - import { ref, Ref, withDefaults } from 'vue'; 6 + import { ref, Ref, withDefaults, onMounted, watch } from 'vue';
7 import { useECharts } from '/@/hooks/web/useECharts'; 7 import { useECharts } from '/@/hooks/web/useECharts';
  8 + import { getTrendData } from '/@/api/dashboard/index';
8 9
9 interface Props { 10 interface Props {
10 width?: string; 11 width?: string;
11 height?: string; 12 height?: string;
  13 + tenantTrendList?: Array<[number, string]>;
12 } 14 }
13 - withDefaults(defineProps<Props>(), { 15 + const props = withDefaults(defineProps<Props>(), {
14 width: '100%', 16 width: '100%',
15 height: '280px', 17 height: '280px',
  18 + tenantTrendList: () => [],
16 }); 19 });
17 20
  21 + watch(
  22 + () => props.tenantTrendList,
  23 + (newValue) => {
  24 + setOptions({
  25 + tooltip: {
  26 + trigger: 'axis',
  27 + axisPointer: {
  28 + type: 'shadow',
  29 + },
  30 + },
  31 + xAxis: {
  32 + type: 'time',
  33 + },
  34 + yAxis: {},
  35 + grid: {
  36 + left: '3%',
  37 + right: '4%',
  38 + bottom: '3%',
  39 + containLabel: true,
  40 + },
  41 + series: [
  42 + {
  43 + name: '当前趋势',
  44 + type: 'line',
  45 + data: newValue,
  46 + },
  47 + ],
  48 + });
  49 + }
  50 + );
  51 +
18 const chartRef = ref<HTMLDivElement | null>(null); 52 const chartRef = ref<HTMLDivElement | null>(null);
19 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); 53 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
  54 + onMounted(async () => {
  55 + const endTs = Date.now();
  56 + const res = await getTrendData({
  57 + startTs: endTs - 2592000000,
  58 + endTs,
  59 + interval: 86400000,
  60 + trend: 'TENANT_TREND',
  61 + });
  62 + const transferResult = res.map((item) => {
  63 + return [item.ts, item.value];
  64 + });
  65 + setOptions({
  66 + tooltip: {
  67 + trigger: 'axis',
  68 + axisPointer: {
  69 + type: 'shadow',
  70 + },
  71 + },
  72 + xAxis: {
  73 + type: 'time',
  74 + },
  75 + yAxis: {},
  76 + grid: {
  77 + left: '3%',
  78 + right: '4%',
  79 + bottom: '3%',
  80 + containLabel: true,
  81 + },
  82 + series: [
  83 + {
  84 + name: '当前趋势',
  85 + type: 'line',
  86 + data: transferResult,
  87 + },
  88 + ],
  89 + });
  90 + });
20 </script> 91 </script>
@@ -47,6 +47,7 @@ @@ -47,6 +47,7 @@
47 type: 'bar', 47 type: 'bar',
48 stack: 'Total', 48 stack: 'Total',
49 data: props.alarmList, 49 data: props.alarmList,
  50 + color: '#3C78FF',
50 }, 51 },
51 ], 52 ],
52 }); 53 });
@@ -77,6 +78,7 @@ @@ -77,6 +78,7 @@
77 name: '告警数', 78 name: '告警数',
78 type: 'bar', 79 type: 'bar',
79 stack: 'Total', 80 stack: 'Total',
  81 + color: '#3C78FF',
80 data: newValue, 82 data: newValue,
81 }, 83 },
82 ], 84 ],
@@ -68,14 +68,14 @@ @@ -68,14 +68,14 @@
68 type: 'bar', 68 type: 'bar',
69 stack: 'total', 69 stack: 'total',
70 data: newValue, 70 data: newValue,
71 - color: '#9fe080', 71 + color: '#5AEEED',
72 }, 72 },
73 { 73 {
74 name: '传输消息量', 74 name: '传输消息量',
75 type: 'bar', 75 type: 'bar',
76 stack: 'total', 76 stack: 'total',
77 data: newValue1, 77 data: newValue1,
78 - color: '#5c7bd9', 78 + color: '#3C78FF',
79 }, 79 },
80 ], 80 ],
81 }); 81 });
1 import { PropType } from 'vue'; 1 import { PropType } from 'vue';
2 -import type { BasicColumn } from '/@/components/Table';  
3 export interface BasicProps { 2 export interface BasicProps {
4 width: string; 3 width: string;
5 height: string; 4 height: string;
@@ -14,16 +13,3 @@ export const basicProps = { @@ -14,16 +13,3 @@ export const basicProps = {
14 default: '280px', 13 default: '280px',
15 }, 14 },
16 }; 15 };
17 -  
18 -export const columns: BasicColumn[] = [  
19 - {  
20 - title: '租户名称',  
21 - dataIndex: 'name',  
22 - width: 120,  
23 - },  
24 - {  
25 - title: '过期时间',  
26 - dataIndex: 'tenantExpireTime',  
27 - width: 120,  
28 - },  
29 -];  
1 import { ref } from 'vue'; 1 import { ref } from 'vue';
  2 +import { getTrendData } from '/@/api/dashboard';
2 export function useDate() { 3 export function useDate() {
3 const tenantDateValue = ref([]); 4 const tenantDateValue = ref([]);
4 const customerDateValue = ref([]); 5 const customerDateValue = ref([]);
  6 + const tenantTrendList = ref([]);
  7 + const customerTrendList = ref([]);
5 const activeTenantIndex = ref(0); 8 const activeTenantIndex = ref(0);
6 const activeCustomerIndex = ref(0); 9 const activeCustomerIndex = ref(0);
7 const TenantOrCustomerDateList = ref([ 10 const TenantOrCustomerDateList = ref([
@@ -11,21 +14,34 @@ export function useDate() { @@ -11,21 +14,34 @@ export function useDate() {
11 ]); 14 ]);
12 15
13 // 租户趋势和客户趋势快速选择时间 16 // 租户趋势和客户趋势快速选择时间
14 - function quickQueryTenantOrCustomerTime( 17 + async function quickQueryTenantOrCustomerTime(
15 index: number, 18 index: number,
16 value: number, 19 value: number,
17 flag: 'tenant' | 'customer' 20 flag: 'tenant' | 'customer'
18 ) { 21 ) {
  22 + const endTs = Date.now();
19 if (flag === 'tenant') { 23 if (flag === 'tenant') {
20 if (activeTenantIndex.value === index) return; 24 if (activeTenantIndex.value === index) return;
21 activeTenantIndex.value = index; 25 activeTenantIndex.value = index;
22 tenantDateValue.value = []; 26 tenantDateValue.value = [];
23 - console.log(value); 27 + const res = await getTrendData({
  28 + startTs: endTs - value,
  29 + endTs,
  30 + interval: value === 2592000000 ? 86400000 : value === 7776000000 ? 172800000 : 2592000000,
  31 + trend: 'TENANT_TREND',
  32 + });
  33 + tenantTrendList.value = res.map((item) => [item.ts, item.value]);
24 } else { 34 } else {
25 if (activeCustomerIndex.value === index) return; 35 if (activeCustomerIndex.value === index) return;
26 activeCustomerIndex.value = index; 36 activeCustomerIndex.value = index;
27 customerDateValue.value = []; 37 customerDateValue.value = [];
28 - console.log(value); 38 + const res = await getTrendData({
  39 + startTs: endTs - value,
  40 + endTs,
  41 + interval: value === 2592000000 ? 86400000 : value === 7776000000 ? 172800000 : 2592000000,
  42 + trend: 'CUSTOMER_TREND',
  43 + });
  44 + customerTrendList.value = res.map((item) => [item.ts, item.value]);
29 } 45 }
30 } 46 }
31 // 租户选择日期 47 // 租户选择日期
@@ -41,6 +57,8 @@ export function useDate() { @@ -41,6 +57,8 @@ export function useDate() {
41 return { 57 return {
42 tenantDateValue, 58 tenantDateValue,
43 customerDateValue, 59 customerDateValue,
  60 + tenantTrendList,
  61 + customerTrendList,
44 activeTenantIndex, 62 activeTenantIndex,
45 activeCustomerIndex, 63 activeCustomerIndex,
46 TenantOrCustomerDateList, 64 TenantOrCustomerDateList,
@@ -10,7 +10,12 @@ @@ -10,7 +10,12 @@
10 </div> 10 </div>
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 - <HelpDoc :role="role" /> 13 + <Card
  14 + :style="{ width: '100%', height: !isAdmin(role) ? '100%' : '98.5%' }"
  15 + :title="!isAdmin(role) ? '帮助文档' : ''"
  16 + >
  17 + <HelpDoc :role="role" />
  18 + </Card>
14 </div> 19 </div>
15 </div> 20 </div>
16 </template> 21 </template>
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 :canFullscreen="false" 6 :canFullscreen="false"
7 centered 7 centered
8 @ok="dispatchCustomer" 8 @ok="dispatchCustomer"
  9 + @cancel="resetFields"
9 :minHeight="150" 10 :minHeight="150"
10 okText="分配" 11 okText="分配"
11 > 12 >
@@ -59,6 +60,7 @@ @@ -59,6 +60,7 @@
59 registerModal, 60 registerModal,
60 registerForm, 61 registerForm,
61 dispatchCustomer, 62 dispatchCustomer,
  63 + resetFields,
62 }; 64 };
63 }, 65 },
64 }); 66 });
@@ -5,42 +5,27 @@ @@ -5,42 +5,27 @@
5 :alwaysShowTitle="true" 5 :alwaysShowTitle="true"
6 style="z-index: 99; position: absolute; width: 40px; height: 100px; left: 10%; top: -20px" 6 style="z-index: 99; position: absolute; width: 40px; height: 100px; left: 10%; top: -20px"
7 /> 7 />
  8 +
  9 + <AppDarkModeToggle
  10 + class="absolute top-3 right-10 enter-x"
  11 + v-if="!sessionTimeout"
  12 + @click="toggleDark"
  13 + />
8 <AppLocalePicker 14 <AppLocalePicker
9 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"
10 :showText="false" 16 :showText="false"
11 v-if="!sessionTimeout && showLocale" 17 v-if="!sessionTimeout && showLocale"
12 /> 18 />
13 - <AppDarkModeToggle  
14 - class="absolute top-3 right-7 enter-x"  
15 - v-if="!sessionTimeout"  
16 - @click="toggleDark"  
17 - />  
18 </div> 19 </div>
19 <div class="login-container" :class="{ light1: isDark, dark: !isDark }"> 20 <div class="login-container" :class="{ light1: isDark, dark: !isDark }">
20 - <div class="login-description">  
21 - <h1>物联网平台</h1>  
22 - <h2>输入您的个人详细信息开始使用!</h2>  
23 - </div>  
24 <div class="flex w-full h-full py-5 xl:h-auto xl:py-0 xl:my-0 xl:w-6/12"> 21 <div class="flex w-full h-full py-5 xl:h-auto xl:py-0 xl:my-0 xl:w-6/12">
  22 + <div class="login-description absolute right-65 top-30">
  23 + <h1>物联网平台</h1>
  24 + <h2>输入您的个人详细信息开始使用!</h2>
  25 + </div>
25 <div 26 <div
26 :class="`${prefixCls}-form`" 27 :class="`${prefixCls}-form`"
27 - class="  
28 - relative  
29 - w-full  
30 - px-5  
31 - py-8  
32 - mx-auto  
33 - my-auto  
34 - rounded-md  
35 - shadow-md  
36 - xl:ml-16 xl:bg-transparent  
37 - sm:px-8  
38 - xl:p-4 xl:shadow-none  
39 - sm:w-3/4  
40 - lg:w-2/4  
41 - xl:w-auto  
42 - enter-x  
43 - " 28 + class="relative w-full px-5 py-8 mx-auto my-auto rounded-md shadow-md xl:ml-16 xl:bg-transparent sm:px-8 xl:p-4 xl:shadow-none sm:w-3/4 lg:w-2/4 xl:w-auto enter-x"
44 :style="{ backgroundColor: isDark ? '#fff' : '#1a2030' }" 29 :style="{ backgroundColor: isDark ? '#fff' : '#1a2030' }"
45 > 30 >
46 <LoginForm /> 31 <LoginForm />
@@ -50,7 +35,17 @@ @@ -50,7 +35,17 @@
50 <QrCodeForm /> 35 <QrCodeForm />
51 </div> 36 </div>
52 </div> 37 </div>
53 - <div style="position: absolute; bottom: 20px; left: 45%">{{ getCopyRight }}</div> 38 + <div
  39 + style="
  40 + width: 100%;
  41 + display: flex;
  42 + justify-content: center;
  43 + position: absolute;
  44 + bottom: 1.25rem;
  45 + color: #fff;
  46 + "
  47 + >{{ getCopyRight }}</div
  48 + >
54 </div> 49 </div>
55 </div> 50 </div>
56 </template> 51 </template>
@@ -82,7 +77,10 @@ @@ -82,7 +77,10 @@
82 }; 77 };
83 const userStore = useUserStore(); 78 const userStore = useUserStore();
84 const getCopyRight = computed(() => { 79 const getCopyRight = computed(() => {
85 - return (userStore.platInfo?.copyright ?? '') + (userStore.platInfo?.presentedOurselves ?? ''); 80 + return (
  81 + (userStore.platInfo?.copyright ?? 'Copyright@ 云腾五洲 蜀ICP') +
  82 + (userStore.platInfo?.presentedOurselves ?? '')
  83 + );
86 }); 84 });
87 </script> 85 </script>
88 <style lang="less"> 86 <style lang="less">
@@ -104,9 +102,6 @@ @@ -104,9 +102,6 @@
104 height: 60px; 102 height: 60px;
105 width: 100%; 103 width: 100%;
106 background-color: #1d3794; 104 background-color: #1d3794;
107 - .vben-dark-switch {  
108 - margin-left: 1840px;  
109 - }  
110 } 105 }
111 106
112 .login-container { 107 .login-container {
@@ -117,28 +112,25 @@ @@ -117,28 +112,25 @@
117 height: calc(100% - 60px); 112 height: calc(100% - 60px);
118 background-size: 100% 100%; 113 background-size: 100% 100%;
119 background-repeat: no-repeat; 114 background-repeat: no-repeat;
120 - .vben-login-form {  
121 - position: absolute;  
122 -  
123 - width: 410px;  
124 - right: 200px;  
125 - top: 50%;  
126 - margin-top: -180px;  
127 - }  
128 .login-description { 115 .login-description {
129 - position: absolute;  
130 - right: 13%;  
131 - top: 15%; 116 + text-align: center;
132 h1 { 117 h1 {
133 - font-size: 26px;  
134 color: #5aeeed; 118 color: #5aeeed;
135 - text-align: center; 119 +
  120 + font-size: 26px;
136 } 121 }
137 h2 { 122 h2 {
138 - font-size: 20px;  
139 color: #5aeeed; 123 color: #5aeeed;
  124 + font-size: 20px;
140 } 125 }
141 } 126 }
  127 + .vben-login-form {
  128 + position: absolute;
  129 + width: 25.625rem;
  130 + right: 12.5rem;
  131 + top: 50%;
  132 + margin-top: -11.25rem;
  133 + }
142 } 134 }
143 } 135 }
144 </style> 136 </style>