2025-04-22 10:22:33 +08:00

251 lines
6.5 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.

<!-- src/pages/view/notice/index.vue -->
<template>
<view class="notice-list-page">
<BasicListLayout @register="register">
<template #default="{ data }">
<view class="notice-card" @click="goToDetail(data.id)">
<view class="card-header">
<text class="notice-title">{{ data.title }}</text>
<text class="notice-status" :class="getStatusClass(data.status)">{{
data.statusText
}}</text>
</view>
<view class="card-body">
<!-- 可选显示封面缩略图 -->
<image
v-if="data.coverImage"
:src="data.coverImage"
mode="aspectFill"
class="cover-thumbnail"
></image>
<text class="notice-excerpt">{{ data.excerpt }}</text>
</view>
<view class="card-footer">
<text class="footer-item">发布者: {{ data.publisher }}</text>
<text class="footer-item">{{ data.publishTime }}</text>
<text class="footer-item" v-if="data.target"
>范围: {{ data.target }}</text
>
</view>
</view>
</template>
</BasicListLayout>
<!-- 新建通知按钮 -->
<view class="fab-button" @click="goToPublish">
<uni-icons type="plusempty" size="24" color="#fff"></uni-icons>
</view>
</view>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { useLayout } from "@/components/BasicListLayout/hooks/useLayout";
interface NoticeItem {
id: string;
title: string;
excerpt: string; // 内容摘要
status: "published" | "draft" | "ended"; // 状态
statusText: string; // 状态文字
publisher: string;
publishTime: string;
coverImage?: string; // 封面图 URL (可选)
target?: string; // 通知范围 (可选)
}
// 模拟获取通知列表数据的 API 函数
const fetchNoticeList = async (params: any): Promise<any> => {
// 返回类型改为 Promise<any>
console.log("Fetching notice list with params:", params);
return new Promise((resolve) => {
setTimeout(() => {
// 根据 params.pageNo 和 params.pageSize 模拟分页
const pageNo = params.pageNo || 1;
const pageSize = params.pageSize || 10;
const total = 35; // 模拟总数
const mockData: NoticeItem[] = [];
const startIndex = (pageNo - 1) * pageSize;
for (let i = 0; i < pageSize; i++) {
const currentIndex = startIndex + i;
if (currentIndex >= total) break; // 超出总数则停止
const status =
currentIndex % 3 === 0
? "draft"
: currentIndex % 3 === 1
? "published"
: "ended";
mockData.push({
id: `notice_${currentIndex + 1}`,
title: `重要通知标题 ${currentIndex + 1}`,
excerpt: `这是通知 ${currentIndex + 1} 的内容摘要,只显示一部分...`,
status: status,
statusText:
status === "draft"
? "草稿"
: status === "published"
? "已发布"
: "已结束",
publisher: "教务处",
publishTime: `2024-06-${String(
18 - Math.floor(currentIndex / 5)
).padStart(2, "0")}`,
target: currentIndex % 2 === 0 ? "一年级3班" : "全体教师",
// coverImage: i % 3 === 0 ? '/static/mock/cover.png' : undefined
});
}
resolve({
message: "获取成功",
resultCode: 1,
rows: mockData,
total: total,
});
}, 800); // 模拟网络延迟
});
};
const [register, { reload }] = useLayout({
api: fetchNoticeList,
});
// 跳转到详情页
const goToDetail = (noticeId: string) => {
uni.navigateTo({
url: `/pages/view/notice/detail?id=${noticeId}`,
});
};
// 跳转到发布页
const goToPublish = () => {
uni.navigateTo({
url: "/pages/view/notice/publish",
});
};
// 根据状态获取对应的 CSS 类
const getStatusClass = (status: "published" | "draft" | "ended") => {
if (status === "published") return "status-published";
if (status === "draft") return "status-draft";
if (status === "ended") return "status-ended";
return "";
};
</script>
<style scoped lang="scss">
.notice-list-page {
position: relative; // 为了 FAB 定位
min-height: 100vh; // 确保 FAB 总在视图内
}
.notice-card {
background-color: #ffffff;
border-radius: 8px;
padding: 15px;
margin-bottom: 12px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
border-left: 4px solid #447ade; // 左侧加个强调色条
}
.card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 8px;
.notice-title {
font-size: 16px;
font-weight: bold;
color: #333;
flex: 1;
margin-right: 10px;
// 最多显示两行
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.notice-status {
font-size: 12px;
padding: 2px 6px;
border-radius: 4px;
color: #fff;
white-space: nowrap;
flex-shrink: 0;
&.status-published {
background-color: #19be6b; // 绿色-已发布
}
&.status-draft {
background-color: #ff9f0a; // 橙色-草稿
}
&.status-ended {
background-color: #999999; // 灰色-已结束
}
}
}
.card-body {
// 封面图样式 (如果启用)
.cover-thumbnail {
width: 80px;
height: 60px;
border-radius: 4px;
margin-right: 10px;
float: left; // 文字环绕图片
}
.notice-excerpt {
font-size: 14px;
color: #666;
line-height: 1.5;
// 最多显示 3 行
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
// 清除浮动影响(如果用了 float
// &::after {
// content: "";
// display: table;
// clear: both;
// }
}
.card-footer {
margin-top: 10px;
padding-top: 8px;
border-top: 1px solid #f0f0f0;
font-size: 12px;
color: #999;
display: flex;
flex-wrap: wrap; // 允许换行
gap: 5px 15px; // 行间距 列间距
.footer-item {
white-space: nowrap;
}
}
// FAB 按钮样式
.fab-button {
position: fixed;
right: 20px;
bottom: 40px; // 根据需要调整距离底部的距离
width: 50px;
height: 50px;
background-color: #4477ee;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
z-index: 10;
}
</style>