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.
Files changed (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/m3.css +310 -0
  4. package/dist/m3.js +1 -0
  5. package/es/m3.css +310 -0
  6. package/es/m3.js +20919 -0
  7. package/lib/m3.css +310 -0
  8. package/lib/m3.js +20959 -0
  9. package/package.json +132 -0
  10. package/src/.DS_Store +0 -0
  11. package/src/framework/Ajax.ts +96 -0
  12. package/src/framework/Assembly.tsx +165 -0
  13. package/src/framework/Init.tsx +196 -0
  14. package/src/framework/M3.tsx +94 -0
  15. package/src/framework/MContext.ts +15 -0
  16. package/src/framework/MFieldViewer.tsx +32 -0
  17. package/src/framework/MUtil.tsx +653 -0
  18. package/src/framework/MViewer.less +128 -0
  19. package/src/framework/MViewer.tsx +180 -0
  20. package/src/framework/MViewerDebug.tsx +95 -0
  21. package/src/framework/Persistant.ts +90 -0
  22. package/src/framework/Schema.ts +386 -0
  23. package/src/framework/SchemaFunc.ts +30 -0
  24. package/src/framework/Validator.ts +160 -0
  25. package/src/framework/editorMap.ts +109 -0
  26. package/src/index.ts +33 -0
  27. package/src/types/MArrayType.ts +73 -0
  28. package/src/types/MCascadeType.ts +35 -0
  29. package/src/types/MCnAddressType.ts +54 -0
  30. package/src/types/MDateRangeType.ts +52 -0
  31. package/src/types/MDateTimeType.ts +53 -0
  32. package/src/types/MDecorationType.ts +6 -0
  33. package/src/types/MEnumType.ts +65 -0
  34. package/src/types/MExperienceType.ts +81 -0
  35. package/src/types/MFloatType.ts +10 -0
  36. package/src/types/MGB2260Type.ts +56 -0
  37. package/src/types/MIntDiffType.ts +6 -0
  38. package/src/types/MIntType.ts +44 -0
  39. package/src/types/MKvSetType.ts +50 -0
  40. package/src/types/MMatrixType.ts +52 -0
  41. package/src/types/MObjectType.ts +89 -0
  42. package/src/types/MSetType.ts +220 -0
  43. package/src/types/MStringType.ts +27 -0
  44. package/src/types/MTelType.ts +14 -0
  45. package/src/types/MType.ts +77 -0
  46. package/src/types/MVLPairType.ts +35 -0
  47. package/src/types/gb2260.json +1 -0
  48. package/src/ui/BaseViewer.tsx +110 -0
  49. package/src/ui/editor/.DS_Store +0 -0
  50. package/src/ui/editor/basic/.DS_Store +0 -0
  51. package/src/ui/editor/basic/ACascadePicker.tsx +114 -0
  52. package/src/ui/editor/basic/ACheckBox.tsx +104 -0
  53. package/src/ui/editor/basic/ADatetimePicker.tsx +76 -0
  54. package/src/ui/editor/basic/AGB2260.tsx +52 -0
  55. package/src/ui/editor/basic/AInputBox.tsx +59 -0
  56. package/src/ui/editor/basic/AIntBox.tsx +39 -0
  57. package/src/ui/editor/basic/AKvSet.less +9 -0
  58. package/src/ui/editor/basic/AKvSet.tsx +90 -0
  59. package/src/ui/editor/basic/ARadio.tsx +86 -0
  60. package/src/ui/editor/basic/ARangePicker.tsx +129 -0
  61. package/src/ui/editor/basic/ARate.less +8 -0
  62. package/src/ui/editor/basic/ARate.tsx +37 -0
  63. package/src/ui/editor/basic/ARemoteSelector.tsx +116 -0
  64. package/src/ui/editor/basic/ASelector.tsx +88 -0
  65. package/src/ui/editor/basic/ASetSelector.tsx +65 -0
  66. package/src/ui/editor/basic/ASpecInputBox.tsx +20 -0
  67. package/src/ui/editor/basic/ATreeSelect.tsx +41 -0
  68. package/src/ui/editor/basic/AUpload.tsx +119 -0
  69. package/src/ui/editor/basic/NPS.less +21 -0
  70. package/src/ui/editor/basic/NPS.tsx +47 -0
  71. package/src/ui/editor/complex/AArray.less +10 -0
  72. package/src/ui/editor/complex/AArray.tsx +104 -0
  73. package/src/ui/editor/complex/AArrayGrid.tsx +115 -0
  74. package/src/ui/editor/complex/ACnAddress.less +15 -0
  75. package/src/ui/editor/complex/ACnAddress.tsx +61 -0
  76. package/src/ui/editor/complex/ADialogForm.tsx +45 -0
  77. package/src/ui/editor/complex/AExperience.tsx +85 -0
  78. package/src/ui/editor/complex/AForm.less +35 -0
  79. package/src/ui/editor/complex/AForm.tsx +340 -0
  80. package/src/ui/editor/complex/AIntDiff.tsx +77 -0
  81. package/src/ui/editor/complex/AMatrix.less +18 -0
  82. package/src/ui/editor/complex/AMatrix.tsx +242 -0
  83. package/src/ui/editor/complex/ATable.less +4 -0
  84. package/src/ui/editor/complex/ATable.tsx +33 -0
  85. package/src/ui/editor/complex/JsonEditor.tsx +37 -0
  86. package/src/ui/readable/A.tsx +33 -0
  87. package/src/ui/readable/ArrayViewer.tsx +46 -0
  88. package/src/ui/readable/DecorationViewer.tsx +76 -0
  89. package/src/ui/readable/DivViewer.tsx +11 -0
  90. package/src/ui/widget/Collapsible.tsx +156 -0
  91. package/src/ui/widget/Segment.less +39 -0
  92. package/src/ui/widget/Segment.tsx +40 -0
  93. package/src/ui/widget/SegmentEditSwitch.tsx +46 -0
  94. package/src/ui/widget/SelectBox.tsx +43 -0
  95. package/src/ui/widget/UnderlineInputBox.less +47 -0
  96. package/src/ui/widget/UnderlineInputBox.tsx +10 -0
  97. package/types/framework/Ajax.d.ts +5 -0
  98. package/types/framework/Assembly.d.ts +59 -0
  99. package/types/framework/Init.d.ts +4 -0
  100. package/types/framework/M3.d.ts +6 -0
  101. package/types/framework/MContext.d.ts +11 -0
  102. package/types/framework/MFieldViewer.d.ts +8 -0
  103. package/types/framework/MUtil.d.ts +180 -0
  104. package/types/framework/MViewer.d.ts +75 -0
  105. package/types/framework/MViewerDebug.d.ts +11 -0
  106. package/types/framework/Persistant.d.ts +17 -0
  107. package/types/framework/Schema.d.ts +306 -0
  108. package/types/framework/SchemaFunc.d.ts +14 -0
  109. package/types/framework/Validator.d.ts +53 -0
  110. package/types/framework/editorMap.d.ts +107 -0
  111. package/types/index.d.ts +21 -0
  112. package/types/types/MArrayType.d.ts +2 -0
  113. package/types/types/MCascadeType.d.ts +11 -0
  114. package/types/types/MCnAddressType.d.ts +2 -0
  115. package/types/types/MDateRangeType.d.ts +7 -0
  116. package/types/types/MDateTimeType.d.ts +11 -0
  117. package/types/types/MDecorationType.d.ts +7 -0
  118. package/types/types/MEnumType.d.ts +2 -0
  119. package/types/types/MExperienceType.d.ts +5 -0
  120. package/types/types/MFloatType.d.ts +2 -0
  121. package/types/types/MGB2260Type.d.ts +9 -0
  122. package/types/types/MIntDiffType.d.ts +2 -0
  123. package/types/types/MIntType.d.ts +2 -0
  124. package/types/types/MKvSetType.d.ts +11 -0
  125. package/types/types/MMatrixType.d.ts +5 -0
  126. package/types/types/MObjectType.d.ts +11 -0
  127. package/types/types/MSetType.d.ts +7 -0
  128. package/types/types/MStringType.d.ts +2 -0
  129. package/types/types/MTelType.d.ts +4 -0
  130. package/types/types/MType.d.ts +46 -0
  131. package/types/types/MVLPairType.d.ts +5 -0
  132. package/types/ui/BaseViewer.d.ts +45 -0
  133. package/types/ui/editor/basic/ACascadePicker.d.ts +11 -0
  134. package/types/ui/editor/basic/ACheckBox.d.ts +17 -0
  135. package/types/ui/editor/basic/ADatetimePicker.d.ts +15 -0
  136. package/types/ui/editor/basic/AGB2260.d.ts +10 -0
  137. package/types/ui/editor/basic/AInputBox.d.ts +8 -0
  138. package/types/ui/editor/basic/AIntBox.d.ts +9 -0
  139. package/types/ui/editor/basic/AKvSet.d.ts +19 -0
  140. package/types/ui/editor/basic/ARadio.d.ts +14 -0
  141. package/types/ui/editor/basic/ARangePicker.d.ts +30 -0
  142. package/types/ui/editor/basic/ARate.d.ts +13 -0
  143. package/types/ui/editor/basic/ARemoteSelector.d.ts +15 -0
  144. package/types/ui/editor/basic/ASelector.d.ts +14 -0
  145. package/types/ui/editor/basic/ASetSelector.d.ts +10 -0
  146. package/types/ui/editor/basic/ASpecInputBox.d.ts +9 -0
  147. package/types/ui/editor/basic/ATreeSelect.d.ts +18 -0
  148. package/types/ui/editor/basic/AUpload.d.ts +33 -0
  149. package/types/ui/editor/basic/NPS.d.ts +13 -0
  150. package/types/ui/editor/complex/AArray.d.ts +11 -0
  151. package/types/ui/editor/complex/AArrayGrid.d.ts +13 -0
  152. package/types/ui/editor/complex/ACnAddress.d.ts +10 -0
  153. package/types/ui/editor/complex/ADialogForm.d.ts +11 -0
  154. package/types/ui/editor/complex/AExperience.d.ts +16 -0
  155. package/types/ui/editor/complex/AForm.d.ts +46 -0
  156. package/types/ui/editor/complex/AIntDiff.d.ts +14 -0
  157. package/types/ui/editor/complex/AMatrix.d.ts +48 -0
  158. package/types/ui/editor/complex/ATable.d.ts +9 -0
  159. package/types/ui/editor/complex/JsonEditor.d.ts +9 -0
  160. package/types/ui/readable/A.d.ts +5 -0
  161. package/types/ui/readable/ArrayViewer.d.ts +5 -0
  162. package/types/ui/readable/DecorationViewer.d.ts +3 -0
  163. package/types/ui/readable/DivViewer.d.ts +5 -0
  164. package/types/ui/widget/Collapsible.d.ts +46 -0
  165. package/types/ui/widget/Segment.d.ts +18 -0
  166. package/types/ui/widget/SegmentEditSwitch.d.ts +20 -0
  167. package/types/ui/widget/SelectBox.d.ts +13 -0
  168. 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,6 @@
1
+
2
+ import {EmtpyType} from "./MType";
3
+ import _ from "lodash";
4
+
5
+ /** HTML装饰物,并不修改数据 */
6
+ export const MDecorationType = EmtpyType;
@@ -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,6 @@
1
+
2
+ import { MType} from "./MType";
3
+ import _ from "lodash";
4
+ import { MIntType } from "./MIntType";
5
+
6
+ export const MIntDiffType: MType = MIntType;
@@ -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
+ });