index.vue 5.9 KB

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