@cloudbase/weda-ui-mp 3.30.0 → 3.31.0
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/components/form/uploaderFile/index.json +2 -1
- package/components/form/uploaderFile/index.wxml +1 -2
- package/components/swiper/index.js +15 -0
- package/components/wd-form/remote-value.js +77 -10
- package/components/wd-input-number/index.js +20 -40
- package/components/wd-input-phone/index.wxml +1 -0
- package/components/wd-menu-layout/wd-menu-layout.wxss +4 -0
- package/components/wd-menu-list/wd-menu-list.wxss +4 -0
- package/components/wd-select/select/index.js +8 -0
- package/components/wd-select/select/index.wxml +7 -1
- package/components/wd-select/select/index.wxss +1 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"usingComponents": {
|
|
5
5
|
"mp-cells": "weui-miniprogram/cells/cells",
|
|
6
6
|
"mp-cell": "weui-miniprogram/cell/cell",
|
|
7
|
-
"mp-actionSheet": "weui-miniprogram/actionsheet/actionsheet"
|
|
7
|
+
"mp-actionSheet": "weui-miniprogram/actionsheet/actionsheet",
|
|
8
|
+
"wd-button": "../../wd-button/index"
|
|
8
9
|
}
|
|
9
10
|
}
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
{{label}}
|
|
7
7
|
</view>
|
|
8
8
|
<view class="weda-uploader-files__btn-contain">
|
|
9
|
-
<button
|
|
10
|
-
|
|
9
|
+
<wd-button size="sm" disabled="{{disabled}}" variant="outline" text="{{uploadButtonText}}" bindtap="onButtonTap"> </wd-button>
|
|
11
10
|
<view wx:if="{{maxCount!=1}}" class="weda-uploader-files__tips">{{uploadTipText}}</view>
|
|
12
11
|
<view wx:else>
|
|
13
12
|
<slot name="tips"></slot>
|
|
@@ -41,6 +41,12 @@ Component({
|
|
|
41
41
|
value: true,
|
|
42
42
|
type: Boolean,
|
|
43
43
|
},
|
|
44
|
+
// 新增统一字段:circularEnabled 一旦显式有值(true/false),优先级高于历史 circular 字段。
|
|
45
|
+
// 仅当用户在编辑器主动开启/关闭时才有值;缺省时(null)保持旧 circular 字段语义。
|
|
46
|
+
circularEnabled: {
|
|
47
|
+
type: null,
|
|
48
|
+
value: null,
|
|
49
|
+
},
|
|
44
50
|
vertical: {
|
|
45
51
|
value: false,
|
|
46
52
|
type: Boolean,
|
|
@@ -82,4 +88,13 @@ Component({
|
|
|
82
88
|
},
|
|
83
89
|
]),
|
|
84
90
|
},
|
|
91
|
+
observers: {
|
|
92
|
+
// 当 circularEnabled 显式设置时(非 null/undefined),用其值覆盖 circular,
|
|
93
|
+
// 让 wxml 中的 circular="{{circular}}" 直接反映新字段语义,无需改动模板。
|
|
94
|
+
circularEnabled: function (circularEnabled) {
|
|
95
|
+
if (circularEnabled === null || circularEnabled === undefined) return;
|
|
96
|
+
if (this.data.circular === circularEnabled) return;
|
|
97
|
+
this.setData({ circular: circularEnabled });
|
|
98
|
+
},
|
|
99
|
+
},
|
|
85
100
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WdCompError } from '../../utils/error';
|
|
2
|
+
import { convertDayjs } from '../../utils/getFormLegacy.js';
|
|
2
3
|
|
|
3
4
|
// father-son 是老的,新的叫many-one
|
|
4
5
|
const SINGLE_SELECT_FORMATS = [
|
|
@@ -14,22 +15,86 @@ const SINGLE_SELECT_FORMATS = [
|
|
|
14
15
|
|
|
15
16
|
const MULTI_SELECT_FORMATS = ['many-many', 'one-many'];
|
|
16
17
|
|
|
18
|
+
// 判断关联关系字段是否有有效值(排除 null, undefined, '', {}, [])
|
|
19
|
+
function isValidRelationValue(value) {
|
|
20
|
+
if (value === null || value === undefined || value === '') {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
// 排除空对象 {}
|
|
24
|
+
if (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
// 排除空数组 []
|
|
28
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 单选关联字段值规范化:对象提取 _id,空对象置 undefined,原始值(字符串/null)透传
|
|
35
|
+
// 用于 father-son / related / many-one / one-one / one-one-r
|
|
36
|
+
function normalizeSingleRelationValue(v, fallback) {
|
|
37
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
38
|
+
return isValidRelationValue(v) ? v._id : undefined;
|
|
39
|
+
}
|
|
40
|
+
// 字符串/null/undefined 等原始值,透传 fallback(即原始字段值)
|
|
41
|
+
return fallback;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 多选关联字段值规范化:过滤无效项后提取每个 _id,空结果置 undefined
|
|
45
|
+
// 用于 one-many / many-many
|
|
46
|
+
function normalizeMultiRelationValue(v) {
|
|
47
|
+
if (Array.isArray(v)) {
|
|
48
|
+
const ids = v
|
|
49
|
+
.map((item) => (isValidRelationValue(item) ? item?.['_id'] : undefined))
|
|
50
|
+
.filter((id) => id !== undefined && id !== null && id !== '');
|
|
51
|
+
return ids.length > 0 ? ids : undefined;
|
|
52
|
+
}
|
|
53
|
+
if (!isValidRelationValue(v)) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
return v;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 日期字段格式化:将后端 $date 对象 / 'date'/'datetime' format 转为时间戳
|
|
60
|
+
function normalizeDateValue(fieldValue, format, type) {
|
|
61
|
+
if (type !== 'number') return undefined;
|
|
62
|
+
if (fieldValue && Object.prototype.hasOwnProperty.call(fieldValue, '$date')) {
|
|
63
|
+
return convertDayjs(fieldValue)?.valueOf() ?? null;
|
|
64
|
+
}
|
|
65
|
+
if (['date', 'datetime'].includes(format)) {
|
|
66
|
+
return convertDayjs(fieldValue)?.valueOf() ?? null;
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
17
71
|
export function convertRemoteValueToFormData(dataSourceType, dataSourceProfile, fetchedInitialValues) {
|
|
18
|
-
|
|
72
|
+
// 修正历史拼写错误 'experssion',但保留兼容
|
|
73
|
+
if (dataSourceType === 'expression' || dataSourceType === 'experssion') {
|
|
19
74
|
return fetchedInitialValues;
|
|
20
75
|
}
|
|
21
|
-
|
|
76
|
+
return Object.keys(fetchedInitialValues).reduce((acc, field) => {
|
|
22
77
|
const format = dataSourceProfile?.schema?.properties?.[field]?.format;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
78
|
+
const type = dataSourceProfile?.schema?.properties?.[field]?.type;
|
|
79
|
+
const fieldValue = fetchedInitialValues[field];
|
|
80
|
+
acc[field] = fieldValue;
|
|
81
|
+
|
|
82
|
+
// 关联关系字段:father-son / related / many-one / one-one / one-one-r
|
|
83
|
+
if (['father-son', 'related', ...SINGLE_SELECT_FORMATS].includes(format)) {
|
|
84
|
+
acc[field] = normalizeSingleRelationValue(fieldValue, fieldValue);
|
|
85
|
+
} else if (MULTI_SELECT_FORMATS.includes(format)) {
|
|
86
|
+
// 多选关联:one-many / many-many
|
|
87
|
+
acc[field] = normalizeMultiRelationValue(fieldValue);
|
|
26
88
|
}
|
|
27
|
-
|
|
28
|
-
|
|
89
|
+
|
|
90
|
+
// 日期字段:转时间戳(覆盖关联字段处理结果,因为日期字段不会同时是关联字段)
|
|
91
|
+
const dateValue = normalizeDateValue(fieldValue, format, type);
|
|
92
|
+
if (dateValue !== undefined) {
|
|
93
|
+
acc[field] = dateValue;
|
|
29
94
|
}
|
|
95
|
+
|
|
30
96
|
return acc;
|
|
31
97
|
}, {});
|
|
32
|
-
return result;
|
|
33
98
|
}
|
|
34
99
|
|
|
35
100
|
export function convertFormDataToSubmitParams(dataSourceProfile, formData, formType, _id, fields) {
|
|
@@ -38,10 +103,12 @@ export function convertFormDataToSubmitParams(dataSourceProfile, formData, formT
|
|
|
38
103
|
const format = dataSourceProfile.schema?.properties?.[cur]?.format;
|
|
39
104
|
acc[cur] = formData[cur];
|
|
40
105
|
if (SINGLE_SELECT_FORMATS.includes(format)) {
|
|
41
|
-
|
|
106
|
+
// 空值(null/undefined/''/{})时不转换,保持 null,避免提交 { _id: null } 或 { _id: {} }
|
|
107
|
+
acc[cur] = isValidRelationValue(formData[cur]) ? { _id: formData[cur] } : null;
|
|
42
108
|
}
|
|
43
109
|
if (MULTI_SELECT_FORMATS.includes(format)) {
|
|
44
|
-
|
|
110
|
+
// 空值时返回 null,有值时转换为 [{ _id: 'xxx' }] 格式
|
|
111
|
+
acc[cur] = isValidRelationValue(formData[cur]) ? formData[cur].map((_id) => ({ _id })) : null;
|
|
45
112
|
}
|
|
46
113
|
if ('x-json' === format && typeof formData[cur] === 'string') {
|
|
47
114
|
try {
|
|
@@ -105,6 +105,10 @@ Component({
|
|
|
105
105
|
},
|
|
106
106
|
min: {},
|
|
107
107
|
max: {},
|
|
108
|
+
inputValue: {
|
|
109
|
+
type: Number,
|
|
110
|
+
value: null,
|
|
111
|
+
},
|
|
108
112
|
},
|
|
109
113
|
data: {
|
|
110
114
|
isInit: true,
|
|
@@ -181,21 +185,20 @@ Component({
|
|
|
181
185
|
const toReal = getRealValue({ value: toShow, format });
|
|
182
186
|
const detail = { ...e.detail, value: toReal };
|
|
183
187
|
|
|
184
|
-
if (needSetData) {
|
|
185
|
-
this.changeForm(detail);
|
|
186
|
-
this.triggerEvent('change', detail);
|
|
187
|
-
} else {
|
|
188
|
-
this.triggerEvent('input', detail);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
188
|
const upDownState = this.getStepDisabled(null, toReal);
|
|
192
189
|
|
|
193
|
-
|
|
190
|
+
// 先更新 realValue,避免 value 观察者触发时 realValue 还是旧值导致重复处理
|
|
191
|
+
if (needSetData) {
|
|
194
192
|
this.setData({
|
|
195
193
|
realValue: toReal,
|
|
196
194
|
showValue: toShow,
|
|
197
195
|
...upDownState,
|
|
198
196
|
});
|
|
197
|
+
this.changeForm(detail);
|
|
198
|
+
this.triggerEvent('change', detail);
|
|
199
|
+
} else {
|
|
200
|
+
this.triggerEvent('input', detail);
|
|
201
|
+
}
|
|
199
202
|
|
|
200
203
|
return toReal;
|
|
201
204
|
},
|
|
@@ -288,7 +291,7 @@ Component({
|
|
|
288
291
|
...{ ...this.properties, ...props },
|
|
289
292
|
type: format,
|
|
290
293
|
});
|
|
291
|
-
const toReal = getRealValue({ value: toShow });
|
|
294
|
+
const toReal = getRealValue({ value: toShow, format });
|
|
292
295
|
|
|
293
296
|
const { stepPlusDisabled, stepMinusDisabled } = this.getStepDisabled(
|
|
294
297
|
{ readOnly, disabled, status, max, min, format },
|
|
@@ -447,24 +450,17 @@ Component({
|
|
|
447
450
|
},
|
|
448
451
|
// 监听非输入引起的value变化,比如调用 setValue, clearValue
|
|
449
452
|
value: function (value) {
|
|
453
|
+
if (equal(value, this.data.realValue)) return;
|
|
450
454
|
const { format } = this.properties;
|
|
451
455
|
|
|
452
|
-
|
|
453
|
-
|
|
456
|
+
// value 是真实值,不需要做百分比转换,只需要格式化显示
|
|
457
|
+
const toReal = isNumber(value) ? value : null;
|
|
454
458
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
type: format,
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// 初始化时同步真实值到表单
|
|
465
|
-
if (isNumber(toReal) && this.data.isInit) {
|
|
466
|
-
this.changeForm({ value: toReal });
|
|
467
|
-
}
|
|
459
|
+
const toShow = this.getShowValue({
|
|
460
|
+
...this.properties,
|
|
461
|
+
value: `${isNumber(value) ? value : ''}`,
|
|
462
|
+
type: format,
|
|
463
|
+
});
|
|
468
464
|
|
|
469
465
|
const readValue = `${toShow}${getPercentUnit(format)}`;
|
|
470
466
|
|
|
@@ -482,22 +478,6 @@ Component({
|
|
|
482
478
|
});
|
|
483
479
|
}, 0);
|
|
484
480
|
},
|
|
485
|
-
inputValue: function (inputValue) {
|
|
486
|
-
if (equal(inputValue, this.data._oldInputValue)) return;
|
|
487
|
-
const { toReal, toShow, stepPlusDisabled, stepMinusDisabled, readValue } = this.getRealAndShowData({
|
|
488
|
-
value: inputValue,
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
this.setData({
|
|
492
|
-
readValue,
|
|
493
|
-
realValue: toReal,
|
|
494
|
-
showValue: this.data.readOnly ? readValue : toShow,
|
|
495
|
-
stepPlusDisabled,
|
|
496
|
-
stepMinusDisabled,
|
|
497
|
-
});
|
|
498
|
-
this.changeForm({ value: toReal });
|
|
499
|
-
this.data._oldInputValue = inputValue;
|
|
500
|
-
},
|
|
501
481
|
},
|
|
502
482
|
lifetimes: {
|
|
503
483
|
attached: function () {
|
|
@@ -299,6 +299,14 @@ Component({
|
|
|
299
299
|
if (Array.isArray(values) && Array.isArray(options)) {
|
|
300
300
|
const rm = arrayToMap(options, 'value');
|
|
301
301
|
labels = values.map((d) => {
|
|
302
|
+
// 兜底:value 元素可能是关联字段对象({ _id } / {} 空对象等)
|
|
303
|
+
// 对象一律提取 _id 当 key;提取不到说明是空值,直接返回空串避免渲染 [object Object]
|
|
304
|
+
if (d && typeof d === 'object' && !Array.isArray(d)) {
|
|
305
|
+
if (d._id === undefined || d._id === null || d._id === '') {
|
|
306
|
+
return '';
|
|
307
|
+
}
|
|
308
|
+
d = d._id;
|
|
309
|
+
}
|
|
302
310
|
const obj = rm[d];
|
|
303
311
|
let item = lodashGet(obj, 'text') ?? lodashGet(obj, 'label') ?? d;
|
|
304
312
|
return textToString(item);
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<wd-form-item-read-only version="{{version}}" readOnly="{{readOnly}}" readValue="{{displayValue}}">
|
|
2
2
|
<view class="wd-select">
|
|
3
3
|
<view class="wd-select-input-group" bindchange="onChange" bindtap="onOpenPicker" data-show="true">
|
|
4
|
-
<
|
|
4
|
+
<input
|
|
5
|
+
class="wd-select-input"
|
|
6
|
+
placeholder-class="weui-input__placeholder"
|
|
7
|
+
placeholder="{{placeholder}}"
|
|
8
|
+
value="{{displayValue}}"
|
|
9
|
+
disabled="true"
|
|
10
|
+
/>
|
|
5
11
|
</view>
|
|
6
12
|
<block wx:if="{{allPickerShow}}">
|
|
7
13
|
<dropdownSelect
|