用户端不要强制用户输入手机号
This commit is contained in:
@@ -105,8 +105,8 @@ export default function PhoneVerifySheet({
|
||||
const sheetDesc =
|
||||
description ??
|
||||
(mode === 'wechat_bind_phone'
|
||||
? '微信授权成功,请绑定手机号以完成支付'
|
||||
: '下单前需验证手机号,以便接收订单通知');
|
||||
? '建议绑定手机号,便于订单通知与售后;关闭可跳过继续支付'
|
||||
: '建议绑定手机号,便于订单通知与售后;关闭可跳过继续下单');
|
||||
|
||||
return (
|
||||
<div className="phone-verify-overlay" role="dialog" aria-modal="true">
|
||||
@@ -159,6 +159,9 @@ export default function PhoneVerifySheet({
|
||||
<button type="button" className="login-sms-btn" disabled={loading} onClick={submit}>
|
||||
{loading ? '验证中...' : mode === 'wechat_bind_phone' ? '确认绑定' : '确认验证'}
|
||||
</button>
|
||||
<button type="button" className="phone-verify-skip" onClick={onClose}>
|
||||
暂不绑定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -51,12 +51,6 @@ export default function LoginPage() {
|
||||
}, [wxAuthorize]);
|
||||
|
||||
function handleWechatLoginResult(result: WechatLoginResult) {
|
||||
if (result.needBindPhone && result.wxSessionKey) {
|
||||
setBindMode(true);
|
||||
setWxSessionKey(result.wxSessionKey);
|
||||
setMsg('微信授权成功,请绑定手机号完成登录');
|
||||
return;
|
||||
}
|
||||
if (result.accessToken) {
|
||||
applySession({
|
||||
accessToken: result.accessToken,
|
||||
@@ -68,6 +62,12 @@ export default function LoginPage() {
|
||||
void finishLogin(navigate, returnTo);
|
||||
return;
|
||||
}
|
||||
if (result.needBindPhone && result.wxSessionKey) {
|
||||
setBindMode(true);
|
||||
setWxSessionKey(result.wxSessionKey);
|
||||
setMsg('微信授权成功,可绑定手机号(也可跳过,稍后在下单时再绑定)');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function ensureAgreed() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import SubPageHeader from '../components/SubPageHeader';
|
||||
import AppImage from '@dukang/shared-ui/AppImage';
|
||||
@@ -73,6 +73,7 @@ export default function OrderConfirmPage() {
|
||||
const [previewLoading, setPreviewLoading] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [msg, setMsg] = useState('');
|
||||
const phonePromptSkipped = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
request<Address[]>('USER_H5', '/user/addresses').then((list) => {
|
||||
@@ -195,7 +196,7 @@ export default function OrderConfirmPage() {
|
||||
setMsg('请选择收货地址');
|
||||
return;
|
||||
}
|
||||
if (!phoneVerified) {
|
||||
if (!phoneVerified && !phonePromptSkipped.current) {
|
||||
setPendingSubmit(true);
|
||||
setShowPhoneVerify(true);
|
||||
return;
|
||||
@@ -204,6 +205,7 @@ export default function OrderConfirmPage() {
|
||||
const authResult = await ensureWechatAuthForPay();
|
||||
if (!authResult.ok) {
|
||||
if ('needBindPhone' in authResult) {
|
||||
// 兼容旧接口:微信授权后提示可选绑定
|
||||
setWxSessionKey(authResult.wxSessionKey);
|
||||
setShowWechatBindPhone(true);
|
||||
setPendingSubmit(true);
|
||||
@@ -418,9 +420,35 @@ export default function OrderConfirmPage() {
|
||||
<PhoneVerifySheet
|
||||
open={showPhoneVerify}
|
||||
defaultPhone={selectedAddress?.phone}
|
||||
title="建议绑定手机号"
|
||||
description="绑定后便于订单通知与售后联系;关闭即可跳过,不绑定也能继续下单。"
|
||||
onClose={() => {
|
||||
setShowPhoneVerify(false);
|
||||
setPendingSubmit(false);
|
||||
if (pendingSubmit) {
|
||||
phonePromptSkipped.current = true;
|
||||
setPendingSubmit(false);
|
||||
void (async () => {
|
||||
setLoading(true);
|
||||
setMsg('');
|
||||
try {
|
||||
const authResult = await ensureWechatAuthForPay();
|
||||
if (!authResult.ok) {
|
||||
if ('needBindPhone' in authResult) {
|
||||
setWxSessionKey(authResult.wxSessionKey);
|
||||
setShowWechatBindPhone(true);
|
||||
setPendingSubmit(true);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
await doSubmit();
|
||||
} catch (e) {
|
||||
setMsg(e instanceof Error ? e.message : '下单失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}}
|
||||
onSuccess={handlePhoneVerified}
|
||||
/>
|
||||
@@ -430,10 +458,26 @@ export default function OrderConfirmPage() {
|
||||
mode="wechat_bind_phone"
|
||||
wxSessionKey={wxSessionKey ?? undefined}
|
||||
defaultPhone={selectedAddress?.phone}
|
||||
title="建议绑定手机号"
|
||||
description="绑定后便于订单通知与售后联系;关闭即可跳过继续下单。"
|
||||
onClose={() => {
|
||||
setShowWechatBindPhone(false);
|
||||
setWxSessionKey(null);
|
||||
setPendingSubmit(false);
|
||||
if (pendingSubmit) {
|
||||
phonePromptSkipped.current = true;
|
||||
setPendingSubmit(false);
|
||||
void (async () => {
|
||||
setLoading(true);
|
||||
setMsg('');
|
||||
try {
|
||||
await doSubmit();
|
||||
} catch (e) {
|
||||
setMsg(e instanceof Error ? e.message : '下单失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}}
|
||||
onSuccess={handleWechatPhoneBound}
|
||||
/>
|
||||
|
||||
@@ -5663,6 +5663,18 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.phone-verify-skip {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-top: 12px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 14px;
|
||||
color: var(--color-on-surface-variant, #888);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.login-msg--hint {
|
||||
color: var(--color-success, #2d6a4f);
|
||||
}
|
||||
|
||||
@@ -68,13 +68,6 @@ export default function WechatShareBootstrap() {
|
||||
handleWechatAuthCallback()
|
||||
.then((result) => {
|
||||
if (!result) return;
|
||||
if (result.needBindPhone && result.wxSessionKey) {
|
||||
goLogin(returnFromLogin, {
|
||||
bindMode: '1',
|
||||
wxSessionKey: result.wxSessionKey,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (saveWechatLoginResult(result)) {
|
||||
toast('微信授权成功', 'success');
|
||||
if (
|
||||
@@ -83,6 +76,14 @@ export default function WechatShareBootstrap() {
|
||||
) {
|
||||
finishLoginNavigate(returnFromLogin || params.get('return') || undefined);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 兼容旧接口:仅 needBindPhone 时引导可选绑定,不阻塞浏览
|
||||
if (result.needBindPhone && result.wxSessionKey) {
|
||||
goLogin(returnFromLogin, {
|
||||
bindMode: '1',
|
||||
wxSessionKey: result.wxSessionKey,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { fetchClientConfig, fetchUserProfile, needsWechatAuthForPay } from './pa
|
||||
|
||||
/**
|
||||
* 支付前门禁:
|
||||
* - 未登录 / 未验手机 → 跳转登录页
|
||||
* - 未登录 → 跳转登录页(微信授权即可,不强制手机号)
|
||||
* - H5 微信内缺 openId → 尝试 OAuth(可能跳转微信授权页)
|
||||
* - 小程序缺绑定 → 跳转登录页 needWechat
|
||||
*/
|
||||
@@ -17,10 +17,6 @@ export async function ensurePayReady(returnPath: string): Promise<boolean> {
|
||||
|
||||
try {
|
||||
const [config, profile] = await Promise.all([fetchClientConfig(), fetchUserProfile()]);
|
||||
if (!profile.phoneVerified) {
|
||||
goLogin(returnPath, { needPhone: '1' });
|
||||
return false;
|
||||
}
|
||||
if (!needsWechatAuthForPay(config, profile)) {
|
||||
return true;
|
||||
}
|
||||
@@ -28,8 +24,9 @@ export async function ensurePayReady(returnPath: string): Promise<boolean> {
|
||||
if (process.env.TARO_ENV === 'h5') {
|
||||
const auth = await ensureWechatAuthForPay();
|
||||
if (auth.ok) return true;
|
||||
// 旧版 needBindPhone 已不再返回;缺 openId 时走登录补微信绑定
|
||||
if ('needBindPhone' in auth && auth.needBindPhone) {
|
||||
goLogin(returnPath, { bindMode: '1', wxSessionKey: auth.wxSessionKey });
|
||||
goLogin(returnPath, { needWechat: '1' });
|
||||
return false;
|
||||
}
|
||||
// redirecting:正在跳转微信 OAuth
|
||||
|
||||
@@ -121,17 +121,18 @@ export default function LoginPage() {
|
||||
}
|
||||
|
||||
function handleWechatLoginResult(result: WechatLoginResult, wxInfo?: MiniWechatProfile | null) {
|
||||
// 微信授权成功即登录;手机号改为下单页可选绑定
|
||||
if (result.accessToken) {
|
||||
applySessionAndLeave(result, undefined, wxInfo);
|
||||
return;
|
||||
}
|
||||
if (result.needBindPhone && result.wxSessionKey) {
|
||||
setBindMode(true);
|
||||
setWxSessionKey(result.wxSessionKey);
|
||||
setMsg('微信授权成功,请绑定手机号完成登录');
|
||||
setMsg('微信授权成功,可绑定手机号(也可跳过,稍后在下单时再绑定)');
|
||||
setSentHint('');
|
||||
return;
|
||||
}
|
||||
if (result.accessToken) {
|
||||
applySessionAndLeave(result, undefined, wxInfo);
|
||||
return;
|
||||
}
|
||||
setMsg('微信登录未完成,请重试或使用手机号登录');
|
||||
}
|
||||
|
||||
@@ -286,13 +287,17 @@ export default function LoginPage() {
|
||||
<View className="login-welcome">
|
||||
<Text className="login-welcome-title">
|
||||
{completeMode === 'phone'
|
||||
? '完成手机验证'
|
||||
? '建议绑定手机号'
|
||||
: completeMode === 'wechat'
|
||||
? '完成微信授权'
|
||||
: '欢迎来到杜康好客'}
|
||||
</Text>
|
||||
<Text className="login-welcome-sub">
|
||||
{completeMode ? '完成后将返回继续支付' : '买美酒,享好礼'}
|
||||
{completeMode === 'phone'
|
||||
? '便于订单通知与售后,也可稍后绑定'
|
||||
: completeMode === 'wechat'
|
||||
? '完成后将返回继续支付'
|
||||
: '买美酒,享好礼'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -365,6 +370,17 @@ export default function LoginPage() {
|
||||
: '登录'}
|
||||
</Text>
|
||||
</View>
|
||||
{completeMode === 'phone' ? (
|
||||
<View
|
||||
className="login-skip-bind"
|
||||
onClick={() => finishLoginNavigate(returnTo)}
|
||||
style={{ marginTop: 12, textAlign: 'center' }}
|
||||
>
|
||||
<Text className="u-muted" style={{ fontSize: 14 }}>
|
||||
暂不绑定,继续下单
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { View, Text, Image } from '@tarojs/components';
|
||||
import Taro, { useRouter } from '@tarojs/taro';
|
||||
import PageShell from '../../components/PageShell';
|
||||
import SubPageHeader from '../../components/SubPageHeader';
|
||||
import { goLogin } from '../../lib/auth-nav';
|
||||
import { buildAddressListUrl, buildPayUrl, readCheckoutContext } from '../../lib/checkout-nav';
|
||||
import { tryGetClientGpsLocation } from '../../lib/client-location';
|
||||
import { maskPhone } from '../../lib/phone';
|
||||
import { ensurePayReady } from '../../lib/pay-ready';
|
||||
import { fetchUserProfile } from '../../lib/pay-wechat';
|
||||
import { request } from '../../lib/api';
|
||||
import { getProductMainImage } from '../../lib/product-images';
|
||||
|
||||
@@ -58,6 +60,7 @@ export default function OrderConfirmPage() {
|
||||
const [previewLoading, setPreviewLoading] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [msg, setMsg] = useState('');
|
||||
const phonePromptSkipped = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
request<Address[]>('/user/addresses')
|
||||
@@ -161,6 +164,30 @@ export default function OrderConfirmPage() {
|
||||
}
|
||||
|
||||
const returnPath = `/pages/order-confirm/index?productId=${productId}&qty=${quantity}&addressId=${addressId}${forceCross ? '&cross=1' : ''}`;
|
||||
|
||||
if (!phonePromptSkipped.current) {
|
||||
try {
|
||||
const profile = await fetchUserProfile();
|
||||
if (!profile.phoneVerified) {
|
||||
const { confirm, cancel } = await Taro.showModal({
|
||||
title: '建议绑定手机号',
|
||||
content: '绑定后便于订单通知与售后联系;也可跳过,不绑定也能继续下单。',
|
||||
confirmText: '去绑定',
|
||||
cancelText: '暂不绑定',
|
||||
});
|
||||
if (confirm) {
|
||||
goLogin(returnPath, { needPhone: '1' });
|
||||
return;
|
||||
}
|
||||
if (cancel) {
|
||||
phonePromptSkipped.current = true;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
/* 拉取档案失败不阻塞下单 */
|
||||
}
|
||||
}
|
||||
|
||||
const ready = await ensurePayReady(returnPath);
|
||||
if (!ready) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user