feat: 日志模块 + netRequest 封装 + PROJECT.md 更新

日志模块(文件持久化 + 事件总线联动 + 脱敏)
    新增:
      - shared/types/logging.ts         — LogLevel / LogCategory / LogEntry 类型
      - electron/main/logger.ts         — 主进程日志核心(JSON Lines / 每日轮转 / 7天清理)
      - electron/main/log-ipc.ts        — 渲染进程日志 IPC 通道接收
      - src/utils/logger.ts             — 渲染进程日志器(IPC 转发 / DEV 控制台 / 事件总线钩子)
      - shared/utils/sanitize.ts        — 脱敏工具(ID哈希 / 邮箱 / 手机 / 名称 / Token)
    修改:
      - electron/main.ts                — initLogger + flushLogger + uncaughtException
      - src/main.tsx                    — renderer 全局错误捕获
      - src/utils/event-bus.ts          — setEventLogListener 钩子,emit 自动审计
      - src/services/request.ts         — 拦截器结构化错误分级记录
      - electron/main/updater.ts        — 14处 console → logger 迁移
      - src/components/AppProvider.tsx   — 登录/登出/自动登录 auth 事件日志
      - shared/constants/ipc-channels.ts — 新增 LOG_MESSAGE 通道

  netRequest 封装(Electron net.request 的 axios 风格 API)
    新增:
      - electron/main/net-request.ts     — netRequest.get/post/put/del 命名空间
    修改:
      - electron/main/updater.ts         — fetchUpdateInfo 改用 netRequest(22→12行)

  文档更新
    - PROJECT.md                       — 目录结构 / 状态管理 / 日志系统 / IPC 章节同步现状
    - TODO.md                          — 增量更新改造 + 日志模块待办
    - UpdateA.md                       — API blockmap 字段 / 数据库字段说明
This commit is contained in:
2026-06-04 11:03:25 +08:00
parent 337234443a
commit ae733016bb
21 changed files with 1245 additions and 154 deletions

View File

@@ -13,6 +13,7 @@ import type { AppContextValue } from '@/contexts/app-context';
import type { LoginResponseBody } from '@/services/modules';
import { setToken, clearToken } from '@/services/request';
import { emit, EVENTS } from '@/utils/event-bus';
import { logger } from '@/utils/logger';
import { AuthAPI } from '@/services/modules';
import { getAutoLoginFlag, clearAutoLoginFlag } from '@/pages/login/hooks/use-auth-state';
import {
@@ -41,10 +42,15 @@ export function AppProvider({ children }: AppProviderProps) {
setStoredRefreshToken(auth.refresh_token);
setUser(auth);
setIsLoggedIn(true);
logger.info('auth', 'User logged in', {
userId: auth.user_id,
username: auth.username,
});
emit(EVENTS.LOGIN_SUCCESS, auth);
}, []);
const logout = useCallback(() => {
logger.info('auth', 'User logged out');
clearToken();
clearStoredRefreshToken();
setUser(null);
@@ -71,6 +77,7 @@ export function AppProvider({ children }: AppProviderProps) {
setToken(res.access_token);
setStoredRefreshToken(res.refresh_token);
setIsLoggedIn(true);
logger.info('auth', 'Auto-login succeeded');
// 补全用户信息
AuthAPI.getUserInfo().then((info) => {
const u: LoginResponseBody = {
@@ -97,6 +104,7 @@ export function AppProvider({ children }: AppProviderProps) {
});
})
.catch(() => {
logger.warn('auth', 'Auto-login failed, refresh_token expired');
clearStoredRefreshToken();
// 仅清除自动登录标记,保留用户名+密码供下次表单回填
clearAutoLoginFlag();
@@ -109,9 +117,7 @@ export function AppProvider({ children }: AppProviderProps) {
const handler = (_event: unknown, info: unknown) => {
const data = info as { platform?: string; edition?: string } | undefined;
if (data) {
if (isDev()) {
console.log('[AppContext] 主进程平台信息:', data);
}
logger.debug('app', 'Received platform info from main process', data as Record<string, unknown>);
}
};
safeIpcOn('platform-info', handler);