<template>
|
<view class="min-h-screen bg-gray-100">
|
<!-- Tab 切换 -->
|
<view class="p-2 w-95-percent">
|
<uni-segmented-control :current="currentTab" :values="tabs" @clickItem="onTabChange" style-type="button"
|
active-color="#3b82f6" class="mb-4" />
|
</view>
|
<!-- 加载提示 -->
|
<view v-if="loading" class="text-center text-gray-500 py-8">
|
加载中...
|
</view>
|
<!-- 预约信息卡片列表 -->
|
<scroll-view scroll-y class="p-2 h-calc-100vh-120px w-95-percent">
|
<view v-for="(item, index) in filterednotices" :key="index"
|
class="bg-white rounded-lg shadow p-4 mb-4 flex flex-row" @click="gotoDetail(item)">
|
|
<div class="w-24 h-16 mt-4 flex-shrink-0 mr-2 rounded-5">
|
<img :src="parseContentImg(item.content) || `https://farm.evcc.top/Uploads/yuanboyuan/news/${encodeURIComponent(item.category)}.jpg`"
|
mode="aspectFill" alt="icon" class="w-24 h-16 rounded-5" />
|
</div>
|
<!-- 右侧内容 -->
|
<div class="flex-1 space-y-2">
|
<view class="text-sm space-y-2">
|
<!--<text class="text-gray-600 font-bold">消息标题:</text> -->
|
<text>{{ item.title.length > 36 ? item.title.slice(0, 36) + '……' : item.title }}</text>
|
</view>
|
<view class="text-sm space-y-2">
|
<text class="text-gray-600">发布时间:</text>
|
<text>{{ item.createTime }}</text>
|
</view>
|
<!--
|
<view class="text-sm space-y-2">
|
<text class="text-gray-600">消息正文:</text>
|
<text>{{ parseContentText(item.content) }}</text>
|
</view>
|
-->
|
</div>
|
|
<!-- 卡片内容 -->
|
|
</view>
|
<!-- 无数据提示 -->
|
<view v-if="!filterednotices.length" class="text-center text-gray-500 py-8">
|
暂无{{ tabs[currentTab] }}的信息
|
</view>
|
</scroll-view>
|
</view>
|
</template>
|
|
<script>
|
import {
|
ref,
|
computed,
|
onMounted
|
} from 'vue'
|
import {
|
apiService
|
} from '@/apiservice/apiService'
|
|
export default {
|
setup() {
|
// Tab 数据
|
const tabs = ['景区动态', '新闻报道', '活动演出', '景区通知'];
|
const currentTab = ref(0);
|
let notices = ref([]);
|
const loading = ref(false);
|
|
// 获取预约列表
|
const fetchnotices = async () => {
|
loading.value = true;
|
try {
|
const res = await apiService.noticeList()
|
if (res.code === 1000) {
|
notices.value = res.data
|
|
} else {
|
console.warn('查询失败:', res.message)
|
}
|
|
} catch (error) {
|
console.error('获取预约信息错误:', error);
|
uni.showToast({
|
title: '网络错误',
|
icon: 'none'
|
});
|
} finally {
|
loading.value = false;
|
}
|
};
|
|
const parseContentImg = (content = '') => {
|
if (!content || typeof content !== 'string') {
|
return null;
|
}
|
const imgMatch = content.match(/<img[^>]+src=["']?([^"'>]+)["']?/i);
|
const imgSrc = imgMatch ? imgMatch[1] : null;
|
|
return imgSrc;
|
|
};
|
const parseContentText = (content = '') => {
|
if (!content || typeof content !== 'string') {
|
return '';
|
}
|
let text = content
|
.replace(/<[^>]+>/g, '') // 去掉HTML标签
|
.replace(/\s+/g, ' ') // 合并多余空格
|
.trim();
|
if (text.length > 50) {
|
text = text.slice(0, 50) + '......'; // 截取前50字符
|
}
|
|
return text;
|
};
|
const gotoDetail = (item) => {
|
const data = encodeURIComponent(JSON.stringify(item));
|
uni.navigateTo({
|
url: `/pages/index/notices-detail?data=${data}`
|
});
|
};
|
|
// 根据当前 Tab 过滤数据
|
const filterednotices = computed(() => {
|
return notices.value.filter(item => item.category === tabs[currentTab.value]);
|
});
|
|
|
// Tab 切换
|
const onTabChange = (e) => {
|
currentTab.value = e.currentIndex;
|
};
|
|
// 页面加载时获取数据
|
onMounted(() => {
|
fetchnotices();
|
});
|
|
return {
|
tabs,
|
currentTab,
|
notices,
|
filterednotices,
|
loading,
|
onTabChange,
|
parseContentImg,
|
parseContentText,
|
gotoDetail
|
};
|
}
|
};
|
</script>
|
|
<style>
|
.min-h-screen {
|
min-height: 100vh;
|
}
|
|
.bg-gray-100 {
|
background-color: #f3f4f6;
|
}
|
|
.ml-5 {
|
left: 10rpx;
|
}
|
|
.w-95-percent {
|
width: 95%;
|
}
|
|
.mr-5 {
|
right: 10rpx;
|
}
|
|
.mb-4 {
|
margin-bottom: 1rem;
|
}
|
|
.mt-4 {
|
margin-top: 1rem;
|
}
|
|
.text-center {
|
text-align: center;
|
}
|
|
.text-gray-500 {
|
color: #6b7280;
|
}
|
|
.text-gray-600 {
|
color: #4b5563;
|
}
|
|
.py-8 {
|
padding-top: 2rem;
|
/* 32px */
|
padding-bottom: 2rem;
|
}
|
|
.h-calc-100vh-120px {
|
height: calc(100vh - 120px);
|
}
|
|
.px-4 {
|
padding-left: 1rem;
|
padding-right: 1rem;
|
}
|
|
.bg-white {
|
background-color: #ffffff;
|
}
|
|
.rounded-lg {
|
border-radius: 0.5rem;
|
/* 8px */
|
}
|
|
.shadow {
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
|
}
|
|
.p-4 {
|
padding: 1rem;
|
}
|
|
.p-2 {
|
padding: 0.5rem;
|
}
|
|
.mb-4 {
|
margin-bottom: 1rem;
|
}
|
|
.mt-1 {
|
margin-top: 0.2rem;
|
}
|
|
.relative {
|
position: relative;
|
}
|
|
.absolute {
|
position: absolute;
|
}
|
|
.top-2 {
|
top: 0.5rem;
|
/* 8px */
|
}
|
|
.right-2 {
|
right: 0.5rem;
|
/* 8px */
|
}
|
|
.bg-red-500 {
|
background-color: #ef4444;
|
}
|
|
.bg-blue-500 {
|
background-color: #3b82f6;
|
}
|
|
.text-white {
|
color: #ffffff;
|
}
|
|
.text-sm {
|
font-size: 0.875rem;
|
/* 14px */
|
line-height: 1.25rem;
|
/* 20px */
|
}
|
|
.text-base {
|
font-size: 1rem;
|
/* 14px */
|
line-height: 1.5rem;
|
/* 20px */
|
}
|
|
.px-2 {
|
padding-left: 0.5rem;
|
padding-right: 0.5rem;
|
}
|
|
.py-1 {
|
padding-top: 0.25rem;
|
padding-bottom: 0.25rem;
|
}
|
|
.rounded {
|
border-radius: 0.25rem;
|
/* 4px */
|
}
|
|
.space-y-2 {
|
margin-top: 0.5rem;
|
/* 8px */
|
}
|
|
.flex {
|
display: flex;
|
}
|
|
.justify-between {
|
justify-content: space-between;
|
}
|
|
.font-bold {
|
font-weight: 700;
|
}
|
|
.text-lg {
|
font-size: 1.125rem;
|
/* 18px */
|
line-height: 1.75rem;
|
/* 28px */
|
}
|
|
.w-24 {
|
width: 6rem;
|
/* 32px */
|
|
}
|
|
.h-16 {
|
height: 5rem;
|
/* 32px */
|
}
|
|
.flex-shrink-0 {
|
flex-shrink: 0;
|
}
|
|
.mr-2 {
|
margin-right: 0.5rem;
|
/* 8px */
|
}
|
|
.rounded-5 {
|
border-radius: 5px;
|
}
|
</style>
|