index.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <script setup lang="ts">
  2. import Motion from "./utils/motion";
  3. import { useRouter } from "vue-router";
  4. import { message } from "@/utils/message";
  5. import { loginRules } from "./utils/rule";
  6. import { useNav } from "@/layout/hooks/useNav";
  7. import type { FormInstance } from "element-plus";
  8. import { useLayout } from "@/layout/hooks/useLayout";
  9. import { useUserStoreHook } from "@/store/modules/user";
  10. import { initRouter, getTopMenu } from "@/router/utils";
  11. import { bg, avatar, illustration } from "./utils/static";
  12. import { useRenderIcon } from "@/components/ReIcon/src/hooks";
  13. import lockOn from "../../assets/icon-png/lock-on.svg";
  14. import userPng from "@/assets/icon-png/user.svg";
  15. import {
  16. ref,
  17. reactive,
  18. toRaw,
  19. onMounted,
  20. onBeforeUnmount,
  21. computed
  22. } from "vue";
  23. import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
  24. import { encryption } from "@/utils/encrypt";
  25. import dayIcon from "@/assets/svg/day.svg?component";
  26. import darkIcon from "@/assets/svg/dark.svg?component";
  27. import Lock from "@iconify-icons/ri/lock-fill";
  28. import User from "@iconify-icons/ri/user-3-fill";
  29. defineOptions({
  30. name: "Login"
  31. });
  32. const router = useRouter();
  33. const loading = ref(false);
  34. const ruleFormRef = ref<FormInstance>();
  35. const { initStorage } = useLayout();
  36. initStorage();
  37. const { dataTheme, dataThemeChange } = useDataThemeChange();
  38. dataThemeChange();
  39. const { title } = useNav();
  40. const ruleForm = reactive({
  41. username: "",
  42. password: ""
  43. // username: "admin",
  44. // password: "123456"
  45. });
  46. const handleBlur = () => {
  47. // @ts-ignore
  48. localStorage.setItem("password", ruleForm.password);
  49. // @ts-ignore
  50. localStorage.setItem("rolesName", ruleForm.username);
  51. };
  52. const onLogin = async (formEl: FormInstance | undefined) => {
  53. loading.value = true;
  54. if (!formEl) return;
  55. await formEl.validate((valid, fields) => {
  56. if (valid) {
  57. useUserStoreHook()
  58. .loginByUsername({
  59. username: encryption(ruleForm.username),
  60. password: encryption(ruleForm.password)
  61. // username: ruleForm.username,
  62. // password: ruleForm.password
  63. })
  64. .then(res => {
  65. // @ts-ignore
  66. if (res.code === 200) {
  67. // @ts-ignore
  68. localStorage.setItem("token", res.data.token);
  69. // @ts-ignore
  70. localStorage.setItem("userName", res.data.realName);
  71. // 获取后端路由动态路由逻辑,不可删除
  72. initRouter().then(() => {
  73. // router.push(getTopMenu(true).path);
  74. router.push("/");
  75. message("登录成功", { type: "success" });
  76. });
  77. // router.push("/");
  78. console.log("登录成功", res);
  79. // message("登录成功", { type: "success" });
  80. } else {
  81. // @ts-ignore
  82. console.log("登录失败", res.msg);
  83. // @ts-ignore
  84. message(res.msg, { type: "error" });
  85. }
  86. })
  87. .catch(err => {
  88. loading.value = false;
  89. message(err, { type: "error" });
  90. return fields;
  91. });
  92. } else {
  93. loading.value = false;
  94. return fields;
  95. }
  96. });
  97. };
  98. /** 使用公共函数,避免`removeEventListener`失效 */
  99. function onkeypress({ code }: KeyboardEvent) {
  100. if (code === "Enter") {
  101. onLogin(ruleFormRef.value);
  102. }
  103. }
  104. onMounted(() => {
  105. window.document.addEventListener("keypress", onkeypress);
  106. });
  107. onBeforeUnmount(() => {
  108. window.document.removeEventListener("keypress", onkeypress);
  109. });
  110. </script>
  111. <template>
  112. <div class="select-none">
  113. <img :src="bg" class="wave" />
  114. <div class="login-container">
  115. <img src="@/assets/login/logo@2x.png" class="wave-logo" />
  116. <!-- <img src="@/assets/login/logo.png" class="wave-logo" /> -->
  117. <div class="img">
  118. <!-- -->
  119. </div>
  120. <div class="login-box">
  121. <div class="login-form">
  122. <div class="logo-box-form">
  123. <Motion>
  124. <!-- <h2 class="outline-none">{{ title }}</h2> -->
  125. <h2 class="">您好,欢迎登录!</h2>
  126. </Motion>
  127. <el-form
  128. ref="ruleFormRef"
  129. :model="ruleForm"
  130. :rules="loginRules"
  131. size="large"
  132. class="mt-10"
  133. >
  134. <Motion :delay="100">
  135. <el-form-item
  136. :rules="[
  137. {
  138. required: true,
  139. message: '请输入账号',
  140. trigger: 'blur'
  141. }
  142. ]"
  143. prop="username"
  144. >
  145. <el-input
  146. v-model="ruleForm.username"
  147. clearable
  148. placeholder="账号"
  149. :prefix-icon="userPng"
  150. class="custom-input"
  151. />
  152. </el-form-item>
  153. </Motion>
  154. <Motion :delay="150">
  155. <el-form-item prop="password">
  156. <el-input
  157. v-model="ruleForm.password"
  158. clearable
  159. show-password
  160. placeholder="密码"
  161. :prefix-icon="lockOn"
  162. @blur="handleBlur"
  163. />
  164. </el-form-item>
  165. </Motion>
  166. <Motion :delay="250">
  167. <el-button
  168. class="w-full mt-4"
  169. size="default"
  170. type="primary"
  171. :loading="loading"
  172. @click="onLogin(ruleFormRef)"
  173. >
  174. 登录
  175. </el-button>
  176. </Motion>
  177. </el-form>
  178. </div>
  179. </div>
  180. </div>
  181. </div>
  182. </div>
  183. </template>
  184. <style scoped>
  185. @import url("@/style/login.css");
  186. </style>
  187. <style lang="scss" scoped>
  188. :deep(.el-input-group__append, .el-input-group__prepend) {
  189. padding: 0;
  190. }
  191. .gongshi {
  192. // font-family: PingFangSC-Regular;
  193. font-size: 13px;
  194. font-weight: 400;
  195. line-height: 20px;
  196. color: #333;
  197. text-align: center;
  198. }
  199. :deep(.el-input__prefix) {
  200. font-size: 20px; /* 设置图标大小 */
  201. }
  202. </style>