# Server模块Service缓存调整为Vo对象 - 任务1分析报告

## 1. 概述

本报告是对Contract-Manager项目Server模块中所有注解了@CacheConfig的Service类的结构和依赖关系的详细分析。分析结果将作为后续任务（实体类和VO类转换机制设计、缓存策略设计、Service类修改等）的基础输入。

## 2. 核心接口定义

### 2.1 IEntityService接口

```java
public interface IEntityService<T> {
    T getById(Integer id);
    Page<T> findAll(Specification<T> spec, Pageable pageable);
    Specification<T> getSpecification(String searchText);
    default List<T> search(String searchText);
    void delete(T entity);
    T save(T entity);
}
```

- **泛型参数T**: 代表实体类类型（Model）
- **主要职责**: 提供对实体类的基本CRUD操作
- **特别说明**: `getById`方法不能使用@Cacheable注解（如果实体类有关联实体）

### 2.2 QueryService接口

```java
public interface QueryService<Vo> {
    Vo findById(Integer id);
    Page<Vo> findAll(JsonNode paramsNode, Pageable pageable);
    default long count(JsonNode paramsNode);
}
```

- **泛型参数Vo**: 代表视图对象类型
- **主要职责**: 提供基于JSON参数的查询功能，返回VO对象
- **特点**: 专为WebSocket通信设计的查询接口

### 2.3 VoableService接口

```java
public interface VoableService<M, Vo> {
    void updateByVo(M model, Vo vo);
}
```

- **泛型参数M**: 代表实体类类型
- **泛型参数Vo**: 代表视图对象类型
- **主要职责**: 提供将VO对象的属性更新到实体对象的功能

## 3. WebSocket服务与Service接口的交互分析

### 3.1 WebSocketServerCallbackManager

WebSocketServerCallbackManager负责处理WebSocket客户端发送的消息，并调用相应的Service方法。核心交互逻辑如下：

1. **消息处理流程**:
   - 接收客户端发送的JSON消息
   - 根据消息中的service和method字段确定要调用的服务和方法
   - 调用对应的处理方法（invokerFindAllMethod、invokerFindByIdMethod、invokerSaveMethod等）
   - 将结果转换为VO对象（如果结果是Voable类型）
   - 将结果发送回客户端

2. **与IEntityService的交互**:
   - 在`invokerSaveMethod`、`invokerDeleteMethod`等方法中，将service对象强制转换为IEntityService类型
   - 调用IEntityService接口的方法进行实体操作
   - 通过泛型参数分析确定实体类型（findEntityTypeInInterfaces、findEntityTypeInSuperclass等方法）

3. **与QueryService的交互**:
   - 在`invokerFindAllMethod`和`invokerCountMethod`中，将service对象强制转换为QueryService类型
   - 调用QueryService接口的方法进行查询操作
   - 自动将查询结果转换为VO对象（如果结果是Voable类型）

4. **与VoableService的交互**:
   - 在`invokerSaveMethod`中，检查service是否实现了VoableService接口
   - 如果实现了，则调用updateByVo方法更新实体属性

### 3.2 WebSocketServerTaskManager和WebSocketServerHandler

这两个类主要负责WebSocket会话管理和任务调度，与Service接口没有直接的数据操作交互。

## 4. Service类结构分析

### 4.1 典型Service类结构（以ProjectFileTypeService为例）

```java
@Lazy
@Service
@CacheConfig(cacheNames = "project-file-type")
public class ProjectFileTypeService
        implements IEntityService<ProjectFileTypeLocal>, QueryService<ProjectFileTypeLocalVo>,
        VoableService<ProjectFileTypeLocal, ProjectFileTypeLocalVo> {
    // 实现各接口的方法...
}
```

### 4.2 核心方法实现特点

1. **IEntityService方法实现**:
   - `getById`: 直接调用Repository的findById方法
   - `findAll(Specification<T>, Pageable)`: 直接调用Repository的findAll方法
   - `save/delete`: 添加缓存清理注解

2. **QueryService方法实现**:
   - `findById`: 调用Repository的findById方法，然后调用实体类的toVo方法转换为VO对象
   - `findAll(JsonNode, Pageable)`: 构建Specification，调用IEntityService的findAll方法，然后使用Stream API的map方法将结果转换为VO对象

3. **VoableService方法实现**:
   - `updateByVo`: 将VO对象的属性逐个复制到实体对象

### 4.3 缓存配置特点

- 使用@CacheConfig注解指定缓存名称
- 使用@Cacheable、@CacheEvict、@Caching等注解进行缓存管理
- 缓存键通常包含实体ID或查询条件
- save/delete操作会清理相关缓存

## 5. 注解了@CacheConfig的Service类列表

通过搜索，共发现64个注解了@CacheConfig的Service类，分布在多个包中：

### 5.1 项目相关Service类（15个）:
- ProjectFundPlanService
- ProjectCostItemService
- ProjectQuotationService
- ProjectFileTypeService
- ProjectTypeService
- ProjectService
- ProjectSaleTypeRequireFileTypeService
- ProjectFileService
- ProjectIndustryService
- ProjectSaleTypeService
- ProjectBidService
- ProductTypeService
- CustomerSatisfactionSurveyService
- ProductUsageService
- ProjectCostService
- DeliverySignMethodService

### 5.2 合同相关Service类（15个）:
- ContractPayPlanService
- SalesOrderItemService
- ContractBidVendorService
- PurchaseBillVoucherItemService
- ContractCatalogService
- ContractGroupService
- ContractTypeService
- ContractFileService
- PurchaseOrderItemService
- ContractService
- SalesBillVoucherService
- ContractItemService
- ContractFileTypeService
- ContractKindService
- PurchaseBillVoucherService
- SaleOrdersService
- PurchaseOrdersService
- ExtendVendorInfoService

### 5.3 客户相关Service类（6个）:
- CustomerFileTypeService
- CustomerCatalogService
- CompanyCustomerFileService
- CompanyCustomerFileTypeService
- CompanyCustomerEntityService
- CompanyCustomerEvaluationFormFileService
- CompanyCustomerService

### 5.4 供应商相关Service类（7个）:
- VendorTypeService
- VendorFileTypeService
- VendorEntityService
- VendorService
- VendorCatalogService
- VendorGroupService
- VendorGroupRequireFileTypeService

### 5.5 公司相关Service类（7个）:
- InvoiceService
- CompanyBankAccountService
- CompanyExtendInfoService
- CompanyService
- CompanyFileService
- CompanyContactService
- CompanyInvoiceInfoService
- CompanyFileTypeService

### 5.6 其他Service类（14个）:
- CloudRkService
- InventoryService
- InventoryCatalogService
- PermissionService
- BankService
- EmployeeAuthBindService
- DepartmentService
- EmployeeLoginHistoryService
- FunctionService
- InventoryHistoryPriceService
- YongYouU8Service
- EmployeeRoleService
- SysConfService
- EmployeeService

## 6. 依赖关系分析

### 6.1 Service类之间的依赖关系

- Service类之间通过@Autowired注解进行依赖注入
- 通常Service类依赖于对应的Repository类
- 部分Service类依赖于其他Service类来处理关联实体

### 6.2 Service类与WebSocket服务的依赖关系

- WebSocketServerCallbackManager通过SpringApp.getBean()动态获取Service实例
- Service类不需要直接依赖WebSocket服务
- WebSocket服务通过反射机制调用Service类的方法

### 6.3 实体类与VO类的依赖关系

- 实体类通常实现Voable接口，提供toVo方法将自身转换为VO对象
- Service类在findById、findAll等方法中将实体对象转换为VO对象返回
- Service类通过VoableService接口将VO对象的属性更新到实体对象

## 7. 关键发现和建议

1. **接口分离**：
   - IEntityService负责实体操作
   - QueryService负责VO查询
   - VoableService负责实体和VO之间的转换
   - 这种分离设计清晰，但需要Service类同时实现多个接口

2. **泛型参数**：
   - 当前Service类的泛型参数使用不够统一
   - 部分Service类可能没有正确实现QueryService接口
   - 需要统一规范Service类实现多个接口时的泛型参数使用

3. **缓存策略**：
   - 大多数Service类使用了@CacheConfig和相关缓存注解
   - 缓存键的设计各不相同，缺乏统一规范
   - 需要设计统一的缓存键命名规则

4. **转换机制**：
   - 实体类到VO的转换通过实体类的toVo方法实现
   - VO到实体的转换通过VoableService接口的updateByVo方法实现
   - 需要确保转换逻辑的一致性和安全性

5. **WebSocket交互**：
   - WebSocketServerCallbackManager通过反射机制调用Service方法
   - 这种方式灵活但可能存在性能问题
   - 需要确保类型转换的安全性

## 8. 结论

通过对Service类结构和依赖关系的分析，可以看出当前系统已经具备了实体类和VO类分离的基础，但在接口实现、泛型参数使用、缓存策略等方面还需要进一步规范和优化。后续任务将基于这些分析结果，设计实体类和VO类之间的转换机制、缓存策略，并修改Service类以实现缓存调整为Vo对象的目标。