|
|
@@ -0,0 +1,273 @@
|
|
|
+<template>
|
|
|
+ <div class="p-4 k-search-table">
|
|
|
+ <!-- -->
|
|
|
+ <search ref="$form"
|
|
|
+ v-bind="$attrs"
|
|
|
+ @reset="onReset"
|
|
|
+ @search="onSearch">
|
|
|
+ <slot name="searchs"></slot>
|
|
|
+ </search>
|
|
|
+
|
|
|
+ <!-- tab -->
|
|
|
+ <tab v-bind="$attrs"
|
|
|
+ @change="onTabChange"></tab>
|
|
|
+
|
|
|
+ <!-- 按钮 -->
|
|
|
+ <el-row v-if="$slots['buttons'] || urlExport"
|
|
|
+ class="mb-4 button-container">
|
|
|
+ <el-col :span="24">
|
|
|
+ <slot name="buttons"></slot>
|
|
|
+ <el-button v-if="urlExport"
|
|
|
+ type="success"
|
|
|
+ @click="onExport">导出数据
|
|
|
+ </el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <!-- -->
|
|
|
+ <el-table v-if="$slots['columns']"
|
|
|
+ ref="$table"
|
|
|
+ :data="dataList"
|
|
|
+ :default-expand-all="expand"
|
|
|
+ :height="tableHeight"
|
|
|
+ :row-class-name="onTableRowClassName"
|
|
|
+ :row-key="rowKey"
|
|
|
+ :show-summary="false"
|
|
|
+ :span-method="spanMethod"
|
|
|
+ :summary-method="getSummaries"
|
|
|
+ border
|
|
|
+ class="w-full"
|
|
|
+ stripe
|
|
|
+ @select="onSelects"
|
|
|
+ @sort-change="onSort"
|
|
|
+ @select-all="onSelectss"
|
|
|
+ @selection-change="handleSelectionChange">
|
|
|
+ <!-- 不用element的, 不好控制要调用方法 -->
|
|
|
+ <el-table-column v-if="select" width="45"><!--宽度不能再调小,否则表格不对齐-->
|
|
|
+ <template slot="header"
|
|
|
+ slot-scope="scope">
|
|
|
+ <el-checkbox v-show="showSelectAll" v-model="selectAll">
|
|
|
+ {{scope.o }}
|
|
|
+ </el-checkbox>
|
|
|
+ </template>
|
|
|
+ <template slot-scope="r">
|
|
|
+ <el-checkbox v-model="r.row[selectField]" @change="onSelect(r.row)"></el-checkbox>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <!-- -->
|
|
|
+ <slot name="columns"></slot>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <!-- -->
|
|
|
+ <el-pagination v-if="pageable && $slots['columns']"
|
|
|
+ :current-page.sync="pageIndex"
|
|
|
+ :page-size.sync="pageSize"
|
|
|
+ :total="total"
|
|
|
+ class="mt-4 pagination"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ @current-change="onPageChange"
|
|
|
+ @size-change="onSizeChange"></el-pagination>
|
|
|
+
|
|
|
+ <div class="clearfix"></div>
|
|
|
+ <div v-if="$slots['content']" class="mb-4">
|
|
|
+ <slot name="content"></slot>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import Search from './components/search'
|
|
|
+import Tab from './components/tab'
|
|
|
+import Sortable from 'sortablejs'
|
|
|
+
|
|
|
+import MixSearch from './mix.search'
|
|
|
+import MixTableSelect from './mix.table.select'
|
|
|
+
|
|
|
+const pageCache = {}
|
|
|
+
|
|
|
+export default {
|
|
|
+ inheritAttrs: false,
|
|
|
+ mixins: [MixSearch, MixTableSelect],
|
|
|
+ components: {
|
|
|
+ Tab,
|
|
|
+ Search,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {}
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ expand: {},
|
|
|
+ drag: {
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ rowKey: {
|
|
|
+ default: 'id',
|
|
|
+ },
|
|
|
+ showSummary: {
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ searchData: {
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ showData: {
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ tableHeight: {
|
|
|
+ default: 525
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ type: Array,
|
|
|
+ default: function () {
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ },
|
|
|
+ spanMethod: {
|
|
|
+ type: Function,
|
|
|
+ default: function ({row, column, rowIndex, columnIndex}) {
|
|
|
+ return [1, 1];
|
|
|
+ },
|
|
|
+ }
|
|
|
+ },
|
|
|
+ model: {
|
|
|
+ prop: 'data',
|
|
|
+ event: 'cc',
|
|
|
+ },
|
|
|
+ computed: {},
|
|
|
+ watch: {
|
|
|
+ dataList() {
|
|
|
+ this.$emit('cc', this.dataList)
|
|
|
+ },
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ redrag() {
|
|
|
+ if (!this.drag) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const el = this.$el.querySelectorAll(
|
|
|
+ '.el-table__body-wrapper > table > tbody'
|
|
|
+ )[0]
|
|
|
+ this.sortable = Sortable.create(el, {
|
|
|
+ ghostClass: 'sortable-ghost',
|
|
|
+ setData: function (dataTransfer) {
|
|
|
+ dataTransfer.setData('Text', '')
|
|
|
+ },
|
|
|
+ onEnd: (evt) => {
|
|
|
+ this.$emit('drag', {
|
|
|
+ newIndex: evt.newIndex,
|
|
|
+ oldIndex: evt.oldIndex,
|
|
|
+ })
|
|
|
+ },
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getSummaries(param) {
|
|
|
+ const {columns, data} = param
|
|
|
+ const sums = []
|
|
|
+ columns.forEach((column, index) => {
|
|
|
+ if (index === 0) {
|
|
|
+ sums[index] = '合计'
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const values = data.map((item) =>
|
|
|
+ // Number(item[column.property])
|
|
|
+
|
|
|
+ {
|
|
|
+ return item[column.property]
|
|
|
+ }
|
|
|
+ )
|
|
|
+ if (!values.every((value) => isNaN(value))) {
|
|
|
+ sums[index] = values.reduce((prev, curr) => {
|
|
|
+ const value = Number(curr)
|
|
|
+ if (!isNaN(value)) {
|
|
|
+ return prev + curr
|
|
|
+ } else {
|
|
|
+ return prev
|
|
|
+ }
|
|
|
+ }, 0)
|
|
|
+ sums[index] += ''
|
|
|
+ } else {
|
|
|
+ sums[index] = 'N/A'
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return sums
|
|
|
+ },
|
|
|
+ onSelects(selection, row) {
|
|
|
+ this.$emit('select', selection)
|
|
|
+ },
|
|
|
+ onSelectss(selection) {
|
|
|
+ this.$emit('select-all', selection)
|
|
|
+ },
|
|
|
+ handleSelectionChange(selection) {
|
|
|
+ this.$emit('handleSelectionChange', selection)
|
|
|
+ },
|
|
|
+ onTabChange({name, value}) {
|
|
|
+ this.$set(this.searchData, name, value)
|
|
|
+ },
|
|
|
+ onFilter(kv) {
|
|
|
+ this.$emit('filter', kv)
|
|
|
+ },
|
|
|
+ onReset() {
|
|
|
+ this.$refs.$form.resetFields()
|
|
|
+ this.$emit('reset')
|
|
|
+ },
|
|
|
+ onSearch() {
|
|
|
+ this.search()
|
|
|
+ },
|
|
|
+ onTableRowClassName(row, index) {
|
|
|
+ if (index === 1) {
|
|
|
+ return 'info-row'
|
|
|
+ } else if (index === 3) {
|
|
|
+ return 'positive-row'
|
|
|
+ }
|
|
|
+ return ''
|
|
|
+ },
|
|
|
+ ClearTableData() {
|
|
|
+ this.dataList = [];
|
|
|
+ this.total = 0;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ if (this.url && !this.manual) {
|
|
|
+ this.load(this.searchData)
|
|
|
+ }
|
|
|
+ },
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.k-search-table {
|
|
|
+ width: calc(100% - 1px);
|
|
|
+ // height: 837px;
|
|
|
+ overflow: auto;
|
|
|
+ //
|
|
|
+ .el-table .info-row {
|
|
|
+ background: #c9e5f5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-table .positive-row {
|
|
|
+ background: #e2f0e4;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-table {
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ .el-pagination {
|
|
|
+ float: right;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-pagination__sizes {
|
|
|
+ .el-input__inner {
|
|
|
+ height: 28px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ .sortable-ghost {
|
|
|
+ opacity: 0.8;
|
|
|
+ color: #fff !important;
|
|
|
+ background: #42b983 !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|