feat: 完成70%全局样式与可读性优化

This commit is contained in:
rain
2026-07-31 11:27:15 +08:00
parent 96524e4d6c
commit 555aa00043
116 changed files with 1928 additions and 1169 deletions
+31
View File
@@ -0,0 +1,31 @@
<template>
<image class="app-avatar" :src="avatarSource" mode="aspectFill" />
</template>
<script setup>
import { computed } from "vue";
import { getDefaultAvatar } from "@/utils/avatar.js";
const props = defineProps({
sex: {
type: [String, Number],
default: "",
},
src: {
type: String,
default: "",
},
});
const avatarSource = computed(
() => props.src.trim() || getDefaultAvatar(props.sex),
);
</script>
<style scoped>
.app-avatar {
display: block;
width: 100%;
height: 100%;
}
</style>
+9 -7
View File
@@ -15,7 +15,7 @@
@click="handleClick"
>
<image class="app-button__skin" :src="skin" mode="aspectFit" />
<text class="app-button__label"
<text class="app-button__label app-single-line"
><slot>{{ label }}</slot></text
>
</button>
@@ -45,7 +45,7 @@ const handleClick = (event) => {
</script>
<style scoped lang="scss">
@use "../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../styles/adaptive-frame-profiles.scss";
.app-button {
display: inline-grid;
@@ -70,17 +70,17 @@ const handleClick = (event) => {
.app-button--compact {
}
.app-button--compact.app-button--primary {
@include adaptive.adaptive-scroll-button(primary);
@include adaptive-scroll-button(primary);
}
.app-button--compact.app-button--secondary {
@include adaptive.adaptive-scroll-button(secondary);
@include adaptive-scroll-button(secondary);
}
.app-button--compact .app-button__skin {
display: none;
}
.app-button--compact .app-button__label {
padding: 0;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
letter-spacing: 0;
white-space: nowrap;
}
@@ -95,11 +95,13 @@ const handleClick = (event) => {
}
.app-button__label {
z-index: 1;
padding: 0 38rpx;
padding: 12rpx 38rpx;
box-sizing: border-box;
color: #fffaf0;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
font-weight: 700;
letter-spacing: 3rpx;
line-height: 1.35;
text-align: center;
}
.app-button--secondary .app-button__label {
+9 -5
View File
@@ -116,7 +116,7 @@ const cancel = () => {
</script>
<style scoped lang="scss">
@use "../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../styles/adaptive-frame-profiles.scss";
.app-dialog-layer {
position: fixed;
@@ -136,7 +136,7 @@ const cancel = () => {
max-height: calc(var(--app-viewport-height, 100vh) - 80rpx - env(safe-area-inset-top) - env(safe-area-inset-bottom));
flex-direction: column;
overflow: hidden;
@include adaptive.adaptive-auth-dialog;
@include adaptive-auth-dialog;
}
.app-dialog__content {
z-index: 1;
@@ -163,13 +163,13 @@ const cancel = () => {
}
.app-dialog__eyebrow {
color: #9f170f;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
font-weight: 700;
letter-spacing: 4rpx;
}
.app-dialog__title {
color: #8f160f;
font-size: 42rpx;
font-size: clamp(22px, 42rpx, 28px);
font-weight: 700;
letter-spacing: 4rpx;
}
@@ -179,7 +179,7 @@ const cancel = () => {
.app-dialog__message {
margin-top: 22rpx;
color: #513a28;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
line-height: 1.65;
}
.app-dialog__actions {
@@ -189,6 +189,10 @@ const cancel = () => {
gap: 16rpx;
margin-top: 26rpx;
}
.app-dialog__actions :deep(.app-button__label) {
padding-right: 18rpx;
padding-left: 18rpx;
}
.app-dialog__actions--single {
display: flex;
justify-content: center;
+4 -4
View File
@@ -82,11 +82,11 @@ defineProps({
}
.app-loading--page .app-loading__copy {
margin-top: 22rpx;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
}
.app-loading--page .app-loading__description {
margin-top: 14rpx;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.app-loading--section {
@@ -103,11 +103,11 @@ defineProps({
}
.app-loading--section .app-loading__copy {
margin-top: 14rpx;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.app-loading--section .app-loading__description {
margin-top: 10rpx;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
@keyframes app-loading-seal-breathe {
0%,
+5 -2
View File
@@ -17,7 +17,7 @@
mode="aspectFit"
aria-hidden="true"
/>
<text :class="['tab-label', { active: active === item.key }]">{{
<text :class="['tab-label', 'app-single-line', { active: active === item.key }]">{{
item.label
}}</text>
</button>
@@ -77,6 +77,7 @@ const switchRoot = (item) => {
.tab-item {
display: flex;
min-width: 0;
min-height: 88rpx;
flex: 1;
flex-direction: column;
@@ -104,10 +105,12 @@ const switchRoot = (item) => {
}
.tab-label {
max-width: 100%;
color: $ink-muted;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
letter-spacing: 2rpx;
line-height: 1.2;
text-align: center;
}
.tab-label.active {
+3 -3
View File
@@ -18,7 +18,7 @@ defineProps({
</script>
<style scoped lang="scss">
@use "../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../styles/adaptive-frame-profiles.scss";
.app-toast {
position: fixed;
@@ -31,7 +31,7 @@ defineProps({
min-height: 82rpx;
align-items: center;
justify-content: center;
@include adaptive.adaptive-feedback-toast;
@include adaptive-feedback-toast;
transform: translateX(-50%);
pointer-events: none;
}
@@ -39,7 +39,7 @@ defineProps({
z-index: 1;
padding: 14rpx 30rpx;
color: #5c4330;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 500;
line-height: 1.45;
text-align: center;
+30 -10
View File
@@ -6,16 +6,17 @@
src="/static/assets/modules/auth/opaque/a01-vnext-header-v1.png"
mode="widthFix"
/>
<image
class="auth-shell__seal"
src="/static/assets/foundation/transparent/brand-seal.png"
mode="aspectFit"
/>
<view class="auth-shell__brand-lockup">
<image
class="auth-shell__seal"
src="/static/assets/foundation/transparent/brand-seal.png"
mode="aspectFit"
/>
<text class="auth-shell__project-name">代代相传</text>
</view>
</view>
<view class="auth-shell__paper">
<slot />
</view>
<view class="auth-shell__paper"><slot /></view>
<slot name="overlay" />
</view>
@@ -51,13 +52,21 @@
pointer-events: none;
}
.auth-shell__seal {
.auth-shell__brand-lockup {
position: absolute;
top: calc(var(--app-safe-top) + clamp(46px, 11.5vw, 58px));
left: 50%;
display: flex;
align-items: center;
gap: 12rpx;
transform: translateX(-50%);
white-space: nowrap;
}
.auth-shell__seal {
position: static;
width: clamp(56px, 17vw, 78px);
height: clamp(67px, 20.4vw, 94px);
transform: translateX(-50%);
pointer-events: none;
}
@@ -75,4 +84,15 @@
background-size: 100% auto, 100% auto;
background-repeat: no-repeat, repeat-y;
}
.auth-shell__project-name {
color: #f8dfa6;
font-family: "STKaiti", "KaiTi", serif;
font-size: clamp(14px, 24rpx, 17px);
font-weight: 700;
letter-spacing: 4rpx;
line-height: 1;
white-space: nowrap;
}
</style>
+84 -85
View File
@@ -27,36 +27,34 @@
<view class="card-main">
<view class="card-title-row">
<text class="card-name">{{ genealogy.name }}</text>
<view class="card-side">
<text class="card-role">{{ role }}</text>
<image
class="card-chevron"
src="/static/assets/foundation/transparent/chevron-right.png"
mode="aspectFit"
/>
</view>
<image
class="card-chevron"
src="/static/assets/foundation/transparent/chevron-right.png"
mode="aspectFit"
/>
</view>
<view class="card-detail-row">
<view class="card-updated">
<text>更新于 {{ genealogy.updatedAt }}</text>
<view class="card-meta-item card-meta-item--location">
<image
class="card-meta-icon"
src="/static/assets/foundation/transparent/meta-location.png"
mode="aspectFit"
/>
<text class="card-meta">{{ genealogy.location }}</text>
</view>
<view class="card-metas">
<view class="card-meta-item">
<image
class="card-meta-icon"
src="/static/assets/foundation/transparent/meta-location.png"
mode="aspectFit"
/>
<text class="card-meta">{{ genealogy.location }}</text>
</view>
<view class="card-meta-item">
<image
class="card-meta-icon"
src="/static/assets/foundation/transparent/meta-member.png"
mode="aspectFit"
/>
<text class="card-meta">{{ genealogy.memberCount }} 位成员</text>
</view>
<view class="card-meta-item card-meta-item--members">
<image
class="card-meta-icon"
src="/static/assets/foundation/transparent/meta-member.png"
mode="aspectFit"
/>
<text class="card-meta">{{ genealogy.memberCount }} 位成员</text>
</view>
<view class="card-trailing">
<text class="card-role app-single-line">{{ role }}</text>
<text v-if="genealogy.updatedAt" class="card-updated app-single-line"
>更新于 {{ genealogy.updatedAt }}</text
>
</view>
</view>
</view>
@@ -82,13 +80,13 @@ const accessibleLabel = computed(
<style scoped lang="scss">
.genealogy-card {
--card-padding-x: 24rpx;
--card-padding-y: 18rpx;
--card-padding-y: 20rpx;
display: grid;
grid-template-columns: 72rpx minmax(0, 1fr);
min-height: 178rpx;
grid-template-columns: 68rpx minmax(0, 1fr);
min-height: 204rpx;
align-items: center;
column-gap: 22rpx;
padding: 18rpx 24rpx;
column-gap: 20rpx;
padding: 20rpx 24rpx;
box-sizing: border-box;
background: transparent;
}
@@ -114,8 +112,8 @@ const accessibleLabel = computed(
grid-column: 1;
grid-row: 1;
z-index: 2;
width: 72rpx;
height: 112rpx;
width: 68rpx;
height: 106rpx;
place-items: center;
color: #fff5df;
}
@@ -132,14 +130,14 @@ const accessibleLabel = computed(
.surname-seal-copy {
z-index: 1;
display: flex;
height: 82rpx;
height: 78rpx;
align-items: center;
justify-content: center;
}
.seal-title {
color: #fff5df;
font-family: "STKaiti", "KaiTi", serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
letter-spacing: 2rpx;
line-height: 1;
@@ -165,45 +163,47 @@ const accessibleLabel = computed(
.card-title-row {
display: flex;
min-width: 0;
align-items: flex-start;
align-items: center;
justify-content: space-between;
gap: 12rpx;
}
.card-name {
min-width: 0;
flex: 1;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 37rpx;
font-size: clamp(18px, 34rpx, 23px);
font-weight: 700;
line-height: 1.25;
overflow: hidden;
overflow-wrap: anywhere;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.card-detail-row {
display: flex;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
min-width: 0;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin-top: 8rpx;
}
.card-metas {
display: flex;
min-width: 0;
width: 100%;
flex-wrap: wrap;
align-items: center;
margin-top: 2rpx;
gap: 4rpx 18rpx;
column-gap: 16rpx;
row-gap: 4rpx;
margin-top: 10rpx;
}
.card-meta-item {
display: flex;
min-width: 0;
align-items: center;
margin-right: 0;
}
.card-meta-item--location {
grid-column: 1 / -1;
}
.card-meta-item--members {
grid-column: 1;
}
.card-meta-icon {
width: 46rpx;
height: 46rpx;
width: 38rpx;
height: 38rpx;
flex: 0 0 auto;
margin-right: 6rpx;
opacity: 1;
@@ -212,73 +212,72 @@ const accessibleLabel = computed(
.card-meta {
min-width: 0;
color: #62584c;
font-size: 26rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 500;
overflow-wrap: anywhere;
}
.card-trailing {
grid-column: 2;
display: flex;
min-width: 0;
align-items: flex-end;
justify-content: center;
row-gap: 4rpx;
flex-direction: column;
}
.card-updated {
display: flex;
width: 100%;
flex: 0 0 auto;
align-items: center;
justify-content: flex-end;
margin-top: 0;
margin-left: 0;
color: #62584c;
font-size: 24rpx;
font-size: clamp(14px, 22rpx, 17px);
font-weight: 500;
line-height: 1.35;
white-space: nowrap;
overflow-wrap: anywhere;
}
.card-side {
z-index: 1;
display: flex;
min-width: 0;
flex: 0 1 auto;
flex-direction: row;
align-items: center;
justify-content: flex-end;
margin-left: 20rpx;
}
.card-role {
min-width: 0;
color: #62584c;
font-size: 26rpx;
font-weight: 500;
overflow-wrap: anywhere;
padding: 3rpx 10rpx 4rpx;
border: 1rpx solid rgba(181, 138, 75, 0.56);
border-radius: 999rpx;
color: #7f4f16;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 600;
line-height: 1.25;
white-space: nowrap;
}
.card-chevron {
width: 34rpx;
height: 34rpx;
margin-left: 14rpx;
width: 30rpx;
height: 30rpx;
margin-left: 8rpx;
}
@media screen and (max-width: 340px) {
.genealogy-card {
--card-padding-x: 18rpx;
grid-template-columns: 66rpx minmax(0, 1fr);
grid-template-columns: 62rpx minmax(0, 1fr);
column-gap: 16rpx;
min-height: 148rpx;
min-height: 176rpx;
padding-right: 18rpx;
padding-left: 18rpx;
}
.surname-seal {
width: 66rpx;
height: 100rpx;
width: 62rpx;
height: 96rpx;
}
.card-name {
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
}
.card-meta {
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.card-updated {
display: none;
}
.card-side {
margin-left: 12rpx;
}
.card-chevron {
width: 28rpx;
height: 28rpx;
+1
View File
@@ -27,4 +27,5 @@
width: 100%;
opacity: 0.28;
}
</style>
+60 -6
View File
@@ -46,7 +46,20 @@
</button>
</view>
<text class="header-title">{{ title }}</text>
<view
class="header-project-lockup"
:class="{ 'header-project-lockup--root': root }"
>
<image
v-if="!root"
class="header-project-lockup__logo"
src="/static/assets/foundation/transparent/brand-seal.png"
mode="aspectFit"
aria-hidden="true"
/>
<text class="header-project-name">代代相传</text>
</view>
<text class="header-title app-single-line">{{ title }}</text>
<view class="header-side header-side--right">
<button
@@ -65,10 +78,10 @@
</button>
<button
v-else-if="root && action"
class="header-action header-action--root"
class="header-action header-action--root app-single-line"
@click="$emit('action')"
>{{ action }}</button>
<button v-else-if="action" class="header-action" @click="$emit('action')">{{
<button v-else-if="action" class="header-action app-single-line" @click="$emit('action')">{{
action
}}</button>
<view
@@ -168,6 +181,7 @@ const handleBack = () => {
.header-side {
display: flex;
flex: 0 0 120rpx;
width: 120rpx;
min-height: 88rpx;
align-items: center;
@@ -179,6 +193,10 @@ const handleBack = () => {
.header-side--right {
justify-content: flex-end;
}
.page-header:not(.page-header--root) .header-side--right {
flex-basis: 152rpx;
width: 152rpx;
}
.header-icon-button {
display: grid;
@@ -246,9 +264,12 @@ const handleBack = () => {
border: 0;
background: transparent;
color: #ffe3a7;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
line-height: normal;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.header-action-placeholder {
width: 100%;
@@ -280,12 +301,45 @@ const handleBack = () => {
.header-back--pressed {
opacity: 0.62;
}
.header-project-lockup {
position: absolute;
top: calc(var(--status-bar-height, 0px) + 52rpx);
left: 112rpx;
z-index: 3;
display: flex;
align-items: center;
gap: 7rpx;
transform: translateY(-50%);
pointer-events: none;
}
.header-project-lockup--root {
top: calc(var(--status-bar-height, 0px) + 62rpx);
left: 116rpx;
}
.header-project-lockup__logo {
width: 34rpx;
height: 34rpx;
flex: 0 0 auto;
}
.header-project-name {
color: #ffe3a7;
font-family: "STKaiti", "KaiTi", serif;
font-size: clamp(11px, 19rpx, 14px);
font-weight: 700;
letter-spacing: 3rpx;
line-height: 1;
white-space: nowrap;
}
.header-title {
min-width: 0;
flex: 1;
overflow: hidden;
color: #fff9ed;
font-family: serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
letter-spacing: 4rpx;
text-align: center;
@@ -296,7 +350,7 @@ const handleBack = () => {
.page-header--root .header-title {
color: #ffe3a7;
font-family: "STKaiti", "KaiTi", serif;
font-size: 48rpx;
font-size: clamp(24px, 48rpx, 30px);
letter-spacing: 5rpx;
transform: translateY(2rpx);
}
@@ -0,0 +1,33 @@
# 家谱 App 迭代进度记录(完成 70%)
日期:2026-07-31
当前分支:`main`
## 本轮已完成
- 完成全项目字体可读性与长文本换行治理,优先保证手机端、长辈用户的阅读体验。
- 调整公共页头:项目名称“代代相传”以“Logo + 名称”组合呈现,页面功能标题保持居中;认证页与“我的”页同步使用该品牌组合。
- 接入默认头像:男性使用男童国风头像,女性使用唐装女性头像;未选择性别时默认使用男性头像。
- 完善成员资料展示,隐藏不应面向普通用户展示的业务用户与内部人物编号信息。
- 修复“我的”、家谱、家族、人物录、通知等模块中已发现的文字截断、状态提示与空/错误态表达问题。
- 保留 T02 世系谱的参考项目结构,仅做兼容性和可读性处理,未改变其核心展示逻辑。
- 新增并通过默认头像、个人资料、消息中心等重点契约检查。
## 当前状态
- 整体功能与视觉治理进度:约 70%。
- 页面入口已完成全局品牌标识覆盖;业务页面仍可继续在真机/模拟器逐页复核细节。
- 相册图片是否能展示取决于接口是否返回可访问的图片地址;当前不伪造图片链接。
## 在另一台电脑运行
1. 拉取 `main` 分支的最新代码。
2. 使用 HBuilderX 导入项目根目录 `jiapuapp`
3. 等待 HBuilderX 完成编译后,选择“运行到 Android App 基座”并连接 MuMu 或真机。
4. 项目所需头像和页面静态资源已随代码提交,不需要单独拷贝资源文件。
## 后续建议
- 在目标设备尺寸上复核页头品牌组合、表单按钮与底部导航的间距。
- 继续覆盖未登录、空数据、接口异常和超长文本等状态。
- 按接口返回能力补充相册图片的真实访问地址或签名 URL。
+37 -21
View File
@@ -188,9 +188,10 @@
</button>
</view>
<view
class="agreement-area"
:class="{ 'agreement-area--error': agreementError }"
<view
:key="agreementShakeVersion"
class="agreement-area"
:class="{ 'agreement-area--error': agreementError }"
>
<view class="agreement-row">
<button
@@ -289,6 +290,7 @@ const password = ref("");
const verificationCode = ref("");
const agreed = ref(false);
const agreementError = ref(false);
const agreementShakeVersion = ref(0);
const tacVisible = ref(false);
const tacContext = ref(null);
const sendingCode = ref(false);
@@ -394,9 +396,10 @@ const validatePhone = () => {
};
const requireAgreement = () => {
if (agreed.value) return true;
agreementError.value = true;
return false;
if (agreed.value) return true;
agreementError.value = true;
agreementShakeVersion.value += 1;
return false;
};
const closeTac = () => {
@@ -696,7 +699,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
.login-title {
color: #9f170f;
font-size: 58rpx;
font-size: clamp(29px, 58rpx, 36px);
font-weight: 700;
letter-spacing: 5rpx;
line-height: 1;
@@ -722,7 +725,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
justify-content: center;
min-height: 88rpx;
color: #80684f;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
letter-spacing: 2rpx;
}
@@ -764,7 +767,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
left: 0;
content: "*";
color: #b42318;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1;
}
@@ -785,7 +788,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
min-width: 0;
min-height: var(--app-touch-min);
color: #493323;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
}
.input-placeholder {
@@ -816,7 +819,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
padding: 0 8rpx;
background: transparent !important;
color: #a9160d;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
white-space: nowrap;
}
@@ -836,7 +839,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
align-items: center;
min-height: var(--app-touch-min);
color: #a9160d;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.login-submit {
@@ -860,7 +863,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
z-index: 1;
grid-area: 1 / 1;
color: #fffaf1;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
letter-spacing: 5rpx;
}
@@ -870,7 +873,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
justify-content: center;
min-height: var(--app-touch-min);
color: #493323;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.register-link {
@@ -882,16 +885,19 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
}
.agreement-area {
position: relative;
margin-bottom: 48rpx;
color: #58483c;
}
.agreement-row {
display: flex;
align-items: center;
flex-wrap: nowrap;
justify-content: center;
min-height: var(--app-touch-min);
font-size: 24rpx;
line-height: 32rpx;
font-size: clamp(12px, 22rpx, 14px);
line-height: 1.45;
}
.agreement-icon {
@@ -905,17 +911,22 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
flex: 0 0 auto;
align-items: center;
justify-content: center;
width: var(--app-touch-min);
min-width: var(--app-touch-min);
min-height: var(--app-touch-min);
margin-right: 2rpx;
box-sizing: border-box;
margin: 0 -12rpx 0 0;
padding-top: 0;
}
.agreement-copy {
display: flex;
flex: 0 1 auto;
flex: 0 0 auto;
align-items: center;
min-width: 0;
padding-top: 2rpx;
}
.agreement-copy text {
white-space: nowrap;
}
.agreement-link {
@@ -923,13 +934,18 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
align-items: center;
min-height: var(--app-touch-min);
color: #a9160d;
white-space: nowrap;
}
.agreement-error {
position: absolute;
top: calc(100% + 4rpx);
right: 0;
left: 0;
display: block;
color: #b42318;
font-size: 20rpx;
line-height: 30rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: max(1.35em, clamp(17px, 30rpx, 22px));
text-align: center;
}
+31 -16
View File
@@ -141,7 +141,7 @@
:class="{ 'field-block--error': fieldErrors.password }"
>
<view class="input-row">
<label class="input-label" for="a04-password"
<label class="input-label input-label--password" for="a04-password"
><text class="required-mark">*</text>设置密码</label
>
<input
@@ -174,7 +174,7 @@
:class="{ 'field-block--error': fieldErrors.confirmPassword }"
>
<view class="input-row">
<label class="input-label" for="a04-confirm-password"
<label class="input-label input-label--password" for="a04-confirm-password"
><text class="required-mark">*</text>确认密码</label
>
<input
@@ -681,7 +681,7 @@ const submitRegister = async () => {
grid-column: 1;
grid-row: 1;
color: #9f170f;
font-size: 58rpx;
font-size: clamp(29px, 58rpx, 36px);
font-weight: 700;
letter-spacing: 7rpx;
}
@@ -691,7 +691,7 @@ const submitRegister = async () => {
grid-row: 2;
margin-top: 12rpx;
color: #806c58;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
letter-spacing: 2rpx;
}
@@ -721,14 +721,18 @@ const submitRegister = async () => {
.input-label {
flex: 0 0 152rpx;
color: #674b35;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
}
.input-label--password {
flex-basis: 220rpx;
white-space: nowrap;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: #b42318;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1;
transform: translateY(-3rpx);
}
@@ -738,7 +742,7 @@ const submitRegister = async () => {
min-width: 0;
min-height: var(--app-touch-min);
color: #493323;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
}
.get-code {
@@ -751,7 +755,7 @@ const submitRegister = async () => {
border-left: 1rpx solid #d7bd94;
background: transparent !important;
color: #a7160c;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
white-space: nowrap;
}
@@ -767,8 +771,8 @@ const submitRegister = async () => {
.agreement-error {
display: block;
color: #b42318;
font-size: 21rpx;
line-height: 32rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: max(1.35em, clamp(17px, 32rpx, 22px));
}
.field-error {
@@ -796,23 +800,25 @@ const submitRegister = async () => {
z-index: 1;
grid-area: 1 / 1;
color: #fffaf0;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
letter-spacing: 6rpx;
}
.agreement-area {
position: relative;
min-height: 118rpx;
margin-top: 18rpx;
color: #493323;
}
.agreement-row {
display: flex;
align-items: center;
flex-wrap: nowrap;
justify-content: center;
min-height: var(--app-touch-min);
color: #493323;
font-size: 24rpx;
line-height: 30rpx;
font-size: clamp(12px, 22rpx, 14px);
line-height: 1.45;
}
.agreement-icon {
@@ -829,12 +835,20 @@ const submitRegister = async () => {
width: var(--app-touch-min);
min-width: var(--app-touch-min);
min-height: var(--app-touch-min);
margin-right: 2rpx;
box-sizing: border-box;
margin: 0 -12rpx 0 0;
padding-top: 0;
}
.agreement-copy {
display: flex;
flex: 0 0 auto;
align-items: center;
min-width: 0;
padding-top: 2rpx;
}
.agreement-copy text {
white-space: nowrap;
}
.agreement-link {
@@ -842,6 +856,7 @@ const submitRegister = async () => {
align-items: center;
min-height: var(--app-touch-min);
color: #a7160c;
white-space: nowrap;
}
.agreement-error {
text-align: center;
@@ -871,7 +886,7 @@ const submitRegister = async () => {
min-height: 82rpx;
margin-top: auto;
color: #493323;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.login-entry__link {
+16 -12
View File
@@ -153,7 +153,7 @@
:class="{ 'field-block--error': fieldErrors.confirmPassword }"
>
<view class="input-row">
<label class="input-label" for="a05-confirm-password"
<label class="input-label input-label--confirm" for="a05-confirm-password"
><text class="required-mark">*</text>确认新密码</label
>
<input
@@ -582,7 +582,7 @@ const submitReset = async () => {
grid-column: 1;
grid-row: 1;
color: #9f170f;
font-size: 58rpx;
font-size: clamp(29px, 58rpx, 36px);
font-weight: 700;
letter-spacing: 7rpx;
}
@@ -591,7 +591,7 @@ const submitReset = async () => {
grid-row: 2;
margin-top: 12rpx;
color: #806c58;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
letter-spacing: 1rpx;
}
.reset-divider {
@@ -619,13 +619,17 @@ const submitReset = async () => {
.input-label {
flex: 0 0 162rpx;
color: #674b35;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
}
.input-label--confirm {
flex-basis: 220rpx;
white-space: nowrap;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: #b42318;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1;
transform: translateY(-3rpx);
}
@@ -634,7 +638,7 @@ const submitReset = async () => {
min-width: 0;
min-height: var(--app-touch-min);
color: #493323;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
}
.placeholder {
color: #9f968d;
@@ -649,7 +653,7 @@ const submitReset = async () => {
border-left: 1rpx solid #d7bd94;
background: transparent !important;
color: #a7160c;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
white-space: nowrap;
}
.get-code--disabled {
@@ -659,8 +663,8 @@ const submitReset = async () => {
display: block;
padding-top: 4rpx;
color: #b42318;
font-size: 21rpx;
line-height: 28rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: max(1.35em, clamp(16px, 28rpx, 20px));
text-align: right;
}
.field-block--error .input-row {
@@ -683,14 +687,14 @@ const submitReset = async () => {
z-index: 1;
grid-area: 1 / 1;
color: #fffaf0;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
letter-spacing: 6rpx;
}
.reset-tip {
display: block;
margin-top: 22rpx;
color: #806c58;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
text-align: center;
}
.login-entry {
@@ -700,7 +704,7 @@ const submitReset = async () => {
min-height: var(--app-touch-min);
margin-top: auto;
color: #493323;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.login-entry__link {
display: flex;
+16 -16
View File
@@ -234,7 +234,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
grid-column: 1;
grid-row: 1;
color: #9f170f;
font-size: 58rpx;
font-size: clamp(29px, 58rpx, 36px);
font-weight: 700;
letter-spacing: 7rpx;
}
@@ -243,7 +243,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
grid-row: 2;
margin-top: 12rpx;
color: #806c58;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
letter-spacing: 1rpx;
}
.status-divider {
@@ -270,13 +270,13 @@ onBackPress((event) => handleBackPress(event, requestBack));
.status-eyebrow {
margin-top: 10rpx;
color: #a7160c;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
letter-spacing: 3rpx;
}
.status-title {
margin-top: 10rpx;
color: #3f2c1d;
font-size: 40rpx;
font-size: clamp(20px, 40rpx, 26px);
font-weight: 700;
letter-spacing: 3rpx;
}
@@ -285,7 +285,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
width: 100%;
margin-top: 12rpx;
color: #786654;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.status-details {
@@ -304,13 +304,13 @@ onBackPress((event) => handleBackPress(event, requestBack));
.status-detail__label {
flex: 0 0 116rpx;
color: #9f170f;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.status-detail__value {
flex: 1;
color: #5f4a38;
font-size: 23rpx;
line-height: 34rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: max(1.35em, clamp(19px, 34rpx, 24px));
}
.status-primary {
@@ -329,7 +329,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
z-index: 1;
grid-area: 1 / 1;
color: #fffaf0;
font-size: 38rpx;
font-size: clamp(20px, 38rpx, 26px);
letter-spacing: 5rpx;
}
.status-secondary {
@@ -338,7 +338,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
justify-content: center;
min-height: var(--app-touch-min);
color: #a7160c;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.recovery-layer {
@@ -377,21 +377,21 @@ onBackPress((event) => handleBackPress(event, requestBack));
}
.recovery-title {
color: #8f160f;
font-size: 42rpx;
font-size: clamp(22px, 42rpx, 28px);
font-weight: 700;
letter-spacing: 4rpx;
}
.recovery-copy {
margin-top: 20rpx;
color: #513a28;
font-size: 26rpx;
line-height: 40rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: max(1.35em, clamp(20px, 40rpx, 26px));
}
.recovery-note {
margin-top: 12rpx;
color: #8d7965;
font-size: 20rpx;
line-height: 31rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: max(1.35em, clamp(17px, 31rpx, 22px));
}
.recovery-action {
display: grid;
@@ -404,7 +404,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
z-index: 1;
grid-area: 1 / 1;
color: #fffaf0;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
letter-spacing: 4rpx;
}
.tap-fade,
+17 -12
View File
@@ -158,7 +158,7 @@ const handlePrimaryAction = () =>
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.family-page {
display: flex;
min-height: 100vh;
@@ -179,13 +179,13 @@ const handlePrimaryAction = () =>
.feed-heading text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.feed-heading text:last-child {
margin-top: 6rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.feed-shortcuts {
display: grid;
@@ -200,7 +200,7 @@ const handlePrimaryAction = () =>
}
.feed-shortcut text {
color: $ink;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
font-weight: 700;
}
.feed-list {
@@ -208,7 +208,7 @@ const handlePrimaryAction = () =>
}
.feed-card,
.feed-state-card {
@include adaptive.adaptive-family-letter;
@include adaptive-family-letter;
box-sizing: border-box;
margin-top: 16rpx;
padding: 30rpx;
@@ -219,18 +219,23 @@ const handlePrimaryAction = () =>
}
.feed-card__publisher {
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.feed-card__content {
display: -webkit-box;
margin-top: 12rpx;
overflow: hidden;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
line-height: 1.55;
overflow-wrap: anywhere;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
.feed-card__meta {
margin-top: 12rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.feed-state-card {
min-height: 230rpx;
@@ -241,17 +246,17 @@ const handlePrimaryAction = () =>
}
.feed-state-card text:first-child {
color: $ink;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.feed-state-card text:last-child {
margin-top: 13rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.45;
}
.feed-action {
@include adaptive.adaptive-scroll-button(primary);
@include adaptive-scroll-button(primary);
width: 514rpx;
max-width: 100%;
min-height: 76rpx;
@@ -263,7 +268,7 @@ const handlePrimaryAction = () =>
align-items: center;
justify-content: center;
color: #fff9ed;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
</style>
+15 -15
View File
@@ -150,7 +150,7 @@ const resultCopy = computed(
},
error: {
title: "动态未提交",
copy: "当前内容仍保留在页面中,可返回表单继续核对。",
copy: submitError.value || "当前内容仍保留在页面中,可返回表单继续核对。",
action: "返回填写",
},
invalid: {
@@ -248,7 +248,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.publish-page {
display: flex;
min-height: 100vh;
@@ -257,7 +257,7 @@ onUnmounted(() => {
}
.publish-page__header,
.publish-panel {
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
z-index: 1;
}
.publish-panel {
@@ -274,32 +274,32 @@ onUnmounted(() => {
.publish-result > text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.publish-form > text:nth-child(2),
.publish-result > text:nth-child(2) {
margin-top: 12rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.6;
}
.publish-field {
@include adaptive.adaptive-family-field;
@include adaptive-family-field;
margin-top: 20rpx;
padding: 18rpx 22rpx;
}
.publish-field__label {
display: block;
color: $ink;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 700;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1;
transform: translateY(-3rpx);
}
@@ -310,7 +310,7 @@ onUnmounted(() => {
width: 100%;
margin-top: 12rpx;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.publish-field input {
min-height: 64rpx;
@@ -328,11 +328,11 @@ onUnmounted(() => {
}
.publish-field__value--readonly text:first-child {
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.publish-field__value--readonly text:last-child {
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.publish-field--content textarea {
min-height: 200rpx;
@@ -346,7 +346,7 @@ onUnmounted(() => {
display: block;
margin-top: 6rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -357,11 +357,11 @@ onUnmounted(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.publish-placeholder {
@@ -370,7 +370,7 @@ onUnmounted(() => {
.publish-error {
margin-top: 12rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.5;
}
.publish-form > .app-button {
+14 -14
View File
@@ -283,7 +283,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.feed-detail-page {
display: flex;
@@ -305,7 +305,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
.feed-card,
.comment-section,
.feed-state-card {
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
box-sizing: border-box;
}
.feed-card {
@@ -321,27 +321,27 @@ onBackPress((event) => handleBackPress(event, requestBack));
.feed-card__heading text:first-child,
.comment-card__heading text:first-child {
color: $brand-red;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.feed-card__heading text:last-child,
.comment-card__heading text:last-child {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
text-align: right;
}
.feed-card__content {
display: block;
margin-top: 20rpx;
color: $ink;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
line-height: 1.7;
white-space: pre-wrap;
}
.feed-card__meta {
margin-top: 22rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.feed-card .app-button {
margin-top: 18rpx;
@@ -350,7 +350,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
.like-error {
display: block;
margin-top: 10rpx;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.like-note {
color: $ink-muted;
@@ -366,7 +366,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
display: block;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
}
.comment-list {
@@ -380,7 +380,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
display: block;
margin-top: 10rpx;
color: $ink;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
line-height: 1.55;
white-space: pre-wrap;
}
@@ -388,7 +388,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
display: block;
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.5;
}
.comment-editor {
@@ -405,7 +405,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
border: 1rpx solid rgba(128, 89, 49, 0.3);
border-radius: 12rpx;
color: $ink;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
line-height: 1.55;
}
.comment-editor__placeholder {
@@ -418,7 +418,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
display: block;
margin-top: 10rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.feed-state-card {
min-height: 340rpx;
@@ -432,13 +432,13 @@ onBackPress((event) => handleBackPress(event, requestBack));
.feed-state-card > text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.feed-state-card > text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.feed-state-card .app-button {
+23 -15
View File
@@ -29,7 +29,12 @@
<view v-else class="article-list-state-card">
<text>{{ stateCopy.title }}</text>
<text>{{ stateCopy.copy }}</text>
<AppButton block :label="stateCopy.action" @click="handleStateAction" />
<AppButton
v-if="!hasValidContext || listState !== 'loading'"
block
:label="stateCopy.action"
@click="handleStateAction"
/>
</view>
</view>
</view>
@@ -97,19 +102,17 @@ const createArticle = () =>
? openPage("F06", { genealogyId: genealogyId.value, mode: "create" }, "F04")
: Promise.resolve(false);
const openArticle = (item) =>
openPage(
"F05",
{ genealogyId: genealogyId.value, articleId: item.id },
"F04",
);
openPage("F05", { genealogyId: genealogyId.value, articleId: item.id }, "F04");
const handleStateAction = () => {
if (!hasValidContext.value) return goBack();
return listState.value === "error" ? loadArticles() : createArticle();
if (listState.value === "error") return loadArticles();
if (listState.value === "empty") return createArticle();
return undefined;
};
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.article-list-page {
display: flex;
min-height: 100vh;
@@ -127,7 +130,7 @@ const handleStateAction = () => {
margin-top: 24rpx;
}
.article-card {
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
display: flex;
min-height: 150rpx;
flex-direction: column;
@@ -142,22 +145,27 @@ const handleStateAction = () => {
.article-card__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.article-card__summary {
display: -webkit-box;
margin-top: 9rpx;
overflow: hidden;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.45;
overflow-wrap: anywhere;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.article-card__meta {
margin-top: 10rpx;
color: $brand-red;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.article-list-state-card {
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
width: 100%;
min-height: 340rpx;
margin-top: 30rpx;
@@ -170,13 +178,13 @@ const handleStateAction = () => {
.article-list-state-card > text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.article-list-state-card > text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.article-list-state-card .app-button {
+10 -10
View File
@@ -131,7 +131,7 @@ const handleStateAction = () =>
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.article-detail-page {
display: flex;
@@ -149,7 +149,7 @@ const handleStateAction = () =>
}
.article-card,
.article-state-card {
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
box-sizing: border-box;
}
.article-card {
@@ -166,26 +166,26 @@ const handleStateAction = () =>
}
.article-card__category {
color: $brand-red;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.article-card__title {
margin-top: 14rpx;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 40rpx;
font-size: clamp(20px, 40rpx, 26px);
font-weight: 700;
line-height: 1.32;
}
.article-card__meta {
margin-top: 16rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.article-card__summary {
margin-top: 22rpx;
color: $ink-muted;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
line-height: 1.6;
}
.article-card__divider {
@@ -195,14 +195,14 @@ const handleStateAction = () =>
}
.article-card__content {
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
line-height: 1.85;
white-space: pre-wrap;
}
.article-card__views {
margin-top: 30rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
text-align: right;
}
.article-state-card {
@@ -217,13 +217,13 @@ const handleStateAction = () =>
.article-state-card > text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.article-state-card > text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.article-state-card .app-button {
+17 -17
View File
@@ -283,7 +283,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.article-editor-page {
display: flex;
min-height: 100vh;
@@ -299,7 +299,7 @@ onUnmounted(() => {
}
.editor-panel,
.editor-result-card {
@include adaptive.adaptive-family-panel;
@include adaptive-family-panel;
width: 100%;
}
.editor-panel__body {
@@ -308,7 +308,7 @@ onUnmounted(() => {
.editor-eyebrow {
display: block;
color: $brand-red;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
letter-spacing: 3rpx;
text-align: center;
}
@@ -317,7 +317,7 @@ onUnmounted(() => {
margin-top: 10rpx;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
text-align: center;
}
@@ -325,7 +325,7 @@ onUnmounted(() => {
display: block;
margin: 10rpx 8rpx 22rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.55;
text-align: center;
}
@@ -336,19 +336,19 @@ onUnmounted(() => {
display: block;
margin: 0 8rpx 8rpx;
color: $ink;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 700;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1;
transform: translateY(-3rpx);
}
.editor-control {
@include adaptive.adaptive-family-field;
@include adaptive-family-field;
display: flex;
min-height: 82rpx;
align-items: center;
@@ -358,7 +358,7 @@ onUnmounted(() => {
box-sizing: border-box;
width: 100%;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.editor-control input {
min-height: 82rpx;
@@ -374,7 +374,7 @@ onUnmounted(() => {
.editor-control--unavailable {
padding: 0 28rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.editor-control textarea {
min-height: 92rpx;
@@ -397,7 +397,7 @@ onUnmounted(() => {
.editor-field__hint {
display: block;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -409,11 +409,11 @@ onUnmounted(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.editor-placeholder {
@@ -423,8 +423,8 @@ onUnmounted(() => {
display: block;
margin: 12rpx 8rpx 0;
color: $brand-red;
font-size: 24rpx;
line-height: 34rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: max(1.35em, clamp(19px, 34rpx, 24px));
text-align: center;
}
.editor-panel__body > .app-button {
@@ -442,14 +442,14 @@ onUnmounted(() => {
margin-top: 14rpx;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.editor-result-card__copy {
display: block;
margin-top: 16rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.editor-result-card__body > .app-button {
+12 -12
View File
@@ -252,7 +252,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.album-list-page {
display: flex;
min-height: 100vh;
@@ -268,7 +268,7 @@ onUnmounted(() => {
}
.album-state-card,
.album-card {
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
}
.album-state-card {
min-height: 340rpx;
@@ -283,14 +283,14 @@ onUnmounted(() => {
.album-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.album-state-card text:nth-child(2),
.album-card text:not(:first-child) {
margin-top: 12rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.55;
}
.album-state-card .app-button {
@@ -313,25 +313,25 @@ onUnmounted(() => {
.album-dialog-field--cover > view > text:first-child {
display: block;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
}
.album-dialog-field input,
.album-dialog-field textarea {
@include adaptive.adaptive-family-field;
@include adaptive-family-field;
box-sizing: border-box;
display: block;
width: 100%;
margin-top: 10rpx;
padding: 16rpx 22rpx;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.album-dialog-field input {
min-height: 76rpx;
@@ -354,7 +354,7 @@ onUnmounted(() => {
display: block;
margin-top: 6rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -366,18 +366,18 @@ onUnmounted(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.album-field-error {
display: block;
margin-top: 8rpx;
color: $brand-red;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
}
</style>
+6 -6
View File
@@ -111,7 +111,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.album-detail-page {
display: flex;
min-height: 100vh;
@@ -127,7 +127,7 @@ onUnload(() => {
}
.album-state-card,
.photo-card {
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
}
.album-state-card {
width: 100%;
@@ -142,13 +142,13 @@ onUnload(() => {
.album-state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.album-state-card text:nth-child(2) {
margin-top: 10rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.6;
}
.album-state-card .app-button {
@@ -168,13 +168,13 @@ onUnload(() => {
.photo-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.photo-card text:not(:first-child) {
margin-top: 8rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.5;
}
</style>
+14 -14
View File
@@ -274,7 +274,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.media-upload-page {
display: flex;
@@ -292,7 +292,7 @@ onUnmounted(() => {
}
.media-panel,
.media-state-card {
@include adaptive.adaptive-family-panel;
@include adaptive-family-panel;
box-sizing: border-box;
}
.media-panel {
@@ -307,13 +307,13 @@ onUnmounted(() => {
.media-panel__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.media-panel__note {
margin-top: 10rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.55;
}
.media-field {
@@ -322,25 +322,25 @@ onUnmounted(() => {
.media-field__label {
margin: 0 6rpx 8rpx;
color: $ink;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 700;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1;
transform: translateY(-3rpx);
}
.media-field input,
.media-field textarea {
@include adaptive.adaptive-family-field;
@include adaptive-family-field;
box-sizing: border-box;
display: block;
width: 100%;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.media-field input {
min-height: 78rpx;
@@ -359,7 +359,7 @@ onUnmounted(() => {
border-radius: 12rpx;
background: rgba(255, 252, 245, 0.7);
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.media-field textarea {
min-height: 116rpx;
@@ -389,17 +389,17 @@ onUnmounted(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.field-error {
margin-top: 10rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.45;
}
.media-panel .app-button {
@@ -416,13 +416,13 @@ onUnmounted(() => {
.media-state-card__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.media-state-card__copy {
margin-top: 16rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.65;
}
.media-state-card .app-button {
+9 -9
View File
@@ -124,26 +124,26 @@ const handleStateAction = () => returnToFamily();
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.video-page { display: flex; min-height: 100vh; flex-direction: column; background: $paper; }
.page-header, .page-content { z-index: 1; }
.page-content { flex: 1; padding: 18rpx 24rpx 72rpx; }
.video-panel, .video-state-card { box-sizing: border-box; @include adaptive.adaptive-family-content; }
.video-panel, .video-state-card { box-sizing: border-box; @include adaptive-family-content; }
.video-panel { padding: 30rpx; }
.video-panel__title, .video-panel__note, .video-field__label, .video-state-card text { display: block; }
.video-panel__title, .video-state-card__title { color: $ink; font-family: STKaiti, KaiTi, serif; font-size: 34rpx; font-weight: 700; }
.video-panel__note, .video-state-card__copy { margin-top: 12rpx; color: $ink-muted; font-size: 23rpx; line-height: 1.6; }
.video-panel__title, .video-state-card__title { color: $ink; font-family: STKaiti, KaiTi, serif; font-size: clamp(19px, 34rpx, 24px); font-weight: 700; }
.video-panel__note, .video-state-card__copy { margin-top: 12rpx; color: $ink-muted; font-size: clamp(14px, 23rpx, 17px); line-height: 1.6; }
.video-field { margin-top: 24rpx; }
.video-field__label { margin-bottom: 10rpx; color: $ink; font-size: 24rpx; font-weight: 700; }
.video-field input, .video-field textarea { width: 100%; box-sizing: border-box; border: 1rpx solid rgba(143, 108, 63, .34); border-radius: 8rpx; background: rgba(255, 253, 247, .8); color: $ink; font-size: 24rpx; }
.video-field__label { margin-bottom: 10rpx; color: $ink; font-size: clamp(15px, 24rpx, 18px); font-weight: 700; }
.video-field input, .video-field textarea { width: 100%; box-sizing: border-box; border: 1rpx solid rgba(143, 108, 63, .34); border-radius: 8rpx; background: rgba(255, 253, 247, .8); color: $ink; font-size: clamp(15px, 24rpx, 18px); }
.video-field input { height: 76rpx; padding: 0 18rpx; }
.video-field textarea { min-height: 140rpx; padding: 16rpx 18rpx; }
.video-field--upload { display: flex; flex-wrap: wrap; align-items: center; gap: 12rpx; }
.video-field--upload .video-field__label { width: 100%; }
.upload-button { margin: 0; padding: 0 26rpx; border: 1rpx solid #b78a42; border-radius: 8rpx; background: #fffaf0; color: #805723; font-size: 23rpx; line-height: 64rpx; }
.upload-receipt { color: $ink-muted; font-size: 21rpx; }
.upload-button { margin: 0; padding: 0 26rpx; border: 1rpx solid #b78a42; border-radius: 8rpx; background: #fffaf0; color: #805723; font-size: clamp(14px, 23rpx, 17px); line-height: 64rpx; }
.upload-receipt { color: $ink-muted; font-size: clamp(13px, 21rpx, 16px); }
.required-mark, .field-error { color: $brand-red; }
.field-error { display: block; margin-top: 12rpx; font-size: 22rpx; }
.field-error { display: block; margin-top: 12rpx; font-size: clamp(14px, 22rpx, 17px); }
.video-panel .app-button { margin-top: 28rpx; }
.video-state-card { min-height: 340rpx; padding: 78rpx 52rpx 50rpx; text-align: center; }
.video-state-card .app-button { margin-top: 28rpx; }
+73 -56
View File
@@ -68,7 +68,7 @@
</view>
<view class="current-info-divider"></view>
<view class="current-meta">
<view class="current-meta-item">
<view class="current-meta-item current-meta-item--location">
<image
class="current-meta-icon"
src="/static/assets/foundation/transparent/meta-location.png"
@@ -78,7 +78,7 @@
currentGenealogy.location
}}</text>
</view>
<view class="current-meta-item">
<view class="current-meta-item current-meta-item--members">
<image
class="current-meta-icon"
src="/static/assets/foundation/transparent/meta-member.png"
@@ -88,7 +88,7 @@
>{{ currentGenealogy.memberCount }} 位成员</text
>
</view>
<view class="current-meta-item">
<view class="current-meta-item current-meta-item--role">
<image
class="current-meta-icon"
src="/static/assets/foundation/transparent/meta-admin.png"
@@ -710,7 +710,7 @@ const openShortcut = (key) => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.genealogy-index {
display: flex;
@@ -754,9 +754,9 @@ const openShortcut = (key) => {
}
.current-slip {
@include adaptive.adaptive-genealogy-current-slip;
@include adaptive-genealogy-current-slip;
display: block;
min-height: 268rpx;
min-height: 300rpx;
padding: 30rpx 34rpx 28rpx;
}
@@ -775,7 +775,7 @@ const openShortcut = (key) => {
.current-seal-title {
color: #fff7e7;
font-family: "STKaiti", "KaiTi", serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
letter-spacing: 2rpx;
writing-mode: vertical-rl;
@@ -790,59 +790,76 @@ const openShortcut = (key) => {
flex: 1;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 38rpx;
font-size: clamp(18px, 34rpx, 24px);
font-weight: 700;
line-height: 1.25;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
overflow-wrap: anywhere;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.current-switch-copy {
flex: 0 0 auto;
margin-left: auto;
margin-left: 16rpx;
padding: 4rpx 12rpx;
border: 1rpx solid rgba(159, 23, 15, 0.34);
border-radius: 999rpx;
color: $brand-red;
font-size: 28rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 600;
line-height: 1.3;
white-space: nowrap;
}
.current-info-divider {
width: 100%;
height: 1rpx;
margin: 14rpx 0 16rpx;
margin: 18rpx 0 16rpx;
background: rgba(181, 138, 75, 0.48);
}
.current-meta {
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
column-gap: 28rpx;
row-gap: 10rpx;
margin-top: 0;
color: #62584c;
font-size: 27rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 500;
line-height: 1.4;
}
.current-meta-item {
display: flex;
min-width: 0;
align-items: center;
margin: 0;
flex-wrap: wrap;
.current-meta-item-text {
min-width: 0;
overflow-wrap: anywhere;
}
}
.current-meta-item--location {
grid-column: 1 / -1;
}
.current-meta-item--role {
justify-self: end;
}
.current-meta-icon {
width: 36rpx;
height: 36rpx;
width: 34rpx;
height: 34rpx;
flex: 0 0 auto;
margin-right: 8rpx;
opacity: 1;
}
.shortcut-grid {
display: flex;
min-height: 194rpx;
min-height: 168rpx;
align-items: center;
margin-top: 24rpx;
margin-top: 18rpx;
padding: 8rpx 0;
}
@@ -854,15 +871,15 @@ const openShortcut = (key) => {
align-items: center;
}
.shortcut-icon {
width: 82rpx;
height: 82rpx;
width: 76rpx;
height: 76rpx;
}
.shortcut-label {
width: 100%;
margin-top: 12rpx;
margin-top: 10rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 29rpx;
font-size: clamp(16px, 27rpx, 19px);
font-weight: 700;
text-align: center;
overflow-wrap: anywhere;
@@ -890,7 +907,7 @@ const openShortcut = (key) => {
margin-bottom: 8rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
@@ -907,7 +924,7 @@ const openShortcut = (key) => {
}
.application-record {
@include adaptive.adaptive-genealogy-list-card;
@include adaptive-genealogy-list-card;
display: flex;
min-height: 138rpx;
align-items: center;
@@ -928,7 +945,7 @@ const openShortcut = (key) => {
.application-record__name {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
overflow-wrap: anywhere;
}
@@ -936,7 +953,7 @@ const openShortcut = (key) => {
flex: 0 0 auto;
margin-left: 16rpx;
color: #7f4f16;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
font-weight: 600;
}
.application-record__status--rejected {
@@ -949,7 +966,7 @@ const openShortcut = (key) => {
display: block;
margin-top: 10rpx;
color: #62584c;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
font-weight: 500;
line-height: 1.4;
}
@@ -965,7 +982,7 @@ const openShortcut = (key) => {
align-items: center;
justify-content: center;
box-sizing: border-box;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
}
.create-action {
@@ -976,7 +993,7 @@ const openShortcut = (key) => {
background: rgba(255, 249, 238, 0.66);
color: $brand-red;
font-family: "STKaiti", "KaiTi", serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
letter-spacing: 3rpx;
}
@@ -1019,18 +1036,18 @@ const openShortcut = (key) => {
margin-top: 24rpx;
color: $ink;
font-family: serif;
font-size: 38rpx;
font-size: clamp(20px, 38rpx, 26px);
font-weight: 700;
}
.state-copy {
margin-top: 14rpx;
color: $ink-muted;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
line-height: 1.7;
}
.state-panel--error {
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
min-height: 1120rpx;
padding: 0;
}
@@ -1060,7 +1077,7 @@ const openShortcut = (key) => {
margin-top: 30rpx;
color: #392719;
font-family: "STKaiti", "KaiTi", serif;
font-size: 42rpx;
font-size: clamp(22px, 42rpx, 28px);
font-weight: 700;
letter-spacing: 2rpx;
}
@@ -1070,7 +1087,7 @@ const openShortcut = (key) => {
min-height: 72rpx;
margin-top: 16rpx;
color: #786654;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
line-height: 1.65;
}
@@ -1092,7 +1109,7 @@ const openShortcut = (key) => {
}
.empty-panel {
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
min-height: 1120rpx;
}
@@ -1120,7 +1137,7 @@ const openShortcut = (key) => {
.empty-seal__text {
color: #fff7e7;
font-family: "STKaiti", "KaiTi", serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
letter-spacing: 2rpx;
writing-mode: vertical-rl;
@@ -1131,7 +1148,7 @@ const openShortcut = (key) => {
margin-top: 30rpx;
color: #392719;
font-family: "STKaiti", "KaiTi", serif;
font-size: 48rpx;
font-size: clamp(24px, 48rpx, 30px);
font-weight: 700;
letter-spacing: 2rpx;
}
@@ -1141,7 +1158,7 @@ const openShortcut = (key) => {
min-height: 84rpx;
margin-top: 18rpx;
color: #786654;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
line-height: 1.65;
}
@@ -1177,7 +1194,7 @@ const openShortcut = (key) => {
.empty-invite-action__copy {
color: #7b4e24;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
letter-spacing: 3rpx;
}
@@ -1194,13 +1211,13 @@ const openShortcut = (key) => {
}
.empty-create-action__copy {
font-family: "STKaiti", "KaiTi", serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
}
.empty-create-note {
display: block;
color: $ink-muted;
font-size: 26rpx;
line-height: 38rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: max(1.35em, clamp(20px, 38rpx, 26px));
}
.state-retry {
@@ -1216,7 +1233,7 @@ const openShortcut = (key) => {
.state-retry__copy {
color: #fff9ec;
font-family: "STKaiti", "KaiTi", serif;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
}
.add-dialog-layer {
@@ -1230,7 +1247,7 @@ const openShortcut = (key) => {
background: rgba(34, 20, 12, 0.68);
}
.add-dialog {
@include adaptive.adaptive-g01-add-sheet;
@include adaptive-g01-add-sheet;
width: 100%;
min-height: 780rpx;
max-height: calc(100vh - 80rpx);
@@ -1301,7 +1318,7 @@ const openShortcut = (key) => {
background: rgba(34, 20, 12, 0.58);
}
.genealogy-switcher {
@include adaptive.adaptive-g01-switcher;
@include adaptive-g01-switcher;
width: 670rpx;
max-width: 100%;
min-height: 600rpx;
@@ -1346,14 +1363,14 @@ const openShortcut = (key) => {
.dialog-title {
color: $brand-red;
font-family: "STKaiti", "KaiTi", serif;
font-size: 42rpx;
font-size: clamp(22px, 42rpx, 28px);
font-weight: 700;
letter-spacing: 4rpx;
}
.dialog-copy {
margin-top: 12rpx;
color: $ink-muted;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
line-height: 1.5;
}
.switcher-item {
@@ -1381,17 +1398,17 @@ const openShortcut = (key) => {
.switcher-item__name {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
}
.switcher-item__meta {
margin-top: 6rpx;
color: #62584c;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.switcher-item__state {
color: $brand-red;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 600;
}
.switcher-item--active {
@@ -1412,10 +1429,10 @@ const openShortcut = (key) => {
padding-left: 20rpx;
}
.current-name {
font-size: 40rpx;
font-size: clamp(20px, 40rpx, 26px);
}
.shortcut-label {
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.current-meta-icon {
width: 32rpx;
+25 -24
View File
@@ -503,7 +503,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.create-page {
display: flex;
@@ -516,7 +516,7 @@ onUnload(() => {
padding: 24rpx 32rpx 72rpx;
}
.create-card {
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
padding: 48rpx 38rpx 42rpx;
}
.create-card__eyebrow,
@@ -528,7 +528,7 @@ onUnload(() => {
}
.create-card__eyebrow {
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
font-weight: 700;
letter-spacing: 3rpx;
}
@@ -536,13 +536,13 @@ onUnload(() => {
margin-top: 12rpx;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 42rpx;
font-size: clamp(22px, 42rpx, 28px);
font-weight: 700;
}
.create-card__note {
margin-top: 16rpx;
color: $ink-muted;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
line-height: 1.65;
}
.field-row {
@@ -556,18 +556,19 @@ onUnload(() => {
background: rgba(255, 252, 245, 0.7);
}
.field-row__label {
width: 142rpx;
width: 184rpx;
flex: 0 0 auto;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
white-space: nowrap;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1;
transform: translateY(-3rpx);
}
@@ -575,7 +576,7 @@ onUnload(() => {
min-width: 0;
flex: 1;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.field-row--selector {
justify-content: space-between;
@@ -585,7 +586,7 @@ onUnload(() => {
min-width: 0;
flex: 1;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
text-align: right;
overflow-wrap: anywhere;
}
@@ -606,7 +607,7 @@ onUnload(() => {
display: block;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.intro-field textarea {
@@ -615,7 +616,7 @@ onUnload(() => {
min-height: 120rpx;
margin-top: 14rpx;
color: $ink;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
line-height: 1.55;
}
.cover-field {
@@ -631,14 +632,14 @@ onUnload(() => {
display: block;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.cover-field__hint {
display: block;
margin-top: 6rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -650,18 +651,18 @@ onUnload(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.field-error,
.submit-error {
margin-top: 10rpx;
color: $brand-red;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.5;
}
.access-rule {
@@ -670,7 +671,7 @@ onUnload(() => {
.access-rule__label {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.access-rule__options {
@@ -684,7 +685,7 @@ onUnload(() => {
border: 1rpx solid rgba(128, 89, 49, 0.34);
border-radius: 12rpx;
color: $ink-muted;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
text-align: center;
}
.access-rule__option--active {
@@ -726,7 +727,7 @@ onUnload(() => {
.region-sheet__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.region-sheet__picker {
@@ -745,7 +746,7 @@ onUnload(() => {
width: 33.333%;
padding: 24rpx 12rpx;
color: $ink-muted;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
text-align: center;
}
.region-sheet__column-heading + .region-sheet__column-heading {
@@ -761,7 +762,7 @@ onUnload(() => {
overflow: hidden;
padding: 0 6rpx;
color: $ink-muted;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 104rpx;
text-align: center;
text-overflow: ellipsis;
@@ -781,7 +782,7 @@ onUnload(() => {
min-width: 116rpx;
padding: 20rpx 10rpx;
color: $ink-muted;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
text-align: center;
}
.region-sheet__confirm {
@@ -793,7 +794,7 @@ onUnload(() => {
border-radius: 10rpx;
background: $brand-red;
color: #fff;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
font-weight: 700;
line-height: 82rpx;
}
+31 -32
View File
@@ -428,14 +428,18 @@ const applyToJoin = () => {
if (!publicCanApply.value) return false;
return openPage(
"G08",
{ genealogyId: genealogyId.value, source: "search" },
{
genealogyId: genealogyId.value,
genealogyName: genealogy.name,
source: "search",
},
"G05",
);
};
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.overview-page {
display: flex;
min-height: 100vh;
@@ -446,7 +450,7 @@ const applyToJoin = () => {
z-index: 3;
}
.overview-surface {
@include adaptive.adaptive-g05-overview-surface;
@include adaptive-g05-overview-surface;
z-index: 2;
width: 100%;
min-height: min(483px, calc(100vw * 1.3422));
@@ -509,28 +513,23 @@ const applyToJoin = () => {
.overview-hero__kicker {
display: block;
color: #dec483;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.5;
}
.overview-hero__title {
display: block;
margin-bottom: 6rpx;
font-family: "STKaiti", "KaiTi", serif;
font-size: 42rpx;
font-size: clamp(22px, 42rpx, 28px);
font-weight: 700;
letter-spacing: 2rpx;
}
.overview-hero__motto {
display: block;
height: 66rpx;
margin-top: 22rpx;
color: #e9dcc1;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.55;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.overview-hero__stats {
display: flex;
@@ -538,7 +537,7 @@ const applyToJoin = () => {
gap: 8rpx 0;
margin-top: 18rpx;
color: #dbc990;
font-size: 19rpx;
font-size: clamp(13px, 19rpx, 16px);
line-height: 1.4;
}
.overview-hero__stats text {
@@ -571,7 +570,7 @@ const applyToJoin = () => {
border-top: 1rpx solid rgba(152, 119, 72, 0.28);
box-sizing: border-box;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.5;
}
.overview-action--tree {
@@ -618,11 +617,11 @@ const applyToJoin = () => {
margin-bottom: 5rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.overview-action--tree .overview-action__title {
font-size: 40rpx;
font-size: clamp(20px, 40rpx, 26px);
}
.overview-summary {
grid-template-columns: minmax(0, 1fr);
@@ -637,7 +636,7 @@ const applyToJoin = () => {
padding: 20rpx 0;
border-top: 1rpx solid rgba(152, 119, 72, 0.28);
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.5;
}
.overview-family text {
@@ -647,7 +646,7 @@ const applyToJoin = () => {
margin-bottom: 3rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
font-weight: 700;
}
.overview-note {
@@ -657,18 +656,18 @@ const applyToJoin = () => {
padding: 18rpx 0 0;
border-top: 1rpx solid rgba(152, 119, 72, 0.28);
color: $ink-muted;
font-size: 19rpx;
font-size: clamp(13px, 19rpx, 16px);
line-height: 1.55;
}
.overview-note__title {
margin-bottom: 5rpx;
color: $brand-red;
font-family: "STKaiti", "KaiTi", serif;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.overview-state {
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
display: flex;
width: 100%;
min-height: 0;
@@ -699,14 +698,14 @@ const applyToJoin = () => {
margin-top: 28rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 42rpx;
font-size: clamp(22px, 42rpx, 28px);
font-weight: 700;
}
.overview-state-panel__copy {
max-width: 520rpx;
margin-top: 18rpx;
color: $ink-muted;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
line-height: 1.7;
}
.overview-state-panel__action {
@@ -722,7 +721,7 @@ const applyToJoin = () => {
.overview-state-panel__action text {
z-index: 1;
color: #fff9ed;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.overview-public {
@@ -740,14 +739,14 @@ const applyToJoin = () => {
.overview-public__eyebrow {
display: block;
color: #dec483;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
letter-spacing: 3rpx;
}
.overview-public__title {
display: block;
margin-top: 10rpx;
font-family: "STKaiti", "KaiTi", serif;
font-size: 43rpx;
font-size: clamp(22px, 43rpx, 28px);
font-weight: 700;
letter-spacing: 4rpx;
}
@@ -755,7 +754,7 @@ const applyToJoin = () => {
display: block;
margin-top: 7rpx;
color: #e9dcc1;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.overview-public__details {
display: grid;
@@ -785,13 +784,13 @@ const applyToJoin = () => {
}
.overview-public__details text:first-child {
color: $brand-red;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.overview-public__details text:last-child {
margin-top: 6rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
}
.overview-public__trust {
display: grid;
@@ -799,15 +798,15 @@ const applyToJoin = () => {
gap: 10rpx 24rpx;
margin: 28rpx 9% 0;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
}
.overview-public__notice {
display: flex;
margin: 54rpx 9% 0;
color: $ink-muted;
font-size: 19rpx;
line-height: 26rpx;
font-size: clamp(13px, 19rpx, 16px);
line-height: max(1.35em, clamp(16px, 26rpx, 20px));
}
.overview-public__notice text:first-child {
flex: 0 0 auto;
@@ -827,7 +826,7 @@ const applyToJoin = () => {
.overview-public__action text {
z-index: 1;
color: #fff9ed;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
font-weight: 700;
letter-spacing: 3rpx;
}
+9 -9
View File
@@ -111,7 +111,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.search-page {
display: flex;
min-height: 100vh;
@@ -128,7 +128,7 @@ onUnload(() => {
.search-note,
.state-card,
.genealogy-card {
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
}
.search-note {
display: flex;
@@ -140,13 +140,13 @@ onUnload(() => {
.search-note text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.search-note text:last-child {
margin-top: 6rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.state-card {
display: flex;
@@ -158,7 +158,7 @@ onUnload(() => {
padding: 42rpx;
text-align: center;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.state-card .app-button {
width: 100%;
@@ -182,20 +182,20 @@ onUnload(() => {
.card-heading text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
overflow-wrap: anywhere;
}
.card-heading text:last-child {
flex: 0 0 auto;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.card-meta,
.card-copy {
display: block;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.5;
}
.card-meta {
@@ -211,7 +211,7 @@ onUnload(() => {
gap: 18rpx;
margin-top: 20rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.card-footer .app-button {
min-width: 180rpx;
+9 -9
View File
@@ -171,7 +171,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.join-page {
display: flex;
min-height: 100vh;
@@ -187,7 +187,7 @@ onUnmounted(() => {
}
.state-card,
.join-form {
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
}
.state-card {
min-height: 340rpx;
@@ -201,13 +201,13 @@ onUnmounted(() => {
.form-heading text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button,
@@ -226,7 +226,7 @@ onUnmounted(() => {
}
.form-heading text:last-child {
color: $brand-red;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.form-field {
margin-top: 22rpx;
@@ -234,19 +234,19 @@ onUnmounted(() => {
.form-field > text {
display: block;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.form-field input,
.form-field textarea {
@include adaptive.adaptive-genealogy-form-field;
@include adaptive-genealogy-form-field;
box-sizing: border-box;
display: block;
width: 100%;
margin-top: 10rpx;
padding: 16rpx 22rpx;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.form-field input {
min-height: 76rpx;
@@ -261,7 +261,7 @@ onUnmounted(() => {
display: block;
margin-top: 16rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.45;
}
</style>
+4 -4
View File
@@ -74,7 +74,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.applications-page {
display: flex;
min-height: 100vh;
@@ -93,7 +93,7 @@ onUnload(() => {
min-height: 340rpx;
padding: 78rpx 52rpx 50rpx;
text-align: center;
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
}
.state-card text {
display: block;
@@ -101,13 +101,13 @@ onUnload(() => {
.state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
+4 -4
View File
@@ -86,7 +86,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.review-page {
display: flex;
min-height: 100vh;
@@ -105,7 +105,7 @@ onUnload(() => {
min-height: 340rpx;
padding: 78rpx 52rpx 50rpx;
text-align: center;
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
}
.state-card text {
display: block;
@@ -113,13 +113,13 @@ onUnload(() => {
.state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
+25 -24
View File
@@ -513,7 +513,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.settings-page {
display: flex;
@@ -531,7 +531,7 @@ onUnload(() => {
}
.settings-card,
.state-card {
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
box-sizing: border-box;
}
.settings-card {
@@ -546,13 +546,13 @@ onUnload(() => {
.settings-card__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 40rpx;
font-size: clamp(20px, 40rpx, 26px);
font-weight: 700;
}
.settings-card__note {
margin-top: 12rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.55;
}
.field-row {
@@ -566,18 +566,19 @@ onUnload(() => {
background: rgba(255, 252, 245, 0.7);
}
.field-row__label {
width: 142rpx;
width: 184rpx;
flex: 0 0 auto;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
white-space: nowrap;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1;
transform: translateY(-3rpx);
}
@@ -585,7 +586,7 @@ onUnload(() => {
min-width: 0;
flex: 1;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.field-row--selector {
justify-content: space-between;
@@ -595,7 +596,7 @@ onUnload(() => {
min-width: 0;
flex: 1;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
text-align: right;
overflow-wrap: anywhere;
}
@@ -616,7 +617,7 @@ onUnload(() => {
display: block;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.intro-field textarea {
@@ -625,7 +626,7 @@ onUnload(() => {
min-height: 120rpx;
margin-top: 14rpx;
color: $ink;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
line-height: 1.55;
}
.cover-field {
@@ -636,7 +637,7 @@ onUnload(() => {
display: block;
margin-top: 6rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -648,18 +649,18 @@ onUnload(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.field-error,
.submit-error {
margin-top: 10rpx;
color: $brand-red;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.5;
}
.access-rule {
@@ -668,7 +669,7 @@ onUnload(() => {
.access-rule__label {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.access-rule__options {
@@ -682,7 +683,7 @@ onUnload(() => {
border: 1rpx solid rgba(128, 89, 49, 0.34);
border-radius: 12rpx;
color: $ink-muted;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
text-align: center;
}
.access-rule__option--active {
@@ -705,13 +706,13 @@ onUnload(() => {
.state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
@@ -744,7 +745,7 @@ onUnload(() => {
display: block;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.region-sheet__picker {
@@ -762,7 +763,7 @@ onUnload(() => {
width: 33.333%;
padding: 24rpx 12rpx;
color: $ink-muted;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
text-align: center;
}
.region-sheet__column-heading + .region-sheet__column-heading {
@@ -777,7 +778,7 @@ onUnload(() => {
height: 104rpx;
padding: 0 6rpx;
color: $ink-muted;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 104rpx;
text-align: center;
text-overflow: ellipsis;
@@ -797,7 +798,7 @@ onUnload(() => {
min-width: 116rpx;
padding: 20rpx 10rpx;
color: $ink-muted;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
text-align: center;
}
.region-sheet__confirm {
@@ -809,7 +810,7 @@ onUnload(() => {
border-radius: 10rpx;
background: $brand-red;
color: #fff;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
font-weight: 700;
line-height: 82rpx;
}
+20 -20
View File
@@ -411,7 +411,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.poem-page {
display: flex;
min-height: 100vh;
@@ -422,7 +422,7 @@ onUnload(() => {
z-index: 3;
}
.poem-panel {
@include adaptive.adaptive-genealogy-state-panel;
@include adaptive-genealogy-state-panel;
z-index: 2;
width: calc(100% - 32rpx);
margin: 18rpx auto 0;
@@ -440,7 +440,7 @@ onUnload(() => {
.poem-list__eyebrow {
display: block;
color: $brand-red;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
letter-spacing: 3rpx;
}
.poem-list__title {
@@ -448,14 +448,14 @@ onUnload(() => {
margin-top: 11rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.poem-list__copy {
display: block;
margin-top: 10rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.55;
}
.poem-rows {
@@ -472,11 +472,11 @@ onUnload(() => {
}
.poem-load-more text {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.poem-row {
@include adaptive.adaptive-genealogy-form-field;
@include adaptive-genealogy-form-field;
display: grid;
min-height: 72rpx;
margin-top: 10rpx;
@@ -488,7 +488,7 @@ onUnload(() => {
grid-column: 1;
margin-left: 24rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.poem-row__character {
z-index: 1;
@@ -497,7 +497,7 @@ onUnload(() => {
padding: 12rpx 16rpx 12rpx 0;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
line-height: 1.4;
overflow-wrap: anywhere;
@@ -508,7 +508,7 @@ onUnload(() => {
grid-column: 3;
margin-right: 22rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.poem-row--disabled .poem-row__character,
.poem-row--disabled .poem-row__status {
@@ -537,12 +537,12 @@ onUnload(() => {
justify-content: center;
height: 100%;
color: #fff9ed;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 700;
letter-spacing: 2rpx;
}
.poem-field {
@include adaptive.adaptive-genealogy-form-field;
@include adaptive-genealogy-form-field;
display: grid;
min-height: 118rpx;
margin-top: 22rpx;
@@ -553,7 +553,7 @@ onUnload(() => {
align-self: center;
margin-left: 24rpx;
color: $ink;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
font-weight: 700;
}
.poem-field textarea {
@@ -567,7 +567,7 @@ onUnload(() => {
margin-left: 164rpx;
padding-top: 34rpx;
color: $ink;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.5;
}
.poem-placeholder {
@@ -577,8 +577,8 @@ onUnload(() => {
display: block;
margin-top: 4rpx;
color: $brand-red;
font-size: 24rpx;
line-height: 34rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: max(1.35em, clamp(19px, 34rpx, 24px));
text-align: right;
}
.poem-policy {
@@ -589,7 +589,7 @@ onUnload(() => {
}
.poem-policy > text {
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.poem-policy__option {
@@ -610,7 +610,7 @@ onUnload(() => {
justify-content: center;
height: 100%;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.poem-policy__option .poem-policy__option-text--active {
@@ -620,7 +620,7 @@ onUnload(() => {
display: block;
margin-top: 22rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.6;
}
.poem-editor__actions {
@@ -668,7 +668,7 @@ onUnload(() => {
.poem-feedback text {
z-index: 1;
color: $ink;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
@media (min-width: 400px) {
.poem-panel {
+79 -10
View File
@@ -19,12 +19,22 @@
><text>暂无消息</text><text>消息列表会直接从服务端读取</text
><AppButton block label="返回我的" @click="returnToProfile"
/></view>
<view v-else class="state-card"
><text>已读取 {{ notifications.length }} 条消息</text
><text
>消息详情接口尚未开放当前不会用本地数据补造正文或已读状态</text
><AppButton block label="返回我的" @click="returnToProfile"
/></view>
<view v-else class="message-list">
<text class="message-list__count"> {{ notifications.length }} 条消息</text>
<view
v-for="(item, index) in notifications"
:key="notificationKey(item, index)"
class="message-card"
>
<view class="message-card__heading"
><text>{{ notificationTitle(item) }}</text><text>消息</text></view
>
<text class="message-card__summary">{{ notificationSummary(item) }}</text>
<text v-if="notificationTime(item)" class="message-card__time">{{
notificationTime(item)
}}</text>
</view>
</view>
</view>
<AppTabbar active="profile" />
</view>
@@ -49,6 +59,14 @@ const notifications = ref([]);
const state = ref("loading");
const controller = createRequestController();
let active = true;
const notificationKey = (item, index) =>
String(item?.notificationId ?? item?.id ?? index);
const notificationTitle = (item) =>
String(item?.noticeTitle ?? item?.title ?? "通知消息");
const notificationSummary = (item) =>
String(item?.noticeContent ?? item?.content ?? "点击查看消息详情");
const notificationTime = (item) =>
String(item?.publishTime ?? item?.time ?? item?.createdAt ?? "");
const loadNotifications = async () => {
controller.abort();
state.value = "loading";
@@ -75,7 +93,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.message-page {
display: flex;
min-height: 100vh;
@@ -95,7 +113,7 @@ onUnload(() => {
min-height: 340rpx;
padding: 78rpx 52rpx 50rpx;
text-align: center;
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
}
.state-card text {
display: block;
@@ -103,16 +121,67 @@ onUnload(() => {
.state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
margin-top: 28rpx;
}
.message-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.message-list__count {
display: block;
color: $ink-muted;
font-size: clamp(13px, 21rpx, 16px);
}
.message-card {
padding: 28rpx 34rpx;
@include adaptive-family-content;
}
.message-card__heading {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: 16rpx;
}
.message-card__heading text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
overflow-wrap: anywhere;
}
.message-card__heading text:last-child {
color: $brand-red;
font-size: clamp(13px, 21rpx, 16px);
}
.message-card__summary,
.message-card__time {
display: block;
}
.message-card__summary {
display: -webkit-box;
margin-top: 12rpx;
overflow: hidden;
color: $ink-muted;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
overflow-wrap: anywhere;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.message-card__time {
margin-top: 12rpx;
color: #8b7d6c;
font-size: clamp(13px, 20rpx, 16px);
}
</style>
+21 -8
View File
@@ -20,6 +20,11 @@
/>
<AppButton block label="返回消息中心" @click="backToMessages" />
</view>
<view v-else-if="state === 'invalid'" class="state-card">
<text>消息不存在或链接已失效</text>
<text>请返回消息中心查看最新通知</text>
<AppButton block label="返回消息中心" @click="backToMessages" />
</view>
<view v-else class="detail-card">
<text class="detail-title">{{ detail.noticeTitle || "通知消息" }}</text>
<text v-if="detail.publishTime" class="detail-time">{{
@@ -77,6 +82,10 @@ const controller = createRequestController();
let active = true;
const loadDetail = async () => {
if (!/^[1-9]\d*$/.test(notificationId.value)) {
state.value = "invalid";
return;
}
controller.abort();
state.value = "loading";
loadError.value = "";
@@ -96,7 +105,11 @@ const loadDetail = async () => {
const backToMessages = () => returnTo("N01");
onLoad((options) => {
notificationId.value = options?.id || "";
notificationId.value = String(options?.id || "");
if (!/^[1-9]\d*$/.test(notificationId.value)) {
state.value = "invalid";
return;
}
loadDetail();
});
onUnload(() => {
@@ -106,7 +119,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.message-detail-page {
display: flex;
min-height: 100vh;
@@ -124,7 +137,7 @@ onUnload(() => {
.state-card,
.detail-card {
box-sizing: border-box;
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
}
.state-card {
min-height: 340rpx;
@@ -138,13 +151,13 @@ onUnload(() => {
.detail-title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
@@ -160,12 +173,12 @@ onUnload(() => {
.detail-time {
margin-top: 16rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.detail-content {
margin-top: 36rpx;
color: $ink;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
line-height: 1.8;
white-space: pre-wrap;
}
@@ -179,7 +192,7 @@ onUnload(() => {
gap: 22rpx;
padding: 10rpx 0;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.5;
}
.detail-meta__row text:first-child {
+137 -54
View File
@@ -8,7 +8,14 @@
}"
>
<view v-if="compactHeader" class="profile-compact-header" aria-hidden="true">
<text>我的</text>
<view class="profile-compact-header__brand-lockup">
<image
src="/static/assets/foundation/transparent/brand-seal.png"
mode="aspectFit"
/>
<text>代代相传</text>
</view>
<text class="profile-compact-header__title">我的</text>
</view>
<view v-if="loading" class="profile-state-card">
@@ -30,6 +37,14 @@
aria-hidden="true"
/>
<view class="profile-hero__content">
<view class="profile-hero__brand-lockup">
<image
src="/static/assets/foundation/transparent/brand-seal.png"
mode="aspectFit"
aria-hidden="true"
/>
<text>代代相传</text>
</view>
<view class="profile-hero__label">
<text>我的</text>
<view
@@ -46,12 +61,9 @@
</view>
<view class="profile-hero__identity">
<image
class="profile-hero__emblem"
src="/static/assets/modules/profile/transparent/m01-profile-tree-medallion.png"
mode="aspectFit"
aria-hidden="true"
/>
<view class="profile-hero__emblem">
<AppAvatar :sex="profile.sex" />
</view>
<view class="profile-hero__copy">
<text>{{ profile.nickName || "未设置昵称" }}</text>
<text>{{ profile.realName || "未设置真实姓名" }}</text>
@@ -73,7 +85,7 @@
mode="aspectFit"
aria-hidden="true"
/>
<view><text>性别</text><text>{{ sexText }}</text></view>
<view><text>性别</text><text class="app-single-line">{{ sexText }}</text></view>
</view>
<view class="profile-metadata__item">
<image
@@ -82,7 +94,7 @@
mode="aspectFit"
aria-hidden="true"
/>
<view><text>生日</text><text>{{ birthdayText }}</text></view>
<view><text>生日</text><text class="app-single-line">{{ birthdayText }}</text></view>
</view>
<view class="profile-metadata__item profile-metadata__item--email">
<image
@@ -91,7 +103,7 @@
mode="aspectFit"
aria-hidden="true"
/>
<view><text>邮箱</text><text>{{ profile.email || "未设置" }}</text></view>
<view><text>邮箱</text><text class="app-long-value">{{ profile.email || "未设置" }}</text></view>
</view>
</view>
@@ -145,6 +157,7 @@
<script setup>
import { computed, reactive, ref } from "vue";
import { onPageScroll, onShow, onUnload } from "@dcloudio/uni-app";
import AppAvatar from "@/components/AppAvatar.vue";
import AppButton from "@/components/AppButton.vue";
import AppTabbar from "@/components/AppTabbar.vue";
import {
@@ -217,7 +230,10 @@ const serviceGroups = [
},
];
const sexText = computed(() => (profile.sex ? "待确认" : "未设置"));
const sexText = computed(() => {
const labels = { 0: "男", 1: "女", 2: "未知" };
return labels[String(profile.sex)] || "未设置";
});
const birthdayText = computed(() =>
/^\d{4}-\d{2}-\d{2}/.test(profile.birthday)
? profile.birthday.slice(0, 10)
@@ -257,9 +273,10 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.profile-page {
position: relative;
width: 100%;
min-height: 100vh;
padding-bottom: 166rpx;
@@ -274,22 +291,53 @@ onUnload(() => {
right: 0;
left: 0;
z-index: 30;
height: 88rpx;
height: calc(104rpx + var(--status-bar-height, 0px));
box-sizing: border-box;
padding: 38rpx 48rpx 0;
padding: calc(var(--status-bar-height, 0px) + 46rpx) 48rpx 0;
background: linear-gradient(90deg, #6a1d17, #4e120f);
box-shadow: 0 2rpx 12rpx rgba(58, 16, 12, 0.22);
color: #f2d9a8;
font-family: STKaiti, KaiTi, serif;
font-size: 28rpx;
font-weight: 700;
letter-spacing: 3rpx;
line-height: 1;
pointer-events: none;
}
.profile-compact-header__brand-lockup {
position: absolute;
top: calc(var(--status-bar-height, 0px) + 8rpx);
left: 50%;
display: flex;
align-items: center;
gap: 7rpx;
transform: translateX(-50%);
white-space: nowrap;
}
.profile-compact-header__brand-lockup image {
width: 32rpx;
height: 32rpx;
}
.profile-compact-header__brand-lockup text {
color: #f2d9a8;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(11px, 19rpx, 14px);
font-weight: 700;
letter-spacing: 3rpx;
line-height: 1;
}
.profile-compact-header__title {
display: block;
color: #f2d9a8;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(16px, 28rpx, 20px);
font-weight: 700;
letter-spacing: 3rpx;
line-height: 1;
}
.profile-state-card {
@include adaptive.adaptive-profile-summary;
@include adaptive-profile-summary;
margin: 48rpx 30rpx;
padding: 64rpx 44rpx;
color: #382c25;
@@ -298,18 +346,18 @@ onUnload(() => {
.profile-state-card text {
display: block;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1.6;
}
.profile-state-card text + text {
margin-top: 12rpx;
color: #806e5d;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.profile-state-card .app-button {
@include adaptive.adaptive-scroll-button(primary);
@include adaptive-scroll-button(primary);
margin-top: 28rpx;
}
@@ -331,6 +379,7 @@ onUnload(() => {
}
.profile-hero__content {
position: relative;
display: flex;
flex-direction: column;
z-index: 1;
@@ -338,6 +387,31 @@ onUnload(() => {
box-sizing: border-box;
}
.profile-hero__brand-lockup {
position: absolute;
top: calc(var(--status-bar-height, 0px) + 4rpx);
left: 50%;
display: flex;
align-items: center;
gap: 7rpx;
transform: translateX(-50%);
white-space: nowrap;
}
.profile-hero__brand-lockup image {
width: 32rpx;
height: 32rpx;
}
.profile-hero__brand-lockup text {
color: #f2d9a8;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(11px, 19rpx, 14px);
font-weight: 700;
letter-spacing: 3rpx;
line-height: 1;
}
.profile-hero__label {
display: flex;
width: 100%;
@@ -345,7 +419,7 @@ onUnload(() => {
justify-content: space-between;
color: #f0d6a4;
font-family: STKaiti, KaiTi, serif;
font-size: 54rpx;
font-size: clamp(27px, 54rpx, 34px);
font-weight: 700;
letter-spacing: 5rpx;
line-height: 1;
@@ -372,19 +446,27 @@ onUnload(() => {
align-items: flex-start;
position: relative;
margin-top: 43rpx;
margin-left: -30rpx;
margin-left: -22rpx;
column-gap: 20rpx;
}
.profile-hero__emblem {
width: 220rpx;
height: 220rpx;
display: block;
width: 196rpx;
height: 196rpx;
flex: 0 0 auto;
box-sizing: border-box;
border: 4rpx solid #d8ad5d;
border-radius: 50%;
background: #fff7e6;
box-shadow: 0 8rpx 18rpx rgba(44, 15, 12, 0.32);
overflow: hidden;
}
.profile-hero__copy {
min-width: 0;
flex: 1;
margin: 46rpx 0 0 -5rpx;
margin: 40rpx 0 0;
}
.profile-hero__copy text {
@@ -395,24 +477,26 @@ onUnload(() => {
.profile-hero__copy text:first-child {
color: #fff2da;
font-family: STSong, SimSun, serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
letter-spacing: 1rpx;
line-height: 1.25;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.profile-hero__copy text:nth-child(2) {
margin-top: 14rpx;
color: #ecd2a4;
font-size: 27rpx;
font-size: clamp(16px, 27rpx, 20px);
line-height: 1.35;
}
.profile-hero__copy text:last-child {
margin-top: 18rpx;
color: #e8bd78;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
letter-spacing: 1rpx;
}
@@ -429,7 +513,7 @@ onUnload(() => {
background: transparent url("/static/assets/modules/profile/transparent/m01-profile-edit-button-v2.png") center / 100% 100% no-repeat;
box-shadow: none;
color: #fff6e5;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
font-weight: 700;
letter-spacing: 1rpx;
}
@@ -439,11 +523,11 @@ onUnload(() => {
}
.profile-metadata {
display: flex;
min-height: 146rpx;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
z-index: 1;
margin: -36rpx 34rpx 0;
padding: 5rpx 0;
padding: 10rpx 12rpx 12rpx;
border: 1rpx solid rgba(117, 83, 52, 0.09);
border-radius: 18rpx;
background: rgba(239, 234, 224, 0.92);
@@ -452,31 +536,30 @@ onUnload(() => {
.profile-metadata__item {
display: flex;
min-width: 0;
align-items: center;
flex: 1;
gap: 10rpx;
padding: 0 10rpx;
border-right: 1rpx solid rgba(117, 83, 52, 0.16);
}
.profile-metadata__item:last-child {
align-items: flex-start;
gap: 12rpx;
padding: 14rpx 12rpx;
border-right: 0;
}
.profile-metadata__item:first-child {
border-right: 1rpx solid rgba(117, 83, 52, 0.16);
}
.profile-metadata__item--email {
flex: 2.3;
grid-column: 1 / -1;
border-top: 1rpx solid rgba(117, 83, 52, 0.16);
}
.profile-metadata__icon {
width: 42rpx;
height: 42rpx;
width: 56rpx;
height: 56rpx;
flex: 0 0 auto;
filter: sepia(0.7) saturate(0.8) hue-rotate(330deg) brightness(0.82);
transform: scale(2.1);
}
.profile-metadata__item view {
min-width: 0;
transform: translateY(14rpx);
}
.profile-metadata__item text {
@@ -485,20 +568,20 @@ onUnload(() => {
.profile-metadata__item text:first-child {
color: #857263;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.profile-metadata__item text:last-child {
margin-top: 0;
margin-top: 4rpx;
color: #382c25;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.25;
overflow-wrap: anywhere;
}
.profile-metadata__item--email text:last-child {
font-size: 13rpx;
white-space: nowrap;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.35;
}
.profile-services {
@@ -514,7 +597,7 @@ onUnload(() => {
align-items: center;
color: #382c25;
font-family: STSong, SimSun, serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
letter-spacing: 2rpx;
}
@@ -587,7 +670,7 @@ onUnload(() => {
}
.profile-service-row text {
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
line-height: 1.3;
}
+69 -17
View File
@@ -17,9 +17,19 @@
<template v-else>
<view class="form-panel">
<view class="avatar-row">
<view
><text>头像</text><text>{{ avatarMessage }}</text></view
>
<view class="avatar-summary">
<view class="avatar-preview">
<image
v-if="avatarPreviewUrl"
:src="avatarPreviewUrl"
mode="aspectFill"
/>
<AppAvatar v-else :sex="form.sex" />
</view>
<view class="avatar-summary__copy"
><text>头像</text><text>{{ avatarMessage }}</text></view
>
</view>
<button
class="upload-button"
:disabled="uploading || saving"
@@ -77,7 +87,7 @@
></picker
>
</view>
<view class="form-row"
<view class="form-row form-row--email"
><text>邮箱</text
><input
v-model.trim="form.email"
@@ -106,6 +116,7 @@
<script setup>
import { computed, reactive, ref } from "vue";
import { onLoad, onUnload } from "@dcloudio/uni-app";
import AppAvatar from "@/components/AppAvatar.vue";
import AppButton from "@/components/AppButton.vue";
import AppToast from "@/components/AppToast.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
@@ -139,6 +150,7 @@ const original = reactive({
});
const avatarId = ref(null);
const avatarFileName = ref("");
const avatarPreviewUrl = ref("");
const loading = ref(true);
const loadError = ref("");
const uploading = ref(false);
@@ -164,7 +176,7 @@ const sexIndex = computed(() => {
const avatarMessage = computed(() => {
if (avatarFileName.value) return `已选择 ${avatarFileName.value}`;
return avatarId.value ? "当前头像已设置" : "尚未设置头像";
return avatarId.value ? "当前头像已设置" : "当前使用默认头像";
});
const showFeedback = (message) => {
@@ -197,6 +209,7 @@ const loadProfile = async () => {
Object.assign(original, { ...form, avatar: profile.avatar });
avatarId.value = profile.avatar;
avatarFileName.value = "";
avatarPreviewUrl.value = "";
} catch (error) {
if (pageActive && !isRequestCancelled(error))
loadError.value = error?.message || "请稍后重试";
@@ -222,6 +235,7 @@ const uploadAvatar = async () => {
if (!pageActive) return;
avatarId.value = toConsumerOssId(receipt.ossId);
avatarFileName.value = receipt.fileName || "新头像";
avatarPreviewUrl.value = receipt.thumbnailUrl || receipt.url || "";
} catch (error) {
if (
pageActive &&
@@ -287,7 +301,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.profile-edit-page {
display: flex;
min-height: 100vh;
@@ -304,7 +318,7 @@ onUnload(() => {
}
.state-card,
.form-panel {
@include adaptive.adaptive-profile-content;
@include adaptive-profile-content;
}
.state-card {
box-sizing: border-box;
@@ -318,13 +332,13 @@ onUnload(() => {
.state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
@@ -342,19 +356,43 @@ onUnload(() => {
gap: 16rpx;
border-bottom: 1rpx solid rgba(181, 137, 63, 0.42);
}
.avatar-row > view text {
.avatar-summary {
display: flex;
min-width: 0;
align-items: center;
gap: 14rpx;
}
.avatar-preview {
width: 72rpx;
height: 72rpx;
flex: 0 0 auto;
overflow: hidden;
border: 2rpx solid rgba(181, 137, 63, 0.58);
border-radius: 50%;
background: #fff8ea;
}
.avatar-preview image,
.avatar-preview .app-avatar {
display: block;
width: 100%;
height: 100%;
}
.avatar-summary__copy {
min-width: 0;
}
.avatar-summary__copy text {
display: block;
}
.avatar-row > view text:first-child,
.avatar-summary__copy text:first-child,
.form-row > text {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.avatar-row > view text:last-child {
.avatar-summary__copy text:last-child {
margin-top: 4rpx;
color: $ink-muted;
font-size: 19rpx;
font-size: clamp(13px, 19rpx, 16px);
overflow-wrap: anywhere;
}
.upload-button {
@@ -365,7 +403,7 @@ onUnload(() => {
border: 0;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
text-align: right;
}
.form-row input,
@@ -374,9 +412,23 @@ onUnload(() => {
min-width: 0;
min-height: 68rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
text-align: right;
}
.form-row.form-row--email {
grid-template-columns: minmax(0, 1fr);
min-height: 132rpx;
align-content: center;
gap: 4rpx;
padding: 14rpx 0 16rpx;
}
.form-row--email input {
width: 100%;
min-height: 56rpx;
font-size: clamp(13px, 20rpx, 16px);
letter-spacing: 0;
text-align: left;
}
.picker-value {
display: flex;
align-items: center;
@@ -391,7 +443,7 @@ onUnload(() => {
.form-note {
display: block;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.5;
}
.field-error,
+8 -12
View File
@@ -22,10 +22,6 @@
><text>账号编号</text
><text>{{ profile.userNo || "未提供" }}</text></view
>
<view class="security-field"
><text>账号状态</text
><text>{{ profile.status || "未提供" }}</text></view
>
<text class="security-note"
>当前仅展示可确认的账户信息其他安全记录暂不可查看</text
>
@@ -55,7 +51,7 @@ import {
} from "@/utils/api.js";
import { openPage, returnTo } from "@/utils/navigation.js";
const profile = reactive({ phone: "", userNo: "", status: "" });
const profile = reactive({ phone: "", userNo: "" });
const loading = ref(false);
const loadError = ref("");
const controller = createRequestController();
@@ -91,7 +87,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.security-page {
display: flex;
min-height: 100vh;
@@ -110,7 +106,7 @@ onUnload(() => {
box-sizing: border-box;
min-height: 340rpx;
padding: 54rpx 42rpx 44rpx;
@include adaptive.adaptive-family-content;
@include adaptive-family-content;
}
.state-card {
text-align: center;
@@ -123,13 +119,13 @@ onUnload(() => {
.security-card__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
@@ -148,19 +144,19 @@ onUnload(() => {
}
.security-field text:first-child {
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.security-field text:last-child {
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
text-align: right;
overflow-wrap: anywhere;
}
.security-note {
margin-top: 22rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.6;
}
.security-card .app-button {
+11 -10
View File
@@ -183,7 +183,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.password-page {
display: flex;
min-height: 100vh;
@@ -199,7 +199,7 @@ onUnload(() => {
}
.security-tip,
.form-panel {
@include adaptive.adaptive-profile-content;
@include adaptive-profile-content;
}
.security-tip {
min-height: 170rpx;
@@ -211,13 +211,13 @@ onUnload(() => {
}
.security-tip text:first-child {
color: $ink;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
}
.security-tip text:last-child {
margin-top: 10rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.form-panel {
@@ -229,7 +229,7 @@ onUnload(() => {
}
.form-row {
display: grid;
grid-template-columns: 142rpx minmax(0, 1fr) 74rpx;
grid-template-columns: 184rpx minmax(0, 1fr) 74rpx;
min-height: 92rpx;
align-items: center;
gap: 12rpx;
@@ -237,15 +237,16 @@ onUnload(() => {
}
.form-row > text {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
white-space: nowrap;
}
.form-row input {
width: auto;
min-width: 0;
min-height: 68rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.password-toggle {
display: flex;
@@ -253,13 +254,13 @@ onUnload(() => {
align-items: center;
justify-content: flex-end;
color: $brand-red;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.field-error {
display: block;
padding-top: 7rpx;
color: #b42318;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.4;
text-align: right;
}
@@ -276,7 +277,7 @@ onUnload(() => {
padding-left: 26rpx;
}
.form-row {
grid-template-columns: 120rpx minmax(0, 1fr) 64rpx;
grid-template-columns: 184rpx minmax(0, 1fr) 64rpx;
gap: 8rpx;
}
}
+43 -20
View File
@@ -42,13 +42,12 @@
placeholder="4 位验证码"
@input="errors.smsCode = ''"
/>
<AppButton
compact
type="secondary"
<button
class="code-action"
:disabled="phoneState !== 'ready' || cooldownSeconds > 0"
:label="cooldownSeconds > 0 ? `${cooldownSeconds}s 后重试` : '获取验证码'"
hover-class="code-action--pressed"
@click="prepareGetCode"
/>
>{{ cooldownSeconds > 0 ? `${cooldownSeconds}s 后重试` : '获取验证码' }}</button>
</view>
<text v-if="errors.smsCode" class="field-error">{{ errors.smsCode }}</text>
</view>
@@ -320,7 +319,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.phone-page {
display: flex;
min-height: 100vh;
@@ -336,7 +335,7 @@ onUnload(() => {
}
.security-tip,
.form-panel {
@include adaptive.adaptive-profile-content;
@include adaptive-profile-content;
}
.security-tip {
min-height: 170rpx;
@@ -348,13 +347,13 @@ onUnload(() => {
}
.security-tip text:first-child {
color: $ink;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
}
.security-tip text:last-child {
margin-top: 10rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.form-panel {
@@ -366,37 +365,61 @@ onUnload(() => {
}
.form-row {
display: grid;
grid-template-columns: 142rpx minmax(0, 1fr);
grid-template-columns: 170rpx minmax(0, 1fr);
min-height: 92rpx;
align-items: center;
gap: 12rpx;
border-bottom: 1px solid rgba(181, 137, 63, 0.42);
}
.form-row--code {
grid-template-columns: 142rpx minmax(0, 1fr) 170rpx;
grid-template-columns: 170rpx minmax(0, 1fr) 198rpx;
}
.form-row > text {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
white-space: nowrap;
}
.form-row input {
width: auto;
min-width: 0;
min-height: 68rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.form-row--code .app-button {
.code-action {
justify-self: end;
width: 170rpx;
width: 198rpx;
min-height: 68rpx;
margin: 0;
padding: 0 14rpx;
box-sizing: border-box;
border: 1rpx solid rgba(159, 23, 15, 0.64);
border-radius: 10rpx;
background: rgba(255, 250, 238, 0.96);
box-shadow: inset 0 0 0 3rpx rgba(213, 176, 104, 0.18);
color: $brand-red;
font-size: clamp(13px, 20rpx, 15px);
font-weight: 700;
line-height: 1;
white-space: nowrap;
}
.code-action::after {
border: 0;
}
.code-action--pressed {
background: rgba(248, 232, 201, 0.96);
}
.code-action[disabled] {
border-color: rgba(128, 89, 49, 0.28);
color: #9d8b76;
opacity: 1;
}
.field-error {
display: block;
padding-top: 7rpx;
color: #b42318;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.4;
text-align: right;
}
@@ -413,14 +436,14 @@ onUnload(() => {
padding-left: 26rpx;
}
.form-row {
grid-template-columns: 120rpx minmax(0, 1fr);
grid-template-columns: 170rpx minmax(0, 1fr);
gap: 8rpx;
}
.form-row--code {
grid-template-columns: 120rpx minmax(0, 1fr) 150rpx;
grid-template-columns: 170rpx minmax(0, 1fr) 190rpx;
}
.form-row--code .app-button {
width: 150rpx;
.code-action {
width: 190rpx;
}
}
</style>
+56 -15
View File
@@ -4,8 +4,18 @@
<ModulePageBackground module="profile" />
<view class="page-layer"><PageHeader title="帮助中心" /></view>
<view class="page-content page-layer">
<text class="help-source-note">{{ sourceNote }}</text>
<view class="search-box"
<view v-if="helpState === 'loading'" class="help-state-card"
><AppLoading text="正在读取帮助内容"
/></view>
<view v-else-if="helpState === 'error'" class="help-state-card">
<text>帮助内容暂时无法读取</text>
<text>请检查网络后重新加载或直接提交问题反馈</text>
<AppButton block type="secondary" label="重新加载" @click="loadHelpArticles" />
<AppButton block label="提交问题反馈" @click="contactSupport" />
</view>
<template v-else>
<text class="help-source-note">{{ sourceNote }}</text>
<view class="search-box"
><input
v-model.trim="keyword"
aria-label="搜索帮助"
@@ -56,6 +66,7 @@
label="联系家谱助手"
@click="contactSupport"
/>
</template>
</view>
</view>
</template>
@@ -64,6 +75,7 @@
import { computed, ref } from "vue";
import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
import AppButton from "@/components/AppButton.vue";
import AppLoading from "@/components/AppLoading.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
import {
@@ -149,7 +161,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.help-page {
display: flex;
min-height: 100vh;
@@ -167,11 +179,40 @@ onUnload(() => {
display: block;
margin: 0 4rpx 16rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.55;
}
.help-state-card {
display: flex;
min-height: 300rpx;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 52rpx 42rpx;
text-align: center;
@include adaptive-profile-content;
}
.help-state-card text {
display: block;
}
.help-state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(18px, 32rpx, 22px);
font-weight: 700;
}
.help-state-card text:nth-child(2) {
margin-top: 16rpx;
color: $ink-muted;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.6;
}
.help-state-card .app-button {
width: 100%;
margin-top: 20rpx;
}
.search-box {
@include adaptive.adaptive-profile-field;
@include adaptive-profile-field;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
min-height: 86rpx;
@@ -184,11 +225,11 @@ onUnload(() => {
min-width: 0;
min-height: 68rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.search-box text {
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.category-scroll {
width: 100%;
@@ -209,10 +250,10 @@ onUnload(() => {
padding: 0 22rpx;
box-sizing: border-box;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.category-chip.active {
@include adaptive.adaptive-scroll-button(secondary);
@include adaptive-scroll-button(secondary);
color: $brand-red;
font-weight: 700;
}
@@ -224,7 +265,7 @@ onUnload(() => {
}
.question-card,
.empty-card {
@include adaptive.adaptive-profile-content;
@include adaptive-profile-content;
}
.question-card {
min-height: 104rpx;
@@ -239,20 +280,20 @@ onUnload(() => {
}
.question-heading text:first-child {
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
overflow-wrap: anywhere;
}
.question-heading text:last-child {
color: $brand-red;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.answer {
display: block;
padding: 14rpx 4rpx 6rpx;
border-top: 1px solid rgba(181, 137, 63, 0.32);
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.65;
overflow-wrap: anywhere;
}
@@ -266,13 +307,13 @@ onUnload(() => {
}
.empty-card text:first-child {
color: $ink;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
font-weight: 700;
}
.empty-card text:last-child {
margin-top: 12rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.5;
}
.page-content > .app-button {
+13 -13
View File
@@ -318,7 +318,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.feedback-page {
display: flex;
min-height: 100vh;
@@ -335,7 +335,7 @@ onUnload(() => {
.lead {
display: block;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.5;
text-align: center;
}
@@ -345,7 +345,7 @@ onUnload(() => {
.field-note {
display: block;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.5;
}
.type-grid {
@@ -360,13 +360,13 @@ onUnload(() => {
border: 0;
background: transparent;
line-height: normal;
@include adaptive.adaptive-profile-field;
@include adaptive-profile-field;
display: flex;
min-height: 88rpx;
align-items: center;
justify-content: center;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
text-align: center;
}
.type-chip::after {
@@ -381,7 +381,7 @@ onUnload(() => {
opacity: 0.55;
}
.form-panel {
@include adaptive.adaptive-profile-content;
@include adaptive-profile-content;
margin-top: 20rpx;
padding: 30rpx 34rpx;
}
@@ -391,7 +391,7 @@ onUnload(() => {
min-width: 0;
min-height: 210rpx;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.form-panel textarea[disabled],
@@ -401,7 +401,7 @@ onUnload(() => {
.counter {
display: block;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
text-align: right;
}
.contact-row {
@@ -415,7 +415,7 @@ onUnload(() => {
}
.contact-row text {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.contact-row input {
@@ -423,14 +423,14 @@ onUnload(() => {
min-width: 0;
min-height: 68rpx;
color: $ink;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
text-align: right;
}
.field-error {
display: block;
margin-top: 7rpx;
color: #b42318;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.4;
text-align: right;
}
@@ -438,7 +438,7 @@ onUnload(() => {
display: block;
margin-top: 15rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.5;
text-align: center;
}
@@ -447,7 +447,7 @@ onUnload(() => {
padding: 18rpx 20rpx;
border: 1px solid rgba(122, 91, 46, 0.24);
border-radius: 12rpx;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.55;
}
.feedback-result--success {
+8 -8
View File
@@ -103,7 +103,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.promotion-page {
display: flex;
min-height: 100vh;
@@ -120,7 +120,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
.invite-hero,
.state-card,
.promotion-card {
@include adaptive.adaptive-profile-content;
@include adaptive-profile-content;
}
.invite-hero {
display: flex;
@@ -142,13 +142,13 @@ onBackPress((event) => handleBackPress(event, requestBack));
margin-top: 12rpx;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.invite-hero text:last-child {
margin-top: 12rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.state-card {
@@ -161,7 +161,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
padding: 38rpx;
text-align: center;
color: $ink;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
}
.state-card .app-button {
width: 100%;
@@ -182,7 +182,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
}
.promotion-title {
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
font-weight: 700;
overflow-wrap: anywhere;
}
@@ -193,13 +193,13 @@ onBackPress((event) => handleBackPress(event, requestBack));
border: 1rpx solid rgba(181, 46, 34, 0.26);
border-radius: 999rpx;
color: $brand-red;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.3;
}
.promotion-copy {
margin-top: 12rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
overflow-wrap: anywhere;
}
+24 -24
View File
@@ -236,7 +236,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.orders-page {
display: flex;
min-height: 100vh;
@@ -252,7 +252,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
}
.state-card,
.order-empty {
@include adaptive.adaptive-profile-content;
@include adaptive-profile-content;
}
.vip-intro {
position: relative;
@@ -280,7 +280,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
}
.vip-intro__eyebrow {
color: $brand-red;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
font-weight: 700;
letter-spacing: 5rpx;
}
@@ -288,14 +288,14 @@ onBackPress((event) => handleBackPress(event, requestBack));
margin-top: 16rpx;
color: #33261d;
font-family: STKaiti, KaiTi, serif;
font-size: 38rpx;
font-size: clamp(20px, 38rpx, 26px);
font-weight: 700;
letter-spacing: 1rpx;
}
.vip-intro__copy {
margin-top: 14rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.55;
}
.state-card {
@@ -308,7 +308,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
padding: 36rpx;
text-align: center;
color: $ink;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
}
.state-card .app-button {
width: 100%;
@@ -352,19 +352,19 @@ onBackPress((event) => handleBackPress(event, requestBack));
.package-heading > view text:first-child {
color: #302319;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.package-heading > view text:last-child {
margin-top: 10rpx;
color: #77675a;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.55;
}
.package-price {
color: $brand-red;
font-family: Georgia, STKaiti, serif;
font-size: 38rpx;
font-size: clamp(20px, 38rpx, 26px);
font-weight: 700;
line-height: 1.1;
}
@@ -379,7 +379,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
}
.package-duration {
color: #837164;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.purchase-button {
display: inline-flex;
@@ -394,7 +394,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
border-radius: 999rpx;
background: $brand-red;
color: #fffaf1;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
letter-spacing: 1rpx;
line-height: normal;
@@ -411,19 +411,19 @@ onBackPress((event) => handleBackPress(event, requestBack));
margin: 44rpx 6rpx 16rpx;
color: #38281d;
font-family: STKaiti, KaiTi, serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
}
.section-heading text:last-child {
color: #8a796b;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
font-weight: 400;
}
.order-notice {
display: block;
margin: 0 6rpx 14rpx;
color: #786556;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.5;
}
.order-card {
@@ -433,7 +433,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
padding: 26rpx 4rpx;
border-bottom: 1rpx solid rgba(117, 84, 52, 0.14);
color: #48372a;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.order-card > view text {
display: block;
@@ -444,18 +444,18 @@ onBackPress((event) => handleBackPress(event, requestBack));
.order-card > view text:last-child {
margin-top: 8rpx;
color: #8a796b;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.order-card text:last-child {
flex: 0 0 auto;
color: #7f6959;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.order-empty {
padding: 38rpx;
text-align: center;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
:deep(.orders-header .page-header) {
height: calc(104rpx + var(--status-bar-height, 0px));
@@ -468,7 +468,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
:deep(.orders-header .header-title) {
color: #302319;
font-family: STKaiti, KaiTi, serif;
font-size: 37rpx;
font-size: clamp(20px, 37rpx, 26px);
}
:deep(.orders-header .header-back__icon) {
filter: none;
@@ -509,7 +509,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
:deep(.payment-sheet .app-dialog__title) {
color: #302319;
font-family: STKaiti, KaiTi, serif;
font-size: 42rpx;
font-size: clamp(22px, 42rpx, 28px);
letter-spacing: 1rpx;
text-align: left;
}
@@ -536,7 +536,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
}
:deep(.payment-sheet .app-button--secondary .app-button__label) {
color: #8a796b;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 400;
}
.sheet-order-summary {
@@ -556,7 +556,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
padding: 0 24rpx;
border-bottom: 1rpx solid rgba(117, 84, 52, 0.1);
color: #5a4432;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.sheet-order-summary > view:last-child {
border-bottom: 0;
@@ -570,7 +570,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
.sheet-order-summary > view:last-child text:last-child {
color: $brand-red;
font-family: Georgia, STKaiti, serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
}
.payment-method {
width: 100%;
@@ -590,7 +590,7 @@ onBackPress((event) => handleBackPress(event, requestBack));
width: 100%;
margin-top: 16rpx;
color: #8a796b;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.55;
}
.purchase-error {
+8 -8
View File
@@ -136,7 +136,7 @@ onUnload(() => logoutRequestController.abort());
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.about-page {
display: flex;
min-height: 100vh;
@@ -151,7 +151,7 @@ onUnload(() => logoutRequestController.abort());
padding: 28rpx 30rpx 72rpx;
}
.brand-card {
@include adaptive.adaptive-profile-summary;
@include adaptive-profile-summary;
display: flex;
min-height: 300rpx;
flex-direction: column;
@@ -171,20 +171,20 @@ onUnload(() => logoutRequestController.abort());
margin-top: 6rpx;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 40rpx;
font-size: clamp(20px, 40rpx, 26px);
font-weight: 700;
letter-spacing: 4rpx;
}
.brand-card text:nth-child(3) {
margin-top: 8rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.5;
}
.brand-card text:last-child {
margin-top: 10rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.settings-list {
display: flex;
@@ -193,7 +193,7 @@ onUnload(() => logoutRequestController.abort());
margin-top: 22rpx;
}
.settings-row {
@include adaptive.adaptive-profile-field;
@include adaptive-profile-field;
display: grid;
grid-template-columns: minmax(0, 1fr) 32rpx;
min-height: 104rpx;
@@ -210,13 +210,13 @@ onUnload(() => logoutRequestController.abort());
}
.settings-row text:first-child {
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.settings-row text:last-child {
margin-top: 6rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.settings-row image {
width: 30rpx;
+10 -10
View File
@@ -211,7 +211,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.people-page {
display: flex;
@@ -228,7 +228,7 @@ onUnload(() => {
padding: 22rpx 24rpx 100rpx;
}
.people-search {
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
display: grid;
grid-template-columns: minmax(0, 1fr) 126rpx;
width: 100%;
@@ -243,7 +243,7 @@ onUnload(() => {
padding-left: 31rpx;
box-sizing: border-box;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.people-search__placeholder {
color: #8a7965;
@@ -257,14 +257,14 @@ onUnload(() => {
align-items: center;
justify-content: center;
color: $brand-red;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.people-list {
margin-top: 12px;
}
.person-card {
@include adaptive.adaptive-records-person;
@include adaptive-records-person;
display: flex;
width: 100%;
min-height: clamp(92px, 190rpx, 108px);
@@ -283,18 +283,18 @@ onUnload(() => {
.person-card__name {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.person-card__meta {
margin-top: 7rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.person-card__hint {
margin-top: 8rpx;
color: #806a51;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.people-primary-action {
margin: 22rpx auto 0;
@@ -322,14 +322,14 @@ onUnload(() => {
.people-state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.people-result-empty text:last-child,
.people-state-card text:last-child {
margin-top: 13rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.5;
}
.people-result-empty .app-button,
+13 -13
View File
@@ -204,7 +204,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.person-detail-page {
display: flex;
@@ -224,7 +224,7 @@ onUnload(() => {
padding: 18rpx 24rpx 72rpx;
}
.person-identity-card {
@include adaptive.adaptive-records-person;
@include adaptive-records-person;
display: flex;
min-height: 190rpx;
padding: 30rpx 10%;
@@ -241,19 +241,19 @@ onUnload(() => {
.person-identity-card__name {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 38rpx;
font-size: clamp(20px, 38rpx, 26px);
font-weight: 700;
}
.person-identity-card__meta {
margin-top: 8rpx;
color: $ink-muted;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 600;
}
.person-identity-card__hint {
margin-top: 8rpx;
color: #806a51;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.person-archive-card {
min-height: 154rpx;
@@ -263,20 +263,20 @@ onUnload(() => {
}
.person-archive-card,
.person-state-card {
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.person-archive-card text {
display: block;
}
.person-archive-card text:first-child {
color: $brand-red;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.person-archive-card text:last-child {
margin-top: 11rpx;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.55;
}
.person-edit-action {
@@ -301,12 +301,12 @@ onUnload(() => {
color: $ink-muted;
}
.person-related-unavailable text:first-child {
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 700;
}
.person-related-unavailable text:last-child {
margin-top: 4rpx;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.person-state-card {
display: flex;
@@ -323,13 +323,13 @@ onUnload(() => {
.person-state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.person-state-card text:last-child {
margin-top: 16rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.6;
}
.person-state-action {
@@ -347,7 +347,7 @@ onUnload(() => {
padding-left: 18rpx;
}
.person-identity-card__name {
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
}
}
</style>
+6 -6
View File
@@ -117,7 +117,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.gift-page {
display: flex;
min-height: 100vh;
@@ -133,7 +133,7 @@ onUnload(() => {
}
.state-card,
.record-card {
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.state-card {
display: flex;
@@ -144,7 +144,7 @@ onUnload(() => {
padding: 42rpx;
text-align: center;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.state-card .app-button {
width: 100%;
@@ -173,20 +173,20 @@ onUnload(() => {
.record-card > view text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
overflow-wrap: anywhere;
}
.record-card > view text:not(:first-child) {
margin-top: 7rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
overflow-wrap: anywhere;
}
.record-card > text {
flex: 0 0 auto;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
</style>
+15 -15
View File
@@ -291,7 +291,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.gift-editor-page {
display: flex;
min-height: 100vh;
@@ -309,20 +309,20 @@ onUnmounted(() => {
.state-card {
box-sizing: border-box;
padding: 46rpx;
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.form-card > text:first-child,
.state-card > text:first-child {
display: block;
color: $ink;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.form-copy {
display: block;
margin-top: 12rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.field-row {
@@ -334,26 +334,26 @@ onUnmounted(() => {
margin-top: 14rpx;
padding: 14rpx 24rpx;
box-sizing: border-box;
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
}
.field-row > text,
.upload-field > view > text:first-child {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
transform: translateY(-3rpx);
}
.field-row input,
.field-row textarea {
min-width: 0;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
text-align: right;
}
.field-row--textarea {
@@ -372,14 +372,14 @@ onUnmounted(() => {
align-items: center;
justify-content: flex-end;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.upload-field {
display: grid;
gap: 12rpx;
margin-top: 14rpx;
padding: 18rpx 24rpx;
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
}
.upload-field > view > text {
display: block;
@@ -387,7 +387,7 @@ onUnmounted(() => {
.upload-field > view > text:last-child {
margin-top: 6rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -399,18 +399,18 @@ onUnmounted(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-field > text {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.save-error {
display: block;
margin-top: 14rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.form-card .app-button {
margin-top: 18rpx;
@@ -424,7 +424,7 @@ onUnmounted(() => {
display: block;
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
+13 -7
View File
@@ -38,7 +38,7 @@
><view
><text>{{ item.title }}</text
><text>{{ item.type }}{{ item.time ? ` · ${item.time}` : "" }}</text
><text v-if="item.description">{{ item.description }}</text></view
><text v-if="item.description" class="ceremony-card__description">{{ item.description }}</text></view
><text>{{ item.giftCount }} 笔献礼</text></view
></view
>
@@ -117,7 +117,7 @@ onUnload(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.ritual-list-page {
display: flex;
min-height: 100vh;
@@ -133,7 +133,7 @@ onUnload(() => {
}
.state-card,
.ceremony-card {
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.state-card {
display: flex;
@@ -144,7 +144,7 @@ onUnload(() => {
padding: 42rpx;
text-align: center;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.state-card .app-button {
width: 100%;
@@ -173,20 +173,26 @@ onUnload(() => {
.ceremony-card > view text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
overflow-wrap: anywhere;
}
.ceremony-card > view text:not(:first-child) {
margin-top: 7rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
overflow-wrap: anywhere;
}
.ceremony-card__description {
display: -webkit-box !important;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.ceremony-card > text {
flex: 0 0 auto;
color: $brand-red;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
</style>
+16 -5
View File
@@ -5,11 +5,13 @@
><view class="page-content"
><view v-if="!valid" class="state-card"
><text>礼仪入口无效</text
><text>未获取到可查看的礼仪活动标识请从活动列表重新进入</text
><AppButton block label="返回上一页" @click="returnToList" /></view
><view v-else-if="state === 'loading'" class="state-card"
><AppLoading text="正在读取礼仪详情" /></view
><view v-else-if="state === 'error'" class="state-card"
><text>暂时无法读取礼仪详情</text
><text>请检查网络后重新加载</text
><AppButton
block
type="secondary"
@@ -97,7 +99,7 @@ const returnToList = () =>
: goBack();
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.ritual-detail-page {
display: flex;
min-height: 100vh;
@@ -113,7 +115,7 @@ const returnToList = () =>
}
.state-card,
.detail-card {
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.state-card {
display: flex;
@@ -124,12 +126,21 @@ const returnToList = () =>
padding: 42rpx;
text-align: center;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
}
.state-card .app-button {
width: 100%;
margin-top: 24rpx;
}
.state-card text {
display: block;
}
.state-card text:nth-child(2) {
margin-top: 14rpx;
color: $ink-muted;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.detail-card {
display: flex;
min-height: 320rpx;
@@ -142,13 +153,13 @@ const returnToList = () =>
.detail-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.detail-card text:not(:first-child) {
margin-top: 14rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.6;
}
</style>
+16 -16
View File
@@ -302,7 +302,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.ritual-editor-page {
display: flex;
min-height: 100vh;
@@ -319,7 +319,7 @@ onUnmounted(() => {
}
.editor-card,
.state-card {
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
box-sizing: border-box;
}
.editor-card {
@@ -335,13 +335,13 @@ onUnmounted(() => {
.editor-card__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 38rpx;
font-size: clamp(20px, 38rpx, 26px);
font-weight: 700;
}
.editor-card__note {
margin-top: 10rpx;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.55;
}
.field-row {
@@ -358,14 +358,14 @@ onUnmounted(() => {
width: 150rpx;
flex: 0 0 auto;
color: $ink;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
font-weight: 700;
}
.field-row input {
min-width: 0;
flex: 1;
color: $ink;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
}
.field-row--picker picker {
min-width: 0;
@@ -376,13 +376,13 @@ onUnmounted(() => {
display: flex;
align-items: center;
color: $ink;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
transform: translateY(-3rpx);
}
.placeholder {
@@ -399,7 +399,7 @@ onUnmounted(() => {
.textarea-field__label,
.cover-field__label {
color: $ink;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
font-weight: 700;
}
.textarea-field textarea {
@@ -408,7 +408,7 @@ onUnmounted(() => {
min-height: 122rpx;
margin-top: 12rpx;
color: $ink;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
line-height: 1.55;
}
.cover-field {
@@ -419,7 +419,7 @@ onUnmounted(() => {
display: block;
margin-top: 5rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -431,17 +431,17 @@ onUnmounted(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.form-error {
margin-top: 10rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.45;
}
.editor-card .app-button {
@@ -457,13 +457,13 @@ onUnmounted(() => {
}
.state-card text:first-child {
color: $ink;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
+32 -21
View File
@@ -131,6 +131,7 @@
</view>
<view v-else-if="!valid" class="state-card"
><text>成长日志入口无效</text
><text>未获取到可查看的家谱标识请从家族页面重新进入</text
><AppButton block label="返回上一页" @click="requestBack"
/></view>
<view v-else-if="listState === 'loading'" class="state-card"
@@ -138,6 +139,7 @@
/></view>
<view v-else-if="listState === 'error'" class="state-card"
><text>暂时无法读取成长记录</text
><text>请检查网络后重新加载</text
><AppButton
block
type="secondary"
@@ -399,7 +401,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.record-page {
display: flex;
min-height: 100vh;
@@ -416,7 +418,7 @@ onUnmounted(() => {
.form-card,
.state-card,
.record-card {
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.form-card {
box-sizing: border-box;
@@ -425,14 +427,14 @@ onUnmounted(() => {
.form-card > text:first-child {
display: block;
color: $ink;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.form-copy {
display: block;
margin-top: 12rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.field {
@@ -442,26 +444,26 @@ onUnmounted(() => {
display: block;
margin: 0 8rpx 8rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
transform: translateY(-3rpx);
}
.field input,
.field textarea,
.field--picker picker > view {
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
box-sizing: border-box;
width: 100%;
min-height: 76rpx;
padding: 16rpx 22rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.field textarea {
min-height: 150rpx;
@@ -473,7 +475,7 @@ onUnmounted(() => {
color: $ink-muted;
}
.field--context > view {
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
display: flex;
min-height: 76rpx;
align-items: center;
@@ -483,31 +485,31 @@ onUnmounted(() => {
}
.field--context > view > text:first-child {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.field--context > view > text:last-child {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
}
.upload-field {
display: grid;
gap: 12rpx;
margin-top: 16rpx;
padding: 18rpx 22rpx;
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
}
.upload-field > view > text {
display: block;
}
.upload-field > view > text:first-child {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.upload-field > view > text:last-child {
margin-top: 6rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -519,19 +521,19 @@ onUnmounted(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-field > text,
.error {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.error {
display: block;
margin-top: 12rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.form-actions {
display: grid;
@@ -551,13 +553,22 @@ onUnmounted(() => {
justify-content: center;
padding: 42rpx;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
text-align: center;
}
.state-card .app-button {
width: 100%;
margin-top: 24rpx;
}
.state-card text {
display: block;
}
.state-card text:nth-child(2) {
margin-top: 14rpx;
color: $ink-muted;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.record-list {
display: flex;
flex-direction: column;
@@ -566,7 +577,7 @@ onUnmounted(() => {
.save-notice {
display: block;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.record-card {
min-height: 128rpx;
@@ -578,13 +589,13 @@ onUnmounted(() => {
.record-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.record-card text:not(:first-child) {
margin-top: 7rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
overflow-wrap: anywhere;
}
+4 -4
View File
@@ -32,7 +32,7 @@ const returnToRecords = () =>
: goBack();
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.life-page {
display: flex;
min-height: 100vh;
@@ -51,20 +51,20 @@ const returnToRecords = () =>
min-height: 340rpx;
padding: 78rpx 52rpx 50rpx;
text-align: center;
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.state-card text {
display: block;
}
.state-card text:first-child {
color: $ink;
font-size: 35rpx;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
+25 -19
View File
@@ -110,7 +110,7 @@
><view
><text>{{ item.title }}</text
><text v-if="item.remindTime">{{ item.remindTime }}</text
><text v-if="item.content">{{ item.content }}</text></view
><text v-if="item.content" class="memo-card__content">{{ item.content }}</text></view
></view
>
</view>
@@ -319,7 +319,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.memo-page {
display: flex;
min-height: 100vh;
@@ -336,7 +336,7 @@ onUnmounted(() => {
.form-card,
.state-card,
.memo-card {
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.form-card {
box-sizing: border-box;
@@ -345,14 +345,14 @@ onUnmounted(() => {
.form-card > text:first-child {
display: block;
color: $ink;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.form-copy {
display: block;
margin-top: 12rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.field {
@@ -364,26 +364,26 @@ onUnmounted(() => {
margin-top: 14rpx;
padding: 14rpx 24rpx;
box-sizing: border-box;
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
}
.field > text,
.upload-field > view > text:first-child {
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
transform: translateY(-3rpx);
}
.field input,
.field > text:last-child {
min-width: 0;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
text-align: right;
}
.field--textarea {
@@ -392,7 +392,7 @@ onUnmounted(() => {
.field textarea {
min-height: 116rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.55;
}
.upload-field {
@@ -400,7 +400,7 @@ onUnmounted(() => {
gap: 12rpx;
margin-top: 14rpx;
padding: 18rpx 24rpx;
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
}
.upload-field > view > text {
display: block;
@@ -408,7 +408,7 @@ onUnmounted(() => {
.upload-field > view > text:last-child {
margin-top: 6rpx;
color: $ink-muted;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
line-height: 1.45;
}
.upload-button {
@@ -420,18 +420,18 @@ onUnmounted(() => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.upload-field > text {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
overflow-wrap: anywhere;
}
.error {
display: block;
margin-top: 12rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.form-actions {
display: grid;
@@ -451,7 +451,7 @@ onUnmounted(() => {
justify-content: center;
padding: 42rpx;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
text-align: center;
}
.state-card .app-button {
@@ -466,7 +466,7 @@ onUnmounted(() => {
.save-notice {
display: block;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.memo-card {
min-height: 128rpx;
@@ -478,14 +478,20 @@ onUnmounted(() => {
.memo-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.memo-card text:not(:first-child) {
margin-top: 7rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
overflow-wrap: anywhere;
}
.memo-card__content {
display: -webkit-box !important;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
</style>
+15 -15
View File
@@ -333,7 +333,7 @@ onUnmounted(() => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.merit-page {
display: flex;
min-height: 100vh;
@@ -350,7 +350,7 @@ onUnmounted(() => {
.form-card,
.state-card,
.merit-card {
@include adaptive.adaptive-records-content;
@include adaptive-records-content;
}
.form-card {
box-sizing: border-box;
@@ -359,14 +359,14 @@ onUnmounted(() => {
.form-card > text:first-child {
display: block;
color: $ink;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.form-copy {
display: block;
margin-top: 12rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.field {
@@ -376,26 +376,26 @@ onUnmounted(() => {
display: block;
margin: 0 8rpx 8rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
font-weight: 700;
}
.required-mark {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
transform: translateY(-3rpx);
}
.field input,
.field textarea,
.field--picker picker > view {
@include adaptive.adaptive-records-field;
@include adaptive-records-field;
box-sizing: border-box;
width: 100%;
min-height: 76rpx;
padding: 16rpx 22rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.field textarea {
min-height: 150rpx;
@@ -410,7 +410,7 @@ onUnmounted(() => {
display: block;
margin-top: 12rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.form-actions {
display: grid;
@@ -430,7 +430,7 @@ onUnmounted(() => {
justify-content: center;
padding: 42rpx;
color: $ink;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
text-align: center;
}
.state-card .app-button {
@@ -445,12 +445,12 @@ onUnmounted(() => {
.save-notice {
display: block;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.merit-summary {
display: block;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.merit-card {
display: flex;
@@ -470,20 +470,20 @@ onUnmounted(() => {
.merit-card > view text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
overflow-wrap: anywhere;
}
.merit-card > view text:not(:first-child) {
margin-top: 7rpx;
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.45;
overflow-wrap: anywhere;
}
.merit-card > text {
flex: 0 0 auto;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
</style>
+58 -52
View File
@@ -11,7 +11,7 @@
>
<ModulePageBackground module="tree" />
<view class="tree-page__header">
<PageHeader title="树状图" action="世系" @action="toPedigree" />
<PageHeader title="树状图" action="世系表格" @action="toPedigree" />
</view>
<view v-if="treeState !== 'loading'" class="tree-toolbar">
@@ -49,10 +49,7 @@
class="generation-band"
:style="generationBandStyle(row)"
>
<image
src="/static/assets/modules/genealogy/transparent/section-divider.png"
mode="scaleToFill"
/>
<view class="generation-band__line" aria-hidden="true" />
<view class="generation-band__copy">
<text>{{ row.label }}</text>
<text>{{ row.summary }}</text>
@@ -109,11 +106,7 @@
>
<view class="member-node__surface">
<view class="member-node__portrait">
<image
class="member-node__avatar"
src="/static/assets/foundation/transparent/tab-profile.png"
mode="aspectFit"
/>
<AppAvatar :sex="member.sex" />
</view>
<image
class="member-node__divider"
@@ -125,7 +118,7 @@
<text class="node-relation">{{
nodeRelationText(member)
}}</text>
<text class="node-years">{{ member.years }}</text>
<text class="node-years">{{ member.treeYears || member.years }}</text>
</view>
</view>
</view>
@@ -181,11 +174,9 @@
:aria-label="`查看${selected.name}的资料`"
@click="toMember"
>
<image
class="member-action-profile__avatar"
src="/static/assets/modules/tree/transparent/t01-member-medallion-v2.png"
mode="aspectFit"
/>
<view class="member-action-profile__avatar">
<AppAvatar :sex="selected.sex" />
</view>
<view class="member-action-profile__copy">
<text>{{ selected.name }}</text>
<text> {{ selected.generation }} · {{ selected.relation }}</text>
@@ -290,6 +281,7 @@
<script setup>
import { computed, nextTick, ref } from "vue";
import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
import AppAvatar from "@/components/AppAvatar.vue";
import AppDialog from "@/components/AppDialog.vue";
import AppLoading from "@/components/AppLoading.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
@@ -320,10 +312,10 @@ let pageActive = true;
let skipNextShowRefresh = true;
const GRID_UNIT = 5;
const NODE_HALF_WIDTH = 80;
const NODE_HALF_HEIGHT = 94;
const NODE_HALF_HEIGHT = 112;
const FAMILY_LINK_OFFSET = 18;
const MEMBER_GAP = 178;
const GENERATION_GAP = 260;
const GENERATION_GAP = 296;
const members = ref([]);
const memberActions = Object.freeze([
@@ -603,7 +595,7 @@ const generationRangeLabel = computed(() => {
return first === last ? `${first}` : `${first}${last}`;
});
const generationBandStyle = (row) => ({
gridRow: `${Math.max(1, Math.round((row.y - 88) / GRID_UNIT) + 1)} / span 12`,
gridRow: `${Math.max(1, Math.round((row.y - NODE_HALF_HEIGHT) / GRID_UNIT) + 1)} / span 21`,
});
const lineageConnectors = computed(() => {
const memberById = new Map(
@@ -969,19 +961,19 @@ const openMemberAction = (action) => {
.tree-toolbar__title text:first-child {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 28rpx;
font-size: clamp(16px, 28rpx, 20px);
font-weight: 700;
}
.tree-toolbar__title text:last-child {
margin-top: 5rpx;
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.tree-toolbar__actions {
display: flex;
gap: 24rpx;
color: $brand-red;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.tree-stage {
min-height: 0;
@@ -992,7 +984,7 @@ const openMemberAction = (action) => {
}
.tree-stage--lineage {
display: grid;
grid-template-columns: 144rpx minmax(0, 1fr);
grid-template-columns: 72rpx minmax(0, 1fr);
align-items: start;
}
.tree-scroll {
@@ -1003,7 +995,7 @@ const openMemberAction = (action) => {
.generation-rail {
display: grid;
z-index: 4;
width: 144rpx;
width: 72rpx;
height: 100%;
box-sizing: border-box;
border-right: 1rpx solid rgba(143, 108, 63, 0.2);
@@ -1027,38 +1019,49 @@ const openMemberAction = (action) => {
z-index: 3;
margin: 8rpx 22rpx 0 0;
color: #9a7748;
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
letter-spacing: 1rpx;
}
.generation-band {
position: relative;
display: grid;
justify-self: center;
z-index: 3;
width: 126rpx;
height: 58rpx;
width: 62rpx;
height: 104rpx;
color: #8f6c3f;
font-size: 22rpx;
font-size: clamp(12px, 18rpx, 14px);
text-align: center;
}
.generation-band image,
.generation-band__line,
.generation-band__copy {
grid-area: 1 / 1;
}
.generation-band image {
width: 100%;
height: 100%;
.generation-band__line {
align-self: stretch;
justify-self: center;
width: 0;
margin: 3rpx 0;
border-left: 1rpx solid rgba(183, 138, 66, 0.7);
}
.generation-band__copy {
z-index: 1;
display: flex;
flex-direction: column;
flex-direction: row;
align-items: center;
justify-content: center;
justify-content: space-between;
gap: 0;
height: 100%;
padding: 0 4rpx;
box-sizing: border-box;
}
.generation-band__copy text {
writing-mode: vertical-rl;
text-orientation: upright;
white-space: nowrap;
}
.generation-band__copy text:last-child {
margin-top: 1rpx;
font-size: 18rpx;
font-size: clamp(11px, 14rpx, 13px);
}
.lineage-connector {
align-self: stretch;
@@ -1075,7 +1078,7 @@ const openMemberAction = (action) => {
justify-self: start;
z-index: 2;
width: 160rpx;
height: 188rpx;
height: 224rpx;
transform: translate(-50%, -50%);
text-align: center;
}
@@ -1104,10 +1107,6 @@ const openMemberAction = (action) => {
background: #fffdf7;
overflow: hidden;
}
.member-node__avatar {
width: 48rpx;
height: 48rpx;
}
.member-node__divider {
width: 56rpx;
height: 14rpx;
@@ -1128,7 +1127,7 @@ const openMemberAction = (action) => {
color: #6b2419;
font-family: "STKaiti", "KaiTi", serif;
overflow: hidden;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
line-height: 1.1;
-webkit-box-orient: vertical;
@@ -1139,7 +1138,7 @@ const openMemberAction = (action) => {
overflow: hidden;
margin-top: 2rpx;
color: #644b2e;
font-size: 18rpx;
font-size: clamp(12px, 18rpx, 14px);
line-height: 1.2;
text-overflow: ellipsis;
white-space: nowrap;
@@ -1148,7 +1147,7 @@ const openMemberAction = (action) => {
overflow: hidden;
margin-top: 2rpx;
color: #695b4c;
font-size: 17rpx;
font-size: clamp(12px, 17rpx, 14px);
line-height: 1.2;
text-overflow: ellipsis;
white-space: nowrap;
@@ -1194,7 +1193,7 @@ const openMemberAction = (action) => {
.tree-state-card__eyebrow {
display: block;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
letter-spacing: 3rpx;
}
.tree-state-card__title {
@@ -1202,14 +1201,14 @@ const openMemberAction = (action) => {
margin-top: 12rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.tree-state-card__copy {
display: block;
margin-top: 16rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.tree-state-card__action {
@@ -1233,7 +1232,7 @@ const openMemberAction = (action) => {
justify-content: center;
height: 100%;
color: #fff9ed;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.member-action-panel-layer {
@@ -1324,10 +1323,17 @@ const openMemberAction = (action) => {
box-sizing: border-box;
}
.member-action-profile__avatar {
display: block;
width: 92rpx;
height: 92rpx;
aspect-ratio: 1;
flex: 0 0 92rpx;
box-sizing: border-box;
border: 3rpx solid #d0a65d;
border-radius: 50%;
background: #fff8e8;
box-shadow: 0 3rpx 8rpx rgba(105, 65, 29, 0.18);
overflow: hidden;
}
.member-action-profile__copy {
min-width: 0;
@@ -1339,13 +1345,13 @@ const openMemberAction = (action) => {
.member-action-profile__copy text:first-child {
color: #70261f;
font-family: "STKaiti", "KaiTi", serif;
font-size: 38rpx;
font-size: clamp(20px, 38rpx, 26px);
font-weight: 700;
}
.member-action-profile__copy text:nth-child(2) {
margin-top: 4rpx;
color: #74533a;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.member-action-profile__copy text:last-child {
display: none;
@@ -1402,7 +1408,7 @@ const openMemberAction = (action) => {
.member-action-map__item text {
z-index: 1;
color: #672820;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
font-weight: 700;
white-space: nowrap;
}
@@ -1463,7 +1469,7 @@ const openMemberAction = (action) => {
}
.member-action-grid__item text {
color: #672820;
font-size: 25rpx;
font-size: clamp(15px, 25rpx, 18px);
font-weight: 700;
}
.member-action-panel__hint {
+12 -14
View File
@@ -252,10 +252,7 @@ const handlePedigreePageChange = (event) => {
};
const memberRelation = (member) =>
member.spouseOf ? "配偶" : member.relation || "家谱成员";
const memberDetail = (member) =>
[member.years, member.sex, member.personStatus]
.filter((item) => item && item !== "生卒待补")
.join(" · ") || "生卒待补";
const memberDetail = (member) => member.treeYears || member.years || "生卒待补";
const openMemberProfile = (member) =>
openPage(
"T03",
@@ -431,7 +428,7 @@ onUnload(() => {
.member-node__relation {
align-items: center;
border-bottom: 1rpx solid #e2e2e2;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.pedigree-column__name,
.member-node__name {
@@ -439,7 +436,7 @@ onUnload(() => {
border-bottom: 1rpx solid #e2e2e2;
color: #2f2925;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.pedigree-column__detail,
@@ -447,12 +444,12 @@ onUnload(() => {
align-items: flex-start;
gap: 18rpx;
padding: 28rpx 20rpx;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.7;
white-space: normal;
}
.pedigree-column__detail {
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
.member-node__surface {
display: contents;
@@ -476,6 +473,7 @@ onUnload(() => {
}
.node-years {
color: #3f3934;
text-combine-upright: all;
}
.generation-rail {
width: 92rpx;
@@ -511,12 +509,12 @@ onUnload(() => {
flex-direction: column;
align-items: center;
color: #a7241d;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
writing-mode: vertical-rl;
text-orientation: upright;
}
.generation-band__copy text:last-child {
font-size: 18rpx;
font-size: clamp(12px, 18rpx, 14px);
}
.pedigree-state-card {
display: grid;
@@ -544,20 +542,20 @@ onUnload(() => {
}
.pedigree-state-card__eyebrow {
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
letter-spacing: 3rpx;
}
.pedigree-state-card__title {
margin-top: 12rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
.pedigree-state-card__copy {
margin-top: 16rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.pedigree-state-card__action {
@@ -580,7 +578,7 @@ onUnload(() => {
align-items: center;
justify-content: center;
color: #fff9ed;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
</style>
+40 -39
View File
@@ -38,9 +38,9 @@
class="member-detail"
>
<view class="member-heading">
<view class="member-heading__seal"
><text>{{ member.name.slice(0, 1) }}</text></view
>
<view class="member-heading__seal">
<AppAvatar :sex="member.sex" />
</view>
<view>
<text>{{ member.name }}</text>
<text
@@ -103,9 +103,9 @@
class="member-restricted"
>
<view class="member-heading">
<view class="member-heading__seal"
><text>{{ member.name.slice(0, 1) }}</text></view
>
<view class="member-heading__seal">
<AppAvatar :sex="member.sex" />
</view>
<view>
<text>{{ member.name }}</text>
<text> {{ member.generation }} · {{ member.relation }}</text>
@@ -132,6 +132,7 @@
<script setup>
import { computed, reactive, ref } from "vue";
import { onBackPress, onLoad, onShow, onUnload } from "@dcloudio/uni-app";
import AppAvatar from "@/components/AppAvatar.vue";
import AppLoading from "@/components/AppLoading.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
@@ -415,7 +416,7 @@ const toTree = requestBack;
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.member-page {
display: flex;
@@ -431,7 +432,7 @@ const toTree = requestBack;
z-index: 2;
}
.member-context {
@include adaptive.adaptive-tree-field;
@include adaptive-tree-field;
width: calc(100% - 32rpx);
margin: 18rpx auto 0;
padding: 16rpx 24rpx;
@@ -439,16 +440,16 @@ const toTree = requestBack;
.member-context text {
display: block;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.45;
}
.member-context text:first-child {
color: $ink;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
font-weight: 700;
}
.member-panel {
@include adaptive.adaptive-tree-panel;
@include adaptive-tree-panel;
width: calc(100% - 32rpx);
margin: 16rpx auto 0;
padding: 9% 8%;
@@ -468,30 +469,30 @@ const toTree = requestBack;
flex: 0 0 74rpx;
align-items: center;
justify-content: center;
background: url("/static/assets/modules/genealogy/transparent/current-seal-frame.png")
center / contain no-repeat;
}
.member-heading__seal text {
color: #fff7e7;
font-size: 28rpx;
box-sizing: border-box;
border: 2rpx solid #c39851;
border-radius: 50%;
background: #fff8e8;
box-shadow: 0 3rpx 7rpx rgba(100, 65, 29, 0.14);
overflow: hidden;
}
.member-heading > view:last-child text {
display: block;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.45;
}
.member-heading > view:last-child text:last-child {
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.member-heading > view:last-child text:first-child {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 36rpx;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.member-status-entry {
@include adaptive.adaptive-genealogy-list-card;
@include adaptive-genealogy-list-card;
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
@@ -501,7 +502,7 @@ const toTree = requestBack;
}
.member-status-entry text {
color: $ink-muted;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.4;
}
.member-status-entry text:first-child,
@@ -513,11 +514,11 @@ const toTree = requestBack;
display: block;
margin-top: 24rpx;
color: $brand-red;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.member-info-row {
@include adaptive.adaptive-tree-field;
@include adaptive-tree-field;
display: grid;
grid-template-columns: auto minmax(0, 1fr);
min-height: 64rpx;
@@ -528,7 +529,7 @@ const toTree = requestBack;
}
.member-info-row text {
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.45;
}
.member-info-row text:last-child {
@@ -537,7 +538,7 @@ const toTree = requestBack;
}
.member-relatives {
margin-top: 8rpx;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.member-relatives > view {
display: flex;
@@ -545,7 +546,7 @@ const toTree = requestBack;
gap: 20rpx;
padding: 12rpx 18rpx;
color: $ink;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.member-relatives > view text:last-child {
color: $brand-red;
@@ -553,7 +554,7 @@ const toTree = requestBack;
.member-relatives > text {
display: block;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.5;
}
.member-record-actions {
@@ -563,7 +564,7 @@ const toTree = requestBack;
margin-top: 20rpx;
}
.member-record-actions > view {
@include adaptive.adaptive-scroll-button(secondary);
@include adaptive-scroll-button(secondary);
display: flex;
min-height: 72rpx;
align-items: center;
@@ -573,12 +574,12 @@ const toTree = requestBack;
}
.member-record-actions text {
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
font-weight: 700;
line-height: 1.35;
}
.member-profile-action {
@include adaptive.adaptive-scroll-button(primary);
@include adaptive-scroll-button(primary);
display: flex;
min-height: 76rpx;
align-items: center;
@@ -587,7 +588,7 @@ const toTree = requestBack;
}
.member-profile-action text {
color: #fff9ed;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.member-restricted {
@@ -596,7 +597,7 @@ const toTree = requestBack;
.member-restricted > text {
display: block;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.6;
text-align: center;
}
@@ -604,14 +605,14 @@ const toTree = requestBack;
margin-top: 28rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
}
.member-restricted > text + text {
margin-top: 12rpx;
}
.member-restricted-action {
@include adaptive.adaptive-scroll-button(secondary);
@include adaptive-scroll-button(secondary);
display: flex;
min-height: 76rpx;
align-items: center;
@@ -620,7 +621,7 @@ const toTree = requestBack;
}
.member-restricted-action text {
color: $brand-red;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.member-error {
@@ -630,16 +631,16 @@ const toTree = requestBack;
.member-error > text {
display: block;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.55;
}
.member-error > text:nth-child(2) {
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.member-error > text:first-child {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
}
@media (min-width: 400px) {
+14 -24
View File
@@ -75,10 +75,6 @@
}}</text>
</view>
</picker>
<view class="form-field">
<text>业务用户</text>
<text class="form-field__hint">{{ appUserBindingHint }}</text>
</view>
<text v-if="fieldErrors.bindingMode" class="field-error">{{
fieldErrors.bindingMode
}}</text>
@@ -405,12 +401,6 @@ const relationOptions = computed(() => {
const relationLabel = computed(
() => activeRelationIntent.value?.label || addForm.relation || "亲属关系",
);
const appUserBindingHint = computed(() => {
if (addForm.bindingMode === "NONE") return "不绑定账号,不提交业务用户 ID";
if (addForm.bindingMode === "SELF")
return "由服务端从 Token 绑定当前登录账号,不提交业务用户 ID";
return "需先选择指定业务用户;当前没有可用候选接口";
});
const hasValidContext = computed(
() =>
Boolean(genealogyId.value) &&
@@ -675,7 +665,7 @@ const returnToTree = async () => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.add-relative-page {
display: flex;
@@ -687,7 +677,7 @@ const returnToTree = async () => {
z-index: 3;
}
.add-relative-panel {
@include adaptive.adaptive-tree-panel;
@include adaptive-tree-panel;
z-index: 2;
width: calc(100% - 32rpx);
margin: 18rpx auto 28rpx;
@@ -696,7 +686,7 @@ const returnToTree = async () => {
.form-eyebrow {
display: block;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
letter-spacing: 3rpx;
}
.form-title {
@@ -704,7 +694,7 @@ const returnToTree = async () => {
margin-top: 10rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
line-height: 1.35;
}
@@ -713,12 +703,12 @@ const returnToTree = async () => {
display: block;
margin-top: 10rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.5;
}
.member-context,
.form-field {
@include adaptive.adaptive-tree-field;
@include adaptive-tree-field;
display: grid;
grid-template-columns: auto minmax(0, 1fr);
min-height: 78rpx;
@@ -730,7 +720,7 @@ const returnToTree = async () => {
.member-context text:first-child,
.form-field > text:first-child {
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.member-context text:last-child,
@@ -739,7 +729,7 @@ const returnToTree = async () => {
.form-field textarea {
min-width: 0;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.45;
text-align: right;
}
@@ -747,7 +737,7 @@ const returnToTree = async () => {
display: inline-block;
margin-right: 4rpx;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1;
transform: translateY(-2rpx);
}
@@ -759,7 +749,7 @@ const returnToTree = async () => {
.form-field__hint,
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.4;
text-align: right;
}
@@ -776,7 +766,7 @@ const returnToTree = async () => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.form-field--summary {
align-items: start;
@@ -789,8 +779,8 @@ const returnToTree = async () => {
display: block;
margin: 5rpx 18rpx 0;
color: $brand-red;
font-size: 22rpx;
line-height: 32rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: max(1.35em, clamp(17px, 32rpx, 22px));
}
.form-note {
text-align: center;
@@ -813,7 +803,7 @@ const returnToTree = async () => {
align-items: center;
justify-content: center;
color: #fff9ed;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.add-result {
+13 -30
View File
@@ -47,10 +47,6 @@
fieldErrors.name
}}</text>
<view class="form-field">
<text>人物编号</text>
<text>{{ originalMember.personNo || "服务端生成" }}</text>
</view>
<picker
:range="sexOptions.map((item) => item.label)"
:value="optionIndex(sexOptions, editForm.sex)"
@@ -82,10 +78,6 @@
}}</text>
</view>
</picker>
<view class="form-field">
<text>业务用户</text>
<text class="form-field__hint">{{ appUserBindingHint }}</text>
</view>
<text v-if="fieldErrors.bindingMode" class="field-error">{{
fieldErrors.bindingMode
}}</text>
@@ -396,15 +388,6 @@ const personOptions = ref([{ label: "不选择", value: "" }]);
const personOptionLabels = computed(() =>
personOptions.value.map((item) => item.label),
);
const appUserBindingHint = computed(() => {
if (editForm.bindingMode === "NONE")
return "不绑定账号,保存时不提交业务用户 ID";
if (editForm.bindingMode === "SELF")
return "由服务端从 Token 绑定当前登录账号,保存时不提交业务用户 ID";
return editForm.appUserId
? "保留当前已认领的指定业务用户"
: "需先选择指定业务用户;当前没有可用候选接口";
});
const isDeceased = computed(() => editForm.personStatus === "1");
const formSnapshot = computed(() => JSON.stringify(editForm));
@@ -706,7 +689,7 @@ const handleResultAction = () => {
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.edit-member-page {
display: flex;
@@ -718,7 +701,7 @@ const handleResultAction = () => {
z-index: 3;
}
.edit-member-panel {
@include adaptive.adaptive-tree-panel;
@include adaptive-tree-panel;
z-index: 2;
width: calc(100% - 32rpx);
margin: 18rpx auto 28rpx;
@@ -727,7 +710,7 @@ const handleResultAction = () => {
.form-eyebrow {
display: block;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
letter-spacing: 3rpx;
}
.form-title {
@@ -735,7 +718,7 @@ const handleResultAction = () => {
margin-top: 10rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
line-height: 1.35;
}
@@ -744,12 +727,12 @@ const handleResultAction = () => {
display: block;
margin-top: 10rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.5;
}
.member-context,
.form-field {
@include adaptive.adaptive-tree-field;
@include adaptive-tree-field;
display: grid;
grid-template-columns: auto minmax(0, 1fr);
min-height: 78rpx;
@@ -761,7 +744,7 @@ const handleResultAction = () => {
.member-context text:first-child,
.form-field > text:first-child {
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.member-context text:last-child,
@@ -770,7 +753,7 @@ const handleResultAction = () => {
.form-field textarea {
min-width: 0;
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.45;
text-align: right;
}
@@ -782,7 +765,7 @@ const handleResultAction = () => {
.form-field__hint,
.upload-receipt {
color: $ink-muted;
font-size: 21rpx;
font-size: clamp(13px, 21rpx, 16px);
line-height: 1.4;
text-align: right;
}
@@ -799,7 +782,7 @@ const handleResultAction = () => {
border-radius: 8rpx;
background: transparent;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.form-field--summary {
align-items: start;
@@ -812,8 +795,8 @@ const handleResultAction = () => {
display: block;
margin: 5rpx 18rpx 0;
color: $brand-red;
font-size: 22rpx;
line-height: 32rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: max(1.35em, clamp(17px, 32rpx, 22px));
}
.form-note {
text-align: center;
@@ -836,7 +819,7 @@ const handleResultAction = () => {
align-items: center;
justify-content: center;
color: #fff9ed;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.edit-result {
+9 -9
View File
@@ -140,7 +140,7 @@ onBackPress((event) => handleBackPress(event, goBack));
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.rank-page {
display: flex;
@@ -152,7 +152,7 @@ onBackPress((event) => handleBackPress(event, goBack));
z-index: 3;
}
.rank-panel {
@include adaptive.adaptive-tree-panel;
@include adaptive-tree-panel;
z-index: 2;
width: calc(100% - 32rpx);
margin: 18rpx auto 28rpx;
@@ -161,7 +161,7 @@ onBackPress((event) => handleBackPress(event, goBack));
.form-eyebrow {
display: block;
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
letter-spacing: 3rpx;
}
.form-title {
@@ -169,7 +169,7 @@ onBackPress((event) => handleBackPress(event, goBack));
margin-top: 10rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
line-height: 1.35;
}
@@ -177,12 +177,12 @@ onBackPress((event) => handleBackPress(event, goBack));
display: block;
margin-top: 10rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.5;
}
.member-context,
.rank-notice {
@include adaptive.adaptive-tree-field;
@include adaptive-tree-field;
display: grid;
grid-template-columns: auto minmax(0, 1fr);
min-height: 78rpx;
@@ -194,14 +194,14 @@ onBackPress((event) => handleBackPress(event, goBack));
.member-context text:first-child,
.rank-notice text:first-child {
color: $ink;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.member-context text:last-child,
.rank-notice text:last-child {
min-width: 0;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.45;
text-align: right;
}
@@ -223,7 +223,7 @@ onBackPress((event) => handleBackPress(event, goBack));
align-items: center;
justify-content: center;
color: #fff9ed;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.rank-result {
+28 -21
View File
@@ -115,8 +115,15 @@ let loadSequence = 0;
const hasValidContext = computed(() => Boolean(genealogyId.value));
const memberMeta = (member) =>
`${member.generation} 世 · ${member.generationName || "字辈待补"} · ${member.branch}`;
const memberStatus = (member) =>
member.personStatus ? `人物状态:${member.personStatus}` : "人物状态待补";
const memberStatus = (member) => {
const labels = {
0: "健在",
1: "已故",
2: "未知",
};
const label = labels[String(member.personStatus ?? "").trim()];
return label ? `人物状态:${label}` : "人物状态待确认";
};
const hasMore = computed(() => members.value.length < total.value);
const loadMembers = async ({ append = false } = {}) => {
@@ -178,7 +185,7 @@ onUnload(() => {
});
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.directory-page {
display: flex;
@@ -203,16 +210,16 @@ onUnload(() => {
.directory-context__name {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
}
.directory-context__meta {
color: #62584c;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 500;
}
.directory-search {
@include adaptive.adaptive-tree-field;
@include adaptive-tree-field;
display: grid;
width: calc(100% - 48rpx);
min-height: 44px;
@@ -225,7 +232,7 @@ onUnload(() => {
margin-right: 110rpx;
margin-left: 26rpx;
color: $ink;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 44px;
}
.directory-search__action {
@@ -239,7 +246,7 @@ onUnload(() => {
justify-content: center;
margin-right: 8rpx;
color: $brand-red;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.directory-placeholder {
@@ -256,15 +263,15 @@ onUnload(() => {
.directory-summary text:first-child {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
font-weight: 700;
}
.directory-summary text:last-child {
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
}
.directory-card {
@include adaptive.adaptive-genealogy-list-card;
@include adaptive-genealogy-list-card;
display: flex;
width: 100%;
min-height: 196rpx;
@@ -283,7 +290,7 @@ onUnload(() => {
.directory-card__name {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
line-height: 1.3;
overflow-wrap: anywhere;
@@ -291,7 +298,7 @@ onUnload(() => {
.directory-card__meta {
margin-top: 7rpx;
color: #62584c;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.45;
overflow-wrap: anywhere;
}
@@ -301,11 +308,11 @@ onUnload(() => {
padding: 2rpx 10rpx;
border: 1rpx solid rgba(174, 45, 36, 0.32);
color: $brand-red;
font-size: 22rpx;
line-height: 30rpx;
font-size: clamp(14px, 22rpx, 17px);
line-height: max(1.35em, clamp(17px, 30rpx, 22px));
}
.directory-state-card {
@include adaptive.adaptive-genealogy-list-card;
@include adaptive-genealogy-list-card;
display: flex;
width: 100%;
min-height: 220rpx;
@@ -327,13 +334,13 @@ onUnload(() => {
.directory-state-card text:first-child {
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 30rpx;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
}
.directory-state-card text:last-child {
margin-top: 14rpx;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.5;
}
.directory-content > .app-button {
@@ -346,13 +353,13 @@ onUnload(() => {
padding-left: 22rpx;
}
.directory-card__name {
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
}
.directory-card__meta {
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
}
.directory-card__status {
font-size: 20rpx;
font-size: clamp(13px, 20rpx, 16px);
}
}
</style>
+13 -13
View File
@@ -154,7 +154,7 @@ const handleAction = () => goBack();
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
@import "../../styles/adaptive-frame-profiles.scss";
.member-status-page {
display: flex;
@@ -172,7 +172,7 @@ const handleAction = () => goBack();
z-index: 2;
}
.member-status-context {
@include adaptive.adaptive-tree-field;
@include adaptive-tree-field;
width: calc(100% - 32rpx);
margin: 18rpx auto 0;
padding: 16rpx 24rpx;
@@ -180,16 +180,16 @@ const handleAction = () => goBack();
.member-status-context text {
display: block;
color: $ink-muted;
font-size: 23rpx;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.45;
}
.member-status-context text:first-child {
color: $ink;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
font-weight: 700;
}
.status-card {
@include adaptive.adaptive-tree-panel;
@include adaptive-tree-panel;
width: calc(100% - 32rpx);
min-height: 330rpx;
margin: 18rpx auto 0;
@@ -198,28 +198,28 @@ const handleAction = () => goBack();
.status-card__copy text {
display: block;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.55;
text-align: center;
}
.status-card__copy text:first-child {
color: $brand-red;
font-size: 22rpx;
font-size: clamp(14px, 22rpx, 17px);
letter-spacing: 3rpx;
}
.status-card__copy text:nth-child(2) {
margin-top: 12rpx;
color: $ink;
font-family: "STKaiti", "KaiTi", serif;
font-size: 32rpx;
font-size: clamp(17px, 32rpx, 22px);
font-weight: 700;
}
.status-card__copy text:last-child {
margin-top: 14rpx;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
}
.status-guidance {
@include adaptive.adaptive-genealogy-list-card;
@include adaptive-genealogy-list-card;
width: calc(100% - 48rpx);
margin: 16rpx auto 0;
padding: 24rpx 28rpx;
@@ -227,13 +227,13 @@ const handleAction = () => goBack();
.status-guidance text {
display: block;
color: $ink-muted;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.6;
}
.status-guidance text:first-child {
margin-bottom: 8rpx;
color: $ink;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
font-weight: 700;
}
.status-action {
@@ -254,7 +254,7 @@ const handleAction = () => goBack();
align-items: center;
justify-content: center;
color: #fff9ed;
font-size: 24rpx;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
@media (min-width: 400px) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

+28 -4
View File
@@ -8,6 +8,30 @@ page {
font-family: "STKaiti", "KaiTi", serif
}
// 全局文字流基础任何元素进入 flex / grid 后都可以收缩避免长值把同排布局顶坏
// 是否必须单行由下面的语义类决定正文姓名和地址仍按内容自然换行
view,
text,
input,
textarea,
button {
min-width: 0;
}
// 用于页头操作导航标签按钮等短操作文案保持一行空间不足时给出省略号
.app-single-line {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// 用于邮箱编号等连续长值允许在必要处断开不能撑破卡片或表单
.app-long-value {
min-width: 0;
overflow-wrap: anywhere;
}
@supports (height: 100dvh) {
page {
--app-viewport-height: 100dvh;
@@ -34,14 +58,14 @@ view:not(.page-header-slot):has(> .page-header-slot) {
.section-title {
color: $ink;
font-size: 34rpx;
font-size: clamp(19px, 34rpx, 24px);
font-weight: 700;
letter-spacing: 2rpx;
}
.muted-copy {
color: $ink-muted;
font-size: 26rpx;
font-size: clamp(16px, 26rpx, 20px);
line-height: 1.7;
}
@@ -54,7 +78,7 @@ view:not(.page-header-slot):has(> .page-header-slot) {
border-radius: 14rpx;
background: $brand-red;
color: #fff8ec;
font-size: 31rpx;
font-size: clamp(17px, 31rpx, 22px);
font-weight: 700;
letter-spacing: 3rpx;
}
@@ -68,7 +92,7 @@ view:not(.page-header-slot):has(> .page-header-slot) {
border-radius: 14rpx;
background: transparent;
color: $brand-red;
font-size: 29rpx;
font-size: clamp(16px, 29rpx, 20px);
font-weight: 600;
}
+5 -5
View File
@@ -105,14 +105,14 @@ foreach ($selector in @('page-title', 'page-subtitle', 'register-divider')) {
}
foreach ($ruleContract in @(
@{ Selector = 'register-submit__content'; Expected = 'font-size: 36rpx;' },
@{ Selector = 'agreement-row'; Expected = 'font-size: 24rpx;' },
@{ Selector = 'register-submit__content'; Expected = 'font-size: clamp(19px, 36rpx, 24px);' },
@{ Selector = 'agreement-row'; Expected = 'font-size: clamp(15px, 24rpx, 18px);' },
@{ Selector = 'agreement-row'; Expected = 'color: #493323;' },
@{ Selector = 'input-label'; Expected = 'font-size: 30rpx;' },
@{ Selector = 'auth-input'; Expected = 'font-size: 30rpx;' },
@{ Selector = 'input-label'; Expected = 'font-size: clamp(17px, 30rpx, 22px);' },
@{ Selector = 'auth-input'; Expected = 'font-size: clamp(17px, 30rpx, 22px);' },
@{ Selector = 'auth-input'; Expected = 'color: #493323;' },
@{ Selector = 'placeholder'; Expected = 'color: #9f968d;' },
@{ Selector = 'login-entry'; Expected = 'font-size: 28rpx;' },
@{ Selector = 'login-entry'; Expected = 'font-size: clamp(16px, 28rpx, 20px);' },
@{ Selector = 'login-entry'; Expected = 'color: #493323;' },
@{ Selector = 'login-entry'; Expected = 'margin-top: auto;' }
)) {
+3 -3
View File
@@ -6,8 +6,8 @@ foreach ($token in @(
'compact: { type: Boolean, default: false }',
"'app-button--compact': compact",
'@use "../styles/adaptive-frame-profiles.scss" as adaptive;',
'@include adaptive.adaptive-scroll-button(primary);',
'@include adaptive.adaptive-scroll-button(secondary);',
'@include adaptive-scroll-button(primary);',
'@include adaptive-scroll-button(secondary);',
'a01-scroll-primary-v3.png',
'a01-scroll-secondary-v3.png'
)) {
@@ -21,7 +21,7 @@ if ($button.Contains('border-image-slice: 56 300 fill;')) {
if ($button -notmatch '(?s)\.app-button--compact \.app-button__skin\s*\{[^}]*display:\s*none;') {
throw 'AppButton compact mode must hide the aspectFit image skin'
}
if ($button -notmatch '(?s)\.app-button--compact \.app-button__label\s*\{[^}]*padding:\s*0;[^}]*font-size:\s*23rpx;[^}]*letter-spacing:\s*0;[^}]*white-space:\s*nowrap;') {
if ($button -notmatch '(?s)\.app-button--compact \.app-button__label\s*\{[^}]*padding:\s*0;[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\);[^}]*letter-spacing:\s*0;[^}]*white-space:\s*nowrap;') {
throw 'AppButton compact label must preserve four-character action capacity'
}
@@ -7,7 +7,7 @@ foreach ($token in @(
'class="app-dialog__copy"',
':compact="compactActions && showCancel"',
'@use "../styles/adaptive-frame-profiles.scss" as adaptive;',
'@include adaptive.adaptive-auth-dialog;',
'@include adaptive-auth-dialog;',
'padding: calc(40rpx + env(safe-area-inset-top)) 40rpx calc(40rpx + env(safe-area-inset-bottom));',
'max-height: calc(var(--app-viewport-height, 100vh) - 80rpx - env(safe-area-inset-top) - env(safe-area-inset-bottom));',
'min-height: 0;',
+4 -4
View File
@@ -17,12 +17,12 @@ Assert-Match -Content $component -Pattern 'class="app-loading__seal"\s+src="/sta
Assert-Match -Content $component -Pattern 'class="app-loading__knot"\s+src="/static/assets/foundation/transparent/auth-divider-knot\.png"' -Message 'AppLoading must render the approved real gold knot asset'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--page\s*\{[^}]*min-height:\s*320rpx;' -Message 'AppLoading page variant must use the approved minimum height'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--page\s+\.app-loading__seal\s*\{[^}]*width:\s*132rpx;[^}]*height:\s*136rpx;' -Message 'AppLoading page seal must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--page\s+\.app-loading__copy\s*\{[^}]*font-size:\s*30rpx;' -Message 'AppLoading page copy must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--page\s+\.app-loading__description\s*\{[^}]*font-size:\s*24rpx;' -Message 'AppLoading page description must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--page\s+\.app-loading__copy\s*\{[^}]*font-size:\s*clamp\(17px, 30rpx, 22px\);' -Message 'AppLoading page copy must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--page\s+\.app-loading__description\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);' -Message 'AppLoading page description must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--section\s*\{[^}]*min-height:\s*180rpx;' -Message 'AppLoading section variant must use the approved minimum height'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--section\s+\.app-loading__seal\s*\{[^}]*width:\s*88rpx;[^}]*height:\s*90rpx;' -Message 'AppLoading section seal must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--section\s+\.app-loading__copy\s*\{[^}]*font-size:\s*24rpx;' -Message 'AppLoading section copy must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--section\s+\.app-loading__description\s*\{[^}]*font-size:\s*22rpx;' -Message 'AppLoading section description must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--section\s+\.app-loading__copy\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);' -Message 'AppLoading section copy must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--section\s+\.app-loading__description\s*\{[^}]*font-size:\s*clamp\(14px, 22rpx, 17px\);' -Message 'AppLoading section description must use the approved size'
Assert-Match -Content $component -Pattern 'app-loading-seal-breathe\s+1\.6s' -Message 'AppLoading seal must use the approved restrained breathing rhythm'
Assert-Match -Content $component -Pattern '@media\s*\(prefers-reduced-motion:\s*reduce\)' -Message 'AppLoading must respect reduced-motion preferences'
Assert-Match -Content $component -Pattern '(?s)@media\s*\(prefers-reduced-motion:\s*reduce\).*?\.app-loading__seal\s*\{[^}]*animation:\s*none;[^}]*transform:\s*none;' -Message 'Reduced-motion seal must stop animation and transforms'
+34
View File
@@ -0,0 +1,34 @@
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
$avatar = Get-Content -LiteralPath (Join-Path $root 'utils/avatar.js') -Raw -Encoding UTF8
$component = Get-Content -LiteralPath (Join-Path $root 'components/AppAvatar.vue') -Raw -Encoding UTF8
foreach ($required in @(
'DEFAULT_MALE_AVATAR',
'mjpc0703_A_cartoon_illustration_of_a_boy_wearing_a_red_Chinese__0@2x.png',
'DEFAULT_FEMALE_AVATAR',
'loyel003_Ancient_Beauty_Wearing_Tang_Dynasty_ClothingLooking_to_07cb98a9-ec37-4620-a032-ebe511fa93b5@2x.png',
'String(sex ?? "").trim() === "1"'
)) {
if (-not $avatar.Contains($required)) {
throw "Default avatar contract missing: $required"
}
}
if (-not $component.Contains('getDefaultAvatar(props.sex)')) {
throw 'AppAvatar must own the fallback-avatar selection'
}
foreach ($page in @(
'pages/tree/t01-tree-overview.vue',
'pages/tree/t03-member-profile.vue',
'pages/profile/m01-profile-home.vue'
)) {
$source = Get-Content -LiteralPath (Join-Path $root $page) -Raw -Encoding UTF8
if (-not $source.Contains('import AppAvatar from "@/components/AppAvatar.vue"')) {
throw "Shared avatar component is not wired in: $page"
}
}
Write-Output 'DEFAULT-AVATAR-CONTRACT PASS'
@@ -7,10 +7,10 @@ function Assert-Match([string]$Content, [string]$Pattern, [string]$Message) { if
$f01 = Read-Utf8 'pages/family/f01-family-feed.vue'
$f02 = Read-Utf8 'pages/family/f02-publish-feed.vue'
foreach ($expected in @('24rpx','23rpx','22rpx')) {
foreach ($expected in @('clamp\(15px, 24rpx, 18px\)','clamp\(14px, 23rpx, 17px\)','clamp\(14px, 22rpx, 17px\)')) {
Assert-Match $f01 "font-size:\s*$expected" "F01 readability token missing: $expected"
}
foreach ($expected in @('24rpx','23rpx')) {
foreach ($expected in @('clamp\(15px, 24rpx, 18px\)','clamp\(14px, 23rpx, 17px\)')) {
Assert-Match $f02 "font-size:\s*$expected" "F02 readability token missing: $expected"
}
Write-Output 'F01-F02 readability visual contract passed.'
+3 -3
View File
@@ -7,9 +7,9 @@ foreach ($expected in @(
'box-sizing: border-box',
'width: 514rpx',
'@use "../../styles/adaptive-frame-profiles.scss" as adaptive;',
'@include adaptive.adaptive-scroll-button(secondary);',
'@include adaptive.adaptive-family-letter;',
'@include adaptive.adaptive-scroll-button(primary);'
'@include adaptive-scroll-button(secondary);',
'@include adaptive-family-letter;',
'@include adaptive-scroll-button(primary);'
)) {
if (-not $page.Contains($expected)) { throw "F01 document-flow contract missing: $expected" }
}
+2 -2
View File
@@ -3,8 +3,8 @@ $root = Split-Path $PSScriptRoot -Parent
$page = [System.IO.File]::ReadAllText((Join-Path $root 'pages/family/f02-publish-feed.vue'), [System.Text.Encoding]::UTF8)
foreach ($expected in @(
'@include adaptive.adaptive-family-content;',
'@include adaptive.adaptive-family-field;'
'@include adaptive-family-content;',
'@include adaptive-family-field;'
)) {
if (-not $page.Contains($expected)) { throw "F02 document-flow contract missing: $expected" }
}
+2 -2
View File
@@ -27,8 +27,8 @@ foreach ($expected in @(
'ModulePageBackground',
'AppDialog',
'AppButton',
'@include adaptive.adaptive-family-panel;',
'@include adaptive.adaptive-family-field;'
'@include adaptive-family-panel;',
'@include adaptive-family-field;'
)) {
Assert-Contains $expected "F06 article editor contract missing: $expected"
}
+1 -1
View File
@@ -22,7 +22,7 @@ foreach ($expected in @(
'PageHeader',
'AppButton',
'@use "../../styles/adaptive-frame-profiles.scss" as adaptive;',
'@include adaptive.adaptive-family-panel;'
'@include adaptive-family-panel;'
)) {
Assert-Contains $page $expected "F10 contract missing: $expected"
}
@@ -5,8 +5,8 @@ $editor = [System.IO.File]::ReadAllText((Join-Path $root 'pages/family/f06-artic
if ($publish -match 'position\s*:') { throw 'F02 must keep its editor in document flow' }
if ($editor -match 'position\s*:') { throw 'F06 must keep its editor in document flow' }
if (-not $publish.Contains('@include adaptive.adaptive-family-field;')) { throw 'F02 field frame must come from the adaptive profile owner' }
if (-not $editor.Contains('@include adaptive.adaptive-family-field;')) { throw 'F06 field frame must come from the adaptive profile owner' }
if (-not $publish.Contains('@include adaptive-family-field;')) { throw 'F02 field frame must come from the adaptive profile owner' }
if (-not $editor.Contains('@include adaptive-family-field;')) { throw 'F06 field frame must come from the adaptive profile owner' }
if ($publish -notmatch '(?s)<textarea[^>]*\sauto-height(?:\s|>)') { throw 'F02 long-form textarea must grow with its content' }
if ($editor -notmatch '(?s)<textarea[^>]*\sauto-height(?:\s|>)') { throw 'F06 long-form textarea must grow with its content' }
if ($publish -match '100%\s+100%\s+no-repeat' -or $editor -match '100%\s+100%\s+no-repeat') { throw 'Family editors must not stretch decorative backgrounds' }
+3 -3
View File
@@ -3,9 +3,9 @@ $root = Split-Path $PSScriptRoot -Parent
$page = [System.IO.File]::ReadAllText((Join-Path $root 'pages/genealogy/g01-my-genealogies.vue'), [System.Text.Encoding]::UTF8)
foreach ($expected in @(
'@include adaptive.adaptive-genealogy-current-slip',
'@include adaptive.adaptive-genealogy-list-card',
'@include adaptive.adaptive-genealogy-state-panel',
'@include adaptive-genealogy-current-slip',
'@include adaptive-genealogy-list-card',
'@include adaptive-genealogy-state-panel',
'background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png") center / contain no-repeat',
'grid-template-columns: minmax(0, 1fr) 96rpx'
)) {
+6 -6
View File
@@ -36,7 +36,7 @@ foreach ($required in @(
'empty-search-action',
'empty-invite-action',
'empty-create-note',
'@include adaptive.adaptive-genealogy-state-panel;',
'@include adaptive-genealogy-state-panel;',
'const createGenealogy = () =>',
'const hasGenealogies = computed('
)) {
@@ -63,16 +63,16 @@ Assert-Match -Content $g01 -Pattern '(?s)\.genealogy-empty-state\s*\{[^}]*min-he
Assert-Match -Content $g01 -Pattern '(?s)\.empty-panel\s*\{[^}]*min-height:\s*1120rpx;' -Message 'G01 empty panel does not retain the approved minimum height'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-panel__content\s*\{[^}]*justify-content:\s*center;[^}]*padding:\s*50rpx 28rpx 46rpx;' -Message 'G01 empty panel content is not centered with the approved responsive padding'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-seal\s*\{[^}]*width:\s*120rpx;[^}]*height:\s*184rpx;' -Message 'G01 empty seal does not use the approved prominent size'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-title\s*\{[^}]*margin-top:\s*30rpx;[^}]*font-size:\s*48rpx;' -Message 'G01 empty title does not use the approved prominent size and spacing'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-copy\s*\{[^}]*min-height:\s*84rpx;[^}]*margin-top:\s*18rpx;[^}]*font-size:\s*28rpx;' -Message 'G01 empty guidance does not use the approved prominent size and spacing'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-title\s*\{[^}]*margin-top:\s*30rpx;[^}]*font-size:\s*clamp\(24px, 48rpx, 30px\);' -Message 'G01 empty title does not use the approved prominent size and spacing'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-copy\s*\{[^}]*min-height:\s*84rpx;[^}]*margin-top:\s*18rpx;[^}]*font-size:\s*clamp\(16px, 28rpx, 20px\);' -Message 'G01 empty guidance does not use the approved prominent size and spacing'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-search-action,\s*\.empty-invite-action\s*\{[^}]*width:\s*560rpx;[^}]*min-height:\s*124rpx;' -Message 'G01 empty actions do not retain the approved prominent minimum size'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-search-action__copy,\s*\.empty-invite-action__copy\s*\{[^}]*font-size:\s*34rpx;' -Message 'G01 empty action labels do not use the approved prominent size'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-search-action__copy,\s*\.empty-invite-action__copy\s*\{[^}]*font-size:\s*clamp\(19px, 34rpx, 24px\);' -Message 'G01 empty action labels do not use the approved prominent size'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-create-action\s*\{[^}]*min-height:\s*76rpx;[^}]*margin-top:\s*14rpx;' -Message 'G01 empty create action does not use the approved prominent hit area and spacing'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-create-action__copy\s*\{[^}]*font-size:\s*31rpx;' -Message 'G01 empty create action does not use the approved prominent size'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-create-action__copy\s*\{[^}]*font-size:\s*clamp\(17px, 31rpx, 22px\);' -Message 'G01 empty create action does not use the approved prominent size'
if ($g01 -match '(?s)\.empty-create-action__copy\s*\{[^}]*text-decoration:\s*underline') {
throw 'G01 empty create action must not render a text underline'
}
Assert-Match -Content $g01 -Pattern '(?s)\.empty-create-note\s*\{[^}]*font-size:\s*26rpx;[^}]*line-height:\s*38rpx;' -Message 'G01 empty-state create note does not use the approved readable size'
Assert-Match -Content $g01 -Pattern '(?s)\.empty-create-note\s*\{[^}]*font-size:\s*clamp\(16px, 26rpx, 20px\);[^}]*line-height:\s*max\(1.35em, clamp\(20px, 38rpx, 26px\)\);' -Message 'G01 empty-state create note does not use the approved readable size'
if ($g01 -match '(?s)<view v-else class="genealogy-empty-state">.*?<image[^>]+g01-empty-panel\.png') { throw 'G01 empty state must not retain the opaque panel background' }
foreach ($className in @('empty-panel', 'empty-create-action', 'empty-search-action')) {
+2 -2
View File
@@ -17,8 +17,8 @@ Assert-Match -Content $g01 -Pattern '(?s)\.state-panel--error\s*\{[^}]*@include\
Assert-Match -Content $g01 -Pattern '(?s)\.state-retry\s*\{[^}]*background:\s*url\("/static/assets/foundation/transparent/a01-scroll-primary-v3\.png"\)\s*center\s*/\s*contain\s+no-repeat;' -Message 'G01 retry must use the approved scroll skin as a container background'
Assert-Match -Content $g01 -Pattern '(?s)\.state-panel--error\s*\{[^}]*min-height:\s*1120rpx;' -Message 'G01 error state must retain the approved minimum frame height'
Assert-Match -Content $g01 -Pattern '(?s)\.error-panel__seal\s*\{[^}]*width:\s*132rpx;[^}]*height:\s*136rpx;' -Message 'G01 error state seal must use the approved prominent size'
Assert-Match -Content $g01 -Pattern '(?s)\.state-panel--error\s+\.state-title\s*\{[^}]*font-size:\s*42rpx;' -Message 'G01 error title must use the approved hierarchy'
Assert-Match -Content $g01 -Pattern '(?s)\.state-panel--error\s+\.state-copy\s*\{[^}]*font-size:\s*27rpx;' -Message 'G01 error guidance must use the approved readable size'
Assert-Match -Content $g01 -Pattern '(?s)\.state-panel--error\s+\.state-title\s*\{[^}]*font-size:\s*clamp\(22px, 42rpx, 28px\);' -Message 'G01 error title must use the approved hierarchy'
Assert-Match -Content $g01 -Pattern '(?s)\.state-panel--error\s+\.state-copy\s*\{[^}]*font-size:\s*clamp\(16px, 27rpx, 20px\);' -Message 'G01 error guidance must use the approved readable size'
Assert-Match -Content $g01 -Pattern '(?s)\.state-panel--error\s+\.state-retry\s*\{[^}]*width:\s*560rpx;[^}]*height:\s*124rpx;' -Message 'G01 retry action must match the approved primary action size'
if ($errorBlock -match 'modules/genealogy/opaque/g01-empty-panel\.png') { throw 'G01 error state must not retain the legacy opaque panel' }
+22 -22
View File
@@ -51,7 +51,7 @@ if ($header -notmatch 'height:\s*calc\(124rpx\s*\+\s*var\(--status-bar-height,\s
if ($header -notmatch 'padding-top:\s*var\(--status-bar-height,\s*0px\)') { throw 'Header does not reserve the real system status-bar height.' }
if ($tabbar -match '/static/icons/tab-') { throw 'Tabbar still references rejected legacy tab assets.' }
if ($tabbar -notmatch 'safe-area-inset-bottom') { throw 'Tabbar has no Android safe-area padding.' }
if ($tabbar -notmatch 'font-size:\s*30rpx') { throw 'Tabbar label size does not match the approved visual weight.' }
if ($tabbar -notmatch 'font-size:\s*clamp\(17px, 30rpx, 22px\)') { throw 'Tabbar label size does not match the approved visual weight.' }
if ($tabbar -notmatch 'width:\s*64rpx') { throw 'Tabbar icon size does not match the approved visual weight.' }
$page = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages/genealogy/g01-my-genealogies.vue')
@@ -124,7 +124,7 @@ if ($page -match '(?s)\.add-dialog__heading\s*\{[^}]*top\s*:') {
if ($page -notmatch '(?s)\.add-dialog__close\s*\{[^}]*grid-column:\s*2;[^}]*grid-row:\s*1\s*/\s*span\s+2;[^}]*margin-right:\s*-22rpx;') {
throw 'G-01 add sheet close control does not follow the heading grid.'
}
if ($page -notmatch 'adaptive\.adaptive-g01-add-sheet' -or $profiles -notmatch [regex]::Escape('/static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3.png')) {
if ($page -notmatch '@include\s+adaptive-g01-add-sheet' -or $profiles -notmatch [regex]::Escape('/static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3.png')) {
throw 'G-01 add sheet does not use the approved complete background asset.'
}
if ($profiles -notmatch '(?s)@mixin\s+adaptive-g01-add-sheet\s*\{[^}]*border-image-source:\s*url\("/static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3\.png"\);[^}]*border-image-slice:\s*220\s+0\s+1\s+0\s+fill;[^}]*border-image-width:\s*118rpx\s+0\s+1rpx;') {
@@ -152,7 +152,7 @@ if ($page -notmatch '(?s)\.genealogy-switcher-layer\s*\{[^}]*align-items:\s*cent
if ($page -match 'class="genealogy-switcher__skin"') {
throw 'G-01 switcher must not render the complete background as a fixed aspectFit image.'
}
if ($page -notmatch '(?s)\.genealogy-switcher\s*\{[^}]*@include\s+adaptive\.adaptive-g01-switcher;[^}]*min-height:\s*600rpx;[^}]*max-height:\s*calc\(100vh\s*-\s*120rpx\);' -or $profiles -notmatch '(?s)@mixin\s+adaptive-g01-switcher\s*\{[^}]*border-image-source:\s*url\("/static/assets/modules/auth/transparent/a01-scroll-dialog-v3\.png"\);[^}]*border-image-slice:\s*300\s+260\s+360\s+260\s+fill;[^}]*border-image-width:\s*110rpx\s+48rpx\s+132rpx\s+48rpx;') {
if ($page -notmatch '(?s)\.genealogy-switcher\s*\{[^}]*@include\s+adaptive-g01-switcher;[^}]*min-height:\s*600rpx;[^}]*max-height:\s*calc\(100vh\s*-\s*120rpx\);' -or $profiles -notmatch '(?s)@mixin\s+adaptive-g01-switcher\s*\{[^}]*border-image-source:\s*url\("/static/assets/modules/auth/transparent/a01-scroll-dialog-v3\.png"\);[^}]*border-image-slice:\s*300\s+260\s+360\s+260\s+fill;[^}]*border-image-width:\s*110rpx\s+48rpx\s+132rpx\s+48rpx;') {
throw 'G-01 switcher does not use the approved stretchable complete background.'
}
if ($page -notmatch '(?s)\.genealogy-switcher__content\s*\{[^}]*min-height:\s*600rpx;[^}]*max-height:\s*calc\(100vh\s*-\s*120rpx\);[^}]*padding:\s*120rpx\s+58rpx\s+140rpx;') {
@@ -176,11 +176,11 @@ foreach ($nativeUi in @('uni.showToast', 'uni.showModal', 'uni.showLoading', 'un
foreach ($asset in @('shortcut-tree.png', 'shortcut-members.png', 'shortcut-generation-poem.png', 'shortcut-application.png', 'add.png')) {
if ($page -notmatch [regex]::Escape($asset)) { throw "G-01 does not consume $asset" }
}
if ($page -notmatch 'adaptive\.adaptive-genealogy-current-slip' -or $profiles -notmatch 'current-slip-frame\.png') { throw 'G-01 does not consume the approved current genealogy frame profile.' }
if ($page -notmatch '@include\s+adaptive-genealogy-current-slip' -or $profiles -notmatch 'current-slip-frame\.png') { throw 'G-01 does not consume the approved current genealogy frame profile.' }
foreach ($token in @('current-summary', 'current-meta-item', 'current-seal-frame', 'meta-location.png', 'meta-member.png', 'meta-admin.png', 'create-cloud.png')) {
if ($page -notmatch $token) { throw "G-01 current panel is missing $token" }
}
if ($page -notmatch 'width:\s*82rpx') { throw 'G-01 shortcut icons remain below the reference visual size.' }
if ($page -notmatch '(?s)\.shortcut-icon\s*\{[^}]*width:\s*76rpx;[^}]*height:\s*76rpx;') { throw 'G-01 shortcut icons do not keep the compact readable size.' }
if ($page -notmatch '<GenealogyPageBackground\s*/>') { throw 'G-01 does not consume the shared genealogy background component.' }
if ($page -notmatch 'section-divider\.png') { throw 'G-01 does not consume the approved section divider asset.' }
$pageWithoutAddMarkup = $page.Replace($addMarkup, '')
@@ -223,26 +223,26 @@ if ($card -match 'calendar-v1\.png') { throw 'G-01 list shows a calendar icon th
if ($card -match 'genealogy\.surname') { throw 'G-01 list seal still shows a surname instead of the fixed 家谱 seal.' }
if ($card -match 'card-copy') { throw 'G-01 list still retains the superseded split content column.' }
if ($card -notmatch '(?s)\.card-title-row\s*\{.*?justify-content:\s*space-between') { throw 'G-01 list title, role, and chevron do not share the required first row.' }
if ($page -notmatch '(?s)\.current-switch-copy\s*\{[^}]*font-size:\s*28rpx') { throw 'G-01 switch copy does not use the approved 28rpx size.' }
if ($page -notmatch '(?s)\.current-meta\s*\{[^}]*font-size:\s*27rpx') { throw 'G-01 current genealogy metadata must retain its original 27rpx size.' }
if ($page -notmatch '(?s)\.current-meta-icon\s*\{[^}]*width:\s*36rpx;[^}]*height:\s*36rpx;[^}]*opacity:\s*1;') { throw 'G-01 current genealogy metadata icons do not use the approved 36rpx size and full opacity.' }
if ($page -notmatch '(?s)\.current-switch-copy\s*\{[^}]*border-radius:\s*999rpx;[^}]*font-size:\s*clamp\(15px, 25rpx, 18px\)') { throw 'G-01 switch copy is not a compact visual action.' }
if ($page -notmatch '(?s)\.current-meta\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*minmax\(0, 1fr\)\s+auto;[^}]*font-size:\s*clamp\(15px, 25rpx, 18px\)') { throw 'G-01 current metadata is not split into readable rows.' }
if ($page -notmatch '(?s)\.current-meta-item--location\s*\{[^}]*grid-column:\s*1\s*/\s*-1;') { throw 'G-01 location does not have its own metadata row.' }
if ($page -notmatch '(?s)\.current-meta-icon\s*\{[^}]*width:\s*34rpx;[^}]*height:\s*34rpx;[^}]*opacity:\s*1;') { throw 'G-01 current genealogy metadata icons do not use the compact readable size.' }
if ($page -notmatch '(?s)@media screen and \(max-width:\s*340px\)[^{]*\{.*?\.current-meta-icon\s*\{[^}]*width:\s*32rpx;[^}]*height:\s*32rpx;') { throw 'G-01 compact viewport metadata icons do not preserve the approved 32rpx size.' }
if ($card -notmatch '(?s)\.card-meta-icon\s*\{[^}]*width:\s*46rpx;[^}]*height:\s*46rpx;[^}]*flex:\s*0 0 auto;[^}]*opacity:\s*1;[^}]*filter:\s*saturate\(1\.35\) brightness\(0\.82\) contrast\(1\.15\);') { throw 'G-01 list location and member icons do not use the approved balanced size and contrast.' }
if ($card -notmatch '(?s)\.card-meta-item\s*\{[^}]*margin-right:\s*0;') { throw 'G-01 list metadata groups still retain the superseded trailing margin.' }
if ($card -notmatch '(?s)\.card-metas\s*\{[^}]*flex-wrap:\s*wrap;[^}]*gap:\s*4rpx 18rpx;') { throw 'G-01 list metadata groups must preserve the approved separation while allowing data-driven wrapping.' }
if ($card -notmatch '(?s)\.genealogy-card\s*\{[^}]*min-height:\s*178rpx;') { throw 'G-01 list cards do not reserve the approved height for the update-date row.' }
if ($card -notmatch '(?s)\.card-detail-row\s*\{[^}]*flex-wrap:\s*wrap;') { throw 'G-01 list detail row does not allow the update date to occupy its own row.' }
if ($card -notmatch '(?s)<view class="card-detail-row">\s*<view class="card-updated">.*?</view>\s*<view class="card-metas">') { throw 'G-01 update date must precede metadata in the approved visual and DOM order.' }
if ($card -notmatch '(?s)\.card-updated\s*\{[^}]*width:\s*100%;[^}]*justify-content:\s*flex-end;[^}]*margin-top:\s*0;[^}]*margin-left:\s*0;') { throw 'G-01 update date does not use the approved right-aligned second row.' }
if ($card -notmatch '(?s)\.card-metas\s*\{[^}]*width:\s*100%;[^}]*margin-top:\s*2rpx;') { throw 'G-01 list metadata does not use the approved third row.' }
if ($card -notmatch '(?s)@media screen and \(max-width:\s*340px\)[^{]*\{.*?\.genealogy-card\s*\{[^}]*min-height:\s*148rpx;') { throw 'G-01 compact list cards must retain their original 148rpx height.' }
if ($card -notmatch '(?s)\.card-meta\s*\{[^}]*font-size:\s*26rpx') { throw 'G-01 list metadata must retain its original 26rpx size.' }
if ($card -notmatch '(?s)\.card-updated\s*\{[^}]*font-size:\s*24rpx') { throw 'G-01 list update date must retain its original 24rpx size.' }
if ($card -notmatch '(?s)\.card-role\s*\{[^}]*font-size:\s*26rpx') { throw 'G-01 list role must retain its original 26rpx size.' }
if ($card -notmatch '(?s)\.card-meta-icon\s*\{[^}]*width:\s*38rpx;[^}]*height:\s*38rpx;[^}]*flex:\s*0 0 auto;[^}]*opacity:\s*1;[^}]*filter:\s*saturate\(1\.35\) brightness\(0\.82\) contrast\(1\.15\);') { throw 'G-01 list location and member icons do not use the balanced compact size and contrast.' }
if ($card -notmatch '(?s)\.genealogy-card\s*\{[^}]*grid-template-columns:\s*68rpx\s+minmax\(0, 1fr\);[^}]*min-height:\s*204rpx;') { throw 'G-01 list cards do not reserve the readable three-row layout.' }
if ($card -notmatch '(?s)\.card-detail-row\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*minmax\(0, 1fr\)\s+auto;') { throw 'G-01 list details are not arranged as a two-column grid.' }
if ($card -notmatch '(?s)<view class="card-detail-row">\s*<view class="card-meta-item card-meta-item--location">.*?</view>\s*<view class="card-meta-item card-meta-item--members">.*?</view>\s*<view class="card-trailing">') { throw 'G-01 list card must show location, member count, then role in the readable order.' }
if ($card -notmatch '(?s)\.card-meta-item--location\s*\{[^}]*grid-column:\s*1\s*/\s*-1;') { throw 'G-01 list location does not have its own full row.' }
if ($card -notmatch '(?s)\.card-trailing\s*\{[^}]*grid-column:\s*2;[^}]*flex-direction:\s*column;') { throw 'G-01 role and update date are not anchored to the member-count row.' }
if ($card -notmatch 'v-if="genealogy\.updatedAt"') { throw 'G-01 must not show an empty update-date label.' }
if ($card -notmatch '(?s)@media screen and \(max-width:\s*340px\)[^{]*\{.*?\.genealogy-card\s*\{[^}]*min-height:\s*176rpx;') { throw 'G-01 compact list cards do not reserve the readable layout.' }
if ($card -notmatch '(?s)\.card-meta\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\)') { throw 'G-01 list metadata does not use the approved readable size.' }
if ($card -notmatch '(?s)\.card-updated\s*\{[^}]*font-size:\s*clamp\(14px, 22rpx, 17px\)') { throw 'G-01 list update date does not use the secondary readable size.' }
if ($card -notmatch '(?s)\.card-role\s*\{[^}]*border-radius:\s*999rpx;[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\)') { throw 'G-01 list role is not presented as a compact status tag.' }
if ($page -match '(?s)\.create-action\s*>\s*text\s*\{[^}]*white-space:\s*nowrap') { throw 'G-01 create action text must not use a fixed single-line capacity.' }
if ($page -notmatch '(?s)\.application-record\s*\+\s*\.application-record\s*\{[^}]*margin-top:\s*12rpx') { throw 'G-01 adjacent application cards must keep the approved 12rpx separation.' }
if ($page -notmatch '(?s)\.application-record__copy\s*\{[^}]*color:\s*#62584c;[^}]*font-size:\s*28rpx;[^}]*font-weight:\s*500;[^}]*line-height:\s*1\.4;') { throw 'G-01 application descriptions do not use the approved readable style.' }
if ($page -notmatch '(?s)\.application-record__status\s*\{[^}]*color:\s*#7f4f16;[^}]*font-size:\s*27rpx;[^}]*font-weight:\s*600;') { throw 'G-01 application statuses do not use the approved readable base style.' }
if ($page -notmatch '(?s)\.application-record__copy\s*\{[^}]*color:\s*#62584c;[^}]*font-size:\s*clamp\(16px, 28rpx, 20px\);[^}]*font-weight:\s*500;[^}]*line-height:\s*1\.4;') { throw 'G-01 application descriptions do not use the approved readable style.' }
if ($page -notmatch '(?s)\.application-record__status\s*\{[^}]*color:\s*#7f4f16;[^}]*font-size:\s*clamp\(16px, 27rpx, 20px\);[^}]*font-weight:\s*600;') { throw 'G-01 application statuses do not use the approved readable base style.' }
if ($page -notmatch '(?s)\.application-record__status--rejected\s*\{[^}]*color:\s*#a7160c;') { throw 'G-01 rejected status must preserve the approved semantic red.' }
if ($page -notmatch '(?s)\.application-record__status--muted\s*\{[^}]*color:\s*#62584c;') { throw 'G-01 muted status does not use the approved readable color.' }
+1 -1
View File
@@ -5,7 +5,7 @@ $page = Get-Content -LiteralPath (Join-Path $root 'pages/genealogy/g03-create-ge
$style = [regex]::Match($page, '(?s)<style[^>]*>(.*?)</style>').Groups[1].Value
foreach ($required in @(
'@include adaptive.adaptive-genealogy-state-panel;',
'@include adaptive-genealogy-state-panel;',
'.create-card',
'.field-row',
'.region-sheet',
+3 -3
View File
@@ -11,9 +11,9 @@ function Assert-Match {
if ($g03 -match '<text>返回</text>') { throw 'G03 header must use the shared PageHeader back control' }
Assert-Match -Content $g03 -Pattern '(?s)<PageHeader\s+title="[^"]+"\s+custom-back\s+@back="backToGenealogies"\s*/>' -Message 'G03 must use PageHeader with its guarded back handler'
if ($g03 -match 'flow-header|flow-header__back|flow-header__title') { throw 'G03 must not retain a private header implementation' }
Assert-Match -Content $g03 -Pattern '(?s)\.create-card__note\s*\{[^}]*font-size:\s*25rpx;' -Message 'G03 guidance copy must use the approved readable size'
Assert-Match -Content $g03 -Pattern '(?s)\.access-rule__option\s*\{[^}]*font-size:\s*25rpx;' -Message 'G03 visibility options must use the approved readable size'
Assert-Match -Content $g03 -Pattern '(?s)\.field-error,\s*\.submit-error\s*\{[^}]*font-size:\s*24rpx;[^}]*line-height:\s*1\.5;' -Message 'G03 validation errors must use the approved readable size'
Assert-Match -Content $g03 -Pattern '(?s)\.create-card__note\s*\{[^}]*font-size:\s*clamp\(15px, 25rpx, 18px\);' -Message 'G03 guidance copy must use the approved readable size'
Assert-Match -Content $g03 -Pattern '(?s)\.access-rule__option\s*\{[^}]*font-size:\s*clamp\(15px, 25rpx, 18px\);' -Message 'G03 visibility options must use the approved readable size'
Assert-Match -Content $g03 -Pattern '(?s)\.field-error,\s*\.submit-error\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);[^}]*line-height:\s*1\.5;' -Message 'G03 validation errors must use the approved readable size'
Assert-Match -Content $g03 -Pattern '(?s)\.create-card\s*\.app-button\s*\{[^}]*margin-top:\s*32rpx;' -Message 'G03 primary action spacing must remain stable'
Write-Output 'G03-VISUAL-STATES-CONTRACT PASS'
+2 -2
View File
@@ -13,8 +13,8 @@ if ($positions.Count -ne 0) {
}
foreach ($required in @(
'@include adaptive.adaptive-g05-overview-surface;',
'@include adaptive.adaptive-genealogy-state-panel;',
'@include adaptive-g05-overview-surface;',
'@include adaptive-genealogy-state-panel;',
'background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")'
)) {
if ($page -notmatch [regex]::Escape($required)) {
+3 -3
View File
@@ -13,9 +13,9 @@ if ($positions.Count -ne 0) {
}
foreach ($required in @(
'@include adaptive.adaptive-g06-search-field;',
'@include adaptive.adaptive-g06-search-action;',
'@include adaptive.adaptive-genealogy-list-card;',
'@include adaptive-g06-search-field;',
'@include adaptive-g06-search-action;',
'@include adaptive-genealogy-list-card;',
'background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")'
)) {
if ($styleWithoutComments -notmatch [regex]::Escape($required)) {
+2 -2
View File
@@ -6,8 +6,8 @@ $positions = [regex]::Matches([regex]::Replace($style, '(?s)/\*.*?\*/', ''), '(?
if ($positions.Count -ne 0) { throw "G08 join flow must use document flow; found $($positions.Count) position declarations" }
foreach ($required in @(
'<GenealogyPageBackground />',
'@include adaptive.adaptive-genealogy-state-panel;',
'@include adaptive.adaptive-genealogy-form-field;',
'@include adaptive-genealogy-state-panel;',
'@include adaptive-genealogy-form-field;',
'appApi.applyToJoin',
'createRequestController',
'auto-height'
+7 -7
View File
@@ -3,16 +3,16 @@ $root = Split-Path -Parent $PSScriptRoot
$page = Get-Content -LiteralPath (Join-Path $root 'pages/genealogy/g09-my-applications.vue') -Raw -Encoding utf8
$rules = @(
'(?s)\.application-intro text:last-child\s*\{[^}]*font-size:\s*24rpx;',
'(?s)\.application-card__time\s*\{[^}]*font-size:\s*23rpx;',
'(?s)\.application-card__relation\s*\{[^}]*font-size:\s*24rpx;',
'(?s)\.application-card__status\s*\{[^}]*font-size:\s*25rpx;',
'(?s)\.application-card__hint\s*\{[^}]*font-size:\s*23rpx;',
'(?s)\.application-card__action\s*\{[^}]*font-size:\s*23rpx;',
'(?s)\.application-intro text:last-child\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);',
'(?s)\.application-card__time\s*\{[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\);',
'(?s)\.application-card__relation\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);',
'(?s)\.application-card__status\s*\{[^}]*font-size:\s*clamp\(15px, 25rpx, 18px\);',
'(?s)\.application-card__hint\s*\{[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\);',
'(?s)\.application-card__action\s*\{[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\);',
'(?s)\.application-card__action\s*\{[^}]*white-space:\s*nowrap;',
'(?s)\.application-card\s*\{[^}]*@include\s+adaptive\.adaptive-genealogy-list-card;[^}]*min-height:\s*210rpx;[^}]*margin-bottom:\s*12rpx;',
'(?s)\.application-card__body\s*\{[^}]*min-height:\s*174rpx;[^}]*gap:\s*8rpx 14rpx;[^}]*padding:\s*26rpx 28rpx 22rpx 40rpx;',
'(?s)\.application-state-card__copy text:last-child\s*\{[^}]*font-size:\s*24rpx;'
'(?s)\.application-state-card__copy text:last-child\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);'
)
if ($page -match '(?s)\.application-card\s*\{[^}]*background:\s*url\("/static/assets/modules/genealogy/transparent/list-slip-frame\.png"\)[^}]*100%\s+100%') {
throw 'G09 application card must not stretch the complete frame asset to 100% 100%'
+1 -1
View File
@@ -5,7 +5,7 @@ $style = [regex]::Match($page, '(?s)<style[^>]*>(.*?)</style>').Groups[1].Value
$positions = [regex]::Matches([regex]::Replace($style, '(?s)/\*.*?\*/', ''), '(?m)\bposition\s*:\s*([^;]+);')
if ($positions.Count -ne 0) { throw "G09 application list must use document flow; found $($positions.Count) position declarations" }
foreach ($required in @(
'@include adaptive.adaptive-genealogy-list-card;',
'@include adaptive-genealogy-list-card;',
'background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")'
)) { if ($page -notmatch [regex]::Escape($required)) { throw "G09 is missing real asset background: $required" } }
if ($page -match 'class="application-card__skin"') { throw 'G09 must not retain decorative card image layers' }
+5 -5
View File
@@ -19,16 +19,16 @@ foreach ($required in @(
}
$rules = @(
'(?s)\.review-intro text:nth-child\(2\)\s*\{[^}]*font-size:\s*24rpx;',
'(?s)\.application-card__phone\s*\{[^}]*font-size:\s*23rpx;',
'(?s)\.application-card__time\s*\{[^}]*font-size:\s*23rpx;',
'(?s)\.application-card__relation\s*\{[^}]*font-size:\s*24rpx;',
'(?s)\.review-intro text:nth-child\(2\)\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);',
'(?s)\.application-card__phone\s*\{[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\);',
'(?s)\.application-card__time\s*\{[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\);',
'(?s)\.application-card__relation\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);',
'(?s)\.application-card\s*\{[^}]*@include\s+adaptive\.adaptive-genealogy-list-card;[^}]*min-height:\s*218rpx;[^}]*margin-bottom:\s*12rpx;',
'(?s)\.application-card__body\s*\{[^}]*min-height:\s*182rpx;[^}]*gap:\s*8rpx 0;[^}]*padding:\s*28rpx 28rpx 22rpx 40rpx;',
'(?s)\.review-actions \.app-button\s*\{[^}]*width:\s*148rpx;[^}]*min-height:\s*68rpx;',
'(?s)\.review-result\s*\{[^}]*@include\s+adaptive\.adaptive-scroll-button\(primary\);[^}]*width:\s*308rpx;[^}]*min-height:\s*68rpx;',
'(?s)\.review-state-card\s*\{[^}]*@include\s+adaptive\.adaptive-genealogy-list-card;',
'(?s)\.review-state-card__copy text:last-child\s*\{[^}]*font-size:\s*24rpx;'
'(?s)\.review-state-card__copy text:last-child\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);'
)
if ($page -match 'a01-(?:primary|secondary)-button-v2\.png') {
throw 'G10 must not render the ultra-wide v2 assets through aspectFit inside narrow action buttons'
+3 -3
View File
@@ -3,15 +3,15 @@ $root = Split-Path $PSScriptRoot -Parent
$page = [System.IO.File]::ReadAllText((Join-Path $root 'pages/genealogy/g10-application-review.vue'), [System.Text.Encoding]::UTF8)
foreach ($expected in @(
'@include adaptive.adaptive-genealogy-list-card',
'@include adaptive.adaptive-feedback-toast',
'@include adaptive-genealogy-list-card',
'@include adaptive-feedback-toast',
'background: url("/static/assets/modules/genealogy/transparent/section-divider.png") bottom center / 100% 14rpx no-repeat',
'grid-template-columns: auto minmax(0, 1fr) auto',
'padding: 28rpx 28rpx 22rpx 40rpx',
'<AppButton',
'compact-actions',
'z-index: 1',
'@include adaptive.adaptive-genealogy-form-field'
'@include adaptive-genealogy-form-field'
)) {
if (-not $page.Contains($expected)) { throw "G10 document-flow contract missing: $expected" }
}
+2 -2
View File
@@ -7,8 +7,8 @@ if ($positions.Count -ne 1 -or $positions[0].Groups[1].Value.Trim() -ne 'fixed')
throw "G11 must retain only its fixed feedback layer; found $($positions.Count) position declarations"
}
foreach ($required in @(
'@include adaptive.adaptive-genealogy-state-panel;',
'@include adaptive.adaptive-genealogy-form-field;',
'@include adaptive-genealogy-state-panel;',
'@include adaptive-genealogy-form-field;',
'background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")',
'background: url("/static/assets/foundation/transparent/a01-scroll-secondary-v3.png")'
)) { if ($page -notmatch [regex]::Escape($required)) { throw "G11 is missing adaptive asset surface: $required" } }
+10 -10
View File
@@ -4,21 +4,21 @@ $g11 = Get-Content -LiteralPath (Join-Path $root 'pages/genealogy/g11-genealogy-
$g12 = Get-Content -LiteralPath (Join-Path $root 'pages/genealogy/g12-generation-poems.vue') -Raw -Encoding utf8
foreach ($rule in @(
'(?s)\.settings-form__copy,\s*\.settings-result__copy\s*\{[^}]*font-size:\s*24rpx;',
'(?s)\.settings-field-error\s*\{[^}]*font-size:\s*24rpx;[^}]*line-height:\s*34rpx;',
'(?s)\.visibility-block__hint\s*\{[^}]*font-size:\s*22rpx;',
'(?s)\.visibility-option text\s*\{[^}]*font-size:\s*24rpx;'
'(?s)\.settings-form__copy,\s*\.settings-result__copy\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);',
'(?s)\.settings-field-error\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);[^}]*line-height:\s*max\(1.35em, clamp\(19px, 34rpx, 24px\)\);',
'(?s)\.visibility-block__hint\s*\{[^}]*font-size:\s*clamp\(14px, 22rpx, 17px\);',
'(?s)\.visibility-option text\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);'
)) {
if ($g11 -notmatch $rule) { throw "G11 readable visual rule missing: $rule" }
}
foreach ($rule in @(
'(?s)\.poem-list__copy\s*\{[^}]*font-size:\s*24rpx;',
'(?s)\.poem-row__number\s*\{[^}]*font-size:\s*23rpx;',
'(?s)\.poem-row__status\s*\{[^}]*font-size:\s*22rpx;',
'(?s)\.poem-field-error\s*\{[^}]*font-size:\s*24rpx;[^}]*line-height:\s*34rpx;',
'(?s)\.poem-policy > text\s*\{[^}]*font-size:\s*24rpx;',
'(?s)\.poem-preview\s*\{[^}]*font-size:\s*23rpx;'
'(?s)\.poem-list__copy\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);',
'(?s)\.poem-row__number\s*\{[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\);',
'(?s)\.poem-row__status\s*\{[^}]*font-size:\s*clamp\(14px, 22rpx, 17px\);',
'(?s)\.poem-field-error\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);[^}]*line-height:\s*max\(1.35em, clamp\(19px, 34rpx, 24px\)\);',
'(?s)\.poem-policy > text\s*\{[^}]*font-size:\s*clamp\(15px, 24rpx, 18px\);',
'(?s)\.poem-preview\s*\{[^}]*font-size:\s*clamp\(14px, 23rpx, 17px\);'
)) {
if ($g12 -notmatch $rule) { throw "G12 readable visual rule missing: $rule" }
}
+2 -2
View File
@@ -7,8 +7,8 @@ if ($positions.Count -ne 1 -or $positions[0].Groups[1].Value.Trim() -ne 'fixed')
throw "G12 must retain only its fixed feedback layer; found $($positions.Count) position declarations"
}
foreach ($required in @(
'@include adaptive.adaptive-genealogy-state-panel;',
'@include adaptive.adaptive-genealogy-form-field;',
'@include adaptive-genealogy-state-panel;',
'@include adaptive-genealogy-form-field;',
'background: url("/static/assets/foundation/transparent/a01-scroll-secondary-v3.png")'
)) { if ($page -notmatch [regex]::Escape($required)) { throw "G12 is missing adaptive asset surface: $required" } }
if ($page -notmatch '(?s)<textarea[^>]*auto-height') { throw 'G12 generation poem field must grow from its text data' }
+78
View File
@@ -0,0 +1,78 @@
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
function Read-Utf8([string]$relativePath) {
return [System.IO.File]::ReadAllText(
(Join-Path $root $relativePath),
[System.Text.Encoding]::UTF8
)
}
$pages = Get-Content -LiteralPath (Join-Path $root 'pages.json') -Raw -Encoding UTF8 |
ConvertFrom-Json
$responsiveCoverage = Get-Content -LiteralPath (Join-Path $PSScriptRoot 'responsive-layout-coverage.json') -Raw -Encoding UTF8 |
ConvertFrom-Json
foreach ($page in $pages.pages) {
$relativeSource = "$($page.path).vue"
$source = Join-Path $root $relativeSource
if (-not (Test-Path -LiteralPath $source)) {
throw "Registered page has no source file: $($page.path)"
}
if ($responsiveCoverage.covered -notcontains $relativeSource) {
throw "Registered page is missing responsive coverage: $relativeSource"
}
}
$global = Read-Utf8 'styles/global.scss'
foreach ($rule in @(
'(?s)\.app-single-line\s*\{[^}]*overflow:\s*hidden;[^}]*text-overflow:\s*ellipsis;[^}]*white-space:\s*nowrap;',
'(?s)\.app-long-value\s*\{[^}]*overflow-wrap:\s*anywhere;'
)) {
if ($global -notmatch $rule) { throw "Global text-flow rule missing: $rule" }
}
foreach ($component in @(
'components/PageHeader.vue',
'components/AppButton.vue',
'components/AppTabbar.vue',
'components/GenealogyCard.vue'
)) {
if ((Read-Utf8 $component) -notmatch 'app-single-line') {
throw "Shared compact-text owner is not using the global rule: $component"
}
}
$profile = Read-Utf8 'pages/profile/m01-profile-home.vue'
if ($profile -notmatch 'app-long-value') {
throw 'Profile email must use the global long-value rule'
}
foreach ($relativePath in @(
'pages/genealogy/g03-create-genealogy.vue',
'pages/genealogy/g11-genealogy-settings.vue'
)) {
$source = Read-Utf8 $relativePath
if ($source -notmatch '(?s)\.field-row__label\s*\{[^}]*width:\s*184rpx;[^}]*white-space:\s*nowrap;') {
throw "Genealogy form labels must retain a four-character single-line column: $relativePath"
}
}
foreach ($relativePath in @(
'pages/profile/m04-change-password.vue',
'pages/profile/m05-change-phone.vue'
)) {
$source = Read-Utf8 $relativePath
if ($source -notmatch '(?s)\.form-row\s*>\s*text\s*\{[^}]*white-space:\s*nowrap;') {
throw "Profile form labels must remain single-line: $relativePath"
}
}
$phone = Read-Utf8 'pages/profile/m05-change-phone.vue'
if ($phone -notmatch 'class="code-action"') {
throw 'Phone verification action must own a readable secondary treatment'
}
if ($phone -notmatch '(?s)\.code-action\s*\{[^}]*background:\s*rgba\(255, 250, 238, 0\.96\);[^}]*white-space:\s*nowrap;') {
throw 'Phone verification action must not use the cramped scroll frame'
}
Write-Output 'GLOBAL-TEXT-FLOW-CONTRACT PASS'
+1 -1
View File
@@ -63,7 +63,6 @@ foreach ($required in @(
}
foreach ($required in @(
'originalMember.personNo ||',
'v-model="editForm.generation"',
'v-model="editForm.sortOrder"',
'sex: editForm.sex',
@@ -88,6 +87,7 @@ foreach ($required in @(
}
foreach ($forbidden in @(
'<text>人物编号</text>',
'v-model="addForm.personNo"',
'personNo: addForm.personNo',
'v-model="addForm.fatherId"',
@@ -4,9 +4,9 @@ $m01 = Get-Content -LiteralPath (Join-Path $root 'pages/profile/m01-profile-home
foreach ($required in @(
'/static/assets/foundation/transparent/brand-seal.png',
'font-size:\s*25rpx',
'font-size:\s*23rpx',
'font-size:\s*21rpx'
'font-size:\s*clamp\(15px, 25rpx, 18px\)',
'font-size:\s*clamp\(14px, 23rpx, 17px\)',
'font-size:\s*clamp\(13px, 21rpx, 16px\)'
)) {
if ($m01 -notmatch $required) { throw "M01 visual contract missing: $required" }
}
@@ -0,0 +1,14 @@
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
foreach ($pageName in @('t04-add-relative.vue', 't05-edit-member.vue')) {
$page = Get-Content -LiteralPath (Join-Path $root "pages/tree/$pageName") -Raw -Encoding UTF8
if ($page.Contains('<text>业务用户</text>') -or $page.Contains('appUserBindingHint')) {
throw "$pageName must not expose the internal business-user field"
}
if (-not $page.Contains('bindingMode')) {
throw "$pageName must retain the member binding payload contract"
}
}
Write-Output 'MEMBER-APP-USER-VISIBILITY-CONTRACT PASS'
@@ -0,0 +1,15 @@
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
$page = Get-Content -LiteralPath (Join-Path $root 'pages/tree/t05-edit-member.vue') -Raw -Encoding UTF8
foreach ($forbidden in @('<text>人物编号</text>', '<text>业务用户</text>')) {
if ($page.Contains($forbidden)) {
throw "Edit-member form must not expose the internal identifier: $forbidden"
}
}
if (-not $page.Contains('appApi.updatePerson(')) {
throw 'Edit-member save contract must remain intact'
}
Write-Output 'MEMBER-INTERNAL-IDENTIFIERS-VISIBILITY-CONTRACT PASS'

Some files were not shown because too many files have changed in this diff Show More