包含: - furniture-3d-system:Next.js 16 全栈应用(资产中心、产品管理、3D装配动画) - autocad-plugin:AutoCAD 家具导出插件源码 - 资产中心改造:编辑弹窗化、删除功能、Toast反馈、自定义Select组件 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10 KiB
10 KiB
Phase 5: 产品归属实现 - 完成文档
📋 概述
Phase 5 已完成,实现了完整的产品协作者管理、SKU 负责人交接、产品列表权限过滤和产品详情权限控制功能。
完成时间:2025-12-12
状态:✅ 已完成
✅ 已完成功能
1. 产品协作者管理 API ✅
文件:src/app/api/products/[id]/collaborators/route.ts
- ✅
GET /api/products/[id]/collaborators- 获取产品的协作者列表 - ✅
POST /api/products/[id]/collaborators- 添加协作者 - ✅
DELETE /api/products/[id]/collaborators- 移除协作者
功能特点:
- 支持添加编辑者(editor)和查看者(viewer)两种角色
- 自动记录协作者添加时间和操作者
- 完整的权限检查(创建者、管理员、部门管理员可管理)
- 防止重复添加协作者
- 记录操作日志
2. SKU 交接 API ✅
文件:src/app/api/skus/[id]/transfer/route.ts
- ✅
POST /api/skus/[id]/transfer- 交接 SKU 负责人
功能特点:
- 支持管理员交接和负责人自主交接
- 负责人只能交接给同部门或同小组成员
- 必须填写交接原因
- 完整的交接历史记录
- 自动通知相关人员
- 记录操作日志
3. 产品列表权限过滤 API ✅
文件:src/app/api/products/route.ts
- ✅
GET /api/products- 获取产品列表(带权限过滤) - ✅
POST /api/products- 创建产品
权限过滤规则:
- 超级管理员/管理员:查看所有产品
- 部门管理员:查看本部门的产品
- 组长:查看本小组成员创建的产品
- 设计师:查看自己创建的、协作的、以及根据可见性可访问的产品
- 查看者:查看 PUBLIC 和本部门 DEPARTMENT 可见性的产品
查询功能:
- 支持搜索(型号、名称、描述)
- 支持分类过滤
- 支持可见性过滤
- 支持分页
4. 产品详情权限 API ✅
文件:src/app/api/products/[id]/route.ts
- ✅
GET /api/products/[id]- 获取产品详情(带权限检查) - ✅
PUT /api/products/[id]- 更新产品 - ✅
DELETE /api/products/[id]- 删除产品(软删除)
功能特点:
- 完整的产品信息(包括 SKU、装配步骤、板件、分享链接、反馈)
- 返回用户对此产品的权限信息
- 软删除机制(同时删除所有 SKU)
- 完整的权限检查
- 记录操作日志
5. 权限检查函数增强 ✅
文件:src/lib/permissions.ts
- ✅ 新增
canManageCollaborators()- 检查是否可以管理协作者
📁 文件结构
furniture-3d-system/
├── src/
│ ├── app/
│ │ └── api/
│ │ ├── products/
│ │ │ ├── route.ts # 产品列表和创建 API
│ │ │ └── [id]/
│ │ │ ├── route.ts # 产品详情、更新、删除 API
│ │ │ └── collaborators/
│ │ │ └── route.ts # 协作者管理 API
│ │ └── skus/
│ │ └── [id]/
│ │ └── transfer/
│ │ └── route.ts # SKU 交接 API
│ └── lib/
│ └── permissions.ts # 更新:添加协作者管理权限
└── docs/
└── PHASE5_COMPLETE.md # 本文档
🔐 权限控制
产品协作者管理权限
- 添加/移除协作者:超级管理员、管理员、部门管理员(本部门)、产品创建者
SKU 交接权限
- 管理员交接:超级管理员、管理员、部门管理员(本部门)
- 负责人自主交接:SKU 负责人(只能交接给同部门或同小组成员)
产品查看权限
- 超级管理员/管理员:所有产品
- 部门管理员:本部门产品
- 组长:本小组产品
- 设计师:自己创建的、协作的、可见性允许的产品
- 查看者:PUBLIC 和本部门 DEPARTMENT 产品
产品编辑权限
- 超级管理员/管理员:所有产品
- 部门管理员:本部门产品
- 组长:本小组产品
- 产品创建者:自己的产品
- 协作者(editor):协作的产品
产品删除权限
- 超级管理员/管理员:所有产品
- 部门管理员:本部门产品
- 组长:本小组产品
📊 数据模型
产品协作者结构
interface Collaborator {
userId: string; // 协作者用户ID
role: 'editor' | 'viewer'; // 角色:编辑者或查看者
addedAt: string; // 添加时间
addedBy: string; // 添加者ID
}
// 存储在 Product.collaborators (JSON)
SKU 交接记录结构
interface TransferRecord {
fromUserId: string; // 原负责人ID
fromUserName: string; // 原负责人姓名
toUserId: string; // 新负责人ID
toUserName: string; // 新负责人姓名
transferredAt: string; // 交接时间
reason: string; // 交接原因
operatorId: string; // 操作者ID
operatorName: string; // 操作者姓名
operatorRole: string; // 操作者角色
}
// 存储在 ProductSKU.transferHistory (JSON)
产品可见性枚举
enum Visibility {
PRIVATE = 'PRIVATE', // 私有(仅创建者和协作者)
TEAM = 'TEAM', // 小组可见
DEPARTMENT = 'DEPARTMENT', // 部门可见
PUBLIC = 'PUBLIC', // 公开(所有人可见)
}
📝 API 使用示例
1. 获取产品列表(带权限过滤)
const response = await fetch('/api/products?page=1&pageSize=20&search=沙发', {
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = await response.json();
// {
// products: [...],
// pagination: {
// page: 1,
// pageSize: 20,
// total: 50,
// totalPages: 3
// }
// }
2. 获取产品详情(带权限信息)
const response = await fetch(`/api/products/${productId}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = await response.json();
// {
// product: {...},
// permissions: {
// canEdit: true,
// canDelete: false,
// canManageCollaborators: true
// }
// }
3. 添加协作者
const response = await fetch(`/api/products/${productId}/collaborators`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
userId: 'user123',
role: 'editor', // 或 'viewer'
}),
});
4. 移除协作者
const response = await fetch(
`/api/products/${productId}/collaborators?userId=user123`,
{
method: 'DELETE',
headers: {
Authorization: `Bearer ${token}`,
},
}
);
5. 交接 SKU
const response = await fetch(`/api/skus/${skuId}/transfer`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
toUserId: 'user456',
reason: '离职交接',
}),
});
6. 创建产品
const response = await fetch('/api/products', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
modelNumber: 'A001',
name: '现代简约沙发',
description: '舒适的三人座沙发',
category: '沙发',
visibility: 'TEAM',
}),
});
7. 更新产品
const response = await fetch(`/api/products/${productId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
name: '现代简约沙发(升级版)',
description: '更新的描述',
visibility: 'DEPARTMENT',
}),
});
8. 删除产品(软删除)
const response = await fetch(`/api/products/${productId}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${token}`,
},
});
✅ 验收标准
- 产品协作者 CRUD API 正常工作
- SKU 交接 API 正常工作
- 产品列表根据角色正确过滤
- 产品详情权限检查正确
- 协作者角色(editor/viewer)正确区分
- SKU 负责人自主交接限制正确(同部门/同小组)
- 交接历史记录完整
- 产品可见性(PRIVATE/TEAM/DEPARTMENT/PUBLIC)正确实现
- 软删除机制正常工作
- 操作日志记录完整
- 权限检查函数完善
- API 返回数据结构合理
📊 代码统计
- 新增文件:4 个
- 修改文件:1 个
- 新增代码行数:约 1000 行
- API 端点:8 个
🔄 数据关系
Product (产品)
├── createdBy → User (创建者)
├── departmentId → Department (所属部门)
├── collaborators → JSON (协作者列表)
│ └── [{ userId, role, addedAt, addedBy }]
├── visibility → Enum (可见性)
└── skus → ProductSKU[] (SKU 列表)
ProductSKU (SKU)
├── productId → Product (所属产品)
├── ownerId → User (负责人)
└── transferHistory → JSON (交接历史)
└── [{ fromUserId, toUserId, transferredAt, reason, operatorId }]
🚀 下一步
Phase 5 已完成,可以继续后续阶段:
Phase 6: 离职交接实现
- 离职检测
- SKU 交接界面
- 交接历史记录
- 通知系统
Phase 7: 问题反馈实现
- 反馈提交界面
- 反馈处理界面
- 自动分配逻辑
- 反馈统计
Phase 8: 数据安全与日志
- 操作日志查询
- 数据备份
- 审计报表
📞 注意事项
-
协作者角色:
editor:可以编辑产品viewer:只能查看产品
-
SKU 交接限制:
- 管理员可以交接给任何人
- 负责人只能交接给同部门或同小组成员
- 必须填写交接原因
-
产品可见性:
PRIVATE:仅创建者和协作者可见TEAM:小组成员可见DEPARTMENT:部门成员可见PUBLIC:所有人可见
-
软删除:
- 删除产品时同时软删除所有 SKU
- 软删除的数据不会在列表中显示
- 可以通过数据库恢复
-
权限过滤:
- 产品列表根据用户角色自动过滤
- 不同角色看到的产品列表不同
- 确保数据安全
Phase 5 完成! ✅
产品归属功能已全部实现,支持协作者管理、SKU 交接、权限过滤和详情权限控制。