# 线下选举发布与计票操作说明 ## 规则与权限 - 活动必须指定一个投票范围。创建页可停在省、市、区县、镇街或村社任一级;系统管理员还可选择“全国”。全国范围是系统保留的持久化范围,覆盖所有有效行政区,但不会改写 AreaCity 原始层级。只有直接被分配至目标行政区的省、市、区、镇或村管理员可创建、编辑及发布;全国范围仅系统管理员可创建、编辑及发布。上级管理员仍可以只读查看其下级范围的活动。 - 活动在草稿阶段依次配置议题、选项和计票所。发布后定义冻结,不能增删候选人、计票所或改变计票规则。 - 一个活动可以包含多个 `CandidateElection`(岗位/多席位竞选)及 `Proposition`(议案)议题。每个议题独立记录每个选项的有效票、弃权、无效票和系统计算的缺投数。 - 每个议题可配置席位数、最少/最多选择数、最高票/简单多数/绝对多数/特定比例门槛、计票分母(仅有效票或全部投出选票)以及平票后的人工复核或无结果处理。 ## 线下计票闭环 1. 活动投票截止后,已分配的计票员在自己被分配的计票所创建计票批次。 2. 两名不同计票员各自提交完整汇总。计票员输入本题计票张数、各选项有效票、弃权和无效票;缺投不可编辑,系统按 `max(0, 计票张数 × 最少选择数 − 有效选项票数 − 弃权 − 无效)` 自动计算。系统不保存选民身份、单张选票或选票内容,只保存计票所级的汇总数字和录入人。 3. 两份录入逐项完全一致才进入“待监督确认”;不一致进入“待复核”。监督员填写原因后创建新的复点版本,原版本封存为已替代。 4. 监督员不能确认自己的录入;确认后的批次不可编辑。需要更正时,监督员必须填写原因并创建新版本,旧版本保留为已替代。 5. 只有当前已确认版本进入汇总和公开接口。所有指定计票所都确认后,计票截止任务自动发布最终结果;有任一未确认或差异批次时不会自动发布。 ## 对外公开 - `GET /api/public/elections/{electionId}/results` 与 `/results` 公开看板仅返回活动明确允许的数据。截止及结果发布前,默认只能按活动配置公开参与量;候选人或议案票数只有在 `PublishLiveCandidateTotals=true` 或最终结果发布后才返回。开启实时票数必须同时开启参与量公开。 - SignalR 端点为 `/hubs/public-results`;客户端调用 `Subscribe(electionId)` 后接收 `resultUpdated`。Hub 订阅和推送与公开接口使用同一公开策略,不能借此读取未获准公开的票数。公开看板每 15 秒受控轮询接口,以便在实时连接不可用时仍可刷新。 - 每次确认、以及后台每分钟推进活动状态时都会更新公开数据。所有时间均为 UTC。 ## 管理 API - `POST /api/admin/elections` 创建草稿;`POST /{id}/contests`、`POST /{id}/contests/{contestId}/options`、`PUT /{id}/counting-stations` 配置;`POST /{id}/publish` 发布。 - `POST /api/offline-counting/sessions` 开始计票;`POST /sessions/{id}/submissions` 双人独立录入;`POST /sessions/{id}/confirm` 监督确认。 - `POST /sessions/{id}/resolve-discrepancy` 对不一致结果启动复点;`POST /sessions/{id}/corrections` 更正已确认版本。 这些接口的写入均经过地域或计票所角色检查,并由现有保存拦截器产生审计记录。公开接口不包含工作人员身份、审计记录或未确认数据。