index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. <template>
  2. <view class="login-wrapper" :style="colorStyle">
  3. <view class="shading">
  4. <image :src="logoUrl" />
  5. </view>
  6. <view class="whiteBg" v-if="formItem === 1">
  7. <view class="list" v-if="current !== 1">
  8. <form @submit.prevent="submit">
  9. <view class="item">
  10. <view class="acea-row row-middle">
  11. <image src="../static/phone_1.png" style="width: 24rpx; height: 34rpx"></image>
  12. <input type="text" :placeholder="$t(`输入手机号码`)" v-model="account" maxlength="11" required />
  13. </view>
  14. </view>
  15. <view class="item">
  16. <view class="acea-row row-middle">
  17. <image src="../static/code_1.png" style="width: 28rpx; height: 32rpx"></image>
  18. <input type="password" :placeholder="$t(`填写登录密码`)" v-model="password" required />
  19. </view>
  20. </view>
  21. </form>
  22. <!-- <navigator class="forgetPwd" hover-class="none" url="/pages/users/retrievePassword/index">
  23. <span class="iconfont icon-wenti"></span>忘记密码
  24. </navigator> -->
  25. </view>
  26. <view class="list" v-if="current !== 0 || appLoginStatus || appleLoginStatus">
  27. <view class="item">
  28. <view class="acea-row row-middle">
  29. <image src="../static/phone_1.png" style="width: 24rpx; height: 34rpx"></image>
  30. <input type="text" :placeholder="$t(`输入手机号码`)" v-model="account" :maxlength="11" />
  31. </view>
  32. </view>
  33. <view class="item">
  34. <view class="acea-row row-middle">
  35. <image src="../static/code_2.png" style="width: 28rpx; height: 32rpx"></image>
  36. <input type="text" :placeholder="$t(`填写验证码`)" :maxlength="6" class="codeIput" v-model="captcha" />
  37. <button class="code" :disabled="disabled" :class="disabled === true ? 'on' : ''" @click="code">
  38. {{ text }}
  39. </button>
  40. </view>
  41. </view>
  42. <!-- <view class="item" v-if="isShowCode">
  43. <view class="acea-row row-middle">
  44. <image src="../static/code_2.png" style="width: 28rpx; height: 32rpx;"></image>
  45. <input type="text" :placeholder="$t(`填写验证码`)" class="codeIput" v-model="codeVal" />
  46. <view class="code" @click="again"><img :src="codeUrl" /></view>
  47. </view>
  48. </view> -->
  49. </view>
  50. <view class="logon" @click="loginMobile" v-if="current !== 0">{{ $t(`登录`) }}</view>
  51. <view class="logon" @click="submit" v-if="current === 0">{{ $t(`登录`) }}</view>
  52. <!-- #ifndef APP-PLUS -->
  53. <view class="tips">
  54. <view v-if="current == 0" @click="current = 1">{{ $t(`快速登录`) }}</view>
  55. <view v-if="current == 1" @click="current = 0">{{ $t(`账号登录`) }}</view>
  56. </view>
  57. <!-- #endif -->
  58. <!-- #ifdef APP-PLUS -->
  59. <view class="appLogin" v-if="!appLoginStatus && !appleLoginStatus">
  60. <view class="hds">
  61. <span class="line"></span>
  62. <p>{{ $t(`其他方式登录`) }}</p>
  63. <span class="line"></span>
  64. </view>
  65. <view class="btn-wrapper">
  66. <view class="btn wx" @click="wxLogin">
  67. <span class="iconfont icon-s-weixindenglu1"></span>
  68. </view>
  69. <view class="btn mima" v-if="current == 1" @click="current = 0">
  70. <span class="iconfont icon-s-mimadenglu1"></span>
  71. </view>
  72. <view class="btn yanzheng" v-if="current == 0" @click="current = 1">
  73. <span class="iconfont icon-s-yanzhengmadenglu1"></span>
  74. </view>
  75. <view class="apple-btn" @click="appleLogin" v-if="appleShow">
  76. <view class="iconfont icon-s-pingguo"></view>
  77. </view>
  78. </view>
  79. </view>
  80. <!-- #endif -->
  81. <view class="protocol">
  82. <checkbox-group @change="ChangeIsDefault">
  83. <checkbox :class="inAnimation ? 'trembling' : ''" @animationend="inAnimation = false" :checked="protocol ? true : false" />
  84. {{ $t(`已阅读并同意`) }}
  85. <text class="main-color" @click="privacy(4)">{{ $t(`《用户协议》`) }}</text>
  86. {{ $t(`与`) }}
  87. <text class="main-color" @click="privacy(3)">{{ $t(`《隐私协议》`) }}</text>
  88. </checkbox-group>
  89. </view>
  90. </view>
  91. <view class="bottom">
  92. <view class="ver" v-if="copyRight">{{ copyRight }}</view>
  93. <view v-else class="ver">
  94. <a href="https://www.crmeb.com">Copyright ©2024 CRMEB. All Rights</a>
  95. </view>
  96. </view>
  97. <Verify @success="success" :captchaType="captchaType" :imgSize="{ width: '330px', height: '155px' }" ref="verify"></Verify>
  98. </view>
  99. </template>
  100. <script>
  101. import dayjs from '@/plugin/dayjs/dayjs.min.js';
  102. import sendVerifyCode from '@/mixins/SendVerifyCode';
  103. import { loginH5, loginMobile, registerVerify, register, getCodeApi, getUserInfo, appleLogin } from '@/api/user';
  104. import attrs, { required, alpha_num, chs_phone } from '@/utils/validate';
  105. import { getLogo } from '@/api/public';
  106. // import cookie from "@/utils/store/cookie";
  107. import { VUE_APP_API_URL } from '@/utils';
  108. // #ifdef APP-PLUS
  109. import { wechatAppAuth } from '@/api/api.js';
  110. // #endif
  111. const BACK_URL = 'login_back_url';
  112. import colors from '@/mixins/color.js';
  113. import Verify from '../components/verify/index.vue';
  114. export default {
  115. name: 'Login',
  116. components: {
  117. Verify
  118. },
  119. mixins: [sendVerifyCode, colors],
  120. data: function () {
  121. return {
  122. copyRight: '',
  123. inAnimation: false,
  124. protocol: false,
  125. navList: [this.$t(`快速登录`), this.$t(`账号登录`)],
  126. current: 1,
  127. account: '',
  128. password: '',
  129. captcha: '',
  130. formItem: 1,
  131. type: 'login',
  132. logoUrl: '',
  133. keyCode: '',
  134. codeUrl: '',
  135. codeVal: '',
  136. isShowCode: false,
  137. appLoginStatus: false, // 微信登录强制绑定手机号码状态
  138. appUserInfo: null, // 微信登录保存的用户信息
  139. appleLoginStatus: false, // 苹果登录强制绑定手机号码状态
  140. appleUserInfo: null,
  141. appleShow: false, // 苹果登录版本必须要求ios13以上的
  142. keyLock: true
  143. };
  144. },
  145. watch: {
  146. formItem: function (nval, oVal) {
  147. if (nval == 1) {
  148. this.type = 'login';
  149. } else {
  150. this.type = 'register';
  151. }
  152. }
  153. },
  154. onLoad() {
  155. let self = this;
  156. uni.getSystemInfo({
  157. success: (res) => {
  158. if (res.platform.toLowerCase() == 'ios' && this.getSystem(res.system)) {
  159. self.appleShow = true;
  160. }
  161. }
  162. });
  163. if (uni.getStorageSync('copyRight').copyrightContext) {
  164. this.copyRight = uni.getStorageSync('copyRight').copyrightContext;
  165. }
  166. },
  167. mounted() {
  168. // this.getCode();
  169. this.getLogoImage();
  170. },
  171. methods: {
  172. ChangeIsDefault(e) {
  173. this.$set(this, 'protocol', !this.protocol);
  174. },
  175. privacy(type) {
  176. uni.navigateTo({
  177. url: '/pages/users/privacy/index?type=' + type
  178. });
  179. },
  180. // IOS 版本号判断
  181. getSystem(system) {
  182. let str;
  183. system.toLowerCase().indexOf('ios') === -1 ? (str = system) : (str = system.split(' ')[1]);
  184. if (str.indexOf('.')) return str.split('.')[0] >= 13;
  185. return str >= 13;
  186. },
  187. // 苹果登录
  188. appleLogin() {
  189. let self = this;
  190. this.account = '';
  191. this.captcha = '';
  192. if (!self.protocol) {
  193. this.inAnimation = true;
  194. return self.$util.Tips({
  195. title: '请先阅读并同意协议'
  196. });
  197. }
  198. uni.showLoading({
  199. title: this.$t(`登录中`)
  200. });
  201. uni.login({
  202. provider: 'apple',
  203. timeout: 10000,
  204. success(loginRes) {
  205. uni.getUserInfo({
  206. provider: 'apple',
  207. success: function (infoRes) {
  208. self.appleUserInfo = infoRes.userInfo;
  209. self.appleLoginApi();
  210. },
  211. fail() {
  212. uni.showToast({
  213. title: self.$t(`获取用户信息失败`),
  214. icon: 'none',
  215. duration: 2000
  216. });
  217. },
  218. complete() {
  219. uni.hideLoading();
  220. }
  221. });
  222. },
  223. fail(error) {
  224. console.log(error);
  225. }
  226. });
  227. },
  228. // 苹果登录Api
  229. appleLoginApi() {
  230. let self = this;
  231. appleLogin({
  232. openId: self.appleUserInfo.openId,
  233. email: self.appleUserInfo.email || '',
  234. phone: this.account,
  235. captcha: this.captcha
  236. })
  237. .then(({ data }) => {
  238. if (data.isbind) {
  239. uni.showModal({
  240. title: self.$t(`提示`),
  241. content: self.$t(`请绑定手机号后,继续操作`),
  242. showCancel: false,
  243. success: function (res) {
  244. if (res.confirm) {
  245. self.current = 1;
  246. self.appleLoginStatus = true;
  247. }
  248. }
  249. });
  250. } else {
  251. self.$store.commit('LOGIN', {
  252. token: data.token,
  253. time: data.expires_time - self.$Cache.time()
  254. });
  255. let backUrl = self.$Cache.get(BACK_URL) || '/pages/index/index';
  256. self.$Cache.clear(BACK_URL);
  257. self.$store.commit('SETUID', data.userInfo.uid);
  258. uni.reLaunch({
  259. url: backUrl
  260. });
  261. }
  262. })
  263. .catch((error) => {
  264. uni.showModal({
  265. title: self.$t(`提示`),
  266. content: self.$t(`错误信息`) + `${error}`,
  267. success: function (res) {
  268. if (res.confirm) {
  269. console.log(self.$t(`用户点击确定`));
  270. } else if (res.cancel) {
  271. console.log(self.$t(`用户点击取消`));
  272. }
  273. }
  274. });
  275. });
  276. },
  277. // App微信登录
  278. wxLogin() {
  279. let self = this;
  280. this.account = '';
  281. this.captcha = '';
  282. if (!self.protocol) {
  283. this.inAnimation = true;
  284. return self.$util.Tips({
  285. title: '请先阅读并同意协议'
  286. });
  287. }
  288. uni.showLoading({
  289. title: self.$t(`登录中`)
  290. });
  291. uni.login({
  292. provider: 'weixin',
  293. success: function (loginRes) {
  294. // 获取用户信息
  295. uni.getUserInfo({
  296. provider: 'weixin',
  297. success: function (infoRes) {
  298. self.appUserInfo = infoRes.userInfo;
  299. self.wxLoginApi();
  300. },
  301. fail() {
  302. uni.showToast({
  303. title: self.$t(`获取用户信息失败`),
  304. icon: 'none',
  305. duration: 2000
  306. });
  307. },
  308. complete() {
  309. uni.hideLoading();
  310. }
  311. });
  312. },
  313. fail() {
  314. uni.showToast({
  315. title: self.$t(`登录失败`),
  316. icon: 'none',
  317. duration: 2000
  318. });
  319. }
  320. });
  321. },
  322. wxLoginApi() {
  323. let self = this;
  324. wechatAppAuth({
  325. userInfo: self.appUserInfo,
  326. phone: this.account,
  327. code: this.captcha
  328. })
  329. .then(({ data }) => {
  330. if (data.isbind) {
  331. uni.showModal({
  332. title: self.$t(`提示`),
  333. content: self.$t(`请绑定手机号后,继续操作`),
  334. showCancel: false,
  335. success: function (res) {
  336. if (res.confirm) {
  337. self.current = 1;
  338. self.appLoginStatus = true;
  339. }
  340. }
  341. });
  342. } else {
  343. self.$store.commit('LOGIN', {
  344. token: data.token,
  345. time: data.expires_time - self.$Cache.time()
  346. });
  347. let backUrl = self.$Cache.get(BACK_URL) || '/pages/index/index';
  348. self.$Cache.clear(BACK_URL);
  349. self.$store.commit('SETUID', data.userInfo.uid);
  350. uni.reLaunch({
  351. url: backUrl
  352. });
  353. }
  354. })
  355. .catch((error) => {
  356. uni.showModal({
  357. title: self.$t(`提示`),
  358. content: self.$t(`错误信息`) + `${error}`,
  359. success: function (res) {
  360. if (res.confirm) {
  361. console.log(self.$t(`用户点击确定`));
  362. } else if (res.cancel) {
  363. console.log(self.$t(`用户点击取消`));
  364. }
  365. }
  366. });
  367. });
  368. },
  369. again() {
  370. this.codeUrl = VUE_APP_API_URL + '/sms_captcha?' + 'key=' + this.keyCode + Date.parse(new Date());
  371. },
  372. success(data) {
  373. this.$refs.verify.hide();
  374. getCodeApi()
  375. .then((res) => {
  376. this.keyCode = res.data.key;
  377. this.getCode(data);
  378. })
  379. .catch((res) => {
  380. this.$util.Tips({
  381. title: res
  382. });
  383. });
  384. },
  385. code() {
  386. let that = this;
  387. if (!that.protocol) {
  388. this.inAnimation = true;
  389. return that.$util.Tips({
  390. title: '请先阅读并同意协议'
  391. });
  392. }
  393. if (!that.account)
  394. return that.$util.Tips({
  395. title: that.$t(`请填写手机号码`)
  396. });
  397. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account))
  398. return that.$util.Tips({
  399. title: that.$t(`请输入正确的手机号码`)
  400. });
  401. this.$refs.verify.show();
  402. },
  403. async getLogoImage() {
  404. let that = this;
  405. getLogo(2).then((res) => {
  406. that.logoUrl = res.data.logo_url;
  407. });
  408. },
  409. async loginMobile() {
  410. let that = this;
  411. if (!that.protocol) {
  412. this.inAnimation = true;
  413. return that.$util.Tips({
  414. title: '请先阅读并同意协议'
  415. });
  416. }
  417. if (!that.account)
  418. return that.$util.Tips({
  419. title: that.$t(`请填写手机号码`)
  420. });
  421. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account))
  422. return that.$util.Tips({
  423. title: that.$t(`请输入正确的手机号码`)
  424. });
  425. if (!that.captcha)
  426. return that.$util.Tips({
  427. title: that.$t(`请填写验证码`)
  428. });
  429. if (!/^[\w\d]+$/i.test(that.captcha))
  430. return that.$util.Tips({
  431. title: that.$t(`请输入正确的验证码`)
  432. });
  433. if (that.appLoginStatus) {
  434. that.wxLoginApi();
  435. } else if (that.appleLoginStatus) {
  436. that.appleLoginApi();
  437. } else {
  438. if (this.keyLock) {
  439. this.keyLock = !this.keyLock;
  440. } else {
  441. return that.$util.Tips({
  442. title: that.$t(`请勿重复点击`)
  443. });
  444. }
  445. loginMobile({
  446. phone: that.account,
  447. captcha: that.captcha,
  448. spread: that.$Cache.get('spread')
  449. })
  450. .then((res) => {
  451. let data = res.data;
  452. that.$store.commit('LOGIN', {
  453. token: data.token,
  454. time: data.expires_time - this.$Cache.time()
  455. });
  456. let backUrl = that.$Cache.get(BACK_URL) || '/pages/index/index';
  457. that.$Cache.clear(BACK_URL);
  458. getUserInfo().then((res) => {
  459. this.keyLock = true;
  460. that.$store.commit('SETUID', res.data.uid);
  461. if (backUrl.indexOf('/pages/users/login/index') !== -1) {
  462. backUrl = '/pages/index/index';
  463. }
  464. uni.reLaunch({
  465. url: backUrl
  466. });
  467. });
  468. })
  469. .catch((res) => {
  470. this.keyLock = true;
  471. that.$util.Tips({
  472. title: res
  473. });
  474. });
  475. }
  476. },
  477. async register() {
  478. let that = this;
  479. if (!that.protocol) {
  480. this.inAnimation = true;
  481. return that.$util.Tips({
  482. title: '请先阅读并同意协议'
  483. });
  484. }
  485. if (!that.account)
  486. return that.$util.Tips({
  487. title: that.$t(`请填写手机号码`)
  488. });
  489. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account))
  490. return that.$util.Tips({
  491. title: that.$t(`请输入正确的手机号码`)
  492. });
  493. if (!that.captcha)
  494. return that.$util.Tips({
  495. title: that.$t(`请填写验证码`)
  496. });
  497. if (!/^[\w\d]+$/i.test(that.captcha))
  498. return that.$util.Tips({
  499. title: that.$t(`请输入正确的验证码`)
  500. });
  501. if (!that.password)
  502. return that.$util.Tips({
  503. title: that.$t(`请填写密码`)
  504. });
  505. if (/^([0-9]|[a-z]|[A-Z]){0,6}$/i.test(that.password))
  506. return that.$util.Tips({
  507. title: that.$t(`您输入的密码过于简单`)
  508. });
  509. register({
  510. account: that.account,
  511. captcha: that.captcha,
  512. password: that.password,
  513. spread: that.$Cache.get('spread')
  514. })
  515. .then((res) => {
  516. that.$util.Tips({
  517. title: res
  518. });
  519. that.formItem = 1;
  520. })
  521. .catch((res) => {
  522. that.$util.Tips({
  523. title: res
  524. });
  525. });
  526. },
  527. async getCode(data) {
  528. let that = this;
  529. if (!that.protocol) {
  530. this.inAnimation = true;
  531. return that.$util.Tips({
  532. title: '请先阅读并同意协议'
  533. });
  534. }
  535. if (!that.account)
  536. return that.$util.Tips({
  537. title: that.$t(`请填写手机号码`)
  538. });
  539. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account))
  540. return that.$util.Tips({
  541. title: that.$t(`请输入正确的手机号码`)
  542. });
  543. if (that.formItem == 2) that.type = 'register';
  544. await registerVerify({
  545. phone: that.account,
  546. type: that.type,
  547. key: that.keyCode,
  548. captchaType: this.captchaType,
  549. captchaVerification: data.captchaVerification
  550. })
  551. .then((res) => {
  552. this.sendCode();
  553. that.$util.Tips({
  554. title: res.msg
  555. });
  556. })
  557. .catch((res) => {
  558. that.$util.Tips({
  559. title: res
  560. });
  561. });
  562. },
  563. navTap: function (index) {
  564. this.current = index;
  565. },
  566. async submit() {
  567. let that = this;
  568. if (!that.protocol) {
  569. this.inAnimation = true;
  570. return that.$util.Tips({
  571. title: '请先阅读并同意协议'
  572. });
  573. }
  574. if (!that.account)
  575. return that.$util.Tips({
  576. title: that.$t(`请填写账号`)
  577. });
  578. if (!/^[\w\d]{5,16}$/i.test(that.account))
  579. return that.$util.Tips({
  580. title: that.$t(`请输入正确的账号`)
  581. });
  582. if (!that.password)
  583. return that.$util.Tips({
  584. title: that.$t(`请填写密码`)
  585. });
  586. if (this.keyLock) {
  587. this.keyLock = !this.keyLock;
  588. } else {
  589. return that.$util.Tips({
  590. title: that.$t(`请勿重复点击`)
  591. });
  592. }
  593. loginH5({
  594. account: that.account,
  595. password: that.password,
  596. spread: that.$Cache.get('spread')
  597. })
  598. .then(({ data }) => {
  599. that.$store.commit('LOGIN', {
  600. token: data.token,
  601. time: data.expires_time - this.$Cache.time()
  602. });
  603. let backUrl = that.$Cache.get(BACK_URL) || '/pages/index/index';
  604. that.$Cache.clear(BACK_URL);
  605. getUserInfo()
  606. .then((res) => {
  607. this.keyLock = true;
  608. that.$store.commit('SETUID', res.data.uid);
  609. uni.reLaunch({
  610. url: backUrl
  611. });
  612. })
  613. .catch((error) => {
  614. this.keyLock = true;
  615. });
  616. })
  617. .catch((e) => {
  618. this.keyLock = true;
  619. that.$util.Tips({
  620. title: e
  621. });
  622. });
  623. }
  624. }
  625. };
  626. </script>
  627. <style>
  628. page {
  629. background: #fff;
  630. }
  631. </style>
  632. <style lang="scss">
  633. .appLogin {
  634. margin-top: 60rpx;
  635. .hds {
  636. display: flex;
  637. justify-content: center;
  638. align-items: center;
  639. font-size: 24rpx;
  640. color: #b4b4b4;
  641. .line {
  642. width: 68rpx;
  643. height: 1rpx;
  644. background: #cccccc;
  645. }
  646. p {
  647. margin: 0 20rpx;
  648. }
  649. }
  650. .btn-wrapper {
  651. display: flex;
  652. align-items: center;
  653. justify-content: center;
  654. margin-top: 30rpx;
  655. .btn {
  656. display: flex;
  657. align-items: center;
  658. justify-content: center;
  659. width: 68rpx;
  660. height: 68rpx;
  661. border-radius: 50%;
  662. }
  663. .apple-btn {
  664. display: flex;
  665. align-items: center;
  666. justify-content: center;
  667. width: 68rpx;
  668. height: 68rpx;
  669. border-radius: 50%;
  670. background: #000;
  671. .icon-s-pingguo {
  672. color: #fff;
  673. font-size: 44rpx;
  674. }
  675. }
  676. .iconfont {
  677. font-size: 40rpx;
  678. color: #fff;
  679. }
  680. .wx {
  681. margin-right: 30rpx;
  682. background-color: #61c64f;
  683. }
  684. .mima {
  685. margin-right: 30rpx;
  686. background-color: #28b3e9;
  687. }
  688. .yanzheng {
  689. margin-right: 30rpx;
  690. background-color: #f89c23;
  691. }
  692. }
  693. }
  694. .code img {
  695. width: 100%;
  696. height: 100%;
  697. }
  698. .acea-row.row-middle {
  699. input {
  700. margin-left: 20rpx;
  701. display: block;
  702. }
  703. }
  704. .login-wrapper {
  705. padding: 30rpx;
  706. .shading {
  707. display: flex;
  708. align-items: center;
  709. justify-content: center;
  710. width: 100%;
  711. /* #ifdef APP-VUE */
  712. margin-top: 50rpx;
  713. /* #endif */
  714. /* #ifndef APP-VUE */
  715. margin-top: 200rpx;
  716. /* #endif */
  717. image {
  718. width: 240rpx;
  719. height: 240rpx;
  720. }
  721. }
  722. .whiteBg {
  723. margin-top: 100rpx;
  724. .list {
  725. border-radius: 16rpx;
  726. overflow: hidden;
  727. .item {
  728. border-bottom: 1px solid #f0f0f0;
  729. background: #fff;
  730. .row-middle {
  731. position: relative;
  732. padding: 16rpx 45rpx;
  733. input {
  734. flex: 1;
  735. font-size: 28rpx;
  736. height: 80rpx;
  737. }
  738. .code {
  739. position: absolute;
  740. right: 30rpx;
  741. top: 50%;
  742. color: var(--view-theme);
  743. font-size: 26rpx;
  744. transform: translateY(-50%);
  745. }
  746. }
  747. }
  748. }
  749. .logon {
  750. display: flex;
  751. align-items: center;
  752. justify-content: center;
  753. width: 100%;
  754. height: 86rpx;
  755. margin-top: 80rpx;
  756. background-color: var(--view-theme);
  757. border-radius: 120rpx;
  758. color: #ffffff;
  759. font-size: 30rpx;
  760. }
  761. .tips {
  762. margin: 30rpx;
  763. text-align: center;
  764. color: #999;
  765. }
  766. }
  767. }
  768. .protocol {
  769. margin-top: 40rpx;
  770. color: #999999;
  771. font-size: 24rpx;
  772. text-align: center;
  773. bottom: 20rpx;
  774. }
  775. /* #ifdef H5 */
  776. @media (min-aspect-ratio: 13/20) {
  777. .bottom {
  778. display: none !important;
  779. }
  780. }
  781. /* #endif */
  782. .bottom {
  783. position: fixed;
  784. bottom: 30rpx;
  785. left: 0;
  786. display: flex;
  787. width: 100%;
  788. justify-content: center;
  789. color: #999999;
  790. .ver {
  791. font-size: 20rpx;
  792. }
  793. .ver-msg {
  794. margin-left: 10rpx;
  795. }
  796. a {
  797. color: #999999;
  798. margin-left: 10rpx;
  799. text-decoration: none;
  800. }
  801. }
  802. .trembling {
  803. animation: shake 0.6s;
  804. }
  805. .main-color {
  806. color: var(--view-theme);
  807. }
  808. </style>