<!-- -->
<template>
<P-PageCard v-bind="PageCardConfig">
<!-- 此块内容暂不开启 s -->
<div v-if="headerConfig.show" slot="header" class="pc-header">
<div class="pc-header-con">
<div class="pc-header-title">
<a-icon v-if="headerConfig.title.icon" :type="headerConfig.title.icon" class="pc-header-title-icon" />
<slot v-if="!headerConfig.title.icon" name="titleIcon"></slot>
<span :class="['pc-header-title-label',headerConfig.title.labelClass]" :style="headerConfig.title.labelStyle">{{headerConfig.title.label}}</span>
</div>
<div v-if="headerConfig.backBtn.show" class="pc-header-btn">
<a-button :type="headerConfig.backBtn.btnType" :icon="headerConfig.backBtn.icon" @click="btnEvent('backBtn')" class="header-btn-item">{{headerConfig.backBtn.label}}</a-button>
</div>
</div>
</div>
<!-- 此块内容暂不开启 e -->
<div class="pc-body-con">
<div class="pc-body-query">
<div class="pc-query">
<!-- <slot name="default"></slot> -->
<p-PageForm ref="PPageFormDefault" :PEvent="formEvent" :formDataList="formConfig.formDataListDefault" :layout="formConfig.layouttDefault" :showHelp="showHelp">
<!-- <slot name="defaultForm"></slot> -->
<!-- <template v-slot:userName7="{value, itemData}" ></template> -->
</p-PageForm>
</div>
<div class="pc-body-btn">
<a-button type="primary" icon="search" class="body-btn-item" @click="btnEvent('query')">查询</a-button>
<a-button icon="reload" class="body-btn-item" @click="btnEvent('reset')">重置</a-button>
<a-button :key="btnItem.btnKey" v-for="(btnItem,index) in btnList" v-has="btnItem.vhas" @click="btnEvent(btnItem.btnKey,index,btnItem)" :type="btnItem.btnType" :disabled="btnItem.disabled" :icon="btnItem.icon" class="body-btn-item" v-bind="otherAttr">{{btnItem.label}}</a-button>
<a-button type="link" class="body-btn-item" @click="showPanel" v-if="formConfig.formDataListOther.length>0">
更多<a-icon type="down" class="tb"/>
</a-button>
</div>
</div>
<div :class="['pc-body-panel',headerConfig.isDefaultHeadBottomBorder == true&&'show-border-top']">
<!-- <slot name="other"></slot> -->
<p-PageForm ref="PPageFormOther" v-if="formConfig.formDataListOther.length>0" :PEvent="formEvent" :formDataList="formConfig.formDataListOther" :layout="formConfig.layouttOther" :showHelp="showHelp">
<!-- <template v-slot:userName7="{value, itemData}" >
<component :is="'Pbutton'"></component>
</template> -->
</p-PageForm>
</div>
<div class="pc-body-table">
<slot v-if="showTableSlot==true" name="table"></slot>
<a-table v-if="showTableSlot==false" :columns="columns" :data-source="dataSource" :pagination="pagination" @change="tableChangeEvent" v-bind="otherAttr">
<template v-for="(item) in customRenderList" :slot="item.keyName" slot-scope="text, record,index">
<slot :name="item.keyName" :data="{ text, record, index, indent: { [item.keyName]: text ,[item.title]:item.dataIndex} }"></slot>
</template>
</a-table>
<!-- <span v-if="showTableHeader==true" >
<template slot="title" slot-scope="currentPageData">
<slot name="title" :data="currentPageData"></slot>
</template>
</span>
<span v-if="showTableFooter==true" slot="footer" slot-scope="currentPageData">
<slot name="footer" :data="currentPageData"></slot>
</span> -->
</div>
</div>
</P-PageCard>
</template>
<script>
import IS from './../utils/is'
import UUID from './../utils/uuid'
import anime from "animejs/lib/anime.js";
import PPageCard from './../Card'
// import Vue from 'Vue';
export default {
// import引入的组件需要注入到对象中才能使用
name: "PQueryCard",
components: {PPageCard},
props: {
// 事件池
eventPool: {
type: Function, // backBtn query reset form-Panel 【queryBtnList按钮事件 btnKey = cloudDownload】
},
config:{
type:Object,
default: ()=>{
return {
/**
* 整个组件的最外层设置 包括 外围样式 等
*/
PageCardConfig: {
// 表示是否显示外围边框
isCardBorder: false,
// 头部下的边框
isHeadBottomBorder: true,
// card-body 的样式 class
bodyClass: "",
// card-body 的样式 style
bodyStyle: {
width: "100%",
display: "flex",
"justify-content": "center",
"align-items": "center",
"margin-top":"40px",
},
// 表示是否显示阴影 always 表示一直显示 hover 表示鼠标移动上面时显示 never 表示不显示
shadow: "never",
style: { margin: "10px", width: "100%" },
},
/**
* 顶部标题设置
*/
headerConfig:{
show:true,
title:{
icon:'bars', // 支持 插槽 插槽名称【titleIcon】 当icon 的值为空时启用插槽
label:'这是标题',
labelClass:'',
labelStyle:{},
},
backBtn:{
show:true,
icon:'left',
btnType:'', // 组件库 Button 的 type 类型值
label:'返回'
},
// 是否显示查询条件的分割线
isDefaultHeadBottomBorder: false,
},
// 查询表单的布局设置 rowNum 表示行数 columnNum 表示列数 rowGap 行间距 rowHeight 行高 coliumnGap 列间距 labelCol 表单label的自适应设置 wrapperCol 表单的值部分的自适应设置
// xs <576px sm ≥576px md ≥768px lg ≥992px xl ≥1200px xxl ≥1600px
layouttDefault:{ rowNum: 1, columnNum: 3, rowGap: "1px",rowHeight:'50px', coliumnGap: "10px", labelCol: { xs: 12, sm: 12, md: 10, lg: 10, xl:10, xxl:10 }, wrapperCol: { xs: 12, sm: 12, md: 12, lg: 12, xl:12, xxl:12}},
layouttOther:{ rowNum: 4, columnNum: 4, rowGap: "1px",rowHeight:'50px', coliumnGap: "10px", labelCol: { xs: 12, sm: 12, md: 10, lg: 10, xl:10, xxl:10 }, wrapperCol: { xs: 12, sm: 12, md: 12, lg: 12, xl:12, xxl:12}},
}
},
},
// 和查询按钮并排放的按钮集合 如 下载 {btnKey:'11',label:'下载',icon:'cloud-download',btnType:'',vhas:'', disabled:false, otherAttr:{}}
queryBtnList:{type:Array},
// 查询表单集合 具体 参照表单属性 新增 componentName:'Pbutton', componentItem:Pbutton
formDataList:{type:Array},
// table 表设置 支持插槽 插槽名称 table
tableConfig:{type:Object,default:()=>{
return {
// 用于控制是否启用自定义table的插槽, false 表示不起用 使用默认table true 表示启用自定义table插槽
showTableSlot:false,
// 是否显示table title ; 默认为false,不显示 true 表示显示
showTableHeader:false,
// 是否显示table footer ; 默认为false,不显示 true 表示显示
showTableFooter:false,
columns:[],
data:[],
pagination:{
current: 1,
pageSize: 10,
total: 0,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return " 共" + total + "条"
},
showSizeChanger: true
},
// table 的其他属性
otherAttr:{}
}
}},
showHelp:{type:Boolean, default: () => { return false }}
},
data() {
// 这里存放数据
return {
animeSwitch: false,
configKey:'',
/**
* 此块内容暂不开启
*/
PageCardConfig: {
// 表示是否显示外围边框
isCardBorder: false,
// 头部下的边框
isHeadBottomBorder: true,
// card-body 的样式 class
bodyClass: "",
// card-body 的样式 style
bodyStyle: {
width: "100%",
display: "flex",
"justify-content": "center",
"align-items": "center",
"margin-top":"40px",
},
// 表示是否显示阴影 always 表示一直显示 hover 表示鼠标移动上面时显示 never 表示不显示
shadow: "never",
style: { padding: "10px", width: "100%" },
},
/**
* 此块内容暂不开启
*/
headerConfig:{
show:true,
// 是否显示查询条件的分割线
isDefaultHeadBottomBorder: false,
title:{
icon:'bars',
label:'这是标题',
labelClass:'',
labelStyle:{},
},
backBtn:{
show:true,
icon:'left',
btnType:'',
label:'返回'
}
},
btnList:[
// {btnKey:'cloudDownload',label:'下载',icon:'cloud-download',btnType:'',disabled:false}
],
formConfig:{
layouttDefault:{ rowNum: 1, columnNum: 3, rowGap: "1px",rowHeight:'50px', coliumnGap: "10px",labelCol: { xs: 12, sm: 12, md: 10, lg: 10, xl:10, xxl:10 }, wrapperCol: { xs: 12, sm: 12, md: 12, lg: 12, xl:12, xxl:12}},
layouttOther:{ rowNum: 4, columnNum: 4, rowGap: "1px",rowHeight:'50px', coliumnGap: "10px", labelCol: { xs: 12, sm: 12, md: 10, lg: 10, xl:10, xxl:10 }, wrapperCol: { xs: 12, sm: 12, md: 12, lg: 12, xl:12, xxl:12}},
formDataListDefault:[],
formDataListOther:[],
},
formData:{},
formData_:{},
// 用于处理值是否发生变化的key
tableConfigKey:'',
showTableSlot:true,
// 是否显示table title ; 默认为false,不显示 true 表示显示
showTableHeader:false,
// 是否显示table footer ; 默认为false,不显示 true 表示显示
showTableFooter:false,
columns:[],
dataSource:[],
// table 的其他属性
otherAttr:{
bordered:true,
},
pagination:{
current: 1,
pageSize: 10,
total: 0,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return " 共" + total + "条"
},
showSizeChanger: true
},
customRenderList:[],
}
},
// 监听属性 类似于data概念
computed: {},
// 监控data中的数据变化
watch: {
queryBtnList: {
handler(val) {
if(IS.isArray(val)){
this.btnList = val
}
},
deep: true,
immediate: true,
},
formDataList: {
handler(val) {
if(IS.isArray(val)){
this.setFormData(val)
}
},
deep: true,
immediate: true,
},
config: {
handler(val) {
const newKey = UUID('MDUUID',JSON.stringify(val))
if(!IS.isNullOrUnDef(val) && IS.isObject(val) && newKey != this.configKey){
this.setConfig(val)
this.configKey = newKey
}
},
deep: true,
immediate: true,
},
tableConfig: {
handler(val) {
const newKey = UUID('MDUUID',JSON.stringify(val))
if(!IS.isNullOrUnDef(val) && IS.isObject(val) && newKey!=this.tableConfigKey){
this.setTable(val)
this.tableConfigKey = newKey
}
},
deep: true,
immediate: true,
},
},
// 生命周期 - 创建完成(可以访问当前this实例)
created() {},
// 生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
this.$nextTick(()=>{
this.showPanel()
})
if(this.$isShowHelp == true && this.showHelp==true){
console.log(`
组件名称:
PQueryCard
使用方法:样式【swiper-slide】必填
<p-SwiperCon :onChange="onSWChange">
<div class="swiper-slide">插槽1</div>
<div class="swiper-slide">插槽2</div>
<div class="swiper-slide">插槽3</div>
</p-SwiperCon>
props参数说明:
props:{
// 此参数可选 用于相应组件的变化事件 此事件的参数为 当前切换的索引值,索引从0开始
onChange: {type: Function},
},
`)
}
},
// 方法集合
methods: {
showPanel() {
const {formConfig:{formDataListOther,layouttOther},animeSwitch,eventPool,formData} = this
let height_ = "0px";
let rotate_ = 0;
let padding_ = ''
// rowInfo
const ys = formDataListOther.length % layouttOther.columnNum >0 ? 1 : 0;
const rowSize = Math.floor(formDataListOther.length / layouttOther.columnNum)+ys;
const btnSize = 3;
const tempHeight = rowSize * 40 + 20 // rowSize * 65 + 20 + (btnSize > 0 ? 54 : 0);
// 54
if (animeSwitch) {
height_ = tempHeight + "px"; // '180px'
rotate_ = 180;
padding_ = '10px 20px'
}
if (!animeSwitch) {
height_ = "0px";
rotate_ = 0;
padding_ = '0px'
}
// console.log(rowSize,height_,this.formConfig.formDataListOther.length, this.formConfig.layouttOther.columnNum)
anime({
targets: ".pc-body-panel",
height: height_,
duration: 400,
// backgroundColor: '#A4FF4F',
padding:padding_,
easing: "easeInOutQuad",
});
anime({
targets: ".tb",
rotate: {
value: rotate_,
duration: 400,
easing: "easeInOutSine",
},
});
this.getFormData()
this.animeSwitch = !animeSwitch;
eventPool && eventPool(`form-Panel`,{ItemData:null,formData:formData})
},
setConfig(config_){
const {formConfig:{layouttDefault,layouttOther},headerConfig,PageCardConfig} = this
const {PageCardConfig:PageCardConfig_={},headerConfig:headerConfig_={},layouttDefault:layouttDefault_={},layouttOther:layouttOther_={}} = config_
if(!IS.isEmpty(PageCardConfig_)){
this.PageCardConfig =Object.assign({},PageCardConfig,PageCardConfig_)
}else{
this.PageCardConfig =Object.assign({},PageCardConfig)
}
if(!IS.isEmpty(headerConfig_)){
this.headerConfig = Object.assign({},headerConfig,headerConfig_)
}else{
this.headerConfig = Object.assign({},headerConfig)
}
if(!IS.isEmpty(layouttDefault_)){
this.formConfig.layouttDefault = Object.assign({},layouttDefault,layouttDefault_)
}else{
this.formConfig.layouttDefault = Object.assign({},layouttDefault)
}
if(!IS.isEmpty(layouttOther_)){
this.formConfig.layouttOther = Object.assign({},layouttOther,layouttOther_)
}else{
this.formConfig.layouttOther = Object.assign({},layouttOther)
}
// console.log('@@@@@@@@@@@@@@',config_,this.formConfig);
},
setFormData(formList){
if(formList.length==0){
return false
}
let defaultListArr = [], otherListArr = []
formList.forEach(item=>{
const {isDefault,component,...args} = item
if(isDefault===true){
defaultListArr.push({...args})
}else{
otherListArr.push({...args})
}
})
// 当没有设置 isDefault 属性时,从otherListArr中选择前三个方进去
const tempotherListArr = []
if(defaultListArr.length==0){
otherListArr.forEach((item,index)=>{
if(index<3){
defaultListArr.push(item)
}else{
tempotherListArr.push(item)
}
})
otherListArr = tempotherListArr
}
this.formConfig.formDataListDefault = defaultListArr
this.formConfig.formDataListOther = otherListArr
},
setCustomRender(columns){
const tempArr = []
if(!IS.isNullOrUnDef(columns) && IS.isArray(columns)){
columns.forEach(item=>{
const { scopedSlots,dataIndex,title } = item
if (scopedSlots && scopedSlots.customRender) {
tempArr.push({keyName:scopedSlots.customRender,dataIndex,title})
}
})
}
this.customRenderList = tempArr
},
setTable(config_){
const {showTableSlot,columns,data,pagination,otherAttr,showTableHeader,showTableFooter} = config_
this.showTableSlot = showTableSlot || false
this.columns = columns
this.dataSource = data
this.showTableHeader = showTableHeader || false
this.showTableFooter = showTableFooter || false
this.setCustomRender(columns)
if(!IS.isEmpty(otherAttr)){
this.otherAttr = Object.assign({},this.otherAttr,otherAttr)
}else{
this.otherAttr = Object.assign({},this.otherAttr)
}
if(!IS.isEmpty(pagination)){
this.pagination = Object.assign({},this.pagination,pagination)
}else{
this.pagination = Object.assign({},this.pagination)
}
if(IS.isBoolean(pagination) && pagination==false){
this.pagination = pagination
}
},
async getFormData(){
const formRes = await this.$refs.PPageFormDefault.onSubmit()
this.formData = {...this.formData,...formRes}
this.formData_ = {...this.formData_,...this.$refs.PPageFormDefault.form}
if(this.$refs.PPageFormOther){
const formRes1 = await this.$refs.PPageFormOther.onSubmit()
this.formData = {...this.formData,...formRes1}
this.formData_ = {...this.formData_,...this.$refs.PPageFormOther.form}
}
// this.$refs.PPageFormDefault.onSubmit((formRes)=>{
// this.formData = {...this.formData,...formRes}
// })
// this.$refs.PPageFormOther && this.$refs.PPageFormOther.onSubmit((formRes)=>{
// this.formData = {...this.formData,...formRes}
// })
},
resetFormData(){
this.formConfig.formDataListDefault.forEach(item=>{
// item.value =
})
},
formEvent(...param){
this.getFormData().then(item=>{
this.eventPool && this.eventPool(`form-${param[0]}`,{ItemData:param,formData:{...this.formData,[param[1]]:param[2]}})
})
},
btnEvent(key,item,data){
// console.log('btnEvent 111===>',key,item,data);
const queryAction = ()=>{
this.getFormData().then((data)=>{
this.eventPool && this.eventPool(key,{ItemData:data,formData:this.formData})
})
}
const actionList={
'query':(item_,data_)=>{
queryAction()
},
'reset':()=>{
this.$refs.PPageFormDefault && this.$refs.PPageFormDefault.resetForm()
this.$refs.PPageFormOther && this.$refs.PPageFormOther.resetForm()
this.getFormData().then(res=>{
this.$nextTick().then(()=>{
console.log('**********************reset**********************',JSON.stringify(this.formData),JSON.stringify(res));
this.eventPool && this.eventPool('reset',{ItemData:data,formData:this.formData})
})
})
}
}
actionList[key] && actionList[key](item,data)
if(!actionList[key]){
queryAction()
}
},
tableChangeEvent(pagination, filters, sorter, { currentDataSource }){
this.pagination.current = pagination.current
this.pagination.pageSize = pagination.pageSize
this.getFormData().then(res=>{
this.eventPool && this.eventPool(`table-change`,{ItemData:{pagination, filters, sorter,currentDataSource},formData:{...this.formData}})
})
},
},
}
</script>
<style lang="less" scoped>
.pc-header {
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
.pc-header-con {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.pc-header-title {
.pc-header-title-icon {
margin-right: 5px;
}
.pc-header-title-label {
font-weight: 600;
color: rgba(48, 49, 51, 0.5);
}
}
.pc-header-btn {
.header-btn-item {
margin: 0 3px;
}
}
}
.pc-header-panel {
width: 100%;
border: 1px solid #c3c3c3;
}
}
.pc-body-con{
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
.pc-body-query {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.pc-query {
height: 100%;
flex: 1;
display: flex;
justify-content:flex-start;
align-items: center;
/deep/.ant-form-item{
margin-bottom: 0px;
}
}
.pc-body-btn {
.body-btn-item {
margin: 0 3px;
}
}
}
.pc-body-panel {
width: 100%;
// border: 1px solid #c3c3c3;
overflow: auto;
margin: 10px 0;
padding: 10px 20px;
box-sizing: border-box;
/deep/.ant-form-item{
margin-bottom: 0px;
}
&.show-border-top{
border-top: 1px solid #c3c3c3;
}
&.show-border{
border: 1px solid #c3c3c3;
}
}
.pc-body-table{
width: 100%;
// min-height: 500px;
// border: 1px solid #c3c3c3;
}
}
</style>