Review changes batch 3 of 6

This commit is contained in:
2026-07-20 06:52:23 +08:00
parent c848653758
commit 3e3251a4fc
9 changed files with 1644 additions and 171 deletions
File diff suppressed because it is too large Load Diff
+436 -3
View File
@@ -1,4 +1,437 @@
<!-- 页面编号M-01用途个人中心首页提醒与服务导航 -->
<template><view class="profile-page" :class="{'profile-state--ready':profileState==='ready','profile-state--error':profileState==='error'}"><ModulePageBackground module="profile"/><view class="profile-page__header"><PageHeader title="我的" action="资料" @action="toProfile"/></view><view class="profile-content"><view v-if="profileState==='ready'" class="profile-panel"><image class="profile-panel__skin" src="/static/assets/modules/genealogy/opaque/g03-create-flow-panel.png" mode="scaleToFill"/><view class="profile-panel__body"><view class="profile-heading"><image src="/static/assets/modules/genealogy/transparent/current-seal-frame.png" mode="scaleToFill"/><view><text>汤文清</text><text>139****6421 · 家谱成员</text></view></view><view class="profile-todo" @click="toNotifications"><image src="/static/assets/modules/genealogy/opaque/application-status-card.png" mode="scaleToFill"/><view><text>待你处理</text><text>2 条家谱提醒与审核通知</text></view></view><view v-for="item in menuItems" :key="item.label" class="profile-menu" @click="openItem(item)"><image src="/static/assets/modules/genealogy/opaque/g06-search-input-wide.png" mode="scaleToFill"/><view><text>{{item.label}}</text><text>{{item.note}}</text></view><text>查看</text></view></view></view><view v-else class="profile-error"><image src="/static/assets/modules/genealogy/opaque/application-status-card.png" mode="scaleToFill"/><view><text>个人资料暂不可用</text><text>请稍后重新进入,账号和家谱资料不会受到影响。</text></view></view></view><AppTabbar active="profile"/></view></template>
<script setup>import{ref}from'vue';import{onLoad}from'@dcloudio/uni-app';import ModulePageBackground from'@/components/ModulePageBackground.vue';import PageHeader from'@/components/PageHeader.vue';import AppTabbar from'@/components/AppTabbar.vue';const profileState=ref('ready');const menuItems=[{label:'账号与安全',note:'密码、手机与设备',url:'/pages/profile/m03-security-settings'},{label:'帮助与反馈',note:'使用说明与问题反馈',url:'/pages/profile/m06-help-center'},{label:'关于家谱',note:'协议、隐私与版本',url:'/pages/profile/m10-about-settings'}];onLoad(query=>{profileState.value=query.state==='error'?'error':'ready'});const toProfile=()=>uni.navigateTo({url:'/pages/profile/m02-edit-profile'});const toNotifications=()=>uni.navigateTo({url:'/pages/notification/n01-message-center'});const openItem=item=>uni.navigateTo({url:item.url})</script>
<style scoped lang="scss">.profile-page{position:relative;min-height:100vh;overflow:hidden;background:$paper}.profile-page__header,.profile-content{position:relative;z-index:2}.profile-content{padding:18rpx 24rpx 190rpx}.profile-panel{position:relative;width:100%;height:min(650px,calc((100vw - 24px)*1.5))}.profile-panel__skin{position:absolute;inset:0;width:100%;height:100%}.profile-panel__body{position:absolute;inset:7% 8%}.profile-heading{display:flex;align-items:center;gap:18rpx}.profile-heading>image{width:76rpx;height:98rpx}.profile-heading text{display:block}.profile-heading text:first-child{color:$ink;font-family:STKaiti,KaiTi,serif;font-size:35rpx;font-weight:700}.profile-heading text:last-child{margin-top:7rpx;color:$ink-muted;font-size:19rpx}.profile-todo{position:relative;height:124rpx;margin-top:18rpx}.profile-todo>image,.profile-menu>image,.profile-error>image{position:absolute;inset:0;width:100%;height:100%}.profile-todo>view{position:absolute;inset:22% 9%;z-index:1}.profile-todo text{display:block}.profile-todo text:first-child{color:$brand-red;font-size:22rpx;font-weight:700}.profile-todo text:last-child{margin-top:7rpx;color:$ink-muted;font-size:19rpx}.profile-menu{position:relative;height:76rpx;margin-top:11rpx}.profile-menu>view{position:absolute;top:14rpx;left:22rpx;z-index:1}.profile-menu>view text{display:block}.profile-menu>view text:first-child{color:$ink;font-size:21rpx;font-weight:700}.profile-menu>view text:last-child{margin-top:3rpx;color:$ink-muted;font-size:17rpx}.profile-menu>text{position:absolute;top:29rpx;right:22rpx;z-index:1;color:$brand-red;font-size:18rpx}.profile-error{position:relative;height:230rpx;margin-top:70rpx}.profile-error>view{position:absolute;inset:27% 12%;z-index:1;text-align:center}.profile-error text{display:block}.profile-error text:first-child{color:$ink;font-family:STKaiti,KaiTi,serif;font-size:30rpx;font-weight:700}.profile-error text:last-child{margin-top:13rpx;color:$ink-muted;font-size:20rpx}</style>
<template>
<view
class="profile-page"
:class="{
'profile-state--ready': profileState === 'ready',
'profile-state--error': profileState === 'error',
}"
>
<ModulePageBackground module="profile" />
<view class="profile-page__header">
<PageHeader
title="我的"
:action="profileState === 'ready' ? '资料' : ''"
@action="toProfile"
/>
</view>
<view class="profile-content">
<template v-if="profileState === 'ready'">
<view class="profile-hero">
<image
class="profile-hero__frame"
src="/static/assets/modules/profile/transparent/m01-profile-summary-card.png"
mode="scaleToFill"
/>
<image
class="profile-hero__hall"
src="/static/assets/foundation/transparent/root-header-hall.png"
mode="aspectFit"
/>
<image
class="profile-hero__cloud"
src="/static/assets/foundation/transparent/auth-title-cloud.png"
mode="aspectFit"
/>
<view class="profile-hero__label"
><text></text><text></text><text></text><text></text></view
>
<view class="profile-identity">
<image
class="profile-identity__seal"
src="/static/assets/foundation/transparent/brand-seal.png"
mode="aspectFit"
/>
<view class="profile-identity__copy">
<text class="profile-identity__name">汤文清</text>
<text class="profile-identity__role">汤氏家谱 · 家谱成员</text>
<text class="profile-identity__phone">139****6421</text>
</view>
</view>
</view>
<view
class="profile-scroll-notice"
role="button"
aria-label="查看待处理消息"
@click="toNotifications"
>
<image
class="profile-scroll-notice__skin"
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
mode="scaleToFill"
/>
<view class="profile-scroll-notice__copy">
<text>待你处理</text>
<text>2 条家谱提醒与审核通知</text>
</view>
</view>
<view class="profile-services">
<view class="profile-section-heading">
<image
src="/static/assets/foundation/transparent/auth-divider-knot.png"
mode="aspectFit"
/>
<text>服务与设置</text>
<image
src="/static/assets/foundation/transparent/auth-divider-knot.png"
mode="aspectFit"
/>
</view>
<view class="profile-menu-list">
<view
v-for="item in menuItems"
:key="item.label"
class="profile-menu"
role="button"
:aria-label="`查看${item.label}`"
@click="openItem(item)"
>
<image
class="profile-menu__icon"
:src="item.icon"
mode="aspectFit"
/>
<view class="profile-menu__copy">
<text class="profile-menu__label">{{ item.label }}</text>
<text class="profile-menu__note">{{ item.note }}</text>
</view>
<image
class="profile-menu__chevron"
src="/static/assets/foundation/transparent/chevron-right.png"
mode="aspectFit"
/>
</view>
</view>
</view>
</template>
<view v-else class="profile-error">
<image
class="profile-error__skin"
src="/static/assets/modules/profile/transparent/m01-profile-summary-card.png"
mode="scaleToFill"
/>
<view class="profile-error__copy">
<text class="profile-error__title">个人资料暂不可用</text>
<text class="profile-error__description"
>请稍后重新进入账号和家谱资料不会受到影响</text
>
</view>
<AppButton
block
type="secondary"
label="重新查看"
@click="restoreProfile"
/>
</view>
</view>
<AppTabbar active="profile" />
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import AppButton from "@/components/AppButton.vue";
import AppTabbar from "@/components/AppTabbar.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
const profileState = ref("ready");
const menuItems = [
{
label: "账号与安全",
note: "密码、手机与设备",
icon: "/static/assets/modules/auth/transparent/a01-icon-lock-v1.png",
url: "/pages/profile/m03-security-settings",
},
{
label: "帮助与反馈",
note: "使用说明与问题反馈",
icon: "/static/assets/foundation/transparent/notice.png",
url: "/pages/profile/m06-help-center",
},
{
label: "关于家谱",
note: "协议、隐私与版本",
icon: "/static/assets/foundation/transparent/brand-seal.png",
url: "/pages/profile/m10-about-settings",
},
];
onLoad((query) => {
profileState.value = query.state === "error" ? "error" : "ready";
});
const restoreProfile = () => {
profileState.value = "ready";
};
const toProfile = () =>
uni.navigateTo({ url: "/pages/profile/m02-edit-profile" });
const toNotifications = () =>
uni.navigateTo({ url: "/pages/notification/n01-message-center" });
const openItem = (item) => uni.navigateTo({ url: item.url });
</script>
<style scoped lang="scss">
.profile-page {
position: relative;
min-height: 100vh;
overflow-x: hidden;
background: $paper;
}
.profile-page__header,
.profile-content {
position: relative;
z-index: 2;
}
.profile-content {
padding: 26rpx 30rpx 190rpx;
}
.profile-hero {
position: relative;
width: 100%;
min-height: 252rpx;
overflow: hidden;
}
.profile-hero__frame {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.profile-hero__hall {
position: absolute;
right: -18rpx;
bottom: -30rpx;
width: 330rpx;
height: 122rpx;
opacity: 0.12;
}
.profile-hero__cloud {
position: absolute;
top: 22rpx;
right: 30rpx;
width: 96rpx;
height: 52rpx;
opacity: 0.32;
}
.profile-hero__label {
position: absolute;
top: 50%;
left: 40rpx;
z-index: 2;
display: flex;
width: 42rpx;
min-height: 152rpx;
box-sizing: border-box;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2rpx solid #c9964c;
border-radius: 4rpx;
background: linear-gradient(180deg, #9f241f, #bd3427);
box-shadow: inset 0 0 0 3rpx rgba(255, 222, 147, 0.24);
color: #ffe6a9;
font-family: STKaiti, KaiTi, serif;
font-size: 21rpx;
line-height: 1.12;
transform: translateY(-50%);
}
.profile-identity {
position: relative;
z-index: 1;
display: flex;
min-height: 252rpx;
box-sizing: border-box;
align-items: center;
gap: 24rpx;
padding: 34rpx 52rpx 32rpx 112rpx;
}
.profile-identity__seal {
width: 92rpx;
height: 106rpx;
flex: 0 0 auto;
}
.profile-identity__name,
.profile-identity__role,
.profile-identity__phone {
display: block;
}
.profile-identity__name {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 38rpx;
font-weight: 700;
letter-spacing: 3rpx;
}
.profile-identity__role {
margin-top: 10rpx;
color: #6f5942;
font-size: 23rpx;
}
.profile-identity__phone {
margin-top: 7rpx;
color: $ink-muted;
font-size: 21rpx;
letter-spacing: 2rpx;
}
.profile-scroll-notice {
position: relative;
width: 88%;
min-height: 112rpx;
margin: 22rpx auto 0;
}
.profile-scroll-notice__skin {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.profile-scroll-notice__copy {
position: relative;
z-index: 1;
display: flex;
min-height: 112rpx;
box-sizing: border-box;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 13rpx 70rpx;
color: #fff4d3;
text-align: center;
}
.profile-scroll-notice__copy text:first-child {
font-family: STKaiti, KaiTi, serif;
font-size: 26rpx;
font-weight: 700;
letter-spacing: 3rpx;
}
.profile-scroll-notice__copy text:last-child {
margin-top: 4rpx;
color: #ffe4a8;
font-size: 18rpx;
}
.profile-services {
margin-top: 26rpx;
padding: 0 12rpx;
}
.profile-section-heading {
display: flex;
align-items: center;
justify-content: center;
gap: 20rpx;
padding-bottom: 12rpx;
}
.profile-section-heading image {
width: 88rpx;
height: 28rpx;
opacity: 0.78;
}
.profile-section-heading image:last-child {
transform: scaleX(-1);
}
.profile-section-heading text {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-weight: 700;
letter-spacing: 4rpx;
}
.profile-menu-list {
border-top: 1px solid rgba(181, 137, 63, 0.55);
}
.profile-menu {
display: flex;
min-height: 116rpx;
align-items: center;
padding: 0 8rpx;
border-bottom: 1px solid rgba(181, 137, 63, 0.4);
}
.profile-menu__icon {
width: 52rpx;
height: 52rpx;
margin-right: 22rpx;
flex: 0 0 auto;
}
.profile-menu__copy {
min-width: 0;
flex: 1;
}
.profile-menu__label,
.profile-menu__note {
display: block;
}
.profile-menu__label {
color: $ink;
font-size: 25rpx;
font-weight: 700;
}
.profile-menu__note {
margin-top: 5rpx;
color: $ink-muted;
font-size: 21rpx;
}
.profile-menu__chevron {
width: 30rpx;
height: 30rpx;
margin-left: 18rpx;
opacity: 0.75;
}
.profile-error {
position: relative;
margin-top: 38rpx;
text-align: center;
}
.profile-error__skin {
position: absolute;
top: 0;
right: 0;
left: 0;
width: 100%;
height: 220rpx;
min-height: 118px;
}
.profile-error__copy {
position: relative;
z-index: 1;
display: flex;
height: 220rpx;
min-height: 118px;
box-sizing: border-box;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 54rpx;
}
.profile-error__title,
.profile-error__description {
display: block;
}
.profile-error__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-weight: 700;
}
.profile-error__description {
margin-top: 13rpx;
color: $ink-muted;
font-size: 23rpx;
line-height: 1.5;
}
.profile-error .app-button {
margin: 20rpx auto 0;
}
@media (min-width: 400px) {
.profile-content {
padding-right: 38rpx;
padding-left: 38rpx;
}
}
/* M01 medium-ornate profile folio styles remain page-scoped and extensible. */
</style>