474 lines
9.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">
<el-table
:data="props.tableData"
:height="props.tableHeight"
style="width: 100%; min-height: 300px"
: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"
:width="column.width"
:min-width="column.width === 'auto' ? '100px' : undefined"
>
<template v-if="column.slot" #default="{ row }">
<slot :name="column.slot" :row="row"></slot>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div class="pagination">
<el-pagination
:current-page="props.currentPage"
:page-size="props.pageSize"
:page-sizes="props.pageSizes"
:total="props.total"
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";
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;
:deep(.el-select__wrapper) {
background: #122c46 !important;
}
}
// 表格区域
.table-section {
width: 100%;
padding: 0 24px;
background: #16334e;
}
:deep(.el-table__inner-wrapper:before) {
width: 0% !important;
}
// 分页
.pagination {
display: flex;
align-items: center;
justify-content: flex-end;
padding: 12px 24px;
:deep(.btn-prev) {
background: #19334b !important;
color: #fff;
border: 1px solid #1f4f80;
}
:deep(.btn-next) {
background: #19334b !important;
color: #fff;
border: 1px solid #1f4f80;
}
:deep(.number) {
background: #19334b !important;
color: #2d90e3;
border: 1px solid #2d90e3;
}
:deep(.el-pagination) {
background: #16334e !important;
gap: 10px;
}
:deep(.el-pager) {
background: #16334e !important;
gap: 10px;
}
:deep(.el-input__wrapper) {
background: #16334e !important;
.el-input__inner {
color: #fff !important;
}
}
:deep(.el-pagination__jump) {
color: #fff !important;
}
:deep(.el-pagination__total) {
color: #fff !important;
}
}
// 下拉
.el-select {
.el-select__wrapper {
border-radius: 4px;
box-shadow: 0 0 0 1px #c5c5c5 inset;
height: 40px;
line-height: 40px;
background: #122c46;
color: #fff;
}
.el-select__wrapper.is-hovering,
.el-select__wrapper.is-focused {
box-shadow: 0 0 0 1px #3380ec inset;
// filter: brightness(1.3);
}
}
:deep(.el-select__placeholder) {
font-weight: 400;
color: #40a9ff !important;
}
// 下拉选项浮窗
.el-popper {
// 下拉选项
.el-select-dropdown {
background: #122c46;
.el-select-dropdown__item {
display: flex;
align-items: center;
color: #fff;
background-color: #122c46;
text-stroke: 0px #3a6fbf;
-webkit-text-stroke: 0px #3a6fbf;
height: 40px;
&.is-hovering {
background: #0f2e6d;
font-weight: bold;
color: #7bc8ef;
text-stroke: 0px #7bc8ef;
font-style: normal;
text-transform: none;
-webkit-text-stroke: 0px #7bc8ef;
}
}
}
}
/* 修改小三角箭头的背景色和边框 */
:deep(.el-popper__arrow::before) {
background-color: #122c46 !important;
}
:deep(.custom-select-popper) {
background-color: #122c46 !important; /* 整体背景色 */
border: 1px solid #122c46 !important; /* 边框颜色 */
border-radius: 8px !important; /* 圆角 */
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important; /* 阴影 */
}
/* 覆盖下拉框的白色边框 */
:deep(.el-popper.is-light .el-popper__arrow::before) {
background-color: #122c46 !important;
border-color: #122c46 !important;
}
:deep(.el-select-dropdown) {
border: 1px solid #122c46 !important;
background-color: #122c46 !important;
}
:deep(.el-popper[data-popper-placement^="bottom"]) {
border: 1px solid #122c46 !important;
}
:deep(.el-popper[data-popper-placement^="top"]) {
border: 1px solid #122c46 !important;
}
:deep(.el-popper__arrow) {
border-color: #122c46 !important;
}
:deep(.el-popper__arrow::after) {
border-color: #122c46 !important;
}
:deep(.el-pager li.is-active) {
background-color: #2598ff !important;
color: #fff !important;
}
</style>