ui库和web端产品库合并版本(还需修复细节)
This commit is contained in:
446
ui/packages/basic/AiTable.vue
Normal file
446
ui/packages/basic/AiTable.vue
Normal file
@@ -0,0 +1,446 @@
|
||||
<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"></slot>
|
||||
<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.sync="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 "../../meta/js/dict"
|
||||
|
||||
let 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)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'AiTable',
|
||||
props: {
|
||||
colConfigs: Array,
|
||||
tableData: Array,
|
||||
current: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
isShowPagination: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
total: {
|
||||
type: Number
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'slot,->, prev, pager, next, sizes, jumper'
|
||||
},
|
||||
stripe: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
tooltipEffect: {
|
||||
type: String
|
||||
},
|
||||
tableSize: {
|
||||
type: String
|
||||
},
|
||||
tableRef: String,
|
||||
dict: {default: () => dict},
|
||||
pagerCount: {default: 5},
|
||||
pageSizes: {default: () => [10, 20, 50, 100]}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: '',
|
||||
chooseList: []
|
||||
}
|
||||
},
|
||||
components: {renderSlot},
|
||||
computed: {
|
||||
refName() {
|
||||
return this.tableRef || `aiTable${new Date().getTime()}`
|
||||
},
|
||||
isShowBorder() {
|
||||
return !!this.$attrs.border || this.$attrs.border === ''
|
||||
},
|
||||
|
||||
isHasPaginationBtnsSlot() {
|
||||
return this.$slots.paginationBtns
|
||||
},
|
||||
|
||||
page() {
|
||||
return {
|
||||
current: this.current,
|
||||
size: this.size,
|
||||
total: this.total,
|
||||
pagerCount: this.pagerCount
|
||||
}
|
||||
},
|
||||
isIndeterminate() {
|
||||
return this.chooseList.length > 0 && this.chooseList.length < this.tableData.length
|
||||
},
|
||||
checkAll() {
|
||||
return this.chooseList.length == this.tableData.length && this.tableData !== 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange(e) {
|
||||
this.$emit('update:current', e)
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$emit('getList')
|
||||
})
|
||||
},
|
||||
handleSizeChange(e) {
|
||||
this.$emit('update:size', e)
|
||||
this.$nextTick(() => {
|
||||
this.$emit('getList')
|
||||
})
|
||||
},
|
||||
handleSelectionChange(e) {
|
||||
this.chooseList = e
|
||||
this.$emit('handleSelectionChange', e)
|
||||
},
|
||||
getValue(colConfig, row) {
|
||||
if (this.isFunction(colConfig.formart)) {
|
||||
return colConfig.formart.call(this, row[colConfig.prop])
|
||||
}
|
||||
|
||||
if (colConfig.dateFormat) {
|
||||
return moment(row[colConfig.prop]).format(colConfig.dateFormat)
|
||||
}
|
||||
|
||||
return this.isInvalidValue(row[colConfig.prop])
|
||||
},
|
||||
isInvalidValue(value) {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
|
||||
return value
|
||||
},
|
||||
isFunction(fun) {
|
||||
return typeof fun === 'function'
|
||||
},
|
||||
/**
|
||||
* 表格方法代理
|
||||
*/
|
||||
clearSelection() {
|
||||
this.$refs[this.refName].clearSelection()
|
||||
},
|
||||
toggleRowSelection() {
|
||||
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;
|
||||
}
|
||||
|
||||
::v-deep .ai-header__border .ai-table__header {
|
||||
border-bottom: 1px solid $borderColor !important;
|
||||
border-right: 1px solid $borderColor !important;
|
||||
}
|
||||
|
||||
::v-deep .el-table--border {
|
||||
border: 1px solid $borderColor;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
::v-deep .el-table {
|
||||
color: #222;
|
||||
|
||||
.caret-wrapper {
|
||||
height: 24px;
|
||||
|
||||
.ascending {
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.descending {
|
||||
bottom: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
thead {
|
||||
color: #555
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .cell {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep .el-table__header {
|
||||
th {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
tr {
|
||||
.cell {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
th:first-child {
|
||||
.cell {
|
||||
padding-left: 40px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-table__body {
|
||||
tr td:first-child .cell {
|
||||
padding-left: 40px !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-table__fixed-right {
|
||||
.el-table__body {
|
||||
tr td:first-child .cell {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .ai-table__header {
|
||||
border-bottom: none;
|
||||
background: #F3F4F5;
|
||||
}
|
||||
|
||||
::v-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;
|
||||
|
||||
::v-deep span, ::v-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;
|
||||
}
|
||||
|
||||
::v-deep .el-pagination button, .el-pagination span:not([class*=suffix]) {
|
||||
line-height: 1 !important;
|
||||
}
|
||||
|
||||
::v-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 {
|
||||
::v-deep .el-table td, ::v-deep .el-table th.is-center {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-table::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td {
|
||||
background: #F5F6F9;
|
||||
}
|
||||
|
||||
::v-deep .el-table__fixed-right::before, ::v-deep .el-table__fixed::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user