refactor: 前端 SSE 鉴权改造与公共逻辑抽取,修复统计分组空指针
- SSE 由 EventSource 改为 fetch 流式读取(新增 utils/sse.ts),token 走 Authorization 请求头,避免令牌经 URL 泄露到访问日志 - 抽取 useKeywordHistory,统一备注关键词与 AI 查询历史的读写、下拉与清空 - 抽取 renderCategoryLabel 至 utils/render.ts,消除多处重复实现 - 导出改用统一 request 实例(自动携带鉴权头),并将 blob 错误体解析为业务异常 - 新增 untagged 筛选参数;AI 智能查询改为弹窗入口并补充三语文案 - 分类/标签/邮箱/交易表单补充提交 loading,避免重复提交 - 交易时间改用本地格式化,修复 toISOString 造成的时区偏移 - 移除 Naive UI 全局注册;修正 NLog 的 rows 属性为 lines - 修复未分类记录分组时 categoryMap.get(null) 抛出的 NPE
This commit is contained in:
@@ -20,7 +20,27 @@ request.interceptors.request.use((config) => {
|
||||
|
||||
// 响应拦截器:统一处理响应数据和错误
|
||||
request.interceptors.response.use(
|
||||
(response) => {
|
||||
async (response) => {
|
||||
// 二进制响应(文件下载)不走业务状态码校验;
|
||||
// 后端出错时会返回 JSON 错误体,这里解析后按业务错误抛出,避免下载到损坏文件
|
||||
if (response.config.responseType === 'blob') {
|
||||
const blob = response.data as Blob
|
||||
if (blob?.type?.includes('application/json')) {
|
||||
let bizMessage = '请求失败'
|
||||
let bizCode: number | undefined
|
||||
try {
|
||||
const parsed = JSON.parse(await blob.text())
|
||||
bizMessage = parsed.message || bizMessage
|
||||
bizCode = parsed.code
|
||||
} catch {
|
||||
// 解析失败时使用默认错误信息
|
||||
}
|
||||
const bizError: any = new Error(bizMessage)
|
||||
bizError.code = bizCode
|
||||
return Promise.reject(bizError)
|
||||
}
|
||||
return response
|
||||
}
|
||||
const data = response.data
|
||||
// 如果业务状态码不是 200,视为请求失败
|
||||
if (data.code !== 200) {
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface StatisticsFilterParams {
|
||||
types?: string[]
|
||||
categoryIds?: number[]
|
||||
uncategorized?: boolean
|
||||
untagged?: boolean
|
||||
paymentMethods?: string[]
|
||||
minAmount?: number
|
||||
maxAmount?: number
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 收支记录相关 API 接口:交易记录的增删改查(分页)
|
||||
import request from './request'
|
||||
import axios from 'axios'
|
||||
import { useUserStore } from '../store/user'
|
||||
|
||||
/** 获取系统支持的支付方式编码列表(含账单导入来源与人工支付方式) */
|
||||
export function getPaymentMethods() {
|
||||
@@ -25,6 +23,7 @@ export function getTransactionPage(params: {
|
||||
sortField?: string
|
||||
sortOrder?: string
|
||||
tagIds?: number[]
|
||||
untagged?: boolean
|
||||
}) {
|
||||
return request.get('/transaction/page', { params })
|
||||
}
|
||||
@@ -174,16 +173,13 @@ export function exportTransaction(params: {
|
||||
sortField?: string
|
||||
sortOrder?: string
|
||||
tagIds?: number[]
|
||||
untagged?: boolean
|
||||
}) {
|
||||
const userStore = useUserStore()
|
||||
return axios.get('/api/transaction/export', {
|
||||
return request.get('/transaction/export', {
|
||||
params,
|
||||
paramsSerializer: {
|
||||
indexes: null,
|
||||
},
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
Authorization: `Bearer ${userStore.token}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user