# 选举与投票信息系统 - 实施清单 ## 项目目标 建设一个面向组织内部选举的 ASP.NET Core 系统,统一支持在线匿名投票、线下纸质票计票、混合汇总、公开内容发布与实时公开看板。系统应确保资格受控、投票唯一、选票匿名、计票可复核、结果可审计。 ## 技术基线 - 后端:ASP.NET Core Web API、EF Core、OpenAPI(Scalar 或 Swagger) - 业务基础设施:ABP Framework(按需采用其身份、权限、审计和模块化能力) - 数据库:MySql(首选;SQL Server 为可支持替代) - 身份认证:OpenIddict 或 Keycloak,采用 OpenID Connect / OAuth 2.0 - 实时与任务:SignalR、Hangfire、Redis - 文件:MinIO 或 S3 兼容对象存储 - 管理端:Vue 3 + Element Plus;公开站点:Nuxt 3(优先;当前基础实现为 Razor Pages 服务端渲染) - 编辑与可视化:CKEditor 5 或 TinyMCE、ECharts、ClosedXML - 可观测性:Serilog + Seq 或 OpenSearch ## 业务规则(实现前必须确认) - [ ] 明确选民身份认证来源:本地账号、统一身份认证或两者并行。 - [ ] 明确是否存在实名投票;默认在线投票为匿名投票。 - [ ] 明确线上、线下混合投票时,是否允许同一选民跨渠道投票;默认不允许。 - [ ] 明确线下票是否必须双人独立录入和监票确认;建议必须。 - [ ] 明确结果公开策略:默认实时公开参与率,截止前不公开候选人实时得票。 - [ ] 明确票数相同、无效票、弃权票、候选人退出和补选的规则。 - [ ] 明确组织层级、管理员授权范围与数据保留期限。 ## 第一阶段:项目骨架与基础能力 - [x] 创建解决方案与模块边界:Identity、Organization、Election、Voting、OfflineCounting、Cms、PublicBoard、Audit。 - [x] 配置 MySQL、EF Core 初始迁移、开发环境配置与健康检查。 - [x] 内置身份认证:ASP.NET Core Identity 本地用户、密码策略、锁定、安全 Cookie、首个系统管理员初始化,以及地域角色范围授权。 - [x] 建立统一 API 错误格式和分页响应模型;参数校验、排序和筛选随首个业务列表接口落地。 - [x] 建立基础审计拦截器;Serilog 与敏感字段脱敏随身份及业务字段接入时配置。 - [ ] 配置 Redis、Hangfire、对象存储和本地开发替代实现。 - [x] 建立单元测试基础设施;集成测试和权限越权测试随受保护 API 接入。 ## 第二阶段:组织、选民与候选人 - [x] 行政区划目录:省、市、区县、镇街、村社区五级;省市区镇采用受控 AreaCity 数据版本,村社区采用本地确认目录。 - [x] 地域角色与范围:省、市、区、镇、村管理员的下级覆盖;计票员、监督员与具体计票所分配。 - [x] 用户和选民资料:导入预校验/确认、停用、有效状态、地域范围查询。 - [ ] 选民资格规则:按组织、名单、身份属性或人工审核确定。 - [x] 候选人管理:提名、自荐、服务端资格状态转换、撤回、取消资格和公示;资格材料文件待对象存储阶段接入。 - [x] 提供 Excel 批量导入,导入预校验并返回逐行错误;导出将在管理端与授权下载审计接入时实施。 - [x] 管理端基础资料页面:使用 Razor Pages + Blazor Interactive Server 提供地域、选民、候选人、角色、计票所与导入操作,不引入独立 SPA。 ## 第三阶段:选举活动与在线投票 - [ ] 活动状态机:草稿、待发布、公示中、投票中、已截止、计票中、已发布、已归档。 - [ ] 配置活动类型:单选、多选、多席位、赞成/反对/弃权。 - [ ] 配置时间窗口、选民范围、候选人范围、最少/最多选择数、平票和当选规则。 - [ ] 创建选民资格快照;投票开始前完成冻结,冻结后的变更必须走受控流程。 - [ ] 实现在线投票资格校验、时间校验、规则校验、限流和防重复投票。 - [ ] 分离“投票资格/已投状态”和“匿名选票”存储;常规查询不得反向关联。 - [ ] 通过数据库唯一约束、事务和并发控制保障每个活动每名选民只能完成一次投票。 - [ ] 实现投票回执,仅证明投票完成,不透露选票内容。 - [ ] 覆盖:越权、重复提交、截止边界、并发投票、非法候选人和异常恢复测试。 ## 第四阶段:线下投票与计票复核 - [x] 管理线下计票批次:按已分配计票所、工作人员、监督员及活动截止时间控制;地点/票箱信息沿用计票所资料。 - [ ] 实现线下签到或名单核验,与线上已投状态交叉校验。 - [x] 支持按候选人/议案选项录入有效票、无效票、弃权票和缺投数。 - [x] 支持双人独立计票录入,自动比对并将差异送入复核。 - [x] 实现计票批次、复核、监票确认与更正版本记录;封存附件待对象存储阶段接入。 - [ ] 已确认线下计票不得原地修改;更正必须保留前版本、原因、审核人与时间。 - [x] 仅将“已确认”的线下票纳入活动最终汇总。 ## 第五阶段:结果、公开看板与 CMS - [x] 按活动规则汇总已确认线下票,生成候选人/议案选项得票、有效/无效/弃权/缺投统计及当选名单;线上投票接入后复用同一结果服务。 - [ ] 建立结果审核、监票确认、发布和归档流程。 - [x] SignalR 推送已确认线下计票的公开看板数据;断线后使用公开结果接口受控轮询兜底。 - [ ] 公开看板显示活动状态、参与人数、参与率、数据更新时间和公开规则说明。 - [ ] 候选人实时票数、排名和图表只在活动明确开启后公开;不得公开未确认线下结果。 - [x] CMS 公开信息基础:建立八类固定内容定义(选举公告、规则与政策、候选人公示、选民指南、结果公告、常见问题、资料下载、历史归档)及只读公开内容契约。 - [x] 公开信息前端:提供八类内容的首页最新发布区、直接栏目菜单入口、目录/详情页、发布内容空状态与服务不可用提示;采用响应式中性政务信息风格。 - [ ] CMS:栏目、文章、公告、政策、操作指南、候选人公示、结果公告、媒体库与附件。 - [ ] CMS 支持草稿、审核、发布、下线、定时发布、版本历史、回滚、分类、标签、SEO。 - [ ] 建立 CMS 内容与选举活动、公开看板、结果公告之间的关联。 ## 第六阶段:安全、运维与交付 - [ ] 实现全量审计:配置、名单、审核、投票状态、线下计票、结果发布和 CMS 发布。 - [ ] 审计日志中不得存储线上匿名选票与选民身份的可查询关联。 - [ ] 配置接口限流、防自动化滥用、CSRF 策略(如采用 Cookie 会话)与安全响应头。 - [ ] 制定备份、恢复、归档和日志保留策略。 - [ ] 容器化部署:API、前端、PostgreSQL、Redis、MinIO、反向代理。 - [ ] 建立 CI:格式检查、编译、单元测试、集成测试、数据库迁移验证与镜像构建。 - [ ] 编写管理员、监票员、线下计票员、CMS 编辑与选民操作手册。 ## 验收场景 - [ ] 无资格选民不能查看或提交目标活动的选票。 - [ ] 同一选民无法在线重复投票,也无法在线上与线下重复参与。 - [ ] 管理员可查看参与状态,但无法从正常业务查询获知匿名选民投给谁。 - [ ] 两份线下独立计票不一致时,结果不能进入最终汇总。 - [ ] 未审核/未确认的线下票不出现在对外公开看板或最终结果中。 - [ ] 实时公开数据严格遵守活动的公开策略,且不会泄露个人投票信息。 - [ ] 活动截止、结果确认、发布、撤销发布等关键动作均可审计追溯。 - [ ] CMS 内容经过审核后可公开发布,历史版本可追溯和恢复。