index.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. <template>
  2. <view v-if="isUp" :data-theme="theme">
  3. <view class="mobile-bg" v-if="isShow" @click="close"></view>
  4. <view class="mobile-mask" :class="[{animated:isPos}]"
  5. :style="{position:isPos?'fixed':'static'}">
  6. <view class="input-item">
  7. <view class="item">
  8. <input class="ipt" type="number" v-model="account" placeholder-class='placeholder'
  9. placeholder="输入手机号" maxlength="11" />
  10. </view>
  11. </view>
  12. <view class="input-item">
  13. <view class="item acea-row row-between-wrapper">
  14. <input class="ipt codeIput" type="number" v-model="codeNum" placeholder-class='placeholder'
  15. placeholder="输入验证码" maxlength="6" />
  16. <view class="line">
  17. </view>
  18. <button class="code font-num" :disabled="disabled" @click="code">{{text}}</button>
  19. </view>
  20. </view>
  21. <view class="sub_btn" @click="loginBtn">
  22. {{(!userInfo.phone && isLogin) || (userInfo.phone && isLogin)?'立即绑定':'立即登录'}}
  23. </view>
  24. </view>
  25. <Verify @success="handlerOnVerSuccess" :captchaType="'clickWord'"
  26. :imgSize="{ width: '330px', height: '155px' }" ref="verify"></Verify>
  27. </view>
  28. </template>
  29. <script>
  30. // +----------------------------------------------------------------------
  31. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  32. // +----------------------------------------------------------------------
  33. // | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
  34. // +----------------------------------------------------------------------
  35. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  36. // +----------------------------------------------------------------------
  37. // | Author: CRMEB Team <admin@crmeb.com>
  38. // +----------------------------------------------------------------------
  39. const app = getApp();
  40. import Verify from '../verifition/verify.vue';
  41. import sendVerifyCode from "@/mixins/SendVerifyCode";
  42. import Routine from '@/libs/routine';
  43. import {
  44. mapGetters
  45. } from "vuex";
  46. import {
  47. registerVerify,
  48. getCodeApi
  49. } from "@/api/user";
  50. import {
  51. getUserPhone,
  52. iosBinding
  53. } from '@/api/public';
  54. import {
  55. Debounce
  56. } from '@/utils/validate.js'
  57. import {silenceBindingSpread} from "../../../../utils";
  58. const BACK_URL = "login_back_url";
  59. export default {
  60. name: 'login_mobile',
  61. computed: mapGetters(['userInfo', 'isLogin', 'globalData']),
  62. props: {
  63. isUp: {
  64. type: Boolean,
  65. default: false,
  66. },
  67. authKey: {
  68. type: String,
  69. default: '',
  70. },
  71. isShow: {
  72. type: Boolean,
  73. default: true
  74. },
  75. // 是否定位
  76. isPos: {
  77. type: Boolean,
  78. default: true
  79. },
  80. appleShow: {
  81. type: String,
  82. default: ''
  83. },
  84. platform: {
  85. type: String,
  86. default: '',
  87. },
  88. //小程序code值
  89. wxCode: {
  90. type: String,
  91. default: '',
  92. },
  93. // 小程序绑定手机号,isPhone其他手机号绑定
  94. loginConfig: {
  95. type: String,
  96. default: '',
  97. },
  98. },
  99. data() {
  100. return {
  101. theme: app.globalData.theme,
  102. keyCode: '',
  103. account: '',
  104. codeNum: '',
  105. isApp: 0
  106. }
  107. },
  108. mixins: [sendVerifyCode],
  109. components: {
  110. Verify
  111. },
  112. methods: {
  113. //滑块验证成功后
  114. handlerOnVerSuccess(data) {
  115. this.$refs.verify.hide();
  116. this.codeSend(data);
  117. },
  118. codeSend() {
  119. registerVerify(this.account).then(res => {
  120. this.$util.Tips({
  121. title: res.msg
  122. });
  123. this.sendCode();
  124. }).catch(err => {
  125. return this.$util.Tips({
  126. title: err
  127. })
  128. })
  129. },
  130. // 获取验证码
  131. code: Debounce(function() {
  132. let that = this;
  133. if (!that.account) return that.$util.Tips({
  134. title: '请填写手机号码'
  135. });
  136. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
  137. title: '请输入正确的手机号码'
  138. });
  139. that.$refs.verify.show();
  140. }),
  141. // 获取验证码api
  142. getCode() {
  143. let that = this
  144. getCodeApi().then(res => {
  145. that.keyCode = res.data.key;
  146. }).catch(res => {
  147. that.$util.Tips({
  148. title: res
  149. });
  150. });
  151. },
  152. close() {
  153. this.$emit('close', false)
  154. },
  155. // 登录
  156. loginBtn() {
  157. let that = this
  158. if (!that.account) return that.$util.Tips({
  159. title: '请填写手机号码'
  160. });
  161. if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
  162. title: '请输入正确的手机号码'
  163. });
  164. if (!that.codeNum) return that.$util.Tips({
  165. title: '请填写验证码'
  166. });
  167. if (!/^[\w\d]+$/i.test(that.codeNum)) return that.$util.Tips({
  168. title: '请输入正确的验证码'
  169. });
  170. uni.showLoading({
  171. title: !this.userInfo.phone && this.isLogin ? '正在绑定中' : '正在登录中'
  172. });
  173. if (!this.userInfo.phone && this.isLogin) {
  174. iosBinding({
  175. captcha: that.codeNum,
  176. phone: that.account
  177. }).then(res => {
  178. that.isApp = 1;
  179. that.onSuccess();
  180. }).catch(error => {
  181. uni.hideLoading()
  182. that.$util.Tips({
  183. title: error
  184. })
  185. })
  186. } else {
  187. getUserPhone({
  188. captcha: that.codeNum,
  189. phone: that.account,
  190. // #ifdef H5
  191. type: 'wechat',
  192. // #endif
  193. // #ifdef MP
  194. type: 'routine',
  195. code: this.wxCode,
  196. // #endif
  197. // #ifdef APP-PLUS
  198. type: that.platform === 'ios' ? 'iosWx' : 'androidWx',
  199. // #endif
  200. key: that.authKey
  201. }).then(res => {
  202. that.$store.commit('LOGIN', {
  203. token: res.data.token
  204. });
  205. that.$store.commit("SETUID", res.data.id);
  206. that.onSuccess();
  207. if (res.data.isNew && res.data.newPeopleCouponList && res.data.newPeopleCouponList.length !== 0) {
  208. this.$Cache.set('newGift', res.data.newPeopleCouponList);
  209. } else {
  210. this.$Cache.clear('newGift');
  211. }
  212. }).catch(error => {
  213. uni.hideLoading()
  214. that.$util.Tips({
  215. title: error
  216. })
  217. })
  218. }
  219. },
  220. /**
  221. * 登录成功后的方法
  222. */
  223. onSuccess() {
  224. uni.hideLoading();
  225. this.$store.dispatch("GetTokenIsExist");
  226. //分销绑定
  227. silenceBindingSpread(true,this.globalData.spread);
  228. // #ifdef MP
  229. if(!this.$Cache.get('wechatQRcode')) Routine.getQrcode()
  230. // #endif
  231. let backUrl = this.$Cache.get(BACK_URL) || "/pages/index/index";
  232. // #ifdef MP
  233. this.$util.Tips({
  234. title: '绑定手机号成功'
  235. }, {
  236. tab: 4,
  237. url: backUrl
  238. });
  239. this.close()
  240. // #endif
  241. // #ifdef H5
  242. this.$emit('wechatPhone', true)
  243. // #endif
  244. // #ifdef APP-PLUS
  245. if (this.isApp == 0) {
  246. let backUrl = this.$Cache.get(BACK_URL) || "/pages/index/index";
  247. if (backUrl.indexOf('/pages/users/login/index') !== -1) {
  248. backUrl = '/pages/index/index';
  249. }
  250. uni.reLaunch({
  251. url: backUrl
  252. });
  253. }
  254. // #endif
  255. },
  256. }
  257. }
  258. </script>
  259. <style lang="scss" scoped>
  260. .mobile-bg {
  261. position: fixed;
  262. left: 0;
  263. top: 0;
  264. width: 100%;
  265. height: 100%;
  266. background: rgba(0, 0, 0, 0.5);
  267. }
  268. .isPos {
  269. position: static;
  270. }
  271. .mobile-mask {
  272. z-index: 20;
  273. // position: fixed;
  274. left: 0;
  275. bottom: 0;
  276. width: 100%;
  277. padding: 67rpx 72rpx;
  278. background: #fff;
  279. .input-item {
  280. display: flex;
  281. justify-content: space-between;
  282. width: 606rpx;
  283. height: 88rpx;
  284. margin-bottom: 38rpx;
  285. .codeIput {
  286. width: 300rpx !important;
  287. }
  288. .ipt {
  289. width: 100%;
  290. height: 100%;
  291. font-size: 32rpx;
  292. }
  293. .item {
  294. width: 100%;
  295. background: #F5F5F5;
  296. flex: 1;
  297. height: 100%;
  298. padding: 0 32rpx 0 48rpx;
  299. border-radius: 45rpx;
  300. font-size: 28rpx;
  301. font-family: PingFang SC-Regular, PingFang SC;
  302. font-weight: 400;
  303. color: #333333;
  304. line-height: 40px;
  305. .placeholder {
  306. color: #BBBBBB;
  307. font-size: 28rpx;
  308. }
  309. }
  310. .line {
  311. width: 2rpx;
  312. height: 28rpx;
  313. background: #CCCCCC;
  314. }
  315. .code {
  316. background: none;
  317. font-size: 28rpx;
  318. @include main_color(theme);
  319. border-radius: 43rpx;
  320. &[disabled] {
  321. color: #999;
  322. }
  323. }
  324. }
  325. .sub_btn {
  326. width: 100%;
  327. height: 86rpx;
  328. line-height: 86rpx;
  329. margin-top: 60rpx;
  330. @include main_bg_color(theme);
  331. border-radius: 43rpx;
  332. color: #fff;
  333. font-size: 28rpx;
  334. text-align: center;
  335. }
  336. }
  337. .animated {
  338. animation-duration: .4s
  339. }
  340. </style>