feat(mp): 登录页 UX 优化 — 协议区域就近显示
- 协议勾选移至对应操作区域(微信登录 + 绑定区)更直觉 - 统一 SHOW_DEV_LOGIN 常量控制开发模式入口 - 抽取 requireAgreement() 复用协议检查逻辑
This commit is contained in:
@@ -9,6 +9,7 @@ declare const __wxConfig: Record<string, unknown> | undefined;
|
|||||||
|
|
||||||
const IS_DEV = process.env.NODE_ENV !== 'production';
|
const IS_DEV = process.env.NODE_ENV !== 'production';
|
||||||
const IS_SIMULATOR = typeof __wxConfig !== 'undefined' && (__wxConfig as Record<string, unknown>)?.envVersion === 'develop';
|
const IS_SIMULATOR = typeof __wxConfig !== 'undefined' && (__wxConfig as Record<string, unknown>)?.envVersion === 'develop';
|
||||||
|
const SHOW_DEV_LOGIN = (IS_DEV || IS_SIMULATOR) && !!(process.env.TARO_APP_DEV_USER && process.env.TARO_APP_DEV_PASS);
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const [agreed, setAgreed] = useState(false);
|
const [agreed, setAgreed] = useState(false);
|
||||||
@@ -40,11 +41,16 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleWechatLogin = async () => {
|
const requireAgreement = () => {
|
||||||
if (!agreed) {
|
if (!agreed) {
|
||||||
Taro.showToast({ title: '请先阅读并同意用户协议', icon: 'none' });
|
Taro.showToast({ title: '请先阅读并同意用户协议', icon: 'none' });
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleWechatLogin = async () => {
|
||||||
|
if (!requireAgreement()) return;
|
||||||
try {
|
try {
|
||||||
const { code } = await Taro.login();
|
const { code } = await Taro.login();
|
||||||
const result = await login(code);
|
const result = await login(code);
|
||||||
@@ -60,23 +66,6 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDevQuickLogin = async () => {
|
|
||||||
const devUser = process.env.TARO_APP_DEV_USER || '';
|
|
||||||
const devPass = process.env.TARO_APP_DEV_PASS || '';
|
|
||||||
if (!devUser || !devPass) {
|
|
||||||
Taro.showToast({ title: '未配置开发账号', icon: 'none' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const success = await credentialLogin(devUser, devPass);
|
|
||||||
if (success) {
|
|
||||||
navigateAfterLogin();
|
|
||||||
}
|
|
||||||
} catch (err: unknown) {
|
|
||||||
Taro.showToast({ title: err instanceof Error ? err.message : '登录失败', icon: 'none' });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleGetPhone = async (e: { detail: { errMsg: string; encryptedData: string; iv: string } }) => {
|
const handleGetPhone = async (e: { detail: { errMsg: string; encryptedData: string; iv: string } }) => {
|
||||||
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
|
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
|
||||||
Taro.showToast({ title: '需要授权手机号', icon: 'none' });
|
Taro.showToast({ title: '需要授权手机号', icon: 'none' });
|
||||||
@@ -100,6 +89,7 @@ export default function Login() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// DevTools 中 getPhoneNumber 不可用,直接传 mock 数据绕过微信 SDK
|
// DevTools 中 getPhoneNumber 不可用,直接传 mock 数据绕过微信 SDK
|
||||||
|
// 仅在后端 wechat_dev_mode=true 时有效,后端会生成 mock 手机号
|
||||||
const handleDevBindPhone = async () => {
|
const handleDevBindPhone = async () => {
|
||||||
try {
|
try {
|
||||||
const success = await bindPhone('dev_mock', 'dev_mock');
|
const success = await bindPhone('dev_mock', 'dev_mock');
|
||||||
@@ -117,6 +107,21 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDevQuickLogin = async () => {
|
||||||
|
if (!requireAgreement()) return;
|
||||||
|
const devUser = process.env.TARO_APP_DEV_USER || '';
|
||||||
|
const devPass = process.env.TARO_APP_DEV_PASS || '';
|
||||||
|
if (!devUser || !devPass) return;
|
||||||
|
try {
|
||||||
|
const success = await credentialLogin(devUser, devPass);
|
||||||
|
if (success) {
|
||||||
|
navigateAfterLogin();
|
||||||
|
}
|
||||||
|
} catch (err: unknown) {
|
||||||
|
Taro.showToast({ title: err instanceof Error ? err.message : '登录失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="login-page">
|
<View className="login-page">
|
||||||
{/* 品牌区 */}
|
{/* 品牌区 */}
|
||||||
@@ -130,16 +135,32 @@ export default function Login() {
|
|||||||
|
|
||||||
{!needBind ? (
|
{!needBind ? (
|
||||||
<>
|
<>
|
||||||
{/* 微信一键登录 */}
|
{/* 微信一键登录(主按钮) */}
|
||||||
<View className="login-wechat-btn" onClick={handleWechatLogin}>
|
<View className="login-wechat-btn" onClick={handleWechatLogin}>
|
||||||
<Text className="login-wechat-icon">微</Text>
|
<Text className="login-wechat-icon">微</Text>
|
||||||
<Text className="login-wechat-text">微信一键登录</Text>
|
<Text className="login-wechat-text">微信一键登录</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{/* 协议 */}
|
||||||
|
<View className="agreement-row">
|
||||||
|
<View
|
||||||
|
className={`agreement-check ${agreed ? 'checked' : ''}`}
|
||||||
|
onClick={() => setAgreed(!agreed)}
|
||||||
|
>
|
||||||
|
{agreed && <Text className="agreement-check-mark">✓</Text>}
|
||||||
|
</View>
|
||||||
|
<Text className="agreement-text">
|
||||||
|
登录即同意
|
||||||
|
<Text className="agreement-link" onClick={() => safeNavigateTo('/pages/legal/user-agreement')}>《用户协议》</Text>
|
||||||
|
和
|
||||||
|
<Text className="agreement-link" onClick={() => safeNavigateTo('/pages/legal/privacy-policy')}>《隐私政策》</Text>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<View className="login-bind-section">
|
<View className="login-bind-section">
|
||||||
{/* 真机:微信手机号授权 */}
|
{/* 真机:微信手机号授权 */}
|
||||||
{!(IS_DEV || IS_SIMULATOR) && (
|
{!SHOW_DEV_LOGIN && (
|
||||||
<Button
|
<Button
|
||||||
className="login-btn-bind"
|
className="login-btn-bind"
|
||||||
openType="getPhoneNumber"
|
openType="getPhoneNumber"
|
||||||
@@ -151,7 +172,7 @@ export default function Login() {
|
|||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{/* DevTools:跳过微信 SDK 直接调后端(后端 wechat_dev_mode 会用 mock 手机号) */}
|
{/* DevTools:跳过微信 SDK 直接调后端(后端 wechat_dev_mode 会用 mock 手机号) */}
|
||||||
{(IS_DEV || IS_SIMULATOR) && (
|
{SHOW_DEV_LOGIN && (
|
||||||
<Button
|
<Button
|
||||||
className="login-btn-bind"
|
className="login-btn-bind"
|
||||||
onClick={handleDevBindPhone}
|
onClick={handleDevBindPhone}
|
||||||
@@ -161,29 +182,28 @@ export default function Login() {
|
|||||||
授权手机号完成绑定(开发模式)
|
授权手机号完成绑定(开发模式)
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
{/* 协议 */}
|
||||||
|
<View className="agreement-row" style={{ marginTop: '16px' }}>
|
||||||
|
<View
|
||||||
|
className={`agreement-check ${agreed ? 'checked' : ''}`}
|
||||||
|
onClick={() => setAgreed(!agreed)}
|
||||||
|
>
|
||||||
|
{agreed && <Text className="agreement-check-mark">✓</Text>}
|
||||||
|
</View>
|
||||||
|
<Text className="agreement-text">
|
||||||
|
登录即同意
|
||||||
|
<Text className="agreement-link" onClick={() => safeNavigateTo('/pages/legal/user-agreement')}>《用户协议》</Text>
|
||||||
|
和
|
||||||
|
<Text className="agreement-link" onClick={() => safeNavigateTo('/pages/legal/privacy-policy')}>《隐私政策》</Text>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 协议 */}
|
|
||||||
<View className="agreement-row">
|
|
||||||
<View
|
|
||||||
className={`agreement-check ${agreed ? 'checked' : ''}`}
|
|
||||||
onClick={() => setAgreed(!agreed)}
|
|
||||||
>
|
|
||||||
{agreed && <Text className="agreement-check-mark">✓</Text>}
|
|
||||||
</View>
|
|
||||||
<Text className="agreement-text">
|
|
||||||
登录即同意
|
|
||||||
<Text className="agreement-link" onClick={() => safeNavigateTo('/pages/legal/user-agreement')}>《用户协议》</Text>
|
|
||||||
和
|
|
||||||
<Text className="agreement-link" onClick={() => safeNavigateTo('/pages/legal/privacy-policy')}>《隐私政策》</Text>
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View style={{ flex: 1 }} />
|
<View style={{ flex: 1 }} />
|
||||||
|
|
||||||
{/* 开发模式 */}
|
{/* 开发模式快速登录 — 仅 dev 构建 + DevTools 中显示 */}
|
||||||
{(IS_DEV || IS_SIMULATOR) && (
|
{SHOW_DEV_LOGIN && (
|
||||||
<View className="login-dev-btn" onClick={handleDevQuickLogin}>
|
<View className="login-dev-btn" onClick={handleDevQuickLogin}>
|
||||||
<Text className="login-dev-btn-text">开发模式快速登录 ›</Text>
|
<Text className="login-dev-btn-text">开发模式快速登录 ›</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
Reference in New Issue
Block a user