<template>
|
<div class="right">
|
<div class="right-top">
|
<span>模拟结果</span>
|
</div>
|
<div class="echartsBox" id="layerBox">
|
<div class="echartCont">
|
<p style="cursor: pointer" @click="rainClick">降雨数据</p>
|
<div class="echartBox">
|
<div id="echarts1" style="width: 100%; height: 100%"></div>
|
</div>
|
</div>
|
<div class="echartCont">
|
<p>断面模拟</p>
|
<div class="echartBox">
|
<div id="echarts2" style="width: 100%; height: 100%"></div>
|
</div>
|
</div>
|
<div class="echartCont">
|
<p style="cursor: pointer" @click="debuffClick">威胁对象</p>
|
<div class="echartBox">
|
<div class="table-container" ref="tableContainer">
|
<el-table
|
:data="tableData"
|
style="width: 100%; font-size: 10px"
|
height="100%"
|
@row-click="handleRowClick"
|
>
|
<el-table-column label="影响区名称" width="30" align="center">
|
<template #default="scope">
|
影响区{{ scope.row.zoneId }}
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="time"
|
label="影响时间"
|
width="50"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="population"
|
label="人员(人)"
|
width="23"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="room"
|
label="房屋(间)"
|
width="23"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="households"
|
label="户数(户)"
|
width="23"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="property"
|
label="财产(万元)"
|
width="23"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="maxDepth"
|
label="最大水深(米)"
|
width="28"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="maxVelocity"
|
label="最大流速(m/s)"
|
width="35"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="raininess"
|
label="雨强(mm/h)"
|
width="28"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="warningLevel"
|
label="预警等级"
|
width="28"
|
align="center"
|
></el-table-column>
|
</el-table>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import * as echarts from "echarts";
|
import { EventBus } from "@/eventBus"; // 引入事件总线
|
import {
|
ref,
|
onMounted,
|
onBeforeUnmount,
|
nextTick,
|
watch,
|
onUnmounted,
|
} from "vue";
|
import dayjs from "dayjs";
|
import { useSimStore } from "@/store/simulation";
|
const simStore = useSimStore();
|
const { rainFalls, intensityUnit } = simStore;
|
|
let dataIntervalId = null; // 表格定时器 ID
|
const jsonData = ref([]); // JSON 数据
|
const tableData = ref([]); // 表格数据
|
const currentIndex = ref(0); // 当前加载索引
|
const isPaused = ref(false); // 是否暂停标志
|
const chart1Data = ref(null); //降雨数据
|
const chart2Data = ref(null); //断面数据
|
let intervalId1 = null; //降雨数据定时器
|
let intervalId2 = null; //断面数据定时器
|
|
// 根据时间轴匹配的x轴的时间显示
|
const nowTime = ref(null);
|
|
const props = defineProps({
|
isDynamicMode: {
|
type: Boolean,
|
},
|
isFinish: {
|
type: Boolean,
|
},
|
});
|
|
watch(
|
() => props.isFinish,
|
(newVal) => {
|
if (!newVal) {
|
resetTable();
|
chart1Data.value.resetLoading();
|
chart1Data.value.startUpdating(1000); // 每隔 1 秒更新一次
|
chart2Data.value.resetLoading();
|
chart2Data.value.startUpdating(1000); // 每隔 1 秒更新一次
|
}
|
}
|
);
|
// 清除函数=====================================================================
|
// 监听事件总线的自定义事件
|
EventBus.on("reset-table", () => {
|
resetTable(); // 调用重置表格的函数
|
});
|
|
// 清除echarts图表
|
EventBus.on("clear-echart", () => {
|
chart1Data.value.resetLoading();
|
chart2Data.value.resetLoading();
|
});
|
|
// 清除断面
|
EventBus.on("clear-dM", () => {
|
chart2Data.value.stopUpdating();
|
chart2Data.value.resetLoading();
|
clearInterval(intervalId2);
|
intervalId2 = null;
|
});
|
|
// 清除威胁对象中的数据
|
const resetTable = () => {
|
currentIndex.value = 0;
|
tableData.value = [];
|
if (dataIntervalId) {
|
clearInterval(dataIntervalId);
|
}
|
startAddingData();
|
};
|
|
// 暂停时停止所有的更新
|
const handleHideSchemeInfo = () => {
|
// 停止所有动态更新
|
if (intervalId1) {
|
clearInterval(intervalId1);
|
chart1Data.value.stopUpdating(); // 每隔 1 秒更新一次
|
intervalId1 = null;
|
}
|
if (intervalId2) {
|
clearInterval(intervalId2);
|
chart2Data.value.stopUpdating(); // 每隔 1 秒更新一次
|
intervalId2 = null;
|
}
|
if (dataIntervalId) {
|
clearInterval(dataIntervalId);
|
dataIntervalId = null;
|
}
|
};
|
|
// 监听时间轴结束模拟
|
EventBus.on("hide-schemeInfo", handleHideSchemeInfo);
|
|
// 监听父组件传递的数据变化
|
watch(
|
() => props.isDynamicMode,
|
(isEnabled) => {
|
isPaused.value = !isEnabled;
|
|
if (isEnabled) {
|
// 如果启用了动态模式
|
if (jsonData.value.length === 0) {
|
getDangerInfo(); // 加载初始数据
|
} else {
|
startAddingData(); // 开始添加数据
|
}
|
|
// 启动第一个图表的定时更新
|
if (!intervalId1 && chart1Data.value) {
|
intervalId1 = setInterval(() => {
|
chart1Data.value.startUpdating(1000);
|
}, 10);
|
}
|
|
// 启动第二个图表的定时更新
|
if (!intervalId2 && chart2Data.value) {
|
intervalId2 = setInterval(() => {
|
chart2Data.value.startUpdating(1000); // 每隔 1 秒更新一次
|
}, 10);
|
}
|
} else {
|
handleHideSchemeInfo();
|
}
|
},
|
{ immediate: true } // 立即执行监听器
|
);
|
|
// 点击数据实现面片闪动的触发函数
|
function handleRowClick(row) {
|
console.log("Row clicked:", row);
|
// 触发事件,将当前行的 ID 发送到地图组件
|
EventBus.emit("row-clicked", row.id);
|
}
|
|
const rainChangeShow = ref(false);
|
const tableContainer = ref(null);
|
|
let myChart1 = null;
|
let myChart2 = null;
|
|
// 威胁对象数据
|
const getDangerInfo = async () => {
|
try {
|
const response = await fetch(
|
"/json/listMaxInfluenceArea_wgs84_output.json"
|
);
|
const result = await response.json();
|
console.log("Loaded JSON data:", result);
|
if (result && result.data && Array.isArray(result.data.items)) {
|
jsonData.value = result.data.items;
|
console.log("jsonData is an array with length:", jsonData.value.length);
|
startAddingData();
|
} else {
|
console.error(
|
"Invalid JSON format: 'data.items' is missing or not an array!"
|
);
|
}
|
} catch (error) {
|
console.error("Error fetching data:", error);
|
}
|
};
|
|
const startAddingData = () => {
|
// 如果定时器已存在,先清除
|
if (dataIntervalId) {
|
clearInterval(dataIntervalId);
|
}
|
|
dataIntervalId = setInterval(() => {
|
if (isPaused.value) {
|
console.log("Loading is paused. Waiting for resume...");
|
return; // 如果暂停,则不执行后续逻辑
|
}
|
|
if (currentIndex.value < jsonData.value.length) {
|
const newItem = jsonData.value[currentIndex.value];
|
tableData.value.unshift(newItem);
|
scrollToTop();
|
currentIndex.value++;
|
} else {
|
console.log("All items added.");
|
clearInterval(dataIntervalId);
|
}
|
}, 2000);
|
};
|
|
const scrollToTop = () => {
|
nextTick(() => {
|
if (tableContainer.value) {
|
tableContainer.value.scrollTop = 0;
|
}
|
});
|
};
|
|
const rainClick = () => {
|
rainChangeShow.value = !rainChangeShow.value;
|
let desc = { func_name: "RainChange", visibility: rainChangeShow.value };
|
ps.emitMessage(desc);
|
};
|
|
const debuffClick = () => {
|
console.log("Debuff click");
|
};
|
|
const chartssize = (container, charts) => {
|
if (!charts || !charts.style) return;
|
const style = window.getComputedStyle(container);
|
charts.style.width = style.width;
|
charts.style.height = style.height;
|
};
|
|
// 时间轴时间截取处理
|
const syncTimeWithTimeline = () => {
|
if (nowTime.value) {
|
const timeParts = nowTime.value.split(" ");
|
const timeOnly = timeParts[1]; // 获取 "mm:ss" 部分
|
return timeOnly;
|
}
|
};
|
|
const setEcharts1 = () => {
|
const chartDom = document.getElementById("echarts1");
|
const myChart1 = echarts.init(chartDom);
|
|
// 图表数据
|
let rainfallData = ref([]);
|
let data1 = ref([]);
|
let data2 = ref([]);
|
let xAxisData = ref(["00:00"]);
|
let updateInterval = null;
|
let dataIndex = ref(0);
|
|
// 动态计算Y轴范围
|
const getDynamicYAxis = (dataArray) => {
|
const currentMax = Math.max(...dataArray, 1);
|
const step = Math.ceil(currentMax / 3);
|
return {
|
max: step * 3,
|
interval: step,
|
};
|
};
|
|
// 加载JSON数据
|
const loadJsonData = async () => {
|
try {
|
const result = simStore.rainFalls;
|
if (result?.length) {
|
rainfallData.value = result;
|
|
// 判断 intensityUnit 是否为 mm/15min
|
if (rainfallData.value.length > 0) {
|
// 如果是 mm/15min,则将所有 intensity * 60
|
if (intensityUnit === "mm/15min") {
|
rainfallData.value = rainfallData.value.map((item) => ({
|
...item,
|
intensity: item.intensity * 60,
|
total: item.total * 60,
|
}));
|
}
|
|
// 初始化 data1 和 data2(从 0 开始)
|
data1.value = [0];
|
data2.value = [0];
|
|
// 使用第一个数据项的 time 作为初始值
|
xAxisData.value = [rainfallData.value[0]?.time || "00:00"];
|
|
updateChart();
|
}
|
}
|
} catch (error) {
|
console.error("数据加载失败:", error);
|
}
|
};
|
|
// 更新图表配置
|
const updateChart = () => {
|
const option = {
|
animation: false,
|
tooltip: { trigger: "axis" },
|
grid: {
|
bottom: "1%",
|
containLabel: false,
|
},
|
legend: {
|
data: ["降雨数据", "累计雨量"],
|
textStyle: { color: "#fff" },
|
right: "10px",
|
selected: {
|
降雨数据: true,
|
累计雨量: true,
|
},
|
},
|
xAxis: [
|
{
|
type: "category",
|
data: xAxisData.value,
|
axisLabel: { color: "#fff", rotate: 0 },
|
},
|
],
|
yAxis: [
|
{
|
type: "value",
|
name: "单位:mm",
|
min: 0,
|
...getDynamicYAxis(data1.value),
|
axisLabel: { color: "#fff" },
|
splitLine: { show: false },
|
nameTextStyle: {
|
color: "#fff",
|
},
|
},
|
{
|
type: "value",
|
name: "单位:mm",
|
min: 0,
|
...getDynamicYAxis(data2.value),
|
axisLabel: { color: "#fff" },
|
splitLine: { show: true },
|
nameTextStyle: {
|
color: "#fff",
|
},
|
},
|
],
|
series: [
|
{
|
name: "降雨数据",
|
type: "bar",
|
data: data1.value,
|
itemStyle: { color: "#3268fe" },
|
},
|
{
|
name: "累计雨量",
|
type: "line",
|
yAxisIndex: 1,
|
data: data2.value,
|
lineStyle: { color: "#ffb637" },
|
},
|
],
|
};
|
myChart1.setOption(option, true);
|
};
|
|
// 数据更新 - 每次添加一条数据
|
const updateData = () => {
|
if (dataIndex.value < rainfallData.value.length) {
|
const item = rainfallData.value[dataIndex.value];
|
data1.value.push(item.intensity);
|
data2.value.push(item.total);
|
xAxisData.value.push(item.time); // ✅ 改用 item.time
|
dataIndex.value++;
|
updateChart();
|
} else {
|
stopUpdating();
|
}
|
};
|
|
let fixedFrameNum = null;
|
let startTime = null; // 将startTime移到外层
|
let elapsedBeforePause = 0; // 记录暂停前已经过去的时间
|
|
const startUpdating = () => {
|
if (updateInterval || dataIndex.value >= rainfallData.value.length) {
|
// console.log("Animation already running or completed");
|
return;
|
}
|
|
// 如果是首次启动或重新开始
|
if (fixedFrameNum === null) {
|
fixedFrameNum = simStore.frameNum;
|
elapsedBeforePause = 0;
|
startTime = Date.now();
|
} else {
|
// 如果是暂停后继续,调整startTime以反映已经过去的时间
|
startTime = Date.now() - elapsedBeforePause;
|
}
|
|
const totalDuration = fixedFrameNum * 1000;
|
const totalPoints = rainfallData.value.length;
|
|
const animate = (index) => {
|
if (index >= totalPoints) {
|
console.log("Animation completed");
|
stopUpdating();
|
return;
|
}
|
|
const now = Date.now();
|
const expectedTime = (index / (totalPoints - 1)) * totalDuration;
|
const delay = Math.max(0, startTime + expectedTime - now);
|
|
updateInterval = setTimeout(() => {
|
dataIndex.value = index;
|
updateData();
|
animate(index + 1);
|
}, delay);
|
};
|
|
animate(dataIndex.value);
|
};
|
|
// 暂停函数需要记录已经过去的时间
|
const stopUpdating = () => {
|
if (updateInterval) {
|
clearTimeout(updateInterval);
|
updateInterval = null;
|
// 记录暂停时已经过去的时间
|
elapsedBeforePause = Date.now() - startTime;
|
}
|
};
|
|
const resetLoading = () => {
|
stopUpdating();
|
fixedFrameNum = null;
|
startTime = null;
|
elapsedBeforePause = 0;
|
dataIndex.value = 0;
|
data1.value = [0];
|
data2.value = [0];
|
xAxisData.value = [rainfallData.value[0]?.time || "00:00"];
|
updateChart();
|
};
|
|
// 初始化
|
loadJsonData();
|
|
return {
|
myChart1,
|
startUpdating,
|
stopUpdating,
|
resetLoading,
|
};
|
};
|
|
const setEcharts2 = () => {
|
const chartDom = document.getElementById("echarts2");
|
const myChart2 = echarts.init(chartDom);
|
|
// 图表数据
|
let flowData = ref([]); // 原始数据
|
let data1 = ref([]); // 实时流量
|
let data2 = ref([]); // 流速
|
let data3 = ref([]); // 深度(新增)
|
let xAxisData = ref(["00:00"]);
|
let updateInterval = ref(null);
|
let dataIndex = ref(0);
|
|
// 将各种时间格式转换为时间戳
|
const parseTimeToTimestamp = (time) => {
|
if (!time) return 0;
|
|
// 如果是时间戳(毫秒)
|
if (typeof time === "number" && time > 1000000000000) {
|
return time;
|
}
|
|
// 如果是Date对象
|
if (time instanceof Date) {
|
return time.getTime();
|
}
|
|
// 如果是时间字符串(如"2023-01-01 12:00:00")
|
if (typeof time === "string") {
|
return new Date(time).getTime() || 0;
|
}
|
|
return 0;
|
};
|
|
// 动态计算Y轴范围(支持深度数据特殊处理)
|
const calculateDynamicYAxis = (dataArray, isDepth = false) => {
|
const filteredData = dataArray.filter((val) => val != null && val > 0);
|
|
if (filteredData.length === 0) {
|
return {
|
min: 0,
|
max: isDepth ? 10 : 0.001, // 深度默认范围更大
|
interval: isDepth ? 2 : 0.0002,
|
};
|
}
|
|
const maxValue = Math.max(...filteredData);
|
const exponent = Math.floor(Math.log10(maxValue));
|
const base = Math.pow(10, exponent);
|
let step, max;
|
|
if (isDepth) {
|
// 深度数据的特殊处理
|
step = Math.ceil(maxValue / 5); // 固定分为5段
|
max = step * 5;
|
} else if (maxValue < 0.01) {
|
// 对于小数值,使用更精细的步长
|
step = base / 5;
|
max = step * 5;
|
} else {
|
// 常规处理
|
step = base / 2;
|
max = step * Math.ceil(maxValue / step) + step;
|
}
|
|
const decimalPlaces = Math.max(0, -exponent + 1);
|
|
return {
|
min: 0,
|
max: parseFloat(max.toFixed(decimalPlaces)),
|
interval: parseFloat(step.toFixed(decimalPlaces)),
|
};
|
};
|
|
// 根据当前时间加载数据
|
const loadDataByCurrentTime = () => {
|
if (!flowData.value.length) return;
|
|
// 将nowTime.value转换为时间戳
|
const currentTimestamp = parseTimeToTimestamp(nowTime.value);
|
|
// 找到当前时间及之前的所有数据
|
const pastData = flowData.value.filter(
|
(item) => item.time <= currentTimestamp
|
);
|
|
if (pastData.length) {
|
// 一次性加载历史数据
|
data1.value = pastData.map((item) => item.flowRate);
|
data2.value = pastData.map((item) => item.velocity);
|
data3.value = pastData.map((item) => item.depth); // 加载深度数据
|
xAxisData.value = pastData.map((item) => formatTime(item.time));
|
|
// 设置从下一个数据点开始继续更新
|
dataIndex.value = pastData.length;
|
} else {
|
// 没有历史数据,初始化空数据
|
resetLoading();
|
}
|
|
updateChart();
|
};
|
|
// 时间格式化函数(时间戳转"HH:mm:ss")
|
const formatTime = (timestamp) => {
|
const date = new Date(timestamp);
|
const hours = date.getHours().toString().padStart(2, "0");
|
const minutes = date.getMinutes().toString().padStart(2, "0");
|
const seconds = date.getSeconds().toString().padStart(2, "0");
|
return `${hours}:${minutes}:${seconds}`;
|
};
|
|
const loadJsonData = () => {
|
const crossSectionData = simStore.crossSection;
|
if (crossSectionData?.length) {
|
flowData.value = crossSectionData;
|
loadDataByCurrentTime(); // 加载当前时间之前的数据
|
} else {
|
resetLoading();
|
}
|
};
|
|
// 图表配置
|
const updateChart = () => {
|
const option = {
|
animation: false,
|
tooltip: {
|
trigger: "axis",
|
axisPointer: { type: "cross" },
|
},
|
grid: {
|
bottom: "1%",
|
containLabel: false,
|
},
|
legend: {
|
data: ["实时流量", "流速", "深度"],
|
textStyle: { color: "#fff" },
|
right: "10px",
|
selected: {
|
实时流量: true,
|
流速: true,
|
深度: true,
|
},
|
},
|
xAxis: [
|
{
|
type: "category",
|
data: xAxisData.value,
|
axisLabel: {
|
color: "#fff",
|
rotate: 0,
|
},
|
},
|
],
|
yAxis: [
|
{
|
type: "value",
|
name: "流量(m³/min)",
|
min: 0,
|
...calculateDynamicYAxis(data1.value),
|
axisLabel: { color: "#fff" },
|
splitLine: { show: false },
|
nameTextStyle: { color: "#fff" },
|
},
|
{
|
type: "value",
|
name: "流速(m/s)",
|
min: 0,
|
...calculateDynamicYAxis(data2.value),
|
axisLabel: { color: "#fff" },
|
splitLine: { show: true },
|
nameTextStyle: { color: "#fff" },
|
},
|
{
|
type: "value",
|
name: "深度(m)",
|
min: 0,
|
...calculateDynamicYAxis(data3.value, true),
|
axisLabel: { color: "#fff" },
|
splitLine: { show: false },
|
nameTextStyle: { color: "#fff" },
|
position: "right",
|
offset: 80,
|
},
|
],
|
series: [
|
{
|
name: "实时流量",
|
type: "bar",
|
data: data1.value,
|
itemStyle: { color: "#3268fe" },
|
},
|
{
|
name: "流速",
|
type: "line",
|
yAxisIndex: 1,
|
data: data2.value,
|
lineStyle: { color: "#ffb637" },
|
},
|
{
|
name: "深度",
|
type: "line",
|
yAxisIndex: 2,
|
data: data3.value,
|
lineStyle: { color: "#00ff99" },
|
symbol: "none",
|
smooth: true,
|
},
|
],
|
};
|
myChart2.setOption(option, true);
|
};
|
|
// 数据更新
|
const updateData = () => {
|
if (dataIndex.value < flowData.value.length) {
|
const item = flowData.value[dataIndex.value];
|
data1.value.push(item.flowRate);
|
data2.value.push(item.velocity);
|
data3.value.push(item.depth); // 更新深度数据
|
xAxisData.value.push(formatTime(item.time));
|
dataIndex.value++;
|
updateChart();
|
} else {
|
stopUpdating();
|
}
|
};
|
|
// 控制方法
|
const startUpdating = (interval = 1000) => {
|
if (!updateInterval.value) {
|
updateInterval.value = setInterval(updateData, interval);
|
}
|
};
|
|
const stopUpdating = () => {
|
if (updateInterval.value) {
|
clearInterval(updateInterval.value);
|
updateInterval.value = null;
|
}
|
};
|
|
const resetLoading = () => {
|
stopUpdating();
|
dataIndex.value = 0;
|
data1.value = [0];
|
data2.value = [0];
|
data3.value = [0]; // 重置深度数据
|
xAxisData.value = ["00:00"];
|
updateChart();
|
};
|
|
// 初始化
|
loadJsonData();
|
|
return {
|
myChart2,
|
startUpdating,
|
stopUpdating,
|
loadJsonData,
|
resetLoading,
|
};
|
};
|
|
// 监听 simStore.crossSection 的变化
|
watch(
|
() => simStore.crossSection,
|
(newVal) => {
|
// 确定时间轴是播放的状态
|
if (newVal && !isPaused.value) {
|
chart2Data.value.stopUpdating();
|
chart2Data.value.startUpdating();
|
}
|
chart2Data.value.loadJsonData();
|
},
|
{ deep: true }
|
);
|
|
const handleResize = () => {
|
const chartBox1 = document.getElementById("echarts1");
|
const chartBox2 = document.getElementById("echarts2");
|
if (chartBox1 && myChart1) chartssize(chartBox1, myChart1);
|
if (chartBox2 && myChart2) chartssize(chartBox2, myChart2);
|
};
|
|
onMounted(() => {
|
// 时间轴时间的变化
|
EventBus.on("time-update", (time) => {
|
nowTime.value = time;
|
});
|
chart1Data.value = setEcharts1();
|
chart2Data.value = setEcharts2();
|
myChart1 = chart1Data.value.myChart1;
|
myChart2 = chart2Data.value.myChart2;
|
window.addEventListener("resize", handleResize);
|
});
|
|
onBeforeUnmount(() => {
|
nowTime.value = null;
|
if (intervalId1) clearInterval(intervalId1);
|
if (intervalId2) clearInterval(intervalId2);
|
if (dataIntervalId) clearInterval(dataIntervalId);
|
if (myChart1) myChart1.dispose();
|
if (myChart2) myChart2.dispose();
|
window.removeEventListener("resize", handleResize);
|
});
|
onUnmounted(() => {
|
EventBus.off("reset-table"); // 移除事件监听
|
EventBus.off("clear-echart");
|
EventBus.off("clear-dM");
|
EventBus.off("time-update"); // 清理事件监听
|
});
|
</script>
|
|
<style lang="less" scoped>
|
@import url("../../assets/css/right.css");
|
@import url("../../assets/css/infobox.css");
|
|
:deep(.el-table td),
|
:deep(.el-table th) {
|
padding: 0 !important;
|
}
|
|
:deep(.el-table .cell) {
|
line-height: normal !important;
|
padding: 0 1px !important;
|
}
|
|
.table-container {
|
margin-left: 20px;
|
max-height: 100%;
|
overflow-y: auto;
|
}
|
|
.warp {
|
height: calc(27% - 1px);
|
width: 95%;
|
position: absolute;
|
margin: 0 auto;
|
overflow: hidden;
|
color: white;
|
|
ul {
|
list-style: none;
|
padding: 0;
|
margin: 0 auto;
|
|
li,
|
a {
|
display: block;
|
height: 30px;
|
line-height: 30px;
|
display: flex;
|
justify-content: space-between;
|
font-size: 15px;
|
}
|
|
.date {
|
width: 85px;
|
}
|
}
|
}
|
</style>
|