refactor(auth): simplify login page by removing redundant profile form and focusing on one-click auth
这个提交包含在:
@@ -8,45 +8,6 @@
|
||||
<text class="brand-app-name">同城陪玩生活圈</text>
|
||||
<text class="brand-slogan">年轻人的同城搭子与温暖陪伴社交平台</text>
|
||||
</view>
|
||||
|
||||
<!-- 微信小程序官方标准:头像与昵称授权填写卡片 -->
|
||||
<view class="auth-profile-card">
|
||||
<view class="profile-card-header">
|
||||
<text class="profile-card-title">完善个人主页资料</text>
|
||||
<text class="profile-card-tip">遵循微信小程序用户资料填写规范</text>
|
||||
</view>
|
||||
|
||||
<!-- 微信官方 open-type="chooseAvatar" 原生头像选择 -->
|
||||
<view class="avatar-choose-row">
|
||||
<button
|
||||
class="avatar-picker-btn btn-active"
|
||||
open-type="chooseAvatar"
|
||||
@chooseavatar="onChooseAvatar"
|
||||
>
|
||||
<image class="chosen-avatar" :src="userForm.avatar || DEFAULT_AVATAR" mode="aspectFill" />
|
||||
<view class="avatar-badge">
|
||||
<image class="camera-icon-svg" :src="ICONS.camera" mode="aspectFit" />
|
||||
</view>
|
||||
</button>
|
||||
<view class="avatar-tip-wrap">
|
||||
<text class="avatar-tip-title">点击设置微信头像</text>
|
||||
<text class="avatar-tip-sub">轻触一键拉起微信头像快速选用</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 微信官方 type="nickname" 原生昵称输入框 -->
|
||||
<view class="nickname-input-row">
|
||||
<text class="input-label">昵称</text>
|
||||
<input
|
||||
class="nickname-input"
|
||||
type="nickname"
|
||||
v-model="userForm.nickname"
|
||||
placeholder="点击快速填入或输入昵称"
|
||||
placeholder-class="ph-style"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 微信手机号授权快捷登录主操作区 (微信官方推荐格式) -->
|
||||
<view class="main-action-section">
|
||||
<button
|
||||
@@ -108,7 +69,6 @@ import { ref, onMounted } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import { ICONS } from '@/common/icons.js';
|
||||
import { getCurrentThemeKey, applyThemeToNativeUI } from '@/common/theme.js';
|
||||
import { uploadImage } from '@/common/api.js';
|
||||
|
||||
const APP_LOGO = 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=200';
|
||||
const DEFAULT_AVATAR = 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=200';
|
||||
@@ -117,11 +77,6 @@ const currentThemeKey = ref(getCurrentThemeKey());
|
||||
const agreedProtocol = ref(true);
|
||||
const redirectUrl = ref('');
|
||||
|
||||
const userForm = ref({
|
||||
avatar: DEFAULT_AVATAR,
|
||||
nickname: '微信用户'
|
||||
});
|
||||
|
||||
const DEMO_ACCOUNTS = [
|
||||
{
|
||||
id: 1001,
|
||||
@@ -169,19 +124,6 @@ onShow(() => {
|
||||
applyThemeToNativeUI(currentThemeKey.value);
|
||||
});
|
||||
|
||||
const onChooseAvatar = async (e) => {
|
||||
const avatarUrl = e?.detail?.avatarUrl;
|
||||
if (!avatarUrl) return;
|
||||
|
||||
userForm.value.avatar = avatarUrl;
|
||||
try {
|
||||
const onlineUrl = await uploadImage(avatarUrl);
|
||||
if (onlineUrl) {
|
||||
userForm.value.avatar = onlineUrl;
|
||||
}
|
||||
} catch (_) {}
|
||||
};
|
||||
|
||||
const completeLogin = (userId, customData = {}) => {
|
||||
uni.showLoading({ title: '正在登录...' });
|
||||
|
||||
@@ -189,13 +131,11 @@ const completeLogin = (userId, customData = {}) => {
|
||||
uni.hideLoading();
|
||||
uni.removeStorageSync('user_has_logged_out');
|
||||
uni.setStorageSync('userId', userId);
|
||||
if (customData.nickname || userForm.value.nickname) {
|
||||
uni.setStorageSync('userInfo', {
|
||||
id: userId,
|
||||
nickname: customData.nickname || userForm.value.nickname,
|
||||
avatar: customData.avatar || userForm.value.avatar
|
||||
});
|
||||
}
|
||||
uni.setStorageSync('userInfo', {
|
||||
id: userId,
|
||||
nickname: customData.nickname || '微信用户',
|
||||
avatar: customData.avatar || DEFAULT_AVATAR
|
||||
});
|
||||
|
||||
uni.$emit('login-success', { userId });
|
||||
uni.showToast({ title: '登录成功', icon: 'success', duration: 1500 });
|
||||
@@ -230,8 +170,8 @@ const handleGetPhoneNumber = (e) => {
|
||||
// #ifdef MP-WEIXIN
|
||||
if (e && e.detail && (e.detail.code || e.detail.encryptedData)) {
|
||||
completeLogin(1001, {
|
||||
nickname: userForm.value.nickname || '微信用户',
|
||||
avatar: userForm.value.avatar
|
||||
nickname: '微信用户',
|
||||
avatar: DEFAULT_AVATAR
|
||||
});
|
||||
} else {
|
||||
console.warn('[WeChat Login] 未授权手机号或环境受限:', e?.detail?.errMsg);
|
||||
@@ -310,8 +250,8 @@ const openPrivacyAgreement = () => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 24rpx;
|
||||
margin-bottom: 44rpx;
|
||||
margin-top: 60rpx;
|
||||
margin-bottom: 64rpx;
|
||||
|
||||
.brand-logo-wrap {
|
||||
width: 140rpx;
|
||||
@@ -344,128 +284,6 @@ const openPrivacyAgreement = () => {
|
||||
}
|
||||
}
|
||||
|
||||
/* 微信官方头像昵称卡片 */
|
||||
.auth-profile-card {
|
||||
background: #151D30;
|
||||
border-radius: 28rpx;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
padding: 32rpx;
|
||||
margin-bottom: 36rpx;
|
||||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.3);
|
||||
|
||||
.profile-card-header {
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.profile-card-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #F8FAFC;
|
||||
display: block;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
.profile-card-tip {
|
||||
font-size: 20rpx;
|
||||
color: #64748B;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-choose-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
padding-bottom: 24rpx;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
|
||||
.avatar-picker-btn {
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
border-radius: 55rpx;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
background: transparent;
|
||||
border: none;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.chosen-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 55rpx;
|
||||
border: 4rpx solid #6366F1;
|
||||
}
|
||||
|
||||
.avatar-badge {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 50%;
|
||||
background: #6366F1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2rpx solid #151D30;
|
||||
|
||||
.camera-icon-svg {
|
||||
width: 22rpx;
|
||||
height: 22rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-tip-wrap {
|
||||
flex: 1;
|
||||
|
||||
.avatar-tip-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: #F8FAFC;
|
||||
display: block;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
.avatar-tip-sub {
|
||||
font-size: 20rpx;
|
||||
color: #94A3B8;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nickname-input-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 24rpx;
|
||||
|
||||
.input-label {
|
||||
width: 100rpx;
|
||||
font-size: 26rpx;
|
||||
color: #94A3B8;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.nickname-input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
font-size: 26rpx;
|
||||
color: #F8FAFC;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 14rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.ph-style {
|
||||
color: #64748B;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 主操作按钮区 */
|
||||
.main-action-section {
|
||||
display: flex;
|
||||
@@ -676,58 +494,6 @@ const openPrivacyAgreement = () => {
|
||||
}
|
||||
}
|
||||
|
||||
.auth-profile-card {
|
||||
background: #FFFFFF;
|
||||
border-color: #E7E5E4;
|
||||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);
|
||||
|
||||
.profile-card-header {
|
||||
.profile-card-title {
|
||||
color: #1C1917;
|
||||
}
|
||||
.profile-card-tip {
|
||||
color: #A8A29E;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-choose-row {
|
||||
border-bottom-color: #F5F5F4;
|
||||
|
||||
.avatar-picker-btn .chosen-avatar {
|
||||
border-color: #EA580C;
|
||||
}
|
||||
.avatar-picker-btn .avatar-badge {
|
||||
background: #EA580C;
|
||||
border-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.avatar-tip-wrap {
|
||||
.avatar-tip-title {
|
||||
color: #1C1917;
|
||||
}
|
||||
.avatar-tip-sub {
|
||||
color: #78716C;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nickname-input-row {
|
||||
.input-label {
|
||||
color: #78716C;
|
||||
}
|
||||
|
||||
.nickname-input {
|
||||
background: #FDFBF7;
|
||||
border-color: #E7E5E4;
|
||||
color: #1C1917;
|
||||
}
|
||||
|
||||
.ph-style {
|
||||
color: #A8A29E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main-action-section {
|
||||
.auth-guarantee-tip {
|
||||
color: #A8A29E;
|
||||
|
||||
@@ -453,18 +453,18 @@ describe('ContentSecurityService & Compliance Architecture (TDD 微信内容安
|
||||
expect(pagesJson).toContain('账号登录与注册');
|
||||
});
|
||||
|
||||
it('登录页面必须符合微信官方头像昵称与手机号快捷授权标准', () => {
|
||||
it('登录页面必须符合微信官方手机号快捷授权与极简合规标准', () => {
|
||||
const loginPath = path.join(rootDir, 'pwuniapp', 'pages', 'auth', 'login.vue');
|
||||
const content = fs.readFileSync(loginPath, 'utf-8');
|
||||
expect(content).toContain('open-type="chooseAvatar"');
|
||||
expect(content).toContain('@chooseavatar="onChooseAvatar"');
|
||||
expect(content).toContain('type="nickname"');
|
||||
expect(content).toContain('open-type="getPhoneNumber"');
|
||||
expect(content).toContain('@getphonenumber="handleGetPhoneNumber"');
|
||||
expect(content).toContain('一键授权快捷登录');
|
||||
expect(content).toContain('DEMO_ACCOUNTS');
|
||||
expect(content).toContain('用户服务协议');
|
||||
expect(content).toContain('隐私保护指引');
|
||||
// 验证已彻底移除登录大门前强制填写的头像昵称卡片,保障成熟商业极速登录体验
|
||||
expect(content).not.toContain('open-type="chooseAvatar"');
|
||||
expect(content).not.toContain('type="nickname"');
|
||||
});
|
||||
|
||||
it('登录注册页面代码严禁包含任何系统 Emoji', () => {
|
||||
|
||||
在新工单中引用
屏蔽一个用户