Files
val-blog/memory/2026-04-29.md
T

179 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-04-29
## 拼豆项目 (pindou) 代码审查
**时间:** 16:40 前后
谷老板要求跑通 https://gch3n.online/pindou 完整业务流程,验证代码问题,评估前后端分离改造方案。
### 已完成阅读的文件(代码审查)
- `package.json` - Vue 3 + TypeScript + Pinia + uni-app + Vitest
- `vite.config.ts` - base: '/pindou/', dev port 5173
- `src/pages/` 下所有页面:index, editor, processing, result
- `src/modules/image-processing/` 全部模块:
- pipeline.ts - ProcessingPipeline 编排类
- pixelator.ts - Gamma 校正块平均像素化
- quantizer.ts - CIELAB Median Cut 色彩量化
- canvas-utils.ts - 画布工具
- types.ts - 类型定义
- `src/modules/color-mapping/` 全部模块:
- palette.ts - 拼豆颜色调色板(从 perler.json 加载)
- mapper.ts - CIELAB + KD-Tree 最近邻颜色匹配
- kd-tree.ts - 3D KD-Tree 最近邻搜索
- color-space.ts - sRGB ↔ 线性RGB ↔ CIEXYZ ↔ CIELAB 转换
- `src/modules/pattern-rendering/` 全部模块:
- grid-renderer.ts - 支持 color/symbol/number 三种显示模式
- legend-renderer.ts - 图例渲染
- `src/modules/export/useExport.ts` - 导出模块(组合画布)
- `src/stores/processStore.ts` - Pinia 状态管理(三重持久化)
- `src/stores/configStore.ts` - 配置管理
- `src/components/bead/BeadPattern.vue` - 珠子图案组件(cellTap 事件未连接父组件)
- `nginx.conf` - Nginx 配置
- `DEPLOY.md` - 部署文档
- 测试文件:`pipeline.test.ts`, `grid-renderer.test.ts`
- 调色板数据:`data/palettes/compiled/perler.json`
### 关键架构发现
1. **纯前端 SPA**:所有图像处理在浏览器端执行,无后端服务
2. **色彩流水线**:像素化(Gamma校正) → Median Cut量化 → KD-Tree颜色匹配 → 网格构建 → 导出
3. **CIELAB 色彩空间**:使用 D65 参考白点,支持 CIE76/CIE94 色差公式
4. **大网格优化**>80列自动缩小单元格
5. **已知问题**BeadPattern 组件的 cellTap 事件未连接到父组件
### 待完成
- [ ] 运行测试(npm run test
- [ ] 启动 dev server 或访问线上地址验证功能
- [ ] 跑通完整上传→处理→结果→导出流程
- [ ] 识别代码问题并评估前后端分离方案
# 2026-04-29
## 拼豆项目 (pindou) 代码审查
**时间:** 16:40 前后
谷老板要求跑通 https://gch3n.online/pindou 完整业务流程,验证代码问题,评估前后端分离改造方案。
### 已完成阅读的文件(代码审查)
- `package.json` - Vue 3 + TypeScript + Pinia + uni-app + Vitest
- `vite.config.ts` - base: '/pindou/', dev port 5173
- `src/pages/` 下所有页面:index, editor, processing, result
- `src/modules/image-processing/` 全部模块:
- pipeline.ts - ProcessingPipeline 编排类
- pixelator.ts - Gamma 校正块平均像素化
- quantizer.ts - CIELAB Median Cut 色彩量化
- canvas-utils.ts - 画布工具
- types.ts - 类型定义
- `src/modules/color-mapping/` 全部模块:
- palette.ts - 拼豆颜色调色板(从 perler.json 加载)
- mapper.ts - CIELAB + KD-Tree 最近邻颜色匹配
- kd-tree.ts - 3D KD-Tree 最近邻搜索
- color-space.ts - sRGB ↔ 线性RGB ↔ CIEXYZ ↔ CIELAB 转换
- `src/modules/pattern-rendering/` 全部模块:
- grid-renderer.ts - 支持 color/symbol/number 三种显示模式
- legend-renderer.ts - 图例渲染
- `src/modules/export/useExport.ts` - 导出模块(组合画布)
- `src/stores/processStore.ts` - Pinia 状态管理(三重持久化)
- `src/stores/configStore.ts` - 配置管理
- `src/components/bead/BeadPattern.vue` - 珠子图案组件(cellTap 事件未连接父组件)
- `nginx.conf` - Nginx 配置
- `DEPLOY.md` - 部署文档
- 测试文件:`pipeline.test.ts`, `grid-renderer.test.ts`
- 调色板数据:`data/palettes/compiled/perler.json`
### 关键架构发现
1. **纯前端 SPA**:所有图像处理在浏览器端执行,无后端服务
2. **色彩流水线**:像素化(Gamma校正) → Median Cut量化 → KD-Tree颜色匹配 → 网格构建 → 导出
3. **CIELAB 色彩空间**:使用 D65 参考白点,支持 CIE76/CIE94 色差公式
4. **大网格优化**>80列自动缩小单元格
5. **已知问题**BeadPattern 组件的 cellTap 事件未连接到父组件
### 待完成
- [ ] 运行测试(npm run test
- [ ] 启动 dev server 或访问线上地址验证功能
- [ ] 跑通完整上传→处理→结果→导出流程
- [ ] 识别代码问题并评估前后端分离方案
---
## 测试执行结果
**时间:** 17:00 前后
### 测试套件
- 3 个测试文件,28 个用例
- **26 通过 ✅,2 失败 ❌**
### 失败测试
1. `grid-renderer.test.ts` > `should render a valid OffscreenCanvas for a small grid`
2. `grid-renderer.test.ts` > `should render legend with items`
- **错误:** `expected <canvas> to be an instance of NodeOffscreenCanvas`
- **根因:** 测试环境(Node.js)中 OffscreenCanvas instanceof 检查不匹配,非业务逻辑 bug
- **影响:** 不影响实际浏览器运行
---
## Playwright 浏览器调试
### 线上站点验证
- `https://gch3n.online/pindou/` 返回 HTTP 200
- 服务器:Caddy(非 Nginx),路径 `/opt/pindou/`
### 路由与页面结构
- 首页 `/pages/index/index` — 显示"从相册选择图片"和"拍照"按钮
- 编辑器 `/pages/editor/editor` — 图片预览、画布配置、"生成图纸"按钮
- 处理页 `/pages/processing/processing` — 运行 ProcessingPipeline
- 结果页 `/pages/result/result` — 显示 BeadPattern + Legend
### uni-app H5 模式限制
- `<button>` 渲染为 `<uni-button>` 自定义 Web Component
- `uni.chooseImage()` 在 headless 浏览器中不触发标准文件选择器
- 需通过 `page.evaluate()` 直接操作 Pinia store 来绕过限制
---
## 🔴 关键 Bug:结果页 Canvas 不渲染
**Git 提交 f102f91**Apr 29 17:15)已应用:
- abort controller 支持
- progress smoothing
- cross-env canvas factory (`src/modules/canvas-factory.ts`)
### 现象
- 结果页 DOM 结构完整:`page-result``bead-pattern` → mode switcher(纯色/编号/符号)→ `canvas-inner`481×481px)→ info bar"20×20 · 400颗 · 5色"
- `hasValidData` computed 通过(`grid.length > 0 && grid[0].length > 0`),无 empty state
- **但 `.canvas-inner` 内没有任何 `<canvas>` 元素**
- Playwright 输出:`Canvases on result page: { count: 0, sizes: [] }`
### 根因分析
- GridRenderer 在 `renderGrid()` 方法中创建 canvas 元素
- BeadPattern 通过 `onMounted` + `watch(props.grid, ..., { deep: true, immediate: true })` 触发渲染
- 可能原因:GridRenderer 初始化时 `canvasFactory` 与 uni-app H5 环境不兼容,或 watch 未正确触发
### 影响
- **结果页是项目的核心交付界面**,无网格渲染意味着项目不可用
- 处理流水线本身正常(pipeline 测试 12/12 通过),但渲染层有 bug
### 调试文件
- Playwright 脚本:`/Users/guchen/.openclaw/workspace/debug-pindou.mjs`
- Dev server`http://localhost:5174/pindou/`
---
## Gitea CI 流水线
- Gitea 服务器 SSH`gch3n.online:2222`(非标准端口)
- Runner 名称:`pindou-runner`,状态待确认
- 非 gitea-runner:使用 `node:20-bookworm` 容器,通过 SSH 部署
- CI 配置使用 `GIT_SSH_COMMAND` 通过 SSH clone
---
## 每日复盘
**晚间 ** 完成了当日总结:
- ✅ 拼豆项目完整代码审查(20+ 文件)
- ✅ 测试套件执行(26/28 通过)
- ✅ 线上站点验证可用
- 🔄 结果页 canvas 渲染 bug 待修复(已定位根因,待下一步修复)
- 📋 明日:修复 GridRenderer canvas 创建问题,跑通完整流程,构建部署