mi-assessment/.kiro/steering/development-standards.md
zpc 2c3940895f docs(db): 添加双数据库架构规范文档
- 在开发规范 steering 文件中新增第九节:双数据库架构规范
- 在开发文档中新增第八节:双数据库架构说明
- 明确 Admin 库与 Business 库的职责划分
- 定义配置数据分离规则和 DbContext 映射关系
- 规定跨库访问只读原则
2026-02-20 15:52:28 +08:00

18 KiB
Raw Blame History

学业邑规划 - 开发规范

本文档定义了 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
后台管理前端 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/JavaScript)

类型 规范 示例
组件文件 PascalCase UserList.vue, OrderDetail.vue
组合式函数 use + camelCase useUserList.js, useAuth.js
工具函数 camelCase formatDate.js, request.js
变量/函数 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": {
    "list": [],
    "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 注释 (JavaScript)

/**
 * 获取用户列表
 * @param {Object} params - 查询参数
 * @param {number} [params.page] - 页码
 * @param {number} [params.pageSize] - 每页数量
 * @param {string} [params.phone] - 手机号
 * @returns {Promise<Object>} 分页用户列表
 */
export async function getUserList(params) {
  // ...
}

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 数据库划分

本项目采用双数据库架构,严格区分后台管理数据与业务数据:

数据库 名称 职责
Admin 库 MiAssessment_Admin 后台管理系统自身运行所需数据RBAC、审计、运营配置
Business 库 MiAssessment_Business C端用户产生的或直接服务C端的业务数据

9.2 Admin 库表清单

表名 说明
admin_users 后台管理员
roles 角色
menus 菜单
departments 部门
permissions 权限
role_menus 角色-菜单关联
role_permissions 角色-权限关联
user_roles 用户-角色关联
operation_logs 操作日志
refresh_tokens 刷新令牌
admin_configs 运营配置(支付、小程序、上传、短信等)
dict_types 字典类型
dict_items 字典项

9.3 Business 库表清单

表名 说明
configs 业务配置(测评价格、佣金比例、提现限额、联系方式、协议等)
banners 轮播图
promotions 宣传图
assessment_types 测评类型
questions 题目
report_categories 报告分类
question_category_mappings 题目-分类映射
report_conclusions 报告结论
assessment_records 测评记录
assessment_answers 测评答案
assessment_results 测评结果
users C端用户
orders 订单
planners 规划师
planner_bookings 规划预约
invite_codes 邀请码
commissions 佣金记录
withdrawals 提现记录
business_pages 业务页面

9.4 配置数据分离规则

配置类型 所在库 表名 示例 Key
运营配置 Admin 库 admin_configs weixinpay_setting, miniprogram_setting, upload_setting, sms_setting, app_setting, base
业务配置 Business 库 configs assessment_price, commission_rate_direct, commission_rate_indirect, withdraw_min_amount, contact_wechat, user_agreement, privacy_policy

9.5 DbContext 映射

DbContext 所在项目 连接数据库 读写权限 用途
AdminDbContext MiAssessment.Admin Admin 库 读写 后台管理系统主上下文
AdminBusinessDbContext MiAssessment.Admin.Business Business 库 读写 后台管理业务数据
AdminConfigDbContext MiAssessment.Admin.Business Admin 库 只读 Business 项目读取运营配置
AdminConfigReadDbContext MiAssessment.Model Admin 库 只读 Core/API 项目读取运营配置
MiAssessmentDbContext MiAssessment.Model Business 库 读写 小程序 API 主上下文

9.6 跨库访问规则

  1. Business 项目对 Admin 库只读:通过 AdminConfigDbContext 读取运营配置,禁止写入
  2. Core/API 项目对 Admin 库只读:通过 AdminConfigReadDbContext 读取运营配置,禁止写入
  3. Admin 库的写操作只通过 Admin 项目进行:所有运营配置的增删改必须通过 AdminDbContext
  4. 连接字符串命名Admin 库使用 AdminConnectionBusiness 库使用 DefaultConnection

9.7 新增配置项规则

  • 如果配置是运营/系统级别(支付密钥、上传凭证、短信配置等)→ 存入 Admin 库 admin_configs
  • 如果配置是业务级别(价格、佣金比例、协议内容等)→ 存入 Business 库 configs
  • 新增 DbContext 时必须明确标注读写权限,跨库上下文必须标注 只读

十、状态值定义

9.1 通用状态

说明
0 禁用/下线
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>
/**
 * 用户列表组件
 */
import { ref, onMounted, defineProps, defineEmits } from 'vue'
import { getUserList } from '@/api/user'

// Props
const props = defineProps({
  status: {
    type: Number,
    default: null
  }
})

// Emits
const emit = defineEmits(['select'])

// State
const loading = ref(false)
const userList = ref([])

// Methods
async function fetchData() {
  loading.value = true
  try {
    const res = await getUserList({ status: props.status })
    userList.value = res.data.list
  } finally {
    loading.value = false
  }
}

// Lifecycle
onMounted(() => {
  fetchData()
})
</script>

<template>
  <view class="user-list">
    <!-- 内容 -->
  </view>
</template>

<style scoped lang="scss">
.user-list {
  /* 样式 */
}
</style>

12.2 API 请求规范

// api/user.js
import { get, post } from '@/api/request'

/**
 * 获取用户列表
 * @param {Object} params - 查询参数
 * @returns {Promise<Object>}
 */
export function getUserList(params) {
  return get('/user/getList', params)
}

/**
 * 更新用户状态
 * @param {number} id - 用户ID
 * @param {number} status - 状态
 * @returns {Promise<Object>}
 */
export function updateUserStatus(id, status) {
  return post('/user/updateStatus', { id, status })
}

12.3 常量定义规范

// constants/user.js

/** 用户等级 */
export const USER_LEVEL = {
  NORMAL: 1,      // 普通用户
  PARTNER: 2,     // 合伙人
  CHANNEL: 3      // 渠道合伙人
}

/** 订单状态 */
export const ORDER_STATUS = {
  PENDING: 1,     // 待支付
  PAID: 2,        // 已支付
  COMPLETED: 3,   // 已完成
  REFUNDING: 4,   // 退款中
  REFUNDED: 5,    // 已退款
  CANCELLED: 6    // 已取消
}