Files
jiapuapp/pages/tree/t03-member-profile.vue
T
2026-07-20 06:52:33 +08:00

285 lines
7.1 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.
<!-- 页面编号T-03用途成员档案详情与失败状态页面设计阶段使用本地模拟数据)。 -->
<template>
<view
class="member-page"
:class="{
'member-state--detail': memberState === 'detail',
'member-state--error': memberState === 'error',
}"
>
<ModulePageBackground module="tree" />
<view class="member-page__header"
><PageHeader
title="成员档案"
:action="memberState === 'detail' ? '编辑' : ''"
@action="toEdit"
/></view>
<view class="member-panel">
<image
class="member-panel__skin"
src="/static/assets/modules/tree/transparent/t01-state-panel.png"
mode="scaleToFill"
/>
<AppLoading
v-if="memberState === 'loading'"
text="正在读取成员档案"
description="请稍候,正在整理成员资料。"
/>
<view v-else-if="memberState === 'detail'" class="member-detail">
<view class="member-heading">
<view class="member-heading__seal"
><image
src="/static/assets/modules/genealogy/transparent/current-seal-frame.png"
mode="scaleToFill"
/><text>{{ member.name.slice(0, 1) }}</text></view
>
<view
><text>{{ member.name }}</text
><text
> {{ member.generation }} · {{ member.relation }} ·
{{ member.branch }}</text
></view
>
</view>
<text class="member-section-title">基本资料</text>
<view v-for="item in details" :key="item.label" class="member-info-row">
<image
src="/static/assets/modules/tree/transparent/t07-search-input-frame.png"
mode="scaleToFill"
/><text>{{ item.label }}</text
><text>{{ item.value }}</text>
</view>
<text class="member-section-title member-section-title--relation"
>亲属关系</text
>
<view class="member-relatives">
<text>长子 · 汤正国</text><text>次子 · 汤正华</text>
</view>
<view class="member-profile-action" @click="toEdit">
<image
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
mode="aspectFit"
/><text>完善成员档案</text>
</view>
</view>
<view v-else class="member-error">
<text>成员档案暂不可用</text
><text>请从世系树重新选择成员当前没有可展示的个人资料</text>
<view class="member-profile-action" @click="toTree"
><image
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
mode="aspectFit"
/><text>返回世系树</text></view
>
</view>
</view>
</view>
</template>
<script setup>
import { computed, ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import AppLoading from "@/components/AppLoading.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
import { genealogyContext } from "@/utils/genealogy-context.js";
const genealogyId = ref("");
const personId = ref("");
const memberState = ref("loading");
const member = ref({
id: 101,
name: "汤文远",
generation: 12,
relation: "始祖",
branch: "主支",
generationName: "文字辈",
birthDate: "1940年3月",
years: "1940—2012",
});
const details = computed(() => [
{ label: "字辈", value: member.value.generationName },
{ label: "出生日期", value: member.value.birthDate },
{ label: "生卒信息", value: member.value.years },
{ label: "所属支系", value: member.value.branch },
]);
onLoad((query) => {
genealogyId.value =
query.genealogyId || genealogyContext.getCurrentGenealogyId() || "";
personId.value = query.personId || "";
if (genealogyId.value)
genealogyContext.setCurrentGenealogyId(genealogyId.value);
memberState.value =
query.state === "loading"
? "loading"
: query.state === "error" || !personId.value
? "error"
: "detail";
});
const toEdit = () =>
uni.navigateTo({
url: `/pages/tree/t05-edit-member?genealogyId=${genealogyId.value}&personId=${personId.value}`,
});
const toTree = () => uni.navigateBack();
</script>
<style scoped lang="scss">
.member-page {
position: relative;
min-height: 100vh;
overflow: hidden;
background: $paper;
}
.member-page__header {
position: relative;
z-index: 3;
}
.member-panel {
position: relative;
z-index: 2;
width: calc(100% - 32rpx);
height: min(650px, calc((100vw - 16px) * 1.5));
margin: 18rpx auto 0;
}
.member-panel__skin {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.member-detail {
position: absolute;
inset: 7% 8%;
}
.member-heading {
display: flex;
align-items: center;
gap: 20rpx;
}
.member-heading__seal {
position: relative;
display: flex;
width: 84rpx;
height: 108rpx;
align-items: center;
justify-content: center;
}
.member-heading__seal image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.member-heading__seal text {
position: relative;
z-index: 1;
color: #fff8ec;
font-family: "STKaiti", "KaiTi", serif;
font-size: 33rpx;
}
.member-heading > view:last-child text {
display: block;
}
.member-heading > view:last-child text:first-child {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 38rpx;
font-weight: 700;
}
.member-heading > view:last-child text:last-child {
margin-top: 8rpx;
color: $ink-muted;
font-size: 23rpx;
}
.member-section-title {
display: block;
margin: 20rpx 0 4rpx;
color: $brand-red;
font-size: 24rpx;
font-weight: 700;
letter-spacing: 2rpx;
}
.member-info-row {
position: relative;
height: 62rpx;
margin-top: 7rpx;
}
.member-info-row image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.member-info-row text {
position: absolute;
top: 21rpx;
z-index: 1;
font-size: 23rpx;
}
.member-info-row text:nth-child(2) {
left: 22rpx;
color: $ink-muted;
}
.member-info-row text:last-child {
right: 22rpx;
color: $ink;
font-weight: 700;
}
.member-section-title--relation {
margin-top: 18rpx;
}
.member-relatives {
display: flex;
justify-content: space-between;
color: $ink;
font-size: 23rpx;
}
.member-profile-action {
position: relative;
width: 100%;
height: 72rpx;
margin-top: 20rpx;
}
.member-profile-action image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.member-profile-action text {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: #fff9ed;
font-size: 24rpx;
font-weight: 700;
}
.member-error {
position: absolute;
top: 31%;
right: 12%;
left: 12%;
text-align: center;
}
.member-error > text {
display: block;
}
.member-error > text:first-child {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 35rpx;
font-weight: 700;
}
.member-error > text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
line-height: 1.65;
}
@media (min-width: 400px) {
.member-panel {
width: calc(100% - 48rpx);
}
}
</style>