vue2-client 1.12.89 → 1.12.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +109 -109
- package/src/base-client/components/common/XTimeline/XTimeline.vue +58 -13
- package/src/base-client/components/common/XTimeline/index.md +191 -0
- package/src/base-client/components/his/XRadio/XRadio.vue +65 -9
- package/src/base-client/components/his/XRadio/index.md +137 -9
package/package.json
CHANGED
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "vue2-client",
|
|
3
|
-
"version": "1.12.
|
|
4
|
-
"private": false,
|
|
5
|
-
"scripts": {
|
|
6
|
-
"serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
|
|
7
|
-
"serve:gaslink": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode gaslink",
|
|
8
|
-
"serve:revenue": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode revenue",
|
|
9
|
-
"serve:liuli": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode liuli",
|
|
10
|
-
"serve:scada": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode scada",
|
|
11
|
-
"serve:iot": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode iot",
|
|
12
|
-
"serve:his": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode his",
|
|
13
|
-
"mac-serve": "vue-cli-service serve --no-eslint --mode his",
|
|
14
|
-
"build": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
|
|
15
|
-
"test:unit": "vue-cli-service test:unit",
|
|
16
|
-
"lint": "vue-cli-service lint",
|
|
17
|
-
"build:preview": "vue-cli-service build --mode preview",
|
|
18
|
-
"lint:nofix": "vue-cli-service lint --no-fix",
|
|
19
|
-
"test": "jest"
|
|
20
|
-
},
|
|
21
|
-
"dependencies": {
|
|
22
|
-
"@afwenming123/vue-easy-tree": "^1.0.1",
|
|
23
|
-
"@afwenming123/vue-plugin-hiprint": "^0.0.70",
|
|
24
|
-
"@amap/amap-jsapi-loader": "^1.0.1",
|
|
25
|
-
"@antv/data-set": "^0.11.8",
|
|
26
|
-
"@antv/g2plot": "^2.4.31",
|
|
27
|
-
"@hufe921/canvas-editor": "^0.9.49",
|
|
28
|
-
"@microsoft/fetch-event-source": "^2.0.1",
|
|
29
|
-
"@vue/babel-preset-jsx": "^1.4.0",
|
|
30
|
-
"animate.css": "^4.1.1",
|
|
31
|
-
"ant-design-vue": "^1.7.8",
|
|
32
|
-
"axios": "^0.27.2",
|
|
33
|
-
"clipboard": "^2.0.11",
|
|
34
|
-
"core-js": "^3.33.0",
|
|
35
|
-
"crypto-js": "^4.1.1",
|
|
36
|
-
"date-fns": "^2.29.3",
|
|
37
|
-
"dayjs": "^1.11.13",
|
|
38
|
-
"default-passive-events": "^2.0.0",
|
|
39
|
-
"dotenv": "^16.3.1",
|
|
40
|
-
"echarts": "^5.5.0",
|
|
41
|
-
"enquire.js": "^2.1.6",
|
|
42
|
-
"file-saver": "^2.0.5",
|
|
43
|
-
"highlight.js": "^11.7.0",
|
|
44
|
-
"html2canvas": "^1.4.1",
|
|
45
|
-
"js-base64": "^3.7.5",
|
|
46
|
-
"js-cookie": "^2.2.1",
|
|
47
|
-
"jsencrypt": "^3.3.2",
|
|
48
|
-
"jspdf": "^2.5.1",
|
|
49
|
-
"lodash.clonedeep": "^4.5.0",
|
|
50
|
-
"lodash.debounce": "^4",
|
|
51
|
-
"lodash.get": "^4.4.2",
|
|
52
|
-
"marked": "^4",
|
|
53
|
-
"mockjs": "^1.1.0",
|
|
54
|
-
"nprogress": "^0.2.0",
|
|
55
|
-
"qs": "^6.11.2",
|
|
56
|
-
"regenerator-runtime": "^0.14.0",
|
|
57
|
-
"videojs-contrib-hls": "^5.15.0",
|
|
58
|
-
"viser-vue": "^2.4.8",
|
|
59
|
-
"vue": "^2.7.14",
|
|
60
|
-
"vue-codemirror": "4.0.6",
|
|
61
|
-
"vue-draggable-resizable": "^2",
|
|
62
|
-
"vue-i18n": "^8.28.2",
|
|
63
|
-
"vue-json-viewer": "^2.2.22",
|
|
64
|
-
"vue-router": "^3.6.5",
|
|
65
|
-
"vue-video-player": "^5.0.2",
|
|
66
|
-
"vue-virtual-scroller": "^1.1.2",
|
|
67
|
-
"vuedraggable": "^2.24.3",
|
|
68
|
-
"vuex": "^3.6.2",
|
|
69
|
-
"xlsx": "0.18.5"
|
|
70
|
-
},
|
|
71
|
-
"devDependencies": {
|
|
72
|
-
"@ant-design/colors": "^7.0.0",
|
|
73
|
-
"@babel/core": "^7.22.20",
|
|
74
|
-
"@babel/eslint-parser": "^7.22.15",
|
|
75
|
-
"@babel/preset-env": "^7.22.20",
|
|
76
|
-
"@jest/globals": "^29.7.0",
|
|
77
|
-
"@vue/cli-plugin-babel": "^5.0.8",
|
|
78
|
-
"@vue/cli-plugin-eslint": "^5.0.8",
|
|
79
|
-
"@vue/cli-service": "^5.0.8",
|
|
80
|
-
"@vue/eslint-config-standard": "^8.0.1",
|
|
81
|
-
"@vue/test-utils": "^1.3.6",
|
|
82
|
-
"babel-plugin-transform-remove-console": "^6.9.4",
|
|
83
|
-
"compression-webpack-plugin": "^10.0.0",
|
|
84
|
-
"css-minimizer-webpack-plugin": "^5.0.1",
|
|
85
|
-
"deepmerge": "^4.3.1",
|
|
86
|
-
"eslint": "^8.51.0",
|
|
87
|
-
"eslint-plugin-vue": "^9.17.0",
|
|
88
|
-
"fast-deep-equal": "^3.1.3",
|
|
89
|
-
"ignore-loader": "^0.1.2",
|
|
90
|
-
"jest": "^29.7.0",
|
|
91
|
-
"jest-environment-jsdom": "^29.7.0",
|
|
92
|
-
"jest-transform-stub": "^2.0.0",
|
|
93
|
-
"less-loader": "^6.2.0",
|
|
94
|
-
"script-loader": "^0.7.2",
|
|
95
|
-
"style-resources-loader": "^1.5.0",
|
|
96
|
-
"vue-cli-plugin-style-resources-loader": "^0.1.5",
|
|
97
|
-
"vue-jest": "^4.0.1",
|
|
98
|
-
"vue-template-compiler": "^2.7.14",
|
|
99
|
-
"webpack": "^5.88.2",
|
|
100
|
-
"webpack-theme-color-replacer": "^1.4.7",
|
|
101
|
-
"whatwg-fetch": "^3.6.19"
|
|
102
|
-
},
|
|
103
|
-
"browserslist": [
|
|
104
|
-
"> 1%",
|
|
105
|
-
"last 2 versions",
|
|
106
|
-
"not dead",
|
|
107
|
-
"not ie 11"
|
|
108
|
-
]
|
|
109
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "vue2-client",
|
|
3
|
+
"version": "1.12.90",
|
|
4
|
+
"private": false,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
|
|
7
|
+
"serve:gaslink": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode gaslink",
|
|
8
|
+
"serve:revenue": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode revenue",
|
|
9
|
+
"serve:liuli": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode liuli",
|
|
10
|
+
"serve:scada": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode scada",
|
|
11
|
+
"serve:iot": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode iot",
|
|
12
|
+
"serve:his": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode his",
|
|
13
|
+
"mac-serve": "vue-cli-service serve --no-eslint --mode his",
|
|
14
|
+
"build": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
|
|
15
|
+
"test:unit": "vue-cli-service test:unit",
|
|
16
|
+
"lint": "vue-cli-service lint",
|
|
17
|
+
"build:preview": "vue-cli-service build --mode preview",
|
|
18
|
+
"lint:nofix": "vue-cli-service lint --no-fix",
|
|
19
|
+
"test": "jest"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@afwenming123/vue-easy-tree": "^1.0.1",
|
|
23
|
+
"@afwenming123/vue-plugin-hiprint": "^0.0.70",
|
|
24
|
+
"@amap/amap-jsapi-loader": "^1.0.1",
|
|
25
|
+
"@antv/data-set": "^0.11.8",
|
|
26
|
+
"@antv/g2plot": "^2.4.31",
|
|
27
|
+
"@hufe921/canvas-editor": "^0.9.49",
|
|
28
|
+
"@microsoft/fetch-event-source": "^2.0.1",
|
|
29
|
+
"@vue/babel-preset-jsx": "^1.4.0",
|
|
30
|
+
"animate.css": "^4.1.1",
|
|
31
|
+
"ant-design-vue": "^1.7.8",
|
|
32
|
+
"axios": "^0.27.2",
|
|
33
|
+
"clipboard": "^2.0.11",
|
|
34
|
+
"core-js": "^3.33.0",
|
|
35
|
+
"crypto-js": "^4.1.1",
|
|
36
|
+
"date-fns": "^2.29.3",
|
|
37
|
+
"dayjs": "^1.11.13",
|
|
38
|
+
"default-passive-events": "^2.0.0",
|
|
39
|
+
"dotenv": "^16.3.1",
|
|
40
|
+
"echarts": "^5.5.0",
|
|
41
|
+
"enquire.js": "^2.1.6",
|
|
42
|
+
"file-saver": "^2.0.5",
|
|
43
|
+
"highlight.js": "^11.7.0",
|
|
44
|
+
"html2canvas": "^1.4.1",
|
|
45
|
+
"js-base64": "^3.7.5",
|
|
46
|
+
"js-cookie": "^2.2.1",
|
|
47
|
+
"jsencrypt": "^3.3.2",
|
|
48
|
+
"jspdf": "^2.5.1",
|
|
49
|
+
"lodash.clonedeep": "^4.5.0",
|
|
50
|
+
"lodash.debounce": "^4",
|
|
51
|
+
"lodash.get": "^4.4.2",
|
|
52
|
+
"marked": "^4",
|
|
53
|
+
"mockjs": "^1.1.0",
|
|
54
|
+
"nprogress": "^0.2.0",
|
|
55
|
+
"qs": "^6.11.2",
|
|
56
|
+
"regenerator-runtime": "^0.14.0",
|
|
57
|
+
"videojs-contrib-hls": "^5.15.0",
|
|
58
|
+
"viser-vue": "^2.4.8",
|
|
59
|
+
"vue": "^2.7.14",
|
|
60
|
+
"vue-codemirror": "4.0.6",
|
|
61
|
+
"vue-draggable-resizable": "^2",
|
|
62
|
+
"vue-i18n": "^8.28.2",
|
|
63
|
+
"vue-json-viewer": "^2.2.22",
|
|
64
|
+
"vue-router": "^3.6.5",
|
|
65
|
+
"vue-video-player": "^5.0.2",
|
|
66
|
+
"vue-virtual-scroller": "^1.1.2",
|
|
67
|
+
"vuedraggable": "^2.24.3",
|
|
68
|
+
"vuex": "^3.6.2",
|
|
69
|
+
"xlsx": "0.18.5"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@ant-design/colors": "^7.0.0",
|
|
73
|
+
"@babel/core": "^7.22.20",
|
|
74
|
+
"@babel/eslint-parser": "^7.22.15",
|
|
75
|
+
"@babel/preset-env": "^7.22.20",
|
|
76
|
+
"@jest/globals": "^29.7.0",
|
|
77
|
+
"@vue/cli-plugin-babel": "^5.0.8",
|
|
78
|
+
"@vue/cli-plugin-eslint": "^5.0.8",
|
|
79
|
+
"@vue/cli-service": "^5.0.8",
|
|
80
|
+
"@vue/eslint-config-standard": "^8.0.1",
|
|
81
|
+
"@vue/test-utils": "^1.3.6",
|
|
82
|
+
"babel-plugin-transform-remove-console": "^6.9.4",
|
|
83
|
+
"compression-webpack-plugin": "^10.0.0",
|
|
84
|
+
"css-minimizer-webpack-plugin": "^5.0.1",
|
|
85
|
+
"deepmerge": "^4.3.1",
|
|
86
|
+
"eslint": "^8.51.0",
|
|
87
|
+
"eslint-plugin-vue": "^9.17.0",
|
|
88
|
+
"fast-deep-equal": "^3.1.3",
|
|
89
|
+
"ignore-loader": "^0.1.2",
|
|
90
|
+
"jest": "^29.7.0",
|
|
91
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
92
|
+
"jest-transform-stub": "^2.0.0",
|
|
93
|
+
"less-loader": "^6.2.0",
|
|
94
|
+
"script-loader": "^0.7.2",
|
|
95
|
+
"style-resources-loader": "^1.5.0",
|
|
96
|
+
"vue-cli-plugin-style-resources-loader": "^0.1.5",
|
|
97
|
+
"vue-jest": "^4.0.1",
|
|
98
|
+
"vue-template-compiler": "^2.7.14",
|
|
99
|
+
"webpack": "^5.88.2",
|
|
100
|
+
"webpack-theme-color-replacer": "^1.4.7",
|
|
101
|
+
"whatwg-fetch": "^3.6.19"
|
|
102
|
+
},
|
|
103
|
+
"browserslist": [
|
|
104
|
+
"> 1%",
|
|
105
|
+
"last 2 versions",
|
|
106
|
+
"not dead",
|
|
107
|
+
"not ie 11"
|
|
108
|
+
]
|
|
109
|
+
}
|
|
@@ -78,16 +78,23 @@ export default {
|
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
computed: {
|
|
81
|
-
//
|
|
81
|
+
// 计算需要显示的日期范围,固定显示周一到周日
|
|
82
82
|
displayDates () {
|
|
83
83
|
const dates = []
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
// 计算当前日期所在周的周一
|
|
85
|
+
const currentDay = dayjs(this.baseDate)
|
|
86
|
+
const dayOfWeek = currentDay.day() || 7 // 获取星期几,将周日的0转换为7
|
|
87
|
+
const mondayOfWeek = currentDay.subtract(dayOfWeek - 1, 'day') // 减去相应的天数得到周一
|
|
88
|
+
|
|
89
|
+
// 从周一开始,生成一周的日期
|
|
90
|
+
dates.push(mondayOfWeek.format('YYYY-MM-DD')) // 周一
|
|
91
|
+
dates.push(dayjs(mondayOfWeek).add(1, 'day').format('YYYY-MM-DD')) // 周二
|
|
92
|
+
dates.push(dayjs(mondayOfWeek).add(2, 'day').format('YYYY-MM-DD')) // 周三
|
|
93
|
+
dates.push(dayjs(mondayOfWeek).add(3, 'day').format('YYYY-MM-DD')) // 周四
|
|
94
|
+
dates.push(dayjs(mondayOfWeek).add(4, 'day').format('YYYY-MM-DD')) // 周五
|
|
95
|
+
dates.push(dayjs(mondayOfWeek).add(5, 'day').format('YYYY-MM-DD')) // 周六
|
|
96
|
+
dates.push(dayjs(mondayOfWeek).add(6, 'day').format('YYYY-MM-DD')) // 周日
|
|
97
|
+
|
|
91
98
|
return dates
|
|
92
99
|
}
|
|
93
100
|
},
|
|
@@ -207,8 +214,15 @@ export default {
|
|
|
207
214
|
if (this.config?.minDate && newDate.isBefore(this.config.minDate)) {
|
|
208
215
|
return
|
|
209
216
|
}
|
|
217
|
+
// 更新基准日期
|
|
210
218
|
this.baseDate = newDate.format('YYYY-MM-DD')
|
|
219
|
+
// 同时选中新的日期
|
|
220
|
+
this.currentDate = this.baseDate
|
|
221
|
+
this.$emit('update:modelValue', this.currentDate)
|
|
222
|
+
// 触发前一天事件
|
|
211
223
|
this.$emit('prev-day', this.baseDate)
|
|
224
|
+
// 触发变更事件
|
|
225
|
+
this.$emit('change', this.currentDate)
|
|
212
226
|
},
|
|
213
227
|
|
|
214
228
|
// 后一天
|
|
@@ -217,13 +231,26 @@ export default {
|
|
|
217
231
|
if (this.config?.maxDate && newDate.isAfter(this.config.maxDate)) {
|
|
218
232
|
return
|
|
219
233
|
}
|
|
234
|
+
// 更新基准日期
|
|
220
235
|
this.baseDate = newDate.format('YYYY-MM-DD')
|
|
236
|
+
// 同时选中新的日期
|
|
237
|
+
this.currentDate = this.baseDate
|
|
238
|
+
this.$emit('update:modelValue', this.currentDate)
|
|
239
|
+
// 触发后一天事件
|
|
221
240
|
this.$emit('next-day', this.baseDate)
|
|
241
|
+
// 触发变更事件
|
|
242
|
+
this.$emit('change', this.currentDate)
|
|
222
243
|
},
|
|
223
|
-
|
|
224
244
|
// 前一周
|
|
225
245
|
goToPrevWeek () {
|
|
226
|
-
|
|
246
|
+
// 计算当前日期所在周的周一
|
|
247
|
+
const currentDay = dayjs(this.baseDate)
|
|
248
|
+
const dayOfWeek = currentDay.day() || 7 // 获取星期几,将周日的0转换为7
|
|
249
|
+
const mondayOfWeek = currentDay.subtract(dayOfWeek - 1, 'day') // 减去相应的天数得到周一
|
|
250
|
+
|
|
251
|
+
// 前一周的周一
|
|
252
|
+
const newDate = mondayOfWeek.subtract(7, 'day')
|
|
253
|
+
|
|
227
254
|
if (this.config?.minDate && newDate.isBefore(this.config.minDate)) {
|
|
228
255
|
return
|
|
229
256
|
}
|
|
@@ -233,7 +260,12 @@ export default {
|
|
|
233
260
|
|
|
234
261
|
// 后一周
|
|
235
262
|
goToNextWeek () {
|
|
236
|
-
|
|
263
|
+
// 计算当前日期所在周的周一
|
|
264
|
+
const currentDay = dayjs(this.baseDate)
|
|
265
|
+
const dayOfWeek = currentDay.day() || 7 // 获取星期几,将周日的0转换为7
|
|
266
|
+
const mondayOfWeek = currentDay.subtract(dayOfWeek - 1, 'day') // 减去相应的天数得到周一
|
|
267
|
+
// 后一周的周一
|
|
268
|
+
const newDate = mondayOfWeek.add(7, 'day')
|
|
237
269
|
if (this.config?.maxDate && newDate.isAfter(this.config.maxDate)) {
|
|
238
270
|
return
|
|
239
271
|
}
|
|
@@ -278,8 +310,15 @@ export default {
|
|
|
278
310
|
transition: all 0.3s;
|
|
279
311
|
}
|
|
280
312
|
|
|
281
|
-
|
|
282
|
-
|
|
313
|
+
/* 非选中日期的悬浮效果 */
|
|
314
|
+
.date-item:hover:not(.ant-btn-disabled):not(.ant-btn-primary) {
|
|
315
|
+
background: #e6f7ff;
|
|
316
|
+
color: #1890ff;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* 选中日期不需要悬浮效果 */
|
|
320
|
+
.date-item.ant-btn-primary:hover {
|
|
321
|
+
background: #1890ff;
|
|
283
322
|
}
|
|
284
323
|
|
|
285
324
|
.date-item.ant-btn-primary {
|
|
@@ -292,6 +331,12 @@ export default {
|
|
|
292
331
|
color: #fff;
|
|
293
332
|
}
|
|
294
333
|
|
|
334
|
+
/* 非选中日期悬浮时的字体颜色 */
|
|
335
|
+
.date-item:hover:not(.ant-btn-disabled):not(.ant-btn-primary) .weekday,
|
|
336
|
+
.date-item:hover:not(.ant-btn-disabled):not(.ant-btn-primary) .date {
|
|
337
|
+
color: #1890ff;
|
|
338
|
+
}
|
|
339
|
+
|
|
295
340
|
.date-item.date-weekend:not(.ant-btn-disabled):not(.ant-btn-primary) {
|
|
296
341
|
color: #ff4d4f;
|
|
297
342
|
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# XTimeline
|
|
2
|
+
|
|
3
|
+
基于配置的时间轴组件,支持日期选择和日期范围导航,可通过配置动态调整显示方式和行为。
|
|
4
|
+
|
|
5
|
+
## 何时使用
|
|
6
|
+
|
|
7
|
+
当需要在界面中展示一个按日期排列的时间轴,并允许用户在日期之间进行选择和导航时使用。适用于日程安排、预约系统、历史记录查看等场景。
|
|
8
|
+
|
|
9
|
+
## 引用方式
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
import XTimeline from '@vue2-client/base-client/components/common/XTimeline/XTimeline'
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
components: {
|
|
16
|
+
XTimeline
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 代码演示
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<x-timeline
|
|
25
|
+
v-model="selectedDate"
|
|
26
|
+
:queryParamsName="timelineConfigName"
|
|
27
|
+
@change="handleDateChange"
|
|
28
|
+
@init="handleInit">
|
|
29
|
+
</x-timeline>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## API
|
|
33
|
+
|
|
34
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
35
|
+
|------|------|------|------|
|
|
36
|
+
| modelValue (v-model) | 当前选中的日期值 | String | '' |
|
|
37
|
+
| queryParamsName | 查询配置名称 | String | '' |
|
|
38
|
+
|
|
39
|
+
### 事件
|
|
40
|
+
|
|
41
|
+
| 事件名 | 说明 | 回调参数 |
|
|
42
|
+
|------|------|------|
|
|
43
|
+
| update:modelValue | 选中日期变化时触发,用于v-model绑定 | function(date: string) |
|
|
44
|
+
| change | 用户选择日期时触发 | function(date: string) |
|
|
45
|
+
| prev-week | 点击"前一周"按钮时触发 | function(date: string) |
|
|
46
|
+
| next-week | 点击"后一周"按钮时触发 | function(date: string) |
|
|
47
|
+
| prev-day | 点击"前一天"按钮时触发 | function(date: string) |
|
|
48
|
+
| next-day | 点击"后一天"按钮时触发 | function(date: string) |
|
|
49
|
+
| init | 组件初始化完成时触发 | function(date: string) |
|
|
50
|
+
|
|
51
|
+
## 配置说明
|
|
52
|
+
|
|
53
|
+
组件通过 `queryParamsName` 从后端获取配置,配置格式如下:
|
|
54
|
+
|
|
55
|
+
### 基本配置
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"range": 7,
|
|
60
|
+
"defaultValue": "",
|
|
61
|
+
"dateFormat": "MM/DD",
|
|
62
|
+
"weekFormat": "周dd",
|
|
63
|
+
"prevWeekText": "前一周",
|
|
64
|
+
"nextWeekText": "后一周",
|
|
65
|
+
"prevDayText": "前一天",
|
|
66
|
+
"nextDayText": "后一天",
|
|
67
|
+
"minDate": "2024-01-01",
|
|
68
|
+
"maxDate": "2099-12-31",
|
|
69
|
+
"highlightWeekend": true,
|
|
70
|
+
"logicName": "",
|
|
71
|
+
"parameter": {}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 指定默认日期的配置
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"range": 7,
|
|
80
|
+
"defaultValue": "2024-05-15",
|
|
81
|
+
"dateFormat": "MM/DD",
|
|
82
|
+
"weekFormat": "周dd",
|
|
83
|
+
"prevWeekText": "前一周",
|
|
84
|
+
"nextWeekText": "后一周",
|
|
85
|
+
"prevDayText": "前一天",
|
|
86
|
+
"nextDayText": "后一天",
|
|
87
|
+
"minDate": "2024-01-01",
|
|
88
|
+
"maxDate": "2024-12-31",
|
|
89
|
+
"highlightWeekend": true
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 自定义日期格式的配置
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"range": 7,
|
|
98
|
+
"defaultValue": "",
|
|
99
|
+
"dateFormat": "M月D日",
|
|
100
|
+
"weekFormat": "ddd",
|
|
101
|
+
"prevWeekText": "上周",
|
|
102
|
+
"nextWeekText": "下周",
|
|
103
|
+
"prevDayText": "前一天",
|
|
104
|
+
"nextDayText": "后一天",
|
|
105
|
+
"minDate": "2024-01-01",
|
|
106
|
+
"maxDate": "2024-12-31",
|
|
107
|
+
"highlightWeekend": true
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 注意事项
|
|
112
|
+
|
|
113
|
+
1. 时间轴固定显示周一到周日的七天日期,不可更改
|
|
114
|
+
2. 日期选择范围可通过 `minDate` 和 `maxDate` 进行限制
|
|
115
|
+
3. 如果配置中有 `defaultValue`,组件将默认选中该日期
|
|
116
|
+
4. 组件使用 dayjs 处理日期,支持其格式化语法
|
|
117
|
+
5. 周末日期可通过 `highlightWeekend` 配置是否高亮显示
|
|
118
|
+
6. 导航按钮文本可通过配置自定义
|
|
119
|
+
7. 点击"前一天"和"后一天"按钮会同时更新显示范围和选中的日期
|
|
120
|
+
8. 点击"前一周"和"后一周"按钮只会更新显示范围,不会改变选中的日期
|
|
121
|
+
9. 禁用的日期无法点击选择
|
|
122
|
+
|
|
123
|
+
## 常见问题解答(FAQ)
|
|
124
|
+
|
|
125
|
+
### 1. 如何设置默认选中的日期?
|
|
126
|
+
|
|
127
|
+
可以通过配置中的 `defaultValue` 字段设置:
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"defaultValue": "2024-05-15"
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
或者通过 v-model 绑定:
|
|
135
|
+
```html
|
|
136
|
+
<x-timeline v-model="selectedDate"></x-timeline>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
export default {
|
|
141
|
+
data() {
|
|
142
|
+
return {
|
|
143
|
+
selectedDate: "2024-05-15"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 2. 如何限制可选日期范围?
|
|
150
|
+
|
|
151
|
+
通过配置中的 `minDate` 和 `maxDate` 字段设置:
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"minDate": "2024-01-01",
|
|
155
|
+
"maxDate": "2024-12-31"
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 3. 如何禁用特定日期?
|
|
160
|
+
|
|
161
|
+
可以通过配置中的 `logicName` 指定后端逻辑,返回包含 `disabledDates` 数组的结果:
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"logicName": "getDisabledDates",
|
|
165
|
+
"parameter": {
|
|
166
|
+
"userId": "123"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
后端逻辑返回的结果格式为:
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"disabledDates": ["2024-05-01", "2024-05-03", "2024-05-05"]
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 4. 如何自定义日期和星期的显示格式?
|
|
179
|
+
|
|
180
|
+
通过配置中的 `dateFormat` 和 `weekFormat` 字段设置:
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"dateFormat": "YYYY年MM月DD日",
|
|
184
|
+
"weekFormat": "ddd"
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### 5. 点击导航按钮有什么区别?
|
|
189
|
+
|
|
190
|
+
- 点击"前一天"/"后一天"按钮:会更新显示范围并同时选中新的日期
|
|
191
|
+
- 点击"前一周"/"后一周"按钮:只更新显示范围,不会改变选中的日期
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<a-radio-group v-model="innerValue" @change="onChange">
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<div class="x-radio-container">
|
|
3
|
+
<a-radio-group v-model="innerValue" @change="onChange" class="x-radio-group">
|
|
4
|
+
<div v-for="item in data" :key="item.value" class="x-radio-item-container">
|
|
5
|
+
<a-radio :value="item.value" class="x-radio-item">
|
|
6
|
+
{{ item.label }}
|
|
7
|
+
</a-radio>
|
|
8
|
+
<div
|
|
9
|
+
v-if="config.showIndicator && item.bottomLine !== false"
|
|
10
|
+
class="x-radio-indicator"
|
|
11
|
+
:style="{
|
|
12
|
+
width: item.indicatorWidth || '100%',
|
|
13
|
+
backgroundColor: item.indicatorColor || config.indicatorActiveColor,
|
|
14
|
+
height: config.indicatorHeight + 'px'
|
|
15
|
+
}"
|
|
16
|
+
></div>
|
|
17
|
+
</div>
|
|
7
18
|
</a-radio-group>
|
|
8
19
|
</div>
|
|
9
20
|
</template>
|
|
@@ -24,7 +35,8 @@ export default {
|
|
|
24
35
|
data () {
|
|
25
36
|
return {
|
|
26
37
|
data: [],
|
|
27
|
-
innerValue: null
|
|
38
|
+
innerValue: null,
|
|
39
|
+
config: null
|
|
28
40
|
}
|
|
29
41
|
},
|
|
30
42
|
created () {
|
|
@@ -42,15 +54,27 @@ export default {
|
|
|
42
54
|
// 1. 先加载选项
|
|
43
55
|
if (res.radio && Array.isArray(res.radio)) {
|
|
44
56
|
this.data = res.radio
|
|
45
|
-
// 2.
|
|
57
|
+
// 2. 加载指示器配置
|
|
58
|
+
if (res.indicator !== undefined) {
|
|
59
|
+
// 如果indicator是布尔值,则只控制显示/隐藏
|
|
60
|
+
if (typeof res.indicator === 'boolean') {
|
|
61
|
+
this.config.showIndicator = res.indicator
|
|
62
|
+
} else if (typeof res.indicator === 'object') {
|
|
63
|
+
this.config = {
|
|
64
|
+
...this.config,
|
|
65
|
+
...res.indicator
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// 3. 初始化默认值(优先级: 配置defaultValue > 第一个选项)
|
|
46
70
|
if (res.defaultValue !== undefined && res.defaultValue !== null) {
|
|
47
|
-
//
|
|
71
|
+
// 使用配置中的defaultValue
|
|
48
72
|
this.innerValue = res.defaultValue
|
|
49
73
|
} else if (this.data.length > 0) {
|
|
50
74
|
// 如果没有默认值但有选项,使用第一个选项
|
|
51
75
|
this.innerValue = this.data[0].value
|
|
52
76
|
}
|
|
53
|
-
//
|
|
77
|
+
// 4. 触发初始化事件
|
|
54
78
|
this.$emit('init', this.innerValue)
|
|
55
79
|
} else {
|
|
56
80
|
this.$message.error('配置错误,radio字段不是数组')
|
|
@@ -64,3 +88,35 @@ export default {
|
|
|
64
88
|
}
|
|
65
89
|
}
|
|
66
90
|
</script>
|
|
91
|
+
|
|
92
|
+
<style scoped>
|
|
93
|
+
.x-radio-container {
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.x-radio-group {
|
|
99
|
+
display: flex;
|
|
100
|
+
justify-content: space-around;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.x-radio-item-container {
|
|
104
|
+
flex: 1;
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-direction: column;
|
|
107
|
+
align-items: center;
|
|
108
|
+
text-align: center;
|
|
109
|
+
padding: 0 8px;
|
|
110
|
+
box-sizing: border-box;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.x-radio-item {
|
|
114
|
+
margin-bottom: 8px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.x-radio-indicator {
|
|
118
|
+
height: 3px;
|
|
119
|
+
transition: all 0.3s;
|
|
120
|
+
max-width: 100%;
|
|
121
|
+
}
|
|
122
|
+
</style>
|
|
@@ -74,33 +74,161 @@ export default {
|
|
|
74
74
|
## 配置示例
|
|
75
75
|
----
|
|
76
76
|
|
|
77
|
+
### 基本配置
|
|
78
|
+
|
|
77
79
|
```json
|
|
78
80
|
{
|
|
79
81
|
"radio": [
|
|
80
82
|
{
|
|
81
|
-
"label": "
|
|
82
|
-
"value":
|
|
83
|
+
"label": "全部",
|
|
84
|
+
"value": "all",
|
|
85
|
+
"bottomLine": true,
|
|
86
|
+
"indicatorColor": "#1890ff",
|
|
87
|
+
"indicatorWidth": "50%"
|
|
83
88
|
},
|
|
84
89
|
{
|
|
85
|
-
"label": "
|
|
86
|
-
"value":
|
|
90
|
+
"label": "已过期",
|
|
91
|
+
"value": "expired",
|
|
92
|
+
"bottomLine": true,
|
|
93
|
+
"indicatorColor": "#ff4d4f",
|
|
94
|
+
"indicatorWidth": "70%"
|
|
87
95
|
},
|
|
88
96
|
{
|
|
89
|
-
"label": "
|
|
90
|
-
"value":
|
|
97
|
+
"label": "30天内",
|
|
98
|
+
"value": "30days",
|
|
99
|
+
"bottomLine": true,
|
|
100
|
+
"indicatorColor": "#52c41a",
|
|
101
|
+
"indicatorWidth": "60%"
|
|
91
102
|
},
|
|
92
103
|
{
|
|
93
|
-
"label": "
|
|
94
|
-
"value":
|
|
104
|
+
"label": "90天内",
|
|
105
|
+
"value": "90days",
|
|
106
|
+
"bottomLine": false
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"label": "180天内",
|
|
110
|
+
"value": "180days",
|
|
111
|
+
"bottomLine": true,
|
|
112
|
+
"indicatorColor": "#722ed1",
|
|
113
|
+
"indicatorWidth": "30px"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"label": "360天内",
|
|
117
|
+
"value": "360days",
|
|
118
|
+
"bottomLine": true,
|
|
119
|
+
"indicatorColor": "#eb2f96",
|
|
120
|
+
"indicatorWidth": "40%"
|
|
95
121
|
}
|
|
96
122
|
],
|
|
97
|
-
"defaultValue":
|
|
123
|
+
"defaultValue": "all",
|
|
124
|
+
"indicator": {
|
|
125
|
+
"showIndicator": true,
|
|
126
|
+
"indicatorHeight": 4,
|
|
127
|
+
"indicatorBgColor": "#f5f5f5",
|
|
128
|
+
"indicatorActiveColor": "#1890ff"
|
|
129
|
+
}
|
|
98
130
|
}
|
|
99
131
|
```
|
|
100
132
|
|
|
133
|
+
### 不同线条宽度效果示例
|
|
134
|
+
|
|
135
|
+
以下是几种常见的线条宽度配置效果:
|
|
136
|
+
|
|
137
|
+
1. **完整宽度**:`"indicatorWidth": "100%"`(默认值)
|
|
138
|
+
- 线条完全填充选项宽度
|
|
139
|
+
- 适合强调整个选项区域
|
|
140
|
+
|
|
141
|
+
2. **居中宽度**:`"indicatorWidth": "50%"`
|
|
142
|
+
- 线条占选项宽度的一半,自动居中
|
|
143
|
+
- 提供清晰的视觉提示,同时保持简洁
|
|
144
|
+
|
|
145
|
+
3. **固定宽度**:`"indicatorWidth": "30px"`
|
|
146
|
+
- 线条使用固定像素宽度,不随选项宽度变化
|
|
147
|
+
- 适合保持所有线条视觉上的一致性
|
|
148
|
+
|
|
149
|
+
4. **较小宽度**:`"indicatorWidth": "20%"`
|
|
150
|
+
- 线条宽度较小,提供微妙的视觉提示
|
|
151
|
+
- 适合不希望线条过于引人注目的场景
|
|
152
|
+
|
|
101
153
|
注意事项
|
|
102
154
|
----
|
|
103
155
|
|
|
104
156
|
1. 如果配置中有 `defaultValue`,组件将默认选中该值对应的选项
|
|
105
157
|
2. 如果没有 `defaultValue` 但有选项,将默认选中第一个选项
|
|
106
158
|
3. 如果外部通过 `value` 属性传入值,优先使用外部值
|
|
159
|
+
4. 每个选项可以通过 `bottomLine` 属性控制是否显示底部线条
|
|
160
|
+
5. 可以通过 `indicatorColor` 设置线条颜色,线条颜色始终显示,不受选中状态影响
|
|
161
|
+
6. 通过 `indicatorWidth` 可以自定义线条宽度
|
|
162
|
+
7. 线条宽度仅在其所属选项范围内显示,不会侵入其他选项区域
|
|
163
|
+
8. 线条宽度如果设置为百分比值(如"50%"),则是相对于选项宽度计算的
|
|
164
|
+
9. 线条默认宽度为"100%",即完全填充选项宽度
|
|
165
|
+
10. 要完全隐藏线条区域,可以在全局配置中设置 `"indicator": false`
|
|
166
|
+
11. 要隐藏单个选项的线条,可以为该选项设置 `"bottomLine": false`
|
|
167
|
+
12. 全局配置中的 `indicatorHeight` 控制所有线条的高度,单位为像素
|
|
168
|
+
13. 推荐为每个选项设置不同颜色,以增强视觉辨识度
|
|
169
|
+
14. 线条宽度建议不要设置过小,以免影响用户视觉体验
|
|
170
|
+
|
|
171
|
+
## 常见问题解答(FAQ)
|
|
172
|
+
|
|
173
|
+
### 1. 如何控制线条的显示和隐藏?
|
|
174
|
+
|
|
175
|
+
**全局控制**:
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"indicator": false
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**单个选项控制**:
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"radio": [
|
|
186
|
+
{ "label": "选项A", "value": 1, "bottomLine": true },
|
|
187
|
+
{ "label": "选项B", "value": 2, "bottomLine": false }
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 2. 线条颜色如何设置?
|
|
193
|
+
|
|
194
|
+
每个选项可以单独设置线条颜色:
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"radio": [
|
|
198
|
+
{ "label": "选项A", "value": 1, "indicatorColor": "#1890ff" },
|
|
199
|
+
{ "label": "选项B", "value": 2, "indicatorColor": "#52c41a" }
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
也可以设置全局默认颜色:
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"indicator": {
|
|
208
|
+
"indicatorActiveColor": "#1890ff"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 3. 如何调整线条宽度?
|
|
214
|
+
|
|
215
|
+
线条宽度可以使用百分比或像素值:
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"radio": [
|
|
219
|
+
{ "label": "选项A", "value": 1, "indicatorWidth": "50%" },
|
|
220
|
+
{ "label": "选项B", "value": 2, "indicatorWidth": "30px" }
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 4. 如何调整线条高度?
|
|
226
|
+
|
|
227
|
+
线条高度在全局配置中统一设置:
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"indicator": {
|
|
231
|
+
"indicatorHeight": 5
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|