227 lines
5.9 KiB
Vue
227 lines
5.9 KiB
Vue
<template>
|
|
|
|
<section class="traffic-7">
|
|
|
|
<StationTimeFilter
|
|
|
|
class="traffic-7__filter"
|
|
|
|
v-model:line="selectedLine"
|
|
|
|
v-model:station="selectedStation"
|
|
|
|
v-model:month="selectedMonth"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<div class="activity-list">
|
|
|
|
<article v-for="activity in activityList" :key="activity.id" class="activity-card">
|
|
|
|
<div class="activity-status" :class="`activity-status--${activity.statusType}`">
|
|
|
|
{{ activity.status }}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<h3 class="activity-name">{{ activity.name }}</h3>
|
|
|
|
|
|
|
|
<div class="activity-meta">
|
|
|
|
<span class="activity-label">时间:</span>
|
|
|
|
<span>{{ activity.time }}</span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="activity.venue" class="activity-meta activity-meta--venue">
|
|
|
|
<span class="activity-label">举办场馆:</span>
|
|
|
|
<span>{{ activity.venue }}</span>
|
|
|
|
</div>
|
|
|
|
</article>
|
|
|
|
</div>
|
|
|
|
</section>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
import { onMounted, ref, watch } from 'vue'
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
import StationTimeFilter from './StationTimeFilter.vue'
|
|
|
|
import server from '@/utils/service'
|
|
|
|
import { formatActivityMonth, processBigActivityList } from '@/utils/traffic'
|
|
|
|
|
|
|
|
const selectedLine = ref('7')
|
|
|
|
const selectedStation = ref('0753')
|
|
|
|
const selectedMonth = ref(dayjs().format('YYYY-M'))
|
|
|
|
const activityList = ref([])
|
|
|
|
const lineApiIdMap = ref({})
|
|
|
|
|
|
|
|
const loadLineApiIdMap = async () => {
|
|
|
|
try {
|
|
|
|
const response = await server.getLineList()
|
|
|
|
if (response.data.success && response.data.data?.length) {
|
|
|
|
lineApiIdMap.value = Object.fromEntries(
|
|
|
|
response.data.data.map(item => [String(item.lineId), String(item.id)])
|
|
|
|
)
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error('获取线路列表失败:', error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const fetchActivityList = async () => {
|
|
|
|
const metroLine = lineApiIdMap.value[selectedLine.value]
|
|
|
|
if (!metroLine || !selectedStation.value || !selectedMonth.value) {
|
|
|
|
activityList.value = []
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
const response = await server.getBigActivityList({
|
|
|
|
metroLine,
|
|
|
|
metroStation: selectedStation.value,
|
|
|
|
activityMonth: formatActivityMonth(selectedMonth.value)
|
|
|
|
})
|
|
|
|
|
|
|
|
if (response.data.success) {
|
|
|
|
activityList.value = processBigActivityList(response.data.data)
|
|
|
|
} else {
|
|
|
|
activityList.value = []
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error('获取重大活动清单失败:', error)
|
|
|
|
activityList.value = []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
watch([selectedLine, selectedStation, selectedMonth], fetchActivityList)
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
await loadLineApiIdMap()
|
|
|
|
await fetchActivityList()
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.traffic-7 {
|
|
|
|
position: absolute;
|
|
|
|
left: 2948px;
|
|
|
|
top: 707px;
|
|
|
|
width: 892px;
|
|
|
|
height: 880px;
|
|
|
|
background: url('/imgs/traffic/7-bg.png') no-repeat center center;
|
|
|
|
background-size: cover;
|
|
|
|
|
|
|
|
.traffic-7__filter {
|
|
|
|
position: absolute;
|
|
|
|
top: 12px;
|
|
|
|
right: 30px;
|
|
|
|
z-index: 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
.activity-list {
|
|
|
|
position: absolute;
|
|
|
|
top: 75px;
|
|
|
|
right: 12px;
|
|
|
|
bottom: 20px;
|
|
|
|
left: 20px;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
gap: 15px;
|
|
|
|
overflow-x: hidden;
|
|
|
|
overflow-y: scroll;
|
|
|
|
padding-right: 6px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.activity-card {
|
|
|
|
position: relative;
|
|
|
|
min-height: 89px;
|
|
|
|
box-sizing: border-box;
|
|
|
|
padding: 12px 104px 10px 31px;
|
|
|
|
overflow: hidden;
|
|
|
|
border-radius: 5px;
|
|
|
|
letter-spacing: 0.03em;
|
|
|
|
flex-shrink: 0;
|
|
|
|
background: rgba(44, 121, 236, 0.35);
|
|
|
|
}
|
|
|
|
|
|
|
|
.activity-empty {
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
:deep(.el-empty__description p) {
|
|
|
|
color: rgba(220, 236, 255, 0.78);
|
|
|
|
font-size: 18px;
|
|
|
|
font-weight: 700;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.activity-name {
|
|
|
|
margin: 0;
|
|
|
|
color: #FFFFFF;
|
|
|
|
font-size: 22px;
|
|
|
|
font-weight: 500;
|
|
|
|
line-height: 32px;
|
|
|
|
letter-spacing: 0.03em;
|
|
|
|
}
|
|
|
|
|
|
|
|
.activity-meta {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
// gap: 37px;
|
|
|
|
margin-top: 7px;
|
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
font-weight: 400;
|
|
|
|
line-height: 28px;
|
|
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
&--venue {
|
|
|
|
margin-top: 7px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.activity-label {
|
|
|
|
color: rgba(228, 243, 255, 0.74);
|
|
|
|
flex-shrink: 0;
|
|
|
|
width: 94px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.activity-status {
|
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
right: 0;
|
|
|
|
z-index: 1;
|
|
|
|
width: 91px;
|
|
|
|
height: 35px;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
font-size: 20px;
|
|
|
|
font-weight: 500;
|
|
|
|
line-height: 1;
|
|
|
|
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5);
|
|
|
|
|
|
|
|
&::before {
|
|
|
|
content: '';
|
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
left: -20px;
|
|
|
|
width: 0;
|
|
|
|
height: 0;
|
|
|
|
border-top: 35px solid var(--status-bg-start);
|
|
|
|
border-left: 20px solid transparent;
|
|
|
|
}
|
|
|
|
|
|
|
|
&--active {
|
|
|
|
--status-bg-start: #078b66;
|
|
|
|
--status-bg-end: #08b279;
|
|
|
|
color: #02FF5F;
|
|
|
|
background: linear-gradient(90deg, var(--status-bg-start) 0%, var(--status-bg-end) 100%);
|
|
|
|
}
|
|
|
|
|
|
|
|
&--ended {
|
|
|
|
--status-bg-start: #9b7f7f;
|
|
|
|
--status-bg-end: #bba1a1;
|
|
|
|
color: #cfcfcf;
|
|
|
|
background: linear-gradient(90deg, var(--status-bg-start) 0%, var(--status-bg-end) 100%);
|
|
|
|
}
|
|
|
|
|
|
|
|
&--pending {
|
|
|
|
--status-bg-start: #546174;
|
|
|
|
--status-bg-end: #6f7c91;
|
|
|
|
color: #f0f0f0;
|
|
|
|
background: linear-gradient(90deg, var(--status-bg-start) 0%, var(--status-bg-end) 100%);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
</style>
|
|
|