Commit a235990f2e17cf48dfaf5d317443a3cd54af7442
Merge branch 'sqy_dev' into 'main'
联调首页接口 See merge request huang/yun-teng-iot-front!66
Showing
15 changed files
with
411 additions
and
156 deletions
| @@ -6,12 +6,18 @@ VITE_PUBLIC_PATH = / | @@ -6,12 +6,18 @@ VITE_PUBLIC_PATH = / | ||
| 6 | 6 | ||
| 7 | # Cross-domain proxy, you can configure multiple | 7 | # Cross-domain proxy, you can configure multiple | 
| 8 | # Please note that no line breaks | 8 | # Please note that no line breaks | 
| 9 | -# VITE_PROXY = [["/api","http://192.168.10.118:8080/api"],["/upload","http://192.168.10.116:3300/upload"]] | 9 | + | 
| 10 | +# 本地 | ||
| 11 | +# VITE_PROXY = [["/api","http://192.168.10.123:8080/api"],["/upload","http://192.168.10.124:3300/upload"]] | ||
| 12 | + | ||
| 13 | +# 线上 | ||
| 10 | VITE_PROXY = [["/api","http://101.133.234.90:8080/api"],["/upload","http://192.168.10.116:3300/upload"]] | 14 | VITE_PROXY = [["/api","http://101.133.234.90:8080/api"],["/upload","http://192.168.10.116:3300/upload"]] | 
| 11 | -# VITE_PROXY=[["/api","https://vvbin.cn/test"]] | 15 | + | 
| 16 | +# 实时数据的ws地址 | ||
| 17 | +VITE_WEB_SOCKET = ws://101.133.234.90:8080/api/ws/plugins/telemetry?token= | ||
| 12 | 18 | ||
| 13 | # Delete console | 19 | # Delete console | 
| 14 | -VITE_DROP_CONSOLE = false | 20 | +VITE_DROP_CONSOLE = true | 
| 15 | 21 | ||
| 16 | # Basic interface address SPA | 22 | # Basic interface address SPA | 
| 17 | VITE_GLOB_API_URL=/api | 23 | VITE_GLOB_API_URL=/api | 
| @@ -17,7 +17,7 @@ enum Api { | @@ -17,7 +17,7 @@ enum Api { | ||
| 17 | export const getMenuList = () => { | 17 | export const getMenuList = () => { | 
| 18 | const userStore = useUserStore(); | 18 | const userStore = useUserStore(); | 
| 19 | let url = Api.GetMenuList; | 19 | let url = Api.GetMenuList; | 
| 20 | - if (userStore.getRoleList.find((v) => v == RoleEnum.ROLE_SYS_ADMIN)) { | 20 | + if (userStore.getRoleList.find((v) => v == RoleEnum.SYS_ADMIN)) { | 
| 21 | url = Api.SysAdminMenuList; | 21 | url = Api.SysAdminMenuList; | 
| 22 | } | 22 | } | 
| 23 | return defHttp.get<getMenuListResultModel>({ url }); | 23 | return defHttp.get<getMenuListResultModel>({ url }); | 
| 1 | export enum RoleEnum { | 1 | export enum RoleEnum { | 
| 2 | - ROLE_SYS_ADMIN = 'SYS_ADMIN', | ||
| 3 | - ROLE_TENANT_ADMIN = 'TENANT_ADMIN', | ||
| 4 | - ROLE_PLATFORM_ADMIN = 'PLATFORM_ADMIN', | ||
| 5 | - ROLE_NORMAL_USER = 'CUSTOMER_USER', | 2 | + SYS_ADMIN = 'SYS_ADMIN', | 
| 3 | + PLATFORM_ADMIN = 'PLATFORM_ADMIN', | ||
| 4 | + TENANT_ADMIN = 'TENANT_ADMIN', | ||
| 5 | + CUSTOMER_USER = 'CUSTOMER_USER', | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +export function isAdmin(role: string) { | ||
| 9 | + if (role === RoleEnum.SYS_ADMIN || role === RoleEnum.PLATFORM_ADMIN) { | ||
| 10 | + return true; | ||
| 11 | + } else if (role === RoleEnum.TENANT_ADMIN || role === RoleEnum.CUSTOMER_USER) { | ||
| 12 | + return false; | ||
| 13 | + } | ||
| 6 | } | 14 | } | 
| @@ -38,9 +38,7 @@ | @@ -38,9 +38,7 @@ | ||
| 38 | <div class="mr-4" | 38 | <div class="mr-4" | 
| 39 | ><img | 39 | ><img | 
| 40 | :src=" | 40 | :src=" | 
| 41 | - role === 'TENANT_ADMIN' | ||
| 42 | - ? '/src/assets/images/alarm-count.png' | ||
| 43 | - : '/src/assets/images/zh.png' | 41 | + !isAdmin(role) ? '/src/assets/images/alarm-count.png' : '/src/assets/images/zh.png' | 
| 44 | " | 42 | " | 
| 45 | style="width: 5rem; height: 5rem" | 43 | style="width: 5rem; height: 5rem" | 
| 46 | /></div> | 44 | /></div> | 
| @@ -51,7 +49,7 @@ | @@ -51,7 +49,7 @@ | ||
| 51 | }}</div> | 49 | }}</div> | 
| 52 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> | 50 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> | 
| 53 | </div> | 51 | </div> | 
| 54 | - <div> {{ role === 'TENANT_ADMIN' ? '11月告警数(条)' : '租户总量(个)' }}</div> | 52 | + <div> {{ !isAdmin(role) ? '11月告警数(条)' : '租户总量(个)' }}</div> | 
| 55 | </div> | 53 | </div> | 
| 56 | </div> | 54 | </div> | 
| 57 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> | 55 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> | 
| @@ -62,11 +60,7 @@ | @@ -62,11 +60,7 @@ | ||
| 62 | <div class="flex" style="height: 100px"> | 60 | <div class="flex" style="height: 100px"> | 
| 63 | <div class="mr-4" | 61 | <div class="mr-4" | 
| 64 | ><img | 62 | ><img | 
| 65 | - :src=" | ||
| 66 | - role === 'TENANT_ADMIN' | ||
| 67 | - ? '/src/assets/images/msg-count.png' | ||
| 68 | - : '/src/assets/images/kf.png' | ||
| 69 | - " | 63 | + :src="!isAdmin(role) ? '/src/assets/images/msg-count.png' : '/src/assets/images/kf.png'" | 
| 70 | style="width: 5rem; height: 5rem" | 64 | style="width: 5rem; height: 5rem" | 
| 71 | /></div> | 65 | /></div> | 
| 72 | <div class="flex-auto"> | 66 | <div class="flex-auto"> | 
| @@ -76,7 +70,7 @@ | @@ -76,7 +70,7 @@ | ||
| 76 | }}</div> | 70 | }}</div> | 
| 77 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> | 71 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> | 
| 78 | </div> | 72 | </div> | 
| 79 | - <div> {{ role === 'TENANT_ADMIN' ? '11月消息量(条)' : '客户总量(个)' }} </div> | 73 | + <div> {{ !isAdmin(role) ? '11月消息量(条)' : '客户总量(个)' }} </div> | 
| 80 | </div> | 74 | </div> | 
| 81 | </div> | 75 | </div> | 
| 82 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> | 76 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> | 
| @@ -86,9 +80,16 @@ | @@ -86,9 +80,16 @@ | ||
| 86 | </div> | 80 | </div> | 
| 87 | </template> | 81 | </template> | 
| 88 | <script lang="ts" setup> | 82 | <script lang="ts" setup> | 
| 89 | - import { defineProps, ref, onMounted } from 'vue'; | 83 | + import { defineProps, defineExpose, ref, onMounted } from 'vue'; | 
| 90 | import { Card } from 'ant-design-vue'; | 84 | import { Card } from 'ant-design-vue'; | 
| 91 | import { getHomeData } from '/@/api/dashboard'; | 85 | import { getHomeData } from '/@/api/dashboard'; | 
| 86 | + import { isAdmin } from '/@/enums/roleEnum'; | ||
| 87 | + defineProps<{ | ||
| 88 | + role: string; | ||
| 89 | + }>(); | ||
| 90 | + defineExpose({ | ||
| 91 | + isAdmin, | ||
| 92 | + }); | ||
| 92 | interface CardList { | 93 | interface CardList { | 
| 93 | deviceInfo: { | 94 | deviceInfo: { | 
| 94 | sumCount: number; | 95 | sumCount: number; | 
| @@ -104,9 +105,5 @@ | @@ -104,9 +105,5 @@ | ||
| 104 | onMounted(async () => { | 105 | onMounted(async () => { | 
| 105 | const res = await getHomeData(); | 106 | const res = await getHomeData(); | 
| 106 | growCardList.value = res; | 107 | growCardList.value = res; | 
| 107 | - console.log(growCardList.value); | ||
| 108 | }); | 108 | }); | 
| 109 | - defineProps<{ | ||
| 110 | - role: string; | ||
| 111 | - }>(); | ||
| 112 | </script> | 109 | </script> | 
| 1 | <template> | 1 | <template> | 
| 2 | <div> | 2 | <div> | 
| 3 | - <Card title="帮助文档" v-if="role === 'TENANT_ADMIN'"> | 3 | + <Card title="帮助文档" 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="role === 'TENANT_ADMIN'" | 10 | + v-if="!isAdmin(role)" | 
| 11 | :tab-list="tabListTitle" | 11 | :tab-list="tabListTitle" | 
| 12 | v-bind="$attrs" | 12 | v-bind="$attrs" | 
| 13 | :active-tab-key="activeKey" | 13 | :active-tab-key="activeKey" | 
| @@ -58,7 +58,7 @@ | @@ -58,7 +58,7 @@ | ||
| 58 | </Card> | 58 | </Card> | 
| 59 | </Card> | 59 | </Card> | 
| 60 | 60 | ||
| 61 | - <Card v-if="role !== 'TENANT_ADMIN'"> | 61 | + <Card v-if="isAdmin(role)"> | 
| 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="(item, index) in 10" :key="index"> | 
| 64 | <DescriptionsItem> | 64 | <DescriptionsItem> | 
| @@ -100,7 +100,7 @@ | @@ -100,7 +100,7 @@ | ||
| 100 | </template> | 100 | </template> | 
| 101 | </Descriptions> | 101 | </Descriptions> | 
| 102 | </Card> | 102 | </Card> | 
| 103 | - <BasicTable @register="registerTable" v-if="role !== 'TENANT_ADMIN'" /> | 103 | + <BasicTable @register="registerTable" v-if="isAdmin(role)" /> | 
| 104 | </div> | 104 | </div> | 
| 105 | </template> | 105 | </template> | 
| 106 | 106 | ||
| @@ -124,6 +124,7 @@ | @@ -124,6 +124,7 @@ | ||
| 124 | import { useGo } from '/@/hooks/web/usePage'; | 124 | import { useGo } from '/@/hooks/web/usePage'; | 
| 125 | import { BasicTable, useTable } from '/@/components/Table'; | 125 | import { BasicTable, useTable } from '/@/components/Table'; | 
| 126 | import { columns } from './props'; | 126 | import { columns } from './props'; | 
| 127 | + import { isAdmin } from '/@/enums/roleEnum'; | ||
| 127 | export default defineComponent({ | 128 | export default defineComponent({ | 
| 128 | components: { | 129 | components: { | 
| 129 | Card, | 130 | Card, | 
| @@ -139,7 +140,10 @@ | @@ -139,7 +140,10 @@ | ||
| 139 | DescriptionsItem, | 140 | DescriptionsItem, | 
| 140 | }, | 141 | }, | 
| 141 | props: { | 142 | props: { | 
| 142 | - role: String, | 143 | + role: { | 
| 144 | + type: String, | ||
| 145 | + required: true, | ||
| 146 | + }, | ||
| 143 | }, | 147 | }, | 
| 144 | setup(props) { | 148 | setup(props) { | 
| 145 | // 通知数据 | 149 | // 通知数据 | 
| @@ -196,7 +200,7 @@ | @@ -196,7 +200,7 @@ | ||
| 196 | return userStore.enterPriseInfo?.qrCode; | 200 | return userStore.enterPriseInfo?.qrCode; | 
| 197 | }); | 201 | }); | 
| 198 | onMounted(async () => { | 202 | onMounted(async () => { | 
| 199 | - if (props.role !== 'TENANT_ADMIN') return; | 203 | + if (isAdmin(props.role)) return; | 
| 200 | const res = await getEnterPriseDetail(); | 204 | const res = await getEnterPriseDetail(); | 
| 201 | const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 }); | 205 | const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 }); | 
| 202 | userStore.setEnterPriseInfo(res); | 206 | userStore.setEnterPriseInfo(res); | 
| @@ -215,6 +219,7 @@ | @@ -215,6 +219,7 @@ | ||
| 215 | dataSource, | 219 | dataSource, | 
| 216 | go, | 220 | go, | 
| 217 | registerTable, | 221 | registerTable, | 
| 222 | + isAdmin, | ||
| 218 | }; | 223 | }; | 
| 219 | }, | 224 | }, | 
| 220 | }); | 225 | }); | 
| @@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
| 5 | :active-tab-key="activeKey" | 5 | :active-tab-key="activeKey" | 
| 6 | @tabChange="onTabChange" | 6 | @tabChange="onTabChange" | 
| 7 | > | 7 | > | 
| 8 | - <template #tabBarExtraContent v-if="role === 'TENANT_ADMIN'"> | 8 | + <template #tabBarExtraContent v-if="!isAdmin(role)"> | 
| 9 | <div class="extra-date"> | 9 | <div class="extra-date"> | 
| 10 | <template v-for="(item, index) in dateList" :key="item"> | 10 | <template v-for="(item, index) in dateList" :key="item"> | 
| 11 | <span @click="changeDate(index)" :class="{ active: index === activeIndex }">{{ | 11 | <span @click="changeDate(index)" :class="{ active: index === activeIndex }">{{ | 
| @@ -15,53 +15,275 @@ | @@ -15,53 +15,275 @@ | ||
| 15 | <DatePicker @change="onDateChange" /> | 15 | <DatePicker @change="onDateChange" /> | 
| 16 | </div> | 16 | </div> | 
| 17 | </template> | 17 | </template> | 
| 18 | - <div v-if="activeKey === 'tab1'"> | ||
| 19 | - <p class="center">{{ role === 'TENANT_ADMIN' ? '告警数' : '租户趋势' }}</p> | ||
| 20 | - <VisitAnalysis v-if="role === 'TENANT_ADMIN'" /> | 18 | + <div v-if="activeKey === '1'"> | 
| 19 | + <p class="center">{{ !isAdmin(role) ? '告警数' : '租户趋势' }}</p> | ||
| 20 | + <VisitAnalysis v-if="!isAdmin(role)" :alarmList="state.alarmList" /> | ||
| 21 | <VisitAnalysisBar v-else /> | 21 | <VisitAnalysisBar v-else /> | 
| 22 | </div> | 22 | </div> | 
| 23 | - <div v-else> | ||
| 24 | - <p class="center">消息数</p> | ||
| 25 | - <VisitAnalysisBar /> | 23 | + <div v-if="activeKey === '2'"> | 
| 24 | + <p class="center">消息量</p> | ||
| 25 | + <VisitAnalysisBar :dataPointList="state.dataPointList" :messageList="state.messageList" /> | ||
| 26 | </div> | 26 | </div> | 
| 27 | </Card> | 27 | </Card> | 
| 28 | + <Card v-bind="$attrs" :tab-list="tab1ListTitle" v-if="isAdmin(role)"> | ||
| 29 | + <p class="center">客户趋势</p> | ||
| 30 | + <VisitAnalysis | ||
| 31 | + /></Card> | ||
| 28 | </template> | 32 | </template> | 
| 29 | <script lang="ts" setup> | 33 | <script lang="ts" setup> | 
| 30 | - import { ref } from 'vue'; | 34 | + import { ref, defineExpose, reactive } from 'vue'; | 
| 31 | import { Card, DatePicker } from 'ant-design-vue'; | 35 | import { Card, DatePicker } from 'ant-design-vue'; | 
| 32 | import VisitAnalysis from './VisitAnalysis.vue'; | 36 | import VisitAnalysis from './VisitAnalysis.vue'; | 
| 33 | import VisitAnalysisBar from './VisitAnalysisBar.vue'; | 37 | import VisitAnalysisBar from './VisitAnalysisBar.vue'; | 
| 34 | import { defineProps } from 'vue'; | 38 | import { defineProps } from 'vue'; | 
| 39 | + import { isAdmin } from '/@/enums/roleEnum'; | ||
| 40 | + import { useWebSocket } from '@vueuse/core'; | ||
| 41 | + import { getAuthCache } from '/@/utils/auth'; | ||
| 42 | + import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; | ||
| 35 | 43 | ||
| 44 | + defineExpose({ | ||
| 45 | + isAdmin, | ||
| 46 | + }); | ||
| 36 | const props = defineProps<{ | 47 | const props = defineProps<{ | 
| 37 | role: string; | 48 | role: string; | 
| 38 | }>(); | 49 | }>(); | 
| 39 | - const activeKey = ref('tab1'); | 50 | + const activeKey = ref('1'); | 
| 40 | 51 | ||
| 41 | // 动态根据登录角色来判断 | 52 | // 动态根据登录角色来判断 | 
| 42 | - const tabListTitle = | ||
| 43 | - props.role === 'TENANT_ADMIN' | ||
| 44 | - ? [ | 53 | + const tabListTitle = !isAdmin(props.role) | 
| 54 | + ? [ | ||
| 55 | + { | ||
| 56 | + key: '1', | ||
| 57 | + tab: '告警数统计', | ||
| 58 | + }, | ||
| 59 | + { | ||
| 60 | + key: '2', | ||
| 61 | + tab: '消息量统计', | ||
| 62 | + }, | ||
| 63 | + ] | ||
| 64 | + : [ | ||
| 65 | + { | ||
| 66 | + key: '1', | ||
| 67 | + tab: '租户', | ||
| 68 | + }, | ||
| 69 | + ]; | ||
| 70 | + | ||
| 71 | + const tab1ListTitle = [ | ||
| 72 | + { | ||
| 73 | + key: '1', | ||
| 74 | + tab: '客户', | ||
| 75 | + }, | ||
| 76 | + ]; | ||
| 77 | + | ||
| 78 | + const dateList = ref(['1小时', '1天', '7天', '30天']); | ||
| 79 | + // web Socket | ||
| 80 | + const token: string = getAuthCache(JWT_TOKEN_KEY); | ||
| 81 | + const sendValue = JSON.stringify({ | ||
| 82 | + entityDataCmds: [ | ||
| 83 | + { | ||
| 84 | + query: { | ||
| 85 | + entityFilter: { | ||
| 86 | + type: 'singleEntity', | ||
| 87 | + singleEntity: { | ||
| 88 | + id: '33782740-5d97-11ec-8ac9-f38ed935ea2a', | ||
| 89 | + entityType: 'API_USAGE_STATE', | ||
| 90 | + }, | ||
| 91 | + }, | ||
| 92 | + pageLink: { | ||
| 93 | + pageSize: 1024, | ||
| 94 | + page: 0, | ||
| 95 | + sortOrder: { | ||
| 96 | + key: { | ||
| 97 | + type: 'ENTITY_FIELD', | ||
| 98 | + key: 'createdTime', | ||
| 99 | + }, | ||
| 100 | + direction: 'DESC', | ||
| 101 | + }, | ||
| 102 | + }, | ||
| 103 | + entityFields: [ | ||
| 104 | + { | ||
| 105 | + type: 'ENTITY_FIELD', | ||
| 106 | + key: 'name', | ||
| 107 | + }, | ||
| 108 | + { | ||
| 109 | + type: 'ENTITY_FIELD', | ||
| 110 | + key: 'label', | ||
| 111 | + }, | ||
| 112 | + { | ||
| 113 | + type: 'ENTITY_FIELD', | ||
| 114 | + key: 'additionalInfo', | ||
| 115 | + }, | ||
| 116 | + ], | ||
| 117 | + latestValues: [ | ||
| 118 | + { | ||
| 119 | + type: 'TIME_SERIES', | ||
| 120 | + key: 'createdAlarmsCountHourly', | ||
| 121 | + }, | ||
| 122 | + ], | ||
| 123 | + }, | ||
| 124 | + cmdId: activeKey.value, | ||
| 125 | + }, | ||
| 126 | + ], | ||
| 127 | + }); | ||
| 128 | + const activeIndex = ref(0); | ||
| 129 | + const state = reactive({ | ||
| 130 | + server: `${import.meta.env.VITE_WEB_SOCKET}${token}`, | ||
| 131 | + alarmList: new Array<[number, string]>(), | ||
| 132 | + alarmItem: new Array<[number, string]>(), | ||
| 133 | + dataPointList: new Array<[number, string]>(), | ||
| 134 | + messageList: new Array<[number, string]>(), | ||
| 135 | + dataPoint: new Array<[number, string]>(), | ||
| 136 | + MsgCount: new Array<[number, string]>(), | ||
| 137 | + }); | ||
| 138 | + const { send, close } = useWebSocket(state.server, { | ||
| 139 | + onConnected() { | ||
| 140 | + send(sendValue); | ||
| 141 | + console.log('建立连接了'); | ||
| 142 | + }, | ||
| 143 | + onMessage(_, e) { | ||
| 144 | + const { data, update } = JSON.parse(e.data); | ||
| 145 | + if (activeKey.value === '1') { | ||
| 146 | + if (data) { | ||
| 147 | + const { createdAlarmsCountHourly } = data.data[0].latest.TIME_SERIES; | ||
| 148 | + state.alarmItem = [createdAlarmsCountHourly.ts, createdAlarmsCountHourly.value]; | ||
| 149 | + state.alarmList.push([createdAlarmsCountHourly.ts, createdAlarmsCountHourly.value]); | ||
| 150 | + } | ||
| 151 | + if (update) { | ||
| 152 | + const { createdAlarmsCountHourly } = update[0].timeseries; | ||
| 153 | + const newArray: any = []; | ||
| 154 | + for (const item of createdAlarmsCountHourly) { | ||
| 155 | + newArray.push([item.ts, item.value]); | ||
| 156 | + } | ||
| 157 | + state.alarmList = [state.alarmItem, ...newArray]; | ||
| 158 | + } | ||
| 159 | + } else { | ||
| 160 | + if (data) { | ||
| 161 | + const { transportDataPointsCountHourly, transportMsgCountHourly } = | ||
| 162 | + data.data[0].latest.TIME_SERIES; | ||
| 163 | + state.dataPoint = [ | ||
| 164 | + transportDataPointsCountHourly.ts, | ||
| 165 | + transportDataPointsCountHourly.value, | ||
| 166 | + ]; | ||
| 167 | + | ||
| 168 | + state.MsgCount = [ | ||
| 169 | + transportDataPointsCountHourly.ts, | ||
| 170 | + transportDataPointsCountHourly.value, | ||
| 171 | + ]; | ||
| 172 | + state.dataPointList.push([ | ||
| 173 | + transportDataPointsCountHourly.ts, | ||
| 174 | + transportDataPointsCountHourly.value, | ||
| 175 | + ]); | ||
| 176 | + state.messageList.push([transportMsgCountHourly.ts, transportMsgCountHourly.value]); | ||
| 177 | + } | ||
| 178 | + if (update) { | ||
| 179 | + const { transportDataPointsCountHourly, transportMsgCountHourly } = update[0].timeseries; | ||
| 180 | + const newArray: any = []; | ||
| 181 | + const newArray1: any = []; | ||
| 182 | + for (const item of transportDataPointsCountHourly) { | ||
| 183 | + newArray.push([item.ts, item.value]); | ||
| 184 | + } | ||
| 185 | + for (const item of transportMsgCountHourly) { | ||
| 186 | + newArray1.push([item.ts, item.value]); | ||
| 187 | + } | ||
| 188 | + state.dataPointList = [state.dataPoint, ...newArray]; | ||
| 189 | + state.messageList = [state.MsgCount, ...newArray1]; | ||
| 190 | + } | ||
| 191 | + } | ||
| 192 | + }, | ||
| 193 | + onDisconnected() { | ||
| 194 | + console.log('断开连接了'); | ||
| 195 | + close(); | ||
| 196 | + }, | ||
| 197 | + }); | ||
| 198 | + function onTabChange(key: string) { | ||
| 199 | + activeKey.value = key; | ||
| 200 | + if (key === '1') { | ||
| 201 | + const sendAlarmValue = JSON.stringify({ | ||
| 202 | + entityDataCmds: [ | ||
| 45 | { | 203 | { | 
| 46 | - key: 'tab1', | ||
| 47 | - tab: '告警数统计', | 204 | + cmdId: activeKey.value, | 
| 205 | + historyCmd: { | ||
| 206 | + keys: ['createdAlarmsCountHourly'], | ||
| 207 | + startTs: 1638778336692, | ||
| 208 | + endTs: 1641370336692, | ||
| 209 | + interval: 43200000, | ||
| 210 | + limit: 60, | ||
| 211 | + agg: 'SUM', | ||
| 212 | + }, | ||
| 48 | }, | 213 | }, | 
| 214 | + ], | ||
| 215 | + }); | ||
| 216 | + send(sendAlarmValue); | ||
| 217 | + } else { | ||
| 218 | + const sendMessageValue = JSON.stringify({ | ||
| 219 | + entityDataCmds: [ | ||
| 49 | { | 220 | { | 
| 50 | - key: 'tab2', | ||
| 51 | - tab: '消息量统计', | 221 | + query: { | 
| 222 | + entityFilter: { | ||
| 223 | + type: 'singleEntity', | ||
| 224 | + singleEntity: { | ||
| 225 | + id: '33782740-5d97-11ec-8ac9-f38ed935ea2a', | ||
| 226 | + entityType: 'API_USAGE_STATE', | ||
| 227 | + }, | ||
| 228 | + }, | ||
| 229 | + pageLink: { | ||
| 230 | + pageSize: 1024, | ||
| 231 | + page: 0, | ||
| 232 | + sortOrder: { | ||
| 233 | + key: { | ||
| 234 | + type: 'ENTITY_FIELD', | ||
| 235 | + key: 'createdTime', | ||
| 236 | + }, | ||
| 237 | + direction: 'DESC', | ||
| 238 | + }, | ||
| 239 | + }, | ||
| 240 | + entityFields: [ | ||
| 241 | + { | ||
| 242 | + type: 'ENTITY_FIELD', | ||
| 243 | + key: 'name', | ||
| 244 | + }, | ||
| 245 | + { | ||
| 246 | + type: 'ENTITY_FIELD', | ||
| 247 | + key: 'label', | ||
| 248 | + }, | ||
| 249 | + { | ||
| 250 | + type: 'ENTITY_FIELD', | ||
| 251 | + key: 'additionalInfo', | ||
| 252 | + }, | ||
| 253 | + ], | ||
| 254 | + latestValues: [ | ||
| 255 | + { | ||
| 256 | + type: 'TIME_SERIES', | ||
| 257 | + key: 'transportMsgCountHourly', | ||
| 258 | + }, | ||
| 259 | + { | ||
| 260 | + type: 'TIME_SERIES', | ||
| 261 | + key: 'transportDataPointsCountHourly', | ||
| 262 | + }, | ||
| 263 | + ], | ||
| 264 | + }, | ||
| 265 | + cmdId: activeKey.value, | ||
| 52 | }, | 266 | }, | 
| 53 | - ] | ||
| 54 | - : [ | 267 | + ], | 
| 268 | + }); | ||
| 269 | + const sendMessageValue2 = JSON.stringify({ | ||
| 270 | + entityDataCmds: [ | ||
| 55 | { | 271 | { | 
| 56 | - key: 'tab1', | ||
| 57 | - tab: '租户', | 272 | + cmdId: activeKey.value, | 
| 273 | + historyCmd: { | ||
| 274 | + keys: ['transportMsgCountHourly', 'transportDataPointsCountHourly'], | ||
| 275 | + startTs: 1641283221226, | ||
| 276 | + endTs: 1641369621226, | ||
| 277 | + interval: 7200000, | ||
| 278 | + limit: 12, | ||
| 279 | + agg: 'AVG', | ||
| 280 | + }, | ||
| 58 | }, | 281 | }, | 
| 59 | - ]; | ||
| 60 | - | ||
| 61 | - const dateList = ref(['1小时', '1天', '7天', '30天']); | ||
| 62 | - const activeIndex = ref(0); | ||
| 63 | - function onTabChange(key) { | ||
| 64 | - activeKey.value = key; | 282 | + ], | 
| 283 | + }); | ||
| 284 | + send(sendMessageValue); | ||
| 285 | + send(sendMessageValue2); | ||
| 286 | + } | ||
| 65 | } | 287 | } | 
| 66 | function onDateChange(date, dateString) { | 288 | function onDateChange(date, dateString) { | 
| 67 | console.log(date, dateString); | 289 | console.log(date, dateString); | 
| @@ -2,17 +2,25 @@ | @@ -2,17 +2,25 @@ | ||
| 2 | <div ref="chartRef" :style="{ height, width }"></div> | 2 | <div ref="chartRef" :style="{ height, width }"></div> | 
| 3 | </template> | 3 | </template> | 
| 4 | <script lang="ts" setup> | 4 | <script lang="ts" setup> | 
| 5 | - import { onMounted, ref, Ref } from 'vue'; | 5 | + import { onMounted, ref, Ref, withDefaults, defineProps, watch } from 'vue'; | 
| 6 | import { useECharts } from '/@/hooks/web/useECharts'; | 6 | import { useECharts } from '/@/hooks/web/useECharts'; | 
| 7 | - import { basicProps } from './props'; | ||
| 8 | 7 | ||
| 9 | - defineProps({ | ||
| 10 | - ...basicProps, | 8 | + interface Props { | 
| 9 | + width?: string; | ||
| 10 | + height?: string; | ||
| 11 | + alarmList: [number, string][]; | ||
| 12 | + } | ||
| 13 | + const props = withDefaults(defineProps<Props>(), { | ||
| 14 | + width: '100%', | ||
| 15 | + height: '280px', | ||
| 16 | + alarmList: () => [], | ||
| 11 | }); | 17 | }); | 
| 18 | + | ||
| 12 | const chartRef = ref<HTMLDivElement | null>(null); | 19 | const chartRef = ref<HTMLDivElement | null>(null); | 
| 13 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); | 20 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); | 
| 14 | 21 | ||
| 15 | onMounted(() => { | 22 | onMounted(() => { | 
| 23 | + console.log(props.alarmList); | ||
| 16 | setOptions({ | 24 | setOptions({ | 
| 17 | tooltip: { | 25 | tooltip: { | 
| 18 | trigger: 'axis', | 26 | trigger: 'axis', | 
| @@ -24,28 +32,8 @@ | @@ -24,28 +32,8 @@ | ||
| 24 | }, | 32 | }, | 
| 25 | }, | 33 | }, | 
| 26 | xAxis: { | 34 | xAxis: { | 
| 27 | - type: 'category', | 35 | + type: 'time', | 
| 28 | boundaryGap: false, | 36 | boundaryGap: false, | 
| 29 | - data: [ | ||
| 30 | - '6:00', | ||
| 31 | - '7:00', | ||
| 32 | - '8:00', | ||
| 33 | - '9:00', | ||
| 34 | - '10:00', | ||
| 35 | - '11:00', | ||
| 36 | - '12:00', | ||
| 37 | - '13:00', | ||
| 38 | - '14:00', | ||
| 39 | - '15:00', | ||
| 40 | - '16:00', | ||
| 41 | - '17:00', | ||
| 42 | - '18:00', | ||
| 43 | - '19:00', | ||
| 44 | - '20:00', | ||
| 45 | - '21:00', | ||
| 46 | - '22:00', | ||
| 47 | - '23:00', | ||
| 48 | - ], | ||
| 49 | splitLine: { | 37 | splitLine: { | 
| 50 | show: true, | 38 | show: true, | 
| 51 | lineStyle: { | 39 | lineStyle: { | 
| @@ -58,30 +46,12 @@ | @@ -58,30 +46,12 @@ | ||
| 58 | show: false, | 46 | show: false, | 
| 59 | }, | 47 | }, | 
| 60 | }, | 48 | }, | 
| 61 | - yAxis: [ | ||
| 62 | - { | ||
| 63 | - type: 'value', | ||
| 64 | - max: 80000, | ||
| 65 | - splitNumber: 4, | ||
| 66 | - axisTick: { | ||
| 67 | - show: false, | ||
| 68 | - }, | ||
| 69 | - splitArea: { | ||
| 70 | - show: true, | ||
| 71 | - areaStyle: { | ||
| 72 | - color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'], | ||
| 73 | - }, | ||
| 74 | - }, | ||
| 75 | - }, | ||
| 76 | - ], | 49 | + yAxis: {}, | 
| 77 | grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, | 50 | grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, | 
| 78 | series: [ | 51 | series: [ | 
| 79 | { | 52 | { | 
| 80 | smooth: true, | 53 | smooth: true, | 
| 81 | - data: [ | ||
| 82 | - 111, 222, 4000, 18000, 33333, 55555, 66666, 33333, 14000, 36000, 66666, 44444, 22222, | ||
| 83 | - 11111, 4000, 2000, 500, 333, 222, 111, | ||
| 84 | - ], | 54 | + data: props.alarmList, | 
| 85 | type: 'line', | 55 | type: 'line', | 
| 86 | areaStyle: {}, | 56 | areaStyle: {}, | 
| 87 | itemStyle: { | 57 | itemStyle: { | 
| @@ -91,4 +61,49 @@ | @@ -91,4 +61,49 @@ | ||
| 91 | ], | 61 | ], | 
| 92 | }); | 62 | }); | 
| 93 | }); | 63 | }); | 
| 64 | + watch( | ||
| 65 | + () => props.alarmList, | ||
| 66 | + (newValue) => { | ||
| 67 | + console.log(newValue); | ||
| 68 | + setOptions({ | ||
| 69 | + tooltip: { | ||
| 70 | + trigger: 'axis', | ||
| 71 | + axisPointer: { | ||
| 72 | + lineStyle: { | ||
| 73 | + width: 1, | ||
| 74 | + color: '#019680', | ||
| 75 | + }, | ||
| 76 | + }, | ||
| 77 | + }, | ||
| 78 | + xAxis: { | ||
| 79 | + type: 'time', | ||
| 80 | + boundaryGap: false, | ||
| 81 | + splitLine: { | ||
| 82 | + show: true, | ||
| 83 | + lineStyle: { | ||
| 84 | + width: 1, | ||
| 85 | + type: 'solid', | ||
| 86 | + color: 'rgba(226,226,226,0.5)', | ||
| 87 | + }, | ||
| 88 | + }, | ||
| 89 | + axisTick: { | ||
| 90 | + show: false, | ||
| 91 | + }, | ||
| 92 | + }, | ||
| 93 | + yAxis: {}, | ||
| 94 | + grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, | ||
| 95 | + series: [ | ||
| 96 | + { | ||
| 97 | + smooth: true, | ||
| 98 | + data: newValue, | ||
| 99 | + type: 'line', | ||
| 100 | + areaStyle: {}, | ||
| 101 | + itemStyle: { | ||
| 102 | + color: '#5ab1ef', | ||
| 103 | + }, | ||
| 104 | + }, | ||
| 105 | + ], | ||
| 106 | + }); | ||
| 107 | + } | ||
| 108 | + ); | ||
| 94 | </script> | 109 | </script> | 
| @@ -2,57 +2,54 @@ | @@ -2,57 +2,54 @@ | ||
| 2 | <div ref="chartRef" :style="{ height, width }"></div> | 2 | <div ref="chartRef" :style="{ height, width }"></div> | 
| 3 | </template> | 3 | </template> | 
| 4 | <script lang="ts" setup> | 4 | <script lang="ts" setup> | 
| 5 | - import { onMounted, ref, Ref } from 'vue'; | 5 | + import { ref, Ref, watch, withDefaults, defineProps } from 'vue'; | 
| 6 | import { useECharts } from '/@/hooks/web/useECharts'; | 6 | import { useECharts } from '/@/hooks/web/useECharts'; | 
| 7 | - import { basicProps } from './props'; | ||
| 8 | - | ||
| 9 | - defineProps({ | ||
| 10 | - ...basicProps, | 7 | + type DataItem = [number, string]; | 
| 8 | + interface Props { | ||
| 9 | + width?: string; | ||
| 10 | + height?: string; | ||
| 11 | + dataPointList: DataItem[]; | ||
| 12 | + messageList: DataItem[]; | ||
| 13 | + } | ||
| 14 | + const props = withDefaults(defineProps<Props>(), { | ||
| 15 | + width: '100%', | ||
| 16 | + height: '280px', | ||
| 17 | + dataPointList: () => [], | ||
| 18 | + messageList: () => [], | ||
| 11 | }); | 19 | }); | 
| 12 | - | ||
| 13 | const chartRef = ref<HTMLDivElement | null>(null); | 20 | const chartRef = ref<HTMLDivElement | null>(null); | 
| 14 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); | 21 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); | 
| 15 | - onMounted(() => { | ||
| 16 | - setOptions({ | ||
| 17 | - tooltip: { | ||
| 18 | - trigger: 'axis', | ||
| 19 | - axisPointer: { | ||
| 20 | - lineStyle: { | ||
| 21 | - width: 1, | ||
| 22 | - color: '#019680', | ||
| 23 | - }, | 22 | + watch( | 
| 23 | + () => [props.dataPointList, props.messageList], | ||
| 24 | + ([newValue, newValue1]) => { | ||
| 25 | + setOptions({ | ||
| 26 | + tooltip: {}, | ||
| 27 | + xAxis: { | ||
| 28 | + type: 'time', | ||
| 24 | }, | 29 | }, | 
| 25 | - }, | ||
| 26 | - grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, | ||
| 27 | - xAxis: { | ||
| 28 | - type: 'category', | ||
| 29 | - data: [ | ||
| 30 | - '1月', | ||
| 31 | - '2月', | ||
| 32 | - '3月', | ||
| 33 | - '4月', | ||
| 34 | - '5月', | ||
| 35 | - '6月', | ||
| 36 | - '7月', | ||
| 37 | - '8月', | ||
| 38 | - '9月', | ||
| 39 | - '10月', | ||
| 40 | - '11月', | ||
| 41 | - '12月', | ||
| 42 | - ], | ||
| 43 | - }, | ||
| 44 | - yAxis: { | ||
| 45 | - type: 'value', | ||
| 46 | - max: 8000, | ||
| 47 | - splitNumber: 4, | ||
| 48 | - }, | ||
| 49 | - series: [ | ||
| 50 | - { | ||
| 51 | - data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800], | ||
| 52 | - type: 'bar', | ||
| 53 | - barMaxWidth: 80, | 30 | + legend: { | 
| 31 | + data: ['传输数据点', '传输消息量'], | ||
| 32 | + left: '10%', | ||
| 54 | }, | 33 | }, | 
| 55 | - ], | ||
| 56 | - }); | ||
| 57 | - }); | 34 | + yAxis: {}, | 
| 35 | + grid: { | ||
| 36 | + bottom: 100, | ||
| 37 | + }, | ||
| 38 | + series: [ | ||
| 39 | + { | ||
| 40 | + name: '传输数据点', | ||
| 41 | + type: 'bar', | ||
| 42 | + stack: 'one', | ||
| 43 | + data: newValue, | ||
| 44 | + }, | ||
| 45 | + { | ||
| 46 | + name: '传输消息量', | ||
| 47 | + type: 'bar', | ||
| 48 | + stack: 'one', | ||
| 49 | + data: newValue1, | ||
| 50 | + }, | ||
| 51 | + ], | ||
| 52 | + }); | ||
| 53 | + } | ||
| 54 | + ); | ||
| 58 | </script> | 55 | </script> | 
| @@ -3,9 +3,9 @@ | @@ -3,9 +3,9 @@ | ||
| 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" /> | 
| 6 | - <div class="md:flex enter-y" v-if="role === 'TENANT_ADMIN'"> | 6 | + <div class="md:flex enter-y" v-if="!isAdmin(role)"> | 
| 7 | <Card title="核心流程指南" style="width: 100%"> | 7 | <Card title="核心流程指南" style="width: 100%"> | 
| 8 | - <img alt="核心流程指南" src="../../../assets/images/flow.png" /> | 8 | + <img alt="核心流程指南" src="/src/assets/images/flow.png" /> | 
| 9 | </Card> | 9 | </Card> | 
| 10 | </div> | 10 | </div> | 
| 11 | </div> | 11 | </div> | 
| @@ -15,13 +15,18 @@ | @@ -15,13 +15,18 @@ | ||
| 15 | </div> | 15 | </div> | 
| 16 | </template> | 16 | </template> | 
| 17 | <script lang="ts" setup> | 17 | <script lang="ts" setup> | 
| 18 | - import { ref } from 'vue'; | 18 | + import { ref, defineExpose } from 'vue'; | 
| 19 | import GrowCard from './components/GrowCard.vue'; | 19 | import GrowCard from './components/GrowCard.vue'; | 
| 20 | import SiteAnalysis from './components/SiteAnalysis.vue'; | 20 | import SiteAnalysis from './components/SiteAnalysis.vue'; | 
| 21 | import { Card } from 'ant-design-vue'; | 21 | import { Card } from 'ant-design-vue'; | 
| 22 | import HelpDoc from './components/HelpDoc.vue'; | 22 | import HelpDoc from './components/HelpDoc.vue'; | 
| 23 | import { USER_INFO_KEY } from '/@/enums/cacheEnum'; | 23 | import { USER_INFO_KEY } from '/@/enums/cacheEnum'; | 
| 24 | import { getAuthCache } from '/@/utils/auth'; | 24 | import { getAuthCache } from '/@/utils/auth'; | 
| 25 | + import { isAdmin } from '/@/enums/roleEnum'; | ||
| 26 | + defineExpose({ | ||
| 27 | + isAdmin, | ||
| 28 | + }); | ||
| 29 | + | ||
| 25 | const userInfo: any = getAuthCache(USER_INFO_KEY); | 30 | const userInfo: any = getAuthCache(USER_INFO_KEY); | 
| 26 | const role = userInfo.roles[0]; | 31 | const role = userInfo.roles[0]; | 
| 27 | console.log(role); | 32 | console.log(role); | 
| @@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
| 24 | setup(props) { | 24 | setup(props) { | 
| 25 | const token: string = getAuthCache(JWT_TOKEN_KEY); | 25 | const token: string = getAuthCache(JWT_TOKEN_KEY); | 
| 26 | const state = reactive({ | 26 | const state = reactive({ | 
| 27 | - server: `ws://101.133.234.90:8080/api/ws/plugins/telemetry?token=${token}`, | 27 | + server: `${import.meta.env.VITE_WEB_SOCKET}${token}`, | 
| 28 | sendValue: JSON.stringify({ | 28 | sendValue: JSON.stringify({ | 
| 29 | attrSubCmds: [], | 29 | attrSubCmds: [], | 
| 30 | tsSubCmds: [ | 30 | tsSubCmds: [ | 
| @@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
| 16 | label: '删除', | 16 | label: '删除', | 
| 17 | icon: 'ant-design:delete-outlined', | 17 | icon: 'ant-design:delete-outlined', | 
| 18 | color: 'error', | 18 | color: 'error', | 
| 19 | - ifShow: record.roleType != RoleEnum.ROLE_SYS_ADMIN, | 19 | + ifShow: record.roleType != RoleEnum.SYS_ADMIN, | 
| 20 | popConfirm: { | 20 | popConfirm: { | 
| 21 | title: '是否确认删除', | 21 | title: '是否确认删除', | 
| 22 | confirm: handleDelete.bind(null, record), | 22 | confirm: handleDelete.bind(null, record), | 
| @@ -171,7 +171,7 @@ | @@ -171,7 +171,7 @@ | ||
| 171 | showIndexColumn: false, | 171 | showIndexColumn: false, | 
| 172 | searchInfo: { | 172 | searchInfo: { | 
| 173 | tenantId, | 173 | tenantId, | 
| 174 | - roleType: RoleEnum.ROLE_TENANT_ADMIN, | 174 | + roleType: RoleEnum.TENANT_ADMIN, | 
| 175 | }, | 175 | }, | 
| 176 | actionColumn: { | 176 | actionColumn: { | 
| 177 | width: 100, | 177 | width: 100, | 
| @@ -75,7 +75,7 @@ export const tenantFormSchema: FormSchema[] = [ | @@ -75,7 +75,7 @@ export const tenantFormSchema: FormSchema[] = [ | ||
| 75 | mode: 'multiple', | 75 | mode: 'multiple', | 
| 76 | api: getAllRoleList, | 76 | api: getAllRoleList, | 
| 77 | params: { | 77 | params: { | 
| 78 | - roleType: RoleEnum.ROLE_TENANT_ADMIN, | 78 | + roleType: RoleEnum.TENANT_ADMIN, | 
| 79 | }, | 79 | }, | 
| 80 | labelField: 'name', | 80 | labelField: 'name', | 
| 81 | valueField: 'id', | 81 | valueField: 'id', | 
| @@ -156,7 +156,7 @@ | @@ -156,7 +156,7 @@ | ||
| 156 | name: values.name, | 156 | name: values.name, | 
| 157 | remark: values.remark, | 157 | remark: values.remark, | 
| 158 | status: values.status, | 158 | status: values.status, | 
| 159 | - roleType: RoleEnum.ROLE_TENANT_ADMIN, | 159 | + roleType: RoleEnum.TENANT_ADMIN, | 
| 160 | menu: allCheckedKeys.value as string[], | 160 | menu: allCheckedKeys.value as string[], | 
| 161 | }; | 161 | }; | 
| 162 | console.log(req, '请求参数'); | 162 | console.log(req, '请求参数'); | 
| @@ -73,7 +73,7 @@ export const searchFormSchema: FormSchema[] = [ | @@ -73,7 +73,7 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 73 | label: '', | 73 | label: '', | 
| 74 | component: 'Input', | 74 | component: 'Input', | 
| 75 | colProps: { span: 8 }, | 75 | colProps: { span: 8 }, | 
| 76 | - defaultValue: RoleEnum.ROLE_TENANT_ADMIN, | 76 | + defaultValue: RoleEnum.TENANT_ADMIN, | 
| 77 | ifShow: false, | 77 | ifShow: false, | 
| 78 | }, | 78 | }, | 
| 79 | { | 79 | { |