Files
AIclinicalresearch/docs/04-开发规范/10-模块认证规范.md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
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%)
2026-01-14 19:15:01 +08:00

6.7 KiB
Raw Blame History

<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> getUserId()<>𨭌<EFBFBD>賣㺭
    • 蝘駁膄<EFBFBD><EFBFBD><EFBFBD>?MOCK_USER_ID <20>𣇉蝻𣇉<E89DBB>暺䁅恕<E48185>?
    • 雿輻鍂 getUserId(request) <20><EFBFBD><E79195><EFBFBD> ID

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>:

  1. <EFBFBD><EFBFBD><EFBFBD>蝡?API <20>臬炏雿輻鍂 apiClient <20>?getAuthHeaders()
  2. <EFBFBD><EFBFBD>?localStorage 銝剜糓<E5899C><EFBFBD> accessToken
  3. <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