<template>
	<view class="container">
		<!-- 内容区域 -->
		<view class="content">
			<view class="content-wrapper">
				<!-- 公告列表 -->
				<view class="notice-list">
					<!-- 骨架屏 -->
					<view class="skeleton-wrapper" v-if="isLoading && noticesList.length === 0">
						<view class="skeleton-item" v-for="i in 5" :key="'skeleton-'+i">
							<view class="skeleton-image"></view>
							<view class="skeleton-content">
								<view class="skeleton-line"></view>
								<view class="skeleton-line short"></view>
								<view class="skeleton-line shorter"></view>
							</view>
						</view>
					</view>
					
					<!-- 实际列表 -->
					<view class="notice-item" 
					      v-for="(item,index) in noticesList"
						  :key="item.id"
					      @click="goNoticeDetail(item.id)">
						<image :src="item.cover" 
                               class="notice-image"
                               mode="aspectFill"
                               lazy-load
                               :show-menu-by-longpress="true"
                               @error="handleImageError(index)"></image>
						<view class="notice-content">
							<view class="notice-title line-clamp-1">{{item.title}}</view>
							<view class="notice-description line-clamp-2" v-html="item.desc"></view>
							<view class="notice-footer">
								<text class="notice-date">{{formatTime(item.createdAt,'YYYY-MM-DD')}}</text>
								<text class="notice-more">查看详情 →</text>
							</view>
						</view>
					</view>
					
					<!-- 加载更多提示 -->
					<view class="load-more" v-if="noticesList.length > 0 && currentPage < totalPages">
						<text>{{isLoading ? '加载中...' : '上拉加载更多'}}</text>
					</view>
					
					<!-- 空状态 -->
					<view class="empty-state" v-if="noticesList.length === 0 && !isLoading">
						<image src="/static/images/empty-notice.png" class="empty-image"></image>
						<text class="empty-text">暂无公告</text>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 底部导航 -->
		<Footer></Footer>
	</view>
</template>

<script>
	import { get } from '@/utils/request';
	import { IMAGE_BASE_URL } from '@/utils/config';
	import { formatTime } from '@/utils/timeFormat';
	import Footer from '@/components/footer_common.vue';
	
	export default {
		components: { Footer },
		data() {
			return {
				formatTime,
				IMAGE_BASE_URL,
				noticesList: [],
				cachedNotices: uni.getStorageSync('cachedNotices') || [],
				isLoading: false,
				currentPage: 1,
				totalPages: 1,
				lastRequestTime: 0
			};
		},
		mounted() {
			this.getNotices();
			this.initScrollListener();
		},
		beforeDestroy() {
			this.removeScrollListener();
		},
		methods: {
			async getNotices() {
				// 防止重复请求
				const now = Date.now();
				if (this.isLoading || (now - this.lastRequestTime < 1000)) return;
				this.lastRequestTime = now;
				
				// 第一页尝试使用缓存
				if (this.currentPage === 1 && this.cachedNotices.length > 0) {
					this.noticesList = [...this.cachedNotices];
					// 仍然在后台更新数据
					setTimeout(() => this.fetchNotices(), 300);
					return;
				}
				
				await this.fetchNotices();
			},
			
			async fetchNotices() {
				this.isLoading = true;
				uni.showLoading({ title: '加载中...', mask: true });
				
				try {
					const res = await get('/api/v1/apps/home/notices', {
						current: this.currentPage,
						pageSize: 10,
					}, {
						timeout: 5000 // 设置超时时间
					});
					
					if (res?.success) {
						const processedData = res.data.map(item => ({
							...item,
							cover: this.processImageUrl(item.cover),
							desc: this.filterHtmlTags(item.desc) // 过滤HTML标签防止XSS
						}));
						
						if (this.currentPage === 1) {
							this.noticesList = processedData;
							// 缓存第一页数据
							uni.setStorage({
								key: 'cachedNotices',
								data: processedData,
								expire: 3600 // 1小时缓存
							});
						} else {
							this.noticesList = this.noticesList.concat(processedData);
						}
						
						this.totalPages = Math.ceil(res.total / 10);
					}
				} catch (err) {
					console.error('获取公告失败:', err);
					if (this.currentPage === 1) {
						uni.showToast({
							title: '加载公告失败',
							icon: 'none'
						});
					}
				} finally {
					uni.hideLoading();
					this.isLoading = false;
				}
			},
			
			processImageUrl(url) {
				if (!url) return '/static/images/default-cover.jpg';
				return url.startsWith('http') ? url : IMAGE_BASE_URL + url;
			},
			
			filterHtmlTags(str) {
				if (!str) return '';
				return str.replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ');
			},
			
			handleImageError(index) {
				this.$set(this.noticesList, index, {
					...this.noticesList[index],
					cover: '/static/images/default-cover.jpg'
				});
			},
			
			goNoticeDetail(id) {
				uni.navigateTo({
					url: `/pages/serviceNoticeDetail/index?Id=${id}`,
					animationType: 'slide-in-right'
				});
			},
			
			initScrollListener() {
				this.onScroll = () => {
					const scrollHeight = document.documentElement.scrollHeight;
					const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
					const clientHeight = document.documentElement.clientHeight;
					
					// 距离底部200px时加载更多
					if (scrollTop + clientHeight >= scrollHeight - 200 && 
						this.currentPage < this.totalPages && 
						!this.isLoading) {
						this.currentPage++;
						this.getNotices();
					}
				};
				
				window.addEventListener('scroll', this.onScroll);
			},
			
			removeScrollListener() {
				if (this.onScroll) {
					window.removeEventListener('scroll', this.onScroll);
				}
			}
		}
	};
</script>

<style lang="scss" scoped>
	/* 基础变量 */
	:root {
		--primary-color: #3b8cff;
		--secondary-color: #4a90e2;
		--text-color: #333;
		--text-light: #7d7d7d;
		--bg-color: #f8f9fa;
		--card-bg: #fff;
		--border-color: rgba(59, 140, 255, 0.2);
		--shadow: 0 4rpx 12rpx rgba(59, 140, 255, 0.1);
		--radius: 16rpx;
	}
	
	.container {
		display: flex;
		flex-direction: column;
		min-height: 100vh;
		background: linear-gradient(180deg, rgba(255, 241, 235, 0.8) 0%, rgba(192, 219, 250, 0.8) 100%);
		position: relative;
	}
	
	.content {
		flex: 1;
		margin-top: 30rpx;
		border-radius: 30rpx 30rpx 0 0;
		background-color: rgba(255, 255, 255, 0.85);
		padding-bottom: env(safe-area-inset-bottom);
		box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05);
		
		.content-wrapper {
			padding: 30rpx 0;
			
			.notice-list {
				display: flex;
				flex-direction: column;
				gap: 24rpx;
				padding: 0 30rpx;
				
				.notice-item {
					display: flex;
					background: var(--card-bg);
					border-radius: var(--radius);
					overflow: hidden;
					transition: all 0.3s ease;
					box-shadow: var(--shadow);
					border: 1rpx solid var(--border-color);
					
					&:active {
						transform: scale(0.98);
						opacity: 0.9;
					}
					
					.notice-image {
						width: 220rpx;
						height: 220rpx;
						flex-shrink: 0;
						background-color: #f5f5f5;
						will-change: transform;
						image-rendering: -webkit-optimize-contrast;
					}
					
					.notice-content {
						flex: 1;
						padding: 24rpx;
						display: flex;
						flex-direction: column;
						
						.notice-title {
							font-size: 32rpx;
							font-weight: 600;
							color: var(--secondary-color);
							margin-bottom: 12rpx;
						}
						
						.notice-description {
							font-size: 26rpx;
							color: var(--text-light);
							line-height: 1.5;
							margin-bottom: 16rpx;
							flex: 1;
						}
						
						.notice-footer {
							display: flex;
							justify-content: space-between;
							align-items: center;
							
							.notice-date {
								font-size: 24rpx;
								color: var(--text-light);
							}
							
							.notice-more {
								font-size: 24rpx;
								color: var(--primary-color);
							}
						}
					}
				}
				
				.load-more {
					text-align: center;
					padding: 30rpx 0;
					color: var(--text-light);
					font-size: 26rpx;
				}
				
				.empty-state {
					display: flex;
					flex-direction: column;
					align-items: center;
					justify-content: center;
					padding: 80rpx 0;
					
					.empty-image {
						width: 200rpx;
						height: 200rpx;
						margin-bottom: 30rpx;
						opacity: 0.6;
					}
					
					.empty-text {
						font-size: 28rpx;
						color: var(--text-light);
					}
				}
				
				/* 骨架屏样式 */
				.skeleton-wrapper {
					display: flex;
					flex-direction: column;
					gap: 24rpx;
					
					.skeleton-item {
						display: flex;
						background: #fff;
						border-radius: var(--radius);
						overflow: hidden;
						height: 220rpx;
						
						.skeleton-image {
							width: 220rpx;
							height: 220rpx;
							background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 50%, #f2f2f2 75%);
							background-size: 400% 100%;
							animation: loading 1.5s ease infinite;
						}
						
						.skeleton-content {
							flex: 1;
							padding: 24rpx;
							display: flex;
							flex-direction: column;
							justify-content: space-between;
							
							.skeleton-line {
								height: 32rpx;
								background: #f2f2f2;
								border-radius: 8rpx;
								margin-bottom: 16rpx;
								animation: loading 1.5s ease infinite;
								
								&.short {
									width: 60%;
								}
								
								&.shorter {
									width: 40%;
								}
							}
						}
					}
				}
				
				@keyframes loading {
					0% {
						background-position: 100% 50%;
					}
					100% {
						background-position: 0 50%;
					}
				}
			}
		}
	}
	
	/* 通用工具类 */
	.line-clamp-1 {
		display: -webkit-box;
		-webkit-line-clamp: 1;
		-webkit-box-orient: vertical;
		overflow: hidden;
	}
	
	.line-clamp-2 {
		display: -webkit-box;
		-webkit-line-clamp: 2;
		-webkit-box-orient: vertical;
		overflow: hidden;
	}
</style>