Commit 6984fb1f5bec0dbc364e9da98c777f651090ad10
1 parent
7c87f4b7
'fix:优化未查到数据界面,修复用户详情404问题,改为静态路由,首页增加过滤时间'
Showing
14 changed files
with
149 additions
and
128 deletions
... | ... | @@ -16,11 +16,11 @@ VITE_BUILD_COMPRESS = 'gzip' |
16 | 16 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false |
17 | 17 | |
18 | 18 | # Basic interface address SPA |
19 | -VITE_GLOB_API_URL=http://localhost:8080/api | |
19 | +VITE_GLOB_API_URL=http://101.133.234.90:8080/api | |
20 | 20 | |
21 | 21 | # File upload address, optional |
22 | 22 | # It can be forwarded by nginx or write the actual address directly |
23 | -VITE_GLOB_UPLOAD_URL=http://localhost:8080/upload | |
23 | +VITE_GLOB_UPLOAD_URL=http://101.133.234.90:8080/upload | |
24 | 24 | |
25 | 25 | # Interface prefix |
26 | 26 | VITE_GLOB_API_URL_PREFIX=/yt | ... | ... |
... | ... | @@ -158,10 +158,10 @@ export const dispatchCustomer = (data) => { |
158 | 158 | }; |
159 | 159 | // 取消分配客户 |
160 | 160 | export const cancelDispatchCustomer = (data) => { |
161 | - const { customerId, tbDeviceId } = data; | |
161 | + const { tbDeviceId } = data; | |
162 | 162 | return defHttp.delete( |
163 | 163 | { |
164 | - url: `/customer/${customerId}/device/${tbDeviceId}`, | |
164 | + url: `/customer/device/${tbDeviceId}`, | |
165 | 165 | }, |
166 | 166 | { |
167 | 167 | joinPrefix: false, | ... | ... |
... | ... | @@ -14,8 +14,9 @@ import { setupStore } from '/@/store'; |
14 | 14 | import { setupGlobDirectives } from '/@/directives'; |
15 | 15 | import { setupI18n } from '/@/locales/setupI18n'; |
16 | 16 | import { registerGlobComp } from '/@/components/registerGlobComp'; |
17 | -import 'ant-design-vue/dist/antd.less'; | |
18 | - | |
17 | +if (import.meta.env.DEV) { | |
18 | + import('ant-design-vue/dist/antd.less'); | |
19 | +} | |
19 | 20 | async function bootstrap() { |
20 | 21 | const app = createApp(App); |
21 | 22 | ... | ... |
... | ... | @@ -76,31 +76,3 @@ export const ERROR_LOG_ROUTE: AppRouteRecordRaw = { |
76 | 76 | }, |
77 | 77 | ], |
78 | 78 | }; |
79 | - | |
80 | -// export const UPDATE_SYSTEM_PASSWORD: AppRouteRecordRaw = { | |
81 | -// path: '/system', | |
82 | -// name: 'routes.common.system.system', | |
83 | -// component: LAYOUT, | |
84 | -// redirect: '/system/systemManagement', | |
85 | -// meta: { | |
86 | -// icon: 'bx:bx-home', | |
87 | -// title: 'routes.common.system.system', | |
88 | -// status: '0', | |
89 | -// menuType: '0', | |
90 | -// }, | |
91 | -// children: [ | |
92 | -// { | |
93 | -// path: '/system/password', | |
94 | -// name: 'routes.common.system.modifyPassword', | |
95 | -// component: () => import('/@/views/system/password/index.vue'), | |
96 | -// meta: { | |
97 | -// icon: 'bx:bx-home', | |
98 | -// title: 'routes.common.system.modifyPassword', | |
99 | -// menuType: '1', | |
100 | -// ignoreKeepAlive: true, | |
101 | -// hideMenu: false, | |
102 | -// status: '0', | |
103 | -// }, | |
104 | -// }, | |
105 | -// ], | |
106 | -// }; | ... | ... |
... | ... | @@ -5,6 +5,7 @@ import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic'; |
5 | 5 | import { mainOutRoutes } from './mainOut'; |
6 | 6 | import { PageEnum } from '/@/enums/pageEnum'; |
7 | 7 | import { t } from '/@/hooks/web/useI18n'; |
8 | +import { LAYOUT } from '../constant'; | |
8 | 9 | |
9 | 10 | const modules = import.meta.globEager('./modules/**/*.ts'); |
10 | 11 | |
... | ... | @@ -39,10 +40,33 @@ export const LoginRoute: AppRouteRecordRaw = { |
39 | 40 | }, |
40 | 41 | }; |
41 | 42 | |
43 | +// 用户详情静态路由 | |
44 | +export const AccountDetail: AppRouteRecordRaw = { | |
45 | + path: '/system', | |
46 | + name: '系统管理', | |
47 | + component: LAYOUT, | |
48 | + meta: { | |
49 | + title: '系统管理', | |
50 | + hideBreadcrumb: true, | |
51 | + hideChildrenInMenu: true, | |
52 | + }, | |
53 | + children: [ | |
54 | + { | |
55 | + path: 'account_detail/:id', | |
56 | + name: 'Account_Detail', | |
57 | + component: () => import('/@/views/system/account/AccountDetail.vue'), | |
58 | + meta: { | |
59 | + title: '用户详情', | |
60 | + }, | |
61 | + }, | |
62 | + ], | |
63 | +}; | |
64 | + | |
42 | 65 | // Basic routing without permission |
43 | 66 | export const basicRoutes = [ |
44 | 67 | LoginRoute, |
45 | 68 | RootRoute, |
69 | + AccountDetail, | |
46 | 70 | ...mainOutRoutes, |
47 | 71 | REDIRECT_ROUTE, |
48 | 72 | PAGE_NOT_FOUND_ROUTE, | ... | ... |
src/router/routes/modules/about.ts
deleted
100644 → 0
1 | -// import type { AppRouteModule } from '/@/router/types'; | |
2 | - | |
3 | -// import { LAYOUT } from '/@/router/constant'; | |
4 | -// import { t } from '/@/hooks/web/useI18n'; | |
5 | - | |
6 | -// const dashboard: AppRouteModule = { | |
7 | -// path: '/about', | |
8 | -// name: 'About', | |
9 | -// component: LAYOUT, | |
10 | -// redirect: '/about/index', | |
11 | -// meta: { | |
12 | -// hideChildrenInMenu: true, | |
13 | -// icon: 'simple-icons:about-dot-me', | |
14 | -// title: t('routes.dashboard.about'), | |
15 | -// orderNo: 100000, | |
16 | -// }, | |
17 | -// children: [ | |
18 | -// { | |
19 | -// path: 'index', | |
20 | -// name: 'AboutPage', | |
21 | -// component: () => import('/@/views/sys/about/index.vue'), | |
22 | -// meta: { | |
23 | -// title: t('routes.dashboard.about'), | |
24 | -// icon: 'simple-icons:about-dot-me', | |
25 | -// hideMenu: true, | |
26 | -// }, | |
27 | -// }, | |
28 | -// ], | |
29 | -// }; | |
30 | - | |
31 | -// export default dashboard; |
src/router/routes/modules/dashboard.ts
deleted
100644 → 0
1 | -// import type { AppRouteModule } from '/@/router/types'; | |
2 | - | |
3 | -// import { LAYOUT } from '/@/router/constant'; | |
4 | -// import { t } from '/@/hooks/web/useI18n'; | |
5 | - | |
6 | -// const dashboard: AppRouteModule = { | |
7 | -// path: '/dashboard', | |
8 | -// name: 'Dashboard', | |
9 | -// component: LAYOUT, | |
10 | -// redirect: '/dashboard/analysis', | |
11 | -// meta: { | |
12 | -// orderNo: 10, | |
13 | -// icon: 'ion:grid-outline', | |
14 | -// title: t('routes.dashboard.dashboard'), | |
15 | -// }, | |
16 | -// children: [ | |
17 | -// { | |
18 | -// path: 'analysis', | |
19 | -// name: 'Analysis', | |
20 | -// component: () => import('/@/views/dashboard/analysis/index.vue'), | |
21 | -// meta: { | |
22 | -// // affix: true, | |
23 | -// title: t('routes.dashboard.analysis'), | |
24 | -// }, | |
25 | -// }, | |
26 | -// { | |
27 | -// path: 'workbench', | |
28 | -// name: 'Workbench', | |
29 | -// component: () => import('/@/views/dashboard/workbench/index.vue'), | |
30 | -// meta: { | |
31 | -// title: t('routes.dashboard.workbench'), | |
32 | -// }, | |
33 | -// }, | |
34 | -// ], | |
35 | -// }; | |
36 | - | |
37 | -// export default dashboard; |
... | ... | @@ -34,13 +34,7 @@ |
34 | 34 | :canFullscreen="false" |
35 | 35 | > |
36 | 36 | <BasicForm @register="registerForm" /> |
37 | - <Alert | |
38 | - v-if="!isNull" | |
39 | - message="当前时间节点暂无历史数据" | |
40 | - description="请尝试选择其他时间段查询历史数据" | |
41 | - type="warning" | |
42 | - show-icon | |
43 | - /> | |
37 | + <Empty v-if="!isNull" /> | |
44 | 38 | <div v-show="isNull" ref="chartRef" :style="{ height: '600px', width }"></div> |
45 | 39 | </BasicModal> |
46 | 40 | <DeviceDetailDrawer @register="registerDetailDrawer" /> |
... | ... | @@ -52,7 +46,7 @@ |
52 | 46 | import { formSchema, columns } from './config.data'; |
53 | 47 | import { BasicTable, useTable } from '/@/components/Table'; |
54 | 48 | import { devicePage } from '/@/api/alarm/contact/alarmContact'; |
55 | - import { Tag, Alert } from 'ant-design-vue'; | |
49 | + import { Tag, Empty } from 'ant-design-vue'; | |
56 | 50 | import { DeviceState } from '/@/api/device/model/deviceModel'; |
57 | 51 | import { BAI_DU_MAP_URL } from '/@/utils/fnUtils'; |
58 | 52 | import { useModal, BasicModal } from '/@/components/Modal'; |
... | ... | @@ -72,7 +66,7 @@ |
72 | 66 | components: { |
73 | 67 | BasicTable, |
74 | 68 | Tag, |
75 | - Alert, | |
69 | + Empty, | |
76 | 70 | BasicModal, |
77 | 71 | BasicForm, |
78 | 72 | DeviceDetailDrawer, | ... | ... |
... | ... | @@ -27,12 +27,46 @@ |
27 | 27 | <VisitAnalysisBar :dataPointList="state.dataPointList" :messageList="state.messageList" /> |
28 | 28 | </div> |
29 | 29 | </Card> |
30 | - <Card v-bind="$attrs" v-if="isAdmin(role)" title="租户趋势"> | |
31 | - <TenantTrend /> | |
32 | - </Card> | |
33 | - <Card v-bind="$attrs" v-if="isAdmin(role)" title="客户趋势"> | |
34 | - <CustomerTrend /> | |
35 | - </Card> | |
30 | + <div v-if="isAdmin(role)"> | |
31 | + <Card v-bind="$attrs" title="租户趋势"> | |
32 | + <template #extra> | |
33 | + <div class="extra-date"> | |
34 | + <template v-for="(item, index) in TenantOrCustomerDateList" :key="item.value"> | |
35 | + <span | |
36 | + @click="quickQueryTenantOrCustomerTime(index, item.value, 'tenant')" | |
37 | + :class="{ active: index === activeTenantIndex }" | |
38 | + >{{ item.label }}</span | |
39 | + > | |
40 | + </template> | |
41 | + <DatePicker.RangePicker | |
42 | + @change="onDateTenantChange" | |
43 | + size="small" | |
44 | + v-model:value="tenantDateValue" | |
45 | + /> | |
46 | + </div> | |
47 | + </template> | |
48 | + <TenantTrend /> | |
49 | + </Card> | |
50 | + <Card v-bind="$attrs" title="客户趋势"> | |
51 | + <template #extra> | |
52 | + <div class="extra-date"> | |
53 | + <template v-for="(item, index) in TenantOrCustomerDateList" :key="item.value"> | |
54 | + <span | |
55 | + @click="quickQueryTenantOrCustomerTime(index, item.value, 'customer')" | |
56 | + :class="{ active: index === activeCustomerIndex }" | |
57 | + >{{ item.label }}</span | |
58 | + > | |
59 | + </template> | |
60 | + <DatePicker.RangePicker | |
61 | + @change="onDateCustomerChange" | |
62 | + size="small" | |
63 | + v-model:value="customerDateValue" | |
64 | + /> | |
65 | + </div> | |
66 | + </template> | |
67 | + <CustomerTrend /> | |
68 | + </Card> | |
69 | + </div> | |
36 | 70 | </template> |
37 | 71 | <script lang="ts" setup> |
38 | 72 | import { ref, reactive } from 'vue'; |
... | ... | @@ -42,11 +76,12 @@ |
42 | 76 | import { isAdmin } from '/@/enums/roleEnum'; |
43 | 77 | import { useWebSocket } from '@vueuse/core'; |
44 | 78 | import { getAuthCache } from '/@/utils/auth'; |
45 | - import CustomerTrend from './CustomerTrend.vue'; | |
46 | - import TenantTrend from './TenantTrend.vue'; | |
47 | 79 | import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; |
48 | 80 | import { formatToDateTime } from '/@/utils/dateUtil'; |
49 | 81 | import { getEntitiesId } from '/@/api/dashboard/index'; |
82 | + import CustomerTrend from './CustomerTrend.vue'; | |
83 | + import TenantTrend from './TenantTrend.vue'; | |
84 | + import { useDate } from '../hooks/useDate'; | |
50 | 85 | defineExpose({ |
51 | 86 | isAdmin, |
52 | 87 | }); |
... | ... | @@ -75,6 +110,7 @@ |
75 | 110 | { label: '7天', value: 604800000 }, |
76 | 111 | { label: '30天', value: 2592000000 }, |
77 | 112 | ]); |
113 | + | |
78 | 114 | // web Socket |
79 | 115 | const token: string = getAuthCache(JWT_TOKEN_KEY); |
80 | 116 | const state = reactive({ |
... | ... | @@ -342,6 +378,17 @@ |
342 | 378 | |
343 | 379 | console.log(JSON.parse(sendValue), '----interval', state.alarmList); |
344 | 380 | } |
381 | + | |
382 | + const { | |
383 | + tenantDateValue, | |
384 | + customerDateValue, | |
385 | + activeTenantIndex, | |
386 | + activeCustomerIndex, | |
387 | + TenantOrCustomerDateList, | |
388 | + quickQueryTenantOrCustomerTime, | |
389 | + onDateTenantChange, | |
390 | + onDateCustomerChange, | |
391 | + } = useDate(); | |
345 | 392 | </script> |
346 | 393 | |
347 | 394 | <style lang="less"> | ... | ... |
... | ... | @@ -2,13 +2,13 @@ |
2 | 2 | <div> |
3 | 3 | <p class="center">告警数</p> |
4 | 4 | <div ref="chartRef" :style="{ height, width }" v-show="alarmList.length"></div> |
5 | - <div v-show="!alarmList.length">暂无数据</div> | |
5 | + <div v-show="!alarmList.length"><Empty /></div> | |
6 | 6 | </div> |
7 | 7 | </template> |
8 | 8 | <script lang="ts" setup> |
9 | 9 | import { onMounted, ref, Ref, withDefaults, watch } from 'vue'; |
10 | 10 | import { useECharts } from '/@/hooks/web/useECharts'; |
11 | - | |
11 | + import { Empty } from 'ant-design-vue'; | |
12 | 12 | interface Props { |
13 | 13 | width?: string; |
14 | 14 | height?: string; | ... | ... |
... | ... | @@ -2,12 +2,13 @@ |
2 | 2 | <div> |
3 | 3 | <p class="center">消息量</p> |
4 | 4 | <div ref="chartRef" :style="{ height, width }" v-show="dataPointList.length"></div> |
5 | - <div v-show="!dataPointList.length">暂无数据</div> | |
5 | + <div v-show="!dataPointList.length"><Empty /></div> | |
6 | 6 | </div> |
7 | 7 | </template> |
8 | 8 | <script lang="ts" setup> |
9 | 9 | import { ref, Ref, watch, withDefaults } from 'vue'; |
10 | 10 | import { useECharts } from '/@/hooks/web/useECharts'; |
11 | + import { Empty } from 'ant-design-vue'; | |
11 | 12 | type DataItem = [number, string]; |
12 | 13 | interface Props { |
13 | 14 | width?: string; | ... | ... |
1 | +import { ref } from 'vue'; | |
2 | +export function useDate() { | |
3 | + const tenantDateValue = ref([]); | |
4 | + const customerDateValue = ref([]); | |
5 | + const activeTenantIndex = ref(0); | |
6 | + const activeCustomerIndex = ref(0); | |
7 | + const TenantOrCustomerDateList = ref([ | |
8 | + { label: '30天', value: 2592000000 }, | |
9 | + { label: '最近三个月', value: 7776000000 }, | |
10 | + { label: '最近一年', value: 31536000000 }, | |
11 | + ]); | |
12 | + | |
13 | + // 租户趋势和客户趋势快速选择时间 | |
14 | + function quickQueryTenantOrCustomerTime( | |
15 | + index: number, | |
16 | + value: number, | |
17 | + flag: 'tenant' | 'customer' | |
18 | + ) { | |
19 | + if (flag === 'tenant') { | |
20 | + if (activeTenantIndex.value === index) return; | |
21 | + activeTenantIndex.value = index; | |
22 | + tenantDateValue.value = []; | |
23 | + console.log(value); | |
24 | + } else { | |
25 | + if (activeCustomerIndex.value === index) return; | |
26 | + activeCustomerIndex.value = index; | |
27 | + customerDateValue.value = []; | |
28 | + console.log(value); | |
29 | + } | |
30 | + } | |
31 | + // 租户选择日期 | |
32 | + function onDateTenantChange(_, dateString) { | |
33 | + activeTenantIndex.value = -1; | |
34 | + console.log(dateString); | |
35 | + } | |
36 | + // 客户趋势选择日期 | |
37 | + function onDateCustomerChange(_, dateString) { | |
38 | + activeCustomerIndex.value = -1; | |
39 | + console.log(dateString); | |
40 | + } | |
41 | + return { | |
42 | + tenantDateValue, | |
43 | + customerDateValue, | |
44 | + activeTenantIndex, | |
45 | + activeCustomerIndex, | |
46 | + TenantOrCustomerDateList, | |
47 | + quickQueryTenantOrCustomerTime, | |
48 | + onDateTenantChange, | |
49 | + onDateCustomerChange, | |
50 | + }; | |
51 | +} | ... | ... |
... | ... | @@ -52,17 +52,17 @@ |
52 | 52 | :actions="[ |
53 | 53 | record.customerId |
54 | 54 | ? { |
55 | - tooltip: '取消分配给客户', | |
55 | + label: '取消分配', | |
56 | 56 | icon: 'mdi:account-arrow-left', |
57 | 57 | ifShow: authBtn(role), |
58 | 58 | popConfirm: { |
59 | - title: '是否取消分配给客户', | |
59 | + title: '是否取消分配客户', | |
60 | 60 | confirm: handleCancelDispatchCustomer.bind(null, record), |
61 | 61 | }, |
62 | 62 | } |
63 | 63 | : { |
64 | + label: '分配客户', | |
64 | 65 | icon: 'mdi:account-arrow-right', |
65 | - tooltip: '分配给客户', | |
66 | 66 | ifShow: authBtn(role), |
67 | 67 | onClick: handleDispatchCustomer.bind(null, record), |
68 | 68 | }, |
... | ... | @@ -156,7 +156,7 @@ |
156 | 156 | showIndexColumn: false, |
157 | 157 | searchInfo: searchInfo, |
158 | 158 | actionColumn: { |
159 | - width: 250, | |
159 | + width: 300, | |
160 | 160 | title: '操作', |
161 | 161 | dataIndex: 'action', |
162 | 162 | slots: { customRender: 'action' }, |
... | ... | @@ -179,7 +179,7 @@ |
179 | 179 | // 取消分配客户 |
180 | 180 | async function handleCancelDispatchCustomer(record: Recordable) { |
181 | 181 | console.log('record', record); |
182 | - await cancelDispatchCustomer({ ...record, customerId: '' }); | |
182 | + await cancelDispatchCustomer(record); | |
183 | 183 | handleSuccess(); |
184 | 184 | } |
185 | 185 | ... | ... |