This commit is contained in:
gaofeng
2026-08-13 15:18:53 +08:00
parent 2ae0bfcf06
commit e29687c5ff

View File

@@ -9,6 +9,8 @@ use think\facade\Log;
class MiniProgramWechatService
{
private const ACCESS_TOKEN_ERROR_CODES = [40001, 40014, 42001];
private string $miniAppCode;
private array $miniApp;
@@ -44,24 +46,46 @@ class MiniProgramWechatService
public function mobileByPhoneCode(string $phoneCode): string
{
$accessToken = $this->wechatAccessToken();
if ($phoneCode === '' || $accessToken === '') {
if ($phoneCode === '') {
return '';
}
$response = Httpcurl::request(
'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . urlencode($accessToken),
'post',
json_encode(['code' => $phoneCode], JSON_UNESCAPED_UNICODE),
['Content-Type: application/json'],
8
);
$result = $this->decodeWechatResponse($response, 'miniapi wx get phone number');
$phoneInfo = $result['phone_info'] ?? [];
return (string)($phoneInfo['purePhoneNumber'] ?? $phoneInfo['phoneNumber'] ?? '');
for ($attempt = 0; $attempt < 2; $attempt++) {
$accessToken = $this->wechatAccessToken($attempt === 1);
if ($accessToken === '') {
return '';
}
$response = Httpcurl::request(
'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . urlencode($accessToken),
'post',
json_encode(['code' => $phoneCode], JSON_UNESCAPED_UNICODE),
['Content-Type: application/json'],
8
);
$result = $this->decodeResponse($response, 'miniapi wx get phone number');
if ($result === []) {
return '';
}
$errcode = intval($result['errcode'] ?? 0);
if ($errcode !== 0) {
Log::warning('miniapi wx get phone number failed: ' . json_encode($result, JSON_UNESCAPED_UNICODE));
if ($attempt === 0 && in_array($errcode, self::ACCESS_TOKEN_ERROR_CODES, true)) {
Cache::delete($this->wechatAccessTokenCacheKey());
continue;
}
return '';
}
$phoneInfo = $result['phone_info'] ?? [];
return (string)($phoneInfo['purePhoneNumber'] ?? $phoneInfo['phoneNumber'] ?? '');
}
return '';
}
private function wechatAccessToken(): string
private function wechatAccessToken(bool $forceRefresh = false): string
{
$config = $this->wechatConfig();
if ($config['appid'] === '' || $config['secret'] === '') {
@@ -69,17 +93,26 @@ class MiniProgramWechatService
return '';
}
$cacheKey = 'miniapp_access_token_' . $this->miniAppCode;
$cached = Cache::get($cacheKey);
if (!empty($cached)) {
return (string)$cached;
$cacheKey = $this->wechatAccessTokenCacheKey();
if (!$forceRefresh) {
$cached = Cache::get($cacheKey);
if (!empty($cached)) {
return (string)$cached;
}
}
$response = Httpcurl::request('https://api.weixin.qq.com/cgi-bin/token', 'get', [
'grant_type' => 'client_credential',
'appid' => $config['appid'],
'secret' => $config['secret'],
], [], 8);
$response = Httpcurl::request(
'https://api.weixin.qq.com/cgi-bin/stable_token',
'post',
json_encode([
'grant_type' => 'client_credential',
'appid' => $config['appid'],
'secret' => $config['secret'],
'force_refresh' => $forceRefresh,
], JSON_UNESCAPED_UNICODE),
['Content-Type: application/json'],
8
);
$result = $this->decodeWechatResponse($response, 'miniapi wx access token');
if (empty($result['access_token'])) {
return '';
@@ -90,6 +123,12 @@ class MiniProgramWechatService
return (string)$result['access_token'];
}
private function wechatAccessTokenCacheKey(): string
{
$appid = (string)($this->miniApp['wechat_appid'] ?? '');
return 'miniapp_stable_access_token_' . md5($this->miniAppCode . '|' . $appid);
}
private function wechatConfig(): array
{
return [