docs: 重构文档结构和组织

- 重新组织docs目录结构,按功能模块分类
- 新增deployment和development目录
- 更新API文档结构
- 添加客户端README文档
- 移除过时的文档文件
This commit is contained in:
moyin
2025-12-24 18:04:14 +08:00
parent 032c97a1fc
commit 85d488a508
20 changed files with 2416 additions and 1763 deletions

View File

@@ -0,0 +1,527 @@
# 命名规范
本文档定义了项目中所有代码的命名规范,确保代码风格统一,提高可读性和可维护性。
## 目录
- [文件和文件夹命名](#文件和文件夹命名)
- [变量和函数命名](#变量和函数命名)
- [类和构造函数命名](#类和构造函数命名)
- [常量命名](#常量命名)
- [接口路由命名](#接口路由命名)
- [TypeScript 特定规范](#typescript-特定规范)
- [命名示例](#命名示例)
## 文件和文件夹命名
**规则使用下划线分隔snake_case**
### 文件命名
```
✅ 正确示例:
- order_controller.ts
- user_service.ts
- game_gateway.ts
- player_entity.ts
- create_room_dto.ts
- database_config.ts
❌ 错误示例:
- OrderController.ts
- userService.ts
- game-gateway.ts
- playerEntity.ts
```
### 文件夹命名
```
✅ 正确示例:
- src/api/
- src/service/
- src/model/dto/
- src/utils/
- src/config/
- test/unit_test/
- test/integration_test/
❌ 错误示例:
- src/API/
- src/Service/
- src/model-dto/
- src/Utils/
```
### 特殊说明
- 所有文件和文件夹名使用小写字母
- 多个单词之间使用下划线 `_` 连接
- 避免使用缩写,除非是广泛认可的缩写(如 dto、api
## 变量和函数命名
**规则使用小驼峰命名camelCase**
### 变量命名
```typescript
const userName = 'Alice';
let playerScore = 100;
const roomId = '12345';
const isGameStarted = false;
const maxPlayerCount = 4;
const UserName = 'Alice';
const player_score = 100;
const RoomId = '12345';
const is_game_started = false;
```
### 函数命名
```typescript
function getUserInfo() { }
async function queryUserInfo() { }
function calculateDamage() { }
function isPlayerAlive() { }
function handlePlayerMove() { }
function GetUserInfo() { }
function query_user_info() { }
function CalculateDamage() { }
function IsPlayerAlive() { }
```
### 命名建议
- 使用动词开头描述函数功能:
- `get` - 获取数据(如 `getUserById`
- `set` - 设置数据(如 `setPlayerPosition`
- `create` - 创建实体(如 `createRoom`
- `update` - 更新数据(如 `updatePlayerScore`
- `delete` - 删除数据(如 `deleteRoom`
- `is/has` - 布尔判断(如 `isGameOver``hasPermission`
- `handle` - 事件处理(如 `handlePlayerAttack`
- `calculate` - 计算逻辑(如 `calculateDamage`
- `validate` - 验证逻辑(如 `validateInput`
- 布尔变量使用 `is``has``can` 等前缀:
```typescript
const isActive = true;
const hasPermission = false;
const canMove = true;
```
## 类和构造函数命名
**规则使用大驼峰命名PascalCase**
### 类命名
```typescript
✅ 正确示例:
class UserModel { }
class OrderService { }
class GameController { }
class PlayerEntity { }
class RoomGateway { }
class DatabaseConnection { }
❌ 错误示例:
class userModel { }
class order_service { }
class gameController { }
class player_entity { }
```
### 接口命名
```typescript
✅ 正确示例:
interface User { }
interface GameConfig { }
interface PlayerData { }
interface RoomOptions { }
// 或使用 I 前缀(可选)
interface IUser { }
interface IGameConfig { }
❌ 错误示例:
interface user { }
interface game_config { }
interface playerData { }
```
### DTO 命名
```typescript
✅ 正确示例:
class CreateUserDto { }
class UpdatePlayerDto { }
class JoinRoomDto { }
class GameStateDto { }
❌ 错误示例:
class createUserDto { }
class update_player_dto { }
class joinRoomDTO { }
```
### 装饰器命名
```typescript
✅ 正确示例:
@Controller('users')
@Injectable()
@Module()
@Get()
// 自定义装饰器
function CustomDecorator() { }
```
## 常量命名
**规则:全大写 + 下划线分隔SCREAMING_SNAKE_CASE**
```typescript
✅ 正确示例:
const PORT = 3000;
const DB_HOST = 'localhost';
const MAX_PLAYERS = 10;
const API_VERSION = 'v1';
const DEFAULT_TIMEOUT = 5000;
const GAME_STATUS_WAITING = 'waiting';
const GAME_STATUS_PLAYING = 'playing';
❌ 错误示例:
const port = 3000;
const dbHost = 'localhost';
const maxPlayers = 10;
const ApiVersion = 'v1';
const default_timeout = 5000;
```
### 枚举命名
```typescript
✅ 正确示例:
enum GameStatus {
WAITING = 'waiting',
PLAYING = 'playing',
FINISHED = 'finished',
}
enum PlayerRole {
ADMIN = 'admin',
PLAYER = 'player',
SPECTATOR = 'spectator',
}
❌ 错误示例:
enum gameStatus {
waiting = 'waiting',
playing = 'playing',
}
enum PlayerRole {
admin = 'admin',
player = 'player',
}
```
## 接口路由命名
**规则:全小写 + 短横线分隔kebab-case**
```typescript
✅ 正确示例:
@Get('user/get-info')
@Post('order/create-order')
@Put('player/update-position')
@Delete('room/delete-room')
@Get('game/get-state')
@Post('room/join-room')
❌ 错误示例:
@Get('user/getInfo')
@Post('order/createOrder')
@Put('player/update_position')
@Delete('room/DeleteRoom')
@Get('game/GetState')
```
### 路由结构建议
```typescript
// 资源型路由
@Controller('api/players')
export class PlayerController {
@Get() // GET /api/players
@Get(':id') // GET /api/players/:id
@Post() // POST /api/players
@Put(':id') // PUT /api/players/:id
@Delete(':id') // DELETE /api/players/:id
}
// 动作型路由
@Controller('api/game')
export class GameController {
@Post('start-game') // POST /api/game/start-game
@Post('end-game') // POST /api/game/end-game
@Get('get-state') // GET /api/game/get-state
}
// 嵌套资源路由
@Controller('api/rooms')
export class RoomController {
@Post(':id/join') // POST /api/rooms/:id/join
@Post(':id/leave') // POST /api/rooms/:id/leave
@Get(':id/players') // GET /api/rooms/:id/players
}
```
## TypeScript 特定规范
### 类型别名
```typescript
✅ 正确示例:
type UserId = string;
type PlayerPosition = { x: number; y: number };
type GameCallback = (state: GameState) => void;
❌ 错误示例:
type userId = string;
type player_position = { x: number; y: number };
```
### 泛型参数
```typescript
✅ 正确示例:
function findById<T>(id: string): T { }
class Repository<T, K> { }
interface Response<T> { }
// 使用有意义的名称
function mapArray<TInput, TOutput>(arr: TInput[]): TOutput[] { }
❌ 错误示例:
function findById<t>(id: string): t { }
class Repository<type, key> { }
```
### 装饰器参数
```typescript
✅ 正确示例:
@Column({ name: 'user_name' })
@IsString({ message: 'Name must be a string' })
@ApiProperty({ description: 'User ID' })
❌ 错误示例:
@Column({ name: 'UserName' })
@IsString({ message: 'name_must_be_string' })
```
## 命名示例
### 完整的模块示例
```typescript
// 文件src/api/player_controller.ts
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { PlayerService } from '../service/player_service';
import { CreatePlayerDto } from '../model/dto/create_player_dto';
const MAX_PLAYERS = 100;
@Controller('api/players')
export class PlayerController {
constructor(private readonly playerService: PlayerService) {}
@Get()
async getAllPlayers() {
return this.playerService.findAll();
}
@Get(':id')
async getPlayerById(@Param('id') playerId: string) {
return this.playerService.findById(playerId);
}
@Post()
async createPlayer(@Body() createPlayerDto: CreatePlayerDto) {
return this.playerService.create(createPlayerDto);
}
@Post(':id/update-position')
async updatePlayerPosition(
@Param('id') playerId: string,
@Body() body: { x: number; y: number }
) {
const { x, y } = body;
return this.playerService.updatePosition(playerId, x, y);
}
}
```
```typescript
// 文件src/service/player_service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { Player } from '../model/player_entity';
import { CreatePlayerDto } from '../model/dto/create_player_dto';
const DEFAULT_HEALTH = 100;
const DEFAULT_SPEED = 5;
@Injectable()
export class PlayerService {
private players: Map<string, Player> = new Map();
findAll(): Player[] {
return Array.from(this.players.values());
}
findById(playerId: string): Player {
const player = this.players.get(playerId);
if (!player) {
throw new NotFoundException(`Player with ID ${playerId} not found`);
}
return player;
}
create(createPlayerDto: CreatePlayerDto): Player {
const newPlayer: Player = {
id: this.generatePlayerId(),
name: createPlayerDto.name,
health: DEFAULT_HEALTH,
speed: DEFAULT_SPEED,
position: { x: 0, y: 0 },
isAlive: true,
createdAt: new Date(),
};
this.players.set(newPlayer.id, newPlayer);
return newPlayer;
}
updatePosition(playerId: string, x: number, y: number): Player {
const player = this.findById(playerId);
player.position = { x, y };
return player;
}
private generatePlayerId(): string {
return `player_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private calculateDamage(attackPower: number, defense: number): number {
return Math.max(0, attackPower - defense);
}
isPlayerAlive(playerId: string): boolean {
const player = this.findById(playerId);
return player.isAlive && player.health > 0;
}
}
```
```typescript
// 文件src/model/player_entity.ts
export interface Player {
id: string;
name: string;
health: number;
speed: number;
position: Position;
isAlive: boolean;
createdAt: Date;
}
export interface Position {
x: number;
y: number;
}
export enum PlayerStatus {
IDLE = 'idle',
MOVING = 'moving',
ATTACKING = 'attacking',
DEAD = 'dead',
}
```
```typescript
// 文件src/model/dto/create_player_dto.ts
import { IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator';
export class CreatePlayerDto {
@IsString()
@IsNotEmpty()
@MinLength(3)
@MaxLength(20)
name: string;
}
```
## 检查清单
在提交代码前,请确保:
- [ ] 所有文件和文件夹使用下划线分隔命名
- [ ] 所有变量和函数使用小驼峰命名
- [ ] 所有类、接口、DTO 使用大驼峰命名
- [ ] 所有常量和枚举值使用全大写 + 下划线命名
- [ ] 所有路由使用全小写 + 短横线命名
- [ ] 函数名清晰表达其功能
- [ ] 布尔变量使用 is/has/can 前缀
- [ ] 避免使用无意义的缩写
## 工具配置
### ESLint 配置建议
```json
{
"rules": {
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "variable",
"format": ["camelCase", "UPPER_CASE"]
},
{
"selector": "function",
"format": ["camelCase"]
},
{
"selector": "class",
"format": ["PascalCase"]
},
{
"selector": "interface",
"format": ["PascalCase"]
}
]
}
}
```
## 总结
遵循统一的命名规范能够:
- 提高代码可读性
- 减少团队沟通成本
- 降低代码维护难度
- 避免命名冲突
- 提升项目专业度
记住:**好的命名是自解释的,不需要额外的注释。**