index.vue 15 KB

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