新增claude 上下文文件夹
This commit is contained in:
parent
9834302f98
commit
be52af65af
1
.gitignore
vendored
1
.gitignore
vendored
@ -93,4 +93,3 @@ target/
|
||||
.DS_Store
|
||||
|
||||
devops-monitor-id_rsa.key
|
||||
/claude/
|
||||
|
||||
36
README.en.md
36
README.en.md
@ -1,36 +0,0 @@
|
||||
# red-circle-service
|
||||
|
||||
#### Description
|
||||
服务后台
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
|
||||
#### Installation
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Instructions
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Contribution
|
||||
|
||||
1. Fork the repository
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit your code
|
||||
4. Create Pull Request
|
||||
|
||||
|
||||
#### Gitee Feature
|
||||
|
||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
93
claude/ai-context/ARCHITECTURE.md
Normal file
93
claude/ai-context/ARCHITECTURE.md
Normal file
@ -0,0 +1,93 @@
|
||||
# 架构说明
|
||||
|
||||
## 一、子服务内部分层(DDD + CQRS)
|
||||
|
||||
每个子服务(如 rc-service-other)都遵循以下固定分层:
|
||||
|
||||
```
|
||||
{service}-adapter # 适配层:Controller,对外 REST API
|
||||
{service}-application # 应用层:ServiceImpl、CmdExe、QryExe、Manager、Scheduler
|
||||
{service}-client # 客户端接口层:Service 接口、Cmd、CO、枚举
|
||||
{service}-domain # 领域层:Entity、领域服务接口(纯业务,无框架依赖)
|
||||
{service}-infrastructure # 基础设施层:DAO、DatabaseService、Gateway、缓存、MQ
|
||||
{service}-inner-endpoint # 内部服务端点:供其他微服务 Feign 调用的实现
|
||||
{service}-start # 启动模块:Spring Boot 入口、application.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、层次调用链
|
||||
|
||||
```
|
||||
HTTP 请求
|
||||
↓
|
||||
Controller(adapter)
|
||||
↓
|
||||
ServiceImpl(application)
|
||||
↓
|
||||
CmdExe / QryExe(application)
|
||||
↓ 简单场景 ↓ 复杂场景
|
||||
DatabaseService Gateway(封装锁+缓存+多数据源)
|
||||
↓ ↓
|
||||
DAO DAO / Redis / MongoDB
|
||||
```
|
||||
|
||||
**强制规则**:
|
||||
- Controller 只调用 Service
|
||||
- Service 只调用 CmdExe/QryExe
|
||||
- CmdExe 可直接调用 DatabaseService(简单)或 Gateway(复杂)
|
||||
- 禁止跨层调用
|
||||
|
||||
---
|
||||
|
||||
## 三、跨服务调用(Feign)
|
||||
|
||||
```
|
||||
调用方服务
|
||||
└── 注入 Feign 客户端(来自 rc-inner-api/{service}-inner/{service}-inner-api)
|
||||
|
||||
rc-inner-api/
|
||||
└── {service}-inner/
|
||||
├── {service}-inner-api/ # Feign 接口定义(endpoint 包)
|
||||
├── {service}-inner-model/ # 传输数据模型(model 包)
|
||||
└── (实现在 {service}-inner-endpoint 子服务中)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、文件路径速查(以 other 服务为例)
|
||||
|
||||
| 文件类型 | 路径 |
|
||||
|---------|------|
|
||||
| Controller | `other-adapter/src/.../adapter/app/{模块}/` |
|
||||
| Service 接口 | `other-client/src/.../app/service/{模块}/` |
|
||||
| Cmd / QryCmd | `other-client/src/.../app/dto/cmd/{模块}/` |
|
||||
| CO(返回对象) | `other-client/src/.../app/dto/clientobject/{模块}/` |
|
||||
| CmdExe | `other-application/src/.../app/command/{模块}/` |
|
||||
| QryExe | `other-application/src/.../app/command/{模块}/query/` |
|
||||
| ServiceImpl | `other-application/src/.../app/service/{模块}/` |
|
||||
| Manager | `other-application/src/.../app/manager/{模块}/` |
|
||||
| Gateway 接口+实现 | `other-infrastructure/src/.../infra/gateway/{模块}/` |
|
||||
| DAO | `other-infrastructure/src/.../infra/database/rds/dao/` |
|
||||
| Entity | `other-infrastructure/src/.../infra/database/rds/entity/` |
|
||||
| DatabaseService | `other-infrastructure/src/.../infra/database/rds/service/` |
|
||||
| MongoDB | `other-infrastructure/src/.../infra/database/mongo/` |
|
||||
| Cache | `other-infrastructure/src/.../infra/database/cache/` |
|
||||
| Inner API 接口 | `rc-inner-api/other-inner/other-inner-api/endpoint/{模块}/` |
|
||||
| Inner Model | `rc-inner-api/other-inner/other-inner-model/model/{模块}/` |
|
||||
| Inner 实现 | `other-inner-endpoint/src/.../app/inner/service/{模块}/` |
|
||||
|
||||
---
|
||||
|
||||
## 五、常见功能模块目录名
|
||||
`user` / `room` / `activity` / `game` / `family` / `gift` / `task` / `material` / `ranking` / `vip`
|
||||
|
||||
---
|
||||
|
||||
## 六、Gateway 使用原则
|
||||
|
||||
**需要 Gateway 的场景**:分布式锁、缓存+DB 双写、多数据源聚合、复杂事务协调
|
||||
|
||||
**不需要 Gateway 的场景**:简单 CRUD、单表查询、无缓存的简单操作
|
||||
|
||||
**原则:简单直接,复杂封装,不过度设计**
|
||||
244
claude/ai-context/CODING_STYLE.md
Normal file
244
claude/ai-context/CODING_STYLE.md
Normal file
@ -0,0 +1,244 @@
|
||||
# 编码风格规范
|
||||
|
||||
## 一、命名规范
|
||||
|
||||
| 类型 | 命名规则 | 示例 |
|
||||
|------|---------|------|
|
||||
| Controller | `{功能}RestController` | `LotteryActivityRestController` |
|
||||
| Service 接口 | `{功能}Service` | `LotteryActivityRestService` |
|
||||
| Service 实现 | `{功能}ServiceImpl` | `LotteryActivityRestServiceImpl` |
|
||||
| 写操作执行器 | `{功能}CmdExe` 或 `{功能}Exe` | `LotteryDrawExe` |
|
||||
| 查询执行器 | `{功能}QryExe` | `LotteryRecordQryExe` |
|
||||
| 写命令 | `{功能}Cmd` | `LotteryDrawCmd` |
|
||||
| 查询命令 | `{功能}QryCmd` | `LotteryRecordQryCmd` |
|
||||
| 返回对象 | `{功能}CO` | `LotteryDrawResultCO` |
|
||||
| DAO | `{实体名}DAO` | `LotteryTicketDAO` |
|
||||
| Entity | `{实体名}` | `LotteryTicket` |
|
||||
| 数据库服务 | `{功能}DatabaseService` | `LotteryActivityDatabaseService` |
|
||||
| Gateway | `{功能}Gateway` + `{功能}GatewayImpl` | `LotteryActivityGateway` |
|
||||
|
||||
---
|
||||
|
||||
## 二、Controller 规范
|
||||
|
||||
```java
|
||||
/**
|
||||
* 功能说明.
|
||||
*
|
||||
* @author xxx
|
||||
* @eo.api-type http
|
||||
* @eo.groupName 模块名.子模块名
|
||||
* @eo.path /模块/资源
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(value = "/user/user-profile", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequiredArgsConstructor
|
||||
public class UserProfileRestController extends BaseController {
|
||||
|
||||
private final UserProfileService userProfileService;
|
||||
|
||||
/**
|
||||
* 接口说明.
|
||||
*
|
||||
* @eo.name 接口名称
|
||||
* @eo.url /具体路径(GET 无路径时留空)
|
||||
* @eo.method get/post/put/delete
|
||||
* @eo.request-type formdata(GET)/ json(POST/PUT)
|
||||
*/
|
||||
@GetMapping
|
||||
public UserProfileDTO getProfile(UserProfileQryCmd cmd) {
|
||||
return userProfileService.getUserProfile(cmd);
|
||||
}
|
||||
|
||||
@PostMapping("/draw")
|
||||
public LotteryDrawResultCO draw(@RequestBody @Validated LotteryDrawCmd cmd) {
|
||||
return lotteryService.draw(cmd);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
- 继承 `BaseController`
|
||||
- `@RequiredArgsConstructor`(构造器注入)
|
||||
- API 文档用 `@eo.` 注解,不用 Swagger
|
||||
- GET 请求参数直接用 Cmd 对象接收(无 `@RequestBody`)
|
||||
- POST/PUT 用 `@RequestBody @Validated`
|
||||
|
||||
---
|
||||
|
||||
## 三、Cmd / CO 规范
|
||||
|
||||
```java
|
||||
// 写命令 - 继承 AppExtCommand(包含 reqUserId 等公共字段)
|
||||
@Data
|
||||
public class LotteryDrawCmd extends AppExtCommand {
|
||||
@NotNull
|
||||
private Long activityId;
|
||||
|
||||
@Min(1) @Max(10)
|
||||
private Integer drawCount;
|
||||
}
|
||||
|
||||
// 查询命令 - 分页继承 PageQueryCmd
|
||||
@Data
|
||||
public class LotteryRecordQryCmd extends PageQueryCmd {
|
||||
private Long activityId;
|
||||
}
|
||||
|
||||
// 返回对象
|
||||
@Data
|
||||
public class LotteryDrawResultCO {
|
||||
private Long prizeId;
|
||||
private String prizeName;
|
||||
}
|
||||
```
|
||||
|
||||
**规则**:
|
||||
- 校验注解用 `jakarta.validation.constraints.*`(不用 javax)
|
||||
- Cmd 需要用户身份时继承 `AppExtCommand`,通过 `cmd.getReqUserId()` 获取当前用户
|
||||
|
||||
---
|
||||
|
||||
## 四、Service / CmdExe 规范
|
||||
|
||||
```java
|
||||
// ServiceImpl - 门面,调用 CmdExe
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class LotteryActivityRestServiceImpl implements LotteryActivityRestService {
|
||||
private final LotteryDrawExe lotteryDrawExe;
|
||||
private final LotteryRecordQryExe recordQryExe;
|
||||
|
||||
@Override
|
||||
public LotteryDrawResultCO draw(LotteryDrawCmd cmd) {
|
||||
return lotteryDrawExe.execute(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
// CmdExe - 核心业务逻辑
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class LotteryDrawExe {
|
||||
private final LotteryActivityDatabaseService lotteryDbService;
|
||||
|
||||
@Transactional
|
||||
public LotteryDrawResultCO execute(LotteryDrawCmd cmd) {
|
||||
// 1. 参数校验
|
||||
// 2. 业务逻辑
|
||||
// 3. 记录日志
|
||||
log.info("用户抽奖: userId={}, activityId={}", cmd.getReqUserId(), cmd.getActivityId());
|
||||
// 4. 返回结果
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、Infrastructure 规范
|
||||
|
||||
```java
|
||||
// DAO - 继承 BaseDAO
|
||||
public interface LotteryTicketDAO extends BaseDAO<LotteryTicket> {}
|
||||
|
||||
// DatabaseService - 简单场景直接用
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LotteryActivityDatabaseService {
|
||||
private final LotteryTicketDAO ticketDAO;
|
||||
|
||||
public void consumeTicket(Long userId, Long activityId) {
|
||||
LambdaQueryWrapper<LotteryTicket> wrapper = new LambdaQueryWrapper<LotteryTicket>()
|
||||
.eq(Objects.nonNull(userId), LotteryTicket::getUserId, userId)
|
||||
.eq(Objects.nonNull(activityId), LotteryTicket::getActivityId, activityId);
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// Gateway - 复杂场景:锁 + 缓存 + 多数据源
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class LotteryActivityGatewayImpl implements LotteryActivityGateway {
|
||||
private final LotteryTicketDAO ticketDAO;
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Override
|
||||
public void consumeTicketWithLock(Long userId, Long activityId) {
|
||||
String lockKey = "lottery:lock:" + userId;
|
||||
// 分布式锁 + DB 操作 + 缓存更新
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、通用代码规范
|
||||
|
||||
### 条件判断
|
||||
```java
|
||||
// ✅
|
||||
if (StringUtils.isNotBlank(name)) { ... }
|
||||
if (Objects.nonNull(userId)) { ... }
|
||||
|
||||
// ❌
|
||||
if (name != null && !name.isEmpty()) { ... }
|
||||
if (userId != null) { ... }
|
||||
```
|
||||
|
||||
### 金额
|
||||
```java
|
||||
// ✅
|
||||
BigDecimal amount = new BigDecimal("100.00");
|
||||
BigDecimal total = a.add(b);
|
||||
|
||||
// ❌ 禁止
|
||||
double amount = 100.00;
|
||||
```
|
||||
|
||||
### 返回分页
|
||||
```java
|
||||
return PageResult.of(records, total, cmd.getPageNum(), cmd.getPageSize());
|
||||
```
|
||||
|
||||
### 异常
|
||||
```java
|
||||
// ✅
|
||||
throw new BusinessException("抽奖券不足");
|
||||
|
||||
// ❌
|
||||
throw new RuntimeException("抽奖券不足");
|
||||
```
|
||||
|
||||
### Redis Key 规范
|
||||
```
|
||||
缓存: {module}:{entity}:{id} user:info:10001
|
||||
排行榜: ranking:{type}:{period}:{date} ranking:send_gift:day:20240101
|
||||
分布式锁: {module}:lock:{bizId} coin:lock:10001
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、新功能开发顺序(黄金路径)
|
||||
|
||||
1. 定义 Cmd / CO(other-client)
|
||||
2. 定义 Service 接口(other-client)
|
||||
3. 实现 CmdExe(other-application)
|
||||
4. 实现 ServiceImpl(other-application)
|
||||
5. 创建 Controller(other-adapter)
|
||||
6. 按需创建 DatabaseService 或 Gateway(other-infrastructure)
|
||||
7. 如需跨服务调用,添加 Inner API
|
||||
|
||||
---
|
||||
|
||||
## 八、质量检查清单
|
||||
|
||||
- [ ] 命名清晰,无 a/b/temp 类命名
|
||||
- [ ] 参数校验(`@Validated`、`@NotNull`)
|
||||
- [ ] 写操作有 `@Transactional`
|
||||
- [ ] 金额操作有幂等性保障(bizNo)
|
||||
- [ ] 并发场景有分布式锁
|
||||
- [ ] 关键操作有 `log.info` / `log.error`
|
||||
- [ ] 业务异常用 `BusinessException`
|
||||
- [ ] 无魔法值(常量或枚举)
|
||||
- [ ] 分页查询用 `PageResult`
|
||||
52
claude/ai-context/CONTEXT.md
Normal file
52
claude/ai-context/CONTEXT.md
Normal file
@ -0,0 +1,52 @@
|
||||
# likei-services 项目上下文
|
||||
|
||||
## 项目概述
|
||||
社交娱乐平台,核心服务为 `rc-service`(多子服务),约 1000 DAU,运行于 AWS EKS。
|
||||
前端通过 REST API 调用;微服务之间通过 Feign(Inner API)调用。
|
||||
|
||||
---
|
||||
|
||||
## 技术栈
|
||||
| 类型 | 技术 |
|
||||
|------|------|
|
||||
| 框架 | Spring Boot,DDD + CQRS |
|
||||
| ORM | MyBatis-Plus,`BaseDAO<T>` |
|
||||
| 数据库 | MySQL、MongoDB、Redis |
|
||||
| 消息队列 | RocketMQ(部分模块用 RabbitMQ) |
|
||||
| 服务间调用 | Spring Cloud Feign |
|
||||
| 配置/注册 | Nacos |
|
||||
| 基础设施 | AWS EKS(Kubernetes) |
|
||||
| 校验 | `jakarta.validation.constraints.*`(非 javax) |
|
||||
| 文档 | `@eo.` 注解系列(非 Swagger) |
|
||||
|
||||
---
|
||||
|
||||
## 子服务清单
|
||||
| 子服务 | 说明 |
|
||||
|--------|------|
|
||||
| rc-service-other | 综合业务:用户、房间、家族、礼物、活动、任务等 |
|
||||
| rc-service-live | 直播相关 |
|
||||
| rc-service-wallet | 钱包、金币、支付 |
|
||||
| rc-service-order | 订单 |
|
||||
| rc-service-console | 管理后台接口 |
|
||||
| rc-service-external | 对外开放接口 |
|
||||
| rc-auth | 认证授权 |
|
||||
| rc-gateway | Spring Cloud Gateway 网关 |
|
||||
| rc-scheduling | 定时任务 |
|
||||
| rc-service-game | 游戏子服务(百顺、灵仙等) |
|
||||
|
||||
---
|
||||
|
||||
## 核心编码规范(速查)
|
||||
- 条件判断:`StringUtils.isNotBlank()` / `Objects.nonNull()`
|
||||
- 查询构造:`LambdaQueryWrapper`,禁止字符串字段名
|
||||
- 金额:`BigDecimal`,禁止 `float` / `double`
|
||||
- 时间:`LocalDateTime` / `LocalDate`
|
||||
- 返回值:统一 `Result<T>` 或 `PageResult<T>`
|
||||
- 异常:`throw new BusinessException("...")`
|
||||
- 注入:`@RequiredArgsConstructor`(构造器注入),禁止 `@Autowired` 字段注入
|
||||
- 日志:`@Slf4j`,关键操作必须 log
|
||||
- 事务:写操作必须 `@Transactional`
|
||||
|
||||
> 详细规范见 CODING_STYLE.md
|
||||
> 架构分层与调用链见 ARCHITECTURE.md
|
||||
92
claude/api/_TEMPLATE.md
Normal file
92
claude/api/_TEMPLATE.md
Normal file
@ -0,0 +1,92 @@
|
||||
# API 接口文档模板
|
||||
|
||||
> 复制此文件,命名为 {module}-api.md,记录该模块对外暴露的 REST 接口。
|
||||
|
||||
---
|
||||
|
||||
## 模块信息
|
||||
- **模块名**:{模块中文名} / {module}
|
||||
- **Controller**:`{功能}RestController`
|
||||
- **@eo.groupName**:`{一级模块}.{二级模块}`
|
||||
- **@eo.path(base)**:`/{模块}/{资源}`
|
||||
- **文件路径**:`other-adapter/src/.../adapter/app/{模块}/{功能}RestController.java`
|
||||
|
||||
---
|
||||
|
||||
## 接口列表
|
||||
|
||||
### 1. {接口名称}
|
||||
|
||||
```java
|
||||
/**
|
||||
* {接口说明}.
|
||||
*
|
||||
* @eo.name {接口名称}
|
||||
* @eo.url {子路径,GET无子路径时留空}
|
||||
* @eo.method get
|
||||
* @eo.request-type formdata
|
||||
*/
|
||||
@GetMapping("/{sub-path}")
|
||||
public {返回CO或DTO} {methodName}({QryCmd} cmd) {
|
||||
return {service}.{method}(cmd);
|
||||
}
|
||||
```
|
||||
|
||||
**请求参数(QryCmd 字段)**:
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| userId | Long | 否 | 目标用户ID(不传则取当前登录用户) |
|
||||
|
||||
**响应(CO 字段)**:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| userId | Long | 用户ID |
|
||||
| nickname | String | 昵称 |
|
||||
|
||||
---
|
||||
|
||||
### 2. {写操作接口名称}
|
||||
|
||||
```java
|
||||
/**
|
||||
* {接口说明}.
|
||||
*
|
||||
* @eo.name {接口名称}
|
||||
* @eo.url /{sub-path}
|
||||
* @eo.method post
|
||||
* @eo.request-type json
|
||||
*/
|
||||
@PostMapping("/{sub-path}")
|
||||
public {返回CO} {methodName}(@RequestBody @Validated {Cmd} cmd) {
|
||||
return {service}.{method}(cmd);
|
||||
}
|
||||
```
|
||||
|
||||
**请求体(Cmd 字段)**:
|
||||
| 字段 | 类型 | 必填 | 校验 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| activityId | Long | 是 | @NotNull | 活动ID |
|
||||
| drawCount | Integer | 否 | @Min(1) @Max(10) | 抽奖次数 |
|
||||
|
||||
**响应(CO 字段)**:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| prizeId | Long | 奖品ID |
|
||||
| prizeName | String | 奖品名称 |
|
||||
|
||||
---
|
||||
|
||||
## 枚举值说明
|
||||
|
||||
| 枚举类 | 值 | 说明 |
|
||||
|-------|----|------|
|
||||
| StatusEnum | 0 | 正常 |
|
||||
| StatusEnum | 1 | 禁用 |
|
||||
|
||||
---
|
||||
|
||||
## 关联文件
|
||||
- Service 接口:`other-client/src/.../app/service/{模块}/{功能}Service.java`
|
||||
- Cmd:`other-client/src/.../app/dto/cmd/{模块}/`
|
||||
- CO:`other-client/src/.../app/dto/clientobject/{模块}/`
|
||||
- CmdExe:`other-application/src/.../app/command/{模块}/`
|
||||
688
claude/likei-services.md
Normal file
688
claude/likei-services.md
Normal file
@ -0,0 +1,688 @@
|
||||
# Other 模块 DDD 架构说明文档
|
||||
|
||||
## 一、模块概览
|
||||
|
||||
Other 服务是一个综合性的业务模块,包含用户、房间、游戏、活动、家族、礼物、任务等多个子领域。采用标准的 DDD(领域驱动设计)+ CQRS 架构模式。
|
||||
|
||||
### 模块列表
|
||||
|
||||
```
|
||||
rc-service-other/
|
||||
├── other-domain # 领域层(核心业务实体)
|
||||
├── other-infrastructure # 基础设施层(数据访问、外部服务)
|
||||
├── other-client # 客户端接口层(DTO、Service接口)
|
||||
├── other-application # 应用层(业务逻辑实现)
|
||||
├── other-adapter # 适配层(REST API、Controller)
|
||||
├── other-inner-endpoint # 内部服务端点(跨服务调用实现)
|
||||
└── other-start # 启动模块(Spring Boot入口)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、各模块详细说明
|
||||
|
||||
### 1. other-domain(领域层)
|
||||
**作用**:定义核心领域模型和业务规则
|
||||
**依赖**:无外部依赖(最纯净的业务模型)
|
||||
**路径**:`other-domain/src/main/java/com/red/circle/other/domain/`
|
||||
|
||||
**职责**:
|
||||
- 定义领域实体(Entity)
|
||||
- 定义值对象(Value Object)
|
||||
- 定义领域服务接口
|
||||
- 不包含任何基础设施相关代码
|
||||
|
||||
**典型文件**:
|
||||
- 领域实体定义
|
||||
- 业务规则封装
|
||||
|
||||
---
|
||||
|
||||
### 2. other-infrastructure(基础设施层)
|
||||
**作用**:提供技术基础设施支持
|
||||
**依赖**:`other-domain`、框架组件(MyBatis、Redis、MongoDB、RocketMQ)
|
||||
**路径**:`other-infrastructure/src/main/java/com/red/circle/other/infra/`
|
||||
|
||||
**目录结构**:
|
||||
```
|
||||
infra/
|
||||
├── database/ # 数据访问
|
||||
│ ├── rds/ # MySQL 数据库
|
||||
│ │ ├── dao/ # MyBatis DAO(继承BaseDAO)
|
||||
│ │ ├── entity/ # 数据库实体
|
||||
│ │ ├── service/ # 数据库服务封装
|
||||
│ │ └── query/ # 查询条件构建
|
||||
│ ├── mongo/ # MongoDB 数据库
|
||||
│ └── cache/ # Redis 缓存
|
||||
├── gateway/ # 网关实现(可选)
|
||||
├── convertor/ # 对象转换器
|
||||
├── config/ # 配置类
|
||||
└── utils/ # 工具类
|
||||
```
|
||||
|
||||
**关键说明**:
|
||||
- **DAO 命名规范**:`{实体名}DAO`,继承 `BaseDAO<T>`
|
||||
- **Service 命名规范**:`{功能}DatabaseService`
|
||||
- **不是所有功能都需要 Gateway**,简单功能直接在 CmdExe 中调用 Infrastructure 的接口
|
||||
|
||||
---
|
||||
|
||||
### 3. other-client(客户端接口层)
|
||||
**作用**:定义对外暴露的接口和数据模型
|
||||
**依赖**:无
|
||||
**路径**:`other-client/src/main/java/com/red/circle/other/app/`
|
||||
|
||||
**目录结构**:
|
||||
```
|
||||
app/
|
||||
├── dto/ # 数据传输对象
|
||||
│ ├── cmd/ # 命令对象(写操作)
|
||||
│ │ └── {功能模块}/
|
||||
│ └── clientobject/ # 客户端对象(读操作返回值)
|
||||
│ └── {功能模块}/
|
||||
├── service/ # 服务接口定义
|
||||
│ └── {功能模块}/
|
||||
└── enums/ # 枚举类
|
||||
```
|
||||
|
||||
**命名规范**:
|
||||
- **Cmd(命令)**:用于写操作,如 `LotteryDrawCmd`、`UserProfileModifyCmd`
|
||||
- **CO(客户端对象)**:用于读操作返回,如 `LotteryActivityCO`、`UserProfileCO`
|
||||
- **QryCmd(查询命令)**:用于查询操作,如 `LotteryRecordQryCmd`
|
||||
|
||||
**注解规范**:
|
||||
- 使用 `@Data` + 文件格式注释
|
||||
- Cmd 需要时继承 `com.red.circle.common.business.dto.cmd.AppExtCommand`
|
||||
- 分页查询继承 `com.red.circle.common.business.dto.PageQueryCmd`
|
||||
- 校验注解使用 `jakarta.validation.constraints.*`(不用 javax)
|
||||
|
||||
---
|
||||
|
||||
### 4. other-application(应用层)
|
||||
**作用**:实现业务逻辑
|
||||
**依赖**:`other-client`、`other-infrastructure`
|
||||
**路径**:`other-application/src/main/java/com/red/circle/other/app/`
|
||||
|
||||
**目录结构**:
|
||||
```
|
||||
app/
|
||||
├── command/ # 命令执行器
|
||||
│ └── {功能模块}/
|
||||
│ ├── {功能}CmdExe.java # 写操作执行器
|
||||
│ └── query/ # 查询执行器
|
||||
│ └── {功能}QryExe.java
|
||||
├── service/ # 服务实现
|
||||
│ └── {功能模块}/
|
||||
│ └── {功能}ServiceImpl.java
|
||||
├── convertor/ # 对象转换器(MapStruct)
|
||||
├── listener/ # 事件监听器
|
||||
├── scheduler/ # 定时任务
|
||||
├── manager/ # 业务管理器(复杂业务编排)
|
||||
├── common/ # 通用业务逻辑
|
||||
└── config/ # 应用配置
|
||||
```
|
||||
|
||||
**核心原则**:
|
||||
- **ServiceImpl 调用 CmdExe**:ServiceImpl 是门面,具体业务由 CmdExe 实现
|
||||
- **CmdExe 命名规范**:`{功能名}CmdExe` 或 `{功能名}QryExe`
|
||||
- **是否需要 Gateway**:
|
||||
- ✅ 简单功能:CmdExe 直接调用 Infrastructure 的 DatabaseService
|
||||
- ✅ 复杂功能:CmdExe 通过 Gateway 封装复杂的数据访问逻辑
|
||||
- 原则:**简单直接,复杂封装,不要过度设计**
|
||||
|
||||
**代码质量要求**:
|
||||
- 关键业务必须添加 `@Transactional` 事务
|
||||
- 金额操作必须保证幂等性(使用 bizNo)
|
||||
- 重要操作记录日志(`@Slf4j`)
|
||||
- 完善的参数校验和异常处理
|
||||
|
||||
---
|
||||
|
||||
### 5. other-adapter(适配层)
|
||||
**作用**:对外提供 REST API
|
||||
**依赖**:`other-application`
|
||||
**路径**:`other-adapter/src/main/java/com/red/circle/other/adapter/app/`
|
||||
|
||||
**目录结构**:
|
||||
```
|
||||
adapter/app/
|
||||
└── {功能模块}/
|
||||
└── {功能名}RestController.java
|
||||
```
|
||||
|
||||
**命名规范**:
|
||||
- Controller 命名:`{功能名}RestController`
|
||||
- 继承 `BaseController`
|
||||
- 使用 `@RestController` + `@RequestMapping`
|
||||
|
||||
**注解规范**:
|
||||
- API 文档使用 `@eo.` 系列注解(不使用 Swagger)
|
||||
- 路径规范:`/功能模块/资源`,如 `/activity/lottery`
|
||||
|
||||
**职责**:
|
||||
- 接收 HTTP 请求
|
||||
- 参数校验(`@Validated`)
|
||||
- 调用 Service 层
|
||||
- 返回统一格式的响应
|
||||
|
||||
---
|
||||
|
||||
### 6. other-inner-endpoint(内部服务端点)
|
||||
**作用**:提供跨服务调用的实现(供其他微服务通过 Feign 调用)
|
||||
**依赖**:`other-application`、`other-inner-api`
|
||||
**路径**:`other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/`
|
||||
|
||||
**与 other-client 的区别**:
|
||||
| 维度 | other-client | other-inner-endpoint |
|
||||
|------|-------------|---------------------|
|
||||
| 调用方 | 前端 App、Web | 其他微服务(如 wallet、live) |
|
||||
| 传输协议 | HTTP REST | HTTP Feign |
|
||||
| 接口定义位置 | `other-client/service/` | `other-inner-api/endpoint/` |
|
||||
| 接口实现位置 | `other-application/service/` | `other-inner-endpoint/service/` |
|
||||
| DTO 定义位置 | `other-client/dto/` | `other-inner-model/model/` |
|
||||
|
||||
**典型场景**:
|
||||
- 钱包服务调用 other 服务获取用户信息
|
||||
- 直播服务调用 other 服务更新房间状态
|
||||
|
||||
---
|
||||
|
||||
### 7. other-start(启动模块)
|
||||
**作用**:Spring Boot 应用入口
|
||||
**依赖**:`other-adapter`、`other-inner-endpoint`
|
||||
**路径**:`other-start/src/main/java/com/red/circle/`
|
||||
|
||||
**职责**:
|
||||
- 定义 Spring Boot 主类
|
||||
- 引入所有模块依赖
|
||||
- 配置文件(application.yml)
|
||||
|
||||
---
|
||||
|
||||
## 三、跨模块通信说明
|
||||
|
||||
### 内部模块调用关系图
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ other-start │
|
||||
│ (Spring Boot 入口) │
|
||||
└────────────┬────────────────────┬────────────────┘
|
||||
│ │
|
||||
┌────────▼────────┐ ┌───────▼────────────┐
|
||||
│ other-adapter │ │ other-inner-endpoint│
|
||||
│ (REST API) │ │ (Feign 服务端) │
|
||||
└────────┬────────┘ └───────┬────────────┘
|
||||
│ │
|
||||
└────────┬───────────┘
|
||||
│
|
||||
┌─────────▼──────────┐
|
||||
│ other-application │
|
||||
│ (业务逻辑层) │
|
||||
│ ├── CmdExe │
|
||||
│ ├── ServiceImpl │
|
||||
│ └── Manager │
|
||||
└─────────┬──────────┘
|
||||
│
|
||||
┌─────────────┼─────────────┐
|
||||
│ │ │
|
||||
┌───────▼────────┐ ┌─▼──────────┐ ┌▼──────────┐
|
||||
│ other-client │ │ other-infra│ │other-domain│
|
||||
│ (接口+DTO) │ │ (数据访问) │ │ (实体) │
|
||||
└────────────────┘ └────────────┘ └───────────┘
|
||||
```
|
||||
|
||||
### 跨服务调用说明
|
||||
|
||||
**场景示例**:钱包服务需要调用 other 服务获取用户信息
|
||||
|
||||
1. **定义 API 接口**(在 `rc-inner-api/other-inner/other-inner-api/`):
|
||||
```java
|
||||
// endpoint 包下定义 Feign 客户端接口
|
||||
@FeignClient(name = "other-service")
|
||||
public interface UserProfileClientService {
|
||||
UserProfileDTO getByUserId(Long userId);
|
||||
}
|
||||
```
|
||||
|
||||
2. **定义数据模型**(在 `rc-inner-api/other-inner/other-inner-model/`):
|
||||
```java
|
||||
// model 包下定义传输对象
|
||||
public class UserProfileDTO {
|
||||
private Long userId;
|
||||
private String nickname;
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
3. **实现服务端点**(在 `other-inner-endpoint/`):
|
||||
```java
|
||||
@RestController
|
||||
public class UserProfileClientServiceImpl implements UserProfileClientService {
|
||||
@Autowired
|
||||
private UserProfileService userProfileService;
|
||||
|
||||
public UserProfileDTO getByUserId(Long userId) {
|
||||
// 调用 application 层服务
|
||||
return userProfileService.getByUserId(userId);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. **钱包服务调用**(在 wallet 服务中):
|
||||
```java
|
||||
@Service
|
||||
public class WalletServiceImpl {
|
||||
@Autowired
|
||||
private UserProfileClientService userProfileClient; // Feign 客户端
|
||||
|
||||
public void someMethod() {
|
||||
UserProfileDTO user = userProfileClient.getByUserId(123L);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、新增功能开发流程
|
||||
|
||||
### 标准开发顺序(必须遵循)
|
||||
|
||||
以"抽奖活动"为例,演示完整的开发流程:
|
||||
|
||||
#### 1. 定义数据模型(other-client)
|
||||
```
|
||||
other-client/src/main/java/com/red/circle/other/app/dto/
|
||||
├── cmd/activity/
|
||||
│ ├── LotteryDrawCmd.java # 抽奖命令
|
||||
│ └── LotteryRecordQryCmd.java # 查询抽奖记录
|
||||
└── clientobject/activity/
|
||||
├── LotteryActivityCO.java # 活动信息
|
||||
└── LotteryDrawResultCO.java # 抽奖结果
|
||||
```
|
||||
|
||||
#### 2. 定义 Service 接口(other-client)
|
||||
```java
|
||||
// other-client/src/main/java/com/red/circle/other/app/service/activity/
|
||||
public interface LotteryActivityRestService {
|
||||
LotteryDrawResultCO draw(LotteryDrawCmd cmd);
|
||||
PageResult<LotteryRecordCO> listMyRecords(LotteryRecordQryCmd cmd);
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 实现 CmdExe(other-application)
|
||||
```
|
||||
other-application/src/main/java/com/red/circle/other/app/command/activity/
|
||||
├── LotteryDrawExe.java # 抽奖执行器
|
||||
└── query/
|
||||
└── LotteryRecordQryExe.java # 查询执行器
|
||||
```
|
||||
|
||||
**示例代码**:
|
||||
```java
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class LotteryDrawExe {
|
||||
private final LotteryActivityDatabaseService lotteryDbService;
|
||||
private final LotteryPrizeGrantService prizeService;
|
||||
|
||||
@Transactional
|
||||
public LotteryDrawResultCO execute(LotteryDrawCmd cmd) {
|
||||
// 1. 参数校验
|
||||
validateTicket(cmd.getUserId());
|
||||
|
||||
// 2. 扣除抽奖券(直接调用 Infrastructure 的服务)
|
||||
lotteryDbService.consumeTicket(cmd.getUserId(), cmd.getActivityId());
|
||||
|
||||
// 3. 随机抽奖
|
||||
LotteryPrize prize = prizeService.randomDraw(cmd.getActivityId());
|
||||
|
||||
// 4. 记录中奖
|
||||
lotteryDbService.saveDrawRecord(cmd.getUserId(), prize);
|
||||
|
||||
// 5. 返回结果
|
||||
return convertToResult(prize);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 实现 ServiceImpl(other-application)
|
||||
```java
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LotteryActivityRestServiceImpl implements LotteryActivityRestService {
|
||||
private final LotteryDrawExe lotteryDrawExe;
|
||||
private final LotteryRecordQryExe recordQryExe;
|
||||
|
||||
@Override
|
||||
public LotteryDrawResultCO draw(LotteryDrawCmd cmd) {
|
||||
return lotteryDrawExe.execute(cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<LotteryRecordCO> listMyRecords(LotteryRecordQryCmd cmd) {
|
||||
return recordQryExe.query(cmd);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. 创建 Controller(other-adapter)
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/activity/lottery")
|
||||
@RequiredArgsConstructor
|
||||
public class LotteryActivityRestController extends BaseController {
|
||||
private final LotteryActivityRestService lotteryService;
|
||||
|
||||
/**
|
||||
* 执行抽奖
|
||||
* @eo.name 执行抽奖
|
||||
* @eo.url /draw
|
||||
* @eo.method post
|
||||
*/
|
||||
@PostMapping("/draw")
|
||||
public LotteryDrawResultCO draw(@RequestBody @Validated LotteryDrawCmd cmd) {
|
||||
return lotteryService.draw(cmd);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 6. 数据访问层(other-infrastructure)
|
||||
|
||||
**简单功能**(直接使用 DAO 和 DatabaseService):
|
||||
```java
|
||||
// DAO
|
||||
public interface LotteryTicketDAO extends BaseDAO<LotteryTicket> {}
|
||||
|
||||
// DatabaseService
|
||||
@Service
|
||||
public class LotteryActivityDatabaseService {
|
||||
@Autowired
|
||||
private LotteryTicketDAO ticketDAO;
|
||||
|
||||
public void consumeTicket(Long userId, Long activityId) {
|
||||
// 直接操作数据库
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**复杂功能**(使用 Gateway 封装):
|
||||
```java
|
||||
// Gateway 接口
|
||||
public interface LotteryActivityGateway {
|
||||
void consumeTicketWithLock(Long userId, Long activityId);
|
||||
}
|
||||
|
||||
// Gateway 实现
|
||||
@Component
|
||||
public class LotteryActivityGatewayImpl implements LotteryActivityGateway {
|
||||
@Autowired
|
||||
private LotteryTicketDAO ticketDAO;
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public void consumeTicketWithLock(Long userId, Long activityId) {
|
||||
// 分布式锁 + 数据库操作 + 缓存更新
|
||||
String lockKey = "lottery:lock:" + userId;
|
||||
// ... 复杂逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 7. 跨服务调用(可选)
|
||||
|
||||
如果需要被其他服务调用,创建 Inner API:
|
||||
|
||||
```
|
||||
rc-inner-api/other-inner/
|
||||
├── other-inner-api/endpoint/activity/
|
||||
│ └── LotteryActivityClientService.java # Feign 接口
|
||||
├── other-inner-model/model/activity/
|
||||
│ └── LotteryDrawDTO.java # 数据模型
|
||||
└── other-inner-endpoint/service/activity/
|
||||
└── LotteryActivityClientServiceImpl.java # 实现
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、文件路径快速参考
|
||||
|
||||
### 按功能类型查找路径
|
||||
|
||||
| 文件类型 | 路径模板 | 示例 |
|
||||
|---------|---------|------|
|
||||
| **Controller** | `other-adapter/src/main/java/com/red/circle/other/adapter/app/{模块}/` | `activity/LotteryActivityRestController.java` |
|
||||
| **Service 接口** | `other-client/src/main/java/com/red/circle/other/app/service/{模块}/` | `activity/LotteryActivityRestService.java` |
|
||||
| **Cmd** | `other-client/src/main/java/com/red/circle/other/app/dto/cmd/{模块}/` | `activity/LotteryDrawCmd.java` |
|
||||
| **CO** | `other-client/src/main/java/com/red/circle/other/app/dto/clientobject/{模块}/` | `activity/LotteryDrawResultCO.java` |
|
||||
| **CmdExe** | `other-application/src/main/java/com/red/circle/other/app/command/{模块}/` | `activity/LotteryDrawExe.java` |
|
||||
| **QryExe** | `other-application/src/main/java/com/red/circle/other/app/command/{模块}/query/` | `activity/query/LotteryRecordQryExe.java` |
|
||||
| **ServiceImpl** | `other-application/src/main/java/com/red/circle/other/app/service/{模块}/` | `activity/LotteryActivityRestServiceImpl.java` |
|
||||
| **Gateway** | `other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/{模块}/` | `activity/LotteryActivityGatewayImpl.java` |
|
||||
| **DAO** | `other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/dao/` | `LotteryTicketDAO.java` |
|
||||
| **Entity** | `other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/` | `LotteryTicket.java` |
|
||||
| **DatabaseService** | `other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/` | `LotteryActivityDatabaseService.java` |
|
||||
| **Inner API** | `rc-inner-api/other-inner/other-inner-api/endpoint/{模块}/` | `activity/LotteryActivityClientService.java` |
|
||||
| **Inner Model** | `rc-inner-api/other-inner/other-inner-model/model/{模块}/` | `activity/LotteryDrawDTO.java` |
|
||||
| **Inner Endpoint** | `other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/{模块}/` | `activity/LotteryActivityClientServiceImpl.java` |
|
||||
|
||||
### 按模块查找路径
|
||||
|
||||
#### 常见功能模块
|
||||
- `activity` - 活动相关
|
||||
- `user` - 用户相关
|
||||
- `room` - 房间相关
|
||||
- `game` - 游戏相关
|
||||
- `family` - 家族相关
|
||||
- `gift` - 礼物相关
|
||||
- `task` - 任务相关
|
||||
- `material` - 素材/道具相关
|
||||
|
||||
---
|
||||
|
||||
## 六、核心开发规范
|
||||
|
||||
### 1. 命名规范
|
||||
|
||||
| 类型 | 命名规则 | 示例 |
|
||||
|------|---------|------|
|
||||
| Controller | `{功能}RestController` | `LotteryActivityRestController` |
|
||||
| Service 接口 | `{功能}Service` | `LotteryActivityRestService` |
|
||||
| Service 实现 | `{功能}ServiceImpl` | `LotteryActivityRestServiceImpl` |
|
||||
| CmdExe | `{功能}CmdExe` / `{功能}Exe` | `LotteryDrawExe` |
|
||||
| QryExe | `{功能}QryExe` | `LotteryRecordQryExe` |
|
||||
| Cmd | `{功能}Cmd` | `LotteryDrawCmd` |
|
||||
| QryCmd | `{功能}QryCmd` | `LotteryRecordQryCmd` |
|
||||
| CO | `{功能}CO` | `LotteryDrawResultCO` |
|
||||
| DAO | `{实体名}DAO` | `LotteryTicketDAO` |
|
||||
| Entity | `{实体名}` | `LotteryTicket` |
|
||||
| Gateway | `{功能}Gateway` + Impl | `LotteryActivityGateway` |
|
||||
|
||||
### 2. 注解规范
|
||||
|
||||
#### DTO 层
|
||||
```java
|
||||
@Data // Lombok
|
||||
public class LotteryDrawCmd extends AppExtCommand {
|
||||
@NotNull
|
||||
private Long activityId;
|
||||
|
||||
@Min(1)
|
||||
@Max(10)
|
||||
private Integer drawCount;
|
||||
}
|
||||
```
|
||||
|
||||
#### 分页查询
|
||||
```java
|
||||
@Data
|
||||
public class LotteryRecordQryCmd extends PageQueryCmd {
|
||||
private Long activityId;
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller 层
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/activity/lottery")
|
||||
@RequiredArgsConstructor // Lombok 构造器注入
|
||||
public class LotteryActivityRestController extends BaseController {
|
||||
|
||||
/**
|
||||
* 执行抽奖
|
||||
* @eo.name 执行抽奖
|
||||
* @eo.url /draw
|
||||
* @eo.method post
|
||||
* @eo.request-type json
|
||||
*/
|
||||
@PostMapping("/draw")
|
||||
public LotteryDrawResultCO draw(@RequestBody @Validated LotteryDrawCmd cmd) {
|
||||
return lotteryService.draw(cmd);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Service 层
|
||||
```java
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j // 日志
|
||||
public class LotteryActivityRestServiceImpl implements LotteryActivityRestService {
|
||||
|
||||
private final LotteryDrawExe lotteryDrawExe;
|
||||
|
||||
@Override
|
||||
@Transactional // 需要事务的方法
|
||||
public LotteryDrawResultCO draw(LotteryDrawCmd cmd) {
|
||||
log.info("用户抽奖: userId={}, activityId={}",
|
||||
cmd.getReqUserId(), cmd.getActivityId());
|
||||
return lotteryDrawExe.execute(cmd);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 分页返回
|
||||
|
||||
统一使用 `com.red.circle.framework.dto.PageResult<T>`:
|
||||
|
||||
```java
|
||||
public PageResult<LotteryRecordCO> listMyRecords(LotteryRecordQryCmd cmd) {
|
||||
// 查询数据
|
||||
List<LotteryRecordCO> records = queryRecords(cmd);
|
||||
// 查询总数
|
||||
long total = countRecords(cmd);
|
||||
|
||||
return PageResult.of(records, total, cmd.getPageNum(), cmd.getPageSize());
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 异常处理
|
||||
|
||||
使用业务异常,不直接抛出 RuntimeException:
|
||||
|
||||
```java
|
||||
if (ticket == null) {
|
||||
throw new BusinessException("抽奖券不足");
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 事务控制
|
||||
|
||||
- **写操作**:必须添加 `@Transactional`
|
||||
- **读操作**:不需要事务
|
||||
- **跨服务调用**:考虑分布式事务或最终一致性
|
||||
|
||||
---
|
||||
|
||||
## 七、关键设计原则
|
||||
|
||||
### 1. Gateway 使用原则
|
||||
|
||||
**何时使用 Gateway**:
|
||||
- ✅ 需要分布式锁的场景
|
||||
- ✅ 需要缓存 + 数据库双写的场景
|
||||
- ✅ 需要多个数据源聚合的场景
|
||||
- ✅ 需要复杂的事务协调
|
||||
- ✅ 业务逻辑复杂,需要封装的场景
|
||||
|
||||
**何时不用 Gateway**:
|
||||
- ❌ 简单的 CRUD 操作
|
||||
- ❌ 单表查询
|
||||
- ❌ 不需要缓存的简单操作
|
||||
- ❌ 逻辑简单清晰的场景
|
||||
|
||||
**原则**:简单直接,复杂封装,避免过度设计
|
||||
|
||||
### 2. 层次调用原则
|
||||
|
||||
```
|
||||
Controller → Service → CmdExe → Gateway/DatabaseService → DAO
|
||||
```
|
||||
|
||||
- Controller 只调用 Service
|
||||
- Service 只调用 CmdExe
|
||||
- CmdExe 可直接调用 Infrastructure(简单场景)或通过 Gateway(复杂场景)
|
||||
- 禁止跨层调用
|
||||
|
||||
### 3. 代码质量原则
|
||||
|
||||
参考主项目文档中的质量检查清单:
|
||||
|
||||
- [ ] 命名清晰(避免 a、b、temp)
|
||||
- [ ] 完整的注释
|
||||
- [ ] 参数校验(@Valid、@NotNull)
|
||||
- [ ] 异常处理
|
||||
- [ ] 并发安全(金额操作)
|
||||
- [ ] 幂等性(bizNo)
|
||||
- [ ] 事务注解(@Transactional)
|
||||
- [ ] 关键日志(log.info/error)
|
||||
- [ ] 性能考虑(N+1、缓存)
|
||||
- [ ] 安全防护(SQL 注入、XSS)
|
||||
|
||||
---
|
||||
|
||||
## 八、常见问题 FAQ
|
||||
|
||||
### Q1: 什么时候需要 Gateway?
|
||||
A: 当业务逻辑涉及多个数据源、分布式锁、缓存同步等复杂场景时使用 Gateway。简单的 CRUD 直接使用 DatabaseService。
|
||||
|
||||
### Q2: CmdExe 和 ServiceImpl 的区别?
|
||||
A: ServiceImpl 是门面,负责接口定义和调用编排。CmdExe 是具体的业务逻辑实现。一个 ServiceImpl 可能调用多个 CmdExe。
|
||||
|
||||
### Q3: 跨服务调用如何实现?
|
||||
A: 通过 Inner API + Feign。在 `other-inner-api` 定义接口,在 `other-inner-endpoint` 实现,其他服务通过 Feign 客户端调用。
|
||||
|
||||
### Q4: 如何处理分布式事务?
|
||||
A: 优先考虑最终一致性(如消息队列)。如果必须强一致,考虑 TCC 或 Saga 模式,但要评估复杂度。
|
||||
|
||||
### Q5: MongoDB 和 MySQL 如何选择?
|
||||
A:
|
||||
- MySQL:强一致性、事务、关系查询
|
||||
- MongoDB:高性能、灵活 schema、大数据量统计
|
||||
|
||||
---
|
||||
|
||||
## 九、总结
|
||||
|
||||
### 开发新功能的黄金路径
|
||||
|
||||
1. ✅ 先定义 DTO(Cmd、CO)
|
||||
2. ✅ 定义 Service 接口
|
||||
3. ✅ 实现 CmdExe(核心业务逻辑)
|
||||
4. ✅ 实现 ServiceImpl(调用 CmdExe)
|
||||
5. ✅ 创建 Controller(暴露 API)
|
||||
6. ✅ 根据需要创建 Gateway 或直接用 DatabaseService
|
||||
7. ✅ 如需跨服务调用,添加 Inner API
|
||||
|
||||
### 核心理念
|
||||
|
||||
- **领域驱动**:按业务领域划分模块
|
||||
- **分层清晰**:各层职责明确,禁止跨层调用
|
||||
- **简单优先**:不过度设计,够用即可
|
||||
- **质量第一**:代码清晰、测试完善、文档齐全
|
||||
|
||||
---
|
||||
|
||||
**文档版本**:v1.0
|
||||
**最后更新**:2025-01-15
|
||||
**维护者**:开发团队
|
||||
32
claude/modules/_TEMPLATE.md
Normal file
32
claude/modules/_TEMPLATE.md
Normal file
@ -0,0 +1,32 @@
|
||||
# 模块文档模板
|
||||
|
||||
> 复制此文件,重命名为 {module}.md,按实际情况填写
|
||||
|
||||
## 模块名称
|
||||
{模块中文名} / {模块英文名}
|
||||
|
||||
## 功能概述
|
||||
> 一句话说明该模块的职责
|
||||
|
||||
## 核心实体
|
||||
| 实体 | 表/集合 | 说明 |
|
||||
|------|--------|------|
|
||||
| XxxEntity | t_xxx | ... |
|
||||
|
||||
## 主要功能点
|
||||
- [ ] 功能1
|
||||
- [ ] 功能2
|
||||
|
||||
## 关键业务逻辑
|
||||
> 描述复杂逻辑、计算规则、状态流转等
|
||||
|
||||
## 对外接口(供其他模块调用)
|
||||
```java
|
||||
// 接口签名 + 说明
|
||||
```
|
||||
|
||||
## 依赖的其他模块
|
||||
- 依赖 xxx 模块的 xxx 功能
|
||||
|
||||
## 已知问题 / 注意事项
|
||||
- 注意点1
|
||||
31
claude/modules/agency.md
Normal file
31
claude/modules/agency.md
Normal file
@ -0,0 +1,31 @@
|
||||
# 工会/金币代理模块 / agency
|
||||
|
||||
## 功能概述
|
||||
工会管理体系,包含工会创建/管理、主播归属、收益分成结算,以及金币代理商管理。
|
||||
|
||||
## 核心实体
|
||||
| 实体 | 表/集合 | 说明 |
|
||||
|------|--------|------|
|
||||
| Agency | t_agency | 工会信息 |
|
||||
| AgencyAnchor | t_agency_anchor | 工会-主播关联 |
|
||||
| CoinAgent | t_coin_agent | 金币代理商 |
|
||||
| AgencyIncome | mongo: agency_income | 工会收益流水 |
|
||||
|
||||
## 主要功能点
|
||||
- [ ] 工会创建/编辑/解散
|
||||
- [ ] 主播加入/退出工会
|
||||
- [ ] 工会收益结算(礼物分成)
|
||||
- [ ] 金币代理商管理
|
||||
- [ ] 代理商充值佣金计算
|
||||
|
||||
## 关键业务逻辑
|
||||
- 收益分成比例:平台 / 主播 / 工会,比例可按工会单独配置
|
||||
- 主播同一时间只能归属一个工会
|
||||
- 代理商有充值额度限制,超额需申请
|
||||
|
||||
## 依赖的其他模块
|
||||
- gift 模块:礼物收益来源
|
||||
- bd 模块:BD 管辖工会范围
|
||||
|
||||
## 注意事项
|
||||
- 结算周期为月结,月初定时任务触发上月结算
|
||||
29
claude/modules/user.md
Normal file
29
claude/modules/user.md
Normal file
@ -0,0 +1,29 @@
|
||||
# 用户模块 / user
|
||||
|
||||
## 功能概述
|
||||
用户基础信息管理,包含注册、登录、主播认证、用户画像。
|
||||
|
||||
## 核心实体
|
||||
| 实体 | 表/集合 | 说明 |
|
||||
|------|--------|------|
|
||||
| User | t_user | 用户基础信息 |
|
||||
| AnchorInfo | t_anchor_info | 主播扩展信息 |
|
||||
| UserFollow | t_user_follow | 关注关系 |
|
||||
|
||||
## 用户角色
|
||||
| 角色 | 说明 |
|
||||
|------|------|
|
||||
| 普通用户 | 观看直播、送礼 |
|
||||
| 主播 | 开播、收礼 |
|
||||
| 工会长 | 管理工会 |
|
||||
| 代理商 | 金币代理充值 |
|
||||
|
||||
## 主要功能点
|
||||
- [ ] 用户注册/登录(手机号/第三方)
|
||||
- [ ] 用户信息编辑
|
||||
- [ ] 主播申请与认证
|
||||
- [ ] 关注/粉丝关系
|
||||
|
||||
## 注意事项
|
||||
- 用户 Token 使用 JWT,存 Redis 做黑名单
|
||||
- 用户状态变更(封号/解封)需清除相关缓存
|
||||
47
claude/tasks/_TEMPLATE.md
Normal file
47
claude/tasks/_TEMPLATE.md
Normal file
@ -0,0 +1,47 @@
|
||||
# 任务文件模板
|
||||
|
||||
> 复制此文件到 tasks/current/,命名格式:{YYYYMMDD}-{任务简称}.md
|
||||
> 任务完成后移动到 tasks/done/
|
||||
|
||||
---
|
||||
|
||||
## 任务名称
|
||||
{任务名称}
|
||||
|
||||
## 任务类型
|
||||
> 勾选对应类型
|
||||
|
||||
- [ ] 重构/加字段/小改动
|
||||
- [ ] 原有功能扩展
|
||||
- [ ] 新功能/新模块
|
||||
- [ ] 性能/代码优化
|
||||
- [ ] Bug 修复
|
||||
- [ ] 数据修复/脚本
|
||||
- [ ] 跨模块联动
|
||||
- [ ] 前后端联调
|
||||
- [ ] 基础设施/运维
|
||||
|
||||
## 涉及模块
|
||||
> 列出本次任务涉及的模块,并上传对应 modules/*.md
|
||||
|
||||
- [ ] {module1}
|
||||
- [ ] {module2}
|
||||
|
||||
## 需求描述
|
||||
> 简洁描述要做什么,背景是什么
|
||||
|
||||
## 关键约束
|
||||
> 需要特别注意的边界条件、兼容性要求、性能要求等
|
||||
|
||||
## 涉及的表/集合
|
||||
> 列出会读写的表或集合
|
||||
|
||||
## 预期产出
|
||||
> 接口 / 代码文件 / SQL脚本 / 其他
|
||||
|
||||
## 完成记录
|
||||
> 任务完成后填写,方便归档复盘
|
||||
|
||||
- 完成时间:
|
||||
- 改动文件:
|
||||
- 备注:
|
||||
Loading…
x
Reference in New Issue
Block a user