452 lines
10 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.

<template>
<div v-if="visible" class="tongnan-dialog-overlay" @click="handleOverlayClick">
<div class="tongnan-dialog" @click.stop>
<!-- 标题栏 -->
<div class="dialog-header">
<div class="header-title">潼南基本信息表</div>
<div class="close-btn" @click="handleClose">
<el-icon><Close /></el-icon>
</div>
</div>
<!-- 数据表格 -->
<div class="table-section">
<div class="table-header">
<div
v-for="(column, index) in tableColumns"
:key="index"
class="th"
:style="{ width: column.width, flex: column.flex || 'none' }"
>
{{ column.label }}
</div>
</div>
<div class="table-body">
<div
v-for="(item, index) in tableData"
:key="item.id"
class="table-row"
:class="{ 'row-even': index % 2 === 1 }"
>
<div class="td" style="width: 60px">{{ item.id }}</div>
<div class="td" style="width: 140px">{{ item.region }}</div>
<div class="td" style="width: 100px">{{ item.name }}</div>
<div class="td" style="width: 120px">{{ item.phone }}</div>
<div class="td" style="width: 180px">
<el-tooltip :content="item.stationName" placement="top" :show-after="500">
<span class="station-name-text" @click="handleStationNameClick(item)">{{ item.stationName }}</span>
</el-tooltip>
</div>
<div class="td" style="flex: 1">{{ item.type }}</div>
<div class="td" style="width: 140px">
<div class="action-btns">
<div class="action-btn" @click="handleVideo(item)" title="视频">
<el-icon><VideoCamera /></el-icon>
</div>
<div class="action-btn" @click="handleVoice(item)" title="语音">
<el-icon><Microphone /></el-icon>
</div>
<div class="action-btn" @click="handleCall(item)" title="电话">
<el-icon><Phone /></el-icon>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 分页 -->
<div class="pagination">
<span class="total">{{ total }}条数据</span>
<div class="page-btns">
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
<el-icon><ArrowLeft /></el-icon>
</div>
<div
v-for="page in visiblePages"
:key="page"
class="page-btn"
:class="{ active: currentPage === page }"
@click="goToPage(page)"
>
{{ page }}
</div>
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
<el-icon><ArrowRight /></el-icon>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch } from "vue";
import { Close, VideoCamera, Microphone, Phone, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:visible", "close", "video", "voice", "call", "stationNameClick"]);
// 表格列配置
const tableColumns = ref([
{ label: "序号", width: "60px" },
{ label: "区县/镇街", width: "140px" },
{ label: "姓名", width: "100px" },
{ label: "电话", width: "120px" },
{ label: "驻地名称", width: "180px" },
{ label: "类型", flex: "1" },
{ label: "调度", width: "140px" },
]);
// 表格数据
const tableData = ref([
{
id: 1,
region: "沙坪坝区",
name: "赵海浪",
phone: "1862352068",
stationName: "沙坪坝区S545茅山峡公路桥新建工程渝黔铁路扩能改造工程项目经理部",
type: "交通主管部门",
},
{
id: 2,
region: "沙坪坝区",
name: "府效能",
phone: "1862352068",
stationName: "沙坪坝区S545茅山峡公路桥新建工程渝黔铁路扩能改造工程项目经理部",
type: "公路机构",
},
{
id: 3,
region: "万州区柏梓镇",
name: "王鑫",
phone: "1862352068",
stationName: "万州区项目经理部",
type: "公路机构",
},
{
id: 4,
region: "万州区柏梓镇",
name: "王鑫",
phone: "1862352068",
stationName: "万州区项目经理部",
type: "公路机构",
},
]);
// 分页
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(36);
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
const visiblePages = computed(() => {
const pages = [];
const maxVisible = 4;
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
let end = Math.min(totalPages.value, start + maxVisible - 1);
if (end - start + 1 < maxVisible) {
start = Math.max(1, end - maxVisible + 1);
}
for (let i = start; i <= end; i++) {
pages.push(i);
}
return pages;
});
// 关闭对话框
const handleClose = () => {
emit("update:visible", false);
emit("close");
};
// 点击遮罩关闭
const handleOverlayClick = () => {
handleClose();
};
// 操作按钮
const handleVideo = (item) => {
emit("video", item);
};
const handleVoice = (item) => {
emit("voice", item);
};
const handleCall = (item) => {
emit("call", item);
};
// 点击驻地名称
const handleStationNameClick = (item) => {
emit("stationNameClick", item);
};
// 分页操作
const prevPage = () => {
if (currentPage.value > 1) {
currentPage.value--;
fetchData();
}
};
const nextPage = () => {
if (currentPage.value < totalPages.value) {
currentPage.value++;
fetchData();
}
};
const goToPage = (page) => {
currentPage.value = page;
fetchData();
};
// 获取数据
const fetchData = () => {
console.log("获取第", currentPage.value, "页数据");
// 实际项目中调用API获取数据
};
// 监听visible变化
watch(
() => props.visible,
(newVal) => {
if (newVal) {
currentPage.value = 1;
fetchData();
}
}
);
</script>
<style lang="scss" scoped>
.tongnan-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;
z-index: 2100;
}
.tongnan-dialog {
width: 80vw;
max-width: 1000px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px;
padding: 24px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
// 标题栏
.dialog-header {
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin-bottom: 20px;
.header-title {
font-size: 20px;
font-weight: 600;
color: #fff;
padding: 8px 40px;
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
border-bottom: 2px solid #40a9ff;
}
.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;
}
}
}
// 表格区域
.table-section {
background-color: rgba(30, 70, 120, 0.3);
border-radius: 8px;
overflow: hidden;
margin-bottom: 20px;
.table-header {
display: flex;
background-color: rgba(64, 169, 255, 0.2);
padding: 12px 16px;
.th {
font-size: 14px;
font-weight: 500;
color: #fff;
text-align: center;
}
}
.table-body {
max-height: 320px;
overflow-y: auto;
.table-row {
display: flex;
padding: 14px 16px;
align-items: center;
transition: background-color 0.3s;
&:hover {
background-color: rgba(64, 169, 255, 0.1);
}
&.row-even {
background-color: rgba(30, 70, 120, 0.2);
}
.td {
font-size: 13px;
color: rgba(255, 255, 255, 0.85);
text-align: center;
.station-name-text {
display: block;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 180px;
color: #40a9ff;
transition: all 0.3s;
&:hover {
color: #69c0ff;
text-shadow: 0 0 8px rgba(105, 192, 255, 0.6);
}
}
.action-btns {
display: flex;
justify-content: center;
gap: 16px;
.action-btn {
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
color: rgba(255, 255, 255, 0.7);
cursor: pointer;
font-size: 18px;
transition: all 0.3s;
&:hover {
color: #40a9ff;
transform: scale(1.1);
}
.el-icon {
font-size: 18px;
}
}
}
}
}
}
}
// 分页
.pagination {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 16px;
.total {
font-size: 13px;
color: rgba(255, 255, 255, 0.6);
}
.page-btns {
display: flex;
gap: 8px;
.page-btn {
min-width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(64, 169, 255, 0.1);
border: 1px solid rgba(64, 169, 255, 0.2);
border-radius: 4px;
font-size: 12px;
color: rgba(255, 255, 255, 0.8);
cursor: pointer;
transition: all 0.3s;
&:hover:not(.disabled):not(.active) {
background-color: rgba(64, 169, 255, 0.2);
border-color: rgba(64, 169, 255, 0.4);
}
&.active {
background-color: #40a9ff;
border-color: #40a9ff;
color: #fff;
}
&.disabled {
opacity: 0.4;
cursor: not-allowed;
}
}
}
}
// 滚动条样式
.table-body::-webkit-scrollbar {
width: 6px;
}
.table-body::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.2);
border-radius: 3px;
}
.table-body::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
border-radius: 3px;
}
.table-body::-webkit-scrollbar-thumb:hover {
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
}
</style>