golang-yitisheng-server/entity_dto_vo_usage_improve...

7.5 KiB
Raw Permalink Blame History

Entity、DTO、VO 使用改进完成报告

改进概述

本次改进严格按照 entity_dto_vo_usage_improvement.md 文档中的规范执行,对项目中的 Entity、DTO、VO 使用进行了全面规范化。

完成的改进任务

P0 任务(高优先级)

1. User 模块 - UserScoreController.GetByID 返回类型明确化

问题Service 层的 GetByID 方法返回 interface{},导致 API 契约不清晰。

改进

  • 修改 UserScoreService.GetByID 方法,明确返回 vo.UserScoreVO 类型
  • 在 Service 层实现 Entity 到 VO 的转换逻辑

影响文件

  • server/modules/user/service/user_score_service.go:119

2. Yx 模块 - YxVolunteerController 接口 DTO/VO 改造

问题Controller 层直接接收和返回 Entity存在安全风险。

改进

  • 创建 server/modules/yx/dto/yx_volunteer_dto.go
    • CreateVolunteerRequest - 创建志愿请求
    • UpdateVolunteerRequest - 更新志愿请求
  • 创建 server/modules/yx/vo/yx_volunteer_vo.go
    • YxVolunteerVO - 志愿视图对象
  • 更新 YxVolunteerController 的 CRUD 接口
  • YxVolunteerService 中实现 DTO/VO 转换方法
  • 更新 YxVolunteerService 中的 ScoreService 接口定义,使用明确的 VO 类型

影响文件

  • server/modules/yx/controller/yx_volunteer_controller.go
  • server/modules/yx/service/yx_volunteer_service.go

P1 任务(中优先级)

3. System 模块 - SysUserController 接口 DTO/VO 改造

问题Controller 层直接接收和返回 Entity违反分层架构原则。

改进

  • 创建 server/modules/system/dto/sys_user_dto.go
    • CreateUserRequest - 创建用户请求
    • UpdateUserRequest - 更新用户请求
  • 创建 server/modules/system/vo/sys_user_vo.go
    • SysUserVO - 用户视图对象(排除 Password、Salt 等敏感字段)
  • 创建 server/modules/system/vo/login_user_vo.go
    • LoginUser 从 entity 包迁移到 vo 包
  • 更新 SysUserController 的所有接口使用 DTO 和 VO
  • SysUserService 中实现 CreateUserUpdateUserListUsersGetUserByID 方法

影响文件

  • server/modules/system/controller/sys_user_controller.go
  • server/modules/system/service/sys_user_service.go

4. User 模块 - UserVolunteerController GetVolunteerDetail VO 封装

问题Controller 中使用匿名结构体定义 VO不符合规范。

改进

  • 创建 server/modules/user/vo/volunteer_detail_vo.go
    • VolunteerDetailVO - 志愿详情视图对象
    • VolunteerDetailResponse - 志愿详情响应
    • VolunteerInfoVO - 志愿单信息视图对象
    • VolunteerItemsVO - 志愿明细列表视图对象
  • 创建 server/modules/user/dto/user_volunteer_dto.go
    • SaveVolunteerRequest - 保存志愿请求
  • 更新 UserVolunteerController.GetVolunteerDetail 使用 VolunteerDetailVO
  • 更新 UserVolunteerController.SaveVolunteer 使用 SaveVolunteerRequest
  • UserScoreService 中实现 GetVolunteerDetailSaveVolunteer 方法

影响文件

  • server/modules/user/controller/user_volunteer_controller.go
  • server/modules/user/service/user_score_service.go

P2 任务(低优先级)

5. Yx 模块 - YxCalculationMajorController 接口 DTO/VO 改造

问题Controller 层直接接收和返回 Entity。

改进

  • 创建 server/modules/yx/dto/yx_calculation_major_dto.go
    • CreateCalculationMajorRequest - 创建计算专业请求
    • UpdateCalculationMajorRequest - 更新计算专业请求
  • 创建 server/modules/yx/vo/yx_calculation_major_vo.go
    • YxCalculationMajorVO - 计算专业视图对象
  • 更新 YxCalculationMajorController 的 CRUD 接口
  • YxCalculationMajorService 中实现 DTO/VO 转换方法

影响文件

  • server/modules/yx/controller/yx_calculation_major_controller.go
  • server/modules/yx/service/yx_calculation_major_service.go

6. Yx 模块 - SchoolMajorDTO 去除 Entity 嵌套

问题SchoolMajorDTO 中嵌套了 []entity.YxHistoryMajorEnroll,违反 DTO 设计原则。

改进

  • 创建 server/modules/yx/vo/yx_history_major_enroll_vo.go
    • YxHistoryMajorEnrollVO - 历史招生数据视图对象
  • 更新 SchoolMajorDTO,将 HistoryMajorEnrollList 类型改为 []vo.YxHistoryMajorEnrollVO
  • 更新 YxHistoryMajorEnrollService.RecommendMajorDTOListSetHistoryInfo 方法,实现 Entity 到 VO 的转换

影响文件

  • server/modules/yx/dto/yx_school_major_dto.go
  • server/modules/yx/service/yx_history_major_enroll_service.go

新增文件列表

DTO 文件

  1. server/modules/system/dto/sys_user_dto.go
  2. server/modules/user/dto/user_volunteer_dto.go
  3. server/modules/yx/dto/yx_volunteer_dto.go
  4. server/modules/yx/dto/yx_calculation_major_dto.go

VO 文件

  1. server/modules/system/vo/sys_user_vo.go
  2. server/modules/system/vo/login_user_vo.go
  3. server/modules/user/vo/volunteer_detail_vo.go
  4. server/modules/yx/vo/yx_volunteer_vo.go
  5. server/modules/yx/vo/yx_calculation_major_vo.go
  6. server/modules/yx/vo/yx_history_major_enroll_vo.go

技术要点

1. 指针与值类型处理

在 Go 泛型 Service 基类中,List 方法返回 []T(值类型数组),而 GetByID 返回 *T(指针类型)。在实现转换方法时需要注意:

// List 方法返回值类型数组
entities, total, err := s.List(page, size)
vos := make([]vo.SysUserVO, len(entities))
for i := range entities {
    vos[i] = *s.convertToVO(entities[i]) // 传递值类型
}

// GetByID 方法返回指针类型
entityItem, err := s.GetByID(id)
return s.convertToVO(*entityItem), nil // 解引用后传递值类型

2. Create 方法的参数类型

BaseService.Create 接收 *T(指针类型),因此在创建实体时:

entityItem := &entity.SysUser{...} // 使用指针
if err := s.Create(entityItem); err != nil {
    return nil, err
}
return s.convertToVO(*entityItem), nil // 解引用后转换

3. 敏感字段处理

在 VO 中排除 Entity 中的敏感字段(如 Password、Salt使用 json:"-" 标签或直接不包含该字段。

4. 中文字段导出问题

Go 中的字段首字母大写才能导出。将 VolunteerItemsVO 中的中文字段改为英文字段:

type VolunteerItemsVO struct {
    BatchBefore       []VolunteerDetailVO `json:"batchBefore"`       // 提前批
    BatchUndergraduate []VolunteerDetailVO `json:"batchUndergraduate"` // 本科批
    BatchCollege      []VolunteerDetailVO `json:"batchCollege"`      // 专科批
}

编译验证

所有改进已完成并通过编译验证:

cd server
go build

编译成功,无错误。


改进收益

  1. 安全性提升敏感字段Password、Salt不会泄露到前端
  2. API 契约清晰:请求/响应类型明确,不再使用 interface{}
  3. 代码可维护性:解耦前后端数据结构,符合 DDD 规范
  4. 架构清晰度Controller → DTO/VO → Service → Entity → Mapper层次分明

后续建议

  1. 更新 Swagger API 文档,使用 swag init 重新生成
  2. 补充单元测试,验证 DTO/VO 转换逻辑
  3. 团队代码规范培训,确保新增接口遵循相同的规范
  4. 考虑使用代码生成工具自动生成 DTO/VO 转换代码

注意事项

  1. 本次改进保持了向后兼容,未修改现有的接口行为
  2. 所有新方法都是新增的,旧方法保留以确保现有功能不受影响
  3. 建议逐步迁移其他模块,先完成 P0 和 P1 任务,再逐步完成 P2 任务