Files
dvcp_v2_webapp/ui/packages/basic/AiTable.vue
yanran200730 249917b3d9 考试记录
2023-02-15 17:16:59 +08:00

405 lines
10 KiB
Vue

<template>
<div class="ai-table" :class="[isShowBorder ? 'ai-table__border' : 'ai-table__noborder']">
<el-table :data="tableData"
header-cell-class-name="ai-table__header"
cell-class-name="ai-table__cell"
row-class-name="ai-table__row"
:class="{'ai-header__border': isShowBorder}"
:ref="refName"
:size="tableSize"
:stripe="stripe"
:tooltip-effect="tooltipEffect"
@selection-change="handleSelectionChange"
v-on="$listeners"
v-bind="$attrs"
v-loading="loading">
<template v-for="colConfig in colConfigs.filter(e=>!e.hide)">
<slot v-if="colConfig.slot && colConfig.slot !== 'options'" :name="colConfig.slot"/>
<component
:key="colConfig.id"
v-else-if="colConfig.component"
:is="colConfig.component"
:col-config="colConfig">
</component>
<el-table-column
v-else-if="colConfig.dict"
:key="colConfig.id"
v-bind="colConfig">
<span slot-scope="{row}" :style="{color:colConfig.color||dict.getColor(colConfig.dict, row[colConfig.prop])}">
{{ dict.getLabel(colConfig.dict, row[colConfig.prop]) }}
</span>
</el-table-column>
<el-table-column
v-else-if="colConfig.openType"
:key="colConfig.id"
v-bind="colConfig">
<template v-slot="{row}">
<ai-open-data :type="colConfig.openType" :openid="row[colConfig.prop]"/>
</template>
</el-table-column>
<el-table-column
v-else-if="colConfig.type"
:key="colConfig.id"
v-bind="colConfig"
:width="colConfig.width || 100"/>
<el-table-column v-else v-bind="colConfig" :key="colConfig.id"
:show-overflow-tooltip="colConfig['show-overflow-tooltip'] != false">
<template slot-scope="scope">
<render-slot v-if="colConfig.render" :render="colConfig.render" :row="scope.row" :index="scope.$index"
:column="colConfig"/>
<span v-else>{{ getValue(colConfig, scope.row) }}</span>
</template>
</el-table-column>
</template>
<slot class="table-options" name="options"/>
<template #empty>
<slot v-if="$scopedSlots.empty" name="empty"/>
<div v-else class="no-data" style="height:160px;"/>
</template>
</el-table>
<div class="pagination newPagination" v-if="isShowPagination">
<el-pagination
background
:current-page="page.current"
:total="page.total"
:page-size="page.size"
v-bind="$attrs"
:page-sizes="pageSizes"
:layout="layout"
:pager-count="page.pagerCount"
@size-change="handleSizeChange"
@current-change="handleChange">
<div class="paginationPre">
<el-checkbox v-if="isHasPaginationBtnsSlot" :disabled="!tableData.length" :indeterminate="isIndeterminate"
:value="checkAll" @click.native="toggleAllSelection">全选
</el-checkbox>
<slot name="pagination"/>
<div class="pagination-btns">
<slot name="paginationBtns"></slot>
</div>
<div class="paginationPre-total" :style="{marginLeft: isHasPaginationBtnsSlot ? '24px' : 0}"><label class="color-primary">{{ page.total }}</label>条记录
</div>
</div>
</el-pagination>
</div>
</div>
</template>
<script>
import moment from 'dayjs'
import dict from "../../lib/js/dict"
export default {
name: 'AiTable',
model: {
prop: "tableData",
event: "change"
},
props: {
colConfigs: {type: Array, required: true},
tableData: {type: Array, required: true, default: () => []},
current: {default: 1},
size: {default: 10},
isShowPagination: {type: Boolean, default: true},
total: Number,
layout: {type: String, default: 'slot,->, prev, pager, next, sizes, jumper'},
stripe: {type: Boolean, default: true},
loading: {type: Boolean, default: false},
tooltipEffect: String,
tableSize: String,
tableRef: String,
dict: {default: () => dict},
pagerCount: {default: 5},
pageSizes: {default: () => [10, 20, 50, 100]},
pageConfig: Object
},
data() {
return {
name: '',
chooseList: [],
defaultPage: {}
}
},
components: {
renderSlot: {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {type: Object, default: null},
},
render: (h, data) => {
const params = {
row: data.props.row,
index: data.props.index
}
if (data.props.column) {
params.column = data.props.column
}
return data.props.render(h, params)
}
}
},
computed: {
refName: v => v.tableRef || `aiTable${new Date().getTime()}`,
isShowBorder: v => !!v.$attrs.border || v.$attrs.border === '',
isHasPaginationBtnsSlot: v => v.$scopedSlots.paginationBtns,
isIndeterminate: v => v.chooseList.length > 0 && v.chooseList.length < v.tableData.length,
checkAll: v => v.chooseList.length == v.tableData.length && v.tableData !== 0,
page() {
return {
current: this.current,
size: this.size,
total: this.total,
pagerCount: this.pagerCount,
...this.pageConfig
}
},
},
methods: {
handleChange(current) {
this.$emit('update:current', current)
this.$emit('update:pageConfig', {...this.pageConfig, current})
this.$nextTick(() => {
this.$emit('getList')
})
},
handleSizeChange(size) {
this.$emit('update:size', size)
this.$emit('update:pageConfig', {...this.pageConfig, size})
this.$nextTick(() => {
this.$emit('getList')
})
},
handleSelectionChange(e) {
this.chooseList = e
this.$emit('handleSelectionChange', e)
},
getValue(colConfig, row) {
if (typeof colConfig.format === 'function') {
return colConfig.format.call(this, row[colConfig.prop])
}
if (colConfig.dateFormat) {
return moment(row[colConfig.prop]).format(colConfig.dateFormat)
}
return row[colConfig.prop] === 0 || row[colConfig.prop] ? row[colConfig.prop] : '-'
},
/**
* 表格方法代理
*/
clearSelection() {
this.$refs[this.refName].clearSelection()
},
toggleRowSelection() {
console.log(22)
this.$refs[this.refName].toggleRowSelection(...arguments)
},
toggleAllSelection() {
this.$refs[this.refName].toggleAllSelection()
},
toggleRowExpansion() {
this.$refs[this.refName].toggleRowExpansion(...arguments)
},
setCurrentRow() {
this.$refs[this.refName].setCurrentRow(...arguments)
},
clearSort() {
this.$refs[this.refName].clearSort()
},
clearFilter() {
this.$refs[this.refName].clearFilter(...arguments)
},
doLayout() {
this.$refs[this.refName].doLayout()
},
sort() {
this.$refs[this.refName].sort(...arguments)
},
}
}
</script>
<style lang="scss" scoped>
.ai-table {
.color-primary {
color: $primaryColor;
}
:deep( .ai-header__border .ai-table__header ) {
border-bottom: 1px solid $borderColor !important;
border-right: 1px solid $borderColor !important;
}
:deep( .el-table--border ) {
border: 1px solid $borderColor;
border-right: none;
border-bottom: none;
}
:deep( .el-table ) {
color: #222;
.caret-wrapper {
height: 24px;
.ascending {
top: 1px;
}
.descending {
bottom: 1px;
}
}
thead {
color: #555
}
}
:deep( .cell ) {
line-height: 24px;
}
:deep( .el-table__header ) {
th {
padding: 8px 0;
}
tr {
.cell {
font-weight: 700;
}
th:first-child {
.cell {
padding-left: 40px !important;
}
}
}
}
:deep( .el-table__body ) {
tr td:first-child .cell {
padding-left: 40px !important;
}
}
:deep( .el-table__fixed-right ) {
.el-table__body {
tr td:first-child .cell {
padding-left: 0 !important;
padding-right: 0;
}
}
}
:deep( .ai-table__header ) {
border-bottom: none;
background: #F3F4F5;
}
:deep(.el-pager ) {
li.active + li {
border-left: 1px solid $borderColor;
}
}
.newPagination {
width: 100%;
display: flex;
align-items: center;
height: 64px;
padding: 0 40px !important;
.el-pagination {
width: 100%;
padding: 0;
}
.paginationPre {
display: flex;
height: 28px;
line-height: 1;
font-size: 14px;
font-weight: normal;
align-items: center;
.pagination-btns {
display: flex;
align-items: center;
gap: 8px;
color: $primaryColor !important;
:deep( span), :deep( div ) {
font-size: 12px;
cursor: pointer;
color: $primaryColor !important;
&:hover {
opacity: 0.8;
}
}
}
.paginationPre-total {
font-size: 12px;
color: #555;
label {
padding: 0 2px;
font-weight: 700;
}
}
& > * + * {
margin-left: 24px;
}
:deep( .el-pagination button), .el-pagination span:not([class*=suffix]) {
line-height: 1 !important;
}
:deep(.el-checkbox ) {
display: flex;
align-items: center;
.el-checkbox__input, .el-checkbox__inner {
width: 14px;
height: 14px;
min-width: 0 !important;
line-height: 1 !important;
}
.el-checkbox__label {
font-size: 12px;
color: #222222;
height: auto !important;
line-height: 1 !important;
padding-left: 3px !important;
}
}
}
}
}
.ai-table__noborder {
:deep( .el-table td), :deep( .el-table th.is-center ) {
border: none;
}
.el-table::before {
display: none;
}
:deep( .el-table--striped .el-table__body tr.el-table__row--striped td ) {
background: #F5F6F9;
}
:deep( .el-table__fixed-right::before), :deep( .el-table__fixed::before ) {
display: none;
}
}
</style>