# admin.xpcool.com 变更记录 > 倒序:最新在上。格式:YYYY-MM-DD | 类型 | 摘要 2026-09-15 | FIX | **「commit 卡死」真凶定位并修复:eslint 规则 `n/no-extraneous-import`(此前的"checkType 全量"判断为误判,特此更正)**:症状=IDE 提交后长时间无输出,进程链 `git commit` → `sh .git/hooks/pre-commit` → `lefthook.exe` → `node eslint.js`,eslint **满核空转 900~1400 秒 CPU**(本次卡了 23 分钟,不会自愈)。定位法:①`eslint --no-config-lookup` → 0.5s(排除本体)②`eslint --print-config` → 2.9s(排除配置加载)③同一文件带完整配置 lint → **>300s 不结束** ④用「按前缀关闭插件规则」的临时探针配置二分:关整个 `n/` → **1.7s**,再逐条缩到唯一元凶 `n/no-extraneous-import`(pnpm hoisted + workspace 包名 + `imports` 别名下解析代价近乎无界)。修复:`internal/lint-configs/eslint-config/src/configs/node.ts` 将 `n/no-extraneous-import` 置 `off`(含注释);因该包经 `dist/` 分发且 `dist` 被 gitignore,改 `src` 后**须重建才生效**,但本机 `pnpm --filter @vben/eslint-config run stub`(tsdown)报 `Failed to import module "unrun"`(tsdown 可选依赖 unrun 未落地,node_modules 与 lock 均无),故**手工同步本地 `dist/index.mjs`**(本地派生物)。验证:待提交的 **7 个文件 lint 由卡死 >15 分钟 → 1.9s** ✅,并暴露 2 处待 `--fix` 的排序问题(`api/notice.ts:181`、`notice/log/index.vue:3`)。附带:`lefthook.yml` 的 `checkType` 同步改为增量 `turbo run typecheck --filter=...[HEAD] --concurrency=4`(38 → 10 个任务,属缩时优化非根因)。已清理卡死进程链,`.git/index.lock` 无残留 2026-09-14 | FIX | **commit「卡死」排查(次要优化):pre-commit 类型检查改增量**:`lefthook.yml` 的 `checkType` 原为全量 `pnpm check:type`(`turbo run typecheck`,实测 **38 个任务**,turbo 默认并发 10 个 vue-tsc 进程,本机 16 核/31G 再加 dev server 与 IDE 极易打满内存),改为 `pnpm exec turbo run typecheck --filter=...[HEAD] --concurrency=4`(只校验「自 HEAD 起有改动的包 + 依赖它们的包」,实测降为 **10 个任务**,并限制并发)。应急跳过:`LEFTHOOK=0 git commit ...`。另核实:Git Bash 下 `pnpm --version` → 11.16.0(启动器 shim 生效,钩子执行环境正常,`pnpm exec oxlint` 0.8s) 2026-09-14 | FIX | **Git commit/push 异常修复**:①commit 报 `fatal: Unable to create '.git/index.lock': File exists` —— 23:46 一次中断的 Git 操作残留锁(IDE 状态栏 `git add` 失败即此),确认无 git 进程持有后手动删除 `.git/index.lock`,`git status` 恢复正常;②push 卡死 —— 系统级 `credential.helper=manager`(GCM 2.6.1)**未存 `git.xpcool.com` 凭证**(凭据管理器只有 `admin.git.ybtdev.com`),且 GCM 对自建站点自动探测 provider **超时 >2000ms**(`warning: auto-detection of host provider took too long`)导致长时间挂起;已加全局配置 `credential.https://git.xpcool.com.provider=generic` 消除探测超时,凭证需**首次在有交互的终端输一次账号密码**由 GCM 持久化(详见 agents.md 第 8 节) 2026-09-14 | FIX | **pnpm `node:sqlite` 崩溃的真正根因定位 + 最终修复**:环境变量路线无效(IDE 注入的进程级 `NODE_OPTIONS` 优先级高于用户级/profile),改从**启动器层面**修 —— `C:\Program Files\nodejs\` 下三个 shim(`pnpm.cmd` / `pnpm.ps1` / `pnpm`)给 node 加 `--experimental-sqlite` **并同时注入 `NODE_OPTIONS`**。关键机理:全局 pnpm 是 **10.26.2**,它发现 `packageManager: pnpm@11.16.0` 会**另起一个 node 子进程**去跑 11.16.0(报错栈里的 `.tools/pnpm/11.16.0_tmp_33856` 即此),命令行 flag 传不过去,**只有环境变量会被子进程继承**;而 11.16.0 有 12 处 `node:sqlite` 引用(10.26.2 为 0 处),叠加本机 Node v23.0.0(< 23.4 需 flag)必崩。实测 `pnpm.cmd --version` → `11.16.0` ✅。备份:`C:\Users\xxl\pnpm-shim-backup-20260914`。⚠️ 重装 Node 会覆盖 shim 2026-09-14 | FIX | pnpm 11.16.0 启动即崩 `ERR_UNKNOWN_BUILTIN_MODULE: No such built-in module: node:sqlite`(本机 Node v23.0.0,该内置模块 23.4 前需 `--experimental-sqlite` 才启用):①新建 PowerShell **AllHosts** profile `C:\Users\xxl\Documents\WindowsPowerShell\profile.ps1`(`Microsoft.PowerShell_profile.ps1` 被误建成目录,故改用 AllHosts)幂等追加 `NODE_OPTIONS=--experimental-sqlite`,保留 IDE 注入的 `--require` shim;②新建 `~/.bashrc` 同样幂等追加(Git Bash 场景);③`setx NODE_OPTIONS "--experimental-sqlite"` 用户级兜底(cmd/外部终端);④`.npmrc` 加 `engine-strict=false` + 说明注释(`.npmrc` 的 node-options 对 pnpm 自身无效)。根治方案:升级 Node 到 24.12+(满足 engines,node:sqlite 已默认启用,无需任何 flag) 2026-09-14 | CHG | **壁纸模块(admin 侧)上线**:①`api/wallpaper.ts`(244 行,12 接口,全 POST、URL 无参)——open 组 `sources/list/random/download-track`,admin 组 `list/upload/save/delete/stats/source-list/source-save/source-test`;上传走 multipart,**须由后端 fullBody 加密豁免**(见 service 侧 FIX);②`views/wallpaper/library/index.vue`(569 行)我的图库:多选/拖拽上传 + 进度、缩略图网格、标题/标签/来源编辑、分页、批量删除、原图预览**含全屏查看**;③`views/wallpaper/source/index.vue`(310 行)开源平台管理:Bing/Picsum/Unsplash/Pexels/Wallhaven 五平台启停 + 排序 + 密钥配置 + 连通性测试。菜单由 service 端 `018_wallpaper.sql` 动态下发(RBAC 按 POST+path 精确匹配)。**PC/移动双端适配**:≤768px 工具栏折行、卡片转单列列表。本站已在生产环境以 `VITE_GLOB_API_ENCRYPT=true` 全量加密模式完成端到端验证 2026-09-14 | CHG | 壁纸全屏功能(前台 + 后台双端):前台 xpcool.com 新增 `composables/useFullscreen.ts`,`ControlDock` 增全屏按钮,壁纸预览支持全屏;后台 admin 图库预览页支持图片全屏。统一走 Fullscreen API(`requestFullscreen`/`exitFullscreen`),监听 `fullscreenchange` 同步按钮态与 ESC 退出,不支持元素级全屏的浏览器降级为「新窗口打开原图」 2026-09-14 | CFG | **ICP 备案号更正为 `黔ICP备2026003933号`**(原 `闽ICP备19024351号`):与 xpcool.com 主站同域名同备案。改三处保持一致 —— ①`packages/preferences/src/index.ts` 的 `appCopyrightPreferences`(**真正生效处**,被 apps/web-tdesign/src/preferences.ts 覆盖引用)②`packages/@core/preferences/src/config.ts` 框架默认值 ③`__tests__/__snapshots__/config.test.ts.snap` 快照;push main/dev 由 Gitea Actions 自动构建部署到 /data/www/admin.xpcool.com 2026-08-27 | CHG | 登录接口豁免全量加密,永远只加密密码字段:loginApi 始终走 hybridEncryptLogin(提交 {username 明文, encryptedKey, encryptedData});request.ts PLAIN_ROUTE_FRAGMENTS 增 /auth/login(请求拦截器不再整体加密登录 body)。全量模式 5 项 + dev 15 项 E2E 验证通过 2026-08-27 | CHG | 全量请求/响应加密(生产 VITE_GLOB_API_ENCRYPT=true):①crypto.ts 增 encryptPayload(整体加密任意对象,返回 aesKeyB64 会话密钥)+ decryptPayload(AES-GCM 解密后端响应,密文=nonce||ciphertext||tag);②request.ts 增 installCryptoInterceptors——请求拦截器将整个 JSON body 混合加密(public-key 豁免、FormData/无 body 跳过)、响应解密拦截器最先注册(axios 响应拦截器按注册顺序执行)还原 {code,message,data},requestClient 与 baseRequestClient 均安装;apiFullBodyEncrypt/fetchPublicKeyForCrypto 导出;③auth.ts loginApi、system.ts createAdmin/resetAdminPassword 全量模式下直接传明文密码由拦截器整体加密(开发模式仍走密码字段混合加密);④.env.production VITE_GLOB_API_ENCRYPT=true / .env.development=false。⚠️TS 坑:Uint8Array.subarray 返回 ArrayBufferLike 泛型不满足 BufferSource,需 new Uint8Array() 拷贝;axios 类型从 @vben/request re-export 导入(web-tdesign 未声明 axios 依赖)。typecheck+oxlint 全绿,全量/仅密码两种模式 E2E 均通过 2026-08-27 | CHG | 登录/创建/重置密码全链路加密传输(RSA+AES 混合加密,与后端配套):①新增 src/utils/crypto.ts——Web Crypto API 零依赖:importKey('spki') 导入后端公钥、随机 AES-256-GCM 加密载荷(nonce 12B 前置、GCM tag 随密文)、RSA-OAEP(SHA-256) 加密 AES 密钥,输出 {encryptedKey, encryptedData};公钥 5 分钟内存缓存。②api/core/auth.ts:getPublicKeyApi(并发去重)+ loginApi 先拉公钥再加密 username/password 提交,网络传输无明文密码。③api/system.ts:createAdmin/resetAdminPassword 的 password 走 hybridEncryptField 加密(encryptField 复用公钥缓存)。④注意:Web Crypto 仅安全上下文可用(https/localhost/127.0.0.1),http://IP 访问会明确报错。typecheck + oxlint 全绿 2026-08-27 | CHG | 用户管理改造(页面标题改"用户管理",表单/列表加 Bark设备ID、pushplus token)+ 通知模块 3 页(规则:渠道多选+用户多选+标题/内容模板+测试按钮;渠道:启用+JSON 配置;日志:事件/渠道/结果/时间筛选)+ 自动任务 2 页(任务列表:cron 编辑/启停/手动执行;运行日志:按任务筛选+耗时/摘要/错误);api/notice.ts + autoJob.ts + system.ts 扩展(AdminItem 加渠道字段);typecheck 通过 2026-08-27 | FIX | 前后端联查修复「界面/菜单/工作台异常」:①本地库缺 010_server_log_enhance 增量列(admin_operation_log 无 ip_location/admin_username 等)致操作日志接口 500,已导;②本地缺工作台/招聘菜单+admin_role_menu 关联,已导 013_workbench_menu+recruitment/003_menu;③工作台快捷入口 /system/log/* 是死链(真实路由 /log/*)已改;④打通 Drawer 重构遗留编译错:6 页 @vben-core/popup-ui 误引改 @vben/common-ui、preferences 补 languageToggleButtonPosition、清未用变量、menu/log 页 lint 债(7dc9bc6,钩子全绿);⑤发现审计 admin_username/user_agent 长期为空=线上跑旧二进制,新构建验证 248 号记录字段完整,历史空账号已按 user_id 回填(121 条);⑥本地 xxcool/opuser 密码已重置为 opuser123 便于联调 2026-08-27 | CHG | 三大改造:①移除国际化多语言仅留中文——preferences.ts 固定 locale=zh-CN;删除 header/toolbar/user-dropdown 三处语言切换入口、偏好面板语言选择项(general.vue/appLocale/widget.vue languageToggle 位置配置);config.ts 禁 languageToggle 且 order 移除;删除主应用与 packages/locales 的 en-US 语言包;locales/index.ts loadDayjsLocale 仅留 zh-CN。②新增主题色管理——theme.css 品牌色改为引用 --primary 变量(不再写死 #4f5bff),背景/主按钮渐变用 color-mix 跟随主题色,配合 useTDesignDesignTokens 使偏好面板 BuiltinTheme 切换主题色真正生效;constants.ts default 主题色与 config.ts colorPrimary 统一为靛蓝 hsl(235 100% 65%)。③业务弹窗统一为 vben 抽屉——6 页(system/{role,menu,admin}、recruitment/push、house/{listing,community})的 t-dialog 全部替换为 useVbenDrawer(),drawerApi.open/close/setState(标题)/lock(提交中);community/listing 抽屉加宽(class w-160/w-150) 2026-08-27 | CHG | 服务器安全日志页(挂在系统监控菜单下,id=96):views/monitor/security/index.vue——顶部 4 统计卡片(SSH爆破/fail2ban封禁/成功登录/总数)+ TOP 攻击源标签区 + 筛选(来源IP/事件类型/时间范围 t-date-range-picker)+ Vben VxeTable 列表(时间/来源IP/来源端口/目标端口/事件类型标签/详情 tooltip,事件标签按类型配色);api/serverSecurity.ts(list/stats 全 POST,无 URL 参数);typecheck 通过 2026-08-27 | CHG | 全量表格重构:views 下全部 11 个 t-table 页面统一改为 Vben Vxe Table(useVbenVxeGrid,#/adapter/vxe-table)+ Vben TableAction 行操作——system/{log(范式),login-log,admin,role}、recruitment/{info,crawler,push}、house/{data,listing,community,presale}、dashboard/workbench(两处本地小表 proxyConfig.enabled=false + gridApi.setGridOptions 写数据)。要点:gridOptions 需注解 VxeTableGridOptions(否则 type:'seq' 推断 string 报错);单元格自定义用 columns[].slots.default + h(TDesign组件);远程分页走 proxyConfig.ajax.query 返回 {items,total};筛选区保留手写 TDesign 组件不动;admin/role/listing/community 行操作 ActionItem 带 auth 权限码、删除 danger 标红;listing 多选批量标记改 vxe checkboxConfig + gridApi.grid.getCheckboxRecords();confirm 弹窗交互(删除/重置密码)保留 DialogPlugin 不变;typecheck 通过 2026-08-27 | FIX | 恢复丢失的前端代码:recovery 分支经 rebase/改名(dev↔main)折腾后工作树回退,未提交改动全丢;从悬空提交 f02a514(recovery 工作树快照,含 HEAD 缺失的全部文件)整体恢复 apps/web-tdesign/src——含 styles/theme.css 全局主题、dashboard/workbench 工作台页、system 五页卡片化美化、操作日志增强版(VxeTable)、house 预售/楼盘地图、recruitment 页面;另补 log 页卡片美化(wb-page-head+t-card)。已提交保护 2026-08-26 | CFG | 安装 TDesign MCP(~/.workbuddy/mcp.json 新增 tdesign-mcp-server: `npx -y tdesign-mcp-server@latest`,v0.2.4 启动验证通过);约定:后续后台界面开发优先用 TDesign MCP 查官方文档(get-component-docs 等) 2026-08-26 | FIX+CHG | 修复前端编译错误(access.ts layoutMap 重复声明致 vite Transform PARSE_ERROR);菜单管理树形改用 tdesign 官方方案:`t-enhanced-table`(t-table 不支持 tree)+ tree{childrenKey/treeNodeColumnIndex/defaultExpandAll/indent} + 异步数据后 `ref.expandAll()`(defaultExpandAll 仅首次渲染生效)——替代先前扁平化+缩进的自造方案 2026-08-27 | CHG | 看房新增新房预售页:views/house/presale/index.vue(预售证列表:证号/楼盘/开发商/区县/位置/楼栋/套数/面积/用途/发证/公示日期,筛选 region/purpose/keyword);api/house.ts 加 PresaleItem/getPresaleList;菜单 95 新房预售(014 种子,component=house/presale/index);typecheck 通过 2026-08-26 | CFG | 新增 .gitea/workflows/deploy.yml(Gitea act_runner 自动部署):push main/dev → 下载 node22 二进制(npmmirror,覆盖镜像 node20,pnpm11 需 node:sqlite)→ corepack pnpm@11.16.0 → pnpm install → 直接 vite build(避开 turbo 卡死)→ cp dist 到 /data/www/admin.xpcool.com/;YAML 已校验 2026-08-26 | CHG | 看房 house 模块前端落地:api/house.ts + views/house/{community,listing,dashboard,data}/index.vue(小区 CRUD、房源多维筛选+多选批量标记笋盘/低可信、看板 echarts 概览卡片/区域均价柱状/挂牌vs成交趋势);菜单走后端动态路由(011 种子 component=house/xxx/index),图表复用 @vben/plugins/echarts 的 EchartsUI/useEcharts 2026-08-26 | DEP | 线上 dist 更新为「无下拉版」(vite build 产物,index-index-B-XlZ2uN.js)并部署 /data/www/admin.xpcool.com/,修复登录 no rows:根因=线上仍是 19:32 旧版(默认 admin/admin123),admin 已删故报错;验证:线上 index 新版 + xxcool 登录成功 + js 无 admin123;⚠️ webhook 自动部署未生效:deploy-webhook.service disabled/inactive(8/22 11:52 停止,9000 未监听),提交代码不会自动部署,需 `sudo systemctl enable --now deploy-webhook` + Gitea 仓库 webhook 配置 2026-08-26 | CHG | 登录页移除账号下拉与代码内置账号密码:删除 selectAccount 字段、MOCK_USER_OPTIONS 及自动填充逻辑(BasicOption import 一并清理),前端不再存任何账号密码,改为手输 + 勾选「记住账号」(AuthenticationLogin 内置 rememberMe,localStorage 仅记用户名不存密码);本地 dev(5173) 浏览器验证:无下拉、仅用户名/密码/滑块 + 记住账号复选框 2026-08-26 | CHG | 登录页默认账号替换为 xxcool/xxCool@2026:MOCK_USER_OPTIONS 仅留 Super(xxcool),selectAccount 默认值、密码自动填充同步;本地 dev(5173) 验证登录页下拉正常(combobox Super、账号密码自动填充、展开有 Super 选项),无 admin123 残留;⚠️ 构建注意:pnpm/turbo build 会卡死(两次 15min+ 无产出),需直接 `./node_modules/.bin/vite build --mode production`(约 20s)完成;线上 dist 仍为旧版,待部署 2026-08-26 | DEP | 生产部署上线(193.112.118.168):pnpm build:tdesign 构建 web-tdesign 上传 /data/www/admin.xpcool.com/;nginx HTTPS 站点(证书 /data/nginx/ssl/admin.xpcool.com/,80→301,静态托管 + /api/service 反代 127.0.0.1:10100);https://admin.xpcool.com 首页 200、同源 API 登录通过 2026-08-26 | CHG | .env.production 的 VITE_GLOB_API_URL 由 https://mock-napi.vben.pro/api 改为 /api/service(同源相对路径,由 nginx 反代到后端 10100) 2026-08-26 | REQ | RBAC 至按钮级细粒度全链路核查通过:backend 动态路由(menu/routes)+ 23 权限码下发(auth/codes)+ 三个管理页(admin/role/menu)按钮级 hasAccessByCodes 与后端 seed 权限码逐一匹配;dev server(20104)经 vite 代理→10100 登录/取码 200;后端配套修复禁用角色权限隔离漏洞(见 service CHANGELOG) 2026-08-26 | FIX | 登录接口 502 联调修复:根因为后端 10100 未启动(vite 代理连接拒绝→502);启动后端后 login/info/codes/menu-routes 全链路 200。另记:本机 corepack/pnpm shim 路径转换损坏,需用 `npm exec --package=pnpm@11.16.0` 代替 pnpm 命令 2026-08-26 | CFG | CHANGELOG 纳入 git 管理(.gitignore 放行 .workbuddy/memory/CHANGELOG.md),中央工作空间迁移至 ../workbuddy.xpcool.com(相对路径索引) 2026-08-26 | CHG | 后端 API 统一前缀 /api/service/ + 端口 10100:vite 代理改为 '/api/service'→:10100(合并原 /admin、/api 两条);api 文件全部适配(auth/menu/user/system/log:去 v1、前缀 /api/service、全 POST、CRUD 改动作式路径) 2026-08-26 | FIX | 修复依赖装不上:pnpm 11.16.0 强依赖 node:sqlite,需 `NODE_OPTIONS=--experimental-sqlite` 后 install 成功;同步更正 agents.md 主应用为 web-tdesign(dev:tdesign,5999/6000 端口) 2026-08-26 | CHG | 修正登录页默认账号:selectAccount 默认 admin,密码映射改为种子账号 admin/admin123,便于联调 2026-08-26 | CHG | 同步三铁律(中文注释/做记录/中文优先)至 AGENTS.md「统一工作约定」小节 2026-08-26 | CFG | 建立统一变更记录机制(CHANGELOG),接入 xpcool.com 中央索引