feat(web): 用户端骨架——登录、工作台、新建项目、解析进度、读标清单
- packages/api-client:从 openapi.yaml 生成类型;cookie + CSRF / Bearer 两种鉴权、 分片上传、fetch 读事件流(API2) - apps/web:Vue 3 + Vite + TanStack Query,样式只来自 tokens.css / components.css(AR10); 扣点说明放在「开始解析」旁边(红线 9);接口地址、路由方式运行时可配(架构 §5.2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
24
apps/web/src/lib/queryClient.ts
Normal file
24
apps/web/src/lib/queryClient.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { ApiError } from "@bid-doctor/api-client";
|
||||
import { MutationCache, QueryCache, QueryClient } from "@tanstack/vue-query";
|
||||
|
||||
let onUnauthorized: (e: ApiError) => void = () => {};
|
||||
/** 会话失效(401:过期、被其他设备挤下线)时的统一处理,由 main.ts 注入(需要 router)。 */
|
||||
export function setUnauthorizedHandler(fn: (e: ApiError) => void) {
|
||||
onUnauthorized = fn;
|
||||
}
|
||||
|
||||
const handle = (e: unknown) => {
|
||||
if (e instanceof ApiError && e.status === 401) onUnauthorized(e);
|
||||
};
|
||||
|
||||
export const queryClient = new QueryClient({
|
||||
queryCache: new QueryCache({ onError: handle }),
|
||||
mutationCache: new MutationCache({ onError: handle }),
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
// 4xx 是确定的结果,不重试;网络和 5xx 重试两次
|
||||
retry: (count, e) => !(e instanceof ApiError && e.status < 500) && count < 2,
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user