|
@@ -1,585 +1,751 @@
|
|
|
<template>
|
|
|
- <div class="header-actions" v-if="getActionList.length != 0">
|
|
|
- <div class="overflow-box">
|
|
|
- <el-button
|
|
|
- v-for="(item, index) in getActionList"
|
|
|
- :key="index"
|
|
|
- :type="item.type || 'primary'"
|
|
|
- :plain="item.plain || false"
|
|
|
- v-bind="getHeaderActions(item)"
|
|
|
- @click="item.action"
|
|
|
- :disabled="item.disabled || false"
|
|
|
- >
|
|
|
- {{ item.text }}
|
|
|
- </el-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="table-list-container by-table">
|
|
|
- <!-- v-if="!hideHeader" -->
|
|
|
- <header v-if="false" class="header">
|
|
|
- <h2>{{ title }}</h2>
|
|
|
- </header>
|
|
|
- <div class="by-search" v-if="!hideSearch">
|
|
|
- <div style="display: flex">
|
|
|
- <div
|
|
|
- class="by-dropdown"
|
|
|
- v-for="(i, index) in selectConfigCopy"
|
|
|
- :key="i.prop"
|
|
|
- style="margin-right: 10px"
|
|
|
- >
|
|
|
- <div class="by-dropdown-title">
|
|
|
- {{ i.label || i.labelCopy
|
|
|
- }}<i
|
|
|
- style="margin-left: 5px"
|
|
|
- class="iconfont icon-iconm_xialan1"
|
|
|
- ></i>
|
|
|
- </div>
|
|
|
- <ul class="by-dropdown-lists">
|
|
|
- <li
|
|
|
- @click="searchItemSelct('all', i, index)"
|
|
|
- v-if="i.isShowAll === false ? i.isShowAll : true"
|
|
|
- style="
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- "
|
|
|
- >
|
|
|
- {{$t('common.all')}}
|
|
|
- </li>
|
|
|
- <li
|
|
|
- v-for="j in i.data"
|
|
|
- :key="j.value"
|
|
|
- @click="searchItemSelct(j, i)"
|
|
|
- style="
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- "
|
|
|
- >
|
|
|
- {{ j.label }}
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+
|
|
|
+ <div class="header-actions" v-if="getActionList.length != 0">
|
|
|
+ <div class="overflow-box">
|
|
|
+ <el-button
|
|
|
+ v-for="(item, index) in getActionList"
|
|
|
+ :key="index"
|
|
|
+ :type="item.type || 'primary'"
|
|
|
+ :plain="item.plain || false"
|
|
|
+ v-bind="getHeaderActions(item)"
|
|
|
+ @click="item.action"
|
|
|
+ :disabled="item.disabled || false"
|
|
|
+ >
|
|
|
+ {{ item.text }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="stat-warp" v-if="statConfig.length != 0">
|
|
|
+ <div class="title">
|
|
|
+
|
|
|
+ <select v-model="statSelectVal" v-if="statConfig.length > 1">
|
|
|
+ <option :value="index" v-for="(i,index) in statConfig" :key="index">{{i.label}}</option>
|
|
|
+ </select>
|
|
|
+ <div v-if="statConfig.length === 1">{{statConfig[0].label}}</div>
|
|
|
+ </div>
|
|
|
+ <ul>
|
|
|
+ <li v-show="!i.data" :class="'theme' + i.type" v-for="(i,index) in statConfig[statSelectVal].data" :key='index'>
|
|
|
+ <div class="label">{{i.label}}</div>
|
|
|
+ <div class="num">300000.00</div>
|
|
|
+ </li>
|
|
|
+ <li v-show="i.data" v-for="(i,index) in statConfig[statSelectVal].data" :key='index' class="multi-data">
|
|
|
+ <div class="label">{{i.label}}</div>
|
|
|
+ <div class="num-warp">
|
|
|
+ <div class="num-box" v-for="(j,jindex) in i.data" :key="jindex">
|
|
|
+ <div class="num-small" :style="'color:' + j.color">{{j.num}}</div>
|
|
|
+ <div class="label-small">{{j.label}}</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ <div class="table-list-container by-table">
|
|
|
+ <!-- v-if="!hideHeader" -->
|
|
|
+ <header v-if="false" class="header">
|
|
|
+ <h2>{{ title }}</h2>
|
|
|
+ </header>
|
|
|
+ <div class="by-search" v-if="!hideSearch">
|
|
|
+ <div style="display: flex">
|
|
|
+ <div
|
|
|
+ class="by-dropdown"
|
|
|
+ v-for="(i, index) in selectConfigCopy"
|
|
|
+ :key="i.prop"
|
|
|
+ style="margin-right: 10px"
|
|
|
+ >
|
|
|
+ <div class="by-dropdown-title">
|
|
|
+ {{ i.label || i.labelCopy
|
|
|
+ }}<i
|
|
|
+ style="margin-left: 5px"
|
|
|
+ class="iconfont icon-iconm_xialan1"
|
|
|
+ ></i>
|
|
|
+ </div>
|
|
|
+ <ul class="by-dropdown-lists">
|
|
|
+ <li
|
|
|
+ @click="searchItemSelct('all', i, index)"
|
|
|
+ v-if="i.isShowAll === false ? i.isShowAll : true"
|
|
|
+ style="
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ $t('common.all') }}
|
|
|
+ </li>
|
|
|
+ <li
|
|
|
+ v-for="j in i.data"
|
|
|
+ :key="j.value"
|
|
|
+ @click="searchItemSelct(j, i)"
|
|
|
+ style="
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ j.label }}
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
|
|
|
- <div style="display: flex">
|
|
|
- <el-input
|
|
|
- :placeholder="$t('common.pleaseEnterKeywords')"
|
|
|
- suffix-icon="search"
|
|
|
- size="mini"
|
|
|
- v-model="pagination.keyword"
|
|
|
- @keyup.enter="searchFn"
|
|
|
- >
|
|
|
- </el-input>
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- style="margin-left: 10px"
|
|
|
- size="default"
|
|
|
- @click="searchFn"
|
|
|
- >{{$t('common.search')}}</el-button
|
|
|
- >
|
|
|
- <div class="more-icon" @click="retrievalModalFn"><img src="@/assets/images/iconm_xiangyzk.png" alt=""></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <component :is="containerTag">
|
|
|
- <div class="filter-form-container">
|
|
|
- <slot />
|
|
|
- </div>
|
|
|
+ <div style="display: flex">
|
|
|
+ <el-input
|
|
|
+ :placeholder="$t('common.pleaseEnterKeywords')"
|
|
|
+ suffix-icon="search"
|
|
|
+ size="mini"
|
|
|
+ v-model="pagination.keyword"
|
|
|
+ @keyup.enter="searchFn"
|
|
|
+ >
|
|
|
+ </el-input>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ style="margin-left: 10px"
|
|
|
+ size="default"
|
|
|
+ @click="searchFn"
|
|
|
+ >{{ $t('common.search') }}</el-button
|
|
|
+ >
|
|
|
+ <div class="more-icon" @click="retrievalModalFn">
|
|
|
+ <img src="@/assets/images/iconm_xiangyzk.png" alt="" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <component :is="containerTag">
|
|
|
+ <div class="filter-form-container">
|
|
|
+ <slot />
|
|
|
+ </div>
|
|
|
|
|
|
- <el-table
|
|
|
- ref="hocElTable"
|
|
|
- v-loading="loading"
|
|
|
- :data="source"
|
|
|
- v-if="!hideTable"
|
|
|
- style="width: 100%"
|
|
|
- v-bind="$attrs"
|
|
|
- v-on="tableEvents"
|
|
|
- row-key="id"
|
|
|
- :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
|
|
- :height="tableHeight"
|
|
|
- >
|
|
|
- <el-table-column
|
|
|
- v-for="(item, index) in config"
|
|
|
- :key="index"
|
|
|
- v-bind="getAttrsValue(item)"
|
|
|
- :type="item.type || ''"
|
|
|
- :selectable="
|
|
|
- (rowData, rowIndex) => isSelectable(rowData, rowIndex, item)
|
|
|
- "
|
|
|
- >
|
|
|
- <template #default="scope" v-if="!item.type">
|
|
|
- <slot
|
|
|
- :name="item.attrs.slot"
|
|
|
- :item="scope.row"
|
|
|
- v-if="item.attrs.slot"
|
|
|
- >
|
|
|
- 插槽占位符
|
|
|
- </slot>
|
|
|
- <div v-else-if="isFunction(getValue(scope, item))">
|
|
|
- <component
|
|
|
- :is="renderTypeList[getMatchRenderFunction(item)].target"
|
|
|
- :cell-list="getValue(scope, item)()"
|
|
|
- :row="scope.row"
|
|
|
- :parent="getParent"
|
|
|
- @click="
|
|
|
- ($event) => {
|
|
|
- handleNativeClick(getAttrsValue(item), $event, item);
|
|
|
- }
|
|
|
- "
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div v-else>
|
|
|
- {{ getValue(scope, item) }}
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
+ <el-table
|
|
|
+ ref="hocElTable"
|
|
|
+ v-loading="loading"
|
|
|
+ :data="source"
|
|
|
+ v-if="!hideTable"
|
|
|
+ style="width: 100%"
|
|
|
+ v-bind="$attrs"
|
|
|
+ v-on="tableEvents"
|
|
|
+ row-key="id"
|
|
|
+ :tree-props="{
|
|
|
+ children: 'children',
|
|
|
+ hasChildren: 'hasChildren',
|
|
|
+ }"
|
|
|
+ :height="tableHeight"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ v-for="(item, index) in config"
|
|
|
+ :key="index"
|
|
|
+ v-bind="getAttrsValue(item)"
|
|
|
+ :type="item.type || ''"
|
|
|
+ :selectable="
|
|
|
+ (rowData, rowIndex) =>
|
|
|
+ isSelectable(rowData, rowIndex, item)
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <template #default="scope" v-if="!item.type">
|
|
|
+ <slot
|
|
|
+ :name="item.attrs.slot"
|
|
|
+ :item="scope.row"
|
|
|
+ v-if="item.attrs.slot"
|
|
|
+ >
|
|
|
+ 插槽占位符
|
|
|
+ </slot>
|
|
|
+ <div v-else-if="isFunction(getValue(scope, item))">
|
|
|
+ <component
|
|
|
+ :is="
|
|
|
+ renderTypeList[getMatchRenderFunction(item)]
|
|
|
+ .target
|
|
|
+ "
|
|
|
+ :cell-list="getValue(scope, item)()"
|
|
|
+ :row="scope.row"
|
|
|
+ :parent="getParent"
|
|
|
+ @click="
|
|
|
+ ($event) => {
|
|
|
+ handleNativeClick(
|
|
|
+ getAttrsValue(item),
|
|
|
+ $event,
|
|
|
+ item
|
|
|
+ )
|
|
|
+ }
|
|
|
+ "
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div v-else>
|
|
|
+ {{ getValue(scope, item) }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
|
|
|
- <el-row
|
|
|
- v-if="!hidePagination"
|
|
|
- class="table-pagination"
|
|
|
- justify="end"
|
|
|
- type="flex"
|
|
|
- >
|
|
|
- <el-pagination
|
|
|
- background
|
|
|
- layout="total, sizes, prev, pager, next, jumper"
|
|
|
- :current-page="getPagination.pageNum"
|
|
|
- :page-size="getPagination.pageSize"
|
|
|
- :total="getPagination.total"
|
|
|
- @size-change="handleSizeChange"
|
|
|
- @current-change="handlePageChange"
|
|
|
- />
|
|
|
- </el-row>
|
|
|
- </component>
|
|
|
- </div>
|
|
|
+ <el-row
|
|
|
+ v-if="!hidePagination"
|
|
|
+ class="table-pagination"
|
|
|
+ justify="end"
|
|
|
+ type="flex"
|
|
|
+ >
|
|
|
+ <el-pagination
|
|
|
+ background
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ :current-page="getPagination.pageNum"
|
|
|
+ :page-size="getPagination.pageSize"
|
|
|
+ :total="getPagination.total"
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ @current-change="handlePageChange"
|
|
|
+ />
|
|
|
+ </el-row>
|
|
|
+ </component>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { isFunction as isFn, isBoolean } from "./type";
|
|
|
-import ElementsMapping from "./ElementsMapping";
|
|
|
-import ComponentsMapping from "./ComponentsMapping";
|
|
|
-import { computed, defineComponent, getCurrentInstance, ref } from "vue";
|
|
|
-import expand from "./expand";
|
|
|
+import { isFunction as isFn, isBoolean } from './type'
|
|
|
+import ElementsMapping from './ElementsMapping'
|
|
|
+import ComponentsMapping from './ComponentsMapping'
|
|
|
+import { computed, defineComponent, getCurrentInstance, ref } from 'vue'
|
|
|
+import expand from './expand'
|
|
|
export default defineComponent({
|
|
|
- name: "Table",
|
|
|
- components: {
|
|
|
- ElementsMapping,
|
|
|
- ComponentsMapping,
|
|
|
- },
|
|
|
- props: {
|
|
|
- hideSearch: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- hideTable: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- //顶部搜索下拉配置
|
|
|
- selectConfig: {
|
|
|
- type: Array,
|
|
|
- default() {
|
|
|
- return [];
|
|
|
- },
|
|
|
- },
|
|
|
- // 获取表格元数据时携带的参数
|
|
|
- filterParams: {
|
|
|
- type: Object,
|
|
|
- default() {
|
|
|
- return {};
|
|
|
- },
|
|
|
- },
|
|
|
- // 表格加载 loading
|
|
|
- loading: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- // 表格名称
|
|
|
- title: {
|
|
|
- type: String,
|
|
|
- default: "",
|
|
|
- },
|
|
|
- // 表格元数据
|
|
|
- source: {
|
|
|
- type: Array,
|
|
|
- required: true,
|
|
|
- default() {
|
|
|
- return [];
|
|
|
- },
|
|
|
- },
|
|
|
- tableHeight: {
|
|
|
- type: Number,
|
|
|
- required: false,
|
|
|
- },
|
|
|
- searchConfig: {
|
|
|
- type: Object,
|
|
|
- default() {
|
|
|
- return {
|
|
|
- keyword: "",
|
|
|
- };
|
|
|
- },
|
|
|
- },
|
|
|
- // 指定外层容器的渲染组件
|
|
|
- containerTag: {
|
|
|
- type: String,
|
|
|
- default: "div",
|
|
|
- },
|
|
|
- // 是否隐藏表头
|
|
|
- hideHeader: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- // 是否隐藏分页
|
|
|
- hidePagination: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- // 分页配置
|
|
|
- pagination: {
|
|
|
- type: Object,
|
|
|
- default() {
|
|
|
- return {};
|
|
|
- },
|
|
|
- },
|
|
|
- // 表格配置文件
|
|
|
- config: {
|
|
|
- type: Array,
|
|
|
- default() {
|
|
|
- return [];
|
|
|
- },
|
|
|
- },
|
|
|
- // 表头右上方的按钮组
|
|
|
- actionList: {
|
|
|
- type: Array,
|
|
|
- default() {
|
|
|
- return [{ text: "", action: () => {} }];
|
|
|
- },
|
|
|
- },
|
|
|
- // element table 原生事件
|
|
|
- tableEvents: {
|
|
|
- type: Object,
|
|
|
- default() {
|
|
|
- return {};
|
|
|
- },
|
|
|
- },
|
|
|
- searchKey: {
|
|
|
- type: String,
|
|
|
- default: "keyword",
|
|
|
- },
|
|
|
- // 是否显示过滤的全部选项
|
|
|
- // isShowAll: {
|
|
|
- // type: Boolean,
|
|
|
- // default: true,
|
|
|
- // },
|
|
|
- },
|
|
|
- setup(props) {
|
|
|
- const { proxy } = getCurrentInstance();
|
|
|
- const selectConfigCopy = computed(() => {
|
|
|
- return props.selectConfig.map((item) => {
|
|
|
- if (!item.labelCopy) item.labelCopy = { ...item }.label;
|
|
|
- return item;
|
|
|
- });
|
|
|
- });
|
|
|
- const retrievalModal = ref(false);
|
|
|
- console.log(selectConfigCopy);
|
|
|
- const getAttrsValue = (item) => {
|
|
|
- const { attrs } = item;
|
|
|
- const result = {
|
|
|
- ...attrs,
|
|
|
- };
|
|
|
- delete result.prop;
|
|
|
- return result;
|
|
|
- };
|
|
|
- const renderTypeList = ref({
|
|
|
- render: {},
|
|
|
- renderHTML: {
|
|
|
- target: "elements-mapping",
|
|
|
- },
|
|
|
- renderComponent: {
|
|
|
- target: "components-mapping",
|
|
|
- },
|
|
|
- });
|
|
|
- const getParent = computed(() => {
|
|
|
- return proxy.$parent;
|
|
|
- });
|
|
|
- const getPagination = computed(() => {
|
|
|
- const params = {
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 10,
|
|
|
- total: 0,
|
|
|
- };
|
|
|
- return Object.assign({}, params, props.pagination);
|
|
|
- });
|
|
|
- const getActionList = computed(() => {
|
|
|
- return props.actionList
|
|
|
- .slice()
|
|
|
- .reverse()
|
|
|
- .filter((it) => it.text);
|
|
|
- });
|
|
|
- const getValue = (scope, configItem) => {
|
|
|
- const prop = configItem.attrs.prop;
|
|
|
- const renderName = getMatchRenderFunction(configItem);
|
|
|
- const renderObj = renderTypeList.value[renderName];
|
|
|
- if (renderObj && isFunction(configItem[renderName])) {
|
|
|
- return renderObj.target
|
|
|
- ? getRenderValue(scope, configItem, {
|
|
|
- name: renderName,
|
|
|
- type: "bind",
|
|
|
- })
|
|
|
- : getRenderValue(scope, configItem);
|
|
|
- }
|
|
|
- return scope.row[prop];
|
|
|
- };
|
|
|
- const getRenderValue = (
|
|
|
- scope,
|
|
|
- item,
|
|
|
- fn = { name: "render", type: "call" }
|
|
|
- ) => {
|
|
|
- const prop = item.attrs.prop;
|
|
|
- const propValue = prop && scope.row[prop];
|
|
|
- scope.row.$index = scope.$index;
|
|
|
- const args = propValue !== undefined ? propValue : scope.row;
|
|
|
+ name: 'Table',
|
|
|
+ components: {
|
|
|
+ ElementsMapping,
|
|
|
+ ComponentsMapping,
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ hideSearch: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ hideTable: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ //顶部搜索下拉配置
|
|
|
+ selectConfig: {
|
|
|
+ type: Array,
|
|
|
+ default() {
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // 获取表格元数据时携带的参数
|
|
|
+ filterParams: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {}
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // 表格加载 loading
|
|
|
+ loading: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ // 表格名称
|
|
|
+ title: {
|
|
|
+ type: String,
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
+ // 表格元数据
|
|
|
+ source: {
|
|
|
+ type: Array,
|
|
|
+ required: true,
|
|
|
+ default() {
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ },
|
|
|
+ tableHeight: {
|
|
|
+ type: Number,
|
|
|
+ required: false,
|
|
|
+ },
|
|
|
+ searchConfig: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {
|
|
|
+ keyword: '',
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ statConfig: {
|
|
|
+ type: Array,
|
|
|
+ default() {
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // 指定外层容器的渲染组件
|
|
|
+ containerTag: {
|
|
|
+ type: String,
|
|
|
+ default: 'div',
|
|
|
+ },
|
|
|
+ // 是否隐藏表头
|
|
|
+ hideHeader: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ // 是否隐藏分页
|
|
|
+ hidePagination: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ // 分页配置
|
|
|
+ pagination: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {}
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // 表格配置文件
|
|
|
+ config: {
|
|
|
+ type: Array,
|
|
|
+ default() {
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // 表头右上方的按钮组
|
|
|
+ actionList: {
|
|
|
+ type: Array,
|
|
|
+ default() {
|
|
|
+ return [{ text: '', action: () => {} }]
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // element table 原生事件
|
|
|
+ tableEvents: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {}
|
|
|
+ },
|
|
|
+ },
|
|
|
+ searchKey: {
|
|
|
+ type: String,
|
|
|
+ default: 'keyword',
|
|
|
+ },
|
|
|
+ // 是否显示过滤的全部选项
|
|
|
+ // isShowAll: {
|
|
|
+ // type: Boolean,
|
|
|
+ // default: true,
|
|
|
+ // },
|
|
|
+ },
|
|
|
+ setup(props) {
|
|
|
+ const { proxy } = getCurrentInstance()
|
|
|
+ const selectConfigCopy = computed(() => {
|
|
|
+ return props.selectConfig.map((item) => {
|
|
|
+ if (!item.labelCopy) item.labelCopy = { ...item }.label
|
|
|
+ return item
|
|
|
+ })
|
|
|
+ })
|
|
|
+ let statSelectVal = ref(0)
|
|
|
+ const retrievalModal = ref(false)
|
|
|
+ console.log(selectConfigCopy)
|
|
|
+ const getAttrsValue = (item) => {
|
|
|
+ const { attrs } = item
|
|
|
+ const result = {
|
|
|
+ ...attrs,
|
|
|
+ }
|
|
|
+ delete result.prop
|
|
|
+ return result
|
|
|
+ }
|
|
|
+ const renderTypeList = ref({
|
|
|
+ render: {},
|
|
|
+ renderHTML: {
|
|
|
+ target: 'elements-mapping',
|
|
|
+ },
|
|
|
+ renderComponent: {
|
|
|
+ target: 'components-mapping',
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const getParent = computed(() => {
|
|
|
+ return proxy.$parent
|
|
|
+ })
|
|
|
+ const getPagination = computed(() => {
|
|
|
+ const params = {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ total: 0,
|
|
|
+ }
|
|
|
+ return Object.assign({}, params, props.pagination)
|
|
|
+ })
|
|
|
+ const getActionList = computed(() => {
|
|
|
+ return props.actionList
|
|
|
+ .slice()
|
|
|
+ .reverse()
|
|
|
+ .filter((it) => it.text)
|
|
|
+ })
|
|
|
+ const getValue = (scope, configItem) => {
|
|
|
+ const prop = configItem.attrs.prop
|
|
|
+ const renderName = getMatchRenderFunction(configItem)
|
|
|
+ const renderObj = renderTypeList.value[renderName]
|
|
|
+ if (renderObj && isFunction(configItem[renderName])) {
|
|
|
+ return renderObj.target
|
|
|
+ ? getRenderValue(scope, configItem, {
|
|
|
+ name: renderName,
|
|
|
+ type: 'bind',
|
|
|
+ })
|
|
|
+ : getRenderValue(scope, configItem)
|
|
|
+ }
|
|
|
+ return scope.row[prop]
|
|
|
+ }
|
|
|
+ const getRenderValue = (
|
|
|
+ scope,
|
|
|
+ item,
|
|
|
+ fn = { name: 'render', type: 'call' }
|
|
|
+ ) => {
|
|
|
+ const prop = item.attrs.prop
|
|
|
+ const propValue = prop && scope.row[prop]
|
|
|
+ scope.row.$index = scope.$index
|
|
|
+ const args = propValue !== undefined ? propValue : scope.row
|
|
|
|
|
|
- return item[fn.name][fn.type](getParent.value, args);
|
|
|
- };
|
|
|
- // 匹配 render 开头的函数
|
|
|
- const getMatchRenderFunction = (obj) => {
|
|
|
- return Object.keys(obj).find((key) => {
|
|
|
- const matchRender = key.match(/^render.*/);
|
|
|
- return matchRender && matchRender[0];
|
|
|
- });
|
|
|
- };
|
|
|
- const isFunction = (fn) => {
|
|
|
- return isFn(fn);
|
|
|
- };
|
|
|
- const searchFn = (val) => {
|
|
|
- console.log(props);
|
|
|
- proxy.$emit(
|
|
|
- "getList",
|
|
|
- Object.assign(props.filterParams, { [props.searchKey]: props.pagination.keyword })
|
|
|
- );
|
|
|
- }
|
|
|
- const retrievalModalFn = () => {
|
|
|
- proxy.$emit(
|
|
|
- "moreSearch",
|
|
|
- ''
|
|
|
- );
|
|
|
- };
|
|
|
- const handlePageChange = (val) => {
|
|
|
- proxy.$emit(
|
|
|
- "getList",
|
|
|
- Object.assign(props.filterParams, { pageNum: val })
|
|
|
- );
|
|
|
- };
|
|
|
- const handleSizeChange = (val) => {
|
|
|
- proxy.$emit(
|
|
|
- "getList",
|
|
|
- Object.assign(props.filterParams, { pageSize: val })
|
|
|
- );
|
|
|
- };
|
|
|
- const getHeaderActions = (item) => {
|
|
|
- return {
|
|
|
- ...item.attrs,
|
|
|
- };
|
|
|
- };
|
|
|
- const stopBubbles = (e) => {
|
|
|
- const event = e || window.event;
|
|
|
- if (event && event.stopPropagation) {
|
|
|
- event.stopPropagation();
|
|
|
- } else {
|
|
|
- event.cancelBubble = true;
|
|
|
- }
|
|
|
- };
|
|
|
- const handleNativeClick = ({ isBubble }, e, item) => {
|
|
|
- // 考虑到单元格内渲染了组件,并且组件自身可能含有点击事件,故添加了阻止冒泡机制
|
|
|
- // 若指定 isBubble 为 false,则当前单元格恢复冒泡机制
|
|
|
- if (isBoolean(isBubble) && !isBubble) return;
|
|
|
- stopBubbles(e);
|
|
|
- };
|
|
|
- //下拉搜索相关
|
|
|
+ return item[fn.name][fn.type](getParent.value, args)
|
|
|
+ }
|
|
|
+ // 匹配 render 开头的函数
|
|
|
+ const getMatchRenderFunction = (obj) => {
|
|
|
+ return Object.keys(obj).find((key) => {
|
|
|
+ const matchRender = key.match(/^render.*/)
|
|
|
+ return matchRender && matchRender[0]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const isFunction = (fn) => {
|
|
|
+ return isFn(fn)
|
|
|
+ }
|
|
|
+ const searchFn = (val) => {
|
|
|
+ console.log(props)
|
|
|
+ proxy.$emit(
|
|
|
+ 'getList',
|
|
|
+ Object.assign(props.filterParams, {
|
|
|
+ [props.searchKey]: props.pagination.keyword,
|
|
|
+ })
|
|
|
+ )
|
|
|
+ }
|
|
|
+ const retrievalModalFn = () => {
|
|
|
+ proxy.$emit('moreSearch', '')
|
|
|
+ }
|
|
|
+ const handlePageChange = (val) => {
|
|
|
+ proxy.$emit(
|
|
|
+ 'getList',
|
|
|
+ Object.assign(props.filterParams, { pageNum: val })
|
|
|
+ )
|
|
|
+ }
|
|
|
+ const handleSizeChange = (val) => {
|
|
|
+ proxy.$emit(
|
|
|
+ 'getList',
|
|
|
+ Object.assign(props.filterParams, { pageSize: val })
|
|
|
+ )
|
|
|
+ }
|
|
|
+ const getHeaderActions = (item) => {
|
|
|
+ return {
|
|
|
+ ...item.attrs,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const stopBubbles = (e) => {
|
|
|
+ const event = e || window.event
|
|
|
+ if (event && event.stopPropagation) {
|
|
|
+ event.stopPropagation()
|
|
|
+ } else {
|
|
|
+ event.cancelBubble = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const handleNativeClick = ({ isBubble }, e, item) => {
|
|
|
+ // 考虑到单元格内渲染了组件,并且组件自身可能含有点击事件,故添加了阻止冒泡机制
|
|
|
+ // 若指定 isBubble 为 false,则当前单元格恢复冒泡机制
|
|
|
+ if (isBoolean(isBubble) && !isBubble) return
|
|
|
+ stopBubbles(e)
|
|
|
+ }
|
|
|
+ //下拉搜索相关
|
|
|
|
|
|
- const searchItemSelct = (item, i, index) => {
|
|
|
- if (item == "all") {
|
|
|
- i.label = { ...props.selectConfig[index] }.labelCopy;
|
|
|
- proxy.$emit(
|
|
|
- "getList",
|
|
|
- Object.assign(props.filterParams, { [i.prop]: "" })
|
|
|
- );
|
|
|
- return;
|
|
|
- }
|
|
|
- i.label = item.label;
|
|
|
- console.log(item, i);
|
|
|
- proxy.$emit(
|
|
|
- "getList",
|
|
|
- Object.assign(props.filterParams, { [i.prop]: item.value })
|
|
|
- );
|
|
|
- };
|
|
|
+ const searchItemSelct = (item, i, index) => {
|
|
|
+ if (item == 'all') {
|
|
|
+ i.label = { ...props.selectConfig[index] }.labelCopy
|
|
|
+ proxy.$emit(
|
|
|
+ 'getList',
|
|
|
+ Object.assign(props.filterParams, { [i.prop]: '' })
|
|
|
+ )
|
|
|
+ return
|
|
|
+ }
|
|
|
+ i.label = item.label
|
|
|
+ console.log(item, i)
|
|
|
+ proxy.$emit(
|
|
|
+ 'getList',
|
|
|
+ Object.assign(props.filterParams, { [i.prop]: item.value })
|
|
|
+ )
|
|
|
+ }
|
|
|
|
|
|
- const isSelectable = (row, index, item) => {
|
|
|
- if (item.type === "selection") {
|
|
|
- if (item.attrs && item.attrs.checkAtt) {
|
|
|
- if (row[item.attrs.checkAtt]) {
|
|
|
- return row[item.attrs.checkAtt];
|
|
|
- }
|
|
|
- } else {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
+ const isSelectable = (row, index, item) => {
|
|
|
+ if (item.type === 'selection') {
|
|
|
+ if (item.attrs && item.attrs.checkAtt) {
|
|
|
+ if (row[item.attrs.checkAtt]) {
|
|
|
+ return row[item.attrs.checkAtt]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- return {
|
|
|
- getParent,
|
|
|
- getPagination,
|
|
|
- renderTypeList,
|
|
|
- getActionList,
|
|
|
- getAttrsValue,
|
|
|
- getValue,
|
|
|
- getRenderValue,
|
|
|
- getMatchRenderFunction,
|
|
|
- isFunction,
|
|
|
- handlePageChange,
|
|
|
- handleSizeChange,
|
|
|
- getHeaderActions,
|
|
|
- stopBubbles,
|
|
|
- handleNativeClick,
|
|
|
- searchFn,
|
|
|
- searchItemSelct,
|
|
|
- selectConfigCopy,
|
|
|
- isSelectable,
|
|
|
- retrievalModal,
|
|
|
- retrievalModalFn
|
|
|
- };
|
|
|
- },
|
|
|
-});
|
|
|
+ return {
|
|
|
+ getParent,
|
|
|
+ getPagination,
|
|
|
+ renderTypeList,
|
|
|
+ getActionList,
|
|
|
+ getAttrsValue,
|
|
|
+ getValue,
|
|
|
+ getRenderValue,
|
|
|
+ getMatchRenderFunction,
|
|
|
+ isFunction,
|
|
|
+ handlePageChange,
|
|
|
+ handleSizeChange,
|
|
|
+ getHeaderActions,
|
|
|
+ stopBubbles,
|
|
|
+ handleNativeClick,
|
|
|
+ searchFn,
|
|
|
+ searchItemSelct,
|
|
|
+ selectConfigCopy,
|
|
|
+ isSelectable,
|
|
|
+ retrievalModal,
|
|
|
+ retrievalModalFn,
|
|
|
+ statSelectVal
|
|
|
+ }
|
|
|
+ },
|
|
|
+})
|
|
|
</script>
|
|
|
- <style>
|
|
|
+<style>
|
|
|
.table-list-container th {
|
|
|
- color: #333 !important;
|
|
|
+ color: #333 !important;
|
|
|
}
|
|
|
.by-table td .el-button + .el-button {
|
|
|
- margin-left: 0 !important;
|
|
|
+ margin-left: 0 !important;
|
|
|
}
|
|
|
.by-table td .el-button {
|
|
|
- background: none !important;
|
|
|
- margin: 0 !important;
|
|
|
- padding: 8px 6px !important;
|
|
|
+ background: none !important;
|
|
|
+ margin: 0 !important;
|
|
|
+ padding: 8px 6px !important;
|
|
|
}
|
|
|
.el-checkbox__input.is-disabled .el-checkbox__inner {
|
|
|
- background-color: #dee1e6;
|
|
|
- border-color: #b2b4b9;
|
|
|
+ background-color: #dee1e6;
|
|
|
+ border-color: #b2b4b9;
|
|
|
}
|
|
|
.el-table .cell {
|
|
|
- line-height: 34px;
|
|
|
+ line-height: 34px;
|
|
|
}
|
|
|
</style>
|
|
|
- <style lang="scss" scoped>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.stat-warp{
|
|
|
+ margin-bottom: 20px;
|
|
|
+ background: #fff;
|
|
|
+ padding: 0 20px;
|
|
|
+ .title{
|
|
|
+ height: 60px;
|
|
|
+ select{
|
|
|
+ height: 60px;
|
|
|
+ border:none;
|
|
|
+ outline: none;
|
|
|
+ -webkit-appearance: none;
|
|
|
+ appearance: none;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ background:url('@/assets/images/sanjiao.png') no-repeat right center;
|
|
|
+ padding-right: 20px;
|
|
|
+ }
|
|
|
+ div{
|
|
|
+ height: 60px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 60px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ul{
|
|
|
+ padding: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ margin: 0;
|
|
|
+ li{
|
|
|
+ list-style: none;
|
|
|
+ min-width: 368px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ margin:0 20px 20px 0;
|
|
|
+ background: #EFF6FF;
|
|
|
+ float: left;
|
|
|
+ overflow: hidden;
|
|
|
+ padding:20px;
|
|
|
+ color: #333333;
|
|
|
+ border-radius: 10px;
|
|
|
+ .label{
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ .label::before{
|
|
|
+ width: 10px;
|
|
|
+ height: 10px;
|
|
|
+ content: '';
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #0084FF;
|
|
|
+ display: inline-block;
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+ .num{
|
|
|
+ margin-top:10px;
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //#F5F3FF #9E64ED
|
|
|
+ .theme2{
|
|
|
+ background: #F5F3FF;
|
|
|
+ .label::before{
|
|
|
+ background: #9E64ED;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //#FFF1E1 #FF9315
|
|
|
+ .theme3{
|
|
|
+ background: #FFF1E1;
|
|
|
+ .label::before{
|
|
|
+ background: #FF9315;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //#E2FBE8 #39C55A
|
|
|
+ .theme4{
|
|
|
+ background: #E2FBE8;
|
|
|
+ .label::before{
|
|
|
+ background: #39C55A;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .theme5{
|
|
|
+ background: #FFEBE9;
|
|
|
+ .label::before{
|
|
|
+ background: #F94539;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .theme6{
|
|
|
+ background: #E4F9F9;
|
|
|
+ .label::before{
|
|
|
+ background: #53CBCB;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .multi-data{
|
|
|
+ .label::before{
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ .label{
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom:8px;
|
|
|
+ }
|
|
|
+ .num-warp{
|
|
|
+ overflow: hidden;
|
|
|
+ .num-box{
|
|
|
+ float: left;
|
|
|
+ min-width: 80px;
|
|
|
+ margin-right: 20px;
|
|
|
+ .num-small{
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom:8px;
|
|
|
+ }
|
|
|
+ .label-small{
|
|
|
+ color:#666;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
.by-search {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- margin-bottom: 10px;
|
|
|
- .more-icon{
|
|
|
- float: right;
|
|
|
- cursor: pointer;
|
|
|
- }
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ .more-icon {
|
|
|
+ float: right;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
}
|
|
|
.by-dropdown {
|
|
|
- position: relative;
|
|
|
- text-align: left;
|
|
|
- height: 32px;
|
|
|
- z-index: 1010;
|
|
|
- padding: 0 10px;
|
|
|
- transition: all 0.5s ease;
|
|
|
- cursor: pointer;
|
|
|
- line-height: 32px;
|
|
|
+ position: relative;
|
|
|
+ text-align: left;
|
|
|
+ height: 32px;
|
|
|
+ z-index: 1010;
|
|
|
+ padding: 0 10px;
|
|
|
+ transition: all 0.5s ease;
|
|
|
+ cursor: pointer;
|
|
|
+ line-height: 32px;
|
|
|
|
|
|
- .by-dropdown-title {
|
|
|
- font-size: 14px;
|
|
|
- background-color: #fff;
|
|
|
- }
|
|
|
- ul {
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
+ .by-dropdown-title {
|
|
|
+ font-size: 14px;
|
|
|
+ background-color: #fff;
|
|
|
+ }
|
|
|
+ ul {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
|
|
|
- top: 32px;
|
|
|
- padding: 0;
|
|
|
- margin: 0;
|
|
|
- z-index: 100;
|
|
|
- display: none;
|
|
|
- white-space: nowrap;
|
|
|
- li {
|
|
|
- list-style: none;
|
|
|
- font-size: 12px;
|
|
|
- height: 30px;
|
|
|
- padding: 0 10px;
|
|
|
- }
|
|
|
- li:hover {
|
|
|
- background-color: #eff6ff;
|
|
|
- color: #0084ff;
|
|
|
- }
|
|
|
- }
|
|
|
+ top: 32px;
|
|
|
+ padding: 0;
|
|
|
+ margin: 0;
|
|
|
+ z-index: 100;
|
|
|
+ display: none;
|
|
|
+ white-space: nowrap;
|
|
|
+ li {
|
|
|
+ list-style: none;
|
|
|
+ font-size: 12px;
|
|
|
+ height: 30px;
|
|
|
+ padding: 0 10px;
|
|
|
+ }
|
|
|
+ li:hover {
|
|
|
+ background-color: #eff6ff;
|
|
|
+ color: #0084ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.by-dropdown::before {
|
|
|
- display: block;
|
|
|
- width: 1px;
|
|
|
- content: " ";
|
|
|
- position: absolute;
|
|
|
- height: 14px;
|
|
|
- top: 8px;
|
|
|
- background-color: #ddd;
|
|
|
- right: 0;
|
|
|
- z-index: 1011;
|
|
|
+ display: block;
|
|
|
+ width: 1px;
|
|
|
+ content: ' ';
|
|
|
+ position: absolute;
|
|
|
+ height: 14px;
|
|
|
+ top: 8px;
|
|
|
+ background-color: #ddd;
|
|
|
+ right: 0;
|
|
|
+ z-index: 1011;
|
|
|
}
|
|
|
|
|
|
.by-dropdown:hover {
|
|
|
- background: #ffffff;
|
|
|
+ background: #ffffff;
|
|
|
|
|
|
- border-radius: 2px 2px 2px 2px;
|
|
|
- opacity: 1;
|
|
|
- ul {
|
|
|
- background: #ffffff;
|
|
|
- box-shadow: 0px 2px 16px 1px rgba(0, 0, 0, 0.06);
|
|
|
- border-radius: 2px 2px 2px 2px;
|
|
|
- opacity: 1;
|
|
|
- display: block;
|
|
|
- text-align: left;
|
|
|
- }
|
|
|
+ border-radius: 2px 2px 2px 2px;
|
|
|
+ opacity: 1;
|
|
|
+ ul {
|
|
|
+ background: #ffffff;
|
|
|
+ box-shadow: 0px 2px 16px 1px rgba(0, 0, 0, 0.06);
|
|
|
+ border-radius: 2px 2px 2px 2px;
|
|
|
+ opacity: 1;
|
|
|
+ display: block;
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
}
|
|
|
.header-actions {
|
|
|
- flex: 1;
|
|
|
- overflow-x: auto;
|
|
|
- padding: 20px;
|
|
|
- background: #fff;
|
|
|
- margin-bottom: 20px;
|
|
|
- .overflow-box {
|
|
|
- :deep() .el-button:nth-child(1) {
|
|
|
- margin-left: 10px;
|
|
|
- }
|
|
|
- }
|
|
|
+ flex: 1;
|
|
|
+ overflow-x: auto;
|
|
|
+ padding: 20px;
|
|
|
+ background: #fff;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ .overflow-box {
|
|
|
+ :deep() .el-button:nth-child(1) {
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
.table-list-container {
|
|
|
- background: #fff;
|
|
|
- padding: 13px 20px 20px;
|
|
|
- .table-pagination {
|
|
|
- padding-top: 20px;
|
|
|
- }
|
|
|
- .header {
|
|
|
- display: flex;
|
|
|
- padding-bottom: 20px;
|
|
|
- }
|
|
|
- .el-table {
|
|
|
- :deep() th {
|
|
|
- font-size: 14px;
|
|
|
- }
|
|
|
- :deep() td {
|
|
|
- font-size: 14px;
|
|
|
- }
|
|
|
- }
|
|
|
+ background: #fff;
|
|
|
+ padding: 13px 20px 20px;
|
|
|
+ .table-pagination {
|
|
|
+ padding-top: 20px;
|
|
|
+ }
|
|
|
+ .header {
|
|
|
+ display: flex;
|
|
|
+ padding-bottom: 20px;
|
|
|
+ }
|
|
|
+ .el-table {
|
|
|
+ :deep() th {
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ :deep() td {
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
.by-dropdown-lists {
|
|
|
- max-height: 50vh;
|
|
|
- overflow-y: auto;
|
|
|
- line-height: 1;
|
|
|
+ max-height: 50vh;
|
|
|
+ overflow-y: auto;
|
|
|
+ line-height: 1;
|
|
|
}
|
|
|
</style>
|