|
@@ -1,15 +1,18 @@
|
|
|
<template>
|
|
|
- <div style="margin-top:10px">
|
|
|
+ <div>
|
|
|
<div>
|
|
|
<field v-if="searchType" :searchType="searchType" @onSubmit="search"></field>
|
|
|
</div>
|
|
|
- <a-card :bodyStyle="{padding:'10px'}">
|
|
|
+ <a-card id="fulltable" :bodyStyle="{padding:'10px'}">
|
|
|
<template #title>
|
|
|
<div class="flex">
|
|
|
<slot name="operation"></slot>
|
|
|
<div class="pointer">
|
|
|
<a-space size="middle">
|
|
|
<slot name="operationRight"></slot>
|
|
|
+ <sync-outlined @click="tableData" :spin="loading"/>
|
|
|
+ <setting-columns ref="setColumns" :columns="columns" :tableName="props.tableName"></setting-columns>
|
|
|
+ <fullScreen domId="fulltable"></fullScreen>
|
|
|
<a-dropdown :getPopupContainer="
|
|
|
triggerNode => {
|
|
|
return triggerNode.parentNode || document.body;
|
|
@@ -32,7 +35,25 @@
|
|
|
</template>
|
|
|
<template #extra>
|
|
|
</template>
|
|
|
- <a-table class="ant-table-striped" :loading="loading" size="small" :dataSource="dataSource" :columns="columns" :pagination="{showSizeChanger:true,defaultPageSize:20,total:total}" :scroll="{x:'max-content'}" :row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)" @change="onChange">
|
|
|
+ <a-table class="ant-table-small ant-table-red" :loading="loading" size="small" :dataSource="dataSource" :columns="columns" :pagination="{showSizeChanger:true,defaultPageSize:20,total:total}" :scroll="fullscreen?{x:'max-content',y:'86vh'}:{x:'max-content'}" :row-class-name="(_record, index) => formatter(_record, index)" @change="onChange" bordered>
|
|
|
+ <template #headerCell="{ column }">
|
|
|
+ <div style="width:100%;" v-if="column.filter == 1 || column.filter == 2">
|
|
|
+ <a-input v-model:value="column.value" :placeholder="column.title" @change="setSearchParam(column.dataIndex,column.value)" @pressEnter="tableData" :bordered="true">
|
|
|
+ <template v-if="column.sortable == 1" #suffix>
|
|
|
+ <sort-ascending-outlined v-if="column.sort == 0" @click="setSort(column,1)"/>
|
|
|
+ <sort-descending-outlined v-else @click="setSort(column,0)"/>
|
|
|
+ </template>
|
|
|
+ </a-input>
|
|
|
+ </div>
|
|
|
+ <div v-else class="flex-between">
|
|
|
+ <span >{{column.title}}</span>
|
|
|
+ <span v-if="column.sortable == 1">
|
|
|
+ <sort-ascending-outlined v-if="column.sort == 0" @click="setSort(column,1)"/>
|
|
|
+ <sort-descending-outlined v-else @click="setSort(column,0)"/>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </template>
|
|
|
<template #bodyCell="{ column, record }">
|
|
|
<template v-if="column.dataIndex === 'status'">
|
|
|
<a-tag :color="utils.statusAndColor(record.status)">{{record.status}}</a-tag>
|
|
@@ -51,17 +72,21 @@
|
|
|
import field from './field/index.vue'
|
|
|
import Api from '@/api/api'
|
|
|
import utils from '@/utils/utils'
|
|
|
- import {ref,getCurrentInstance,onMounted,defineExpose,watch,defineEmits} from 'vue'
|
|
|
- import { SortAscendingOutlined,SortDescendingOutlined,DownOutlined } from '@ant-design/icons-vue';
|
|
|
+ import settingColumns from '@/components/tableConfiguration/settingColumns.vue'
|
|
|
+ import fullScreen from '@/components/tableConfiguration/fullScreen.vue'
|
|
|
+ import {ref,getCurrentInstance,onMounted,defineExpose,watch, computed,onActivated} from 'vue'
|
|
|
+ import { SortAscendingOutlined,SortDescendingOutlined,DownOutlined,SyncOutlined,SettingOutlined } from '@ant-design/icons-vue';
|
|
|
import { storeToRefs } from 'pinia'
|
|
|
import { useRouter,onBeforeRouteLeave } from "vue-router";
|
|
|
import { useAuthStore } from '@/stores/modules/auth'
|
|
|
+ import { useColumnsStore } from '@/stores/modules/columns'
|
|
|
import { useBaseStore } from '@/stores/modules/base'
|
|
|
const store = useAuthStore()
|
|
|
+ const colStore = useColumnsStore()
|
|
|
const base = useBaseStore()
|
|
|
let { app } = storeToRefs(store)
|
|
|
- let { PageUpParam,nowPageData,keyid,pageTotal } = storeToRefs(base)
|
|
|
- const emit = defineEmits('listData')
|
|
|
+ let { PageUpParam,nowPageData,keyid,pageTotal,fullscreen } = storeToRefs(base)
|
|
|
+ let { selectedColumns } = storeToRefs(colStore)
|
|
|
const router = useRouter()
|
|
|
const props = defineProps({
|
|
|
param: Object,
|
|
@@ -69,45 +94,47 @@
|
|
|
keyRouteName:String,
|
|
|
searchType:Array,
|
|
|
detailPage:Object,
|
|
|
- noAutoQuery:Boolean
|
|
|
+ noAutoQuery:Boolean,
|
|
|
+ tableRowStyle:Function
|
|
|
})
|
|
|
const loading = ref(false)
|
|
|
const columns = ref([])
|
|
|
const dataSource = ref([])
|
|
|
const total = ref(0)
|
|
|
|
|
|
- // const app = JSON.parse(sessionStorage.getItem('app'))
|
|
|
- const { proxy } = getCurrentInstance();
|
|
|
-
|
|
|
+ const formatter = (_record, index) => {
|
|
|
+ if (props.tableRowStyle)
|
|
|
+ return props.tableRowStyle(_record, index)
|
|
|
+ if (index % 2 === 1) {
|
|
|
+ return 'table-striped'
|
|
|
+ } else {
|
|
|
+ return null
|
|
|
+ }
|
|
|
+ }
|
|
|
const onChange = (pagination, filters, sorter, { currentDataSource })=>{
|
|
|
props.param.content.pageNumber = pagination.current
|
|
|
props.param.content.pageSize = pagination.pageSize
|
|
|
tableData()
|
|
|
}
|
|
|
const getTableLayout = ()=>{
|
|
|
- try {
|
|
|
- let _app = {}
|
|
|
- _app = app.value
|
|
|
- columns.value = _app.meta.tables[props.tableName].tablecols.map(e=>{
|
|
|
- return {
|
|
|
- title:e.title,
|
|
|
- dataIndex:e.columnname,
|
|
|
- width:e.width == 0?'150':e.width,
|
|
|
- ellipsis:true,
|
|
|
- fixed:e.columnname == 'operation'?'right':''
|
|
|
- }
|
|
|
- })
|
|
|
- } catch (error) {
|
|
|
+ /**
|
|
|
+ * 开启列过滤时需要传tableid,因此在获取表格数据的时候把table赋值到请求参数中
|
|
|
+ */
|
|
|
+ props.param.content.tableid = app.value.meta.tables[props.tableName].tableid
|
|
|
|
|
|
+ let param = {
|
|
|
+ tableName:props.tableName,
|
|
|
+ app:app.value,
|
|
|
+ fn:()=>{
|
|
|
+ columns.value = utils.TBLayout(props.tableName)
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
+ colStore.setConfig(param)
|
|
|
}
|
|
|
const sort = ref([])
|
|
|
const tableData = async ()=>{
|
|
|
loading.value = true
|
|
|
const res = await Api.requested(props.param)
|
|
|
- emit('listData',res)
|
|
|
- console.log(res.data);
|
|
|
dataSource.value = res.data
|
|
|
total.value = res.total
|
|
|
sort.value = res.sort
|
|
@@ -137,24 +164,80 @@
|
|
|
props.param.content.sort = [nowSort.value]
|
|
|
tableData()
|
|
|
}
|
|
|
+ const cache = ref([])
|
|
|
+ const setSearchParam = (dataIndex,value)=>{
|
|
|
+ props.param.content.pageNumber = 1
|
|
|
+ props.param.content.where.tablefilter = props.param.content.where.tablefilter ? props.param.content.where.tablefilter : {}
|
|
|
+ props.param.content.where.tablefilter[dataIndex] = value
|
|
|
+
|
|
|
+ //缓存搜索数据
|
|
|
+ let rs = cache.value.some(item=>item.dataIndex == dataIndex)
|
|
|
+ if (rs) {
|
|
|
+ cache.value.forEach(e=>{
|
|
|
+ if (e.dataIndex == dataIndex) {
|
|
|
+ e.value = value
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ cache.value.push({
|
|
|
+ dataIndex:dataIndex,
|
|
|
+ value:value
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ let param = {
|
|
|
+ tableName:props.tableName,
|
|
|
+ app:app.value,
|
|
|
+ cache:cache.value
|
|
|
+ }
|
|
|
+ colStore.cacheInputParam(param)
|
|
|
+ }
|
|
|
+ const setSort = (column,sort)=>{
|
|
|
+ props.param.content.simplesort = {}
|
|
|
+ column.sort = props.param.content.simplesort[column.dataIndex] = sort
|
|
|
+ columns.value.forEach(e=>{
|
|
|
+ if (e.dataIndex !== column.dataIndex) {
|
|
|
+ e.sort = 0
|
|
|
+ }
|
|
|
+ })
|
|
|
+ tableData()
|
|
|
+
|
|
|
+ }
|
|
|
defineExpose({
|
|
|
tableData
|
|
|
})
|
|
|
+ /**
|
|
|
+ * 开启缓存后需要拉取新数据
|
|
|
+ */
|
|
|
+ onActivated(()=>{
|
|
|
+ getTableLayout()
|
|
|
+ })
|
|
|
onMounted (()=>{
|
|
|
getTableLayout()
|
|
|
props.noAutoQuery ? '' : tableData()
|
|
|
})
|
|
|
+ watch (() => selectedColumns.value,(n, o) => {
|
|
|
+ columns.value = colStore.getCacheInputParam({
|
|
|
+ tableName:props.tableName,
|
|
|
+ app:app.value,
|
|
|
+ columns:selectedColumns.value
|
|
|
+ })
|
|
|
+ })
|
|
|
</script>
|
|
|
<style scoped>
|
|
|
.btn-link{
|
|
|
text-decoration: underline;
|
|
|
}
|
|
|
-.ant-table-striped :deep td{
|
|
|
+.ant-table-small :deep td{
|
|
|
font-size: 12px;
|
|
|
+ min-width: 150px;
|
|
|
}
|
|
|
-.ant-table-striped :deep(.table-striped) td {
|
|
|
- background-color: #fafafa;
|
|
|
-
|
|
|
+.ant-table-small :deep(.table-striped) td {
|
|
|
+ background-color: #f8f9fd;
|
|
|
+
|
|
|
+}
|
|
|
+.ant-table-small :deep(.table-striped-red) td {
|
|
|
+ color: #d9363e;
|
|
|
}
|
|
|
.flex{
|
|
|
display: flex;
|
|
@@ -167,7 +250,11 @@
|
|
|
text-align: right;
|
|
|
}
|
|
|
.ant-dropdown-link{
|
|
|
- /* font-size: 12px; */
|
|
|
color:#333
|
|
|
}
|
|
|
-</style>
|
|
|
+.flex-between{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+</style>
|