# Inventory 实体类说明文档 ## 1. 概述 `Inventory` 类是 Contract-Manager 项目中的核心实体类,代表**存货物品清单**,用于管理和存储各类存货物品的详细信息。该类位于 `common` 模块中,实现了 `IdentityEntity`、`BasedEntity` 和 `Serializable` 接口,支持数据持久化和对象序列化。 ## 2. 类结构 ```java @Getter @Setter @Entity @Table(name = "INVENTORY", schema = "supplier_ms") public class Inventory implements IdentityEntity, BasedEntity, Serializable { // 类实现内容 } ``` ### 2.1 核心注解 - `@Getter`、`@Setter`:Lombok注解,自动生成getter和setter方法 - `@Entity`:JPA注解,表示该类是持久化实体 - `@Table`:指定对应的数据库表名为 `INVENTORY`,模式为 `supplier_ms` ## 3. 字段说明 ### 3.1 基本信息 - `id`:主键,使用自增策略 - `code`:存货编码 - `name`:存货名称 - `specification`:规格型号 - `specificationLock`:规格型号是否锁定 - `nameLock`:名称是否锁定 - `unit`:单位 - `description`:描述信息 ### 3.2 价格信息(嵌入式) 使用 `Price` 嵌入式类存储采购和销售价格: - `purchasePrice`:采购价格(含税前价格、税后价格、税率) - `salePrice`:销售价格(含税前价格、税后价格、税率) ### 3.3 重量与尺寸信息 - `weight`:产品重量 - `packagedWeight`:包装重量 - `weightUnit`:重量单位(默认:kg) - `volumeUnit`:体积单位(默认:m³) - `sizeUnit`:尺寸单位(默认:mm) ### 3.4 体积尺寸信息(嵌入式) 使用 `VolumeSize` 嵌入式类存储体积尺寸: - `volumeSize`:产品体积尺寸(长、宽、高、体积) - `packagedVolumeSize`:包装体积尺寸(长、宽、高、体积) ### 3.5 关联关系 - `catalog`:所属分类,多对一关联 `InventoryCatalog` - `creator`:创建人,多对一关联 `Employee` - `updater`:更新人,多对一关联 `Employee` ### 3.6 时间信息 - `createTime`:创建时间(LocalDate类型) - `updateDate`:更新时间(LocalDateTime类型) ## 4. 接口实现 ### 4.1 IdentityEntity 接口 - 实现了 `getId()` 和 `setId(Integer id)` 方法 - 重写了 `equals(Object object)` 方法,基于ID进行比较 ### 4.2 BasedEntity 接口 - 实现了 `toPrettyString()` 方法,返回 "名称+规格" 格式的字符串 ## 5. 关联实体类 ### 5.1 InventoryCatalog - 表示存货分类 - 与Inventory是一对多关系 ### 5.2 Price - 嵌入式类,存储价格相关信息 - 包含税率、税前价格、税后价格 ### 5.3 VolumeSize - 嵌入式类,存储体积尺寸信息 - 包含体积、长度、宽度、高度 ### 5.4 Employee - 表示系统用户/员工 - 与Inventory是多对一关系(创建人和更新人) ## 6. 数据访问层 `InventoryRepository` 接口提供了对Inventory实体的数据库访问功能: ```java @Repository public interface InventoryRepository extends JpaRepository, JpaSpecificationExecutor { Optional findByCode(String code); } ``` - 继承自 `JpaRepository`,提供基本的CRUD操作 - 继承自 `JpaSpecificationExecutor`,支持动态查询条件 - 自定义方法 `findByCode`,通过编码查询存货 ## 7. 服务层 ### 7.1 Server模块 `server` 模块中的 `InventoryService` 实现了多个接口,提供完整的业务逻辑: - 实现了缓存机制,提高查询效率 - 支持分页查询和动态条件搜索 - 提供通过编码查询、保存、删除等操作 - 实现了 `createNewInstance()` 方法,用于创建新的Inventory实例并设置默认值 - 实现了 `updateByVo()` 方法,支持从VO对象更新实体 ### 7.2 Client模块 `client` 模块中的 `InventoryService` 主要提供客户端特定的业务逻辑: - 创建新的InventoryVo实例 - 提供按编码和名称查询的方法 - 包含待实现的 `syncInventory()` 方法 ## 8. 数据传输对象 `InventoryVo` 类用于在不同层之间传输Inventory相关数据: - 包含与Inventory实体对应的主要字段 - 添加了 `active` 字段,表示状态 - 使用关联实体的ID替代直接引用(如 `catalogId`、`creatorId` 等) ## 9. 代码优化建议 ### 9.1 数据一致性 - **问题**:`InventoryService.createNewInstance()` 方法设置了默认的税率为13%,但没有自动计算税后价格 - **建议**: ```java public Inventory createNewInstance() { Inventory inventory = new Inventory(); // 设置默认值 inventory.setNameLock(false); inventory.setSpecificationLock(false); // 设置税率并自动计算税后价格 float defaultTaxRate = 13; double defaultPrice = 0; Price purchasePrice = inventory.getPurchasePrice(); purchasePrice.setTaxRate(defaultTaxRate); purchasePrice.setPreTaxPrice(defaultPrice); purchasePrice.setPostTaxPrice(defaultPrice * (1 + defaultTaxRate / 100)); Price salePrice = inventory.getSalePrice(); salePrice.setTaxRate(defaultTaxRate); salePrice.setPreTaxPrice(defaultPrice); salePrice.setPostTaxPrice(defaultPrice * (1 + defaultTaxRate / 100)); // 其他默认值设置 inventory.setWeightUnit("kg"); inventory.setVolumeUnit("m³"); inventory.setSizeUnit("mm"); inventory.setCreateTime(LocalDate.now()); return inventory; } ``` ### 9.2 时间类型一致性 - **问题**:创建时间使用 `LocalDate` 类型,更新时间使用 `LocalDateTime` 类型,类型不一致 - **建议**:统一使用 `LocalDateTime` 类型,以便更精确地记录时间信息 ### 9.3 完整性验证 - **问题**:缺少对必填字段的完整性验证 - **建议**:在 `save` 方法中添加基本的验证逻辑: ```java @Caching(evict = { @CacheEvict(key = "#p0.id"), @CacheEvict(key = "'code-'+#p0.code"), })public Inventory save(Inventory entity) { // 基本验证 if (entity == null) { throw new IllegalArgumentException("Inventory entity cannot be null"); } if (!StringUtils.hasText(entity.getName())) { throw new IllegalArgumentException("Inventory name is required"); } // 更新时间戳 entity.setUpdateDate(LocalDateTime.now()); return inventoryRepository.save(entity); } ``` ### 9.4 性能优化 - **问题**:`search` 方法中排序设置可能存在问题 - **建议**:优化排序逻辑: ```java public List search(String searchText) { Pageable pageable = PageRequest.of(0, getSearchPageSize(), Sort.by(Sort.Direction.DESC, "id")); Specification specification = getSpecification(searchText); return inventoryRepository.findAll(specification, pageable).getContent(); } ``` ## 10. 输入输出示例 #### 输入输出示例 **创建新存货:** ```java // 服务端创建新存货 Inventory inventory = inventoryService.createNewInstance(); inventory.setName("笔记本电脑"); inventory.setCode("NB-001"); inventory.setSpecification("ThinkPad X1 Carbon"); inventory.setUnit("台"); // 设置价格信息 Price salePrice = inventory.getSalePrice(); salePrice.setPreTaxPrice(9999.00); salePrice.setPostTaxPrice(9999.00 * 1.13); // 保存 inventory = inventoryService.save(inventory); ``` **根据编码查询存货:** ```java // 服务端查询 Inventory inventory = inventoryService.findByCode("NB-001"); System.out.println("存货名称:" + inventory.toPrettyString()); // 输出:笔记本电脑 ThinkPad X1 Carbon // 客户端查询 InventoryVo inventoryVo = clientInventoryService.findByCode("NB-001"); System.out.println("存货ID:" + inventoryVo.getId() + ", 名称:" + inventoryVo.getName()); ``` ## 11. 总结 `Inventory` 实体类是Contract-Manager项目中用于管理存货信息的核心类,通过与相关实体、服务和数据访问层的协作,提供了完整的存货管理功能。该类设计合理,包含了存货的各种属性信息,并通过实现相关接口提供了标准的行为规范。通过实施建议的优化,可以进一步提高代码的健壮性、一致性和性能。