1
Development Guide
biss edited this page 2026-07-24 12:00:48 +08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

开发指南

本页说明本地开发、代码结构、前后端联调、验证和变更约定。首次启动请先完成快速开始

1. 技术栈与版本

领域 技术
运行时 .NET 10
Web ASP.NET Core Minimal API
前端 Vue 3.5、Vue Router 5、Vite 8
数据访问 Microsoft.Data.Sqlite、MySqlConnector
缓存与认证状态 StackExchange.Redis
Excel ClosedXML
HTML 清理 AngleSharp
二维码 QRCoder
测试 xUnit

Directory.Build.props 全局启用:

  • Nullable
  • Implicit Usings
  • 最新 C# 语言版本;
  • 最新分析级别;
  • 警告视为错误。

依赖版本集中在 Directory.Packages.props 管理。

2. 解决方案结构

Eis.slnx
├─ src/Eis.Domain
├─ src/Eis.Application
├─ src/Eis.Infrastructure
├─ src/Eis.Tools
├─ src/Eis.Web
│  ├─ ClientApp
│  └─ wwwroot
└─ tests/Eis.Infrastructure.Tests

职责:

  • Eis.Domain:领域值、跨层通用业务概念。
  • Eis.Application:服务接口和应用层契约,不依赖 Web 页面。
  • Eis.InfrastructureSQLite/MySQL、认证、缓存、Excel、PDF 数据、仓储和业务实现。
  • Eis.Tools:数据库初始化、重建和演示数据命令行工具。
  • Eis.Web:进程入口、依赖注入、HTTP 端点、健康检查和静态资源托管。
  • ClientAppVue 源码。
  • tests:基础设施和核心业务自动化测试。

详细依赖关系见系统架构

3. 日常开发启动

终端一,启动 ASP.NET Core

dotnet run --project .\src\Eis.Web\Eis.Web.csproj

终端二,启动 Vite

Set-Location .\src\Eis.Web\ClientApp
npm run dev

访问 http://127.0.0.1:5173。Vite 将 API、健康检查和旧的浏览器 PDF 模块代理到 4173

仅修改后端且已经有前端生产构建时,可只访问 http://127.0.0.1:4173

4. 前端开发

主要入口

路径 用途
src/main.js Vue 应用入口
src/router/index.js 公开、考生、管理和招生路由
src/stores/session.js 会话和用户上下文
src/lib/api.js API 请求与错误处理
src/lib/navigation.js 按角色和级别生成菜单
src/views 页面级视图
src/components 可复用业务组件
src/styles 全局和首页样式

路由约定

  • 公开://announcements/verify/:code/auth/...
  • 考生:/candidate/:page
  • 管理员:/admin/:page
  • 招生学校:/admission/:page

新增受保护页面时,应同时考虑:

  1. 路由的 meta.roles
  2. 菜单是否对正确管理级别显示;
  3. 会话过期后的重新登录路径;
  4. 服务端端点的角色和范围校验;
  5. History 模式下刷新是否能由宿主正确回退。

前端隐藏按钮不是权限控制。所有敏感操作必须由服务端再次拒绝越权请求。

API 调用

统一使用 src/lib/api.js,不要在组件中重复实现 Cookie、JSON 解析和错误状态处理。401 表示会话失效时,应引导重新登录,不应仅提示用户刷新页面。

构建产物

Set-Location .\src\Eis.Web\ClientApp
npm run build

Vite 固定输出:

  • wwwroot/vue-app/app.js
  • wwwroot/vue-app/app.css
  • 必要的 chunks 和 assets

不要直接修改构建产物;源码变更后重新运行构建。

5. 后端开发

进程启动

src/Eis.Web/Program.cs 的主要顺序:

  1. 查找应用根目录并加载 .env
  2. 建立配置和依赖注入;
  3. 初始化数据库;
  4. 检查认证后端;
  5. 注册异常处理和安全响应头;
  6. 注册健康检查;
  7. 注册公开、认证、考生、管理端点;
  8. 为未知 /api/* 返回原生 JSON 404
  9. 映射前端静态资源和 SPA 回退。

新增业务

推荐顺序:

  1. Eis.Application 定义清晰的服务契约。
  2. Eis.Infrastructure 实现业务和持久化。
  3. SQLite 与 MySQL 走相同业务规则,并分别验证 SQL 差异。
  4. Eis.Web 只处理 HTTP 输入、身份上下文和响应映射。
  5. 添加服务层或基础设施测试。
  6. 再接入 Vue 页面。

不要把复杂审批、录取或成绩规则直接写在端点委托或 Vue 组件中。

端点约定

  • /api/public/...:公开读取。
  • /api/auth/...:登录、注册、密码、TOTP 和退出。
  • /api/candidate/...:考生本人业务。
  • /api/admin/...:管理员业务。
  • /api/admission/...:招生学校业务。

未知 API 会返回:

{
  "ok": false,
  "message": "API 接口不存在"
}

新增端点时要避免与兜底路由冲突,并保持错误响应对前端可理解。

6. 数据库开发

系统同时支持 SQLite 与 MySQL 8.4。数据库变更必须考虑:

  • 两份 schema 资源;
  • 外键、唯一约束和索引;
  • v20 结构版本;
  • 初始化空库;
  • 已有数据库的版本检查;
  • 数据库工具的 seed/reset 行为;
  • 考试和学校专属物理分表;
  • 对现有测试的影响。

应用只会在空库自动创建当前结构。检测到低版本数据库时会要求先备份并执行明确升级流程,不应静默猜测迁移。

业务写入与审计日志应在同一事务内提交。预览、扫描预检、Excel 解析等明确标注为 preview 的操作不得修改数据库。

涉及真实数据前先阅读数据库与数据工具

7. 认证、权限和敏感信息

  • 密码通过 PBKDF2 加盐哈希保存。
  • TOTP 密钥使用 AES-256-GCM 加密。
  • 恢复码只保存带服务端密钥的哈希。
  • 登录使用 HttpOnly、SameSite Cookie。
  • 每个端点按角色和业务数据范围授权。
  • 多实例部署时必须使用 Redis 共享认证状态。

实现管理功能时,至少验证:

  1. 角色是否允许;
  2. 管理级别是否允许;
  3. 学校或班级范围是否匹配;
  4. 目标业务状态是否允许写入;
  5. 是否需要审批或审计;
  6. 归档状态是否应锁定操作。

日志、异常和 API 响应中不要输出密码、TOTP 密钥、恢复码、数据库连接密码或完整敏感身份信息。

8. 缓存开发

缓存命名空间当前包括 publicresults。写操作完成后要使受影响命名空间失效。

Redis 不可用时,公开/结果缓存可回退到有界本机缓存;认证状态不同:一旦明确配置认证 Redis,连接失败会阻止启动,避免多实例随机掉线。

新增缓存时需要考虑:

  • key 是否包含完整业务范围;
  • TTL
  • 并发热点请求合并;
  • 写后失效;
  • Redis 和本机回退的一致性;
  • 敏感数据是否适合缓存。

9. Excel 与文书

Excel 导入遵守:

  • 限制文件大小;
  • 逐行验证;
  • 返回明确行号;
  • 预览与确认分离;
  • 确认阶段原子写入;
  • 不绕过审批和数据范围。

成绩单和录取通知书包含 HMAC 防伪查询码。任何影响文书载荷或验真算法的变更,都要补充 DocumentVerificationCodeServiceTests 并检查历史兼容性。

10. 自动化测试

运行全部测试:

dotnet test .\Eis.slnx

运行指定测试项目:

dotnet test .\tests\Eis.Infrastructure.Tests\Eis.Infrastructure.Tests.csproj

按测试名称筛选:

dotnet test .\Eis.slnx --filter FullyQualifiedName~DatabaseInitializerTests

前端生产构建:

Set-Location .\src\Eis.Web\ClientApp
npm ci
npm run build

纯 .NET 发布产物烟测:

pwsh.exe -NoLogo -NoProfile -NonInteractive -File .\scripts\smoke-dotnet-native.ps1

测试使用临时 SQLite 数据库,不应连接生产数据库。

11. 发布前本地检查

推荐顺序:

dotnet test .\Eis.slnx
pwsh.exe -NoLogo -NoProfile -NonInteractive -File .\scripts\publish.ps1
pwsh.exe -NoLogo -NoProfile -NonInteractive -File .\scripts\smoke-dotnet-native.ps1
git diff --check
git status --short

再人工检查:

  • 首页和登录;
  • 不同角色菜单;
  • 关键列表筛选和分页;
  • 401 后重新登录;
  • Excel 预览不写库;
  • 归档后的写入锁定;
  • 公开缓存写后失效;
  • 直接刷新语义化 URL。

12. 变更注意事项

  • 保留已有业务工作流,不用“最终状态”替代每轮即时结果。
  • 敏感规则同时修改前端交互和服务端校验。
  • 管理台账应提供搜索、有效筛选、结果范围选择、批量操作、分页和清楚状态文案。
  • 审批详情应展示完整上下文。
  • 数据脚本要可重复、可指定目标、支持 dry-run 和备份。
  • 不把测试库结果当作生产库现状。
  • 更新配置或脚本后,明确是否需要修改 npm/.NET 命令和部署文档。