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.

206 lines
6.0 KiB

  1. <script setup lang="ts">
  2. import Motion from "./utils/motion";
  3. import { useRouter } from "vue-router";
  4. import { loginRules } from "./utils/rule";
  5. import phone from "./components/phone.vue";
  6. import qrCode from "./components/qrCode.vue";
  7. import regist from "./components/regist.vue";
  8. import update from "./components/update.vue";
  9. import { initRouter } from "/@/router/utils";
  10. import { message } from "@pureadmin/components";
  11. import type { FormInstance } from "element-plus";
  12. import { storageSession } from "/@/utils/storage";
  13. import { ref, reactive, watch, computed } from "vue";
  14. import { operates, thirdParty } from "./utils/enums";
  15. import { useUserStoreHook } from "/@/store/modules/user";
  16. import { bg, avatar, currentWeek } from "./utils/static";
  17. import { ReImageVerify } from "/@/components/ReImageVerify";
  18. import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
  19. const imgCode = ref("");
  20. const router = useRouter();
  21. const loading = ref(false);
  22. const checked = ref(false);
  23. const ruleFormRef = ref<FormInstance>();
  24. const currentPage = computed(() => {
  25. return useUserStoreHook().currentPage;
  26. });
  27. const ruleForm = reactive({
  28. username: "admin",
  29. password: "admin123",
  30. verifyCode: ""
  31. });
  32. const onLogin = async (formEl: FormInstance | undefined) => {
  33. loading.value = true;
  34. if (!formEl) return;
  35. await formEl.validate((valid, fields) => {
  36. if (valid) {
  37. // 模拟请求,需根据实际开发进行修改
  38. setTimeout(() => {
  39. loading.value = false;
  40. storageSession.setItem("info", {
  41. username: "admin",
  42. accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
  43. });
  44. initRouter("admin").then(() => {});
  45. message.success("登陆成功");
  46. router.push("/");
  47. }, 2000);
  48. } else {
  49. loading.value = false;
  50. return fields;
  51. }
  52. });
  53. };
  54. function onHandle(value) {
  55. useUserStoreHook().SET_CURRENTPAGE(value);
  56. }
  57. watch(imgCode, value => {
  58. useUserStoreHook().SET_VERIFYCODE(value);
  59. });
  60. </script>
  61. <template>
  62. <img :src="bg" class="wave" />
  63. <div class="login-container">
  64. <div class="img">
  65. <component :is="currentWeek" />
  66. </div>
  67. <div class="login-box">
  68. <div class="login-form">
  69. <avatar class="avatar" />
  70. <Motion>
  71. <h2>Pure Admin</h2>
  72. </Motion>
  73. <el-form
  74. v-if="currentPage === 0"
  75. ref="ruleFormRef"
  76. :model="ruleForm"
  77. :rules="loginRules"
  78. size="large"
  79. @keyup.enter="onLogin(ruleFormRef)"
  80. >
  81. <Motion :delay="100">
  82. <el-form-item prop="username">
  83. <el-input
  84. clearable
  85. v-model="ruleForm.username"
  86. placeholder="账号"
  87. :prefix-icon="useRenderIcon('user')"
  88. />
  89. </el-form-item>
  90. </Motion>
  91. <Motion :delay="150">
  92. <el-form-item prop="password">
  93. <el-input
  94. clearable
  95. show-password
  96. v-model="ruleForm.password"
  97. placeholder="密码"
  98. :prefix-icon="useRenderIcon('lock')"
  99. />
  100. </el-form-item>
  101. </Motion>
  102. <Motion :delay="200">
  103. <el-form-item prop="verifyCode">
  104. <el-input
  105. clearable
  106. v-model="ruleForm.verifyCode"
  107. placeholder="验证码"
  108. >
  109. <template v-slot:append>
  110. <ReImageVerify v-model:code="imgCode" />
  111. </template>
  112. </el-input>
  113. </el-form-item>
  114. </Motion>
  115. <Motion :delay="250">
  116. <el-form-item>
  117. <div class="w-full h-20px flex justify-between items-center">
  118. <el-checkbox v-model="checked">记住密码</el-checkbox>
  119. <el-button
  120. type="text"
  121. @click="useUserStoreHook().SET_CURRENTPAGE(4)"
  122. >
  123. 忘记密码?
  124. </el-button>
  125. </div>
  126. <el-button
  127. class="w-full mt-4"
  128. size="default"
  129. type="primary"
  130. :loading="loading"
  131. @click="onLogin(ruleFormRef)"
  132. >
  133. 登录
  134. </el-button>
  135. </el-form-item>
  136. </Motion>
  137. <Motion :delay="300">
  138. <el-form-item>
  139. <div class="w-full h-20px flex justify-between items-center">
  140. <el-button
  141. v-for="(item, index) in operates"
  142. :key="index"
  143. class="w-full mt-4"
  144. size="default"
  145. @click="onHandle(index + 1)"
  146. >
  147. {{ item.title }}
  148. </el-button>
  149. </div>
  150. </el-form-item>
  151. </Motion>
  152. </el-form>
  153. <Motion v-if="currentPage === 0" :delay="350">
  154. <el-form-item>
  155. <el-divider>
  156. <p class="text-gray-500 text-xs">第三方登录</p>
  157. </el-divider>
  158. <div class="w-full flex justify-evenly">
  159. <span
  160. v-for="(item, index) in thirdParty"
  161. :key="index"
  162. :title="`${item.title}登陆`"
  163. >
  164. <IconifyIconOnline
  165. :icon="`ri:${item.icon}-fill`"
  166. width="20"
  167. class="cursor-pointer text-gray-500 hover:text-blue-400"
  168. />
  169. </span>
  170. </div>
  171. </el-form-item>
  172. </Motion>
  173. <!-- 手机号登陆 -->
  174. <phone v-if="currentPage === 1" />
  175. <!-- 二维码登陆 -->
  176. <qrCode v-if="currentPage === 2" />
  177. <!-- 注册 -->
  178. <regist v-if="currentPage === 3" />
  179. <!-- 忘记密码 -->
  180. <update v-if="currentPage === 4" />
  181. </div>
  182. </div>
  183. </div>
  184. </template>
  185. <style scoped>
  186. @import url("/@/style/login.css");
  187. </style>
  188. <style lang="scss" scoped>
  189. :deep(.el-input-group__append, .el-input-group__prepend) {
  190. padding: 0;
  191. }
  192. </style>