376 lines
7.5 KiB
Vue
376 lines
7.5 KiB
Vue
|
|
<template>
|
||
|
|
<div
|
||
|
|
v-if="props.visible"
|
||
|
|
class="base-dialog-overlay"
|
||
|
|
:style="{ zIndex: props.zIndex }"
|
||
|
|
@click="handleOverlayClick"
|
||
|
|
>
|
||
|
|
<div class="base-dialog" @click.stop :style="{ maxWidth: `${props.maxWidth}px` }">
|
||
|
|
<!-- 四个角的装饰 -->
|
||
|
|
<div class="corner corner-top-left"></div>
|
||
|
|
<div class="corner corner-top-right"></div>
|
||
|
|
<div class="corner corner-bottom-left"></div>
|
||
|
|
<div class="corner corner-bottom-right"></div>
|
||
|
|
|
||
|
|
<!-- 标题栏 -->
|
||
|
|
<div class="dialog-header">
|
||
|
|
<div class="header-title">{{ props.title }}</div>
|
||
|
|
<div class="close-btn" @click="handleClose">
|
||
|
|
<el-icon><Close /></el-icon>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 标题栏下方自定义插槽 -->
|
||
|
|
<div class="header-slot">
|
||
|
|
<slot name="header"></slot>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 筛选区域 -->
|
||
|
|
<div class="filter-section" v-if="props.showFilter">
|
||
|
|
<slot name="filter"></slot>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 数据表格 -->
|
||
|
|
<div class="table-section" v-if="props.tableData.length > 0">
|
||
|
|
<el-table
|
||
|
|
:data="props.tableData"
|
||
|
|
:height="props.tableHeight"
|
||
|
|
style="width: 100%"
|
||
|
|
:header-cell-style="headerCellStyle"
|
||
|
|
:cell-style="cellStyle"
|
||
|
|
size="small"
|
||
|
|
>
|
||
|
|
<el-table-column
|
||
|
|
v-for="column in props.tableColumns"
|
||
|
|
:key="column.prop"
|
||
|
|
:prop="column.prop"
|
||
|
|
:label="column.label"
|
||
|
|
>
|
||
|
|
<template v-if="column.slot" #default="{ row }">
|
||
|
|
<slot :name="column.slot" :row="row"></slot>
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
</el-table>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 分页 -->
|
||
|
|
<div class="pagination" v-if="props.showPagination && props.tableData.length > 0">
|
||
|
|
<el-pagination
|
||
|
|
:current-page="props.currentPage"
|
||
|
|
:page-size="props.pageSize"
|
||
|
|
:page-sizes="props.pageSizes"
|
||
|
|
:total="props.total"
|
||
|
|
background
|
||
|
|
layout="prev, pager, next, jumper, ->, total"
|
||
|
|
@size-change="handleSizeChange"
|
||
|
|
@current-change="handleCurrentChange"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup>
|
||
|
|
import { ref, watch } from "vue";
|
||
|
|
import { Close } from "@element-plus/icons-vue";
|
||
|
|
import { ElTable, ElTableColumn, ElPagination } from "element-plus";
|
||
|
|
|
||
|
|
const props = defineProps({
|
||
|
|
visible: {
|
||
|
|
type: Boolean,
|
||
|
|
default: false,
|
||
|
|
},
|
||
|
|
title: {
|
||
|
|
type: String,
|
||
|
|
default: "弹窗标题",
|
||
|
|
},
|
||
|
|
zIndex: {
|
||
|
|
type: Number,
|
||
|
|
default: 1000,
|
||
|
|
},
|
||
|
|
maxWidth: {
|
||
|
|
type: Number,
|
||
|
|
default: 1000,
|
||
|
|
},
|
||
|
|
showFilter: {
|
||
|
|
type: Boolean,
|
||
|
|
default: true,
|
||
|
|
},
|
||
|
|
showPagination: {
|
||
|
|
type: Boolean,
|
||
|
|
default: true,
|
||
|
|
},
|
||
|
|
tableData: {
|
||
|
|
type: Array,
|
||
|
|
default: () => [],
|
||
|
|
},
|
||
|
|
tableColumns: {
|
||
|
|
type: Array,
|
||
|
|
default: () => [],
|
||
|
|
},
|
||
|
|
tableHeight: {
|
||
|
|
type: Number,
|
||
|
|
default: 300,
|
||
|
|
},
|
||
|
|
currentPage: {
|
||
|
|
type: Number,
|
||
|
|
default: 1,
|
||
|
|
},
|
||
|
|
pageSize: {
|
||
|
|
type: Number,
|
||
|
|
default: 10,
|
||
|
|
},
|
||
|
|
pageSizes: {
|
||
|
|
type: Array,
|
||
|
|
default: () => [10, 20, 30, 40],
|
||
|
|
},
|
||
|
|
total: {
|
||
|
|
type: Number,
|
||
|
|
default: 0,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
const emit = defineEmits(["update:visible", "close", "size-change", "current-change", "update:current-page", "update:page-size"]);
|
||
|
|
|
||
|
|
// 关闭对话框
|
||
|
|
const handleClose = () => {
|
||
|
|
emit("update:visible", false);
|
||
|
|
emit("close");
|
||
|
|
};
|
||
|
|
|
||
|
|
// 点击遮罩关闭
|
||
|
|
const handleOverlayClick = () => {
|
||
|
|
handleClose();
|
||
|
|
};
|
||
|
|
|
||
|
|
// 监听visible变化
|
||
|
|
watch(
|
||
|
|
() => props.visible,
|
||
|
|
(newVal) => {
|
||
|
|
if (newVal) {
|
||
|
|
// 弹窗打开时的逻辑
|
||
|
|
}
|
||
|
|
},
|
||
|
|
);
|
||
|
|
|
||
|
|
// 分页操作
|
||
|
|
const handleSizeChange = (val) => {
|
||
|
|
emit("update:page-size", val);
|
||
|
|
emit("size-change", val);
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleCurrentChange = (val) => {
|
||
|
|
emit("update:current-page", val);
|
||
|
|
emit("current-change", val);
|
||
|
|
};
|
||
|
|
|
||
|
|
// 表格样式
|
||
|
|
const headerCellStyle = () => {
|
||
|
|
return {
|
||
|
|
backgroundColor: "#1D5194",
|
||
|
|
color: "#fff",
|
||
|
|
fontSize: "14px",
|
||
|
|
fontWeight: "500",
|
||
|
|
textAlign: "center",
|
||
|
|
padding: "5px 0px",
|
||
|
|
border: "none",
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
const cellStyle = () => {
|
||
|
|
return {
|
||
|
|
backgroundColor: "#16334E",
|
||
|
|
color: "rgba(255, 255, 255, 0.85)",
|
||
|
|
fontSize: "13px",
|
||
|
|
textAlign: "center",
|
||
|
|
padding: "5px 0px",
|
||
|
|
border: "none",
|
||
|
|
};
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style lang="scss" scoped>
|
||
|
|
.base-dialog-overlay {
|
||
|
|
position: fixed;
|
||
|
|
top: 0;
|
||
|
|
left: 0;
|
||
|
|
right: 0;
|
||
|
|
bottom: 0;
|
||
|
|
background-color: rgba(0, 0, 0, 0.6);
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
}
|
||
|
|
:deep(.el-table--small) {
|
||
|
|
background: #16334E;
|
||
|
|
}
|
||
|
|
|
||
|
|
.base-dialog {
|
||
|
|
width: 80vw;
|
||
|
|
max-height: 80vh;
|
||
|
|
position: relative;
|
||
|
|
background: #16334e;
|
||
|
|
border: 1px solid rgba(64, 169, 255, 0.3);
|
||
|
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||
|
|
// 四个角的装饰
|
||
|
|
.corner {
|
||
|
|
position: absolute;
|
||
|
|
width: 20px;
|
||
|
|
height: 20px;
|
||
|
|
border: 1px solid #40a9ff;
|
||
|
|
z-index: 100;
|
||
|
|
pointer-events: none;
|
||
|
|
|
||
|
|
&.corner-top-left {
|
||
|
|
top: 0;
|
||
|
|
left: 0;
|
||
|
|
border-right: none;
|
||
|
|
border-bottom: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
&.corner-top-right {
|
||
|
|
top: 0;
|
||
|
|
right: 0;
|
||
|
|
border-left: none;
|
||
|
|
border-bottom: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
&.corner-bottom-left {
|
||
|
|
bottom: 0;
|
||
|
|
left: 0;
|
||
|
|
border-right: none;
|
||
|
|
border-top: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
&.corner-bottom-right {
|
||
|
|
bottom: 0;
|
||
|
|
right: 0;
|
||
|
|
border-left: none;
|
||
|
|
border-top: none;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 标题栏
|
||
|
|
.dialog-header {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
position: relative;
|
||
|
|
margin-bottom: 20px;
|
||
|
|
width: 100%;
|
||
|
|
|
||
|
|
.header-title {
|
||
|
|
background-image: url("../../../assets/RiskWarning_img/标题@2x.png");
|
||
|
|
background-size: 100% 100%;
|
||
|
|
background-position: right;
|
||
|
|
font-size: 18px;
|
||
|
|
font-weight: 600;
|
||
|
|
color: #fff;
|
||
|
|
width: 50%;
|
||
|
|
text-align: center;
|
||
|
|
padding: 12px 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.close-btn {
|
||
|
|
position: absolute;
|
||
|
|
right: 0;
|
||
|
|
top: 0;
|
||
|
|
width: 32px;
|
||
|
|
height: 32px;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
color: rgba(255, 255, 255, 0.7);
|
||
|
|
cursor: pointer;
|
||
|
|
font-size: 20px;
|
||
|
|
transition: color 0.3s;
|
||
|
|
|
||
|
|
&:hover {
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 标题栏下方自定义插槽
|
||
|
|
.header-slot {
|
||
|
|
margin-bottom: 20px;
|
||
|
|
padding: 0 24px;
|
||
|
|
overflow-y: auto;
|
||
|
|
max-height: 70vh;
|
||
|
|
scrollbar-width: none;
|
||
|
|
-ms-overflow-style: none;
|
||
|
|
|
||
|
|
&::-webkit-scrollbar {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 筛选区域
|
||
|
|
.filter-section {
|
||
|
|
margin-bottom: 16px;
|
||
|
|
padding: 0 24px;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 表格区域
|
||
|
|
.table-section {
|
||
|
|
width: 100%;
|
||
|
|
padding: 0 24px;
|
||
|
|
background: #16334E
|
||
|
|
}
|
||
|
|
|
||
|
|
// 分页
|
||
|
|
.pagination {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: flex-end;
|
||
|
|
gap: 16px;
|
||
|
|
padding: 12px;
|
||
|
|
background: #16334E;
|
||
|
|
|
||
|
|
:deep(.el-pagination) {
|
||
|
|
background: #16334E;
|
||
|
|
|
||
|
|
.el-pagination__total {
|
||
|
|
color: rgba(255, 255, 255, 0.6);
|
||
|
|
}
|
||
|
|
|
||
|
|
.el-pagination__sizes .el-input__inner {
|
||
|
|
background: #16334E;
|
||
|
|
border: 1px solid rgba(64, 169, 255, 0.3);
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.el-pagination__btn {
|
||
|
|
background: #16334E;
|
||
|
|
border: 1px solid rgba(64, 169, 255, 0.3);
|
||
|
|
color: rgba(255, 255, 255, 0.8);
|
||
|
|
|
||
|
|
&:hover:not(.is-disabled) {
|
||
|
|
background: rgba(64, 169, 255, 0.2);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.el-pagination__item {
|
||
|
|
background: #16334E;
|
||
|
|
border: 1px solid rgba(64, 169, 255, 0.3);
|
||
|
|
color: rgba(255, 255, 255, 0.8);
|
||
|
|
|
||
|
|
&:hover:not(.is-disabled) {
|
||
|
|
background: rgba(64, 169, 255, 0.2);
|
||
|
|
}
|
||
|
|
|
||
|
|
&.is-active {
|
||
|
|
background: #40a9ff;
|
||
|
|
border-color: #40a9ff;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.el-pagination__jump .el-input__inner {
|
||
|
|
background: #16334E;
|
||
|
|
border: 1px solid rgba(64, 169, 255, 0.3);
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|