login.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <div>
  3. <form-data :item="config" ref="form" @keyUpEnter="handleLogin">
  4. <template slot="verification">
  5. <img v-if="showVerify" class="imgCode" :src="verificationCodeSrc" title="获取验证码" @click="fetchGetVerificationCode" />
  6. </template>
  7. <template slot="default">
  8. <v-btn
  9. :loading="loading"
  10. color="primary"
  11. style="width: 100%; margin-bottom: 30px;"
  12. @click.native.prevent="handleLogin"
  13. >
  14. 登 录
  15. </v-btn>
  16. </template>
  17. </form-data>
  18. </div>
  19. </template>
  20. <script>
  21. import FormData from '@/components/Form'
  22. // import {
  23. // getSettingInfo
  24. // setBurialPoint
  25. // } from '@/api/system'
  26. import { mapMutations } from 'vuex'
  27. export default {
  28. name: 'login-page',
  29. components: { FormData },
  30. data () {
  31. return {
  32. loading: false,
  33. config: {
  34. options: [
  35. {
  36. label: '登录账号',
  37. type: 'text',
  38. key: 'username',
  39. value: '',
  40. outlined: true,
  41. class: 'mt-5',
  42. autofocus: true,
  43. prependInnerIcon: 'mdi-account',
  44. autocomplete: 'username',
  45. rules: [v => !!v || '请填写登录账号'],
  46. keyupEnterNative: this.handleLogin,
  47. change: this.handleChange
  48. },
  49. {
  50. label: '密码',
  51. type: 'password',
  52. key: 'password',
  53. value: '',
  54. outlined: true,
  55. prependInnerIcon: 'mdi-lock',
  56. rules: [v => !!v || '请填写密码'],
  57. appendIcon: 'mdi-eye-off-outline',
  58. autocomplete: 'current-password',
  59. keyupEnterNative: this.handleLogin,
  60. clickAppend: this.clickAppendPasswordType,
  61. change: this.handleChange
  62. },
  63. {
  64. label: '验证码',
  65. type: 'text',
  66. key: 'verificationCode',
  67. slotName: 'verification',
  68. rules: [v => !!v || '请填写验证码'],
  69. hide: true,
  70. value: '',
  71. outlined: true,
  72. prependInnerIcon: 'mdi-email',
  73. keyupEnterNative: this.handleLogin,
  74. change: this.handleChange
  75. }
  76. ]
  77. },
  78. queryForm: {
  79. username: '',
  80. password: '',
  81. verificationCode: ''
  82. },
  83. passwordType: false,
  84. errorCount: 0,
  85. errorCountTop: 3,
  86. showVerify: false,
  87. verificationCodeSrc: '',
  88. query: '1'
  89. }
  90. },
  91. watch: {
  92. error (val) {
  93. if (val) {
  94. this.open()
  95. }
  96. }
  97. },
  98. methods: {
  99. ...mapMutations('system', ['SET_SYSTEM_INFO']),
  100. open () {
  101. this.config.options.find(e => e.key === 'verificationCode').hide = false
  102. this.fetchGetVerificationCode()
  103. this.showVerify = true
  104. },
  105. handleChange (v) {
  106. Object.assign(this.queryForm, v)
  107. },
  108. async handleLogin () {
  109. if (this.$refs.form.$refs.form.validate()) {
  110. this.loading = true
  111. try {
  112. const query = Object.assign(this.queryForm, {
  113. query: this.query
  114. })
  115. await this.$store.dispatch('user/login', query)
  116. const routes = await this.$store.dispatch('menu/getMenu2')
  117. if (!routes.length) {
  118. this.$snackbar.error('没有访问权限')
  119. return
  120. }
  121. this.$snackbar.success('登录成功')
  122. // const { data } = await getSettingInfo({ path: '', hostName: '' })
  123. // this.SET_SYSTEM_INFO(this.flattenObject(data))
  124. if (this.$route.query?.redirect) {
  125. this.$router.push(this.$route.query.redirect)
  126. return
  127. }
  128. // 登录成功记录访问 + 1
  129. // this.handleBurialPoint()
  130. this.$router.push('/')
  131. } catch (error) {
  132. if (typeof error === 'object' && error?.code) {
  133. this.$snackbar.error(error.msg || error)
  134. this.open()
  135. return
  136. }
  137. // 生成验证码
  138. this.fetchGetVerificationCode()
  139. this.$snackbar.error(error)
  140. } finally {
  141. this.loading = false
  142. }
  143. }
  144. },
  145. // async handleBurialPoint () {
  146. // try {
  147. // await setBurialPoint({ accessRecordIndex: 'home' })
  148. // } catch (error) {
  149. // console.log('访问新增失败')
  150. // }
  151. // },
  152. fetchGetVerificationCode () {
  153. const api = this.$api
  154. const rand = Math.ceil(Math.random() * 10)
  155. this.query = Math.ceil(Math.random() * 1000)
  156. this.verificationCodeSrc = `${api}/authentication/get/verificationCode?type=login&rand=${rand}&query=${this.query}`
  157. },
  158. clickAppendPasswordType () {
  159. this.passwordType = !this.passwordType
  160. if (this.passwordType) {
  161. this.config.options[1].type = 'text'
  162. this.config.options[1].appendIcon = 'mdi-eye-outline'
  163. return
  164. }
  165. this.config.options[1].type = 'password'
  166. this.config.options[1].appendIcon = 'mdi-eye-off-outline'
  167. },
  168. // 获取个性化配置信息
  169. flattenObject (obj) {
  170. let result = {}
  171. for (const key in obj) {
  172. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  173. const value = obj[key]
  174. if (typeof value === 'object' && value !== null) {
  175. result = { ...result, ...this.flattenObject(value, key) }
  176. } else {
  177. result[key] = value || null
  178. }
  179. }
  180. }
  181. return result
  182. }
  183. // async getInfo () {
  184. // try {
  185. // const { data } = await getSettingInfo({ path: '', hostName: '' })
  186. // this.SET_SYSTEM_INFO(this.flattenObject(data))
  187. // } catch (error) {
  188. // this.$snackbar.error(error)
  189. // }
  190. // }
  191. }
  192. }
  193. </script>
  194. <style lang="scss" scoped>
  195. .imgCode {
  196. position: absolute;
  197. width: 100px;
  198. height: 40px;
  199. top: 8px;
  200. right: 10px;
  201. }
  202. </style>