vue2-client 1.12.36 → 1.12.38

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,592 +1,601 @@
1
- <template>
2
- <div>
3
- <div v-if="render" class="XCard">
4
- <template v-for="(card, itemIndex) in data">
5
- <a-card
6
- :key="'card' + itemIndex"
7
- class="data-card"
8
- :class="{ 'card-clicked': card.isClicked }"
9
- >
10
- <div
11
- v-if="config && card[config.ribbon]"
12
- class="ribbon"
13
- :style="{ backgroundColor: getRibbonColor(card[config.ribbonColor]) }">
14
- {{ card[config.ribbon] }}
15
- </div>
16
- <!-- 自定义标题 -->
17
- <template #title>
18
- <div class="custom-title" @click="clickFooter(card, 'cardclick', itemIndex)">
19
- <a-tooltip placement="top">
20
- <template #title>{{ card[config.id] }}</template>
21
- <div class="title-id" v-if="card[config.id]">{{ card[config.id] }}</div>
22
- </a-tooltip>
23
- <div class="title-basic">
24
- <div class="title-main">
25
- <span class="title-name">{{ card[config.title] }}</span>
26
- <span class="title-info">{{ card[config.title2] }}</span>
27
- <span class="title-title3">{{ card[config.title3] }}</span>
28
- </div>
29
- <div class="additional-info" v-if="card[config.subtitle2] || card[config.subtitle3] || card[config.subtitle4]">
30
- <a-tooltip placement="top" v-if="card[config.subtitle2]">
31
- <template #title>{{ card[config.subtitle2] }}</template>
32
- <span class="subtitle2">{{ card[config.subtitle2] }}</span>
33
- </a-tooltip>
34
- <a-tooltip placement="top" v-if="card[config.subtitle3]">
35
- <template #title>{{ card[config.subtitle3] }}</template>
36
- <span class="subtitle3">{{ card[config.subtitle3] }}</span>
37
- </a-tooltip>
38
- <span class="subtitle4" v-if="card[config.subtitle4]">{{ card[config.subtitle4] }}</span>
39
- </div>
40
- </div>
41
- </div>
42
- </template>
43
- <!-- 主体 -->
44
- <div class="body" v-if="card[config.text] || (config.content && config.content.length > 0)">
45
- <div class="body-text" v-if="card[config.text]">
46
- <a-tooltip :title="card[config.text]">
47
- <span class="text-ellipsis">{{ card[config.text] }}</span>
48
- </a-tooltip>
49
- </div>
50
- <template v-for="(item, bodyIndex) in config.content" v-if="bodyIndex < 6">
51
- <div :key="'body' + bodyIndex" class="body-item">
52
- <span class="body-item-label">{{ item.label }}:</span>
53
- <template v-if="item.type === 'progress'">
54
- <div class="progress">
55
- <div class="progress-bar">
56
- <div class="progress-done" :style="'width:' + card[item.key] * 100 + '%;backgroundColor: ' + determineRatioColor(card[item.key] * 100)"></div>
57
- </div>
58
- </div>
59
- <div class="progress-num">{{ card[item.key] * 100 }}%</div>
60
- </template>
61
- <template v-else-if="item.type === 'custom' && tableColumns">
62
- <!-- 根据 tableColumns 显示自定义内容 -->
63
- <span v-for="column in tableColumns" v-if="column.dataIndex === item.key" :key="column.dataIndex">
64
- <template v-if="column.slotType === 'badge'">
65
- <x-badge
66
- :service-name="serviceName"
67
- :env="env"
68
- :dataCard="true"
69
- :badge-key="column.slotKeyMap"
70
- :value="card[item.key]" />
71
- </template>
72
- <template v-else>
73
- <slot :name="column.slots.customRender">{{ card[item.key] }}</slot>
74
- </template>
75
- </span>
76
- </template>
77
- <template v-else>
78
- <span class="body-item-value">{{ card[item.key] }}</span>
79
- </template>
80
- </div>
81
- <a-divider
82
- v-if="bodyIndex !== config.content.length - 1"
83
- dashed
84
- :key="'body' + bodyIndex + 'after'"
85
- class="body-split" />
86
- </template>
87
- </div>
88
- <!-- 下方按钮 -->
89
- <template #actions>
90
- <a-row align="middle" class="custom-actions" v-if="config && config.footer && config.footer.length > 0">
91
- <template v-for="(item, footerIndex) in config.footer">
92
- <a-col :key="'footer_' + footerIndex" class="footer-item" :span="11" @click="clickFooter(card, item.emit, itemIndex)">
93
- <span>
94
- <a-icon :type="item.icon" class="footer-icon" />
95
- <span>{{ item.label }}</span>
96
- </span>
97
- </a-col>
98
- <a-col
99
- v-if="footerIndex !== config.footer.length - 1"
100
- :span="1"
101
- :key="'footer_' + footerIndex + 'after'"
102
- class="footer-item-split">
103
- |
104
- </a-col>
105
- </template>
106
- </a-row>
107
- </template>
108
- </a-card>
109
- </template>
110
- </div>
111
- <div v-else>
112
- <a-skeleton />
113
- </div>
114
- <div v-if="this.showPagination">
115
- <a-divider />
116
- <a-pagination
117
- v-model="pageNum"
118
- style="float: right"
119
- :total="total"
120
- show-less-items
121
- :page-size="pageSize"
122
- :page-size-options="pageSizeOptions"
123
- show-size-changer
124
- @change="pageNumChange"
125
- :showTotal="paginationShowTotal"
126
- @showSizeChange="pageSizeChange">
127
- </a-pagination>
128
- </div>
129
- </div>
130
- </template>
131
-
132
- <script>
133
- import XBadge from '@vue2-client/base-client/components/common/XBadge'
134
-
135
- export default {
136
- name: 'XDataCard',
137
- components: {
138
- XBadge,
139
- },
140
- props: {
141
- // 卡片数据更新方法
142
- cardData: {
143
- type: Function,
144
- default: undefined
145
- },
146
- // 卡片的配置
147
- cardConfig: {
148
- type: Object,
149
- default: undefined
150
- },
151
- showPagination: {
152
- type: Boolean,
153
- default: false
154
- },
155
- // 临时
156
- testData: {
157
- type: Array,
158
- default: undefined
159
- },
160
- tableColumns: {
161
- type: Array,
162
- default: undefined
163
- },
164
- // 服务名称
165
- serviceName: undefined,
166
- // 当前环境
167
- env: {
168
- type: String,
169
- default: 'prod'
170
- },
171
- // pageSize参数
172
- prePageSize: {
173
- type: Number,
174
- default: undefined
175
- },
176
- // 初始是否加载数据
177
- createdQuery: {
178
- type: Boolean,
179
- default: false
180
- }
181
- },
182
- inject: ['getConfigByName'],
183
- data () {
184
- return {
185
- // 配置
186
- config: {},
187
- // 数据
188
- data: {},
189
- // 当前页码
190
- pageNum: 1,
191
- // 控制渲染
192
- render: true,
193
- // 分页大小
194
- pageSize: 10,
195
- // 分页大小选项
196
- pageSizeOptions: ['4', '6', '8', '10'],
197
- // 数据总数
198
- total: 0,
199
- activeCardIndex: null, // 新增:记录当前激活的卡片索引
200
- }
201
- },
202
- created () {
203
- // 根据参数初始化数据值
204
- if (this.prePageSize) {
205
- this.pageSize = this.prePageSize
206
- }
207
- },
208
- mounted () {
209
- // 配置初始化
210
- if (this.cardConfig) {
211
- this.config = this.cardConfig
212
- } else {
213
- this.config = {
214
- id: '未获取到配置',
215
- title: '未获取到配置',
216
- title2: '未获取到配置',
217
- title3: '未获取到配置',
218
- subtitle2: '未获取到配置',
219
- subtitle3: '未获取到配置',
220
- subtitle4: '未获取到配置',
221
- text: '未获取到配置',
222
- ribbon: '未获取到配置',
223
- ribbonColor: '未获取到配置',
224
- content: [
225
- {
226
- label: '未获取到配置',
227
- key: 'one'
228
- },
229
- {
230
- label: '未获取到配置',
231
- key: 'two'
232
- },
233
- {
234
- label: '未获取到配置',
235
- key: 'three'
236
- },
237
- {
238
- label: '未获取到配置',
239
- key: 'four'
240
- },
241
- {
242
- label: '未获取到配置',
243
- key: 'five'
244
- },
245
- {
246
- label: '未获取到配置',
247
- key: 'six',
248
- type: 'progress'
249
- }
250
- ],
251
- footer: [
252
- {
253
- icon: 'edit',
254
- label: '未获取到配置',
255
- emit: 'planEdit'
256
- },
257
- {
258
- icon: 'user',
259
- label: '未获取到配置',
260
- emit: 'user'
261
- }
262
- ]
263
- }
264
- console.warn(this.config)
265
- }
266
-
267
- // 数据初始化
268
- if (this.cardData) {
269
- // if (this.createdQuery) {
270
- // this.loadData()
271
- // }
272
- } else {
273
- this.data = {
274
- one: '未获取到配置',
275
- two: '未获取到配置',
276
- three: '未获取到配置',
277
- four: '未获取到配置',
278
- five: '未获取到配置',
279
- six: 70
280
- }
281
- }
282
- // 测试数据初始化
283
- if (this.testData) {
284
- this.data = this.testData
285
- }
286
- },
287
- methods: {
288
- // 根据比例计算出颜色
289
- determineRatioColor (ratio, isNum = false) {
290
- let result
291
- // 如果是数字,并且比例大于79,则将数字显示为黑色
292
- if (isNum && ratio > 79) {
293
- return 'rgb(0,0,0)'
294
- }
295
- if (ratio >= 90) {
296
- result = 'rgb( 1,245, 38 )'
297
- } else if (ratio >= 75) {
298
- result = 'rgb( 139,245, 0)'
299
- } else if (ratio >= 40) {
300
- result = 'rgb(245,163, 0)'
301
- } else if (ratio >= 20) {
302
- result = 'rgb(244, 96, 0)'
303
- } else {
304
- result = 'rgb(255, 0, 0)'
305
- }
306
- return result
307
- },
308
- // 点击按钮
309
- clickFooter (data, eventName, index) {
310
- if (eventName === 'cardclick') {
311
- this.$set(data, 'oldIndex', this.data.newIndex)
312
- this.$set(data, 'newIndex', index)
313
- // 清除所有卡片的点击状态
314
- if (this.data && Array.isArray(this.data)) {
315
- this.data.forEach(item => {
316
- if (item.isClicked) {
317
- this.$set(item, 'isClicked', false)
318
- }
319
- })
320
- }
321
- // 设置当前卡片的点击状态
322
- this.$set(data, 'isClicked', true)
323
- }
324
- this.$emit('cardEmit', data, eventName)
325
- },
326
- // 获取数据
327
- loadData () {
328
- this.render = false
329
- const parameter = Object.assign({
330
- querySummary: false, // 分页查询的情况不重新获取汇总数据
331
- pageNo: this.pageNum,
332
- pageSize: this.pageSize
333
- }
334
- )
335
- this.cardData(parameter).then(res => {
336
- this.data = res.data
337
- this.total = res.totalCount
338
- this.render = true
339
- })
340
- },
341
- // 页码改变
342
- pageNumChange (page, pageSize) {
343
- this.pageNum = page
344
- this.pageSize = pageSize
345
- this.loadData()
346
- },
347
- // 分页大小改变
348
- pageSizeChange (current, pageSize) {
349
- this.pageSize = pageSize
350
- this.loadData()
351
- },
352
- // 刷新
353
- refresh () {
354
- this.loadData()
355
- },
356
- // 分页前展示当前项和总数
357
- paginationShowTotal () {
358
- return `${(this.pageNum - 1) * this.pageSize + 1 } - ${ this.pageNum * this.pageSize } | 共 ${ this.total } 项`
359
- },
360
- getRibbonColor (color) {
361
- switch (color) {
362
- case 'red':
363
- return '#ff4d4f'
364
- case 'blue':
365
- return '#1890ff'
366
- case 'yellow':
367
- return '#fadb14'
368
- default:
369
- return '#ff4d4f' // 默认红色
370
- }
371
- }
372
- }
373
- }
374
- </script>
375
-
376
- <style lang="less" scoped>
377
- .hide-page-numbers /deep/ .ant-pagination-item,
378
- .hide-page-numbers /deep/ .ant-pagination-jump-next {
379
- display: none !important; /* 隐藏数字页码和多页跳转 */
380
- }
381
- .hide-page-numbers /deep/ .ant-pagination-prev,
382
- .hide-page-numbers /deep/ .ant-pagination-next {
383
- display: inline-block !important; /* 保留左右跳转按钮 */
384
- }
385
-
386
- .XCard {
387
- display: flex;
388
- flex-wrap: wrap;
389
- justify-content: flex-start;
390
- overflow-y: auto;
391
- overflow-x: hidden;
392
- max-height: 85vh;
393
- .data-card {
394
- width: 100%;
395
- max-width: 300px;
396
- border: 2px solid rgb(244,244,244);
397
- border-radius: 5px;
398
- margin: 2px;
399
- overflow: hidden;
400
-
401
- ::v-deep .ant-card-body {
402
- padding: 15px !important; // 使用 !important 确保样式覆盖
403
- }
404
-
405
- .header {
406
- width: 100%;
407
- background-color: rgb(244,244,244);
408
- padding: 5px 15px;
409
-
410
- span {
411
- font-weight: bold;
412
- font-size: 1.1em;
413
- }
414
- }
415
-
416
- .body {
417
- .body-text{
418
- width: 500px;
419
- font-weight: bold;
420
- font-size: 1.1em;
421
- .text-ellipsis{
422
- display: inline-block;
423
- max-width: 260px; /* 控制文本的最大宽度 */
424
- white-space: nowrap;
425
- overflow: hidden;
426
- text-overflow: ellipsis;
427
- }
428
- }
429
-
430
- .body-item {
431
- padding: 3px 5px;
432
- }
433
-
434
- .body-split {
435
- margin: 1px 0;
436
- }
437
-
438
- .body-item-label {
439
- color: rgba(117, 117, 117, 0.8);
440
- font-size: 0.95em;
441
- }
442
-
443
- .body-item-value {
444
- color: black;
445
- }
446
-
447
- .progress {
448
- display: inline-block;
449
- width: 60%;
450
- height: 60%;
451
- float: right;
452
- padding-right: 1.5%;
453
- margin-top: 0.5%;
454
-
455
- .progress-bar {
456
- width: 100%;
457
- height: 90%;
458
- display: inline-block;
459
- border-radius: 10%;
460
- background-color: rgba(212,217,218, 0.6);
461
-
462
- .progress-done {
463
- float: left;
464
- display: inline-block;
465
- height: 100%;
466
- border-radius: 10%;
467
- }
468
- }
469
- }
470
- .progress-num {
471
- position: relative;
472
- top: -83%;
473
- left: -3%;
474
- text-align: end;
475
- font-size: 0.9em;
476
- color: black;
477
- }
478
- }
479
-
480
- &.card-clicked {
481
- :deep(.ant-card-head) {
482
- background-color: #e6f7ff;
483
- transition: background-color 0.3s ease;
484
- }
485
- }
486
- }
487
-
488
- .custom-title {
489
- display: flex;
490
- align-items: center;
491
- gap: 12px;
492
-
493
- &:hover {
494
- cursor: pointer;
495
- }
496
-
497
- .title-id {
498
- flex-shrink: 0;
499
- width: 65px;
500
- color: #1890ff;
501
- font-size: 16px;
502
- font-weight: bold;
503
- padding: 4px 8px;
504
- border: 1px solid #1890ff;
505
- border-radius: 4px;
506
- line-height: 1.4;
507
- text-align: center;
508
- white-space: nowrap;
509
- overflow: hidden;
510
- text-overflow: ellipsis;
511
- }
512
-
513
- .title-basic {
514
- display: flex;
515
- flex-direction: column;
516
- flex-grow: 1;
517
-
518
- .subtitle2, .subtitle3 {
519
- display: inline-block;
520
- max-width: 50px; /* 固定宽度 */
521
- white-space: nowrap;
522
- overflow: hidden;
523
- text-overflow: ellipsis;
524
- }
525
-
526
- .title-main {
527
- display: flex;
528
- align-items: center;
529
- gap: 8px;
530
- .title-info {
531
- margin-left: 6px;
532
- color: #808080;
533
- }
534
- .title-title3 {
535
- color: #808080;
536
- }
537
- }
538
-
539
- .additional-info {
540
- display: flex;
541
- gap: 8px;
542
- font-size: 13px;
543
- color: #808080;
544
- .subtitle4 {
545
- color: rgba(0, 0, 255, 0.8);
546
- }
547
- }
548
- }
549
- }
550
-
551
- .ribbon {
552
- position: absolute;
553
- top: 16px;
554
- right: -6px;
555
- background-color: #ff4d4f;
556
- color: white;
557
- padding: 5px 25px;
558
- font-size: 12px;
559
- transform: rotate(45deg) translateX(30%);
560
- transform-origin: top right;
561
- z-index: 1;
562
- }
563
-
564
- .custom-actions {
565
- .footer-icon {
566
- margin-right: 5px;
567
- }
568
-
569
- .footer-item-split {
570
- color: rgba(220, 220, 220, 0.59);
571
- }
572
-
573
- .footer-item {
574
- color: rgba(117, 117, 117, 0.8);
575
- font-size: 1em;
576
- }
577
-
578
- .footer-item:hover {
579
- color: rgb( 24,144,255 );
580
- cursor: pointer;
581
- }
582
- }
583
- }
584
-
585
- .ellipsis {
586
- display: inline-block;
587
- max-width: 60px;
588
- white-space: nowrap;
589
- overflow: hidden;
590
- text-overflow: ellipsis;
591
- }
592
- </style>
1
+ <template>
2
+ <div>
3
+ <div v-if="render" class="XCard">
4
+ <template v-for="(card, itemIndex) in data">
5
+ <a-card
6
+ :key="'card' + itemIndex"
7
+ class="data-card"
8
+ :class="{ 'card-clicked': card.isClicked }"
9
+ >
10
+ <div
11
+ v-if="config && card[config.ribbon]"
12
+ class="ribbon"
13
+ :style="{ backgroundColor: getRibbonColor(card[config.ribbonColor]) }">
14
+ {{ card[config.ribbon] }}
15
+ </div>
16
+ <!-- 自定义标题 -->
17
+ <template #title>
18
+ <div class="custom-title" @click="clickFooter(card, 'cardclick', itemIndex)">
19
+ <a-tooltip placement="top">
20
+ <template #title>{{ card[config.id] }}</template>
21
+ <div class="title-id" v-if="card[config.id]">{{ card[config.id] }}</div>
22
+ </a-tooltip>
23
+ <div class="title-basic">
24
+ <div class="title-main">
25
+ <span class="title-name">{{ card[config.title] }}</span>
26
+ <span class="title-info">{{ card[config.title2] }}</span>
27
+ <span class="title-title3">{{ card[config.title3] }}</span>
28
+ </div>
29
+ <div class="additional-info" v-if="card[config.subtitle2] || card[config.subtitle3] || card[config.subtitle4]">
30
+ <a-tooltip placement="top" v-if="card[config.subtitle2]">
31
+ <template #title>{{ card[config.subtitle2] }}</template>
32
+ <span class="subtitle2">{{ card[config.subtitle2] }}</span>
33
+ </a-tooltip>
34
+ <a-tooltip placement="top" v-if="card[config.subtitle3]">
35
+ <template #title>{{ card[config.subtitle3] }}</template>
36
+ <span class="subtitle3">{{ card[config.subtitle3] }}</span>
37
+ </a-tooltip>
38
+ <span class="subtitle4" v-if="card[config.subtitle4]">{{ card[config.subtitle4] }}</span>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </template>
43
+ <!-- 主体 -->
44
+ <div class="body" v-if="card[config.text] || (config.content && config.content.length > 0)">
45
+ <div class="body-text" v-if="card[config.text]">
46
+ <a-tooltip :title="card[config.text]">
47
+ <span class="text-ellipsis">{{ card[config.text] }}</span>
48
+ </a-tooltip>
49
+ </div>
50
+ <template v-for="(item, bodyIndex) in config.content" v-if="bodyIndex < 6">
51
+ <div :key="'body' + bodyIndex" class="body-item">
52
+ <span class="body-item-label">{{ item.label }}:</span>
53
+ <template v-if="item.type === 'progress'">
54
+ <div class="progress">
55
+ <div class="progress-bar">
56
+ <div class="progress-done" :style="'width:' + card[item.key] * 100 + '%;backgroundColor: ' + determineRatioColor(card[item.key] * 100)"></div>
57
+ </div>
58
+ </div>
59
+ <div class="progress-num">{{ card[item.key] * 100 }}%</div>
60
+ </template>
61
+ <template v-else-if="item.type === 'custom' && tableColumns">
62
+ <!-- 根据 tableColumns 显示自定义内容 -->
63
+ <span v-for="column in tableColumns" v-if="column.dataIndex === item.key" :key="column.dataIndex">
64
+ <template v-if="column.slotType === 'badge'">
65
+ <x-badge
66
+ :service-name="serviceName"
67
+ :env="env"
68
+ :dataCard="true"
69
+ :badge-key="column.slotKeyMap"
70
+ :value="card[item.key]" />
71
+ </template>
72
+ <template v-else>
73
+ <slot :name="column.slots.customRender">{{ card[item.key] }}</slot>
74
+ </template>
75
+ </span>
76
+ </template>
77
+ <template v-else>
78
+ <span class="body-item-value">{{ card[item.key] }}</span>
79
+ </template>
80
+ </div>
81
+ <a-divider
82
+ v-if="bodyIndex !== config.content.length - 1"
83
+ dashed
84
+ :key="'body' + bodyIndex + 'after'"
85
+ class="body-split" />
86
+ </template>
87
+ </div>
88
+ <!-- 下方按钮 -->
89
+ <template #actions>
90
+ <a-row align="middle" class="custom-actions" v-if="config && config.footer && config.footer.length > 0">
91
+ <template v-for="(item, footerIndex) in config.footer">
92
+ <a-col :key="'footer_' + footerIndex" class="footer-item" :span="11" @click="clickFooter(card, item.emit, itemIndex)">
93
+ <span>
94
+ <a-icon :type="item.icon" class="footer-icon" />
95
+ <span>{{ item.label }}</span>
96
+ </span>
97
+ </a-col>
98
+ <a-col
99
+ v-if="footerIndex !== config.footer.length - 1"
100
+ :span="1"
101
+ :key="'footer_' + footerIndex + 'after'"
102
+ class="footer-item-split">
103
+ |
104
+ </a-col>
105
+ </template>
106
+ </a-row>
107
+ </template>
108
+ </a-card>
109
+ </template>
110
+ </div>
111
+ <div v-else>
112
+ <a-skeleton />
113
+ </div>
114
+ <div v-if="this.showPagination">
115
+ <a-divider />
116
+ <a-pagination
117
+ v-model="pageNum"
118
+ style="float: right"
119
+ :total="total"
120
+ show-less-items
121
+ :page-size="pageSize"
122
+ :page-size-options="pageSizeOptions"
123
+ show-size-changer
124
+ @change="pageNumChange"
125
+ :showTotal="paginationShowTotal"
126
+ @showSizeChange="pageSizeChange">
127
+ </a-pagination>
128
+ </div>
129
+ </div>
130
+ </template>
131
+
132
+ <script>
133
+ import XBadge from '@vue2-client/base-client/components/common/XBadge'
134
+
135
+ export default {
136
+ name: 'XDataCard',
137
+ components: {
138
+ XBadge,
139
+ },
140
+ props: {
141
+ // 卡片数据更新方法
142
+ cardData: {
143
+ type: Function,
144
+ default: undefined
145
+ },
146
+ // 卡片的配置
147
+ cardConfig: {
148
+ type: Object,
149
+ default: undefined
150
+ },
151
+ showPagination: {
152
+ type: Boolean,
153
+ default: false
154
+ },
155
+ // 临时
156
+ testData: {
157
+ type: Array,
158
+ default: undefined
159
+ },
160
+ tableColumns: {
161
+ type: Array,
162
+ default: undefined
163
+ },
164
+ // 服务名称
165
+ serviceName: undefined,
166
+ // 当前环境
167
+ env: {
168
+ type: String,
169
+ default: 'prod'
170
+ },
171
+ // pageSize参数
172
+ prePageSize: {
173
+ type: Number,
174
+ default: undefined
175
+ },
176
+ // 初始是否加载数据
177
+ createdQuery: {
178
+ type: Boolean,
179
+ default: false
180
+ }
181
+ },
182
+ inject: ['getConfigByName'],
183
+ data () {
184
+ return {
185
+ // 配置
186
+ config: {},
187
+ // 数据
188
+ data: {},
189
+ // 当前页码
190
+ pageNum: 1,
191
+ // 控制渲染
192
+ render: true,
193
+ // 分页大小
194
+ pageSize: 10,
195
+ // 分页大小选项
196
+ pageSizeOptions: ['4', '6', '8', '10'],
197
+ // 数据总数
198
+ total: 0,
199
+ activeCardIndex: null, // 新增:记录当前激活的卡片索引
200
+ // 混入插槽组件的数据
201
+ mixinData: {},
202
+ }
203
+ },
204
+ created () {
205
+ // 根据参数初始化数据值
206
+ if (this.prePageSize) {
207
+ this.pageSize = this.prePageSize
208
+ }
209
+ },
210
+ mounted () {
211
+ // 配置初始化
212
+ if (this.cardConfig) {
213
+ this.config = this.cardConfig
214
+ } else {
215
+ this.config = {
216
+ id: '未获取到配置',
217
+ title: '未获取到配置',
218
+ title2: '未获取到配置',
219
+ title3: '未获取到配置',
220
+ subtitle2: '未获取到配置',
221
+ subtitle3: '未获取到配置',
222
+ subtitle4: '未获取到配置',
223
+ text: '未获取到配置',
224
+ ribbon: '未获取到配置',
225
+ ribbonColor: '未获取到配置',
226
+ content: [
227
+ {
228
+ label: '未获取到配置',
229
+ key: 'one'
230
+ },
231
+ {
232
+ label: '未获取到配置',
233
+ key: 'two'
234
+ },
235
+ {
236
+ label: '未获取到配置',
237
+ key: 'three'
238
+ },
239
+ {
240
+ label: '未获取到配置',
241
+ key: 'four'
242
+ },
243
+ {
244
+ label: '未获取到配置',
245
+ key: 'five'
246
+ },
247
+ {
248
+ label: '未获取到配置',
249
+ key: 'six',
250
+ type: 'progress'
251
+ }
252
+ ],
253
+ footer: [
254
+ {
255
+ icon: 'edit',
256
+ label: '未获取到配置',
257
+ emit: 'planEdit'
258
+ },
259
+ {
260
+ icon: 'user',
261
+ label: '未获取到配置',
262
+ emit: 'user'
263
+ }
264
+ ]
265
+ }
266
+ console.warn(this.config)
267
+ }
268
+
269
+ // 数据初始化
270
+ if (this.cardData) {
271
+ // if (this.createdQuery) {
272
+ // this.loadData()
273
+ // }
274
+ } else {
275
+ this.data = {
276
+ one: '未获取到配置',
277
+ two: '未获取到配置',
278
+ three: '未获取到配置',
279
+ four: '未获取到配置',
280
+ five: '未获取到配置',
281
+ six: 70
282
+ }
283
+ }
284
+ // 测试数据初始化
285
+ if (this.testData) {
286
+ this.data = this.testData
287
+ }
288
+ },
289
+ methods: {
290
+ // 根据比例计算出颜色
291
+ determineRatioColor (ratio, isNum = false) {
292
+ let result
293
+ // 如果是数字,并且比例大于79,则将数字显示为黑色
294
+ if (isNum && ratio > 79) {
295
+ return 'rgb(0,0,0)'
296
+ }
297
+ if (ratio >= 90) {
298
+ result = 'rgb( 1,245, 38 )'
299
+ } else if (ratio >= 75) {
300
+ result = 'rgb( 139,245, 0)'
301
+ } else if (ratio >= 40) {
302
+ result = 'rgb(245,163, 0)'
303
+ } else if (ratio >= 20) {
304
+ result = 'rgb(244, 96, 0)'
305
+ } else {
306
+ result = 'rgb(255, 0, 0)'
307
+ }
308
+ return result
309
+ },
310
+ // 点击按钮
311
+ clickFooter (data, eventName, index) {
312
+ if (eventName === 'cardclick') {
313
+ // 先触发 beforeSwitch 事件
314
+ if (this.data && Array.isArray(this.data)) {
315
+ this.data.forEach(item => {
316
+ if (item.isClicked) {
317
+ // 对当前选中的卡片触发 beforeSwitch 事件
318
+ this.$emit('cardEmit', item, 'beforeSwitch')
319
+ }
320
+ })
321
+ }
322
+ // 清除所有卡片的点击状态
323
+ if (this.data && Array.isArray(this.data)) {
324
+ this.data.forEach(item => {
325
+ if (item.isClicked) {
326
+ this.$set(item, 'isClicked', false)
327
+ }
328
+ })
329
+ }
330
+ // 设置当前卡片的点击状态
331
+ this.$set(data, 'isClicked', true)
332
+ }
333
+ this.$emit('cardEmit', data, eventName)
334
+ },
335
+ // 获取数据
336
+ loadData () {
337
+ this.render = false
338
+ const parameter = Object.assign({
339
+ querySummary: false, // 分页查询的情况不重新获取汇总数据
340
+ pageNo: this.pageNum,
341
+ pageSize: this.pageSize
342
+ }
343
+ )
344
+ this.cardData(parameter).then(res => {
345
+ this.data = res.data
346
+ this.total = res.totalCount
347
+ this.render = true
348
+ })
349
+ },
350
+ // 页码改变
351
+ pageNumChange (page, pageSize) {
352
+ this.pageNum = page
353
+ this.pageSize = pageSize
354
+ this.loadData()
355
+ },
356
+ // 分页大小改变
357
+ pageSizeChange (current, pageSize) {
358
+ this.pageSize = pageSize
359
+ this.loadData()
360
+ },
361
+ // 刷新
362
+ refresh () {
363
+ this.loadData()
364
+ },
365
+ // 分页前展示当前项和总数
366
+ paginationShowTotal () {
367
+ return `${(this.pageNum - 1) * this.pageSize + 1 } - ${ this.pageNum * this.pageSize } | 共 ${ this.total } 项`
368
+ },
369
+ getRibbonColor (color) {
370
+ switch (color) {
371
+ case 'red':
372
+ return '#ff4d4f'
373
+ case 'blue':
374
+ return '#1890ff'
375
+ case 'yellow':
376
+ return '#fadb14'
377
+ default:
378
+ return '#ff4d4f' // 默认红色
379
+ }
380
+ }
381
+ }
382
+ }
383
+ </script>
384
+
385
+ <style lang="less" scoped>
386
+ .hide-page-numbers /deep/ .ant-pagination-item,
387
+ .hide-page-numbers /deep/ .ant-pagination-jump-next {
388
+ display: none !important; /* 隐藏数字页码和多页跳转 */
389
+ }
390
+ .hide-page-numbers /deep/ .ant-pagination-prev,
391
+ .hide-page-numbers /deep/ .ant-pagination-next {
392
+ display: inline-block !important; /* 保留左右跳转按钮 */
393
+ }
394
+
395
+ .XCard {
396
+ display: flex;
397
+ flex-wrap: wrap;
398
+ justify-content: flex-start;
399
+ overflow-y: auto;
400
+ overflow-x: hidden;
401
+ max-height: 85vh;
402
+ .data-card {
403
+ width: 100%;
404
+ max-width: 300px;
405
+ border: 2px solid rgb(244,244,244);
406
+ border-radius: 5px;
407
+ margin: 2px;
408
+ overflow: hidden;
409
+
410
+ ::v-deep .ant-card-body {
411
+ padding: 15px !important; // 使用 !important 确保样式覆盖
412
+ }
413
+
414
+ .header {
415
+ width: 100%;
416
+ background-color: rgb(244,244,244);
417
+ padding: 5px 15px;
418
+
419
+ span {
420
+ font-weight: bold;
421
+ font-size: 1.1em;
422
+ }
423
+ }
424
+
425
+ .body {
426
+ .body-text{
427
+ width: 500px;
428
+ font-weight: bold;
429
+ font-size: 1.1em;
430
+ .text-ellipsis{
431
+ display: inline-block;
432
+ max-width: 260px; /* 控制文本的最大宽度 */
433
+ white-space: nowrap;
434
+ overflow: hidden;
435
+ text-overflow: ellipsis;
436
+ }
437
+ }
438
+
439
+ .body-item {
440
+ padding: 3px 5px;
441
+ }
442
+
443
+ .body-split {
444
+ margin: 1px 0;
445
+ }
446
+
447
+ .body-item-label {
448
+ color: rgba(117, 117, 117, 0.8);
449
+ font-size: 0.95em;
450
+ }
451
+
452
+ .body-item-value {
453
+ color: black;
454
+ }
455
+
456
+ .progress {
457
+ display: inline-block;
458
+ width: 60%;
459
+ height: 60%;
460
+ float: right;
461
+ padding-right: 1.5%;
462
+ margin-top: 0.5%;
463
+
464
+ .progress-bar {
465
+ width: 100%;
466
+ height: 90%;
467
+ display: inline-block;
468
+ border-radius: 10%;
469
+ background-color: rgba(212,217,218, 0.6);
470
+
471
+ .progress-done {
472
+ float: left;
473
+ display: inline-block;
474
+ height: 100%;
475
+ border-radius: 10%;
476
+ }
477
+ }
478
+ }
479
+ .progress-num {
480
+ position: relative;
481
+ top: -83%;
482
+ left: -3%;
483
+ text-align: end;
484
+ font-size: 0.9em;
485
+ color: black;
486
+ }
487
+ }
488
+
489
+ &.card-clicked {
490
+ :deep(.ant-card-head) {
491
+ background-color: #e6f7ff;
492
+ transition: background-color 0.3s ease;
493
+ }
494
+ }
495
+ }
496
+
497
+ .custom-title {
498
+ display: flex;
499
+ align-items: center;
500
+ gap: 12px;
501
+
502
+ &:hover {
503
+ cursor: pointer;
504
+ }
505
+
506
+ .title-id {
507
+ flex-shrink: 0;
508
+ width: 65px;
509
+ color: #1890ff;
510
+ font-size: 16px;
511
+ font-weight: bold;
512
+ padding: 4px 8px;
513
+ border: 1px solid #1890ff;
514
+ border-radius: 4px;
515
+ line-height: 1.4;
516
+ text-align: center;
517
+ white-space: nowrap;
518
+ overflow: hidden;
519
+ text-overflow: ellipsis;
520
+ }
521
+
522
+ .title-basic {
523
+ display: flex;
524
+ flex-direction: column;
525
+ flex-grow: 1;
526
+
527
+ .subtitle2, .subtitle3 {
528
+ display: inline-block;
529
+ max-width: 50px; /* 固定宽度 */
530
+ white-space: nowrap;
531
+ overflow: hidden;
532
+ text-overflow: ellipsis;
533
+ }
534
+
535
+ .title-main {
536
+ display: flex;
537
+ align-items: center;
538
+ gap: 8px;
539
+ .title-info {
540
+ margin-left: 6px;
541
+ color: #808080;
542
+ }
543
+ .title-title3 {
544
+ color: #808080;
545
+ }
546
+ }
547
+
548
+ .additional-info {
549
+ display: flex;
550
+ gap: 8px;
551
+ font-size: 13px;
552
+ color: #808080;
553
+ .subtitle4 {
554
+ color: rgba(0, 0, 255, 0.8);
555
+ }
556
+ }
557
+ }
558
+ }
559
+
560
+ .ribbon {
561
+ position: absolute;
562
+ top: 16px;
563
+ right: -6px;
564
+ background-color: #ff4d4f;
565
+ color: white;
566
+ padding: 5px 25px;
567
+ font-size: 12px;
568
+ transform: rotate(45deg) translateX(30%);
569
+ transform-origin: top right;
570
+ z-index: 1;
571
+ }
572
+
573
+ .custom-actions {
574
+ .footer-icon {
575
+ margin-right: 5px;
576
+ }
577
+
578
+ .footer-item-split {
579
+ color: rgba(220, 220, 220, 0.59);
580
+ }
581
+
582
+ .footer-item {
583
+ color: rgba(117, 117, 117, 0.8);
584
+ font-size: 1em;
585
+ }
586
+
587
+ .footer-item:hover {
588
+ color: rgb( 24,144,255 );
589
+ cursor: pointer;
590
+ }
591
+ }
592
+ }
593
+
594
+ .ellipsis {
595
+ display: inline-block;
596
+ max-width: 60px;
597
+ white-space: nowrap;
598
+ overflow: hidden;
599
+ text-overflow: ellipsis;
600
+ }
601
+ </style>