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 | 6 | |
| 7 | 7 | # Cross-domain proxy, you can configure multiple |
| 8 | 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 | 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 | 19 | # Delete console |
| 14 | -VITE_DROP_CONSOLE = false | |
| 20 | +VITE_DROP_CONSOLE = true | |
| 15 | 21 | |
| 16 | 22 | # Basic interface address SPA |
| 17 | 23 | VITE_GLOB_API_URL=/api | ... | ... |
| ... | ... | @@ -17,7 +17,7 @@ enum Api { |
| 17 | 17 | export const getMenuList = () => { |
| 18 | 18 | const userStore = useUserStore(); |
| 19 | 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 | 21 | url = Api.SysAdminMenuList; |
| 22 | 22 | } |
| 23 | 23 | return defHttp.get<getMenuListResultModel>({ url }); | ... | ... |
| 1 | 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 | 38 | <div class="mr-4" |
| 39 | 39 | ><img |
| 40 | 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 | 43 | style="width: 5rem; height: 5rem" |
| 46 | 44 | /></div> |
| ... | ... | @@ -51,7 +49,7 @@ |
| 51 | 49 | }}</div> |
| 52 | 50 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> |
| 53 | 51 | </div> |
| 54 | - <div> {{ role === 'TENANT_ADMIN' ? '11月告警数(条)' : '租户总量(个)' }}</div> | |
| 52 | + <div> {{ !isAdmin(role) ? '11月告警数(条)' : '租户总量(个)' }}</div> | |
| 55 | 53 | </div> |
| 56 | 54 | </div> |
| 57 | 55 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
| ... | ... | @@ -62,11 +60,7 @@ |
| 62 | 60 | <div class="flex" style="height: 100px"> |
| 63 | 61 | <div class="mr-4" |
| 64 | 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 | 64 | style="width: 5rem; height: 5rem" |
| 71 | 65 | /></div> |
| 72 | 66 | <div class="flex-auto"> |
| ... | ... | @@ -76,7 +70,7 @@ |
| 76 | 70 | }}</div> |
| 77 | 71 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> |
| 78 | 72 | </div> |
| 79 | - <div> {{ role === 'TENANT_ADMIN' ? '11月消息量(条)' : '客户总量(个)' }} </div> | |
| 73 | + <div> {{ !isAdmin(role) ? '11月消息量(条)' : '客户总量(个)' }} </div> | |
| 80 | 74 | </div> |
| 81 | 75 | </div> |
| 82 | 76 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
| ... | ... | @@ -86,9 +80,16 @@ |
| 86 | 80 | </div> |
| 87 | 81 | </template> |
| 88 | 82 | <script lang="ts" setup> |
| 89 | - import { defineProps, ref, onMounted } from 'vue'; | |
| 83 | + import { defineProps, defineExpose, ref, onMounted } from 'vue'; | |
| 90 | 84 | import { Card } from 'ant-design-vue'; |
| 91 | 85 | import { getHomeData } from '/@/api/dashboard'; |
| 86 | + import { isAdmin } from '/@/enums/roleEnum'; | |
| 87 | + defineProps<{ | |
| 88 | + role: string; | |
| 89 | + }>(); | |
| 90 | + defineExpose({ | |
| 91 | + isAdmin, | |
| 92 | + }); | |
| 92 | 93 | interface CardList { |
| 93 | 94 | deviceInfo: { |
| 94 | 95 | sumCount: number; |
| ... | ... | @@ -104,9 +105,5 @@ |
| 104 | 105 | onMounted(async () => { |
| 105 | 106 | const res = await getHomeData(); |
| 106 | 107 | growCardList.value = res; |
| 107 | - console.log(growCardList.value); | |
| 108 | 108 | }); |
| 109 | - defineProps<{ | |
| 110 | - role: string; | |
| 111 | - }>(); | |
| 112 | 109 | </script> | ... | ... |
| 1 | 1 | <template> |
| 2 | 2 | <div> |
| 3 | - <Card title="帮助文档" v-if="role === 'TENANT_ADMIN'"> | |
| 3 | + <Card title="帮助文档" v-if="!isAdmin(role)"> | |
| 4 | 4 | <div> |
| 5 | 5 | <template v-for="item in helpDoc" :key="item.title"> |
| 6 | 6 | <AnchorLink v-bind="item" /> |
| 7 | 7 | </template> |
| 8 | 8 | </div> |
| 9 | 9 | <Card |
| 10 | - v-if="role === 'TENANT_ADMIN'" | |
| 10 | + v-if="!isAdmin(role)" | |
| 11 | 11 | :tab-list="tabListTitle" |
| 12 | 12 | v-bind="$attrs" |
| 13 | 13 | :active-tab-key="activeKey" |
| ... | ... | @@ -58,7 +58,7 @@ |
| 58 | 58 | </Card> |
| 59 | 59 | </Card> |
| 60 | 60 | |
| 61 | - <Card v-if="role !== 'TENANT_ADMIN'"> | |
| 61 | + <Card v-if="isAdmin(role)"> | |
| 62 | 62 | <Descriptions title="租户消息量TOP10" :column="1"> |
| 63 | 63 | <template v-for="(item, index) in 10" :key="index"> |
| 64 | 64 | <DescriptionsItem> |
| ... | ... | @@ -100,7 +100,7 @@ |
| 100 | 100 | </template> |
| 101 | 101 | </Descriptions> |
| 102 | 102 | </Card> |
| 103 | - <BasicTable @register="registerTable" v-if="role !== 'TENANT_ADMIN'" /> | |
| 103 | + <BasicTable @register="registerTable" v-if="isAdmin(role)" /> | |
| 104 | 104 | </div> |
| 105 | 105 | </template> |
| 106 | 106 | |
| ... | ... | @@ -124,6 +124,7 @@ |
| 124 | 124 | import { useGo } from '/@/hooks/web/usePage'; |
| 125 | 125 | import { BasicTable, useTable } from '/@/components/Table'; |
| 126 | 126 | import { columns } from './props'; |
| 127 | + import { isAdmin } from '/@/enums/roleEnum'; | |
| 127 | 128 | export default defineComponent({ |
| 128 | 129 | components: { |
| 129 | 130 | Card, |
| ... | ... | @@ -139,7 +140,10 @@ |
| 139 | 140 | DescriptionsItem, |
| 140 | 141 | }, |
| 141 | 142 | props: { |
| 142 | - role: String, | |
| 143 | + role: { | |
| 144 | + type: String, | |
| 145 | + required: true, | |
| 146 | + }, | |
| 143 | 147 | }, |
| 144 | 148 | setup(props) { |
| 145 | 149 | // 通知数据 |
| ... | ... | @@ -196,7 +200,7 @@ |
| 196 | 200 | return userStore.enterPriseInfo?.qrCode; |
| 197 | 201 | }); |
| 198 | 202 | onMounted(async () => { |
| 199 | - if (props.role !== 'TENANT_ADMIN') return; | |
| 203 | + if (isAdmin(props.role)) return; | |
| 200 | 204 | const res = await getEnterPriseDetail(); |
| 201 | 205 | const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 }); |
| 202 | 206 | userStore.setEnterPriseInfo(res); |
| ... | ... | @@ -215,6 +219,7 @@ |
| 215 | 219 | dataSource, |
| 216 | 220 | go, |
| 217 | 221 | registerTable, |
| 222 | + isAdmin, | |
| 218 | 223 | }; |
| 219 | 224 | }, |
| 220 | 225 | }); | ... | ... |
| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | :active-tab-key="activeKey" |
| 6 | 6 | @tabChange="onTabChange" |
| 7 | 7 | > |
| 8 | - <template #tabBarExtraContent v-if="role === 'TENANT_ADMIN'"> | |
| 8 | + <template #tabBarExtraContent v-if="!isAdmin(role)"> | |
| 9 | 9 | <div class="extra-date"> |
| 10 | 10 | <template v-for="(item, index) in dateList" :key="item"> |
| 11 | 11 | <span @click="changeDate(index)" :class="{ active: index === activeIndex }">{{ |
| ... | ... | @@ -15,53 +15,275 @@ |
| 15 | 15 | <DatePicker @change="onDateChange" /> |
| 16 | 16 | </div> |
| 17 | 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 | 21 | <VisitAnalysisBar v-else /> |
| 22 | 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 | 26 | </div> |
| 27 | 27 | </Card> |
| 28 | + <Card v-bind="$attrs" :tab-list="tab1ListTitle" v-if="isAdmin(role)"> | |
| 29 | + <p class="center">客户趋势</p> | |
| 30 | + <VisitAnalysis | |
| 31 | + /></Card> | |
| 28 | 32 | </template> |
| 29 | 33 | <script lang="ts" setup> |
| 30 | - import { ref } from 'vue'; | |
| 34 | + import { ref, defineExpose, reactive } from 'vue'; | |
| 31 | 35 | import { Card, DatePicker } from 'ant-design-vue'; |
| 32 | 36 | import VisitAnalysis from './VisitAnalysis.vue'; |
| 33 | 37 | import VisitAnalysisBar from './VisitAnalysisBar.vue'; |
| 34 | 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 | 47 | const props = defineProps<{ |
| 37 | 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 | 288 | function onDateChange(date, dateString) { |
| 67 | 289 | console.log(date, dateString); | ... | ... |
| ... | ... | @@ -2,17 +2,25 @@ |
| 2 | 2 | <div ref="chartRef" :style="{ height, width }"></div> |
| 3 | 3 | </template> |
| 4 | 4 | <script lang="ts" setup> |
| 5 | - import { onMounted, ref, Ref } from 'vue'; | |
| 5 | + import { onMounted, ref, Ref, withDefaults, defineProps, watch } from 'vue'; | |
| 6 | 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 | 19 | const chartRef = ref<HTMLDivElement | null>(null); |
| 13 | 20 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
| 14 | 21 | |
| 15 | 22 | onMounted(() => { |
| 23 | + console.log(props.alarmList); | |
| 16 | 24 | setOptions({ |
| 17 | 25 | tooltip: { |
| 18 | 26 | trigger: 'axis', |
| ... | ... | @@ -24,28 +32,8 @@ |
| 24 | 32 | }, |
| 25 | 33 | }, |
| 26 | 34 | xAxis: { |
| 27 | - type: 'category', | |
| 35 | + type: 'time', | |
| 28 | 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 | 37 | splitLine: { |
| 50 | 38 | show: true, |
| 51 | 39 | lineStyle: { |
| ... | ... | @@ -58,30 +46,12 @@ |
| 58 | 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 | 50 | grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, |
| 78 | 51 | series: [ |
| 79 | 52 | { |
| 80 | 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 | 55 | type: 'line', |
| 86 | 56 | areaStyle: {}, |
| 87 | 57 | itemStyle: { |
| ... | ... | @@ -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 | 109 | </script> | ... | ... |
| ... | ... | @@ -2,57 +2,54 @@ |
| 2 | 2 | <div ref="chartRef" :style="{ height, width }"></div> |
| 3 | 3 | </template> |
| 4 | 4 | <script lang="ts" setup> |
| 5 | - import { onMounted, ref, Ref } from 'vue'; | |
| 5 | + import { ref, Ref, watch, withDefaults, defineProps } from 'vue'; | |
| 6 | 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 | 20 | const chartRef = ref<HTMLDivElement | null>(null); |
| 14 | 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 | 55 | </script> | ... | ... |
| ... | ... | @@ -3,9 +3,9 @@ |
| 3 | 3 | <div class="md:w-7/10 w-full !mr-4 enter-y"> |
| 4 | 4 | <GrowCard :loading="loading" class="enter-y" :role="role" /> |
| 5 | 5 | <SiteAnalysis class="!my-4 enter-y" :loading="loading" :role="role" /> |
| 6 | - <div class="md:flex enter-y" v-if="role === 'TENANT_ADMIN'"> | |
| 6 | + <div class="md:flex enter-y" v-if="!isAdmin(role)"> | |
| 7 | 7 | <Card title="核心流程指南" style="width: 100%"> |
| 8 | - <img alt="核心流程指南" src="../../../assets/images/flow.png" /> | |
| 8 | + <img alt="核心流程指南" src="/src/assets/images/flow.png" /> | |
| 9 | 9 | </Card> |
| 10 | 10 | </div> |
| 11 | 11 | </div> |
| ... | ... | @@ -15,13 +15,18 @@ |
| 15 | 15 | </div> |
| 16 | 16 | </template> |
| 17 | 17 | <script lang="ts" setup> |
| 18 | - import { ref } from 'vue'; | |
| 18 | + import { ref, defineExpose } from 'vue'; | |
| 19 | 19 | import GrowCard from './components/GrowCard.vue'; |
| 20 | 20 | import SiteAnalysis from './components/SiteAnalysis.vue'; |
| 21 | 21 | import { Card } from 'ant-design-vue'; |
| 22 | 22 | import HelpDoc from './components/HelpDoc.vue'; |
| 23 | 23 | import { USER_INFO_KEY } from '/@/enums/cacheEnum'; |
| 24 | 24 | import { getAuthCache } from '/@/utils/auth'; |
| 25 | + import { isAdmin } from '/@/enums/roleEnum'; | |
| 26 | + defineExpose({ | |
| 27 | + isAdmin, | |
| 28 | + }); | |
| 29 | + | |
| 25 | 30 | const userInfo: any = getAuthCache(USER_INFO_KEY); |
| 26 | 31 | const role = userInfo.roles[0]; |
| 27 | 32 | console.log(role); | ... | ... |
| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | setup(props) { |
| 25 | 25 | const token: string = getAuthCache(JWT_TOKEN_KEY); |
| 26 | 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 | 28 | sendValue: JSON.stringify({ |
| 29 | 29 | attrSubCmds: [], |
| 30 | 30 | tsSubCmds: [ | ... | ... |
| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | label: '删除', |
| 17 | 17 | icon: 'ant-design:delete-outlined', |
| 18 | 18 | color: 'error', |
| 19 | - ifShow: record.roleType != RoleEnum.ROLE_SYS_ADMIN, | |
| 19 | + ifShow: record.roleType != RoleEnum.SYS_ADMIN, | |
| 20 | 20 | popConfirm: { |
| 21 | 21 | title: '是否确认删除', |
| 22 | 22 | confirm: handleDelete.bind(null, record), | ... | ... |
| ... | ... | @@ -156,7 +156,7 @@ |
| 156 | 156 | name: values.name, |
| 157 | 157 | remark: values.remark, |
| 158 | 158 | status: values.status, |
| 159 | - roleType: RoleEnum.ROLE_TENANT_ADMIN, | |
| 159 | + roleType: RoleEnum.TENANT_ADMIN, | |
| 160 | 160 | menu: allCheckedKeys.value as string[], |
| 161 | 161 | }; |
| 162 | 162 | console.log(req, '请求参数'); | ... | ... |