vue2-client 1.8.237 → 1.8.239
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/AddressSearchCombobox/AddressSearchCombobox.vue +58 -42
- package/src/base-client/components/common/AddressSearchCombobox/demo.vue +36 -35
- package/src/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue +32 -1
- package/src/base-client/components/common/Upload/Upload.vue +6 -2
- package/src/base-client/components/common/XDescriptions/lowcodeEditorRegister.js +23 -21
- package/src/base-client/components/common/XFormGroup/demo.vue +40 -40
- package/src/base-client/components/common/XReport/XReport.vue +144 -10
- package/src/base-client/components/common/XReport/XReportDemo.vue +2225 -578
- package/src/base-client/components/common/XReport/XReportDesign.vue +42 -0
- package/src/base-client/components/common/XReport/XReportJsonRender.vue +42 -9
- package/src/base-client/components/common/XReport/XReportTrGroup.vue +91 -12
- package/src/base-client/components/common/XReportSlot/index.md +48 -48
- package/src/pages/lowCode/lowCodeEditor.vue +155 -152
- package/src/utils/reg.js +19 -19
- package/vue.config.js +1 -0
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
+
<!-- 骨架屏 -->
|
|
3
4
|
<a-card v-if="showSkeleton">
|
|
4
5
|
<a-skeleton active/>
|
|
5
6
|
</a-card>
|
|
6
7
|
<template v-if="noPadding">
|
|
7
8
|
<!-- 主体表格 -->
|
|
8
9
|
<XReportDesign
|
|
10
|
+
@updateImg="updateImg"
|
|
9
11
|
v-if="scanFinish"
|
|
12
|
+
:use-oss-for-img="useOssForImg"
|
|
13
|
+
:display-only="displayOnly"
|
|
10
14
|
:config="type === 'display' ? originalConfig : activeConfig"
|
|
11
15
|
:slot-config-name="type === 'display' ? undefined : activatedSlotName"
|
|
12
16
|
:for-display="type === 'display'"
|
|
@@ -23,7 +27,7 @@
|
|
|
23
27
|
<!-- 用以包裹整个页面 -->
|
|
24
28
|
<a-card v-if="!showSkeleton">
|
|
25
29
|
<!-- 切换菜单 -->
|
|
26
|
-
<a-radio-group v-model="type" default-value="a" button-style="solid" @change="tabChanged" v-show="!onlyDisplay">
|
|
30
|
+
<a-radio-group v-model="type" default-value="a" button-style="solid" @change="tabChanged" v-show="!onlyDisplay && editMode">
|
|
27
31
|
<a-radio-button value="design" v-if="!onlyDisplay">
|
|
28
32
|
设计
|
|
29
33
|
</a-radio-button>
|
|
@@ -31,12 +35,15 @@
|
|
|
31
35
|
预览
|
|
32
36
|
</a-radio-button>
|
|
33
37
|
</a-radio-group>
|
|
34
|
-
<a-radio-button @click="saveConfig" style="border-radius: 0 4px 4px 0" v-if="
|
|
38
|
+
<a-radio-button @click="saveConfig" style="border-radius: 0 4px 4px 0" v-if="showSaveButton">
|
|
35
39
|
保存
|
|
36
40
|
</a-radio-button>
|
|
37
41
|
<!-- 主体表格 -->
|
|
38
42
|
<XReportDesign
|
|
39
43
|
v-if="scanFinish"
|
|
44
|
+
@updateImg="updateImg"
|
|
45
|
+
:use-oss-for-img="useOssForImg"
|
|
46
|
+
:display-only="displayOnly"
|
|
40
47
|
:config="type === 'display' ? originalConfig : activeConfig"
|
|
41
48
|
:slot-config-name="type === 'display' ? undefined : activatedSlotName"
|
|
42
49
|
:for-display="type === 'display'"
|
|
@@ -78,60 +85,96 @@ export default {
|
|
|
78
85
|
return []
|
|
79
86
|
}
|
|
80
87
|
},
|
|
88
|
+
// 控制用户权限,user和admin
|
|
81
89
|
authority: {
|
|
82
90
|
type: String,
|
|
83
91
|
default: 'user'
|
|
84
92
|
},
|
|
93
|
+
// 是否为编辑模式
|
|
94
|
+
editMode: {
|
|
95
|
+
type: Boolean,
|
|
96
|
+
default: true
|
|
97
|
+
},
|
|
98
|
+
// 配置名
|
|
85
99
|
configName: {
|
|
86
100
|
type: String,
|
|
87
101
|
required: true
|
|
88
102
|
},
|
|
103
|
+
// 插槽名
|
|
89
104
|
activatedSlotName: {
|
|
90
105
|
type: String,
|
|
91
106
|
default: undefined
|
|
92
107
|
},
|
|
108
|
+
// 本地配置,调试用
|
|
93
109
|
localConfig: {
|
|
94
110
|
type: Object,
|
|
95
111
|
default: undefined
|
|
96
112
|
},
|
|
113
|
+
// 兼容老版本配置
|
|
97
114
|
dontFormat: {
|
|
98
115
|
type: Boolean,
|
|
99
|
-
default:
|
|
116
|
+
default: true
|
|
100
117
|
},
|
|
118
|
+
// 数据
|
|
101
119
|
configData: {
|
|
102
120
|
type: Object,
|
|
103
121
|
default: undefined
|
|
104
122
|
},
|
|
123
|
+
// 命名空间
|
|
105
124
|
serverName: {
|
|
106
125
|
type: String,
|
|
107
126
|
default: 'af-system'
|
|
108
127
|
},
|
|
128
|
+
// 只做展示
|
|
109
129
|
displayOnly: {
|
|
110
130
|
type: Boolean,
|
|
111
131
|
default: false
|
|
112
132
|
},
|
|
133
|
+
// 表格没有边距
|
|
113
134
|
noPadding: {
|
|
114
135
|
type: Boolean,
|
|
115
136
|
default: false
|
|
116
137
|
},
|
|
138
|
+
// 表格没有上边框,与noPadding搭配可以实现连续表格
|
|
117
139
|
noTopBorder: {
|
|
118
140
|
type: Boolean,
|
|
119
141
|
default: false
|
|
120
142
|
},
|
|
143
|
+
// 是否展示标题
|
|
121
144
|
showTitle: {
|
|
122
145
|
type: Boolean,
|
|
123
146
|
default: true
|
|
124
147
|
},
|
|
148
|
+
// 是否展示保存按钮
|
|
149
|
+
showSaveButton: {
|
|
150
|
+
type: Boolean,
|
|
151
|
+
default: true
|
|
152
|
+
},
|
|
153
|
+
// 是否将组件注册到外层提供的容器中,方便外侧统一保存
|
|
154
|
+
registerMap: {
|
|
155
|
+
type: Array,
|
|
156
|
+
default: undefined
|
|
157
|
+
},
|
|
158
|
+
// 图片是否使用OSS来保存
|
|
159
|
+
useOssForImg: {
|
|
160
|
+
type: Boolean,
|
|
161
|
+
default: true
|
|
162
|
+
}
|
|
125
163
|
},
|
|
126
164
|
components: {
|
|
127
165
|
XReportDesign
|
|
128
166
|
},
|
|
129
167
|
data () {
|
|
130
168
|
return {
|
|
169
|
+
// 控制骨架屏显隐
|
|
131
170
|
showSkeleton: true,
|
|
171
|
+
// 配置
|
|
132
172
|
config: undefined,
|
|
173
|
+
// 当前显示模式,编辑模式,预览模式
|
|
133
174
|
type: 'design',
|
|
175
|
+
// 仅供展示,不可编辑
|
|
134
176
|
onlyDisplay: false,
|
|
177
|
+
// 每行最大列数,非必要请勿更改,现在的设计器完全是基于每行12列来设计的
|
|
135
178
|
maxColSpan: 12,
|
|
136
179
|
// 定义是否完成配置的扫描,未完成不要渲染子组件
|
|
137
180
|
scanFinish: false,
|
|
@@ -142,12 +185,20 @@ export default {
|
|
|
142
185
|
originalConfig: null,
|
|
143
186
|
// 扫描到的配置
|
|
144
187
|
configFromWeb: {},
|
|
188
|
+
// 用于获取配置的锁
|
|
145
189
|
timer: undefined,
|
|
190
|
+
// 是否包含图片
|
|
146
191
|
hasImages: false,
|
|
147
|
-
|
|
192
|
+
// 图片列表
|
|
193
|
+
imageList: [],
|
|
194
|
+
// 保存最原始的数据,用于判断哪些数据被更改了
|
|
195
|
+
dataCache: undefined,
|
|
196
|
+
// 判断哪些数据被更改了,存储对应的key
|
|
197
|
+
diff: []
|
|
148
198
|
}
|
|
149
199
|
},
|
|
150
200
|
watch: {
|
|
201
|
+
// 如果配置名更改了,重新获取配置
|
|
151
202
|
configName (val) {
|
|
152
203
|
if (val) {
|
|
153
204
|
getConfigByName(this.configName, undefined, res => {
|
|
@@ -156,6 +207,7 @@ export default {
|
|
|
156
207
|
})
|
|
157
208
|
}
|
|
158
209
|
},
|
|
210
|
+
// 如果本地配置更改了,重新初始化
|
|
159
211
|
localConfig (val) {
|
|
160
212
|
if (val) {
|
|
161
213
|
this.config = val
|
|
@@ -164,13 +216,71 @@ export default {
|
|
|
164
216
|
}
|
|
165
217
|
},
|
|
166
218
|
methods: {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
219
|
+
// 向外暴露图片修改后的数据,某些外部需要自己管理图片的保存与修改
|
|
220
|
+
updateImg (data) {
|
|
221
|
+
this.$emit('updateImg', data)
|
|
222
|
+
},
|
|
223
|
+
// 导出数据,某些外部需要统一控制数据的变动
|
|
224
|
+
exportData () {
|
|
225
|
+
// 获取当前修改后的数据
|
|
226
|
+
let tempData
|
|
227
|
+
if (this.activeConfig === undefined || this.activeConfig === null) {
|
|
228
|
+
tempData = this.originalConfig.data
|
|
229
|
+
} else {
|
|
230
|
+
const tempDataKeys = Object.keys(this.activeConfig.tempData)
|
|
231
|
+
tempDataKeys.forEach(key => {
|
|
232
|
+
this.changeDeepObject(this.activeConfig.data, key, this.activeConfig.tempData[key])
|
|
233
|
+
})
|
|
234
|
+
tempData = this.activeConfig.data
|
|
235
|
+
}
|
|
236
|
+
// 对比数据的差异
|
|
237
|
+
this.diff = []
|
|
238
|
+
this.compareProps(tempData, this.dataCache)
|
|
239
|
+
this.diff.forEach(eachDiff => {
|
|
240
|
+
const arr = eachDiff.split('.')
|
|
241
|
+
let targetData = tempData[arr[0]]
|
|
242
|
+
if (arr.length !== 1) {
|
|
243
|
+
for (let i = 1; i < arr.length - 1; i++) {
|
|
244
|
+
const path = arr[i]
|
|
245
|
+
targetData = targetData[path]
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// 将修改的数据,添加update = true属性
|
|
249
|
+
targetData.update = true
|
|
171
250
|
})
|
|
172
|
-
|
|
251
|
+
return tempData
|
|
252
|
+
},
|
|
253
|
+
// 对比两个obj有哪里不同
|
|
254
|
+
compareProps (obj1, obj2, path = '') {
|
|
255
|
+
for (const key in obj1) {
|
|
256
|
+
// 如果一个是undefined
|
|
257
|
+
if (typeof obj2[key] === 'undefined') {
|
|
258
|
+
this.diff.push(path + key)
|
|
259
|
+
// 如果是数组长度不一样
|
|
260
|
+
} else if (obj1[key].length !== obj2[key].length) {
|
|
261
|
+
this.diff.push(path + key)
|
|
262
|
+
// 如果都是对象,并且存在同样的key,递归子key
|
|
263
|
+
} else if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
|
|
264
|
+
this.compareProps(obj1[key], obj2[key], path + key + '.')
|
|
265
|
+
// 如果不是obj,对比其数据
|
|
266
|
+
} else if (obj1[key] !== obj2[key]) {
|
|
267
|
+
this.diff.push(path + key)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
// 正常的保存方法,当前修改内容会直接全部导出到外部
|
|
272
|
+
saveConfig () {
|
|
273
|
+
if (this.activeConfig === undefined || this.activeConfig === null) {
|
|
274
|
+
return this.originalConfig.data
|
|
275
|
+
} else {
|
|
276
|
+
const tempDataKeys = Object.keys(this.activeConfig.tempData)
|
|
277
|
+
tempDataKeys.forEach(key => {
|
|
278
|
+
this.changeDeepObject(this.activeConfig.data, key, this.activeConfig.tempData[key])
|
|
279
|
+
})
|
|
280
|
+
this.$emit('saveConfig', this.$refs.XReportDesign.activatedConfig)
|
|
281
|
+
}
|
|
173
282
|
},
|
|
283
|
+
// 通过@@@分割临时变量,找到对应的key,并修改它的值
|
|
174
284
|
changeDeepObject (obj, strPath, newVal) {
|
|
175
285
|
const arr = strPath.split('@@@')
|
|
176
286
|
if (obj[arr[0]] === undefined) {
|
|
@@ -302,6 +412,7 @@ export default {
|
|
|
302
412
|
this.config.columns = newArr
|
|
303
413
|
}
|
|
304
414
|
},
|
|
415
|
+
// 路径中含有@@@的key,将其解析,并返回其数据
|
|
305
416
|
getDeepObject (obj, strPath) {
|
|
306
417
|
const arr = strPath.split('@@@')
|
|
307
418
|
let result = obj[arr[0]]
|
|
@@ -566,6 +677,7 @@ export default {
|
|
|
566
677
|
})
|
|
567
678
|
})
|
|
568
679
|
|
|
680
|
+
// 使用定时器循环判断锁状态,用于多个插槽,要等待统一获取完成之后,再进行下一步初始化
|
|
569
681
|
const timer = setInterval(() => {
|
|
570
682
|
console.log('插槽下载进度,当前:' + count + '/' + total)
|
|
571
683
|
if (count >= total) {
|
|
@@ -592,14 +704,18 @@ export default {
|
|
|
592
704
|
},
|
|
593
705
|
// 获取配置之后的初始化
|
|
594
706
|
configInit () {
|
|
707
|
+
// 上锁,等待所有配置获取完成
|
|
595
708
|
const lock = { status: true }
|
|
596
709
|
|
|
710
|
+
// 获取插槽
|
|
597
711
|
this.getConfigAndJoin(this.config, lock)
|
|
598
712
|
|
|
713
|
+
// 用定时器循环查看锁状态
|
|
599
714
|
this.timer = setInterval(() => {
|
|
600
715
|
if (!lock.status) {
|
|
601
716
|
clearInterval(this.timer)
|
|
602
717
|
console.log('拼接完成', this.config)
|
|
718
|
+
// 将初始化好的配置拷贝一份留存
|
|
603
719
|
this.originalConfig = Object.assign({}, this.config)
|
|
604
720
|
if (!this.dontFormat) {
|
|
605
721
|
// 扫描配置文件中有没有rowSpan,进行格式化调整
|
|
@@ -607,18 +723,23 @@ export default {
|
|
|
607
723
|
}
|
|
608
724
|
this.activeConfig = this.config
|
|
609
725
|
this.showSkeleton = false
|
|
726
|
+
// 判断是否有动态Index
|
|
610
727
|
this.activeConfig.columns.forEach(row => {
|
|
611
728
|
row.forEach(cell => {
|
|
612
729
|
if (cell.dynamicDataIndex === true) {
|
|
730
|
+
// 如果有动态index,取其函数,运行函数得到真实index保存
|
|
613
731
|
// eslint-disable-next-line no-eval
|
|
614
732
|
const func = eval('(' + cell.customFunctionForDynamicDataIndex + ')')
|
|
615
733
|
cell.dataIndex = func(this.config)
|
|
616
734
|
}
|
|
617
735
|
})
|
|
618
736
|
})
|
|
737
|
+
// 将数据复制到临时数据中,带有@@@的数据,我们将其整体作为一个key保存,当编辑完成后,再将其解析,回填到需要的数据中
|
|
619
738
|
this.activeConfig.tempData = {}
|
|
739
|
+
// 是否有@@@深层引用
|
|
620
740
|
this.activeConfig.columns.forEach(row => {
|
|
621
741
|
row.forEach(cell => {
|
|
742
|
+
// 将@@@解析
|
|
622
743
|
if (cell.dataIndex !== undefined && cell.dataIndex.indexOf('@@@') !== -1) {
|
|
623
744
|
this.activeConfig.tempData[cell.dataIndex] = this.getDeepObject(this.activeConfig.data, cell.dataIndex)
|
|
624
745
|
}
|
|
@@ -638,7 +759,7 @@ export default {
|
|
|
638
759
|
this.originalConfig = Object.assign({}, this.config)
|
|
639
760
|
this.originalConfig.data = JSON.parse(JSON.stringify(this.configData))
|
|
640
761
|
this.type = 'display'
|
|
641
|
-
this.onlyDisplay = true
|
|
762
|
+
// this.onlyDisplay = true
|
|
642
763
|
this.showSkeleton = false
|
|
643
764
|
this.$nextTick(() => {
|
|
644
765
|
this.scanFinish = true
|
|
@@ -647,11 +768,14 @@ export default {
|
|
|
647
768
|
},
|
|
648
769
|
},
|
|
649
770
|
beforeMount () {
|
|
771
|
+
// 如果只是展示
|
|
650
772
|
if (this.displayOnly) {
|
|
651
773
|
this.onlyDisplay = true
|
|
652
774
|
this.type = 'display'
|
|
653
775
|
}
|
|
776
|
+
// 如果有本地配置,优先使用本地配置
|
|
654
777
|
if (this.localConfig) {
|
|
778
|
+
// 如果配置是json渲染器
|
|
655
779
|
if (this.localConfig.designMode === 'json') {
|
|
656
780
|
this.config = this.localConfig
|
|
657
781
|
if (this.configData !== undefined) {
|
|
@@ -659,6 +783,7 @@ export default {
|
|
|
659
783
|
}
|
|
660
784
|
this.jsonConfigInit()
|
|
661
785
|
} else {
|
|
786
|
+
// 如果配置是普通渲染器
|
|
662
787
|
this.config = this.localConfig
|
|
663
788
|
if (this.configData !== undefined) {
|
|
664
789
|
this.config.data = this.configData
|
|
@@ -669,6 +794,7 @@ export default {
|
|
|
669
794
|
this.configInit()
|
|
670
795
|
}
|
|
671
796
|
} else {
|
|
797
|
+
// 如果本地配置没有值,则从琉璃中获取
|
|
672
798
|
getConfigByName(this.configName, this.serverName, res => {
|
|
673
799
|
this.config = res
|
|
674
800
|
if (this.config.designMode === 'json') {
|
|
@@ -687,6 +813,14 @@ export default {
|
|
|
687
813
|
}
|
|
688
814
|
})
|
|
689
815
|
}
|
|
816
|
+
},
|
|
817
|
+
mounted () {
|
|
818
|
+
// 如果外界传来了registerMap,我们将本VM对象注册到map中
|
|
819
|
+
if (this.registerMap !== undefined) {
|
|
820
|
+
this.registerMap.push(this)
|
|
821
|
+
}
|
|
822
|
+
// 将原始数据备份保存
|
|
823
|
+
this.dataCache = JSON.parse(JSON.stringify(this.config.data))
|
|
690
824
|
}
|
|
691
825
|
}
|
|
692
826
|
</script>
|