@zscreate/zhxy-app-component 1.0.76 → 1.0.77

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.
@@ -1,912 +1,912 @@
1
- <template>
2
- <view class="evan-form-show">
3
- <evan-form :hide-required-asterisk="hideRequiredAsterisk" ref="form" >
4
- <template v-for="(item, index) in dataObj.list">
5
- <template v-if="item.type === 'table' && item.options.canView">
6
- <view class="table-wrapper" :key="'table' + index">
7
- <view class="table-header">
8
- {{ item.name }}
9
- </view>
10
- <view class="table-container">
11
- <view class="table-item" v-for="(table, tableCIndex) in tableData[item.model]"
12
- :key="index + 'tableCIndex' + tableCIndex">
13
- <view class="item">
14
- <view class="index">{{table.index + 1}}</view>
15
- <view class="delete icon-delete" v-if="!item.options.disabled"
16
- @click="handleDeleteRow(tableCIndex, item.model)">删除</view>
17
- <view class="extend"
18
- :class="{'icon-arrow-right': !tableRowsShow[item.model][tableCIndex], 'icon-arrow-down':tableRowsShow[item.model][tableCIndex]}"
19
- @click="showTableRow(item.model, tableCIndex)">
20
- {{tableRowsShow[item.model][tableCIndex] ? '收起' : '展开'}}
21
- </view>
22
- </view>
23
- <view class="view-port" v-show="tableRowsShow[item.model][tableCIndex]">
24
- <view v-for="(tableItem, tableItemIndex) in table.columns" :key="index + 'tableItemIndex' + tableItemIndex">
25
- <evan-form-item v-show="tableItem.options.canView"
26
- :labelPosition="labelPosition"
27
- @upDateWidget="upDateTableWidget" :itemkey="tableItemIndex"
28
- :tableKey="item.model" :tableIndex="tableCIndex" :prop="tableItem.model"
29
- :ref="String(Math.random()).split('.')[1]" :models.sync="models"
30
- :rules="rules" :widget="tableItem" :isDraft="isDraft" :formId="formId"
31
- :linkage="linkage" :isApply="isApply">
32
- </evan-form-item>
33
- </view>
34
- </view>
35
- </view>
36
- <view class="add" v-if="isShowAdd && !item.options.disabled" :data-data="item"
37
- :data-model="item.model" data-add-model="addModel"
38
- @click="addToTableData(item, item.model,'addModel')">+添加</view>
39
- </view>
40
- </view>
41
- </template>
42
-
43
- <template v-else-if="item.type === 'all-lay-out' && item.options.canView">
44
- <view v-for="(colItem, colIndex) in item.columns" :key="index + 'all-lay-out—colIndex' + colIndex">
45
- <view v-for="(col, itemIndex) in colItem.list" :key="index + 'all-lay-out—itemIndex' + itemIndex">
46
- <evan-form-item :isCorrect="isCorrect" :labelPosition="labelPosition" :prop="col.model"
47
- :ref="String(Math.random()).split('.')[1]" :models.sync="models" :rules="rules"
48
- :widget="col" :isDraft="isDraft" :formId="formId" :linkage="linkage" :isApply="isApply">
49
- </evan-form-item>
50
- </view>
51
- </view>
52
- </template>
53
-
54
- <template v-else-if="item.type === 'grid-lay-out' && item.options.canView">
55
- <view v-for="(colItem, colIndex) in item.columns" :key="index + 'grid-lay-out-colIndex' + colIndex">
56
- <view v-for="(col, itemIndex) in colItem.list" :key="index + 'grid-lay-out-itemIndex' + itemIndex">
57
- <evan-form-item :isCorrect="isCorrect" :labelPosition="labelPosition" :prop="col.model"
58
- :ref="String(Math.random()).split('.')[1]" :models.sync="models" :rules="rules"
59
- :widget="col" :isDraft="isDraft" :formId="formId" :linkage="linkage" :isApply="isApply">
60
- </evan-form-item>
61
- </view>
62
- </view>
63
- </template>
64
-
65
- <template v-else-if="item.type === 'grid' && item.options.canView">
66
- <view v-for="(colItem, colIndex) in item.columns" :key="index + 'grid—colIndex' +colIndex">
67
- <view v-for="(col, itemIndex) in colItem.list" :key="index + 'grid—itemIndex' + itemIndex">
68
- <evan-form-item :isCorrect="isCorrect" :labelPosition="labelPosition" :prop="col.model"
69
- :ref="String(Math.random()).split('.')[1]" :models.sync="models" :rules="rules"
70
- :widget="col" :isDraft="isDraft" :formId="formId" :linkage="linkage" :isApply="isApply">
71
- </evan-form-item>
72
- </view>
73
- </view>
74
- </template>
75
-
76
- <template v-else-if="item.type == 'verify' && item.options.canView">
77
- <view class="verify">
78
- <view class="verify-step">{{item.name }}</view>
79
- <view class="verify-cot">
80
- <textarea v-model="models[item.model].comments"
81
- :disabled="item.model !== verifyNode" :placeholder="'请输入您的意见'"
82
- @input="handlerText($event, item.model)">
83
- </textarea>
84
- </view>
85
- <view v-if="item.model == verifyNode" class="verify-cot">
86
- <view class="verify-title">{{item.options.operation}}</view>
87
- <view style="width:200rpx;">
88
- <u-input id="suggestSelect" :border="false" type="select" :select-open="selectShow"
89
- input-align="right" v-model="suggestType" placeholder="请点击选择"
90
- @click="selectShow = true"></u-input>
91
- <u-select mode="single-column" :list="selectList" v-model="selectShow"
92
- @confirm="selectConfirm($event,item.model)"></u-select>
93
- <!-- <picker @change="bindPickerChange($event, item.model)" :value="pickerIndex" :range="selectDataTransForm(suggest)">
94
- <view class="uni-input">{{models[item.model].operation ? models[item.model].operation : '请选择'}}</view>
95
- </picker> -->
96
- </view>
97
- </view>
98
- <view v-if="item.model !== verifyNode" class="verify-cot">
99
- <view class="verify-title">{{item.options.operation}}</view>
100
- <view>{{models[item.model].operation}}</view>
101
- </view>
102
- <view class="verify-cot">
103
- <view class="verify-title">{{ item.options.operator }}</view>
104
- <view>{{ models[item.model].operator }}</view>
105
- </view>
106
- <view class="verify-cot">
107
- <view class="verify-title">{{ item.options.operationTime }}</view>
108
- <view>{{ models[item.model].operationTime }}</view>
109
- </view>
110
- </view>
111
- </template>
112
-
113
- <template v-else>
114
- <view :key="'default' + index" v-show="item.options.canView" >
115
- <evan-form-item @upDateWidget="upDateWidget" :labelPosition="labelPosition" :isCorrect="isCorrect" :prop="item.model"
116
- :ref="String(Math.random()).split('.')[1]" :models.sync="models" :rules="rules"
117
- :widget="item" :itemkey="index" :isDraft="isDraft" :formId="formId" :linkage="linkage"
118
- :isApply="isApply">
119
- </evan-form-item>
120
- </view>
121
- </template>
122
- </template>
123
-
124
- </evan-form>
125
- </view>
126
- </template>
127
-
128
- <script>
129
- import utils from '../evan-form/utils.js'
130
- import {
131
- cloneObj
132
- } from "../../utils/util.js";
133
- import Pubsub from 'pubsub-js'
134
- import evanFormItem from "../evan-form-item/evan-form-item";
135
- import evanForm from "../evan-form/evan-form";
136
- export default {
137
- name: 'formContainer',
138
- props: ['dataObj', 'value', 'isButton', 'verifyNode', 'suggest', 'isCorrect', 'isDraft', 'formId', 'linkage', "labelPosition",
139
- 'isApply'
140
- ],
141
- components: { evanFormItem ,evanForm },
142
- data() {
143
- return {
144
- timer: null,
145
- showVerify: false, //默认不展示审核信息
146
- selectShow: false,
147
- suggestType: '',
148
- selectList: [],
149
- models: {
150
-
151
- }, //models
152
- rules: {}, //校验规则1
153
- // value: {}, //后台返回的表单值 (通常是父组件传值过来的)
154
- tableData: {},
155
- tableModel: {},
156
- tableIndex: {},
157
- tableFlag: {
158
-
159
- },
160
- // dataObj:dataObj,
161
- isScroll: true,
162
- tableRowsShow: {},
163
- isShowAdd: true,
164
- hideRequiredAsterisk: false,
165
- sexes: [{
166
- name: '男',
167
- value: 'man'
168
- },
169
- {
170
- name: '女',
171
- value: 'woman'
172
- }
173
- ],
174
- // 表单的内容必须初始化
175
- info: {
176
- name: '',
177
- table: [{
178
- sub: '22'
179
- },
180
- {
181
- sub: '333'
182
- }
183
- ]
184
- },
185
- info2: {
186
- name: '222',
187
- email: '7556@qq.com',
188
- phone: '15232656598',
189
- sub: '',
190
- },
191
- pickerIndex: 0
192
- }
193
- },
194
- watch: {
195
- // models(v) {
196
- // // console.log('container models')
197
- // // console.log(v)
198
- // // console.log(this.models)
199
- // this.isScroll = true;
200
- // },
201
- models: {
202
- deep: true,
203
- handler(v) {
204
- this.isScroll = true;
205
- }
206
- },
207
- dataObj: {
208
- handler(v) {
209
- if (this.dataObj && this.dataObj.list) {
210
- this.rules = {};
211
- this.generateModle(this.dataObj.list);
212
- console.log(this.models)
213
- console.log(JSON.stringify(this.models))
214
- }
215
- },
216
- immediate: true
217
- },
218
- value: {
219
- handler(v) {
220
- if (this.dataObj && this.dataObj.list) {
221
- this.rules = {};
222
- this.generateModle(this.dataObj.list);
223
- console.log(this.models)
224
- console.log(JSON.stringify(this.models))
225
- }
226
- },
227
- immediate: true
228
- },
229
- suggest(v) {
230
- this.selectList = v
231
- },
232
- // linkage:{
233
- // deep: true,
234
- // handler(v){
235
- // console.log(v,'12345675676575')
236
- // },
237
- // }
238
- },
239
- created() {},
240
- updated() {
241
-
242
- },
243
- mounted() {
244
- // 回显关联组件
245
- // setTimeout(() => {
246
- // this.getchildren()
247
- // }, 1000)
248
- // console.log('thisdataObj', this.dataObj)
249
- // this.generateModle(dataObj.list);
250
- // if (this.dataObj && this.dataObj.list) {
251
- // this.rules = {};
252
- // this.generateModle(this.dataObj.list);
253
- // }
254
-
255
- // Pubsub.publish('randomObserve', this.models)
256
- // console.log('models', this.models)
257
- // console.log('tableData', this.tableData);
258
- // console.log('tableModel', this.tableModel)
259
- // console.log('tableIndex', this.tableIndex)
260
- // 这里必须放在mounted中,不然h5,支付宝小程序等会找不到this.$refs.form
261
- // console.log('rules', this.rules)
262
- // this.$refs.form.setRules(this.rules);
263
- // this.initPo();
264
- },
265
- methods: {
266
- //回显关联组件的操作
267
- getchildren() {
268
- // console.log(this.$children[0])
269
- // this.handlerelation(this.$children[0].$children)
270
- },
271
- // 更新所有组件的值
272
- updateAllComponentValue() {
273
- for(const key in this.$refs) {
274
- this.$refs[key] && [].concat(this.$refs[key]).forEach(item => {
275
- item.updateDataModel && item.updateDataModel()
276
- item.showFormData && item.showFormData()
277
- })
278
- }
279
- },
280
- handlerelation(arr) {
281
- for (let i = 0; i < arr.length; i++) {
282
- const item = arr[i]
283
- if (item.widget && item.widget.type == 'relateSub') {
284
- if (item.tableKey) {
285
- item.pulishMsg(
286
- item.models[item.tableKey][item.tableIndex][item.widget.model],
287
- true
288
- )
289
- } else {
290
- item.pulishMsg(item.models[item.widget.model], true)
291
- }
292
- }
293
- if (item.widget && item.widget.type == 'table') {
294
- this.handlerelation(item.$children)
295
- }
296
- }
297
- },
298
- //更新widget 目前应用于关联组件隐藏 禁用
299
- upDateWidget(widget, key) {
300
- console.log(widget.options.canView)
301
- this.dataObj.list.splice(key, 1, widget)
302
- },
303
- //更新widget 目前应用于子表单关联子组件隐藏 禁用
304
- upDateTableWidget(widget, key, tableKey, tableIndex) {
305
- this.tableData[tableKey][tableIndex].columns.splice(key, 1, widget)
306
- },
307
- // 选择操作类型
308
- selectConfirm(e, model) {
309
- e.map((val, index) => {
310
- this.models[model].operation = val.label;
311
- })
312
- this.suggestType = this.models[model].operation
313
- },
314
- scrollToTop(top) {
315
- const _this = this
316
- this.$nextTick(function() {
317
- uni.createSelectorQuery()
318
- .in(_this)
319
- .select('#suggestSelect').boundingClientRect(data => {
320
- uni.pageScrollTo({
321
- scrollTop: data.top - top,
322
- duration: 200
323
- });
324
- }).exec()
325
- })
326
- },
327
- //校验审核组件是否为空
328
- /* checkVerify() {
329
- if(this.suggestType == '') {
330
- uni.showToast({
331
- title: '审核操作不能为空',
332
- duration: 1000,
333
- icon: 'none'
334
- });
335
- this.scrollToTop()
336
- }
337
- }, */
338
- bindPickerChange(e, model) {
339
- // console.log('picker发送选择改变,携带值为', e.target.value)
340
- // console.log(this.suggest)
341
- this.pickerIndex = e.target.value
342
- // this.models[model].operation = e.target.value
343
- this.models[model].operation = this.suggest[e.target.value].value;
344
- console.log(this.models)
345
- },
346
- handlerText($event, model) {
347
- this.models[model].comments = $event.detail.value
348
- },
349
- /***单选修改赋值***/
350
- selectorOption(picked, model) {
351
- console.log(picked);
352
- console.log(model)
353
- this.models[model].operation = picked.value
354
- },
355
- /***option 数据重构**/
356
- selectDataTransForm(data) {
357
-
358
- if (!data || (data.length == 0)) {
359
- return []
360
- } else {
361
- return data.map(item => {
362
- // return {
363
- // label: item.value,
364
- // value: item.label
365
- // }
366
- return item.value
367
- })
368
- }
369
- },
370
- /**展开 收起 子表单列**/
371
- showTableRow(model, index) {
372
- // uni.createSelectorQuery()
373
- // .in(this)
374
- // .select('.table-header').boundingClientRect(data => {
375
- // console.log("得到布局位置信息" + JSON.stringify(data));
376
- // console.log("节点离页面顶部的距离为" + data.top);
377
- // uni.pageScrollTo({
378
- // scrollTop: data.top,
379
- // duration: 800
380
- // });
381
- // }).exec()
382
- // this.$set(this.tableFlag,'flag',[true])
383
- // this.tableFlag.flag = [true];
384
- console.log(this.tableFlag)
385
- this.tableRowsShow[model][index] = !this.tableRowsShow[model][index];
386
- /***解决小程序不能深度监听***/
387
- var tempObj = cloneObj(this.tableRowsShow)
388
- console.log(this.tableRowsShow = tempObj)
389
- console.log(this.tableRowsShow)
390
- // console.log(this.tableRowsShow[model][index])
391
-
392
- // console.log(this.tableRowsShow[model][index])
393
- },
394
- //删除子表单row
395
- handleDeleteRow(index, model) {
396
- // //更新tableData
397
- //更新models
398
- this.models[model].splice(index, 1);
399
- this.tableData[model].splice(index, 1);
400
- this.tableRowsShow[model].splice(index, 1);
401
- let _index = 0;
402
- this.tableData[model].forEach(item => {
403
- item.index = _index++;
404
- });
405
- this.tableIndex[model]--;
406
- },
407
- //添加子表单里面的row
408
- addToTableData(data, model, addModel) {
409
- let dataTemp = JSON.parse(JSON.stringify(data));
410
- this.tableIndex[model] === undefined ?
411
- this.$set(this.tableIndex, model, 0) :
412
- null;
413
- dataTemp.index = this.tableIndex[model];
414
- /***table row show start*/
415
- this.tableRowsShow[model] === undefined ?
416
- this.$set(this.tableRowsShow, model, []) :
417
- null;
418
- this.$set(this.tableRowsShow[model], this.tableIndex[model], true)
419
- /***table row show end*/
420
- this.tableIndex[model]++;
421
- this.tableData[model] === undefined ?
422
- this.$set(this.tableData, model, []) :
423
- null;
424
- if (addModel) {
425
- let addModelObject = {};
426
- dataTemp.columns.forEach(item => {
427
- item.options.isCorrect = false;
428
- addModelObject[item.model] = item.defaultValue ?
429
- item.defaultValue :
430
- item.options.defaultValue;
431
- });
432
- this.models[model].push(addModelObject);
433
- dataTemp.options.isCorrect = false;
434
- } else {
435
- dataTemp.options.isCorrect = true;
436
- }
437
- console.log(`dataTemp`, dataTemp);
438
- this.tableData[model].push(dataTemp);
439
- console.log('===', this.tableData[model])
440
- // console.log(this.tableData[model])
441
- },
442
- //tableData init
443
- generateTableData(gen) {
444
- // console.log('JSON.models',JSON.stringify(this.models))
445
- // this.tableData = {};
446
- // this.tableIndex = {};
447
- this.isShowAdd = true;
448
- if (gen.type === "table") {
449
- var tableModel = gen.model;
450
- if (this.tableData[tableModel] instanceof Array) {
451
- this.tableData[tableModel].length = 0;
452
- this.tableIndex[tableModel] = 0;
453
- }
454
- this.tableModel[tableModel] = gen;
455
- this.tableModel[tableModel]["options"]["defaultValue"] = this.models[
456
- gen.model
457
- ];
458
- this.tableInitByModel(tableModel);
459
- }
460
- },
461
- tableInitByModel(model) {
462
- if (
463
- this.models[model] &&
464
- this.models[model] instanceof Array &&
465
- this.models[model].length > 0
466
- ) {
467
- // console.log('--',this.tableModel[model], model)
468
- this.models[model].forEach((item, index) => {
469
- this.originIndex++;
470
- this.addToTableData(this.tableModel[model], model);
471
- });
472
- }
473
- // console.log('tableData',this.tableData)
474
- // console.log(this.models)
475
- },
476
- /***初始化models***/
477
- generateModle(genList) {
478
- if (!genList || genList.length === 0) return;
479
- for (let i = 0; i < genList.length; i++) {
480
- if (["grid", 'grid-lay-out', 'all-lay-out'].includes(genList[i].type)) {
481
- genList[i].columns.forEach(item => {
482
- this.generateModle(item.list);
483
- });
484
- } else {
485
- if (
486
- this.value &&
487
- Object.keys(this.value).indexOf(genList[i].model) >= 0
488
- ) {
489
- this.models[genList[i].model] = cloneObj(
490
- this.value[genList[i].model]
491
- );
492
-
493
- console.log(genList[i].type)
494
-
495
- /**审核**/
496
- if (genList[i].type === "verify") {
497
- this.models[genList[i].model] = this.value[genList[i].model];
498
- }
499
-
500
- if (genList[i].type === "table") {
501
- this.generateTableData(genList[i]); //生成tableModel
502
- //设置rules
503
- }
504
- } else {
505
- /**审核**/
506
- if (genList[i].type === "verify") {
507
- this.models[genList[i].model] = genList[i].operationColumns;
508
- } else if (genList[i].type === "blank") {
509
- this.$set(
510
- this.models,
511
- genList[i].model,
512
- genList[i].options.defaultType === "String" ?
513
- "" :
514
- genList[i].options.defaultType === "Object" ? {} : []
515
- );
516
- } else if (genList[i].type === "table") {
517
- this.$set(this.models, genList[i].model, this.models[genList[i].model] ?
518
- this.models[genList[i].model] :
519
- (typeof genList[i].options.defaultValue == "string" ? [] : genList[i].options
520
- .defaultValue))
521
- this.generateTableData(genList[i]); //生成tableModel
522
- } else {
523
- // console.log('TO-JSON==',JSON.stringify(this.models));
524
- // console.log(genList[i].model);
525
- let default_value = genList[i].options.defaultValue ? genList[i].options.defaultValue :
526
- '' // 避免默认值为null
527
- this.$set(this.models, genList[i].model, this.models[genList[i].model] ?
528
- this.models[genList[i].model] : default_value
529
- )
530
- // this.models[genList[i].model] = this.models[genList[i].model] ?
531
- // this.models[genList[i].model] :
532
- // genList[i].options.defaultValue;
533
- }
534
- }
535
- if (genList[i].type === "table") {
536
- var tableRlues = {};
537
- if (genList[i].columns.length > 0) {
538
- genList[i].columns.forEach(item => {
539
- if (item.rules) {
540
- tableRlues[item.model] = [
541
- ...item.rules.map(i => {
542
- return {
543
- ...i
544
- };
545
- })
546
- ];
547
- }
548
- });
549
- this.rules[genList[i].model] = tableRlues;
550
- }
551
- } else {
552
- if (this.rules[genList[i].model]) {
553
- if (genList[i].rules) {
554
- this.rules[genList[i].model] = [
555
- ...this.rules[genList[i].model],
556
- ...genList[i].rules.map(item => {
557
- return {
558
- ...item
559
- };
560
- })
561
- ];
562
- }
563
- } else {
564
- if (genList[i].rules) {
565
- this.rules[genList[i].model] = [
566
- ...genList[i].rules.map(item => {
567
- return {
568
- ...item
569
- };
570
- })
571
- ];
572
- }
573
- }
574
- }
575
- }
576
- }
577
- this.$nextTick(() => {
578
- this.$emit('formUpdated')
579
- })
580
- },
581
- validateTable() {
582
-
583
- // 查找所有的table 子表单的配置组件
584
- const findTableComponent = (list = []) => {
585
- return list.reduce((all, curr) => {
586
- if (Array.isArray(curr)) {
587
- return all.concat(findTableComponent(curr))
588
- }
589
- if (curr.type === 'table') return all.concat(curr)
590
- return all
591
- }, [])
592
- }
593
- // 判断子表单内组件有没有必填的校验
594
- const tables = findTableComponent(this.dataObj.list).filter(table => {
595
- if ([table.options.canView, !table.options.disabled].includes(false)) return
596
- const { columns = [] } = table
597
- for (let i = 0; i < columns.length; i++) {
598
- const { rules = [] } = columns[i]
599
- if (rules.some(rule => rule.required)) return true
600
- }
601
- })
602
- // 子表单有必填校验 判断有没有添加行, 没有添加行需要手动添加行, 让它触发校验
603
- tables.forEach(table => {
604
- const model = this.models[table.model]
605
- if ( !model || ( Array.isArray(model) && model.length === 0 )) {
606
- this.addToTableData(table, table.model, 'addModel')
607
- }
608
- })
609
- },
610
- /**
611
- * @param {回调函数} fn 成功的回调函数
612
- * */
613
- async getData(fn) {
614
-
615
- // 校验子表单
616
- this.validateTable()
617
-
618
- await this.$nextTick()
619
-
620
- var promiseArr = [];
621
- for (var i in this.$refs) {
622
- if (this.$refs[i] instanceof Array || this.$refs[i].constructor === Array) {
623
- this.$refs[i].forEach(item => {
624
- const { canView, disabled } = item._props.widget.options
625
- if (!canView || disabled) return
626
- if (item.validateInit && typeof item.validateInit === "function") {
627
- promiseArr.push(item.validateInit().then(res => {}).catch((error) => {
628
- if (this.isScroll && error === false) {
629
- this.isScroll = false;
630
- console.log('校验错误')
631
- uni.createSelectorQuery()
632
- .in(this)
633
- .select('.evan-form-show').boundingClientRect(data => {
634
- console.log('校验', data.top)
635
- item.scrollToTop(data.top)
636
- }).exec()
637
- }
638
- throw new Error(error) //报错 为了阻塞promise 返回
639
- }));
640
-
641
-
642
- }
643
- })
644
- } else {
645
- if (this.$refs[i].validateInit && typeof this.$refs[i].validateInit === "function") {
646
- const { canView, disabled } = item._props.widget.options
647
- if (!canView || disabled) return
648
- promiseArr.push(this.$refs[i].validateInit().then(res => {}).catch((error) => {
649
- if (this.isScroll && error === false) {
650
- this.isScroll = false;
651
- uni.createSelectorQuery()
652
- .in(this)
653
- .select('.evan-form-show').boundingClientRect(data => {
654
- this.$refs[i].scrollToTop(data.top)
655
- }).exec()
656
-
657
- }
658
- throw new Error(error) //报错 为了阻塞promise 返回
659
- }))
660
- }
661
- }
662
- // console.log(promiseArr)
663
- Promise.all(promiseArr).then((result) => {
664
- console.log(result, promiseArr.length)
665
- if (result.length === promiseArr.length) {
666
- console.log('校验成功')
667
- fn(this.models)
668
- } else {
669
- console.log('校验失败')
670
- fn('failed')
671
- } //['成功了', 'success']
672
- }).catch((error) => {
673
- console.log(error)
674
- })
675
- }
676
- // this.$refs.form.validate((res) => {
677
- // if (res) {
678
- // uni.showToast({
679
- // title: '验证通过'
680
- // })
681
- // }
682
- // })
683
- },
684
- saveForm2() {
685
- this.$refs.form.validateField(['sub', 'phone'], (res) => {
686
- if (res) {
687
- uni.showToast({
688
- title: '验证通过'
689
- })
690
- }
691
- })
692
- // this.$refs.form2.validate((res) => {
693
- // if (res) {
694
- // uni.showToast({
695
- // title: '验证通过'
696
- // })
697
- // }
698
- // })
699
- },
700
- utilsSave() {
701
- utils.validate(this.info, this.rules, (res, errors) => {
702
- if (res) {
703
- uni.showToast({
704
- title: '验证通过'
705
- })
706
- }
707
- })
708
- },
709
- hideReqired() {
710
- this.hideRequiredAsterisk = !this.hideRequiredAsterisk
711
- },
712
- }
713
- }
714
- </script>
715
-
716
- <style lang="scss">
717
- @import "../../static/iconfont.css";
718
- $mybottom: 0; //底部按钮
719
-
720
- /**审核组件样式**/
721
- .verify {
722
- font-size: 28upx;
723
- }
724
-
725
- .verify-step {
726
- height: 90upx;
727
- line-height: 90upx;
728
- padding-left: $uni-form-padding-left;
729
- font-size: $uni-form-title-font-size;
730
- }
731
-
732
- .verify-cot {
733
- background-color: #fff;
734
- padding: 20upx $uni-form-padding-left;
735
- display: flex;
736
- justify-content: space-between;
737
- align-items: center;
738
-
739
- textarea {
740
- display: block;
741
- width: 100%;
742
- height: 120rpx;
743
- padding-top: 20rpx;
744
- }
745
-
746
- >view {
747
- height: 50upx;
748
- line-height: 50upx;
749
- }
750
-
751
- >view+view {
752
- height: 70upx;
753
- line-height: 70upx;
754
- font-size: $uni-form-content-font-size;
755
- }
756
-
757
- .verify-title {
758
- // font-weight: bold;
759
- font-size: $uni-form-title-font-size;
760
- }
761
- }
762
-
763
- @include onepx('.verify-cot', 'bottom', 'after', #e6e6e6);
764
-
765
- .table-header {
766
- height: 86upx;
767
- line-height: 86upx;
768
- font-weight: bold;
769
- text-indent: 30upx;
770
- font-size: $uni-form-title-font-size;
771
- }
772
-
773
- .table-wrapper {
774
- margin: 0 auto 20upx auto;
775
- }
776
-
777
- .table-container {
778
- background-color: #ffffff;
779
- font-size: $uni-form-title-font-size;
780
-
781
- .view-port {}
782
-
783
- .add {
784
- color: #539dfa;
785
- text-align: center;
786
- height: 90upx;
787
- line-height: 90upx;
788
- font-size: $uni-form-content-font-size;
789
- }
790
-
791
- .item {
792
- display: flex;
793
- height: 90upx;
794
- line-height: 90upx;
795
- justify-content: space-around;
796
-
797
- >view {
798
- line-height: 90upx;
799
- color: #9b9b9b;
800
- text-indent: 10%;
801
- font-size: $uni-form-content-font-size;
802
- flex: 1;
803
- min-width: 130rpx;
804
- }
805
-
806
- >view+view {
807
- flex-shrink: 18;
808
- }
809
- }
810
-
811
- @include onepx('.item', 'bottom', 'after', #eeeeee);
812
- }
813
-
814
- .evan-form-show {
815
- padding-bottom: $mybottom;
816
- // padding-bottom: $mybottom;
817
- // padding: 0 30rpx;
818
- background-color: #efefef;
819
-
820
- .form-input {
821
- font-size: 28rpx;
822
- color: #333;
823
- text-align: right;
824
- width: 100%;
825
- box-sizing: border-box;
826
- height: 60rpx;
827
-
828
- &.textarea {
829
- height: 240rpx;
830
- padding: 24rpx 0;
831
- text-align: left;
832
- }
833
- }
834
-
835
- .form-input-placeholder {
836
- font-size: $uni-form-content-font-size;
837
- color: #999;
838
- }
839
-
840
- &__button {
841
- width: 100%;
842
- height: 88rpx;
843
- border-radius: 8rpx;
844
- display: flex;
845
- align-items: center;
846
- justify-content: center;
847
- padding: 0;
848
- font-size: 36rpx;
849
- color: #fff;
850
- margin-top: 20rpx;
851
- background-color: #2D87D5;
852
-
853
- &::before,
854
- &::after {
855
- border: none;
856
- }
857
- }
858
-
859
- .customize-form-item {
860
- &__label {
861
- font-size: 28rpx;
862
- color: #333;
863
- margin-bottom: 16rpx;
864
- }
865
-
866
- &__radio {
867
- display: flex;
868
- align-items: center;
869
- margin-bottom: 16rpx;
870
-
871
- &__text {
872
- font-size: 28rpx;
873
- color: #333;
874
- }
875
- }
876
- }
877
- }
878
-
879
- .fixed {
880
- position: fixed;
881
- z-index: 20;
882
- border-top: 1upx solid #eee;
883
- background-color: #539dfa;
884
- height: $mybottom;
885
- width: 100%;
886
- left: 0;
887
- bottom: 0;
888
- font-size: 30upx;
889
- color: #fff;
890
- display: flex;
891
- justify-content: center;
892
- align-items: center;
893
- }
894
-
895
- cover-view button {
896
- letter-spacing: 20upx;
897
- background-color: #539dfa;
898
- font-size: 30upx;
899
- color: #fff;
900
- }
901
-
902
- cover-view button::after {
903
- border: none;
904
- }
905
-
906
-
907
-
908
-
909
- .uni-input {
910
- padding: 5rpx 0;
911
- }
912
- </style>
1
+ <template>
2
+ <view class="evan-form-show">
3
+ <evan-form :hide-required-asterisk="hideRequiredAsterisk" ref="form">
4
+ <template v-for="(item, index) in dataObj.list">
5
+ <template v-if="item.type === 'table' && item.options.canView">
6
+ <view class="table-wrapper" :key="index">
7
+ <view class="table-header">
8
+ {{ item.name }}
9
+ </view>
10
+ <view class="table-container">
11
+ <view class="table-item" v-for="(table, tableCIndex) in tableData[item.model]"
12
+ :key="tableCIndex">
13
+ <view class="item">
14
+ <view class="index">{{table.index + 1}}</view>
15
+ <view class="delete icon-delete" v-if="!item.options.disabled"
16
+ @click="handleDeleteRow(tableCIndex, item.model)">删除</view>
17
+ <view class="extend"
18
+ :class="{'icon-arrow-right': !tableRowsShow[item.model][tableCIndex], 'icon-arrow-down':tableRowsShow[item.model][tableCIndex]}"
19
+ @click="showTableRow(item.model, tableCIndex)">
20
+ {{tableRowsShow[item.model][tableCIndex] ? '收起' : '展开'}}
21
+ </view>
22
+ </view>
23
+ <view class="view-port" v-show="tableRowsShow[item.model][tableCIndex]">
24
+ <view v-for="(tableItem, tableItemIndex) in table.columns" :key="tableItemIndex">
25
+ <evan-form-item v-show="tableItem.options.canView"
26
+ :labelPosition="labelPosition"
27
+ @upDateWidget="upDateTableWidget" :itemkey="tableItemIndex"
28
+ :tableKey="item.model" :tableIndex="tableCIndex" :prop="tableItem.model"
29
+ :ref="String(Math.random()).split('.')[1]" :models.sync="models"
30
+ :rules="rules" :widget="tableItem" :isDraft="isDraft" :formId="formId"
31
+ :linkage="linkage" :isApply="isApply">
32
+ </evan-form-item>
33
+ </view>
34
+ </view>
35
+ </view>
36
+ <view class="add" v-if="isShowAdd && !item.options.disabled" :data-data="item"
37
+ :data-model="item.model" data-add-model="addModel"
38
+ @click="addToTableData(item, item.model,'addModel')">+添加</view>
39
+ </view>
40
+ </view>
41
+ </template>
42
+
43
+ <template v-else-if="item.type === 'all-lay-out' && item.options.canView">
44
+ <view v-for="(colItem, colIndex) in item.columns" :key="colIndex">
45
+ <view v-for="(col, itemIndex) in colItem.list" :key="itemIndex">
46
+ <evan-form-item :isCorrect="isCorrect" :labelPosition="labelPosition" :prop="col.model"
47
+ :ref="String(Math.random()).split('.')[1]" :models.sync="models" :rules="rules"
48
+ :widget="col" :isDraft="isDraft" :formId="formId" :linkage="linkage" :isApply="isApply">
49
+ </evan-form-item>
50
+ </view>
51
+ </view>
52
+ </template>
53
+
54
+ <template v-else-if="item.type === 'grid-lay-out' && item.options.canView">
55
+ <view v-for="(colItem, colIndex) in item.columns" :key="colIndex">
56
+ <view v-for="(col, itemIndex) in colItem.list" :key="itemIndex">
57
+ <evan-form-item :isCorrect="isCorrect" :labelPosition="labelPosition" :prop="col.model"
58
+ :ref="String(Math.random()).split('.')[1]" :models.sync="models" :rules="rules"
59
+ :widget="col" :isDraft="isDraft" :formId="formId" :linkage="linkage" :isApply="isApply">
60
+ </evan-form-item>
61
+ </view>
62
+ </view>
63
+ </template>
64
+
65
+ <template v-else-if="item.type === 'grid' && item.options.canView">
66
+ <view v-for="(colItem, colIndex) in item.columns" :key="colIndex">
67
+ <view v-for="(col, itemIndex) in colItem.list" :key="itemIndex">
68
+ <evan-form-item :isCorrect="isCorrect" :labelPosition="labelPosition" :prop="col.model"
69
+ :ref="String(Math.random()).split('.')[1]" :models.sync="models" :rules="rules"
70
+ :widget="col" :isDraft="isDraft" :formId="formId" :linkage="linkage" :isApply="isApply">
71
+ </evan-form-item>
72
+ </view>
73
+ </view>
74
+ </template>
75
+
76
+ <template v-else-if="item.type == 'verify' && item.options.canView">
77
+ <view class="verify">
78
+ <view class="verify-step">{{item.name }}</view>
79
+ <view class="verify-cot">
80
+ <textarea v-model="models[item.model].comments"
81
+ :disabled="item.model !== verifyNode" :placeholder="'请输入您的意见'"
82
+ @input="handlerText($event, item.model)">
83
+ </textarea>
84
+ </view>
85
+ <view v-if="item.model == verifyNode" class="verify-cot">
86
+ <view class="verify-title">{{item.options.operation}}</view>
87
+ <view style="width:200rpx;">
88
+ <u-input id="suggestSelect" :border="false" type="select" :select-open="selectShow"
89
+ input-align="right" v-model="suggestType" placeholder="请点击选择"
90
+ @click="selectShow = true"></u-input>
91
+ <u-select mode="single-column" :list="selectList" v-model="selectShow"
92
+ @confirm="selectConfirm($event,item.model)"></u-select>
93
+ <!-- <picker @change="bindPickerChange($event, item.model)" :value="pickerIndex" :range="selectDataTransForm(suggest)">
94
+ <view class="uni-input">{{models[item.model].operation ? models[item.model].operation : '请选择'}}</view>
95
+ </picker> -->
96
+ </view>
97
+ </view>
98
+ <view v-if="item.model !== verifyNode" class="verify-cot">
99
+ <view class="verify-title">{{item.options.operation}}</view>
100
+ <view>{{models[item.model].operation}}</view>
101
+ </view>
102
+ <view class="verify-cot">
103
+ <view class="verify-title">{{ item.options.operator }}</view>
104
+ <view>{{ models[item.model].operator }}</view>
105
+ </view>
106
+ <view class="verify-cot">
107
+ <view class="verify-title">{{ item.options.operationTime }}</view>
108
+ <view>{{ models[item.model].operationTime }}</view>
109
+ </view>
110
+ </view>
111
+ </template>
112
+
113
+ <template v-else>
114
+ <view :key="index" v-show="item.options.canView">
115
+ <evan-form-item @upDateWidget="upDateWidget" :labelPosition="labelPosition" :isCorrect="isCorrect" :prop="item.model"
116
+ :ref="String(Math.random()).split('.')[1]" :models.sync="models" :rules="rules"
117
+ :widget="item" :itemkey="index" :isDraft="isDraft" :formId="formId" :linkage="linkage"
118
+ :isApply="isApply">
119
+ </evan-form-item>
120
+ </view>
121
+ </template>
122
+ </template>
123
+
124
+ </evan-form>
125
+ </view>
126
+ </template>
127
+
128
+ <script>
129
+ import utils from '../evan-form/utils.js'
130
+ import {
131
+ cloneObj
132
+ } from "../../utils/util.js";
133
+ import Pubsub from 'pubsub-js'
134
+ import evanFormItem from "../evan-form-item/evan-form-item";
135
+ import evanForm from "../evan-form/evan-form";
136
+ export default {
137
+ name: 'formContainer',
138
+ props: ['dataObj', 'value', 'isButton', 'verifyNode', 'suggest', 'isCorrect', 'isDraft', 'formId', 'linkage', "labelPosition",
139
+ 'isApply'
140
+ ],
141
+ components: { evanFormItem ,evanForm },
142
+ data() {
143
+ return {
144
+ timer: null,
145
+ showVerify: false, //默认不展示审核信息
146
+ selectShow: false,
147
+ suggestType: '',
148
+ selectList: [],
149
+ models: {
150
+
151
+ }, //models
152
+ rules: {}, //校验规则1
153
+ // value: {}, //后台返回的表单值 (通常是父组件传值过来的)
154
+ tableData: {},
155
+ tableModel: {},
156
+ tableIndex: {},
157
+ tableFlag: {
158
+
159
+ },
160
+ // dataObj:dataObj,
161
+ isScroll: true,
162
+ tableRowsShow: {},
163
+ isShowAdd: true,
164
+ hideRequiredAsterisk: false,
165
+ sexes: [{
166
+ name: '男',
167
+ value: 'man'
168
+ },
169
+ {
170
+ name: '女',
171
+ value: 'woman'
172
+ }
173
+ ],
174
+ // 表单的内容必须初始化
175
+ info: {
176
+ name: '',
177
+ table: [{
178
+ sub: '22'
179
+ },
180
+ {
181
+ sub: '333'
182
+ }
183
+ ]
184
+ },
185
+ info2: {
186
+ name: '222',
187
+ email: '7556@qq.com',
188
+ phone: '15232656598',
189
+ sub: '',
190
+ },
191
+ pickerIndex: 0
192
+ }
193
+ },
194
+ watch: {
195
+ // models(v) {
196
+ // // console.log('container models')
197
+ // // console.log(v)
198
+ // // console.log(this.models)
199
+ // this.isScroll = true;
200
+ // },
201
+ models: {
202
+ deep: true,
203
+ handler(v) {
204
+ this.isScroll = true;
205
+ }
206
+ },
207
+ dataObj: {
208
+ handler(v) {
209
+ if (this.dataObj && this.dataObj.list) {
210
+ this.rules = {};
211
+ this.generateModle(this.dataObj.list);
212
+ console.log(this.models)
213
+ console.log(JSON.stringify(this.models))
214
+ }
215
+ },
216
+ immediate: true
217
+ },
218
+ value: {
219
+ handler(v) {
220
+ if (this.dataObj && this.dataObj.list) {
221
+ this.rules = {};
222
+ this.generateModle(this.dataObj.list);
223
+ console.log(this.models)
224
+ console.log(JSON.stringify(this.models))
225
+ }
226
+ },
227
+ immediate: true
228
+ },
229
+ suggest(v) {
230
+ this.selectList = v
231
+ },
232
+ // linkage:{
233
+ // deep: true,
234
+ // handler(v){
235
+ // console.log(v,'12345675676575')
236
+ // },
237
+ // }
238
+ },
239
+ created() {},
240
+ updated() {
241
+
242
+ },
243
+ mounted() {
244
+ // 回显关联组件
245
+ // setTimeout(() => {
246
+ // this.getchildren()
247
+ // }, 1000)
248
+ // console.log('thisdataObj', this.dataObj)
249
+ // this.generateModle(dataObj.list);
250
+ // if (this.dataObj && this.dataObj.list) {
251
+ // this.rules = {};
252
+ // this.generateModle(this.dataObj.list);
253
+ // }
254
+
255
+ // Pubsub.publish('randomObserve', this.models)
256
+ // console.log('models', this.models)
257
+ // console.log('tableData', this.tableData);
258
+ // console.log('tableModel', this.tableModel)
259
+ // console.log('tableIndex', this.tableIndex)
260
+ // 这里必须放在mounted中,不然h5,支付宝小程序等会找不到this.$refs.form
261
+ // console.log('rules', this.rules)
262
+ // this.$refs.form.setRules(this.rules);
263
+ // this.initPo();
264
+ },
265
+ methods: {
266
+ //回显关联组件的操作
267
+ getchildren() {
268
+ // console.log(this.$children[0])
269
+ // this.handlerelation(this.$children[0].$children)
270
+ },
271
+ // 更新所有组件的值
272
+ updateAllComponentValue() {
273
+ for(const key in this.$refs) {
274
+ this.$refs[key] && [].concat(this.$refs[key]).forEach(item => {
275
+ item.updateDataModel && item.updateDataModel()
276
+ item.showFormData && item.showFormData()
277
+ })
278
+ }
279
+ },
280
+ handlerelation(arr) {
281
+ for (let i = 0; i < arr.length; i++) {
282
+ const item = arr[i]
283
+ if (item.widget && item.widget.type == 'relateSub') {
284
+ if (item.tableKey) {
285
+ item.pulishMsg(
286
+ item.models[item.tableKey][item.tableIndex][item.widget.model],
287
+ true
288
+ )
289
+ } else {
290
+ item.pulishMsg(item.models[item.widget.model], true)
291
+ }
292
+ }
293
+ if (item.widget && item.widget.type == 'table') {
294
+ this.handlerelation(item.$children)
295
+ }
296
+ }
297
+ },
298
+ //更新widget 目前应用于关联组件隐藏 禁用
299
+ upDateWidget(widget, key) {
300
+ console.log(widget.options.canView)
301
+ this.dataObj.list.splice(key, 1, widget)
302
+ },
303
+ //更新widget 目前应用于子表单关联子组件隐藏 禁用
304
+ upDateTableWidget(widget, key, tableKey, tableIndex) {
305
+ this.tableData[tableKey][tableIndex].columns.splice(key, 1, widget)
306
+ },
307
+ // 选择操作类型
308
+ selectConfirm(e, model) {
309
+ e.map((val, index) => {
310
+ this.models[model].operation = val.label;
311
+ })
312
+ this.suggestType = this.models[model].operation
313
+ },
314
+ scrollToTop(top) {
315
+ const _this = this
316
+ this.$nextTick(function() {
317
+ uni.createSelectorQuery()
318
+ .in(_this)
319
+ .select('#suggestSelect').boundingClientRect(data => {
320
+ uni.pageScrollTo({
321
+ scrollTop: data.top - top,
322
+ duration: 200
323
+ });
324
+ }).exec()
325
+ })
326
+ },
327
+ //校验审核组件是否为空
328
+ /* checkVerify() {
329
+ if(this.suggestType == '') {
330
+ uni.showToast({
331
+ title: '审核操作不能为空',
332
+ duration: 1000,
333
+ icon: 'none'
334
+ });
335
+ this.scrollToTop()
336
+ }
337
+ }, */
338
+ bindPickerChange(e, model) {
339
+ // console.log('picker发送选择改变,携带值为', e.target.value)
340
+ // console.log(this.suggest)
341
+ this.pickerIndex = e.target.value
342
+ // this.models[model].operation = e.target.value
343
+ this.models[model].operation = this.suggest[e.target.value].value;
344
+ console.log(this.models)
345
+ },
346
+ handlerText($event, model) {
347
+ this.models[model].comments = $event.detail.value
348
+ },
349
+ /***单选修改赋值***/
350
+ selectorOption(picked, model) {
351
+ console.log(picked);
352
+ console.log(model)
353
+ this.models[model].operation = picked.value
354
+ },
355
+ /***option 数据重构**/
356
+ selectDataTransForm(data) {
357
+
358
+ if (!data || (data.length == 0)) {
359
+ return []
360
+ } else {
361
+ return data.map(item => {
362
+ // return {
363
+ // label: item.value,
364
+ // value: item.label
365
+ // }
366
+ return item.value
367
+ })
368
+ }
369
+ },
370
+ /**展开 收起 子表单列**/
371
+ showTableRow(model, index) {
372
+ // uni.createSelectorQuery()
373
+ // .in(this)
374
+ // .select('.table-header').boundingClientRect(data => {
375
+ // console.log("得到布局位置信息" + JSON.stringify(data));
376
+ // console.log("节点离页面顶部的距离为" + data.top);
377
+ // uni.pageScrollTo({
378
+ // scrollTop: data.top,
379
+ // duration: 800
380
+ // });
381
+ // }).exec()
382
+ // this.$set(this.tableFlag,'flag',[true])
383
+ // this.tableFlag.flag = [true];
384
+ console.log(this.tableFlag)
385
+ this.tableRowsShow[model][index] = !this.tableRowsShow[model][index];
386
+ /***解决小程序不能深度监听***/
387
+ var tempObj = cloneObj(this.tableRowsShow)
388
+ console.log(this.tableRowsShow = tempObj)
389
+ console.log(this.tableRowsShow)
390
+ // console.log(this.tableRowsShow[model][index])
391
+
392
+ // console.log(this.tableRowsShow[model][index])
393
+ },
394
+ //删除子表单row
395
+ handleDeleteRow(index, model) {
396
+ // //更新tableData
397
+ //更新models
398
+ this.models[model].splice(index, 1);
399
+ this.tableData[model].splice(index, 1);
400
+ this.tableRowsShow[model].splice(index, 1);
401
+ let _index = 0;
402
+ this.tableData[model].forEach(item => {
403
+ item.index = _index++;
404
+ });
405
+ this.tableIndex[model]--;
406
+ },
407
+ //添加子表单里面的row
408
+ addToTableData(data, model, addModel) {
409
+ let dataTemp = JSON.parse(JSON.stringify(data));
410
+ this.tableIndex[model] === undefined ?
411
+ this.$set(this.tableIndex, model, 0) :
412
+ null;
413
+ dataTemp.index = this.tableIndex[model];
414
+ /***table row show start*/
415
+ this.tableRowsShow[model] === undefined ?
416
+ this.$set(this.tableRowsShow, model, []) :
417
+ null;
418
+ this.$set(this.tableRowsShow[model], this.tableIndex[model], true)
419
+ /***table row show end*/
420
+ this.tableIndex[model]++;
421
+ this.tableData[model] === undefined ?
422
+ this.$set(this.tableData, model, []) :
423
+ null;
424
+ if (addModel) {
425
+ let addModelObject = {};
426
+ dataTemp.columns.forEach(item => {
427
+ item.options.isCorrect = false;
428
+ addModelObject[item.model] = item.defaultValue ?
429
+ item.defaultValue :
430
+ item.options.defaultValue;
431
+ });
432
+ this.models[model].push(addModelObject);
433
+ dataTemp.options.isCorrect = false;
434
+ } else {
435
+ dataTemp.options.isCorrect = true;
436
+ }
437
+ console.log(`dataTemp`, dataTemp);
438
+ this.tableData[model].push(dataTemp);
439
+ console.log('===', this.tableData[model])
440
+ // console.log(this.tableData[model])
441
+ },
442
+ //tableData init
443
+ generateTableData(gen) {
444
+ // console.log('JSON.models',JSON.stringify(this.models))
445
+ // this.tableData = {};
446
+ // this.tableIndex = {};
447
+ this.isShowAdd = true;
448
+ if (gen.type === "table") {
449
+ var tableModel = gen.model;
450
+ if (this.tableData[tableModel] instanceof Array) {
451
+ this.tableData[tableModel].length = 0;
452
+ this.tableIndex[tableModel] = 0;
453
+ }
454
+ this.tableModel[tableModel] = gen;
455
+ this.tableModel[tableModel]["options"]["defaultValue"] = this.models[
456
+ gen.model
457
+ ];
458
+ this.tableInitByModel(tableModel);
459
+ }
460
+ },
461
+ tableInitByModel(model) {
462
+ if (
463
+ this.models[model] &&
464
+ this.models[model] instanceof Array &&
465
+ this.models[model].length > 0
466
+ ) {
467
+ // console.log('--',this.tableModel[model], model)
468
+ this.models[model].forEach((item, index) => {
469
+ this.originIndex++;
470
+ this.addToTableData(this.tableModel[model], model);
471
+ });
472
+ }
473
+ // console.log('tableData',this.tableData)
474
+ // console.log(this.models)
475
+ },
476
+ /***初始化models***/
477
+ generateModle(genList) {
478
+ if (!genList || genList.length === 0) return;
479
+ for (let i = 0; i < genList.length; i++) {
480
+ if (["grid", 'grid-lay-out', 'all-lay-out'].includes(genList[i].type)) {
481
+ genList[i].columns.forEach(item => {
482
+ this.generateModle(item.list);
483
+ });
484
+ } else {
485
+ if (
486
+ this.value &&
487
+ Object.keys(this.value).indexOf(genList[i].model) >= 0
488
+ ) {
489
+ this.models[genList[i].model] = cloneObj(
490
+ this.value[genList[i].model]
491
+ );
492
+
493
+ console.log(genList[i].type)
494
+
495
+ /**审核**/
496
+ if (genList[i].type === "verify") {
497
+ this.models[genList[i].model] = this.value[genList[i].model];
498
+ }
499
+
500
+ if (genList[i].type === "table") {
501
+ this.generateTableData(genList[i]); //生成tableModel
502
+ //设置rules
503
+ }
504
+ } else {
505
+ /**审核**/
506
+ if (genList[i].type === "verify") {
507
+ this.models[genList[i].model] = genList[i].operationColumns;
508
+ } else if (genList[i].type === "blank") {
509
+ this.$set(
510
+ this.models,
511
+ genList[i].model,
512
+ genList[i].options.defaultType === "String" ?
513
+ "" :
514
+ genList[i].options.defaultType === "Object" ? {} : []
515
+ );
516
+ } else if (genList[i].type === "table") {
517
+ this.$set(this.models, genList[i].model, this.models[genList[i].model] ?
518
+ this.models[genList[i].model] :
519
+ (typeof genList[i].options.defaultValue == "string" ? [] : genList[i].options
520
+ .defaultValue))
521
+ this.generateTableData(genList[i]); //生成tableModel
522
+ } else {
523
+ // console.log('TO-JSON==',JSON.stringify(this.models));
524
+ // console.log(genList[i].model);
525
+ let default_value = genList[i].options.defaultValue ? genList[i].options.defaultValue :
526
+ '' // 避免默认值为null
527
+ this.$set(this.models, genList[i].model, this.models[genList[i].model] ?
528
+ this.models[genList[i].model] : default_value
529
+ )
530
+ // this.models[genList[i].model] = this.models[genList[i].model] ?
531
+ // this.models[genList[i].model] :
532
+ // genList[i].options.defaultValue;
533
+ }
534
+ }
535
+ if (genList[i].type === "table") {
536
+ var tableRlues = {};
537
+ if (genList[i].columns.length > 0) {
538
+ genList[i].columns.forEach(item => {
539
+ if (item.rules) {
540
+ tableRlues[item.model] = [
541
+ ...item.rules.map(i => {
542
+ return {
543
+ ...i
544
+ };
545
+ })
546
+ ];
547
+ }
548
+ });
549
+ this.rules[genList[i].model] = tableRlues;
550
+ }
551
+ } else {
552
+ if (this.rules[genList[i].model]) {
553
+ if (genList[i].rules) {
554
+ this.rules[genList[i].model] = [
555
+ ...this.rules[genList[i].model],
556
+ ...genList[i].rules.map(item => {
557
+ return {
558
+ ...item
559
+ };
560
+ })
561
+ ];
562
+ }
563
+ } else {
564
+ if (genList[i].rules) {
565
+ this.rules[genList[i].model] = [
566
+ ...genList[i].rules.map(item => {
567
+ return {
568
+ ...item
569
+ };
570
+ })
571
+ ];
572
+ }
573
+ }
574
+ }
575
+ }
576
+ }
577
+ this.$nextTick(() => {
578
+ this.$emit('formUpdated')
579
+ })
580
+ },
581
+ validateTable() {
582
+
583
+ // 查找所有的table 子表单的配置组件
584
+ const findTableComponent = (list = []) => {
585
+ return list.reduce((all, curr) => {
586
+ if (Array.isArray(curr)) {
587
+ return all.concat(findTableComponent(curr))
588
+ }
589
+ if (curr.type === 'table') return all.concat(curr)
590
+ return all
591
+ }, [])
592
+ }
593
+ // 判断子表单内组件有没有必填的校验
594
+ const tables = findTableComponent(this.dataObj.list).filter(table => {
595
+ if ([table.options.canView, !table.options.disabled].includes(false)) return
596
+ const { columns = [] } = table
597
+ for (let i = 0; i < columns.length; i++) {
598
+ const { rules = [] } = columns[i]
599
+ if (rules.some(rule => rule.required)) return true
600
+ }
601
+ })
602
+ // 子表单有必填校验 判断有没有添加行, 没有添加行需要手动添加行, 让它触发校验
603
+ tables.forEach(table => {
604
+ const model = this.models[table.model]
605
+ if ( !model || ( Array.isArray(model) && model.length === 0 )) {
606
+ this.addToTableData(table, table.model, 'addModel')
607
+ }
608
+ })
609
+ },
610
+ /**
611
+ * @param {回调函数} fn 成功的回调函数
612
+ * */
613
+ async getData(fn) {
614
+
615
+ // 校验子表单
616
+ this.validateTable()
617
+
618
+ await this.$nextTick()
619
+
620
+ var promiseArr = [];
621
+ for (var i in this.$refs) {
622
+ if (this.$refs[i] instanceof Array || this.$refs[i].constructor === Array) {
623
+ this.$refs[i].forEach(item => {
624
+ const { canView, disabled } = item._props.widget.options
625
+ if (!canView || disabled) return
626
+ if (item.validateInit && typeof item.validateInit === "function") {
627
+ promiseArr.push(item.validateInit().then(res => {}).catch((error) => {
628
+ if (this.isScroll && error === false) {
629
+ this.isScroll = false;
630
+ console.log('校验错误')
631
+ uni.createSelectorQuery()
632
+ .in(this)
633
+ .select('.evan-form-show').boundingClientRect(data => {
634
+ console.log('校验', data.top)
635
+ item.scrollToTop(data.top)
636
+ }).exec()
637
+ }
638
+ throw new Error(error) //报错 为了阻塞promise 返回
639
+ }));
640
+
641
+
642
+ }
643
+ })
644
+ } else {
645
+ if (this.$refs[i].validateInit && typeof this.$refs[i].validateInit === "function") {
646
+ const { canView, disabled } = item._props.widget.options
647
+ if (!canView || disabled) return
648
+ promiseArr.push(this.$refs[i].validateInit().then(res => {}).catch((error) => {
649
+ if (this.isScroll && error === false) {
650
+ this.isScroll = false;
651
+ uni.createSelectorQuery()
652
+ .in(this)
653
+ .select('.evan-form-show').boundingClientRect(data => {
654
+ this.$refs[i].scrollToTop(data.top)
655
+ }).exec()
656
+
657
+ }
658
+ throw new Error(error) //报错 为了阻塞promise 返回
659
+ }))
660
+ }
661
+ }
662
+ // console.log(promiseArr)
663
+ Promise.all(promiseArr).then((result) => {
664
+ console.log(result, promiseArr.length)
665
+ if (result.length === promiseArr.length) {
666
+ console.log('校验成功')
667
+ fn(this.models)
668
+ } else {
669
+ console.log('校验失败')
670
+ fn('failed')
671
+ } //['成功了', 'success']
672
+ }).catch((error) => {
673
+ console.log(error)
674
+ })
675
+ }
676
+ // this.$refs.form.validate((res) => {
677
+ // if (res) {
678
+ // uni.showToast({
679
+ // title: '验证通过'
680
+ // })
681
+ // }
682
+ // })
683
+ },
684
+ saveForm2() {
685
+ this.$refs.form.validateField(['sub', 'phone'], (res) => {
686
+ if (res) {
687
+ uni.showToast({
688
+ title: '验证通过'
689
+ })
690
+ }
691
+ })
692
+ // this.$refs.form2.validate((res) => {
693
+ // if (res) {
694
+ // uni.showToast({
695
+ // title: '验证通过'
696
+ // })
697
+ // }
698
+ // })
699
+ },
700
+ utilsSave() {
701
+ utils.validate(this.info, this.rules, (res, errors) => {
702
+ if (res) {
703
+ uni.showToast({
704
+ title: '验证通过'
705
+ })
706
+ }
707
+ })
708
+ },
709
+ hideReqired() {
710
+ this.hideRequiredAsterisk = !this.hideRequiredAsterisk
711
+ },
712
+ }
713
+ }
714
+ </script>
715
+
716
+ <style lang="scss">
717
+ @import "../../static/iconfont.css";
718
+ $mybottom: 0; //底部按钮
719
+
720
+ /**审核组件样式**/
721
+ .verify {
722
+ font-size: 28upx;
723
+ }
724
+
725
+ .verify-step {
726
+ height: 90upx;
727
+ line-height: 90upx;
728
+ padding-left: $uni-form-padding-left;
729
+ font-size: $uni-form-title-font-size;
730
+ }
731
+
732
+ .verify-cot {
733
+ background-color: #fff;
734
+ padding: 20upx $uni-form-padding-left;
735
+ display: flex;
736
+ justify-content: space-between;
737
+ align-items: center;
738
+
739
+ textarea {
740
+ display: block;
741
+ width: 100%;
742
+ height: 120rpx;
743
+ padding-top: 20rpx;
744
+ }
745
+
746
+ >view {
747
+ height: 50upx;
748
+ line-height: 50upx;
749
+ }
750
+
751
+ >view+view {
752
+ height: 70upx;
753
+ line-height: 70upx;
754
+ font-size: $uni-form-content-font-size;
755
+ }
756
+
757
+ .verify-title {
758
+ // font-weight: bold;
759
+ font-size: $uni-form-title-font-size;
760
+ }
761
+ }
762
+
763
+ @include onepx('.verify-cot', 'bottom', 'after', #e6e6e6);
764
+
765
+ .table-header {
766
+ height: 86upx;
767
+ line-height: 86upx;
768
+ font-weight: bold;
769
+ text-indent: 30upx;
770
+ font-size: $uni-form-title-font-size;
771
+ }
772
+
773
+ .table-wrapper {
774
+ margin: 0 auto 20upx auto;
775
+ }
776
+
777
+ .table-container {
778
+ background-color: #ffffff;
779
+ font-size: $uni-form-title-font-size;
780
+
781
+ .view-port {}
782
+
783
+ .add {
784
+ color: #539dfa;
785
+ text-align: center;
786
+ height: 90upx;
787
+ line-height: 90upx;
788
+ font-size: $uni-form-content-font-size;
789
+ }
790
+
791
+ .item {
792
+ display: flex;
793
+ height: 90upx;
794
+ line-height: 90upx;
795
+ justify-content: space-around;
796
+
797
+ >view {
798
+ line-height: 90upx;
799
+ color: #9b9b9b;
800
+ text-indent: 10%;
801
+ font-size: $uni-form-content-font-size;
802
+ flex: 1;
803
+ min-width: 130rpx;
804
+ }
805
+
806
+ >view+view {
807
+ flex-shrink: 18;
808
+ }
809
+ }
810
+
811
+ @include onepx('.item', 'bottom', 'after', #eeeeee);
812
+ }
813
+
814
+ .evan-form-show {
815
+ padding-bottom: $mybottom;
816
+ // padding-bottom: $mybottom;
817
+ // padding: 0 30rpx;
818
+ background-color: #efefef;
819
+
820
+ .form-input {
821
+ font-size: 28rpx;
822
+ color: #333;
823
+ text-align: right;
824
+ width: 100%;
825
+ box-sizing: border-box;
826
+ height: 60rpx;
827
+
828
+ &.textarea {
829
+ height: 240rpx;
830
+ padding: 24rpx 0;
831
+ text-align: left;
832
+ }
833
+ }
834
+
835
+ .form-input-placeholder {
836
+ font-size: $uni-form-content-font-size;
837
+ color: #999;
838
+ }
839
+
840
+ &__button {
841
+ width: 100%;
842
+ height: 88rpx;
843
+ border-radius: 8rpx;
844
+ display: flex;
845
+ align-items: center;
846
+ justify-content: center;
847
+ padding: 0;
848
+ font-size: 36rpx;
849
+ color: #fff;
850
+ margin-top: 20rpx;
851
+ background-color: #2D87D5;
852
+
853
+ &::before,
854
+ &::after {
855
+ border: none;
856
+ }
857
+ }
858
+
859
+ .customize-form-item {
860
+ &__label {
861
+ font-size: 28rpx;
862
+ color: #333;
863
+ margin-bottom: 16rpx;
864
+ }
865
+
866
+ &__radio {
867
+ display: flex;
868
+ align-items: center;
869
+ margin-bottom: 16rpx;
870
+
871
+ &__text {
872
+ font-size: 28rpx;
873
+ color: #333;
874
+ }
875
+ }
876
+ }
877
+ }
878
+
879
+ .fixed {
880
+ position: fixed;
881
+ z-index: 20;
882
+ border-top: 1upx solid #eee;
883
+ background-color: #539dfa;
884
+ height: $mybottom;
885
+ width: 100%;
886
+ left: 0;
887
+ bottom: 0;
888
+ font-size: 30upx;
889
+ color: #fff;
890
+ display: flex;
891
+ justify-content: center;
892
+ align-items: center;
893
+ }
894
+
895
+ cover-view button {
896
+ letter-spacing: 20upx;
897
+ background-color: #539dfa;
898
+ font-size: 30upx;
899
+ color: #fff;
900
+ }
901
+
902
+ cover-view button::after {
903
+ border: none;
904
+ }
905
+
906
+
907
+
908
+
909
+ .uni-input {
910
+ padding: 5rpx 0;
911
+ }
912
+ </style>