index.vue 6.2 KB

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