Files
jiapuapp/pages/family/f01-family-feed.vue
T
2026-07-21 20:59:10 +08:00

280 lines
7.2 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.
<!-- 页面编号F-01用途家族动态首页列表空态与失败状态 -->
<template>
<view
class="family-page"
:class="{
'feed-state--list': feedState === 'list',
'feed-state--empty': feedState === 'empty',
'feed-state--error': feedState === 'error',
}"
>
<ModulePageBackground module="family" />
<view class="family-page__header"
><PageHeader title="家族动态" action="发布" @action="toPublish"
/></view>
<view class="feed-content">
<AppLoading
v-if="feedState === 'loading'"
text="正在整理家族动态"
description="请稍候,正在读取家宴、通知与共同记忆。"
/>
<view v-if="feedState !== 'loading'" class="feed-heading"
><text>汤氏家族圈</text><text>家宴通知与共同记忆</text></view
>
<view v-if="feedState !== 'loading'" class="feed-shortcuts">
<view
v-for="item in shortcuts"
:key="item.key"
class="feed-shortcut"
@click="openSection(item.key)"
><text>{{ item.label }}</text></view
>
</view>
<template v-if="feedState === 'list'">
<view
v-for="item in feeds"
:key="item.id"
class="feed-card"
@click="openDetail(item)"
>
<view class="feed-card__copy">
<text class="feed-card__meta"
>{{ item.tag }} · {{ item.time }}</text
>
<text class="feed-card__title">{{ item.title }}</text>
<text class="feed-card__summary">{{ item.content }}</text>
<text class="feed-card__author">发布人{{ item.author }}</text>
</view>
</view>
</template>
<view v-else-if="feedState !== 'loading'" class="feed-state-card">
<view class="feed-state-card__copy"
><text>{{
feedState === "empty" ? "还没有家族动态" : "家族动态暂不可用"
}}</text
><text>{{
feedState === "empty"
? "发布第一条通知、家宴记录或家族故事。"
: "请稍后重新进入,已有内容不会受到影响。"
}}</text></view
>
</view>
<view
v-if="feedState !== 'loading'"
class="feed-action"
@click="feedState === 'error' ? (feedState = 'list') : toPublish()"
><text>{{
feedState === "error" ? "重新查看" : "发布家族动态"
}}</text></view
>
</view>
<AppTabbar active="family" />
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import AppLoading from "@/components/AppLoading.vue";
import PageHeader from "@/components/PageHeader.vue";
import AppTabbar from "@/components/AppTabbar.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import { genealogyContext } from "@/utils/genealogy-context.js";
const genealogyId = ref("");
const feedState = ref("loading");
const feeds = [
{
id: 1,
tag: "团圆记忆",
time: "今天 10:24",
title: "端午家宴",
content: "今年端午全家相聚,留下了许多温暖照片。",
author: "汤正国",
},
{
id: 2,
tag: "家族通知",
time: "昨天 18:02",
title: "修谱资料征集",
content: "请家人补充老照片中的人物姓名与拍摄时间。",
author: "谱主",
},
];
const shortcuts = [
{ key: "articles", label: "谱文" },
{ key: "albums", label: "相册" },
{ key: "rituals", label: "礼仪" },
{ key: "memos", label: "备忘" },
{ key: "people", label: "人物录" },
{ key: "gifts", label: "贺礼簿" },
{ key: "merits", label: "功德录" },
{ key: "videos", label: "家族视频" },
];
onLoad((query) => {
genealogyId.value =
query.genealogyId || genealogyContext.getCurrentGenealogyId() || "";
feedState.value =
query.state === "loading"
? "loading"
: query.state === "empty"
? "empty"
: query.state === "error"
? "error"
: "list";
});
const toPublish = () =>
uni.navigateTo({
url: `/pages/family/f02-publish-feed?genealogyId=${genealogyId.value}`,
});
const openDetail = (item) =>
uni.navigateTo({ url: `/pages/family/f03-feed-detail?feedId=${item.id}` });
const openSection = (key) => {
const routes = {
articles: "/pages/family/f04-article-list",
albums: "/pages/family/f07-album-list",
rituals: "/pages/records/r05-ritual-list",
memos: "/pages/records/r10-memo-list",
people: "/pages/records/r01-people-list",
gifts: "/pages/records/r03-gift-list",
merits: "/pages/records/r11-merit-records",
videos: "/pages/family/f10-video-list",
};
uni.navigateTo({
url: `${routes[key]}?genealogyId=${genealogyId.value}`,
});
};
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
.family-page {
display: flex;
min-height: 100vh;
flex-direction: column;
background: $paper;
}
.family-page__header,
.feed-content {
z-index: 1;
}
.feed-content {
flex: 1;
padding: 24rpx 24rpx 190rpx;
}
.feed-heading text {
display: block;
}
.feed-heading text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-weight: 700;
}
.feed-heading text:last-child {
margin-top: 6rpx;
color: $ink-muted;
font-size: 23rpx;
}
.feed-shortcuts {
@include adaptive.adaptive-scroll-button(secondary);
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
width: 100%;
min-height: 48px;
margin-top: 15rpx;
}
.feed-shortcut {
width: 100%;
height: 48px;
min-height: 44px;
}
.feed-shortcut text {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: $ink;
font-size: 22rpx;
font-weight: 700;
}
.feed-card,
.feed-state-card {
@include adaptive.adaptive-family-letter;
display: flex;
width: 100%;
min-height: 230rpx;
min-height: 98px;
flex-direction: column;
justify-content: center;
margin-top: 17rpx;
box-sizing: border-box;
}
.feed-card__copy {
padding: 15% 9%;
}
.feed-card text {
display: block;
}
.feed-card__meta {
color: #806a51;
font-size: 21rpx;
letter-spacing: 1rpx;
}
.feed-card__title {
margin-top: 5rpx;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-weight: 700;
}
.feed-card__summary {
margin-top: 6rpx;
color: $ink-muted;
font-size: 23rpx;
line-height: 1.4;
}
.feed-card__author {
margin-top: 6rpx;
color: $brand-red;
font-size: 21rpx;
}
.feed-state-card {
margin-top: 70rpx;
}
.feed-state-card__copy {
padding: 23% 10%;
box-sizing: border-box;
text-align: center;
}
.feed-state-card text {
display: block;
}
.feed-state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-weight: 700;
}
.feed-state-card text:last-child {
margin-top: 13rpx;
color: $ink-muted;
font-size: 23rpx;
line-height: 1.45;
}
.feed-action {
@include adaptive.adaptive-scroll-button(primary);
width: 514rpx;
max-width: 100%;
min-height: 76rpx;
margin: 19rpx auto 0;
}
.feed-action text {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: #fff9ed;
font-size: 24rpx;
font-weight: 700;
}
</style>