login.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <template>
  2. <view>
  3. <page-head :title="title"></page-head>
  4. <view class="uni-padding-wrap">
  5. <view style="background:#FFF; padding:40rpx;">
  6. <block v-if="hasLogin === true">
  7. <view class="uni-h3 uni-center uni-common-mt">已登录
  8. <text v-if="isUniverifyLogin" style="font-size: 0.8em;">
  9. <i v-if="!phoneNumber.length" class="uni-icon_toast uni-loading"></i>
  10. <i v-else>({{phoneNumber}})</i>
  11. </text>
  12. </view>
  13. <view class="uni-hello-text uni-center">
  14. <text>每个账号仅需登录 1 次,\n后续每次进入页面即可自动拉取用户信息。</text>
  15. </view>
  16. </block>
  17. <block v-if="hasLogin === false">
  18. <view class="uni-h3 uni-center uni-common-mt">未登录</view>
  19. <view class="uni-hello-text uni-center">
  20. 请点击按钮登录
  21. </view>
  22. </block>
  23. </view>
  24. <view class="uni-btn-v uni- uni-common-mt">
  25. <!-- #ifdef MP-TOUTIAO -->
  26. <button type="primary" class="page-body-button" v-for="(value,key) in providerList" @click="tologin(value)" :key="key">
  27. 登录
  28. </button>
  29. <!-- #endif -->
  30. <!-- #ifndef MP-TOUTIAO -->
  31. <button type="primary" class="page-body-button" v-for="(value,key) in providerList" @click="tologin(value)"
  32. :loading="value.id === 'univerify' ? univerifyBtnLoading : false" :key="key">{{value.name}}</button>
  33. <!-- #endif -->
  34. </view>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. import {
  40. mapState,
  41. mapMutations,
  42. mapActions
  43. } from 'vuex'
  44. const univerifyInfoKey = 'univerifyInfo';
  45. export default {
  46. data() {
  47. return {
  48. title: 'login',
  49. providerList: [],
  50. phoneNumber: '',
  51. univerifyBtnLoading: false
  52. }
  53. },
  54. computed: {
  55. ...mapState(['hasLogin', 'isUniverifyLogin', 'univerifyErrorMsg'])
  56. },
  57. onLoad() {
  58. uni.getProvider({
  59. service: 'oauth',
  60. success: (result) => {
  61. this.providerList = result.provider.map((value) => {
  62. let providerName = '';
  63. switch (value) {
  64. case 'weixin':
  65. providerName = '微信登录'
  66. break;
  67. case 'qq':
  68. providerName = 'QQ登录'
  69. break;
  70. case 'sinaweibo':
  71. providerName = '新浪微博登录'
  72. break;
  73. case 'xiaomi':
  74. providerName = '小米登录'
  75. break;
  76. case 'alipay':
  77. providerName = '支付宝登录'
  78. break;
  79. case 'baidu':
  80. providerName = '百度登录'
  81. break;
  82. case 'jd':
  83. providerName = '京东登录'
  84. break;
  85. case 'toutiao':
  86. providerName = '头条登录'
  87. break;
  88. case 'apple':
  89. providerName = '苹果登录'
  90. break;
  91. case 'univerify':
  92. providerName = '一键登录'
  93. break;
  94. }
  95. return {
  96. name: providerName,
  97. id: value
  98. }
  99. });
  100. },
  101. fail: (error) => {
  102. console.log('获取登录通道失败', error);
  103. }
  104. });
  105. if (this.hasLogin && this.isUniverifyLogin) {
  106. this.getPhoneNumber(uni.getStorageSync(univerifyInfoKey)).then((phoneNumber) => {
  107. this.phoneNumber = phoneNumber
  108. })
  109. }
  110. },
  111. methods: {
  112. ...mapMutations(['login', 'setUniverifyLogin']),
  113. ...mapActions(['getPhoneNumber']),
  114. Toast(data, duration = 1000) {
  115. uni.showToast(Object.assign({}, data, {
  116. duration
  117. }))
  118. },
  119. tologin(provider) {
  120. if (provider.id === 'univerify') {
  121. this.univerifyBtnLoading = true;
  122. }
  123. // 一键登录已在APP onLaunch的时候进行了预登陆,可以显著提高登录速度。登录成功后,预登陆状态会重置
  124. uni.login({
  125. provider: provider.id,
  126. // #ifdef MP-ALIPAY
  127. scopes: 'auth_user', //支付宝小程序需设置授权类型
  128. // #endif
  129. success: async (res) => {
  130. console.log('login success:', res);
  131. this.Toast({
  132. title: '登录成功'
  133. })
  134. // 更新保存在 store 中的登录状态
  135. this.login(provider.id);
  136. // #ifdef APP-PLUS
  137. this.setUniverifyLogin(provider.id === 'univerify')
  138. switch (provider.id) {
  139. case 'univerify':
  140. this.loginByUniverify(provider.id, res)
  141. break;
  142. case 'apple':
  143. this.loginByApple(provider.id, res)
  144. break;
  145. }
  146. // #endif
  147. // #ifdef MP-WEIXIN
  148. console.warn('如需获取openid请参考uni-id: https://uniapp.dcloud.net.cn/uniCloud/uni-id')
  149. uni.request({
  150. url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/user-center',
  151. method: 'POST',
  152. data: {
  153. action: 'loginByWeixin',
  154. params: {
  155. code: res.code,
  156. platform: 'mp-weixin'
  157. }
  158. },
  159. success(res) {
  160. console.log(res);
  161. if (res.data.code !== 0) {
  162. console.log('获取openid失败:', res.data.errMsg);
  163. return
  164. }
  165. uni.setStorageSync('openid', res.data.openid)
  166. },
  167. fail(err) {
  168. console.log('获取openid失败:', err);
  169. }
  170. })
  171. // #endif
  172. },
  173. fail: (err) => {
  174. console.log('login fail:', err);
  175. // 一键登录点击其他登录方式
  176. if (err.code == '30002') {
  177. uni.closeAuthView();
  178. this.Toast({
  179. title: '其他登录方式'
  180. })
  181. return;
  182. }
  183. // 未开通
  184. if (err.code == 1000) {
  185. uni.showModal({
  186. title: '登录失败',
  187. content: `${err.errMsg}\n,错误码:${err.code}`,
  188. confirmText: '开通指南',
  189. cancelText: '确定',
  190. success: (res) => {
  191. if (res.confirm) {
  192. setTimeout(() => {
  193. plus.runtime.openWeb('https://ask.dcloud.net.cn/article/37965')
  194. }, 500)
  195. }
  196. }
  197. });
  198. return;
  199. }
  200. // 一键登录预登陆失败
  201. if (err.code == '30005') {
  202. uni.showModal({
  203. showCancel: false,
  204. title: '预登录失败',
  205. content: this.univerifyErrorMsg || err.errMsg
  206. });
  207. return;
  208. }
  209. // 一键登录用户关闭验证界面
  210. if (err.code != '30003') {
  211. uni.showModal({
  212. showCancel: false,
  213. title: '登录失败',
  214. content: JSON.stringify(err)
  215. });
  216. }
  217. },
  218. complete: () => {
  219. this.univerifyBtnLoading = false;
  220. }
  221. });
  222. },
  223. loginByUniverify(provider, res) {
  224. this.setUniverifyLogin(true);
  225. uni.closeAuthView();
  226. const univerifyInfo = {
  227. provider,
  228. ...res.authResult,
  229. }
  230. this.getPhoneNumber(univerifyInfo).then((phoneNumber) => {
  231. this.phoneNumber = phoneNumber;
  232. uni.setStorageSync(univerifyInfoKey, univerifyInfo)
  233. }).catch(err => {
  234. uni.showModal({
  235. showCancel: false,
  236. title: '手机号获取失败',
  237. content: `${err.errMsg}\n,错误码:${err.code}`
  238. })
  239. console.error(res);
  240. })
  241. },
  242. async loginByApple(provider, res) {
  243. // 获取用户信息
  244. let getUserInfoErr, result
  245. // #ifndef VUE3
  246. [getUserInfoErr, result] = await uni.getUserInfo({
  247. provider
  248. });
  249. // #endif
  250. // #ifdef VUE3
  251. try {
  252. result = await uni.getUserInfo({
  253. provider
  254. });
  255. } catch(e) {
  256. getUserInfoErr = e
  257. }
  258. // #endif
  259. if (getUserInfoErr) {
  260. let content = getUserInfoErr.errMsg;
  261. if (~content.indexOf('uni.login')) {
  262. content = '请在登录页面完成登录操作';
  263. }
  264. uni.showModal({
  265. title: '获取用户信息失败',
  266. content: '错误原因' + content,
  267. showCancel: false
  268. });
  269. }
  270. // uni-id 苹果登录
  271. console.warn('此处使用uni-id处理苹果登录,详情参考: https://uniapp.dcloud.net.cn/uniCloud/uni-id')
  272. uni.request({
  273. url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/user-center',
  274. method: 'POST',
  275. data: {
  276. action: 'loginByApple',
  277. params: result.userInfo
  278. },
  279. success: (res) => {
  280. console.log('uniId login success', res);
  281. if(res.data.code !== 0){
  282. uni.showModal({
  283. showCancel: false,
  284. content: `苹果登录失败: ${JSON.stringify(res.data.msg)}`,
  285. })
  286. } else {
  287. uni.setStorageSync('openid', res.data.openid)
  288. uni.setStorageSync('apple_nickname', res.data.userInfo.nickname)
  289. }
  290. },
  291. fail: (e) => {
  292. uni.showModal({
  293. content: `苹果登录失败: ${JSON.stringify(e)}`,
  294. showCancel: false
  295. })
  296. }
  297. })
  298. }
  299. }
  300. }
  301. </script>
  302. <style>
  303. button {
  304. background-color: #007aff;
  305. color: #ffffff;
  306. }
  307. </style>