index.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <template>
  2. <div class="login-container">
  3. <!-- 背景图 -->
  4. <div class="background-left">
  5. <img class="background-image" :src="loginbg" alt="背景图">
  6. </div>
  7. <!-- 头部 -->
  8. <div class="header">
  9. <myheader />
  10. </div>
  11. <!-- 登录框 -->
  12. <div class="login-form-container">
  13. <div class="login-box">
  14. <el-card class="login-card" shadow="never">
  15. <template #header>
  16. <div class="login-header">
  17. <!-- <img :src="loginLogo" alt="logo" class="login-logo"/> -->
  18. <h2>欢迎登录</h2>
  19. </div>
  20. </template>
  21. <el-form
  22. :model="loginForm"
  23. :rules="loginRules"
  24. ref="loginFormRef"
  25. @keyup.enter="handleLogin"
  26. hide-required-asterisk
  27. label-position="left"
  28. >
  29. <el-form-item prop="username"
  30. label="邮箱:"
  31. style="margin-bottom: 20px;"
  32. label-width="100px">
  33. <el-input
  34. v-model="loginForm.username"
  35. prefix-icon="User"
  36. clearable
  37. />
  38. </el-form-item>
  39. <el-form-item prop="password"
  40. label="密码:"
  41. style="margin-bottom: 20px;"
  42. label-width="100px">
  43. <el-input
  44. v-model="loginForm.password"
  45. prefix-icon="Lock"
  46. show-password
  47. clearable
  48. />
  49. </el-form-item>
  50. <el-form-item prop="remember" style="margin-bottom: 20px;">
  51. <div style="width: 100%; display: flex; justify-content: space-between;">
  52. <el-checkbox v-model="loginForm.remember" class="remember-me">记住密码</el-checkbox>
  53. <el-link type="info" class="forgot-password">忘记密码</el-link>
  54. </div>
  55. </el-form-item>
  56. <el-form-item>
  57. <el-button
  58. type="primary"
  59. class="login-btn"
  60. :loading="loading"
  61. @click="handleLogin"
  62. >
  63. 登录
  64. </el-button>
  65. </el-form-item>
  66. </el-form>
  67. <div class="login-footer">
  68. <div class="register-prompt">没有账号?点击</div>
  69. <el-link type="primary" @click="goToRegister">注册</el-link>
  70. </div>
  71. </el-card>
  72. </div>
  73. </div>
  74. </div>
  75. </template>
  76. <script setup>
  77. import { ElMessage } from 'element-plus'
  78. import router from "@/router"
  79. import { request,enPassword } from "@/utils/request"
  80. import secureStorage from '@/utils/secureStorage'
  81. import { message } from '@/utils/message'
  82. import { getToken, setToken, setUserId} from "@/utils/token"
  83. import { useUserStore } from '@/store/user'
  84. import loginbg from '@/assets/img/login-bg.png'
  85. import myheader from '@/components/layout/header.vue'
  86. // 表单引用
  87. const loginFormRef = ref(null)
  88. // 获取userStore实例
  89. const userStore = useUserStore()
  90. // 登录表单数据
  91. const loginForm = reactive({
  92. username: secureStorage.get('savedUsername') || '',
  93. password: secureStorage.get('savedPassword') || '',
  94. remember: secureStorage.get('rememberPassword') === 'true'
  95. })
  96. // 加载状态
  97. const loading = ref(false)
  98. // 表单验证规则
  99. const loginRules = reactive({
  100. username: [
  101. { min: 3, max: 18, message: '用户名长度在3到18个字符之间', trigger: 'blur' }
  102. ],
  103. password: [
  104. { min: 6, max: 18, message: '密码长度在6到18个字符之间', trigger: 'blur' }
  105. ]
  106. })
  107. // 登录方法
  108. const handleLogin = () => {
  109. loginFormRef.value.validate(valid => {
  110. if (!valid) return
  111. // 检查是否有输入用户名和密码
  112. if (!loginForm.username || !loginForm.password) {
  113. message.error( '请输入用户名和密码');
  114. return;
  115. }
  116. if (loginForm.remember) {
  117. secureStorage.set('savedUsername', loginForm.username)
  118. secureStorage.set('savedPassword', loginForm.password)
  119. secureStorage.set('rememberPassword', 'true')
  120. } else {
  121. secureStorage.remove('savedUsername')
  122. secureStorage.remove('savedPassword')
  123. secureStorage.remove('rememberPassword')
  124. }
  125. loading.value = true
  126. const params = {
  127. transCode: "A00002",
  128. loginName: loginForm.username,
  129. password: enPassword(loginForm.password),
  130. type: "",
  131. }
  132. // console.log(params)
  133. request(params)
  134. .then((res) => {
  135. setToken(res.clientToken)
  136. setUserId(res.userId)
  137. userStore.setToken(res.clientToken)
  138. // 存储用户信息到pinia
  139. userStore.setUserInfo({
  140. userId: res.userId,
  141. userName: res.userName,
  142. nickName: res.nickName,
  143. userType: res.userType,
  144. regTime: res.regTime,
  145. email: res.email || '',
  146. mobileNo: res.mobileNo,
  147. })
  148. router.push({ path: "/project" })
  149. })
  150. .catch((err) => {
  151. console.error('错误信息:',err);
  152. message.error(err.returnMsg);
  153. loading.value = false;
  154. })
  155. .finally(() => {
  156. loading.value = false
  157. });
  158. })
  159. }
  160. // 跳转到注册页面
  161. const goToRegister = () => {
  162. router.push({ path: "/register" })
  163. }
  164. </script>
  165. <style lang="scss" scoped>
  166. .login-container {
  167. position: relative;
  168. width: 100%;
  169. height: 100vh;
  170. min-width: 1200px;
  171. min-height: 600px;
  172. display: flex;
  173. overflow: auto;
  174. }
  175. .background-image {
  176. position: absolute;
  177. top: 0;
  178. left: 0;
  179. width: 100%;
  180. height: 100%;
  181. object-fit: fill;
  182. object-position: center;
  183. z-index: 0;
  184. }
  185. .header {
  186. width: 100%;
  187. height: 70px;
  188. position: absolute;
  189. top: 0;
  190. left: 0;
  191. z-index: 10;
  192. }
  193. .background-left {
  194. width: 100%;
  195. height: 100%;
  196. }
  197. .login-form-container {
  198. position: absolute;
  199. right: 54%;
  200. width: 46%;
  201. height: 100%;
  202. }
  203. .login-box {
  204. height: 100%;
  205. // background-color: rgba(255, 255, 255, 0.6);
  206. display: flex;
  207. justify-content: center;
  208. align-items: center;
  209. }
  210. .login-card {
  211. border: none !important;
  212. width: 55%;
  213. background-color: transparent;
  214. :deep(.el-card__header) {
  215. border-bottom: none;
  216. padding-bottom: 0;
  217. }
  218. }
  219. .login-card {
  220. // 设置label文字大小
  221. :deep(.el-form-item__label) {
  222. font-size: 14px;
  223. font-weight: 400;
  224. line-height: 39px; /* 保持垂直居中 */
  225. color: #2CFFFF; /* 可选:设置label颜色 */
  226. text-align: left;
  227. }
  228. // 设置输入框文字大小
  229. :deep(.el-input__inner) {
  230. font-size: 14px;
  231. height: 39px; /* 可选:调整输入框高度 */
  232. line-height: 39px; /* 保持垂直居中 */
  233. }
  234. :deep(.el-input__wrapper) {
  235. background-color: transparent;
  236. // border: 1px solid #B3B3B3;
  237. height: 39px;
  238. }
  239. // 设置placeholder文字大小
  240. :deep(.el-input__inner::placeholder) {
  241. font-size: 14px;
  242. }
  243. }
  244. .login-header {
  245. text-align: start;
  246. // width: 75%;
  247. margin-bottom: 30px;
  248. h2 {
  249. margin: 0;
  250. font-size: 26px;
  251. font-weight: 400;
  252. color: #2CFFFF;
  253. margin: 10px 0;
  254. font-style: normal;
  255. text-transform: none;
  256. letter-spacing: 1px;
  257. }
  258. }
  259. .login-logo {
  260. width: 110px;
  261. // margin-bottom: 18px;
  262. transform: translateX(-20px); /* 向左移动10px */
  263. }
  264. .forgot-password{
  265. color: #2CFFFF;
  266. }
  267. .remember-me {
  268. color: #FFFFFF;
  269. }
  270. // 选中的checkbox样式
  271. :deep(.el-checkbox__input.is-checked+.el-checkbox__label) {
  272. color: #2CFFFF;
  273. }
  274. // 选中状态的checkbox背景色和边框色
  275. :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  276. background-color: #2CFFFF;
  277. border-color: #2CFFFF;
  278. }
  279. .login-btn {
  280. width: 100%;
  281. height: 42px;
  282. margin-top: 10px;
  283. font-size: 16px;
  284. background: linear-gradient( 355deg, #00ABFF 0%, #023187 100%);
  285. border-radius: 0px 0px 0px 0px;
  286. border: 2px solid #52C6FF;
  287. }
  288. .login-footer {
  289. display: flex;
  290. justify-content: center;
  291. align-items: center;
  292. margin-top: 10px;
  293. }
  294. .register-prompt {
  295. margin-right: 5px;
  296. font-size: 12px;
  297. color: #FFFFFF;
  298. }
  299. :deep(.el-link__inner){
  300. color: #2CFFFF;
  301. }
  302. </style>