# search-center **Repository Path**: Jason404/search-center ## Basic Information - **Project Name**: search-center - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-12 - **Last Updated**: 2026-07-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # search-center 订单中心 DDD Demo 基于 `order-service` 的 `create` 接口,搬迁到 DDD 七模块结构。本 Demo 只迁了**创建订单**的完整链路,其它(update/cancel/accept)未涉及。 ## 一、模块结构与依赖 ``` search-center ├── search-center-common 通用工具 / 统一响应 / 异常基类 ├── search-center-client 对外 SDK(Feign 接口 + Request/Response + 枚举) ├── search-center-domain 领域层(核心) - 聚合根、值对象、Repository / Port 接口 ├── search-center-application 应用层 - 用例编排、事务边界、DTO 装配 ├── search-center-infrastructure 基础设施 - 数据库 / 网关 / MQ / 缓存 / 三方实现 ├── search-center-interfaces 用户接口层 - Controller / RpcProvider └── search-center-start 启动模块 - 唯一含 main 方法 ``` ### 依赖方向(箭头 = 依赖) ``` start ────→ interfaces ────→ application ────→ domain │ ↑ └─→ infrastructure ───────────────┘ (实现 domain 接口) ↑ client (interfaces 实现 Client 契约,application 引用 Request/Response) common (全员可依赖) ``` 铁律: - domain 不依赖任何业务模块,只依赖 client(消费 Request/Response 纯 DTO)+ common - application 只依赖 domain - infrastructure 实现 domain 的 Repository / Port 接口 - 三方依赖统一沉到 `infrastructure/gateway`(取代了原本的独立 third 模块) ## 二、建单链路(13 步对照 order-service) ```text Step 0.5 异步落审计快照(原始请求) OrderSourceSnapshotService.asyncRecordRequest Step 1 入参基础校验 OrderRequestValidator.validateCreate Step 1.5 归一化默认值 OrderRequestNormalizer.normalizeCreate Step 2 幂等命中检查 -> 命中直接返回 OrderRepository.findByIdempotentKey Step 2.5 编排校验(并发拉远程 + 串行校验) ValidationOrchestrator.orchestrate ├── CompanyValidator ├── ShopValidator └── RosterValidator Step 3 生成 orderNo OrderNoGenerator.nextOrderNo Step 4~11 同事务内写主表 + 子表 + 注册 afterCommit MQ ├── OrderCreationAssembler.toOrder ├── OrderRepository.save (主表 + schedule + candidate + grab + service_content + ext) └── OrderEventPublisher.publishCreated Step 12 返回响应 OrderCreateResponse.created 兜底 DuplicateKeyException -> 二次查询返回已存在订单(并发幂等) ``` 事务边界:`OrderCreationServiceImpl#executeCreate` 上的 `@Transactional`, 仅包住 Step 4~11,使 Step 2 / 2.5 的远程调用不占用数据库连接。 ## 三、运行步骤 1. 执行 `docs/schema.sql` 建库建表 2. 修改 `search-center-start/src/main/resources/application.yml` 的 datasource 3. 父项目需先安装:`com.duliday.parent:duliday-parent-springboot3` 4. `mvn clean install -DskipTests` 5. 启动 `OrderCenterApplication` ## 四、接口测试 ### 建单(派单 + 候选人示例) ```bash curl -X POST http://localhost:8080/orders \ -H "Content-Type: application/json" \ -d '{ "tenantId": "YUM", "systemCode": 10, "sourceCode": 1, "outOrderNo": "DEMO-20260521-0001", "companyId": 100001, "shopId": 200001, "signUid": 300001, "workDate": "2026-05-22", "feeMode": 10, "orderCategory": 0, "dispatchMode": 10, "timeSlots": [ { "segmentType": "WORK", "startTime": "2026-05-22T09:00:00", "endTime": "2026-05-22T18:00:00", "rest": { "segmentType": "REST", "startTime": "2026-05-22T12:00:00", "endTime": "2026-05-22T13:00:00" } } ], "candidates": [ {"openUserId": "open-user-001"} ] }' ``` 返回示例: ```json { "code": 0, "message": "success", "data": { "orderNo": "20260521", "idempotent": false } } ``` 重复提交同样的 `outOrderNo + tenantId + systemCode`,会命中幂等返回 `idempotent=true`。 ## 五、DDD 关键点对照 | DDD 概念 | 代码体现 | |----------------|---------| | 聚合根 | `domain.model.order.Order`(Builder 私有构造,内部实体不可外修) | | 聚合内实体 | `OrderSchedule` / `OrderCandidate` / `OrderGrabCondition` / `OrderServiceContent` | | 仓储接口 | `domain.repository.OrderRepository` | | 仓储实现 | `infrastructure.persistence.repository.OrderRepositoryImpl` | | 领域服务(端口)| `OrderRequestValidator` / `OrderRequestNormalizer` / `OrderSourceSnapshotService` / `OrderEventPublisher` | | 领域服务(算法)| `ValidationOrchestrator`(纯 Java,在 ApplicationBeanConfig 中 @Bean 装配) | | 校验阶段 | `ValidationStage`(fetchAsync / awaitResults / validate 三段式) | | 领域事件 | `domain.event.OrderCreatedEvent` | | 应用服务 | `application.service.OrderCreationServiceImpl` | | 装配器 | `application.assembler.OrderCreationAssembler`(Request → 聚合根) | | 事务边界 | `executeCreate` 上的 `@Transactional` | | 事件提交后处理 | `TransactionSynchronizationManager.registerSynchronization(afterCommit)` | | 对外 SDK | `client.OrderCreationClient`(Feign),Controller `implements` 复用路径 | ## 六、目录速查 ```text search-center-client └── com.duliday.order.client ├── OrderCreationClient.java (Feign 接口) ├── enums/ (BaseEnum + 9 业务枚举) ├── model/SourceDTO.java ├── request/OrderCreateRequest.java └── response/OrderCreateResponse.java search-center-domain └── com.duliday.order.domain ├── model/order/Order.java (聚合根) ├── repository/OrderRepository.java (port) ├── event/OrderEventPublisher.java (port) ├── snapshot/OrderSourceSnapshotService (port) ├── normalization/OrderRequestNormalizer(port) ├── validation/ (校验编排器 + 阶段接口) └── util/OrderNoGenerator.java search-center-application └── com.duliday.order.application ├── service/OrderCreationServiceImpl (13 步用例编排) ├── assembler/OrderCreationAssembler (Request → 聚合根) └── config/ApplicationBeanConfig (ValidationOrchestrator @Bean) search-center-infrastructure └── com.duliday.order.infrastructure ├── persistence/ │ ├── po/ (6 张表的 DO) │ ├── mapper/ (6 个 MyBatis-Plus Mapper) │ ├── converter/OrderPoConverter (聚合根 ↔ PO) │ └── repository/OrderRepositoryImpl (port 实现) ├── validation/ (Company/Shop/Roster 三个 Stub 实现) ├── normalization/ (默认值填充实现) ├── snapshot/ (@Async 落审计 Stub) ├── event/ (Spring 进程内事件发布 Stub) ├── gateway/ (Feign 调外部服务的位置,Demo 暂空) └── config/MyBatisPlusConfig search-center-interfaces └── com.duliday.order.interfaces.rest ├── OrderCreationController (implements OrderCreationClient) └── GlobalExceptionHandler search-center-start └── com.duliday.order.start.OrderCenterApplication ``` ## 七、Demo 简化说明 - 三方校验(Company/Shop/Roster)目前是日志占位,真实项目应在 `infrastructure/gateway` 下封装 Feign + 缓存 - 审计快照、MQ 事件均为本地 Stub - `extra` 字段序列化用 `Map#toString` 占位,真实项目接 Jackson - `OrderRepository.save` 中子表用循环 `insert`,真实项目可改 batchInsert 或差异更新