目录
- 代码规范
- Git规范
- API规范
- 数据库规范
- 前端规范
- 文档规范
- 包名:使用小写字母,不使用下划线,与目录名保持一致。
- 变量名:使用驼峰命名法,首字母小写。
- 常量名:使用驼峰命名法,首字母大写。
- 函数名:使用驼峰命名法,首字母小写,公开函数首字母大写。
- 结构体名:使用驼峰命名法,首字母大写。
- 接口名:使用驼峰命名法,首字母大写,通常以 -er 结尾。
// 包名
package user
// 变量名
var userName string
// 常量名
const MaxCount = 100
// 函数名
func getUserInfo() UserInfo {
// 函数体
}
// 公开函数名
func GetUserInfo() UserInfo {
// 函数体
}
// 结构体名
type UserInfo struct {
ID int64
Username string
}
// 接口名
type Reader interface {
Read(p []byte) (n int, err error)
}- 包注释:放在包声明之前,描述包的功能。
- 函数注释:放在函数声明之前,描述函数的功能、参数和返回值。
- 结构体注释:放在结构体声明之前,描述结构体的功能。
- 变量注释:放在变量声明之前,描述变量的用途。
// Package user 提供用户管理功能
package user
// GetUserInfo 获取用户信息
// 参数:
// - id: 用户ID
// 返回值:
// - UserInfo: 用户信息
// - error: 错误信息
func GetUserInfo(id int64) (UserInfo, error) {
// 函数体
}
// UserInfo 用户信息
type UserInfo struct {
ID int64 // 用户ID
Username string // 用户名
}- 使用 errors.New 或 fmt.Errorf 创建错误。
- 使用 errors.Is 或 errors.As 检查错误。
- 错误信息应该小写,不以标点符号结尾。
import (
"errors"
"fmt"
)
// 定义错误
var ErrUserNotFound = errors.New("user not found")
// 创建错误
func getUser(id int64) (UserInfo, error) {
if id <= 0 {
return UserInfo{}, fmt.Errorf("invalid user id: %d", id)
}
// 查询用户
user, err := queryUser(id)
if err != nil {
return UserInfo{}, fmt.Errorf("query user failed: %w", err)
}
if user.ID == 0 {
return UserInfo{}, ErrUserNotFound
}
return user, nil
}
// 检查错误
func handleGetUser(id int64) {
user, err := getUser(id)
if err != nil {
if errors.Is(err, ErrUserNotFound) {
fmt.Println("user not found")
} else {
fmt.Printf("get user failed: %v\n", err)
}
return
}
fmt.Printf("user: %+v\n", user)
}- 按标准库、第三方库、本地库的顺序导入。
- 每组导入之间用空行分隔。
- 使用别名避免导入冲突。
import (
"context"
"fmt"
"time"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
"github.com/spf13/viper"
"gin-fast/global"
"gin-fast/models"
"gin-fast/utils"
)- 结构体字段使用驼峰命名法,首字母大写。
- 结构体标签使用驼峰命名法,首字母小写。
- 结构体标签应该放在同一行,如果太长可以换行。
// User 用户模型
type User struct {
ID int64 `json:"id" gorm:"primaryKey;autoIncrement;comment:用户ID"`
Username string `json:"username" gorm:"type:varchar(50);uniqueIndex;not null;comment:用户名"`
Password string `json:"-" gorm:"type:varchar(100);not null;comment:密码"`
Nickname string `json:"nickname" gorm:"type:varchar(50);comment:昵称"`
Email string `json:"email" gorm:"type:varchar(100);uniqueIndex;comment:邮箱"`
Phone string `json:"phone" gorm:"type:varchar(20);uniqueIndex;comment:手机号"`
Avatar string `json:"avatar" gorm:"type:varchar(255);comment:头像"`
Status int `json:"status" gorm:"type:tinyint;default:1;comment:状态:1-启用,2-禁用"`
CreatedAt time.Time `json:"createdAt" gorm:"comment:创建时间"`
UpdatedAt time.Time `json:"updatedAt" gorm:"comment:更新时间"`
}- 函数参数使用驼峰命名法,首字母小写。
- 函数返回值使用驼峰命名法,首字母小写。
- 函数参数和返回值应该有明确的类型。
- 函数应该有明确的单一职责。
// GetUserByID 根据ID获取用户
func GetUserByID(ctx context.Context, id int64) (*User, error) {
if id <= 0 {
return nil, errors.New("invalid user id")
}
var user User
if err := global.DB.WithContext(ctx).First(&user, id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("user not found")
}
return nil, fmt.Errorf("query user failed: %w", err)
}
return &user, nil
}- 接口名使用驼峰命名法,首字母大写,通常以 -er 结尾。
- 接口方法使用驼峰命名法,首字母小写。
- 接口应该有明确的单一职责。
// UserService 用户服务接口
type UserService interface {
// GetUserByID 根据ID获取用户
GetUserByID(ctx context.Context, id int64) (*User, error)
// GetUserByUsername 根据用户名获取用户
GetUserByUsername(ctx context.Context, username string) (*User, error)
// CreateUser 创建用户
CreateUser(ctx context.Context, user *User) error
// UpdateUser 更新用户
UpdateUser(ctx context.Context, user *User) error
// DeleteUser 删除用户
DeleteUser(ctx context.Context, id int64) error
}- 测试文件以
_test.go结尾。 - 测试函数以
Test开头,接受*testing.T参数。 - 测试用例应该覆盖正常情况和异常情况。
- 使用表驱动测试。
package user
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetUserByID(t *testing.T) {
tests := []struct {
name string
id int64
want *User
wantErr bool
}{
{
name: "valid id",
id: 1,
want: &User{ID: 1, Username: "admin"},
wantErr: false,
},
{
name: "invalid id",
id: 0,
want: nil,
wantErr: true,
},
{
name: "user not found",
id: 999,
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := GetUserByID(context.Background(), tt.id)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, got)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.want, got)
}
})
}
}插件统一放在 plugins/ 目录下,每个插件应具有以下标准结构:
plugins/
└── {plugin_name}/
├── controllers/ # 插件控制器
├── models/ # 插件数据模型和参数验证
├── routes/ # 插件路由注册
└── {plugin_name}init.go # 插件初始化文件
在 plugins/ 目录下创建插件文件夹,例如 plugins/example/
在 plugins/{plugin_name}/models/ 目录下创建模型文件:
- 继承
models.BaseModel基础模型 - 实现标准的 CRUD 方法(Create, Update, Delete, GetByID等)
- 创建对应的参数验证模型(如 CreateRequest, UpdateRequest等)
示例:
// plugins/example/models/example.go
type Example struct {
models.BaseModel
Name string `gorm:"type:varchar(255);comment:名称" json:"name"`
Description string `gorm:"type:varchar(255);comment:描述" json:"description"`
CreatedBy uint `gorm:"type:int(11);comment:创建者ID" json:"createdBy"`
}
// 实现标准方法
func (m *Example) GetByID(id uint) error {
return app.DB().First(m, id).Error
}
func (m *Example) Create() error {
return app.DB().Create(m).Error
}在 plugins/{plugin_name}/controllers/ 目录下创建控制器文件:
- 继承
controllers.Common结构体以复用响应方法 - 实现标准的 RESTful API 方法(Create, Update, Delete, GetByID, List等)
- 使用参数验证模型进行输入验证
- 使用统一的错误处理和响应格式
示例:
// plugins/example/controllers/example.go
type ExampleController struct {
controllers.Common
}
func (ec *ExampleController) Create(c *gin.Context) {
var req models.CreateRequest
if err := req.Validate(c); err != nil {
ec.FailAndAbort(c, err.Error(), err)
}
// 业务逻辑处理
example := models.NewExample()
example.Name = req.Name
// ...
if err := example.Create(); err != nil {
ec.FailAndAbort(c, "创建示例失败", err)
}
ec.Success(c, gin.H{"id": example.ID})
}在 plugins/{plugin_name}/routes/routes.go 中注册插件路由:
- 使用统一的路由前缀
/api/plugins/{plugin_name} - 应用必要的中间件(如 JWT 认证、Casbin 权限验证)
- 注册控制器方法到对应路由
示例:
// plugins/example/routes/routes.go
func RegisterRoutes(engine *gin.Engine) {
example := engine.Group("/api/plugins/example")
example.Use(middleware.JWTAuthMiddleware())
example.Use(middleware.CasbinMiddleware())
{
example.POST("/add", exampleControllers.Create)
example.PUT("/edit", exampleControllers.Update)
// ...
}
}创建 plugins/{plugin_name}/{plugin_name}init.go 文件,在 init() 函数中注册插件路由:
- 使用
ginhelper.RegisterPluginRoutes注册路由 - 记录插件初始化日志
示例:
// plugins/example/exampleinit.go
func init() {
ginhelper.RegisterPluginRoutes(func(engine *gin.Engine) {
routes.RegisterRoutes(engine)
})
app.ZapLog.Info("示例插件初始化完成")
}在 plugins/{plugin_name}/models/ 中创建参数验证模型:
- 继承
models.Validator和models.BasePaging(分页查询时) - 实现
Validate方法进行参数验证 - 实现
Handle方法处理查询条件
示例:
// plugins/example/models/exampleparam.go
type CreateRequest struct {
models.Validator
Name string `json:"name" binding:"required"`
Description string `json:"description" binding:"required"`
}
func (r *CreateRequest) Validate(c *gin.Context) error {
return r.Validator.Check(c, r)
}- 插件目录名应使用小写字母和下划线命名
- 控制器、模型、路由文件名应与功能对应,使用小写字母和下划线
- 结构体和方法名遵循 Go 语言命名规范
- 插件控制器必须继承
controllers.Common结构体 - 插件模型应继承
models.BaseModel基础模型 - 使用统一的错误处理和响应格式
- 插件路由必须以
/api/plugins/{plugin_name}为前缀 - 必须应用 JWT 认证中间件确保安全性
- 根据需要应用 Casbin 权限验证中间件
- 使用
app.ZapLog记录插件相关日志 - 在关键操作和初始化时添加日志记录
- 使用
app.DB()获取数据库连接 - 遵循 GORM 的操作规范
- 注意处理数据库错误
- master:主分支,用于生产环境,始终保持稳定可运行状态。
- develop:开发分支,用于集成开发,始终保持最新开发状态。
- feature/:功能分支,用于开发新功能,从 develop 分支创建,完成后合并到 develop 分支。
- release/:发布分支,用于发布准备,从 develop 分支创建,完成后合并到 master 和 develop 分支。
- hotfix/:修复分支,用于紧急修复,从 master 分支创建,完成后合并到 master 和 develop 分支。
- 提交信息格式:
<type>(<scope>): <subject> - 提交信息应该简明扼要,不超过 50 个字符。
- 提交信息应该使用祈使语气,如 "fix bug" 而不是 "fixed bug"。
- 提交信息应该描述做了什么,而不是为什么做。
# 提交信息格式
<type>(<scope>): <subject>
# 提交信息示例
feat(auth): add login function
fix(user): fix user list pagination error
docs(readme): update installation guide
style(format): format code with gofmt
refactor(user): refactor user service
perf(api): optimize api response time
test(user): add user service tests
chore(deps): update dependencies- feat: 新功能
- fix: 修复bug
- docs: 文档更新
- style: 代码格式(不影响代码运行的变动)
- refactor: 重构(既不是新增功能,也不是修改bug的代码变动)
- perf: 性能优化
- test: 增加测试
- chore: 构建过程或辅助工具的变动
提交范围应该是一个名词,描述提交影响的模块或功能。
# 提交范围示例
feat(auth): add login function
fix(user): fix user list pagination error
docs(readme): update installation guide
style(format): format code with gofmt
refactor(user): refactor user service
perf(api): optimize api response time
test(user): add user service tests
chore(deps): update dependencies提交主体应该描述做了什么,使用祈使语气,不超过 50 个字符。
# 提交主体示例
feat(auth): add login function
fix(user): fix user list pagination error
docs(readme): update installation guide
style(format): format code with gofmt
refactor(user): refactor user service
perf(api): optimize api response time
test(user): add user service tests
chore(deps): update dependencies提交正文应该详细描述提交的内容,包括为什么做、怎么做的、有什么影响等。
# 提交正文示例
feat(auth): add login function
- Add login function with username and password
- Add JWT token generation and validation
- Add password encryption with bcrypt
- Add login rate limiting
- Add login logging提交脚注应该包含相关的引用、链接、问题编号等。
# 提交脚注示例
feat(auth): add login function
- Add login function with username and password
- Add JWT token generation and validation
- Add password encryption with bcrypt
- Add login rate limiting
- Add login logging
Closes #123- 使用小写字母,不使用下划线,使用连字符分隔单词。
- 使用名词复数形式表示资源集合。
- 使用 HTTP 方法表示操作类型。
# URL规范示例
GET /api/users # 获取用户列表
POST /api/users # 创建用户
GET /api/users/{id} # 获取用户详情
PUT /api/users/{id} # 更新用户
DELETE /api/users/{id} # 删除用户
GET /api/users/{id}/roles # 获取用户角色
POST /api/users/{id}/roles # 分配用户角色- 使用 JSON 格式传输数据。
- 使用 Content-Type: application/json 标识请求体格式。
- 使用 Accept: application/json 标识响应体格式。
# 请求规范示例
GET /api/users HTTP/1.1
Host: example.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{
"username": "test",
"password": "123456",
"nickname": "测试用户",
"email": "test@example.com",
"phone": "13800138000"
}- 使用 JSON 格式传输数据。
- 使用统一的响应格式。
// 响应格式示例
{
"code": 0,
"msg": "success",
"data": {
// 响应数据
}
}- 使用 HTTP 状态码表示请求结果。
- 使用自定义状态码表示业务结果。
# HTTP状态码示例
200 OK # 请求成功
201 Created # 资源创建成功
204 No Content # 资源删除成功
400 Bad Request # 请求参数错误
401 Unauthorized # 未授权
403 Forbidden # 禁止访问
404 Not Found # 资源不存在
422 Unprocessable Entity # 请求参数验证失败
500 Internal Server Error # 服务器内部错误
# 自定义状态码示例
0 # 成功
1001 # 参数错误
1002 # 用户不存在
1003 # 密码错误
1004 # 用户已存在
1005 # 验证码错误
1006 # 验证码过期
1007 # 令牌无效
1008 # 令牌过期
1009 # 权限不足
1010 # 系统错误- 使用 page 和 pageSize 参数表示分页。
- 使用 total 表示总记录数。
- 使用 list 表示数据列表。
// 分页响应示例
{
"code": 0,
"msg": "success",
"data": {
"list": [
{
"id": 1,
"username": "admin",
"nickname": "管理员",
"email": "admin@example.com",
"phone": "13800138000",
"status": 1,
"createdAt": "2023-01-01T00:00:00Z",
"updatedAt": "2023-01-01T00:00:00Z"
}
],
"total": 1,
"page": 1,
"pageSize": 10
}
}- 使用 code 和 msg 表示错误信息。
- 使用 data 表示错误详情。
// 错误响应示例
{
"code": 1002,
"msg": "用户不存在",
"data": null
}- 数据库名:使用小写字母,不使用下划线,使用连字符分隔单词。
- 表名:使用小写字母,不使用下划线,使用连字符分隔单词,使用名词复数形式。
- 字段名:使用小写字母,不使用下划线,使用连字符分隔单词。
- 索引名:使用小写字母,不使用下划线,使用连字符分隔单词,以
idx_或uniq_开头。
-- 数据库名
gin-fast
-- 表名
users
user-roles
sys-menus
sys-roles
-- 字段名
id
user-name
created-at
updated-at
-- 索引名
idx-user-name
uniq-user-name- 使用 id 作为主键,类型为 bigint,自增。
- 使用 created-at 和 updated-at 作为时间戳,类型为 datetime。
- 使用 deleted-at 作为软删除标记,类型为 datetime,允许为空。
- 使用 status 作为状态标记,类型为 tinyint,默认值为 1。
-- 用户表
CREATE TABLE users (
id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
user-name varchar(50) NOT NULL COMMENT '用户名',
password varchar(100) NOT NULL COMMENT '密码',
nick-name varchar(50) DEFAULT NULL COMMENT '昵称',
email varchar(100) DEFAULT NULL COMMENT '邮箱',
phone varchar(20) DEFAULT NULL COMMENT '手机号',
avatar varchar(255) DEFAULT NULL COMMENT '头像',
status tinyint(1) DEFAULT 1 COMMENT '状态:1-启用,2-禁用',
created-at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated-at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
deleted-at datetime DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (id),
UNIQUE KEY uniq-user-name (user-name),
UNIQUE KEY uniq-email (email),
UNIQUE KEY uniq-phone (phone),
KEY idx-status (status),
KEY idx-created-at (created-at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';- 主键使用聚簇索引。
- 外键使用普通索引。
- 唯一键使用唯一索引。
- 查询条件使用普通索引。
- 排序字段使用普通索引。
-- 主键索引
PRIMARY KEY (id)
-- 唯一索引
UNIQUE KEY uniq-user-name (user-name)
-- 普通索引
KEY idx-status (status)
KEY idx-created-at (created-at)- 表注释应该描述表的用途。
- 字段注释应该描述字段的用途和取值范围。
-- 表注释
CREATE TABLE users (
-- 字段定义
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
-- 字段注释
id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
user-name varchar(50) NOT NULL COMMENT '用户名',
status tinyint(1) DEFAULT 1 COMMENT '状态:1-启用,2-禁用',- 文件名:使用 kebab-case 命名法,如
user-list.vue。 - 组件名:使用 PascalCase 命名法,如
UserList。 - 变量名:使用 camelCase 命名法,如
userName。 - 常量名:使用 UPPER_SNAKE_CASE 命名法,如
MAX_COUNT。 - 函数名:使用 camelCase 命名法,如
getUserList。 - 类名:使用 PascalCase 命名法,如
UserService。 - CSS类名:使用 kebab-case 命名法,如
user-list。
// 文件名
user-list.vue
// 组件名
export default {
name: 'UserList'
}
// 变量名
const userName = 'admin'
// 常量名
const MAX_COUNT = 100
// 函数名
function getUserList() {
// 函数体
}
// 类名
class UserService {
// 类定义
}
// CSS类名
.user-list {
// 样式定义
}- 组件应该有明确的单一职责。
- 组件应该使用
<script setup>语法。 - 组件应该使用 TypeScript 类型。
- 组件应该使用 scoped 样式。
<template>
<div class="user-list">
<!-- 组件模板 -->
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import type { User } from '@/types/user'
// 组件逻辑
</script>
<style lang="scss" scoped>
.user-list {
// 组件样式
}
</style>- 使用 axios 发送 HTTP 请求。
- 使用 TypeScript 类型定义请求参数和响应数据。
- 使用统一的错误处理。
// API 定义
import request from '@/utils/request'
import type { User, UserListParams } from '@/types/user'
// 获取用户列表
export function getUserList(params: UserListParams) {
return request({
url: '/api/users',
method: 'get',
params
})
}
// 创建用户
export function createUser(data: Partial<User>) {
return request({
url: '/api/users',
method: 'post',
data
})
}
// 更新用户
export function updateUser(id: number, data: Partial<User>) {
return request({
url: `/api/users/${id}`,
method: 'put',
data
})
}
// 删除用户
export function deleteUser(id: number) {
return request({
url: `/api/users/${id}`,
method: 'delete'
})
}- 使用 Pinia 进行状态管理。
- 使用 TypeScript 类型定义状态。
- 使用统一的错误处理。
// 状态定义
import { defineStore } from 'pinia'
import type { User } from '@/types/user'
import { getUserList, createUser, updateUser, deleteUser } from '@/api/user'
interface UserState {
users: User[]
total: number
loading: boolean
}
export const useUserStore = defineStore('user', {
state: (): UserState => ({
users: [],
total: 0,
loading: false
}),
getters: {
userList: (state) => state.users,
userTotal: (state) => state.total,
userLoading: (state) => state.loading
},
actions: {
// 获取用户列表
async getUserList(params: any) {
this.loading = true
try {
const res = await getUserList(params)
this.users = res.data.list
this.total = res.data.total
} catch (error) {
console.error(error)
} finally {
this.loading = false
}
},
// 创建用户
async createUser(data: Partial<User>) {
try {
await createUser(data)
// 重新获取用户列表
await this.getUserList({})
} catch (error) {
console.error(error)
}
},
// 更新用户
async updateUser(id: number, data: Partial<User>) {
try {
await updateUser(id, data)
// 重新获取用户列表
await this.getUserList({})
} catch (error) {
console.error(error)
}
},
// 删除用户
async deleteUser(id: number) {
try {
await deleteUser(id)
// 重新获取用户列表
await this.getUserList({})
} catch (error) {
console.error(error)
}
}
}
})- 使用 Vue Router 进行路由管理。
- 使用 TypeScript 类型定义路由。
- 使用路由守卫进行权限控制。
// 路由定义
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import type { RouteMeta } from '@/types/router'
const routes: Array<RouteRecordRaw> = [
{
path: '/login',
name: 'Login',
component: () => import('@/views/auth/login.vue'),
meta: {
title: '登录',
hidden: true
} as RouteMeta
},
{
path: '/',
name: 'Layout',
component: () => import('@/layout/index.vue'),
redirect: '/dashboard',
meta: {
title: '首页',
icon: 'dashboard'
} as RouteMeta,
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index.vue'),
meta: {
title: '仪表盘',
icon: 'dashboard',
affix: true
} as RouteMeta
},
{
path: 'user',
name: 'User',
component: () => import('@/views/user/index.vue'),
meta: {
title: '用户管理',
icon: 'user',
roles: ['admin']
} as RouteMeta
}
]
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router- 使用 SCSS 预处理器。
- 使用 BEM 命名规范。
- 使用变量定义颜色、字体等。
// 变量定义
$primary-color: #1890ff;
$success-color: #52c41a;
$warning-color: #faad14;
$error-color: #f5222d;
$text-color: rgba(0, 0, 0, 0.85);
$text-color-secondary: rgba(0, 0, 0, 0.45);
$border-color: #d9d9d9;
$background-color: #f0f2f5;
$font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
$font-size-base: 14px;
$line-height-base: 1.5;
// BEM 命名规范
.user-list {
// Block
display: flex;
flex-direction: column;
// Element
&__header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background-color: #fff;
border-bottom: 1px solid $border-color;
}
&__title {
margin: 0;
font-size: 16px;
font-weight: 500;
color: $text-color;
}
&__actions {
display: flex;
gap: 8px;
}
&__content {
flex: 1;
padding: 16px;
background-color: #fff;
}
// Modifier
&--loading {
opacity: 0.5;
pointer-events: none;
}
}- README.md:项目说明文档,包含项目概述、功能特性、技术栈、安装说明等。
- docs/:文档目录,包含详细的技术文档。
- introduction.md:系统介绍文档,包含项目概述、核心特性、技术栈、系统架构、功能模块、适用场景等。
- environment.md:环境搭建文档,包含环境要求、开发工具、环境配置、验证环境等。
- installation.md:系统安装文档,包含安装概述、后端安装、前端安装、数据库初始化、系统配置、启动系统、验证安装等。
- catalog.md:目录结构文档,包含项目结构、目录说明、文件说明、模块说明等。
- exploit.md:开发规范文档,包含代码规范、Git规范、API规范、数据库规范、前端规范、文档规范等。
- frontend-*.md:前端文档,包含前端介绍、前端环境、前端目录、前端指南等。
- deployment.md:部署指南文档,包含部署概述、环境准备、后端部署、前端部署、Nginx配置、Docker部署、常见问题等。
- faq.md:常见问题文档,包含开发环境问题、后端问题、前端问题、部署问题、数据库问题、权限问题、性能问题、其他问题等。
- 使用 Markdown 格式编写文档。
- 使用 TOC(目录)插件生成目录。
- 使用代码块展示代码示例。
- 使用表格展示数据。
- 使用列表展示步骤。
- 文档应该简明扼要,易于理解。
- 文档应该包含必要的示例和说明。
- 文档应该保持最新,与代码同步更新。
- 文档应该使用统一的格式和风格。
- 代码变更时,应该同步更新相关文档。
- 文档更新时,应该提交单独的提交记录。
- 文档更新时,应该包含更新说明。
# 文档更新提交示例
docs(readme): update installation guide
- Add Docker installation guide
- Update environment requirements
- Fix typos in installation steps通过以上规范,我们可以确保代码质量、提高开发效率、降低维护成本。在实际开发中,请严格遵守这些规范,确保项目的一致性和可维护性。