LoginForm2.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <template>
  2. <el-form
  3. ref="formRef"
  4. :show-label="false"
  5. :show-require-mark="false"
  6. size="large"
  7. :model="formInline"
  8. :rules="rules"
  9. class="login-form"
  10. >
  11. <el-form-item prop="tenantId">
  12. <el-select
  13. v-model="formInline.tenantId"
  14. placeholder="请选择租户"
  15. @chnage="tenantIdChange"
  16. class="w-full"
  17. >
  18. <el-option
  19. v-for="item in tenantOptions"
  20. :key="item.tenantId"
  21. :label="item.tenantName"
  22. :value="item.tenantId"
  23. />
  24. <template #prefix>
  25. <el-icon size="18" color="#808695">
  26. <PersonOutline />
  27. </el-icon>
  28. </template>
  29. </el-select>
  30. </el-form-item>
  31. <el-form-item prop="username">
  32. <el-input v-model="formInline.username" placeholder="请输入用户名">
  33. <template #prefix>
  34. <el-icon class="el-input__icon" size="18" color="#808695">
  35. <PersonOutline />
  36. </el-icon>
  37. </template>
  38. </el-input>
  39. </el-form-item>
  40. <el-form-item prop="password">
  41. <el-input
  42. v-model="formInline.password"
  43. type="password"
  44. show-password
  45. placeholder="请输入密码"
  46. @keyup.enter="handleSubmit"
  47. >
  48. <template #prefix>
  49. <el-icon class="el-input__icon" size="18" color="#808695">
  50. <LockClosedOutline />
  51. </el-icon>
  52. </template>
  53. </el-input>
  54. </el-form-item>
  55. <el-form-item prop="verCode" v-if="isEnableCode">
  56. <div class="flex w-full">
  57. <el-input
  58. class="order-first mr-3"
  59. v-model="formInline.verCode"
  60. :input-props="{ autocomplete: 'new-password' }"
  61. placeholder="请输入图形验证码"
  62. >
  63. <template #prefix>
  64. <el-icon class="el-input__icon" size="18" color="#808695">
  65. <CodeOutlined />
  66. </el-icon>
  67. </template>
  68. </el-input>
  69. <el-button
  70. text
  71. :loading="captchaLoading"
  72. style="height: 40px; width: 40%; overflow: hidden"
  73. class="order-last"
  74. @click="getCaptchaImg"
  75. >
  76. <img :src="captchaImgUrl" style="height: 40px" />
  77. </el-button>
  78. </div>
  79. </el-form-item>
  80. <div class="flex items-center justify-between forget">
  81. <div class="flex-initial">
  82. <el-checkbox v-model:checked="autoLogin">自动登录</el-checkbox>
  83. </div>
  84. <!-- <div class="flex-initial order-last">
  85. <a href="javascript:">忘记密码</a>
  86. </div> -->
  87. </div>
  88. <el-form-item :show-label="false">
  89. <el-button
  90. class="w-full"
  91. type="primary"
  92. @click="handleSubmit"
  93. size="large"
  94. :loading="loading"
  95. round
  96. >
  97. 登录
  98. </el-button>
  99. </el-form-item>
  100. <div class="mb-4 default-color">
  101. <!-- <div class="flex view-account-other">
  102. <div class="flex-initial">
  103. <span>其它登录方式</span>
  104. </div>
  105. <div class="flex-initial mx-2">
  106. <a href="javascript:">
  107. <el-icon class="el-input__icon" size="24" color="#2d8cf0">
  108. <LogoGithub />
  109. </el-icon>
  110. </a>
  111. </div>
  112. <div class="flex-initial mx-2">
  113. <a href="javascript:">
  114. <el-icon class="el-input__icon" size="24" color="#2d8cf0">
  115. <LogoFacebook />
  116. </el-icon>
  117. </a>
  118. </div>
  119. <div class="flex-initial" style="margin-left: auto">
  120. <a href="javascript:" @click="goRegister">注册账号</a>
  121. </div>
  122. </div> -->
  123. </div>
  124. </el-form>
  125. </template>
  126. <script lang="ts" setup>
  127. import { reactive, ref, onMounted } from 'vue';
  128. import { useRoute, useRouter } from 'vue-router';
  129. import { useUserStore } from '@/store/modules/user';
  130. import { ElMessage, FormRules } from 'element-plus';
  131. import { ResultEnum } from '@/enums/httpEnum';
  132. import { initData, captchaBase64, tentantList } from '@/api/common/index';
  133. import { CodeOutlined } from '@vicons/antd';
  134. import { PersonOutline, LockClosedOutline } from '@vicons/ionicons5'; //LogoGithub, LogoFacebook
  135. import { PageEnum } from '@/enums/pageEnum';
  136. interface FormState {
  137. username: string;
  138. password: string;
  139. verCode: string;
  140. vercodeType: number;
  141. tenantId: number | undefined;
  142. }
  143. const formRef = ref();
  144. const loading = ref(false);
  145. const autoLogin = ref(true);
  146. const isEnableCode = ref(false);
  147. const captchaLoading = ref(false);
  148. const captchaImgUrl = ref();
  149. const LOGIN_NAME = PageEnum.BASE_LOGIN_NAME;
  150. const tenantOptions = ref<{ tenantCode: string; tenantId: number; tenantName: string }[]>([]);
  151. const tenantAccounts = [
  152. { username: 'bj', password: '123456' },
  153. { username: 'sz', password: '123456' },
  154. { username: 'gz', password: '123456' },
  155. { username: 'sh', password: '123456' },
  156. ];
  157. const formInline = reactive({
  158. username: 'bj',
  159. password: '123456',
  160. verCode: '',
  161. vercodeType: 5,
  162. tenantId: undefined,
  163. });
  164. const rules: FormRules = {
  165. username: { required: true, message: '请输入用户名', trigger: 'blur' },
  166. password: { required: true, message: '请输入密码', trigger: 'blur' },
  167. tenantId: { required: true, message: '请选择租户', type: 'number', trigger: 'change' },
  168. };
  169. // const emit = defineEmits(['goRegister']);
  170. const userStore = useUserStore();
  171. const router = useRouter();
  172. const route = useRoute();
  173. function tenantIdChange() {
  174. const tenantId = formInline.tenantId;
  175. const index = tenantOptions.value.findIndex((item) => item.tenantId === tenantId);
  176. if (index >= 0) {
  177. const info = tenantAccounts[index];
  178. formInline.username = info.username;
  179. formInline.password = info.password;
  180. }
  181. }
  182. function getTentantList() {
  183. tentantList().then((res) => {
  184. tenantOptions.value = res;
  185. if (res.length) {
  186. formInline.tenantId = res[0].tenantId;
  187. }
  188. });
  189. }
  190. //获取验证码
  191. function getCaptcha() {
  192. const vercodeType = formInline.vercodeType;
  193. captchaBase64({ type: vercodeType }).then((res) => {
  194. captchaImgUrl.value = res.img;
  195. });
  196. }
  197. function getCaptchaImg() {
  198. getCaptcha();
  199. }
  200. const handleSubmit = () => {
  201. if (!formRef.value) return;
  202. formRef.value.validate(async (valid) => {
  203. if (valid) {
  204. const { username, password, verCode, vercodeType, tenantId } = formInline;
  205. loading.value = true;
  206. const params: FormState = {
  207. username,
  208. password,
  209. verCode,
  210. vercodeType,
  211. tenantId,
  212. };
  213. try {
  214. const { code, msg } = await userStore.login(params);
  215. if (code == ResultEnum.SUCCESS) {
  216. const toPath = decodeURIComponent((route.query?.redirect || '/') as string);
  217. ElMessage.success('登录成功,即将进入系统');
  218. if (route.name === LOGIN_NAME) {
  219. router.replace('/');
  220. } else router.replace(toPath);
  221. } else {
  222. formInline.verCode = '';
  223. getCaptcha();
  224. ElMessage.error(msg || '登录失败');
  225. }
  226. } finally {
  227. loading.value = false;
  228. }
  229. } else {
  230. ElMessage({
  231. message: '请填写完整信息',
  232. type: 'error',
  233. });
  234. }
  235. });
  236. };
  237. // function goRegister() {
  238. // emit('goRegister');
  239. // }
  240. function getInitData() {
  241. initData().then((res) => {
  242. if (res.isEnableCode === true) {
  243. isEnableCode.value = res.isEnableCode;
  244. getCaptcha();
  245. }
  246. });
  247. }
  248. onMounted(() => {
  249. getInitData();
  250. getTentantList();
  251. });
  252. </script>
  253. <style lang="scss" scoped>
  254. .forget {
  255. margin-bottom: 16px;
  256. margin-top: -10px;
  257. }
  258. .login-form {
  259. :deep(.el-input) {
  260. --el-input-border-radius: 20px !important;
  261. }
  262. }
  263. </style>