LogIn.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <template>
  2. <div class="login-wrapper">
  3. <div id="login-backgroud" class="login-backgroud"></div>
  4. <div class="login-container">
  5. <div class="login-header">
  6. <span class="title-1">排水管网运维养护</span>
  7. <span class="title-2">虚拟仿真教学平台</span>
  8. </div>
  9. <div class="login-form">
  10. <el-form ref="formRef" :model="form" :rules="rules" :validate-on-rule-change="false" @keyup.enter="onSubmit(formRef)">
  11. <el-form-item prop="username">
  12. <el-input ref="usernameRef" v-model="form.username" class="username" clearable placeholder="账号" type="text">
  13. <template #prefix>
  14. <el-icon class="form-item-icon" size="1.5rem" color="#fff"><User /></el-icon>
  15. </template>
  16. </el-input>
  17. </el-form-item>
  18. <el-form-item prop="password">
  19. <el-input ref="passwordRef" v-model="form.password" clearable placeholder="请输入密码" show-password type="password">
  20. <template #prefix>
  21. <el-icon class="form-item-icon" size="1.5rem" color="#fff"><Unlock /></el-icon>
  22. </template>
  23. </el-input>
  24. </el-form-item>
  25. </el-form>
  26. <div class="submits">
  27. <div class="subButton" @click="onSubmit(formRef)">点击登录</div>
  28. </div>
  29. <div class="better-browser">
  30. 推荐使用:
  31. <div class="browser">谷歌浏览器</div>
  32. <div class="browser b2">火狐浏览器</div>
  33. </div>
  34. </div>
  35. <div class="login-footer">
  36. <div class="copyright"></div>
  37. </div>
  38. </div>
  39. </div>
  40. </template>
  41. <script setup lang="ts">
  42. import { onMounted, reactive, ref, nextTick } from 'vue';
  43. import { ElForm, ElInput, ElNotification } from 'element-plus';
  44. import { loginApi, getCurrentUser } from '@/api/userApi';
  45. import { useUserInfo } from '@/stores/userInfo';
  46. import router from '../router/index';
  47. const userInfo = useUserInfo();
  48. const formRef = ref<InstanceType<typeof ElForm>>();
  49. const usernameRef = ref<InstanceType<typeof ElInput>>();
  50. const passwordRef = ref<InstanceType<typeof ElInput>>();
  51. const form = reactive({
  52. username: '',
  53. password: '',
  54. });
  55. const rules = reactive({
  56. username: [
  57. {
  58. required: true,
  59. message: '用户名不能为空',
  60. trigger: 'blur',
  61. },
  62. {
  63. validator: (rule: any, val: string, callback: Function) => {
  64. if (!val) {
  65. return callback();
  66. }
  67. if (!/^[a-zA-Z0-9_]{2,15}$/.test(val)) {
  68. return callback(new Error('请输入正确的账户'));
  69. }
  70. return callback();
  71. },
  72. trigger: 'blur',
  73. },
  74. ],
  75. password: [
  76. {
  77. required: true,
  78. message: '密码不能为空',
  79. trigger: 'blur',
  80. },
  81. {
  82. validator: (rule: any, val: string, callback: Function) => {
  83. if (!val) {
  84. return callback();
  85. }
  86. if (!regularPassword(val)) {
  87. return callback(new Error('请输入正确的密码'));
  88. }
  89. return callback();
  90. },
  91. trigger: 'blur',
  92. },
  93. ],
  94. });
  95. const focusInput = () => {
  96. if (form.username === '') {
  97. usernameRef.value!.focus();
  98. } else if (form.password === '') {
  99. passwordRef.value!.focus();
  100. }
  101. };
  102. const onSubmit = (formEl: InstanceType<typeof ElForm> | undefined) => {
  103. if (!formEl) return;
  104. formEl.validate((valid) => {
  105. if (valid) {
  106. loginApi(form).then((res) => {
  107. if (res.data.data.token) {
  108. userInfo.setToken(res.data.data.token, 'auth');
  109. const userType = res.data.data.userType;
  110. getCurrentUser().then((res) => {
  111. userInfo.dataFill(Object.assign({ userType: userType }, res.data.data));
  112. if (userType == 0) router.push({ path: '/train' });
  113. else if (userType == 1) router.push({ path: '/TaskMng' });
  114. else {
  115. ElNotification({
  116. message: '无效用户',
  117. type: 'info',
  118. });
  119. }
  120. });
  121. }
  122. });
  123. } else {
  124. return false;
  125. }
  126. });
  127. };
  128. const regularPassword = (val: string) => {
  129. if (/^[a-zA-Z0-9_@]{6,32}$/.test(val)) return true;
  130. return false;
  131. };
  132. onMounted(() => {
  133. nextTick(() => focusInput());
  134. });
  135. </script>
  136. <style lang="scss" scoped>
  137. .login-wrapper {
  138. position: absolute;
  139. inset: 0;
  140. display: flex;
  141. justify-content: center;
  142. background-color: #1a212b;
  143. .login-backgroud {
  144. position: absolute;
  145. inset: 0;
  146. background-image: url(../assets/login/backgroud.jpg);
  147. background-size: 100% auto;
  148. background-repeat: no-repeat;
  149. background-position: center center;
  150. }
  151. .login-container {
  152. position: relative;
  153. display: flex;
  154. flex-direction: column;
  155. justify-content: center;
  156. }
  157. .login-header {
  158. display: flex;
  159. flex-direction: column;
  160. align-items: center;
  161. margin-top: 12rem;
  162. .title-1 {
  163. font-size: 4.2rem;
  164. font-family: Source Han Sans CN, Source Han Sans CN;
  165. font-weight: 500;
  166. color: #ffffff;
  167. line-height: 7.4rem;
  168. text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.4);
  169. }
  170. .title-2 {
  171. font-size: 3.4rem;
  172. font-family: Source Han Sans CN, Source Han Sans CN;
  173. font-weight: 400;
  174. color: #f1eaea;
  175. line-height: 6rem;
  176. text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.4);
  177. }
  178. }
  179. .login-form {
  180. margin: 3rem 6rem;
  181. .submits {
  182. display: flex;
  183. justify-content: space-between;
  184. .subButton {
  185. width: 100%;
  186. color: #fff;
  187. background-color: #498bda;
  188. font-size: 1.6rem;
  189. line-height: 4rem;
  190. border-radius: 0.2rem;
  191. cursor: pointer;
  192. box-sizing: border-box;
  193. text-align: center;
  194. }
  195. .subButton.tech {
  196. background-color: #d1b74c;
  197. }
  198. }
  199. .better-browser {
  200. --browser-height: 2rem;
  201. margin-top: 10rem;
  202. display: flex;
  203. line-height: var(--browser-height);
  204. font-size: 1.1rem;
  205. color: rgba(255, 255, 255, 0.7);
  206. .browser {
  207. margin-left: 0.5rem;
  208. display: flex;
  209. align-items: center;
  210. }
  211. .browser::before {
  212. content: '';
  213. margin-right: 0.3rem;
  214. width: var(--browser-height);
  215. height: var(--browser-height);
  216. background-image: url(../assets/login/browser1.png);
  217. background-size: 100% 100%;
  218. }
  219. .browser.b2::before {
  220. background-image: url(../assets/login/browser2.png);
  221. }
  222. }
  223. }
  224. .form-item-icon {
  225. height: auto;
  226. }
  227. .login-footer {
  228. position: absolute;
  229. bottom: 0;
  230. width: 100%;
  231. height: 3rem;
  232. display: flex;
  233. justify-content: center;
  234. .copyright {
  235. width: 11rem;
  236. background-image: url(../assets/login/copyright.png);
  237. background-size: 100% auto;
  238. background-repeat: no-repeat;
  239. }
  240. }
  241. }
  242. :deep(.el-form-item) {
  243. margin-bottom: 2rem;
  244. }
  245. :deep(.el-input) {
  246. --el-input-border-color: #4b92b9;
  247. }
  248. :deep(.el-input__wrapper) {
  249. // background-color: #1a2854;
  250. border: 2px solid #4BA3B9;
  251. background: #1A4854;
  252. }
  253. :deep(.el-input__inner) {
  254. --el-input-inner-height: 4.2rem;
  255. --el-input-text-color: #fff;
  256. font-size: 1.2rem;
  257. &:-webkit-autofill {
  258. transition: background-color 50000s ease-in-out 0s;
  259. -webkit-text-fill-color: #fff;
  260. }
  261. }
  262. </style>