|
@@ -1,475 +0,0 @@
|
|
|
-<script>
|
|
|
-export default {
|
|
|
- name: "SuperTable",
|
|
|
- props: {
|
|
|
- // 数据
|
|
|
- value: {
|
|
|
- type: [Array],
|
|
|
- require: true,
|
|
|
- },
|
|
|
- // 字典
|
|
|
- dict: {
|
|
|
- type: [Object],
|
|
|
- require: true,
|
|
|
- },
|
|
|
- // 分页
|
|
|
- page: {
|
|
|
- type: [Object],
|
|
|
- require: false,
|
|
|
- },
|
|
|
- // 模板
|
|
|
- columns: {
|
|
|
- type: [Array],
|
|
|
- require: true,
|
|
|
- },
|
|
|
- // 是否显示序号
|
|
|
- index: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- // 是否显示单选
|
|
|
- radio: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- // 是否显示多选
|
|
|
- checkbox: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- // 是否显示分页
|
|
|
- pagination: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- // 是否列显示
|
|
|
- hiddenColumns: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- // 是否禁止选择
|
|
|
- selectable: {
|
|
|
- type: Function,
|
|
|
- default: () => {},
|
|
|
- },
|
|
|
-
|
|
|
- // stroage: {
|
|
|
- // type: Boolean,
|
|
|
- // default: false,
|
|
|
- // },
|
|
|
- // hideOperationColumns: {
|
|
|
- // type: Boolean,
|
|
|
- // default: false,
|
|
|
- // },
|
|
|
- },
|
|
|
- components: {
|
|
|
- ElDictTag: () => import("@/components/DictTag/index.vue"),
|
|
|
- ElDraggable: () => import("@/components/draggable/index.vue"),
|
|
|
- ElFilePreview: () => import("@/components/file-preview/index.vue"),
|
|
|
- ElComputedInput: () => import("@/components/computed-input/index.vue"),
|
|
|
- ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
|
|
|
- ElComputedInputV2: () => import("@/components/computed-input-v2/index.vue"),
|
|
|
- ButtonHide: () => import("./hide.vue"),
|
|
|
- ButtonFreeze: () => import("./freeze.vue"),
|
|
|
- IconHide: () => import("./once/hide.vue"),
|
|
|
- IconSort: () => import("./once/sort.vue"),
|
|
|
- IconFilter: () => import("./once/filter.vue"),
|
|
|
- IconFreeze: () => import("./once/freeze.vue"),
|
|
|
- },
|
|
|
- data() {
|
|
|
- const { columns } = this.$props;
|
|
|
- const innerColumns = columns;
|
|
|
- return {
|
|
|
- innerColumns: innerColumns,
|
|
|
- rowKey: "id",
|
|
|
- // 选择
|
|
|
- selectData: [],
|
|
|
- selectState: false,
|
|
|
- // 过滤
|
|
|
- filterData: [],
|
|
|
- filterState: false,
|
|
|
- };
|
|
|
- },
|
|
|
- computed: {
|
|
|
- innerValue: {
|
|
|
- get() {
|
|
|
- if (this.filterState) {
|
|
|
- return this.filterData;
|
|
|
- } else if (this.selectState) {
|
|
|
- return this.selectData;
|
|
|
- } else {
|
|
|
- return this.$props.value;
|
|
|
- }
|
|
|
- },
|
|
|
- set(value) {
|
|
|
- this.$emit("input", value);
|
|
|
- },
|
|
|
- },
|
|
|
- showColumns: {
|
|
|
- get() {
|
|
|
- return this.innerColumns.filter(({ item }) => item.hidden);
|
|
|
- },
|
|
|
- set() {},
|
|
|
- },
|
|
|
- filterRules: {
|
|
|
- get() {
|
|
|
- return Object.fromEntries(
|
|
|
- this.innerColumns
|
|
|
- .filter(({ item }) => item.filter && !!item.filter.length)
|
|
|
- .map(({ item }) => [item.key, item.filter])
|
|
|
- );
|
|
|
- },
|
|
|
- set() {},
|
|
|
- },
|
|
|
- },
|
|
|
- watch: {
|
|
|
- filterRules: {
|
|
|
- handler: function (newValue) {
|
|
|
- function multiFilter(array, filters) {
|
|
|
- const filterKeys = Object.keys(filters);
|
|
|
- // filters all elements passing the criteria
|
|
|
- return array.filter((item) => {
|
|
|
- // dynamically validate all filter criteria
|
|
|
- return filterKeys.every((key) => {
|
|
|
- //ignore when the filter is empty Anne
|
|
|
- if (!filters[key].length) return true;
|
|
|
- return !!~filters[key].indexOf(item[key]);
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- this.filterState = JSON.stringify(newValue) !== "{}";
|
|
|
- this.filterData = multiFilter(this.$props.value, newValue);
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- methods: {
|
|
|
- //
|
|
|
- onSelectionChange(value) {
|
|
|
- this.selectData = value;
|
|
|
- },
|
|
|
- //
|
|
|
- onCellStyle({ row, column }) {
|
|
|
- const { selectable } = this.$props;
|
|
|
- // 禁止状态
|
|
|
- if (!selectable(row)) {
|
|
|
- return {
|
|
|
- cursor: "no-drop",
|
|
|
- };
|
|
|
- }
|
|
|
- // 选中状态
|
|
|
- // if (
|
|
|
- // column.label === "#" &&
|
|
|
- // this.selectData.find((item) => item.id === row.id)
|
|
|
- // ) {
|
|
|
- // return {
|
|
|
- // color: "#fff",
|
|
|
- // backgroundColor: "#409EFF",
|
|
|
- // };
|
|
|
- // }
|
|
|
- },
|
|
|
- //
|
|
|
- onRowClick(row, column, event) {
|
|
|
- const { radio, checkbox, selectable } = this.$props;
|
|
|
- // 单选
|
|
|
- if (radio && selectable(row)) {
|
|
|
- this.selectData = [row];
|
|
|
- this.innerValue = this.innerValue.map((item) => ({
|
|
|
- ...item,
|
|
|
- isChecked: item.id === row.id ? true : false,
|
|
|
- }));
|
|
|
- this.$emit("row-select", this.selectData);
|
|
|
- }
|
|
|
- // 多选
|
|
|
- if (checkbox && selectable(row)) {
|
|
|
- this.$refs.superTable.toggleRowSelection(
|
|
|
- this.innerValue.find((item) => item.id === row.id)
|
|
|
- );
|
|
|
- this.$emit("row-select", this.selectData);
|
|
|
- }
|
|
|
- },
|
|
|
- // 冻结
|
|
|
- onHide() {
|
|
|
- this.$nextTick(() => {
|
|
|
- this.$refs.superTable.doLayout();
|
|
|
- });
|
|
|
- },
|
|
|
- // 排序
|
|
|
- onSort(prop) {
|
|
|
- const { key, sort } = prop;
|
|
|
- this.$nextTick(() => {
|
|
|
- this.$refs.superTable.sort(key, sort);
|
|
|
- this.$refs.superTable.doLayout();
|
|
|
- });
|
|
|
- },
|
|
|
- // 冻结
|
|
|
- onFreeze() {
|
|
|
- this.$nextTick(() => {
|
|
|
- this.$refs.superTable.doLayout();
|
|
|
- });
|
|
|
- },
|
|
|
- // 过滤
|
|
|
- onFilter() {
|
|
|
- this.$nextTick(() => {
|
|
|
- this.$refs.superTable.doLayout();
|
|
|
- });
|
|
|
- },
|
|
|
- onFilters(value) {
|
|
|
- const {
|
|
|
- item: { key },
|
|
|
- attr: { dictName },
|
|
|
- } = value;
|
|
|
- let dataList = [];
|
|
|
- const dict = this.dict.type[dictName];
|
|
|
- dataList = Array.from(
|
|
|
- new Set(this.innerValue.map((item) => item[key]).filter((item) => item))
|
|
|
- ).map((item) => ({
|
|
|
- text: dictName
|
|
|
- ? (dict.find((dictItem) => dictItem.value == item) || {}).label
|
|
|
- : item,
|
|
|
- value: item,
|
|
|
- }));
|
|
|
- return dataList;
|
|
|
- },
|
|
|
- },
|
|
|
- created() {},
|
|
|
- mounted() {},
|
|
|
- destroyed() {},
|
|
|
-};
|
|
|
-</script>
|
|
|
-
|
|
|
-<template>
|
|
|
- <div class="el-super-table">
|
|
|
- <el-table
|
|
|
- v-bind="$attrs"
|
|
|
- v-on="$listeners"
|
|
|
- ref="superTable"
|
|
|
- border
|
|
|
- :row-key="rowKey"
|
|
|
- :data="innerValue"
|
|
|
- :cell-style="onCellStyle"
|
|
|
- :row-style="{ height: '50px' }"
|
|
|
- @row-click="onRowClick"
|
|
|
- @selection-change="onSelectionChange"
|
|
|
- >
|
|
|
- <!-- 序号 -->
|
|
|
- <el-table-column
|
|
|
- v-if="index"
|
|
|
- :resizable="false"
|
|
|
- fixed
|
|
|
- width="50"
|
|
|
- label="序号"
|
|
|
- align="center"
|
|
|
- class="is-index"
|
|
|
- >
|
|
|
- <template slot-scope="scope">
|
|
|
- {{ scope.$index + 1 }}
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <!-- 多选 -->
|
|
|
- <el-table-column
|
|
|
- v-if="checkbox"
|
|
|
- :column-key="rowKey"
|
|
|
- :selectable="selectable"
|
|
|
- fixed
|
|
|
- width="50"
|
|
|
- align="center"
|
|
|
- type="selection"
|
|
|
- reserve-selection
|
|
|
- >
|
|
|
- </el-table-column>
|
|
|
- <el-table-column
|
|
|
- v-for="({ item, attr }, index) in showColumns"
|
|
|
- :key="index"
|
|
|
- :prop="item.key"
|
|
|
- :label="item.title"
|
|
|
- :fixed="item.fixed"
|
|
|
- :width="item.width"
|
|
|
- show-overflow-tooltip
|
|
|
- >
|
|
|
- <template slot="header" slot-scope="scope">
|
|
|
- <template>
|
|
|
- <span
|
|
|
- :style="{
|
|
|
- color:
|
|
|
- item.sort ||
|
|
|
- item.fixed ||
|
|
|
- (item.filter && !!item.filter.length)
|
|
|
- ? '#1890ff'
|
|
|
- : '',
|
|
|
- }"
|
|
|
- >
|
|
|
- {{ item.title }}
|
|
|
- </span>
|
|
|
- <icon-sort
|
|
|
- v-model="item.sort"
|
|
|
- class="icon-sort"
|
|
|
- @sort="onSort(item)"
|
|
|
- :style="{
|
|
|
- color: item.sort ? '#1890ff' : '',
|
|
|
- display: item.sort ? 'inline-block' : '',
|
|
|
- }"
|
|
|
- ></icon-sort>
|
|
|
- <icon-freeze
|
|
|
- v-model="item.fixed"
|
|
|
- class="icon-freeze"
|
|
|
- @freeze="onFreeze"
|
|
|
- :style="{
|
|
|
- color: item.fixed ? '#1890ff' : '',
|
|
|
- display: item.fixed ? 'inline-block' : '',
|
|
|
- }"
|
|
|
- ></icon-freeze>
|
|
|
- <icon-filter
|
|
|
- v-model="item.filter"
|
|
|
- class="icon-filter"
|
|
|
- :filters="onFilters({ item, attr })"
|
|
|
- @filter="onFilter"
|
|
|
- :style="{
|
|
|
- color: item.filter && item.filter.length ? '#1890ff' : '',
|
|
|
- display:
|
|
|
- item.filter && item.filter.length ? 'inline-block' : '',
|
|
|
- }"
|
|
|
- ></icon-filter>
|
|
|
- <icon-hide
|
|
|
- v-if="hiddenColumns"
|
|
|
- v-model="item.hidden"
|
|
|
- class="icon-hide"
|
|
|
- @hide="onHide"
|
|
|
- ></icon-hide>
|
|
|
- </template>
|
|
|
- <!-- <template v-else>{{ item.title }}</template> -->
|
|
|
- </template>
|
|
|
- <template slot-scope="scope">
|
|
|
- <slot :name="item.key" v-bind="scope" :item="item" :attr="attr">
|
|
|
- <template v-if="attr.is">
|
|
|
- <component
|
|
|
- v-if="attr.is === 'el-dict-tag'"
|
|
|
- v-bind="attr"
|
|
|
- :size="$attrs.size"
|
|
|
- :value="scope.row[item.key]"
|
|
|
- :options="dict.type[attr.dictName]"
|
|
|
- ></component>
|
|
|
- <component
|
|
|
- v-else-if="attr.is === 'el-popover-select-v2'"
|
|
|
- v-bind="attr"
|
|
|
- v-model="scope.row[item.key]"
|
|
|
- :size="$attrs.size"
|
|
|
- :source.sync="scope.row"
|
|
|
- >
|
|
|
- </component>
|
|
|
- <component
|
|
|
- v-else-if="attr.is === 'el-select'"
|
|
|
- v-bind="attr"
|
|
|
- v-model="scope.row[item.key]"
|
|
|
- :size="$attrs.size"
|
|
|
- >
|
|
|
- <template>
|
|
|
- <el-option
|
|
|
- v-for="item in dict.type[attr.dictName]"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
- >
|
|
|
- </el-option>
|
|
|
- </template>
|
|
|
- </component>
|
|
|
- <component
|
|
|
- v-else
|
|
|
- v-bind="attr"
|
|
|
- v-model="scope.row[item.key]"
|
|
|
- :size="$attrs.size"
|
|
|
- >
|
|
|
- </component
|
|
|
- ></template>
|
|
|
- <template v-else>
|
|
|
- <component v-if="attr.formatter" is="span">{{
|
|
|
- attr.formatter(scope.row)
|
|
|
- }}</component>
|
|
|
- <component v-else is="span">{{
|
|
|
- scope.row[item.key] || "--"
|
|
|
- }}</component>
|
|
|
- </template>
|
|
|
- </slot>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <slot></slot>
|
|
|
- </el-table>
|
|
|
- <div
|
|
|
- style="
|
|
|
- height: auto;
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
- "
|
|
|
- >
|
|
|
- <div>
|
|
|
- <template v-if="checkbox">
|
|
|
- <el-button
|
|
|
- v-if="selectState"
|
|
|
- size="mini"
|
|
|
- @click="selectState = !selectState"
|
|
|
- >
|
|
|
- 所有列
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- v-else
|
|
|
- :disabled="!selectData.length"
|
|
|
- size="mini"
|
|
|
- @click="selectState = !selectState"
|
|
|
- >
|
|
|
- 选择列
|
|
|
- {{ selectData.length ? ` :${selectData.length}` : "" }}
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- <template v-if="hiddenColumns">
|
|
|
- <button-hide v-model="innerColumns" @hide="onHide"></button-hide>
|
|
|
- <button-freeze
|
|
|
- v-model="showColumns"
|
|
|
- @freeze="onFreeze"
|
|
|
- ></button-freeze>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- <pagination
|
|
|
- v-if="pagination"
|
|
|
- v-show="!selectState"
|
|
|
- :total="page.total"
|
|
|
- :page.sync="page.pageNum"
|
|
|
- :limit.sync="page.pageSize"
|
|
|
- @pagination="$emit('pagination', { ...$event })"
|
|
|
- style="height: 32px; padding: 0 !important"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<style lang="scss" scoped>
|
|
|
-.el-super-table {
|
|
|
- position: relative;
|
|
|
-}
|
|
|
-.el-super-table .el-table__header .cell {
|
|
|
- display: flex;
|
|
|
- .icon-sort {
|
|
|
- display: none;
|
|
|
- }
|
|
|
- &:hover .icon-sort {
|
|
|
- display: inline-block;
|
|
|
- }
|
|
|
- .icon-freeze {
|
|
|
- display: none;
|
|
|
- }
|
|
|
- &:hover .icon-freeze {
|
|
|
- display: inline-block;
|
|
|
- }
|
|
|
- .icon-filter {
|
|
|
- display: none;
|
|
|
- }
|
|
|
- &:hover .icon-filter {
|
|
|
- display: inline-block;
|
|
|
- }
|
|
|
- .icon-hide {
|
|
|
- display: none;
|
|
|
- }
|
|
|
- &:hover .icon-hide {
|
|
|
- display: inline-block;
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|