@ebiz/designer-components 0.0.58 → 0.0.60
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/README.md +29 -29
- package/dist/designer-components.css +1 -1
- package/dist/index.mjs +5925 -5923
- package/package.json +1 -1
- package/src/App.vue +26 -26
- package/src/apiService/SIMPLE_DATA_SERVICE.md +284 -284
- package/src/apiService/mockDataService.js +115 -115
- package/src/apiService/simpleDataService.js +297 -297
- package/src/assets/base.css +86 -86
- package/src/assets/logo.svg +1 -1
- package/src/components/Button.vue +149 -149
- package/src/components/DataContainer.vue +40 -40
- package/src/components/EbizApproval.vue +332 -338
- package/src/components/EbizAutoForm.vue +596 -596
- package/src/components/EbizAvatar.vue +115 -115
- package/src/components/EbizCheckbox.vue +93 -93
- package/src/components/EbizCheckboxGroup.vue +69 -69
- package/src/components/EbizDepartmentSelector.vue +144 -144
- package/src/components/EbizDescriptions.vue +340 -340
- package/src/components/EbizDescriptionsItem.vue +47 -47
- package/src/components/EbizDetailBlock.vue +81 -81
- package/src/components/EbizDialog.vue +260 -260
- package/src/components/EbizDiv.vue +32 -32
- package/src/components/EbizDivider.vue +96 -96
- package/src/components/EbizEmployeeInfo.vue +138 -138
- package/src/components/EbizEmployeeSelector.vue +1093 -1086
- package/src/components/EbizFileUpload.vue +238 -238
- package/src/components/EbizMap.vue +541 -541
- package/src/components/EbizOkrTree.vue +99 -99
- package/src/components/EbizPageHeader.vue +95 -95
- package/src/components/EbizPagination.vue +162 -162
- package/src/components/EbizPopconfirm.vue +47 -47
- package/src/components/EbizRadio.vue +86 -86
- package/src/components/EbizRadioGroup.vue +83 -83
- package/src/components/EbizRemoteSelect.vue +232 -232
- package/src/components/EbizRouteBreadcrumb.vue +46 -46
- package/src/components/EbizSelect.vue +85 -85
- package/src/components/EbizSpace.vue +100 -100
- package/src/components/EbizStatistic.vue +149 -149
- package/src/components/EbizStatsCard.vue +113 -113
- package/src/components/EbizSwiper.vue +113 -113
- package/src/components/EbizSwiperItem.vue +13 -13
- package/src/components/EbizSwitch.vue +85 -85
- package/src/components/EbizTabHeader.vue +132 -132
- package/src/components/EbizTabPanel.vue +22 -22
- package/src/components/EbizTable.vue +469 -469
- package/src/components/EbizTableColumn.vue +116 -116
- package/src/components/EbizTableSort.vue +179 -179
- package/src/components/EbizTabs.vue +142 -142
- package/src/components/EbizTdesignButtonDialog.vue +332 -332
- package/src/components/EbizTdesignLoading.vue +107 -107
- package/src/components/EbizTimePicker.vue +143 -143
- package/src/components/EbizTitle.vue +91 -91
- package/src/components/EbizTree.vue +152 -152
- package/src/components/EbizTreeMergeTable.vue +1414 -1414
- package/src/components/EbizTreeSelector.vue +418 -418
- package/src/components/EbizVxeTable.vue +290 -290
- package/src/components/Form.vue +28 -28
- package/src/components/Home.vue +7 -7
- package/src/components/MyComponent.vue +39 -39
- package/src/components/Table.vue +45 -45
- package/src/components/TdesignAlert.vue +115 -115
- package/src/components/TdesignButton.vue +135 -135
- package/src/components/TdesignCalendar/index.vue +145 -145
- package/src/components/TdesignCard.vue +195 -195
- package/src/components/TdesignCol.vue +101 -101
- package/src/components/TdesignCollapse.vue +142 -142
- package/src/components/TdesignCollapsePanel.vue +79 -79
- package/src/components/TdesignDatePicker.vue +124 -124
- package/src/components/TdesignDescriptions.vue +74 -74
- package/src/components/TdesignDescriptionsItem.vue +50 -50
- package/src/components/TdesignDialog.vue +225 -225
- package/src/components/TdesignForm.vue +138 -138
- package/src/components/TdesignFormItem.vue +105 -105
- package/src/components/TdesignGrid.vue +55 -55
- package/src/components/TdesignIcon.vue +67 -67
- package/src/components/TdesignImage.vue +162 -162
- package/src/components/TdesignImageViewer.vue +200 -200
- package/src/components/TdesignInput.vue +242 -242
- package/src/components/TdesignSelect.vue +444 -444
- package/src/components/TdesignTag.vue +117 -117
- package/src/components/TdesignTextarea.vue +142 -142
- package/src/components/TdesignTimeline.vue +58 -58
- package/src/components/TdesignTimelineItem.vue +71 -71
- package/src/components/TdesignUpload.vue +388 -388
- package/src/components/TdesignWatermark.vue +107 -107
- package/src/components/ebiz-form/components/cascader.vue +61 -61
- package/src/components/ebiz-form/components/checkbox.vue +37 -37
- package/src/components/ebiz-form/components/city.vue +137 -137
- package/src/components/ebiz-form/components/date-panel.vue +52 -52
- package/src/components/ebiz-form/components/date-range-panel.vue +52 -52
- package/src/components/ebiz-form/components/date-range.vue +56 -56
- package/src/components/ebiz-form/components/date.vue +52 -52
- package/src/components/ebiz-form/components/editor-multi-language.vue +47 -47
- package/src/components/ebiz-form/components/editor.vue +78 -78
- package/src/components/ebiz-form/components/file-multi-language.vue +52 -52
- package/src/components/ebiz-form/components/file.vue +149 -149
- package/src/components/ebiz-form/components/images-multi-language.vue +52 -52
- package/src/components/ebiz-form/components/images.vue +129 -129
- package/src/components/ebiz-form/components/img-multi-language.vue +51 -51
- package/src/components/ebiz-form/components/img.vue +129 -129
- package/src/components/ebiz-form/components/number.vue +50 -50
- package/src/components/ebiz-form/components/radio.vue +28 -28
- package/src/components/ebiz-form/components/select.vue +119 -119
- package/src/components/ebiz-form/components/switch.vue +23 -23
- package/src/components/ebiz-form/components/text-multi-language.vue +47 -47
- package/src/components/ebiz-form/components/text.vue +52 -52
- package/src/components/ebiz-form/components/textarea-multi-language.vue +48 -48
- package/src/components/ebiz-form/components/textarea.vue +29 -29
- package/src/components/ebiz-form/components/video-multi-language.vue +51 -51
- package/src/components/ebiz-form/components/video.vue +97 -97
- package/src/components/ebiz-form/index.vue +157 -157
- package/src/components/examples/PopconfirmExample.vue +149 -149
- package/src/components/icons/IconCommunity.vue +7 -7
- package/src/components/icons/IconDocumentation.vue +7 -7
- package/src/components/icons/IconEcosystem.vue +7 -7
- package/src/components/icons/IconSupport.vue +7 -7
- package/src/components/icons/IconTooling.vue +19 -19
- package/src/components/senior/EbizSData/index.vue +262 -260
- package/src/components/senior/EbizSDialog/index.vue +713 -713
- package/src/components/senior/EbizSForm/README.md +157 -157
- package/src/components/senior/EbizSForm/index.vue +668 -668
- package/src/components/senior/EbizSForm/item.vue +522 -522
- package/src/components/senior/EbizSForm/mItems/DateTimePicker.vue +51 -51
- package/src/components/senior/EbizSForm/mItems/Picker.vue +63 -63
- package/src/index.js +218 -218
- package/src/main.js +55 -55
- package/src/router/index.js +374 -374
- package/src/utils/formatCode.js +24 -24
- package/src/utils/generateImportStatement.js +52 -52
- package/src/utils/hasJsx.js +25 -25
- package/src/utils/index.js +166 -166
- package/src/utils/mergeOptions.js +29 -29
- package/src/utils/parseRequiredBlocks.js +18 -18
- package/src/utils/upload.ts +126 -126
- package/src/utils/vue-sfc-validator.js +155 -155
- package/src/views/Button.vue +23 -23
- package/src/views/CheckboxDemo.vue +104 -104
- package/src/views/DataContainer.vue +19 -19
- package/src/views/DialogDemo.vue +125 -125
- package/src/views/EbizApprovalDemo.vue +76 -76
- package/src/views/EbizAutoFormDemo.vue +129 -129
- package/src/views/EbizAvatar.vue +223 -223
- package/src/views/EbizDepartmentSelectorDemo.vue +169 -169
- package/src/views/EbizDetailBlockDemo.vue +30 -30
- package/src/views/EbizEmployeeInfo.vue +249 -249
- package/src/views/EbizEmployeeSelector.vue +83 -83
- package/src/views/EbizMap.vue +201 -201
- package/src/views/EbizRadioDemo.vue +151 -151
- package/src/views/EbizSDataDemo.vue +136 -136
- package/src/views/EbizSDialogDemo.vue +301 -301
- package/src/views/EbizSForm/index.vue +359 -359
- package/src/views/EbizSFormDemo.vue +420 -420
- package/src/views/EbizSpace.vue +185 -185
- package/src/views/EbizSwiper.vue +157 -157
- package/src/views/EbizTdesignButtonDialogExample.vue +437 -437
- package/src/views/Form.vue +19 -19
- package/src/views/GridDemo.vue +238 -238
- package/src/views/Home.vue +146 -146
- package/src/views/Mindmap.vue +17 -17
- package/src/views/MyComponent.vue +19 -19
- package/src/views/OkrTree.vue +19 -19
- package/src/views/PageHeaderDemo.vue +104 -104
- package/src/views/PaginationDemo.vue +96 -96
- package/src/views/PermissionBoxDemo.vue +85 -85
- package/src/views/PopconfirmDemo.vue +80 -80
- package/src/views/RemoteSelect.vue +350 -350
- package/src/views/StatisticDemo.vue +190 -190
- package/src/views/SwitchDemo.vue +79 -79
- package/src/views/Table.vue +19 -19
- package/src/views/TableDemo.vue +334 -334
- package/src/views/TableSortDemo.vue +143 -143
- package/src/views/TableView.vue +68 -68
- package/src/views/TabsDemo.vue +282 -282
- package/src/views/TagDemo.vue +101 -101
- package/src/views/TdesignAlert.vue +98 -98
- package/src/views/TdesignButton.vue +190 -190
- package/src/views/TdesignCalendar.vue +94 -94
- package/src/views/TdesignCard.vue +296 -296
- package/src/views/TdesignCollapse.vue +293 -293
- package/src/views/TdesignDatePicker.vue +187 -187
- package/src/views/TdesignDescriptions.vue +101 -101
- package/src/views/TdesignForm.vue +248 -248
- package/src/views/TdesignIcon.vue +203 -203
- package/src/views/TdesignImage.vue +215 -215
- package/src/views/TdesignImageViewer.vue +198 -198
- package/src/views/TdesignInput.vue +252 -252
- package/src/views/TdesignSelect.vue +473 -473
- package/src/views/TdesignSwiper.vue +157 -157
- package/src/views/TextareaDemo.vue +93 -93
- package/src/views/TimePickerDemo.vue +146 -146
- package/src/views/TimelineDemo.vue +160 -160
- package/src/views/Title.vue +19 -19
- package/src/views/TreeDemo.vue +254 -254
- package/src/views/TreeMergeTableDemo.vue +239 -239
- package/src/views/TreeSelectorDemo.vue +245 -245
- package/src/views/UploadDemo.vue +121 -121
- package/src/views/VxeTableDemo.vue +279 -279
- package/src/views/WatermarkDemo.vue +85 -85
package/src/utils/upload.ts
CHANGED
@@ -1,126 +1,126 @@
|
|
1
|
-
import {request} from "./request";
|
2
|
-
import COS from "cos-js-sdk-v5";
|
3
|
-
import OSS from "ali-oss";
|
4
|
-
import moment from "moment/moment";
|
5
|
-
|
6
|
-
const defaultOnPercent = () => {
|
7
|
-
}
|
8
|
-
const defaultOnSuccess = () => {
|
9
|
-
}
|
10
|
-
const defaultOnFail = () => {
|
11
|
-
}
|
12
|
-
|
13
|
-
export const upload = (options: any) => {
|
14
|
-
const path: string = options.path;
|
15
|
-
const file: any = options.file;
|
16
|
-
const onPercent: Function = options.onProgress || defaultOnPercent;
|
17
|
-
const onSuccess: Function = options.onSuccess || defaultOnSuccess;
|
18
|
-
const onFail: Function = options.onFail || defaultOnFail;
|
19
|
-
|
20
|
-
let credentials: any, url;
|
21
|
-
request.get({
|
22
|
-
url: "/file/getSecretKey"
|
23
|
-
}).then((res) => {
|
24
|
-
if (res.oss_type === 'ALIYUN') {
|
25
|
-
const client = new OSS({
|
26
|
-
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
|
27
|
-
region: res.region,
|
28
|
-
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
|
29
|
-
accessKeyId: res.accessKeyId,
|
30
|
-
accessKeySecret: res.accessKeySecret,
|
31
|
-
// 从STS服务获取的安全令牌(SecurityToken)。
|
32
|
-
stsToken: res.securityToken,
|
33
|
-
// 刷新临时访问凭证的时间间隔,单位为毫秒。
|
34
|
-
refreshSTSTokenInterval: 300000,
|
35
|
-
// 填写Bucket名称。
|
36
|
-
bucket: res.bucket
|
37
|
-
});
|
38
|
-
const options = {
|
39
|
-
mime: "json",
|
40
|
-
headers: {"Content-Type": "text/plain"},
|
41
|
-
};
|
42
|
-
client.put(handleUploadName("img", path, file.name), file.raw, options).then((uploadRes: any) => {
|
43
|
-
console.log(uploadRes)
|
44
|
-
// 创建一个 URL 对象
|
45
|
-
const urlObj = new URL(uploadRes.url);
|
46
|
-
// 从 URL 对象中获取路径部分
|
47
|
-
const url = res.host + urlObj.pathname.substring(1);
|
48
|
-
|
49
|
-
request.get({
|
50
|
-
url: "/file/getAccessUrl",
|
51
|
-
params: {
|
52
|
-
url,
|
53
|
-
}
|
54
|
-
}).then(res => {
|
55
|
-
console.log(res)
|
56
|
-
onSuccess({url: res})
|
57
|
-
})
|
58
|
-
}).catch((e: any) => {
|
59
|
-
onFail(e)
|
60
|
-
});
|
61
|
-
} else {
|
62
|
-
credentials = res.credentials;
|
63
|
-
let cos = new COS({
|
64
|
-
getAuthorization: function (options, callback) {
|
65
|
-
callback({
|
66
|
-
TmpSecretId: credentials.tmpSecretId,
|
67
|
-
TmpSecretKey: credentials.tmpSecretKey,
|
68
|
-
SecurityToken: credentials.sessionToken,
|
69
|
-
StartTime: credentials.startTime,
|
70
|
-
ExpiredTime: credentials.expiredTime
|
71
|
-
});
|
72
|
-
}
|
73
|
-
});
|
74
|
-
cos.uploadFile(
|
75
|
-
{
|
76
|
-
Bucket: credentials.bucket,
|
77
|
-
Region: credentials.region,
|
78
|
-
Key: handleUploadName("img", path, file.name),
|
79
|
-
Body: file.raw,
|
80
|
-
SliceSize: 1024 * 1024 * 5 /* 触发分块上传的阈值,超过5MB使用分块上传,小于5MB使用简单上传。可自行设置,非必须 */,
|
81
|
-
onProgress: (progressData) => {
|
82
|
-
if (!!onPercent) {
|
83
|
-
onPercent({file, percent: progressData.percent});
|
84
|
-
}
|
85
|
-
},
|
86
|
-
onFileFinish: (err, data, options) => {
|
87
|
-
url = credentials.path + "/" + options.Key;
|
88
|
-
request.get({
|
89
|
-
url: "/file/getAccessUrl",
|
90
|
-
params: {
|
91
|
-
url,
|
92
|
-
}
|
93
|
-
}).then(res => {
|
94
|
-
console.log(res)
|
95
|
-
onPercent({file, percent: 100});
|
96
|
-
onSuccess({url: res})
|
97
|
-
})
|
98
|
-
}
|
99
|
-
},
|
100
|
-
function (err, data) {
|
101
|
-
onFail(err)
|
102
|
-
}
|
103
|
-
);
|
104
|
-
}
|
105
|
-
|
106
|
-
});
|
107
|
-
}
|
108
|
-
|
109
|
-
|
110
|
-
// 规范上传图片格式
|
111
|
-
const handleUploadName = function (type: string, path: string, file_name: string) {
|
112
|
-
// /img/类型(avatar/category/article)/年月日/md5(文件名+随机字符串+毫秒数)+时间.文件后缀
|
113
|
-
let newFileName =
|
114
|
-
type +
|
115
|
-
'/' +
|
116
|
-
path +
|
117
|
-
'/' +
|
118
|
-
moment(new Date()).format('YYMMDD') +
|
119
|
-
'/' +
|
120
|
-
file_name.split(file_name.substring(file_name.lastIndexOf('.')))[0] +
|
121
|
-
Math.random().toString(36).substring(2) +
|
122
|
-
Date.now() +
|
123
|
-
moment(new Date()).format('HHmm') +
|
124
|
-
file_name.substring(file_name.lastIndexOf('.'));
|
125
|
-
return newFileName;
|
126
|
-
};
|
1
|
+
import {request} from "./request";
|
2
|
+
import COS from "cos-js-sdk-v5";
|
3
|
+
import OSS from "ali-oss";
|
4
|
+
import moment from "moment/moment";
|
5
|
+
|
6
|
+
const defaultOnPercent = () => {
|
7
|
+
}
|
8
|
+
const defaultOnSuccess = () => {
|
9
|
+
}
|
10
|
+
const defaultOnFail = () => {
|
11
|
+
}
|
12
|
+
|
13
|
+
export const upload = (options: any) => {
|
14
|
+
const path: string = options.path;
|
15
|
+
const file: any = options.file;
|
16
|
+
const onPercent: Function = options.onProgress || defaultOnPercent;
|
17
|
+
const onSuccess: Function = options.onSuccess || defaultOnSuccess;
|
18
|
+
const onFail: Function = options.onFail || defaultOnFail;
|
19
|
+
|
20
|
+
let credentials: any, url;
|
21
|
+
request.get({
|
22
|
+
url: "/file/getSecretKey"
|
23
|
+
}).then((res) => {
|
24
|
+
if (res.oss_type === 'ALIYUN') {
|
25
|
+
const client = new OSS({
|
26
|
+
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
|
27
|
+
region: res.region,
|
28
|
+
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
|
29
|
+
accessKeyId: res.accessKeyId,
|
30
|
+
accessKeySecret: res.accessKeySecret,
|
31
|
+
// 从STS服务获取的安全令牌(SecurityToken)。
|
32
|
+
stsToken: res.securityToken,
|
33
|
+
// 刷新临时访问凭证的时间间隔,单位为毫秒。
|
34
|
+
refreshSTSTokenInterval: 300000,
|
35
|
+
// 填写Bucket名称。
|
36
|
+
bucket: res.bucket
|
37
|
+
});
|
38
|
+
const options = {
|
39
|
+
mime: "json",
|
40
|
+
headers: {"Content-Type": "text/plain"},
|
41
|
+
};
|
42
|
+
client.put(handleUploadName("img", path, file.name), file.raw, options).then((uploadRes: any) => {
|
43
|
+
console.log(uploadRes)
|
44
|
+
// 创建一个 URL 对象
|
45
|
+
const urlObj = new URL(uploadRes.url);
|
46
|
+
// 从 URL 对象中获取路径部分
|
47
|
+
const url = res.host + urlObj.pathname.substring(1);
|
48
|
+
|
49
|
+
request.get({
|
50
|
+
url: "/file/getAccessUrl",
|
51
|
+
params: {
|
52
|
+
url,
|
53
|
+
}
|
54
|
+
}).then(res => {
|
55
|
+
console.log(res)
|
56
|
+
onSuccess({url: res})
|
57
|
+
})
|
58
|
+
}).catch((e: any) => {
|
59
|
+
onFail(e)
|
60
|
+
});
|
61
|
+
} else {
|
62
|
+
credentials = res.credentials;
|
63
|
+
let cos = new COS({
|
64
|
+
getAuthorization: function (options, callback) {
|
65
|
+
callback({
|
66
|
+
TmpSecretId: credentials.tmpSecretId,
|
67
|
+
TmpSecretKey: credentials.tmpSecretKey,
|
68
|
+
SecurityToken: credentials.sessionToken,
|
69
|
+
StartTime: credentials.startTime,
|
70
|
+
ExpiredTime: credentials.expiredTime
|
71
|
+
});
|
72
|
+
}
|
73
|
+
});
|
74
|
+
cos.uploadFile(
|
75
|
+
{
|
76
|
+
Bucket: credentials.bucket,
|
77
|
+
Region: credentials.region,
|
78
|
+
Key: handleUploadName("img", path, file.name),
|
79
|
+
Body: file.raw,
|
80
|
+
SliceSize: 1024 * 1024 * 5 /* 触发分块上传的阈值,超过5MB使用分块上传,小于5MB使用简单上传。可自行设置,非必须 */,
|
81
|
+
onProgress: (progressData) => {
|
82
|
+
if (!!onPercent) {
|
83
|
+
onPercent({file, percent: progressData.percent});
|
84
|
+
}
|
85
|
+
},
|
86
|
+
onFileFinish: (err, data, options) => {
|
87
|
+
url = credentials.path + "/" + options.Key;
|
88
|
+
request.get({
|
89
|
+
url: "/file/getAccessUrl",
|
90
|
+
params: {
|
91
|
+
url,
|
92
|
+
}
|
93
|
+
}).then(res => {
|
94
|
+
console.log(res)
|
95
|
+
onPercent({file, percent: 100});
|
96
|
+
onSuccess({url: res})
|
97
|
+
})
|
98
|
+
}
|
99
|
+
},
|
100
|
+
function (err, data) {
|
101
|
+
onFail(err)
|
102
|
+
}
|
103
|
+
);
|
104
|
+
}
|
105
|
+
|
106
|
+
});
|
107
|
+
}
|
108
|
+
|
109
|
+
|
110
|
+
// 规范上传图片格式
|
111
|
+
const handleUploadName = function (type: string, path: string, file_name: string) {
|
112
|
+
// /img/类型(avatar/category/article)/年月日/md5(文件名+随机字符串+毫秒数)+时间.文件后缀
|
113
|
+
let newFileName =
|
114
|
+
type +
|
115
|
+
'/' +
|
116
|
+
path +
|
117
|
+
'/' +
|
118
|
+
moment(new Date()).format('YYMMDD') +
|
119
|
+
'/' +
|
120
|
+
file_name.split(file_name.substring(file_name.lastIndexOf('.')))[0] +
|
121
|
+
Math.random().toString(36).substring(2) +
|
122
|
+
Date.now() +
|
123
|
+
moment(new Date()).format('HHmm') +
|
124
|
+
file_name.substring(file_name.lastIndexOf('.'));
|
125
|
+
return newFileName;
|
126
|
+
};
|
@@ -1,155 +1,155 @@
|
|
1
|
-
/**
|
2
|
-
* Copyright (c) 2023 - present TinyEngine Authors.
|
3
|
-
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
4
|
-
*
|
5
|
-
* Use of this source code is governed by an MIT-style license.
|
6
|
-
*
|
7
|
-
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
8
|
-
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
9
|
-
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
10
|
-
*
|
11
|
-
*/
|
12
|
-
|
13
|
-
import { parse as parseSFC, compileScript, compileStyle, compileTemplate } from '@vue/compiler-sfc'
|
14
|
-
import { generateCodeFrame } from '@vue/shared'
|
15
|
-
import { randomString } from '.'
|
16
|
-
|
17
|
-
/**
|
18
|
-
* 使用 vue-eslint-parser,校验 vue sfc 是否有效
|
19
|
-
* @param {string} code 源码
|
20
|
-
* @returns {Error[]} 校验出的报错信息
|
21
|
-
*/
|
22
|
-
export function validateByParse(code) {
|
23
|
-
const { parse: parseVue } = require('vue-eslint-parser')
|
24
|
-
let errors = []
|
25
|
-
|
26
|
-
try {
|
27
|
-
const { templateBody, errors: parseErrors } = parseVue(code, {
|
28
|
-
ecmaVersion: 'latest',
|
29
|
-
sourceType: 'module',
|
30
|
-
ecmaFeatures: {
|
31
|
-
jsx: true
|
32
|
-
}
|
33
|
-
})
|
34
|
-
errors = templateBody?.errors || parseErrors || []
|
35
|
-
} catch (error) {
|
36
|
-
// 此处可捕获到 SyntaxError,如:嵌套双引号未转义的问题
|
37
|
-
errors.push(unify(error))
|
38
|
-
}
|
39
|
-
|
40
|
-
return errors.map(({ message, lineNumber: line, column }) => {
|
41
|
-
if (line && column) {
|
42
|
-
return locateErrorMessage(code, { message, loc: { start: { line, column } } })
|
43
|
-
}
|
44
|
-
|
45
|
-
return { message }
|
46
|
-
})
|
47
|
-
}
|
48
|
-
|
49
|
-
/**
|
50
|
-
* 使用 @vue/compiler-sfc, 校验 vue sfc 是否有效
|
51
|
-
* @param {string} filename 文件名称
|
52
|
-
* @param {string} code 源码
|
53
|
-
* @returns {Error[]} 校验出的错误信息
|
54
|
-
*/
|
55
|
-
export function validateByCompile(filename, code) {
|
56
|
-
// validate via parse
|
57
|
-
const { errors, descriptor } = parseSFC(code, {
|
58
|
-
filename,
|
59
|
-
sourceMap: false
|
60
|
-
})
|
61
|
-
|
62
|
-
if (errors.length) {
|
63
|
-
return errors.map((error) => locateErrorMessage(code, error))
|
64
|
-
}
|
65
|
-
|
66
|
-
const id = randomString()
|
67
|
-
|
68
|
-
// validate via compile script
|
69
|
-
let bindingMetadata
|
70
|
-
try {
|
71
|
-
const scriptResult = compileScript(descriptor, { id })
|
72
|
-
bindingMetadata = scriptResult.bindings
|
73
|
-
} catch (error) {
|
74
|
-
// error 可能的类型 string | ParseError (@babel/parser) | CompilerError (compileScript 使用 inlineTemplate 模式时)
|
75
|
-
const scriptError = unify(error)
|
76
|
-
|
77
|
-
// 如果是 ParseError 类型,转换为 locateErrorMessage 可接受的 CompilerError 类型传入
|
78
|
-
if (!scriptError?.loc?.start && scriptError?.loc?.line) {
|
79
|
-
// 只截取原 message 的第一行,后面行数可能已经包含错误的定位信息,避免拼接重复
|
80
|
-
const message = scriptError.message.match(/.*/)[0]
|
81
|
-
const { line, column } = scriptError.loc
|
82
|
-
|
83
|
-
// compileScript 内部抛错误时,可能已定位编译报错信息,但报错所在的行可能有大量字符,此处精简一下
|
84
|
-
return [locateErrorMessage(code, { message, loc: { start: { line, column } } })]
|
85
|
-
}
|
86
|
-
|
87
|
-
return [{ message: scriptError.message }]
|
88
|
-
}
|
89
|
-
|
90
|
-
// validate via compile template
|
91
|
-
const { styles, template, slotted } = descriptor
|
92
|
-
const scoped = styles.some((s) => s.scoped)
|
93
|
-
|
94
|
-
const templateResult = compileTemplate({
|
95
|
-
source: template.content,
|
96
|
-
filename,
|
97
|
-
id,
|
98
|
-
scoped,
|
99
|
-
slotted,
|
100
|
-
compilerOptions: { bindingMetadata }
|
101
|
-
})
|
102
|
-
|
103
|
-
if (templateResult.errors.length) {
|
104
|
-
return templateResult.errors.map(unify).map((error) => locateErrorMessage(code, error))
|
105
|
-
}
|
106
|
-
|
107
|
-
// validate via compile style
|
108
|
-
// 目前暂时没有预处理器,如:less
|
109
|
-
const stylesResult = styles.map(({ content, module }) =>
|
110
|
-
compileStyle({ source: content, filename, id, scoped, modules: Boolean(module) })
|
111
|
-
)
|
112
|
-
const errorsInStyles = stylesResult
|
113
|
-
.filter(({ errors }) => errors.length)
|
114
|
-
.map(({ errors }) => errors)
|
115
|
-
.flat()
|
116
|
-
|
117
|
-
return errorsInStyles
|
118
|
-
}
|
119
|
-
|
120
|
-
/**
|
121
|
-
* 统一报错的格式
|
122
|
-
* @param {(string | Error)} error 原始错误信息
|
123
|
-
* @returns {Error} 统一格式后的错误信息
|
124
|
-
*/
|
125
|
-
function unify(error) {
|
126
|
-
if (typeof error === 'string') {
|
127
|
-
return { message: error }
|
128
|
-
}
|
129
|
-
|
130
|
-
return error
|
131
|
-
}
|
132
|
-
|
133
|
-
/**
|
134
|
-
* 定位报错信息,如果包含报错位置,则追加到 message 中输出
|
135
|
-
* @param {string} originalSource 原始代码
|
136
|
-
* @param {(Error | CompilerError)} error 错误信息
|
137
|
-
* @returns {{message: string}} 可能包含报错位置的错误信息
|
138
|
-
*/
|
139
|
-
function locateErrorMessage(originalSource, error) {
|
140
|
-
let { loc, message } = error
|
141
|
-
|
142
|
-
if (loc?.start) {
|
143
|
-
const { line, column } = loc.start
|
144
|
-
const errorLineCode = originalSource.split(/\r?\n/)[line - 1]
|
145
|
-
|
146
|
-
// 源码字符串未经格式化,报错所在的行可能有大量字符,截取报错位置附近范围的错误信息,比如:前后 50 字符内
|
147
|
-
const SCOPE = 50
|
148
|
-
const scopeStartIndex = Math.max(0, column - SCOPE)
|
149
|
-
const scopeCode = errorLineCode.slice(scopeStartIndex, column + SCOPE)
|
150
|
-
|
151
|
-
message = `${message} \n ${generateCodeFrame(scopeCode, column - scopeStartIndex)}`
|
152
|
-
}
|
153
|
-
|
154
|
-
return { message }
|
155
|
-
}
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2023 - present TinyEngine Authors.
|
3
|
+
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
4
|
+
*
|
5
|
+
* Use of this source code is governed by an MIT-style license.
|
6
|
+
*
|
7
|
+
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
8
|
+
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
9
|
+
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
10
|
+
*
|
11
|
+
*/
|
12
|
+
|
13
|
+
import { parse as parseSFC, compileScript, compileStyle, compileTemplate } from '@vue/compiler-sfc'
|
14
|
+
import { generateCodeFrame } from '@vue/shared'
|
15
|
+
import { randomString } from '.'
|
16
|
+
|
17
|
+
/**
|
18
|
+
* 使用 vue-eslint-parser,校验 vue sfc 是否有效
|
19
|
+
* @param {string} code 源码
|
20
|
+
* @returns {Error[]} 校验出的报错信息
|
21
|
+
*/
|
22
|
+
export function validateByParse(code) {
|
23
|
+
const { parse: parseVue } = require('vue-eslint-parser')
|
24
|
+
let errors = []
|
25
|
+
|
26
|
+
try {
|
27
|
+
const { templateBody, errors: parseErrors } = parseVue(code, {
|
28
|
+
ecmaVersion: 'latest',
|
29
|
+
sourceType: 'module',
|
30
|
+
ecmaFeatures: {
|
31
|
+
jsx: true
|
32
|
+
}
|
33
|
+
})
|
34
|
+
errors = templateBody?.errors || parseErrors || []
|
35
|
+
} catch (error) {
|
36
|
+
// 此处可捕获到 SyntaxError,如:嵌套双引号未转义的问题
|
37
|
+
errors.push(unify(error))
|
38
|
+
}
|
39
|
+
|
40
|
+
return errors.map(({ message, lineNumber: line, column }) => {
|
41
|
+
if (line && column) {
|
42
|
+
return locateErrorMessage(code, { message, loc: { start: { line, column } } })
|
43
|
+
}
|
44
|
+
|
45
|
+
return { message }
|
46
|
+
})
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* 使用 @vue/compiler-sfc, 校验 vue sfc 是否有效
|
51
|
+
* @param {string} filename 文件名称
|
52
|
+
* @param {string} code 源码
|
53
|
+
* @returns {Error[]} 校验出的错误信息
|
54
|
+
*/
|
55
|
+
export function validateByCompile(filename, code) {
|
56
|
+
// validate via parse
|
57
|
+
const { errors, descriptor } = parseSFC(code, {
|
58
|
+
filename,
|
59
|
+
sourceMap: false
|
60
|
+
})
|
61
|
+
|
62
|
+
if (errors.length) {
|
63
|
+
return errors.map((error) => locateErrorMessage(code, error))
|
64
|
+
}
|
65
|
+
|
66
|
+
const id = randomString()
|
67
|
+
|
68
|
+
// validate via compile script
|
69
|
+
let bindingMetadata
|
70
|
+
try {
|
71
|
+
const scriptResult = compileScript(descriptor, { id })
|
72
|
+
bindingMetadata = scriptResult.bindings
|
73
|
+
} catch (error) {
|
74
|
+
// error 可能的类型 string | ParseError (@babel/parser) | CompilerError (compileScript 使用 inlineTemplate 模式时)
|
75
|
+
const scriptError = unify(error)
|
76
|
+
|
77
|
+
// 如果是 ParseError 类型,转换为 locateErrorMessage 可接受的 CompilerError 类型传入
|
78
|
+
if (!scriptError?.loc?.start && scriptError?.loc?.line) {
|
79
|
+
// 只截取原 message 的第一行,后面行数可能已经包含错误的定位信息,避免拼接重复
|
80
|
+
const message = scriptError.message.match(/.*/)[0]
|
81
|
+
const { line, column } = scriptError.loc
|
82
|
+
|
83
|
+
// compileScript 内部抛错误时,可能已定位编译报错信息,但报错所在的行可能有大量字符,此处精简一下
|
84
|
+
return [locateErrorMessage(code, { message, loc: { start: { line, column } } })]
|
85
|
+
}
|
86
|
+
|
87
|
+
return [{ message: scriptError.message }]
|
88
|
+
}
|
89
|
+
|
90
|
+
// validate via compile template
|
91
|
+
const { styles, template, slotted } = descriptor
|
92
|
+
const scoped = styles.some((s) => s.scoped)
|
93
|
+
|
94
|
+
const templateResult = compileTemplate({
|
95
|
+
source: template.content,
|
96
|
+
filename,
|
97
|
+
id,
|
98
|
+
scoped,
|
99
|
+
slotted,
|
100
|
+
compilerOptions: { bindingMetadata }
|
101
|
+
})
|
102
|
+
|
103
|
+
if (templateResult.errors.length) {
|
104
|
+
return templateResult.errors.map(unify).map((error) => locateErrorMessage(code, error))
|
105
|
+
}
|
106
|
+
|
107
|
+
// validate via compile style
|
108
|
+
// 目前暂时没有预处理器,如:less
|
109
|
+
const stylesResult = styles.map(({ content, module }) =>
|
110
|
+
compileStyle({ source: content, filename, id, scoped, modules: Boolean(module) })
|
111
|
+
)
|
112
|
+
const errorsInStyles = stylesResult
|
113
|
+
.filter(({ errors }) => errors.length)
|
114
|
+
.map(({ errors }) => errors)
|
115
|
+
.flat()
|
116
|
+
|
117
|
+
return errorsInStyles
|
118
|
+
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* 统一报错的格式
|
122
|
+
* @param {(string | Error)} error 原始错误信息
|
123
|
+
* @returns {Error} 统一格式后的错误信息
|
124
|
+
*/
|
125
|
+
function unify(error) {
|
126
|
+
if (typeof error === 'string') {
|
127
|
+
return { message: error }
|
128
|
+
}
|
129
|
+
|
130
|
+
return error
|
131
|
+
}
|
132
|
+
|
133
|
+
/**
|
134
|
+
* 定位报错信息,如果包含报错位置,则追加到 message 中输出
|
135
|
+
* @param {string} originalSource 原始代码
|
136
|
+
* @param {(Error | CompilerError)} error 错误信息
|
137
|
+
* @returns {{message: string}} 可能包含报错位置的错误信息
|
138
|
+
*/
|
139
|
+
function locateErrorMessage(originalSource, error) {
|
140
|
+
let { loc, message } = error
|
141
|
+
|
142
|
+
if (loc?.start) {
|
143
|
+
const { line, column } = loc.start
|
144
|
+
const errorLineCode = originalSource.split(/\r?\n/)[line - 1]
|
145
|
+
|
146
|
+
// 源码字符串未经格式化,报错所在的行可能有大量字符,截取报错位置附近范围的错误信息,比如:前后 50 字符内
|
147
|
+
const SCOPE = 50
|
148
|
+
const scopeStartIndex = Math.max(0, column - SCOPE)
|
149
|
+
const scopeCode = errorLineCode.slice(scopeStartIndex, column + SCOPE)
|
150
|
+
|
151
|
+
message = `${message} \n ${generateCodeFrame(scopeCode, column - scopeStartIndex)}`
|
152
|
+
}
|
153
|
+
|
154
|
+
return { message }
|
155
|
+
}
|
package/src/views/Button.vue
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
<template>
|
2
|
-
<div>
|
3
|
-
<ebiz-route-breadcrumb />
|
4
|
-
<ebiz-button :text="测试" :apiConfig="{ apiId: 802, apiType: 5 }" @prepare="onPrepare" />
|
5
|
-
</div>
|
6
|
-
</template>
|
7
|
-
|
8
|
-
<script>
|
9
|
-
import { EbizButton } from '@/index.js'
|
10
|
-
|
11
|
-
export default {
|
12
|
-
name: 'ButtonDemo',
|
13
|
-
components: {
|
14
|
-
EbizButton
|
15
|
-
},
|
16
|
-
methods: {
|
17
|
-
onPrepare() {
|
18
|
-
|
19
|
-
}
|
20
|
-
}
|
21
|
-
}
|
22
|
-
</script>
|
23
|
-
|
1
|
+
<template>
|
2
|
+
<div>
|
3
|
+
<ebiz-route-breadcrumb />
|
4
|
+
<ebiz-button :text="测试" :apiConfig="{ apiId: 802, apiType: 5 }" @prepare="onPrepare" />
|
5
|
+
</div>
|
6
|
+
</template>
|
7
|
+
|
8
|
+
<script>
|
9
|
+
import { EbizButton } from '@/index.js'
|
10
|
+
|
11
|
+
export default {
|
12
|
+
name: 'ButtonDemo',
|
13
|
+
components: {
|
14
|
+
EbizButton
|
15
|
+
},
|
16
|
+
methods: {
|
17
|
+
onPrepare() {
|
18
|
+
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
</script>
|
23
|
+
|
24
24
|
<style scoped></style>
|