p-pc-ui 1.3.12 → 1.3.14
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/dist/components/p-button-rounded/p-button-rounded.vue +1 -1
- package/dist/components/p-form/form-utils.ts +167 -0
- package/dist/components/p-form/p-form.vue +211 -272
- package/dist/components/p-modal/p-modal.vue +1 -1
- package/dist/components/p-modal-confirm/p-modal-confirm.vue +1 -3
- package/dist/components/p-modal-form/p-form-modal.vue +10 -6
- package/dist/components/p-table/p-table.vue +62 -158
- package/dist/components/p-table/table-utils.ts +115 -0
- package/dist/env.d.ts +6 -0
- package/package.json +1 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ref, reactive,
|
|
2
|
+
import { ref, reactive, onBeforeMount, useSlots, toRaw, isRef, isReactive } from "vue";
|
|
3
3
|
import type { FormDataItem } from "./index";
|
|
4
|
+
import { initFormStateFromRenderData, normalizeFormRenderData, type FormRenderItem } from "./form-utils";
|
|
4
5
|
import {
|
|
5
6
|
Button as AButton,
|
|
6
7
|
message,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
Upload as AUpload,
|
|
17
18
|
Textarea as ATextarea,
|
|
18
19
|
Space as ASpace,
|
|
20
|
+
DatePicker as ADatePicker,
|
|
19
21
|
} from "ant-design-vue";
|
|
20
22
|
import type { FormInstance } from "ant-design-vue";
|
|
21
23
|
import * as _ from "../../utils/dataUtils";
|
|
@@ -49,7 +51,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
49
51
|
});
|
|
50
52
|
|
|
51
53
|
// 渲染后的表单
|
|
52
|
-
const renderData = ref<
|
|
54
|
+
const renderData = ref<FormRenderItem[]>([]);
|
|
53
55
|
|
|
54
56
|
// 表单数据
|
|
55
57
|
const formState: any = reactive({});
|
|
@@ -77,6 +79,7 @@ type SelectLoadState = {
|
|
|
77
79
|
keyword: string;
|
|
78
80
|
hasMore: boolean;
|
|
79
81
|
loading: boolean;
|
|
82
|
+
requestId: number;
|
|
80
83
|
};
|
|
81
84
|
|
|
82
85
|
const getSelectValueField = (renderItem: any) => {
|
|
@@ -91,6 +94,7 @@ const ensureSelectLoadState = (renderItem: FormDataItem & { [key: string]: any }
|
|
|
91
94
|
keyword: "",
|
|
92
95
|
hasMore: true,
|
|
93
96
|
loading: false,
|
|
97
|
+
requestId: 0,
|
|
94
98
|
} as SelectLoadState;
|
|
95
99
|
}
|
|
96
100
|
|
|
@@ -137,14 +141,13 @@ const buildSelectLoadParams = (renderItem: FormDataItem & { [key: string]: any }
|
|
|
137
141
|
const normalizeSelectLoadResult = (res: SelectLoadResult, state: SelectLoadState) => {
|
|
138
142
|
const list = Array.isArray(res) ? res : res?.data || [];
|
|
139
143
|
|
|
140
|
-
const hasMore =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
: typeof res?.pages?.total === "number" && typeof res?.pages?.now === "number"
|
|
144
|
+
const hasMore = Array.isArray(res)
|
|
145
|
+
? list.length >= state.pageSize
|
|
146
|
+
: typeof res?.pages?.total === "number" && typeof res?.pages?.now === "number"
|
|
144
147
|
? res.pages.now < res.pages.total
|
|
145
148
|
: typeof res?.count === "number"
|
|
146
|
-
|
|
147
|
-
|
|
149
|
+
? state.pageNum * state.pageSize < res.count
|
|
150
|
+
: list.length >= state.pageSize;
|
|
148
151
|
|
|
149
152
|
return {
|
|
150
153
|
list,
|
|
@@ -154,7 +157,7 @@ const normalizeSelectLoadResult = (res: SelectLoadResult, state: SelectLoadState
|
|
|
154
157
|
|
|
155
158
|
const fetchSelectOptions = async (
|
|
156
159
|
renderItem: FormDataItem & { [key: string]: any },
|
|
157
|
-
options: { reset?: boolean; keyword?: string } = {}
|
|
160
|
+
options: { reset?: boolean; keyword?: string } = {},
|
|
158
161
|
) => {
|
|
159
162
|
if (renderItem.type !== "select" || !renderItem.loadDataFunc) return;
|
|
160
163
|
const state = ensureSelectLoadState(renderItem);
|
|
@@ -174,8 +177,11 @@ const fetchSelectOptions = async (
|
|
|
174
177
|
if (!state.hasMore) return;
|
|
175
178
|
|
|
176
179
|
state.loading = true;
|
|
180
|
+
const requestId = state.requestId + 1;
|
|
181
|
+
state.requestId = requestId;
|
|
177
182
|
try {
|
|
178
183
|
const res = (await renderItem.loadDataFunc(buildSelectLoadParams(renderItem, state))) as SelectLoadResult;
|
|
184
|
+
if (requestId !== state.requestId) return;
|
|
179
185
|
const normalizedRes = normalizeSelectLoadResult(res, state);
|
|
180
186
|
const list = normalizedRes.list;
|
|
181
187
|
if (options.reset) {
|
|
@@ -188,7 +194,9 @@ const fetchSelectOptions = async (
|
|
|
188
194
|
state.pageNum += 1;
|
|
189
195
|
}
|
|
190
196
|
} finally {
|
|
191
|
-
state.
|
|
197
|
+
if (requestId === state.requestId) {
|
|
198
|
+
state.loading = false;
|
|
199
|
+
}
|
|
192
200
|
}
|
|
193
201
|
};
|
|
194
202
|
|
|
@@ -237,106 +245,44 @@ onBeforeMount(async () => {
|
|
|
237
245
|
* 处理渲染表单
|
|
238
246
|
*/
|
|
239
247
|
const disposeRenderData = async (renderData: FormDataItem[]) => {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
let { fieldType, fieldRules, label } = renderItem;
|
|
247
|
-
// 处理校验规则
|
|
248
|
-
const rules: any = [];
|
|
249
|
-
const operateType = ["select", "treeSelect", "date", "datePicker"].includes(renderItem.type) ? "选择" : "输入";
|
|
250
|
-
for (const fieldRule of fieldRules || []) {
|
|
251
|
-
const { msg, required, min, max, regex } = fieldRule;
|
|
252
|
-
|
|
253
|
-
// 图片需要额外处理
|
|
254
|
-
if (
|
|
255
|
-
(renderItem.type == "uploadOss" || renderItem.type == "uploadTos" || renderItem.type == "upload") &&
|
|
256
|
-
renderItem.fieldType == "string"
|
|
257
|
-
) {
|
|
258
|
-
fieldType = "array";
|
|
259
|
-
}
|
|
248
|
+
let mapInfo = {};
|
|
249
|
+
try {
|
|
250
|
+
mapInfo = JSON.parse(localStorage.getItem("map") || "{}");
|
|
251
|
+
} catch (error) {
|
|
252
|
+
mapInfo = {};
|
|
253
|
+
}
|
|
260
254
|
|
|
255
|
+
const _renderData = normalizeFormRenderData(renderData, mapInfo);
|
|
261
256
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
if (min) {
|
|
271
|
-
rules.push({
|
|
272
|
-
type: fieldType,
|
|
273
|
-
min: min,
|
|
274
|
-
message: msg || `${label}需大于等于${min}${fieldType == "string" ? "个字符" : ""}`,
|
|
275
|
-
trigger: ["blur", "change"],
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (max) {
|
|
280
|
-
rules.push({
|
|
281
|
-
type: fieldType,
|
|
282
|
-
max: max,
|
|
283
|
-
message: `${label}需小于等于${max}${fieldType == "string" ? "个字符" : ""}`,
|
|
284
|
-
trigger: ["blur", "change"],
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
if (regex) {
|
|
288
|
-
rules.push({
|
|
289
|
-
type: fieldType,
|
|
290
|
-
pattern: regex,
|
|
291
|
-
message: msg || `${label}格式错误`,
|
|
292
|
-
trigger: ["blur", "change"],
|
|
293
|
-
});
|
|
257
|
+
await Promise.all(
|
|
258
|
+
_renderData.map(async (renderItem) => {
|
|
259
|
+
if (
|
|
260
|
+
(renderItem.type !== "treeSelect" && renderItem.type !== "select" && renderItem.type !== "radio") ||
|
|
261
|
+
!renderItem.loadDataFunc
|
|
262
|
+
) {
|
|
263
|
+
return;
|
|
294
264
|
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
|
|
298
265
|
|
|
299
|
-
|
|
266
|
+
let point: string[] = [];
|
|
267
|
+
const interval = window.setInterval(() => {
|
|
268
|
+
if (point.length >= 3) point = [];
|
|
269
|
+
point.push(".");
|
|
270
|
+
renderItem.placeholder = "加载中" + point.join("");
|
|
271
|
+
}, 500);
|
|
300
272
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
// 立即执行函数, 获取下拉的列表
|
|
304
|
-
if (renderItem.loadDataFunc) {
|
|
305
|
-
let point: string[] = [];
|
|
306
|
-
const interval = setInterval(() => {
|
|
307
|
-
if (point.length >= 3) point = [];
|
|
308
|
-
point.push(".");
|
|
309
|
-
renderItem.placeholder = "加载中" + point.join("");
|
|
310
|
-
}, 500);
|
|
311
|
-
|
|
312
|
-
if (renderItem.type == "select") {
|
|
273
|
+
try {
|
|
274
|
+
if (renderItem.type === "select") {
|
|
313
275
|
await fetchSelectOptions(renderItem as FormDataItem & { [key: string]: any }, { reset: true });
|
|
314
276
|
} else {
|
|
315
277
|
const res = await renderItem.loadDataFunc();
|
|
316
|
-
renderItem
|
|
278
|
+
renderItem.optionList = Array.isArray(res) ? res : res?.data || [];
|
|
317
279
|
}
|
|
280
|
+
} finally {
|
|
318
281
|
clearInterval(interval);
|
|
319
282
|
renderItem.placeholder = `请选择${renderItem.label}`;
|
|
320
283
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if (renderItem.mapPath) {
|
|
324
|
-
const mapInfoStr = localStorage.getItem("map");
|
|
325
|
-
if (mapInfoStr) {
|
|
326
|
-
const mapInfo = JSON.parse(mapInfoStr);
|
|
327
|
-
const mapItem = _.get(mapInfo, renderItem.mapPath);
|
|
328
|
-
const optionList: any[] = [];
|
|
329
|
-
for (const key in mapItem) {
|
|
330
|
-
optionList.push({
|
|
331
|
-
label: mapItem[key],
|
|
332
|
-
value: key,
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
renderItem["optionList"] = optionList;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
284
|
+
}),
|
|
285
|
+
);
|
|
340
286
|
|
|
341
287
|
return _renderData;
|
|
342
288
|
};
|
|
@@ -344,110 +290,14 @@ const disposeRenderData = async (renderData: FormDataItem[]) => {
|
|
|
344
290
|
/**
|
|
345
291
|
* 初始化表单数据
|
|
346
292
|
*/
|
|
347
|
-
const initFormState = (renderData:
|
|
348
|
-
const _formState: any = {};
|
|
349
|
-
for (const renderItem of renderData) {
|
|
350
|
-
// 处理json字段 例如 data.name = data:{name:xxx}
|
|
351
|
-
renderItem["key"] = renderItem["key"].replaceAll(".", "__");
|
|
352
|
-
let initValue;
|
|
353
|
-
// 判断渲染表单是否有默认值
|
|
354
|
-
if (renderItem.default != undefined) {
|
|
355
|
-
initValue = renderItem.default;
|
|
356
|
-
_formState[renderItem.key] = initValue;
|
|
357
|
-
continue;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
initValue = _.get(initFromData, renderItem["key"].split("__").join("."));
|
|
361
|
-
|
|
362
|
-
if (initValue == undefined) {
|
|
363
|
-
switch (renderItem.fieldType) {
|
|
364
|
-
case "array":
|
|
365
|
-
initValue = [];
|
|
366
|
-
break;
|
|
367
|
-
case "string":
|
|
368
|
-
// 如果是图片类型, 并且是string类型,代表用户只需要1张图片,并且已文本的形式存放
|
|
369
|
-
if (renderItem.type == "uploadOss" || renderItem.type == "uploadTos" || renderItem.type == "upload") {
|
|
370
|
-
initValue = [];
|
|
371
|
-
} else {
|
|
372
|
-
initValue = "";
|
|
373
|
-
}
|
|
374
|
-
break;
|
|
375
|
-
case "number":
|
|
376
|
-
initValue = 0;
|
|
377
|
-
break;
|
|
378
|
-
case "date":
|
|
379
|
-
initValue: "";
|
|
380
|
-
break;
|
|
381
|
-
default:
|
|
382
|
-
initValue = undefined;
|
|
383
|
-
break;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// 判断是否是下拉组件 并且设置默认值
|
|
388
|
-
const renderItemType = renderItem.type;
|
|
389
|
-
if (renderItemType == "select" || renderItemType == "treeSelect" || renderItemType == "radio") {
|
|
390
|
-
// 初始化值避免为空导致后续异步操作push失败
|
|
391
|
-
if (_.isEmpty(renderItem.optionList)) {
|
|
392
|
-
renderItem.optionList = [];
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (renderItem.type == "select" && renderItem.isMultiple) {
|
|
396
|
-
if (!_.isArray(initValue)) {
|
|
397
|
-
initValue = [];
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
if (!initValue && renderItem.optionList) {
|
|
402
|
-
if (!(renderItem.type == "select" && renderItem.isMultiple)) {
|
|
403
|
-
const valueKey = renderItem.fieldNames?.value || (renderItem.type == "treeSelect" ? "id" : "value");
|
|
404
|
-
initValue = renderItem["optionList"][0]?.[valueKey];
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (renderItem.loadDataFunc) {
|
|
409
|
-
initValue = renderItem.type == "select" && renderItem.isMultiple ? [] : undefined;
|
|
410
|
-
}
|
|
411
|
-
} else if (renderItem.type == "uploadOss") {
|
|
412
|
-
if (!_.isArray(initValue)) {
|
|
413
|
-
initValue = [initValue];
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
initValue = initValue.map((val) => {
|
|
417
|
-
return {
|
|
418
|
-
key: val,
|
|
419
|
-
url: renderItem.baseOssUrl + val,
|
|
420
|
-
};
|
|
421
|
-
});
|
|
422
|
-
} else if (renderItem.type == "uploadTos") {
|
|
423
|
-
if (!_.isArray(initValue)) {
|
|
424
|
-
initValue = [initValue];
|
|
425
|
-
}
|
|
426
|
-
initValue = initValue.map((val) => {
|
|
427
|
-
return {
|
|
428
|
-
key: val,
|
|
429
|
-
url: renderItem.baseTosUrl + val,
|
|
430
|
-
};
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
_formState[renderItem["key"]] = initValue;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
return _formState;
|
|
438
|
-
};
|
|
293
|
+
const initFormState = (renderData: FormRenderItem[], initFromData = {}) => initFormStateFromRenderData(renderData, initFromData);
|
|
439
294
|
|
|
440
295
|
const handlePicPreview = (file: any) => {
|
|
441
|
-
const url = URL.createObjectURL(file.originFileObj);
|
|
296
|
+
const url = file.url || file.key || file.thumbUrl || (file.originFileObj ? URL.createObjectURL(file.originFileObj) : "");
|
|
442
297
|
|
|
443
|
-
|
|
444
|
-
};
|
|
445
|
-
|
|
446
|
-
const replaceUrl = (str, urlToReplace, replacement) => {
|
|
447
|
-
// 转义特殊字符
|
|
448
|
-
let escapedUrl = urlToReplace.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
|
|
449
|
-
let pattern = new RegExp(escapedUrl, "g");
|
|
450
|
-
return str.replace(pattern, replacement);
|
|
298
|
+
if (url) {
|
|
299
|
+
viewerApi({ images: [url] });
|
|
300
|
+
}
|
|
451
301
|
};
|
|
452
302
|
|
|
453
303
|
/**
|
|
@@ -467,6 +317,7 @@ const getFormData = async (options: { no_check?: Boolean } = {}) => {
|
|
|
467
317
|
const returnFormData = {};
|
|
468
318
|
for (const renderItem of renderData.value) {
|
|
469
319
|
const { key } = renderItem;
|
|
320
|
+
const rawKey = renderItem.rawKey || key;
|
|
470
321
|
|
|
471
322
|
// 如果控制显隐函数,判断值是否有效
|
|
472
323
|
if (renderItem?.visibleHook && !renderItem.visibleHook(formData)) {
|
|
@@ -478,21 +329,33 @@ const getFormData = async (options: { no_check?: Boolean } = {}) => {
|
|
|
478
329
|
const keys = fileData.map((val) => {
|
|
479
330
|
return val?.response?.key || val.key;
|
|
480
331
|
});
|
|
481
|
-
|
|
332
|
+
if (rawKey.includes(".")) {
|
|
333
|
+
_.set(returnFormData, rawKey, renderItem?.fieldType == "string" ? keys[0] : keys);
|
|
334
|
+
} else {
|
|
335
|
+
returnFormData[rawKey] = renderItem?.fieldType == "string" ? keys[0] : keys;
|
|
336
|
+
}
|
|
482
337
|
}
|
|
483
338
|
// 获取file对象
|
|
484
339
|
else if (renderItem.type == "upload") {
|
|
485
340
|
const formatData = formState[key].map((val) => ({ base64: val.thumbUrl, file: val.originFileObj }));
|
|
486
|
-
|
|
341
|
+
if (rawKey.includes(".")) {
|
|
342
|
+
_.set(returnFormData, rawKey, formatData);
|
|
343
|
+
} else {
|
|
344
|
+
returnFormData[rawKey] = formatData;
|
|
345
|
+
}
|
|
487
346
|
}
|
|
488
347
|
|
|
489
348
|
// 转换成上传对象
|
|
490
|
-
else if (
|
|
491
|
-
_.set(returnFormData,
|
|
349
|
+
else if (rawKey.includes(".")) {
|
|
350
|
+
_.set(returnFormData, rawKey, formData[key]);
|
|
492
351
|
} else if (renderItem.type == "datePicker") {
|
|
493
|
-
returnFormData[
|
|
352
|
+
returnFormData[rawKey] = formData[key] ? dayjs(formData[key]).format("YYYY-MM-DD HH:mm:ss") : "";
|
|
353
|
+
}
|
|
354
|
+
else if ( isRef(formData[key]) || isReactive(formData[key]) ) {
|
|
355
|
+
|
|
356
|
+
returnFormData[rawKey] = toRaw(formData[key]);
|
|
494
357
|
} else {
|
|
495
|
-
returnFormData[
|
|
358
|
+
returnFormData[rawKey] = formData[key];
|
|
496
359
|
}
|
|
497
360
|
}
|
|
498
361
|
|
|
@@ -510,9 +373,13 @@ const resetForm = () => {
|
|
|
510
373
|
* 确认按钮点击
|
|
511
374
|
*/
|
|
512
375
|
const confirmClick = async () => {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
376
|
+
try {
|
|
377
|
+
const formData = await getFormData();
|
|
378
|
+
if (Object.keys(formData).length == 0) return;
|
|
379
|
+
emits("confirm", formData, resetForm);
|
|
380
|
+
} catch (error) {
|
|
381
|
+
console.warn("Form validation failed:", error);
|
|
382
|
+
}
|
|
516
383
|
};
|
|
517
384
|
|
|
518
385
|
const uploadChange = (e, renderItem) => {
|
|
@@ -621,26 +488,46 @@ defineExpose({
|
|
|
621
488
|
</script>
|
|
622
489
|
|
|
623
490
|
<template>
|
|
624
|
-
<a-form
|
|
625
|
-
|
|
491
|
+
<a-form
|
|
492
|
+
ref="formRef"
|
|
493
|
+
:model="formState"
|
|
494
|
+
name="basic"
|
|
495
|
+
autocomplete="off"
|
|
496
|
+
:layout="layout"
|
|
497
|
+
:required-mark="requiredMark"
|
|
498
|
+
>
|
|
626
499
|
<div v-for="(renderItem, index) in renderData">
|
|
627
|
-
<a-form-item
|
|
500
|
+
<a-form-item
|
|
501
|
+
:label-col="{ span: renderItem.hideLabel ? 0 : renderItem.labelSpan || labelSpan }"
|
|
628
502
|
:wrapper-col="{ span: renderItem.hideLabel ? undefined : renderItem.valueSpan || valueSpan }"
|
|
629
503
|
v-show="!renderItem.visibleHook || (renderItem.visibleHook && renderItem.visibleHook(formState))"
|
|
630
|
-
:label="renderItem.label && !renderItem.hideLabel ? renderItem.label : ''"
|
|
631
|
-
:
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}"
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
504
|
+
:label="renderItem.label && !renderItem.hideLabel ? renderItem.label : ''"
|
|
505
|
+
:name="renderItem.key"
|
|
506
|
+
:colon="renderItem.colon == undefined ? true : renderItem.colon"
|
|
507
|
+
:rules="
|
|
508
|
+
!renderItem.visibleHook || (renderItem.visibleHook && renderItem.visibleHook(formState))
|
|
509
|
+
? renderItem.rules
|
|
510
|
+
: undefined
|
|
511
|
+
"
|
|
512
|
+
:style="{
|
|
513
|
+
marginBottom: isSearchForm ? '20px' : '0px',
|
|
514
|
+
}"
|
|
515
|
+
:tooltip="renderItem.tooltip"
|
|
516
|
+
:label-align="renderItem.labelAlign || 'right'"
|
|
517
|
+
>
|
|
518
|
+
<div
|
|
519
|
+
:style="{
|
|
520
|
+
opacity: renderItem.disabled ? 0.6 : 1,
|
|
521
|
+
cursor: renderItem.disabled ? 'not-allowed' : 'auto',
|
|
522
|
+
}"
|
|
523
|
+
>
|
|
524
|
+
<a-input
|
|
525
|
+
v-model:value="formState[renderItem.key]"
|
|
526
|
+
v-if="renderItem.type == 'input' && [undefined, 'string'].includes(renderItem.fieldType)"
|
|
527
|
+
type="text"
|
|
528
|
+
:disabled="renderItem.disabled"
|
|
529
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
530
|
+
>
|
|
644
531
|
<template v-if="renderItem.prefix" v-slot:prefix>
|
|
645
532
|
<component :is="renderItem.prefix" />
|
|
646
533
|
</template>
|
|
@@ -649,9 +536,13 @@ defineExpose({
|
|
|
649
536
|
</template>
|
|
650
537
|
</a-input>
|
|
651
538
|
|
|
652
|
-
<a-input
|
|
653
|
-
v-
|
|
654
|
-
|
|
539
|
+
<a-input
|
|
540
|
+
v-model:value.number="formState[renderItem.key]"
|
|
541
|
+
v-if="(renderItem.type == 'input' && renderItem.fieldType == 'number') || renderItem.type == 'number'"
|
|
542
|
+
type="number"
|
|
543
|
+
:disabled="renderItem.disabled"
|
|
544
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
545
|
+
>
|
|
655
546
|
<template v-if="renderItem.prefix" v-slot:prefix>
|
|
656
547
|
<component :is="renderItem.prefix" />
|
|
657
548
|
</template>
|
|
@@ -660,25 +551,37 @@ defineExpose({
|
|
|
660
551
|
</template>
|
|
661
552
|
</a-input>
|
|
662
553
|
|
|
663
|
-
<a-input-password
|
|
664
|
-
|
|
665
|
-
|
|
554
|
+
<a-input-password
|
|
555
|
+
v-model:value="formState[renderItem.key]"
|
|
556
|
+
v-if="renderItem.type == 'password'"
|
|
557
|
+
type="password"
|
|
558
|
+
:disabled="renderItem.disabled"
|
|
559
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
560
|
+
>
|
|
666
561
|
<template v-if="renderItem.prefix" v-slot:prefix>
|
|
667
562
|
<component :is="renderItem.prefix" />
|
|
668
563
|
</template>
|
|
669
564
|
</a-input-password>
|
|
670
565
|
|
|
671
|
-
<a-input
|
|
672
|
-
v-
|
|
673
|
-
|
|
566
|
+
<a-input
|
|
567
|
+
v-model:value="formState[renderItem.key]"
|
|
568
|
+
v-if="renderItem.type == 'code' && [undefined, 'string'].includes(renderItem.fieldType)"
|
|
569
|
+
type="text"
|
|
570
|
+
:disabled="renderItem.disabled"
|
|
571
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
572
|
+
>
|
|
674
573
|
<template v-if="renderItem.prefix" v-slot:prefix>
|
|
675
574
|
<component :is="renderItem.prefix" />
|
|
676
575
|
</template>
|
|
677
576
|
<template v-slot:suffix>
|
|
678
|
-
<span
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
577
|
+
<span
|
|
578
|
+
v-if="
|
|
579
|
+
(!renderItem.activityFunc || (renderItem.activityFunc && renderItem.activityFunc(formState))) &&
|
|
580
|
+
renderItem.sendStatus != 'sending'
|
|
581
|
+
"
|
|
582
|
+
class="send-notice send-notice-activity"
|
|
583
|
+
@click="sendNoticeClick(renderItem)"
|
|
584
|
+
>
|
|
682
585
|
{{ renderItem.codeName }}
|
|
683
586
|
</span>
|
|
684
587
|
<span v-else class="send-notice">
|
|
@@ -687,50 +590,83 @@ defineExpose({
|
|
|
687
590
|
</template>
|
|
688
591
|
</a-input>
|
|
689
592
|
|
|
690
|
-
<a-textarea
|
|
691
|
-
:
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
:
|
|
696
|
-
|
|
697
|
-
|
|
593
|
+
<a-textarea
|
|
594
|
+
v-model:value="formState[renderItem.key]"
|
|
595
|
+
v-if="renderItem.type == 'textarea'"
|
|
596
|
+
:disabled="renderItem.disabled"
|
|
597
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
598
|
+
:auto-size="{ minRows: 2, maxRows: 10 }"
|
|
599
|
+
/>
|
|
600
|
+
|
|
601
|
+
<a-select
|
|
602
|
+
style="min-width: 170px; margin-right: 15px"
|
|
603
|
+
v-model:value="formState[renderItem.key]"
|
|
604
|
+
:placeholder="renderItem.placeholder || `请选择`"
|
|
605
|
+
v-if="renderItem.type == 'select'"
|
|
606
|
+
:disabled="renderItem.disabled"
|
|
607
|
+
:fieldNames="renderItem.fieldNames || { label: 'label', value: 'value' }"
|
|
608
|
+
:options="renderItem.optionList"
|
|
609
|
+
:mode="renderItem.isMultiple ? 'multiple' : undefined"
|
|
698
610
|
:show-search="renderItem.enableSearch || !!renderItem.loadDataFunc"
|
|
699
611
|
:filter-option="renderItem.loadDataFunc ? false : !!renderItem.enableSearch"
|
|
700
612
|
:option-filter-prop="renderItem.fieldNames?.label || 'label'"
|
|
701
613
|
:loading="(renderItem as any).__selectState?.loading"
|
|
702
614
|
@search="(keyword) => onSelectSearch(keyword, renderItem as any)"
|
|
703
|
-
@popupScroll="(e) => onSelectPopupScroll(e, renderItem as any)"
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
615
|
+
@popupScroll="(e) => onSelectPopupScroll(e, renderItem as any)"
|
|
616
|
+
></a-select>
|
|
617
|
+
|
|
618
|
+
<a-radio-group
|
|
619
|
+
v-if="renderItem.type == 'radio'"
|
|
620
|
+
v-model:value="formState[renderItem.key]"
|
|
621
|
+
:disabled="renderItem.disabled"
|
|
622
|
+
>
|
|
707
623
|
<a-radio v-for="item in renderItem.optionList" :value="item[renderItem.fieldNames?.value || 'value']">
|
|
708
624
|
{{ item[renderItem.fieldNames?.label || "label"] }}
|
|
709
625
|
</a-radio>
|
|
710
626
|
</a-radio-group>
|
|
711
627
|
|
|
712
|
-
<a-date-picker
|
|
713
|
-
:
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
:
|
|
628
|
+
<a-date-picker
|
|
629
|
+
v-model:value="formState[renderItem.key]"
|
|
630
|
+
v-if="renderItem.type === 'datePicker'"
|
|
631
|
+
show-time
|
|
632
|
+
:disabled="renderItem.disabled"
|
|
633
|
+
:placeholder="`请选择${renderItem.label}`"
|
|
634
|
+
class="ant-input"
|
|
635
|
+
format="YYYY-MM-DD HH:mm:ss"
|
|
636
|
+
value-format="YYYY-MM-DD HH:mm:ss"
|
|
637
|
+
/>
|
|
638
|
+
|
|
639
|
+
<a-tree-select
|
|
640
|
+
style="min-width: 170px; margin-right: 15px"
|
|
641
|
+
v-model:value="formState[renderItem.key]"
|
|
642
|
+
:tree-data="renderItem.optionList"
|
|
643
|
+
v-if="renderItem.type == 'treeSelect'"
|
|
644
|
+
:disabled="renderItem.disabled"
|
|
718
645
|
:fieldNames="renderItem.fieldNames || { children: 'children', label: 'name', value: 'id' }"
|
|
719
|
-
:placeholder="renderItem.placeholder || `请选择`"
|
|
646
|
+
:placeholder="renderItem.placeholder || `请选择`"
|
|
647
|
+
></a-tree-select>
|
|
720
648
|
|
|
721
649
|
<a-upload
|
|
722
650
|
v-if="renderItem.type == 'uploadOss' || renderItem.type == 'uploadTos' || renderItem.type == 'upload'"
|
|
723
|
-
:file-list="formState[renderItem.key]"
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
651
|
+
:file-list="formState[renderItem.key]"
|
|
652
|
+
:multiple="true"
|
|
653
|
+
:max-count="renderItem?.maxCount || 1"
|
|
654
|
+
@preview="handlePicPreview"
|
|
655
|
+
:customRequest="
|
|
656
|
+
(e) => {
|
|
657
|
+
uploadRequest(e, renderItem);
|
|
658
|
+
}
|
|
659
|
+
"
|
|
660
|
+
@change="
|
|
661
|
+
(e) => {
|
|
662
|
+
uploadChange(e, renderItem);
|
|
663
|
+
}
|
|
664
|
+
"
|
|
665
|
+
:headers="{
|
|
666
|
+
'Cache-Control': 'max-age=15552000',
|
|
667
|
+
}"
|
|
668
|
+
:list-type="renderItem.uploadType == 'pic' ? 'picture-card' : undefined"
|
|
669
|
+
>
|
|
734
670
|
<div v-if="renderItem.uploadType == 'pic'">
|
|
735
671
|
<plus-outlined />
|
|
736
672
|
<div style="margin-top: 8px">{{ renderItem.label }}</div>
|
|
@@ -744,8 +680,11 @@ defineExpose({
|
|
|
744
680
|
</div>
|
|
745
681
|
</a-upload>
|
|
746
682
|
|
|
747
|
-
<component
|
|
748
|
-
v-
|
|
683
|
+
<component
|
|
684
|
+
v-if="renderItem.type == 'component'"
|
|
685
|
+
:is="renderItem.component"
|
|
686
|
+
v-model:[renderItem.key]="formState[renderItem.key]"
|
|
687
|
+
></component>
|
|
749
688
|
</div>
|
|
750
689
|
</a-form-item>
|
|
751
690
|
</div>
|
|
@@ -753,10 +692,10 @@ defineExpose({
|
|
|
753
692
|
<div v-if="uSlots.button || showResetButton || showSubmitButton" style="display: flex; justify-content: center">
|
|
754
693
|
<slot name="button"></slot>
|
|
755
694
|
<a-space size="small">
|
|
756
|
-
<a-button v-if="showResetButton" @click="resetForm"
|
|
695
|
+
<a-button v-if="showResetButton" @click="resetForm" style="padding: 0 30px">
|
|
757
696
|
{{ resetButtonText || "取消" }}
|
|
758
697
|
</a-button>
|
|
759
|
-
<a-button type="primary" @click="confirmClick"
|
|
698
|
+
<a-button type="primary" @click="confirmClick" v-if="showSubmitButton" style="padding: 0 30px">
|
|
760
699
|
{{ submitButtonText || "确认" }}
|
|
761
700
|
</a-button>
|
|
762
701
|
</a-space>
|