feat(oa): 新增 BOM 管理、产品管理和分类功能

- 添加 BOM 头和 BOM 明细相关实体、控制器、服务和 Mapper
- 实现 BOM 头和 BOM 明细的增删查改功能
- 添加产品和产品分类相关实体、控制器、服务和 Mapper
- 实现产品和产品分类的增删查改功能- 为所有新增功能添加相应的 Excel 导出功能
This commit is contained in:
2025-08-19 13:53:30 +08:00
parent 6b1a1ca5a6
commit 45f44d8ada
41 changed files with 2730 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
package com.gear.oa.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.gear.common.annotation.ExcelDictFormat;
import com.gear.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
/**
* BOM 明细,存放属性–值视图对象 gear_bom_item
*
* @author Joshi
* @date 2025-08-19
*/
@Data
@ExcelIgnoreUnannotated
public class GearBomItemVo {
private static final long serialVersionUID = 1L;
/**
* BOM 明细ID
*/
@ExcelProperty(value = "BOM 明细ID")
private Long itemId;
/**
* 关联 wms_bom.bom_id
*/
@ExcelProperty(value = "关联 wms_bom.bom_id")
private Long bomId;
/**
* 属性名称
*/
@ExcelProperty(value = "属性名称")
private String attrKey;
/**
* 属性值
*/
@ExcelProperty(value = "属性值")
private String attrValue;
/**
* 是否启用0=否1=是)
*/
@ExcelProperty(value = "是否启用", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0==否1=是")
private Integer isEnabled;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,58 @@
package com.gear.oa.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.gear.common.annotation.ExcelDictFormat;
import com.gear.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
/**
* BOM 头,关联产品或原材料视图对象 gear_bom
*
* @author Joshi
* @date 2025-08-19
*/
@Data
@ExcelIgnoreUnannotated
public class GearBomVo {
private static final long serialVersionUID = 1L;
/**
* BOM 主键ID
*/
@ExcelProperty(value = "BOM 主键ID")
private Long bomId;
/**
* BOM 编码(可选)
*/
@ExcelProperty(value = "BOM 编码", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "可=选")
private String bomCode;
/**
* BOM 名称(可选)
*/
@ExcelProperty(value = "BOM 名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "可=选")
private String bomName;
/**
* 是否启用0=否1=是)
*/
@ExcelProperty(value = "是否启用", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0==否1=是")
private Integer isEnabled;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,65 @@
package com.gear.oa.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.gear.common.annotation.ExcelDictFormat;
import com.gear.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
/**
* 产品分类树视图对象 gear_product_category
*
* @author Joshi
* @date 2025-08-19
*/
@Data
@ExcelIgnoreUnannotated
public class GearProductCategoryVo {
private static final long serialVersionUID = 1L;
/**
* 树节点唯一标识(根节点用固定值)
*/
@ExcelProperty(value = "树节点唯一标识", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "根=节点用固定值")
private Long categoryId;
/**
* 父节点tree_id根节点的父节点为null
*/
@ExcelProperty(value = "父节点tree_id", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "根=节点的父节点为null")
private Long parentId;
/**
* 节点名称根节点为类型名产品节点为product_name
*/
@ExcelProperty(value = "节点名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "根=节点为类型名产品节点为product_name")
private String categoryName;
/**
* 节点类型root=根节点、product=产品节点)
*/
@ExcelProperty(value = "节点类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "r=oot=根节点、product=产品节点")
private String categoryType;
/**
* 同级排序号
*/
@ExcelProperty(value = "同级排序号")
private Long sortNo;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,85 @@
package com.gear.oa.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.gear.common.annotation.ExcelDictFormat;
import com.gear.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
/**
* 产品视图对象 gear_product
*
* @author Joshi
* @date 2025-08-19
*/
@Data
@ExcelIgnoreUnannotated
public class GearProductVo {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long productId;
/**
* 产品编号
*/
@ExcelProperty(value = "产品编号")
private String productCode;
/**
* 产品名称
*/
@ExcelProperty(value = "产品名称")
private String productName;
/**
* 负责人
*/
@ExcelProperty(value = "负责人")
private String owner;
/**
* 单位
*/
@ExcelProperty(value = "单位")
private String unit;
/**
* BOM 表头ID
*/
@ExcelProperty(value = "BOM 表头ID")
private Long bomId;
/**
* 产品类型product=产品semi=半成品raw=原料)
*/
@ExcelProperty(value = "产品类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "p=roduct=产品semi=半成品raw=原料")
private String type;
/**
* 是否启用0=否1=是)
*/
@ExcelProperty(value = "是否启用", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0==否1=是")
private Integer isEnabled;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 分类ID
*/
@ExcelProperty(value = "分类ID")
private Long categoryId;
}

View File

@@ -0,0 +1,54 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
import java.util.Date;
/**
* 原料维度推荐VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class MaterialRecommendationVO {
/**
* 原料名称
*/
private String materialName;
/**
* 原料编码
*/
private String materialCode;
/**
* 推荐采购数量
*/
private Integer recommendedPurchaseQuantity;
/**
* 推荐供应商
*/
private String recommendedSupplier;
/**
* 推荐原因
*/
private String recommendationReason;
/**
* 紧急程度
*/
private String urgencyLevel;
/**
* 预计到货时间
*/
private Date estimatedArrivalTime;
/**
* 建议操作
*/
private String suggestedAction;
}

View File

@@ -0,0 +1,43 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
/**
* 订单数量统计VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class OrderCountStatisticsVO {
/**
* 总订单数量
*/
private Integer totalOrderCount;
/**
* 已完成订单数量
*/
private Integer completedOrderCount;
/**
* 进行中订单数量
*/
private Integer inProgressOrderCount;
/**
* 待处理订单数量
*/
private Integer pendingOrderCount;
/**
* 本月新增订单数量
*/
private Integer monthlyNewOrderCount;
/**
* 完成率
*/
private Double completionRate;
}

View File

@@ -0,0 +1,43 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
/**
* 订单所需产品统计VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class OrderProductStatisticsVO {
/**
* 产品名称
*/
private String productName;
/**
* 产品编码
*/
private String productCode;
/**
* 订单需求数量
*/
private Integer orderDemandQuantity;
/**
* 当前库存数量
*/
private Integer currentStockQuantity;
/**
* 库存缺口
*/
private Integer stockGap;
/**
* 相关订单数量
*/
private Integer relatedOrderCount;
}

View File

@@ -0,0 +1,49 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
import java.util.Date;
/**
* 订单维度推荐VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class OrderRecommendationVO {
/**
* 订单编码
*/
private String orderCode;
/**
* 客户名称
*/
private String customerName;
/**
* 订单状态
*/
private String orderStatus;
/**
* 优先级
*/
private String priority;
/**
* 推荐原因
*/
private String recommendationReason;
/**
* 建议操作
*/
private String suggestedAction;
/**
* 预计完成时间
*/
private Date estimatedCompletionTime;
}

View File

@@ -0,0 +1,54 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
import java.util.List;
/**
* 产品数据看板综合VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class ProductDashboardVO {
/**
* 产品销售情况
*/
private List<ProductSalesPerformanceVO> productSalesPerformance;
/**
* 销售人员业绩
*/
private List<SalesPersonPerformanceVO> salesPersonPerformance;
/**
* 总订单数量统计
*/
private OrderCountStatisticsVO orderCountStatistics;
/**
* 订单所需的产品统计
*/
private List<OrderProductStatisticsVO> orderProductStatistics;
/**
* 根据BOM计算的原料需求
*/
private List<ProductMaterialRequirementVO> productMaterialRequirements;
/**
* 原料库存和需求情况
*/
private List<RawMaterialInventoryVO> rawMaterialInventory;
/**
* 订单维度推荐
*/
private List<OrderRecommendationVO> orderRecommendations;
/**
* 原料维度推荐
*/
private List<MaterialRecommendationVO> materialRecommendations;
}

View File

@@ -0,0 +1,53 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
/**
* 产品原料需求VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class ProductMaterialRequirementVO {
/**
* 产品名称
*/
private String productName;
/**
* 产品编码
*/
private String productCode;
/**
* 原料名称
*/
private String materialName;
/**
* 原料编码
*/
private String materialCode;
/**
* 需求数量
*/
private Integer requiredQuantity;
/**
* 当前库存数量
*/
private Integer currentStockQuantity;
/**
* 在途数量
*/
private Integer inTransitQuantity;
/**
* 库存缺口
*/
private Integer stockGap;
}

View File

@@ -0,0 +1,43 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
/**
* 产品销售情况VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class ProductSalesPerformanceVO {
/**
* 产品名称
*/
private String productName;
/**
* 产品编码
*/
private String productCode;
/**
* 销售数量
*/
private Integer salesQuantity;
/**
* 销售金额
*/
private Double salesAmount;
/**
* 增长率
*/
private Double growthRate;
/**
* 销售排名
*/
private Integer salesRank;
}

View File

@@ -0,0 +1,53 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
/**
* 原料库存和需求情况VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class RawMaterialInventoryVO {
/**
* 原料名称
*/
private String materialName;
/**
* 原料编码
*/
private String materialCode;
/**
* 当前库存数量
*/
private Integer currentStockQuantity;
/**
* 在途数量
*/
private Integer inTransitQuantity;
/**
* 总需求数量
*/
private Integer totalRequiredQuantity;
/**
* 库存缺口
*/
private Integer stockGap;
/**
* 安全库存
*/
private Integer safetyStock;
/**
* 库存状态(充足/不足/紧急)
*/
private String stockStatus;
}

View File

@@ -0,0 +1,38 @@
package com.gear.oa.domain.vo.dashboard;
import lombok.Data;
/**
* 销售人员业绩VO
*
* @author Joshi
* @date 2025-08-19
*/
@Data
public class SalesPersonPerformanceVO {
/**
* 销售人员姓名
*/
private String salesPersonName;
/**
* 订单数量
*/
private Integer orderCount;
/**
* 销售金额
*/
private Double salesAmount;
/**
* 完成率
*/
private Double completionRate;
/**
* 业绩排名
*/
private Integer performanceRank;
}