# 获取微信code

注意

该函数仅支持 微信小程序 平台

# 使用方式

  1. mixin 提供了一个 code 属性,该属性可以获取到微信小程序的 code 值。
  2. 默认在 created 事件中调用了 getWxLoginCode 方法,获取微信登录的 code 值。
  3. 提供了一个 codeRefresh 方法,可以刷新到微信登录的 code 值。每次调用服务器接口使用 code 后,需要调用此方法进行刷新。

TIP

为什么不是使用的时候直接获取 code 值?,因为该 code 生效是异步的,获取后立即调用接口,此时服务器会认为该 code 无效

import WxCode from 'sadais-piui/mixin/wx-code'
export default {
  mixins: [WxCode]
}
1
2
3
4

# 源码

使用前请仔细阅读源码

/**
 * 微信code获取mixin
 * @return {Object} {data: {code: ''}}
 */
export default {
  // #ifdef MP
  data() {
    return {
      code: '' // 微信login获取的code
    }
  },
  created() {
    this.getWxLoginCode()
  },
  methods: {
    /**
     * 获取微信登录code
     */
    async getWxLoginCode() {
      const [, { code }] = await uni.login({
        provider: 'weixin'
      })
      console.log('获取微信授权code为:', code)
      this.code = code
    },
    /**
     * 刷新微信登录code
     */
    async codeRefresh() {
      const session = await uni.checkSession()
      console.log('检查微信session是否过期,结果:', session)
      const [, { errMsg }] = session
      if (errMsg !== 'checkSession:ok') {
        await this.getWxLoginCode()
      }
      return true
    }
  }
  // #endif
}

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

# 示例

配合piui组件使用

<template>
  <view class="pi-scroll-container">
    <view class="pi-scroll pi-flex-column pi-align-center" style="padding-top: 168rpx;">
      <pi-opentype-button
        v-if="isMP"
        type="primary"
        width="622"
        size="large"
        round
        :disabled="!isCheckInfo"
        :custom-style="{ color: '#ffffff' }"
        open-type="getUserInfo"
        @getuserinfo="handleGetUserProfile"
      >
        微信授权登录
      </pi-opentype-button>

      <pi-button
        v-else
        type="primary"
        width="622"
        round
        size="large"
        :disabled="!isCheckInfo"
        :custom-style="{ color: '#ffffff' }"
        @click="handlePhoneLogin"
      >
        微信授权登录
      </pi-button>

      <view class="pi-gray pi-mg-top-32" @tap="handleNaviBack">
        暂不登录
      </view>
    </view>
  </view>
</template>

<script>
import WxCode from 'sadais-piui/mixin/wx-code'
import { apiGetWxInfo, apiWxLogin, apiPhoneLogin } from '@/api'
import { mapState, mapActions } from 'vuex'
const TAG = 'Login'

export default {
  name: TAG,
  mixins: [WxCode],
  props: {
    value: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      params: {},
      isCheckInfo: false
    }
  },
  computed: {
    ...mapState(['userInfo'])
  },
  methods: {
    ...mapActions(['refreshData']),
    async handleNaviBack() {
      this.$hideLoading()
      try {
        const result = await this.$pi.navi.navigateBack()
        const msg = result && result.length && result[result.length - 1].errMsg
        const isSuccess = msg.includes(':ok')
        if (!isSuccess) {
          // 如果跳转失败,则跳转到主页
          this.$pi.navi.switchTab('pages/index/index')
        }
      } catch (e) {
        this.$pi.navi.switchTab('pages/index/index')
      }
    },
    async handlePhoneLogin() {
      const testphone = uni.getStorageSync('testphone') || 13750022242
      const { data, head } = await apiPhoneLogin(testphone) // 15919177724 13750022243
      if (head.ret !== this.$consts.RET_CODE.SUCCESS) {
        // this.handleNaviBack()
        return this.$toast(head.msg)
      }
      const { accountInfoDto, tokenDto, userInfoDto } = data
      this.$core.auth.saveTokenId(tokenDto.accesstoken)
      this.$core.auth.saveRefreshTokenId(tokenDto.refreshtoken)
      this.$core.auth.saveUserInfo(userInfoDto)
      if (userInfoDto.enterpriseId) {
        await this.handleGetCompanyInfo(userInfoDto.enterpriseId)
      }
      this.refreshData({
        userInfo: userInfoDto
      })
      this.$hideLoading()
      this.handleNaviBack()
    },

    async handleGetUserProfile(res) {
      console.log(res)
      const { errMsg, iv, encryptedData } = res.detail
      const isOK = ['getUserProfile:ok', 'getUserInfo:ok'].includes(errMsg)
      if (!isOK) {
        this.getWxLoginCode()
        this.handleNaviBack()
        return
      }
      try {
        this.$loading()

        await this.codeRefresh() // 刷新code,以保证code未过期
        const { data, head } = await apiGetWxInfo(this.code, encryptedData, iv)
        this.getWxLoginCode() // code 只能用一次,接口调用后需要刷新
        if (head.ret !== this.$consts.RET_CODE.SUCCESS) {
          // this.handleNaviBack()
          return this.$toast(head.msg)
        }
        console.log('解密的信息:', data)
        this.handleWxLogin(data)
      } catch (error) {
        this.$hideLoading()
        this.handleNaviBack()
      }
    },
    async handleWxLogin(wxRes) {
      const openId = wxRes.wxInfo.openid
      uni.setStorageSync('openId', openId)
      const { data, head } = await apiWxLogin({ ...wxRes.wxInfo, accesstoken: wxRes.accessData })
      if (head.ret !== this.$consts.RET_CODE.SUCCESS) {
        this.handleNaviBack()
        return this.$toast(head.msg)
      }
      const { accountInfoDto, tokenDto, userInfoDto } = data
      this.$core.auth.saveTokenId(tokenDto.accesstoken)
      this.$core.auth.saveRefreshTokenId(tokenDto.refreshtoken)
      this.$core.auth.saveUserInfo(userInfoDto)

      this.refreshData({
        userInfo: userInfoDto
      })

      this.$hideLoading()
      this.handleNaviBack()
    }
  }
}
</script>

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
Last updated: 2021/9/2 下午5:06:26