Files
jiapuapp/pages/auth/a01-entry.vue
T
2026-07-14 07:01:45 +08:00

317 lines
8.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 页面编号A-01用途启动登录引导视觉基准已由用户验收地基迁移不得改变可见效果 -->
<template>
<view class="auth-page entry-page">
<!-- 不透明纸纹底图承担页面底色透明山水只作为上层装饰 -->
<image class="paper-background" src="/static/assets/foundation/opaque/auth-page-paper.jpg" mode="aspectFill" />
<image class="scenery-background" src="/static/assets/foundation/transparent/auth-ink-scenery.png" mode="aspectFill" />
<view class="auth-content">
<view class="auth-header">
<image class="header-background" src="/static/assets/foundation/opaque/auth-header.png" mode="aspectFill" />
<image class="header-seal" src="/static/assets/foundation/transparent/brand-seal.png" mode="aspectFit" />
</view>
<view class="brand-intro">
<view class="title-decoration">
<image class="title-cloud title-cloud-left" src="/static/assets/foundation/transparent/auth-title-cloud.png" mode="aspectFit" />
<text class="brand-title">家谱</text>
<image class="title-cloud title-cloud-right" src="/static/assets/foundation/transparent/auth-title-cloud.png" mode="aspectFit" />
</view>
<view class="brand-divider brand-divider--top">
<view class="brand-divider__line" />
<image class="brand-divider__ornament" src="/static/assets/foundation/transparent/auth-divider-knot.png" mode="aspectFit" />
<view class="brand-divider__line" />
</view>
<text class="brand-subtitle">为家族留存可传承的记忆</text>
<view class="brand-divider brand-divider--bottom">
<view class="brand-divider__line" />
<image class="brand-divider__ornament" src="/static/assets/foundation/transparent/auth-divider-knot.png" mode="aspectFit" />
<view class="brand-divider__line" />
</view>
</view>
<view class="entry-actions">
<view class="entry-button entry-button--primary" hover-class="entry-button--pressed" @click="openLogin">
<!-- 完整不透明按钮皮肤承载底色边框与角纹内容组只保留可访问的图标和文案 -->
<image class="entry-button__skin" src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
<view class="entry-button__content">
<image class="entry-button__icon" src="/static/assets/foundation/transparent/auth-login-outline.png" mode="aspectFit" />
<text>登录</text>
</view>
</view>
<view class="entry-button entry-button--secondary" hover-class="entry-button--pressed" @click="prepareWechatLogin">
<image class="entry-button__skin" src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" />
<view class="entry-button__content">
<image class="entry-button__icon entry-button__icon--wechat" src="/static/assets/foundation/transparent/auth-wechat.png" mode="aspectFit" />
<text>微信登录</text>
</view>
</view>
<view class="register-link" hover-class="link-hover" @click="prepareRegister">
<text>还没有账号<text class="register-emphasis">注册账号</text></text>
</view>
</view>
<view class="agreement-row" @click="toggleAgreement">
<view class="agreement-check" :class="{ checked: agreed }">
<text v-if="agreed"></text>
</view>
<view class="agreement-copy">
<text>我已阅读并同意</text>
<text class="agreement-link" @click.stop="prepareAgreement">用户协议</text>
<text></text>
<text class="agreement-link" @click.stop="prepareAgreement">隐私政策</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const agreed = ref(false)
const toggleAgreement = () => {
agreed.value = !agreed.value
}
const requireAgreement = () => {
if (agreed.value) return true
uni.showToast({ title: '请先阅读并同意相关协议', icon: 'none' })
return false
}
const openLogin = () => {
if (!requireAgreement()) return
uni.navigateTo({ url: '/pages/auth/a02-login?agreed=1' })
}
const prepareWechatLogin = () => {
if (!requireAgreement()) return
uni.showToast({ title: '微信登录功能准备中', icon: 'none' })
}
const prepareRegister = () => {
if (!requireAgreement()) return
uni.showToast({ title: '注册页面准备中', icon: 'none' })
}
const prepareAgreement = () => {
uni.showToast({ title: '协议页面准备中', icon: 'none' })
}
</script>
<style scoped lang="scss">
.auth-page {
position: relative;
min-height: 100vh;
background: #f7f1e6;
}
.paper-background,
.scenery-background {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.paper-background { opacity: 0.96; }
.scenery-background { opacity: 0.82; }
.auth-content {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
box-sizing: border-box;
min-height: 100vh;
padding-bottom: calc(44rpx + env(safe-area-inset-bottom));
}
.auth-header {
position: relative;
height: 253rpx;
overflow: hidden;
}
.header-background {
width: 100%;
height: 100%;
}
.header-seal {
position: absolute;
top: 70rpx;
left: 50%;
width: 136rpx;
height: 136rpx;
transform: translateX(-50%);
}
.brand-intro {
display: flex;
flex-direction: column;
align-items: center;
padding: 150rpx 56rpx 0;
color: #3f2c1d;
}
.title-decoration {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
.brand-title {
margin: 0 12rpx;
font-family: STKaiti, KaiTi, serif;
font-size: 112rpx;
font-weight: 700;
letter-spacing: 12rpx;
line-height: 1;
}
.title-cloud { width: 64rpx; height: 40rpx; }
.title-cloud-left { margin-right: 0; }
.title-cloud-right { margin-left: 0; transform: scaleX(-1); }
.brand-divider {
display: flex;
align-items: center;
justify-content: center;
width: 426rpx;
}
.brand-divider--top { margin: 47rpx 0 21rpx; }
.brand-divider--bottom { margin: 34rpx 0 30rpx; }
.brand-divider__line {
flex: 1;
height: 1rpx;
background: #d5a34f;
}
.brand-divider__ornament {
width: 44rpx;
height: 24rpx;
margin: 0 14rpx;
}
.brand-subtitle {
color: #624631;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
letter-spacing: 4rpx;
}
.entry-actions {
margin: 95rpx 110rpx 0;
}
.entry-button {
position: relative;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: 100%;
height: 118rpx;
font-family: STKaiti, KaiTi, serif;
font-size: 38rpx;
letter-spacing: 4rpx;
}
.entry-button__skin {
position: absolute;
inset: 0;
z-index: 1;
width: 100%;
height: 100%;
pointer-events: none;
}
.entry-button--primary {
color: #fffaf0;
}
.entry-button--secondary {
margin-top: 51rpx;
color: #60442f;
}
.entry-button__icon {
width: 46rpx;
height: 46rpx;
margin-right: 18rpx;
}
.entry-button__icon--wechat { width: 52rpx; }
.entry-button--primary .entry-button__icon { filter: brightness(0) invert(1); }
.entry-button__content {
position: relative;
z-index: 3;
display: flex;
align-items: center;
transform: translateX(-20rpx);
}
.entry-button--pressed { opacity: 0.84; }
.register-link {
display: flex;
align-items: center;
justify-content: center;
margin-top: 98rpx;
color: #60442f;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
letter-spacing: 2rpx;
white-space: nowrap;
}
.register-emphasis { color: #b7170d; }
.link-hover { opacity: 0.65; }
.agreement-row {
display: flex;
align-items: center;
justify-content: center;
margin-top: 141rpx;
padding: 0 44rpx calc(32rpx + env(safe-area-inset-bottom));
color: #6b5a4a;
font-size: 20rpx;
line-height: 30rpx;
}
.agreement-check {
display: flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: 30rpx;
height: 30rpx;
margin: 0 12rpx 0 0;
border: 2rpx solid #b88d4b;
border-radius: 50%;
color: #fffaf0;
font-size: 20rpx;
line-height: 1;
}
.agreement-check.checked { background: #b7170d; border-color: #b7170d; }
.agreement-copy {
display: flex;
align-items: center;
line-height: 30rpx;
text-align: center;
white-space: nowrap;
}
.agreement-link { color: #b7170d; }
</style>