Major Changes: - Add StreamingService with OpenAI Compatible format - Upgrade Chat component V2 with Ant Design X integration - Implement AIA module with 12 intelligent agents - Update API routes to unified /api/v1 prefix - Update system documentation Backend (~1300 lines): - common/streaming: OpenAI Compatible adapter - modules/aia: 12 agents, conversation service, streaming integration - Update route versions (RVW, PKB to v1) Frontend (~3500 lines): - modules/aia: AgentHub + ChatWorkspace (100% prototype restoration) - shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook - Update API endpoints to v1 Documentation: - AIA module status guide - Universal capabilities catalog - System overview updates - All module documentation sync Tested: Stream response verified, authentication working Status: AIA V2.0 core completed (85%)
6.7 KiB
6.7 KiB
璅∪<EFBFBD>霈方<EFBFBD>閫<EFBFBD><EFBFBD>
<EFBFBD>祆<EFBFBD>獢<EFBFBD><EFBFBD>銋劐<EFBFBD>銝𡁜𦛚璅∪<EFBFBD>憒<EFBFBD><EFBFBD>甇<EFBFBD>&雿輻鍂撟喳蝱霈方<EFBFBD><EFBFBD>賢<EFBFBD>嚗𣬚&靽脲<EFBFBD><EFBFBD>?API <20>賣迤蝖格𡉼撣血<E692A3>撉諹<E69289><E8ABB9>冽<EFBFBD>頨思遢<E6809D>?
1. <20>嗆<EFBFBD>璁<EFBFBD><E79281>
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<0A>? <20>滨垢 <20>?
<0A>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<0A>? <20>? common/api/axios.ts <20>?撣西恕霂<E68195><E99C82> axios 摰硺<E691B0> <20>? <20>?
<0A>? <20>? framework/auth/api.ts <20>?Token 蝞∠<E89D9E> (getAccessToken)<29>? <20>?
<0A>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<0A>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>?
<20>?Authorization: Bearer <token>
<20>?
<0A>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<0A>? <20>𡒊垢 <20>?
<0A>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<0A>? <20>? common/auth/auth.middleware.ts <20>? <20>?
<0A>? <20>? - authenticate: 撉諹<E69289> JWT Token <20>? <20>?
<0A>? <20>? - requirePermission: <20><><EFBFBD>璉<EFBFBD><E79289>? <20>? <20>?
<0A>? <20>? - requireRoles: 閫坿𠧧璉<F0A0A7A7><E79289>? <20>? <20>?
<0A>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<0A>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
2. <20>滨垢閫<E59EA2><E996AB>
2.1 雿輻鍂撣西恕霂<E68195><E99C82> axios 摰硺<E691B0>嚗<EFBFBD>綫<EFBFBD>琜<EFBFBD>
// 撖澆<E69296>撣西恕霂<E68195><E99C82> apiClient
import apiClient from '../../../common/api/axios';
// 雿輻鍂<E8BCBB>孵<EFBFBD>銝?axios 摰<><E691B0><EFBFBD>詨<EFBFBD>嚗諹䌊<E8ABB9>冽𡉼撣?JWT Token
const response = await apiClient.get('/api/v2/xxx');
const response = await apiClient.post('/api/v2/xxx', data);
2.2 雿輻鍂<E8BCBB>毺<EFBFBD> fetch嚗<68><E59A97><EFBFBD>见𢆡瘛餃<E7989B> Token嚗?
import { getAccessToken } from '../../../framework/auth/api';
// <20>𥕦遣 getAuthHeaders <20>賣㺭
function getAuthHeaders(): HeadersInit {
const headers: Record<string, string> = {
'Content-Type': 'application/json',
};
const token = getAccessToken();
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return headers;
}
// <20><><EFBFBD>?fetch 霂瑟<E99C82>雿輻鍂 getAuthHeaders()
const response = await fetch(url, {
headers: getAuthHeaders(),
});
// <20><>辣銝𠹺<E98A9D>嚗<EFBFBD><E59A97>霈曄蔭 Content-Type嚗?
const token = getAccessToken();
const headers: HeadersInit = {};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await fetch(url, {
method: 'POST',
headers,
body: formData,
});
3. <20>𡒊垢閫<E59EA2><E996AB>
3.1 頝舐眏瘛餃<E7989B>霈方<E99C88>銝剝𡢿隞?
// 撖澆<E69296>霈方<E99C88>銝剝𡢿隞?
import { authenticate, requirePermission } from '../../../common/auth/auth.middleware.js';
// 瘛餃<E7989B><E9A483>啗楝<E59597>?
fastify.get('/xxx', { preHandler: [authenticate] }, handler);
// <20><>閬<EFBFBD>鸌摰𡁏<E691B0><F0A1818F>?
fastify.post('/xxx', {
preHandler: [authenticate, requirePermission('module:action')]
}, handler);
3.2 <20>批<EFBFBD><E689B9>刻繮<E588BB>𣇉鍂<F0A38789>?ID
/**
* <20>瑕<EFBFBD><E79195>冽<EFBFBD>ID嚗<44><E59A97>JWT Token銝剛繮<E5899B>吔<EFBFBD>
*/
function getUserId(request: FastifyRequest): string {
const userId = (request as any).user?.userId;
if (!userId) {
throw new Error('User not authenticated');
}
return userId;
}
// <20>冽綉<E586BD>嗅膥<E59785>寞<EFBFBD>銝凋蝙<E5878B>?
async function myHandler(request: FastifyRequest, reply: FastifyReply) {
const userId = getUserId(request);
// ... 雿輻鍂 userId
}
3.3 JWT Token 蝏𤘪<E89D8F>
interface DecodedToken {
userId: string; // <20>冽<EFBFBD>ID
phone: string; // <20>𧢲㦤<F0A7A2B2>?
role: string; // 閫坿𠧧
tenantId: string; // 蝘<><E89D98>ID
tenantCode?: string; // 蝘<><E89D98>Code
iat: number; // 蝑曉<E89D91><E69B89>園𡢿
exp: number; // 餈<><E9A488><EFBFBD>園𡢿
}
4. 璉<><E79289>交<EFBFBD><E4BAA4>?
4.1 <20>唳芋<E594B3>堒<EFBFBD><E5A092>烐<EFBFBD><E78390>交<EFBFBD><E4BAA4>?
-
<EFBFBD>滨垢 API <20><>辣
- 雿輻鍂
apiClient<20>𡝗溶<F0A19D97>?getAuthHeaders() - <EFBFBD><EFBFBD>辣銝𠹺<EFBFBD><EFBFBD>閧𡠺憭<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD>霈曄蔭 Content-Type嚗?
- 撖澆枂<EFBFBD>賣㺭銝滚<EFBFBD><EFBFBD>急<EFBFBD>霂閧鍂 userId <20><>㺭
- 雿輻鍂
-
<EFBFBD>𡒊垢頝舐眏<EFBFBD><EFBFBD>辣
- 撖澆<EFBFBD>
authenticate銝剝𡢿隞? - <EFBFBD><EFBFBD><EFBFBD>厰<EFBFBD>閬<EFBFBD>恕霂<EFBFBD><EFBFBD>頝舐眏瘛餃<EFBFBD>
preHandler: [authenticate] - <EFBFBD>砍<EFBFBD> API嚗<49><E59A97>璅⊥踎<E28AA5>𡑒”嚗匧虾銝齿溶<E9BDBF>㰘恕霂?
- 撖澆<EFBFBD>
-
*<EFBFBD>𡒊垢<EFBFBD>批<EFBFBD><EFBFBD>冽<EFBFBD>隞?
- 瘛餃<EFBFBD>
getUserId()颲<>𨭌<EFBFBD>賣㺭 - 蝘駁膄<EFBFBD><EFBFBD><EFBFBD>?
MOCK_USER_ID<20>𣇉′蝻𣇉<E89DBB>暺䁅恕<E48185>? - 雿輻鍂
getUserId(request)<20>瑕<EFBFBD><E79195>冽<EFBFBD> ID
- 瘛餃<EFBFBD>
4.2 撌脣<E6928C><E884A3>鞉芋<E99E89>㛖𠶖<E39B96>?
| 璅∪<EFBFBD> | <EFBFBD>滨垢 API | <EFBFBD>𡒊垢頝舐眏 | <EFBFBD>𡒊垢<EFBFBD>批<EFBFBD><EFBFBD>? | <EFBFBD>嗆<EFBFBD>? |
|---|---|---|---|---|
| RVW | <EFBFBD>?apiClient | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>? |
| PKB | <EFBFBD>?<3F>行⏛<E8A18C>? | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>? |
| ASL | <EFBFBD>?getAuthHeaders | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>? |
| DC Tool B | <EFBFBD>?getAuthHeaders | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>? |
| DC Tool C | <EFBFBD>?apiClient | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>? |
| IIT | N/A (隡<><E99AA1>敺桐縑) | N/A | <EFBFBD>?隡<><E99AA1>敺桐縑userId | <EFBFBD>? |
| Prompt蝞∠<EFBFBD> | <EFBFBD>?getAuthHeaders | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>? |
5. 撣貉<E692A3><E8B289>躰秤<E8BAB0>諹圾<E8ABB9>單䲮獢?
5.1 401 Unauthorized
<EFBFBD>笔<EFBFBD>: <20>滨垢瘝⊥<E7989D><E28AA5>箏蒂 JWT Token <20>?Token 餈<><E9A488>
閫<EFBFBD><EFBFBD>:
- 璉<EFBFBD><EFBFBD>亙<EFBFBD>蝡?API <20>臬炏雿輻鍂
apiClient<20>?getAuthHeaders() - 璉<EFBFBD><EFBFBD>?localStorage 銝剜糓<E5899C>行<EFBFBD>
accessToken - 憒<EFBFBD><EFBFBD> Token 餈<><E9A488>嚗<EFBFBD><E59A97>霂訫<E99C82><E8A8AB>唳<EFBFBD><E594B3>齿鰵<E9BDBF>餃<EFBFBD>
5.2 User not authenticated
<EFBFBD>笔<EFBFBD>: <20>𡒊垢頝舐眏瘝⊥<E7989D>瘛餃<E7989B> authenticate 銝剝𡢿隞?
閫<EFBFBD><EFBFBD>: <20>刻楝<E588BB>勗<EFBFBD>銋劐葉瘛餃<E7989B> preHandler: [authenticate]
5.3 TypeError: Cannot read property 'userId' of undefined
<EFBFBD>笔<EFBFBD>: 雿輻鍂鈭<E98D82><E988AD>霂舐<E99C82>撅墧<E69285>批<EFBFBD>嚗Ǒrequest.user.id<EFBFBD>屸<EFBFBD>request.user.userId`嚗?
閫<EFBFBD><EFBFBD>: 雿輻鍂 (request as any).user?.userId
6. <20><><EFBFBD><EFBFBD><EFBFBD>隞?
- <EFBFBD>滨垢 axios 摰硺<E691B0>:
frontend-v2/src/common/api/axios.ts - <EFBFBD>滨垢 Token 蝞∠<E89D9E>:
frontend-v2/src/framework/auth/api.ts - <EFBFBD>𡒊垢霈方<EFBFBD>銝剝𡢿隞?
backend/src/common/auth/auth.middleware.ts - <EFBFBD>𡒊垢 JWT <20>滚𦛚:
backend/src/common/auth/jwt.service.ts