index.vue 19 KB

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