diff --git a/.kiro/steering/project-guidelines.md b/.kiro/steering/project-guidelines.md index c3321bf..7d33cdd 100644 --- a/.kiro/steering/project-guidelines.md +++ b/.kiro/steering/project-guidelines.md @@ -16,7 +16,7 @@ inclusion: always ## 编码规范 - 颜色用尽量用variables.scss里的统一颜色变量,特别是背景,按钮,文字的颜色 -- 除了Home.vue首页外,其他页面我上传了截图要写页面或组件的,需要参考图片里文字和布局结构,在保证美观前提上自由发挥 +- 除了Home.vue首页外,其他页面我上传了截图要写页面或组件的,需要参考图片里文字和布局结构,在保证美观前提上自由发挥(如果我粘贴了图片内容里的完整样式过来,那就要参考我给的样式结合图片里的结构和样式代码保证还原度) - 全局用1rem=100px的格式并注意对某些特殊元素组件的line-height行高影响,纵布局如非必要不用flex-direction: column布局 - 如果是建一个组件,这个组件看我说是用在views里哪个页面的,比如用在Profile.vue里的组件,组件名字最前面要加Profile,而且整个组件的命名不能过度简化,要容易看懂组件的用途;如果检测到某种名字开头的组件数量比如Profile开头的超过15个,就在components里新建个类似profile这样的页面名字的文件夹,把这类命名的组件都移到文件夹里并查找更新组件所有被引用地方的文件地址 diff --git a/src/App.vue b/src/App.vue index 0ab3184..090ef25 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,13 +1,11 @@ diff --git a/src/assets/styles/pages/login.scss b/src/assets/styles/pages/login.scss index 9c1aca6..89720ad 100644 --- a/src/assets/styles/pages/login.scss +++ b/src/assets/styles/pages/login.scss @@ -1,87 +1,421 @@ -.login-dialog { - width: 6rem; - .el-dialog__header { - padding: 0.16rem 0.16rem 0; - margin-right: 0; - } - - .el-dialog__body { - padding: 0 0.4rem 0.4rem; - } +/* 登录页面 — 左右分栏全屏布局 */ +.login-view { + font-size: 0.14rem; + display: flex; + align-items: flex-start; + width: 100%; + height: var(--app-height, 100vh); + background: #F7FEFC; } -.login-page { +/* ==================== 左侧品牌面板 ==================== */ +.login-view__left { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 57%; + height: 100%; + background: linear-gradient(180deg, #0A9E97 0%, #12C7BE 50%, #06B6D4 100%); + position: relative; + overflow: hidden; +} + +/* 装饰圆圈 */ +.login-view__deco-circle { + border-radius: 50%; + position: absolute; +} + +.login-view__deco-circle--lg { + width: 4.8rem; + height: 4.8rem; + background: rgba(255, 255, 255, 0.06); + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.login-view__deco-circle--sm { + width: 3.2rem; + height: 3.2rem; + background: rgba(255, 255, 255, 0.08); + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +/* 左侧中心内容 */ +.login-view__left-content { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 0.32rem; + position: relative; + z-index: 1; +} + +/* Logo 行 */ +.login-view__logo-row { + display: flex; + align-items: center; + gap: 0.12rem; +} + +.login-view__logo-box { + display: flex; + justify-content: center; + align-items: center; + width: 0.56rem; + height: 0.56rem; + border-radius: 0.16rem; + font-weight: 700; + font-size: 0.22rem; + line-height: 1; +} + +.login-view__logo-box--light { + background: rgba(255, 255, 255, 0.2); + color: #FFFFFF; +} + +.login-view__logo-box--green { + background: rgba(9, 170, 119, 0.2); + color: #351616; +} + +.login-view__logo-text { + font-weight: 700; + font-size: 0.28rem; + line-height: 0.34rem; +} + +.login-view__logo-text--white { + color: #FFFFFF; +} + +.login-view__logo-text--dark { + color: #351616; +} + +/* 标语 */ +.login-view__slogan { + font-weight: 700; + font-size: 0.4rem; + line-height: 0.56rem; text-align: center; + color: #FFFFFF; +} - .login-title { - font-size: 0.28rem; - font-weight: 700; - color: #1a1a2e; - margin-bottom: 0.4rem; - } +.login-view__sub-slogan { + font-weight: 400; + font-size: 0.16rem; + line-height: 0.19rem; + text-align: center; + color: rgba(255, 255, 255, 0.85); +} - .login-form { - display: flex; - flex-direction: column; - gap: 0.16rem; - } +/* 特性药丸标签 */ +.login-view__pills { + display: flex; + flex-direction: column; + align-items: center; + padding-top: 0.24rem; + gap: 0.12rem; +} - .login-input { - height: 0.4rem; - .el-input__wrapper { - background-color: #f5f5f7; - border-radius: 0.08rem; - box-shadow: none; - padding: 0.00rem 0.16rem; - } - } +.login-view__pill { + display: flex; + align-items: center; + padding: 0.12rem 0.2rem; + gap: 0.08rem; + background: rgba(255, 255, 255, 0.15); + border-radius: 0.24rem; + font-weight: 500; + font-size: 0.14rem; + line-height: 0.17rem; + color: #FFFFFF; +} - .code-row { - display: flex; - align-items: center; - gap: 0.12rem; +/* ==================== 右侧表单面板 ==================== */ +.login-view__right { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 43%; + height: 100%; + background: #F6FDFB; +} - .login-input { - flex: 1; - } +.login-view__logo-row--right { + margin-bottom: 0.4rem; +} - .send-code-btn { - white-space: nowrap; - border-radius: 0.2rem; - padding: 0.08rem 0.2rem; - font-size: 0.14rem; - } - } +/* 表单包裹 */ +.login-view__form-wrap { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.28rem; + width: 4rem; +} - .login-btn { - margin-top: 0.16rem; - width: 100%; - height: 0.52rem; - border-radius: 0.26rem; - font-size: 0.18rem; - font-weight: 600; - background-color: #1a1a2e; - border-color: #1a1a2e; +/* 标题 */ +.login-view__heading { + width: 100%; + display: flex; + flex-direction: column; + gap: 0.1rem; +} - &:hover, - &:focus { - background-color: #2d2d44; - border-color: #2d2d44; - } - } +.login-view__title { + font-weight: 700; + font-size: 0.32rem; + line-height: 0.39rem; + color: #132034; +} - .register-link { - margin-top: 0.08rem; - font-size: 0.14rem; - color: #666; +.login-view__subtitle { + font-weight: 400; + font-size: 0.15rem; + line-height: 0.18rem; + color: #64748B; +} - a { - color: #409eff; - text-decoration: none; +/* ==================== 手机号输入行 ==================== */ +.login-view__phone-row { + display: flex; + align-items: center; + width: 100%; + height: 0.52rem; + border-radius: 0.12rem; + overflow: hidden; +} - &:hover { - text-decoration: underline; - } - } +.login-view__country-code { + display: flex; + align-items: center; + padding: 0 0.16rem; + gap: 0.06rem; + width: 0.96rem; + height: 100%; + background: #F3FFFD; + border: 1px solid #BFE8E2; + border-radius: 0.12rem 0 0 0.12rem; + cursor: pointer; +} + +.login-view__flag { + font-size: 0.16rem; + line-height: 1; +} + +.login-view__code-text { + font-weight: 500; + font-size: 0.15rem; + line-height: 0.18rem; + color: #132034; +} + +.login-view__code-arrow { + font-size: 0.11rem; + color: #94A3B8; +} + +.login-view__separator { + width: 1px; + height: 100%; + background: #BFE8E2; +} + +.login-view__phone-input { + flex: 1; + height: 100%; + padding: 0 0.16rem; + background: #FAFBFC; + border: 1px solid #E2E8F0; + border-left: none; + border-radius: 0 0.12rem 0.12rem 0; + font-size: 0.15rem; + color: #132034; + outline: none; + + &::placeholder { + color: #94A3B8; + } +} + +/* ==================== 发送验证码按钮(步骤一) ==================== */ +.login-view__send-btn { + width: 100%; + height: 0.52rem; + background: linear-gradient(90deg, #12C7BE 0%, #06B6D4 100%); + border-radius: 0.12rem; + border: none; + font-weight: 600; + font-size: 0.16rem; + color: #FFFFFF; + cursor: pointer; + transition: opacity 0.2s; + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + &:not(:disabled):hover { + opacity: 0.9; + } +} + +/* ==================== OTP 验证码输入(步骤二) ==================== */ +.login-view__otp-wrap { + position: relative; + display: flex; + align-items: flex-start; + gap: 0.1rem; + width: 100%; + cursor: text; +} + +.login-view__otp-hidden-input { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + z-index: 2; + font-size: 0.16rem; + caret-color: transparent; +} + +.login-view__otp-box { + display: flex; + justify-content: center; + align-items: center; + width: 0.56rem; + height: 0.64rem; + background: #FAFBFC; + border: 1px solid #E2E8F0; + border-radius: 0.12rem; + transition: border-color 0.2s, background 0.2s; +} + +.login-view__otp-box--active { + background: #F3FFFD; + border: 2px solid #12C7BE; +} + +.login-view__otp-box--filled { + background: #F3FFFD; + border: 2px solid #12C7BE; +} + +.login-view__otp-digit { + font-weight: 700; + font-size: 0.24rem; + line-height: 0.29rem; + color: #132034; +} + +/* 闪烁光标 */ +.login-view__otp-cursor { + display: inline-block; + width: 2px; + height: 0.28rem; + background: #12C7BE; + border-radius: 1px; + animation: login-otp-blink 1s ease-in-out infinite; +} + +@keyframes login-otp-blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } +} + +/* ==================== 状态按钮(步骤二) ==================== */ +.login-view__status-btn { + width: 100%; + height: 0.52rem; + background: linear-gradient(90deg, #12C7BE 0%, #06B6D4 100%); + border-radius: 0.12rem; + border: none; + font-weight: 600; + font-size: 0.16rem; + color: #FFFFFF; + cursor: default; + display: flex; + align-items: center; + justify-content: center; + gap: 0.08rem; +} + +/* 登录中转圈动画 */ +.login-view__spinner { + display: inline-block; + width: 0.18rem; + height: 0.18rem; + border: 2px solid rgba(255, 255, 255, 0.3); + border-top-color: #FFFFFF; + border-radius: 50%; + animation: login-spin 0.7s linear infinite; +} + +@keyframes login-spin { + to { transform: rotate(360deg); } +} + +/* ==================== 协议勾选 ==================== */ +.login-view__agreement { + display: flex; + align-items: center; + gap: 0.06rem; +} + +.login-view__checkbox { + box-sizing: border-box; + width: 0.18rem; + height: 0.18rem; + background: #FFFFFF; + border: 1.5px solid #CBD5E1; + border-radius: 0.05rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s; +} + +.login-view__checkbox--checked { + background: #12C7BE; + border-color: #12C7BE; +} + +.login-view__check-icon { + font-size: 0.11rem; + color: #FFFFFF; + font-weight: 700; + line-height: 1; +} + +.login-view__agreement-text { + font-weight: 400; + font-size: 0.12rem; + line-height: 0.15rem; + color: #94A3B8; +} + +.login-view__agreement-link { + font-weight: 500; + font-size: 0.12rem; + line-height: 0.15rem; + color: #12C7BE; + cursor: pointer; + + &:hover { + text-decoration: underline; } } diff --git a/src/components/LoginDialog.vue b/src/components/LoginDialog.vue index 78c3c44..59ce36c 100644 --- a/src/components/LoginDialog.vue +++ b/src/components/LoginDialog.vue @@ -1,4 +1,8 @@