2026-05-11-phase3-map-to-dto.md 4.5 KB

Phase 3: Map→DTO + Entity DTO 重构

Goal: Convert Map input parameters and Entity @RequestBody parameters to proper DTOs with Bean Validation, eliminating unsafe type casting and enabling automatic validation.

Architecture: Create dedicated DTOs for each Map/Entity endpoint, add @Valid to Controller methods, then simplify the Controller logic. Focus on input Maps (not response Maps) and Entity @RequestBody (overposting risk). Skip pagination-only Maps (low value, high churn).

Tech Stack: Spring Boot 2.7.18, javax.validation, MyBatis-Plus, Java 8


Scope Decision

DO convert: Map params that carry business input (create/update/action endpoints), Entity @RequestBody (overposting vulnerability)

SKIP: Pagination-only Maps (page/size/filter — many identical patterns, low validation value), Response-only Maps (return type, not input), Payment callback Maps (external systems, fragile to change)

Prioritized Task Groups

Group A: Core Business Input Maps (highest validation value)

  1. AssessmentOrderController: createOrder, getOrderDetail, payOrder
  2. AssessmentAppointmentController: createAppointment
  3. PointsController: adjustPoints
  4. WishController: setPrice, approveExchange, rejectWish, cancelWish
  5. RewardController: exchangeReward, approveReward, getWishlist, getExchangeHistory
  6. TaskController: completeMinigameTask, getTodayTasks, getTaskHistory

Group B: User/Role/Family Input Maps

  1. FamilyUserController: joinFamily, createFamily, switchMode, switchRole, switchToChild
  2. FamilyController: updateFamilyName
  3. UserController: updateUser
  4. BindInviteController: validateToken
  5. ParentController: createParentWishlist, exchangeParentWishlist

Group C: Guide/Teacher Input Maps

  1. GuideFamilyTaskController: createTaskForChild, batchReviewTasks
  2. TeacherMessageController: sendMessage, replyMessage
  3. GuideAssessmentController: enableFamilyAssessment
  4. GuidePackageController: getPackageDetail, updatePackage, updateStatus, deletePackage, getTemplateDetail, incrementSales
  5. GuideManagementController: addGuidePackage, updateGuidePackage
  6. GuideOrderController: confirmOrder

Group D: Other Input Maps

  1. MiniGameController: completeGame
  2. MediaController: uploadText, attachMedia
  3. TaskTemplatePackageController: publishPackage
  4. MarketController: getPublicPackages
  5. GrowthRecordController: syncExternalResult
  6. PackagePaymentController: getOrderStatus, getWechatPayParams, applyAfterPayment

Group E: Admin Input Maps + Entity Params

  1. AdminController: createUser, resetUserPassword, adjustPoints, approveReward + Entity params (updateUser User, updateChild Child, createRewardTemplate Reward, updateRewardTemplate Reward, updateFamily Family, createTaskTemplate TaskTemplate, updateTaskTemplate TaskTemplate)
  2. AdminAuthController: sendCode, resetPassword, verifyCode
  3. AdminGuideController: Entity params (createPackage GuidePackage, updatePackage GuidePackage)
  4. ServiceContentController: list, getById, update, delete
  5. AssessmentAdminController: createMaterial, updateMaterial, updatePointsConfig
  6. OperationLogController: list, getLogDetail

Group F: Pagination-only Maps (SKIP - use shared PageQueryDTO if needed later)

  • AdminController: getUsers, getChildren, getTasks, getRewards, getPointsLogs, getFamilies, getTaskTemplates, getGuideApplications, getTeacherFamilyTasks, getTeacherFamilyRewards
  • PointsController: getBalance, getPointsLogs
  • TaskReminderController: all 4 methods
  • StreetController: search, getStatistics
  • GuideOrderController: getOrders
  • MembershipController: canUseFeature
  • GuideFamilyTaskController: getFamilyTasks (pagination)
  • TeacherMessageController: getMessages

Group G: Payment/Callback Maps (SKIP - external systems)

  • PaymentController: all 4 methods
  • PackagePaymentController: (already in Group D for non-payment)
  • MembershipController: createOrder, paymentNotify
  • AdminAuthController: login, loginByPassword (response Map, input is AdminLoginDTO already @Valid)

Implementation Approach

For each DTO:

  1. Create DTO class in com.etotem.cfc.dto with @Data + @NotNull/@NotBlank/@Size annotations
  2. Add @Valid + new DTO type to Controller method signature
  3. Replace Map field extraction with DTO getter calls
  4. Remove redundant null checks now covered by @Valid
  5. Compile verify after each group

DTO Naming Convention

  • {Entity}{Action}DTO for action DTOs (e.g., AssessmentCreateOrderDTO)
  • Simple names for common patterns (e.g., AdjustPointsDTO)