login.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <template>
  2. <view class="container">
  3. <view style="height: 140rpx;"></view>
  4. <view class="title">
  5. <text class="title--text">欢迎使用源享住</text>
  6. </view>
  7. <view v-if="quickLogin" class="quick-login">
  8. <!-- #ifdef MP-WEIXIN -->
  9. <u-button text="本机号码一键登录" :openType="openType" @getphonenumber="getPhoneNumber" @click="checkAgree"
  10. shape="circle" color="#de9db7"></u-button>
  11. <!-- #endif -->
  12. <!-- #ifdef MP-ALIPAY -->
  13. <button class="quick-login--alipay" :openType="openTypeAlipay" :scope="scopeAlipay" @click="checkAgree"
  14. @getAuthorize="getPhoneNumberAlipay" @error="handleAuthError">本机号码一键登录</button>
  15. <!-- #endif -->
  16. </view>
  17. <view v-else class="phone-login">
  18. <view class="phone-login--tel">
  19. <u-input prefixIcon="account" placeholder="请输入手机号" shape="circle" v-model="phone" clearable
  20. type="number" maxlength="11" placeholderStyle="color: #FFFFFF" color="#FFFFFF"
  21. prefixIconStyle="color: #FFFFFF"></u-input>
  22. </view>
  23. <view class="phone-login--code">
  24. <u-input prefixIcon="lock" placeholder="请输入验证码" shape="circle" v-model="verificationCode" type="number"
  25. maxlength="4" placeholderStyle="color: #FFFFFF" color="#FFFFFF" prefixIconStyle="color: #FFFFFF">
  26. <template slot="suffix">
  27. <u-code ref="uCode" @change="codeChange" seconds="60" startText="点击发送"></u-code>
  28. <u-button class="verification-btn" @click="getVerificationCode" color="#de9db7" shape="circle"
  29. size="mini" :text="tips"></u-button>
  30. </template>
  31. </u-input>
  32. </view>
  33. <view class="phone-login--btn">
  34. <u-button @click="phoneLogin" text="登录" shape="circle" color="#de9db7"></u-button>
  35. </view>
  36. </view>
  37. <view class="other-phone">
  38. <u-text :text="changeLoginTypeText" size="24rpx" color="#FFFFFF;" align="center"
  39. @click="quickLogin=!quickLogin"></u-text>
  40. </view>
  41. <view class="agree">
  42. <checkbox-group @change="checkboxChange">
  43. <label>
  44. <!-- #ifdef MP-WEIXIN -->
  45. <checkbox style="transform:scale(0.75)" color="#9e97c3" />
  46. <!-- #endif -->
  47. <!-- #ifdef MP-ALIPAY -->
  48. <checkbox style="transform:scale(0.75)" color="#FFFFFF" />
  49. <!-- #endif -->
  50. <text>请阅读并同意源享住</text>
  51. <text @click.stop="gotoProtocol">《用户协议》</text>
  52. <text>和</text>
  53. <text @click.stop="gotoProtocol">《隐私条款》</text>
  54. </label>
  55. </checkbox-group>
  56. </view>
  57. <view class="version">
  58. <u-text :text="version" align="right"></u-text>
  59. </view>
  60. </view>
  61. </template>
  62. <script>
  63. import {
  64. numberNotZero,
  65. stringHasText,
  66. jsonParamIsTrue,
  67. } from '../../utils/commonUtils.js'
  68. import {
  69. IMG_BASE_URL
  70. } from '../../config.js'
  71. import {
  72. mapMutations,
  73. mapState
  74. } from 'vuex'
  75. export default {
  76. data() {
  77. return {
  78. iconSrc: IMG_BASE_URL + '/icon.png',
  79. phone: '',
  80. tips: '',
  81. verificationCode: '',
  82. agree: false,
  83. hotelId: null,
  84. version: '',
  85. quickLogin: true,
  86. }
  87. },
  88. computed: {
  89. ...mapState('m_user', ['token', 'userInfo', 'lastLoginPhone']),
  90. ...mapState('m_business', ['currentHotel']),
  91. openType() {
  92. return this.agree ? 'getPhoneNumber' : ''
  93. },
  94. // #ifdef MP-ALIPAY
  95. openTypeAlipay() {
  96. return this.agree ? 'getAuthorize' : ''
  97. },
  98. scopeAlipay() {
  99. return this.agree ? 'phoneNumber' : ''
  100. },
  101. // #endif
  102. changeLoginTypeText() {
  103. return this.quickLogin ? '使用其他手机号登录' : '手机号快速登录'
  104. }
  105. },
  106. methods: {
  107. ...mapMutations('m_user', ['updateUserInfo', 'updateToken', 'updateLastLoginPhone']),
  108. ...mapMutations('m_business', ['updateCurrentHotel']),
  109. checkboxChange() {
  110. this.agree = !this.agree
  111. },
  112. gotoLogin() {
  113. uni.navigateTo({
  114. url: '/pages/login/login'
  115. })
  116. },
  117. gotoProtocol() {
  118. uni.navigateTo({
  119. url: '/subpkg/protocol/protocol'
  120. })
  121. },
  122. checkAgree() {
  123. if (!this.agree) {
  124. uni.showModal({
  125. content: "请同意相关条款,勾选后代表您同意《用户协议》、《隐私条款》",
  126. confirmText: "我知道了",
  127. showCancel: false
  128. })
  129. }
  130. },
  131. async getPhoneNumber(e) {
  132. // console.log("获取手机号", e);
  133. if (e.detail.errMsg === 'getPhoneNumber:ok') {
  134. let res = await uni.$http.post('/userInfo/login', {
  135. code: e.detail.code,
  136. platform: "WECHAT"
  137. })
  138. if (res.data.code === 200 && res.data.success === true) {
  139. await this.afterLoginSuccess(res)
  140. }
  141. //登录失败
  142. else {
  143. uni.$showMsg(res.data.msg)
  144. }
  145. } else if (e.detail.errMsg === 'getPhoneNumber:fail user deny') {
  146. }
  147. console.log(e)
  148. },
  149. // #ifdef MP-ALIPAY
  150. async getPhoneNumberAlipay(e) {
  151. // console.log("getPhoneNumberAlipay", e);
  152. let cipherText = await my.getPhoneNumber({
  153. protocols: {
  154. isvAppId: "2021004141650063"
  155. }
  156. })
  157. // console.log("cipherText", cipherText);
  158. let res = await uni.$http.post('/userInfo/login', {
  159. code: cipherText.response,
  160. platform: "ALIPAY"
  161. })
  162. if (res.data.code === 200 && res.data.success === true) {
  163. await this.afterLoginSuccess(res)
  164. }
  165. //登录失败
  166. else {
  167. uni.$showMsg(res.data.msg)
  168. }
  169. },
  170. handleAuthError(e) {
  171. // console.log("handleAuthError", e.detail.errorMessage);
  172. if (e.detail.errorMessage === "用户取消授权") {
  173. uni.showModal({
  174. title: "提示",
  175. content: "本机号码一键登录功能需要授权,取消授权将无法使用一键登录功能",
  176. confirmText: "我知道了",
  177. showCancel: false
  178. })
  179. }
  180. },
  181. // #endif
  182. async phoneLogin() {
  183. if (!this.agree) {
  184. uni.showModal({
  185. content: "请同意相关条款,勾选后代表您同意《用户协议》、《隐私条款》",
  186. confirmText: "我知道了",
  187. showCancel: false
  188. })
  189. return
  190. }
  191. //没有输入验证码
  192. let codeLength = this.verificationCode.length
  193. if (!numberNotZero(codeLength)) {
  194. uni.$showMsg('请输入验证码')
  195. return;
  196. }
  197. if (codeLength < 4) {
  198. uni.$showMsg('验证码格式错误')
  199. return;
  200. }
  201. //输入4位数字验证码
  202. const res = await uni.$http.post(`/login`, {
  203. phone: this.phone,
  204. verificationCode: this.verificationCode,
  205. })
  206. console.log(res)
  207. if (res.data.code === 200 && res.data.success === true) {
  208. await this.afterLoginSuccess(res)
  209. }
  210. },
  211. async afterLoginSuccess(res) {
  212. let userInfo = res.data.data.userInfo
  213. //是否跳过人证比对
  214. let params = JSON.parse(res.data.data.params)
  215. console.log(params)
  216. if (params && jsonParamIsTrue(params.skipIdMatching)) {
  217. userInfo.skipIdMatching = true
  218. } else {
  219. userInfo.skipIdMatching = false
  220. }
  221. //是否调用人脸动态检测
  222. if (params && jsonParamIsTrue(params.staticFaceCheck)) {
  223. userInfo.staticFaceCheck = true
  224. } else {
  225. userInfo.staticFaceCheck = false
  226. }
  227. //是否可以选择酒店
  228. if (params && jsonParamIsTrue(params.selectHotel)) {
  229. userInfo.selectHotel = true
  230. } else {
  231. userInfo.selectHotel = false
  232. }
  233. //是否为测试账号
  234. if (params && jsonParamIsTrue(params.isDebug)) {
  235. userInfo.isDebug = true
  236. } else {
  237. userInfo.isDebug = false
  238. }
  239. //保存用户信息至local storage
  240. this.updateUserInfo(res.data.data.userInfo)
  241. //保存token
  242. this.updateToken(res.data.data.tokenValue)
  243. //上次登录的手机号
  244. this.updateLastLoginPhone(this.phone)
  245. //设置酒店信息
  246. if (this.hotelId) {
  247. await this.setHotelInfoById(this.hotelId)
  248. }
  249. //当前用户没设置身份证号则跳转
  250. if (this.currentHotel && this.currentHotel != {}) {
  251. uni.switchTab({
  252. url: '/pages/home/home'
  253. })
  254. } else {
  255. uni.reLaunch({
  256. url: '/subpkg/chooseHotel/chooseHotel?source=home'
  257. })
  258. }
  259. },
  260. async getVerificationCode() {
  261. var pattern = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
  262. if (!pattern.test(this.phone)) {
  263. uni.$showMsg("手机号格式错误! ")
  264. return;
  265. }
  266. if (this.$refs.uCode.canGetCode) {
  267. this.$refs.uCode.start()
  268. const res = await uni.$http.get(`/verificationCode/${this.phone}`)
  269. if (res.statusCode == 200 && res.data.data === true) {
  270. // uni.$showMsg("验证码发送成功!")
  271. } else {
  272. uni.$showMsg('验证码发送失败!')
  273. }
  274. } else {
  275. uni.$showMsg('请倒计时结束后再发送!')
  276. }
  277. },
  278. codeChange(e) {
  279. if (e.length > 4 && e != '获取验证码')
  280. e = e.substring(0, e.length - 5) + 's'
  281. this.tips = e;
  282. },
  283. async setHotelInfoById(hotelId) {
  284. let res = await uni.$http.post('/hotel', {
  285. hotelId: hotelId,
  286. pageNo: 1,
  287. pageSize: 2
  288. })
  289. let hotelList = res.data.data.records
  290. if (hotelList.length === 1) {
  291. this.updateCurrentHotel(hotelList[0])
  292. } else {
  293. this.updateCurrentHotel({})
  294. }
  295. },
  296. },
  297. async onLoad(query) {
  298. // #ifdef MP-WEIXIN
  299. //二维码扫描时传入hotelId
  300. if (query.q !== null && query.q !== undefined) {
  301. let url = decodeURIComponent(query.q)
  302. let hotelId = url.split('=')[1]
  303. if (stringHasText(hotelId)) {
  304. try {
  305. this.hotelId = Number(hotelId)
  306. } catch (err) {
  307. this.hotelId = null
  308. }
  309. }
  310. //未登录则在登录后查询hotelId是否存在对应酒店
  311. //已登录则直接查询
  312. if (this.token) {
  313. await this.setHotelInfoById(this.hotelId)
  314. }
  315. } else {
  316. this.hotelId = null
  317. }
  318. //设置版本号,只有正式版本可以获取到
  319. const accountInfo = wx.getAccountInfoSync();
  320. this.version = accountInfo.miniProgram.version
  321. // #endif
  322. // #ifdef MP-ALIPAY
  323. this.hotelId = uni.getStorageSync('hotelIdTemp')
  324. if (stringHasText(this.hotelId)) {
  325. if (stringHasText(this.token)) {
  326. this.hotelId = Number(this.hotelId)
  327. await this.setHotelInfoById(this.hotelId)
  328. }
  329. }
  330. // #endif
  331. this.phone = this.lastLoginPhone
  332. if (stringHasText(this.token)) {
  333. uni.switchTab({
  334. url: '/pages/home/home'
  335. })
  336. }
  337. },
  338. // #ifdef MP-WEIXIN
  339. onShareAppMessage(info) {
  340. return {
  341. title: '源享住',
  342. path: 'pages/quickLogin/quickLogin',
  343. imageUrl: "/static/logo.png"
  344. }
  345. },
  346. onShareTimeline(info) {}
  347. // #endif
  348. }
  349. </script>
  350. <style>
  351. .u-input__content__field-wrapper__field {
  352. background-color: transparent;
  353. }
  354. </style>
  355. <style lang="scss" scoped>
  356. page {
  357. .container {
  358. width: 100vw;
  359. height: 100vh;
  360. background-image: url("../../static/login.jpg");
  361. background-size: cover;
  362. background-repeat: no-repeat;
  363. .title {
  364. height: 160rpx;
  365. display: flex;
  366. justify-content: center;
  367. padding-top: 300rpx;
  368. .title--text {
  369. font-size: 40rpx;
  370. color: #FFFFFF;
  371. letter-spacing: 6rpx;
  372. }
  373. }
  374. .quick-login {
  375. margin: 0 100rpx;
  376. padding-top: 40rpx;
  377. padding-bottom: 20rpx;
  378. .quick-login--alipay {
  379. border-top-left-radius: 200rpx;
  380. border-bottom-left-radius: 200rpx;
  381. border-top-right-radius: 200rpx;
  382. border-bottom-right-radius: 200rpx;
  383. background-color: #de9db7;
  384. color: #FFFFFF;
  385. border: 0;
  386. padding: 0;
  387. }
  388. }
  389. .phone-login {
  390. .phone-login--tel {
  391. margin: 0 100rpx 50rpx 100rpx;
  392. }
  393. .phone-login--code {
  394. margin: 0 100rpx 50rpx 100rpx;
  395. }
  396. .phone-login--btn {
  397. margin: 0 100rpx 50rpx 100rpx;
  398. }
  399. }
  400. .other-phone {
  401. width: 100%;
  402. display: flex;
  403. align-items: center;
  404. justify-content: center;
  405. }
  406. .agree {
  407. margin: 20rpx 60rpx;
  408. color: #FFFFFF;
  409. display: flex;
  410. flex-direction: row;
  411. align-items: center;
  412. position: fixed;
  413. bottom: 100rpx;
  414. checkbox-group {
  415. label {
  416. font-size: 26rpx;
  417. display: flex;
  418. flex-direction: row;
  419. align-items: center;
  420. }
  421. }
  422. }
  423. .version {
  424. position: fixed;
  425. bottom: 0;
  426. right: 20rpx;
  427. }
  428. }
  429. }
  430. </style>