vue2-client 1.12.36 → 1.12.37

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,592 @@
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
+ },
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', 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>