返回 AiToEarn
wx.service.ts
根目录 / project / aitoearn-electron / server / src / lib / wx / wx.service.ts
1 /*
2 * @Author: nevin
3 * @Date: 2024-06-17 16:12:56
4 * @LastEditTime: 2025-02-24 22:20:10
5 * @LastEditors: nevin
6 * @Description: 微信服务
7 */
8 import { Injectable } from '@nestjs/common';
9 import axios from 'axios';
10 import { ConfigService } from '@nestjs/config';
11 import { generateSignature } from './utils';
12 import { RedisService } from '../redis/redis.service';
13
14 @Injectable()
15 export class WxService {
16 appId = '';
17 appSecret = '';
18 constructor(
19 private readonly configService: ConfigService,
20 private readonly redisService: RedisService,
21 ) {
22 this.appId = this.configService.get('WX_CONFIG.APP_ID');
23 this.appSecret = this.configService.get('WX_CONFIG.APP_SECRET');
24 }
25
26 /**
27 * 获取access_token
28 * @returns
29 */
30 private async getMiniAppAccessToken(): Promise<string> {
31 const orgValue: string = await this.redisService.get(
32 `${this.appId}:access_token`,
33 );
34 if (orgValue) return orgValue;
35
36 const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`;
37 const result: {
38 data: {
39 access_token: string;
40 expires_in: number;
41 };
42 } = await axios.get(url);
43
44 if (result.data.access_token) {
45 await this.redisService.setKey(
46 `${this.appId}:access_token`,
47 result.data.access_token,
48 result.data.expires_in,
49 );
50 }
51
52 return result.data.access_token;
53 }
54
55 async code2Session(code: string): Promise<{
56 session_key: string;
57 unionid: string;
58 errmsg: string;
59 openid: string;
60 errcode: number;
61 }> {
62 const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${this.appId}&secret=${this.appSecret}&js_code=${code}&grant_type=authorization_code`;
63 const result = await axios.get(url);
64 return result.data;
65 }
66
67 /**
68 * 校验登录状态
69 * @param openid
70 * @param session_key
71 * @returns
72 */
73 async checkSessionKey(openid: string, session_key: string): Promise<boolean> {
74 const access_token: string = await this.getMiniAppAccessToken();
75
76 const url = `https://api.weixin.qq.com/wxa/checksession?access_token=${access_token}&signature=${generateSignature(session_key)}&openid=${openid}&sig_method=hmac_sha256`;
77 const result = await axios.get(url);
78 return result.data.errcode === 0;
79 }
80
81 /**
82 * 获取手机号
83 * @param code
84 * @returns
85 */
86 async getPhoneNumber(code: string): Promise<string> {
87 const access_token: string = await this.getMiniAppAccessToken();
88
89 const url = `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${access_token}`;
90 const result = await axios.post(url, {
91 code: code,
92 });
93
94 return result.data.phone_info.phoneNumber;
95 }
96
97 /**
98 * 获取app的认证信息
99 * @param code
100 * @returns
101 */
102 async getAppAuthInfo(code: string): Promise<{
103 access_token: string;
104 expires_in: number;
105 refresh_token: string;
106 openid: string;
107 scope: string;
108 unionid: string;
109 }> {
110 const key: string = `wx_auth_info:${code}`;
111 const orgValue = await this.redisService.get(key);
112 if (orgValue) return orgValue;
113
114 const url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appId}&secret=${this.appSecret}&code=${code}&grant_type=authorization_code`;
115 const result = await axios.get(url);
116
117 if (result.data)
118 this.redisService.setKey(key, result.data, result.data.expires_in);
119
120 return result.data;
121 }
122 }
123
123 lines TYPESCRIPT