跳到主要内容
版本:Current

核心概念

概念落地表 / 字段含义
用户public.users登录白名单 + 角色 + 部门 + 职位
竞选public.campaigns一场公投;ongoing 表示是否接受投票
票数规则campaign_rule_weights本场「部门 + 职位」→ 正整数票数;无匹配默认 1
候选人名簿campaign_candidate_options展示名列表;投票指向选项 id,不是用户 id
参与participation用户是否加入本场;isCandidate 对名簿模型已废弃
选票行ballots每用户每场一行;weight 是可投总票数快照
分票ballot_allocations一张选票拆给多个选项,合计须等于 weight

权重怎么算​

lib/campaign-voter-weight.ts 用用户当前的 department、position 去匹配本场规则(trim 后精确相等)。改规则后 syncBallotWeightsForCampaign 会刷新 ballots.weight,并对已有分票按比例缩放(最大余额法),使分票合计仍等于新权重。

名簿替换​

保存候选人名单会 DELETE 本场全部 campaign_candidate_options 再插入。ballot_allocations.candidate_option_id 外键 ON DELETE CASCADE,已投明细会一起消失。生产改名单前必须确认是否已有投票。

遗留字段​

campaigns.code、candidateCode、defaultBallots 仍写入数据库,编辑表单以隐藏字段保留旧值,加入与投票主路径不读它们。不要按旧文档实现邀请码流程。