@cicctencent/low-code-simulate-base 0.0.0-stage → 1.1.10

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 (82) hide show
  1. package/README.md +1 -3
  2. package/__tests__/plugin.spec.ts +40 -0
  3. package/__tests__/utils.transform.test.ts +37 -0
  4. package/api-extractor.json +36 -0
  5. package/build/md.js +25 -0
  6. package/dist/VCComponent.d.ts +5 -0
  7. package/dist/VCComponent.js +91 -0
  8. package/dist/domain/BaseProjectDomain.d.ts +389 -0
  9. package/dist/domain/BaseProjectDomain.js +1305 -0
  10. package/dist/domain/ComponentManager.d.ts +78 -0
  11. package/dist/domain/ComponentManager.js +293 -0
  12. package/dist/domain/DataHistoryDomain.d.ts +53 -0
  13. package/dist/domain/DataHistoryDomain.js +110 -0
  14. package/dist/domain/PreviewDomain.d.ts +208 -0
  15. package/dist/domain/PreviewDomain.js +490 -0
  16. package/dist/domain/ProjectDomain.d.ts +209 -0
  17. package/dist/domain/ProjectDomain.js +138 -0
  18. package/dist/event/generateEventHandler.d.ts +21 -0
  19. package/dist/event/generateEventHandler.js +218 -0
  20. package/dist/event/generateEventSchema.d.ts +123 -0
  21. package/dist/event/generateEventSchema.js +342 -0
  22. package/dist/event/register.d.ts +56 -0
  23. package/dist/event/register.js +207 -0
  24. package/dist/index.d.ts +1369 -0
  25. package/dist/index.js +28 -0
  26. package/dist/plugin/onH5PageValidate.d.ts +7 -0
  27. package/dist/plugin/onH5PageValidate.js +178 -0
  28. package/dist/plugin/onPlaceholder.d.ts +6 -0
  29. package/dist/plugin/onPlaceholder.js +68 -0
  30. package/dist/plugin/subscribeInsertUploadList.d.ts +6 -0
  31. package/dist/plugin/subscribeInsertUploadList.js +49 -0
  32. package/dist/plugin/subscribeSetTitle.d.ts +6 -0
  33. package/dist/plugin/subscribeSetTitle.js +16 -0
  34. package/dist/plugin/subscribeTransformComponentMeta.d.ts +14 -0
  35. package/dist/plugin/subscribeTransformComponentMeta.js +31 -0
  36. package/dist/plugin/subscribeValidateField.d.ts +7 -0
  37. package/dist/plugin/subscribeValidateField.js +57 -0
  38. package/dist/plugin/subscribeValidateUpload.d.ts +6 -0
  39. package/dist/plugin/subscribeValidateUpload.js +92 -0
  40. package/dist/utils/base64.d.ts +14 -0
  41. package/dist/utils/base64.js +14 -0
  42. package/dist/utils/buildInVariable.d.ts +61 -0
  43. package/dist/utils/buildInVariable.js +216 -0
  44. package/dist/utils/dom.d.ts +14 -0
  45. package/dist/utils/dom.js +19 -0
  46. package/dist/utils/index.d.ts +55 -0
  47. package/dist/utils/index.js +201 -0
  48. package/dist/utils/transform.d.ts +39 -0
  49. package/dist/utils/transform.js +191 -0
  50. package/dist/utils/validate.d.ts +7 -0
  51. package/dist/utils/validate.js +18 -0
  52. package/docs/.api/low-code-simulate-base.api.json +8450 -0
  53. package/jest.config.ts +20 -0
  54. package/package.json +45 -4
  55. package/src/VCComponent.ts +118 -0
  56. package/src/domain/BaseProjectDomain.ts +1341 -0
  57. package/src/domain/ComponentManager.ts +241 -0
  58. package/src/domain/DataHistoryDomain.ts +102 -0
  59. package/src/domain/PreviewDomain.ts +424 -0
  60. package/src/domain/ProjectDomain.ts +244 -0
  61. package/src/event/generateEventHandler.ts +162 -0
  62. package/src/event/generateEventSchema.ts +371 -0
  63. package/src/event/register.ts +181 -0
  64. package/src/index.ts +61 -0
  65. package/src/plugin/onH5PageValidate.ts +179 -0
  66. package/src/plugin/onPlaceholder.ts +71 -0
  67. package/src/plugin/subscribeInsertUploadList.ts +51 -0
  68. package/src/plugin/subscribeSetTitle.ts +18 -0
  69. package/src/plugin/subscribeTransformComponentMeta.ts +38 -0
  70. package/src/plugin/subscribeValidateField.ts +65 -0
  71. package/src/plugin/subscribeValidateUpload.ts +116 -0
  72. package/src/utils/base64.ts +17 -0
  73. package/src/utils/buildInVariable.ts +157 -0
  74. package/src/utils/dom.ts +30 -0
  75. package/src/utils/index.ts +194 -0
  76. package/src/utils/transform.ts +171 -0
  77. package/src/utils/validate.ts +19 -0
  78. package/temp/low-code-simulate-base.api.md +597 -0
  79. package/test/plugin.test.ts +4 -0
  80. package/tsconfig.build.json +9 -0
  81. package/tsconfig.json +9 -0
  82. package/tsconfig.test.json +14 -0
package/src/index.ts ADDED
@@ -0,0 +1,61 @@
1
+ import BaseProjectDomain from './domain/BaseProjectDomain';
2
+ import PreviewDomain from './domain/PreviewDomain';
3
+ import ProjectDomain from './domain/ProjectDomain';
4
+ import ComponentManager from './domain/ComponentManager';
5
+ import onH5PageValidate from './plugin/onH5PageValidate';
6
+ import onPlaceholder from './plugin/onPlaceholder';
7
+ import subscribeInsertUploadList from './plugin/subscribeInsertUploadList';
8
+ import subscribeTransformComponentMeta from './plugin/subscribeTransformComponentMeta';
9
+ import subscribeValidateField from './plugin/subscribeValidateField';
10
+ import subscribeValidateUpload from './plugin/subscribeValidateUpload';
11
+ import subscribeSetTitle from './plugin/subscribeSetTitle';
12
+ export * from './domain/PreviewDomain';
13
+ export * from './domain/ProjectDomain';
14
+ import DataHistoryDomain from './domain/DataHistoryDomain';
15
+ export { ProjectDomainState } from './domain/BaseProjectDomain'
16
+ import VcComponent from './VCComponent';
17
+ export * from './utils/base64';
18
+ export * from './utils/index';
19
+ export * from './utils/transform';
20
+ export * from './utils/validate';
21
+ export {
22
+ VcComponent,
23
+ PreviewDomain,
24
+ BaseProjectDomain,
25
+ ProjectDomain,
26
+ ComponentManager,
27
+ onH5PageValidate,
28
+ onPlaceholder,
29
+ subscribeInsertUploadList,
30
+ subscribeTransformComponentMeta,
31
+ subscribeValidateField,
32
+ subscribeValidateUpload,
33
+ subscribeSetTitle,
34
+ DataHistoryDomain
35
+ };
36
+ export {
37
+ initAllEventsFormSchema,
38
+ initEventsFormSchema,
39
+ generateEventProperties,
40
+ initMiddlewareFormSchema,
41
+ } from './event/generateEventSchema';
42
+ export {
43
+ generateEventHandlers,
44
+ executeMiddleware,
45
+ } from './event/generateEventHandler';
46
+ export * from './event/register';
47
+
48
+ export * from './utils/buildInVariable'
49
+ declare global {
50
+ interface Window {
51
+ JT_VERSION: Record<string, string>;
52
+ }
53
+ }
54
+ export * from './utils/dom';
55
+
56
+ window.JT_VERSION = Object.assign(
57
+ {
58
+ '__rollup__name__@__rollup__version__': '__rollup__date__',
59
+ },
60
+ window.JT_VERSION
61
+ );
@@ -0,0 +1,179 @@
1
+ import type {
2
+ ComponentItem,
3
+ CheckRequestItem,
4
+ CheckResponseItem,
5
+ } from '@cicctencent/low-code-core';
6
+ import { getComponentKeyValue, groupBy } from '../utils';
7
+ import BaseProjectDomain from '../domain/BaseProjectDomain';
8
+ import PreviewDomain from '../domain/PreviewDomain';
9
+ import { formilyValidate } from '../utils/validate';
10
+ import { transform } from '../utils/transform';
11
+ import { cloneDeep, set, toPlainObject, log, get } from '@cicctencent/ark-util';
12
+ const logTag = '[low-code-creator onH5PageValidate]';
13
+ const logInfo = log(logTag);
14
+ import { validate } from '@cicctencent/low-code-validate';
15
+
16
+ export function findComponentById(components, componentId) {
17
+ for (const component of components) {
18
+ if (component.componentId === componentId) {
19
+ return component;
20
+ }
21
+ if (component.children) {
22
+ const res = findComponentById(component.children, componentId);
23
+ if (res) {
24
+ return res;
25
+ }
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+
31
+ /**
32
+ * @public
33
+ * @param previewDomain - previewDomain
34
+ */
35
+ export default function (previewDomain: PreviewDomain) {
36
+ const project = previewDomain.state.project as BaseProjectDomain;
37
+ /**
38
+ * 转换校验的Extend配置
39
+ */
40
+ function transformValidateExtendConfig(config, cId) {
41
+ const result = {};
42
+ // 获取组件信息
43
+ let componentInfo = findComponentById(project.components, cId);
44
+ Object.keys(config || {}).forEach(it => {
45
+ if ('x-data' in config[it] && 'extend' in config[it]['x-data']) {
46
+ // 有可能组件在children中
47
+ const extraData = {};
48
+ // x-data.extend
49
+ if (componentInfo) {
50
+ const extend: Record<string, string> =
51
+ config[it]['x-data']['extend'] || {};
52
+ Object.keys(extend).forEach(ek => {
53
+ extraData[ek] = getComponentKeyValue(
54
+ extend[ek].replace('$', ''),
55
+ componentInfo
56
+ );
57
+ });
58
+ }
59
+ result[it] = { ...config[it], extraData };
60
+ } else {
61
+ // 不需要特殊处理
62
+ result[it] = config[it];
63
+ }
64
+ });
65
+ return result;
66
+ }
67
+ previewDomain.on(
68
+ 'validatePage',
69
+ (fillData?: CheckResponseItem[]): CheckRequestItem[] => {
70
+
71
+ logInfo('validatePage', 'project', previewDomain.projectData);
72
+ // 点击发布报错对话框确认按钮回填数据 并再次校验
73
+ if (fillData) {
74
+ logInfo(
75
+ 'validatePage',
76
+ 'fillData',
77
+ fillData,
78
+ previewDomain.projectData
79
+ );
80
+ //填充数据
81
+ try {
82
+ const newProject = cloneDeep(previewDomain.projectData);
83
+ fillData.forEach(item => {
84
+ set(newProject, item.path, item.value);
85
+ });
86
+ project.state.project = newProject;
87
+ logInfo('validatePage', 'newProject', newProject);
88
+ // 更新模拟器,编辑器
89
+ previewDomain.emit('updateProject', project);
90
+ previewDomain.publish.update(true);
91
+ } catch (error) {
92
+ console.error(error);
93
+ }
94
+ }
95
+ const errItems: Array<CheckRequestItem> = [];
96
+ // const prependPath = 'pages[0].components[0].list[0].formData';
97
+ // 处理components 没有schema的情况
98
+ const components = project.componentsWithConfig;
99
+
100
+ const validateData = components.reduce((acc, cur) => {
101
+ return cur?.children?.length
102
+ ? acc.concat(
103
+ // @ts-ignore
104
+ cur.formData,
105
+ (cur.children as ComponentItem[]).map(c => c.formData)
106
+ )
107
+ : // @ts-ignore
108
+ acc.concat(cur.formData);
109
+ }, []);
110
+ logInfo('validatePage', 'validateData', validateData);
111
+
112
+ try {
113
+ for (let i = 0; i < components.length; i++) {
114
+ components[i].config = transform(
115
+ components[i].config,
116
+ project.getFlagWordMap(i)
117
+ );
118
+ const result = validate(components[i], validateData);
119
+ console.log('组件校验结果:', result);
120
+ if (Array.isArray(result) && result.length) {
121
+ // 根据title进行分组
122
+ const groups = groupBy(result, 'title');
123
+ Object.keys(groups).forEach(key => {
124
+ errItems.push({
125
+ title: key,
126
+ type: 0,
127
+ list: groups[key].map(m => {
128
+ const componentPath = m.path?.includes('children')
129
+ ? `pages[0].components[0].list[${i}].${m.path}`.replace(
130
+ /\.formData[\s\S]*$/,
131
+ ''
132
+ )
133
+ : `pages[0].components[0].list[${i}]`;
134
+ const component = get(project.state.project, componentPath);
135
+ return {
136
+ schema: transformValidateExtendConfig(
137
+ m.schema,
138
+ component?.componentId
139
+ ),
140
+ path: m.path?.includes('children')
141
+ ? `pages[0].components[0].list[${i}].${m.path}`
142
+ : `pages[0].components[0].list[${i}].formData.${m.path}`,
143
+ };
144
+ }),
145
+ });
146
+ });
147
+ }
148
+ // 处理容器内的组件
149
+ }
150
+ logInfo('validatePage', 'compoennt validate', errItems);
151
+ // 页面校验
152
+ const pageValidateResult = formilyValidate(
153
+ {
154
+ config: project.state.pageConfig as any,
155
+ formData: project.pageMeta,
156
+ },
157
+ []
158
+ );
159
+ if (Array.isArray(pageValidateResult) && pageValidateResult.length) {
160
+ logInfo('validatePage', 'page validate', pageValidateResult);
161
+ errItems.push({
162
+ title: '页面基础信息',
163
+ type: 1,
164
+ list: pageValidateResult.map(m => {
165
+ return {
166
+ ...m,
167
+ path: `pages[0].pageMeta.${m.path}`,
168
+ };
169
+ }),
170
+ });
171
+ }
172
+ logInfo('validatePage', 'errItems', errItems);
173
+ } catch (error) {
174
+ console.error(error);
175
+ }
176
+ return toPlainObject(errItems);
177
+ }
178
+ );
179
+ }
@@ -0,0 +1,71 @@
1
+ import type { ComponentItem } from '@cicctencent/low-code-core';
2
+ import PreviewDomain from '../domain/PreviewDomain';
3
+ import { get, toPlainObject, getLog } from '@cicctencent/ark-util';
4
+ import { getSchemaObjectAttribute } from '../utils';
5
+ import { transformComponentMeta } from './subscribeTransformComponentMeta';
6
+ import BaseProjectDomain from '../domain/BaseProjectDomain';
7
+ const logTag = '[low-code-creator onPlaceholder]';
8
+ const logger = getLog(logTag);
9
+
10
+ /**
11
+ * @public
12
+ * @param previewDomain - previewDomain
13
+ */
14
+ export default function (previewDomain: PreviewDomain) {
15
+ const project = previewDomain.state.project as BaseProjectDomain;
16
+ previewDomain.on('clickPlaceholder', (id: number) => {
17
+ try {
18
+ const componentPath = project.generateComponentPath(id);
19
+ const { componentListPath } = project.getIndexByKey(componentPath);
20
+ const components = get(project.pages, componentListPath);
21
+ const componentData = components.find(c => c.componentId == id);
22
+ const component: ComponentItem = {
23
+ ...project.cManager.get(componentData.name),
24
+ ...componentData,
25
+ };
26
+
27
+ let data = {};
28
+ let field = null;
29
+ // 是否处理点击
30
+ if (component?.placeholderConfig?.click) {
31
+ // 存在path配置
32
+ if (component.placeholderConfig?.path) {
33
+ // 获取属性名
34
+ const matchResult =
35
+ component.placeholderConfig.path.match(/\.(\w+)$/);
36
+ if (!matchResult || !component?.config) {
37
+ return;
38
+ }
39
+ // 通过属性名获取相应的配置
40
+ const config = getSchemaObjectAttribute(
41
+ component?.config,
42
+ matchResult[1]
43
+ );
44
+ // 存在path的情况
45
+ // 获取到配置信息
46
+ if (config) {
47
+ field = config;
48
+ let placeholderData = {
49
+ exportUrl: config?.['x-component-props']?.exportUrl,
50
+ data: Object.assign(
51
+ {},
52
+ config?.['x-component-props']?.data || {},
53
+ get(component.formData || {}, component.placeholderConfig.path)
54
+ ),
55
+ };
56
+ data = transformComponentMeta.bind(previewDomain)({
57
+ data: { config, data: placeholderData },
58
+ });
59
+ }
60
+ }
61
+ // 发送消息给管理端
62
+ previewDomain.commit('message', {
63
+ type: component.placeholderConfig?.action,
64
+ data: { id, data, name: component.name, component, field },
65
+ });
66
+ }
67
+ } catch (error) {
68
+ logger.error('clickPlaceholder error:', error);
69
+ }
70
+ });
71
+ }
@@ -0,0 +1,51 @@
1
+ import BaseProjectDomain from '../domain/BaseProjectDomain';
2
+ import PreviewDomain from '../domain/PreviewDomain';
3
+ import { cloneDeep, get } from '@cicctencent/ark-util';
4
+
5
+ /**
6
+ * @public
7
+ * @param previewDomain - previewDomain
8
+ */
9
+ export default function (previewDomain: PreviewDomain) {
10
+ const project = previewDomain.state.project as BaseProjectDomain;
11
+ /**
12
+ * 插入上传列表
13
+ */
14
+ previewDomain.state.communicator.subscribe(
15
+ 'insertUploadList',
16
+ function ({ data: { key, list, name } }) {
17
+ let start = -1;
18
+ const url = list[0];
19
+ const currentComponentPath = project.generateComponentPath(
20
+ project.currentComponent?.componentId
21
+ );
22
+ const { componentListPath } = project.getIndexByKey(currentComponentPath);
23
+ const components = get(project.pages, componentListPath);
24
+ components.forEach((c, i) => {
25
+ if (c.componentId === project.currentComponent?.componentId) {
26
+ c.formData.props.imgUrl = url;
27
+ start = i;
28
+ }
29
+ });
30
+ // 通过配置文件判断是否存在图片组件
31
+ let imageComponent = project.cManager.get(name);
32
+ if (imageComponent && list.length > 1 && start > -1) {
33
+ list.slice(1).forEach((url, idx) =>
34
+ project.componentListSplice(
35
+ start + idx + 1,
36
+ 0,
37
+ {
38
+ ...cloneDeep(imageComponent),
39
+ formData: {
40
+ props: { imgUrl: url },
41
+ },
42
+ },
43
+ componentListPath
44
+ )
45
+ );
46
+ }
47
+ previewDomain.emit('updateProject', project);
48
+ previewDomain.publish.update();
49
+ }
50
+ );
51
+ }
@@ -0,0 +1,18 @@
1
+ import { toPlainObject } from '@cicctencent/ark-util';
2
+ import BaseProjectDomain from '../domain/BaseProjectDomain';
3
+ import PreviewDomain from '../domain/PreviewDomain';
4
+
5
+ /**
6
+ * @public
7
+ * @param previewDomain - previewDomain
8
+ */
9
+ export default function (previewDomain: PreviewDomain) {
10
+ const project = previewDomain.state.project as BaseProjectDomain;
11
+ /* 设置title */
12
+ previewDomain.state.communicator.subscribe('setTitle', ({ data: value }) => {
13
+ project.state.project = Object.assign(project.state.project, value);
14
+ previewDomain.publish.update();
15
+ previewDomain.emit('updateProject', project);
16
+ return toPlainObject(project.config);
17
+ });
18
+ }
@@ -0,0 +1,38 @@
1
+ import { getComponentKeyValue } from '../utils';
2
+ import PreviewDomain from '../domain/PreviewDomain';
3
+ import { cloneDeep } from '@cicctencent/ark-util';
4
+ /**
5
+ * 转化云组件额外参数
6
+ * @param - data
7
+ * @returns
8
+ */
9
+
10
+ export function transformComponentMeta({ data }): Record<string, any> {
11
+ const { data: res, config } = data;
12
+ const transformResult: Record<string, any> = cloneDeep(res);
13
+ if (config && 'x-data' in config && 'extend' in config['x-data']) {
14
+ transformResult['_extend'] = {};
15
+ const extend: Record<string, string> = config['x-data'].extend;
16
+ Object.keys(extend).forEach(key => {
17
+ if (extend[key].indexOf('$') > -1) {
18
+ transformResult['_extend'][key] = cloneDeep(
19
+ getComponentKeyValue(
20
+ extend[key].replace('$', ''),
21
+ this.state?.project?.currentComponent
22
+ )
23
+ );
24
+ }
25
+ });
26
+ }
27
+ return transformResult;
28
+ }
29
+ /**
30
+ * @public
31
+ * @param previewDomain - previewDomain
32
+ */
33
+ export default function (previewDomain: PreviewDomain) {
34
+ previewDomain.state.communicator.subscribe(
35
+ 'transformComponentMeta',
36
+ transformComponentMeta.bind(previewDomain)
37
+ );
38
+ }
@@ -0,0 +1,65 @@
1
+ import BaseProjectDomain from '../domain/BaseProjectDomain';
2
+ import PreviewDomain from '../domain/PreviewDomain';
3
+
4
+ function chinaTransformUnicode(value: string) {
5
+ if (value) {
6
+ return escape(value)
7
+ .replace(/%u\w{4}/g, function ($0) {
8
+ return $0[3] + $0[5];
9
+ })
10
+ .toLowerCase();
11
+ }
12
+ return '';
13
+ }
14
+ /**
15
+ * @public
16
+ * @param previewDomain - previewDomain
17
+ */
18
+ export default function (previewDomain: PreviewDomain | BaseProjectDomain) {
19
+ const project = previewDomain.state.project as BaseProjectDomain;
20
+ function validateBuryReportName(value) {
21
+ if (!/^[A-Za-z0-9_-]+$/g.test(chinaTransformUnicode(value))) {
22
+ return '您输入的埋点名称存在非法字符,请重新输入「埋点名称应为:大/小写字母、数字、中文、横杠、下划线或其组合」';
23
+ }
24
+ // 判断是否存在重复埋点
25
+ const componentList =
26
+ project.state.project?.pages?.[0]?.components?.[0]?.list || [];
27
+ const errText = componentList.reduce((err, component) => {
28
+ const jsonStr = JSON.stringify(component || {});
29
+ const regex = /"buryReportName":"([^"]+)"/g;
30
+ const result: any[] = [];
31
+ let match;
32
+ while ((match = regex.exec(jsonStr)) !== null) {
33
+ result.push(match[1]);
34
+ }
35
+ if (result.includes(value)) {
36
+ return err + ` ${component.title} id: ${component.componentId} `;
37
+ }
38
+ return err + '';
39
+ }, '');
40
+ if (errText) {
41
+ return `您输入的埋点名称和「${errText}」的埋点名称重复,请重新输入`;
42
+ }
43
+ return '';
44
+ }
45
+ // @ts-ignore
46
+ previewDomain.state.communicator.subscribe(
47
+ 'validateField',
48
+ function ({ data }) {
49
+ // 校验类型
50
+ const validateType = data?.type;
51
+ // 检验值
52
+ const validateValue = data?.value;
53
+
54
+ if (!validateValue || !validateType) {
55
+ return '';
56
+ }
57
+
58
+ if (validateType === 'buryReportName') {
59
+ return validateBuryReportName(validateValue);
60
+ }
61
+
62
+ return '';
63
+ }
64
+ );
65
+ }
@@ -0,0 +1,116 @@
1
+ import { getFileSizeStr } from '../utils';
2
+ import BaseProjectDomain from '../domain/BaseProjectDomain';
3
+ import PreviewDomain from '../domain/PreviewDomain';
4
+ import { tipIcon } from '../utils/base64';
5
+ import { toPlainObject } from '@cicctencent/ark-util';
6
+ import { getSchemaObjectAttribute, getImageType } from '../utils';
7
+ import type { ConfirmMessageBoxData } from '@cicctencent/low-code-core';
8
+ /**
9
+ * @public
10
+ * @param previewDomain - previewDomain
11
+ */
12
+ export default function (previewDomain: PreviewDomain) {
13
+ const project = previewDomain.state.project as BaseProjectDomain;
14
+ /**
15
+ * 上传校验 校验点击模拟器占位图上传图片的大小和二倍图以及表单上传图片的大小
16
+ * @param - fileList 当前upload组件上传的文件列表 目前所有情况只包含一个文件
17
+ */
18
+ previewDomain.state.communicator.subscribe(
19
+ 'validateUpload',
20
+ function ({ data }) {
21
+ // todo 图片组件
22
+ const { fileList, config } = data;
23
+
24
+ let validateConfig =
25
+ config ??
26
+ getSchemaObjectAttribute(
27
+ project.cManager.get(project.currentComponent.name)?.config as Record<
28
+ string,
29
+ any
30
+ >,
31
+ 'imgUrl'
32
+ );
33
+ if (validateConfig && Array.isArray(fileList)) {
34
+ const { upload } = validateConfig['x-validator'] ?? { upload: {} };
35
+ const doubleImage = upload?.expectWidth ? true : false;
36
+ fileList.forEach(file => {
37
+ //匹配链接中的文件后缀,其中\.表示匹配.字符,[^.]+表示匹配除.以外的任意字符,$表示匹配字符串结尾。[1]表示返回匹配到的第一个子串,即文件后缀名。
38
+ const fileSuffix = getImageType(file.url);
39
+ // 需要校验的文件后缀列表
40
+ const expectSuffix: string[] = upload?.expectSuffix || [
41
+ 'png',
42
+ 'jpg',
43
+ 'jpeg',
44
+ ];
45
+ if (expectSuffix.includes(fileSuffix as string)) {
46
+ // 校验图片大小
47
+ if (file?.size > upload?.expectSize) {
48
+ file.err = {
49
+ text: `图片大于${getFileSizeStr(
50
+ upload.expectSize
51
+ )},请与设计师沟通调整图片后重新上传。`,
52
+ };
53
+ //schema上传,则要提示图片过大
54
+ const messageBoxData: ConfirmMessageBoxData = {
55
+ schema: {
56
+ type: 'object',
57
+ properties: {
58
+ _: {
59
+ 'x-component': 'Text',
60
+ 'x-component-props': {
61
+ text: `<span>图片大于${getFileSizeStr(
62
+ upload.expectSize
63
+ )},请与设计师沟通调整图片后重新上传。</span>`,
64
+ },
65
+ },
66
+ },
67
+ },
68
+ type: 'warning',
69
+ title: '提示',
70
+ confirmButton: {
71
+ text: '确认',
72
+ key: undefined,
73
+ },
74
+ cancelButton: {
75
+ text: '',
76
+ key: undefined,
77
+ },
78
+ };
79
+ project.publishEditor(
80
+ 'action',
81
+ toPlainObject({
82
+ key: 'confirm',
83
+ value: messageBoxData,
84
+ })
85
+ );
86
+ }
87
+ // 校验图片2倍图
88
+ if (doubleImage && upload?.expectWidth) {
89
+ if (file.width < upload?.expectWidth) {
90
+ file.err = {
91
+ text: upload?.doubleImageTip || '清晰度过低,请使用2倍图上传',
92
+ icon: tipIcon,
93
+ guide: upload.guide,
94
+ };
95
+ project.publishEditor(
96
+ 'action',
97
+ toPlainObject({
98
+ key: 'doubleImage',
99
+ value: {
100
+ text:
101
+ upload?.doubleImageTip ||
102
+ '图片清晰度过低,请使用上传2倍图',
103
+ icon: tipIcon,
104
+ guide: upload?.guide,
105
+ },
106
+ })
107
+ );
108
+ }
109
+ }
110
+ }
111
+ });
112
+ }
113
+ return toPlainObject(fileList);
114
+ }
115
+ );
116
+ }
@@ -0,0 +1,17 @@
1
+
2
+ /**
3
+ * @public
4
+ */
5
+ export const placeholderIcon = `data:image/webp;base64,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`;
6
+ /**
7
+ * @public
8
+ * 提示图标
9
+ */
10
+ export const tipIcon =
11
+ "data:image/webp;base64,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";
12
+
13
+ /**
14
+ * @public
15
+ * 非图片图标
16
+ * */
17
+ export const notImageIcon = `data:image/webp;base64,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`;