middleground_code_v2/src/components/base/baseLayout/index.vue

684 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @name: 页面基本结构组件
* @author: zhangpengcheng
* @date: 2022-08-23
-->
<!-- style="overflow: auto;" -->
<template>
<div class="container" v-loading="loading" :style="'backgroundColor:' +
bgColor +
';paddingBottom:' +
paddingBottom +
';height:' +
bodyHight
" ref="baseLayout">
<!-- 标题 -->
<div flex="cross:center" style="padding: 10px" :style="{
'justify-content':
searchShow || showTitle ? 'space-between' : 'flex-end',
}" v-if="showTitle">
<div class="title" v-if="showTitle">
<span v-if="showTitle">{{ title }}</span>
</div>
<div flex="cross:center" v-if="searchShow">
<i class="queryIcon" :class="queryShow ? 'el-icon-arrow-down' : 'el-icon-arrow-right'"
@click="queryShowChange"></i>
<el-dropdown trigger="click">
<span class="el-dropdown-link" style="cursor: pointer; color: #303133; font-size: 14px">
默认条件<i class="el-icon-arrow-down el-icon--right" style="margin-left: 8px"></i>
</span>
<el-dropdown-menu slot="dropdown" style="
padding: 7px 20px;
background-color: #f5f7fa;
border: 1px soild #dcdfe6;
">
<el-dropdown-item command="a" class="requirementList">默认查询
</el-dropdown-item>
<el-dropdown-item v-for="(item, index) in requirementList" :key="item.command" :command="item.command">
<div flex="cross:center main:justify">
<p>{{ item.title }}</p>
<div flex="cross:center ">
<i class="el-icon-edit" @click="edit(item)"></i>
<i class="el-icon-close" @click="del(item)"></i>
</div>
</div>
</el-dropdown-item>
<el-dropdown-item command="d">创建方案</el-dropdown-item>
<el-dropdown-item command="e">高级查询</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<!-- <p>高级查询</p> -->
</div>
<div flex="cross:centet" v-if="buttonList && buttonList.length > 0">
<el-dropdown v-for="(item, index) in buttonList" class="buttonList" :key="index" @command="dropClick">
<el-button :type="item.type ? item.type : 'primary'" size="small" class="iconfont" :icon="item.icon"
@keyup.prevent.native @keydown.enter.prevent.native @click="funNewClick(item)">
{{
item.menuName
}}<i v-if="item.dropList && item.dropList.length > 0" class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<!-- <i class="el-icon-arrow-down el-icon--right"> -->
<el-dropdown-item v-for="(dropItem, dropIndex) in item.dropList" :key="dropIndex" :icon="dropItem.icon"
:command="dropItem.dropFun">{{ dropItem.title }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<!-- <div class="main":style="'backgroundColor:'+ mainColor " > -->
<!-- 搜索 -->
<div class="main" :style="'height:' + mainHight + ';backgroundColor:' + mainColor">
<!-- 搜索 -->
<div v-show="queryShow" style="padding: 16px;" flex="cross:center" ref="serchRefs" class="searchContainer">
<div v-for="(row, indexRow) in searchList" class="searchBox" :key="indexRow">
<el-input v-model="ruleForm[row.prop]" clearable :type="row.type ? row.type : 'text'" style="width: 100%"
:placeholder="!row.placeholder ? '请输入' : row.placeholder" v-if="row.tag === 'elInput'" min="1">
</el-input>
<el-date-picker v-model="ruleForm[row.prop]" v-if="row.tag === 'elDatePicker'"
:class="{ one: row.type ? 'date' : row.type }" style="width: 100%"
:value-format="!row.valueFormat ? 'yyyy-MM-dd' : row.valueFormat" range-separator="至" start-placeholder="开始日期"
end-placeholder="结束日期" :type="!row.type ? 'date' : row.type"
:placeholder="!row.placeholder ? '请选择' : row.placeholder">
</el-date-picker>
<el-radio-group v-model="ruleForm[row.prop]" v-if="row.tag === 'elRadio'">
<el-radio-button v-for="el in row.options" :label="el.value" :key="el.value">{{ el.label }}
</el-radio-button>
</el-radio-group>
<div v-if="row.tag === 'elDialog'" class="elDialog" style="cursor: pointer; height: 32px; ine-height: 32px">
<p :style="{ color: ruleForm[row.prop] ? '#000' : '#c0c4cc' }" style="width: 100%; margin: 0"
@click="elDialogClick(row, indexRow, indexRow)">
{{
ruleForm[row.prop]
? ruleForm[row.prop]
: row.placeholder
? row.placeholder
: "请点击选择"
}}
</p>
<i class="el-icon-more" @click="elDialogClick(row, index, indexRow)"
v-if="!row.disabled && !ruleForm[row.prop]"></i>
<i class="el-icon-circle-close" v-if="!row.disabled && ruleForm[row.prop]" @click="elDialogClear(row)"
style="margin-left: 10px"></i>
</div>
<el-select v-model="ruleForm[row.prop]" filterable style="width: 100%"
@change="selectChange($event, indexRow, indexRow, row)" :clearable="row.clearable ? row.clearable : true"
:placeholder="!row.placeholder ? '请选择' : row.placeholder" v-if="row.tag === 'elSelect'">
<el-option v-for="(el, elIndex) in row.options" :key="!row.optionValue ? el['value'] : el[row.optionValue]"
:label="!row.optionLabel ? el['label'] : el[row.optionLabel]"
:value="!row.optionValue ? el['value'] : el[row.optionValue]">
</el-option>
</el-select>
</div>
<!-- 搜索按钮 -->
<!-- <el-input
auto-complete="off"
placeholder="验证码"
style="width: calc(100% - 130px)"
v-show="false"
clearable
@keyup.enter.native="testEnter"
>
</el-input> -->
<el-button type="primary" icon="el-icon-search searchIcon" class="searchIcon" v-if="searchBtnShow" @click="search"
@keyup.enter="testEnter" style="margin-left: 15px">
</el-button>
<el-button type="primary" icon="el-icon-refresh searchIcon" class="searchIcon" v-if="resetBtnShow"
@click="refresh">
</el-button>
<el-button v-for="item in searchBtnList" :key="item.btnFunction" :type="item.type ? item.type : 'primary'"
size="small" class="searchIcon" :icon="item.icon" style="font-size:14px;" @click="funSearchBtnClick(item)">
{{ item.name }}
</el-button>
</div>
<div flex="cross:center" v-if="(searchModel.length != 0 && bottonShow) || nowBtns.length != 0">
<el-button type="primary" icon="el-icon-search" size="small" @click="showSearch" v-if="searchModel.length != 0">检索
</el-button>
<el-button type="primary" icon="el-icon-refresh" :plain="true" size="small" @click="refresh" v-if="false">刷新
</el-button>
</div>
<!-- 主要内容 -->
<slot name="main" :tableHeight="tableHeight"></slot>
<!-- 分页 -->
<base-page v-if="isPage" :pageModel.sync="pageModel" @onPageChange="onPageChange"></base-page>
</div>
</div>
</template>
<script>
// import heightTransition from '@/common/js/heightTransition'
// import customCascader from "@/components/customCascader";
import elementResizeDetectorMaker from "element-resize-detector";
import { exportDown, wordDown, zipDown } from "@/utils/util.js";
import basePage from "@/components/base/basePage";
import { TokenKeys } from "@/utils/variable";
// import fetch from '../../api/request'
import { getApiSign } from "@/utils/apiSign";
// import domainsFuc from '@/api/domains.js'
export default {
components: {
// heightTransition,
basePage,
// customCascader
},
props: {
// 搜索按钮列表
searchBtnList: {
type: Array,
default: () => {
return [];
},
},
// 是否展示标题
showTitle: {
type: Boolean,
default: true,
},
// 是否显示搜索按钮
searchBtnShow: {
type: Boolean,
default: true,
},
// 是否显示重置按钮
resetBtnShow: {
type: Boolean,
default: true,
},
// main高度
mainHight: {
type: [Number, String, Boolean],
default: "auto",
},
// 标题
title: {
type: String,
default: "",
},
// 标题
fixModel: {
type: String | Array,
default: () => {
return [];
},
},
// 查询列表
requirementList: {
type: Array,
default: () => {
return [];
},
},
// 搜索列表
searchList: {
type: Array,
default: () => {
return [];
},
},
// 背景颜色
bgColor: {
type: String,
default: "#ffffff",
},
// 背景颜色
mainColor: {
type: String,
default: "",
},
// 底部padding
paddingBottom: {
type: String,
// default: '68px'
},
// 高度
bodyHight: {
type: [Number, String],
default: "calc(100vh - 88px)",
},
// 搜索配置
searchModel: {
type: Array,
default: () => {
return [];
},
},
// 搜索配置
nowBtnTab: {
type: Array,
default: () => {
return [];
},
},
// 按钮配置
nowBtns: {
type: Array,
default: () => {
return [];
},
},
// 按钮配置
buttonList: {
type: Array,
default: () => {
return [];
},
},
// 是否展示分页
isPage: {
type: Boolean,
default: false,
},
// 搜索按钮显示
bottonShow: {
type: Boolean,
default: true,
},
// 默认条件隐藏显示
searchShow: {
type: Boolean,
default: false,
},
queryShow: {
type: Boolean,
default: true,
},
enterClickType: {
type: Boolean,
default: true,
},
// 导出接口地址
exportUrl: {
default: "",
},
// 导入接口地址
importUrl: {
default: "",
},
//多选
selectTable: {
default: "",
},
//单选
only: {
default: "",
},
},
watch: {},
data() {
return {
// 表单数据
ruleForm: {},
// queryShow: true,
onlyUrl: "",
clientHeight: "",
// 上传请求头
uploadHeaders: {},
// uurl: domainsFuc().domain,
uurl: "http://www.wldxt.cn:8089/taizhou/daxitong/crm/",
// 参数
model: {},
// 收起/展开搜索
isSearch: false,
// 分页数据
pageModel: {
total: 0,
pageIndex: 1,
pageSize: 10,
},
// 清除状态
clearState: 0,
// 操作按钮
tableHeight: "calc(100vh - 218px)",
loading: false,
};
},
created() {
},
mounted() {
this.watchSize();
document.addEventListener("keydown", (e) => {
let key = window.event.keyCode;
if (key == 13) {
this.testEnter();
}
});
// window.onresize = () => {
// this.clientHeight = document.documentElement.clientHeight;
// },
// this.importUpload(); //初始化上传
},
computed: {
// menuJson() {
// return JSON.parse(localStorage.getItem(TokenKeys.MENU_JSON))
// }
},
methods: {
watchSize() {
const _this = this;
var erd = elementResizeDetectorMaker();
if (!this.queryShow) {
_this.getTableHight();
} else {
erd.listenTo(this.$refs.serchRefs, (element) => {
// 这里的this.$refs.fan指定要监听的元素对象对应的是<div ref=“fan”></div>
var height = element.offsetHeight;
_this.$nextTick(() => {
_this.getTableHight(height);
});
});
}
},
getTableHight(height = 0) {
// 导航栏+标签栏 102 按钮列表64 查询条件64 分页32 102 + 64 + 32
let reduceHight = 0;
let windowHeight = this.$refs.baseLayout.offsetHeight;
if (this.isPage) {
reduceHight = reduceHight + 52;
}
if (this.queryShow) {
let searchHeight = this.$refs.serchRefs.offsetHeight;
reduceHight = reduceHight + searchHeight;
}
if (this.buttonList && this.buttonList.length > 0) {
reduceHight = reduceHight + 68;
}
this.tableHeight = windowHeight - reduceHight + "px";
},
//参数propLabel 值value
getField(propLabel, value) {
this.$set(this.ruleForm, propLabel, value);
},
setQueryShow(type) {
this.queryShow = type;
},
elDialogClick(row, index, indexRow) {
if (row.disabled) {
return;
}
this.$emit("elDialogClick", row, index);
},
elDialogClear(row) {
this.resetField(row.prop);
this.$emit("elDialogClear", row);
},
// 重置表单字段
resetField(field) {
if (this.ruleForm[field]) {
this.$set(this.ruleForm, field, "");
}
},
edit(item) {
},
del(item) {
},
pageClear() {
this.pageModel.pageIndex = 1;
},
// importUpload() {
// const timestamp = new Date().getTime() + '';
// const sign = getApiSign(timestamp);
// this.uploadHeaders['timestamp'] = timestamp;
// this.uploadHeaders['appKey'] = TokenKeys.APP_KEY;
// this.uploadHeaders['sign'] = sign;
// this.uploadHeaders[TokenKeys.ACCESS_TOKEN] = localStorage.getItem(TokenKeys.ACCESS_TOKEN);
// },
handleSuccess(res) {
const { code, msg, data } = res;
if (code && code == 10000) {
this.loading = false;
this.$vmNews("上传成功", "success");
} else {
this.$vmNews(msg);
this.loading = false;
}
},
handleProgress() {
this.loading = true;
},
handleError() {
this.$vmNews("上传失败", "error");
},
// 设置按钮
// 自定义级联选择器返回值
getCascader(value, field) {
this.$set(this.model, field, value);
},
// 设置分页total值
setPageTotal(total) {
this.$set(this.pageModel, "total", total);
},
setPageNum(pageNum) {
this.$set(this.pageModel, "page", pageNum);
},
// 搜索按钮点击事件
funSearchBtnClick(item) {
this.$emit("onFuncSearchBtn", item);
},
// 返回
goBack() {
this.$router.go(-1);
},
// 按钮点击事件
funNewClick(item) {
if (item.menuName == "刷新") {
this.$tab.refreshPage(this.$route);
} else {
this.$emit("onFuncBtn", item);
}
},
dropClick(item) {
this.$emit("dropClick", item);
},
// 查询隐藏展示
queryShowChange() {
this.queryShow = !this.queryShow;
this.$nextTick(() => {
this.watchSize();
});
this.$emit("queryShowChange", this.queryShow);
},
// 操作按钮点击事件
funcClick(btnItem) {
// console.log(btnItem,"btnItem")
this.$emit("onFuncBtn", btnItem);
},
// 导出函数
eventExport(params) {
// return fetch.get(this.onlyUrl ? this.onlyUrl : this.exportUrl, {
// params,
// responseType: 'blob'
// })
},
// 设置某个参数的值
setSomeParam(field, value = null) {
this.$set(this.model, field, value);
},
// 查询、重置事件
queryEvent(state) {
this.$emit("onQuery", this.mergeParam(true));
},
// 条件查询-下拉框
selectChange(event, index, indexItem, row) {
// if (typeof event == "number" && event < 3) {
// if (Number(event) == 2) {
// event = 0;
// } else {
// event = event - 1;
// }
// }
if (event !== "" && event != undefined) {
this.$emit("onElSelect", event, index, indexItem, this.model, row);
}
},
// 刷新
refresh() {
},
// 页数或每页条数更改时触发
onPageChange() {
this.$emit("pageChange", this.mergeParam());
},
// 合并参数
mergeParam(state) {
if (state) {
this.pageModel.pageIndex = 1;
}
let page = {
pageIndex: this.pageModel.pageIndex,
pageSize: this.pageModel.pageSize,
};
for (let i in this.model) {
if (!this.model[i]) {
this.model[i] = null;
}
}
let search = Object.assign({}, page, this.model);
return Object.assign({}, page, this.model);
},
// 收起展开分页
showSearch() {
this.isSearch = !this.isSearch;
},
search() {
this.$emit("search", this.ruleForm);
},
refresh() {
this.ruleForm = Object.assign({}, "");
this.$emit("onQuery", this.mergeParam(true));
},
testEnter() {
if (this.enterClickType) {
this.search();
}
},
},
};
</script>
<style scoped lang='scss'>
p {
margin: 0;
}
::v-deep .iconfont {
font-size: 12px;
}
.queryIcon {
font-size: 16px;
color: #606266;
margin-right: 16px;
cursor: pointer;
}
.searchIcon {
font-size: 18px;
/* padding: 0 12px; */
height: 32px;
/* line-height: 32px; */
margin-left: 8px;
display: flex;
justify-content: center;
align-items: center;
}
.requirementList {
width: 160px;
height: 30px;
line-height: 30px;
}
.container {
width: 100%;
height: 100%;
overflow: auto;
.title {
/* @include boxBase(100%, 48px, $base-color); */
/* @include fontBase(16px, #fff); */
font-size: 14px;
padding: 12px;
}
.buttonList {}
.buttonList+.buttonList {
margin-left: 8px;
}
.main {
/* height: auto !important; */
overflow-y: auto;
flex-wrap: wrap;
/* padding:0 12px; */
.search {
height: auto;
background: #f5f5f5;
border: 1px solid #d8d8d8;
padding: 12px;
transition: all 0.2s ease-in-out;
.row {
/* @include fontBase(14px, #333) */
}
}
.hide {
height: 0;
}
}
.main::-webkit-scrollbar {
width: 5px;
/* background-color: #D8D8D8; */
}
.main::-webkit-scrollbar-thumb {
border-radius: 5px;
width: 5px;
background: #b4bccc;
}
.w-100 {
width: 100%;
}
.mb-12 {
margin-bottom: 12px;
}
.back {
cursor: pointer;
}
}
.elDialog {
display: flex;
/* width: calc(100% - 14px);1 */
align-items: center;
justify-content: space-between;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 15px;
cursor: pointer;
background-color: white;
i {
color: #c0c4cc;
}
}
.searchBox {
width: 200px;
}
.searchBox+.searchBox {
margin-left: 8px;
}
::v-deep.el-radio-button--medium .el-radio-button__inner {
padding: 8px !important;
}
</style>