完成70%
This commit is contained in:
@@ -3,9 +3,7 @@
|
||||
<view
|
||||
class="member-status-page"
|
||||
:class="{
|
||||
'member-status--privacy': statusState === 'privacy',
|
||||
'member-status--deceased': statusState === 'deceased',
|
||||
'member-status--forbidden': statusState === 'forbidden',
|
||||
'member-status--available': statusState === 'available',
|
||||
'member-status--error': statusState === 'error',
|
||||
}"
|
||||
>
|
||||
@@ -19,21 +17,26 @@
|
||||
</view>
|
||||
|
||||
<view class="status-card">
|
||||
<view class="status-card__copy">
|
||||
<AppLoading
|
||||
v-if="statusState === 'loading'"
|
||||
text="正在读取成员状态"
|
||||
description="请稍候,正在读取人物详情中的状态字段。"
|
||||
/>
|
||||
<view v-else class="status-card__copy">
|
||||
<text>{{ activeStatus.eyebrow }}</text>
|
||||
<text>{{ activeStatus.title }}</text>
|
||||
<text>{{ activeStatus.copy }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="status-guidance">
|
||||
<view v-if="statusState !== 'loading'" class="status-guidance">
|
||||
<view>
|
||||
<text>{{ activeStatus.guideTitle }}</text>
|
||||
<text v-for="line in activeStatus.guides" :key="line">{{ line }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="status-action" @click="handleAction">
|
||||
<view v-if="statusState !== 'loading'" class="status-action" @click="handleAction">
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="scaleToFill" />
|
||||
<text>{{ activeStatus.action }}</text>
|
||||
</view>
|
||||
@@ -42,43 +45,38 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { onLoad, onUnload } from "@dcloudio/uni-app";
|
||||
import AppLoading from "@/components/AppLoading.vue";
|
||||
import ModulePageBackground from "@/components/ModulePageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
import { findTreeMemberPresentationFixture } from "@/data/mock.js";
|
||||
import { goBack, goRoot } from "@/utils/navigation.js";
|
||||
import { appApi, createRequestController, isRequestCancelled } from "@/utils/api.js";
|
||||
import { goBack } from "@/utils/navigation.js";
|
||||
|
||||
const genealogyId = ref("");
|
||||
const personId = ref("");
|
||||
const statusState = ref("loading");
|
||||
const genealogyName = ref("汤氏家谱");
|
||||
const member = ref(null);
|
||||
const statusRequestController = createRequestController();
|
||||
let loadSequence = 0;
|
||||
|
||||
const states = {
|
||||
privacy: {
|
||||
eyebrow: "隐私成员",
|
||||
title: "敏感资料只向授权成员展示",
|
||||
copy: "该成员姓名和世系位置仍然保留,出生信息、联系方式和生平内容按权限隐藏。",
|
||||
guideTitle: "当前可见范围",
|
||||
guides: ["姓名、世代与家族关系可见", "联系方式和详细生平已隐藏", "本人或谱主可维护授权范围"],
|
||||
action: "返回成员档案",
|
||||
loading: {
|
||||
eyebrow: "正在读取",
|
||||
title: "正在读取成员状态",
|
||||
copy: "",
|
||||
guideTitle: "",
|
||||
guides: [],
|
||||
action: "",
|
||||
},
|
||||
deceased: {
|
||||
eyebrow: "离世纪念",
|
||||
title: "这位家人的生命记录被温和保留",
|
||||
copy: "离世状态不会删除成员关系;有权限的家人仍可共同维护生卒年月、生平和追思资料。",
|
||||
guideTitle: "纪念资料范围",
|
||||
guides: ["生卒年月与世系关系继续保留", "生平内容由有权限家人维护", "敏感资料继续遵守原有隐私设置"],
|
||||
available: {
|
||||
eyebrow: "人物状态",
|
||||
title: "当前状态已由服务端返回",
|
||||
copy: "页面只展示人物详情中的原始状态值,不把未声明的字典值解释成隐私、纪念或访问限制。",
|
||||
guideTitle: "当前合同范围",
|
||||
guides: ["人物状态值来自 personStatus 字段", "状态展示文案需要后端提供字典 owner", "当前页不执行停用或任何状态写入"],
|
||||
action: "返回成员档案",
|
||||
},
|
||||
forbidden: {
|
||||
eyebrow: "访问受限",
|
||||
title: "当前账号没有查看该档案的权限",
|
||||
copy: "页面不会展示被隐藏字段,也不会提供绕过家谱权限的入口。",
|
||||
guideTitle: "如何申请查看",
|
||||
guides: ["先确认已经加入对应家谱", "联系谱主说明亲属关系和用途", "权限变更后重新进入成员档案"],
|
||||
action: "返回我的家谱",
|
||||
},
|
||||
error: {
|
||||
eyebrow: "成员状态不可用",
|
||||
title: "没有找到要查看的成员",
|
||||
@@ -89,35 +87,48 @@ const states = {
|
||||
},
|
||||
};
|
||||
const activeStatus = computed(() => states[statusState.value] || states.error);
|
||||
const pageTitle = computed(() => statusState.value === "deceased" ? "成员纪念" : statusState.value === "privacy" ? "隐私资料" : "成员状态");
|
||||
const pageTitle = computed(() => "成员状态");
|
||||
const hasValidContext = computed(() => Boolean(genealogyId.value && personId.value));
|
||||
const memberIdentityCopy = computed(() => {
|
||||
if (!member.value) return "";
|
||||
const identity = `${member.value.name} · 第 ${member.value.generation} 世`;
|
||||
return ["privacy", "forbidden"].includes(member.value.status)
|
||||
? `${identity} · ${member.value.relation}`
|
||||
: `${identity} · ${member.value.branch}`;
|
||||
const status = member.value.personStatus || "未填写";
|
||||
return `${member.value.name} · 第 ${member.value.generation} 世 · 状态值 ${status}`;
|
||||
});
|
||||
|
||||
const loadMember = async () => {
|
||||
const activeLoad = ++loadSequence;
|
||||
statusState.value = "loading";
|
||||
try {
|
||||
const result = await appApi.getPerson(genealogyId.value, personId.value, {
|
||||
requestController: statusRequestController,
|
||||
});
|
||||
if (activeLoad !== loadSequence) return;
|
||||
member.value = result;
|
||||
genealogyName.value = result.genealogyName;
|
||||
statusState.value = "available";
|
||||
} catch (error) {
|
||||
if (activeLoad !== loadSequence || isRequestCancelled(error)) return;
|
||||
member.value = null;
|
||||
statusState.value = "error";
|
||||
}
|
||||
};
|
||||
|
||||
onLoad((query) => {
|
||||
genealogyId.value = String(query.genealogyId || "");
|
||||
personId.value = String(query.personId || "");
|
||||
member.value = hasValidContext.value
|
||||
? findTreeMemberPresentationFixture(genealogyId.value, personId.value)
|
||||
: null;
|
||||
const requestedState = ["privacy", "deceased", "forbidden"].includes(query.state) ? query.state : "";
|
||||
const derivedState = member.value?.status || "";
|
||||
statusState.value = member.value && (!requestedState || requestedState === derivedState)
|
||||
? requestedState || derivedState
|
||||
: "error";
|
||||
if (!hasValidContext.value || query.state === "error") {
|
||||
statusState.value = "error";
|
||||
return;
|
||||
}
|
||||
void loadMember();
|
||||
});
|
||||
|
||||
const handleAction = () => {
|
||||
if (statusState.value === "forbidden") {
|
||||
return goRoot("G01");
|
||||
}
|
||||
return goBack();
|
||||
};
|
||||
onUnload(() => {
|
||||
loadSequence += 1;
|
||||
statusRequestController.abort();
|
||||
});
|
||||
|
||||
const handleAction = () => goBack();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user