index.vue 18 KB

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