学业邑规划 - 开发规范
本文档定义了 MiAssessment 项目的开发规范和编码标准,所有开发工作必须遵循这些规范。
项目概述
学业邑规划是一个基于多元智能理论的学业规划测评系统,包含微信小程序和后台管理系统。
相关文档
- 需求文档:
docs/需求文档.md
- 数据库设计:
docs/数据库设计文档.md
- 开发文档:
docs/开发文档.md
- 题库资料:
docs/题库和结论/
- UI 设计图:
docs/设计图/
- UI 切图:
docs/切图/
一、技术栈
| 层级 |
技术 |
| 后端框架 |
.NET 10 Web API (C#) |
| 数据库 |
SQL Server 2022 |
| ORM |
Entity Framework Core |
| 缓存 |
Redis |
| 接口风格 |
RPC 风格(仅 GET / POST 请求) |
| 小程序前端 |
UniApp + Vue 3 + TypeScript |
| 后台管理前端 |
Vue 3 + TypeScript + Vite |
二、项目结构
整体结构
mi-assessment/
├── docs/ # 文档资料
│ ├── 需求文档.md
│ ├── 数据库设计文档.md
│ ├── 开发文档.md
│ ├── 开发规范/ # 详细编码规范
│ ├── 设计图/ # UI 设计图
│ ├── 切图/ # UI 切图资源
│ └── 题库和结论/ # 测评题库与报告模板
├── server/MiAssessment/ # 后端服务
└── uniapp/ # 小程序前端
后端项目结构
server/MiAssessment/src/
├── MiAssessment.Api/ # 小程序 API 接口
├── MiAssessment.Admin/ # 后台管理系统基础模块
│ └── admin-web/ # 后台管理前端 (Vue 3)
├── MiAssessment.Admin.Business/ # 后台业务模块(主要开发区域)
├── MiAssessment.Core/ # 核心业务逻辑
├── MiAssessment.Infrastructure/ # 基础设施
└── MiAssessment.Model/ # 数据模型
Admin.Business 项目结构
MiAssessment.Admin.Business/
├── Controllers/ # 控制器(API 入口)
├── Services/ # 业务服务
│ └── Interfaces/ # 服务接口
├── Models/ # 请求/响应模型(DTO)
│ ├── Common/ # 通用模型
│ └── {Module}/ # 各模块模型
├── Entities/ # 数据库实体类
├── Data/ # 数据库上下文
└── Attributes/ # 自定义特性
三、命名规范
3.1 数据库命名
| 类型 |
规范 |
示例 |
| 表名 |
snake_case(小写下划线) |
users, assessment_records |
| 字段名 |
PascalCase |
UserId, CreateTime |
| 主键 |
Id (bigint 自增) |
Id |
| 外键 |
{表名}Id |
UserId, OrderId |
| 时间字段 |
CreateTime, UpdateTime |
- |
| 状态字段 |
Status |
- |
| 软删除 |
IsDeleted (bit) |
- |
3.2 C# 代码命名
| 类型 |
规范 |
示例 |
| 命名空间 |
PascalCase |
MiAssessment.Admin.Business.Services |
| 类名 |
PascalCase |
UserService, OrderController |
| 接口 |
I + PascalCase |
IUserService, IOrderService |
| 方法 |
PascalCase + Async 后缀 |
GetUserListAsync, CreateOrderAsync |
| 属性 |
PascalCase |
UserId, CreateTime |
| 私有字段 |
_camelCase |
_userService, _dbContext |
| 参数 |
camelCase |
userId, request |
| 常量 |
PascalCase |
MaxPageSize, DefaultStatus |
3.3 文件命名
| 类型 |
规范 |
示例 |
| 实体类 |
单数形式 |
User.cs, Order.cs |
| 服务接口 |
I + 服务名 |
IUserService.cs |
| 服务实现 |
服务名 |
UserService.cs |
| 控制器 |
模块名 + Controller |
UserController.cs |
| DTO 模型 |
功能 + Request/Dto |
CreateUserRequest.cs, UserDto.cs |
3.4 前端命名 (Vue/TypeScript)
| 类型 |
规范 |
示例 |
| 组件文件 |
PascalCase |
UserList.vue, OrderDetail.vue |
| 组合式函数 |
use + camelCase |
useUserList.ts, useAuth.ts |
| 工具函数 |
camelCase |
formatDate.ts, request.ts |
| 类型定义 |
PascalCase |
UserInfo, OrderStatus |
| 变量/函数 |
camelCase |
userList, handleSubmit |
| 常量 |
UPPER_SNAKE_CASE |
API_BASE_URL, MAX_PAGE_SIZE |
| CSS 类名 |
kebab-case |
user-list, order-card |
四、代码规范
4.1 实体类规范
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MiAssessment.Admin.Business.Entities;
/// <summary>
/// 用户表
/// </summary>
[Table("users")]
public class User
{
/// <summary>
/// 主键ID
/// </summary>
[Key]
public long Id { get; set; }
/// <summary>
/// 用户UID
/// </summary>
[Required]
[MaxLength(6)]
public string Uid { get; set; } = null!;
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
public DateTime UpdateTime { get; set; }
/// <summary>
/// 软删除标记
/// </summary>
public bool IsDeleted { get; set; }
}
要点:
- 使用
[Table("表名")] 指定数据库表名
- 使用
[Key] 标记主键
- 使用
[Required] 标记必填字段
- 使用
[MaxLength(n)] 限制字符串长度
- 所有属性必须有 XML 注释
- 字符串属性使用
= null! 初始化
4.2 服务接口规范
namespace MiAssessment.Admin.Business.Services.Interfaces;
/// <summary>
/// 用户服务接口
/// </summary>
public interface IUserService
{
/// <summary>
/// 获取用户列表
/// </summary>
Task<PagedResult<UserDto>> GetUserListAsync(UserQueryRequest request);
/// <summary>
/// 获取用户详情
/// </summary>
Task<UserDetailDto?> GetUserDetailAsync(long id);
/// <summary>
/// 更新用户状态
/// </summary>
Task<bool> UpdateUserStatusAsync(long id, int status);
}
4.3 服务实现规范
namespace MiAssessment.Admin.Business.Services;
/// <summary>
/// 用户服务实现
/// </summary>
public class UserService : IUserService
{
private readonly AdminBusinessDbContext _dbContext;
private readonly ILogger<UserService> _logger;
public UserService(
AdminBusinessDbContext dbContext,
ILogger<UserService> logger)
{
_dbContext = dbContext;
_logger = logger;
}
/// <inheritdoc />
public async Task<PagedResult<UserDto>> GetUserListAsync(UserQueryRequest request)
{
var query = _dbContext.Users
.Where(u => !u.IsDeleted);
// 条件筛选
if (!string.IsNullOrEmpty(request.Phone))
{
query = query.Where(u => u.Phone.Contains(request.Phone));
}
// 获取总数
var total = await query.CountAsync();
// 分页查询
var items = await query
.OrderByDescending(u => u.CreateTime)
.Skip(request.Skip)
.Take(request.PageSize)
.Select(u => new UserDto
{
Id = u.Id,
Uid = u.Uid,
// ...
})
.ToListAsync();
return new PagedResult<UserDto>(items, total, request.Page, request.PageSize);
}
}
4.4 控制器规范
namespace MiAssessment.Admin.Business.Controllers;
/// <summary>
/// 用户管理控制器
/// </summary>
[Route("api/admin/user")]
public class UserController : BusinessControllerBase
{
private readonly IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService;
}
/// <summary>
/// 获取用户列表
/// </summary>
[HttpGet("getList")]
public async Task<IActionResult> GetList([FromQuery] UserQueryRequest request)
{
var result = await _userService.GetUserListAsync(request);
return Ok(result);
}
/// <summary>
/// 更新用户状态
/// </summary>
[HttpPost("updateStatus")]
public async Task<IActionResult> UpdateStatus([FromBody] UpdateStatusRequest request)
{
var success = await _userService.UpdateUserStatusAsync(request.Id, request.Status);
return success ? Ok() : Error(ErrorCodes.UserNotFound, "用户不存在");
}
}
五、API 接口规范
5.1 接口风格
- 仅使用 GET 和 POST 请求
- GET:查询操作,参数通过 Query String 传递
- POST:新增、修改、删除操作,参数通过 Request Body (JSON) 传递
5.2 路由规范
小程序 API: /api/{module}/{action}
后台管理 API: /api/admin/{module}/{action}
| 操作 |
方法 |
路由示例 |
| 获取列表 |
GET |
/api/admin/user/getList |
| 获取详情 |
GET |
/api/admin/user/getDetail?id=1 |
| 创建 |
POST |
/api/admin/user/create |
| 更新 |
POST |
/api/admin/user/update |
| 删除 |
POST |
/api/admin/user/delete |
| 更新状态 |
POST |
/api/admin/user/updateStatus |
| 更新排序 |
POST |
/api/admin/user/updateSort |
5.3 响应格式
{
"code": 0,
"message": "success",
"data": {}
}
code: 0 表示成功,非 0 表示错误
message: 提示信息
data: 业务数据
5.4 分页响应
{
"code": 0,
"message": "success",
"data": {
"items": [],
"total": 100,
"page": 1,
"pageSize": 20,
"totalPages": 5
}
}
六、错误码规范
| 范围 |
说明 |
| 0 |
成功 |
| 1000-1999 |
通用错误 |
| 2000-2999 |
业务错误 |
| 3000-3099 |
配置模块错误 |
| 3100-3199 |
内容模块错误 |
| 3200-3299 |
测评模块错误 |
| 3300-3399 |
用户模块错误 |
| 3400-3499 |
订单模块错误 |
| 3500-3599 |
规划师模块错误 |
| 3600-3699 |
分销模块错误 |
| 5000-5999 |
系统错误 |
七、注释规范
7.1 XML 注释 (C#)
所有公开的类、方法、属性必须有 XML 注释:
/// <summary>
/// 获取用户列表
/// </summary>
/// <param name="request">查询参数</param>
/// <returns>分页用户列表</returns>
public async Task<PagedResult<UserDto>> GetUserListAsync(UserQueryRequest request)
7.2 JSDoc 注释 (TypeScript)
/**
* 获取用户列表
* @param params 查询参数
* @returns 分页用户列表
*/
export async function getUserList(params: UserQueryParams): Promise<PagedResult<UserDto>> {
// ...
}
7.3 代码注释
- 使用中文注释
- 复杂逻辑需要添加说明注释
- 避免无意义的注释
八、数据库操作规范
8.1 查询规范
// 始终过滤软删除记录
var query = _dbContext.Users.Where(u => !u.IsDeleted);
// 使用 AsNoTracking 提高只读查询性能
var users = await _dbContext.Users
.AsNoTracking()
.Where(u => !u.IsDeleted)
.ToListAsync();
8.2 软删除
// 删除操作使用软删除
public async Task<bool> DeleteAsync(long id)
{
var entity = await _dbContext.Users.FindAsync(id);
if (entity == null) return false;
entity.IsDeleted = true;
entity.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
return true;
}
8.3 更新时间
// 更新操作自动设置 UpdateTime
entity.UpdateTime = DateTime.Now;
await _dbContext.SaveChangesAsync();
九、状态值定义
9.1 通用状态
9.2 订单状态
| 值 |
说明 |
| 1 |
待支付 |
| 2 |
已支付 |
| 3 |
已完成 |
| 4 |
退款中 |
| 5 |
已退款 |
| 6 |
已取消 |
9.3 用户等级
| 值 |
说明 |
| 1 |
普通用户 |
| 2 |
合伙人 |
| 3 |
渠道合伙人 |
十、测试规范
10.1 测试框架
- 单元测试:xUnit + Moq
- 属性测试:FsCheck
10.2 测试命名
[Fact]
public async Task GetUserListAsync_WithValidRequest_ReturnsPagedResult()
{
// Arrange
// Act
// Assert
}
10.3 属性测试注释
/// <summary>
/// Property: 分页查询返回的记录数不超过 PageSize
/// **Validates: Requirements 9.1**
/// </summary>
[Property]
public Property PaginationReturnsCorrectCount()
{
// ...
}
十一、Git 提交规范
11.1 提交信息格式
<type>(<scope>): <subject>
<body>
11.2 Type 类型
| Type |
说明 |
| feat |
新功能 |
| fix |
修复 bug |
| docs |
文档更新 |
| style |
代码格式 |
| refactor |
重构 |
| test |
测试 |
| chore |
构建/工具 |
11.3 示例
feat(user): 添加用户列表分页查询功能
- 实现 GetUserListAsync 方法
- 支持按手机号、昵称筛选
- 添加分页参数验证
十二、前端开发规范
12.1 Vue 组件规范
<script setup lang="ts">
/**
* 用户列表组件
*/
import { ref, onMounted } from 'vue'
import type { UserDto } from '@/types/user'
import { getUserList } from '@/api/user'
// Props
const props = defineProps<{
status?: number
}>()
// Emits
const emit = defineEmits<{
select: [user: UserDto]
}>()
// State
const loading = ref(false)
const userList = ref<UserDto[]>([])
// Methods
async function fetchData() {
loading.value = true
try {
const res = await getUserList({ status: props.status })
userList.value = res.data.items
} finally {
loading.value = false
}
}
// Lifecycle
onMounted(() => {
fetchData()
})
</script>
<template>
<div class="user-list">
<!-- 内容 -->
</div>
</template>
<style scoped>
.user-list {
/* 样式 */
}
</style>
12.2 API 请求规范
// api/user.ts
import request from '@/utils/request'
import type { UserDto, UserQueryParams, PagedResult } from '@/types'
/**
* 获取用户列表
*/
export function getUserList(params: UserQueryParams) {
return request.get<PagedResult<UserDto>>('/api/admin/user/getList', { params })
}
/**
* 更新用户状态
*/
export function updateUserStatus(id: number, status: number) {
return request.post('/api/admin/user/updateStatus', { id, status })
}
12.3 类型定义规范
// types/user.ts
/** 用户信息 */
export interface UserDto {
id: number
uid: string
nickname: string
phone: string
status: number
createTime: string
}
/** 用户查询参数 */
export interface UserQueryParams {
page?: number
pageSize?: number
phone?: string
status?: number
}