完成50%

This commit is contained in:
2026-07-23 08:23:59 +08:00
parent 9b0ad62df4
commit f1edc6b533
218 changed files with 24318 additions and 5514 deletions
+127 -106
View File
@@ -4,15 +4,15 @@
<GenealogyPageBackground />
<view class="overview-page__header">
<PageHeader
:title="viewMode === 'public' ? '家谱公开预览' : '家谱总览'"
:action="
overviewState === 'ready' &&
viewMode === 'member' &&
accessRole === 'owner'
? '管理'
: ''
:title="
viewMode === 'public'
? '家谱公开预览'
: viewMode === 'preview'
? '创建流程预览'
: '家谱总览'
"
@action="toSettings"
custom-back
@back="requestBack"
/>
</view>
@@ -36,7 +36,7 @@
<view class="overview-hero__stats">
<text> {{ genealogy.memberCount || 0 }} </text>
<text>已激活 {{ genealogy.activeCount || 0 }} </text>
<text>{{ genealogy.visibility || "仅成员可见" }}</text>
<text>{{ getGenealogyAccessPresetLabel(genealogy.accessPreset) }}</text>
</view>
<view class="overview-hero__stats">
<text>始祖 {{ genealogy.ancestorName }}</text>
@@ -52,14 +52,6 @@
<text class="overview-action__title">世系树</text
><text>查看家脉关系</text>
</view>
<view
v-if="accessRole === 'owner'"
class="overview-action overview-action--ancestor"
@click="toFirstPerson"
>
<text class="overview-action__title">录入族人</text
><text>从首代开始完善</text>
</view>
<view
class="overview-action overview-action--poem"
@click="toGenerationPoems"
@@ -75,6 +67,24 @@
<text class="overview-action__title">入谱审核</text
><text>处理加入申请</text>
</view>
<view
v-if="accessRole === 'owner'"
class="overview-action overview-action--settings"
@click="toSettings"
>
<text class="overview-action__title">家谱设置</text
><text>维护公开范围与基础资料</text>
</view>
<template v-else>
<view class="overview-summary">
<text class="overview-action__title">成员身份</text
><text>已加入 · 普通成员</text>
</view>
<view class="overview-summary">
<text class="overview-action__title">访问范围</text
><text>{{ getGenealogyAccessPresetLabel(genealogy.accessPreset) }}</text>
</view>
</template>
</view>
<view class="overview-family" @click="toFamily">
@@ -82,8 +92,8 @@
><text>查看</text>
</view>
<view class="overview-note">
<text class="overview-note__title">家谱资料仅向家人开放</text>
<text>公开范围访问说明与管理权由家谱管理员在设置中维护</text>
<text class="overview-note__title">成员资料按家谱访问规则保护</text>
<text>名称公开范围与家谱简介由谱主在设置中维护</text>
</view>
</view>
</template>
@@ -93,34 +103,49 @@
class="overview-public"
>
<view class="overview-public__hero">
<text class="overview-public__eyebrow">公开家谱</text>
<text class="overview-public__eyebrow">{{
viewMode === "preview" ? "本地流程预览" : "公开家谱"
}}</text>
<text class="overview-public__title">{{ genealogy.name }}</text>
<text class="overview-public__source">{{ genealogy.source }}</text>
<text class="overview-public__source">{{ genealogy.source || "来源信息待同步" }}</text>
</view>
<view class="overview-public__details">
<view
><text>姓氏</text><text>{{ genealogy.surname }}</text></view
>
<view
><text>地区</text><text>{{ genealogy.location }}</text></view
><text>地区</text><text>{{ genealogy.location || "待补充" }}</text></view
>
<view
><text>堂号</text><text>{{ genealogy.hall }}</text></view
><text>堂号</text><text>{{ genealogy.hall || "待补充" }}</text></view
>
<view
><text>当前支系</text><text>{{ genealogy.branchName }}</text></view
><text>当前支系</text><text>{{ genealogy.branchName || "待补充" }}</text></view
>
<view
><text>所属上级谱</text
><text>{{ genealogy.parentName }}</text></view
><text>{{ viewMode === "preview" ? "首代人物" : "所属上级谱" }}</text
><text>{{ (viewMode === "preview" ? genealogy.ancestorName : genealogy.parentName) || "待补充" }}</text></view
>
</view>
<view
v-if="viewMode === 'public' && (genealogy.manager || genealogy.certification)"
class="overview-public__trust"
>
<text>{{ genealogy.manager || "管理者待确认" }}</text>
<text>{{ genealogy.certification || "认证信息待确认" }}</text>
<text>{{ genealogy.memberCount || 0 }} 位成员</text>
<text>更新于 {{ genealogy.updatedAt || "待同步" }}</text>
</view>
<view class="overview-public__notice">
<text>公开说明</text>
<text>{{ genealogy.publicDescription }}</text>
<text>{{ viewMode === "preview" ? "预览说明" : "公开说明" }}</text>
<text>{{ genealogy.publicDescription || "公开说明待补充" }}</text>
</view>
<view class="overview-public__action" @click="applyToJoin">
<text>申请加入这部家谱</text>
<view
v-if="viewMode === 'public' && publicActionLabel"
class="overview-public__action"
@click="applyToJoin"
>
<text>{{ publicActionLabel }}</text>
</view>
</view>
@@ -169,55 +194,39 @@
<script setup>
import { computed, ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { onBackPress, onLoad } from "@dcloudio/uni-app";
import AppLoading from "@/components/AppLoading.vue";
import GenealogyPageBackground from "@/components/GenealogyPageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
import { findGenealogyFixture, getGenealogyFixtureAccess } from "@/data/mock.js";
import { getGenealogyAccessPresetLabel } from "@/utils/genealogy-contracts.js";
import {
goBack,
goRoot,
handleBackPress,
openPage,
returnTo,
} from "@/utils/navigation.js";
const genealogy = ref(null);
const genealogyId = ref("");
const overviewState = ref("loading");
const loadError = ref("");
const viewMode = ref("member");
const accessRole = ref("owner");
const overviewFixture = {
id: "2001",
surname: "汤",
name: "汤氏南阳宗谱",
hall: "敦睦堂",
location: "河南·南阳",
parentName: "汤氏中华总谱",
branchName: "南阳主支",
source: "由南阳汤氏族人整理并维护",
publicDescription:
"公开展示家谱身份、地区、堂号与支系信息;成员资料和世系详情仅向已加入成员开放。",
motto: "敦亲睦族,敬祖传家。",
memberCount: 428,
activeCount: 316,
visibility: "仅成员可见",
ancestorName: "汤文远",
updatedAt: "2026-07-12",
};
const overviewFixtures = {
1001: {
...overviewFixture,
id: "1001",
name: "汤氏家谱",
location: "河南·洛阳",
memberCount: 158,
activeCount: 108,
},
1002: {
...overviewFixture,
id: "1002",
name: "汤氏宗谱",
hall: "承志堂",
location: "山东·济宁",
memberCount: 286,
activeCount: 215,
},
2001: overviewFixture,
};
const accessRole = ref("guest");
const publicRelation = ref("unknown");
const publicCanApply = ref(false);
const publicActionLabel = computed(() => {
if (publicRelation.value === "pending") return "查看申请进度";
if (!publicCanApply.value) return "";
return (
({
available: "申请加入这部家谱",
rejected: "修改后重新申请",
removed: "重新申请加入",
})[publicRelation.value] || ""
);
});
const stateTitle = computed(
() =>
@@ -244,9 +253,11 @@ const loadGenealogy = (query = {}) => {
overviewState.value = "loading";
loadError.value = "";
genealogy.value = null;
genealogyId.value = query.genealogyId || genealogyId.value || "";
viewMode.value = query.mode === "public" ? "public" : "member";
accessRole.value = query.role === "member" ? "member" : "owner";
genealogyId.value = String(query.genealogyId || genealogyId.value || "");
viewMode.value = "member";
accessRole.value = "guest";
publicRelation.value = "unknown";
publicCanApply.value = false;
if (query.state === "empty" || !genealogyId.value) {
overviewState.value = "empty";
@@ -262,45 +273,49 @@ const loadGenealogy = (query = {}) => {
}
if (query.state === "loading") return;
genealogy.value = {
...(overviewFixtures[genealogyId.value] || overviewFixture),
id: genealogyId.value,
};
if (query.genealogyName) {
genealogy.value.name = decodeURIComponent(query.genealogyName);
const fixture = findGenealogyFixture(genealogyId.value);
if (!fixture) {
overviewState.value = "no-permission";
return;
}
const access = getGenealogyFixtureAccess(genealogyId.value);
if (!access.canView) {
overviewState.value = "no-permission";
return;
}
genealogy.value = { ...fixture };
viewMode.value = access.viewMode;
accessRole.value = access.accessRole;
publicRelation.value = access.relation;
publicCanApply.value = access.canApply;
overviewState.value = "ready";
};
const requestBack = () => goBack();
onBackPress((event) => handleBackPress(event, requestBack));
onLoad(loadGenealogy);
const reloadOverview = () => loadGenealogy({ genealogyId: genealogyId.value });
const toGenealogies = () =>
uni.reLaunch({ url: "/pages/genealogy/g01-my-genealogies" });
const toGenealogies = () => returnTo("G01", {});
const toTree = () =>
uni.navigateTo({
url: `/pages/tree/t01-tree-overview?genealogyId=${genealogyId.value}`,
});
const toFirstPerson = () =>
uni.navigateTo({
url: `/pages/genealogy/g03-create-genealogy?step=ancestor&genealogyId=${genealogyId.value}`,
});
const toFamily = () => uni.reLaunch({ url: "/pages/family/f01-family-feed" });
openPage("T01", { genealogyId: genealogyId.value }, "G05");
const toFamily = () => goRoot("F01", { genealogyId: genealogyId.value });
const toApplications = () =>
uni.navigateTo({
url: `/pages/genealogy/g10-application-review?genealogyId=${genealogyId.value}`,
});
openPage("G10", { genealogyId: genealogyId.value }, "G05");
const toSettings = () =>
uni.navigateTo({
url: `/pages/genealogy/g11-genealogy-settings?genealogyId=${genealogyId.value}`,
});
openPage("G11", { genealogyId: genealogyId.value }, "G05");
const toGenerationPoems = () =>
uni.navigateTo({
url: `/pages/genealogy/g12-generation-poems?genealogyId=${genealogyId.value}`,
});
const applyToJoin = () =>
uni.navigateTo({
url: `/pages/genealogy/g08-join-application?source=search&genealogyId=${genealogyId.value}`,
});
openPage("G12", { genealogyId: genealogyId.value }, "G05");
const applyToJoin = () => {
if (publicRelation.value === "pending")
return openPage("G09", { status: "pending" }, "G05");
if (!publicCanApply.value) return false;
return openPage(
"G08",
{ genealogyId: genealogyId.value, source: "search" },
"G05",
);
};
</script>
<style scoped lang="scss">
@@ -380,7 +395,7 @@ const applyToJoin = () =>
min-height: 386rpx;
}
.overview-action,
.overview-action-lock {
.overview-summary {
display: flex;
flex-direction: column;
justify-content: center;
@@ -390,9 +405,6 @@ const applyToJoin = () =>
color: $ink-muted;
font-size: 22rpx;
}
.overview-action-lock {
opacity: 0.58;
}
.overview-action__title {
margin-bottom: 9rpx;
color: $ink;
@@ -562,6 +574,15 @@ const applyToJoin = () =>
font-family: "STKaiti", "KaiTi", serif;
font-size: 27rpx;
}
.overview-public__trust {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: 10rpx 24rpx;
margin: 28rpx 9% 0;
color: $ink-muted;
font-size: 21rpx;
line-height: 1.45;
}
.overview-public__notice {
display: flex;
margin: 54rpx 9% 0;