vue2-client 1.18.38 → 1.18.40
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/docs//350/257/267/346/261/202/345/267/245/345/205/267/344/275/277/347/224/250/350/257/264/346/230/216.md +353 -0
- package/package.json +1 -1
- package/src/base-client/components/common/XDatePicker/demo.vue +31 -0
- package/src/base-client/components/common/XDatePicker/index.vue +61 -0
- package/src/base-client/components/common/XForm/XForm.vue +5 -3
- package/src/base-client/components/common/XForm/XFormItem.vue +1 -1
- package/src/base-client/components/common/XFormTable/demo.vue +123 -125
- package/src/base-client/components/common/XReportGrid/XReportTrGroup.vue +1 -1
- package/src/base-client/components/common/XTable/XTableWrapper.vue +18 -1
- package/src/composables/demo/UseRequestDemo.vue +175 -0
- package/src/composables/index.js +6 -0
- package/src/composables/useGlobalLoading.js +206 -0
- package/src/composables/usePost.js +221 -0
- package/src/services/api/restTools.js +34 -46
- package/src/utils/request.js +103 -0
- package/vue.config.js +5 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# 请求工具使用说明
|
|
2
|
+
|
|
3
|
+
本文档介绍项目中封装的请求工具及其配置方式。
|
|
4
|
+
|
|
5
|
+
## 架构概览
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
9
|
+
│ 业务组件 │
|
|
10
|
+
├─────────────────────────────────────────────────────────────┤
|
|
11
|
+
│ usePost / useRunLogic (响应式 Hook) │
|
|
12
|
+
├─────────────────────────────────────────────────────────────┤
|
|
13
|
+
│ restTools.js │
|
|
14
|
+
│ (post / get / del / put) │
|
|
15
|
+
├─────────────────────────────────────────────────────────────┤
|
|
16
|
+
│ request.js │
|
|
17
|
+
│ (axios 拦截器 + 请求去重 + 错误处理) │
|
|
18
|
+
└─────────────────────────────────────────────────────────────┘
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 一、基础请求方法 (restTools.js)
|
|
24
|
+
|
|
25
|
+
### 1. post - POST 请求
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
import { post } from '@vue2-client/services/api'
|
|
29
|
+
|
|
30
|
+
// 基础用法
|
|
31
|
+
const result = await post('/api/user/save', { name: '张三' })
|
|
32
|
+
|
|
33
|
+
// 带配置
|
|
34
|
+
const result = await post('/api/user/save', { name: '张三' }, {
|
|
35
|
+
globalLoading: '保存中...', // 显示全局 Loading
|
|
36
|
+
dedupe: false // 关闭请求去重(POST 默认开启)
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**配置项说明:**
|
|
41
|
+
|
|
42
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
43
|
+
|------|------|--------|------|
|
|
44
|
+
| `globalLoading` | `boolean \| string` | `false` | 是否显示全局 Loading,传字符串可自定义提示文字 |
|
|
45
|
+
| `dedupe` | `boolean` | `true` | 请求去重开关,POST 请求默认开启 |
|
|
46
|
+
|
|
47
|
+
### 2. get - GET 请求
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
import { get } from '@vue2-client/services/api'
|
|
51
|
+
|
|
52
|
+
const result = await get('/api/user/list', { page: 1, size: 10 })
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. del - DELETE 请求
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
import { del } from '@vue2-client/services/api'
|
|
59
|
+
|
|
60
|
+
const result = await del('/api/user/delete', { id: 1 })
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 4. put - PUT 请求
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
import { put } from '@vue2-client/services/api'
|
|
67
|
+
|
|
68
|
+
const result = await put('/api/user/update', { id: 1, name: '李四' })
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 5. postByServiceName - 按服务名请求
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
import { postByServiceName } from '@vue2-client/services/api'
|
|
75
|
+
|
|
76
|
+
// 自动拼接 URL: /api/{serviceName}/{url}
|
|
77
|
+
const result = await postByServiceName('/user/save', { name: '张三' }, 'af-system')
|
|
78
|
+
|
|
79
|
+
// 开发环境: /devApi/{serviceName}/{url}
|
|
80
|
+
const result = await postByServiceName('/user/save', { name: '张三' }, 'af-system', true)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 二、Composition API Hooks (usePost.js)
|
|
86
|
+
|
|
87
|
+
### 1. usePost - 响应式 POST 请求
|
|
88
|
+
|
|
89
|
+
适用于需要在模板中绑定 loading 状态的场景。
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
import { usePost } from '@vue2-client/composables'
|
|
93
|
+
|
|
94
|
+
export default {
|
|
95
|
+
setup() {
|
|
96
|
+
const { loading, data, error, execute, reset } = usePost('/api/user/save', {
|
|
97
|
+
globalLoading: '保存中...',
|
|
98
|
+
dedupe: true
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
const handleSave = async (formData) => {
|
|
102
|
+
const { success, data, error } = await execute(formData)
|
|
103
|
+
if (success) {
|
|
104
|
+
message.success('保存成功')
|
|
105
|
+
} else {
|
|
106
|
+
// 错误处理(可选,拦截器已统一处理)
|
|
107
|
+
console.error(error)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return { loading, data, error, handleSave }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**模板使用:**
|
|
117
|
+
|
|
118
|
+
```html
|
|
119
|
+
<a-button :loading="loading" @click="handleSave(formData)">保存</a-button>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**返回值说明:**
|
|
123
|
+
|
|
124
|
+
| 属性 | 类型 | 说明 |
|
|
125
|
+
|------|------|------|
|
|
126
|
+
| `loading` | `boolean` | 请求进行中状态(响应式) |
|
|
127
|
+
| `data` | `any` | 请求返回的数据(响应式) |
|
|
128
|
+
| `error` | `Error \| null` | 请求错误信息(响应式) |
|
|
129
|
+
| `execute(params, config)` | `Function` | 执行请求,返回 `{ success, data, error }` |
|
|
130
|
+
| `reset()` | `Function` | 重置状态 |
|
|
131
|
+
|
|
132
|
+
**execute 返回值:**
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
const { success, data, error } = await execute(params)
|
|
136
|
+
// success: boolean - 请求是否成功
|
|
137
|
+
// data: any - 成功时的响应数据
|
|
138
|
+
// error: Error | null - 失败时的错误信息
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 三、业务逻辑请求 (useRunLogic)
|
|
144
|
+
|
|
145
|
+
### useRunLogic - 响应式业务逻辑调用
|
|
146
|
+
|
|
147
|
+
用于调用后端 Logic 业务逻辑,自动拼接 URL。
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
import { useRunLogic } from '@vue2-client/composables'
|
|
151
|
+
|
|
152
|
+
export default {
|
|
153
|
+
setup() {
|
|
154
|
+
const { loading, data, error, execute, reset } = useRunLogic('getUserInfo', {
|
|
155
|
+
serviceName: 'af-system', // 可选,默认使用 VUE_APP_SYSTEM_NAME
|
|
156
|
+
isDev: false, // 可选,是否使用开发环境 API
|
|
157
|
+
globalLoading: '加载中...',
|
|
158
|
+
dedupe: true
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const loadUser = async (userId) => {
|
|
162
|
+
const { success, data: result } = await execute({ userId })
|
|
163
|
+
if (success) {
|
|
164
|
+
console.log('用户信息:', result)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return { loading, data, loadUser }
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**URL 拼接规则:**
|
|
174
|
+
- 生产环境: `/api/{serviceName}/logic/{logicName}`
|
|
175
|
+
- 开发环境: `/devApi/{serviceName}/logic/{logicName}`
|
|
176
|
+
|
|
177
|
+
**配置项说明:**
|
|
178
|
+
|
|
179
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
180
|
+
|------|------|--------|------|
|
|
181
|
+
| `serviceName` | `string` | `VUE_APP_SYSTEM_NAME` | 服务名称 |
|
|
182
|
+
| `isDev` | `boolean` | `false` | 是否使用开发环境 API |
|
|
183
|
+
| `globalLoading` | `boolean \| string` | `false` | 是否显示全局 Loading |
|
|
184
|
+
| `dedupe` | `boolean` | `false` | 请求去重开关 |
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 四、全局功能
|
|
189
|
+
|
|
190
|
+
### 1. 请求去重
|
|
191
|
+
|
|
192
|
+
POST 请求默认开启去重,防止用户快速重复点击导致的重复提交。
|
|
193
|
+
|
|
194
|
+
**工作原理:**
|
|
195
|
+
- 相同的 URL + 参数 组合视为重复请求
|
|
196
|
+
- 重复请求会被直接拒绝(不发起网络请求),控制台输出警告
|
|
197
|
+
- 请求完成后自动清理记录
|
|
198
|
+
|
|
199
|
+
**关闭去重:**
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
post('/api/save', data, { dedupe: false })
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**错误码:**
|
|
206
|
+
- 重复请求被拦截时,error.code 为 `ERR_DUPLICATE_REQUEST`
|
|
207
|
+
|
|
208
|
+
### 2. 全局 Loading
|
|
209
|
+
|
|
210
|
+
显示全屏遮罩 Loading,阻止用户操作。
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
// 使用默认文字 "加载中..."
|
|
214
|
+
post('/api/save', data, { globalLoading: true })
|
|
215
|
+
|
|
216
|
+
// 自定义提示文字
|
|
217
|
+
post('/api/save', data, { globalLoading: '正在保存...' })
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**特性:**
|
|
221
|
+
- 支持引用计数,多个并发请求时正确处理显示/隐藏
|
|
222
|
+
- 默认 30 秒超时自动隐藏,防止异常情况下 Loading 卡死
|
|
223
|
+
- 可通过 `forceHideGlobalLoading()` 强制隐藏
|
|
224
|
+
|
|
225
|
+
**手动控制:**
|
|
226
|
+
|
|
227
|
+
```javascript
|
|
228
|
+
import {
|
|
229
|
+
showGlobalLoading,
|
|
230
|
+
hideGlobalLoading,
|
|
231
|
+
forceHideGlobalLoading
|
|
232
|
+
} from '@vue2-client/composables/useGlobalLoading'
|
|
233
|
+
|
|
234
|
+
// 显示 Loading(默认 30 秒超时)
|
|
235
|
+
showGlobalLoading('处理中...')
|
|
236
|
+
|
|
237
|
+
// 显示 Loading,自定义超时时间(60 秒)
|
|
238
|
+
showGlobalLoading('处理中...', 60000)
|
|
239
|
+
|
|
240
|
+
// 显示 Loading,禁用超时
|
|
241
|
+
showGlobalLoading('处理中...', 0)
|
|
242
|
+
|
|
243
|
+
// 隐藏 Loading(引用计数减一)
|
|
244
|
+
hideGlobalLoading()
|
|
245
|
+
|
|
246
|
+
// 强制隐藏(重置计数器,立即隐藏)
|
|
247
|
+
forceHideGlobalLoading()
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 五、EventStream 流式请求
|
|
253
|
+
|
|
254
|
+
用于 SSE (Server-Sent Events) 场景。
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
import { startEventStream, startEventStreamPOST } from '@vue2-client/services/api'
|
|
258
|
+
|
|
259
|
+
// GET 方式
|
|
260
|
+
const stop = startEventStream(
|
|
261
|
+
'/api/stream/data',
|
|
262
|
+
{ query: 'test' },
|
|
263
|
+
{}, // headers
|
|
264
|
+
(data, eventType) => {
|
|
265
|
+
console.log('收到数据:', data, eventType)
|
|
266
|
+
},
|
|
267
|
+
(error) => {
|
|
268
|
+
console.error('错误:', error)
|
|
269
|
+
}
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
// 停止监听
|
|
273
|
+
stop()
|
|
274
|
+
|
|
275
|
+
// POST 方式
|
|
276
|
+
const stop = startEventStreamPOST('/api/stream/data', params, headers, onData, onError)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 六、最佳实践
|
|
282
|
+
|
|
283
|
+
### 1. 表单提交场景
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
const { loading, execute } = usePost('/api/form/save', {
|
|
287
|
+
globalLoading: '提交中...',
|
|
288
|
+
dedupe: true // 防止重复提交
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
const handleSubmit = async () => {
|
|
292
|
+
const { success } = await execute(formData)
|
|
293
|
+
if (success) {
|
|
294
|
+
message.success('提交成功')
|
|
295
|
+
}
|
|
296
|
+
// 错误已由拦截器统一处理,无需额外处理
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 2. 列表查询场景
|
|
301
|
+
|
|
302
|
+
```javascript
|
|
303
|
+
const { loading, data, execute } = usePost('/api/list/query')
|
|
304
|
+
|
|
305
|
+
const loadData = async () => {
|
|
306
|
+
const { success } = await execute({ page: 1, size: 10 })
|
|
307
|
+
if (success) {
|
|
308
|
+
tableData.value = data
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### 3. 业务逻辑调用
|
|
314
|
+
|
|
315
|
+
```javascript
|
|
316
|
+
const { loading, execute } = useRunLogic('calculatePrice', {
|
|
317
|
+
globalLoading: '计算中...'
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
const calculate = async () => {
|
|
321
|
+
const { success, data } = await execute({ productId: 1, quantity: 10 })
|
|
322
|
+
if (success) {
|
|
323
|
+
price.value = data.totalPrice
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### 4. 错误处理模式
|
|
329
|
+
|
|
330
|
+
```javascript
|
|
331
|
+
const { execute } = usePost('/api/save')
|
|
332
|
+
|
|
333
|
+
// 模式一:只关心成功(推荐,错误由拦截器统一处理)
|
|
334
|
+
const handleSave = async () => {
|
|
335
|
+
const { success, data } = await execute(formData)
|
|
336
|
+
if (success) {
|
|
337
|
+
message.success('保存成功')
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// 模式二:需要自定义错误处理
|
|
342
|
+
const handleSave = async () => {
|
|
343
|
+
const { success, data, error } = await execute(formData)
|
|
344
|
+
if (success) {
|
|
345
|
+
message.success('保存成功')
|
|
346
|
+
} else if (error?.code === 'ERR_DUPLICATE_REQUEST') {
|
|
347
|
+
// 重复请求,静默处理
|
|
348
|
+
} else {
|
|
349
|
+
// 自定义错误处理
|
|
350
|
+
message.error('保存失败: ' + error?.message)
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
package/package.json
CHANGED
|
@@ -23,6 +23,12 @@ export default defineComponent({
|
|
|
23
23
|
components: { XFormDatePicker },
|
|
24
24
|
setup () {
|
|
25
25
|
const formValues = reactive({
|
|
26
|
+
'时间选择器-新增模式': null,
|
|
27
|
+
'时间选择器-查询EQUALS': null,
|
|
28
|
+
'时间选择器-查询BETWEEN': null,
|
|
29
|
+
'时间范围选择器-新增模式': null,
|
|
30
|
+
'时间范围选择器-查询BETWEEN': null,
|
|
31
|
+
|
|
26
32
|
'单日选择器-新增模式': null,
|
|
27
33
|
'单日选择器-查询EQUALS': null,
|
|
28
34
|
'单日选择器-查询BETWEEN': null,
|
|
@@ -49,6 +55,31 @@ export default defineComponent({
|
|
|
49
55
|
}])
|
|
50
56
|
|
|
51
57
|
const all = reactive([
|
|
58
|
+
{
|
|
59
|
+
title: '时间选择器-新增模式',
|
|
60
|
+
attr: { type: 'timePicker' },
|
|
61
|
+
mode: '新增'
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
title: '时间选择器-查询EQUALS',
|
|
65
|
+
attr: { type: 'timePicker', queryType: 'EQUALS' },
|
|
66
|
+
mode: '查询'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
title: '时间选择器-查询BETWEEN',
|
|
70
|
+
attr: { type: 'timePicker', queryType: 'BETWEEN' },
|
|
71
|
+
mode: '查询'
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
title: '时间范围选择器-新增模式',
|
|
75
|
+
attr: { type: 'timeRangePicker' },
|
|
76
|
+
mode: '新增'
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
title: '时间范围选择器-查询BETWEEN',
|
|
80
|
+
attr: { type: 'timeRangePicker', queryType: 'BETWEEN' },
|
|
81
|
+
mode: '查询'
|
|
82
|
+
},
|
|
52
83
|
{
|
|
53
84
|
title: '单日选择器-新增模式',
|
|
54
85
|
attr: { type: 'datePicker' },
|
|
@@ -94,6 +94,26 @@ export default {
|
|
|
94
94
|
this.yearShowOne = false
|
|
95
95
|
},
|
|
96
96
|
},
|
|
97
|
+
// 时间范围选择器的开始时间
|
|
98
|
+
timeRangeStartValue: {
|
|
99
|
+
get () {
|
|
100
|
+
return Array.isArray(this.value) && this.value.length > 0 ? this.value[0] : undefined
|
|
101
|
+
},
|
|
102
|
+
set (val) {
|
|
103
|
+
const end = (Array.isArray(this.value) && this.value.length > 1) ? this.value[1] : ''
|
|
104
|
+
this.$emit('change', [val || '', end])
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
// 时间范围选择器的结束时间
|
|
108
|
+
timeRangeEndValue: {
|
|
109
|
+
get () {
|
|
110
|
+
return Array.isArray(this.value) && this.value.length > 1 ? this.value[1] : undefined
|
|
111
|
+
},
|
|
112
|
+
set (val) {
|
|
113
|
+
const start = (Array.isArray(this.value) && this.value.length > 0) ? this.value[0] : ''
|
|
114
|
+
this.$emit('change', [start, val || ''])
|
|
115
|
+
},
|
|
116
|
+
},
|
|
97
117
|
// 格式化类型
|
|
98
118
|
formatType () {
|
|
99
119
|
let defaultFormat = 'YYYY-MM-DD HH:mm:ss'
|
|
@@ -111,6 +131,8 @@ export default {
|
|
|
111
131
|
defaultFormat = 'YYYY-MM'
|
|
112
132
|
} else if (['yearRangePicker', 'yearPicker'].includes(this.attr.type)) {
|
|
113
133
|
defaultFormat = 'YYYY'
|
|
134
|
+
} else if (['timePicker', 'timeRangePicker'].includes(this.attr.type)) {
|
|
135
|
+
defaultFormat = 'HH:mm:ss'
|
|
114
136
|
}
|
|
115
137
|
return (
|
|
116
138
|
(this.mode === '查询' && this.attr.queryValueFormat
|
|
@@ -146,6 +168,7 @@ export default {
|
|
|
146
168
|
rangePicker: ['开始日期', '结束日期'],
|
|
147
169
|
monthRangePicker: ['开始月份', '结束月份'],
|
|
148
170
|
yearRangePicker: ['开始年份', '结束年份'],
|
|
171
|
+
timeRangePicker: ['开始时间', '结束时间'],
|
|
149
172
|
}
|
|
150
173
|
return placeholders[this.attr.type] || ['开始', '结束']
|
|
151
174
|
},
|
|
@@ -256,6 +279,44 @@ export default {
|
|
|
256
279
|
"
|
|
257
280
|
style="width: 100%"
|
|
258
281
|
/>
|
|
282
|
+
<!-- 时间选择器 -->
|
|
283
|
+
<a-time-picker
|
|
284
|
+
v-else-if="attr.type === 'timePicker'"
|
|
285
|
+
:getCalendarContainer="enablePopupToBody? undefined :getCalendarContainer"
|
|
286
|
+
:getPopupContainer="enablePopupToBody? getBodyContainer : undefined"
|
|
287
|
+
v-model="localValue"
|
|
288
|
+
:disabled="disabled || readOnly"
|
|
289
|
+
style="width: 100%"
|
|
290
|
+
placeholder="请选择时间"
|
|
291
|
+
:format="formatType"
|
|
292
|
+
:valueFormat="formatType"
|
|
293
|
+
/>
|
|
294
|
+
<!-- 时间范围选择器 -->
|
|
295
|
+
<div
|
|
296
|
+
v-else-if="attr.type === 'timeRangePicker'"
|
|
297
|
+
style="display: flex; align-items: center; gap: 8px; width: 100%">
|
|
298
|
+
<a-time-picker
|
|
299
|
+
:getCalendarContainer="enablePopupToBody? undefined :getCalendarContainer"
|
|
300
|
+
:getPopupContainer="enablePopupToBody? getBodyContainer : undefined"
|
|
301
|
+
v-model="timeRangeStartValue"
|
|
302
|
+
:disabled="disabled || readOnly"
|
|
303
|
+
style="flex: 1"
|
|
304
|
+
:placeholder="placeholder[0]"
|
|
305
|
+
:format="formatType"
|
|
306
|
+
:valueFormat="formatType"
|
|
307
|
+
/>
|
|
308
|
+
<span style="color: rgba(0, 0, 0, 0.45)"> - </span>
|
|
309
|
+
<a-time-picker
|
|
310
|
+
:getCalendarContainer="enablePopupToBody? undefined :getCalendarContainer"
|
|
311
|
+
:getPopupContainer="enablePopupToBody? getBodyContainer : undefined"
|
|
312
|
+
v-model="timeRangeEndValue"
|
|
313
|
+
:disabled="disabled || readOnly"
|
|
314
|
+
style="flex: 1"
|
|
315
|
+
:placeholder="placeholder[1]"
|
|
316
|
+
:format="formatType"
|
|
317
|
+
:valueFormat="formatType"
|
|
318
|
+
/>
|
|
319
|
+
</div>
|
|
259
320
|
<!-- 单日范围选择器 / 月份范围选择器/ 年份范围选择器 -->
|
|
260
321
|
<a-range-picker
|
|
261
322
|
v-else-if="
|
|
@@ -302,6 +302,8 @@ export default {
|
|
|
302
302
|
monthRangePicker: 'YYYY-MM',
|
|
303
303
|
datePicker: 'YYYY-MM-DD',
|
|
304
304
|
rangePicker: 'YYYY-MM-DD HH:mm:ss',
|
|
305
|
+
timePicker: 'HH:mm:ss',
|
|
306
|
+
timeRangePicker: 'HH:mm:ss',
|
|
305
307
|
}
|
|
306
308
|
let format = formatMap[type]
|
|
307
309
|
|
|
@@ -331,7 +333,7 @@ export default {
|
|
|
331
333
|
default:
|
|
332
334
|
return undefined
|
|
333
335
|
}
|
|
334
|
-
if (['monthPicker', 'yearPicker', 'datePicker'].includes(type)) {
|
|
336
|
+
if (['monthPicker', 'yearPicker', 'datePicker', 'timePicker'].includes(type)) {
|
|
335
337
|
if (queryType === 'BETWEEN') {
|
|
336
338
|
return [start, end]
|
|
337
339
|
}
|
|
@@ -340,7 +342,7 @@ export default {
|
|
|
340
342
|
} else {
|
|
341
343
|
return end
|
|
342
344
|
}
|
|
343
|
-
} else if (['rangePicker', 'yearRangePicker', 'monthRangePicker'].includes(type)) {
|
|
345
|
+
} else if (['rangePicker', 'yearRangePicker', 'monthRangePicker', 'timeRangePicker'].includes(type)) {
|
|
344
346
|
return [start, end]
|
|
345
347
|
}
|
|
346
348
|
return [start, end]
|
|
@@ -348,7 +350,7 @@ export default {
|
|
|
348
350
|
setFormProps (formData, item) {
|
|
349
351
|
formData[item.model] = undefined
|
|
350
352
|
if (item.queryFormDefault) {
|
|
351
|
-
if (['datePicker', 'rangePicker', 'yearPicker', 'monthPicker', 'yearRangePicker', 'monthRangePicker'].includes(item.type)) {
|
|
353
|
+
if (['datePicker', 'rangePicker', 'yearPicker', 'monthPicker', 'yearRangePicker', 'monthRangePicker', 'timePicker', 'timeRangePicker'].includes(item.type)) {
|
|
352
354
|
formData[item.model] = this.getDateRange(item)
|
|
353
355
|
} else if (['treeSelect', 'select', 'checkbox'].includes(item.type) && ['curOrgId', 'curDepId', 'curUserId'].includes(item.queryFormDefault)) {
|
|
354
356
|
if (item.queryFormDefault === 'curOrgId') {
|
|
@@ -383,7 +383,7 @@
|
|
|
383
383
|
</x-form-col>
|
|
384
384
|
<!-- 时间 日期 框整合 -->
|
|
385
385
|
<x-form-col
|
|
386
|
-
v-else-if="['datePicker', 'rangePicker', 'yearPicker', 'monthPicker', 'yearRangePicker', 'monthRangePicker'].includes(attr.type) && show"
|
|
386
|
+
v-else-if="['datePicker', 'rangePicker', 'yearPicker', 'monthPicker', 'yearRangePicker', 'monthRangePicker', 'timePicker', 'timeRangePicker'].includes(attr.type) && show"
|
|
387
387
|
:labelCol="labelCol"
|
|
388
388
|
:flex="attr.flex">
|
|
389
389
|
<a-form-model-item
|