Table of Contents
开发指南
本页说明本地开发、代码结构、前后端联调、验证和变更约定。首次启动请先完成快速开始。
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.Infrastructure:SQLite/MySQL、认证、缓存、Excel、PDF 数据、仓储和业务实现。Eis.Tools:数据库初始化、重建和演示数据命令行工具。Eis.Web:进程入口、依赖注入、HTTP 端点、健康检查和静态资源托管。ClientApp:Vue 源码。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
新增受保护页面时,应同时考虑:
- 路由的
meta.roles; - 菜单是否对正确管理级别显示;
- 会话过期后的重新登录路径;
- 服务端端点的角色和范围校验;
- History 模式下刷新是否能由宿主正确回退。
前端隐藏按钮不是权限控制。所有敏感操作必须由服务端再次拒绝越权请求。
API 调用
统一使用 src/lib/api.js,不要在组件中重复实现 Cookie、JSON 解析和错误状态处理。401 表示会话失效时,应引导重新登录,不应仅提示用户刷新页面。
构建产物
Set-Location .\src\Eis.Web\ClientApp
npm run build
Vite 固定输出:
wwwroot/vue-app/app.jswwwroot/vue-app/app.css- 必要的 chunks 和 assets
不要直接修改构建产物;源码变更后重新运行构建。
5. 后端开发
进程启动
src/Eis.Web/Program.cs 的主要顺序:
- 查找应用根目录并加载
.env; - 建立配置和依赖注入;
- 初始化数据库;
- 检查认证后端;
- 注册异常处理和安全响应头;
- 注册健康检查;
- 注册公开、认证、考生、管理端点;
- 为未知
/api/*返回原生 JSON 404; - 映射前端静态资源和 SPA 回退。
新增业务
推荐顺序:
- 在
Eis.Application定义清晰的服务契约。 - 在
Eis.Infrastructure实现业务和持久化。 - SQLite 与 MySQL 走相同业务规则,并分别验证 SQL 差异。
- 在
Eis.Web只处理 HTTP 输入、身份上下文和响应映射。 - 添加服务层或基础设施测试。
- 再接入 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 共享认证状态。
实现管理功能时,至少验证:
- 角色是否允许;
- 管理级别是否允许;
- 学校或班级范围是否匹配;
- 目标业务状态是否允许写入;
- 是否需要审批或审计;
- 归档状态是否应锁定操作。
日志、异常和 API 响应中不要输出密码、TOTP 密钥、恢复码、数据库连接密码或完整敏感身份信息。
8. 缓存开发
缓存命名空间当前包括 public 和 results。写操作完成后要使受影响命名空间失效。
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 命令和部署文档。