Showing
6 changed files
with
113 additions
and
32 deletions
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | watch( |
23 | 23 | () => props.customerList, |
24 | 24 | (newValue) => { |
25 | - const transferResult = newValue.map((item) => [item.ts, item.value]); | |
25 | + const transferResult = newValue.map((item) => [item.date, item.value]); | |
26 | 26 | |
27 | 27 | setOptions({ |
28 | 28 | tooltip: { |
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | }, |
36 | 36 | }, |
37 | 37 | xAxis: { |
38 | - type: 'time', | |
38 | + type: 'category', | |
39 | 39 | splitLine: { |
40 | 40 | show: true, |
41 | 41 | lineStyle: { |
... | ... | @@ -90,7 +90,7 @@ |
90 | 90 | trend: props.type, |
91 | 91 | }); |
92 | 92 | |
93 | - const transferResult = res.map((item) => [item.ts, item.value]); | |
93 | + const transferResult = res.map((item) => [item.date, item.value]); | |
94 | 94 | setOptions({ |
95 | 95 | tooltip: { |
96 | 96 | trigger: 'axis', | ... | ... |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | }, |
32 | 32 | }, |
33 | 33 | xAxis: { |
34 | - type: 'time', | |
34 | + type: 'category', | |
35 | 35 | splitLine: { |
36 | 36 | show: true, |
37 | 37 | lineStyle: { |
... | ... | @@ -79,11 +79,11 @@ |
79 | 79 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
80 | 80 | onMounted(async () => { |
81 | 81 | const res = await getTrendData({ |
82 | - ...getDateByShortcutQueryKey(ShortcutQueryKeyEnum.LATEST_30_DAY), | |
82 | + ...getDateByShortcutQueryKey(ShortcutQueryKeyEnum.LATEST_1_MONTH), | |
83 | 83 | trend: 'CUSTOMER_TREND', |
84 | 84 | }); |
85 | 85 | |
86 | - const transferResult = res.map((item) => [item.ts, item.value]); | |
86 | + const transferResult = res.map((item) => [item.date, item.value]); | |
87 | 87 | setOptions({ |
88 | 88 | tooltip: { |
89 | 89 | trigger: 'axis', |
... | ... | @@ -95,7 +95,7 @@ |
95 | 95 | }, |
96 | 96 | }, |
97 | 97 | xAxis: { |
98 | - type: 'time', | |
98 | + type: 'category', | |
99 | 99 | splitLine: { |
100 | 100 | show: true, |
101 | 101 | lineStyle: { | ... | ... |
... | ... | @@ -37,7 +37,15 @@ |
37 | 37 | <DatePicker |
38 | 38 | @change="(_, DateString) => onDateChange(_, DateString, role === RoleEnum.CUSTOMER_USER)" |
39 | 39 | v-model:value="dateValue" |
40 | - /> | |
40 | + > | |
41 | + <Button | |
42 | + type="link" | |
43 | + class="!px-0" | |
44 | + :style="dateValue ? { color: '#0960bd', fontWeight: 500 } : { color: '#000000d9' }" | |
45 | + > | |
46 | + {{ dateValue ? (dateValue as moment.Moment).format('YYYY-MM-DD') : '自定义' }} | |
47 | + </Button> | |
48 | + </DatePicker> | |
41 | 49 | </div> |
42 | 50 | </template> |
43 | 51 | <div v-if="activeKey === '1'"> |
... | ... | @@ -99,13 +107,13 @@ |
99 | 107 | <Tooltip :overlayStyle="{ maxWidth: '340px' }"> |
100 | 108 | <template #title> |
101 | 109 | <section> |
102 | - <div>30天: 查询最近30天的数据,间隔时间为1天.</div> | |
110 | + <div>最近一个月: 查询最近一个月的数据,间隔时间为1天.</div> | |
103 | 111 | <div>最近三个月: 查询最近三个月的数据,间隔时间为1天.</div> |
104 | - <div>最近一年: 查询最近一年的数据,间隔时间为30天.</div> | |
112 | + <div>最近一年: 查询最近一年的数据,间隔时间为1月.</div> | |
105 | 113 | <div> |
106 | 114 | 间隔时间: |
107 | 115 | <span class="font-bold underline"> 以当天的(最后时间)作为结束时间 </span> |
108 | - ,往前推移对应天数或小时的时间作为开始时间,然后在此时间区间内进行分组聚合查询. | |
116 | + ,往前推移对应天数或月的时间作为开始时间,然后在此时间区间内进行分组聚合查询. | |
109 | 117 | </div> |
110 | 118 | </section> |
111 | 119 | </template> |
... | ... | @@ -120,9 +128,28 @@ |
120 | 128 | </template> |
121 | 129 | <DatePicker.RangePicker |
122 | 130 | @change="onDateCustomerChange" |
131 | + :disabledDate="handleDisableDate" | |
132 | + @calendarChange="handleCalendarChange" | |
123 | 133 | size="small" |
124 | 134 | v-model:value="customerDateValue" |
125 | - /> | |
135 | + > | |
136 | + <Button | |
137 | + type="link" | |
138 | + class="!px-0" | |
139 | + :style=" | |
140 | + customerDateValue && customerDateValue.length | |
141 | + ? { color: '#0960bd', fontWeight: 500 } | |
142 | + : { color: '#000000d9' } | |
143 | + " | |
144 | + >{{ | |
145 | + customerDateValue && customerDateValue.length | |
146 | + ? `${(customerDateValue?.[0] as moment.Moment)?.format('YYYY-MM-DD')} | |
147 | + ~ | |
148 | + ${(customerDateValue?.[1] as moment.Moment)?.format('YYYY-MM-DD')}` | |
149 | + : '自定义' | |
150 | + }}</Button | |
151 | + > | |
152 | + </DatePicker.RangePicker> | |
126 | 153 | </div> |
127 | 154 | </template> |
128 | 155 | <CustomerTrend :customerTrendList="customerTrendList" /> |
... | ... | @@ -130,8 +157,8 @@ |
130 | 157 | </div> |
131 | 158 | </template> |
132 | 159 | <script lang="ts" setup> |
133 | - import { ref, reactive } from 'vue'; | |
134 | - import { Card, DatePicker, Tooltip } from 'ant-design-vue'; | |
160 | + import { ref, reactive, unref } from 'vue'; | |
161 | + import { Card, DatePicker, Tooltip, Button } from 'ant-design-vue'; | |
135 | 162 | import VisitAnalysis from './VisitAnalysis.vue'; |
136 | 163 | import VisitAnalysisBar from './VisitAnalysisBar.vue'; |
137 | 164 | import { RoleEnum, isAdmin } from '/@/enums/roleEnum'; |
... | ... | @@ -146,6 +173,7 @@ |
146 | 173 | import { getTrendData } from '/@/api/dashboard'; |
147 | 174 | import { useGlobSetting } from '/@/hooks/setting'; |
148 | 175 | import { QuestionCircleOutlined } from '@ant-design/icons-vue'; |
176 | + import { RangePickerValue } from 'ant-design-vue/lib/date-picker/interface'; | |
149 | 177 | |
150 | 178 | defineExpose({ |
151 | 179 | isAdmin, |
... | ... | @@ -496,6 +524,18 @@ |
496 | 524 | // onDateTenantChange, |
497 | 525 | onDateCustomerChange, |
498 | 526 | } = useDate(); |
527 | + | |
528 | + const handleCalendarChange = (val: RangePickerValue) => { | |
529 | + customerDateValue.value = val as any; | |
530 | + }; | |
531 | + | |
532 | + const handleDisableDate = (current: moment.Moment) => { | |
533 | + if (!unref(customerDateValue) || unref(customerDateValue).length === 0) { | |
534 | + return false; | |
535 | + } | |
536 | + const diffDate = current.diff(unref(customerDateValue)[0], 'days'); | |
537 | + return Math.abs(diffDate) > 30; | |
538 | + }; | |
499 | 539 | </script> |
500 | 540 | |
501 | 541 | <style lang="less"> | ... | ... |
... | ... | @@ -47,7 +47,15 @@ |
47 | 47 | <DatePicker |
48 | 48 | @change="(_, DateString) => onDateChange(_, DateString, role === RoleEnum.CUSTOMER_USER)" |
49 | 49 | v-model:value="dateValue" |
50 | - /> | |
50 | + > | |
51 | + <Button | |
52 | + type="link" | |
53 | + class="!px-0" | |
54 | + :style="dateValue ? { color: '#0960bd', fontWeight: 500 } : { color: '#000000d9' }" | |
55 | + > | |
56 | + {{ dateValue ? (dateValue as moment.Moment).format('YYYY-MM-DD') : '自定义' }} | |
57 | + </Button> | |
58 | + </DatePicker> | |
51 | 59 | </div> |
52 | 60 | </template> |
53 | 61 | <!-- <div v-if="activeKey === '1'"> |
... | ... | @@ -84,13 +92,13 @@ |
84 | 92 | <Tooltip :overlayStyle="{ maxWidth: '340px' }"> |
85 | 93 | <template #title> |
86 | 94 | <section> |
87 | - <div>30天: 查询最近30天的数据,间隔时间为1天.</div> | |
95 | + <div>最近一个月: 查询最近一个月的数据,间隔时间为1天.</div> | |
88 | 96 | <div>最近三个月: 查询最近三个月的数据,间隔时间为1天.</div> |
89 | - <div>最近一年: 查询最近一年的数据,间隔时间为30天.</div> | |
97 | + <div>最近一年: 查询最近一年的数据,间隔时间为1月.</div> | |
90 | 98 | <div> |
91 | 99 | 间隔时间: |
92 | 100 | <span class="font-bold underline"> 以当天的(最后时间)作为结束时间 </span> |
93 | - ,往前推移对应天数或小时的时间作为开始时间,然后在此时间区间内进行分组聚合查询. | |
101 | + ,往前推移对应天数或月的时间作为开始时间,然后在此时间区间内进行分组聚合查询. | |
94 | 102 | </div> |
95 | 103 | </section> |
96 | 104 | </template> |
... | ... | @@ -106,8 +114,27 @@ |
106 | 114 | <DatePicker.RangePicker |
107 | 115 | @change="onDateTenantChange" |
108 | 116 | size="small" |
117 | + @calendarChange="handleCalendarChange" | |
118 | + :disabledDate="handleDisableDate" | |
109 | 119 | v-model:value="tenantDateValue" |
110 | - /> | |
120 | + > | |
121 | + <Button | |
122 | + type="link" | |
123 | + class="!px-0" | |
124 | + :style=" | |
125 | + tenantDateValue && tenantDateValue.length | |
126 | + ? { color: '#0960bd', fontWeight: 500 } | |
127 | + : { color: '#000000d9' } | |
128 | + " | |
129 | + >{{ | |
130 | + tenantDateValue && tenantDateValue.length | |
131 | + ? `${(tenantDateValue?.[0] as moment.Moment)?.format('YYYY-MM-DD')} | |
132 | + ~ | |
133 | + ${(tenantDateValue?.[1] as moment.Moment)?.format('YYYY-MM-DD')}` | |
134 | + : '自定义' | |
135 | + }}</Button | |
136 | + > | |
137 | + </DatePicker.RangePicker> | |
111 | 138 | </div> |
112 | 139 | </template> |
113 | 140 | <TenantTrend :tenantTrendList="tenantTrendList" /> |
... | ... | @@ -139,8 +166,8 @@ |
139 | 166 | </div> |
140 | 167 | </template> |
141 | 168 | <script lang="ts" setup> |
142 | - import { ref, reactive } from 'vue'; | |
143 | - import { Card, DatePicker, Tooltip } from 'ant-design-vue'; | |
169 | + import { ref, reactive, unref } from 'vue'; | |
170 | + import { Card, DatePicker, Tooltip, Button } from 'ant-design-vue'; | |
144 | 171 | import { QuestionCircleOutlined } from '@ant-design/icons-vue'; |
145 | 172 | // import VisitAnalysis from './VisitAnalysis.vue'; |
146 | 173 | import VisitAnalysisBar from './VisitAnalysisBar.vue'; |
... | ... | @@ -155,6 +182,7 @@ |
155 | 182 | import { useDate } from '../hooks/useDate'; |
156 | 183 | import { getTrendData } from '/@/api/dashboard'; |
157 | 184 | import { useGlobSetting } from '/@/hooks/setting'; |
185 | + import { RangePickerValue } from 'ant-design-vue/lib/date-picker/interface'; | |
158 | 186 | |
159 | 187 | defineExpose({ |
160 | 188 | isAdmin, |
... | ... | @@ -514,6 +542,18 @@ |
514 | 542 | onDateTenantChange, |
515 | 543 | // onDateCustomerChange, |
516 | 544 | } = useDate(); |
545 | + | |
546 | + const handleCalendarChange = (val: RangePickerValue) => { | |
547 | + tenantDateValue.value = val as any; | |
548 | + }; | |
549 | + | |
550 | + const handleDisableDate = (current: moment.Moment) => { | |
551 | + if (!unref(tenantDateValue) || unref(tenantDateValue).length === 0) { | |
552 | + return false; | |
553 | + } | |
554 | + const diffDate = current.diff(unref(tenantDateValue)[0], 'days'); | |
555 | + return Math.abs(diffDate) > 30; | |
556 | + }; | |
517 | 557 | </script> |
518 | 558 | |
519 | 559 | <style lang="less"> | ... | ... |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | }, |
32 | 32 | }, |
33 | 33 | xAxis: { |
34 | - type: 'time', | |
34 | + type: 'category', | |
35 | 35 | splitLine: { |
36 | 36 | show: true, |
37 | 37 | lineStyle: { |
... | ... | @@ -79,10 +79,10 @@ |
79 | 79 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
80 | 80 | onMounted(async () => { |
81 | 81 | const res = await getTrendData({ |
82 | - ...getDateByShortcutQueryKey(ShortcutQueryKeyEnum.LATEST_30_DAY), | |
82 | + ...getDateByShortcutQueryKey(ShortcutQueryKeyEnum.LATEST_1_MONTH), | |
83 | 83 | trend: 'TENANT_TREND', |
84 | 84 | }); |
85 | - const transferResult = res.map((item) => [item.ts, item.value]); | |
85 | + const transferResult = res.map((item) => [item.date, item.value]); | |
86 | 86 | setOptions({ |
87 | 87 | tooltip: { |
88 | 88 | trigger: 'axis', |
... | ... | @@ -94,7 +94,7 @@ |
94 | 94 | }, |
95 | 95 | }, |
96 | 96 | xAxis: { |
97 | - type: 'time', | |
97 | + type: 'category', | |
98 | 98 | splitLine: { |
99 | 99 | show: true, |
100 | 100 | lineStyle: { | ... | ... |
1 | 1 | import { dateUtil, formatToDateTime } from '/@/utils/dateUtil'; |
2 | 2 | import { ref } from 'vue'; |
3 | 3 | import { getTrendData } from '/@/api/dashboard'; |
4 | +import { RangePickerValue } from 'ant-design-vue/lib/date-picker/interface'; | |
4 | 5 | |
5 | 6 | export enum ShortcutQueryKeyEnum { |
6 | - LATEST_30_DAY = 'LATEST_30_DAY', | |
7 | + LATEST_1_MONTH = 'LATEST_1_MONTH', | |
7 | 8 | LATEST_3_MONTH = 'LATEST_3_MONTH', |
8 | 9 | LATEST_1_YEAR = 'LATEST_1_YEAR', |
9 | 10 | } |
10 | 11 | |
11 | 12 | export function getDateByShortcutQueryKey(value: ShortcutQueryKeyEnum) { |
12 | 13 | const mapping = { |
13 | - [ShortcutQueryKeyEnum.LATEST_30_DAY]: () => { | |
14 | + [ShortcutQueryKeyEnum.LATEST_1_MONTH]: () => { | |
14 | 15 | return { |
15 | - startTs: dateUtil().subtract(30, 'day').startOf('day').valueOf(), | |
16 | + startTs: dateUtil().subtract(1, 'month').startOf('day').valueOf(), | |
16 | 17 | interval: 24 * 60 * 60 * 1000, |
17 | 18 | }; |
18 | 19 | }, |
... | ... | @@ -40,13 +41,13 @@ export function getDateByShortcutQueryKey(value: ShortcutQueryKeyEnum) { |
40 | 41 | |
41 | 42 | export function useDate() { |
42 | 43 | const tenantDateValue = ref([]); |
43 | - const customerDateValue = ref([]); | |
44 | + const customerDateValue = ref<RangePickerValue>([]); | |
44 | 45 | const tenantTrendList = ref([]); |
45 | 46 | const customerTrendList = ref([]); |
46 | 47 | const activeTenantIndex = ref(0); |
47 | 48 | const activeCustomerIndex = ref(0); |
48 | 49 | const TenantOrCustomerDateList = ref([ |
49 | - { label: '30天', value: ShortcutQueryKeyEnum.LATEST_30_DAY }, | |
50 | + { label: '最近一个月', value: ShortcutQueryKeyEnum.LATEST_1_MONTH }, | |
50 | 51 | { label: '最近三个月', value: ShortcutQueryKeyEnum.LATEST_3_MONTH }, |
51 | 52 | { label: '最近一年', value: ShortcutQueryKeyEnum.LATEST_1_YEAR }, |
52 | 53 | ]); |
... | ... | @@ -65,7 +66,7 @@ export function useDate() { |
65 | 66 | ...getDateByShortcutQueryKey(value), |
66 | 67 | trend: 'TENANT_TREND', |
67 | 68 | }); |
68 | - tenantTrendList.value = res.map((item) => [item.ts, item.value]); | |
69 | + tenantTrendList.value = res.map((item) => [item.date, item.value]); | |
69 | 70 | } else { |
70 | 71 | if (activeCustomerIndex.value === index) return; |
71 | 72 | activeCustomerIndex.value = index; |
... | ... | @@ -74,7 +75,7 @@ export function useDate() { |
74 | 75 | ...getDateByShortcutQueryKey(value), |
75 | 76 | trend: 'CUSTOMER_TREND', |
76 | 77 | }); |
77 | - customerTrendList.value = res.map((item) => [item.ts, item.value]); | |
78 | + customerTrendList.value = res.map((item) => [item.date, item.value]); | |
78 | 79 | } |
79 | 80 | } |
80 | 81 | ... | ... |