You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

508 lines
13 KiB

2 weeks ago
1 week ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
1 week ago
1 week ago
2 weeks ago
1 week ago
1 week ago
1 week ago
2 weeks ago
1 week ago
2 weeks ago
1 week ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
  1. <template>
  2. <div class="site-wrapper site-page--login">
  3. <div class="login-layout">
  4. <section class="brand-panel">
  5. <div class="brand-panel__content">
  6. <img class="brand-panel__logo" src="~@/assets/img/lc.png" alt="龙闯电梯">
  7. <p class="brand-panel__label">LONGTRON ELEVATOR | LIFE AESTHETICS</p>
  8. <h1 class="brand-panel__title">
  9. 高端家用电梯
  10. <span class="divider">·</span>
  11. <span class="sub-title">一站式服务平台</span>
  12. </h1>
  13. <p class="brand-panel__desc">
  14. 龙闯电梯坚持臻选引进自主创新并重为中国高端家庭提供集代理研发生产销售
  15. 安装售后于一体的一站式家用电梯服务
  16. </p>
  17. <div class="brand-panel__stats">
  18. <div class="brand-panel__stat">
  19. <p class="brand-panel__stat-value">设计研发</p>
  20. <p class="brand-panel__stat-label">家用电梯设计家用电梯智能系统研发</p>
  21. </div>
  22. <div class="brand-panel__stat">
  23. <p class="brand-panel__stat-value">制造装配</p>
  24. <p class="brand-panel__stat-label">电梯配件制造模块化组装</p>
  25. </div>
  26. <div class="brand-panel__stat">
  27. <p class="brand-panel__stat-value">现代服务</p>
  28. <p class="brand-panel__stat-label">电梯维保物流仓储市场营销</p>
  29. </div>
  30. </div>
  31. </div>
  32. </section>
  33. <section class="login-panel">
  34. <div class="login-card">
  35. <div class="login-card__header">
  36. <h3 class="login-title">欢迎登录</h3>
  37. <p class="login-subtitle">龙闯电梯管理平台</p>
  38. </div>
  39. <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" status-icon class="login-form">
  40. <el-form-item prop="userName">
  41. <el-input v-model="dataForm.userName" placeholder="请输入账号" size="large"></el-input>
  42. </el-form-item>
  43. <el-form-item prop="password">
  44. <el-input v-model="dataForm.password" type="password" placeholder="请输入密码" size="large"></el-input>
  45. </el-form-item>
  46. <el-form-item>
  47. <el-button class="login-btn" type="primary" @click="dataFormSubmit()">登录系统</el-button>
  48. </el-form-item>
  49. </el-form>
  50. <p class="login-footer">龙闯电梯 · 生活美学倡导者</p>
  51. </div>
  52. </section>
  53. </div>
  54. </div>
  55. </template>
  56. <script>
  57. import {getConfigParams} from '@/api/sysConfig.js'
  58. import { getUUID } from '@/utils'
  59. export default {
  60. data () {
  61. return {
  62. src: 'http://127.0.0.1/upload/ifs.png',
  63. dataForm: {
  64. userName: '',
  65. password: '',
  66. uuid: '',
  67. captcha: ''
  68. },
  69. dataRule: {
  70. userName: [
  71. { required: true, message: '帐号不能为空', trigger: 'blur' }
  72. ],
  73. password: [
  74. { required: true, message: '密码不能为空', trigger: 'blur' }
  75. ]
  76. },
  77. captchaPath: ''
  78. }
  79. },
  80. computed: {
  81. multiLanguage: {
  82. get() {
  83. return this.$store.state.user.multiLanguage
  84. },
  85. set(val) {
  86. this.$store.commit('user/updateMultiLanguage', val)
  87. }
  88. },
  89. authControl: {
  90. get() {
  91. return this.$store.state.user.authControl
  92. },
  93. set(val) {
  94. this.$store.commit('user/updateAuthControl', val)
  95. }
  96. }
  97. },
  98. mounted() {
  99. // 仅当 redirectPath 为空时设置
  100. const redirectPath = this.$route.query.redirect || '/home';
  101. if (!localStorage.getItem('redirectPath')) {
  102. localStorage.setItem('redirectPath', redirectPath);
  103. }
  104. },
  105. created () {
  106. this.userName();
  107. // 如果 redirectPath 已经存在,不要覆盖它
  108. const currentPath = localStorage.getItem('redirectPath');
  109. if (!currentPath) {
  110. localStorage.setItem('redirectPath', this.$route.fullPath);
  111. }
  112. },
  113. methods: {
  114. // 获取上次登陆的用户名
  115. userName(){
  116. this.dataForm.userName = localStorage.getItem('userName')
  117. },
  118. // 提交表单
  119. dataFormSubmit () {
  120. this.$refs['dataForm'].validate((valid) => {
  121. if (valid) {
  122. // 显示全屏loading - 美观且专业
  123. const loading = this.$loading({
  124. lock: true,
  125. text: '正在登录,请稍候...',
  126. spinner: 'el-icon-loading',
  127. background: 'rgba(0, 0, 0, 0.5)',
  128. customClass: 'login-loading'
  129. })
  130. this.$http({
  131. url: this.$http.adornUrl('/sys/login'),
  132. method: 'post',
  133. data: this.$http.adornData({
  134. 'username': this.dataForm.userName,
  135. 'password': this.dataForm.password,
  136. 'uuid': this.dataForm.uuid
  137. })
  138. }).then(({data}) => {
  139. if (data && data.code === 0) {
  140. console.log('跳转前路径:', localStorage.getItem('redirectPath')); // 检查路径是否正确
  141. this.$cookie.set('token', data.token)
  142. // 动态跳转逻辑
  143. const redirectPath = localStorage.getItem('redirectPath') || '';
  144. // 设置需要判断的路径
  145. const pathsToRedirect = ['/auth-authQuote', '/auth-authInquiry'];
  146. if (pathsToRedirect.some(path => redirectPath.indexOf(path) !== -1)) {
  147. this.$router.replace(redirectPath);
  148. } else {
  149. this.$router.replace({ name: 'home' });
  150. }
  151. console.log('Redirecting to:', redirectPath); // 调试输出
  152. this.$i18n.locale=data.language
  153. localStorage.setItem('locale', data.language)
  154. localStorage.setItem('refresh', "0")
  155. localStorage.setItem('userName', this.dataForm.userName)
  156. this.getConfigParams()
  157. // 登录成功后关闭loading(路由跳转会自动关闭,这里作为备用)
  158. setTimeout(() => {
  159. loading.close()
  160. }, 500)
  161. } else {
  162. loading.close() // 登录失败立即关闭loading
  163. this.$message.error(data.msg)
  164. }
  165. }).catch(error => {
  166. loading.close() // 请求异常时关闭loading
  167. this.$message.error('登录请求失败,请检查网络连接')
  168. })
  169. }
  170. })
  171. },
  172. // 获取全局参数变量
  173. getConfigParams() {
  174. getConfigParams().then(({data}) => {
  175. if (data && data.code == 0) {
  176. localStorage.setItem('configParams', JSON.stringify(data.data))
  177. // this.multiLanguage = JSON.parse(localStorage.getItem('configParams')).multiLanguage
  178. // this.authControl = JSON.parse(localStorage.getItem('configParams')).authControl
  179. }
  180. })
  181. },
  182. }
  183. }
  184. </script>
  185. <style lang="scss" scoped>
  186. .site-wrapper.site-page--login {
  187. min-height: 100vh;
  188. background: radial-gradient(circle at 12% 16%, rgba(227, 184, 110, 0.3), rgba(227, 184, 110, 0) 24%),
  189. linear-gradient(130deg, #07141d 0%, #0d2736 48%, #163444 100%);
  190. }
  191. .login-layout {
  192. display: flex;
  193. min-height: 100vh;
  194. position: relative;
  195. }
  196. .brand-panel {
  197. width: 57%;
  198. position: relative;
  199. color: #ffffff;
  200. padding: 68px 76px;
  201. display: flex;
  202. align-items: center;
  203. overflow: hidden;
  204. background:
  205. radial-gradient(circle at 18% 22%, rgba(223, 182, 109, 0.32), rgba(223, 182, 109, 0) 40%),
  206. linear-gradient(150deg, rgba(2, 15, 24, 0.95), rgba(7, 43, 60, 0.86));
  207. }
  208. .brand-panel::before {
  209. content: '';
  210. position: absolute;
  211. inset: 0;
  212. background:
  213. linear-gradient(120deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0) 38%),
  214. repeating-linear-gradient(
  215. -35deg,
  216. rgba(255, 255, 255, 0.045) 0px,
  217. rgba(255, 255, 255, 0.045) 1px,
  218. rgba(255, 255, 255, 0) 1px,
  219. rgba(255, 255, 255, 0) 30px
  220. );
  221. pointer-events: none;
  222. }
  223. .brand-panel::after {
  224. content: '';
  225. position: absolute;
  226. right: -130px;
  227. top: 15%;
  228. width: 320px;
  229. height: 320px;
  230. border-radius: 50%;
  231. background: radial-gradient(circle at center, rgba(224, 179, 96, 0.26), rgba(224, 179, 96, 0) 72%);
  232. filter: blur(1px);
  233. }
  234. .brand-panel__content {
  235. position: relative;
  236. z-index: 1;
  237. max-width: 760px;
  238. }
  239. .brand-panel__logo {
  240. width: 250px;
  241. height: 70px;
  242. object-fit: contain;
  243. margin-bottom: 24px;
  244. }
  245. .brand-panel__label {
  246. margin: 0;
  247. font-size: 12px;
  248. letter-spacing: 2px;
  249. color: rgba(255, 255, 255, 0.74);
  250. }
  251. .brand-panel__title {
  252. font-size: 50px;
  253. font-weight: 800;
  254. color: #fff;
  255. display: flex;
  256. align-items: baseline;
  257. gap: 8px;
  258. line-height: 1;
  259. }
  260. .brand-panel__title .divider {
  261. font-size: 34px;
  262. opacity: 0.8;
  263. }
  264. .brand-panel__title .sub-title {
  265. font-size: 28px;
  266. font-weight: 600;
  267. opacity: 0.95;
  268. }
  269. .brand-panel__desc {
  270. margin: 0;
  271. max-width: 660px;
  272. font-size: 17px;
  273. line-height: 1.85;
  274. color: rgba(255, 255, 255, 0.87);
  275. }
  276. .brand-panel__stats {
  277. margin-top: 40px;
  278. display: flex;
  279. align-items: center;
  280. gap: 10px;
  281. }
  282. .brand-panel__stat {
  283. min-width: 140px;
  284. padding: 14px 16px 13px;
  285. border-radius: 12px;
  286. border: 1px solid rgba(255, 255, 255, 0.2);
  287. background: rgba(11, 41, 56, 0.42);
  288. backdrop-filter: blur(2px);
  289. }
  290. .brand-panel__stat-value {
  291. margin: 0;
  292. font-size: 30px;
  293. line-height: 1.2;
  294. color: #eac07a;
  295. font-weight: 600;
  296. }
  297. .brand-panel__stat-label {
  298. margin: 6px 0 0;
  299. font-size: 13px;
  300. color: rgba(255, 255, 255, 0.72);
  301. }
  302. .brand-panel__service {
  303. margin: 28px 0 0;
  304. font-size: 16px;
  305. letter-spacing: 1px;
  306. color: rgba(255, 255, 255, 0.9);
  307. }
  308. .login-panel {
  309. width: 43%;
  310. min-width: 520px;
  311. padding: 40px 60px;
  312. display: flex;
  313. align-items: center;
  314. justify-content: center;
  315. position: relative;
  316. }
  317. .login-panel::before {
  318. content: '';
  319. position: absolute;
  320. left: 0;
  321. top: 12%;
  322. width: 1px;
  323. height: 76%;
  324. background: linear-gradient(rgba(255, 255, 255, 0), rgba(226, 186, 114, 0.45), rgba(255, 255, 255, 0));
  325. }
  326. .login-card {
  327. width: 460px;
  328. max-width: 100%;
  329. padding: 36px 40px 28px;
  330. border-radius: 18px;
  331. background: rgba(255, 255, 255, 0.97);
  332. box-shadow: 0 24px 55px rgba(5, 16, 24, 0.3);
  333. border: 1px solid rgba(222, 188, 119, 0.38);
  334. }
  335. .login-card__logo {
  336. width: 170px;
  337. height: 48px;
  338. object-fit: contain;
  339. margin-bottom: 18px;
  340. }
  341. .login-card__header {
  342. margin-bottom: 26px;
  343. }
  344. .login-title {
  345. margin: 0;
  346. font-size: 36px;
  347. font-weight: 600;
  348. color: #0f2734;
  349. }
  350. .login-subtitle {
  351. margin: 10px 0 0;
  352. color: #617680;
  353. font-size: 15px;
  354. letter-spacing: 0.3px;
  355. }
  356. .login-form {
  357. /deep/ .el-form-item {
  358. margin-bottom: 20px;
  359. }
  360. /deep/ .el-form-item__content {
  361. height: 34px;
  362. line-height: 30px;
  363. }
  364. /deep/ .el-input__inner {
  365. height: 30px !important;
  366. border-radius: 12px;
  367. border: 1px solid #d0d8dd;
  368. color: #24323b;
  369. transition: all 0.22s ease;
  370. font-size: 15px;
  371. padding-left: 14px;
  372. }
  373. /deep/ .el-input__inner:focus {
  374. border-color: #cfa35d;
  375. box-shadow: 0 0 0 3px rgba(210, 167, 92, 0.15);
  376. }
  377. }
  378. .login-btn {
  379. width: 100%;
  380. height: 50px;
  381. border: none;
  382. border-radius: 12px;
  383. font-size: 16px;
  384. letter-spacing: 1px;
  385. background: linear-gradient(120deg, #c89f5f 0%, #aa773a 100%);
  386. box-shadow: 0 10px 20px rgba(179, 129, 63, 0.28);
  387. }
  388. .login-btn:hover,
  389. .login-btn:focus {
  390. background: linear-gradient(120deg, #d3ad6f 0%, #b6884e 100%);
  391. }
  392. .login-footer {
  393. margin: 36px 0 0;
  394. font-size: 13px;
  395. color: #778891;
  396. text-align: center;
  397. }
  398. @media (max-width: 1200px) {
  399. .brand-panel {
  400. width: 52%;
  401. padding: 48px;
  402. }
  403. .brand-panel__title {
  404. font-size: 45px;
  405. }
  406. .brand-panel__desc {
  407. font-size: 15px;
  408. }
  409. .login-panel {
  410. width: 48%;
  411. min-width: 430px;
  412. padding: 26px 32px;
  413. }
  414. .login-card {
  415. width: 420px;
  416. padding: 30px 30px 24px;
  417. }
  418. .login-title {
  419. font-size: 30px;
  420. }
  421. }
  422. @media (max-width: 992px) {
  423. .brand-panel {
  424. display: none;
  425. }
  426. .login-panel {
  427. width: 100%;
  428. min-width: auto;
  429. padding: 24px;
  430. }
  431. .login-card {
  432. width: 100%;
  433. max-width: 540px;
  434. }
  435. .login-panel::before {
  436. display: none;
  437. }
  438. }
  439. </style>
  440. <style lang="scss">
  441. // 全屏登录loading样式 - 更美观专业
  442. .login-loading {
  443. .el-loading-spinner {
  444. .el-icon-loading {
  445. font-size: 50px;
  446. color: #d2a75c;
  447. }
  448. .el-loading-text {
  449. color: #ffffff;
  450. font-size: 16px;
  451. font-weight: 500;
  452. margin-top: 15px;
  453. letter-spacing: 1px;
  454. }
  455. }
  456. }
  457. </style>