Files
xinlong-shop-taro/.workbuddy/sms-login-preview.html
赵忠林 b47ea6bd90 feat(passport): 重构短信登录页并提供手机号授权降级入口
- 修复购物车数据库缺失 spec_info 字段问题,新增迁移脚本
- 登录页处理手机号授权失败,按错误类型弹窗引导用户改用短信登录
- 登录页新增长期显示的「使用短信验证码登录」入口,提升用户降级体验
- 注册页同步改造,去除微信小程序环境下短信按钮隐藏问题
- 短信登录页整体 UI 重构,弃用 NutUI 组件,采用原生组件实现
- 短信登录页新增渐变背景、浮动光圈、圆形 logo、卡片输入区设计
- 实现手机号输入、验证码发送、倒计时及登录校验逻辑全覆盖
- 短信登录页新增返回微信快捷登录链接,避免用户被困登录流程
- 新增配套样式文件,实现多重动效及分阶段入场动画
- 保证类型检查和编译无误,增加设计稿 HTML 预览文件
2026-07-15 18:55:12 +08:00

310 lines
8.1 KiB
HTML
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.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>sms-login UI 预览</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
background: #f0f0f3;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 40px 0 80px;
font-family: -apple-system, "PingFang SC", "Helvetica Neue", sans-serif;
}
h1 { font-size: 18px; color: #666; margin-bottom: 30px; font-weight: 500; }
.phone {
width: 375px;
height: 812px;
background: #fff;
border-radius: 50px;
box-shadow: 0 30px 80px rgba(0,0,0,0.18), 0 0 0 12px #1a1a1a, 0 0 0 14px #2a2a2a;
overflow: hidden;
position: relative;
}
.phone::before {
content: "";
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 150px;
height: 28px;
background: #1a1a1a;
border-radius: 0 0 18px 18px;
z-index: 100;
}
.status-bar {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 44px;
padding: 0 30px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 15px;
color: #1a1a1a;
font-weight: 600;
z-index: 50;
}
.status-bar .right {
display: flex;
gap: 6px;
align-items: center;
}
.nav-bar {
position: absolute;
top: 44px;
left: 0;
right: 0;
height: 44px;
display: flex;
justify-content: center;
align-items: center;
font-size: 17px;
font-weight: 600;
color: #1a1a1a;
z-index: 50;
}
.nav-bar::before {
content: "<";
position: absolute;
left: 18px;
font-size: 24px;
color: #1a1a1a;
}
.nav-bar::after {
content: "···";
position: absolute;
right: 60px;
font-size: 22px;
color: #1a1a1a;
letter-spacing: 2px;
}
.screen {
width: 100%;
height: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: relative;
overflow: hidden;
padding-top: 88px;
}
.bg-circle {
position: absolute;
border-radius: 50%;
background: #fff;
opacity: 0.1;
}
.bg-c1 { width: 400px; height: 400px; top: -150px; right: -100px; }
.bg-c2 { width: 300px; height: 300px; bottom: 10%; left: -100px; opacity: 0.08; }
.bg-gradient {
position: absolute;
top: -50%; left: -50%; right: -50%; bottom: -50%;
background: radial-gradient(circle at 30% 50%, rgba(255,255,255,0.1) 0%, transparent 50%),
radial-gradient(circle at 70% 80%, rgba(255,255,255,0.08) 0%, transparent 50%);
}
.content {
position: relative;
z-index: 1;
padding: 0 50px;
}
.header {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 32px;
margin-bottom: 60px;
}
.logo {
width: 140px;
height: 140px;
border-radius: 35px;
background: rgba(255,255,255,0.95);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 36px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
.logo-icon { font-size: 72px; line-height: 1; }
.title {
font-size: 52px;
font-weight: 700;
color: #fff;
margin-bottom: 18px;
text-shadow: 0 2px 10px rgba(0,0,0,0.2);
letter-spacing: 2px;
}
.subtitle {
font-size: 26px;
color: rgba(255,255,255,0.85);
text-align: center;
}
.card {
background: rgba(255,255,255,0.98);
border-radius: 28px;
padding: 12px 32px;
margin-bottom: 48px;
box-shadow: 0 20px 60px rgba(0,0,0,0.18);
}
.field {
display: flex;
align-items: center;
height: 110px;
}
.field-icon { font-size: 36px; margin-right: 20px; line-height: 1; }
.field-input {
flex: 1;
font-size: 30px;
color: #333;
background: transparent;
border: none;
outline: none;
}
.field-input::placeholder { color: #b8b8b8; }
.divider {
height: 1px;
background: linear-gradient(to right, transparent, #e8e8e8 20%, #e8e8e8 80%, transparent);
}
.send-btn {
flex-shrink: 0;
height: 64px;
padding: 0 22px;
border-radius: 32px;
background: linear-gradient(135deg, #07c160, #06ad56);
color: #fff;
font-size: 26px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
margin-left: 16px;
box-shadow: 0 6px 20px rgba(7, 193, 96, 0.35);
white-space: nowrap;
}
.submit {
height: 100px;
width: 100%;
border-radius: 50px;
background: linear-gradient(135deg, #07c160, #06ad56);
color: #fff;
font-size: 34px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
letter-spacing: 4px;
box-shadow: 0 12px 36px rgba(7, 193, 96, 0.4);
margin-bottom: 36px;
}
.back {
display: flex;
align-items: center;
justify-content: center;
height: 80px;
margin-bottom: 32px;
}
.back-icon { font-size: 30px; color: rgba(255,255,255,0.9); margin-right: 10px; }
.back-text {
font-size: 28px;
color: rgba(255,255,255,0.9);
text-decoration: underline;
}
.tips {
position: absolute;
bottom: 40px;
left: 0;
right: 0;
padding: 0 50px;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.tips-text { font-size: 22px; color: rgba(255,255,255,0.7); }
.tips-link { font-size: 22px; color: #fff; text-decoration: underline; margin: 0 4px; }
.legend {
margin-top: 30px;
padding: 20px 28px;
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
font-size: 13px;
color: #555;
max-width: 375px;
line-height: 1.7;
}
.legend strong { color: #07c160; }
</style>
</head>
<body>
<h1>sms-login.tsx 新 UI 预览(按真机 375×812 渲染)</h1>
<div class="phone">
<div class="status-bar">
<span>18:36</span>
<span class="right">📶 🔋</span>
</div>
<div class="nav-bar">验证码登录</div>
<div class="screen">
<div class="bg-gradient"></div>
<div class="bg-circle bg-c1"></div>
<div class="bg-circle bg-c2"></div>
<div class="content">
<div class="header">
<div class="logo"><span class="logo-icon">📱</span></div>
<div class="title">验证码登录</div>
<div class="subtitle">未注册的手机号验证后将自动注册</div>
</div>
<div class="card">
<div class="field">
<span class="field-icon">📞</span>
<input class="field-input" type="text" placeholder="请输入手机号码" maxlength="11" />
</div>
<div class="divider"></div>
<div class="field">
<span class="field-icon">🔐</span>
<input class="field-input" type="text" placeholder="请输入6位验证码" maxlength="6" />
<div class="send-btn">获取验证码</div>
</div>
</div>
<div class="submit">登录 / 注册</div>
<div class="back">
<span class="back-icon"></span>
<span class="back-text">返回微信快捷登录</span>
</div>
</div>
<div class="tips">
<span class="tips-text">登录即代表您已阅读并同意</span>
<span class="tips-link">《服务协议》</span>
<span class="tips-text"></span>
<span class="tips-link">《隐私政策》</span>
</div>
</div>
</div>
<div class="legend">
<strong>视觉变更:</strong><br>
① 紫蓝渐变背景 + 浮动光圈(和 login.tsx 同一套色系)<br>
② 顶部圆形 logo + 大字标题 + 副标题<br>
③ 白色卡片输入区(圆角 28px + 阴影),手机号/验证码图标 + 灰线分隔<br>
④ 验证码右侧绿色胶囊「获取验证码」按钮倒计时会变成「60s 后重试」)<br>
⑤ 绿色渐变登录大按钮(圆角 50px + 阴影)<br>
⑥ 「← 返回微信快捷登录」白色下划线链接(避免用户被困住)<br>
⑦ 底部协议 + 服务协议/隐私政策超链接<br>
<br>
<strong>业务逻辑保留:</strong>表单 state、60s 倒计时、handleSendCode/handleLogin 校验、redirect 跳转、邀请参数透传inviter/source/t全部不变
</div>
</body>
</html>