445 lines
11 KiB
Vue
445 lines
11 KiB
Vue
<!-- 页面编号: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="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;
|
||
display: grid;
|
||
grid-template-columns: 42rpx minmax(0, 1fr);
|
||
width: 100%;
|
||
min-height: 252rpx;
|
||
align-items: center;
|
||
gap: 30rpx;
|
||
padding: 34rpx 52rpx 32rpx 40rpx;
|
||
box-sizing: border-box;
|
||
overflow: hidden;
|
||
}
|
||
.profile-hero__frame {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
pointer-events: none;
|
||
}
|
||
.profile-hero__hall {
|
||
position: absolute;
|
||
right: -18rpx;
|
||
bottom: -30rpx;
|
||
width: 330rpx;
|
||
height: 122rpx;
|
||
opacity: 0.12;
|
||
pointer-events: none;
|
||
}
|
||
.profile-hero__cloud {
|
||
position: absolute;
|
||
top: 22rpx;
|
||
right: 30rpx;
|
||
width: 96rpx;
|
||
height: 52rpx;
|
||
opacity: 0.32;
|
||
pointer-events: none;
|
||
}
|
||
.profile-hero__label {
|
||
position: relative;
|
||
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;
|
||
}
|
||
.profile-identity {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: flex;
|
||
min-height: 252rpx;
|
||
box-sizing: border-box;
|
||
align-items: center;
|
||
gap: 24rpx;
|
||
}
|
||
.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%;
|
||
pointer-events: none;
|
||
}
|
||
.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;
|
||
pointer-events: none;
|
||
}
|
||
.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>
|