af-mobile-client-vue3 1.0.85 → 1.0.86

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,597 +1,597 @@
1
- <script setup lang="ts">
2
- import { computed, onMounted, ref, watch } from 'vue'
3
-
4
- import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'
5
- import XReportTrGroup from './XReportTrGroup.vue'
6
- import XReportJsonRender from './XReportJsonRender.vue'
7
-
8
- // Props 类型定义
9
- interface Props {
10
- config: {
11
- data: Record<string, any>
12
- designMode?: string
13
- width?: number
14
- title?: string
15
- style?: Record<string, string>
16
- columns?: any[][]
17
- subTitle?: Array<{
18
- type: string
19
- text?: string
20
- format?: string
21
- dataIndex?: string
22
- inputWidth?: number
23
- inputReadOnly?: boolean
24
- }>
25
- }
26
- showImgInCell?: boolean
27
- forDisplay?: boolean
28
- serverName?: string
29
- env?: string
30
- displayOnly?: boolean
31
- slotConfigName?: string
32
- showImages?: boolean
33
- imageList?: any[]
34
- noPadding?: boolean
35
- noTopBorder?: boolean
36
- showTitle?: boolean
37
- useOssForImg?: boolean
38
- imgPrefix?: string
39
- }
40
-
41
- // Props
42
- const props = withDefaults(defineProps<Props>(), {
43
- serverName: 'af-system',
44
- env: 'prod',
45
- displayOnly: false,
46
- noPadding: true,
47
- noTopBorder: false,
48
- showTitle: true,
49
- useOssForImg: true,
50
- })
51
-
52
- // Emits
53
- const emit = defineEmits(['updateImg', 'selectRow', 'slotRendered'])
54
-
55
- // 注入
56
- const isWidget = false // inject('isWidget', false)
57
-
58
- // 状态
59
- const data = ref(props.config.data || {})
60
- const slotConfig = ref<any>()
61
- const render = ref(false)
62
- const activatedConfig = ref<any>({})
63
-
64
- // 计算属性
65
- const flexItemBodyState = computed(() => ({
66
- padding: isWidget ? '0px' : '24px',
67
- }))
68
-
69
- // 方法
70
- function slotRendered() {
71
- emit('slotRendered')
72
- }
73
-
74
- function updateImg(data: any) {
75
- emit('updateImg', data)
76
- }
77
-
78
- function selectRow(selectedRowKeys: any[], selectedRows: any[]) {
79
- console.log('XReportDesign')
80
- emit('selectRow', selectedRowKeys, selectedRows)
81
- }
82
-
83
- // 格式化相关方法
84
- function calcFormatInputNum(formatStr: string) {
85
- let count = 0
86
- for (let i = 0; i < formatStr.length; i++) {
87
- if (formatStr[i] === '{')
88
- count++
89
- }
90
- return count
91
- }
92
-
93
- function displayFormatText(formatStr: string, num: number) {
94
- let start = 0
95
- let count = 0
96
- num++
97
- for (let i = 0; i < formatStr.length; i++) {
98
- if (formatStr[i] === '}') {
99
- start = i
100
- count++
101
- }
102
- if (count === num) {
103
- for (let j = start + 1; j < formatStr.length; j++) {
104
- if (formatStr[j] === '{')
105
- return formatStr.slice(start + 1, j)
106
-
107
- if (j === formatStr.length - 1 && formatStr[j] !== '}')
108
- return formatStr[j]
109
- }
110
- }
111
- }
112
- }
113
-
114
- function displayFormatStartText(formatStr: string) {
115
- let count = 0
116
- for (let i = 0; i < formatStr.length; i++) {
117
- if (formatStr[i] === '{')
118
- break
119
- count++
120
- }
121
- return formatStr.slice(0, count)
122
- }
123
-
124
- // 生命周期
125
- onMounted(() => {
126
- console.log('>>>> xreportdesign 渲染')
127
- if (props.slotConfigName) {
128
- getConfigByName(props.slotConfigName, (res: any) => {
129
- slotConfig.value = res
130
- res.data = { ...res.data, ...data.value }
131
- props.config.data = res.data
132
- activatedConfig.value = res
133
- render.value = true
134
- }, props.serverName)
135
- }
136
- else {
137
- activatedConfig.value = props.config
138
- render.value = true
139
- }
140
-
141
- if (activatedConfig.value.designMode !== 'json') {
142
- activatedConfig.value.columns?.forEach((row: any[]) => {
143
- if (row[0]?.type === 'list' && row[0]?.listLength === 1) {
144
- row.forEach((cell) => {
145
- cell.listLength = activatedConfig.value.data[cell.dataIndex].length
146
- })
147
- }
148
- })
149
- }
150
- })
151
-
152
- // 监听
153
- watch(() => props.config, (newVal) => {
154
- // 配置变化时的处理
155
- }, { deep: true })
156
-
157
- watch(() => activatedConfig.value, (val) => {
158
- console.log('>>>> activatedConfig: ', val)
159
- })
160
- </script>
161
-
162
- <template>
163
- <div id="xreportdesign">
164
- <template v-if="activatedConfig.designMode === 'json'">
165
- <XReportJsonRender
166
- :img-prefix="imgPrefix"
167
- :server-name="serverName"
168
- :display-only="displayOnly"
169
- :show-title="showTitle"
170
- :no-padding="noPadding"
171
- :no-top-border="noTopBorder"
172
- :config="activatedConfig"
173
- @update-img="updateImg"
174
- @select-row="selectRow"
175
- />
176
- </template>
177
- <template v-else-if="isWidget">
178
- <template v-for="(row, rowIndex) in activatedConfig.columns">
179
- <!-- 插槽展示 -->
180
- <template v-if="row[0].type === 'slot'">
181
- <XReportTrGroup
182
- :show-img-in-cell="showImgInCell"
183
- :img-prefix="imgPrefix"
184
- :server-name="serverName"
185
- :env="env"
186
- :key="rowIndex"
187
- :use-oss-for-img="useOssForImg"
188
- :columns="row"
189
- @update-img="updateImg"
190
- :no-top-border="noTopBorder"
191
- @selectRow="selectRow"
192
- :config-data="activatedConfig.data"
193
- :config="activatedConfig"
194
- :display="true"
195
- />
196
- </template>
197
- <!-- 普通行 -->
198
- <template v-else>
199
- <template v-if="!forDisplay">
200
- <XReportTrGroup
201
- :show-img-in-cell="showImgInCell"
202
- :img-prefix="imgPrefix"
203
- :server-name="serverName"
204
- :env="env"
205
- :key="rowIndex"
206
- :use-oss-for-img="useOssForImg"
207
- :columns="row"
208
- @update-img="updateImg"
209
- :no-top-border="noTopBorder"
210
- @selectRow="selectRow"
211
- :config-data="activatedConfig.data"
212
- :config="activatedConfig"
213
- />
214
- </template>
215
- <template v-else>
216
- <XReportTrGroup
217
- :show-img-in-cell="showImgInCell"
218
- :img-prefix="imgPrefix"
219
- :server-name="serverName"
220
- :env="env"
221
- :use-oss-for-img="useOssForImg"
222
- :config="activatedConfig"
223
- :key="rowIndex"
224
- @update-img="updateImg"
225
- :columns="row"
226
- @selectRow="selectRow"
227
- :no-top-border="noTopBorder"
228
- :config-data="activatedConfig.data"
229
- :display="true"
230
- />
231
- </template>
232
- </template>
233
- </template>
234
- </template>
235
- <template v-else>
236
- <div :class=" noPadding ? 'reportMainNoPadding' : 'reportMain'" :style="activatedConfig.width > 0 ? (`width:${activatedConfig.width}px`) : undefined">
237
- <!-- 大标题 -->
238
- <h2 v-if="showTitle && activatedConfig.title" class="reportTitle" v-html="activatedConfig.title" />
239
- <!-- 小标题 / 介乎于标题与表格之间的内容 -->
240
- <div v-if="activatedConfig.subTitle && activatedConfig.subTitle.length" class="subTitle">
241
- <div v-for="(item, itemIndex) in activatedConfig.subTitle" :key="itemIndex" class="subTitleItems">
242
- <template v-if="item.type === 'column'">
243
- <span>{{ item.text }}</span>
244
- </template>
245
- <template v-else-if="item.type === 'inputs'">
246
- <div class="inputsDiv">
247
- <div v-for="(num, index) of calcFormatInputNum(item.format)" :key="index" class="inputsDivItem">
248
- <span class="inputsDivItemLabel">{{ displayFormatStartText(item.format) }}</span>
249
- <template v-if="!forDisplay">
250
- <template v-if="item.inputReadOnly === true">
251
- <a-input v-model="data[item.dataIndex][index]" :style="`width:${item.inputWidth ? item.inputWidth : '100'}%`" :disabled="true" />
252
- </template>
253
- <template v-else>
254
- <a-input v-model="data[item.dataIndex][index]" :style="`width:${item.inputWidth ? item.inputWidth : '100'}%`" />
255
- </template>
256
- </template>
257
- <template v-else>
258
- {{ activatedConfig.data[item.dataIndex][index] }}
259
- </template>
260
- <span class="inputsDivItemLabel">{{ displayFormatText(item.format, index) }}</span>
261
- </div>
262
- </div>
263
- </template>
264
- </div>
265
- </div>
266
- <!-- 主体表格 -->
267
- <table v-if="render" class="reportTable" :style="activatedConfig.style ? activatedConfig.style : undefined">
268
- <tbody class="reportTable">
269
- <template v-for="(row, rowIndex) in activatedConfig.columns">
270
- <!-- 插槽展示 -->
271
- <template v-if="row[0].type === 'slot'">
272
- <XReportTrGroup
273
- :show-img-in-cell="showImgInCell"
274
- :img-prefix="imgPrefix"
275
- :server-name="serverName"
276
- :env="env"
277
- :use-oss-for-img="useOssForImg"
278
- @update-img="updateImg"
279
- :key="rowIndex"
280
- @select-row="selectRow"
281
- :columns="row"
282
- @slot-rendered="slotRendered"
283
- :no-top-border="noTopBorder"
284
- :config-data="activatedConfig.data"
285
- :config="activatedConfig"
286
- :display="true"
287
- />
288
- </template>
289
- <!-- 列表 list -->
290
- <template v-else-if="row[0].type === 'list'">
291
- <template v-for="(num, listIndex) in row[0].listLength + 1">
292
- <template v-if="!forDisplay">
293
- <XReportTrGroup
294
- :show-img-in-cell="showImgInCell"
295
- :img-prefix="imgPrefix"
296
- :server-name="serverName"
297
- :env="env"
298
- :use-oss-for-img="useOssForImg"
299
- @slot-rendered="slotRendered"
300
- :config="activatedConfig"
301
- @update-img="updateImg"
302
- :key="rowIndex + listIndex"
303
- @select-row="selectRow"
304
- :columns="row"
305
- :no-top-border="noTopBorder"
306
- :config-data="activatedConfig.data"
307
- :list-index="listIndex"
308
- />
309
- </template>
310
- <template v-else>
311
- <XReportTrGroup
312
- :show-img-in-cell="showImgInCell"
313
- :img-prefix="imgPrefix"
314
- :server-name="serverName"
315
- :env="env"
316
- :use-oss-for-img="useOssForImg"
317
- @slot-rendered="slotRendered"
318
- :config="activatedConfig"
319
- @update-img="updateImg"
320
- :key="rowIndex + listIndex"
321
- @select-row="selectRow"
322
- :columns="row"
323
- :no-top-border="noTopBorder"
324
- :config-data="activatedConfig.data"
325
- :list-index="listIndex"
326
- :display="true"
327
- />
328
- </template>
329
- </template>
330
- </template>
331
- <!-- 动态行 inputColumns -->
332
- <template v-else-if="row[0].type === 'inputColumns'">
333
- <template v-if="forDisplay">
334
- <XReportTrGroup
335
- :show-img-in-cell="showImgInCell"
336
- :img-prefix="imgPrefix"
337
- :server-name="serverName"
338
- :env="env"
339
- :use-oss-for-img="useOssForImg"
340
- @slot-rendered="slotRendered"
341
- :config="activatedConfig"
342
- @update-img="updateImg"
343
- :columns="row[0].definition"
344
- @select-row="selectRow"
345
- :config-data="{ arr: activatedConfig.data[row[0].dataIndex] }"
346
- :input-columns="true"
347
- :no-top-border="noTopBorder"
348
- v-for="(item, definitionIndex) in activatedConfig.data[row[0].dataIndex]"
349
- :input-columns-definition-index="definitionIndex"
350
- :display="true"
351
- :key="row[0].dataIndex + definitionIndex + rowIndex"
352
- />
353
- </template>
354
- <template v-if="!forDisplay">
355
- <XReportTrGroup
356
- :show-img-in-cell="showImgInCell"
357
- :img-prefix="imgPrefix"
358
- :server-name="serverName"
359
- :env="env"
360
- :use-oss-for-img="useOssForImg"
361
- @slot-rendered="slotRendered"
362
- :config="activatedConfig"
363
- @update-img="updateImg"
364
- :columns="row[0].definition"
365
- @select-row="selectRow"
366
- :config-data="{ arr: activatedConfig.data[row[0].dataIndex] }"
367
- :input-columns="true"
368
- :no-top-border="noTopBorder"
369
- v-for="(item, definitionIndex) in activatedConfig.data[row[0].dataIndex]"
370
- :input-columns-definition-index="definitionIndex"
371
- :key="row[0].dataIndex + definitionIndex + rowIndex"
372
- />
373
- <!-- 动态行交互按钮 -->
374
- <XReportTrGroup
375
- :show-img-in-cell="showImgInCell"
376
- :img-prefix="imgPrefix"
377
- :server-name="serverName"
378
- :env="env"
379
- :use-oss-for-img="useOssForImg"
380
- @slot-rendered="slotRendered"
381
- :config="activatedConfig"
382
- @update-img="updateImg"
383
- :key="rowIndex"
384
- @select-row="selectRow"
385
- :columns="row"
386
- :no-top-border="noTopBorder"
387
- :config-data="activatedConfig.data"
388
- :input-columns-button="true"
389
- :input-columns="true"
390
- />
391
- </template>
392
- </template>
393
- <!-- 普通行 -->
394
- <template v-else>
395
- <template v-if="!forDisplay">
396
- <XReportTrGroup
397
- :show-img-in-cell="showImgInCell"
398
- :img-prefix="imgPrefix"
399
- :server-name="serverName"
400
- :env="env"
401
- :use-oss-for-img="useOssForImg"
402
- @slot-rendered="slotRendered"
403
- :key="rowIndex"
404
- @update-img="updateImg"
405
- :columns="row"
406
- @select-row="selectRow"
407
- :no-top-border="noTopBorder"
408
- :config-data="activatedConfig.data"
409
- :config="activatedConfig"
410
- />
411
- </template>
412
- <template v-else>
413
- <XReportTrGroup
414
- :show-img-in-cell="showImgInCell"
415
- :img-prefix="imgPrefix"
416
- :server-name="serverName"
417
- :env="env"
418
- :use-oss-for-img="useOssForImg"
419
- @slot-rendered="slotRendered"
420
- :config="activatedConfig"
421
- @update-img="updateImg"
422
- :key="rowIndex"
423
- @select-row="selectRow"
424
- :columns="row"
425
- :no-top-border="noTopBorder"
426
- :config-data="activatedConfig.data"
427
- :display="true"
428
- />
429
- </template>
430
- </template>
431
- </template>
432
- </tbody>
433
- </table>
434
- <div v-if="showImages" style="margin-top: 5%; display: flex;margin-bottom: 5%">
435
- <p>图片:</p>
436
- <div v-for="(img, imgIndex) in imageList" :key="imgIndex" style="margin-left: 3%;width: 200px">
437
- <img :src="img.url" class="img" :alt="img.name">
438
- <p style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;width: 100%;">
439
- {{ img.name }}
440
- </p>
441
- </div>
442
- </div>
443
- </div>
444
- </template>
445
- </div>
446
- </template>
447
-
448
- <style lang="less" scoped>
449
- .img{
450
- width: 95%;
451
- height: 180px;
452
- object-fit: cover;
453
- }
454
- .reportMain {
455
- text-align: center;
456
- margin: 0 auto;
457
- font-size: 16px;
458
- color: #000;
459
- background-color: #fff;
460
- border-radius: 8px;
461
-
462
- .reportTitle {
463
- font-weight: bold;
464
- }
465
-
466
- .subTitle {
467
- display: flex;
468
- justify-content: space-between;
469
- margin-bottom: 1%;
470
-
471
- .subTitleItems {
472
- max-width: 30%;
473
- }
474
- }
475
-
476
- .inputsDiv {
477
- display: flex;
478
- justify-content: space-between;
479
- .inputsDivItem {
480
- display: flex;
481
- align-items: center;
482
- padding: 0 4px;
483
- white-space: nowrap;
484
- .inputsDivItemLabel {
485
- padding: 0 4px;
486
- }
487
- }
488
- }
489
-
490
- .reportTable {
491
- width: 100%;
492
- border-collapse: collapse;
493
- table-layout:fixed;
494
- word-break:break-all;
495
- }
496
- }
497
- .reportMainForDisplay {
498
- text-align: center;
499
- margin: 10% auto;
500
- font-size: 16px;
501
- color: #000;
502
- background-color: #fff;
503
- border-radius: 8px;
504
-
505
- .reportTitle {
506
- font-weight: bold;
507
- }
508
-
509
- .subTitle {
510
- display: flex;
511
- justify-content: space-between;
512
-
513
- .subTitleItems {
514
- max-width: 30%;
515
- }
516
- }
517
-
518
- .inputsDiv {
519
- display: flex;
520
- justify-content: space-around;
521
- .inputsDivItem {
522
- display: flex;
523
- align-items: center;
524
- padding: 0 4px;
525
- white-space: nowrap;
526
- .inputsDivItemLabel {
527
- padding: 0 4px;
528
- }
529
- }
530
- }
531
-
532
- .reportTable {
533
- width: 100%;
534
- border-collapse: collapse;
535
- table-layout:fixed;
536
- word-break:break-all;
537
- }
538
- }
539
- .reportMainNoPadding {
540
- // text-align: center;
541
- margin: 0 auto;
542
- font-size: 16px;
543
- color: #000;
544
- // background-color: #fff;
545
- border-radius: 8px;
546
- height: auto;
547
- min-height : 20vh;
548
- overflow-y: auto;
549
- overflow-x: hidden;
550
-
551
- .reportTitle {
552
- font-weight: bold;
553
- }
554
-
555
- .subTitle {
556
- display: flex;
557
- justify-content: space-between;
558
-
559
- .subTitleItems {
560
- max-width: 30%;
561
- }
562
- }
563
-
564
- .inputsDiv {
565
- display: flex;
566
- justify-content: space-between;
567
- .inputsDivItem {
568
- display: flex;
569
- align-items: center;
570
- padding: 0 4px;
571
- white-space: nowrap;
572
- .inputsDivItemLabel {
573
- padding: 0 4px;
574
- }
575
- }
576
- }
577
-
578
- .reportTable {
579
- width: 100%;
580
- border-collapse: collapse;
581
- table-layout:fixed;
582
- word-break:break-all;
583
- }
584
- }
585
- .tools{
586
- position: fixed;
587
- right: 2%;
588
- text-align: right;
589
- width: 60%;
590
- cursor: pointer;
591
- .toolsItem{
592
- width: 15%;
593
- margin-right: 3%;
594
- display: inline-block;
595
- }
596
- }
597
- </style>
1
+ <script setup lang="ts">
2
+ import { computed, onMounted, ref, watch } from 'vue'
3
+
4
+ import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'
5
+ import XReportTrGroup from './XReportTrGroup.vue'
6
+ import XReportJsonRender from './XReportJsonRender.vue'
7
+
8
+ // Props 类型定义
9
+ interface Props {
10
+ config: {
11
+ data: Record<string, any>
12
+ designMode?: string
13
+ width?: number
14
+ title?: string
15
+ style?: Record<string, string>
16
+ columns?: any[][]
17
+ subTitle?: Array<{
18
+ type: string
19
+ text?: string
20
+ format?: string
21
+ dataIndex?: string
22
+ inputWidth?: number
23
+ inputReadOnly?: boolean
24
+ }>
25
+ }
26
+ showImgInCell?: boolean
27
+ forDisplay?: boolean
28
+ serverName?: string
29
+ env?: string
30
+ displayOnly?: boolean
31
+ slotConfigName?: string
32
+ showImages?: boolean
33
+ imageList?: any[]
34
+ noPadding?: boolean
35
+ noTopBorder?: boolean
36
+ showTitle?: boolean
37
+ useOssForImg?: boolean
38
+ imgPrefix?: string
39
+ }
40
+
41
+ // Props
42
+ const props = withDefaults(defineProps<Props>(), {
43
+ serverName: 'af-system',
44
+ env: 'prod',
45
+ displayOnly: false,
46
+ noPadding: true,
47
+ noTopBorder: false,
48
+ showTitle: true,
49
+ useOssForImg: true,
50
+ })
51
+
52
+ // Emits
53
+ const emit = defineEmits(['updateImg', 'selectRow', 'slotRendered'])
54
+
55
+ // 注入
56
+ const isWidget = false // inject('isWidget', false)
57
+
58
+ // 状态
59
+ const data = ref(props.config.data || {})
60
+ const slotConfig = ref<any>()
61
+ const render = ref(false)
62
+ const activatedConfig = ref<any>({})
63
+
64
+ // 计算属性
65
+ const flexItemBodyState = computed(() => ({
66
+ padding: isWidget ? '0px' : '24px',
67
+ }))
68
+
69
+ // 方法
70
+ function slotRendered() {
71
+ emit('slotRendered')
72
+ }
73
+
74
+ function updateImg(data: any) {
75
+ emit('updateImg', data)
76
+ }
77
+
78
+ function selectRow(selectedRowKeys: any[], selectedRows: any[]) {
79
+ console.log('XReportDesign')
80
+ emit('selectRow', selectedRowKeys, selectedRows)
81
+ }
82
+
83
+ // 格式化相关方法
84
+ function calcFormatInputNum(formatStr: string) {
85
+ let count = 0
86
+ for (let i = 0; i < formatStr.length; i++) {
87
+ if (formatStr[i] === '{')
88
+ count++
89
+ }
90
+ return count
91
+ }
92
+
93
+ function displayFormatText(formatStr: string, num: number) {
94
+ let start = 0
95
+ let count = 0
96
+ num++
97
+ for (let i = 0; i < formatStr.length; i++) {
98
+ if (formatStr[i] === '}') {
99
+ start = i
100
+ count++
101
+ }
102
+ if (count === num) {
103
+ for (let j = start + 1; j < formatStr.length; j++) {
104
+ if (formatStr[j] === '{')
105
+ return formatStr.slice(start + 1, j)
106
+
107
+ if (j === formatStr.length - 1 && formatStr[j] !== '}')
108
+ return formatStr[j]
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ function displayFormatStartText(formatStr: string) {
115
+ let count = 0
116
+ for (let i = 0; i < formatStr.length; i++) {
117
+ if (formatStr[i] === '{')
118
+ break
119
+ count++
120
+ }
121
+ return formatStr.slice(0, count)
122
+ }
123
+
124
+ // 生命周期
125
+ onMounted(() => {
126
+ console.log('>>>> xreportdesign 渲染')
127
+ if (props.slotConfigName) {
128
+ getConfigByName(props.slotConfigName, (res: any) => {
129
+ slotConfig.value = res
130
+ res.data = { ...res.data, ...data.value }
131
+ props.config.data = res.data
132
+ activatedConfig.value = res
133
+ render.value = true
134
+ }, props.serverName)
135
+ }
136
+ else {
137
+ activatedConfig.value = props.config
138
+ render.value = true
139
+ }
140
+
141
+ if (activatedConfig.value.designMode !== 'json') {
142
+ activatedConfig.value.columns?.forEach((row: any[]) => {
143
+ if (row[0]?.type === 'list' && row[0]?.listLength === 1) {
144
+ row.forEach((cell) => {
145
+ cell.listLength = activatedConfig.value.data[cell.dataIndex].length
146
+ })
147
+ }
148
+ })
149
+ }
150
+ })
151
+
152
+ // 监听
153
+ watch(() => props.config, (newVal) => {
154
+ // 配置变化时的处理
155
+ }, { deep: true })
156
+
157
+ watch(() => activatedConfig.value, (val) => {
158
+ console.log('>>>> activatedConfig: ', val)
159
+ })
160
+ </script>
161
+
162
+ <template>
163
+ <div id="xreportdesign">
164
+ <template v-if="activatedConfig.designMode === 'json'">
165
+ <XReportJsonRender
166
+ :img-prefix="imgPrefix"
167
+ :server-name="serverName"
168
+ :display-only="displayOnly"
169
+ :show-title="showTitle"
170
+ :no-padding="noPadding"
171
+ :no-top-border="noTopBorder"
172
+ :config="activatedConfig"
173
+ @update-img="updateImg"
174
+ @select-row="selectRow"
175
+ />
176
+ </template>
177
+ <template v-else-if="isWidget">
178
+ <template v-for="(row, rowIndex) in activatedConfig.columns">
179
+ <!-- 插槽展示 -->
180
+ <template v-if="row[0].type === 'slot'">
181
+ <XReportTrGroup
182
+ :show-img-in-cell="showImgInCell"
183
+ :img-prefix="imgPrefix"
184
+ :server-name="serverName"
185
+ :env="env"
186
+ :key="rowIndex"
187
+ :use-oss-for-img="useOssForImg"
188
+ :columns="row"
189
+ @update-img="updateImg"
190
+ :no-top-border="noTopBorder"
191
+ @selectRow="selectRow"
192
+ :config-data="activatedConfig.data"
193
+ :config="activatedConfig"
194
+ :display="true"
195
+ />
196
+ </template>
197
+ <!-- 普通行 -->
198
+ <template v-else>
199
+ <template v-if="!forDisplay">
200
+ <XReportTrGroup
201
+ :show-img-in-cell="showImgInCell"
202
+ :img-prefix="imgPrefix"
203
+ :server-name="serverName"
204
+ :env="env"
205
+ :key="rowIndex"
206
+ :use-oss-for-img="useOssForImg"
207
+ :columns="row"
208
+ @update-img="updateImg"
209
+ :no-top-border="noTopBorder"
210
+ @selectRow="selectRow"
211
+ :config-data="activatedConfig.data"
212
+ :config="activatedConfig"
213
+ />
214
+ </template>
215
+ <template v-else>
216
+ <XReportTrGroup
217
+ :show-img-in-cell="showImgInCell"
218
+ :img-prefix="imgPrefix"
219
+ :server-name="serverName"
220
+ :env="env"
221
+ :use-oss-for-img="useOssForImg"
222
+ :config="activatedConfig"
223
+ :key="rowIndex"
224
+ @update-img="updateImg"
225
+ :columns="row"
226
+ @selectRow="selectRow"
227
+ :no-top-border="noTopBorder"
228
+ :config-data="activatedConfig.data"
229
+ :display="true"
230
+ />
231
+ </template>
232
+ </template>
233
+ </template>
234
+ </template>
235
+ <template v-else>
236
+ <div :class=" noPadding ? 'reportMainNoPadding' : 'reportMain'" :style="activatedConfig.width > 0 ? (`width:${activatedConfig.width}px`) : undefined">
237
+ <!-- 大标题 -->
238
+ <h2 v-if="showTitle && activatedConfig.title" class="reportTitle" v-html="activatedConfig.title" />
239
+ <!-- 小标题 / 介乎于标题与表格之间的内容 -->
240
+ <div v-if="activatedConfig.subTitle && activatedConfig.subTitle.length" class="subTitle">
241
+ <div v-for="(item, itemIndex) in activatedConfig.subTitle" :key="itemIndex" class="subTitleItems">
242
+ <template v-if="item.type === 'column'">
243
+ <span>{{ item.text }}</span>
244
+ </template>
245
+ <template v-else-if="item.type === 'inputs'">
246
+ <div class="inputsDiv">
247
+ <div v-for="(num, index) of calcFormatInputNum(item.format)" :key="index" class="inputsDivItem">
248
+ <span class="inputsDivItemLabel">{{ displayFormatStartText(item.format) }}</span>
249
+ <template v-if="!forDisplay">
250
+ <template v-if="item.inputReadOnly === true">
251
+ <a-input v-model="data[item.dataIndex][index]" :style="`width:${item.inputWidth ? item.inputWidth : '100'}%`" :disabled="true" />
252
+ </template>
253
+ <template v-else>
254
+ <a-input v-model="data[item.dataIndex][index]" :style="`width:${item.inputWidth ? item.inputWidth : '100'}%`" />
255
+ </template>
256
+ </template>
257
+ <template v-else>
258
+ {{ activatedConfig.data[item.dataIndex][index] }}
259
+ </template>
260
+ <span class="inputsDivItemLabel">{{ displayFormatText(item.format, index) }}</span>
261
+ </div>
262
+ </div>
263
+ </template>
264
+ </div>
265
+ </div>
266
+ <!-- 主体表格 -->
267
+ <table v-if="render" class="reportTable" :style="activatedConfig.style ? activatedConfig.style : undefined">
268
+ <tbody class="reportTable">
269
+ <template v-for="(row, rowIndex) in activatedConfig.columns">
270
+ <!-- 插槽展示 -->
271
+ <template v-if="row[0].type === 'slot'">
272
+ <XReportTrGroup
273
+ :show-img-in-cell="showImgInCell"
274
+ :img-prefix="imgPrefix"
275
+ :server-name="serverName"
276
+ :env="env"
277
+ :use-oss-for-img="useOssForImg"
278
+ @update-img="updateImg"
279
+ :key="rowIndex"
280
+ @select-row="selectRow"
281
+ :columns="row"
282
+ @slot-rendered="slotRendered"
283
+ :no-top-border="noTopBorder"
284
+ :config-data="activatedConfig.data"
285
+ :config="activatedConfig"
286
+ :display="true"
287
+ />
288
+ </template>
289
+ <!-- 列表 list -->
290
+ <template v-else-if="row[0].type === 'list'">
291
+ <template v-for="(num, listIndex) in row[0].listLength + 1">
292
+ <template v-if="!forDisplay">
293
+ <XReportTrGroup
294
+ :show-img-in-cell="showImgInCell"
295
+ :img-prefix="imgPrefix"
296
+ :server-name="serverName"
297
+ :env="env"
298
+ :use-oss-for-img="useOssForImg"
299
+ @slot-rendered="slotRendered"
300
+ :config="activatedConfig"
301
+ @update-img="updateImg"
302
+ :key="rowIndex + listIndex"
303
+ @select-row="selectRow"
304
+ :columns="row"
305
+ :no-top-border="noTopBorder"
306
+ :config-data="activatedConfig.data"
307
+ :list-index="listIndex"
308
+ />
309
+ </template>
310
+ <template v-else>
311
+ <XReportTrGroup
312
+ :show-img-in-cell="showImgInCell"
313
+ :img-prefix="imgPrefix"
314
+ :server-name="serverName"
315
+ :env="env"
316
+ :use-oss-for-img="useOssForImg"
317
+ @slot-rendered="slotRendered"
318
+ :config="activatedConfig"
319
+ @update-img="updateImg"
320
+ :key="rowIndex + listIndex"
321
+ @select-row="selectRow"
322
+ :columns="row"
323
+ :no-top-border="noTopBorder"
324
+ :config-data="activatedConfig.data"
325
+ :list-index="listIndex"
326
+ :display="true"
327
+ />
328
+ </template>
329
+ </template>
330
+ </template>
331
+ <!-- 动态行 inputColumns -->
332
+ <template v-else-if="row[0].type === 'inputColumns'">
333
+ <template v-if="forDisplay">
334
+ <XReportTrGroup
335
+ :show-img-in-cell="showImgInCell"
336
+ :img-prefix="imgPrefix"
337
+ :server-name="serverName"
338
+ :env="env"
339
+ :use-oss-for-img="useOssForImg"
340
+ @slot-rendered="slotRendered"
341
+ :config="activatedConfig"
342
+ @update-img="updateImg"
343
+ :columns="row[0].definition"
344
+ @select-row="selectRow"
345
+ :config-data="{ arr: activatedConfig.data[row[0].dataIndex] }"
346
+ :input-columns="true"
347
+ :no-top-border="noTopBorder"
348
+ v-for="(item, definitionIndex) in activatedConfig.data[row[0].dataIndex]"
349
+ :input-columns-definition-index="definitionIndex"
350
+ :display="true"
351
+ :key="row[0].dataIndex + definitionIndex + rowIndex"
352
+ />
353
+ </template>
354
+ <template v-if="!forDisplay">
355
+ <XReportTrGroup
356
+ :show-img-in-cell="showImgInCell"
357
+ :img-prefix="imgPrefix"
358
+ :server-name="serverName"
359
+ :env="env"
360
+ :use-oss-for-img="useOssForImg"
361
+ @slot-rendered="slotRendered"
362
+ :config="activatedConfig"
363
+ @update-img="updateImg"
364
+ :columns="row[0].definition"
365
+ @select-row="selectRow"
366
+ :config-data="{ arr: activatedConfig.data[row[0].dataIndex] }"
367
+ :input-columns="true"
368
+ :no-top-border="noTopBorder"
369
+ v-for="(item, definitionIndex) in activatedConfig.data[row[0].dataIndex]"
370
+ :input-columns-definition-index="definitionIndex"
371
+ :key="row[0].dataIndex + definitionIndex + rowIndex"
372
+ />
373
+ <!-- 动态行交互按钮 -->
374
+ <XReportTrGroup
375
+ :show-img-in-cell="showImgInCell"
376
+ :img-prefix="imgPrefix"
377
+ :server-name="serverName"
378
+ :env="env"
379
+ :use-oss-for-img="useOssForImg"
380
+ @slot-rendered="slotRendered"
381
+ :config="activatedConfig"
382
+ @update-img="updateImg"
383
+ :key="rowIndex"
384
+ @select-row="selectRow"
385
+ :columns="row"
386
+ :no-top-border="noTopBorder"
387
+ :config-data="activatedConfig.data"
388
+ :input-columns-button="true"
389
+ :input-columns="true"
390
+ />
391
+ </template>
392
+ </template>
393
+ <!-- 普通行 -->
394
+ <template v-else>
395
+ <template v-if="!forDisplay">
396
+ <XReportTrGroup
397
+ :show-img-in-cell="showImgInCell"
398
+ :img-prefix="imgPrefix"
399
+ :server-name="serverName"
400
+ :env="env"
401
+ :use-oss-for-img="useOssForImg"
402
+ @slot-rendered="slotRendered"
403
+ :key="rowIndex"
404
+ @update-img="updateImg"
405
+ :columns="row"
406
+ @select-row="selectRow"
407
+ :no-top-border="noTopBorder"
408
+ :config-data="activatedConfig.data"
409
+ :config="activatedConfig"
410
+ />
411
+ </template>
412
+ <template v-else>
413
+ <XReportTrGroup
414
+ :show-img-in-cell="showImgInCell"
415
+ :img-prefix="imgPrefix"
416
+ :server-name="serverName"
417
+ :env="env"
418
+ :use-oss-for-img="useOssForImg"
419
+ @slot-rendered="slotRendered"
420
+ :config="activatedConfig"
421
+ @update-img="updateImg"
422
+ :key="rowIndex"
423
+ @select-row="selectRow"
424
+ :columns="row"
425
+ :no-top-border="noTopBorder"
426
+ :config-data="activatedConfig.data"
427
+ :display="true"
428
+ />
429
+ </template>
430
+ </template>
431
+ </template>
432
+ </tbody>
433
+ </table>
434
+ <div v-if="showImages" style="margin-top: 5%; display: flex;margin-bottom: 5%">
435
+ <p>图片:</p>
436
+ <div v-for="(img, imgIndex) in imageList" :key="imgIndex" style="margin-left: 3%;width: 200px">
437
+ <img :src="img.url" class="img" :alt="img.name">
438
+ <p style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;width: 100%;">
439
+ {{ img.name }}
440
+ </p>
441
+ </div>
442
+ </div>
443
+ </div>
444
+ </template>
445
+ </div>
446
+ </template>
447
+
448
+ <style lang="less" scoped>
449
+ .img{
450
+ width: 95%;
451
+ height: 180px;
452
+ object-fit: cover;
453
+ }
454
+ .reportMain {
455
+ text-align: center;
456
+ margin: 0 auto;
457
+ font-size: 16px;
458
+ color: #000;
459
+ background-color: #fff;
460
+ border-radius: 8px;
461
+
462
+ .reportTitle {
463
+ font-weight: bold;
464
+ }
465
+
466
+ .subTitle {
467
+ display: flex;
468
+ justify-content: space-between;
469
+ margin-bottom: 1%;
470
+
471
+ .subTitleItems {
472
+ max-width: 30%;
473
+ }
474
+ }
475
+
476
+ .inputsDiv {
477
+ display: flex;
478
+ justify-content: space-between;
479
+ .inputsDivItem {
480
+ display: flex;
481
+ align-items: center;
482
+ padding: 0 4px;
483
+ white-space: nowrap;
484
+ .inputsDivItemLabel {
485
+ padding: 0 4px;
486
+ }
487
+ }
488
+ }
489
+
490
+ .reportTable {
491
+ width: 100%;
492
+ border-collapse: collapse;
493
+ table-layout:fixed;
494
+ word-break:break-all;
495
+ }
496
+ }
497
+ .reportMainForDisplay {
498
+ text-align: center;
499
+ margin: 10% auto;
500
+ font-size: 16px;
501
+ color: #000;
502
+ background-color: #fff;
503
+ border-radius: 8px;
504
+
505
+ .reportTitle {
506
+ font-weight: bold;
507
+ }
508
+
509
+ .subTitle {
510
+ display: flex;
511
+ justify-content: space-between;
512
+
513
+ .subTitleItems {
514
+ max-width: 30%;
515
+ }
516
+ }
517
+
518
+ .inputsDiv {
519
+ display: flex;
520
+ justify-content: space-around;
521
+ .inputsDivItem {
522
+ display: flex;
523
+ align-items: center;
524
+ padding: 0 4px;
525
+ white-space: nowrap;
526
+ .inputsDivItemLabel {
527
+ padding: 0 4px;
528
+ }
529
+ }
530
+ }
531
+
532
+ .reportTable {
533
+ width: 100%;
534
+ border-collapse: collapse;
535
+ table-layout:fixed;
536
+ word-break:break-all;
537
+ }
538
+ }
539
+ .reportMainNoPadding {
540
+ // text-align: center;
541
+ margin: 0 auto;
542
+ font-size: 16px;
543
+ color: #000;
544
+ // background-color: #fff;
545
+ border-radius: 8px;
546
+ height: auto;
547
+ min-height : 20vh;
548
+ overflow-y: auto;
549
+ overflow-x: hidden;
550
+
551
+ .reportTitle {
552
+ font-weight: bold;
553
+ }
554
+
555
+ .subTitle {
556
+ display: flex;
557
+ justify-content: space-between;
558
+
559
+ .subTitleItems {
560
+ max-width: 30%;
561
+ }
562
+ }
563
+
564
+ .inputsDiv {
565
+ display: flex;
566
+ justify-content: space-between;
567
+ .inputsDivItem {
568
+ display: flex;
569
+ align-items: center;
570
+ padding: 0 4px;
571
+ white-space: nowrap;
572
+ .inputsDivItemLabel {
573
+ padding: 0 4px;
574
+ }
575
+ }
576
+ }
577
+
578
+ .reportTable {
579
+ width: 100%;
580
+ border-collapse: collapse;
581
+ table-layout:fixed;
582
+ word-break:break-all;
583
+ }
584
+ }
585
+ .tools{
586
+ position: fixed;
587
+ right: 2%;
588
+ text-align: right;
589
+ width: 60%;
590
+ cursor: pointer;
591
+ .toolsItem{
592
+ width: 15%;
593
+ margin-right: 3%;
594
+ display: inline-block;
595
+ }
596
+ }
597
+ </style>