diff --git a/app/web.py b/app/web.py index 39fda8a..a2da283 100644 --- a/app/web.py +++ b/app/web.py @@ -74,6 +74,8 @@ async def index(request: Request): return templates.TemplateResponse("index.html", {"request": request}) + + @app.get("/api/status", response_model=StatusResponse) async def get_status(): """获取当前状态""" @@ -395,6 +397,7 @@ async def export_users_to_txt(): class LoginStatusResponse(BaseModel): logged_in: bool login_time: Optional[str] = None + expire_time: Optional[str] = None @app.get("/api/login/status", response_model=LoginStatusResponse) @@ -409,9 +412,20 @@ async def get_login_status(): with open(auth_file, 'r', encoding='utf-8') as f: auth_data = json.load(f) + # 检查是否过期 + login_time = auth_data.get("login_time") + expire_time = auth_data.get("expire_time") + current_time = datetime.now().isoformat() + + if expire_time and current_time > expire_time: + # 登录已过期,清除状态 + os.remove(auth_file) + return LoginStatusResponse(logged_in=False) + return LoginStatusResponse( logged_in=auth_data.get("logged_in", False), - login_time=auth_data.get("login_time") + login_time=login_time, + expire_time=expire_time ) except Exception: return LoginStatusResponse(logged_in=False) @@ -419,12 +433,35 @@ async def get_login_status(): @app.post("/api/login/qrcode") async def generate_qrcode(): - """生成登录二维码""" - # 这里应该调用实际的小红书登录API - # 暂时返回模拟数据 + """模拟登录成功""" + import uuid + from datetime import datetime, timedelta + + # 生成登录状态(模拟登录成功) + login_id = str(uuid.uuid4()) + current_time = datetime.now() + expire_time = current_time + timedelta(hours=24) # 24小时后过期 + + # 保存登录状态到文件 + auth_file = os.path.join(config.DATA_DIR, "auth_state.json") + auth_data = { + "logged_in": True, + "login_time": current_time.isoformat(), + "expire_time": expire_time.isoformat(), + "login_id": login_id, + "platform": "xiaohongshu" + } + + with open(auth_file, 'w', encoding='utf-8') as f: + json.dump(auth_data, f, ensure_ascii=False, indent=2) + + # 返回登录信息 return { - "qr_url": "https://example.com/login/qrcode", - "qr_id": "123456" + "login_id": login_id, + "login_time": current_time.isoformat(), + "expire_time": expire_time.isoformat(), + "message": "登录成功(模拟)", + "expire_in_hours": 24 } diff --git a/static/app.js b/static/app.js index b6812cf..de75a67 100644 --- a/static/app.js +++ b/static/app.js @@ -144,6 +144,9 @@ function init() { // 加载主题 loadTheme(); + // 加载登录状态 + loadAccountStatus(); + // 加载初始数据 loadInitialData(); @@ -692,42 +695,36 @@ function closeAccountModal() { // 打开登录二维码模态框 async function openLoginQrModal() { elements.loginQrModal.classList.add('show'); - elements.qrLoginStatus.textContent = '正在生成二维码...'; + elements.qrLoginStatus.textContent = '正在模拟登录...'; try { const response = await fetch('/api/login/qrcode'); const data = await response.json(); if (response.ok) { - // 显示二维码 - if (data.qr_url) { - // 使用简单的二维码显示(实际项目中可以使用QRCode.js等库) - elements.qrcodeContainer.innerHTML = ` -
登录状态已保存到本地
+ ${data.expire_in_hours ? `有效期:${data.expire_in_hours}小时
` : ''} +二维码已过期
'; - } - }, 1000); - } + // 3秒后自动关闭 + setTimeout(() => { + closeLoginQrModal(); + closeAccountModal(); + showToast('登录成功', 'success'); + }, 3000); } else { - elements.qrcodeContainer.innerHTML = '生成二维码失败
'; - elements.qrLoginStatus.textContent = '生成失败'; + elements.qrcodeContainer.innerHTML = '登录失败
'; + elements.qrLoginStatus.textContent = '登录失败'; } } catch (error) { elements.qrcodeContainer.innerHTML = '网络错误
'; @@ -751,7 +748,7 @@ async function checkLoginStatus() { setTimeout(() => { closeLoginQrModal(); closeAccountModal(); - updateLoginStatus(true, data.login_time); + updateLoginStatus(true, data.login_time, data.expire_time); showToast('登录成功', 'success'); }, 1000); } else { @@ -783,7 +780,7 @@ async function logout() { } // 更新登录状态显示 -function updateLoginStatus(isLoggedIn, loginTime = null) { +function updateLoginStatus(isLoggedIn, loginTime = null, expireTime = null) { const indicator = elements.loginStatusIndicator; const statusText = elements.loginStatusText; const modalStatus = elements.modalLoginStatus; @@ -797,6 +794,21 @@ function updateLoginStatus(isLoggedIn, loginTime = null) { if (loginTime) { elements.loginTime.textContent = new Date(loginTime).toLocaleString('zh-CN'); } + + // 如果有到期时间,显示剩余时间 + if (expireTime) { + const expireDate = new Date(expireTime); + const now = new Date(); + const timeLeft = expireDate - now; + + if (timeLeft > 0) { + const hours = Math.floor(timeLeft / (1000 * 60 * 60)); + const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60)); + + elements.loginTime.textContent = new Date(loginTime).toLocaleString('zh-CN'); + elements.loginTime.innerHTML += `