微信小程序审核不通过修改
CI / verify (pull_request) Has been cancelled

This commit is contained in:
2026-07-21 09:32:06 +08:00
parent 350a086a73
commit 935ab0d1d4
14 changed files with 466 additions and 242 deletions
@@ -16,6 +16,7 @@ type TokenCache = { accessToken: string; expiresAt: number };
type TicketCache = { ticket: string; expiresAt: number };
const ACCESS_TOKEN_KEY = 'wechat:access_token';
const MINI_ACCESS_TOKEN_KEY = 'wechat:mini_access_token';
const JSAPI_TICKET_KEY = 'wechat:jsapi_ticket';
@Injectable()
@@ -255,7 +256,7 @@ export class WechatApiProvider implements IWechatProvider {
if (platform === 'h5') {
throw new InternalServerErrorException('H5 请使用短信绑定手机号');
}
const accessToken = await this.getAccessToken();
const accessToken = await this.getMiniAccessToken();
const apiUrl = `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${accessToken}`;
const data = await this.fetchJson<{
errcode?: number;
@@ -433,6 +434,37 @@ export class WechatApiProvider implements IWechatProvider {
return data.access_token;
}
/** 小程序 access_tokengetPhoneNumber 等 wxa 接口必须用小程序 AppID) */
private async getMiniAccessToken(): Promise<string> {
const appId = this.miniAppId;
const appSecret = this.miniAppSecret;
if (!appId || !appSecret) {
throw new InternalServerErrorException(
'小程序未配置:请设置 WX_MINI_APP_ID / WX_MINI_APP_SECRET',
);
}
const cached = await this.redis.getJson<TokenCache>(MINI_ACCESS_TOKEN_KEY);
if (cached && cached.expiresAt > Date.now()) return cached.accessToken;
const url = new URL('https://api.weixin.qq.com/cgi-bin/token');
url.searchParams.set('grant_type', 'client_credential');
url.searchParams.set('appid', appId);
url.searchParams.set('secret', appSecret);
const data = await this.fetchJson<{ access_token?: string; expires_in?: number; errcode?: number; errmsg?: string }>(
url.toString(),
);
if (!data.access_token) {
throw new InternalServerErrorException(data.errmsg || '获取小程序 access_token 失败');
}
const ttl = Math.max((data.expires_in ?? 7200) - 300, 60);
await this.redis.setJson(
MINI_ACCESS_TOKEN_KEY,
{ accessToken: data.access_token, expiresAt: Date.now() + ttl * 1000 },
ttl,
);
return data.access_token;
}
private async getJsapiTicket(): Promise<string> {
const cached = await this.redis.getJson<TicketCache>(JSAPI_TICKET_KEY);
if (cached && cached.expiresAt > Date.now()) return cached.ticket;