feat(plan): 计划自动化执行、结果列表与鉴权请求优化
- 新增 automationApi、PlanAutomationRun、PlanAutomationExecutionList - 计划构建/列表/执行/进度等接入自动化与路由 - request 与 authToken 处理 token 刷新与错误码 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,15 +1,65 @@
|
||||
import axios from 'axios'
|
||||
import { Message } from 'element-ui';
|
||||
import { Message } from 'element-ui'
|
||||
import router from '../router/index'
|
||||
const service = axios.create({
|
||||
// baseURL: 'http://10.250.0.252:5010', // api 的 base_url
|
||||
// baseURL: '', // api 的 base_url
|
||||
baseURL: '/it/api', // api 的 base_url
|
||||
import store from '@/vuex/store'
|
||||
import { clearTokenStorage, tryRefreshAccessToken } from './authToken'
|
||||
|
||||
timeout: 90000 // request timeout
|
||||
const service = axios.create({
|
||||
baseURL: '/it/api',
|
||||
timeout: 90000
|
||||
})
|
||||
|
||||
// 请求拦截 设置统一header
|
||||
function pushLoginExpired(message) {
|
||||
clearTokenStorage()
|
||||
localStorage.removeItem('authUser')
|
||||
localStorage.removeItem('userMenus')
|
||||
store.commit('ClearCurrentUser')
|
||||
router.push({ name: 'login' })
|
||||
Message.error(message || '登录已失效,请重新登录')
|
||||
}
|
||||
|
||||
function apiCode(data) {
|
||||
if (!data || data.code === undefined || data.code === null) return null
|
||||
const n = Number(data.code)
|
||||
return Number.isFinite(n) ? n : null
|
||||
}
|
||||
|
||||
function isMissingToken(data) {
|
||||
return apiCode(data) === 40001
|
||||
}
|
||||
|
||||
/** 仅 451:token 无效或已过期,走静默续期并重试一次 */
|
||||
function isTokenExpiredRefreshable(data) {
|
||||
return apiCode(data) === 451
|
||||
}
|
||||
|
||||
function isForbiddenApi(data) {
|
||||
return apiCode(data) === 40003
|
||||
}
|
||||
|
||||
/** @param {{ config: object, data?: object }} ctx */
|
||||
function handleTokenExpiredRefreshAndRetry(ctx) {
|
||||
const cfg = (ctx && ctx.config) || {}
|
||||
const pdata = (ctx && ctx.data) || {}
|
||||
if (cfg.__retriedTokenRefresh) {
|
||||
pushLoginExpired(pdata.message || 'token无效或已过期!')
|
||||
return Promise.reject(new Error('token无效或已过期'))
|
||||
}
|
||||
return tryRefreshAccessToken().then(ok => {
|
||||
if (!ok) {
|
||||
pushLoginExpired(pdata.message || 'token无效或已过期!')
|
||||
return Promise.reject(new Error('token无效或已过期'))
|
||||
}
|
||||
const nextCfg = Object.assign({}, cfg, { __retriedTokenRefresh: true })
|
||||
nextCfg.headers = Object.assign({}, nextCfg.headers || {})
|
||||
const newAt = localStorage.getItem('accessToken')
|
||||
if (newAt) {
|
||||
nextCfg.headers.accessToken = newAt
|
||||
}
|
||||
return service.request(nextCfg)
|
||||
})
|
||||
}
|
||||
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
const accessToken = localStorage.getItem('accessToken')
|
||||
@@ -18,36 +68,51 @@ service.interceptors.request.use(
|
||||
}
|
||||
return config
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
error => Promise.reject(error)
|
||||
)
|
||||
|
||||
// 响应拦截 401 token过期处理
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const data = response && response.data ? response.data : {}
|
||||
// 兼容后端返回结构:{ success, code, message, data }
|
||||
if (data && data.code === 500) {
|
||||
Message.error('服务异常')
|
||||
return Promise.reject(new Error(data.message || '服务异常'))
|
||||
} else if (data && data.code === 451) {
|
||||
router.push({ name: 'login' })
|
||||
Message.error(data.message || '登录已失效,请重新登录')
|
||||
return Promise.reject(new Error(data.message || '登录已失效'))
|
||||
} else if (data && data.success === false) {
|
||||
Message.error(data.message || '请求失败')
|
||||
return Promise.reject(new Error(data.message || '请求失败'))
|
||||
} else if (data && data.code !== undefined && data.code !== 20000) {
|
||||
Message.error(data.message || '请求失败')
|
||||
return Promise.reject(new Error(data.message || '请求失败'))
|
||||
} else {
|
||||
return response.data
|
||||
}
|
||||
if (data && isMissingToken(data)) {
|
||||
pushLoginExpired(data.message || '缺少token!')
|
||||
return Promise.reject(new Error(data.message || '缺少token'))
|
||||
}
|
||||
if (data && isTokenExpiredRefreshable(data)) {
|
||||
return handleTokenExpiredRefreshAndRetry({ config: response.config, data })
|
||||
}
|
||||
if (data && isForbiddenApi(data)) {
|
||||
Message.error(data.message || '无权限访问该接口!')
|
||||
return Promise.reject(new Error(data.message || '无权限访问该接口'))
|
||||
}
|
||||
if (data && data.success === false) {
|
||||
Message.error(data.message || '请求失败')
|
||||
return Promise.reject(new Error(data.message || '请求失败'))
|
||||
}
|
||||
if (data && data.code !== undefined && data.code !== 20000) {
|
||||
Message.error(data.message || '请求失败')
|
||||
return Promise.reject(new Error(data.message || '请求失败'))
|
||||
}
|
||||
return response.data
|
||||
},
|
||||
error => {
|
||||
// 非 2xx 时会进入这里(如 40009/40012),后端通常会带 JSON body
|
||||
const data = error && error.response && error.response.data ? error.response.data : null
|
||||
const res = error && error.response
|
||||
const data = res && res.data ? res.data : null
|
||||
if (data && isMissingToken(data) && error.config) {
|
||||
pushLoginExpired(data.message || '缺少token!')
|
||||
return Promise.reject(new Error(data.message || '缺少token'))
|
||||
}
|
||||
if (data && isTokenExpiredRefreshable(data) && error.config && !error.config.__retriedTokenRefresh) {
|
||||
return handleTokenExpiredRefreshAndRetry({ config: error.config, data })
|
||||
}
|
||||
if (data && isForbiddenApi(data)) {
|
||||
Message.error(data.message || '无权限访问该接口!')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
if (data && typeof data === 'object') {
|
||||
if (data.success === false) {
|
||||
Message.error(data.message || '请求失败')
|
||||
|
||||
Reference in New Issue
Block a user