register.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. <template>
  2. <view class="login-wrapper" :style="colorStyle">
  3. <view class="shading">
  4. <image :src="logoUrl" />
  5. </view>
  6. <view class="whiteBg">
  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(`填写邀请码`)" class="codeIput" v-model="spread" />
  37. </view>
  38. </view>
  39. <view class="item">
  40. <view class="acea-row row-middle">
  41. <image src="../static/code_2.png" style="width: 28rpx; height: 32rpx;"></image>
  42. <input type="text" :placeholder="$t(`填写验证码`)" :maxlength="6" class="codeIput"
  43. v-model="captcha" />
  44. <button class="code" :disabled="disabled" :class="disabled === true ? 'on' : ''" @click="code">
  45. {{ text }}
  46. </button>
  47. </view>
  48. </view>
  49. <view class="item" v-if="isShowCode">
  50. <view class="acea-row row-middle">
  51. <image src="../static/code_2.png" style="width: 28rpx; height: 32rpx;"></image>
  52. <input type="text" :placeholder="$t(`填写验证码`)" class="codeIput" v-model="codeVal" />
  53. <view class="code" @click="again"><img :src="codeUrl" /></view>
  54. </view>
  55. </view>
  56. </view>
  57. <view class="logon" @click="loginMobile" v-if="current !== 0">{{$t(`注册`)}}</view>
  58. <view class="logon" @click="submit" v-if="current === 0">{{$t(`登录`)}}</view>
  59. <view class="tips">
  60. <!-- <view v-if="current==0" @click="current = 1">{{$t(`快速登录`)}}</view> -->
  61. <!-- <view v-if="current==1" @click="current = 0">{{$t(`账号登录`)}}</view> -->
  62. </view>
  63. <!-- TODO -->
  64. <view class="choose">
  65. <!-- <view class="reg" @click="forget">忘记密码</view>
  66. <view class="xian">|</view> -->
  67. <view class="zhuce" @click="zhuce">账号登录</view>
  68. </view>
  69. <view class="protocol">
  70. <checkbox-group @change='ChangeIsDefault'>
  71. <checkbox :class="inAnimation?'trembling':''" @animationend='inAnimation=false'
  72. :checked="protocol ? true : false" />{{$t(`已阅读并同意`)}} <text class="main-color"
  73. @click="privacy(4)">{{$t(`《用户协议》`)}}</text>
  74. {{$t(`与`)}}<text class="main-color" @click="privacy(3)">{{$t(`《隐私协议》`)}}</text>
  75. </checkbox-group>
  76. </view>
  77. </view>
  78. <!-- <view class="bottom">
  79. <view class="ver" v-if="copyRight">{{copyRight}}</view>
  80. <view v-else class="ver">© 2014-2023
  81. <a href="https://www.crmeb.com">www.crmeb.com</a>
  82. </view>
  83. </view> -->
  84. <Verify @success="success" :captchaType="captchaType" :imgSize="{ width: '330px', height: '155px' }"
  85. ref="verify"></Verify>
  86. </view>
  87. </template>
  88. <script>
  89. import dayjs from "@/plugin/dayjs/dayjs.min.js";
  90. import sendVerifyCode from "@/mixins/SendVerifyCode";
  91. import {
  92. loginH5,
  93. loginMobile,
  94. registerVerify,
  95. register,
  96. getCodeApi,
  97. getUserInfo,
  98. appleLogin
  99. } from "@/api/user";
  100. import attrs, {
  101. required,
  102. alpha_num,
  103. chs_phone
  104. } from "@/utils/validate";
  105. import {
  106. getLogo
  107. } from "@/api/public";
  108. // import cookie from "@/utils/store/cookie";
  109. import {
  110. VUE_APP_API_URL
  111. } from "@/utils";
  112. // #ifdef APP-PLUS
  113. import {
  114. wechatAppAuth
  115. } from '@/api/api.js'
  116. // #endif
  117. const BACK_URL = "login_back_url";
  118. import colors from '@/mixins/color.js';
  119. import Verify from '../components/verify/index.vue';
  120. export default {
  121. name: "Login",
  122. components: {
  123. Verify
  124. },
  125. mixins: [sendVerifyCode, colors],
  126. data: function() {
  127. return {
  128. copyRight: '',
  129. inAnimation: false,
  130. protocol: false,
  131. current: 1,
  132. spread: '',
  133. account: "",
  134. password: "",
  135. captcha: "",
  136. formItem: 2,
  137. type: "login",
  138. logoUrl: "",
  139. keyCode: "",
  140. codeUrl: "",
  141. codeVal: "",
  142. isShowCode: false,
  143. appLoginStatus: false, // 微信登录强制绑定手机号码状态
  144. appUserInfo: null, // 微信登录保存的用户信息
  145. appleLoginStatus: false, // 苹果登录强制绑定手机号码状态
  146. appleUserInfo: null,
  147. appleShow: false, // 苹果登录版本必须要求ios13以上的
  148. keyLock: true
  149. };
  150. },
  151. watch: {
  152. formItem: function(nval, oVal) {
  153. if (nval == 1) {
  154. this.type = 'login'
  155. } else {
  156. this.type = 'register'
  157. }
  158. }
  159. },
  160. onLoad() {
  161. let self = this
  162. if (uni.getStorageSync('copyRight').copyrightContext) {
  163. this.copyRight = uni.getStorageSync('copyRight').copyrightContext
  164. }
  165. self.spread = self.$Cache.get("spread");
  166. },
  167. mounted: function() {
  168. this.getLogoImage();
  169. },
  170. methods: {
  171. ChangeIsDefault(e) {
  172. this.$set(this, 'protocol', !this.protocol);
  173. },
  174. privacy(type) {
  175. uni.navigateTo({
  176. url: "/pages/users/privacy/index?type=" + type
  177. })
  178. },
  179. zhuce() {
  180. uni.navigateTo({
  181. url: "/pages/users/login/index"
  182. })
  183. },
  184. again() {
  185. this.codeUrl =
  186. VUE_APP_API_URL +
  187. "/sms_captcha?" +
  188. "key=" +
  189. this.keyCode +
  190. Date.parse(new Date());
  191. },
  192. success(data) {
  193. this.$refs.verify.hide()
  194. getCodeApi()
  195. .then(res => {
  196. // console.log('get', res);
  197. this.keyCode = res.data.key;
  198. this.getCode(data);
  199. })
  200. .catch(res => {
  201. console.log('res','res');
  202. this.$util.Tips({
  203. title: res
  204. });
  205. });
  206. },
  207. code() {
  208. let that = this
  209. if (!that.protocol) {
  210. this.inAnimation = true
  211. return that.$util.Tips({
  212. title: '请先阅读并同意协议'
  213. });
  214. }
  215. if (!that.account) return that.$util.Tips({
  216. title: that.$t(`请填写手机号码`)
  217. });
  218. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
  219. title: that.$t(`请输入正确的手机号码`)
  220. });
  221. this.$refs.verify.show()
  222. },
  223. async getLogoImage() {
  224. let that = this;
  225. getLogo(2).then(res => {
  226. that.logoUrl = res.data.logo_url;
  227. });
  228. },
  229. async loginMobile() {
  230. let that = this;
  231. if (!that.protocol) {
  232. this.inAnimation = true
  233. return that.$util.Tips({
  234. title: '请先阅读并同意协议'
  235. });
  236. }
  237. if (!that.account) return that.$util.Tips({
  238. title: that.$t(`请填写手机号码`)
  239. });
  240. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
  241. title: that.$t(`请输入正确的手机号码`)
  242. });
  243. if (!that.captcha) return that.$util.Tips({
  244. title: that.$t(`请填写验证码`)
  245. });
  246. if (!that.spread) return that.$util.Tips({
  247. title: that.$t(`请填写邀请码/手机号`)
  248. });
  249. if (!/^[\w\d]+$/i.test(that.captcha)) return that.$util.Tips({
  250. title: that.$t(`请输入正确的验证码`)
  251. });
  252. if (this.keyLock) {
  253. this.keyLock = !this.keyLock
  254. } else {
  255. return that.$util.Tips({
  256. title: that.$t(`请勿重复点击`)
  257. });
  258. }
  259. loginMobile({
  260. phone: that.account,
  261. captcha: that.captcha,
  262. spread: that.spread
  263. })
  264. .then(res => {
  265. let data = res.data;
  266. that.$store.commit("LOGIN", {
  267. 'token': data.token,
  268. 'time': data.expires_time - this.$Cache.time()
  269. });
  270. let backUrl = that.$Cache.get(BACK_URL) || "/pages/index/index";
  271. that.$Cache.clear(BACK_URL);
  272. getUserInfo().then(res => {
  273. this.keyLock = true
  274. that.$store.commit("SETUID", res.data.uid);
  275. if (backUrl.indexOf('/pages/users/login/index') !== -1) {
  276. backUrl = '/pages/index/index';
  277. }
  278. uni.reLaunch({
  279. url: backUrl
  280. });
  281. })
  282. })
  283. .catch(res => {
  284. this.keyLock = true
  285. that.$util.Tips({
  286. title: res
  287. });
  288. });
  289. },
  290. async register() {
  291. let that = this;
  292. if (!that.protocol) {
  293. this.inAnimation = true
  294. return that.$util.Tips({
  295. title: '请先阅读并同意协议'
  296. });
  297. }
  298. if (!that.account) return that.$util.Tips({
  299. title: that.$t(`请填写手机号码`)
  300. });
  301. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
  302. title: that.$t(`请输入正确的手机号码`)
  303. });
  304. if (!that.captcha) return that.$util.Tips({
  305. title: that.$t(`请填写验证码`)
  306. });
  307. if (!/^[\w\d]+$/i.test(that.captcha)) return that.$util.Tips({
  308. title: that.$t(`请输入正确的验证码`)
  309. });
  310. if (!that.password) return that.$util.Tips({
  311. title: that.$t(`请填写密码`)
  312. });
  313. if (/^([0-9]|[a-z]|[A-Z]){0,6}$/i.test(that.password)) return that.$util.Tips({
  314. title: that.$t(`您输入的密码过于简单`)
  315. });
  316. register({
  317. account: that.account,
  318. captcha: that.captcha,
  319. password: that.password,
  320. spread: that.$Cache.get("spread")
  321. })
  322. .then(res => {
  323. that.$util.Tips({
  324. title: res
  325. });
  326. that.formItem = 1;
  327. })
  328. .catch(res => {
  329. console.log('错误1', res);
  330. that.$util.Tips({
  331. title: res
  332. });
  333. });
  334. },
  335. async getCode(data) {
  336. let that = this;
  337. if (!that.protocol) {
  338. this.inAnimation = true
  339. return that.$util.Tips({
  340. title: '请先阅读并同意协议'
  341. });
  342. }
  343. if (!that.account) return that.$util.Tips({
  344. title: that.$t(`请填写手机号码`)
  345. });
  346. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
  347. title: that.$t(`请输入正确的手机号码`)
  348. });
  349. if (that.formItem == 2) that.type = "register";
  350. const updata = {
  351. phone: that.account,
  352. type: that.type,
  353. key: that.keyCode,
  354. captchaType: this.captchaType,
  355. captchaVerification: data.captchaVerification
  356. };
  357. // console.log(updata);
  358. await registerVerify(updata)
  359. .then(res => {
  360. this.sendCode()
  361. that.$util.Tips({
  362. title: res.msg
  363. });
  364. })
  365. .catch(res => {
  366. if(res!='参数错误!'){
  367. that.$util.Tips({
  368. title: res
  369. });
  370. }
  371. });
  372. },
  373. navTap: function(index) {
  374. this.current = index;
  375. },
  376. async submit() {
  377. let that = this;
  378. if (!that.protocol) {
  379. this.inAnimation = true
  380. return that.$util.Tips({
  381. title: '请先阅读并同意协议'
  382. });
  383. }
  384. if (!that.account) return that.$util.Tips({
  385. title: that.$t(`请填写账号`)
  386. });
  387. if (!/^[\w\d]{5,16}$/i.test(that.account)) return that.$util.Tips({
  388. title: that.$t(`请输入正确的账号`)
  389. });
  390. if (!that.password) return that.$util.Tips({
  391. title: that.$t(`请填写密码`)
  392. });
  393. if (this.keyLock) {
  394. this.keyLock = !this.keyLock
  395. } else {
  396. return that.$util.Tips({
  397. title: that.$t(`请勿重复点击`)
  398. });
  399. }
  400. loginH5({
  401. account: that.account,
  402. password: that.password,
  403. spread: that.$Cache.get("spread")
  404. })
  405. .then(({
  406. data
  407. }) => {
  408. that.$store.commit("LOGIN", {
  409. 'token': data.token,
  410. 'time': data.expires_time - this.$Cache.time()
  411. });
  412. let backUrl = that.$Cache.get(BACK_URL) || "/pages/index/index";
  413. that.$Cache.clear(BACK_URL);
  414. getUserInfo().then(res => {
  415. this.keyLock = true
  416. that.$store.commit("SETUID", res.data.uid);
  417. uni.reLaunch({
  418. url: backUrl
  419. });
  420. }).catch(error => {
  421. this.keyLock = true
  422. })
  423. })
  424. .catch(e => {
  425. this.keyLock = true
  426. that.$util.Tips({
  427. title: e
  428. });
  429. });
  430. }
  431. }
  432. };
  433. </script>
  434. <style>
  435. page {
  436. background: #fff;
  437. }
  438. </style>
  439. <style lang="scss">
  440. .appLogin {
  441. margin-top: 60rpx;
  442. .hds {
  443. display: flex;
  444. justify-content: center;
  445. align-items: center;
  446. font-size: 24rpx;
  447. color: #B4B4B4;
  448. .line {
  449. width: 68rpx;
  450. height: 1rpx;
  451. background: #CCCCCC;
  452. }
  453. p {
  454. margin: 0 20rpx;
  455. }
  456. }
  457. .btn-wrapper {
  458. display: flex;
  459. align-items: center;
  460. justify-content: center;
  461. margin-top: 30rpx;
  462. .btn {
  463. display: flex;
  464. align-items: center;
  465. justify-content: center;
  466. width: 68rpx;
  467. height: 68rpx;
  468. border-radius: 50%;
  469. }
  470. .apple-btn {
  471. display: flex;
  472. align-items: center;
  473. justify-content: center;
  474. width: 68rpx;
  475. height: 68rpx;
  476. border-radius: 50%;
  477. background: #000;
  478. .icon-s-pingguo {
  479. color: #fff;
  480. font-size: 44rpx;
  481. }
  482. }
  483. .iconfont {
  484. font-size: 40rpx;
  485. color: #fff;
  486. }
  487. .wx {
  488. margin-right: 30rpx;
  489. background-color: #61C64F;
  490. }
  491. .mima {
  492. margin-right: 30rpx;
  493. background-color: #28B3E9;
  494. }
  495. .yanzheng {
  496. margin-right: 30rpx;
  497. background-color: #F89C23;
  498. }
  499. }
  500. }
  501. .code img {
  502. width: 100%;
  503. height: 100%;
  504. }
  505. .acea-row.row-middle {
  506. input {
  507. margin-left: 20rpx;
  508. display: block;
  509. }
  510. }
  511. .login-wrapper {
  512. padding: 30rpx;
  513. .shading {
  514. display: flex;
  515. align-items: center;
  516. justify-content: center;
  517. width: 100%;
  518. /* #ifdef APP-VUE */
  519. margin-top: 50rpx;
  520. /* #endif */
  521. /* #ifndef APP-VUE */
  522. margin-top: 200rpx;
  523. /* #endif */
  524. image {
  525. width: 240rpx;
  526. height: 240rpx;
  527. }
  528. }
  529. .whiteBg {
  530. margin-top: 100rpx;
  531. .list {
  532. border-radius: 16rpx;
  533. overflow: hidden;
  534. .item {
  535. border-bottom: 1px solid #F0F0F0;
  536. background: #fff;
  537. .row-middle {
  538. position: relative;
  539. padding: 16rpx 45rpx;
  540. input {
  541. flex: 1;
  542. font-size: 28rpx;
  543. height: 80rpx;
  544. }
  545. .code {
  546. position: absolute;
  547. right: 30rpx;
  548. top: 50%;
  549. color: var(--view-theme);
  550. font-size: 26rpx;
  551. transform: translateY(-50%);
  552. }
  553. }
  554. }
  555. }
  556. .logon {
  557. display: flex;
  558. align-items: center;
  559. justify-content: center;
  560. width: 100%;
  561. height: 86rpx;
  562. margin-top: 80rpx;
  563. background-color: var(--view-theme);
  564. border-radius: 120rpx;
  565. color: #FFFFFF;
  566. font-size: 30rpx;
  567. }
  568. .tips {
  569. margin: 30rpx;
  570. text-align: center;
  571. color: #999;
  572. }
  573. }
  574. }
  575. .protocol {
  576. margin-top: 40rpx;
  577. color: #999999;
  578. font-size: 24rpx;
  579. text-align: center;
  580. bottom: 20rpx;
  581. }
  582. .bottom {
  583. position: fixed;
  584. bottom: 30rpx;
  585. left: 0;
  586. display: flex;
  587. width: 100%;
  588. justify-content: center;
  589. color: #999999;
  590. .ver {
  591. font-size: 20rpx;
  592. }
  593. .ver-msg {
  594. margin-left: 10rpx;
  595. }
  596. a {
  597. color: #999999;
  598. margin-left: 10rpx;
  599. text-decoration: none;
  600. }
  601. }
  602. .trembling {
  603. animation: shake 0.6s;
  604. }
  605. .main-color {
  606. color: var(--view-theme);
  607. }
  608. .choose {
  609. display: flex;
  610. justify-content: center;
  611. .reg {
  612. font-size: 28rpx;
  613. font-weight: 500;
  614. color: #ff8d3a;
  615. }
  616. .xian {
  617. color: #FF4C4C;
  618. padding-left: 10rpx;
  619. }
  620. .zhuce {
  621. font-size: 28rpx;
  622. font-weight: 500;
  623. color: #FF4C4C;
  624. padding-left: 10rpx;
  625. }
  626. }
  627. </style>