卢春龙
2026-08-17 f525b6c3cc105bd1a997d893937689bebcc9570d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 
import Taro from '@tarojs/taro';
import { getAuthCode, updateLoginCodeStorage } from './alipay';
 
const ENV = process.env.TARO_ENV;
 
/**
 * 获取登录 code 
 * 注意:
 * 1、Login Code 只能使用一次,并且新 Login Code 会使旧的 Login Code 失效。
 * 2、Login Code 有效期五分钟,过期需要重新获取。
 * 3、Login Code 调用 code2Session 接口用于换取 session_key、 openid、unionid,如果要排查,可以查查哪些接口需要 code 然后返回了 sessionCode,例如 dispatchXpLogin(目前登录后没有强制刷新,如有需要也可以刷)
 * 4、高价值操作前可以重新获取 Login Code,确保 Login Code 的时效性,例如留资
 * 5、login 接口也有限额,可以在微信小程序后台看到是否超限,超限后不一定会报错,具体要看微信那边的资源是否紧张
 * 6、因为 Login Code 只能用一次,本质上不适合做缓存,而应该每次获取最新的,后面慢慢把代码里缓存的地方都改掉
 * @param param0 
 * @returns 
 */
export function getLoginCode({success, fail, catchReject = !!fail}: {success?: (code: number) => void, fail?: (err: any) => void, catchReject?: boolean} = {}) {
 
  // 包装 success 和 fail,防止报错
  const wrapperSuccess = (res) => {
    try {
      typeof success === 'function' && success(res?.code);
    } catch (e) {
      console.error('getLoginCode success error:', e);
    }
  }
  const wrapperFail = (err) => {
    try {
      typeof fail === 'function' && fail(err);
    } catch (e) {
      console.error('getLoginCode fail error:', e);
    }
  }
 
  if (ENV === 'alipay') {
    // 支付宝本也可以统一,只是 getAuthCode 已有多处使用,这里就继续保留
    return getAuthCode({
      success: wrapperSuccess,
      fail: wrapperFail,
      catchReject,
    });
  } else  {
    return new Promise((resolve, reject) => {
        const onSuccess = (res) => {
            updateLoginCodeStorage(res.code);
            wrapperSuccess(res);
            resolve(res.code);
        }
        const onFail = (err) => {
            this.$app.xpReportSend({ pageId: 'P20028', buttonId: 'B003', para: { errMsg: err.errMsg } });
            console.error('getLoginCode error ----------->:', err);
            wrapperFail(err);
            catchReject ? resolve(null) :reject(err);
          }
        if(ENV === 'swan') {
          // @ts-ignore
          swan.getLoginCode({
            success: onSuccess,
            fail: onFail
          });
        } else if(ENV ===  'xhs') {
          // @ts-ignore
          xhs.login({
            success: onSuccess,
            fail: onFail
          });
        } else {
          Taro.login({
            success: onSuccess,
            fail: onFail
          });
        }
      
    });
  }
}
 
export default {
  getLoginCode,
}