form-driver 0.1.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/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/m3.css +310 -0
- package/dist/m3.js +1 -0
- package/es/m3.css +310 -0
- package/es/m3.js +20919 -0
- package/lib/m3.css +310 -0
- package/lib/m3.js +20959 -0
- package/package.json +132 -0
- package/src/.DS_Store +0 -0
- package/src/framework/Ajax.ts +96 -0
- package/src/framework/Assembly.tsx +165 -0
- package/src/framework/Init.tsx +196 -0
- package/src/framework/M3.tsx +94 -0
- package/src/framework/MContext.ts +15 -0
- package/src/framework/MFieldViewer.tsx +32 -0
- package/src/framework/MUtil.tsx +653 -0
- package/src/framework/MViewer.less +128 -0
- package/src/framework/MViewer.tsx +180 -0
- package/src/framework/MViewerDebug.tsx +95 -0
- package/src/framework/Persistant.ts +90 -0
- package/src/framework/Schema.ts +386 -0
- package/src/framework/SchemaFunc.ts +30 -0
- package/src/framework/Validator.ts +160 -0
- package/src/framework/editorMap.ts +109 -0
- package/src/index.ts +33 -0
- package/src/types/MArrayType.ts +73 -0
- package/src/types/MCascadeType.ts +35 -0
- package/src/types/MCnAddressType.ts +54 -0
- package/src/types/MDateRangeType.ts +52 -0
- package/src/types/MDateTimeType.ts +53 -0
- package/src/types/MDecorationType.ts +6 -0
- package/src/types/MEnumType.ts +65 -0
- package/src/types/MExperienceType.ts +81 -0
- package/src/types/MFloatType.ts +10 -0
- package/src/types/MGB2260Type.ts +56 -0
- package/src/types/MIntDiffType.ts +6 -0
- package/src/types/MIntType.ts +44 -0
- package/src/types/MKvSetType.ts +50 -0
- package/src/types/MMatrixType.ts +52 -0
- package/src/types/MObjectType.ts +89 -0
- package/src/types/MSetType.ts +220 -0
- package/src/types/MStringType.ts +27 -0
- package/src/types/MTelType.ts +14 -0
- package/src/types/MType.ts +77 -0
- package/src/types/MVLPairType.ts +35 -0
- package/src/types/gb2260.json +1 -0
- package/src/ui/BaseViewer.tsx +110 -0
- package/src/ui/editor/.DS_Store +0 -0
- package/src/ui/editor/basic/.DS_Store +0 -0
- package/src/ui/editor/basic/ACascadePicker.tsx +114 -0
- package/src/ui/editor/basic/ACheckBox.tsx +104 -0
- package/src/ui/editor/basic/ADatetimePicker.tsx +76 -0
- package/src/ui/editor/basic/AGB2260.tsx +52 -0
- package/src/ui/editor/basic/AInputBox.tsx +59 -0
- package/src/ui/editor/basic/AIntBox.tsx +39 -0
- package/src/ui/editor/basic/AKvSet.less +9 -0
- package/src/ui/editor/basic/AKvSet.tsx +90 -0
- package/src/ui/editor/basic/ARadio.tsx +86 -0
- package/src/ui/editor/basic/ARangePicker.tsx +129 -0
- package/src/ui/editor/basic/ARate.less +8 -0
- package/src/ui/editor/basic/ARate.tsx +37 -0
- package/src/ui/editor/basic/ARemoteSelector.tsx +116 -0
- package/src/ui/editor/basic/ASelector.tsx +88 -0
- package/src/ui/editor/basic/ASetSelector.tsx +65 -0
- package/src/ui/editor/basic/ASpecInputBox.tsx +20 -0
- package/src/ui/editor/basic/ATreeSelect.tsx +41 -0
- package/src/ui/editor/basic/AUpload.tsx +119 -0
- package/src/ui/editor/basic/NPS.less +21 -0
- package/src/ui/editor/basic/NPS.tsx +47 -0
- package/src/ui/editor/complex/AArray.less +10 -0
- package/src/ui/editor/complex/AArray.tsx +104 -0
- package/src/ui/editor/complex/AArrayGrid.tsx +115 -0
- package/src/ui/editor/complex/ACnAddress.less +15 -0
- package/src/ui/editor/complex/ACnAddress.tsx +61 -0
- package/src/ui/editor/complex/ADialogForm.tsx +45 -0
- package/src/ui/editor/complex/AExperience.tsx +85 -0
- package/src/ui/editor/complex/AForm.less +35 -0
- package/src/ui/editor/complex/AForm.tsx +340 -0
- package/src/ui/editor/complex/AIntDiff.tsx +77 -0
- package/src/ui/editor/complex/AMatrix.less +18 -0
- package/src/ui/editor/complex/AMatrix.tsx +242 -0
- package/src/ui/editor/complex/ATable.less +4 -0
- package/src/ui/editor/complex/ATable.tsx +33 -0
- package/src/ui/editor/complex/JsonEditor.tsx +37 -0
- package/src/ui/readable/A.tsx +33 -0
- package/src/ui/readable/ArrayViewer.tsx +46 -0
- package/src/ui/readable/DecorationViewer.tsx +76 -0
- package/src/ui/readable/DivViewer.tsx +11 -0
- package/src/ui/widget/Collapsible.tsx +156 -0
- package/src/ui/widget/Segment.less +39 -0
- package/src/ui/widget/Segment.tsx +40 -0
- package/src/ui/widget/SegmentEditSwitch.tsx +46 -0
- package/src/ui/widget/SelectBox.tsx +43 -0
- package/src/ui/widget/UnderlineInputBox.less +47 -0
- package/src/ui/widget/UnderlineInputBox.tsx +10 -0
- package/types/framework/Ajax.d.ts +5 -0
- package/types/framework/Assembly.d.ts +59 -0
- package/types/framework/Init.d.ts +4 -0
- package/types/framework/M3.d.ts +6 -0
- package/types/framework/MContext.d.ts +11 -0
- package/types/framework/MFieldViewer.d.ts +8 -0
- package/types/framework/MUtil.d.ts +180 -0
- package/types/framework/MViewer.d.ts +75 -0
- package/types/framework/MViewerDebug.d.ts +11 -0
- package/types/framework/Persistant.d.ts +17 -0
- package/types/framework/Schema.d.ts +306 -0
- package/types/framework/SchemaFunc.d.ts +14 -0
- package/types/framework/Validator.d.ts +53 -0
- package/types/framework/editorMap.d.ts +107 -0
- package/types/index.d.ts +21 -0
- package/types/types/MArrayType.d.ts +2 -0
- package/types/types/MCascadeType.d.ts +11 -0
- package/types/types/MCnAddressType.d.ts +2 -0
- package/types/types/MDateRangeType.d.ts +7 -0
- package/types/types/MDateTimeType.d.ts +11 -0
- package/types/types/MDecorationType.d.ts +7 -0
- package/types/types/MEnumType.d.ts +2 -0
- package/types/types/MExperienceType.d.ts +5 -0
- package/types/types/MFloatType.d.ts +2 -0
- package/types/types/MGB2260Type.d.ts +9 -0
- package/types/types/MIntDiffType.d.ts +2 -0
- package/types/types/MIntType.d.ts +2 -0
- package/types/types/MKvSetType.d.ts +11 -0
- package/types/types/MMatrixType.d.ts +5 -0
- package/types/types/MObjectType.d.ts +11 -0
- package/types/types/MSetType.d.ts +7 -0
- package/types/types/MStringType.d.ts +2 -0
- package/types/types/MTelType.d.ts +4 -0
- package/types/types/MType.d.ts +46 -0
- package/types/types/MVLPairType.d.ts +5 -0
- package/types/ui/BaseViewer.d.ts +45 -0
- package/types/ui/editor/basic/ACascadePicker.d.ts +11 -0
- package/types/ui/editor/basic/ACheckBox.d.ts +17 -0
- package/types/ui/editor/basic/ADatetimePicker.d.ts +15 -0
- package/types/ui/editor/basic/AGB2260.d.ts +10 -0
- package/types/ui/editor/basic/AInputBox.d.ts +8 -0
- package/types/ui/editor/basic/AIntBox.d.ts +9 -0
- package/types/ui/editor/basic/AKvSet.d.ts +19 -0
- package/types/ui/editor/basic/ARadio.d.ts +14 -0
- package/types/ui/editor/basic/ARangePicker.d.ts +30 -0
- package/types/ui/editor/basic/ARate.d.ts +13 -0
- package/types/ui/editor/basic/ARemoteSelector.d.ts +15 -0
- package/types/ui/editor/basic/ASelector.d.ts +14 -0
- package/types/ui/editor/basic/ASetSelector.d.ts +10 -0
- package/types/ui/editor/basic/ASpecInputBox.d.ts +9 -0
- package/types/ui/editor/basic/ATreeSelect.d.ts +18 -0
- package/types/ui/editor/basic/AUpload.d.ts +33 -0
- package/types/ui/editor/basic/NPS.d.ts +13 -0
- package/types/ui/editor/complex/AArray.d.ts +11 -0
- package/types/ui/editor/complex/AArrayGrid.d.ts +13 -0
- package/types/ui/editor/complex/ACnAddress.d.ts +10 -0
- package/types/ui/editor/complex/ADialogForm.d.ts +11 -0
- package/types/ui/editor/complex/AExperience.d.ts +16 -0
- package/types/ui/editor/complex/AForm.d.ts +46 -0
- package/types/ui/editor/complex/AIntDiff.d.ts +14 -0
- package/types/ui/editor/complex/AMatrix.d.ts +48 -0
- package/types/ui/editor/complex/ATable.d.ts +9 -0
- package/types/ui/editor/complex/JsonEditor.d.ts +9 -0
- package/types/ui/readable/A.d.ts +5 -0
- package/types/ui/readable/ArrayViewer.d.ts +5 -0
- package/types/ui/readable/DecorationViewer.d.ts +3 -0
- package/types/ui/readable/DivViewer.d.ts +5 -0
- package/types/ui/widget/Collapsible.d.ts +46 -0
- package/types/ui/widget/Segment.d.ts +18 -0
- package/types/ui/widget/SegmentEditSwitch.d.ts +20 -0
- package/types/ui/widget/SelectBox.d.ts +13 -0
- package/types/ui/widget/UnderlineInputBox.d.ts +6 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import 'antd/dist/antd.css';
|
|
2
|
+
import 'antd-mobile/dist/antd-mobile.css';
|
|
3
|
+
import { Ajax } from './framework/Ajax';
|
|
4
|
+
import { M3UISpecSegmentItem, MFieldSchema, M3UISpec, MFieldSchemaAnonymity } from './framework/Schema';
|
|
5
|
+
import { MViewerDebug } from './framework/MViewerDebug';
|
|
6
|
+
import { MORPH, VIEWER, assembly, MTheme, Assembly } from './framework/Assembly';
|
|
7
|
+
import { ViewerState, Viewer, BaseViewer } from './ui/BaseViewer';
|
|
8
|
+
import { MViewer, SubmitBar, useM3Database } from './framework/MViewer';
|
|
9
|
+
import M3 from './framework/M3';
|
|
10
|
+
import { MFieldViewer } from './framework/MFieldViewer';
|
|
11
|
+
import { MContext } from './framework/MContext';
|
|
12
|
+
import { MUtil } from './framework/MUtil';
|
|
13
|
+
import { Segment } from "./ui/widget/Segment";
|
|
14
|
+
import { UnderlineInputBox } from './ui/widget/UnderlineInputBox';
|
|
15
|
+
import { SegmentEditSwitch, SegmentEditSwitchState } from './ui/widget/SegmentEditSwitch';
|
|
16
|
+
import { ensureM3 } from './framework/Init';
|
|
17
|
+
import Validator from './framework/Validator';
|
|
18
|
+
import { MType, EmtpyType, createDefaultValue } from './types/MType';
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
M3,
|
|
22
|
+
MContext, MFieldViewer, BaseViewer, assembly, SegmentEditSwitch, Viewer, UnderlineInputBox, Segment, MUtil, Ajax,
|
|
23
|
+
MViewer,
|
|
24
|
+
MViewerDebug, SubmitBar,
|
|
25
|
+
useM3Database,
|
|
26
|
+
ensureM3,
|
|
27
|
+
Validator,
|
|
28
|
+
EmtpyType,
|
|
29
|
+
createDefaultValue,
|
|
30
|
+
Assembly
|
|
31
|
+
};
|
|
32
|
+
export type { M3UISpec, ViewerState, SegmentEditSwitchState, M3UISpecSegmentItem, MFieldSchema, MFieldSchemaAnonymity, MORPH, VIEWER, MType, MTheme };
|
|
33
|
+
export default M3;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
import { MFieldSchemaAnonymity, MValidationResult } from "../framework/Schema";
|
|
3
|
+
import { MType} from "./MType";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
import { generateJsPrototypeValidate, validateRequired } from "../framework/Validator";
|
|
6
|
+
import { Assembly } from '../framework/Assembly';
|
|
7
|
+
|
|
8
|
+
function arrayValidator(assembly:Assembly, schema:MFieldSchemaAnonymity, value:any, path:string): MValidationResult {
|
|
9
|
+
// 校验一下数组元素
|
|
10
|
+
if(schema.arrayMember){
|
|
11
|
+
for(let i = 0; i < value.length; i++){
|
|
12
|
+
let item = value[i];
|
|
13
|
+
const r = assembly.validate(schema.arrayMember, item, path + "[" + i + "]");
|
|
14
|
+
if(r){
|
|
15
|
+
return {message: "", path};; // 子元素校验没过,数组上不用展示信息
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const min = schema.min ?? (schema.required ? 1: 0);
|
|
20
|
+
const max = schema.max ?? Number.MAX_VALUE;
|
|
21
|
+
if(value.length < min){
|
|
22
|
+
return {message: "最少" + min + "项", path};;
|
|
23
|
+
}
|
|
24
|
+
if(value.length > max) {
|
|
25
|
+
return {message: "最多" + schema.max + "项", path};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const MArrayType: MType = {
|
|
32
|
+
validators: [validateRequired, generateJsPrototypeValidate("[object Array]"), arrayValidator],
|
|
33
|
+
|
|
34
|
+
toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any):string => {
|
|
35
|
+
if(s.arrayMember?.type === "object"){
|
|
36
|
+
const olfs = s.arrayMember.objectLabelFields ?? [_.get(s.arrayMember, "objectFields[0].name") as string];
|
|
37
|
+
return vs?.map((v:any)=>{
|
|
38
|
+
const itemValueArr = [];
|
|
39
|
+
for(let ofs of olfs){
|
|
40
|
+
itemValueArr.push(v[ofs]);
|
|
41
|
+
}
|
|
42
|
+
return itemValueArr.join(",");
|
|
43
|
+
})?.join("\n") ?? assembly.theme.READABLE_BLANK;
|
|
44
|
+
} else {
|
|
45
|
+
return vs?.join(",") ?? assembly.theme.READABLE_BLANK;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
standardValue: (assembly:Assembly, s:MFieldSchemaAnonymity, v:any, strict: boolean):any => {
|
|
50
|
+
if(!_.isArray(v)){
|
|
51
|
+
return s.defaultValue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const def = assembly.types[s.arrayMember?.type];
|
|
55
|
+
if(!def){
|
|
56
|
+
return v;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for(let i = 0; i < v.length; i ++){
|
|
60
|
+
v[i] = def.standardValue(assembly, s.arrayMember, v[i], strict);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return v;
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
createDefaultValue:(assembly:Assembly, s:MFieldSchemaAnonymity) => {
|
|
67
|
+
if(s.defaultValue){
|
|
68
|
+
return _.cloneDeep(s.defaultValue);
|
|
69
|
+
} else {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
import { MFieldSchemaAnonymity } from "../framework/Schema";
|
|
3
|
+
import { MType} from "./MType";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
import { generateSchemaValidate, validateRequired } from "../framework/Validator";
|
|
6
|
+
import { Assembly } from '../framework/Assembly';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 级联多选的值示例:
|
|
10
|
+
* 值类型:
|
|
11
|
+
* [
|
|
12
|
+
* { "label": "jiangsu", "value": "jiangsu" },
|
|
13
|
+
* { "label": "nanjing", "value": "nanjiong, chi" },
|
|
14
|
+
* { "label": "nanjing", "value": "zhong hua men" }
|
|
15
|
+
* ]
|
|
16
|
+
*/
|
|
17
|
+
export const MCascadeType: MType = {
|
|
18
|
+
validators: [validateRequired, generateSchemaValidate({type:"array", arrayMember: {type: "vl"}, min:1}, "请重新填写") ],
|
|
19
|
+
|
|
20
|
+
toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any):string => {
|
|
21
|
+
return vs?.map(e=>e.label)?.join("/") ?? assembly.theme.READABLE_BLANK;
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
standardValue: (assembly:Assembly, s:MFieldSchemaAnonymity, v:any, strict:boolean):any => { // TODO 尚未实现
|
|
25
|
+
return v;
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
createDefaultValue:(assembly:Assembly, s:MFieldSchemaAnonymity) => {
|
|
29
|
+
if(s.defaultValue){
|
|
30
|
+
return _.cloneDeep(s.defaultValue);
|
|
31
|
+
} else {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
import { MFieldSchemaAnonymity } from "../framework/Schema";
|
|
3
|
+
import { EmtpyType, MType} from "./MType";
|
|
4
|
+
import { validateRequired } from "../framework/Validator";
|
|
5
|
+
import { Assembly } from "../framework/Assembly";
|
|
6
|
+
import { MGB2260Type } from "./MGB2260Type";
|
|
7
|
+
import _ from "lodash";
|
|
8
|
+
|
|
9
|
+
export const MCnAddress: MType = _.assign({}, EmtpyType, {
|
|
10
|
+
validators: [validateRequired],
|
|
11
|
+
|
|
12
|
+
toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any):string => {
|
|
13
|
+
if(!vs){
|
|
14
|
+
return assembly.theme.READABLE_BLANK;
|
|
15
|
+
}
|
|
16
|
+
if(!vs?.code && !vs.province){
|
|
17
|
+
return assembly.theme.READABLE_INVALID;
|
|
18
|
+
}
|
|
19
|
+
// 当传入的 database,没有 code,但有 province 时,反查 code
|
|
20
|
+
if (vs.province && !vs.code) {
|
|
21
|
+
for (const p of MGB2260Type.gb2260) {
|
|
22
|
+
if (p.label === vs.province) {
|
|
23
|
+
if (vs.city && p.children) {
|
|
24
|
+
for (const c of p.children) {
|
|
25
|
+
if (c.label === vs.city) {
|
|
26
|
+
if (vs.district && c.children) {
|
|
27
|
+
for (const d of c.children) {
|
|
28
|
+
if (d.label === vs.district) {
|
|
29
|
+
vs.code = d.value
|
|
30
|
+
break
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
vs.code = c.value
|
|
35
|
+
break
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
vs.code = p.value
|
|
41
|
+
break
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const l = MGB2260Type.lookup(vs.code);
|
|
48
|
+
if(!l){
|
|
49
|
+
return assembly.theme.READABLE_INVALID;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return l.label.join("/") + "/" + (vs.address ?? assembly.theme.READABLE_BLANK);
|
|
53
|
+
}
|
|
54
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { MFieldSchemaAnonymity } from "../framework/Schema";
|
|
5
|
+
import { EmtpyType, MType} from "./MType";
|
|
6
|
+
import { validateRequired } from "../framework/Validator";
|
|
7
|
+
import { Assembly } from "../framework/Assembly";
|
|
8
|
+
import moment from "moment";
|
|
9
|
+
import _ from "lodash";
|
|
10
|
+
|
|
11
|
+
function timeExpr(assembly:Assembly, v:any, tillNow:boolean, readableFormat):string {
|
|
12
|
+
if(tillNow){
|
|
13
|
+
return "至今";
|
|
14
|
+
}
|
|
15
|
+
if(!v){
|
|
16
|
+
return assembly.theme.READABLE_UNKNOWN;
|
|
17
|
+
}
|
|
18
|
+
return moment(v, "x").format(readableFormat);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function timeRangeExpr(assembly:Assembly, from:number|string, to:number|string, tillNow:boolean, readableFormat:string = "YYYY年MM月DD日"):string {
|
|
22
|
+
return timeExpr(assembly, from, false, readableFormat) + " ~ " + timeExpr(assembly, to, tillNow, readableFormat)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const MDateRangeType: MType & {toReadableN: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any)=>string|undefined} = _.assign({}, EmtpyType, {
|
|
26
|
+
validators: [validateRequired],
|
|
27
|
+
|
|
28
|
+
toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any):string => {
|
|
29
|
+
if(_.isNil(vs)){
|
|
30
|
+
return assembly.theme.READABLE_BLANK
|
|
31
|
+
}
|
|
32
|
+
if(!_.isArray(vs)){
|
|
33
|
+
return assembly.theme.READABLE_INVALID;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return timeRangeExpr(assembly, vs[0], vs[1], vs[2], s.dateRange?.showTime ? "YYYY年MM月DD日 HH:mm:ss" : "YYYY年MM月DD日");
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 同toReadable,但数据无效时返回nil
|
|
41
|
+
* @param assembly
|
|
42
|
+
* @param s
|
|
43
|
+
* @param vs
|
|
44
|
+
* @returns
|
|
45
|
+
*/
|
|
46
|
+
toReadableN: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any):string|undefined => {
|
|
47
|
+
if(!_.isNil(vs) && _.isArray(vs)) {
|
|
48
|
+
return timeRangeExpr(assembly, vs[0], vs[1], vs[2], s.dateRange?.showTime ? "YYYY年MM月DD日 HH:mm:ss" : "YYYY年MM月DD日");
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
|
|
2
|
+
import {validateDateMinMax, validateRequired} from '../framework/Validator';
|
|
3
|
+
import { MFieldSchemaAnonymity } from '../framework/Schema';
|
|
4
|
+
import { EmtpyType, MType} from "./MType";
|
|
5
|
+
import moment from 'moment';
|
|
6
|
+
import { Assembly } from '../framework/Assembly';
|
|
7
|
+
import _ from 'lodash';
|
|
8
|
+
|
|
9
|
+
export interface MDateTimeAntConf {
|
|
10
|
+
dataFormat: string,
|
|
11
|
+
readableFormat: string,
|
|
12
|
+
mode: undefined | 'date' | 'year' | 'month' | 'time';
|
|
13
|
+
showTime: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const MDateTimeType:MType & {antConf:(schema:MFieldSchemaAnonymity)=>MDateTimeAntConf|undefined} = _.assign({}, EmtpyType, {
|
|
17
|
+
validators: [validateRequired, validateDateMinMax],
|
|
18
|
+
|
|
19
|
+
antConf: (schema:MFieldSchemaAnonymity):MDateTimeAntConf|undefined => {
|
|
20
|
+
let dataFormat:string|undefined = schema.dataFormat;
|
|
21
|
+
let readableFormat: string;
|
|
22
|
+
let mode: undefined | 'date' | 'year' | 'month' | 'time';
|
|
23
|
+
let showTime = false;
|
|
24
|
+
switch(schema.type) {
|
|
25
|
+
case "year":
|
|
26
|
+
mode = "year"; dataFormat = dataFormat ?? 'YYYY'; readableFormat = 'YYYY'; break;
|
|
27
|
+
case "yearMonth":
|
|
28
|
+
mode = "month"; dataFormat = dataFormat ?? 'YYYYMM'; readableFormat = 'YYYY-MM'; break;
|
|
29
|
+
case "yearMonthDay":
|
|
30
|
+
mode = "date"; dataFormat = dataFormat ?? 'YYYYMMDD'; readableFormat = 'YYYY-MM-DD'; break;
|
|
31
|
+
case "datetime":
|
|
32
|
+
mode = undefined; dataFormat = dataFormat ?? 'x'; readableFormat = 'YYYY-MM-DD HH:mm'; showTime = true; break;
|
|
33
|
+
// case "yearAndQuarter":
|
|
34
|
+
// case "yearAndWeek":
|
|
35
|
+
// return MUtil.error(`移动端不支持${this.props.schema.type}`, this.props.schema);
|
|
36
|
+
default:
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
return {dataFormat, readableFormat, mode, showTime};
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
toReadable: (assembly:Assembly, schema:MFieldSchemaAnonymity, v:any):string => {
|
|
43
|
+
if(_.isNil(v)){
|
|
44
|
+
return assembly.theme.READABLE_BLANK;
|
|
45
|
+
}
|
|
46
|
+
let c = MDateTimeType.antConf(schema);
|
|
47
|
+
if(!c) {
|
|
48
|
+
return assembly.theme.READABLE_INVALID;
|
|
49
|
+
}
|
|
50
|
+
let asMoment = moment(v, c.dataFormat)
|
|
51
|
+
return asMoment.format(c.readableFormat);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { MUtil } from "../framework/MUtil";
|
|
2
|
+
import {MValidationResult, MFieldSchemaAnonymity} from '../framework/Schema';
|
|
3
|
+
import { MType} from "./MType";
|
|
4
|
+
import { validateRequired } from "../framework/Validator";
|
|
5
|
+
import { Assembly, assembly } from '../framework/Assembly';
|
|
6
|
+
import _ from "lodash";
|
|
7
|
+
|
|
8
|
+
// 选项是否合法、开放选项是否合法
|
|
9
|
+
function validateCandidate(a:Assembly, schema:MFieldSchemaAnonymity, value:any, path:string): MValidationResult {
|
|
10
|
+
let fs = MUtil.option(schema);
|
|
11
|
+
for(let f of fs){
|
|
12
|
+
if(MUtil.isEquals(f.value, value, schema.tolerate)){
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const openOption = _.clone(schema.openOption ?? schema.enumOpen)
|
|
17
|
+
if(openOption){
|
|
18
|
+
openOption.required = true; // 既然勾上了开放选项,就必须填, TODO 把开放选项标注成必填,可以在schema预处理做
|
|
19
|
+
return assembly.validate(openOption, value, "")
|
|
20
|
+
}
|
|
21
|
+
return {message:'请选择一个选项', path}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const MEnumType: MType = {
|
|
25
|
+
validators: [validateRequired, validateCandidate],
|
|
26
|
+
|
|
27
|
+
createDefaultValue: (assembly:Assembly, s:MFieldSchemaAnonymity):any =>{
|
|
28
|
+
if(s.defaultValue){
|
|
29
|
+
return _.clone(s.defaultValue);
|
|
30
|
+
} else {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, v:any):string => {
|
|
36
|
+
const fs = MUtil.option(s);
|
|
37
|
+
for(let f of fs) {
|
|
38
|
+
if(f.value === v){
|
|
39
|
+
return f.label ?? v;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if(s.openOption){
|
|
43
|
+
return v;
|
|
44
|
+
} else {
|
|
45
|
+
return assembly.theme.READABLE_BLANK;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
standardValue: (assembly:Assembly, s:MFieldSchemaAnonymity, v:any, strict:boolean):any => {
|
|
50
|
+
if(!strict) { // value的类型各种可能都有,如果不要求严格,就不用处理了
|
|
51
|
+
return v;
|
|
52
|
+
}
|
|
53
|
+
const fs = MUtil.option(s);
|
|
54
|
+
for(let f of fs){
|
|
55
|
+
if(MUtil.isEquals(f.value, v, s.tolerate)){
|
|
56
|
+
return v;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if(s.openOption || s.enumOpen) {
|
|
60
|
+
return v;
|
|
61
|
+
} else {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
|
|
2
|
+
import { MFieldSchemaAnonymity, MValidationResult } from "../framework/Schema";
|
|
3
|
+
import { EmtpyType, MType } from "./MType";
|
|
4
|
+
import { validateRequired } from "../framework/Validator";
|
|
5
|
+
import moment from "moment";
|
|
6
|
+
import _ from "lodash";
|
|
7
|
+
import { Assembly } from '../framework/Assembly';
|
|
8
|
+
import { timeRangeExpr } from './MDateRangeType';
|
|
9
|
+
|
|
10
|
+
export function validateExperience(assembly:Assembly, schema:MFieldSchemaAnonymity, value:any, path:string): MValidationResult {
|
|
11
|
+
// 空的不管,有validateRequired呢
|
|
12
|
+
if(_.isNil(value)){
|
|
13
|
+
return undefined
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if(!_.isArray(value)){
|
|
17
|
+
return {message: "数据损坏了", path};
|
|
18
|
+
}
|
|
19
|
+
const format = schema.dataFormat ?? "x";
|
|
20
|
+
let dim = [];
|
|
21
|
+
for(let item of value) {
|
|
22
|
+
let from = moment(item["from"], format).valueOf();
|
|
23
|
+
let to = moment(item["to"], format).valueOf();
|
|
24
|
+
let tillNow = !! item["tillNow"];
|
|
25
|
+
if(tillNow){
|
|
26
|
+
to = Number.MAX_VALUE;
|
|
27
|
+
}
|
|
28
|
+
if(!_.isFinite(from) || !_.isFinite(to)){
|
|
29
|
+
return {message: "没有填写完整", path};
|
|
30
|
+
}
|
|
31
|
+
dim.push({from, to, item});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
dim.sort((a,b)=>{
|
|
35
|
+
if(a.from>b.from){
|
|
36
|
+
return 1
|
|
37
|
+
} else if(a.from < b.from) {
|
|
38
|
+
return -1;
|
|
39
|
+
} else {
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// 看时间区间是不是有重叠
|
|
45
|
+
if(!schema.experience?.overlap) {
|
|
46
|
+
let prevTo = Number.MIN_VALUE;
|
|
47
|
+
for(let item of dim) {
|
|
48
|
+
if(item.from < prevTo){
|
|
49
|
+
return {message: "时间重叠了", path};
|
|
50
|
+
}
|
|
51
|
+
if(item.from > item.to) {
|
|
52
|
+
return {message: "结束时间不能早于开始时间", path};
|
|
53
|
+
}
|
|
54
|
+
prevTo = item.to;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const MExperienceType: MType = _.assign({}, EmtpyType, {
|
|
61
|
+
validators: [validateRequired, validateExperience],
|
|
62
|
+
|
|
63
|
+
toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any):string => {
|
|
64
|
+
const result = [];
|
|
65
|
+
if(_.isNil(vs) || _.size(vs) < 1){
|
|
66
|
+
return assembly.theme.READABLE_BLANK;
|
|
67
|
+
}
|
|
68
|
+
if(!_.isArray(vs)) {
|
|
69
|
+
return assembly.theme.READABLE_INVALID;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for(let item of vs){
|
|
73
|
+
let exp:string[] = [];
|
|
74
|
+
for(let childschema of s.experience?.members ?? []){
|
|
75
|
+
exp.push(assembly.toReadable(childschema, item[childschema.name], item));
|
|
76
|
+
};
|
|
77
|
+
result.push(timeRangeExpr(assembly, item.from, item.to, item.tillNow) + ":"+ exp.join("/"))
|
|
78
|
+
}
|
|
79
|
+
return result.join("\n");
|
|
80
|
+
}
|
|
81
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
|
|
2
|
+
import { MFieldSchemaAnonymity, MValidationResult } from '../framework/Schema';
|
|
3
|
+
import { createDefaultValue, EmtpyType, MType} from "./MType";
|
|
4
|
+
import { validateRequired, validateNumberMinMax, generateRegexValidate } from '../framework/Validator';
|
|
5
|
+
import { Assembly } from "../framework/Assembly";
|
|
6
|
+
import _ from 'lodash';
|
|
7
|
+
|
|
8
|
+
export const MFloatType: MType = _.assign({}, EmtpyType, {
|
|
9
|
+
validators: [validateRequired, generateRegexValidate(/(^(-?\d+)([.]\d+)?$)/, "请输入数字"), validateNumberMinMax],
|
|
10
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
import { MFieldSchemaAnonymity } from "../framework/Schema";
|
|
3
|
+
import { EmtpyType, MType} from "./MType";
|
|
4
|
+
import gb2260 from './gb2260.json';
|
|
5
|
+
import { Assembly } from "../framework/Assembly";
|
|
6
|
+
import _ from "lodash";
|
|
7
|
+
import { validateRequired } from "../framework/Validator";
|
|
8
|
+
|
|
9
|
+
export interface GB2260CodeInfo {
|
|
10
|
+
label: string[];
|
|
11
|
+
code: string[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const MGB2260Type: MType & {lookup: (code: number|string)=>GB2260CodeInfo|undefined, gb2260:any} = _.assign({}, EmtpyType, {
|
|
15
|
+
validators: [validateRequired],
|
|
16
|
+
|
|
17
|
+
toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, v:any):string => {
|
|
18
|
+
let ci = MGB2260Type.lookup(v);
|
|
19
|
+
if(!ci){
|
|
20
|
+
return assembly.theme.READABLE_INVALID;
|
|
21
|
+
}
|
|
22
|
+
return ci.label.join("/");
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
gb2260,
|
|
26
|
+
|
|
27
|
+
lookup: (code: number|string): GB2260CodeInfo|undefined => {
|
|
28
|
+
for(let prv of gb2260){
|
|
29
|
+
// @ts-ignore prv.value全是数字,ts并不知道
|
|
30
|
+
const pdiff = code - prv.value;
|
|
31
|
+
if(pdiff >= 0 && pdiff < 10000){
|
|
32
|
+
if(prv.children.length <= 0) { // 只有省级
|
|
33
|
+
return {label: [prv.label], code: [prv.value]};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for(let city of prv.children){
|
|
37
|
+
// @ts-ignore city.value全是数字,ts并不知道
|
|
38
|
+
const cdiff = code - city.value;
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
if(cdiff === 0){
|
|
41
|
+
return {label: [prv.label, city.label], code: [prv.value, city.value]};
|
|
42
|
+
} else if(cdiff >0 && cdiff < 100){
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
for(let dst of city.children ?? []){
|
|
45
|
+
// eslint-disable-next-line eqeqeq
|
|
46
|
+
if(dst.value == code) {
|
|
47
|
+
return {label: [prv.label, city.label, dst.label], code: [prv.value, city.value, dst.value]};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
import { MFieldSchemaAnonymity, MValidationResult } from '../framework/Schema';
|
|
3
|
+
import { EmtpyType, MType} from "./MType";
|
|
4
|
+
import { validateRequired, validateNumberMinMax, generateRegexValidate } from '../framework/Validator';
|
|
5
|
+
import { Assembly } from "../framework/Assembly";
|
|
6
|
+
import _ from 'lodash';
|
|
7
|
+
|
|
8
|
+
export const MIntType: MType = _.assign({}, EmtpyType, {
|
|
9
|
+
validators: [validateRequired, generateRegexValidate(/(^-?\d+$)/, "请输入整数"), validateNumberMinMax],
|
|
10
|
+
|
|
11
|
+
standardValue: (assembly:Assembly, s:MFieldSchemaAnonymity, v:any, strict: boolean):any => {
|
|
12
|
+
let r:number;
|
|
13
|
+
|
|
14
|
+
// 类型不能错
|
|
15
|
+
if(_.isString(v)) {
|
|
16
|
+
v = Math.round(parseInt(v));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if(_.isNaN(v) || v === Infinity){
|
|
20
|
+
return s.defaultValue
|
|
21
|
+
} else if(_.isNumber(v)) {
|
|
22
|
+
r = v;
|
|
23
|
+
} else if(_.isBoolean(v)){
|
|
24
|
+
r = v ? 1 : 0
|
|
25
|
+
} else if(_.isDate(v)) { // 日期转换成时间戳
|
|
26
|
+
r = v.getTime();
|
|
27
|
+
} else {
|
|
28
|
+
return s.defaultValue;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if(!strict) {
|
|
32
|
+
return r;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 数值不能错
|
|
36
|
+
if(r < s.min) {
|
|
37
|
+
r = s.min;
|
|
38
|
+
} else if(r > s.max) {
|
|
39
|
+
r = s.max;
|
|
40
|
+
}
|
|
41
|
+
return v;
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
import { MEnumField, MFieldSchemaAnonymity, MValidationResult } from "../framework/Schema";
|
|
3
|
+
import { EmtpyType, MType } from "./MType";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
import { Assembly } from '../framework/Assembly';
|
|
6
|
+
import { MUtil } from '../framework/MUtil';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 类似这种题:
|
|
10
|
+
* B8: 您现在在做的事业务部门的岗位吗?
|
|
11
|
+
* 1. 是,具体职位是 _______
|
|
12
|
+
* 2. 否,我的部门是 _______
|
|
13
|
+
*
|
|
14
|
+
* 数据结构
|
|
15
|
+
* {1:'CEO', 2:'营销'}
|
|
16
|
+
*/
|
|
17
|
+
export const MKvSetType: MType = _.assign({}, EmtpyType, {
|
|
18
|
+
validators: [(a:Assembly, schema:MFieldSchemaAnonymity, value:any, path:string): MValidationResult => {
|
|
19
|
+
if(schema.required){
|
|
20
|
+
if(_.isNil(value) || Object.keys(value).length == 0) {
|
|
21
|
+
return {message:'您还没有填完这一项', path};
|
|
22
|
+
}
|
|
23
|
+
for(let k in value){
|
|
24
|
+
if(_.isNil(value[k]) || value[k] == ""){
|
|
25
|
+
return {message:'您还没有填完这一项', path};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}],
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 对象转换成readable文案时,会默认选择展示对象的label/name/id,如果都没有,展示JSON.stringify后的字符串
|
|
34
|
+
* @param assembly
|
|
35
|
+
* @param s
|
|
36
|
+
* @param vs
|
|
37
|
+
*/
|
|
38
|
+
toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any):string => {
|
|
39
|
+
if(_.isNil(vs)){
|
|
40
|
+
return assembly.theme.READABLE_BLANK;
|
|
41
|
+
} else if(_.isObject(vs)){
|
|
42
|
+
let fds = MUtil.standardFields(s.option);
|
|
43
|
+
return Object.keys(vs).map(k => {
|
|
44
|
+
return (_.find(fds, {"name": k}) as MEnumField)?.label ?? k + ":" + vs[k];
|
|
45
|
+
}).join(",");
|
|
46
|
+
} else {
|
|
47
|
+
return assembly.theme.READABLE_INVALID
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
import { MFieldSchemaAnonymity, MValidationResult } from "../framework/Schema";
|
|
3
|
+
import { EmtpyType, MType} from "./MType";
|
|
4
|
+
import { validateRequired } from "../framework/Validator";
|
|
5
|
+
import { MUtil } from "../framework/MUtil";
|
|
6
|
+
import _ from "lodash";
|
|
7
|
+
import { Assembly } from '../framework/Assembly';
|
|
8
|
+
|
|
9
|
+
export function validateMatrix(a:Assembly, schema:MFieldSchemaAnonymity, value:any, path:string): MValidationResult {
|
|
10
|
+
if(_.isNil(value)){
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if(schema.matrix?.minY) {
|
|
15
|
+
let allXValue = MUtil.standardFields(schema.matrix?.x).map(e=>e.value);
|
|
16
|
+
let selectedXValue:any[] = [];
|
|
17
|
+
for(let k in value){
|
|
18
|
+
if(!k){
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const xv = value[k];
|
|
22
|
+
if(_.isArray(xv)){
|
|
23
|
+
selectedXValue = selectedXValue.concat(xv);
|
|
24
|
+
} else {
|
|
25
|
+
selectedXValue.push(xv);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
selectedXValue = _.uniq(selectedXValue);
|
|
29
|
+
const diff = _.difference(allXValue, selectedXValue);
|
|
30
|
+
if(diff.length > 0){
|
|
31
|
+
return {message: `您还没有填"${_.join(diff, ",")}"`, path}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if(schema.matrix?.minX) {
|
|
36
|
+
const yy = MUtil.standardFields(schema.matrix?.y);
|
|
37
|
+
for(let y of yy){
|
|
38
|
+
const yv = value[y.value?.toString()];
|
|
39
|
+
const n = _.isArray(yv) ? yv.length : (yv ? 1 : 0);
|
|
40
|
+
if(n < schema.matrix.minX){
|
|
41
|
+
return {message: `您还没有为"${y.label ?? y.value}"做选择`, path}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const MMatrixType: MType = _.assign({}, EmtpyType, {
|
|
49
|
+
validators: [validateRequired, validateMatrix],
|
|
50
|
+
|
|
51
|
+
standardValue: (assembly:Assembly, s:MFieldSchemaAnonymity, v:any, strict:boolean):any => v, // TODO,矩阵要考虑 tolerate,strict 选项
|
|
52
|
+
});
|