index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <script setup lang="ts">
  2. import type { FormInstance, FormRules } from "element-plus";
  3. import useUserStore from "@/store/modules/user";
  4. import { ref, useTemplateRef, onMounted, onUnmounted } from "vue";
  5. defineOptions({
  6. name: "LoginForm",
  7. });
  8. const props = defineProps<{
  9. userName?: string;
  10. passWord?: string;
  11. captcha?: string;
  12. system?: string;
  13. captchaId?: number;
  14. }>();
  15. const emits = defineEmits<{
  16. onLogin: [userName: string];
  17. onRegister: [userName: string];
  18. onResetPassword: [userName: string];
  19. }>();
  20. const userStore = useUserStore();
  21. // const title = import.meta.env.VITE_APP_TITLE
  22. const baseurl = import.meta.env.VITE_APP_API_BASEURL;
  23. const loading = ref(false);
  24. const remember = ref(false);
  25. const captchaSrc = ref(""); //验证码图片
  26. // const system = ref([
  27. // 'PLATFORM',
  28. // 'JZG'
  29. // ])
  30. // 登录方式,default 账号密码登录,qrcode 扫码登录
  31. const type = ref("default");
  32. const formRef = useTemplateRef<FormInstance>("formRef");
  33. const form = ref({
  34. userName: props.userName ?? localStorage.login_account ?? "",
  35. passWord: "",
  36. captcha: "",
  37. system: "KK123",
  38. captchaId: 0,
  39. systemCode: "",
  40. });
  41. const rules = ref<FormRules>({
  42. userName: [{ required: true, trigger: "blur", message: "请输入用户名" }],
  43. system: [{ required: true, trigger: "blur", message: "请输入租户编码" }],
  44. passWord: [
  45. { required: true, trigger: "blur", message: "请输入密码" },
  46. { min: 6, max: 18, trigger: "blur", message: "密码长度为6到18位" },
  47. ],
  48. });
  49. onMounted(() => {
  50. refreshCaptcha();
  51. window.addEventListener('keydown', handleEnter)
  52. });
  53. onUnmounted(() => {
  54. window.removeEventListener('keydown', handleEnter, false)
  55. })
  56. //获取验证码接口
  57. function refreshCaptcha() {
  58. let randnum = Math.floor(Math.random() * (1000000 - 1 + 1)) + 1;
  59. captchaSrc.value =
  60. baseurl +
  61. "/auth/captchaById?t=" +
  62. new Date().getTime() +
  63. "&captchaId=" +
  64. randnum;
  65. form.value.captchaId = randnum;
  66. }
  67. function handleEnter(e: any) {
  68. // console.log(e)
  69. // console.log(e)
  70. if (e.keyCode == 13 || e.keyCode == 108) {
  71. //登录接口逻辑
  72. handleLogin()
  73. }
  74. }
  75. function handleLogin() {
  76. // console.log(123)
  77. formRef.value?.validate((valid) => {
  78. if (valid) {
  79. loading.value = true;
  80. userStore
  81. .login(form.value)
  82. .then(() => {
  83. if (remember) {
  84. localStorage.setItem("login_account", form.value.userName);
  85. } else {
  86. localStorage.removeItem("login_account");
  87. }
  88. localStorage.setItem("login_system", form.value.system);
  89. emits("onLogin", form.value.userName);
  90. // userStore.getMenu({systemCode:form.value.system}).then((res:any)=>{
  91. // console.log(res)
  92. // })
  93. })
  94. .finally(() => {
  95. loading.value = false;
  96. refreshCaptcha();
  97. });
  98. }
  99. });
  100. }
  101. // function testAccount(userName: string) {
  102. // form.value.userName = userName
  103. // form.value.passWord = '123456'
  104. // handleLogin()
  105. // }
  106. </script>
  107. <style lang="scss" scoped>
  108. :deep(.el-form-item--large) {
  109. margin-bottom: 30px;
  110. }
  111. :deep(.el-input__prefix) {
  112. color: #3275ff;
  113. }
  114. .title1 {
  115. position: relative;
  116. margin-bottom: 56px;
  117. font-size: 36px;
  118. color: #333;
  119. span {
  120. position: relative;
  121. z-index: 9999;
  122. letter-spacing: 5px;
  123. }
  124. .tag {
  125. position: absolute;
  126. bottom: 0;
  127. width: 76px;
  128. height: 8px;
  129. background: linear-gradient(90deg, #4fcaff 0%, #2b62ff 100%);
  130. }
  131. }
  132. .loginCSS {
  133. font-weight: 400;
  134. font-size: 20px;
  135. color: #fff;
  136. height: 50px;
  137. background: linear-gradient( 91deg, #4FCAFF 0%, #2B62FF 100%);
  138. }
  139. </style>
  140. <template>
  141. <ElForm ref="formRef" :model="form" :rules="rules" class="min-h-500px w-full flex-col-stretch-center"
  142. style="padding: 81px 75px;" size="large">
  143. <!-- <div class="mb-6">
  144. <HTabList v-model="type" :options="[
  145. { label: '账号密码登录', value: 'default' },
  146. { label: '扫码登录', value: 'qrcode' },
  147. ]" />
  148. </div> -->
  149. <template v-if="type === 'default'">
  150. <!-- <h3 class="mb-8 text-xl color-[var(--el-text-color-primary)] font-bold">
  151. 欢迎使用 {{ title }} ! 👋🏻
  152. </h3> -->
  153. <div class="title1 strong">
  154. <span>登录</span>
  155. <div class="tag"></div>
  156. </div>
  157. <div>
  158. <ElFormItem prop="system">
  159. <ElInput v-model="form.system" placeholder="输入租户编码" type="text" tabindex="1">
  160. <template #prefix>
  161. <el-icon>
  162. <Postcard />
  163. </el-icon>
  164. </template>
  165. </ElInput>
  166. </ElFormItem>
  167. <ElFormItem prop="userName">
  168. <ElInput v-model="form.userName" placeholder="手机号或工号" type="text" tabindex="1" maxlength="11">
  169. <template #prefix>
  170. <el-icon>
  171. <User />
  172. </el-icon>
  173. </template>
  174. </ElInput>
  175. </ElFormItem>
  176. <ElFormItem prop="passWord">
  177. <ElInput v-model="form.passWord" type="password" placeholder="登录密码" tabindex="2" show-password
  178. @keyup.enter="handleLogin">
  179. <template #prefix>
  180. <el-icon>
  181. <Lock />
  182. </el-icon>
  183. </template>
  184. </ElInput>
  185. </ElFormItem>
  186. <ElFormItem prop="captcha" style="margin-bottom: 0;">
  187. <ElCol :md="14" :sm="14" :xs="14">
  188. <ElInput v-model="form.captcha" placeholder="验证码" type="text" tabindex="3">
  189. <template #prefix>
  190. <el-icon>
  191. <CircleCheck />
  192. </el-icon>
  193. </template>
  194. </ElInput>
  195. </ElCol>
  196. <ElCol :md="10" :sm="10" :xs="10" flex>
  197. <img style="width: 100%; height: 32px; margin-left: 20px;" class="pointer" :src="captchaSrc"
  198. @click="refreshCaptcha" />
  199. </ElCol>
  200. </ElFormItem>
  201. </div>
  202. <div class="mb-17 flex-center-between">
  203. <ElCheckbox v-model="remember" style="color: #666;"> <span style="font-size: 14px;">记住账号</span></ElCheckbox>
  204. <ElLink style="font-size: 14px;color: #3275FF;" :underline="false" @click="emits('onResetPassword', form.userName)">
  205. 忘记密码
  206. </ElLink>
  207. </div>
  208. <ElButton class="loginCSS" text bg :loading="loading" @keydown.enter="handleEnter"
  209. @click.prevent="handleLogin">
  210. 登录
  211. </ElButton>
  212. <!-- <div class="mt-4 flex-center gap-2 text-sm color-[var(--el-text-color-secondary)]">
  213. 还没有帐号?
  214. <ElLink type="primary" :underline="false" @click="emits('onRegister', form.userName)">
  215. 创建新帐号
  216. </ElLink>
  217. </div> -->
  218. </template>
  219. <template v-else-if="type === 'qrcode'">
  220. <div class="flex-col-center">
  221. <el-image src="https://s2.loli.net/2024/04/26/GsahtuIZ9XOg5jr.png" class="h-[250px] w-[250px]" />
  222. <div class="mt-2 op-50">请使用微信扫码登录</div>
  223. </div>
  224. </template>
  225. <!-- <div class="mt-4 text-center -mb-4">
  226. <ElDivider>演示账号一键登录</ElDivider>
  227. <ElButton type="primary" size="small" plain @click="testAccount('admin')">
  228. admin
  229. </ElButton>
  230. <ElButton size="small" plain @click="testAccount('test')">
  231. test
  232. </ElButton>
  233. </div> -->
  234. </ElForm>
  235. </template>