cloud-web-corejs 1.0.127 → 1.0.128
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/package.json
CHANGED
@@ -1,41 +1,57 @@
|
|
1
1
|
<template>
|
2
|
-
<form-item-wrapper
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
<form-item-wrapper
|
3
|
+
:designer="designer"
|
4
|
+
:field="field"
|
5
|
+
:rules="rules"
|
6
|
+
:design-state="designState"
|
7
|
+
:parent-widget="parentWidget"
|
8
|
+
:parent-list="parentList"
|
9
|
+
:index-of-parent-list="indexOfParentList"
|
10
|
+
:sub-form-row-index="subFormRowIndex"
|
11
|
+
:sub-form-col-index="subFormColIndex"
|
12
|
+
:sub-form-row-id="subFormRowId"
|
13
|
+
>
|
6
14
|
<div id="uploadImage" class="upload-img" v-if="designState">
|
7
|
-
<div
|
8
|
-
|
15
|
+
<div
|
16
|
+
class="el-upload el-upload--picture"
|
17
|
+
style="vertical-align: middle; display: inline-block; float: left"
|
18
|
+
>
|
19
|
+
<button type="button" class="avatar-uploader">
|
9
20
|
<i class="el-icon-plus avatar-uploader-icon"></i>
|
10
21
|
</button>
|
11
22
|
</div>
|
12
23
|
</div>
|
13
|
-
<baseUpload
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
<baseUpload
|
25
|
+
accept="file"
|
26
|
+
:file.sync="fieldModel"
|
27
|
+
:hidePasteArea.sync="isH5"
|
28
|
+
:uploadDialogCustomClass="isH5 ? 'dialog-upload-h5' : null"
|
29
|
+
:pickPrivateProfile="false"
|
30
|
+
:multi="field.options.limit !== 1"
|
31
|
+
:limit="field.options.limit"
|
32
|
+
resultType="Array"
|
33
|
+
:edit="!field.options.disabled"
|
34
|
+
@callback="submitFile"
|
35
|
+
:hideInfo="field.options.hideFileInfo"
|
36
|
+
:hideName="field.options.hideFileName"
|
37
|
+
:showSize="!!field.options.showFileSize"
|
38
|
+
:createBy="!!field.options.showFileCreateBy"
|
39
|
+
:createDate="!!field.options.showFileCreateDate"
|
40
|
+
:widgetSize="field.options.fileShowImageSize"
|
41
|
+
v-else
|
42
|
+
></baseUpload>
|
27
43
|
</form-item-wrapper>
|
28
44
|
</template>
|
29
45
|
|
30
46
|
<script>
|
31
|
-
import FormItemWrapper from
|
32
|
-
import emitter from
|
47
|
+
import FormItemWrapper from "./form-item-wrapper";
|
48
|
+
import emitter from "../../../../../components/xform/utils/emitter";
|
33
49
|
import i18n from "../../../../../components/xform/utils/i18n";
|
34
50
|
import fieldMixin from "../../../../../components/xform/form-designer/form-widget/field-widget/fieldMixin";
|
35
51
|
|
36
52
|
export default {
|
37
53
|
name: "vabUpload-widget",
|
38
|
-
componentName:
|
54
|
+
componentName: "FieldWidget", //必须固定为FieldWidget,用于接收父级组件的broadcast事件
|
39
55
|
mixins: [emitter, fieldMixin, i18n],
|
40
56
|
props: {
|
41
57
|
field: Object,
|
@@ -46,44 +62,44 @@ export default {
|
|
46
62
|
|
47
63
|
designState: {
|
48
64
|
type: Boolean,
|
49
|
-
default: false
|
65
|
+
default: false,
|
50
66
|
},
|
51
67
|
|
52
|
-
subFormRowIndex: {
|
53
|
-
type: Number,
|
54
|
-
default: -1
|
68
|
+
subFormRowIndex: {
|
69
|
+
/* 子表单组件行索引,从0开始计数 */ type: Number,
|
70
|
+
default: -1,
|
55
71
|
},
|
56
|
-
subFormColIndex: {
|
57
|
-
type: Number,
|
58
|
-
default: -1
|
72
|
+
subFormColIndex: {
|
73
|
+
/* 子表单组件列索引,从0开始计数 */ type: Number,
|
74
|
+
default: -1,
|
75
|
+
},
|
76
|
+
subFormRowId: {
|
77
|
+
/* 子表单组件行Id,唯一id且不可变 */ type: String,
|
78
|
+
default: "",
|
59
79
|
},
|
60
|
-
subFormRowId: { /* 子表单组件行Id,唯一id且不可变 */
|
61
|
-
type: String,
|
62
|
-
default: ''
|
63
|
-
}
|
64
80
|
},
|
65
81
|
components: {
|
66
82
|
FormItemWrapper,
|
67
83
|
},
|
68
|
-
inject: [
|
84
|
+
inject: ["refList", "globalOptionData", "globalModel", "getFormConfig"],
|
69
85
|
data() {
|
70
86
|
return {
|
71
87
|
oldFieldValue: [], //field组件change之前的值
|
72
88
|
fieldModel: [],
|
73
89
|
rules: [],
|
74
|
-
isH5: false
|
75
|
-
}
|
90
|
+
isH5: false,
|
91
|
+
};
|
76
92
|
},
|
77
93
|
watch: {
|
78
94
|
fieldModel(val) {
|
79
95
|
this.handleChangeEvent(val);
|
80
|
-
}
|
96
|
+
},
|
81
97
|
},
|
82
98
|
computed: {
|
83
99
|
formDataId() {
|
84
100
|
let formRef = this.getFormRef();
|
85
101
|
return formRef.dataId;
|
86
|
-
}
|
102
|
+
},
|
87
103
|
},
|
88
104
|
beforeCreate() {
|
89
105
|
/* 这里不能访问方法和属性!! */
|
@@ -93,26 +109,26 @@ export default {
|
|
93
109
|
/* 注意:子组件mounted在父组件created之后、父组件mounted之前触发,故子组件mounted需要用到的prop
|
94
110
|
需要在父组件created中初始化!! */
|
95
111
|
|
96
|
-
this.isH5 = this.getFormConfig().layoutType ===
|
112
|
+
this.isH5 = this.getFormConfig().layoutType === "H5";
|
97
113
|
|
98
|
-
this.initFieldModel()
|
99
|
-
this.registerToRefList()
|
100
|
-
this.initEventHandler()
|
101
|
-
this.buildFieldRules()
|
114
|
+
this.initFieldModel();
|
115
|
+
this.registerToRefList();
|
116
|
+
this.initEventHandler();
|
117
|
+
this.buildFieldRules();
|
102
118
|
|
103
|
-
this.handleOnCreated()
|
119
|
+
this.handleOnCreated();
|
104
120
|
},
|
105
121
|
|
106
122
|
mounted() {
|
107
|
-
this.handleOnMounted()
|
123
|
+
this.handleOnMounted();
|
108
124
|
},
|
109
125
|
|
110
126
|
beforeDestroy() {
|
111
|
-
this.unregisterFromRefList()
|
127
|
+
this.unregisterFromRefList();
|
112
128
|
},
|
113
129
|
methods: {
|
114
130
|
setValue(val) {
|
115
|
-
let data = val || []
|
131
|
+
let data = val || [];
|
116
132
|
this.fieldModel = data;
|
117
133
|
this.getFormRef().formDataModel[this.fieldKeyName] = data;
|
118
134
|
},
|
@@ -122,10 +138,12 @@ export default {
|
|
122
138
|
let reportTemplate = this.getFormRef().reportTemplate;
|
123
139
|
let formCode = reportTemplate.formCode;
|
124
140
|
let formScriptEnabled = this.field.options.formScriptEnabled || false;
|
125
|
-
let scriptCode = this.field.options.formScriptCode || "getList"
|
141
|
+
let scriptCode = this.field.options.formScriptCode || "getList";
|
126
142
|
if (!scriptCode) return;
|
127
143
|
if (dataId) {
|
128
|
-
let accessParam = this.handleCustomEvent(
|
144
|
+
let accessParam = this.handleCustomEvent(
|
145
|
+
this.field.options.formScriptParam
|
146
|
+
);
|
129
147
|
return this.formHttp({
|
130
148
|
// url: "/" + reportTemplate.serviceName + "/form_ins/getList",
|
131
149
|
scriptCode: scriptCode,
|
@@ -135,22 +153,123 @@ export default {
|
|
135
153
|
taBm: this.fieldKeyName,
|
136
154
|
data: {
|
137
155
|
...accessParam,
|
138
|
-
id: dataId
|
139
|
-
}
|
156
|
+
id: dataId,
|
157
|
+
},
|
140
158
|
},
|
141
|
-
callback: res => {
|
159
|
+
callback: (res) => {
|
142
160
|
let rows = res.objx || [];
|
143
|
-
this.setValue(rows)
|
144
|
-
this.handleCustomEvent(
|
145
|
-
|
161
|
+
this.setValue(rows);
|
162
|
+
this.handleCustomEvent(
|
163
|
+
this.field.options.formScriptSuccess,
|
164
|
+
["res"],
|
165
|
+
[res]
|
166
|
+
);
|
167
|
+
},
|
146
168
|
});
|
147
169
|
}
|
148
170
|
},
|
149
171
|
submitFile(rows, fileInfos) {
|
150
172
|
// this.handlLineCode(fileInfos);
|
151
|
-
let eventParamNames = [
|
173
|
+
let eventParamNames = ["attachments", "fileInfos"];
|
152
174
|
let eventParamValues = [rows, fileInfos];
|
153
|
-
this.handleCustomEvent(
|
175
|
+
this.handleCustomEvent(
|
176
|
+
this.field.options.onAfterConfirmFile,
|
177
|
+
eventParamNames,
|
178
|
+
eventParamValues
|
179
|
+
);
|
180
|
+
},
|
181
|
+
setValueByUrl(fileUrl) {
|
182
|
+
let value = [];
|
183
|
+
if (fileUrl) {
|
184
|
+
let row = this.parseFileUrl(fileUrl);
|
185
|
+
if (row) {
|
186
|
+
value.push(row);
|
187
|
+
}
|
188
|
+
}
|
189
|
+
this.setValue(value);
|
190
|
+
},
|
191
|
+
parseFileUrl(fileUrl) {
|
192
|
+
if (!fileUrl) return null;
|
193
|
+
let result = null;
|
194
|
+
|
195
|
+
// 输入校验
|
196
|
+
if (typeof fileUrl !== "string") {
|
197
|
+
throw new TypeError("输入必须是字符串格式");
|
198
|
+
}
|
199
|
+
if (!fileUrl.trim()) {
|
200
|
+
throw new Error("URL不能为空");
|
201
|
+
}
|
202
|
+
|
203
|
+
// 基本URL格式验证
|
204
|
+
const urlRegex =
|
205
|
+
/^(https?:\/\/)?([\w.-]+)(:\d+)?(\/[^?#]*)?(\?[^#]*)?(#.*)?$/i;
|
206
|
+
if (!urlRegex.test(fileUrl)) {
|
207
|
+
throw new Error("无效的URL格式");
|
208
|
+
}
|
209
|
+
|
210
|
+
// 提取域名部分
|
211
|
+
const domainRegex = /^(https?:\/\/[^\/]+)/i;
|
212
|
+
const domainMatch = fileUrl.match(domainRegex);
|
213
|
+
if (!domainMatch) {
|
214
|
+
throw new Error("URL缺少协议或域名部分");
|
215
|
+
}
|
216
|
+
const domain = domainMatch[0];
|
217
|
+
|
218
|
+
// 提取完整路径
|
219
|
+
const url = fileUrl.substring(domain.length);
|
220
|
+
if (!url || url === "/") {
|
221
|
+
throw new Error("URL缺少文件路径部分");
|
222
|
+
}
|
223
|
+
|
224
|
+
// 提取带扩展名的文件名
|
225
|
+
const filenameRegex = /[^\/]+$/;
|
226
|
+
const filenameMatch = url.match(filenameRegex);
|
227
|
+
if (!filenameMatch) {
|
228
|
+
throw new Error("无法从路径中提取文件名");
|
229
|
+
}
|
230
|
+
const fullFilename = filenameMatch[0];
|
231
|
+
|
232
|
+
// 验证文件名格式(至少1字符+扩展名)
|
233
|
+
const nameFormat = /^.+\..+$/;
|
234
|
+
if (!nameFormat.test(fullFilename)) {
|
235
|
+
throw new Error(`无效的文件名格式: ${fullFilename}`);
|
236
|
+
}
|
237
|
+
|
238
|
+
// 修复点:更可靠的文件名和扩展名分离
|
239
|
+
const lastDotIndex = fullFilename.lastIndexOf(".");
|
240
|
+
const filenameBase = fullFilename.substring(0, lastDotIndex); // 点之前部分
|
241
|
+
const extension = fullFilename.substring(lastDotIndex + 1).toLowerCase(); // 点之后部分
|
242
|
+
|
243
|
+
// 扩展名验证
|
244
|
+
/* const validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'];
|
245
|
+
if (!validExtensions.includes(extension)) {
|
246
|
+
throw new Error(`不支持的扩展名类型: ${extension}`);
|
247
|
+
} */
|
248
|
+
|
249
|
+
let thumbnail = null,
|
250
|
+
large = null,
|
251
|
+
medium = null,
|
252
|
+
source = null;
|
253
|
+
if (this.$commonFileUtil.isPicture(extension)) {
|
254
|
+
thumbnail = url;
|
255
|
+
large = url;
|
256
|
+
medium = url;
|
257
|
+
source = url;
|
258
|
+
}
|
259
|
+
|
260
|
+
result = {
|
261
|
+
extension,
|
262
|
+
domain,
|
263
|
+
url,
|
264
|
+
thumbnail,
|
265
|
+
large,
|
266
|
+
medium,
|
267
|
+
source,
|
268
|
+
name: fullFilename,
|
269
|
+
};
|
270
|
+
|
271
|
+
// 返回结构化对象
|
272
|
+
return result;
|
154
273
|
},
|
155
274
|
/*handlLineCode(fileInfos) {
|
156
275
|
let allPromise = [];
|
@@ -224,8 +343,8 @@ export default {
|
|
224
343
|
this.error = errorMessage;
|
225
344
|
this.loading = false;
|
226
345
|
},*/
|
227
|
-
}
|
228
|
-
}
|
346
|
+
},
|
347
|
+
};
|
229
348
|
</script>
|
230
349
|
|
231
350
|
<style lang="scss" scoped>
|
@@ -236,17 +355,19 @@ export default {
|
|
236
355
|
}
|
237
356
|
|
238
357
|
.hideUploadDiv {
|
239
|
-
::v-deep div.el-upload--picture-card {
|
358
|
+
::v-deep div.el-upload--picture-card {
|
359
|
+
/* 隐藏最后的图片上传按钮 */
|
240
360
|
display: none;
|
241
361
|
}
|
242
362
|
|
243
|
-
::v-deep div.el-upload--text {
|
363
|
+
::v-deep div.el-upload--text {
|
364
|
+
/* 隐藏最后的文件上传按钮 */
|
244
365
|
display: none;
|
245
366
|
}
|
246
367
|
|
247
|
-
::v-deep div.el-upload__tip {
|
368
|
+
::v-deep div.el-upload__tip {
|
369
|
+
/* 隐藏最后的文件上传按钮提示 */
|
248
370
|
display: none;
|
249
371
|
}
|
250
372
|
}
|
251
|
-
|
252
373
|
</style>
|