# 产品管理模块 - API接口文档 > **模块**: 11-产品管理 > **版本**: v1.0 > **日期**: 2025-10-03 > **关联文档**: > - 需求文档: `docs/11-产品管理模块需求.md` > - 原型图: `yuanxing/09-产品管理原型图.md` > - 数据库: `sql/crm/11-crm_product.sql` --- ## 📋 目录 - [1. 产品分类管理接口](#1-产品分类管理接口) - [2. 产品管理接口](#2-产品管理接口) - [3. 统计分析接口](#3-统计分析接口) - [4. 数据模型](#4-数据模型) --- ## 1. 产品分类管理接口 ### 1.1 查询分类列表(树形) **接口地址**: `GET /crm/product/category/tree` **接口描述**: 获取产品分类树形结构,用于分类选择器和分类管理页面 **权限标识**: `crm:product:category:list` **请求参数**: 无 **返回示例**: ```json { "code": 200, "msg": "操作成功", "data": [ { "id": 1, "categoryName": "软件产品", "parentId": 0, "ancestors": "0", "sort": 1, "status": "0", "children": [ { "id": 11, "categoryName": "CRM系统", "parentId": 1, "ancestors": "0,1", "sort": 1, "status": "0", "children": [ { "id": 111, "categoryName": "标准版", "parentId": 11, "ancestors": "0,1,11", "sort": 1, "status": "0" } ] } ] } ] } ``` --- ### 1.2 查询分类详情 **接口地址**: `GET /crm/product/category/{id}` **接口描述**: 根据ID查询分类详细信息 **权限标识**: `crm:product:category:query` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 分类ID | **返回示例**: ```json { "code": 200, "msg": "操作成功", "data": { "id": 1, "categoryName": "软件产品", "parentId": 0, "ancestors": "0", "sort": 1, "status": "0", "createTime": "2025-01-01 10:00:00", "remark": "软件类产品分类" } } ``` --- ### 1.3 新增分类 **接口地址**: `POST /crm/product/category` **接口描述**: 新增产品分类 **权限标识**: `crm:product:category:add` **请求体**: ```json { "categoryName": "软件产品", "parentId": 0, "sort": 1, "status": "0", "remark": "软件类产品分类" } ``` **请求参数说明**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | categoryName | String | 是 | 分类名称,最大100字符 | | parentId | Long | 否 | 父级分类ID,默认0(顶级) | | sort | Integer | 否 | 显示顺序,默认0 | | status | String | 否 | 状态:0-正常 1-停用,默认0 | | remark | String | 否 | 备注,最大500字符 | **返回示例**: ```json { "code": 200, "msg": "操作成功" } ``` --- ### 1.4 修改分类 **接口地址**: `PUT /crm/product/category` **接口描述**: 修改产品分类信息 **权限标识**: `crm:product:category:edit` **请求体**: ```json { "id": 1, "categoryName": "软件产品", "parentId": 0, "sort": 1, "status": "0", "remark": "软件类产品分类" } ``` **请求参数说明**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 分类ID | | categoryName | String | 是 | 分类名称 | | parentId | Long | 否 | 父级分类ID | | sort | Integer | 否 | 显示顺序 | | status | String | 否 | 状态 | | remark | String | 否 | 备注 | **返回示例**: ```json { "code": 200, "msg": "操作成功" } ``` --- ### 1.5 删除分类 **接口地址**: `DELETE /crm/product/category/{ids}` **接口描述**: 删除产品分类(支持批量) **权限标识**: `crm:product:category:remove` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 分类ID数组,多个用逗号分隔 | **业务规则**: - 如果分类下有子分类,不允许删除 - 如果分类下有产品,不允许删除 **返回示例**: ```json { "code": 200, "msg": "操作成功" } ``` --- ## 2. 产品管理接口 ### 2.1 查询产品列表(分页) **接口地址**: `GET /crm/product/list` **接口描述**: 分页查询产品列表,支持多条件筛选 **权限标识**: `crm:product:list` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | pageNum | Integer | 否 | 页码,默认1 | | pageSize | Integer | 否 | 每页条数,默认10 | | productName | String | 否 | 产品名称(模糊查询) | | productNo | String | 否 | 产品编号(模糊查询) | | categoryId | Long | 否 | 分类ID | | status | String | 否 | 状态:on-上架 off-下架 | | minPrice | BigDecimal | 否 | 最低价格 | | maxPrice | BigDecimal | 否 | 最高价格 | | minSaleCount | Integer | 否 | 最小销量 | | maxSaleCount | Integer | 否 | 最大销量 | | beginTime | String | 否 | 开始时间 yyyy-MM-dd HH:mm:ss | | endTime | String | 否 | 结束时间 yyyy-MM-dd HH:mm:ss | **返回示例**: ```json { "code": 200, "msg": "查询成功", "rows": [ { "id": 1, "productNo": "PRD20250101001", "productName": "CRM系统标准版", "categoryId": 11, "categoryName": "CRM系统", "model": "V5.4.0", "unit": "套", "barcode": "6901234567890", "price": 12800.00, "cost": 8000.00, "minPrice": 10000.00, "stock": 100, "lowStock": 10, "status": "on", "description": "适合中小企业的CRM系统", "images": "/upload/product/001.jpg,/upload/product/002.jpg", "saleCount": 156, "createTime": "2025-01-01 10:00:00", "updateTime": "2025-01-15 16:30:00", "remark": "" } ], "total": 89 } ``` --- ### 2.2 查询产品详情 **接口地址**: `GET /crm/product/{id}` **接口描述**: 根据ID查询产品详细信息 **权限标识**: `crm:product:query` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 产品ID | **返回示例**: ```json { "code": 200, "msg": "操作成功", "data": { "id": 1, "productNo": "PRD20250101001", "productName": "CRM系统标准版", "categoryId": 11, "categoryName": "CRM系统", "model": "V5.4.0", "unit": "套", "barcode": "6901234567890", "price": 12800.00, "cost": 8000.00, "minPrice": 10000.00, "stock": 100, "lowStock": 10, "status": "on", "description": "适合中小企业的CRM系统,包含客户管理、销售管理、数据分析等功能", "images": "/upload/product/001.jpg,/upload/product/002.jpg", "saleCount": 156, "createTime": "2025-01-01 10:00:00", "createBy": 1, "updateTime": "2025-01-15 16:30:00", "updateBy": 1, "remark": "标准版产品" } } ``` --- ### 2.3 新增产品 **接口地址**: `POST /crm/product` **接口描述**: 新增产品信息 **权限标识**: `crm:product:add` **请求体**: ```json { "productNo": "PRD20250101001", "productName": "CRM系统标准版", "categoryId": 11, "model": "V5.4.0", "unit": "套", "barcode": "6901234567890", "price": 12800.00, "cost": 8000.00, "minPrice": 10000.00, "stock": 100, "lowStock": 10, "status": "on", "description": "适合中小企业的CRM系统", "images": "/upload/product/001.jpg,/upload/product/002.jpg", "remark": "标准版产品" } ``` **请求参数说明**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | productNo | String | 是 | 产品编号,唯一,最大50字符 | | productName | String | 是 | 产品名称,最大200字符 | | categoryId | Long | 否 | 分类ID | | model | String | 否 | 型号/规格,最大100字符 | | unit | String | 否 | 单位,默认"个",最大20字符 | | barcode | String | 否 | 条码,最大100字符 | | price | BigDecimal | 是 | 标准价格,保留2位小数 | | cost | BigDecimal | 否 | 成本价,保留2位小数 | | minPrice | BigDecimal | 否 | 最低价格,保留2位小数 | | stock | Integer | 否 | 库存数量,默认0 | | lowStock | Integer | 否 | 库存预警值,默认10 | | status | String | 否 | 状态:on-上架 off-下架,默认on | | description | String | 否 | 产品描述,文本类型 | | images | String | 否 | 产品图片,多个用逗号分隔 | | remark | String | 否 | 备注,最大500字符 | **校验规则**: - 产品编号不能重复 - 标准价格必须大于0 - 如果设置了最低价格,最低价格必须≤标准价格 - 如果设置了成本价,成本价必须≤标准价格 **返回示例**: ```json { "code": 200, "msg": "操作成功" } ``` --- ### 2.4 修改产品 **接口地址**: `PUT /crm/product` **接口描述**: 修改产品信息 **权限标识**: `crm:product:edit` **请求体**: ```json { "id": 1, "productNo": "PRD20250101001", "productName": "CRM系统标准版", "categoryId": 11, "model": "V5.4.0", "unit": "套", "barcode": "6901234567890", "price": 12800.00, "cost": 8000.00, "minPrice": 10000.00, "stock": 100, "lowStock": 10, "status": "on", "description": "适合中小企业的CRM系统", "images": "/upload/product/001.jpg,/upload/product/002.jpg", "remark": "标准版产品" } ``` **请求参数说明**: 同新增接口,但需要传入id **返回示例**: ```json { "code": 200, "msg": "操作成功" } ``` --- ### 2.5 删除产品 **接口地址**: `DELETE /crm/product/{ids}` **接口描述**: 删除产品(支持批量) **权限标识**: `crm:product:remove` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 产品ID数组,多个用逗号分隔 | **业务规则**: - 如果产品在商机、报价单、合同中被引用,不允许直接删除 - 建议使用下架功能代替删除 **返回示例**: ```json { "code": 200, "msg": "操作成功" } ``` --- ### 2.6 批量上架/下架 **接口地址**: `PUT /crm/product/status` **接口描述**: 批量修改产品状态(上架/下架) **权限标识**: `crm:product:edit` **请求体**: ```json { "ids": [1, 2, 3], "status": "on" } ``` **请求参数说明**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 产品ID数组 | | status | String | 是 | 状态:on-上架 off-下架 | **返回示例**: ```json { "code": 200, "msg": "操作成功" } ``` --- ### 2.7 批量调价 **接口地址**: `PUT /crm/product/price` **接口描述**: 批量调整产品价格 **权限标识**: `crm:product:edit` **请求体**: ```json { "ids": [1, 2, 3], "priceType": "price", "adjustType": "percent", "adjustValue": 10.0, "remark": "年度调价" } ``` **请求参数说明**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 产品ID数组 | | priceType | String | 是 | 价格类型:price-标准价 cost-成本价 minPrice-最低价 | | adjustType | String | 是 | 调整方式:percent-百分比 fixed-固定金额 | | adjustValue | BigDecimal | 是 | 调整值(百分比或固定金额) | | remark | String | 否 | 调价备注 | **返回示例**: ```json { "code": 200, "msg": "操作成功" } ``` --- ### 2.8 导出产品 **接口地址**: `POST /crm/product/export` **接口描述**: 导出产品数据到Excel **权限标识**: `crm:product:export` **请求体**: 查询参数同2.1列表查询接口 **返回**: Excel文件流 --- ### 2.9 导入产品 **接口地址**: `POST /crm/product/import` **接口描述**: 批量导入产品数据 **权限标识**: `crm:product:import` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | file | MultipartFile | 是 | Excel文件 | | updateSupport | Boolean | 否 | 是否更新已存在的产品,默认false | **返回示例**: ```json { "code": 200, "msg": "操作成功", "data": { "total": 100, "success": 95, "fail": 5, "errors": [ { "row": 3, "error": "产品编号已存在" }, { "row": 7, "error": "分类不存在" } ] } } ``` --- ### 2.10 下载导入模板 **接口地址**: `POST /crm/product/importTemplate` **接口描述**: 下载产品导入Excel模板 **权限标识**: `crm:product:import` **请求参数**: 无 **返回**: Excel文件流 --- ### 2.11 根据编号查询产品 **接口地址**: `GET /crm/product/no/{productNo}` **接口描述**: 根据产品编号查询产品信息 **权限标识**: `crm:product:query` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | productNo | String | 是 | 产品编号 | **返回示例**: 同2.2查询详情接口 --- ### 2.12 产品搜索(下拉选择) **接口地址**: `GET /crm/product/search` **接口描述**: 根据关键词搜索产品,用于产品选择器 **权限标识**: `crm:product:list` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | keyword | String | 否 | 搜索关键词(产品名称/编号) | | categoryId | Long | 否 | 分类ID | | status | String | 否 | 状态,默认只查询上架产品 | | limit | Integer | 否 | 返回条数,默认10 | **返回示例**: ```json { "code": 200, "msg": "查询成功", "data": [ { "id": 1, "productNo": "PRD20250101001", "productName": "CRM系统标准版", "categoryName": "CRM系统", "price": 12800.00, "unit": "套", "stock": 100 } ] } ``` --- ### 2.13 库存预警列表 **接口地址**: `GET /crm/product/stockAlert` **接口描述**: 查询库存低于预警值的产品列表 **权限标识**: `crm:product:list` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | pageNum | Integer | 否 | 页码,默认1 | | pageSize | Integer | 否 | 每页条数,默认10 | **返回示例**: ```json { "code": 200, "msg": "查询成功", "rows": [ { "id": 1, "productNo": "PRD20250101001", "productName": "CRM系统标准版", "stock": 5, "lowStock": 10, "alertLevel": "warning" } ], "total": 8 } ``` --- ## 3. 统计分析接口 ### 3.1 产品统计概览 **接口地址**: `GET /crm/product/statistics/overview` **接口描述**: 获取产品统计概览数据 **权限标识**: `crm:product:list` **请求参数**: 无 **返回示例**: ```json { "code": 200, "msg": "查询成功", "data": { "totalCount": 89, "onlineCount": 76, "offlineCount": 13, "totalSaleCount": 1256, "monthAddCount": 5, "alertCount": 8 } } ``` --- ### 3.2 热销产品排行 **接口地址**: `GET /crm/product/statistics/hot` **接口描述**: 获取热销产品排行榜 **权限标识**: `crm:product:list` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | limit | Integer | 否 | 返回条数,默认10 | **返回示例**: ```json { "code": 200, "msg": "查询成功", "data": [ { "id": 3, "productNo": "PRD20250101003", "productName": "办公自动化系统", "saleCount": 234, "totalAmount": 2059200.00 } ] } ``` --- ### 3.3 分类产品统计 **接口地址**: `GET /crm/product/statistics/category` **接口描述**: 按分类统计产品数量和销量 **权限标识**: `crm:product:list` **请求参数**: 无 **返回示例**: ```json { "code": 200, "msg": "查询成功", "data": [ { "categoryId": 1, "categoryName": "软件产品", "productCount": 45, "saleCount": 856, "totalAmount": 12500000.00 } ] } ``` --- ## 4. 数据模型 ### 4.1 ProductCategoryBo(分类业务对象) ```java public class CrmProductCategoryBo extends BaseEntity { /** 主键ID */ @NotNull(message = "主键不能为空", groups = { EditGroup.class }) private Long id; /** 分类名称 */ @NotBlank(message = "分类名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String categoryName; /** 父级ID */ private Long parentId; /** 祖级列表 */ private String ancestors; /** 显示顺序 */ private Integer sort; /** 状态 */ private String status; /** 备注 */ private String remark; } ``` --- ### 4.2 ProductCategoryVo(分类视图对象) ```java public class CrmProductCategoryVo implements Serializable { /** 主键ID */ @ExcelProperty(value = "ID") private Long id; /** 分类名称 */ @ExcelProperty(value = "分类名称") private String categoryName; /** 父级ID */ private Long parentId; /** 祖级列表 */ private String ancestors; /** 显示顺序 */ @ExcelProperty(value = "显示顺序") private Integer sort; /** 状态 */ @ExcelProperty(value = "状态", converter = ExcelDictConvert.class) @ExcelDictFormat(dictType = "sys_normal_disable") private String status; /** 创建时间 */ @ExcelProperty(value = "创建时间") private LocalDateTime createTime; /** 备注 */ @ExcelProperty(value = "备注") private String remark; /** 子分类列表 */ private List children; } ``` --- ### 4.3 ProductBo(产品业务对象) ```java public class CrmProductBo extends BaseEntity { /** 主键ID */ @NotNull(message = "主键不能为空", groups = { EditGroup.class }) private Long id; /** 产品编号 */ @NotBlank(message = "产品编号不能为空", groups = { AddGroup.class, EditGroup.class }) private String productNo; /** 产品名称 */ @NotBlank(message = "产品名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String productName; /** 分类ID */ private Long categoryId; /** 型号/规格 */ private String model; /** 单位 */ private String unit; /** 条码 */ private String barcode; /** 标准价格 */ @NotNull(message = "标准价格不能为空", groups = { AddGroup.class, EditGroup.class }) private BigDecimal price; /** 成本价 */ private BigDecimal cost; /** 最低价格 */ private BigDecimal minPrice; /** 库存数量 */ private Integer stock; /** 库存预警值 */ private Integer lowStock; /** 状态 */ private String status; /** 产品描述 */ private String description; /** 产品图片 */ private String images; /** 备注 */ private String remark; } ``` --- ### 4.4 ProductVo(产品视图对象) ```java public class CrmProductVo implements Serializable { /** 主键ID */ @ExcelProperty(value = "ID") private Long id; /** 产品编号 */ @ExcelProperty(value = "产品编号") private String productNo; /** 产品名称 */ @ExcelProperty(value = "产品名称") private String productName; /** 分类ID */ private Long categoryId; /** 分类名称 */ @ExcelProperty(value = "产品分类") private String categoryName; /** 型号/规格 */ @ExcelProperty(value = "型号/规格") private String model; /** 单位 */ @ExcelProperty(value = "单位") private String unit; /** 条码 */ @ExcelProperty(value = "条码") private String barcode; /** 标准价格 */ @ExcelProperty(value = "标准价格") private BigDecimal price; /** 成本价 */ @ExcelProperty(value = "成本价") private BigDecimal cost; /** 最低价格 */ @ExcelProperty(value = "最低价格") private BigDecimal minPrice; /** 库存数量 */ @ExcelProperty(value = "库存数量") private Integer stock; /** 库存预警值 */ @ExcelProperty(value = "库存预警值") private Integer lowStock; /** 状态 */ @ExcelProperty(value = "状态", converter = ExcelDictConvert.class) @ExcelDictFormat(dictType = "crm_product_status") private String status; /** 产品描述 */ private String description; /** 产品图片 */ private String images; /** 销售次数 */ @ExcelProperty(value = "销售次数") private Integer saleCount; /** 创建时间 */ @ExcelProperty(value = "创建时间") private LocalDateTime createTime; /** 更新时间 */ @ExcelProperty(value = "更新时间") private LocalDateTime updateTime; /** 备注 */ @ExcelProperty(value = "备注") private String remark; } ``` --- ## 5. 数据字典 ### 5.1 产品状态 (crm_product_status) | 字典值 | 字典标签 | 说明 | |--------|---------|------| | on | 上架 | 产品可销售 | | off | 下架 | 产品不可销售 | --- ## 6. 权限标识汇总 | 权限标识 | 说明 | |---------|------| | crm:product:category:list | 产品分类列表查询 | | crm:product:category:query | 产品分类详情查询 | | crm:product:category:add | 产品分类新增 | | crm:product:category:edit | 产品分类修改 | | crm:product:category:remove | 产品分类删除 | | crm:product:list | 产品列表查询 | | crm:product:query | 产品详情查询 | | crm:product:add | 产品新增 | | crm:product:edit | 产品修改 | | crm:product:remove | 产品删除 | | crm:product:export | 产品导出 | | crm:product:import | 产品导入 | --- ## 7. 注意事项 1. **价格精度**: 所有价格字段保留2位小数 2. **产品编号**: 建议格式为 PRD+yyyyMMdd+4位流水号,确保唯一性 3. **图片路径**: 多个图片用英文逗号分隔,存储相对路径 4. **库存管理**: 库存功能为可选功能,不需要库存管理的产品可以忽略stock相关字段 5. **分类删除**: 删除分类前需检查是否有子分类和关联产品 6. **产品删除**: 建议使用下架功能代替删除,保留历史数据 7. **批量操作**: 批量操作需要注意事务一致性 8. **权限控制**: 成本价字段仅特定权限用户可见 9. **数据脱敏**: 导出时需要根据权限控制成本价等敏感字段的导出 --- **文档结束**