vue2-client 1.8.41 → 1.8.43
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 +1 -1
- package/src/base-client/components/common/XAddNativeFormOA/XAddNativeFormOA.vue +288 -0
- package/src/base-client/components/common/XAddNativeFormOA/index.js +3 -0
- package/src/base-client/components/common/XAddNativeFormOA/index.md +146 -0
- package/src/services/api/common.js +2 -0
- package/src/utils/waterMark.js +31 -31
package/package.json
CHANGED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="table-page-search-wrapper">
|
|
3
|
+
<a-form-model
|
|
4
|
+
v-if="loaded"
|
|
5
|
+
ref="selectForm"
|
|
6
|
+
:zIndex="1001"
|
|
7
|
+
:model="form"
|
|
8
|
+
:rules="rules">
|
|
9
|
+
<a-row :gutter="16">
|
|
10
|
+
<x-form-item
|
|
11
|
+
v-for="(item, index) in realJsonData"
|
|
12
|
+
:key="index"
|
|
13
|
+
:attr="item"
|
|
14
|
+
:disabled="itemDisabled(item)"
|
|
15
|
+
:files="files"
|
|
16
|
+
:form="form"
|
|
17
|
+
:images="images"
|
|
18
|
+
:service-name="serviceName"
|
|
19
|
+
:xl="12"
|
|
20
|
+
:xxl="8"
|
|
21
|
+
mode="新增/修改"
|
|
22
|
+
/>
|
|
23
|
+
</a-row>
|
|
24
|
+
</a-form-model>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
<script>
|
|
28
|
+
import XFormItem from '@vue2-client/base-client/components/common/XForm/XFormItem'
|
|
29
|
+
import { formatDate } from '@vue2-client/utils/util'
|
|
30
|
+
import { mapState } from 'vuex'
|
|
31
|
+
import { post } from '@vue2-client/services/api'
|
|
32
|
+
|
|
33
|
+
export default {
|
|
34
|
+
name: 'XAddNativeFormOA',
|
|
35
|
+
components: {
|
|
36
|
+
XFormItem
|
|
37
|
+
},
|
|
38
|
+
data () {
|
|
39
|
+
return {
|
|
40
|
+
// 内容加载是否完成
|
|
41
|
+
loaded: false,
|
|
42
|
+
// 表单Model
|
|
43
|
+
form: {},
|
|
44
|
+
// 修改有文件得表单时使用
|
|
45
|
+
files: [],
|
|
46
|
+
images: [],
|
|
47
|
+
// 校验
|
|
48
|
+
rules: {}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
computed: {
|
|
52
|
+
// 过滤出用于新增/修改场景的表单项
|
|
53
|
+
realJsonData: function () {
|
|
54
|
+
return this.jsonData.filter(function (item) {
|
|
55
|
+
return item.addOrEdit && item.addOrEdit !== 'no' && item.addOrEdit !== 'silenceAdd' && item.addOrEdit !== 'version'
|
|
56
|
+
})
|
|
57
|
+
},
|
|
58
|
+
// 过滤出用于静默新增场景的表单项
|
|
59
|
+
silenceAddJsonData: function () {
|
|
60
|
+
return this.jsonData.filter(function (item) {
|
|
61
|
+
return item.addOrEdit === 'silenceAdd'
|
|
62
|
+
})
|
|
63
|
+
},
|
|
64
|
+
// 过滤出版本号表单项
|
|
65
|
+
versionJsonData: function () {
|
|
66
|
+
return this.jsonData.filter(function (item) {
|
|
67
|
+
return item.addOrEdit === 'version'
|
|
68
|
+
})
|
|
69
|
+
},
|
|
70
|
+
...mapState('account', { currUser: 'user' })
|
|
71
|
+
},
|
|
72
|
+
props: {
|
|
73
|
+
jsonData: {
|
|
74
|
+
type: Array,
|
|
75
|
+
default: () => {
|
|
76
|
+
return []
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
serviceName: {
|
|
80
|
+
type: String,
|
|
81
|
+
default: 'af-system'
|
|
82
|
+
},
|
|
83
|
+
// 业务类型
|
|
84
|
+
businessType: {
|
|
85
|
+
type: String,
|
|
86
|
+
default: ''
|
|
87
|
+
},
|
|
88
|
+
// 修改操作前查询出的业务数据
|
|
89
|
+
modifyModelData: {
|
|
90
|
+
type: Object,
|
|
91
|
+
default: () => {
|
|
92
|
+
return {}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
// 新增或修改业务是否执行中
|
|
96
|
+
loading: {
|
|
97
|
+
type: Boolean,
|
|
98
|
+
default: () => {
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
// 固定新增表单
|
|
103
|
+
fixedAddForm: {
|
|
104
|
+
type: Object,
|
|
105
|
+
default: () => {
|
|
106
|
+
return {}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
nowStepContent: {
|
|
110
|
+
type: Object,
|
|
111
|
+
default: () => {
|
|
112
|
+
return {}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
watch: {
|
|
117
|
+
visible (rel) {
|
|
118
|
+
if (rel) {
|
|
119
|
+
this.formItemLoad()
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
mounted () {
|
|
124
|
+
this.formItemLoad()
|
|
125
|
+
if (this.nowStepContent) {
|
|
126
|
+
this.form = this.nowStepContent
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
methods: {
|
|
130
|
+
formItemLoad () {
|
|
131
|
+
const formData = Object.assign({}, this.fixedAddForm)
|
|
132
|
+
for (let i = 0; i < this.realJsonData.length; i++) {
|
|
133
|
+
const item = this.realJsonData[i]
|
|
134
|
+
formData[item.model] = undefined
|
|
135
|
+
// 处理表单校验情况
|
|
136
|
+
if (item.rule) {
|
|
137
|
+
this.rules[item.model] = []
|
|
138
|
+
const required = item.rule.required ? item.rule.required === true || item.rule.required === 'true' : false
|
|
139
|
+
let trigger
|
|
140
|
+
let message
|
|
141
|
+
if (required) {
|
|
142
|
+
switch (item.type) {
|
|
143
|
+
case 'select':
|
|
144
|
+
message = '请选择' + item.name
|
|
145
|
+
trigger = 'change'
|
|
146
|
+
break
|
|
147
|
+
default:
|
|
148
|
+
message = '请输入' + item.name
|
|
149
|
+
trigger = 'blur'
|
|
150
|
+
}
|
|
151
|
+
this.rules[item.model].push({
|
|
152
|
+
required: true,
|
|
153
|
+
message: message,
|
|
154
|
+
trigger: trigger
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
switch (item.rule.type) {
|
|
159
|
+
case 'number':
|
|
160
|
+
case 'integer':
|
|
161
|
+
case 'float':
|
|
162
|
+
let defaultValue
|
|
163
|
+
let message
|
|
164
|
+
switch (item.rule.type) {
|
|
165
|
+
case 'number':
|
|
166
|
+
message = '数字'
|
|
167
|
+
defaultValue = 0
|
|
168
|
+
break
|
|
169
|
+
case 'integer':
|
|
170
|
+
message = '整数'
|
|
171
|
+
defaultValue = 0
|
|
172
|
+
break
|
|
173
|
+
case 'float':
|
|
174
|
+
message = '小数'
|
|
175
|
+
defaultValue = 0.0
|
|
176
|
+
break
|
|
177
|
+
}
|
|
178
|
+
this.rules[item.model].push({
|
|
179
|
+
type: item.rule.type,
|
|
180
|
+
message: item.name + '必须为' + message,
|
|
181
|
+
transform: (value) => {
|
|
182
|
+
if (value && value.length !== 0) {
|
|
183
|
+
return Number(value)
|
|
184
|
+
} else {
|
|
185
|
+
return defaultValue
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
trigger: 'blur'
|
|
189
|
+
})
|
|
190
|
+
break
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
this.form = formData
|
|
195
|
+
if (this.modifyModelData.data) {
|
|
196
|
+
this.files = this.modifyModelData.files
|
|
197
|
+
this.images = this.modifyModelData.images
|
|
198
|
+
if (Object.keys(this.modifyModelData.data).length > 0) {
|
|
199
|
+
this.getModifyModelData()
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
this.loaded = true
|
|
203
|
+
},
|
|
204
|
+
itemDisabled (value) {
|
|
205
|
+
return (this.businessType === '新增' && value.addOrEdit === 'edit') ||
|
|
206
|
+
(this.businessType === '修改' && value.addOrEdit === 'add')
|
|
207
|
+
},
|
|
208
|
+
async onSubmit () {
|
|
209
|
+
this.$refs.selectForm.validate(async valid => {
|
|
210
|
+
for (const key of Object.keys(this.form)) {
|
|
211
|
+
if (this.form[key] === null || this.form[key] === '') {
|
|
212
|
+
this.form[key] = undefined
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const requestForm = Object.assign({}, this.form)
|
|
216
|
+
// 追加静默新增字段
|
|
217
|
+
if (this.businessType === '新增') {
|
|
218
|
+
for (const item of this.silenceAddJsonData) {
|
|
219
|
+
switch (item.silencePurpose) {
|
|
220
|
+
case 'createTime':
|
|
221
|
+
requestForm[item.model] = formatDate('now')
|
|
222
|
+
break
|
|
223
|
+
case 'operator':
|
|
224
|
+
requestForm[item.model] = this.currUser.name
|
|
225
|
+
break
|
|
226
|
+
case 'orgId':
|
|
227
|
+
requestForm[item.model] = this.currUser.orgid
|
|
228
|
+
break
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// 通过请求追加静默新增:自定义字段
|
|
232
|
+
for (const item of this.silenceAddJsonData.filter((item) => item.silencePurpose === 'customize')) {
|
|
233
|
+
requestForm[item.model] = await this.getSilenceSource(item.silenceSource, requestForm)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const data = {
|
|
237
|
+
valid: valid,
|
|
238
|
+
form: requestForm
|
|
239
|
+
}
|
|
240
|
+
this.$emit('onSubmit', data)
|
|
241
|
+
})
|
|
242
|
+
},
|
|
243
|
+
/**
|
|
244
|
+
* 获取通过logic静默新增的字段
|
|
245
|
+
* @param logicName logic名称
|
|
246
|
+
* @param requestParameters 请求参数
|
|
247
|
+
*/
|
|
248
|
+
async getSilenceSource (logicName, requestParameters) {
|
|
249
|
+
const result = await post('/api/' + this.serviceName + '/logic/' + logicName, requestParameters)
|
|
250
|
+
return result
|
|
251
|
+
},
|
|
252
|
+
/**
|
|
253
|
+
* 获取被修改记录数据
|
|
254
|
+
* @param modifyModelData 被修改记录的数据
|
|
255
|
+
*/
|
|
256
|
+
getModifyModelData () {
|
|
257
|
+
for (let i = 0; i < this.realJsonData.length; i++) {
|
|
258
|
+
if (['FilesId', 'Images'].includes(this.realJsonData[i])) {
|
|
259
|
+
// 附件需要跳过 因为会通过 modifyModelData中的files,images属性给upload赋值
|
|
260
|
+
// 新增修改表单每次提交时只会提交最新添加的文件
|
|
261
|
+
continue
|
|
262
|
+
}
|
|
263
|
+
const item = this.realJsonData[i]
|
|
264
|
+
if (this.modifyModelData.data[item.model] || this.modifyModelData.data[item.model] === 0) {
|
|
265
|
+
if (this.modifyModelData.data[item.model] instanceof Array) {
|
|
266
|
+
this.form[item.model] = this.modifyModelData.data[item.model]
|
|
267
|
+
} else {
|
|
268
|
+
this.form[item.model] = this.modifyModelData.data[item.model] + ''
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
this.form[item.model] = undefined
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// 追加版本号信息
|
|
275
|
+
for (const item of this.versionJsonData) {
|
|
276
|
+
if (!this.modifyModelData.data[item.model]) {
|
|
277
|
+
this.form[item.model] = 0
|
|
278
|
+
} else {
|
|
279
|
+
this.form[item.model] = this.modifyModelData.data[item.model] + ''
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
onClose () {
|
|
284
|
+
this.$emit('update:visible', false)
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
</script>
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# XAddNativeForm
|
|
2
|
+
|
|
3
|
+
动态新增/修改表单控件,根据JSON配置生成一个完整的可供新增/修改数据的动态表单
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## 何时使用
|
|
7
|
+
|
|
8
|
+
当需要一个可供新增/修改数据的动态生成的表单时
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
引用方式:
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
import XAddNativeForm from '@vue2-client/base-client/components/XAddNativeForm/XAddNativeForm'
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
components: {
|
|
18
|
+
XAddNativeForm
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## 代码演示
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<x-add-native-form
|
|
29
|
+
ref="nativeForm"
|
|
30
|
+
@onSubmit="submit"/>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 构造参数,通过init方法构造
|
|
34
|
+
|
|
35
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
36
|
+
|-----------------|----------------------|-------|--------|
|
|
37
|
+
| formItems | 表单项集合 | array | [] |
|
|
38
|
+
| viewMode | 是否为预览模式 | bool | false |
|
|
39
|
+
| isHandleFormKey | 是否对提交表单的key进行处理 | bool | true |
|
|
40
|
+
| serviceName | 所属服务模块名 | string | system |
|
|
41
|
+
| businessType | 业务类型(新增/修改) | string | - |
|
|
42
|
+
| title | 业务标题 | string | - |
|
|
43
|
+
| getDataParams | 调用logic获取下拉框数据源的追加参数 | {} | - |
|
|
44
|
+
| simpleFormJsonData | 动态简易表单集合 | {} | - |
|
|
45
|
+
|
|
46
|
+
## 事件
|
|
47
|
+
| 事件 | 说明 | 类型 | 默认值 |
|
|
48
|
+
|-----------|----------------------|-------|-----------|
|
|
49
|
+
| @onSubmit | 表单的提交事件 | event | - |
|
|
50
|
+
|
|
51
|
+
## 例子1
|
|
52
|
+
----
|
|
53
|
+
```vue
|
|
54
|
+
<template>
|
|
55
|
+
<x-add-native-form
|
|
56
|
+
ref="nativeForm"
|
|
57
|
+
@onSubmit="submit"/>
|
|
58
|
+
</template>
|
|
59
|
+
<script>
|
|
60
|
+
import { getConfigUrl } from '@vue2-client/services/api/common'
|
|
61
|
+
export default {
|
|
62
|
+
created () {
|
|
63
|
+
this.initComponents()
|
|
64
|
+
},
|
|
65
|
+
methods: {
|
|
66
|
+
initComponents() {
|
|
67
|
+
// 获取请求配置中心的地址
|
|
68
|
+
const url = getConfigUrl('yourConfigModuleName')
|
|
69
|
+
post(url, { configName: 'yourConfigName' }).then(res => {
|
|
70
|
+
if (this.$refs.nativeForm) {
|
|
71
|
+
this.$refs.nativeForm.init({
|
|
72
|
+
formItems: res,
|
|
73
|
+
serviceName: 'af-iot',
|
|
74
|
+
businessType: '新增',
|
|
75
|
+
title: '新增告警记录'
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
},
|
|
80
|
+
submit (res) {
|
|
81
|
+
post(api.addData, res.realForm).then(data => {
|
|
82
|
+
this.$message.success(res.businessType + '成功!')
|
|
83
|
+
}).catch(e => {
|
|
84
|
+
this.$message.error(res.businessType + '失败:' + e)
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
</script>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## JSON配置示例
|
|
93
|
+
----
|
|
94
|
+
`这是一个表单配置示例,通过以下配置,你会得到一个有选项的单选框,一个带校验的输入框,以及一个文本域`
|
|
95
|
+
```json
|
|
96
|
+
[
|
|
97
|
+
{
|
|
98
|
+
"name": "是否通气",
|
|
99
|
+
"model": "is_ventilate",
|
|
100
|
+
"keys": [
|
|
101
|
+
{ "label": "是", "value": "1" },
|
|
102
|
+
{ "label": "否", "value": "0" }
|
|
103
|
+
],
|
|
104
|
+
"type": "radio",
|
|
105
|
+
"addOrEdit": "all",
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"name": "处理人",
|
|
109
|
+
"model": "f_processor",
|
|
110
|
+
"rule": {
|
|
111
|
+
"required": true
|
|
112
|
+
},
|
|
113
|
+
"type": "input",
|
|
114
|
+
"addOrEdit": "all",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "处理内容",
|
|
118
|
+
"model": "f_handle_content",
|
|
119
|
+
"type": "textarea",
|
|
120
|
+
"addOrEdit": "all",
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## JSON配置规范
|
|
126
|
+
----
|
|
127
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
128
|
+
|-----------------|----------------------|-------|-----------|
|
|
129
|
+
| name | 表单项名称 | string | '' |
|
|
130
|
+
| model | 表单项key | string | '' |
|
|
131
|
+
| rule | 表单校验 | json | {} |
|
|
132
|
+
| -> required | 是否必填 | bool | false |
|
|
133
|
+
| type | 表单类型 | string | input |
|
|
134
|
+
| keys | 当表单类型是select,radio时的选项值 | Array | [] |
|
|
135
|
+
| -> label | 选项的字面值 | string | '' |
|
|
136
|
+
| -> value | 选项的实际值 | string | '' |
|
|
137
|
+
| addOrEdit | 新增/修改场景 | string | all |
|
|
138
|
+
| -> add | 仅新增 | string | - |
|
|
139
|
+
| -> edit | 仅修改 | string | - |
|
|
140
|
+
| -> all | 全部支持 | string | - |
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
注意事项
|
|
144
|
+
----
|
|
145
|
+
|
|
146
|
+
> 本组件已经实现了自适应布局,在不同分辨率下的设备均可得到基本理想的展示效果
|
|
@@ -35,6 +35,8 @@ const commonApi = {
|
|
|
35
35
|
fileEntity: 'entity/t_files',
|
|
36
36
|
// 获取所有员工及其部门的级联菜单数据
|
|
37
37
|
getEmpTree: '/api/af-system/logic/getEmpTree',
|
|
38
|
+
// 获取表格列配置
|
|
39
|
+
getColumnsJson: '/api/af-system/logic/getColumns',
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
export function getConfigUrl (serviceName = process.env.VUE_APP_SYSTEM_NAME) {
|
package/src/utils/waterMark.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description: createWaterMark.js 加水印功能
|
|
3
|
-
*/
|
|
4
|
-
let waterMarkDOM
|
|
5
|
-
|
|
6
|
-
const clearWaterMark = () => {
|
|
7
|
-
if (waterMarkDOM) waterMarkDOM.remove()
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* @description: 创建水印
|
|
11
|
-
* @param waterMarkName 水印内容
|
|
12
|
-
*/
|
|
13
|
-
export default function createWaterMark (waterMarkName) {
|
|
14
|
-
clearWaterMark()
|
|
15
|
-
if (!waterMarkName) {
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
const width = window.parseInt(document.body.clientWidth)
|
|
19
|
-
const canvasWidth = width / window.parseInt(width / 320)
|
|
20
|
-
const fontFamily = window.getComputedStyle(document.body)['font-family']
|
|
21
|
-
const fragment = document.createDocumentFragment()
|
|
22
|
-
waterMarkDOM = document.createElement('div')
|
|
23
|
-
waterMarkDOM.className = 'water-mark-wrap'
|
|
24
|
-
let spanStr = ''
|
|
25
|
-
for (let i = 0; i < 100; i++) {
|
|
26
|
-
spanStr += `<span class="water-word" style=width:${canvasWidth}px;height:200px;font: ${fontFamily}>${waterMarkName}</span>`
|
|
27
|
-
}
|
|
28
|
-
waterMarkDOM.innerHTML = spanStr
|
|
29
|
-
fragment.appendChild(waterMarkDOM)
|
|
30
|
-
document.body.appendChild(fragment)
|
|
31
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @description: createWaterMark.js 加水印功能
|
|
3
|
+
*/
|
|
4
|
+
let waterMarkDOM
|
|
5
|
+
|
|
6
|
+
const clearWaterMark = () => {
|
|
7
|
+
if (waterMarkDOM) waterMarkDOM.remove()
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* @description: 创建水印
|
|
11
|
+
* @param waterMarkName 水印内容
|
|
12
|
+
*/
|
|
13
|
+
export default function createWaterMark (waterMarkName) {
|
|
14
|
+
clearWaterMark()
|
|
15
|
+
if (!waterMarkName) {
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
const width = window.parseInt(document.body.clientWidth)
|
|
19
|
+
const canvasWidth = width / window.parseInt(width / 320)
|
|
20
|
+
const fontFamily = window.getComputedStyle(document.body)['font-family']
|
|
21
|
+
const fragment = document.createDocumentFragment()
|
|
22
|
+
waterMarkDOM = document.createElement('div')
|
|
23
|
+
waterMarkDOM.className = 'water-mark-wrap'
|
|
24
|
+
let spanStr = ''
|
|
25
|
+
for (let i = 0; i < 100; i++) {
|
|
26
|
+
spanStr += `<span class="water-word" style=width:${canvasWidth}px;height:200px;font: ${fontFamily}>${waterMarkName}</span>`
|
|
27
|
+
}
|
|
28
|
+
waterMarkDOM.innerHTML = spanStr
|
|
29
|
+
fragment.appendChild(waterMarkDOM)
|
|
30
|
+
document.body.appendChild(fragment)
|
|
31
|
+
}
|