@@ -7,10 +7,13 @@ import { getFullApiUrl } from "./config";
77import { ApiStatus } from "./ApiStatus" ; // 导入API状态码常量
88import { logoutViaBridge , buildAuthHeaders } from "@/modules/security/index.js" ;
99import { enqueueOfflineOperation } from "@/modules/pwa-offline/index.js" ;
10+ import { createLogger } from "@/utils/logger.js" ;
1011import { useOnline } from "@vueuse/core" ;
1112
1213const isOnline = useOnline ( ) ;
1314
15+ const apiLog = createLogger ( "API" ) ;
16+
1417// - 优先使用后端返回的 message
1518// - 附带请求ID(X-Request-Id)方便排查
1619function extractRequestIdFromResponse ( response ) {
@@ -98,11 +101,11 @@ async function addAuthToken(headers) {
98101 const merged = buildAuthHeaders ( headers ) ;
99102
100103 if ( headers . Authorization ) {
101- console . log ( "使用传入的Authorization头:" , headers . Authorization ) ;
104+ apiLog . debug ( "请求已携带 Authorization(来自调用方)" ) ;
102105 } else if ( merged . Authorization ) {
103- console . log ( "ͨ通过authBridge添加Authorization头 ") ;
106+ apiLog . debug ( "请求已携带 Authorization(来自 authBridge) ") ;
104107 } else {
105- console . log ( "未找到认证凭据,请求将不包含Authorization头 ") ;
108+ apiLog . debug ( "请求未携带 Authorization ") ;
106109 }
107110
108111 return merged ;
@@ -157,11 +160,14 @@ export async function fetchApi(endpoint, options = {}) {
157160 timestamp : new Date ( ) . toISOString ( ) ,
158161 } ;
159162
160- console . log ( `🚀 API请求: ${ debugInfo . method } ${ debugInfo . url } ` , debugInfo ) ;
163+ apiLog . debug ( `API请求: ${ debugInfo . method } ${ debugInfo . url } ` , {
164+ hasBody : ! ! debugInfo . body ,
165+ headerKeys : Object . keys ( debugInfo . headers || { } ) ,
166+ } ) ;
161167
162- // 🎯 PWA网络状态检测 - 符合最佳实践
168+ // PWA网络状态检测 - 符合最佳实践
163169 if ( ! isOnline . value ) {
164- console . warn ( `🔌 离线状态,API请求可能失败: ${ url } ` ) ;
170+ apiLog . warn ( " 离线状态,API请求可能失败:" , url ) ;
165171 if ( options . method && options . method !== "GET" ) {
166172 await enqueueOfflineOperation ( endpoint , options ) ;
167173 }
@@ -220,21 +226,18 @@ export async function fetchApi(endpoint, options = {}) {
220226 const endTime = Date . now ( ) ;
221227 const timeTaken = endTime - startTime ;
222228
223- console . log ( `⏱️ API响应耗时: ${ timeTaken } ms, 状态: ${ response . status } `, {
229+ apiLog . debug ( ` API响应耗时: ${ timeTaken } ms, 状态: ${ response . status } `, {
224230 url,
225231 status : response . status ,
226232 statusText : response . statusText ,
227- headers : Object . fromEntries ( [ ...response . headers . entries ( ) ] ) ,
228233 } ) ;
229234
230235 // 304 Not Modified:成熟项目常用的条件请求语义(If-None-Match)
231236 // - 304 无响应体,不应尝试解析 JSON
232237 // - 交由上层用本地缓存数据兜底
233238 if ( response . status === 304 ) {
234239 const etag = response . headers . get ( "etag" ) || response . headers . get ( "ETag" ) || null ;
235- if ( import . meta?. env ?. DEV ) {
236- console . log ( `📦 API响应(${ url } ): 304 Not Modified` , { url, etag } ) ;
237- }
240+ apiLog . debug ( `API响应: 304 Not Modified` , { url, etag } ) ;
238241 return {
239242 success : true ,
240243 notModified : true ,
@@ -252,13 +255,18 @@ export async function fetchApi(endpoint, options = {}) {
252255 // 检查是否需要返回blob响应
253256 if ( options . responseType === "blob" ) {
254257 responseData = await response . blob ( ) ;
255- console . log ( `📦 API响应Blob( ${ url } ) : ${ responseData . size } 字节, 类型: ${ responseData . type } ` ) ;
258+ apiLog . debug ( ` API响应Blob: ${ responseData . size } 字节` , { url , type : responseData . type } ) ;
256259 } else if ( contentType && contentType . includes ( "application/json" ) ) {
257260 responseData = await response . json ( ) ;
258- console . log ( `📦 API响应数据(${ url } ):` , responseData ) ;
261+ apiLog . debug ( `API响应JSON` , {
262+ url,
263+ kind : Array . isArray ( responseData ) ? "array" : typeof responseData ,
264+ keys : responseData && typeof responseData === "object" && ! Array . isArray ( responseData ) ? Object . keys ( responseData ) . slice ( 0 , 20 ) : undefined ,
265+ length : Array . isArray ( responseData ) ? responseData . length : undefined ,
266+ } ) ;
259267 } else {
260268 responseData = await response . text ( ) ;
261- console . log ( `📝 API响应文本( ${ url } ) : ${ responseData . substring ( 0 , 100 ) } ${ responseData . length > 100 ? "..." : "" } `) ;
269+ apiLog . debug ( ` API响应文本: ${ responseData . substring ( 0 , 100 ) } ${ responseData . length > 100 ? "..." : "" } `) ;
262270 }
263271
264272 // 如果响应不成功,抛出错误
@@ -277,15 +285,15 @@ export async function fetchApi(endpoint, options = {}) {
277285
278286 // 特殊处理401未授权错误
279287 if ( response . status === ApiStatus . UNAUTHORIZED ) {
280- console . error ( `🚫 授权失败(${ url } ):` , responseData ) ;
288+ apiLog . error ( `🚫 授权失败(${ url } ):` , responseData ) ;
281289
282290 // 检查特殊的密码验证请求类型
283291 const isPasswordRelatedRequest = checkPasswordRelatedRequest ( endpoint , options ) ;
284292 const { isPasswordVerify, isChangePasswordRequest } = isPasswordRelatedRequest ;
285293
286294 // 如果是密码验证请求,直接返回错误,不清除令牌
287295 if ( isPasswordVerify ) {
288- console . log ( `密码验证失败, 不清除认证令牌。 端点: ${ endpoint } ` ) ;
296+ apiLog . debug ( `密码验证失败: 不清除认证令牌( 端点: ${ endpoint } ) ` ) ;
289297
290298 // 确保返回后端提供的具体错误信息
291299 const errorMessage = responseData && responseData . message ? responseData . message : "密码错误" ;
@@ -327,7 +335,7 @@ export async function fetchApi(endpoint, options = {}) {
327335 const isAdminAuthEndpoint = endpoint . startsWith ( "/admin" ) || endpoint . includes ( "/admin/" ) ;
328336
329337 if ( isAuthErrorCode || isAdminAuthEndpoint ) {
330- console . log ( "管理员令牌验证失败, 执行登出" ) ;
338+ apiLog . debug ( "管理员令牌验证失败: 执行登出" ) ;
331339 await logoutViaBridge ( ) ;
332340 const error = new Error ( "管理员会话已过期,请重新登录" ) ;
333341 error . __logged = true ;
@@ -357,13 +365,13 @@ export async function fetchApi(endpoint, options = {}) {
357365 responseData . message . includes ( "没有权限" ) ) ;
358366
359367 if ( isPermissionIssue ) {
360- console . log ( "API密钥权限不足, 不执行登出" ) ;
368+ apiLog . debug ( "API密钥权限不足: 不执行登出" ) ;
361369 const error = new Error ( responseData . message || "访问被拒绝,您可能无权执行此操作" ) ;
362370 error . __logged = true ;
363371 throw error ;
364372 }
365373
366- console . log ( "API密钥验证失败, 执行登出" ) ;
374+ apiLog . debug ( "API密钥验证失败: 执行登出" ) ;
367375 await logoutViaBridge ( ) ;
368376 const apiKeyError = new Error ( "API密钥无效或已过期" ) ;
369377 apiKeyError . __logged = true ;
@@ -377,7 +385,7 @@ export async function fetchApi(endpoint, options = {}) {
377385
378386 // 对409状态码做特殊处理(链接后缀冲突或其他冲突)
379387 if ( response . status === ApiStatus . CONFLICT ) {
380- console . error ( `❌ 资源冲突错误(${ url } ):` , responseData ) ;
388+ apiLog . error ( `❌ 资源冲突错误(${ url } ):` , responseData ) ;
381389 // 使用后端返回的具体错误信息,无论是字符串形式还是对象形式
382390 if ( typeof responseData === "string" ) {
383391 const error = new Error ( responseData ) ;
@@ -396,7 +404,7 @@ export async function fetchApi(endpoint, options = {}) {
396404
397405 // 处理新的后端错误格式 (code, message)
398406 if ( responseData && typeof responseData === "object" ) {
399- console . error ( `❌ API错误(${ url } ):` , responseData ) ;
407+ apiLog . error ( `❌ API错误(${ url } ):` , responseData ) ;
400408 const baseMessage = responseData . message || `HTTP错误 ${ response . status } : ${ response . statusText } ` ;
401409 const payloadRequestId =
402410 typeof responseData . requestId === "string" && responseData . requestId . trim ( )
@@ -420,7 +428,7 @@ export async function fetchApi(endpoint, options = {}) {
420428 throw error ;
421429 }
422430
423- console . error ( `❌ HTTP错误(${ url } ): ${ response . status } ` , responseData ) ;
431+ apiLog . error ( `❌ HTTP错误(${ url } ): ${ response . status } ` , responseData ) ;
424432 const error = new Error ( appendRequestIdIfNeeded ( `HTTP错误 ${ response . status } : ${ response . statusText } ` , requestId ) ) ;
425433 error . __logged = true ;
426434 if ( requestId ) {
@@ -434,7 +442,7 @@ export async function fetchApi(endpoint, options = {}) {
434442 // success 布尔判断
435443 if ( "success" in responseData ) {
436444 if ( responseData . success !== true ) {
437- console . error ( `❌ API业务错误(${ url } ):` , responseData ) ;
445+ apiLog . error ( `❌ API业务错误(${ url } ):` , responseData ) ;
438446 const baseMessage = responseData . message || "请求失败" ;
439447 const payloadRequestId =
440448 typeof responseData . requestId === "string" && responseData . requestId . trim ( )
@@ -494,23 +502,23 @@ export async function fetchApi(endpoint, options = {}) {
494502 // 处理不同类型的错误
495503 if ( error . name === "AbortError" ) {
496504 // 请求被主动取消时,静默处理,不抛出错误
497- console . log ( `⏹️ API请求被取消(${ url } )`) ;
505+ apiLog . debug ( ` API请求被取消(${ url } )`) ;
498506 // 创建一个特殊的 AbortError 对象,让调用方可以识别
499507 const abortError = new Error ( "请求已取消" ) ;
500508 abortError . name = "AbortError" ;
501509 abortError . __aborted = true ;
502510 abortError . __logged = true ;
503511 throw abortError ;
504512 } else if ( error . name === "TimeoutError" ) {
505- console . error ( `⏰ API请求超时(${ url } ):` , error . message ) ;
513+ apiLog . error ( `⏰ API请求超时(${ url } ):` , error . message ) ;
506514 throw new Error ( "请求超时,服务器响应时间过长" ) ;
507515 } else if ( error . name === "TypeError" && error . message . includes ( "fetch" ) ) {
508- console . error ( `🌐 网络错误(${ url } ):` , error . message ) ;
516+ apiLog . error ( `🌐 网络错误(${ url } ):` , error . message ) ;
509517 throw new Error ( "网络连接失败,请检查网络设置" ) ;
510518 } else {
511519 // 避免对已经在上层记录过的业务错误重复打印日志
512520 if ( ! error . __logged ) {
513- console . error ( `❌ API请求失败(${ url } ):` , error ) ;
521+ apiLog . error ( `❌ API请求失败(${ url } ):` , error ) ;
514522 }
515523 // 兜底:保证抛出去的一定是 Error,避免上层拿不到 error.message 而只能显示“未知错误”
516524 if ( error instanceof Error ) {
@@ -537,19 +545,19 @@ async function handleSuccessfulResponse(endpoint, options, responseData) {
537545 if ( method === "POST" && endpoint . includes ( "/paste" ) && responseData . data ) {
538546 // 存储新创建的文本分享
539547 await pwaUtils . storage . savePaste ( responseData . data ) ;
540- console . log ( `[PWA] 已存储文本分享: ${ responseData . data . slug } ` ) ;
548+ apiLog . debug ( `[PWA] 已存储文本分享: ${ responseData . data . slug } ` ) ;
541549 } else if ( method === "POST" && endpoint . includes ( "/upload" ) && responseData . data ) {
542550 // 存储上传的文件信息
543551 await pwaUtils . storage . saveFile ( responseData . data ) ;
544- console . log ( `[PWA] 已存储文件信息: ${ responseData . data . filename || responseData . data . slug } ` ) ;
552+ apiLog . debug ( `[PWA] 已存储文件信息: ${ responseData . data . filename || responseData . data . slug } ` ) ;
545553 } else if ( method === "POST" && endpoint . includes ( "/admin/settings" ) ) {
546554 // 存储重要设置更新
547555 const settingKey = `admin_setting_${ Date . now ( ) } ` ;
548556 await pwaUtils . storage . saveSetting ( settingKey , responseData ) ;
549- console . log ( `[PWA] 已存储管理员设置: ${ settingKey } ` ) ;
557+ apiLog . debug ( `[PWA] 已存储管理员设置: ${ settingKey } ` ) ;
550558 }
551559 } catch ( error ) {
552- console . warn ( "[PWA] 业务数据存储失败:" , error ) ;
560+ apiLog . warn ( "[PWA] 业务数据存储失败:" , error ) ;
553561 }
554562}
555563
@@ -591,7 +599,7 @@ export async function post(endpoint, data, options = {}) {
591599 partInfo = `,分片: ${ partNumber } ${ isLastPart ? " (最后分片)" : "" } ` ;
592600 }
593601
594- console . log ( `发送二进制数据到 ${ url } ${ partInfo } ,大小: ${ data instanceof Blob ? data . size : data . byteLength } 字节` ) ;
602+ apiLog . debug ( `发送二进制数据到 ${ url } ${ partInfo } ` , { size : data instanceof Blob ? data . size : data . byteLength } ) ;
595603
596604 // 添加对 XHR 对象的处理,以支持取消功能
597605 const xhr = new XMLHttpRequest ( ) ;
@@ -647,10 +655,10 @@ export async function post(endpoint, data, options = {}) {
647655 responseData = xhr . response ;
648656 }
649657
650- console . log ( `✅ 二进制上传请求成功 ${ url } ${ partInfo } `) ;
658+ apiLog . debug ( ` 二进制上传请求成功 ${ url } ${ partInfo } `) ;
651659 resolve ( responseData ) ;
652660 } catch ( e ) {
653- console . error ( `解析响应错误: ${ e . message } ` ) ;
661+ apiLog . error ( `解析响应错误: ${ e . message } ` ) ;
654662 reject ( new Error ( `解析响应错误: ${ e . message } ` ) ) ;
655663 }
656664 } else {
@@ -672,14 +680,14 @@ export async function post(endpoint, data, options = {}) {
672680 errorMsg = `HTTP错误 ${ xhr . status } ` ;
673681 }
674682
675- console . error ( `❌ 二进制上传请求失败 ${ url } ${ partInfo } : ${ errorMsg } ` ) ;
683+ apiLog . error ( `❌ 二进制上传请求失败 ${ url } ${ partInfo } : ${ errorMsg } ` ) ;
676684 reject ( new Error ( errorMsg ) ) ;
677685 }
678686 } ;
679687
680688 // 监听网络错误
681689 xhr . onerror = function ( ) {
682- console . error ( `❌ 网络错误: ${ url } ${ partInfo } ` ) ;
690+ apiLog . error ( `❌ 网络错误: ${ url } ${ partInfo } ` ) ;
683691 reject ( new Error ( "网络错误,请检查连接" ) ) ;
684692 } ;
685693
@@ -688,13 +696,13 @@ export async function post(endpoint, data, options = {}) {
688696
689697 // 监听超时
690698 xhr . ontimeout = function ( ) {
691- console . error ( `❌ 请求超时: ${ url } ${ partInfo } ` ) ;
699+ apiLog . error ( `❌ 请求超时: ${ url } ${ partInfo } ` ) ;
692700 reject ( new Error ( "请求超时,服务器响应时间过长" ) ) ;
693701 } ;
694702
695703 // 监听中止
696704 xhr . onabort = function ( ) {
697- console . log ( `⏹️ 请求已被中止: ${ url } ${ partInfo } `) ;
705+ apiLog . debug ( ` 请求已被中止: ${ url } ${ partInfo } `) ;
698706 reject ( new Error ( "请求已被用户取消" ) ) ;
699707 } ;
700708
@@ -710,7 +718,7 @@ export async function post(endpoint, data, options = {}) {
710718 body : data ,
711719 } ) ;
712720 } catch ( error ) {
713- console . error ( `POST ${ endpoint } 请求错误:` , error ) ;
721+ apiLog . error ( `POST ${ endpoint } 请求错误:` , error ) ;
714722 throw error ;
715723 }
716724}
0 commit comments