bxztApp/packages/screen/src/views/RiskWarning/component/controlSituationDialog.vue

531 lines
12 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="control-dialog-overlay" @click="handleOverlayClick">
<div class="control-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="filter-section">
<div class="filter-row">
<div class="filter-item">
<span class="filter-label">行政区域</span>
<el-select v-model="filterForm.region" placeholder="请选择" class="filter-select" clearable>
<el-option
v-for="item in regionOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="filter-item">
<span class="filter-label">驻地风险等级</span>
<el-select v-model="filterForm.riskLevel" placeholder="请选择" class="filter-select" clearable>
<el-option
v-for="item in riskLevelOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</div>
</div>
<!-- 数据表格 -->
<div class="table-section">
<div class="table-header">
<div class="th" style="width: 60px">序号</div>
<div class="th" style="width: 100px">行政区域</div>
<div class="th" style="width: 200px">驻地名称</div>
<div class="th" style="width: 200px">所属项目</div>
<div class="th" style="width: 80px">驻地人数</div>
<div class="th" style="flex: 1">驻地风险等级</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: 100px">{{ item.region }}</div>
<div class="td" style="width: 200px">
<el-tooltip :content="item.stationName" placement="top" :show-after="500">
<span class="ellipsis-text">{{ item.stationName }}</span>
</el-tooltip>
</div>
<div class="td" style="width: 200px">
<el-tooltip :content="item.project" placement="top" :show-after="500">
<span class="ellipsis-text">{{ item.project }}</span>
</el-tooltip>
</div>
<div class="td" style="width: 80px">{{ item.peopleCount }}</div>
<div class="td" style="flex: 1">
<span :class="['risk-tag', getRiskClass(item.riskLevel)]">{{ item.riskLevel }}</span>
</div>
</div>
</div>
</div>
<!-- 分页 -->
<div class="pagination">
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
上一个
</div>
<div class="page-numbers">
<div
v-for="page in visiblePages"
:key="page"
class="page-num"
:class="{ active: currentPage === page }"
@click="goToPage(page)"
>
{{ page }}
</div>
</div>
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
下一个
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch } from "vue";
import { Close } from "@element-plus/icons-vue";
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:visible", "close"]);
// 筛选表单
const filterForm = ref({
region: "",
riskLevel: "",
});
// 行政区域选项
const regionOptions = ref([
{ label: "沙坪坝区", value: "沙坪坝区" },
{ label: "万州区", value: "万州区" },
{ label: "渝中区", value: "渝中区" },
{ label: "江北区", value: "江北区" },
]);
// 风险等级选项
const riskLevelOptions = ref([
{ label: "Ⅰ级", value: "Ⅰ级" },
{ label: "Ⅱ级", value: "Ⅱ级" },
{ label: "Ⅲ级", value: "Ⅲ级" },
{ label: "Ⅳ级", value: "Ⅳ级" },
]);
// 表格数据
const tableData = ref([
{
id: 1,
region: "沙坪坝区",
stationName: "沙坪坝区S545茅山峡公路桥新建工程渝黔铁路扩能改造工程项目经理部",
project: "沙坪坝区S545茅山峡公路桥新建工程渝黔铁路扩能改造工程",
peopleCount: 21,
riskLevel: "Ⅳ级",
},
{
id: 2,
region: "万州区",
stationName: "万州区项目经理部",
project: "万州区公路改造项目",
peopleCount: 15,
riskLevel: "Ⅲ级",
},
{
id: 3,
region: "渝中区",
stationName: "渝中区桥梁维护项目部",
project: "渝中区桥梁维护工程",
peopleCount: 8,
riskLevel: "Ⅱ级",
},
{
id: 4,
region: "江北区",
stationName: "江北区道路施工项目部",
project: "江北区道路施工项目",
peopleCount: 32,
riskLevel: "Ⅰ级",
},
]);
// 分页
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 = 5;
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 getRiskClass = (level) => {
const classMap = {
"Ⅰ级": "risk-level-1",
"Ⅱ级": "risk-level-2",
"Ⅲ级": "risk-level-3",
"Ⅳ级": "risk-level-4",
};
return classMap[level] || "";
};
// 关闭对话框
const handleClose = () => {
emit("update:visible", false);
emit("close");
};
// 点击遮罩关闭
const handleOverlayClick = () => {
handleClose();
};
// 分页操作
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>
.control-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: 2000;
}
.control-dialog {
width: 900px;
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;
}
}
}
// 筛选区域
.filter-section {
margin-bottom: 16px;
.filter-row {
display: flex;
gap: 24px;
}
.filter-item {
display: flex;
align-items: center;
gap: 8px;
.filter-label {
font-size: 13px;
color: rgba(255, 255, 255, 0.8);
white-space: nowrap;
}
.filter-select {
width: 140px;
:deep(.el-input__wrapper) {
background-color: rgba(30, 70, 120, 0.4);
border: 1px solid rgba(64, 169, 255, 0.3);
box-shadow: none;
border-radius: 4px;
.el-input__inner {
color: #fff;
font-size: 13px;
&::placeholder {
color: rgba(255, 255, 255, 0.4);
}
}
.el-input__suffix {
.el-icon {
color: rgba(255, 255, 255, 0.6);
}
}
}
}
}
}
// 表格区域
.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;
.ellipsis-text {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
cursor: pointer;
}
// 风险等级标签
.risk-tag {
display: inline-block;
padding: 2px 12px;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
&.risk-level-1 {
background-color: rgba(255, 77, 79, 0.2);
color: #ff4d4f;
border: 1px solid rgba(255, 77, 79, 0.4);
}
&.risk-level-2 {
background-color: rgba(255, 122, 0, 0.2);
color: #ff7a00;
border: 1px solid rgba(255, 122, 0, 0.4);
}
&.risk-level-3 {
background-color: rgba(250, 219, 20, 0.2);
color: #fadb14;
border: 1px solid rgba(250, 219, 20, 0.4);
}
&.risk-level-4 {
background-color: rgba(82, 196, 26, 0.2);
color: #52c41a;
border: 1px solid rgba(82, 196, 26, 0.4);
}
}
}
}
}
}
// 分页
.pagination {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
.page-btn {
padding: 6px 16px;
background-color: rgba(64, 169, 255, 0.1);
border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 4px;
font-size: 13px;
color: rgba(255, 255, 255, 0.8);
cursor: pointer;
transition: all 0.3s;
&:hover:not(.disabled) {
background-color: rgba(64, 169, 255, 0.2);
border-color: rgba(64, 169, 255, 0.5);
}
&.disabled {
opacity: 0.4;
cursor: not-allowed;
}
}
.page-numbers {
display: flex;
gap: 8px;
.page-num {
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.3);
border-radius: 4px;
font-size: 13px;
color: rgba(255, 255, 255, 0.8);
cursor: pointer;
transition: all 0.3s;
&:hover:not(.active) {
background-color: rgba(64, 169, 255, 0.2);
border-color: rgba(64, 169, 255, 0.5);
}
&.active {
background-color: #40a9ff;
border-color: #40a9ff;
color: #fff;
}
}
}
}
// 滚动条样式
.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>