Commit 6984fb1f5bec0dbc364e9da98c777f651090ad10

Authored by sqy
1 parent 7c87f4b7

'fix:优化未查到数据界面,修复用户详情404问题,改为静态路由,首页增加过滤时间'

@@ -16,11 +16,11 @@ VITE_BUILD_COMPRESS = 'gzip' @@ -16,11 +16,11 @@ VITE_BUILD_COMPRESS = 'gzip'
16 VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false 16 VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
17 17
18 # Basic interface address SPA 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 # File upload address, optional 21 # File upload address, optional
22 # It can be forwarded by nginx or write the actual address directly 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 # Interface prefix 25 # Interface prefix
26 VITE_GLOB_API_URL_PREFIX=/yt 26 VITE_GLOB_API_URL_PREFIX=/yt
@@ -158,10 +158,10 @@ export const dispatchCustomer = (data) => { @@ -158,10 +158,10 @@ export const dispatchCustomer = (data) => {
158 }; 158 };
159 // 取消分配客户 159 // 取消分配客户
160 export const cancelDispatchCustomer = (data) => { 160 export const cancelDispatchCustomer = (data) => {
161 - const { customerId, tbDeviceId } = data; 161 + const { tbDeviceId } = data;
162 return defHttp.delete( 162 return defHttp.delete(
163 { 163 {
164 - url: `/customer/${customerId}/device/${tbDeviceId}`, 164 + url: `/customer/device/${tbDeviceId}`,
165 }, 165 },
166 { 166 {
167 joinPrefix: false, 167 joinPrefix: false,
@@ -14,8 +14,9 @@ import { setupStore } from '/@/store'; @@ -14,8 +14,9 @@ import { setupStore } from '/@/store';
14 import { setupGlobDirectives } from '/@/directives'; 14 import { setupGlobDirectives } from '/@/directives';
15 import { setupI18n } from '/@/locales/setupI18n'; 15 import { setupI18n } from '/@/locales/setupI18n';
16 import { registerGlobComp } from '/@/components/registerGlobComp'; 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 async function bootstrap() { 20 async function bootstrap() {
20 const app = createApp(App); 21 const app = createApp(App);
21 22
@@ -76,31 +76,3 @@ export const ERROR_LOG_ROUTE: AppRouteRecordRaw = { @@ -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,6 +5,7 @@ import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic';
5 import { mainOutRoutes } from './mainOut'; 5 import { mainOutRoutes } from './mainOut';
6 import { PageEnum } from '/@/enums/pageEnum'; 6 import { PageEnum } from '/@/enums/pageEnum';
7 import { t } from '/@/hooks/web/useI18n'; 7 import { t } from '/@/hooks/web/useI18n';
  8 +import { LAYOUT } from '../constant';
8 9
9 const modules = import.meta.globEager('./modules/**/*.ts'); 10 const modules = import.meta.globEager('./modules/**/*.ts');
10 11
@@ -39,10 +40,33 @@ export const LoginRoute: AppRouteRecordRaw = { @@ -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 // Basic routing without permission 65 // Basic routing without permission
43 export const basicRoutes = [ 66 export const basicRoutes = [
44 LoginRoute, 67 LoginRoute,
45 RootRoute, 68 RootRoute,
  69 + AccountDetail,
46 ...mainOutRoutes, 70 ...mainOutRoutes,
47 REDIRECT_ROUTE, 71 REDIRECT_ROUTE,
48 PAGE_NOT_FOUND_ROUTE, 72 PAGE_NOT_FOUND_ROUTE,
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;  
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,13 +34,7 @@
34 :canFullscreen="false" 34 :canFullscreen="false"
35 > 35 >
36 <BasicForm @register="registerForm" /> 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 <div v-show="isNull" ref="chartRef" :style="{ height: '600px', width }"></div> 38 <div v-show="isNull" ref="chartRef" :style="{ height: '600px', width }"></div>
45 </BasicModal> 39 </BasicModal>
46 <DeviceDetailDrawer @register="registerDetailDrawer" /> 40 <DeviceDetailDrawer @register="registerDetailDrawer" />
@@ -52,7 +46,7 @@ @@ -52,7 +46,7 @@
52 import { formSchema, columns } from './config.data'; 46 import { formSchema, columns } from './config.data';
53 import { BasicTable, useTable } from '/@/components/Table'; 47 import { BasicTable, useTable } from '/@/components/Table';
54 import { devicePage } from '/@/api/alarm/contact/alarmContact'; 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 import { DeviceState } from '/@/api/device/model/deviceModel'; 50 import { DeviceState } from '/@/api/device/model/deviceModel';
57 import { BAI_DU_MAP_URL } from '/@/utils/fnUtils'; 51 import { BAI_DU_MAP_URL } from '/@/utils/fnUtils';
58 import { useModal, BasicModal } from '/@/components/Modal'; 52 import { useModal, BasicModal } from '/@/components/Modal';
@@ -72,7 +66,7 @@ @@ -72,7 +66,7 @@
72 components: { 66 components: {
73 BasicTable, 67 BasicTable,
74 Tag, 68 Tag,
75 - Alert, 69 + Empty,
76 BasicModal, 70 BasicModal,
77 BasicForm, 71 BasicForm,
78 DeviceDetailDrawer, 72 DeviceDetailDrawer,
@@ -58,7 +58,6 @@ export const searchFormSchema: FormSchema[] = [ @@ -58,7 +58,6 @@ export const searchFormSchema: FormSchema[] = [
58 componentProps: { 58 componentProps: {
59 maxLength: 36, 59 maxLength: 36,
60 placeholder: '请输入联系人姓名', 60 placeholder: '请输入联系人姓名',
61 - maxLength: 36,  
62 }, 61 },
63 }, 62 },
64 ]; 63 ];
@@ -27,12 +27,46 @@ @@ -27,12 +27,46 @@
27 <VisitAnalysisBar :dataPointList="state.dataPointList" :messageList="state.messageList" /> 27 <VisitAnalysisBar :dataPointList="state.dataPointList" :messageList="state.messageList" />
28 </div> 28 </div>
29 </Card> 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 </template> 70 </template>
37 <script lang="ts" setup> 71 <script lang="ts" setup>
38 import { ref, reactive } from 'vue'; 72 import { ref, reactive } from 'vue';
@@ -42,11 +76,12 @@ @@ -42,11 +76,12 @@
42 import { isAdmin } from '/@/enums/roleEnum'; 76 import { isAdmin } from '/@/enums/roleEnum';
43 import { useWebSocket } from '@vueuse/core'; 77 import { useWebSocket } from '@vueuse/core';
44 import { getAuthCache } from '/@/utils/auth'; 78 import { getAuthCache } from '/@/utils/auth';
45 - import CustomerTrend from './CustomerTrend.vue';  
46 - import TenantTrend from './TenantTrend.vue';  
47 import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; 79 import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';
48 import { formatToDateTime } from '/@/utils/dateUtil'; 80 import { formatToDateTime } from '/@/utils/dateUtil';
49 import { getEntitiesId } from '/@/api/dashboard/index'; 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 defineExpose({ 85 defineExpose({
51 isAdmin, 86 isAdmin,
52 }); 87 });
@@ -75,6 +110,7 @@ @@ -75,6 +110,7 @@
75 { label: '7天', value: 604800000 }, 110 { label: '7天', value: 604800000 },
76 { label: '30天', value: 2592000000 }, 111 { label: '30天', value: 2592000000 },
77 ]); 112 ]);
  113 +
78 // web Socket 114 // web Socket
79 const token: string = getAuthCache(JWT_TOKEN_KEY); 115 const token: string = getAuthCache(JWT_TOKEN_KEY);
80 const state = reactive({ 116 const state = reactive({
@@ -342,6 +378,17 @@ @@ -342,6 +378,17 @@
342 378
343 console.log(JSON.parse(sendValue), '----interval', state.alarmList); 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 </script> 392 </script>
346 393
347 <style lang="less"> 394 <style lang="less">
@@ -2,13 +2,13 @@ @@ -2,13 +2,13 @@
2 <div> 2 <div>
3 <p class="center">告警数</p> 3 <p class="center">告警数</p>
4 <div ref="chartRef" :style="{ height, width }" v-show="alarmList.length"></div> 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 </div> 6 </div>
7 </template> 7 </template>
8 <script lang="ts" setup> 8 <script lang="ts" setup>
9 import { onMounted, ref, Ref, withDefaults, watch } from 'vue'; 9 import { onMounted, ref, Ref, withDefaults, watch } from 'vue';
10 import { useECharts } from '/@/hooks/web/useECharts'; 10 import { useECharts } from '/@/hooks/web/useECharts';
11 - 11 + import { Empty } from 'ant-design-vue';
12 interface Props { 12 interface Props {
13 width?: string; 13 width?: string;
14 height?: string; 14 height?: string;
@@ -2,12 +2,13 @@ @@ -2,12 +2,13 @@
2 <div> 2 <div>
3 <p class="center">消息量</p> 3 <p class="center">消息量</p>
4 <div ref="chartRef" :style="{ height, width }" v-show="dataPointList.length"></div> 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 </div> 6 </div>
7 </template> 7 </template>
8 <script lang="ts" setup> 8 <script lang="ts" setup>
9 import { ref, Ref, watch, withDefaults } from 'vue'; 9 import { ref, Ref, watch, withDefaults } from 'vue';
10 import { useECharts } from '/@/hooks/web/useECharts'; 10 import { useECharts } from '/@/hooks/web/useECharts';
  11 + import { Empty } from 'ant-design-vue';
11 type DataItem = [number, string]; 12 type DataItem = [number, string];
12 interface Props { 13 interface Props {
13 width?: string; 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,17 +52,17 @@
52 :actions="[ 52 :actions="[
53 record.customerId 53 record.customerId
54 ? { 54 ? {
55 - tooltip: '取消分配给客户', 55 + label: '取消分配',
56 icon: 'mdi:account-arrow-left', 56 icon: 'mdi:account-arrow-left',
57 ifShow: authBtn(role), 57 ifShow: authBtn(role),
58 popConfirm: { 58 popConfirm: {
59 - title: '是否取消分配客户', 59 + title: '是否取消分配客户',
60 confirm: handleCancelDispatchCustomer.bind(null, record), 60 confirm: handleCancelDispatchCustomer.bind(null, record),
61 }, 61 },
62 } 62 }
63 : { 63 : {
  64 + label: '分配客户',
64 icon: 'mdi:account-arrow-right', 65 icon: 'mdi:account-arrow-right',
65 - tooltip: '分配给客户',  
66 ifShow: authBtn(role), 66 ifShow: authBtn(role),
67 onClick: handleDispatchCustomer.bind(null, record), 67 onClick: handleDispatchCustomer.bind(null, record),
68 }, 68 },
@@ -156,7 +156,7 @@ @@ -156,7 +156,7 @@
156 showIndexColumn: false, 156 showIndexColumn: false,
157 searchInfo: searchInfo, 157 searchInfo: searchInfo,
158 actionColumn: { 158 actionColumn: {
159 - width: 250, 159 + width: 300,
160 title: '操作', 160 title: '操作',
161 dataIndex: 'action', 161 dataIndex: 'action',
162 slots: { customRender: 'action' }, 162 slots: { customRender: 'action' },
@@ -179,7 +179,7 @@ @@ -179,7 +179,7 @@
179 // 取消分配客户 179 // 取消分配客户
180 async function handleCancelDispatchCustomer(record: Recordable) { 180 async function handleCancelDispatchCustomer(record: Recordable) {
181 console.log('record', record); 181 console.log('record', record);
182 - await cancelDispatchCustomer({ ...record, customerId: '' }); 182 + await cancelDispatchCustomer(record);
183 handleSuccess(); 183 handleSuccess();
184 } 184 }
185 185