Files
jiapuapp/pages/auth/a05-reset-password.vue
T
2026-07-14 17:36:43 +08:00

329 lines
8.1 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-05用途通过手机号验证后重设登录密码 -->
<template>
<view class="auth-page reset-page">
<!-- 认证页背景复用已验收纸纹与淡墨山水不绘制 CSS 装饰面 -->
<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">
<!-- 朱砂祠堂头和谱印与 A02/A04 保持同一认证入口 -->
<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="reset-panel">
<image class="reset-panel__skin" src="/static/assets/modules/auth/opaque/a02-login-panel.png" mode="scaleToFill" />
<view class="reset-panel__content">
<!-- 页标题只说明当前任务不暴露内部页面编号 -->
<view class="page-heading">
<image class="reset-title-cloud" src="/static/assets/foundation/transparent/auth-title-cloud.png" mode="aspectFit" />
<view class="back-button" hover-class="back-hover" @click="goBack">
<image class="back-button__icon" src="/static/assets/foundation/transparent/chevron-right.png" mode="aspectFit" />
</view>
<view class="page-heading__copy">
<text class="page-title">重设密码</text>
<text class="page-subtitle">验证手机号后重新设置登录密码</text>
</view>
</view>
<image class="reset-divider" src="/static/assets/foundation/transparent/auth-divider-knot.png" mode="aspectFit" />
<!-- 四项真实输入在当前页完成身份验证与两次密码确认 -->
<view class="form-content">
<view class="input-row">
<text class="input-label">手机号</text>
<input v-model.trim="phone" class="auth-input" type="number" maxlength="11" placeholder="请输入手机号" placeholder-class="placeholder" />
</view>
<view class="input-row code-row">
<text class="input-label">验证码</text>
<input v-model.trim="verificationCode" class="auth-input" type="number" maxlength="6" placeholder="请输入验证码" placeholder-class="placeholder" />
<view class="get-code" hover-class="text-hover" @click="prepareGetCode">获取验证码</view>
</view>
<view class="input-row">
<text class="input-label">新密码</text>
<input v-model="password" class="auth-input" password placeholder="请设置新密码" placeholder-class="placeholder" />
</view>
<view class="input-row">
<text class="input-label">确认新密码</text>
<input v-model="confirmPassword" class="auth-input" password placeholder="请再次输入新密码" placeholder-class="placeholder" />
</view>
</view>
<view class="reset-submit" hover-class="button-hover" @click="submitReset">
<image class="reset-submit__skin" src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
<text class="reset-submit__content">确认重设</text>
</view>
<text class="reset-tip">重设完成后请使用新密码登录</text>
<view class="login-entry">
<text>想起密码了</text>
<view class="login-entry__link" hover-class="text-hover" @click="prepareLogin">返回登录</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const phone = ref('')
const verificationCode = ref('')
const password = ref('')
const confirmPassword = ref('')
const goBack = () => {
uni.navigateBack()
}
const prepareLogin = () => uni.navigateTo({ url: '/pages/auth/a02-login' })
const prepareGetCode = () => {
uni.showToast({ title: '验证码功能待接入', icon: 'none' })
}
const submitReset = () => {
if (!/^1\d{10}$/.test(phone.value)) {
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
return
}
if (!/^\d{6}$/.test(verificationCode.value)) {
uni.showToast({ title: '请输入 6 位验证码', icon: 'none' })
return
}
if (!password.value) {
uni.showToast({ title: '请设置新密码', icon: 'none' })
return
}
if (password.value !== confirmPassword.value) {
uni.showToast({ title: '两次密码输入不一致', icon: 'none' })
return
}
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.76; }
.auth-content {
position: relative;
z-index: 1;
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%);
}
.reset-panel {
position: relative;
min-height: 1240rpx;
margin: 32rpx 42rpx 0;
}
.reset-panel__skin {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.reset-panel__content {
position: relative;
z-index: 1;
box-sizing: border-box;
min-height: 1240rpx;
padding: 66rpx 50rpx 72rpx;
}
.page-heading {
position: relative;
display: flex;
align-items: center;
}
.reset-title-cloud {
position: absolute;
top: -26rpx;
right: 2rpx;
width: 154rpx;
height: 92rpx;
opacity: 0.62;
}
.page-heading__copy {
position: relative;
z-index: 1;
}
.back-button {
display: flex;
align-items: center;
justify-content: center;
width: 56rpx;
height: 56rpx;
margin-right: 18rpx;
}
.back-hover { opacity: 0.62; }
.back-button__icon {
width: 42rpx;
height: 42rpx;
transform: scaleX(-1);
}
.page-title,
.page-subtitle {
display: block;
}
.page-title {
color: #3f2c1d;
font-family: STKaiti, KaiTi, serif;
font-size: 50rpx;
font-weight: 700;
letter-spacing: 4rpx;
}
.page-subtitle {
margin-top: 10rpx;
color: #8c7864;
font-size: 24rpx;
letter-spacing: 1rpx;
}
.reset-divider {
display: block;
width: 154rpx;
height: 42rpx;
margin: 40rpx auto 0;
}
.form-content { margin-top: 30rpx; }
.input-row {
display: flex;
align-items: center;
min-height: 112rpx;
border-bottom: 1rpx solid #e5d4b7;
}
.input-label {
width: 174rpx;
color: #674b35;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
}
.auth-input {
flex: 1;
min-width: 0;
height: 104rpx;
color: #3f2c1d;
font-size: 29rpx;
}
.placeholder { color: #b3a895; }
.get-code {
flex: 0 0 auto;
padding-left: 18rpx;
border-left: 1rpx solid #ddc7a3;
color: #a7160c;
font-size: 24rpx;
}
.reset-submit {
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 128rpx;
margin-top: 52rpx;
overflow: hidden;
}
.reset-submit__skin {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.reset-submit__content {
position: relative;
z-index: 1;
color: #fffaf0;
font-family: STKaiti, KaiTi, serif;
font-size: 36rpx;
letter-spacing: 6rpx;
}
.button-hover { opacity: 0.84; }
.text-hover { opacity: 0.64; }
.reset-tip {
display: block;
margin-top: 26rpx;
color: #8c7864;
font-size: 22rpx;
text-align: center;
}
.login-entry {
display: flex;
align-items: center;
justify-content: center;
margin-top: 2rpx;
color: #6b5a4a;
font-size: 24rpx;
}
.login-entry__link {
display: flex;
align-items: center;
min-height: 82rpx;
margin-left: 8rpx;
color: #a7160c;
}
</style>