Files
jiapuapp/pages/auth/entry.vue
T
2026-07-13 15:35:16 +08:00

308 lines
7.6 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.
<template>
<view class="auth-page entry-page">
<image class="paper-background" src="/static/assets/backgrounds/auth-rice-paper-v1.jpg" mode="aspectFill" />
<image class="scenery-background" src="/static/assets/backgrounds/auth-ink-scenery-v1.png" mode="aspectFill" />
<view class="auth-content">
<view class="auth-header">
<image class="header-background" src="/static/assets/backgrounds/auth-ancestral-header-v1.png" mode="aspectFill" />
<image class="header-seal" src="/static/assets/icons/brand/jiapu-seal-logo-header.png" mode="aspectFit" />
</view>
<view class="brand-intro">
<view class="title-decoration">
<image class="title-cloud title-cloud-left" src="/static/assets/icons/action/create-cloud-v2.png" mode="aspectFit" />
<text class="brand-title">家谱</text>
<image class="title-cloud title-cloud-right" src="/static/assets/icons/action/create-cloud-v2.png" mode="aspectFit" />
</view>
<view class="brand-divider brand-divider--top">
<view class="brand-divider__line" />
<image class="brand-divider__ornament" src="/static/assets/icons/action/create-cloud-v2.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/icons/action/create-cloud-v2.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__icon" src="/static/assets/icons/auth/login-outline-v1.png" mode="aspectFit" />
<text>登录</text>
</view>
<view class="entry-button entry-button--secondary" hover-class="entry-button--pressed" @click="prepareWechatLogin">
<image class="entry-button__icon entry-button__icon--wechat" src="/static/assets/icons/auth/wechat-licensed-v1.png" mode="aspectFit" />
<text>微信登录</text>
</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/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: 44rpx;
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 24rpx;
font-family: STKaiti, KaiTi, serif;
font-size: 112rpx;
font-weight: 700;
letter-spacing: 12rpx;
line-height: 1;
}
.title-cloud {
width: 76rpx;
height: 46rpx;
}
.title-cloud-left { margin-right: 10rpx; }
.title-cloud-right { margin-left: 10rpx; 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;
border: 2rpx solid #d8ad63;
border-radius: 6rpx;
font-family: STKaiti, KaiTi, serif;
font-size: 38rpx;
letter-spacing: 4rpx;
}
.entry-button::after {
position: absolute;
inset: 10rpx;
border: 1rpx solid rgba(225, 180, 105, 0.92);
border-radius: 2rpx;
content: '';
pointer-events: none;
}
.entry-button--primary {
border-color: #9e170e;
background: #b7170d;
color: #fffaf0;
}
.entry-button--primary::after { border-color: #edc67c; }
.entry-button--secondary {
margin-top: 51rpx;
background: rgba(255, 252, 245, 0.82);
color: #60442f;
}
.entry-button__icon {
position: relative;
z-index: 1;
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 > text { position: relative; z-index: 1; }
.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: flex-start;
justify-content: center;
margin-top: 128rpx;
padding: 0 44rpx calc(32rpx + env(safe-area-inset-bottom));
color: #6b5a4a;
font-size: 24rpx;
line-height: 1.7;
}
.agreement-check {
display: flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: 28rpx;
height: 28rpx;
margin: 7rpx 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 { text-align: center; }
.agreement-link { color: #b7170d; }
</style>