merchant.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. <template>
  2. <view class="login-box">
  3. <view class="login-title">商家登录</view>
  4. <view class="logo">
  5. <image src="@/static/index/merchant.png" mode="aspectFit"></image>
  6. </view>
  7. <view class="desc">
  8. <image src="@/static/index/desc-merchant.png"></image>
  9. </view>
  10. <view class="form">
  11. <view class="form_item">
  12. <image class="img1" src="@/static/login/phone.png"></image>
  13. <input class="inp1" placeholder-class="pl" type="text" v-model="phone" placeholder="请输入用户名"
  14. @input="onInput" />
  15. </view>
  16. <view class="form_item">
  17. <image class="img1" src="@/static/login/password.png"></image>
  18. <input class="inp1" password="true" placeholder-class="pl" type="text" v-model="password" placeholder="请输入密码" />
  19. </view>
  20. <view class="form_item">
  21. <image class="img1" src="@/static/login/password.png"></image>
  22. <input class="inp1" \placeholder-class="pl" type="text" v-model="code" placeholder="请输入验证码" />
  23. <image class="img2" :src="codeUrl" @click="getCode"></image>
  24. </view>
  25. </view>
  26. <view style="padding-top: 76rpx;">
  27. <button class="btn" @click="userLogin()">登录</button>
  28. <button class="btn" @click="goBack">返回</button>
  29. </view>
  30. <!-- #ifdef MP-WEIXIN -->
  31. <!-- <view class="other-login" @click="getUserProfile()">
  32. <view class="ol-tilte">
  33. <text>快捷登录</text>
  34. </view>
  35. <div class="wx-login">
  36. <image src="@/static/login/weixin_icon.png" mode="aspectFit" />
  37. </div>
  38. </view> -->
  39. <!-- #endif -->
  40. <image class="bottom_img" src="@/static/login/bottom_img.png" mode="widthFix" />
  41. <view class="popup-box" v-show="showPopup">
  42. <view class="login-popup">
  43. <view class="lp-top">
  44. <view class="lpt-left">
  45. <view class="title"> <text>登录</text> </view>
  46. <view class="tips"> <text>登录即可解锁更多权益</text> </view>
  47. </view>
  48. <view class="lpt-right" @click="showPopup=false">
  49. <image src="@/static/login/close_icon.png" mode="aspectFill"></image>
  50. </view>
  51. </view>
  52. <view class="lp-center">
  53. <view class="title">申请获取以下权限</view>
  54. <view class="tips">获得你的公开信息(昵称、头像等)</view>
  55. <view class="tips">获得你的手机号码</view>
  56. </view>
  57. <view class="lp-bottom">
  58. <!-- getUserInfo -->
  59. <button class="option-btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
  60. 获取手机号
  61. </button>
  62. </view>
  63. </view>
  64. </view>
  65. </view>
  66. </template>
  67. <script>
  68. import {
  69. mapState,
  70. mapMutations
  71. } from 'vuex';
  72. import appConfig from "@/config/appConfig.js";
  73. export default {
  74. data() {
  75. return {
  76. phone: 'admin',
  77. password: '',
  78. code: '',
  79. uuid: '',
  80. appConfig,
  81. showLoding: true, // 初始化加载时显示遮挡页
  82. wxUserInfo: null, // 保存微信用户数据(临时)
  83. wxLoginInfo: {
  84. code: null,
  85. openid: null,
  86. session_key: null
  87. }, // 微信登录返回信息(临时)
  88. showPopup: false, // 获取电话弹窗
  89. codeUrl: ''
  90. }
  91. },
  92. onLoad() {
  93. this.initLogin();
  94. this.getCode()
  95. },
  96. onBackPress() {
  97. // console.log(e)
  98. // 这里可以自定义返回逻辑,比如下面跳转其他页面
  99. uni.navigateTo({
  100. url: '/pages/login/index'
  101. });
  102. // return true 表示禁止默认返回
  103. return true
  104. },
  105. computed: {
  106. ...mapState(['token'])
  107. },
  108. methods: {
  109. ...mapMutations(['saveUserInfo', 'sessionToken']),
  110. getCode() {
  111. this.request("get", "captchaImage").then(res => {
  112. this.codeUrl = "data:image/gif;base64," + res.data.img;
  113. this.uuid = res.data.uuid
  114. });
  115. },
  116. userLogin() {
  117. if (this.phone === '') {
  118. uni.showToast({
  119. title: '请输入正确的手机号',
  120. icon: 'none'
  121. })
  122. return false;
  123. }
  124. if (this.password == '') {
  125. uni.showToast({
  126. title: '请输入密码',
  127. icon: 'none'
  128. })
  129. return false;
  130. }
  131. let params = {
  132. username: this.phone,
  133. password: this.password,
  134. ip: '',
  135. code: this.code,
  136. uuid: this.uuid
  137. }
  138. let that = this
  139. that.request("post", "login", null, params).then(res => {
  140. if (res.code === 200) {
  141. // 返回带token, 进入订单页
  142. let duration = 1500; // 延迟跳转页面
  143. that.saveUserInfo(res.data); // 缓存用户基础数据
  144. that.sessionToken(res.data.token); // 缓存token
  145. uni.showToast({
  146. title: '登录成功',
  147. duration
  148. })
  149. that.toTaskPage(duration);
  150. } else {
  151. this.getCode()
  152. }
  153. }, () => this.getCode())
  154. },
  155. /* 判断是否已登录 */
  156. async initLogin() {
  157. try {
  158. let that = this
  159. if (that.token) {
  160. let newUserData = await that.getUserInfo();
  161. if (newUserData) {
  162. that.saveUserInfo(newUserData); // 缓存用户基础数据
  163. that.toTaskPage();
  164. } else {
  165. that.showLoding = false;
  166. }
  167. } else {
  168. that.showLoding = false;
  169. }
  170. } catch (e) {
  171. console.log(e)
  172. }
  173. },
  174. onInput(e) {
  175. this.phone = e.target.value;
  176. },
  177. /* 前往任务列表页 */
  178. toTaskPage(duration = 100) {
  179. // debugger
  180. setTimeout(() => {
  181. uni.navigateTo({
  182. url: '/pages/task/task1'
  183. })
  184. }, duration)
  185. },
  186. goBack() {
  187. uni.navigateTo({
  188. url: '/pages/login/index'
  189. })
  190. },
  191. /* 获取后台用户信息(进入即判断是否过期) */
  192. getUserInfo() {
  193. let that = this;
  194. return new Promise((resolve, reject) => {
  195. that.request("get", "getInfo", that.token, null).then(res => {
  196. if (res.code === 200) {
  197. resolve(res.data)
  198. } else {
  199. reject(res.msg)
  200. }
  201. })
  202. })
  203. },
  204. /* 获取微信用户信息(登录使用) */
  205. getUserProfile() {
  206. // #ifdef MP-WEIXIN
  207. let that = this;
  208. if (that.wxLoginInfo.openid) {
  209. // 已登录,但未获取手机号
  210. that.showPopup = true;
  211. } else if (uni.getUserProfile) {
  212. // 未登录,且版本支持 uni.getUserProfile
  213. uni.getUserProfile({
  214. lang: 'zh_CN',
  215. desc: "获取您的昵称、头像、手机号",
  216. success: async (res) => {
  217. console.log('用户同意了授权', res)
  218. that.wxUserInfo = res.userInfo; // 临时保存微信用户基础数据
  219. that.wxUserInfo['phone'] = '';
  220. that.mpWeixinTologin(); // 微信一键登录
  221. },
  222. fail: (err) => {
  223. console.log('授权失败:', err)
  224. uni.showToast({
  225. title: err
  226. })
  227. }
  228. })
  229. } else {
  230. uni.showToast({
  231. title: '当前版本过低'
  232. })
  233. }
  234. // #endif
  235. // #ifdef H5
  236. this.tempH5Login()
  237. // #endif
  238. },
  239. tempH5Login() {
  240. let data = {
  241. "accessToken": "29478626990E478DA9539866489DD87D",
  242. "avatarUrl": "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83epib9DbQJ7VsbLFhWMgiarZSibmRPXWb2tHOtzicnbzpj7Z8lIoBy6icUn0vESMicnMnv8lbGjxYKwSnspw/132",
  243. "deliveryEnd": "23:00",
  244. "deliveryStart": "8:30",
  245. "gmtCreate": 1666885726000,
  246. "gmtLastLogin": 1667054521000,
  247. "gmtUpdate": 1666885726000,
  248. "id": 151,
  249. "lastLoginIp": "27.10.60.71",
  250. "loginType": 1,
  251. "name": "L",
  252. "openId": "o7LCC5YUDftbpo907smJhvgsMnBs",
  253. "phone": "18522563339",
  254. "sessionKey": "yjKdFE0CMSLBKNmrXmFyyQ==",
  255. "state": 1,
  256. "storageId": 11,
  257. "workState": 1
  258. }
  259. let token = '29478626990E478DA9539866489DD87D';
  260. this.saveUserInfo(data); // 缓存用户基础数据
  261. this.sessionToken(token); // 缓存token
  262. this.toTaskPage(100);
  263. },
  264. /* 微信登录 */
  265. mpWeixinTologin() {
  266. let that = this;
  267. uni.login({
  268. provider: 'weixin',
  269. async success(res) {
  270. console.log('微信一键登录', res);
  271. if (res.errMsg == 'login:ok') {
  272. that.wxLoginInfo.code = res.code;
  273. that.serverLogin(1);
  274. }
  275. },
  276. fail(err) {
  277. console.log('uni.login', err);
  278. }
  279. });
  280. },
  281. /* 获取手机号 */
  282. getPhoneNumber(e) {
  283. console.log('获取手机号', e);
  284. let that = this;
  285. if (!that.wxLoginInfo.openid || !e.detail.encryptedData) {
  286. return false; // 未登录
  287. }
  288. that.showPopup = false; // 显示获取手机号按钮
  289. let content = {
  290. openid: that.wxLoginInfo.openid,
  291. sessionkey: that.wxLoginInfo.session_key,
  292. encryptedData: e.detail.encryptedData,
  293. iv: e.detail.iv,
  294. }
  295. let params = {
  296. raw: JSON.stringify(content)
  297. };
  298. that.request("get", "rider/wxLogin/decryptS5", null, params).then(resolve => {
  299. //console.log('获取解密手机号', resolve)
  300. if (resolve.code === 200) {
  301. //debugger
  302. let data = JSON.parse(resolve.data);
  303. that.wxUserInfo.phone = data.phoneNumber;
  304. that.serverLogin(2);
  305. } else {
  306. uni.showToast({
  307. title: resolve.msg
  308. })
  309. }
  310. })
  311. },
  312. /* 后台登录 */
  313. serverLogin(type) {
  314. // type: 1-第一次后台登录(返回无token) 2-第一次后台登录(返回带token)
  315. let that = this;
  316. let content = {
  317. code: that.wxLoginInfo.code,
  318. phone: that.wxUserInfo.phone,
  319. nickName: that.wxUserInfo.nickName,
  320. avatar: that.wxUserInfo.avatar,
  321. openid: that.wxLoginInfo.openid,
  322. session_key: that.wxLoginInfo.session_key,
  323. };
  324. that.request("post", "rider/wxLogin/wechatLogin", null, content).then(res => {
  325. console.log('获取数据库返回的用户信息', res);
  326. if (res.code === 200) {
  327. // 至此实际已登录
  328. that.wxLoginInfo.openid = res.data.openId;
  329. that.wxLoginInfo.session_key = res.data.sessionKey;
  330. // 保存数据库返回的用户信息
  331. if (type === 1) {
  332. // 返回无token, 另需获取手机号绑定对应的openid
  333. that.showPopup = true; // 显示获取手机号按钮
  334. } else {
  335. // 返回带token, 进入订单页
  336. let duration = 1500; // 延迟跳转页面
  337. that.saveUserInfo(res.data); // 缓存用户基础数据
  338. that.sessionToken(res.data.accessToken); // 缓存token
  339. uni.showToast({
  340. title: '登录成功',
  341. duration
  342. })
  343. that.toTaskPage(duration);
  344. }
  345. } else {
  346. uni.showToast({
  347. title: res.msg
  348. })
  349. }
  350. })
  351. }
  352. }
  353. }
  354. </script>
  355. <style lang="less" scoped>
  356. .login-box {
  357. position: relative;
  358. width: 100vw;
  359. height: 100vh;
  360. }
  361. .login-title {
  362. text-align: center;
  363. padding-top: 74rpx;
  364. font-size: 36rpx;
  365. color: #333333;
  366. font-weight: bold;
  367. }
  368. .logo {
  369. text-align: center;
  370. padding-top: 72rpx;
  371. image {
  372. width: 172rpx;
  373. height: 172rpx;
  374. }
  375. }
  376. .desc {
  377. text-align: center;
  378. padding-top: 48rpx;
  379. image {
  380. width: 284rpx;
  381. height: 46rpx;
  382. }
  383. }
  384. .form {
  385. width: 618rpx;
  386. margin: 0 auto;
  387. padding-top: 32rpx;
  388. .form_item {
  389. height: 100rpx;
  390. border-bottom: 2rpx solid #EFEFEF;
  391. position: relative;
  392. }
  393. .img1 {
  394. width: 36rpx;
  395. height: 40rpx;
  396. position: absolute;
  397. left: 26rpx;
  398. bottom: 28rpx;
  399. }
  400. .inp1 {
  401. width: 524rpx;
  402. display: inline-block;
  403. position: absolute;
  404. bottom: 0;
  405. height: 98rpx;
  406. left: 96rpx;
  407. /* color: #BBBBBB; */
  408. font-size: 30rpx;
  409. line-height: 98rpx;
  410. }
  411. .pl {
  412. color: #BBBBBB;
  413. font-size: 30rpx;
  414. }
  415. .img2 {
  416. width: 260rpx;
  417. height: 70rpx;
  418. right: 0;
  419. position: absolute;
  420. bottom: 14rpx;
  421. z-index: 10;
  422. }
  423. }
  424. .btn {
  425. width: 640rpx;
  426. height: 96rpx;
  427. line-height: 96rpx;
  428. color: #FFFFFF;
  429. background: linear-gradient(to right, #5095F4, #3662DD);
  430. font-size: 32rpx;
  431. border-radius: 8rpx;
  432. margin: 0 auto;
  433. }
  434. .btn+.btn {
  435. margin-top: 20rpx;
  436. }
  437. .other-login {
  438. position: relative;
  439. z-index: 5;
  440. width: 618rpx;
  441. margin: 80rpx auto 0;
  442. .ol-tilte {
  443. display: flex;
  444. align-items: center;
  445. justify-content: center;
  446. &:before,
  447. &:after {
  448. display: block;
  449. content: '';
  450. width: 30%;
  451. border-bottom: 2rpx solid #EFEFEF;
  452. }
  453. text {
  454. color: #666;
  455. font-size: 26rpx;
  456. padding: 0 20rpx;
  457. }
  458. }
  459. .wx-login {
  460. width: 88rpx;
  461. height: 88rpx;
  462. margin: 40rpx auto 0;
  463. image {
  464. display: block;
  465. width: 100%;
  466. height: 100%;
  467. }
  468. }
  469. }
  470. .bottom_img {
  471. position: absolute;
  472. left: 0;
  473. bottom: 0;
  474. display: block;
  475. width: 100%;
  476. }
  477. .popup-box {
  478. position: absolute;
  479. top: 0;
  480. left: 0;
  481. width: 100%;
  482. height: 100%;
  483. z-index: 10;
  484. background-color: rgba(0, 0, 0, .5);
  485. }
  486. .login-popup {
  487. position: absolute;
  488. left: 0;
  489. bottom: 0;
  490. width: 100%;
  491. z-index: 10;
  492. background-color: #fff;
  493. padding-bottom: 40rpx;
  494. .lp-top {
  495. display: flex;
  496. align-items: center;
  497. color: #000;
  498. line-height: 1.2;
  499. .lpt-left {
  500. flex: 1;
  501. padding: 30rpx;
  502. .title {
  503. font-size: 28rpx;
  504. font-weight: 500;
  505. }
  506. .tips {
  507. color: #9a9b9b;
  508. font-size: 18rpx;
  509. margin-top: 10rpx;
  510. }
  511. }
  512. .lpt-right {
  513. padding: 30rpx;
  514. image {
  515. display: block;
  516. width: 28rpx;
  517. height: 28rpx;
  518. }
  519. }
  520. }
  521. .lp-center {
  522. position: relative;
  523. padding: 10rpx 30rpx 40rpx;
  524. color: #000;
  525. &:after {
  526. position: absolute;
  527. bottom: 0;
  528. left: 30rpx;
  529. right: 30rpx;
  530. content: '';
  531. border-bottom: 1rpx solid #ededed;
  532. }
  533. .title {
  534. font-size: 28rpx;
  535. font-weight: 600;
  536. }
  537. .tips {
  538. font-size: 26rpx;
  539. margin-top: 10rpx;
  540. }
  541. }
  542. .lp-bottom {
  543. padding: 0 30rpx;
  544. margin-top: 40rpx;
  545. .option-btn {
  546. height: 86rpx;
  547. color: #fff;
  548. font-size: 22rpx;
  549. text-align: center;
  550. line-height: 86rpx;
  551. padding: 0 30rpx;
  552. background: linear-gradient(to right, #5095F4, #3662DD);
  553. }
  554. }
  555. }
  556. </style>