Version: 0.7.6.dev.260325

后端:
- ♻️ 将 `taskquery` 模块迁移至 `agent2`,并完成与 `agent2` 业务链路及整体结构的正式接入

前端:
- 🧱 已完成基础框架搭建,并完成了登录、注册、主页等页面并对接了对应接口;但整体功能实现仍在完善中
This commit is contained in:
Losita
2026-03-25 00:49:16 +08:00
parent f4ef6fb256
commit e06284d0b0
52 changed files with 8847 additions and 468 deletions

View File

@@ -0,0 +1,87 @@
import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
import type { LoginPayload, RegisterPayload, TokenPair } from '@/types/api'
import { login as loginApi, logout as logoutApi, register as registerApi } from '@/api/auth'
const ACCESS_TOKEN_KEY = 'smartflow_access_token'
const REFRESH_TOKEN_KEY = 'smartflow_refresh_token'
const LAST_USERNAME_KEY = 'smartflow_last_username'
export const useAuthStore = defineStore('auth', () => {
const accessToken = ref(localStorage.getItem(ACCESS_TOKEN_KEY) ?? '')
const refreshToken = ref(localStorage.getItem(REFRESH_TOKEN_KEY) ?? '')
const lastUsername = ref(localStorage.getItem(LAST_USERNAME_KEY) ?? '')
const isAuthenticated = computed(() => accessToken.value.trim().length > 0)
// applyTokenPair 只负责把后端返回的新 token 对落到内存和本地存储。
// 职责边界:
// 1. 负责登录成功、刷新成功后的统一持久化。
// 2. 不负责调用接口,避免把“网络失败”和“本地状态写入”耦合在一起。
// 3. 返回值为空;调用方若需要错误处理,应在接口层完成。
function applyTokenPair(tokens: TokenPair) {
accessToken.value = tokens.access_token
refreshToken.value = tokens.refresh_token
localStorage.setItem(ACCESS_TOKEN_KEY, tokens.access_token)
localStorage.setItem(REFRESH_TOKEN_KEY, tokens.refresh_token)
}
function persistLastUsername(username: string) {
lastUsername.value = username
localStorage.setItem(LAST_USERNAME_KEY, username)
}
// clearSession 只清本地登录态,不调用后端接口。
// 职责边界:
// 1. 负责在 refresh 失败、401 兜底、主动退出后统一清理本地状态。
// 2. 不负责页面跳转;跳转由调用方按场景决定,避免 store 硬绑定 UI。
// 3. lastUsername 保留,用于下次登录时回填用户名,减少重复输入。
function clearSession() {
accessToken.value = ''
refreshToken.value = ''
localStorage.removeItem(ACCESS_TOKEN_KEY)
localStorage.removeItem(REFRESH_TOKEN_KEY)
}
async function login(payload: LoginPayload) {
const tokens = await loginApi(payload)
applyTokenPair(tokens)
persistLastUsername(payload.username)
return tokens
}
async function register(payload: RegisterPayload) {
const result = await registerApi(payload)
persistLastUsername(payload.username)
return result
}
// logout 负责“尽力通知后端 + 一定清理本地状态”。
// 职责边界:
// 1. 先请求后端注销当前 access token让对应 jti 进入黑名单。
// 2. 不保证后端一定成功;即使接口失败,也必须清理本地状态,避免前端假在线。
// 3. 返回值语义:接口成功时返回后端响应;失败时向上抛错,但本地状态已被清空。
async function logout() {
try {
const result = await logoutApi()
clearSession()
return result
} catch (error) {
clearSession()
throw error
}
}
return {
accessToken,
refreshToken,
lastUsername,
isAuthenticated,
applyTokenPair,
clearSession,
login,
register,
logout,
}
})