index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. <template>
  2. <view :style="colorStyle" class="wrapper">
  3. <view class="bag">
  4. <img :src="`../static/login-bg_${colorStatus}.jpg`" alt="" srcset="">
  5. </view>
  6. <view class="system-height" :style="{ height: statusBarHeight }"></view>
  7. <!-- #ifdef MP -->
  8. <view class="title-bar" style="height: 43px;">
  9. <view class="icon" @click="back" v-if="!isHome">
  10. <image src="../static/left.png"></image>
  11. </view>
  12. <view class="icon" @click="home" v-else>
  13. <image src="../static/home.png"></image>
  14. </view>
  15. {{$t(`商城登录`)}}
  16. </view>
  17. <!-- #endif -->
  18. <view class="merchant-msg">
  19. <img :src="configData.wap_login_logo" />
  20. <view class="name">
  21. {{configData.site_name}}
  22. </view>
  23. </view>
  24. <view class="wechat_login">
  25. <view class="btn-wrapper">
  26. <!-- #ifdef H5 -->
  27. <button hover-class="none" @click="wechatLogin" class="bg-theme btn1">{{$t(`微信登录`)}}</button>
  28. <!-- #endif -->
  29. <!-- #ifdef MP -->
  30. <template v-if="configData.wechat_auth_switch">
  31. <button class="bg-theme btn1" v-if="bindPhone" open-type="getPhoneNumber"
  32. @getphonenumber="getphonenumber">{{$t(`授权登录`)}}</button>
  33. <button class="bg-theme btn1" v-else-if="!bindPhone" @click="getAuthLogin">
  34. {{$t(`授权登录`)}}
  35. </button>
  36. </template>
  37. <button v-if="configData.phone_auth_switch" hover-class="none" @click="phoneLogin"
  38. class="btn2">{{$t(`手机号登录`)}}</button>
  39. <view class="cancel-login" @click="onReject">取消登录</view>
  40. <!-- #endif -->
  41. </view>
  42. </view>
  43. <view class="protocol" v-if="!canGetPrivacySetting">
  44. <checkbox-group @click.stop='ChangeIsDefault'>
  45. <checkbox :class="inAnimation?'trembling':''" @animationend='inAnimation=false'
  46. :checked="protocol ? true : false" /> <text @click.stop='ChangeIsDefault'>{{$t(`已阅读并同意`)}}</text>
  47. <text class="main-color" @click.stop="privacy(4)">{{$t(`《用户协议》`)}}</text>
  48. {{$t(`与`)}}<text class="main-color" @click.stop="privacy(3)">{{$t(`《隐私协议》`)}}</text>
  49. </checkbox-group>
  50. </view>
  51. <block v-if="isUp">
  52. <mobileLogin :isUp="isUp" :canClose="canClose" @close="maskClose" :authKey="authKey"
  53. @wechatPhone="wechatPhone"></mobileLogin>
  54. </block>
  55. <block v-if="isPhoneBox">
  56. <routinePhone :logoUrl="logoUrl" :isPhoneBox="isPhoneBox" @loginSuccess="bindPhoneClose" :authKey="authKey">
  57. </routinePhone>
  58. </block>
  59. <block>
  60. <editUserModal :isShow="isShow" @closeEdit="closeEdit" @editSuccess="editSuccess">
  61. </editUserModal>
  62. </block>
  63. <!-- #ifdef MP -->
  64. <privacyAgreementPopup v-if="canGetPrivacySetting" @onReject="onReject" @onAgree="onAgree">
  65. </privacyAgreementPopup>
  66. <!-- #endif -->
  67. </view>
  68. </template>
  69. <script>
  70. const app = getApp();
  71. let statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
  72. import mobileLogin from '../components/login_mobile/index.vue';
  73. import routinePhone from '../components/login_mobile/routine_phone.vue';
  74. import editUserModal from '@/components/eidtUserModal/index.vue'
  75. import privacyAgreementPopup from '@/components/privacyAgreementPopup/index.vue'
  76. import {
  77. getLogo,
  78. silenceAuth,
  79. routineBindingPhone,
  80. wechatAuthV2,
  81. authType,
  82. authLogin,
  83. wechatAuthLogin
  84. } from '@/api/public';
  85. import {
  86. LOGO_URL,
  87. EXPIRES_TIME,
  88. USER_INFO,
  89. STATE_R_KEY
  90. } from '@/config/cache';
  91. import {
  92. getUserInfo
  93. } from '@/api/user.js';
  94. import Routine from '@/libs/routine';
  95. import wechat from '@/libs/wechat';
  96. import colors from '@/mixins/color.js';
  97. import Auth from '@/libs/wechat.js';
  98. import {
  99. HTTP_REQUEST_URL
  100. } from '@/config/app';
  101. import {
  102. isWeixin
  103. } from "@/utils";
  104. import Cache from '@/utils/cache';
  105. export default {
  106. mixins: [colors],
  107. data() {
  108. return {
  109. imgHost: HTTP_REQUEST_URL,
  110. isUp: false,
  111. canClose: true,
  112. phone: '',
  113. statusBarHeight: statusBarHeight,
  114. isHome: false,
  115. isPhoneBox: false,
  116. protocol: false,
  117. isShow: false,
  118. isLogin: false,
  119. logoUrl: '',
  120. code: '',
  121. authKey: '',
  122. options: '',
  123. userInfo: {},
  124. codeNum: 0,
  125. canUseGetUserProfile: false,
  126. canGetPrivacySetting: false,
  127. inAnimation: false,
  128. colorStatus: uni.getStorageSync('color_status'),
  129. mp_is_new: this.$Cache.get('MP_VERSION_ISNEW') || false,
  130. configData: Cache.get('BASIC_CONFIG'),
  131. bindPhone: false
  132. };
  133. },
  134. components: {
  135. mobileLogin,
  136. routinePhone,
  137. editUserModal,
  138. privacyAgreementPopup
  139. },
  140. onLoad(options) {
  141. if (uni.getUserProfile) {
  142. this.canUseGetUserProfile = true
  143. }
  144. // #ifdef MP
  145. if (wx.getPrivacySetting) {
  146. this.canGetPrivacySetting = true
  147. }
  148. // #endif
  149. let that = this;
  150. // #ifdef MP
  151. this.userLogin()
  152. // #endif
  153. // #ifdef H5
  154. const {
  155. code,
  156. state
  157. } = options;
  158. if (code) {
  159. let spread = this.$Cache.get("spread") || '';
  160. let agent_id = this.$Cache.get("agent_id") || '';
  161. let backUrl = state ? decodeURIComponent(state) : ''
  162. this.wechatAuthLogin({
  163. code,
  164. spread,
  165. agent_id
  166. }, backUrl)
  167. }
  168. // #endif
  169. let pages = getCurrentPages();
  170. let prePage = pages[pages.length - 2];
  171. if (prePage && prePage.route == 'pages/order_addcart/order_addcart') {
  172. this.isHome = true;
  173. } else {
  174. this.isHome = false;
  175. }
  176. },
  177. methods: {
  178. wechatAuthLogin(d, back_url) {
  179. uni.showLoading({
  180. title: this.$t(`正在登录中`)
  181. });
  182. wechatAuthLogin(d).then(res => {
  183. uni.hideLoading();
  184. if (res.data.bindPhone) {
  185. this.authKey = res.data.key
  186. uni.navigateTo({
  187. url: `/pages/users/binding_phone/index?authKey=${this.authKey}&backUrl=${back_url}`
  188. })
  189. } else {
  190. let time = res.data.expires_time - this.$Cache.time();
  191. this.$store.commit('LOGIN', {
  192. token: res.data.token,
  193. time: time
  194. });
  195. this.getUserInfo(0, back_url)
  196. }
  197. }).catch(err => {
  198. uni.hideLoading();
  199. uni.showToast({
  200. title: err,
  201. icon: 'none',
  202. duration: 2000
  203. });
  204. });
  205. },
  206. onAgree() {
  207. this.protocol = true
  208. },
  209. // 小程序 22.11.8日删除getUserProfile 接口获取用户昵称头像
  210. userLogin() {
  211. // if (!this.protocol) {
  212. // uni.showToast({
  213. // title: this.$t('请先阅读并同意协议'),
  214. // icon: 'none',
  215. // duration: 2000
  216. // });
  217. // return
  218. // }
  219. Routine.getCode()
  220. .then(code => {
  221. // uni.showLoading({
  222. // title: this.$t(`正在登录中`)
  223. // });
  224. authType({
  225. code,
  226. spread_spid: app.globalData.spid,
  227. spread_code: app.globalData.code,
  228. }).then(res => {
  229. uni.hideLoading();
  230. this.authKey = res.data.key;
  231. this.bindPhone = res.data.bindPhone
  232. // uni.navigateTo({
  233. // url: `/pages/users/binding_phone/index?authKey=${res.data.key}`
  234. // })
  235. })
  236. .catch(err => {
  237. uni.hideLoading();
  238. uni.showToast({
  239. title: err,
  240. icon: 'none',
  241. duration: 2000
  242. });
  243. });
  244. })
  245. .catch(err => {
  246. console.log(err)
  247. });
  248. },
  249. getAuthLogin() {
  250. if (!this.authKey) return
  251. if (!this.protocol) {
  252. uni.showToast({
  253. title: this.$t('请先阅读并同意协议'),
  254. icon: 'none',
  255. duration: 2000
  256. });
  257. return
  258. }
  259. uni.showLoading({
  260. title: this.$t(`正在登录中`)
  261. });
  262. authLogin({
  263. key: this.authKey
  264. }).then(res => {
  265. let time = res.data.expires_time - this.$Cache.time();
  266. this.$store.commit('LOGIN', {
  267. token: res.data.token,
  268. time: time
  269. });
  270. this.getUserInfo(res.data.bindName)
  271. }).catch(err => {
  272. uni.hideLoading();
  273. uni.showToast({
  274. title: err,
  275. icon: 'none',
  276. duration: 2000
  277. });
  278. });
  279. },
  280. ChangeIsDefault(e) {
  281. this.$set(this, 'protocol', !this.protocol);
  282. },
  283. editSuccess() {
  284. this.isShow = false
  285. },
  286. phoneLogin() {
  287. uni.navigateTo({
  288. url: `/pages/users/binding_phone/index?authKey=${this.authKey}&pageType=0`
  289. })
  290. },
  291. closeEdit() {
  292. this.isShow = false
  293. this.$util.Tips({
  294. title: this.$t(`登录成功`),
  295. icon: 'success'
  296. }, {
  297. tab: 3
  298. });
  299. },
  300. onReject() {
  301. uni.navigateBack();
  302. },
  303. // #ifdef MP
  304. back() {
  305. if (this.isLogin) {
  306. this.$store.commit('LOGIN', {
  307. token: '',
  308. time: 0
  309. });
  310. }
  311. uni.navigateBack();
  312. },
  313. // #endif
  314. // #ifndef MP
  315. back() {
  316. uni.navigateBack({
  317. delta: 1
  318. })
  319. },
  320. // #endif
  321. home() {
  322. uni.switchTab({
  323. url: '/pages/index/index'
  324. })
  325. },
  326. // 弹窗关闭
  327. maskClose(new_user) {
  328. this.isUp = false;
  329. // #ifdef MP
  330. if (new_user) {
  331. this.isShow = true
  332. }
  333. // #endif
  334. },
  335. bindPhoneClose(data) {
  336. this.isPhoneBox = false;
  337. if (data.isStatus) {
  338. // #ifdef MP
  339. this.getUserInfo(data.new_user)
  340. // #endif
  341. // #ifndef MP
  342. this.$util.Tips({
  343. title: this.$t(`登录成功`),
  344. icon: 'success'
  345. }, {
  346. tab: 3
  347. });
  348. // #endif
  349. }
  350. },
  351. // #ifdef MP
  352. // 小程序获取手机号码
  353. getphonenumber(e) {
  354. if (!this.protocol) {
  355. uni.showToast({
  356. title: this.$t('请先阅读并同意协议'),
  357. icon: 'none',
  358. duration: 2000
  359. });
  360. return
  361. }
  362. uni.showLoading({
  363. title: this.$t(`正在登录中`)
  364. });
  365. Routine.getCode()
  366. .then(code => {
  367. this.getUserPhoneNumber(e.detail.encryptedData, e.detail.iv, code);
  368. })
  369. .catch(error => {
  370. uni.$emit('closePage', false);
  371. uni.hideLoading();
  372. });
  373. },
  374. // 小程序获取手机号码回调
  375. getUserPhoneNumber(encryptedData, iv, code) {
  376. routineBindingPhone({
  377. encryptedData: encryptedData,
  378. iv: iv,
  379. code: code,
  380. spread_spid: app.globalData.spid,
  381. spread_code: app.globalData.code,
  382. agent_id: app.globalData.agent_id,
  383. key: this.authKey
  384. })
  385. .then(res => {
  386. let time = res.data.expires_time - this.$Cache.time();
  387. this.$store.commit('LOGIN', {
  388. token: res.data.token,
  389. time: time
  390. });
  391. // this.userInfo = res.data.userInfo;
  392. // this.$store.commit('SETUID', res.data.userInfo.uid);
  393. // this.$store.commit('UPDATE_USERINFO', res.data.userInfo);
  394. this.$Cache.clear('snsapiKey');
  395. this.getUserInfo(res.data.bindName)
  396. // this.$util.Tips({
  397. // title: this.$t(`登录成功`),
  398. // icon: 'success'
  399. // }, {
  400. // tab: 3
  401. // });
  402. })
  403. .catch(res => {
  404. uni.hideLoading();
  405. });
  406. },
  407. // #endif
  408. /**
  409. * 获取个人用户信息
  410. */
  411. getUserInfo(new_user, back_url) {
  412. let that = this;
  413. getUserInfo().then(res => {
  414. uni.hideLoading();
  415. that.userInfo = res.data;
  416. that.$store.commit('SETUID', res.data.uid);
  417. that.$store.commit('UPDATE_USERINFO', res.data);
  418. if (new_user) {
  419. this.isShow = true
  420. } else {
  421. // #ifdef MP
  422. that.$util.Tips({
  423. title: that.$t(`登录成功`),
  424. icon: 'success'
  425. }, {
  426. tab: 3
  427. });
  428. // #endif
  429. // #ifndef MP
  430. that.$util.Tips({
  431. title: that.$t(`登录成功`),
  432. icon: 'success'
  433. }, {
  434. tab: 4,
  435. url: back_url || '/pages/user/index'
  436. });
  437. // #endif
  438. }
  439. }).catch(err => {
  440. uni.hideLoading();
  441. uni.showToast({
  442. title: err.msg,
  443. icon: 'none',
  444. duration: 2000
  445. });
  446. });
  447. },
  448. privacy(type) {
  449. uni.navigateTo({
  450. url: "/pages/users/privacy/index?type=" + type
  451. })
  452. },
  453. // #ifdef H5
  454. // 获取url后面的参数
  455. getQueryString(name) {
  456. var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
  457. var reg_rewrite = new RegExp('(^|/)' + name + '/([^/]*)(/|$)', 'i');
  458. var r = window.location.search.substr(1).match(reg);
  459. var q = window.location.pathname.substr(1).match(reg_rewrite);
  460. if (r != null) {
  461. return unescape(r[2]);
  462. } else if (q != null) {
  463. return unescape(q[2]);
  464. } else {
  465. return null;
  466. }
  467. },
  468. // 公众号登录
  469. wechatLogin() {
  470. if (!this.protocol) {
  471. uni.showToast({
  472. title: this.$t('请先阅读并同意协议'),
  473. icon: 'none',
  474. duration: 2000
  475. });
  476. return
  477. }
  478. if (!this.code || this.options.scope !== 'snsapi_base') {
  479. this.$wechat.oAuth('snsapi_userinfo', location.href);
  480. } else {
  481. if (this.authKey) {
  482. // this.isUp = true;
  483. uni.navigateTo({
  484. url: `/pages/users/binding_phone/index?authKey=${this.authKey}`
  485. })
  486. }
  487. }
  488. },
  489. // 输入手机号后的回调
  490. wechatPhone() {
  491. this.$Cache.clear('snsapiKey');
  492. if (this.options.back_url) {
  493. let url = uni.getStorageSync('snRouter');
  494. url = url.indexOf('/pages/index/index') != -1 ? '/' : url;
  495. if (url.indexOf('/pages/users/wechat_login/index') !== -1) {
  496. url = '/';
  497. }
  498. if (!url) {
  499. url = '/pages/index/index';
  500. }
  501. this.isUp = false;
  502. uni.showToast({
  503. title: this.$t(`登录成功`),
  504. icon: 'none'
  505. });
  506. setTimeout(res => {
  507. location.href = url;
  508. }, 800);
  509. } else {
  510. this.isUp = false;
  511. uni.showToast({
  512. title: this.$t(`登录成功`),
  513. icon: 'none'
  514. });
  515. setTimeout(res => {
  516. location.href = '/pages/index/index';
  517. }, 800);
  518. }
  519. }
  520. // #endif
  521. }
  522. };
  523. </script>
  524. <style lang="scss">
  525. page {
  526. background: #fff;
  527. }
  528. .wrapper {
  529. position: relative;
  530. height: 100vh;
  531. .bag {
  532. position: absolute;
  533. top: 0;
  534. left: 0;
  535. width: 100%;
  536. opacity: .8;
  537. z-index: -1;
  538. /* #ifdef H5 */
  539. z-index: 0;
  540. /* #endif */
  541. img {
  542. width: 100%;
  543. height: 838rpx;
  544. }
  545. }
  546. .merchant-msg {
  547. padding-top: 252rpx;
  548. display: flex;
  549. justify-content: center;
  550. align-items: center;
  551. flex-direction: column;
  552. z-index: 2;
  553. /* #ifdef H5 */
  554. position: relative;
  555. /* #endif */
  556. img {
  557. width: 152rpx;
  558. height: 152rpx;
  559. border-radius: 50%;
  560. }
  561. .name {
  562. font-size: 40rpx;
  563. font-weight: 500;
  564. color: #333333;
  565. line-height: 56rpx;
  566. margin-top: 32rpx;
  567. }
  568. }
  569. }
  570. .wechat_login {
  571. margin-top: 96rpx;
  572. .img image {
  573. width: 100%;
  574. }
  575. .btn-wrapper {
  576. padding: 0 66rpx;
  577. button {
  578. width: 100%;
  579. height: 86rpx;
  580. line-height: 86rpx;
  581. margin-bottom: 40rpx;
  582. border-radius: 120rpx;
  583. font-size: 30rpx;
  584. &.btn1 {
  585. color: #fff;
  586. }
  587. &.btn2 {
  588. color: #666666;
  589. border: 1px solid #E4E4E4;
  590. margin-bottom: 30rpx;
  591. }
  592. }
  593. .cancel-login{
  594. color: #999;
  595. font-size: 28rpx;
  596. text-align: center;
  597. }
  598. }
  599. }
  600. .title-bar {
  601. position: relative;
  602. display: flex;
  603. align-items: center;
  604. justify-content: center;
  605. font-size: 34rpx;
  606. font-weight: 500;
  607. color: #333333;
  608. line-height: 48rpx;
  609. }
  610. .icon {
  611. position: absolute;
  612. left: 30rpx;
  613. top: 0;
  614. display: flex;
  615. align-items: center;
  616. justify-content: center;
  617. width: 80rpx;
  618. height: 80rpx;
  619. image {
  620. width: 50rpx;
  621. height: 50rpx;
  622. }
  623. }
  624. .protocol {
  625. position: fixed;
  626. bottom: 52rpx;
  627. left: 0;
  628. width: 100%;
  629. margin: 0 auto;
  630. color: #999999;
  631. font-size: 24rpx;
  632. line-height: 22rpx;
  633. text-align: center;
  634. bottom: calc(52rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
  635. bottom: calc(52rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  636. .main-color {
  637. color: var(--view-theme);
  638. }
  639. .trembling {
  640. animation: shake 0.6s;
  641. }
  642. /deep/ uni-checkbox .uni-checkbox-input {
  643. width: 28rpx;
  644. height: 28rpx;
  645. }
  646. /deep/ uni-checkbox .uni-checkbox-input.uni-checkbox-input-checked::before {
  647. font-size: 24rpx
  648. }
  649. /deep/ uni-checkbox .uni-checkbox-wrapper {
  650. margin-bottom: 1px;
  651. }
  652. /*checkbox 选项框大小 */
  653. /deep/ checkbox .wx-checkbox-input {
  654. width: 28rpx;
  655. height: 28rpx;
  656. }
  657. /*checkbox选中后样式 */
  658. /deep/ checkbox .wx-checkbox-input.wx-checkbox-input-checked {
  659. background: white;
  660. }
  661. /*checkbox选中后图标样式 */
  662. /deep/ checkbox .wx-checkbox-input.wx-checkbox-input-checked::before {
  663. width: 28rpx;
  664. height: 28rpx;
  665. line-height: 28rpx;
  666. text-align: center;
  667. font-size: 22rpx;
  668. background: transparent;
  669. transform: translate(-50%, -50%) scale(1);
  670. -webkit-transform: translate(-50%, -50%) scale(1);
  671. }
  672. }
  673. </style>