Files
dudu/desktop/src/shared/WindowFrame.jsx
T
wangjia 19281d9c42
ci / server (push) Failing after 10s
ci / design-system (push) Failing after 10s
feat(auth+desktop): 邮箱验证码登录 + 登录窗改版(微信/邮箱双方式,无边框)
后端(协议 → 存储 → 接口,E2E 测试全绿):
- protocol:AuthEmailCodeRequest / AuthEmailRequest DTO
- store:EmailIdentity 表(邮箱唯一索引)+ authmail:* Redis key
- auth/email.go:POST /v1/auth/email/code 发 6 位码(crypto/rand,
  60s 冷却 SetNX,10 分钟 TTL);POST /v1/auth/email 常量时间比对、
  码一次性、邮箱建号(昵称取前缀)→ JWT(与微信登录同响应形态)
- Mailer 接口 + MockMailer(验证码打日志供联调;SMTP 未配置自动降级,
  装配结果入启动日志,上线前须换真实实现)
- TestEmailLogin E2E:发码/冷却 429/错码拒绝/登录/token 可用/码防复用

桌面(Rust 命令 + UI 改版):
- api.rs:login_email_code / login_email(成功保存 token + ws 重连,
  与扫码登录同路径)
- 登录窗改版(原型 LoginPurchase 先行,dark 截图验收):logo + 分段
  切换(微信扫码 / 邮箱登录,与设置页同控件语言)+ 邮箱表单
  (60s 倒计时、错误文案、未注册自动建号提示)
- 二维码真渲染:qrcode 库画 canvas(前景/背景取主题 token),
  替换原 URL 文本占位;过期态半透明化
- 登录窗无边框化:transparent + Overlay 标题栏 + 原生贴形阴影;
  抽公共 WindowFrame 组件(设置窗同步重构复用)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 09:40:16 +08:00

32 lines
1.5 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// WindowFrame:透明窗口的自绘 MacWindow 框(对齐原型 DesktopShared.MacWindow 规格)。
// 窗口须配 transparent + titleBarStyle Overlay + hiddenTitle + trafficLightPosition {18,18}
// 阴影用 macOS 原生(贴合内容圆角),窗口即卡片实际尺寸。设置 / 登录等窗口共用。
export function WindowFrame({ title, children }) {
return (
<div style={{
fontFamily: 'var(--font-sans)', position: 'fixed', inset: 0,
background: 'var(--bg-app)', borderRadius: 'var(--radius-md)',
border: '1px solid var(--border-1)',
overflow: 'hidden', display: 'flex', flexDirection: 'column',
}}>
{/* 自绘顶条:系统红绿灯悬浮左上,标题绝对居中(mac 原生习惯);整条可拖拽 */}
<div
data-tauri-drag-region
style={{
position: 'relative', height: 36, flex: 'none', display: 'flex', alignItems: 'center',
background: 'var(--surface-2)', borderBottom: '1px solid var(--border-1)',
userSelect: 'none', WebkitUserSelect: 'none', cursor: 'default',
}}
>
<span style={{
position: 'absolute', left: '50%', transform: 'translateX(-50%)', pointerEvents: 'none',
fontSize: 'var(--text-xs)', fontWeight: 'var(--weight-medium)', color: 'var(--text-2)',
}}>{title}</span>
</div>
<div style={{ overflowY: 'auto', flex: 1, display: 'flex', flexDirection: 'column' }}>
{children}
</div>
</div>
);
}