The file /home/project/AGENTS.md has been updated. Made 1 replacement.
Here's the result of running `cat -n` on a snippet of the edited file:
466→- **UI 优化**
467→ - 纺织厂工作台"原坯布仓库"更名为"已生产坯布"
468→ - 更新首页快捷操作按钮标签
469→
470→## Bug 修复记录
471→
472→### 2025-05-26 计划字段显示不一致问题
473→
474→#### 问题描述
475→采购商和纺织厂的计划总览页面显示字段不一致,纺织厂缺少克重、纱线配比、生产采购价等关键字段。
476→
477→#### 根本原因
478→- `usePlanData.ts` Hook 未查询 `products` 表关联数据
479→- `PlanGroup.tsx` 组件未展示 weight、yarn_ratios、production_price 等字段
480→- 纺织厂 `PlanOverview.tsx` 缺少展开详情视图
481→
482→#### 修复方案
483→1. **数据层**:在 `usePlanData.ts` 中添加 products 表查询,获取 weight、image_url 等字段
484→2. **组件层**:在 `PlanGroup.tsx` 中添加完整字段展示,包括:
485→ - 克重信息(经线/纬线/总克重)
486→ - 纱线配比列表
487→ - 生产采购价
488→ - 产品图片
489→ - 创建时间、计划开始时间、备注
490→3. **页面层**:纺织厂 `PlanOverview.tsx` 添加展开详情功能,与采购商保持一致
491→
492→#### 代码变更
493→- `src/hooks/usePlanData.ts` - 添加 products 表关联查询
494→- `src/components/plans/PlanGroup.tsx` - 扩展字段展示
495→- `src/pages/textile/PlanOverview.tsx` - 添加展开详情视图
496→- `src/pages/purchaser/PlanOverview.tsx` - 同步优化字段展示
497→
498→#### 经验教训
499→- **数据一致性**:同一业务对象在不同页面的展示应保持一致,仅根据角色权限控制敏感字段
500→- **Hook 复用**:通过统一的数据获取 Hook 确保各页面数据一致性
501→- **类型安全**:扩展类型定义时注意与数据库生成的类型保持兼容
502→
503→---
504→
505→### 2025-05-26 移动端退出按钮适配问题
506→
507→#### 问题描述
508→工作台右上角退出按钮在移动端显示为"退出登录"文字,占用过多空间,与整体移动端设计不协调。
509→
510→#### 根本原因
511→- 退出按钮未做响应式适配
512→- 移动端空间宝贵,文字按钮过于拥挤
513→
514→#### 修复方案
515→使用响应式设计,桌面端显示"退出登录"文字,移动端仅显示 LogOut 图标:
516→```tsx
517→
521→```
522→
523→#### 代码变更
524→- `src/pages/purchaser/Dashboard.tsx` - 退出按钮响应式优化
525→- `src/pages/textile/Dashboard.tsx` - 退出按钮响应式优化
526→- `src/pages/washing/Dashboard.tsx` - 退出按钮响应式优化
527→
528→---
529→
530→### 2025-05-26 拒绝计划状态同步问题
531→
532→#### 问题描述
533→纺织厂拒绝计划后,计划卡片未立即更新视觉状态,且仍显示在 Dashboard "最近计划"中。
534→
535→#### 根本原因
536→- 拒绝操作仅更新数据库,未更新本地状态
537→- Dashboard 和 PlanOverview 之间没有共享拒绝状态
538→- 页面刷新后拒绝状态丢失
539→
540→#### 修复方案
541→1. **本地状态管理**:在 `PlanOverview.tsx` 中使用 `Set` 跟踪被拒绝的计划ID
542→2. **持久化存储**:使用 localStorage 存储拒绝状态,键名为 `textile_rejected_plans`
543→3. **跨页面同步**:Dashboard 从 localStorage 读取拒绝状态并过滤最近计划
544→4. **视觉反馈**:被拒绝的计划显示灰色背景、"已拒绝"标签,并自动折叠
545→
546→#### 代码变更
547→- `src/pages/textile/PlanOverview.tsx` - 添加 rejectedPlans 状态和 localStorage 持久化
548→- `src/pages/textile/Dashboard.tsx` - 添加 rejectedPlanIds 状态,过滤最近计划
549→
550→#### 关键代码
551→```typescript
552→// PlanOverview.tsx - 拒绝时持久化
553→const handleRejectStep = async (step: PlanProcessStep) => {
554→ // ... 提交拒绝原因到数据库 ...
555→
556→ // 更新本地状态
557→ setRejectedPlans(prev => new Set([...prev, step.plan_id]));
558→
559→ // 持久化到 localStorage
560→ const stored = localStorage.getItem('textile_rejected_plans');
561→ const rejectedArray = stored ? JSON.parse(stored) : [];
562→ if (!rejectedArray.includes(step.plan_id)) {
563→ rejectedArray.push(step.plan_id);
564→ localStorage.setItem('textile_rejected_plans', JSON.stringify(rejectedArray));
565→ }
566→};
567→
568→// Dashboard.tsx - 读取并过滤
569→useEffect(() => {
570→ // ... 获取计划列表 ...
571→
572→ // 从 localStorage 读取拒绝状态
573→ const stored = localStorage.getItem('textile_rejected_plans');
574→ if (stored) {
575→ setRejectedPlanIds(new Set(JSON.parse(stored)));
576→ }
577→}, []);
578→
579→// 过滤最近计划
580→const filteredPlans = plans.filter(p => !rejectedPlanIds.has(p.id));
581→const recentPlans = filteredPlans.slice(0, 5);
582→```
583→
584→#### 经验教训
585→- **状态共享**:跨页面状态可考虑使用 localStorage、URL 参数或全局状态管理
586→- **乐观更新**:用户操作后应立即更新 UI,再同步后端状态
587→- **数据过滤**:Dashboard 展示的数据应根据业务规则进行过滤,而非直接展示原始数据
588→
589→---
590→
591→### 2025-05-25 TypeScript 类型兼容性问题
592→
593→#### 问题描述
594→添加图片功能后出现类型错误:
595→```
596→Types of property 'image_url' are incompatible.