feat: 完成管理员密码登录修复和项目清理

- 修复BCryptPasswordEncoder密码验证问题
- 实现密码设置提示弹窗功能(仅对无密码用户显示一次)
- 优化修改密码逻辑和验证流程
- 更新Welcome页面背景样式
- 清理临时SQL文件和测试代码
- 移动数据库备份文件到database/backups目录
- 删除不必要的MD文档和临时文件
This commit is contained in:
AIGC Developer
2025-11-21 16:10:00 +08:00
parent 2961d2b0d0
commit dbd06435cb
384 changed files with 8064 additions and 5080 deletions

View File

@@ -7,20 +7,28 @@
<!-- 登录卡片 -->
<div class="login-card">
<!-- Logo图标 -->
<div class="card-logo">
<svg width="306" height="37" viewBox="0 0 306 37" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.266 9.22263e-06L23.218 0.64601C22.952 2.54601 22.648 4.33201 22.268 5.96601H34.276V8.58801C33.668 11.818 32.946 15.048 32.034 18.24L28.158 17.138C28.918 15.048 29.564 12.616 30.096 9.80401H21.242C20.292 12.616 19.152 14.896 17.784 16.644L14.592 14.402C17.024 10.982 18.582 6.15601 19.266 9.22263e-06ZM13.11 29.792C11.97 28.044 10.83 26.334 9.65201 24.662C7.52401 28.766 4.97801 32.034 1.97601 34.466L7.80571e-06 30.894C3.00201 28.69 5.43401 25.536 7.29601 21.432C5.16801 18.658 2.96401 15.96 0.608008 13.3L3.23001 10.792C4.94001 12.502 6.84001 14.668 8.89201 17.252C9.72801 14.516 10.412 11.552 10.944 8.32201H0.684008V4.48401H14.82V8.13201C13.984 12.768 12.844 16.91 11.476 20.558C12.92 22.496 14.402 24.586 15.998 26.866L13.11 29.792ZM22.762 11.894H26.676C26.676 14.516 26.524 16.91 26.22 19.114C28.044 24.738 31.122 29.26 35.53 32.642L32.87 35.758C29.45 32.756 26.828 29.146 24.928 24.928C23.56 29.298 20.406 32.908 15.504 35.758L12.996 32.68C17.176 30.172 19.912 27.17 21.204 23.636C22.192 20.596 22.724 16.682 22.762 11.894ZM41.762 0.83601C44.308 2.81201 46.474 4.82601 48.26 6.84001L45.524 9.57601C44.004 7.67601 41.876 5.58601 39.102 3.34401L41.762 0.83601ZM64.486 35.036C62.32 35.036 59.964 34.998 57.418 34.96C54.834 34.922 52.706 34.694 51.072 34.276C49.438 33.82 48.07 32.946 46.93 31.654C46.398 30.97 45.866 30.666 45.41 30.666C44.65 30.666 43.282 32.452 41.306 36.062L38.494 33.402C40.394 30.286 42.104 28.272 43.7 27.436V16.91H38.57V13.338H47.31V27.702C47.462 27.854 47.652 28.006 47.842 28.234C48.792 29.26 49.704 30.02 50.616 30.514C51.794 31.046 53.542 31.388 55.898 31.464C58.178 31.502 60.876 31.54 63.992 31.54C65.74 31.54 67.488 31.502 69.312 31.464C71.136 31.388 72.504 31.35 73.492 31.274L72.58 35.036H64.486ZM50.198 27.74L49.134 24.244C49.818 23.94 50.198 23.294 50.198 22.344V3.91401C53.466 2.88801 56.05 1.67201 58.026 0.30401L60.23 3.49601C58.634 4.56001 56.544 5.58601 53.884 6.53601V23.066C55.632 22.572 57.304 22.04 58.976 21.47L59.698 25.194C56.962 26.03 53.808 26.866 50.198 27.74ZM68.59 26.448H65.778L64.714 22.686L67.336 22.876C68.02 22.876 68.362 22.458 68.362 21.66V6.00401H64.334V30.514H60.534V2.50801H72.086V22.458C72.086 25.118 70.908 26.448 68.59 26.448ZM84.93 9.15801C86.07 11.02 87.21 13.11 88.312 15.39L85.614 16.758H91.694V8.43601H78.47V4.59801H91.694V0.64601H95.722V4.59801H109.288V8.43601H95.722V16.758H98.762C100.054 14.288 101.156 11.666 102.106 8.89201L105.982 10.26C104.994 12.654 103.892 14.82 102.676 16.758H110.352V20.596H98.762C101.422 24.434 105.716 27.892 111.644 30.932L108.908 34.352C102.752 30.324 98.344 25.84 95.722 20.938V35.644H91.694V20.9C89.224 26.144 84.664 30.628 77.976 34.39L75.772 30.818C82.004 27.74 86.298 24.32 88.578 20.596H76.988V16.758H84.778C83.714 14.516 82.612 12.54 81.434 10.83L84.93 9.15801ZM134.33 28.158V32.11C128.402 33.326 122.056 34.39 115.292 35.226L114.342 31.426C117.268 31.122 120.156 30.78 122.968 30.362V24.434H116.09V20.634H122.968V16.796H126.958V20.634H133.228V24.434H126.958V29.678C129.466 29.222 131.898 28.69 134.33 28.158ZM114.988 1.78601H134.178V5.51001H124.716C123.196 8.58801 121.828 10.982 120.612 12.654C123.348 12.35 126.084 12.008 128.82 11.552C128.136 10.488 127.414 9.38601 126.654 8.28401L129.694 6.34601C132.202 9.65201 134.102 12.54 135.432 14.972L132.126 17.252C131.67 16.34 131.176 15.428 130.644 14.516C125.894 15.352 120.726 16.036 115.178 16.606L114.304 13.072C114.988 12.996 115.482 12.844 115.862 12.692C116.926 11.818 118.484 9.42401 120.46 5.51001H114.988V1.78601ZM144.02 35.34H138.358L137.484 31.502C139.308 31.654 141.018 31.73 142.652 31.73C143.526 31.73 143.982 31.236 143.982 30.324V0.64601H148.01V31.35C148.01 34.01 146.68 35.34 144.02 35.34ZM136.686 4.06601H140.524V27.284H136.686V4.06601Z" fill="white"/>
<path d="M163.552 4.59801H168.378L175.826 26.714H175.94L183.388 4.59801H188.214L178.562 31.73H173.204L163.552 4.59801ZM193.617 4.06601C194.453 4.06601 195.175 4.33201 195.745 4.86401C196.277 5.39601 196.581 6.08001 196.581 6.91601C196.581 7.75201 196.277 8.47401 195.707 9.00601C195.137 9.53801 194.453 9.80401 193.617 9.80401C192.781 9.80401 192.097 9.53801 191.527 9.00601C190.957 8.43601 190.691 7.75201 190.691 6.91601C190.691 6.08001 190.957 5.39601 191.527 4.86401C192.097 4.33201 192.781 4.06601 193.617 4.06601ZM191.451 12.084H195.783V31.73H191.451V12.084ZM215.14 4.06601H219.472V31.73H215.444V29.64C214.076 31.388 212.1 32.262 209.516 32.262C206.59 32.262 204.31 31.236 202.676 29.184C201.156 27.284 200.396 24.814 200.396 21.812C200.396 18.924 201.118 16.53 202.638 14.63C204.234 12.578 206.476 11.552 209.288 11.552C211.568 11.552 213.506 12.616 215.14 14.782V4.06601ZM210.314 15.048C208.338 15.048 206.932 15.694 206.02 16.986C205.222 18.088 204.842 19.684 204.842 21.812C204.842 23.94 205.184 25.574 205.944 26.714C206.818 28.082 208.224 28.766 210.162 28.766C211.834 28.766 213.164 28.082 214.076 26.752C214.874 25.536 215.292 23.94 215.292 22.04V21.736C215.292 19.646 214.76 17.974 213.772 16.758C212.86 15.618 211.682 15.048 210.314 15.048ZM224.395 4.59801H242.901V8.39801H228.841V15.922H242.103V19.722H228.841V31.73H224.395V4.59801ZM246.513 4.06601H250.845V31.73H246.513V4.06601ZM264.901 11.552C267.865 11.552 270.259 12.502 272.083 14.478C273.869 16.416 274.781 18.886 274.781 21.926C274.781 24.928 273.869 27.398 272.121 29.298C270.297 31.274 267.865 32.262 264.901 32.262C261.899 32.262 259.505 31.274 257.681 29.298C255.895 27.398 255.021 24.928 255.021 21.926C255.021 18.886 255.895 16.416 257.719 14.478C259.505 12.502 261.899 11.552 264.901 11.552ZM264.901 15.086C263.077 15.086 261.709 15.77 260.721 17.214C259.885 18.43 259.467 20.026 259.467 21.926C259.467 23.826 259.885 25.384 260.721 26.6C261.709 28.006 263.077 28.728 264.901 28.728C266.687 28.728 268.093 28.006 269.081 26.6C269.917 25.346 270.373 23.788 270.373 21.926C270.373 20.026 269.917 18.43 269.081 17.214C268.093 15.77 266.687 15.086 264.901 15.086ZM276.476 12.084H281.264L285.178 26.6L289.054 12.084H293.044L296.92 26.6L300.834 12.084H305.622L299.01 31.73H294.982L291.068 17.366L287.116 31.73H283.088L276.476 12.084Z" fill="#0DC0FF"/>
</svg>
<!-- 欢迎标题 -->
<div class="welcome-title">
<span class="welcome-text">欢迎来到</span>
<span class="brand-name">VidFlow</span>
</div>
<!-- 登录标题 -->
<div class="login-title">
<div class="login-methods">
<button :class="['method-btn', { active: loginType === 'email' }]" @click="() => { loginType = 'email'; clearForm(); }">邮箱验证码登录</button>
<button :class="['method-btn', { active: loginType === 'password' }]" @click="() => { loginType = 'password'; clearForm(); }">邮箱密码登录</button>
</div>
<!-- 登录方式切换 -->
<div class="login-tabs">
<svg width="248" height="59" viewBox="0 0 248 59" fill="none" xmlns="http://www.w3.org/2000/svg" class="tabs-svg">
<!-- 邮箱登录 -->
<g class="tab-email" :class="{ active: loginType === 'email' }" @click="loginType = 'email'" style="cursor: pointer;">
<path d="M13.598 21.112V40.638H11.076V39.13H4.316V40.638H1.768V21.112H6.344V17.55H8.996V21.112H13.598ZM4.316 36.712H6.344V31.122H4.316V36.712ZM8.996 36.712H11.076V31.122H8.996V36.712ZM4.316 28.73H6.344V23.556H4.316V28.73ZM8.996 23.556V28.73H11.076V23.556H8.996ZM15.34 18.772H24.232V20.748C23.452 23.4 22.62 25.818 21.736 28.054C23.556 30.654 24.466 32.76 24.492 34.398C24.492 35.958 24.154 37.024 23.504 37.596C22.802 38.22 21.398 38.532 19.318 38.532L18.512 35.802C19.474 35.906 20.28 35.984 20.956 35.984C21.372 35.958 21.658 35.828 21.814 35.62C21.918 35.464 21.97 35.048 21.996 34.398C21.97 32.786 20.982 30.68 19.032 28.054C19.864 26.156 20.67 23.868 21.45 21.164H17.914V41.73H15.34V18.772ZM27.716 27.326H31.616V24.83H34.346V27.326H37.57V29.926H34.346V30.446C35.542 31.538 36.79 32.734 38.038 34.06L36.53 36.348C35.698 35.048 34.97 33.93 34.346 33.046V41.756H31.616V33.202C30.654 35.23 29.432 37.102 27.924 38.818L26.754 35.776C28.756 34.06 30.238 32.11 31.226 29.926H27.716V27.326ZM49.4 25.48V41.73H46.774V40.82H41.106V41.73H38.48V25.48H49.4ZM41.106 38.428H46.774V36.244H41.106V38.428ZM41.106 33.956H46.774V32.058H41.106V33.956ZM41.106 29.77H46.774V27.872H41.106V29.77ZM31.538 21.762C30.966 22.75 30.316 23.634 29.614 24.466L27.248 22.958C28.782 21.294 29.874 19.5 30.498 17.576L33.124 18.148C32.968 18.564 32.838 18.98 32.682 19.37H38.974V21.762H35.568C36.088 22.49 36.504 23.192 36.842 23.842L34.346 24.778C33.878 23.738 33.306 22.724 32.682 21.762H31.538ZM42.64 21.762C42.12 22.828 41.574 23.816 40.95 24.726L38.636 23.244C39.962 21.424 40.898 19.474 41.444 17.446L44.018 18.018C43.862 18.486 43.732 18.928 43.602 19.37H50.83V21.762H46.67C47.19 22.49 47.632 23.192 47.97 23.842L45.578 24.752C45.11 23.712 44.538 22.724 43.862 21.762H42.64ZM57.538 28.522H72.566V35.282H57.538V28.522ZM69.836 32.89V30.888H60.268V32.89H69.836ZM60.45 35.438C61.282 36.296 62.036 37.31 62.712 38.454H67.626C68.354 37.466 68.978 36.426 69.524 35.36L72.046 36.27C71.578 37.05 71.084 37.778 70.564 38.454H76.232V41.028H53.716V38.454H59.826C59.28 37.726 58.63 37.05 57.902 36.4L60.45 35.438ZM56.368 21.112C57.564 21.996 58.63 22.854 59.514 23.686C60.424 22.802 61.152 21.866 61.724 20.878H55.822V18.382H64.792V20.41C64.194 21.918 63.388 23.27 62.374 24.466H68.822C67.262 22.75 66.014 20.904 65.104 18.876L67.366 17.628C67.782 18.59 68.276 19.5 68.848 20.358C69.758 19.63 70.538 18.85 71.188 18.018L73.086 19.708C72.306 20.644 71.37 21.528 70.304 22.308C70.72 22.828 71.188 23.296 71.708 23.764C72.8 22.932 73.71 21.996 74.49 20.982L76.388 22.646C75.608 23.634 74.672 24.544 73.632 25.35C74.776 26.182 76.024 26.962 77.428 27.664L75.634 29.744C73.606 28.6 71.838 27.352 70.33 25.974V26.936H60.788V26.104C59.124 27.56 57.07 28.782 54.626 29.796L52.962 27.664C54.782 26.962 56.316 26.156 57.616 25.246C56.758 24.466 55.744 23.66 54.548 22.828L56.368 21.112ZM82.368 18.408H97.864V26.806H102.258V29.276H98.228L100.282 30.966C98.93 32.63 97.396 33.956 95.68 34.892C97.604 36.296 99.84 37.518 102.388 38.61L101.01 41.002C97.37 39.286 94.432 37.232 92.196 34.814V38.974C92.196 40.794 91.39 41.73 89.804 41.73H86.762L86.164 39.182C87.1 39.286 88.01 39.364 88.894 39.364C89.284 39.364 89.492 39 89.492 38.324V34.918C86.944 37.154 83.928 39.156 80.47 40.95L79.378 38.428C83.278 36.66 86.632 34.58 89.492 32.136V29.276H79.768V26.806H95.108V25.012H83.252V22.672H95.108V20.852H82.368V18.408ZM83.018 29.666C84.526 30.706 85.8 31.746 86.84 32.786L85.072 34.554C84.162 33.566 82.888 32.526 81.224 31.382L83.018 29.666ZM98.176 29.276H92.196V31.824C92.69 32.37 93.236 32.89 93.834 33.41C95.498 32.422 96.954 31.044 98.176 29.276Z" />
</g>
<!-- 分隔线 -->
<path d="M124 18.75V40.25" stroke="#9EA9B6"/>
<!-- 密码登录 -->
<g class="tab-password" :class="{ active: loginType === 'password' }" @click="loginType = 'password'" style="cursor: pointer;">
<path d="M155.362 18.46V35.126H152.996V20.956H148.212V35.126H145.768V18.46H155.362ZM149.434 22.49H151.722V31.018C151.644 33.93 151.202 36.27 150.37 38.012C149.564 39.65 148.264 40.898 146.47 41.782L145.014 39.494C146.704 38.636 147.848 37.57 148.472 36.322C149.044 34.944 149.356 33.176 149.434 31.018V22.49ZM152.684 35.724C153.984 37.05 155.076 38.35 155.986 39.624L154.036 41.574C153.308 40.274 152.294 38.896 150.942 37.414L152.684 35.724ZM162.044 30.732H160.328V38.298C161.342 37.882 162.33 37.362 163.318 36.738L163.786 39.156C162.122 40.196 160.224 41.028 158.092 41.704L156.974 39.286C157.442 39.052 157.676 38.688 157.676 38.22V30.732H156.064V28.132H157.676V17.68H160.328V28.132H168.622V30.732H164.384C165.528 34.45 167.14 37.336 169.168 39.364L167.322 41.47C165.008 39.026 163.24 35.438 162.044 30.732ZM166.23 18.746L168.31 20.41C166.516 23.322 164.436 25.506 162.044 26.91L160.588 24.83C162.772 23.478 164.67 21.45 166.23 18.746ZM174.966 18.356H191.034V26.026H174.966V18.356ZM188.278 23.608V20.8H177.722V23.608H188.278ZM176.76 30.16H171.118V27.534H194.856V30.16H179.516L178.814 32.422H191.372C191.164 36.894 190.748 39.546 190.072 40.378C189.396 41.184 188.122 41.6 186.198 41.6C184.924 41.6 183.78 41.522 182.766 41.392L181.882 38.922C183.286 39.052 184.508 39.13 185.6 39.13C186.874 39.13 187.654 38.87 187.966 38.402C188.252 37.908 188.46 36.738 188.59 34.866H175.564L176.76 30.16ZM201.538 28.522H216.566V35.282H201.538V28.522ZM213.836 32.89V30.888H204.268V32.89H213.836ZM204.45 35.438C205.282 36.296 206.036 37.31 206.712 38.454H211.626C212.354 37.466 212.978 36.426 213.524 35.36L216.046 36.27C215.578 37.05 215.084 37.778 214.564 38.454H220.232V41.028H197.716V38.454H203.826C203.28 37.726 202.63 37.05 201.902 36.4L204.45 35.438ZM200.368 21.112C201.564 21.996 202.63 22.854 203.514 23.686C204.424 22.802 205.152 21.866 205.724 20.878H199.822V18.382H208.792V20.41C208.194 21.918 207.388 23.27 206.374 24.466H212.822C211.262 22.75 210.014 20.904 209.104 18.876L211.366 17.628C211.782 18.59 212.276 19.5 212.848 20.358C213.758 19.63 214.538 18.85 215.188 18.018L217.086 19.708C216.306 20.644 215.37 21.528 214.304 22.308C214.72 22.828 215.188 23.296 215.708 23.764C216.8 22.932 217.71 21.996 218.49 20.982L220.388 22.646C219.608 23.634 218.672 24.544 217.632 25.35C218.776 26.182 220.024 26.962 221.428 27.664L219.634 29.744C217.606 28.6 215.838 27.352 214.33 25.974V26.936H204.788V26.104C203.124 27.56 201.07 28.782 198.626 29.796L196.962 27.664C198.782 26.962 200.316 26.156 201.616 25.246C200.758 24.466 199.744 23.66 198.548 22.828L200.368 21.112ZM226.368 18.408H241.864V26.806H246.258V29.276H242.228L244.282 30.966C242.93 32.63 241.396 33.956 239.68 34.892C241.604 36.296 243.84 37.518 246.388 38.61L245.01 41.002C241.37 39.286 238.432 37.232 236.196 34.814V38.974C236.196 40.794 235.39 41.73 233.804 41.73H230.762L230.164 39.182C231.1 39.286 232.01 39.364 232.894 39.364C233.284 39.364 233.492 39 233.492 38.324V34.918C230.944 37.154 227.928 39.156 224.47 40.95L223.378 38.428C227.278 36.66 230.632 34.58 233.492 32.136V29.276H223.768V26.806H239.108V25.012H227.252V22.672H239.108V20.852H226.368V18.408ZM227.018 29.666C228.526 30.706 229.8 31.746 230.84 32.786L229.072 34.554C228.162 33.566 226.888 32.526 225.224 31.382L227.018 29.666ZM242.176 29.276H236.196V31.824C236.69 32.37 237.236 32.89 237.834 33.41C239.498 32.422 240.954 31.044 242.176 29.276Z" />
</g>
</svg>
</div>
<!-- 登录表单 -->
@@ -38,31 +46,28 @@
@keyup.enter="handleLogin"
/>
<div class="input-error" v-if="errors.email">{{ errors.email }}</div>
<!-- 快捷输入标签 -->
<div class="quick-email-tags">
<span class="email-tag" @click="fillQuickEmail('984523799@qq.com')">984523799@qq.com</span>
</div>
</div>
<!-- 验证码输入仅验证码登录显示 -->
<div class="code-input-group" v-if="loginType === 'email'">
<div class="code-input-wrapper" v-if="loginType === 'email'">
<el-input
ref="codeInput"
v-model="loginForm.code"
placeholder="请输入验证码"
class="code-input"
@keyup.enter="handleLogin"
/>
<div class="input-error" v-if="errors.code">{{ errors.code }}</div>
<el-button
type="primary"
plain
class="get-code-btn"
:disabled="countdown > 0 || !isEmailValid"
@click="getEmailCode"
>
{{ countdown > 0 ? `${countdown}s` : '获取验证码' }}
</el-button>
<template #suffix>
<span
class="get-code-text"
:class="{ disabled: countdown > 0 || !isEmailValid }"
@click="getEmailCode"
>
{{ countdown > 0 ? `${countdown}s` : '获取验证码' }}
</span>
</template>
</el-input>
<div class="input-error" v-if="errors.code">{{ errors.code }}</div>
</div>
<!-- 密码输入仅密码登录显示 -->
@@ -84,21 +89,8 @@
<!-- 协议文字 -->
<p class="agreement-text">
登录即表示您同意遵守用户协议和隐私政策
登录即表示您同意遵守<router-link to="/user-agreement" class="agreement-link">用户协议</router-link><router-link to="/privacy-policy" class="agreement-link">隐私政策</router-link>
</p>
<!-- 测试邮箱提示 -->
<div class="test-accounts">
<el-divider>测试邮箱</el-divider>
<div class="account-list">
<div class="account-item" @click="fillTestAccount('admin@example.com', '123456')">
<strong>管理员:</strong> admin@example.com
</div>
<div class="account-item" @click="fillTestAccount('13689270819@example.com', '123456')">
<strong>普通用户:</strong> 13689270819@example.com
</div>
</div>
</div>
</div>
</div>
</div>
@@ -109,7 +101,7 @@ import { ref, reactive, onMounted, computed, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { ElMessage } from 'element-plus'
import { loginWithEmail, login, sendEmailCode, setDevEmailCode } from '@/api/auth'
import { loginWithEmail, login, sendEmailCode, setDevEmailCode, getCurrentUser } from '@/api/auth'
const router = useRouter()
const route = useRoute()
@@ -168,36 +160,12 @@ const clearForm = async () => {
}
// 快速填充测试账号
const fillTestAccount = async (email, code) => {
loginForm.email = email
// 根据当前登录方式,将第二个参数作为验证码或密码
if (loginType.value === 'password') {
loginForm.password = code
await nextTick()
passwordInput.value && passwordInput.value.focus && passwordInput.value.focus()
} else {
loginForm.code = code
await nextTick()
codeInput.value && codeInput.value.focus && codeInput.value.focus()
}
}
// 快速填充邮箱(快捷输入)
const fillQuickEmail = (email) => {
loginForm.email = email
}
// 组件挂载时设置默认测试账号或从URL参数读取邮箱
// 组件挂载时从URL参数读取邮箱
onMounted(() => {
// 从URL参数中读取邮箱
if (route.query.email) {
loginForm.email = route.query.email
} else {
// 设置默认的测试邮箱
loginForm.email = 'admin@example.com'
}
// 不设置验证码,让用户手动输入
})
@@ -314,10 +282,32 @@ const handleLogin = async () => {
if (response && response.data && response.data.success) {
// 保存用户信息和token
sessionStorage.setItem('token', response.data.data.token)
sessionStorage.setItem('user', JSON.stringify(response.data.data.user))
userStore.user = response.data.data.user
userStore.token = response.data.data.token
const loginUser = response.data.data.user
const loginToken = response.data.data.token
sessionStorage.setItem('token', loginToken)
sessionStorage.setItem('user', JSON.stringify(loginUser))
userStore.user = loginUser
userStore.token = loginToken
// 默认不要求设置密码
sessionStorage.removeItem('needSetPassword')
// 额外调用 /auth/me 获取真实的密码状态(避免后端出于安全清空 passwordHash
try {
const meResp = await getCurrentUser()
const meData = meResp.data
if (meData && meData.success && meData.data) {
const userFromMe = meData.data
const pwd = userFromMe.passwordHash
if (!pwd || String(pwd).trim() === '') {
// 当前用户还没有设置密码,标记为需要设置密码
sessionStorage.setItem('needSetPassword', '1')
}
}
} catch (e) {
// 获取用户信息失败时忽略,正常继续登录流程
console.warn('获取当前用户信息用于检测密码状态失败:', e)
}
console.log('登录成功,用户信息:', userStore.user)
ElMessage.success('登录成功')
@@ -325,9 +315,10 @@ const handleLogin = async () => {
// 等待一下确保状态更新
await new Promise(resolve => setTimeout(resolve, 200))
// 跳转到原始路径或个人主页
const redirectPath = route.query.redirect || '/profile'
console.log('准备跳转到:', redirectPath)
// 如果需要设置密码,优先跳转到个人主页,由个人主页负责弹出修改密码弹窗
const needSetPassword = sessionStorage.getItem('needSetPassword') === '1'
const redirectPath = needSetPassword ? '/profile' : (route.query.redirect || '/profile')
console.log('准备跳转到:', redirectPath, '需要设置密码:', needSetPassword)
// 使用replace而不是push避免浏览器历史记录问题
await router.replace(redirectPath)
@@ -350,7 +341,7 @@ const handleLogin = async () => {
<style scoped>
.login-page {
min-height: 100vh;
width: 100vw;
width: 100%;
height: 100vh;
background: url('/images/backgrounds/login-bg.svg') center/cover no-repeat;
position: fixed;
@@ -382,44 +373,67 @@ const handleLogin = async () => {
top: 50%;
right: 145px;
transform: translateY(-50%);
width: 800px;
width: 773px;
height: 796px;
max-width: 90vw;
background: rgba(121, 121, 121, 0.1);
backdrop-filter: blur(50px) saturate(180%);
-webkit-backdrop-filter: blur(50px) saturate(180%);
backdrop-filter: blur(50px);
-webkit-backdrop-filter: blur(50px);
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.5),
0 0 0 1px rgba(255, 255, 255, 0.05) inset;
padding: 50px;
padding: 80px 82px;
z-index: 10;
overflow: hidden;
}
.login-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.15), transparent);
opacity: 0.8;
}
/* 卡片内Logo */
.card-logo {
text-align: center;
margin-bottom: 40px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
justify-content: flex-start;
}
.card-logo svg {
width: auto;
height: 40px;
/* 欢迎标题 */
.welcome-title {
text-align: center;
margin-bottom: 50px;
font-size: 36px;
font-weight: 500;
}
.welcome-text {
color: rgba(255, 255, 255, 0.9);
margin-right: 8px;
}
.brand-name {
color: #00D4FF;
font-weight: 600;
}
/* 登录方式切换 */
.login-tabs {
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 50px;
}
.tabs-svg {
width: 248px;
height: 59px;
}
.tab-email path,
.tab-password path {
fill: #9EA9B6;
transition: fill 0.3s ease;
}
.tab-email.active path,
.tab-password.active path {
fill: white;
}
.tab-email:hover path,
.tab-password:hover path {
fill: rgba(255, 255, 255, 0.8);
}
/* 登录表单 */
@@ -429,56 +443,9 @@ const handleLogin = async () => {
gap: 25px;
}
/* 登录标题 */
.login-title {
text-align: center;
margin-bottom: 20px;
}
.login-subtitle {
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
margin: 0;
text-align: center;
}
/* 登录方式切换 */
.login-methods {
display: inline-flex;
gap: 8px;
}
.method-btn {
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08);
color: rgba(255, 255, 255, 0.7);
padding: 8px 16px;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
font-weight: 500;
}
.method-btn:hover {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.12);
color: rgba(255, 255, 255, 0.85);
}
.method-btn.active {
background: rgba(64, 158, 255, 0.15);
border-color: rgba(64, 158, 255, 0.3);
color: #66B1FF;
}
.password-input-group {
margin-top: 10px;
}
/* 邮箱输入组 */
.email-input-group {
margin-bottom: 20px;
margin-bottom: 0;
}
.email-input {
@@ -515,27 +482,25 @@ const handleLogin = async () => {
}
.email-input :deep(.el-input__wrapper) {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(217, 217, 217, 0.2);
border: none;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
height: 55px;
box-shadow: none;
height: 80px;
transition: all 0.3s ease;
}
.email-input :deep(.el-input__wrapper:hover) {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.15);
background: rgba(217, 217, 217, 0.25);
}
.email-input :deep(.el-input__wrapper.is-focus) {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(64, 158, 255, 0.4);
box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
background: rgba(217, 217, 217, 0.3);
box-shadow: none;
}
.email-input :deep(.el-input__inner) {
color: white;
color: rgba(255, 255, 255, 0.5);
background: transparent;
font-size: 16px;
}
@@ -545,37 +510,31 @@ const handleLogin = async () => {
}
/* 验证码输入组 */
.code-input-group {
display: flex;
gap: 12px;
}
.code-input {
flex: 1;
.code-input-wrapper {
margin-top: 30px;
}
.code-input :deep(.el-input__wrapper) {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(217, 217, 217, 0.2);
border: none;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
height: 55px;
box-shadow: none;
height: 80px;
transition: all 0.3s ease;
padding-right: 15px;
}
.code-input :deep(.el-input__wrapper:hover) {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.15);
background: rgba(217, 217, 217, 0.25);
}
.code-input :deep(.el-input__wrapper.is-focus) {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(64, 158, 255, 0.4);
box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
background: rgba(217, 217, 217, 0.3);
box-shadow: none;
}
.code-input :deep(.el-input__inner) {
color: white;
color: rgba(255, 255, 255, 0.5);
background: transparent;
font-size: 16px;
}
@@ -584,31 +543,56 @@ const handleLogin = async () => {
color: rgba(255, 255, 255, 0.5);
}
.get-code-btn {
background: rgba(64, 158, 255, 0.12);
border: 1px solid rgba(64, 158, 255, 0.3);
color: #66B1FF;
border-radius: 10px;
padding: 0 20px;
font-size: 16px;
height: 55px;
transition: all 0.3s ease;
font-weight: 500;
.get-code-text {
color: #00D4FF;
font-size: 14px;
cursor: pointer;
user-select: none;
white-space: nowrap;
transition: opacity 0.3s ease;
}
.get-code-btn:hover {
background: rgba(64, 158, 255, 0.85);
border-color: rgba(64, 158, 255, 0.8);
color: white;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.25);
.get-code-text:hover {
opacity: 0.8;
}
.get-code-btn:disabled {
.get-code-text.disabled {
opacity: 0.5;
cursor: not-allowed;
}
.password-input-group {
margin-top: 30px;
}
.password-input-group :deep(.el-input__wrapper) {
background: rgba(217, 217, 217, 0.2);
border: none;
border-radius: 10px;
box-shadow: none;
height: 80px;
transition: all 0.3s ease;
}
.password-input-group :deep(.el-input__wrapper:hover) {
background: rgba(217, 217, 217, 0.25);
}
.password-input-group :deep(.el-input__wrapper.is-focus) {
background: rgba(217, 217, 217, 0.3);
box-shadow: none;
}
.password-input-group :deep(.el-input__inner) {
color: rgba(255, 255, 255, 0.5);
background: transparent;
font-size: 16px;
}
.password-input-group :deep(.el-input__inner::placeholder) {
color: rgba(255, 255, 255, 0.5);
}
.input-error {
color: #ff7875;
font-size: 12px;
@@ -619,22 +603,20 @@ const handleLogin = async () => {
/* 登录按钮 */
.login-button {
width: 100%;
height: 52px;
background: linear-gradient(135deg, #409EFF 0%, #66B1FF 100%);
height: 80px;
background: #0DC0FF;
border: none;
border-radius: 10px;
color: white;
font-size: 16px;
font-weight: 600;
margin-top: 15px;
font-size: 18px;
font-weight: 500;
margin-top: 30px;
transition: all 0.3s ease;
box-shadow: 0 4px 16px rgba(64, 158, 255, 0.25);
}
.login-button:hover {
background: linear-gradient(135deg, #66B1FF 0%, #409EFF 100%);
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(64, 158, 255, 0.35);
background: #4DD4FF;
transform: translateY(-1px);
}
.login-button:active {
@@ -644,50 +626,25 @@ const handleLogin = async () => {
/* 协议文字 */
.agreement-text {
text-align: center;
color: rgba(255, 255, 255, 0.5);
font-size: 14px;
margin: 25px 0 0 0;
line-height: 1.4;
}
/* 测试账号提示 */
.test-accounts {
margin-top: 30px;
}
.test-accounts :deep(.el-divider__text) {
color: rgba(255, 255, 255, 0.6);
color: rgba(255, 255, 255, 0.4);
font-size: 12px;
margin: 20px 0 0 0;
line-height: 30px;
width: 266px;
height: 30px;
margin-left: auto;
margin-right: auto;
}
.account-list {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 15px;
.agreement-link {
color: #00D4FF;
text-decoration: none;
transition: opacity 0.3s ease;
}
.account-item {
font-size: 12px;
color: rgba(255, 255, 255, 0.75);
padding: 8px 14px;
background: rgba(255, 255, 255, 0.04);
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, 0.08);
cursor: pointer;
transition: all 0.3s ease;
}
.account-item:hover {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.12);
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
.account-item strong {
color: #409EFF;
margin-right: 8px;
.agreement-link:hover {
opacity: 0.8;
text-decoration: underline;
}
/* 响应式设计 */
@@ -695,6 +652,7 @@ const handleLogin = async () => {
.login-card {
right: 5%;
width: 450px;
height: auto;
}
}
@@ -707,6 +665,7 @@ const handleLogin = async () => {
margin: 50px auto;
width: 90%;
max-width: 500px;
height: auto;
}
.logo {
@@ -722,6 +681,7 @@ const handleLogin = async () => {
@media (max-width: 480px) {
.login-card {
padding: 40px 25px;
height: auto;
}
.code-input-group {