index.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <template>
  2. <div
  3. id="userLayout"
  4. class="w-full h-full relative"
  5. >
  6. <div
  7. class="rounded-lg flex items-center justify-evenly w-full h-full bg-white md:w-screen md:h-screen md:bg-[#194bfb]"
  8. >
  9. <div class="md:w-3/5 w-10/12 h-full flex items-center justify-evenly">
  10. <div class="oblique h-[130%] w-3/5 bg-white transform -rotate-12 absolute -ml-52" />
  11. <!-- 分割斜块 -->
  12. <div class="z-[999] pt-12 pb-10 md:w-96 w-full rounded-lg flex flex-col justify-between box-border">
  13. <div>
  14. <div class="flex items-center justify-center">
  15. <img
  16. class="w-24"
  17. src="../../assets/logo.png"
  18. alt
  19. >
  20. </div>
  21. <div class="mb-9">
  22. <p class="text-center text-4xl font-bold">龙弛智慧路口</p>
  23. </div>
  24. <el-form
  25. ref="loginForm"
  26. :model="loginFormData"
  27. :rules="rules"
  28. :validate-on-rule-change="false"
  29. @keyup.enter="submitForm"
  30. >
  31. <el-form-item
  32. prop="username"
  33. class="mb-6"
  34. >
  35. <el-input
  36. v-model="loginFormData.username"
  37. size="large"
  38. placeholder="请输入用户名"
  39. suffix-icon="user"
  40. />
  41. </el-form-item>
  42. <el-form-item
  43. prop="password"
  44. class="mb-6"
  45. >
  46. <el-input
  47. v-model="loginFormData.password"
  48. show-password
  49. size="large"
  50. type="password"
  51. placeholder="请输入密码"
  52. />
  53. </el-form-item>
  54. <el-form-item
  55. v-if="loginFormData.openCaptcha"
  56. prop="captcha"
  57. class="mb-6"
  58. >
  59. <div class="flex w-full justify-between">
  60. <el-input
  61. v-model="loginFormData.captcha"
  62. placeholder="请输入验证码"
  63. size="large"
  64. class="flex-1 mr-5"
  65. />
  66. <div class="w-1/3 h-11 bg-[#c3d4f2] rounded">
  67. <img
  68. v-if="picPath"
  69. class="w-full h-full"
  70. :src="picPath"
  71. alt="请输入验证码"
  72. @click="loginVerify()"
  73. >
  74. </div>
  75. </div>
  76. </el-form-item>
  77. <el-form-item class="mb-6">
  78. <el-button
  79. class="shadow shadow-blue-600 h-11 w-full"
  80. type="primary"
  81. size="large"
  82. @click="submitForm"
  83. >登 录</el-button>
  84. </el-form-item>
  85. </el-form>
  86. </div>
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. </template>
  92. <script setup>
  93. import JSEncrypt from 'jsencrypt'
  94. import { captcha, routerPublicKey } from '@/api/user'
  95. import { reactive, ref, onMounted } from 'vue'
  96. import { ElMessage } from 'element-plus'
  97. import { useRouter } from 'vue-router'
  98. import { useUserStore } from '@/pinia/modules/user'
  99. defineOptions({
  100. name: 'Login',
  101. })
  102. const router = useRouter()
  103. // 验证函数
  104. const checkUsername = (rule, value, callback) => {
  105. if (value.length < 5) {
  106. return callback(new Error('请输入正确的用户名'))
  107. } else {
  108. callback()
  109. }
  110. }
  111. const checkPassword = (rule, value, callback) => {
  112. if (value.length < 6) {
  113. return callback(new Error('请输入正确的密码'))
  114. } else {
  115. callback()
  116. }
  117. }
  118. // 获取验证码
  119. const loginVerify = async() => {
  120. const ele = await captcha()
  121. rules.captcha.push({
  122. max: ele.data.captchaLength,
  123. min: ele.data.captchaLength,
  124. message: `请输入${ele.data.captchaLength}位验证码`,
  125. trigger: 'blur',
  126. })
  127. picPath.value = ele.data.picPath
  128. loginFormData.captchaId = ele.data.captchaId
  129. loginFormData.openCaptcha = ele.data.openCaptcha
  130. }
  131. loginVerify()
  132. // 登录相关操作
  133. const loginForm = ref(null)
  134. const picPath = ref('')
  135. const loginFormData = reactive({
  136. username: '',
  137. password: '',
  138. captcha: '',
  139. captchaId: '',
  140. openCaptcha: false,
  141. })
  142. const rules = reactive({
  143. username: [{ validator: checkUsername, trigger: 'blur' }],
  144. password: [{ validator: checkPassword, trigger: 'blur' }],
  145. captcha: [
  146. {
  147. message: '验证码格式不正确',
  148. trigger: 'blur',
  149. },
  150. ],
  151. })
  152. const publicKey = ref()
  153. // 获取公钥
  154. const queryPublicKey = async() => {
  155. const req = await routerPublicKey()
  156. publicKey.value = req.data.publicKey
  157. }
  158. const userStore = useUserStore()
  159. //登录
  160. const login = async() => {
  161. //密码加密
  162. const instance = new JSEncrypt();
  163. instance.setPublicKey(publicKey.value);
  164. loginFormData.password = instance.encrypt(loginFormData.password)
  165. const bool = await userStore.LoginIn(loginFormData)
  166. loginFormData.password = ""
  167. return bool
  168. }
  169. const submitForm = () => {
  170. loginForm.value.validate(async(v) => {
  171. if (v) {
  172. const flag = await login()
  173. if (!flag) {
  174. loginVerify()
  175. }
  176. } else {
  177. ElMessage({
  178. type: 'error',
  179. message: '请正确填写登录信息',
  180. showClose: true,
  181. })
  182. loginVerify()
  183. return false
  184. }
  185. })
  186. }
  187. onMounted(() => {
  188. queryPublicKey()
  189. })
  190. </script>