index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. <template>
  2. <view :style="colorStyle">
  3. <view class="system-height" :style="{ height: statusBarHeight }"></view>
  4. <!-- #ifdef MP -->
  5. <view class="title-bar" style="height: 43px;">
  6. <view class="icon" @click="back" v-if="!isHome">
  7. <image src="../static/left.png"></image>
  8. </view>
  9. <view class="icon" @click="home" v-else>
  10. <image src="../static/home.png"></image>
  11. </view>
  12. {{$t(`账户登录`)}}
  13. </view>
  14. <!-- #endif -->
  15. <view class="wechat_login">
  16. <view class="img">
  17. <image src="../static/wechat_login.png" mode="widthFix"></image>
  18. </view>
  19. <view class="btn-wrapper">
  20. <!-- #ifdef H5 -->
  21. <button hover-class="none" @click="wechatLogin" class="bg-green btn1">{{$t(`微信登录`)}}</button>
  22. <!-- #endif -->
  23. <!-- #ifdef MP -->
  24. <button hover-class="none" v-if="mp_is_new" @tap="userLogin"
  25. class="bg-green btn1">{{$t(`微信登录`)}}</button>
  26. <button v-else-if="canUseGetUserProfile && code" hover-class="none" @tap="getUserProfile"
  27. class="bg-green btn1">{{$t(`微信登录`)}}</button>
  28. <button v-else hover-class="none" open-type="getUserInfo" @getuserinfo="setUserInfo"
  29. class="bg-green btn1">{{$t(`微信登录`)}}</button>
  30. <!-- #endif -->
  31. <button hover-class="none" @click="isUp = true" class="btn2">{{$t(`手机号登录`)}}</button>
  32. </view>
  33. </view>
  34. <block v-if="isUp">
  35. <mobileLogin :isUp="isUp" @close="maskClose" :authKey="authKey" @wechatPhone="wechatPhone"></mobileLogin>
  36. </block>
  37. <block v-if="isPhoneBox">
  38. <routinePhone :logoUrl="logoUrl" :isPhoneBox="isPhoneBox" @close="bindPhoneClose" :authKey="authKey">
  39. </routinePhone>
  40. </block>
  41. </view>
  42. </template>
  43. <script>
  44. const app = getApp();
  45. let statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
  46. import mobileLogin from '../components/login_mobile/index.vue';
  47. import routinePhone from '../components/login_mobile/routine_phone.vue';
  48. import {
  49. getLogo,
  50. silenceAuth,
  51. getUserPhone,
  52. wechatAuthV2,
  53. authLogin
  54. } from '@/api/public';
  55. import {
  56. LOGO_URL,
  57. EXPIRES_TIME,
  58. USER_INFO,
  59. STATE_R_KEY
  60. } from '@/config/cache';
  61. import {
  62. getUserInfo
  63. } from '@/api/user.js';
  64. import Routine from '@/libs/routine';
  65. import wechat from '@/libs/wechat';
  66. import colors from '@/mixins/color.js';
  67. import Auth from '@/libs/wechat.js';
  68. export default {
  69. mixins: [colors],
  70. data() {
  71. return {
  72. isUp: false,
  73. phone: '',
  74. statusBarHeight: statusBarHeight,
  75. isHome: false,
  76. isPhoneBox: false,
  77. logoUrl: '',
  78. code: '',
  79. authKey: '',
  80. options: '',
  81. userInfo: {},
  82. codeNum: 0,
  83. canUseGetUserProfile: false,
  84. mp_is_new: this.$Cache.get('MP_VERSION_ISNEW') || false
  85. };
  86. },
  87. components: {
  88. mobileLogin,
  89. routinePhone
  90. },
  91. onLoad(options) {
  92. if (uni.getUserProfile) {
  93. this.canUseGetUserProfile = true
  94. }
  95. getLogo().then(res => {
  96. this.logoUrl = res.data.logo_url;
  97. });
  98. let that = this;
  99. // #ifdef MP
  100. Routine.getCode()
  101. .then(code => {
  102. this.code = code
  103. })
  104. // #endif
  105. // #ifdef H5
  106. document.body.addEventListener('focusout', () => {
  107. setTimeout(() => {
  108. const scrollHeight = document.documentElement.scrollTop || document.body
  109. .scrollTop ||
  110. 0;
  111. window.scrollTo(0, Math.max(scrollHeight - 1, 0));
  112. }, 100);
  113. });
  114. const {
  115. code,
  116. state,
  117. scope
  118. } = options;
  119. this.options = options;
  120. // 获取确认授权code
  121. this.code = code || '';
  122. if (code && this.options.scope !== 'snsapi_base') {
  123. let spread = app.globalData.spid ? app.globalData.spid : '';
  124. //公众号授权登录回调
  125. wechat
  126. .auth(code, state)
  127. .then(res => {
  128. if (res.key !== undefined && res.key) {
  129. that.authKey = res.key;
  130. that.isUp = true;
  131. } else {
  132. let time = res.expires_time - that.$Cache.time();
  133. that.$store.commit('LOGIN', {
  134. token: res.token,
  135. time: time
  136. });
  137. that.userInfo = res.userInfo;
  138. that.$store.commit('SETUID', res.userInfo.uid);
  139. that.$store.commit('UPDATE_USERINFO', res.userInfo);
  140. that.wechatPhone();
  141. }
  142. })
  143. .catch(error => {
  144. // location.replace("/");
  145. });
  146. } else if (code && this.options.scope == 'snsapi_base' && !this.$Cache.has('snsapiKey')) {
  147. //公众号静默授权
  148. let snsapiBase = 'snsapi_base';
  149. let urlData = location.pathname + location.search;
  150. // if (!that.$store.getters.isLogin && uni.getStorageSync('authIng')) {
  151. // uni.setStorageSync('authIng', false)
  152. // }
  153. if (options.back_url) {
  154. uni.setStorageSync('snRouter', options.back_url);
  155. }
  156. if (!that.$store.getters.isLogin && Auth.isWeixin()) {
  157. let code
  158. if (options.code instanceof Array) {
  159. code = options.code[options.code.length - 1]
  160. } else {
  161. code = options.code
  162. }
  163. if (code && code != uni.getStorageSync('snsapiCode') && !this.$Cache.has('snsapiKey')) {
  164. // 存储静默授权code
  165. uni.setStorageSync('snsapiCode', code);
  166. uni.setStorageSync('authIng', true)
  167. silenceAuth({
  168. code: code,
  169. spread: that.$Cache.get('spread'),
  170. spid: that.$Cache.get('spread')
  171. })
  172. .then(res => {
  173. // uni.setStorageSync('authIng', false)
  174. // uni.setStorageSync('snRouter', decodeURIComponent(decodeURIComponent(options.query
  175. // .back_url)));
  176. if (res.data.key !== undefined && res.data.key) {
  177. this.$Cache.set('snsapiKey', res.data.key);
  178. uni.navigateTo({
  179. url: '/pages/users/wechat_login/index'
  180. })
  181. }
  182. })
  183. .catch(error => {
  184. uni.setStorageSync('authIng', false)
  185. let url = ''
  186. if (options.back_url instanceof Array) {
  187. url = options.back_url[options.back_url.length - 1]
  188. } else {
  189. url = options.back_url
  190. }
  191. if (!that.$Cache.has('snsapiKey')) {
  192. Auth.oAuth(snsapiBase, url);
  193. }
  194. });
  195. } else {
  196. Auth.oAuth(snsapiBase, urlData)
  197. }
  198. } else {
  199. if (options.query.back_url) {
  200. location.replace(uni.getStorageSync('snRouter'));
  201. }
  202. }
  203. } else if (!this.$Cache.has('snsapiKey')) {
  204. let urlData = location.pathname + location.search;
  205. Auth.oAuth('snsapi_base', urlData)
  206. }
  207. // #endif
  208. let pages = getCurrentPages();
  209. let prePage = pages[pages.length - 2];
  210. if (prePage && prePage.route == 'pages/order_addcart/order_addcart') {
  211. this.isHome = true;
  212. } else {
  213. this.isHome = false;
  214. }
  215. },
  216. methods: {
  217. // 小程序 22.11.8日删除getUserProfile 接口获取用户昵称头像
  218. userLogin() {
  219. Routine.getCode()
  220. .then(code => {
  221. uni.showLoading({
  222. title: this.$t(`正在登录中`)
  223. });
  224. authLogin({
  225. code,
  226. spread_spid: app.globalData.spid,
  227. spread_code: app.globalData.code
  228. }).then(res => {
  229. if (res.data.key !== undefined && res.data.key) {
  230. uni.hideLoading();
  231. this.authKey = res.data.key;
  232. this.isPhoneBox = true;
  233. } else {
  234. uni.hideLoading();
  235. let time = res.data.expires_time - this.$Cache.time();
  236. this.$store.commit('LOGIN', {
  237. token: res.data.token,
  238. time: time
  239. });
  240. this.getUserInfo()
  241. }
  242. })
  243. })
  244. .catch(err => {
  245. console.log(err)
  246. });
  247. },
  248. back() {
  249. uni.navigateBack();
  250. },
  251. home() {
  252. uni.switchTab({
  253. url: '/pages/index/index'
  254. })
  255. },
  256. // 弹窗关闭
  257. maskClose() {
  258. this.isUp = false;
  259. },
  260. bindPhoneClose(data) {
  261. if (data.isStatus) {
  262. this.isPhoneBox = false;
  263. this.$util.Tips({
  264. title: this.$t(`登录成功`),
  265. icon: 'success'
  266. }, {
  267. tab: 3
  268. });
  269. } else {
  270. this.isPhoneBox = false;
  271. }
  272. },
  273. // #ifdef MP
  274. // 小程序获取手机号码
  275. getphonenumber(e) {
  276. uni.showLoading({
  277. title: this.$t(`正在登录中`)
  278. });
  279. Routine.getCode()
  280. .then(code => {
  281. this.getUserPhoneNumber(e.detail.encryptedData, e.detail.iv, code);
  282. })
  283. .catch(error => {
  284. uni.$emit('closePage', false);
  285. uni.hideLoading();
  286. });
  287. },
  288. // 小程序获取手机号码回调
  289. getUserPhoneNumber(encryptedData, iv, code) {
  290. getUserPhone({
  291. encryptedData: encryptedData,
  292. iv: iv,
  293. code: code,
  294. spread_spid: app.globalData.spid,
  295. spread_code: app.globalData.code
  296. })
  297. .then(res => {
  298. let time = res.data.expires_time - this.$Cache.time();
  299. this.$store.commit('LOGIN', {
  300. token: res.data.token,
  301. time: time
  302. });
  303. this.userInfo = res.data.userInfo;
  304. this.$store.commit('SETUID', res.data.userInfo.uid);
  305. this.$store.commit('UPDATE_USERINFO', res.data.userInfo);
  306. this.$Cache.clear('snsapiKey');
  307. this.$util.Tips({
  308. title: this.$t(`登录成功`),
  309. icon: 'success'
  310. }, {
  311. tab: 3
  312. });
  313. })
  314. .catch(res => {
  315. uni.hideLoading();
  316. });
  317. },
  318. /**
  319. * 获取个人用户信息
  320. */
  321. getUserInfo: function() {
  322. let that = this;
  323. getUserInfo().then(res => {
  324. uni.hideLoading();
  325. that.userInfo = res.data;
  326. that.$store.commit('SETUID', res.data.uid);
  327. that.$store.commit('UPDATE_USERINFO', res.data);
  328. that.$util.Tips({
  329. title: that.$t(`登录成功`),
  330. icon: 'success'
  331. }, {
  332. tab: 3
  333. });
  334. });
  335. },
  336. setUserInfo(e) {
  337. uni.showLoading({
  338. title: this.$t(`正在登录中`)
  339. });
  340. Routine.getCode()
  341. .then(code => {
  342. this.getWxUser(code);
  343. })
  344. .catch(res => {
  345. uni.hideLoading();
  346. });
  347. },
  348. //小程序授权api替换 getUserInfo
  349. getUserProfile() {
  350. uni.showLoading({
  351. title: this.$t(`正在登录中`)
  352. });
  353. let self = this;
  354. Routine.getUserProfile()
  355. .then(res => {
  356. let userInfo = res.userInfo;
  357. userInfo.code = this.code;
  358. userInfo.spread_spid = app.globalData.spid || this.$Cache.get('spread'); //获取推广人ID
  359. userInfo.spread_code = app.globalData.code; //获取推广人分享二维码ID
  360. Routine.authUserInfo(userInfo)
  361. .then(res => {
  362. if (res.data.key !== undefined && res.data.key) {
  363. uni.hideLoading();
  364. self.authKey = res.data.key;
  365. self.isPhoneBox = true;
  366. } else {
  367. uni.hideLoading();
  368. let time = res.data.expires_time - self.$Cache.time();
  369. self.$store.commit('LOGIN', {
  370. token: res.data.token,
  371. time: time
  372. });
  373. this.getUserInfo()
  374. }
  375. })
  376. .catch(res => {
  377. uni.hideLoading();
  378. uni.showToast({
  379. title: res.msg,
  380. icon: 'none',
  381. duration: 2000
  382. });
  383. });
  384. })
  385. .catch(res => {
  386. uni.hideLoading();
  387. });
  388. },
  389. getWxUser(code) {
  390. let self = this;
  391. Routine.getUserInfo()
  392. .then(res => {
  393. let userInfo = res.userInfo;
  394. userInfo.code = code;
  395. userInfo.spread_spid = app.globalData.spid; //获取推广人ID
  396. userInfo.spread_code = app.globalData.code; //获取推广人分享二维码ID
  397. Routine.authUserInfo(userInfo)
  398. .then(res => {
  399. if (res.data.key !== undefined && res.data.key) {
  400. uni.hideLoading();
  401. self.authKey = res.data.key;
  402. self.isPhoneBox = true;
  403. } else {
  404. uni.hideLoading();
  405. let time = res.data.expires_time - self.$Cache.time();
  406. self.$store.commit('LOGIN', {
  407. token: res.data.token,
  408. time: time
  409. });
  410. self.$util.Tips({
  411. title: res.msg,
  412. icon: 'success'
  413. }, {
  414. tab: 3
  415. });
  416. }
  417. })
  418. .catch(res => {
  419. uni.hideLoading();
  420. uni.showToast({
  421. title: res.msg,
  422. icon: 'none',
  423. duration: 2000
  424. });
  425. });
  426. })
  427. .catch(res => {
  428. uni.hideLoading();
  429. });
  430. },
  431. // #endif
  432. // #ifdef H5
  433. // 获取url后面的参数
  434. getQueryString(name) {
  435. var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
  436. var reg_rewrite = new RegExp('(^|/)' + name + '/([^/]*)(/|$)', 'i');
  437. var r = window.location.search.substr(1).match(reg);
  438. var q = window.location.pathname.substr(1).match(reg_rewrite);
  439. if (r != null) {
  440. return unescape(r[2]);
  441. } else if (q != null) {
  442. return unescape(q[2]);
  443. } else {
  444. return null;
  445. }
  446. },
  447. // 公众号登录
  448. wechatLogin() {
  449. if (!this.code || this.options.scope !== 'snsapi_base') {
  450. this.$wechat.oAuth('snsapi_userinfo', '/pages/users/wechat_login/index');
  451. } else {
  452. if (this.authKey) {
  453. this.isUp = true;
  454. }
  455. }
  456. },
  457. // 输入手机号后的回调
  458. wechatPhone() {
  459. console.log(2222)
  460. this.$Cache.clear('snsapiKey');
  461. if (this.options.back_url) {
  462. let url = uni.getStorageSync('snRouter');
  463. url = url.indexOf('/pages/index/index') != -1 ? '/' : url;
  464. if (url.indexOf('/pages/users/wechat_login/index') !== -1) {
  465. url = '/';
  466. }
  467. if (!url) {
  468. url = '/pages/index/index';
  469. }
  470. this.isUp = false;
  471. uni.showToast({
  472. title: this.$t(`登录成功`),
  473. icon: 'none'
  474. });
  475. setTimeout(res => {
  476. location.href = url;
  477. }, 800);
  478. } else {
  479. this.isUp = false;
  480. uni.showToast({
  481. title: this.$t(`登录成功`),
  482. icon: 'none'
  483. });
  484. setTimeout(res => {
  485. location.href = '/pages/index/index';
  486. }, 800);
  487. }
  488. }
  489. // #endif
  490. }
  491. };
  492. </script>
  493. <style lang="scss">
  494. page {
  495. background: #fff;
  496. }
  497. .wechat_login {
  498. padding: 72rpx 34rpx;
  499. .img image {
  500. width: 100%;
  501. }
  502. .btn-wrapper {
  503. margin-top: 86rpx;
  504. padding: 0 66rpx;
  505. button {
  506. width: 100%;
  507. height: 86rpx;
  508. line-height: 86rpx;
  509. margin-bottom: 40rpx;
  510. border-radius: 120rpx;
  511. font-size: 30rpx;
  512. &.btn1 {
  513. color: #fff;
  514. }
  515. &.btn2 {
  516. color: #666666;
  517. border: 1px solid #666666;
  518. }
  519. }
  520. }
  521. }
  522. .title-bar {
  523. position: relative;
  524. display: flex;
  525. align-items: center;
  526. justify-content: center;
  527. font-size: 36rpx;
  528. }
  529. .icon {
  530. position: absolute;
  531. left: 30rpx;
  532. top: 0;
  533. display: flex;
  534. align-items: center;
  535. justify-content: center;
  536. width: 86rpx;
  537. height: 86rpx;
  538. image {
  539. width: 50rpx;
  540. height: 50rpx;
  541. }
  542. }
  543. </style>