c8cfed0add
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 3s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
CI/CD Pipeline / Check push changed paths (push) Successful in 9s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 2m3s
CI/CD Pipeline / Integration Tests (push) Successful in 2m26s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been cancelled
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m24s
CI/CD Pipeline / PR Build API Image (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Web Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m6s
CI/CD Pipeline / Validate - Style (push) Successful in 3m10s
CI/CD Pipeline / Build Staging API Image (push) Successful in 29s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 31s
AI Code Review / AI Code Review (pull_request) Failing after 3m49s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 2m5s
CI/CD Pipeline / Validate - Security (push) Successful in 5m39s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 52s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m35s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 7m54s
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Failing after 261h48m38s
CI/CD Pipeline / Retag skipped Staging Web Image (push) Failing after 261h48m38s
CI/CD Pipeline / Retag skipped Staging API Image (push) Failing after 261h48m38s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Failing after 261h50m20s
CI/CD Pipeline / Integration Tests (pull_request) Failing after 261h51m21s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Failing after 261h51m24s
CI/CD Pipeline / Validate - Security (pull_request) Failing after 261h51m27s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 261h51m40s
CI/CD Pipeline / Validate - Style (pull_request) Failing after 261h51m34s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 261h53m21s
CI/CD Pipeline / PR Build API Image (push) Failing after 261h53m22s
CI/CD Pipeline / Frontend Lint (push) Failing after 261h53m31s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 261h53m45s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 261h53m46s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 262h25m55s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 262h26m7s
CI/CD Pipeline / PR Build Web Image (push) Failing after 262h27m54s
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com> Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
86 lines
1.9 KiB
TypeScript
86 lines
1.9 KiB
TypeScript
/**
|
|
* 认证状态管理
|
|
* 使用 Zustand 管理全局认证状态
|
|
*/
|
|
import { create } from "zustand"
|
|
import { persist } from "zustand/middleware"
|
|
|
|
interface User {
|
|
id: string
|
|
user_id: string
|
|
email: string
|
|
username: string
|
|
display_name: string
|
|
is_email_verified: boolean
|
|
email_verified: boolean
|
|
wechat_bound?: boolean
|
|
wechat_nickname?: string
|
|
avatar_url?: string
|
|
phone?: string
|
|
phone_verified?: boolean
|
|
profile_completed?: boolean
|
|
}
|
|
|
|
interface AuthState {
|
|
user: User | null
|
|
accessToken: string | null
|
|
refreshToken: string | null
|
|
isAuthenticated: boolean
|
|
|
|
// Actions
|
|
setAuth: (user: User, accessToken: string, refreshToken?: string | null) => void
|
|
|
|
clearAuth: () => void
|
|
setUser: (user: User) => void
|
|
}
|
|
|
|
export const useAuthStore = create<AuthState>()(
|
|
persist(
|
|
(set) => ({
|
|
user: null,
|
|
accessToken: null,
|
|
refreshToken: null,
|
|
isAuthenticated: false,
|
|
|
|
setAuth: (user, accessToken, refreshToken = null) => {
|
|
localStorage.setItem("access_token", accessToken)
|
|
if (refreshToken) {
|
|
localStorage.setItem("refresh_token", refreshToken)
|
|
} else {
|
|
localStorage.removeItem("refresh_token")
|
|
}
|
|
set({
|
|
user,
|
|
accessToken,
|
|
refreshToken,
|
|
isAuthenticated: true,
|
|
})
|
|
},
|
|
|
|
clearAuth: () => {
|
|
localStorage.removeItem("access_token")
|
|
localStorage.removeItem("refresh_token")
|
|
set({
|
|
user: null,
|
|
accessToken: null,
|
|
refreshToken: null,
|
|
isAuthenticated: false,
|
|
})
|
|
},
|
|
|
|
setUser: (user) => {
|
|
set({ user })
|
|
},
|
|
}),
|
|
{
|
|
name: "auth-storage",
|
|
partialize: (state) => ({
|
|
user: state.user,
|
|
isAuthenticated: state.isAuthenticated,
|
|
accessToken: state.accessToken,
|
|
refreshToken: state.refreshToken,
|
|
}),
|
|
},
|
|
),
|
|
)
|