Files
jiapuapp/pages/tree/t03-member-profile.vue
T
2026-07-15 08:31:33 +08:00

87 lines
6.3 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' }">
<image class="member-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
<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/genealogy/opaque/g03-create-flow-panel.png" mode="scaleToFill" />
<view v-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/genealogy/opaque/g06-search-input-wide.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/opaque/a01-primary-button.png" mode="scaleToFill" /><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/opaque/a01-primary-button.png" mode="scaleToFill" /><text>返回世系树</text></view>
</view>
</view>
</view>
</template>
<script setup>
import { computed, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
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 === '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__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
.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: 20rpx; }
.member-section-title { display: block; margin: 20rpx 0 4rpx; color: $brand-red; font-size: 22rpx; 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: 20rpx; }
.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: 20rpx; }
.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: 21rpx; line-height: 1.65; }
@media (min-width: 400px) { .member-panel { width: calc(100% - 48rpx); } }
</style>