# CLAUDE.md

本文档为 Claude Code 在本项目中工作提供指导。

## 项目目录结构（重要）

| 目录 | 说明 |
|------|------|
| `java-backend/` | **后端项目目录** - Spring Boot 应用 |
| `java-frontend/` | **前端项目目录** - Vue 3 应用 |

**所有后续开发都基于这两个项目进行。**

## JDK 版本要求（重要）

**必须使用 JDK 17** 进行编译和运行。

如果系统环境变量配置的是 JDK 1.8，请在编译前设置 `JAVA_HOME`：

```bash
# Windows (Git Bash) - 根据实际安装路径调整
export JAVA_HOME="/f/Java/jdk-17"
export PATH="$JAVA_HOME/bin:$PATH"

# 编译项目
cd java-backend
mvn clean compile -DskipTests

# 启动项目
mvn spring-boot:run -Djava.home="/f/Java/jdk-17"
```

## 快速开始

```bash
# 前端 - 安装依赖并启动
cd java-frontend
pnpm install
pnpm dev

# 后端 - 安装依赖并启动
cd java-backend
mvn clean install
mvn spring-boot:run -Dspring.profiles.active=dev
```

## 技术栈

### 后端 (java-backend/)
- **框架**: Spring Boot 3.2 + Java 17
- **持久层**: MyBatis-Plus 3.5+
- **数据库**: MySQL 8.0 + Flyway 迁移
- **认证**: Spring Security + JWT
- **缓存**: Redis
- **对象映射**: MapStruct 1.5+

### 前端 (java-frontend/)
- **框架**: Vue 3 + TypeScript + Vite
- **UI 组件**: Ant Design Vue
- **状态管理**: Pinia
- **样式**: Tailwind CSS + SCSS

## 核心命令

### 后端开发 (java-backend/)
```bash
cd java-backend

# 编译
mvn clean compile -DskipTests

# 启动
mvn spring-boot:run -Dspring.profiles.active=dev

# 打包
mvn clean package -DskipTests

# 数据库迁移
mvn flyway:migrate
```

### 前端开发 (java-frontend/)
```bash
cd java-frontend

# 安装依赖
pnpm install

# 启动开发服务器
pnpm dev

# 构建
pnpm build
```

## 架构概览

### 目录结构
```
library-picturebook-activity/
├── java-backend/                   # Spring Boot 后端
│   ├── src/main/java/
│   │   └── com/lesingle/creation/
│   │       ├── common/             # 公共模块（常量、异常、工具）
│   │       ├── config/             # 配置类
│   │       ├── controller/         # REST 控制器
│   │       ├── dto/                # 数据传输对象
│   │       ├── entity/             # 实体类
│   │       ├── mapper/             # MyBatis Mapper
│   │       ├── service/            # 业务逻辑层
│   │       │   └── impl/           # Service 实现
│   │       └── vo/                 # 视图对象
│   └── src/main/resources/
│       ├── application*.yml        # 配置文件
│       ├── db/migration/           # Flyway 迁移脚本
│       └── mapper/                 # MyBatis XML
│
└── java-frontend/                  # Vue 3 前端
    ├── src/
    │   ├── api/                    # API 接口
    │   ├── views/                  # 页面组件
    │   ├── components/             # 公共组件
    │   ├── stores/                 # Pinia 状态
    │   ├── router/                 # 路由配置
    │   ├── composables/            # 组合式函数
    │   └── utils/                  # 工具函数
    └── public/
```

### 后端模块结构
每个功能模块包含：
- `XxxController.java` - REST 控制器
- `XxxService.java` / `XxxServiceImpl.java` - 业务逻辑
- `XxxMapper.java` - 数据访问层
- `Xxx.java` (entity/) - 实体类
- `XxxDTO.java` / `XxxVO.java` - 数据传输对象

## 关键开发规范

### 后端规范

1. **三层架构原则**：
   - Controller 层：DTO ↔ VO 转换
   - Service 层：使用 Entity，继承 `IService<T>`
   - Mapper 层：使用 Entity

2. **日志规范**：
   - **所有日志必须使用中文**
   - 使用 MDC 实现 TraceId 链路追踪
   - 开发/测试环境：DEBUG 级别
   - 生产环境：INFO/WARN 级别

3. **权限控制**：使用权限注解进行接口保护

4. **DTO 验证**：使用 Validation 注解

### 前端规范

1. **API 调用**：放在 `src/api/` 目录，按模块组织

2. **状态管理**：使用 Pinia，store 命名 `xxxStore`

3. **组件语法**：使用 `<script setup lang="ts">`

4. **路由**：使用 Vue Router 4

## 环境变量

### 后端 (java-backend/src/main/resources/)
- `application.yml` - 主配置
- `application-dev.yml` - 开发环境
- `application-test.yml` - 测试环境
- `application-prod.yml` - 生产环境

### 前端 (java-frontend/)
- `.env.development` - 开发环境
- `.env.test` - 测试环境
- `.env.production` - 生产环境

## Git 提交规范

格式：`类型：描述`

类型：
- `feat` - 新功能
- `fix` - 修复 bug
- `docs` - 文档更新
- `style` - 代码格式调整
- `refactor` - 代码重构
- `test` - 测试相关
- `chore` - 构建/工具相关

## 编码规范

- **语言**：所有注释、日志、提示信息使用中文
- **路径**：使用 Unix 风格路径 `/f/...` 而非 `F:\...`
- **代码**：尽量使用中文注释

## 数据库索引规范（重要）

**项目使用逻辑删除，唯一索引通过应用层控制，而非数据库唯一约束。**

### 背景问题

当表有逻辑删除字段（`deleted`）时，数据库唯一索引会导致：
1. 删除后无法重新添加相同数据
2. 错误信息不友好，直接返回数据库异常

### 解决方案

| 层级 | 职责 | 实现方式 |
|------|------|----------|
| **数据库层** | 普通索引 | `KEY idx_xxx (xxx)` 而非 `UNIQUE KEY uk_xxx (xxx)` |
| **应用层** | 重复校验 | Service 层查询 + 悲观锁 `FOR UPDATE` |
| **异常处理** | 兜底处理 | 全局异常处理器捕获 `DuplicateKeyException` |

### 需要应用层校验的字段

以下字段需要添加应用层重复校验（使用悲观锁）：

| 表 | 字段 | 说明 |
|-----|------|------|
| t_user | username, email, phone | 用户名、邮箱、手机号 |
| t_role | code | 角色编码 |
| t_permission | code | 权限编码 |
| t_dict | code + tenant_id | 字典编码 |
| t_tenant | code | 租户编码 |
| t_sys_config | config_key | 配置键 |

### 实现示例

**Mapper 层（悲观锁查询）**
```java
@Select("SELECT * FROM t_user WHERE username = #{username} AND tenant_id = #{tenantId} AND deleted = 0 FOR UPDATE")
User getUserByUsernameForUpdate(@Param("username") String username, @Param("tenantId") Long tenantId);
```

**Service 层（事务 + 校验）**
```java
@Transactional(rollbackFor = Exception.class)
public UserVO createUser(CreateUserDTO dto, Long tenantId, Long operatorId) {
    // 使用悲观锁检查用户名是否已存在（防止并发）
    User existingUser = userMapper.getUserByUsernameForUpdate(dto.getUsername(), tenantId);
    if (existingUser != null) {
        throw new BusinessException("用户名已存在");
    }
    // 插入用户
    ...
}
```

详细规范参考：`.claude/memory/java-backend.md`
