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, '请求参数'); | ... | ... |