feat(auth): 小程序登录采集微信昵称

This commit is contained in:
2026-06-06 23:59:15 +08:00
parent caa65bf15f
commit b74440373f
16 changed files with 432 additions and 58 deletions

View File

@@ -107,6 +107,10 @@ function parseBooleanQueryFlag(value) {
return value === true || value === '1' || value === 'true' || value === 'yes';
}
function normalizeNicknameInput(value) {
return String(value || '').trim();
}
function normalizeMiniProgramEnv(value) {
const normalized = String(value || '').trim().toLowerCase();
if (normalized === 'release') {
@@ -268,7 +272,7 @@ function wxLogin() {
});
}
function requestMiniProgramLogin(code) {
function requestMiniProgramLogin(code, displayName) {
return new Promise((resolve, reject) => {
const runtimeConfig = resolveMiniProgramRuntimeConfig();
const apiBaseUrl = trimTrailingSlash(runtimeConfig.apiBaseUrl);
@@ -280,7 +284,10 @@ function requestMiniProgramLogin(code) {
wx.request({
url: `${apiBaseUrl}/api/auth/wechat/miniprogram-login`,
method: 'POST',
data: { code },
data: {
code,
...(displayName ? { displayName } : {}),
},
header: {
'content-type': 'application/json',
'x-client-type': MINI_PROGRAM_CLIENT_TYPE,
@@ -310,7 +317,7 @@ function requestMiniProgramLogin(code) {
});
}
function requestMiniProgramBindPhone(authToken, wechatPhoneCode) {
function requestMiniProgramBindPhone(authToken, wechatPhoneCode, displayName) {
return new Promise((resolve, reject) => {
const runtimeConfig = resolveMiniProgramRuntimeConfig();
const apiBaseUrl = trimTrailingSlash(runtimeConfig.apiBaseUrl);
@@ -322,7 +329,10 @@ function requestMiniProgramBindPhone(authToken, wechatPhoneCode) {
wx.request({
url: `${apiBaseUrl}/api/auth/wechat/bind-phone`,
method: 'POST',
data: { wechatPhoneCode },
data: {
wechatPhoneCode,
...(displayName ? { displayName } : {}),
},
header: {
authorization: `Bearer ${authToken}`,
'content-type': 'application/json',
@@ -353,9 +363,9 @@ function requestMiniProgramBindPhone(authToken, wechatPhoneCode) {
});
}
async function resolveAuthResult() {
async function resolveAuthResult(displayName) {
const code = await wxLogin();
const response = await requestMiniProgramLogin(code);
const response = await requestMiniProgramLogin(code, displayName);
if (!response || !response.token) {
throw new Error('服务器未返回登录态');
}
@@ -370,7 +380,10 @@ Page({
authResult: null,
bindingPhone: false,
errorMessage: '',
loggingIn: false,
loading: true,
nicknameInput: '',
nicknameRequired: false,
phoneBindingRequired: false,
returnToPreviousPage: false,
webViewUrl: '',
@@ -395,6 +408,7 @@ Page({
if (!shouldStartAuthFromQuery(query) && !forcedPhoneBinding) {
this.setData({
authResult: null,
bindingPhone: false,
errorMessage: '',
loading: false,
phoneBindingRequired: false,
@@ -414,20 +428,50 @@ Page({
}
this.setData({
loading: true,
authResult: null,
bindingPhone: false,
errorMessage: '',
loggingIn: false,
loading: false,
nicknameRequired: true,
phoneBindingRequired: false,
returnToPreviousPage,
errorMessage: '',
webViewUrl: '',
});
},
handleNicknameInput(event) {
this.setData({
nicknameInput: event.detail ? event.detail.value : '',
});
},
async handleStartLogin() {
const displayName = normalizeNicknameInput(this.data.nicknameInput);
if (!displayName) {
this.setData({
errorMessage: '请先选择或填写微信昵称。',
});
return;
}
this.setData({
errorMessage: '',
loggingIn: true,
});
await this.startAuthFlow(this.data.returnToPreviousPage, displayName);
},
async startAuthFlow(returnToPreviousPage, displayName) {
try {
const authResult = await resolveAuthResult();
const authResult = await resolveAuthResult(displayName);
if (authResult.bindingStatus === 'pending_bind_phone') {
this.setData({
authResult,
errorMessage: '',
loggingIn: false,
loading: false,
nicknameRequired: false,
phoneBindingRequired: true,
returnToPreviousPage,
webViewUrl: '',
@@ -437,6 +481,16 @@ Page({
if (returnToPreviousPage) {
persistAuthResult(authResult);
this.setData({
authResult,
errorMessage: '',
loggingIn: false,
loading: false,
nicknameRequired: false,
phoneBindingRequired: false,
returnToPreviousPage,
webViewUrl: '',
});
wx.navigateBack();
return;
}
@@ -444,7 +498,9 @@ Page({
this.setData({
authResult,
errorMessage: '',
loggingIn: false,
loading: false,
nicknameRequired: false,
phoneBindingRequired: false,
returnToPreviousPage,
webViewUrl: resolveWebViewUrl(authResult),
@@ -454,7 +510,9 @@ Page({
authResult: null,
errorMessage:
error && error.message ? error.message : '微信登录失败,请稍后重试。',
loggingIn: false,
loading: false,
nicknameRequired: true,
phoneBindingRequired: false,
returnToPreviousPage,
webViewUrl: '',
@@ -466,6 +524,13 @@ Page({
const authResult = consumeAuthResult();
if (authResult) {
this.setData({
authResult,
bindingPhone: false,
errorMessage: '',
loggingIn: false,
loading: false,
nicknameRequired: false,
phoneBindingRequired: false,
webViewUrl: resolveWebViewUrl(authResult),
});
}
@@ -510,6 +575,7 @@ Page({
const response = await requestMiniProgramBindPhone(
this.data.authResult.token,
detail.code,
normalizeNicknameInput(this.data.nicknameInput),
);
if (!response || !response.token) {
throw new Error('服务器未返回绑定后的登录态');
@@ -523,7 +589,9 @@ Page({
this.setData({
bindingPhone: false,
errorMessage: '',
loggingIn: false,
loading: false,
nicknameRequired: false,
phoneBindingRequired: false,
});
wx.navigateBack();
@@ -533,7 +601,9 @@ Page({
authResult: nextAuthResult,
bindingPhone: false,
errorMessage: '',
loggingIn: false,
loading: false,
nicknameRequired: false,
phoneBindingRequired: false,
webViewUrl: resolveWebViewUrl(nextAuthResult),
});
@@ -553,7 +623,10 @@ Page({
authResult: null,
bindingPhone: false,
errorMessage: '',
loggingIn: false,
loading: true,
nicknameInput: '',
nicknameRequired: false,
phoneBindingRequired: false,
returnToPreviousPage: false,
webViewUrl: '',

View File

@@ -8,6 +8,32 @@
/>
</block>
<view wx:elif="{{nicknameRequired}}" class="setup-screen">
<view class="setup-card">
<view class="setup-title">登录</view>
<view wx:if="{{errorMessage}}" class="setup-text setup-text--danger">
{{errorMessage}}
</view>
<input
class="nickname-input"
type="nickname"
value="{{nicknameInput}}"
placeholder="微信昵称"
disabled="{{loggingIn}}"
bindinput="handleNicknameInput"
bindblur="handleNicknameInput"
/>
<button
class="retry-button"
loading="{{loggingIn}}"
disabled="{{loggingIn}}"
bindtap="handleStartLogin"
>
{{loggingIn ? '正在登录' : '微信快捷登录'}}
</button>
</view>
</view>
<view wx:elif="{{loading}}" class="setup-screen">
<view class="setup-card">
<view class="setup-title">正在登录</view>

View File

@@ -36,6 +36,19 @@
color: #ffb4a9;
}
.nickname-input {
margin-top: 28rpx;
width: 100%;
min-height: 88rpx;
padding: 0 24rpx;
border: 1rpx solid rgba(255, 255, 255, 0.22);
border-radius: 8rpx;
background: rgba(255, 255, 255, 0.1);
color: #f5f7fb;
font-size: 28rpx;
box-sizing: border-box;
}
.retry-button {
margin-top: 28rpx;
width: 100%;