ol-base-components 2.5.0 → 2.6.0

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,784 +1,883 @@
1
- <template>
2
- <div class="table_list_fix">
3
- <!-- 扩展性内容 -->
4
- <slot name="content_context" />
5
- <template v-if="
6
- btnlist.length ||
7
- tableData.options.headTool ||
8
- tableData.options.refreshBtn ||
9
- tableData.options.downloadBtn
10
- ">
11
- <div
12
- v-if="showBtnBox"
13
- class="btnbox"
14
- >
15
- <!-- 左侧按钮 -->
16
- <div>
17
- <el-button
18
- v-for="(btn, index) in btnlist"
19
- :key="index"
20
- size="small"
21
- :type="btn.types ? btn.types : 'primary'"
22
- @click="btn.method"
23
- >
24
- <i
25
- v-if="btn.icon"
26
- :class="btn.icon"
27
- />
28
- {{ btn.title }}
29
- </el-button>
30
- </div>
31
- <!-- 右侧工具按钮 -->
32
- <div class="toolbox">
33
- <el-dropdown
34
- v-if="tableData.options.headTool"
35
- class="avatar-container right-menu-item hover-effect"
36
- trigger="click"
37
- >
38
- <div class="avatar-wrapper">
39
- <div class="layui-table-tool-self">
40
- <i class="el-icon-s-operation" />
41
- </div>
42
- </div>
43
- <el-dropdown-menu
44
- slot="dropdown"
45
- style="padding: 5px"
46
- >
47
- <el-checkbox-group v-model="checkedTableColumns">
48
- <el-checkbox
49
- v-for="column in checkedTableList"
50
- :key="column.prop"
51
- class="checkbox"
52
- :label="column.prop"
53
- >{{ column.label }}
54
- </el-checkbox>
55
- </el-checkbox-group>
56
- </el-dropdown-menu>
57
- </el-dropdown>
58
- <div
59
- v-if="tableData.options.refreshBtn"
60
- class="avatar-container right-menu-item hover-effect el-dropdown"
61
- @click="refreshTable"
62
- >
63
- <div class="avatar-wrapper">
64
- <div class="layui-table-tool-self">
65
- <i class="el-icon-refresh" />
66
- </div>
67
- </div>
68
- </div>
69
- <div
70
- v-if="tableData.options.downloadBtn"
71
- class="avatar-container right-menu-item hover-effect el-dropdown"
72
- @click="printTable"
73
- >
74
- <div class="avatar-wrapper">
75
- <div class="layui-table-tool-self">
76
- <i class="el-icon-printer" />
77
- </div>
78
- </div>
79
- </div>
80
- </div>
81
- </div>
82
- </template>
83
-
84
- <!-- 表格 -->
85
- <div
86
- class="tablebox"
87
- :key="tableData.columns.length"
88
- >
89
- <el-table
90
- :ref="tableRef"
91
- v-loading="tableData.loading"
92
- border
93
- v-bind="tableData.options"
94
- :data="tableData.rows"
95
- style="width: 100%"
96
- height="100%"
97
- :default-sort="tableData.sort"
98
- v-on="tableEvents"
99
- @selection-change="SelectionChange"
100
- @select="select"
101
- @select-all="selectAll"
102
- @row-click="rowClick"
103
- >
104
-
105
- <el-table-column
106
- v-if="tableData.options && tableData.options.index"
107
- width="60"
108
- align="center"
109
- type="index"
110
- :index="computeTableIndex"
111
- label="序号"
112
- />
113
- <el-table-column
114
- v-if="tableData.options && tableData.options.selection"
115
- width="60"
116
- align="center"
117
- type="selection"
118
- label=""
119
- />
120
- <!-- 新增插槽,允许父组件自定义表头 -->
121
- <template v-if="tableData.options && tableData.options.useSlotHeader">
122
- <slot
123
- name="table-columns"
124
- :columns="bindTableColumns"
125
- >
126
- <template v-for="(item, index) in bindTableColumns">
127
- <my-table-column
128
- :column="item"
129
- :key="index"
130
- />
131
- </template>
132
- </slot>
133
- </template>
134
- <!-- 防止之前逻辑出现纰漏,故保留之前逻辑再扩展自定义插槽方式渲染 -->
135
- <template v-else>
136
- <template v-for="(item, index) in bindTableColumns">
137
- <el-table-column
138
- :key="index"
139
- :label="item.label"
140
- :prop="item.prop"
141
- :min-width="item.minWidth || '150px'"
142
- :show-overflow-tooltip="item.overHidden || true"
143
- :type="item.type || 'normal'"
144
- v-bind="{
145
- align: 'center',
146
- width: item.width,
147
- fixed: item.fixed || false,
148
- sortable: item.sortable || false,
149
- ...item.attrs,
150
- }"
151
- >
152
- <template v-slot:header>
153
- <el-tooltip
154
- :content="`${item.label} ${item.prop}`"
155
- placement="top"
156
- >
157
- <span>{{ item.label }}</span>
158
- </el-tooltip>
159
- </template>
160
- <template
161
- v-if="item.render"
162
- v-slot="scope"
163
- >
164
- <render-dom :render="() => item.render(scope.row)" />
165
- </template>
166
- <template
167
- v-else-if="item.renderSlot"
168
- v-slot="scope"
169
- >
170
- <slot
171
- :row="scope.row"
172
- :name="item.prop"
173
- />
174
- </template>
175
- </el-table-column>
176
- </template>
177
- </template>
178
-
179
- <el-table-column
180
- v-if="tableData.operates && tableData.operates.length > 0"
181
- label="操作"
182
- align="center"
183
- v-bind="tableData.operatesAttrs"
184
- >
185
- <template slot-scope="scope">
186
- <div class="operate-group">
187
- <template v-for="(btn, key) in tableData.operates">
188
- <span
189
- v-if="
190
- !btn.isShow ||
191
- (btn.isShow && btn.isShow(scope.row, scope.$index))
192
- "
193
- :key="key"
194
- >
195
- <el-button
196
- :style="btn.style || ''"
197
- :size="btn.size || 'small'"
198
- :type="btn.type || `text`"
199
- :icon="btn.icon"
200
- :plain="btn.plain"
201
- :disabled="
202
- btn.disabled && btn.disabled(scope.row, scope.$index)
203
- "
204
- @click.stop="btn.method(scope.row, scope.$index)"
205
- >{{ btn.label
206
- }}{{
207
- tableData.operates.length >= 2 ? "&nbsp;&nbsp;" : ""
208
- }}</el-button>
209
- </span>
210
- </template>
211
- </div>
212
- </template>·
213
- </el-table-column>
214
- <div
215
- slot="empty"
216
- class="empty"
217
- >
218
- <img
219
- v-if="tableData.rows.length == 0"
220
- :src="nodata"
221
- />
222
- </div>
223
- </el-table>
224
- </div>
225
- <!-- 分页 -->
226
- <div class="pagebox">
227
- <el-row>
228
- <el-col :span="24">
229
- <el-pagination
230
- v-if="paginations.pagetionShow && paginations.total > 0"
231
- :current-page.sync="paginations.page"
232
- :page-sizes="paginations.page_sizes || pageSizes"
233
- :page-size="paginations.limit"
234
- layout="total, sizes, prev, pager, next, jumper,slot"
235
- :total="paginations.total"
236
- @size-change="handleSizeChange"
237
- @current-change="handleindexChange"
238
- >
239
- <div
240
- v-if="paginations.refresh"
241
- :key="1"
242
- class="avatar-container right-menu-item hover-effect el-dropdown"
243
- style="margin-left: 10px"
244
- @click="refreshTableBTN"
245
- >
246
- <div class="avatar-wrapper">
247
- <div class="layui-table-tool-self">
248
- <i class="el-icon-refresh" />
249
- </div>
250
- </div>
251
- </div>
252
- </el-pagination>
253
- </el-col>
254
- </el-row>
255
- </div>
256
- <printTemplate
257
- v-show="false"
258
- class="printTemplate"
259
- :print-list-obj="printListObj"
260
- />
261
- </div>
262
- </template>
263
- <script>
264
- import printTemplate from "./printTable.vue";
265
- import nodata from "./nodata.jpg";
266
- import { getData } from '../../index.js'
267
- export default {
268
- name: "table",
269
- components: {
270
- printTemplate,
271
- // 函数式组件注册
272
- renderDom: {
273
- functional: true,
274
- props: {
275
- render: Function,
276
- },
277
- render(createElement, renDom) {
278
- return <div>{renDom.props.render()}</div>;
279
- },
280
- },
281
- myTableColumn: {
282
- functional: true,
283
- props: {
284
- column: { type: Object, required: true }
285
- },
286
- render(h, ctx) {
287
- const col = ctx.props.column;
288
-
289
- // 多级表头处理
290
- if (col.children && col.children.length) {
291
- return h(
292
- 'el-table-column',
293
- {
294
- props: {
295
- label: col.label,
296
- ...col.attrs
297
- }
298
- },
299
- col.children.map((child, idx) =>
300
- h(ctx.parent.$options.components.myTableColumn, {
301
- props: { column: child },
302
- key: idx
303
- })
304
- )
305
- );
306
- }
307
-
308
- // 单列表头处理
309
- return h(
310
- 'el-table-column',
311
- {
312
- props: {
313
- label: col.label,
314
- prop: col.prop,
315
- minWidth: col.minWidth || '150px',
316
- showOverflowTooltip: col.overHidden || true,
317
- type: col.type || 'normal',
318
- align: 'center',
319
- width: col.width,
320
- fixed: col.fixed || false,
321
- sortable: col.sortable || false,
322
- ...col.attrs
323
- }
324
- },
325
- [
326
- // 表头插槽 - 添加 el-tooltip
327
- h('template', { slot: 'header' }, [
328
- h('el-tooltip', {
329
- props: {
330
- content: `${col.label} ${col.prop}`,
331
- placement: 'top'
332
- }
333
- }, [
334
- h('span', col.label)
335
- ])
336
- ]),
337
- // 内容插槽 - 支持自定义渲染
338
- col.render ? h('template', { slot: 'default' }, {
339
- render: (scope) => h(ctx.parent.$options.components.renderDom, {
340
- props: { render: () => col.render(scope.row) }
341
- })
342
- }) : null,
343
- // 插槽渲染
344
- col.renderSlot ? h('template', { slot: 'default' }, {
345
- render: (scope) => ctx.parent.$scopedSlots[col.prop] ?
346
- ctx.parent.$scopedSlots[col.prop](scope) : null
347
- }) : null
348
- ].filter(Boolean)
349
- );
350
- }
351
- }
352
- },
353
- model: {
354
- prop: "multipleSelection",
355
- event: "SelectionChange",
356
- },
357
- props: {
358
- url: {
359
- type: String,
360
- default: "",
361
- }, // 接口地址
362
- printListObj: {
363
- type: Object,
364
- default: () => {
365
- return {
366
- title: "",
367
- tableHeader: "",
368
- tableData: "",
369
- };
370
- },
371
- }, // 打印参数
372
- btnlist: Array,
373
- outTable: {
374
- type: Object,
375
- default: () => {
376
- return {
377
- tableProp: {},
378
- };
379
- },
380
- },
381
- // exportBut: {
382
- // type: Array,
383
- // default: [],
384
- // },
385
- // 表格传的形式
386
- tableData: {
387
- type: Object,
388
- default: () => {
389
- return {
390
- loading: false,
391
- options: {
392
- selection: null, // 多选框
393
- index: null, // 序号
394
- headTool: true, // 开启头部工具栏
395
- refreshBtn: true, // 开启表格头部刷新按钮
396
- downloadBtn: true, // 开启表格头部下载按钮
397
- useSlotHeader: false, // 使用插槽自定义表头
398
- }, // 序号和复选框
399
- rows: [], // 表数据
400
- columns: [], // 表头
401
- operates: [], // 表格里面的操作按钮
402
- // tableHeightDiff: 300,
403
- operatesAttrs: {},
404
- };
405
- },
406
- },
407
- tableDataShow: {
408
- type: Boolean,
409
- default: true,
410
- },
411
- pageSizes: {
412
- type: Array,
413
- default: () => {
414
- return [20, 30, 40, 60, 100, 200];
415
- },
416
- },
417
- paginations: {
418
- // 显示复选框,
419
- type: Object,
420
- default: () => {
421
- return {
422
- page: 1, // 当前位于那页面
423
- total: 0, // 总数
424
- limit: 30, // 一页显示多少条
425
- pagetionShow: true,
426
- };
427
- },
428
- },
429
- emptyImg: {
430
- // 显示复选框,
431
- type: Boolean,
432
- default: false,
433
- },
434
- tableEvents: Object,
435
- showBtnBox: {
436
- type: Boolean,
437
- default: true,
438
- },
439
- },
440
- created() {
441
- // 通过swagger完善columns
442
- this.init()
443
- },
444
- data() {
445
- return {
446
- nodata,
447
- tableRef: this.tableData.tableRef || "tableRef", // ref
448
- toggleRowFlage: this.tableData.toggleRowFlage || false, // 点击行高亮select标识
449
- // screenWidth: 0,
450
- // tableHeight:
451
- // document.documentElement.clientHeight - this.tableData.tableHeightDiff,
452
- pagetionShow: this.paginations.pagetionShow || true,
453
- twinPage: 1,
454
- };
455
- },
456
- computed: {
457
- bindTableColumns() {
458
- return this.tableData.columns.filter((column) =>
459
- Object.keys(column).includes("show") ? column.show : true
460
- );
461
- },
462
-
463
- checkedTableList: {
464
- get() {
465
- // 返回选中的列名
466
- return this.tableData.columns.filter(
467
- (item) => item.type != "selection"
468
- );
469
- },
470
- },
471
- /* 这里使用了getter和setter,这样写的好处不用自己手动监听复选框的选中事件 */
472
- checkedTableColumns: {
473
- get() {
474
- // 返回选中的列名
475
- return this.bindTableColumns.map((column) => column.prop);
476
- },
477
- set(checked) {
478
- // 设置表格列的显示与隐藏
479
- this.tableData.columns.forEach((column) => {
480
- // 如果选中,则设置列显示
481
- if (checked.includes(column.prop)) {
482
- this.$set(column, "show", true);
483
- } else {
484
- // 如果未选中,则设置列隐藏
485
- this.$set(column, "show", false);
486
- }
487
- });
488
- this.$nextTick(() => {
489
- this.$refs.tableRef.doLayout()
490
- })
491
- },
492
- },
493
- },
494
- methods: {
495
- // init() {
496
- // // 从 IndexedDB 中获取 Swagger 数据
497
- // getData().then((swaggerData) => {
498
- // const swaggerColumns = swaggerData.paths[this.url].get.responses["200"].content['application/json'].schema.properties.items.items.properties;
499
-
500
- // Object.keys(swaggerColumns).forEach(key => {
501
- // const item = swaggerColumns[key];
502
- // let tempItem = this.tableData.columns.find((e) => e.prop == key);
503
- // if (tempItem) {
504
- // tempItem = { ...item, ...tempItem };
505
- // } else if (item.description) {
506
- // this.tableData.columns.push({
507
- // prop: key,
508
- // label: item.description,
509
- // show: true,
510
- // sortable: false,
511
- // attrs: {}
512
- // });
513
- // }
514
- // });
515
- // console.log(`\x1b[36m\x1b[4mol插件-表格`, this.tableData.columns)
516
- // }).catch((error) => {
517
- // console.error("获取 Swagger 数据失败:", error);
518
- // });
519
- // },
520
- // 支持多级表头 useSlotHeader: true,且支持排序,通过columns中的顺序实现
521
- // columns: [
522
- // {
523
- // label: '一级表头',
524
- // children: [{ prop: 'bindStateEnum', label: '112' }, { prop: 'tagNumber' }]
525
- // },
526
- // {
527
- // prop: "remark",
528
- // label: "备注123",
529
- // },
530
- // ],
531
- init() {
532
- // 从 IndexedDB 中获取 Swagger 数据
533
- getData().then((swaggerData) => {
534
- const swaggerColumns = swaggerData.paths[this.url].get.responses["200"].content['application/json'].schema.properties.items.items.properties;
535
-
536
- // 递归映射函数
537
- const mapSwaggerToColumns = (columns) => {
538
- columns.forEach(column => {
539
- if (column.children && column.children.length) {
540
- mapSwaggerToColumns(column.children);
541
- } else {
542
- if (column.prop && swaggerColumns[column.prop]) {
543
- const swaggerItem = swaggerColumns[column.prop];
544
- Object.assign(column, {
545
- label: swaggerItem.description,
546
- show: true,
547
- sortable: false,
548
- ...column
549
- });
550
- }
551
- }
552
- });
553
- };
554
-
555
- mapSwaggerToColumns(this.tableData.columns);
556
-
557
- Object.keys(swaggerColumns).forEach(key => {
558
- const item = swaggerColumns[key];
559
- const existingColumn = this.findColumnByProp(this.tableData.columns, key);
560
- if (!existingColumn && item.description) {
561
- this.tableData.columns.push({
562
- prop: key,
563
- label: item.description,
564
- show: true,
565
- sortable: false,
566
- attrs: {},
567
- ...item
568
- });
569
- }
570
- });
571
-
572
- console.log(`\x1b[36m\x1b[4mol插件-表格`, this.tableData.columns)
573
- }).catch((error) => {
574
- console.error("获取 Swagger 数据失败:", error);
575
- });
576
- },
577
- // 递归查找列配置的辅助方法
578
- findColumnByProp(columns, prop) {
579
- for (const column of columns) {
580
- if (column.children && column.children.length) {
581
- const found = this.findColumnByProp(column.children, prop);
582
- if (found) return found;
583
- } else if (column.prop === prop) {
584
- return column;
585
- }
586
- }
587
- return null;
588
- },
589
- // 多级表头转换
590
- multilevelHeader() {
591
-
592
- },
593
- radioChange() {
594
- this.$emit("radioChange", this.twinPage);
595
- },
596
- // 刷新表格
597
- refreshTable() {
598
- const view = this.$router.history.current;
599
- this.$store.dispatch("tagsView/delCachedView", view).then(() => {
600
- const { fullPath } = view;
601
- this.$nextTick(() => {
602
- this.$router.replace({
603
- path: "/redirect" + fullPath,
604
- });
605
- });
606
- });
607
- this.$emit("refreshTable");
608
- },
609
- printTable() {
610
- console.log("printTable");
611
- if (this.tableData.rows.length <= 0) return;
612
- this.printListObj.title = this.$router.history.current.name;
613
- this.printListObj.tableHeader = this.tableData.columns;
614
- this.printListObj.tableData = this.tableData.rows;
615
- console.log(this.printListObj);
616
- setTimeout(() => {
617
- $(".printTemplate").show();
618
- $(".printTemplate").jqprint();
619
- $(".printTemplate").hide();
620
- }, 50);
621
- this.$emit("printTable");
622
- },
623
- selectAll(val) {
624
- this.$emit("selectAll", val);
625
- },
626
- select(val, row) {
627
- this.$emit("selectTab", val, row);
628
- },
629
- refreshTableBTN() {
630
- this.$emit("refreshTableBTN");
631
- },
632
- rowClick(row, column) {
633
- if (column.label === "操作") return; // 操作列不处罚行点击事件
634
- this.$emit("rowClick", row);
635
- if (
636
- this.tableData.columns.every((item) => {
637
- return item.label !== "是否只出样件";
638
- })
639
- ) {
640
- // 为true时 点击行高亮select
641
- this.$refs.tableRef.toggleRowSelection(row);
642
- }
643
- },
644
- computeTableIndex(index) {
645
- return (this.paginations.page - 1) * this.paginations.limit + index + 1;
646
- },
647
- // 挑选的数据
648
- SelectionChange(val) {
649
- this.multipleSelection = val;
650
- this.$emit("SelectionChange", val);
651
- },
652
- // 分页选择
653
- handleSizeChange(val) {
654
- this.paginations.limit = val;
655
- this.$emit("handleSizeChange", val);
656
- },
657
- handleindexChange(val) {
658
- this.paginations.page = val;
659
- this.$emit("handleindexChange", val);
660
- },
661
- },
662
- };
663
- </script>
664
- <style lang="scss" scoped>
665
- .table_list_fix {
666
- overflow: auto;
667
- flex: 1;
668
- display: flex;
669
- flex-direction: column;
670
- justify-content: space-between;
671
- padding: 10px;
672
- gap: 10px;
673
-
674
- ::v-deep .el-table {
675
- td {
676
- padding: 0px;
677
-
678
- div {
679
- line-height: 28px;
680
- font-size: 12px;
681
- }
682
- }
683
-
684
- th {
685
- padding: 0px;
686
- background: #f5f7fa;
687
- div {
688
- line-height: 28px;
689
- color: #909399;
690
- font-size: 12px;
691
- }
692
- }
693
- }
694
-
695
- .btn-operates {
696
- margin: 10px 0px 10px 15px;
697
-
698
- ::v-deep a {
699
- color: #fff;
700
- text-decoration: none;
701
- display: inline-block;
702
- margin: 0px 5px;
703
- ::v-deep .el-button {
704
- width: 100%;
705
- padding: 7px;
706
- font-size: 13px;
707
- }
708
- }
709
- }
710
- }
711
-
712
- .table-header {
713
- padding-top: 10px;
714
-
715
- .table-header_button {
716
- text-align: right;
717
- float: right;
718
- margin-bottom: 12px;
719
- line-height: 40px;
720
- }
721
- }
722
-
723
- .newjump {
724
- text-decoration: none;
725
- color: dodgerblue;
726
- }
727
-
728
- .tablebox {
729
- box-sizing: border-box;
730
- flex: 1;
731
- overflow: auto;
732
- }
733
-
734
- ::v-deep .el-table__body tr.current-row > td {
735
- background-color: rgb(24, 144, 255) !important;
736
- color: #fff;
737
- }
738
-
739
- ::v-deep .redrow {
740
- background: #fde6e6 !important;
741
- }
742
-
743
- .btnbox {
744
- width: 100%;
745
- display: flex;
746
- align-items: center;
747
- justify-content: space-between;
748
-
749
- .upload-demo {
750
- display: -webkit-inline-box;
751
- margin-left: 10px;
752
- }
753
-
754
- .el-form-item {
755
- margin-bottom: 0px;
756
- }
757
- }
758
-
759
- .layui-table-tool-self {
760
- display: block;
761
- width: 26px;
762
- height: 26px;
763
- padding: 5px;
764
- line-height: 16px;
765
- text-align: center;
766
- color: #333;
767
- border: 1px solid #ccc;
768
- cursor: pointer;
769
- }
770
-
771
- .checkbox {
772
- display: block;
773
- }
774
- // 操作列按钮布局
775
- .operate-group {
776
- display: flex;
777
- align-items: center;
778
- justify-content: space-around;
779
- }
780
- .toolbox {
781
- display: flex;
782
- gap: 10px;
783
- }
784
- </style>
1
+ <template>
2
+ <div class="table_list_fix">
3
+ <!-- 扩展性内容 -->
4
+ <slot name="content_context" />
5
+ <template
6
+ v-if="
7
+ btnlist.length ||
8
+ tableData.options.headTool ||
9
+ tableData.options.refreshBtn ||
10
+ tableData.options.downloadBtn
11
+ "
12
+ >
13
+ <div v-if="showBtnBox" class="btnbox">
14
+ <!-- 左侧按钮 -->
15
+ <div>
16
+ <el-button
17
+ v-for="(btn, index) in btnlist"
18
+ :key="index"
19
+ size="small"
20
+ :type="btn.types ? btn.types : 'primary'"
21
+ @click="btn.method"
22
+ >
23
+ <i v-if="btn.icon" :class="btn.icon" />
24
+ {{ btn.title }}
25
+ </el-button>
26
+ </div>
27
+ <!-- 右侧工具按钮 -->
28
+ <div class="toolbox">
29
+ <el-dropdown
30
+ v-if="tableData.options.headTool"
31
+ class="avatar-container right-menu-item hover-effect"
32
+ trigger="click"
33
+ >
34
+ <div class="avatar-wrapper">
35
+ <div class="layui-table-tool-self">
36
+ <i class="el-icon-s-operation" />
37
+ </div>
38
+ </div>
39
+ <el-dropdown-menu slot="dropdown" style="padding: 5px">
40
+ <el-checkbox-group v-model="checkedTableColumns">
41
+ <el-checkbox
42
+ v-for="column in checkedTableList"
43
+ :key="column.prop"
44
+ class="checkbox"
45
+ :label="column.prop"
46
+ >{{ column.label }}
47
+ </el-checkbox>
48
+ </el-checkbox-group>
49
+ </el-dropdown-menu>
50
+ </el-dropdown>
51
+ <div
52
+ v-if="tableData.options.refreshBtn"
53
+ class="avatar-container right-menu-item hover-effect el-dropdown"
54
+ @click="refreshTable"
55
+ >
56
+ <div class="avatar-wrapper">
57
+ <div class="layui-table-tool-self">
58
+ <i class="el-icon-refresh" />
59
+ </div>
60
+ </div>
61
+ </div>
62
+ <div
63
+ v-if="tableData.options.downloadBtn"
64
+ class="avatar-container right-menu-item hover-effect el-dropdown"
65
+ @click="printTable"
66
+ >
67
+ <div class="avatar-wrapper">
68
+ <div class="layui-table-tool-self">
69
+ <i class="el-icon-printer" />
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </template>
76
+
77
+ <!-- 表格 -->
78
+ <div class="tablebox" :key="tableData.columns.length">
79
+ <el-table
80
+ :ref="tableRef"
81
+ v-loading="tableData.loading"
82
+ border
83
+ v-bind="tableData.options"
84
+ :data="tableData.rows"
85
+ style="width: 100%"
86
+ height="100%"
87
+ :default-sort="tableData.sort"
88
+ v-on="tableEvents"
89
+ @selection-change="SelectionChange"
90
+ @select="select"
91
+ @select-all="selectAll"
92
+ @row-click="rowClick"
93
+ >
94
+ <el-table-column
95
+ v-if="tableData.options && tableData.options.index"
96
+ width="60"
97
+ align="center"
98
+ type="index"
99
+ :index="computeTableIndex"
100
+ label="序号"
101
+ />
102
+ <el-table-column
103
+ v-if="tableData.options && tableData.options.selection"
104
+ width="60"
105
+ align="center"
106
+ type="selection"
107
+ label=""
108
+ />
109
+ <!-- 新增插槽,允许父组件自定义表头 -->
110
+ <!-- <template v-if="tableData.options && tableData.options.useSlotHeader">
111
+ <slot
112
+ name="table-columns"
113
+ :columns="bindTableColumns"
114
+ >
115
+ <template v-for="(item, index) in bindTableColumns">
116
+ <my-table-column
117
+ :column="item"
118
+ :key="index"
119
+ />
120
+ </template>
121
+ </slot>
122
+ </template> -->
123
+ <!-- 防止之前逻辑出现纰漏,故保留之前逻辑再扩展自定义插槽方式渲染 -->
124
+ <!-- <template v-else> -->
125
+ <!-- <template v-for="(item, index) in bindTableColumns">
126
+ <el-table-column
127
+ :key="index"
128
+ :label="item.label"
129
+ :prop="item.prop"
130
+ :min-width="item.minWidth || '150px'"
131
+ :show-overflow-tooltip="item.overHidden || true"
132
+ :type="item.type || 'normal'"
133
+ v-bind="{
134
+ align: 'center',
135
+ width: item.width,
136
+ fixed: item.fixed || false,
137
+ sortable: item.sortable || false,
138
+ ...item.attrs,
139
+ }"
140
+ >
141
+ <template v-slot:header>
142
+ <el-tooltip
143
+ :content="`${item.label} ${item.prop}`"
144
+ placement="top"
145
+ >
146
+ <span>{{ item.label }}</span>
147
+ </el-tooltip>
148
+ </template>
149
+ <template
150
+ v-if="item.render"
151
+ v-slot="scope"
152
+ >
153
+ <render-dom :render="() => item.render(scope.row)" />
154
+ </template>
155
+ <template
156
+ v-else-if="item.renderSlot"
157
+ v-slot="scope"
158
+ >
159
+ <slot
160
+ :row="scope.row"
161
+ :name="item.prop"
162
+ />
163
+ </template>
164
+ </el-table-column>
165
+ </template> -->
166
+ <!-- </template> -->
167
+
168
+ <template v-for="(item, index) in this.tableData.columns">
169
+ <TableColumn
170
+ :column="item"
171
+ :key="`${item.prop || item.label}-${item.show}-${key}`"
172
+ :id="`${item.prop}-${item.show}-${index}`"
173
+ >
174
+ <template v-for="(slotFn, name) in $scopedSlots" v-slot:[name]="slotProps">
175
+ <slot :name="name" v-bind="slotProps" />
176
+ </template>
177
+ </TableColumn>
178
+ </template>
179
+ <el-table-column
180
+ v-if="tableData.operates && tableData.operates.length > 0"
181
+ label="操作"
182
+ align="center"
183
+ v-bind="tableData.operatesAttrs"
184
+ >
185
+ <template slot-scope="scope">
186
+ <div class="operate-group">
187
+ <template v-for="(btn, key) in tableData.operates">
188
+ <span
189
+ v-if="!btn.isShow || (btn.isShow && btn.isShow(scope.row, scope.$index))"
190
+ :key="key"
191
+ >
192
+ <el-button
193
+ :style="btn.style || ''"
194
+ :size="btn.size || 'small'"
195
+ :type="btn.type || `text`"
196
+ :icon="btn.icon"
197
+ :plain="btn.plain"
198
+ :disabled="btn.disabled && btn.disabled(scope.row, scope.$index)"
199
+ @click.stop="btn.method(scope.row, scope.$index)"
200
+ >{{ btn.label
201
+ }}{{ tableData.operates.length >= 2 ? "&nbsp;&nbsp;" : "" }}</el-button
202
+ >
203
+ </span>
204
+ </template>
205
+ </div> </template
206
+
207
+ </el-table-column>
208
+ <div slot="empty" class="empty">
209
+ <img v-if="tableData.rows.length == 0" :src="nodata" />
210
+ </div>
211
+ </el-table>
212
+ </div>
213
+ <!-- 分页 -->
214
+ <div class="pagebox">
215
+ <el-row>
216
+ <el-col :span="24">
217
+ <el-pagination
218
+ v-if="paginations.pagetionShow && paginations.total > 0"
219
+ :current-page.sync="paginations.page"
220
+ :page-sizes="paginations.page_sizes || pageSizes"
221
+ :page-size="paginations.limit"
222
+ layout="total, sizes, prev, pager, next, jumper,slot"
223
+ :total="paginations.total"
224
+ @size-change="handleSizeChange"
225
+ @current-change="handleindexChange"
226
+ >
227
+ <div
228
+ v-if="paginations.refresh"
229
+ :key="1"
230
+ class="avatar-container right-menu-item hover-effect el-dropdown"
231
+ style="margin-left: 10px"
232
+ @click="refreshTableBTN"
233
+ >
234
+ <div class="avatar-wrapper">
235
+ <div class="layui-table-tool-self">
236
+ <i class="el-icon-refresh" />
237
+ </div>
238
+ </div>
239
+ </div>
240
+ </el-pagination>
241
+ </el-col>
242
+ </el-row>
243
+ </div>
244
+ <printTemplate v-show="false" class="printTemplate" :print-list-obj="printListObj" />
245
+ </div>
246
+ </template>
247
+ <script>
248
+ import { getData } from "../../index.js";
249
+ import nodata from "./nodata.jpg";
250
+ import printTemplate from "./printTable.vue";
251
+ import TableColumn from "./TableColumn.vue";
252
+ export default {
253
+ name: "table",
254
+ components: {
255
+ printTemplate,
256
+ TableColumn,
257
+ // 函数式组件注册
258
+ renderDom: {
259
+ functional: true,
260
+ props: {
261
+ render: Function,
262
+ },
263
+ render(createElement, renDom) {
264
+ return <div>{renDom.props.render()}</div>;
265
+ },
266
+ },
267
+ // myTableColumn: {
268
+ // functional: true,
269
+ // props: {
270
+ // column: { type: Object, required: true }
271
+ // },
272
+ // render(h, ctx) {
273
+ // const col = ctx.props.column;
274
+
275
+ // // 多级表头处理
276
+ // if (col.children && col.children.length) {
277
+ // return h(
278
+ // 'el-table-column',
279
+ // {
280
+ // props: {
281
+ // label: col.label,
282
+ // align: 'center',
283
+ // ...col.attrs,
284
+ // }
285
+ // },
286
+ // col.children.map((child, idx) =>
287
+ // h(ctx.parent.$options.components.myTableColumn, {
288
+ // props: { column: child },
289
+ // key: idx
290
+ // })
291
+ // )
292
+ // );
293
+ // }
294
+
295
+ // // 单列表头处理
296
+ // return h(
297
+ // 'el-table-column',
298
+ // {
299
+ // props: {
300
+ // label: col.label,
301
+ // prop: col.prop,
302
+ // minWidth: col.minWidth || '150px',
303
+ // showOverflowTooltip: col.overHidden || true,
304
+ // type: col.type || 'normal',
305
+ // align: 'center',
306
+ // width: col.width,
307
+ // fixed: col.fixed || false,
308
+ // sortable: col.sortable || false,
309
+ // ...col.attrs
310
+ // }
311
+ // },
312
+ // [
313
+ // // 表头插槽 - 添加 el-tooltip
314
+ // h('template', { slot: 'header' }, [
315
+ // h('el-tooltip', {
316
+ // props: {
317
+ // content: `${col.label} ${col.prop}`,
318
+ // placement: 'top'
319
+ // }
320
+ // }, [
321
+ // h('span', col.label)
322
+ // ])
323
+ // ]),
324
+ // // 内容插槽 - 支持自定义渲染
325
+ // col.render ? h('template', { slot: 'default' }, {
326
+ // render: (scope) => h(ctx.parent.$options.components.renderDom, {
327
+ // props: { render: () => col.render(scope.row) }
328
+ // })
329
+ // }) : null,
330
+ // // 插槽渲染
331
+ // col.renderSlot ? h('template', { slot: 'default' }, {
332
+ // render: (scope) => ctx.parent.$scopedSlots[col.prop] ?
333
+ // ctx.parent.$scopedSlots[col.prop](scope) : null
334
+ // }) : null
335
+ // ].filter(Boolean)
336
+ // );
337
+ // }
338
+ // }
339
+ },
340
+ model: {
341
+ prop: "multipleSelection",
342
+ event: "SelectionChange",
343
+ },
344
+ props: {
345
+ url: {
346
+ type: String,
347
+ default: "",
348
+ }, // 接口地址
349
+ printListObj: {
350
+ type: Object,
351
+ default: () => {
352
+ return {
353
+ title: "",
354
+ tableHeader: "",
355
+ tableData: "",
356
+ };
357
+ },
358
+ }, // 打印参数
359
+ btnlist: Array,
360
+ outTable: {
361
+ type: Object,
362
+ default: () => {
363
+ return {
364
+ tableProp: {},
365
+ };
366
+ },
367
+ },
368
+ // exportBut: {
369
+ // type: Array,
370
+ // default: [],
371
+ // },
372
+ // 表格传的形式
373
+ tableData: {
374
+ type: Object,
375
+ default: () => {
376
+ return {
377
+ loading: false,
378
+ options: {
379
+ selection: null, // 多选框
380
+ index: null, // 序号
381
+ headTool: true, // 开启头部工具栏
382
+ refreshBtn: true, // 开启表格头部刷新按钮
383
+ downloadBtn: true, // 开启表格头部下载按钮
384
+ }, // 序号和复选框
385
+ rows: [], // 表数据
386
+ columns: [], // 表头
387
+ operates: [], // 表格里面的操作按钮
388
+ // tableHeightDiff: 300,
389
+ operatesAttrs: {},
390
+ };
391
+ },
392
+ },
393
+ tableDataShow: {
394
+ type: Boolean,
395
+ default: true,
396
+ },
397
+ pageSizes: {
398
+ type: Array,
399
+ default: () => {
400
+ return [20, 30, 40, 60, 100, 200];
401
+ },
402
+ },
403
+ paginations: {
404
+ // 显示复选框,
405
+ type: Object,
406
+ default: () => {
407
+ return {
408
+ page: 1, // 当前位于那页面
409
+ total: 0, // 总数
410
+ limit: 30, // 一页显示多少条
411
+ pagetionShow: true,
412
+ };
413
+ },
414
+ },
415
+ emptyImg: {
416
+ // 显示复选框,
417
+ type: Boolean,
418
+ default: false,
419
+ },
420
+ tableEvents: Object,
421
+ showBtnBox: {
422
+ type: Boolean,
423
+ default: true,
424
+ },
425
+ },
426
+
427
+ data() {
428
+ return {
429
+ nodata,
430
+ tableRef: this.tableData.tableRef || "tableRef", // ref
431
+ toggleRowFlage: this.tableData.toggleRowFlage || false, // 点击行高亮select标识
432
+ // screenWidth: 0,
433
+ // tableHeight:
434
+ // document.documentElement.clientHeight - this.tableData.tableHeightDiff,
435
+ pagetionShow: this.paginations.pagetionShow || true,
436
+ twinPage: 1,
437
+ columnsWatcher: null,
438
+ key: 0,
439
+ };
440
+ },
441
+ computed: {
442
+ bindTableColumns() {
443
+ return this.tableData.columns.filter(column =>
444
+ Object.keys(column).includes("show") ? column.show : true
445
+ );
446
+ },
447
+
448
+ checkedTableList: {
449
+ get() {
450
+ // 返回选中的列名
451
+ return this.getAllColumnsWithProp(this.tableData.columns);
452
+ },
453
+ },
454
+ /* 这里使用了getter和setter,这样写的好处不用自己手动监听复选框的选中事件 */
455
+ checkedTableColumns: {
456
+ get() {
457
+ // 返回选中的列名
458
+ return this.getAllLabelsWithProp();
459
+ },
460
+ set(checked) {
461
+ this.setColumnsShow(checked);
462
+ this.$nextTick(() => {
463
+ this.$refs.tableRef.doLayout();
464
+ });
465
+ },
466
+ },
467
+ },
468
+ created() {
469
+ // 通过swagger完善columns
470
+ this.init();
471
+ },
472
+ // 组件销毁时清理监听器
473
+ beforeDestroy() {
474
+ this.stopColumnsWatching();
475
+ },
476
+ methods: {
477
+ // init() {
478
+ // // 从 IndexedDB 中获取 Swagger 数据
479
+ // getData().then((swaggerData) => {
480
+ // const swaggerColumns = swaggerData.paths[this.url].get.responses["200"].content['application/json'].schema.properties.items.items.properties;
481
+
482
+ // Object.keys(swaggerColumns).forEach(key => {
483
+ // const item = swaggerColumns[key];
484
+ // let tempItem = this.tableData.columns.find((e) => e.prop == key);
485
+ // if (tempItem) {
486
+ // tempItem = { ...item, ...tempItem };
487
+ // } else if (item.description) {
488
+ // this.tableData.columns.push({
489
+ // prop: key,
490
+ // label: item.description,
491
+ // show: true,
492
+ // sortable: false,
493
+ // attrs: {}
494
+ // });
495
+ // }
496
+ // });
497
+ // console.log(`\x1b[36m\x1b[4mol插件-表格`, this.tableData.columns)
498
+ // }).catch((error) => {
499
+ // console.error("获取 Swagger 数据失败:", error);
500
+ // });
501
+ // },
502
+ // 支持多级表头 useSlotHeader: true,且支持排序,通过columns中的顺序实现
503
+ // columns: [
504
+ // {
505
+ // label: '一级表头',
506
+ // children: [{ prop: 'bindStateEnum', label: '112' }, { prop: 'tagNumber' }]
507
+ // },
508
+ // {
509
+ // prop: "remark",
510
+ // label: "备注123",
511
+ // },
512
+ // ],
513
+ init() {
514
+ // 从 IndexedDB 中获取 Swagger 数据
515
+ getData()
516
+ .then(swaggerData => {
517
+ const swaggerColumns =
518
+ swaggerData.paths[this.url].get.responses["200"].content["application/json"].schema
519
+ .properties.items.items.properties;
520
+
521
+ // 递归映射函数
522
+ const mapSwaggerToColumns = columns => {
523
+ columns.forEach(column => {
524
+ if (column.children && column.children.length) {
525
+ mapSwaggerToColumns(column.children);
526
+ } else {
527
+ if (column.prop && swaggerColumns[column.prop]) {
528
+ const swaggerItem = swaggerColumns[column.prop];
529
+ this.$set(column, "label", swaggerItem.description);
530
+ if (!Object.keys(column).includes("show")) this.$set(column, "show", true);
531
+ }
532
+ }
533
+ });
534
+ };
535
+ // 自定义columns数据
536
+ mapSwaggerToColumns(this.tableData.columns);
537
+
538
+ Object.keys(swaggerColumns).forEach(key => {
539
+ const item = swaggerColumns[key];
540
+ const existingColumn = this.findColumnByProp(this.tableData.columns, key);
541
+ if (!existingColumn && item.description) {
542
+ this.tableData.columns.push({
543
+ prop: key,
544
+ label: item.description,
545
+ show: true,
546
+ sortable: false,
547
+ attrs: {},
548
+ });
549
+ }
550
+ });
551
+ // 根据beforeProp排序
552
+ this.sortColumns(this.tableData.columns);
553
+
554
+ // 添加show, 最后添加show是为了后期swagger可能会增加show字段(扩展)
555
+ // 递归根据当前是否有show键名,没有show就添加show:true
556
+ const addShow = columns => {
557
+ columns.forEach(column => {
558
+ if (!column.hasOwnProperty("show")) this.$set(column, "show", true);
559
+ if (column.children && column.children.length) {
560
+ addShow(column.children);
561
+ } else {
562
+ if (!column.hasOwnProperty("show")) {
563
+ // 用set修改
564
+ this.$set(column, "show", true);
565
+ }
566
+ }
567
+ });
568
+ };
569
+ // 添加show,这里的show只显示隐藏,通过checkbox能实现显示隐藏。如果不想checkbox中出现可添加hidden(这是区别于老框架的逻辑)
570
+ addShow(this.tableData.columns);
571
+ console.log(`\x1b[36m\x1b[4mol插件-表格`, this.tableData.columns);
572
+
573
+ // init 执行完成后,添加深度监听
574
+ this.startColumnsWatching();
575
+ })
576
+ .catch(error => {
577
+ console.error("获取 Swagger 数据失败:", error);
578
+ });
579
+ },
580
+ // 多级表头顺序调整,只争对有多级表头的且包含beforeProp字段的,规则:通过多级表头的beforeProp字段将整个多级表头移到这个字段位置之后。(只会一级出现beforeProp,多级中的排序都要手动实现)
581
+ sortColumns(columns) {
582
+ let index = 0;
583
+ columns.forEach(column => {
584
+ if (!column.beforeProp) {
585
+ column.sort = index;
586
+ index++;
587
+ const tempItem = columns.find(e => e.beforeProp == column.prop);
588
+ if (tempItem) {
589
+ tempItem.sort = index;
590
+ index++;
591
+ }
592
+ }
593
+ });
594
+ columns.sort((a, b) => a.sort - b.sort);
595
+ },
596
+ // 递归查找列配置的辅助方法
597
+ findColumnByProp(columns, prop) {
598
+ for (const column of columns) {
599
+ if (column.children && column.children.length) {
600
+ const found = this.findColumnByProp(column.children, prop);
601
+ if (found) return found;
602
+ } else if (column.prop === prop) {
603
+ return column;
604
+ }
605
+ }
606
+ return null;
607
+ },
608
+ radioChange() {
609
+ this.$emit("radioChange", this.twinPage);
610
+ },
611
+ // 刷新表格
612
+ refreshTable() {
613
+ const view = this.$router.history.current;
614
+ this.$store.dispatch("tagsView/delCachedView", view).then(() => {
615
+ const { fullPath } = view;
616
+ this.$nextTick(() => {
617
+ this.$router.replace({
618
+ path: "/redirect" + fullPath,
619
+ });
620
+ });
621
+ });
622
+ this.$emit("refreshTable");
623
+ },
624
+ printTable() {
625
+ console.log("printTable");
626
+ if (this.tableData.rows.length <= 0) return;
627
+ this.printListObj.title = this.$router.history.current.name;
628
+ this.printListObj.tableHeader = this.tableData.columns;
629
+ this.printListObj.tableData = this.tableData.rows;
630
+ console.log(this.printListObj);
631
+ setTimeout(() => {
632
+ $(".printTemplate").show();
633
+ $(".printTemplate").jqprint();
634
+ $(".printTemplate").hide();
635
+ }, 50);
636
+ this.$emit("printTable");
637
+ },
638
+ selectAll(val) {
639
+ this.$emit("selectAll", val);
640
+ },
641
+ select(val, row) {
642
+ this.$emit("selectTab", val, row);
643
+ },
644
+ refreshTableBTN() {
645
+ this.$emit("refreshTableBTN");
646
+ },
647
+ rowClick(row, column) {
648
+ if (column.label === "操作") return; // 操作列不处罚行点击事件
649
+ this.$emit("rowClick", row);
650
+ if (
651
+ this.tableData.columns.every(item => {
652
+ return item.label !== "是否只出样件";
653
+ })
654
+ ) {
655
+ // 为true时 点击行高亮select
656
+ this.$refs.tableRef.toggleRowSelection(row);
657
+ }
658
+ },
659
+ computeTableIndex(index) {
660
+ return (this.paginations.page - 1) * this.paginations.limit + index + 1;
661
+ },
662
+ // 挑选的数据
663
+ SelectionChange(val) {
664
+ this.multipleSelection = val;
665
+ this.$emit("SelectionChange", val);
666
+ },
667
+ // 分页选择
668
+ handleSizeChange(val) {
669
+ this.paginations.limit = val;
670
+ this.$emit("handleSizeChange", val);
671
+ },
672
+ handleindexChange(val) {
673
+ this.paginations.page = val;
674
+ this.$emit("handleindexChange", val);
675
+ },
676
+ getCheckboxList() {
677
+ return this.tableData.column;
678
+ },
679
+ setCheckboxList(val) {},
680
+
681
+ getAllColumnsWithProp(columns) {
682
+ const result = [];
683
+ const propMap = new Map(); // 使用Map存储prop -> column的映射
684
+
685
+ const traverse = cols => {
686
+ cols.forEach(column => {
687
+ if (column.children && column.children.length) {
688
+ // 如果有子列,递归处理子列
689
+ traverse(column.children);
690
+ } else if (column.prop) {
691
+ // 如果包含prop属性且未重复,添加到结果数组
692
+ if (!propMap.has(column.prop)) {
693
+ propMap.set(column.prop, column);
694
+ result.push(column);
695
+ }
696
+ }
697
+ });
698
+ };
699
+
700
+ traverse(columns);
701
+ return result;
702
+ },
703
+
704
+ // checkbox的显示隐藏
705
+ getAllLabelsWithProp() {
706
+ const result = [];
707
+
708
+ const traverse = cols => {
709
+ cols.forEach(column => {
710
+ if (column.children && column.children.length) {
711
+ // 如果有子列,递归处理子列
712
+ traverse(column.children);
713
+ } else if (column.prop && column.show) {
714
+ // 如果包含prop属性且未重复,添加到结果数组
715
+ if (!result.includes(column.prop) && column.show) {
716
+ result.push(column.prop);
717
+ }
718
+ }
719
+ });
720
+ };
721
+ traverse(this.tableData.columns);
722
+ return result;
723
+ },
724
+ setColumnsShow(checkedList) {
725
+ // 递归更新tableData.columns的show属性
726
+ const traverse = cols => {
727
+ cols.forEach(column => {
728
+ if (column.children && column.children.length) {
729
+ traverse(column.children);
730
+ } else if (column.prop) {
731
+ // 用set修改
732
+ if (checkedList.includes(column.prop)) {
733
+ this.$set(column, "show", true);
734
+ } else {
735
+ this.$set(column, "show", false);
736
+ }
737
+ }
738
+ });
739
+ };
740
+ traverse(this.tableData.columns);
741
+ },
742
+
743
+ // 开启 columns 监听,(二级菜单是递归组件,数据变化dom没有发送变化,故监听直接更新dom)
744
+ startColumnsWatching() {
745
+ this.stopColumnsWatching();
746
+ this.columnsWatcher = this.$watch("tableData.columns", () => (this.key += 1), {
747
+ deep: true, // 深度监听
748
+ immediate: false,
749
+ });
750
+ },
751
+
752
+ // 停止 columns 监听
753
+ stopColumnsWatching() {
754
+ if (this.columnsWatcher) {
755
+ this.columnsWatcher();
756
+ this.columnsWatcher = null;
757
+ }
758
+ },
759
+ },
760
+ };
761
+ </script>
762
+
763
+ <style lang="scss" scoped>
764
+ .table_list_fix {
765
+ overflow: auto;
766
+ flex: 1;
767
+ display: flex;
768
+ flex-direction: column;
769
+ justify-content: space-between;
770
+ padding: 10px;
771
+ gap: 10px;
772
+
773
+ ::v-deep .el-table {
774
+ td {
775
+ padding: 0px;
776
+
777
+ div {
778
+ line-height: 28px;
779
+ font-size: 12px;
780
+ }
781
+ }
782
+
783
+ th {
784
+ padding: 0px;
785
+ background: #f5f7fa;
786
+ div {
787
+ line-height: 28px;
788
+ color: #909399;
789
+ font-size: 12px;
790
+ }
791
+ }
792
+ }
793
+
794
+ .btn-operates {
795
+ margin: 10px 0px 10px 15px;
796
+
797
+ ::v-deep a {
798
+ color: #fff;
799
+ text-decoration: none;
800
+ display: inline-block;
801
+ margin: 0px 5px;
802
+ ::v-deep .el-button {
803
+ width: 100%;
804
+ padding: 7px;
805
+ font-size: 13px;
806
+ }
807
+ }
808
+ }
809
+ }
810
+
811
+ .table-header {
812
+ padding-top: 10px;
813
+
814
+ .table-header_button {
815
+ text-align: right;
816
+ float: right;
817
+ margin-bottom: 12px;
818
+ line-height: 40px;
819
+ }
820
+ }
821
+
822
+ .newjump {
823
+ text-decoration: none;
824
+ color: dodgerblue;
825
+ }
826
+
827
+ .tablebox {
828
+ box-sizing: border-box;
829
+ flex: 1;
830
+ overflow: auto;
831
+ }
832
+
833
+ ::v-deep .el-table__body tr.current-row > td {
834
+ background-color: rgb(24, 144, 255) !important;
835
+ color: #fff;
836
+ }
837
+
838
+ ::v-deep .redrow {
839
+ background: #fde6e6 !important;
840
+ }
841
+
842
+ .btnbox {
843
+ width: 100%;
844
+ display: flex;
845
+ align-items: center;
846
+ justify-content: space-between;
847
+
848
+ .upload-demo {
849
+ display: -webkit-inline-box;
850
+ margin-left: 10px;
851
+ }
852
+
853
+ .el-form-item {
854
+ margin-bottom: 0px;
855
+ }
856
+ }
857
+
858
+ .layui-table-tool-self {
859
+ display: block;
860
+ width: 26px;
861
+ height: 26px;
862
+ padding: 5px;
863
+ line-height: 16px;
864
+ text-align: center;
865
+ color: #333;
866
+ border: 1px solid #ccc;
867
+ cursor: pointer;
868
+ }
869
+
870
+ .checkbox {
871
+ display: block;
872
+ }
873
+ // 操作列按钮布局
874
+ .operate-group {
875
+ display: flex;
876
+ align-items: center;
877
+ justify-content: space-around;
878
+ }
879
+ .toolbox {
880
+ display: flex;
881
+ gap: 10px;
882
+ }
883
+ </style>