feat(plan): 计划自动化执行、结果列表与鉴权请求优化

- 新增 automationApi、PlanAutomationRun、PlanAutomationExecutionList
- 计划构建/列表/执行/进度等接入自动化与路由
- request 与 authToken 处理 token 刷新与错误码

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
qiaoxinjiu
2026-05-11 14:27:55 +08:00
parent 33753361b0
commit 6e9673f7dd
14 changed files with 1587 additions and 48 deletions

58
src/utils/authToken.js Normal file
View File

@@ -0,0 +1,58 @@
import axios from 'axios'
/** 与 request 实例一致,避免走带拦截器的 axios 造成循环 */
const REFRESH_URL = '/it/api/auth/refresh'
let inflightRefresh = null
/**
* 静默续期POST /auth/refresh仅当业务接口返回 code 451 时由 request 响应拦截器调用)
* body 优先 refreshToken否则传 accessToken成功 code=20000 且 data.token
* @returns {Promise<boolean>}
*/
export function tryRefreshAccessToken() {
if (inflightRefresh) {
return inflightRefresh
}
const refreshToken = localStorage.getItem('refreshToken')
const accessToken = localStorage.getItem('accessToken')
if (!refreshToken && !accessToken) {
return Promise.resolve(false)
}
inflightRefresh = axios({
method: 'post',
url: REFRESH_URL,
timeout: 30000,
headers: {
'Content-Type': 'application/json',
...(accessToken ? { accessToken } : {})
},
data: refreshToken ? { refreshToken } : accessToken ? { accessToken } : {}
})
.then(res => {
const body = res && res.data
if (!body || body.code !== 20000) {
return false
}
const d = body.data || {}
const token = d.token || body.token
if (token) {
localStorage.setItem('accessToken', token)
}
const rt = d.refresh_token || d.refreshToken
if (rt) {
localStorage.setItem('refreshToken', rt)
}
return !!token
})
.catch(() => false)
.finally(() => {
inflightRefresh = null
})
return inflightRefresh
}
export function clearTokenStorage() {
localStorage.removeItem('accessToken')
localStorage.removeItem('refreshToken')
}