diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f499fd1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Python +__pycache__/ +*.pyc +*.pyo +*.db + +# Node +node_modules/ +frontend/dist/ + +# IDE +.vscode/ +.idea/ + +# OS +.DS_Store +Thumbs.db + +# Env +.env diff --git a/backend/__pycache__/auth.cpython-310.pyc b/backend/__pycache__/auth.cpython-310.pyc deleted file mode 100644 index 472fea6..0000000 Binary files a/backend/__pycache__/auth.cpython-310.pyc and /dev/null differ diff --git a/backend/__pycache__/calculations.cpython-310.pyc b/backend/__pycache__/calculations.cpython-310.pyc deleted file mode 100644 index fe2fe9f..0000000 Binary files a/backend/__pycache__/calculations.cpython-310.pyc and /dev/null differ diff --git a/backend/__pycache__/config.cpython-310.pyc b/backend/__pycache__/config.cpython-310.pyc deleted file mode 100644 index ec6d96a..0000000 Binary files a/backend/__pycache__/config.cpython-310.pyc and /dev/null differ diff --git a/backend/__pycache__/database.cpython-310.pyc b/backend/__pycache__/database.cpython-310.pyc deleted file mode 100644 index aec53ff..0000000 Binary files a/backend/__pycache__/database.cpython-310.pyc and /dev/null differ diff --git a/backend/__pycache__/main.cpython-310.pyc b/backend/__pycache__/main.cpython-310.pyc deleted file mode 100644 index 48af3a8..0000000 Binary files a/backend/__pycache__/main.cpython-310.pyc and /dev/null differ diff --git a/backend/__pycache__/models.cpython-310.pyc b/backend/__pycache__/models.cpython-310.pyc deleted file mode 100644 index f422413..0000000 Binary files a/backend/__pycache__/models.cpython-310.pyc and /dev/null differ diff --git a/backend/__pycache__/schemas.cpython-310.pyc b/backend/__pycache__/schemas.cpython-310.pyc deleted file mode 100644 index 1f288d7..0000000 Binary files a/backend/__pycache__/schemas.cpython-310.pyc and /dev/null differ diff --git a/backend/airlabs.db b/backend/airlabs.db deleted file mode 100644 index 91408df..0000000 Binary files a/backend/airlabs.db and /dev/null differ diff --git a/backend/auth.py b/backend/auth.py index e6a88cb..7820778 100644 --- a/backend/auth.py +++ b/backend/auth.py @@ -38,10 +38,11 @@ def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends( ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) - user_id: int = payload.get("sub") - if user_id is None: + sub = payload.get("sub") + if sub is None: raise credentials_exception - except JWTError: + user_id = int(sub) + except (JWTError, ValueError, TypeError): raise credentials_exception user = db.query(User).filter(User.id == user_id).first() diff --git a/backend/routers/__pycache__/__init__.cpython-310.pyc b/backend/routers/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index c5cc7b4..0000000 Binary files a/backend/routers/__pycache__/__init__.cpython-310.pyc and /dev/null differ diff --git a/backend/routers/__pycache__/auth.cpython-310.pyc b/backend/routers/__pycache__/auth.cpython-310.pyc deleted file mode 100644 index 851f532..0000000 Binary files a/backend/routers/__pycache__/auth.cpython-310.pyc and /dev/null differ diff --git a/backend/routers/__pycache__/costs.cpython-310.pyc b/backend/routers/__pycache__/costs.cpython-310.pyc deleted file mode 100644 index f3ee76a..0000000 Binary files a/backend/routers/__pycache__/costs.cpython-310.pyc and /dev/null differ diff --git a/backend/routers/__pycache__/dashboard.cpython-310.pyc b/backend/routers/__pycache__/dashboard.cpython-310.pyc deleted file mode 100644 index d10805c..0000000 Binary files a/backend/routers/__pycache__/dashboard.cpython-310.pyc and /dev/null differ diff --git a/backend/routers/__pycache__/projects.cpython-310.pyc b/backend/routers/__pycache__/projects.cpython-310.pyc deleted file mode 100644 index 330608e..0000000 Binary files a/backend/routers/__pycache__/projects.cpython-310.pyc and /dev/null differ diff --git a/backend/routers/__pycache__/submissions.cpython-310.pyc b/backend/routers/__pycache__/submissions.cpython-310.pyc deleted file mode 100644 index 530a0d0..0000000 Binary files a/backend/routers/__pycache__/submissions.cpython-310.pyc and /dev/null differ diff --git a/backend/routers/__pycache__/users.cpython-310.pyc b/backend/routers/__pycache__/users.cpython-310.pyc deleted file mode 100644 index 7234d28..0000000 Binary files a/backend/routers/__pycache__/users.cpython-310.pyc and /dev/null differ diff --git a/backend/routers/auth.py b/backend/routers/auth.py index 8ee2375..887fbee 100644 --- a/backend/routers/auth.py +++ b/backend/routers/auth.py @@ -16,7 +16,7 @@ def login(req: LoginRequest, db: Session = Depends(get_db)): raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户名或密码错误") if not user.is_active: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="账号已停用") - token = create_access_token(data={"sub": user.id}) + token = create_access_token(data={"sub": str(user.id)}) return {"access_token": token, "token_type": "bearer"} diff --git a/frontend/.vscode/extensions.json b/frontend/.vscode/extensions.json deleted file mode 100644 index a7cea0b..0000000 --- a/frontend/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["Vue.volar"] -} diff --git a/frontend/src/api/index.js b/frontend/src/api/index.js index 3ab61a7..7d7a6fd 100644 --- a/frontend/src/api/index.js +++ b/frontend/src/api/index.js @@ -22,9 +22,12 @@ api.interceptors.response.use( err => { const msg = err.response?.data?.detail || '请求失败' if (err.response?.status === 401) { + const isOnLogin = window.location.pathname === '/login' localStorage.removeItem('token') - router.push('/login') - ElMessage.error('登录已过期,请重新登录') + if (!isOnLogin) { + router.push('/login') + ElMessage.error('登录已过期,请重新登录') + } } else { ElMessage.error(msg) } diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index bdc8b60..ca6b2ae 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -27,7 +27,12 @@ const router = createRouter({ router.beforeEach(async (to, from, next) => { const token = localStorage.getItem('token') if (to.meta.public) { - next() + // 已登录时访问登录页,直接跳首页 + if (to.path === '/login' && token) { + next('/') + } else { + next() + } } else if (!token) { next('/login') } else { diff --git a/frontend/src/stores/auth.js b/frontend/src/stores/auth.js index e97d866..ad10cf6 100644 --- a/frontend/src/stores/auth.js +++ b/frontend/src/stores/auth.js @@ -10,10 +10,16 @@ export const useAuthStore = defineStore('auth', () => { const res = await authApi.login({ username, password }) token.value = res.access_token localStorage.setItem('token', res.access_token) - await fetchUser() + // 登录后立即获取用户信息,失败不影响登录流程 + try { + user.value = await authApi.me() + } catch (e) { + console.error('fetchUser after login failed:', e) + } } async function fetchUser() { + if (!token.value) return try { user.value = await authApi.me() } catch {