多租户商城-商户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

718 lines
19 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="login" :style="'background-image:url(' + Background + ');'">
  3. <!-- 登录 -->
  4. <div v-if="getPassword" class="loginBox">
  5. <div class="rightBox">
  6. <el-row><img src="../../assets/images/login_logo.png" class=" loginBox-logo"/></el-row>
  7. <div class="topText">商家登录</div>
  8. <div class="tabTouch">
  9. <div class="tabTouch"
  10. v-for="(item, index) in activeList"
  11. :key="index"
  12. ><div :class="[tabIndex != index ? 'touchOne' : 'touchTwo']"
  13. @click="touchTab(index)"><span class="span-label">{{ item.name }}</span> </div>
  14. <div class="touch-space"></div>
  15. </div>
  16. </div>
  17. <!-- 账户密码登录 -->
  18. <div v-if="!tabIndex">
  19. <el-form
  20. ref="loginForm"
  21. :model="loginForm"
  22. :rules="loginRules"
  23. label-position="left"
  24. label-width="0px"
  25. class="login-form"
  26. >
  27. <el-form-item prop="username">
  28. <el-input
  29. v-model="loginForm.username"
  30. type="text"
  31. maxlength="11"
  32. auto-complete="off"
  33. placeholder="请输入账户"
  34. class="iptHeight username"
  35. >
  36. <i slot="prefix" class="el-input__icon icon-usericon"></i>
  37. </el-input>
  38. </el-form-item>
  39. <el-form-item prop="password">
  40. <el-input
  41. v-model="loginForm.password"
  42. maxlength="16"
  43. type="password"
  44. class="iptHeight"
  45. auto-complete="off"
  46. placeholder="请输入密码"
  47. @keyup.enter.native="handleAccountLogin"
  48. >
  49. <i slot="prefix" class="el-input__icon icon-password"></i>
  50. </el-input>
  51. </el-form-item>
  52. <div class="boxBottom">
  53. <el-checkbox v-model="loginForm.rememberMe" style="margin: 0 0 25px 0; font-size: 14px;">自动登录</el-checkbox>
  54. <div class="forgetPsd" @click="runForgetPassord">忘记密码</div>
  55. </div>
  56. <el-form-item style="width: 100%">
  57. <el-button
  58. :loading="loading"
  59. size="medium"
  60. type="primary"
  61. class="btn-login"
  62. @click.native.prevent="handleAccountLogin"
  63. >
  64. <span v-if="!loading"> </span>
  65. <span v-else> 中...</span>
  66. </el-button>
  67. </el-form-item>
  68. </el-form>
  69. </div>
  70. <!-- 手机号登录 -->
  71. <div v-else>
  72. <el-form
  73. ref="anthorForm"
  74. :model="anthorForm"
  75. :rules="anthorRules"
  76. label-position="left"
  77. label-width="0px"
  78. class="login-form"
  79. >
  80. <el-form-item prop="username">
  81. <el-input
  82. v-model="anthorForm.username"
  83. type="text"
  84. maxlength="11"
  85. auto-complete="off"
  86. placeholder="请输入手机号码"
  87. class="iptHeight"
  88. >
  89. <i slot="prefix" class="el-input__icon icon-phone"></i>
  90. </el-input>
  91. </el-form-item>
  92. <el-form-item prop="code">
  93. <el-input
  94. v-model="anthorForm.code"
  95. maxlength="6"
  96. type="text"
  97. class="iptHeight"
  98. auto-complete="off"
  99. style="width: 63%"
  100. placeholder="请输入验证码"
  101. @keyup.enter.native="handlePhoneLogin"
  102. >
  103. <i slot="prefix" class="el-input__icon icon-code"></i>
  104. </el-input>
  105. <div class="login-code">
  106. <el-button
  107. class="codeBtn"
  108. type="primary"
  109. :loading="codeloading"
  110. @click="getCode(anthorForm.username)"
  111. >
  112. <span v-if="!codeloading">获取验证码</span>
  113. <span v-else>{{ count }} s</span>
  114. </el-button>
  115. </div>
  116. </el-form-item>
  117. <div class="boxBottom">
  118. <el-checkbox v-model="loginForm.rememberMe" style="margin: 0 0 25px 0">自动登录</el-checkbox>
  119. </div>
  120. <el-form-item style="width: 100%">
  121. <el-button
  122. :loading="loading"
  123. size="medium"
  124. type="primary"
  125. class="btn-login"
  126. @click.native.prevent="handlePhoneLogin"
  127. >
  128. <span v-if="!loading"> </span>
  129. <span v-else> 中...</span>
  130. </el-button>
  131. </el-form-item>
  132. </el-form>
  133. </div>
  134. </div>
  135. </div>
  136. <!-- 找回密码 -->
  137. <div v-else class="loginBox">
  138. <div class="box-card">
  139. <div slot="header" class="clearfix">
  140. <span>找回密码</span>
  141. <el-button
  142. style="float: right; padding: 0px 0"
  143. type="text"
  144. @click="getPassword=true"
  145. >返回登录</el-button>
  146. <div class="cardBox">
  147. <el-form
  148. ref="retrievePwd"
  149. :model="retrievePwdForm"
  150. :rules="retrievePwdRules"
  151. label-position="left"
  152. label-width="0px"
  153. class="login-form"
  154. >
  155. <el-form-item prop="username">
  156. <el-input
  157. v-model="retrievePwdForm.username"
  158. type="text"
  159. maxlength="11"
  160. auto-complete="off"
  161. placeholder="请输入手机号码"
  162. class="iptHeight"
  163. >
  164. <i slot="prefix" class="el-input__icon icon-phone"></i>
  165. </el-input>
  166. </el-form-item>
  167. <el-form-item prop="code">
  168. <el-input
  169. v-model="retrievePwdForm.code"
  170. maxlength="6"
  171. type="text"
  172. class="iptHeight"
  173. auto-complete="off"
  174. style="width: 63%"
  175. placeholder="请输入验证码"
  176. @keyup.enter.native="forgetPwdFn"
  177. >
  178. <i slot="prefix" class="el-input__icon icon-code"></i>
  179. </el-input>
  180. <div class="login-code">
  181. <el-button
  182. class="codeBtn"
  183. type="primary"
  184. :loading="codeloading"
  185. @click="getCode(retrievePwdForm.username)"
  186. >
  187. <span v-if="!codeloading">获取验证码</span>
  188. <span v-else>{{ count }} s</span>
  189. </el-button>
  190. </div>
  191. </el-form-item>
  192. <el-form-item prop="newPassword">
  193. <el-input
  194. v-model="retrievePwdForm.newPassword"
  195. type="password"
  196. maxlength="11"
  197. auto-complete="off"
  198. placeholder="新密码"
  199. class="iptHeight"
  200. >
  201. <i slot="prefix" class="el-input__icon icon-password"></i>
  202. </el-input>
  203. </el-form-item>
  204. <el-form-item prop="password">
  205. <el-input
  206. v-model="retrievePwdForm.password"
  207. type="password"
  208. maxlength="11"
  209. auto-complete="off"
  210. placeholder="确认密码"
  211. class="iptHeight"
  212. >
  213. <i slot="prefix" class="el-input__icon icon-password"></i>
  214. </el-input>
  215. </el-form-item>
  216. <el-form-item style="width: 100%">
  217. <el-button
  218. :loading="loading"
  219. size="medium"
  220. type="primary"
  221. class="btn-login"
  222. @click.native.prevent="forgetPwdFn"
  223. >
  224. <span v-if="!loading"> </span>
  225. <span v-else> 中...</span>
  226. </el-button>
  227. </el-form-item>
  228. </el-form>
  229. </div>
  230. </div>
  231. </div>
  232. </div>
  233. <!-- 底部 -->
  234. <div class="login-footer">© 2019 Thee</div>
  235. </div>
  236. </template>
  237. <script>
  238. // import { validUsername } from '@/utils/validate'
  239. import { adminBuild, forgetPassword } from '@/api/user'
  240. import {
  241. getUserId
  242. } from '@/utils/auth' // get token from cookie
  243. const TIME_COUNT = 60 // 更改倒计时时间
  244. import Background from '@/assets/images/login_bg.png'
  245. import { getCode } from '@/api/account'
  246. const JM = require('@/utils/rsaEncrypt.js')
  247. export default {
  248. name: 'Login',
  249. data() {
  250. // const validateUsername = (rule, value, callback) => {
  251. // if (!validUsername(value)) {
  252. // callback(new Error('Please enter the correct user name'))
  253. // } else {
  254. // callback()
  255. // }
  256. // }
  257. // const validatePassword = (rule, value, callback) => {
  258. // if (value.length < 6) {
  259. // callback(new Error('The password can not be less than 6 digits'))
  260. // } else {
  261. // callback()
  262. // }
  263. // }
  264. return {
  265. Background: Background,
  266. cookiePass: '',
  267. loginForm: {
  268. username: '',
  269. password: '',
  270. rememberMe: false
  271. },
  272. anthorForm: {
  273. username: '',
  274. code: '',
  275. rememberMe: false
  276. },
  277. retrievePwdForm: {
  278. code: '',
  279. newPassword: '',
  280. password: '',
  281. username: '' // 手机号
  282. },
  283. tabIndex: 0,
  284. activeList: [
  285. {
  286. name: '账户密码',
  287. id: 0
  288. },
  289. {
  290. name: '手机号码',
  291. id: 1
  292. }
  293. ],
  294. retrievePwdRules: {
  295. username: [
  296. { required: true, trigger: 'blur', message: '手机号码不能为空' }
  297. ],
  298. code: [
  299. { required: true, trigger: 'blur', message: '验证码不能为空' }
  300. ],
  301. newPassword: [
  302. { required: true, trigger: 'blur', message: '密码不能为空' }
  303. ],
  304. password: [
  305. { required: true, trigger: 'blur', message: '确认密码不能为空' }
  306. ]
  307. },
  308. loginRules: {
  309. username: [
  310. { required: true, trigger: 'blur', message: '用户名不能为空' }
  311. ],
  312. password: [{ required: true, trigger: 'blur', message: '密码不能为空' }]
  313. },
  314. anthorRules: {
  315. username: [
  316. { required: true, trigger: 'blur', message: '手机号不能为空' }
  317. ],
  318. code: [{ required: true, trigger: 'blur', message: '验证码不能为空' }]
  319. },
  320. loading: false,
  321. codeloading: false,
  322. count: '',
  323. timer: null,
  324. redirect: undefined,
  325. getPassword: true
  326. }
  327. },
  328. watch: {
  329. $route: {
  330. handler: function(route) {
  331. this.redirect = route.query && route.query.redirect
  332. },
  333. immediate: true
  334. }
  335. },
  336. methods: {
  337. // 点击tab
  338. touchTab(index) {
  339. console.log(index)
  340. this.tabIndex = index
  341. },
  342. // 获取验证码
  343. async getCode(phone) {
  344. console.log(phone)
  345. if (phone === '' || phone === undefined) {
  346. this.$message.error('请填写电话号码')
  347. return
  348. }
  349. const res = await getCode({ phone })
  350. if (res.code === '') {
  351. this.$message({
  352. message: '发送成功,请注意查看手机短信',
  353. type: 'success'
  354. })
  355. if (!this.timer) {
  356. this.codeloading = true
  357. this.count = TIME_COUNT
  358. this.timer = setInterval(() => {
  359. if (this.count > 1 && this.count <= TIME_COUNT) {
  360. this.count--
  361. } else {
  362. clearInterval(this.timer) // 清除定时器
  363. this.timer = null
  364. this.codeloading = false
  365. }
  366. }, 1000)
  367. }
  368. }
  369. // if (!this.timer) {
  370. // this.codeloading = true
  371. // this.count = TIME_COUNT
  372. // this.show = false
  373. // const res = await getCode({ phone })
  374. // if (res.code === '') {
  375. // this.$message({
  376. // message: '发送成功,请注意查看手机短信',
  377. // type: 'success'
  378. // })
  379. // }
  380. // this.timer = setInterval(() => {
  381. // if (this.count > 0 && this.count <= TIME_COUNT) {
  382. // this.count--
  383. // } else {
  384. // this.show = true
  385. // clearInterval(this.timer) // 清除定时器
  386. // this.timer = null
  387. // this.codeloading = false
  388. // }
  389. // }, 1000)
  390. // }
  391. },
  392. // 忘记密码
  393. runForgetPassord() {
  394. this.getPassword = false
  395. },
  396. showPwd() {
  397. if (this.passwordType === 'password') {
  398. this.passwordType = ''
  399. } else {
  400. this.passwordType = 'password'
  401. }
  402. this.$nextTick(() => {
  403. this.$refs.password.focus()
  404. })
  405. },
  406. // 账户登录
  407. handleAccountLogin() {
  408. this.$refs.loginForm.validate(valid => {
  409. if (valid) {
  410. this.loading = true
  411. const data = {
  412. username: JM.encrypt(this.loginForm.username),
  413. password: JM.encrypt(this.loginForm.password),
  414. rememberMe: this.loginForm.rememberMe
  415. }
  416. this.$store
  417. .dispatch('user/login', data)
  418. .then(() => {
  419. console.log(this.redirect)
  420. this.$router.push({ path: this.redirect || '/' })
  421. this.loading = false
  422. adminBuild({ platformUserId: getUserId() }).then(res => {
  423. console.log(res)
  424. })
  425. })
  426. .catch(() => {
  427. this.loading = false
  428. })
  429. } else {
  430. console.log('error submit!!')
  431. return false
  432. }
  433. })
  434. },
  435. // 手机号码
  436. handlePhoneLogin() {
  437. console.log(this.anthorForm)
  438. this.$refs.anthorForm.validate(valid => {
  439. if (valid) {
  440. this.loading = true
  441. const data = {
  442. username: JM.encrypt(this.anthorForm.username),
  443. code: JM.encrypt(this.anthorForm.code),
  444. rememberMe: this.anthorForm.rememberMe
  445. }
  446. this.$store
  447. .dispatch('user/login', data)
  448. .then(() => {
  449. this.$router.push({ path: this.redirect || '/' })
  450. this.loading = false
  451. adminBuild({ platformUserId: getUserId() }).then(res => {
  452. console.log(res)
  453. })
  454. })
  455. .catch(() => {
  456. this.loading = false
  457. })
  458. } else {
  459. console.log('error submit!!')
  460. return false
  461. }
  462. })
  463. },
  464. // 找回密码
  465. forgetPwdFn() {
  466. console.log(this.retrievePwdForm)
  467. this.$refs.retrievePwd.validate(valid => {
  468. if (valid) {
  469. this.loading = true
  470. const data = {
  471. username: JM.encrypt(this.retrievePwdForm.username),
  472. code: JM.encrypt(this.retrievePwdForm.code),
  473. password: JM.encrypt(this.retrievePwdForm.password),
  474. newPassword: JM.encrypt(this.retrievePwdForm.newPassword)
  475. }
  476. forgetPassword(data).then(res => {
  477. if (res.code === '') {
  478. this.loading = false
  479. this.$message({
  480. message: '修改成功',
  481. type: 'success'
  482. })
  483. this.getPassword = true
  484. }
  485. }).catch(() => {
  486. this.loading = false
  487. })
  488. } else {
  489. console.log('error submit!!')
  490. return false
  491. }
  492. })
  493. }
  494. }
  495. }
  496. </script>
  497. <style rel="stylesheet/scss" lang="scss">
  498. .topText {
  499. font-size: 23px;
  500. font-family: Microsoft YaHei;
  501. font-weight: 400;
  502. color: #183ECD;
  503. line-height: 43px;
  504. }
  505. .icon-usericon{
  506. background-image:url(../../assets/images/login_account.png) ;
  507. background-size:cover;
  508. width: 18px;
  509. height: 18px;
  510. background-size: cover;
  511. margin-left: 4px;
  512. }
  513. .icon-password{
  514. background-image:url(../../assets/images/login_password.png);
  515. background-size:cover;
  516. width: 18px;
  517. height: 18px;
  518. background-size: cover;
  519. margin-left: 4px;
  520. }
  521. .icon-phone{
  522. background-image:url(../../assets/images/login_phone.png) ;
  523. background-size:cover;
  524. width: 18px;
  525. height: 18px;
  526. background-size: cover;
  527. margin-left: 4px;
  528. }
  529. .icon-code{
  530. background-image:url(../../assets/images/login_code.png) ;
  531. background-size:cover;
  532. width: 18px;
  533. height: 18px;
  534. background-size: cover;
  535. margin-left: 4px;
  536. }
  537. .login {
  538. display: flex;
  539. justify-content: center;
  540. align-items: center;
  541. height: 100%;
  542. background-size: cover;
  543. }
  544. .loginBox {
  545. width: 840px !important;
  546. height: 538px;
  547. display: flex;
  548. background-image:url(../../assets/images/login_center_bg.png) ;
  549. background-size:cover;
  550. }
  551. .loginBox-logo{
  552. width: 34px;
  553. height: 34px;
  554. }
  555. .leftBox {
  556. width: 50px;
  557. height: 250px;
  558. margin: 180px 0 0 30px;
  559. background-size: cover;
  560. }
  561. .rightBox {
  562. margin-left: 85px;
  563. margin-top: 68px;
  564. width: 300px;
  565. h2 {
  566. text-align: center;
  567. }
  568. }
  569. .tabTouch {
  570. display: flex;
  571. flex-direction: row;
  572. // justify-content: space-around;
  573. // align-content: center;
  574. // width: 360px;
  575. // margin-left: 8px;
  576. }
  577. .touchOne {
  578. width: 60px;
  579. height: 43px;
  580. display: flex;
  581. justify-content: center;
  582. align-items: center;
  583. .span-label{
  584. width: 60px;
  585. text-align: center;
  586. vertical-align: middle;
  587. font-size: 12px;
  588. font-family: Source Han Sans CN;
  589. font-weight: 400;
  590. color: #666666;
  591. }
  592. }
  593. .touchTwo {
  594. width: 60px;
  595. height: 43px;
  596. border-bottom: 1px solid #183ECD;
  597. display: flex;
  598. justify-content: center;
  599. align-items: center;
  600. .span-label{
  601. width: 60px;
  602. text-align: center;
  603. vertical-align: middle;
  604. font-size: 12px;
  605. font-family: Source Han Sans CN;
  606. font-weight: 400;
  607. color: #183ECD;
  608. }
  609. }
  610. .touch-space{
  611. width:24px;
  612. height:1px;
  613. }
  614. .boxBottom {
  615. display: flex;
  616. justify-content: space-between;
  617. .forgetPsd {
  618. font-size: 14px;
  619. color: #1890ff;
  620. cursor: pointer;
  621. font-family: Source Han Sans CN;
  622. font-weight: 400;
  623. color: #183ECD;
  624. line-height: 17px;
  625. }
  626. }
  627. .title {
  628. margin: 0 auto 30px auto;
  629. text-align: center;
  630. color: #707070;
  631. }
  632. .login-form {
  633. padding-top: 25px;
  634. padding-bottom: 25px;
  635. .el-input {
  636. height: 38px;
  637. input {
  638. height: 38px;
  639. }
  640. }
  641. .input-icon {
  642. height: 39px;
  643. width: 14px;
  644. margin-left: 2px;
  645. }
  646. }
  647. .iptHeight {
  648. border-radius: 3px;
  649. height: 40px !important;
  650. background: #F9F9F9;
  651. input {
  652. height: 40px !important;
  653. background: #F9F9F9;
  654. font-size: 14px;
  655. }
  656. span {
  657. display: flex;
  658. align-items: center;
  659. }
  660. .input-icon {
  661. width: 24px;
  662. height: 24px;
  663. }
  664. }
  665. .login-tip {
  666. font-size: 13px;
  667. text-align: center;
  668. color: #bfbfbf;
  669. }
  670. .login-code {
  671. float: right;
  672. .codeBtn {
  673. height: 40px;
  674. display: flex;
  675. justify-content: center;
  676. align-items: center;
  677. width: 100px;
  678. background: #eeeeee;
  679. color: #666666;
  680. border: none;
  681. }
  682. img {
  683. vertical-align: middle;
  684. }
  685. }
  686. .box-card {
  687. width: 100%;
  688. height: 100%;
  689. .clearfix {
  690. margin-left: 85px;
  691. margin-top: 68px;
  692. width: 300px;
  693. }
  694. }
  695. .login-footer {
  696. position: fixed;
  697. bottom: 0;
  698. width: 100%;
  699. text-align: center;
  700. display: none;
  701. }
  702. .btn-login{
  703. width: 100%;
  704. border-radius: 3px;
  705. background-image: linear-gradient(to right, #183ecd,#4184ed);
  706. }
  707. </style>