尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

拆迁台账系统如何避免失控:建模与状态机设计

拆迁台账系统如何避免失控:建模与状态机设计 简介这是一份关于征地拆迁与房屋安置管理系统的设计文档面向政务信息化开发人员、项目经理及相关专业学生。文档从系统设计全过程切入详细梳理了业务流程图并重点分析了两类需求功能性需求涵盖系统设置、征地拆迁、房屋安置、统计汇总、地理信息应用与移动办公应用六大模块非功能性需求则关注可靠性、性能、安全性及可维护性同时介绍了模块化、灵活性、可扩展性等设计原则给出了基于J2EE的B/S/S总体架构、部署结构和技术路线。文档还专门讨论了移动办公与地理信息应用等扩展功能体现了现代政务系统对空间数据和远程协作的支持。资源共一个docx文档压缩包大小613KB目录结构完整章节按背景、系统目标、需求分析、总体设计展开正文篇幅较为充实。当前已有153人学习适合需要快速掌握系统设计文档写法以及正在开展相关项目设计的人员参考。1. 为什么说拆迁台账塞进 Excel 之后必然会失控做城市更新或土地整理项目的同学应该都见过这个场面街道办手里压着几箱子纸质协议桌面上 Excel 开了十几个版本同一个被征收人在不同表格里地址写法都不一样。征地拆迁与房屋安置管理系统的核心工作不是把台账做成网页版 Excel而是把入户调查、面积实测、评估公示、协议签约、审核签批、选房分房、补偿款发放整条业务链变成一条可追溯的数据流。这套系统真正要解决三件事数据口径统一一本产权证只对应一份台账、流程状态可控没审核不能发款没腾房不能选房、资金与房源防重一套房不能被两个人选走。对后端开发来说页面和 CRUD 都不难真正的难点是业务状态机的边界划分和并发控制。下面按我熟悉的 Java Vue3 前后端分离思路讲MySQL 8 做业务存储这套设计思路换到其他技术栈同样成立。2. 台账数据建模被征收人、房屋与协议的表结构怎么立住征地拆迁与房屋安置管理系统里最容易返工的就是表结构。业务方一开始说就是个花名册等做到签约环节又提出每户要挂多个附件、每笔补偿款要单独走审批如果表没提前拆开改动成本会成倍上涨。我的习惯是先认业务对象再动手建表。2.1 四个核心业务对象和它们的关系这套系统的骨架是四个域项目域、被征收人房屋台账域、补偿协议域、安置房源域。资金发放记录和档案附件属于辅助域挂在被征收人台账下面不单独作为表设计的起点。业务对象核心字段代表关联关系征迁项目 project项目编号、片区范围、启动日期一对多关联台账房屋台账 household被征收人、产权证号、实测面积一对多关联协议与资金补偿协议 agreement补偿方式、总金额、签约日期必须先有台账再建协议安置房源 house楼盘、楼栋、房号、面积与台账多对多经选房记录连接有两处容易被忽略。第一一本产权证可能对应多个被征收人比如夫妻共有台账表必须设计主被征收人 家庭成员子表否则后面领款签字时缺少签字人家庭成员提出异议也没有落脚点。第二一个被征收人在一个项目下只能有一条台账主记录但他的房屋如果住宅和商铺混搭可以签多份补偿协议。所以业务关系的准确表述是项目下台账唯一台账下协议可多。2.2 用一张被征收房屋台账表说明关键字段下面这张表是整套系统的基础之一建表语句把关键字段和约束都写出来了CREATE TABLE expropriation_household ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, project_id BIGINT UNSIGNED NOT NULL COMMENT 所属征迁项目ID, owner_name VARCHAR(64) NOT NULL COMMENT 被征收人姓名, owner_id_card CHAR(18) NOT NULL COMMENT 被征收人身份证号, property_cert_no VARCHAR(64) DEFAULT COMMENT 产权证号, cert_area DECIMAL(10,2) NOT NULL COMMENT 证载建筑面积单位平米, survey_area DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT 实测建筑面积, house_usage TINYINT NOT NULL COMMENT 用途1住宅 2商业 3办公 4其他, structure_type TINYINT NOT NULL COMMENT 结构1框架 2混合 3砖木 4简易, district_code VARCHAR(32) NOT NULL COMMENT 片区编号关联数据字典, record_status TINYINT NOT NULL DEFAULT 0 COMMENT 0登记 1冻结 2待签 3已签 4腾房 5完结 6注销, version INT NOT NULL DEFAULT 0 COMMENT 乐观锁版本号, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_project_household (project_id, property_cert_no), KEY idx_owner_id_card (owner_id_card), KEY idx_status (record_status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT被征收房屋台账表;这段 DDL 里最值钱的是uk_project_household联合唯一约束在同一个项目下一本产权证只能出现一次从数据层杜绝了重复签约和重复补偿。征迁业务里人盯人复查环节很多但数据库约束比人可靠。另一个关键是owner_id_card必须留明文后续签约金额计算、家庭成员关联都要靠它做连接键一开始脱敏后面就做不了精确匹配。身份证号的脱敏展示放在查询层处理存储层保持完整。cert_area和survey_area分开存的原因也很直接补偿通常按实测面积算但证载面积是行政复议和审计时的重要依据。只存一个字段后面做面积差异分析时没有数据支撑。house_usage直接决定补偿单价必须做成字典表而不是代码枚举政策调整时数据库改一行不用发版。2.3 状态字段和数据字典拆开存record_status这类字段我一般不在 Java 枚举里写死而是建一张sys_dict_item字典表核心字段只有五个dict_type、item_value、item_label、sort_no、enabled。前端下拉框、后端校验、导出 Excel 的列头全从这张表查。原因很现实征迁政策按年度调整状态名和字典名会变每次改文案都重新部署既慢又不安全。台账表立住之后这只是第一块地基。签约审核环节多人并发操作时状态字段会乱所以第二步要把流程状态机设计好。3. 签约审核流程的状态机九个环节怎么流转不失控3.1 从入户调查到档案归档的完整业务链路征地拆迁的审批流转和普通 OA 不同它的状态是单向主导、局部允许回退。完整链路常见做法是九个环节入户调查 → 面积实测 → 评估公示 → 补偿方案确认 → 协议签订 → 街道初审 → 区级复审 → 腾空交房 → 资金发放或选房 → 档案归档。这里资金发放和选房是二选一分支货币补偿走发放补偿款产权调换走选房但不管哪条路前面都必须经过区级复审通过。这就在状态机里划出一条硬边界没有复审通过的单子财务系统不能查到收款人信息。这个边界要做在权限模型上而不是靠前端按钮——财务角色连查看协议的接口都调不到被征收人列表才算真正控制住。状态机设计最常见的失误是把当前状态和操作动作混在一起存。比如有人把待街道初审和街道初审退回都当成状态存结果列表筛选时同一单子的数据散在多行里。正确做法是状态只保存节点操作结果同意、退回、补充材料记录在操作流水表里。3.2 用状态机约束每一条流转路径状态机的实现我一般用静态配置 代码校验的方式。下面是简化后的 Java 代码核心是当前状态、目标状态、操作角色三元组放行private static final MapInteger, MapInteger, SetInteger STATE_MACHINE Map.of( // 当前待签(3)可以由调查员(2)提交到街道初审(4)或退回登记(0) 3, Map.of(4, Set.of(2), 0, Set.of(2)), // 当前街道初审(4)审查员(3)通过后到区级复审(5)退回则回到待签(3) 4, Map.of(5, Set.of(3), 3, Set.of(2)), // 当前区级复审(5)审批人(4)通过后发腾房(6)或直接走货币发放(7) 5, Map.of(6, Set.of(4), 7, Set.of(4), 4, Set.of(3)) ); public void transit(Protocol protocol, int targetStatus, int operatorRole) { MapInteger, SetInteger allowed STATE_MACHINE.get(protocol.getStatus()); if (allowed null || !allowed.containsKey(targetStatus) || !allowed.get(targetStatus).contains(operatorRole)) { throw new IllegalStateException(非法状态流转: protocol.getStatus() - targetStatus , 角色: operatorRole); } protocol.setStatus(targetStatus); protocol.setVersion(protocol.getVersion() 1); }STATE_MACHINE的 key 是当前状态值内层 key 是目标状态值内层 value 是可执行这次流转的角色集合。比如区级复审(5)通过后到腾房(6)只允许审批人角色(4)操作街道审查员不能越权。执行流转时还要配合台账表的version字段走乐观锁UPDATE ... SET status ? WHERE id ? AND version ?防止两个审核员同时把同一条协议改成不同状态。这种事故在政务系统里出现一次就够写检查了。状态机的价值在于把可能的错挡在前面。实际业务里会有超期未处理的场景我一般不做自动流转而是加一张flow_deadline表设置每环节 SLA超时给经办人和分管领导发提醒。征迁涉及重大利益自动跳转容易担责任提醒让责任人自己决定就够了。3.3 流程留痕表和角色操作权限每次流转操作都要写一条流水表结构如下CREATE TABLE flow_log ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, business_id BIGINT UNSIGNED NOT NULL COMMENT 业务主键ID, business_type VARCHAR(32) NOT NULL COMMENT 业务表名agreement/household等, from_status TINYINT NOT NULL COMMENT 流转前状态, to_status TINYINT NOT NULL COMMENT 流转后状态, action VARCHAR(32) NOT NULL COMMENT submit/approve/reject/rollback, operator_id BIGINT UNSIGNED NOT NULL COMMENT 操作人ID, operator_name VARCHAR(64) NOT NULL COMMENT 操作人姓名, remark VARCHAR(500) DEFAULT COMMENT 补充说明, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY idx_business (business_type, business_id, created_at) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT业务流转日志表;日志表最大的用途是复现用户说数据不对的问题。比如有人说补偿金额算错了查 flow_log 发现协议被改过有人说选房总选不上查 flow_log 发现房源被另一条业务提前锁了。idx_business联合索引一定要加否则这个表过百万行之后查询会非常吃力。权限矩阵建议做成角色-数据范围表下面是这套系统里最基础的划分角色数据范围可操作节点敏感字段调查员本人负责片区的台账入户调查、面积实测无手机号评估师指派单子的台账提交评估结果无身份证街道审查员本街道全部台账街道初审、退回手机号脱敏区级审批人全区台账与协议区级复审、选房放行完整数据财务专员已通过复审的协议资金发放无评估明细数据范围的过滤要在 SQL 层通过project_id和district_code做Vue3 后台管理系统的前端隐藏菜单只是体验优化不是权限边界。4. 安置房选房与补偿资金计算两处最容易出事故的规则实现4.1 选房防重数据库条件更新与乐观锁的取舍安置房分配是这套系统并发压力最大的场景。政策通常是按签约顺序选房签约完成得越早优先级越高。但签约是异步发生的两个被征收人可能同时看中同一套房前端按钮禁用拦不住必须在数据库层挡住。简单可靠的方案是条件更新搭配行级锁一次 SQL 完成判断可选 修改状态UPDATE resettlement_house SET status LOCKED, locked_by #{operatorId}, locked_at NOW(), version version 1 WHERE id #{houseId} AND status AVAILABLE AND project_id #{projectId};这条 UPDATE 返回的影响行数就是判定依据1 表示锁定成功0 表示房源已被别人占用。锁定状态要有超时机制比如 10 分钟内未确认就由定时任务回滚为 AVAILABLE避免用户占着房源不选房、其他人干等。这里不推荐SELECT ... FOR UPDATE悲观锁选房页面用户停留时间长锁会一直占用数据库连接高峰期容易把连接池打满。房源表字段上有一个细节楼栋和房间号必须拆成building_id、unit_no、room_no三个字段。政策里经常有一定楼层以上另算差价的分层定价楼层要能单独参与计算存成一个房号字符串后续只能靠正则拆迟早要返工。4.2 补偿金额计算把标准和规则配置化补偿计算是系统的另一条生命线。公式本身不复杂住宅补偿 实测面积 × 片区评估单价 × 成新率系数 装修及附属物补偿 搬家费 过渡费。复杂的是政策会变而且不同片区、不同房屋用途、不同建筑结构套用的参数完全不同。我的习惯是把每项标准做成参数表而不是在 Service 里写死参数编码参数含义生效值生效起止unit_price_zone_AA片区住宅评估单价12500.00 元/㎡2026-01-01 ~ 2026-12-31renewal_rate_brick_wood砖木结构成新率0.752026-01-01 ~ 2026-12-31moving_fee_small90㎡以下搬家费1200 元/户2026-01-01 ~ 2026-12-31transition_rent过渡租金22 元/㎡/月2026-01-01 ~ 2026-12-31参数表至少要有effective_date、expire_date两个时间字段业务计算时用协议签约日期去匹配生效区间。这里有个实际经验政策常有追溯调整今年签的协议可能去年就启动调查了如果直接用当前日期查单价补差价时结果会错。预计算逻辑代码SELECT param_value FROM compensation_rule WHERE param_code #{ruleCode} AND effective_date #{signDate} AND expire_date #{signDate} AND enabled 14.3 金额存储与前端展示的单位统一金额处理上我强烈建议全系统以分为单位存整数。数据库 DECIMAL 本身精度没问题但 Java 端只要有人把字段定义成 double 做中间计算累计和明细就对不上账。用整数分后入参时统一做一次元转分BigDecimal 乘 100 取整出参时在展示层除以 100对账和打印都不会有误差。补偿金额的字段还要保留一个元的展示位只在协议 PDF 打印时使用这是审计要求。数据表里存分PDF 模板里用BigDecimal做格式化输出。这个约定要在团队文档里写清楚否则 Vue 前端一不小心就把分当元传给后端了。5. 上线前最该做的三个数据校验与排错手段5.1 身份证号与面积差异的入库前拦截身份证校验只做长度 18 位存活不了看一个真实场景系统录入张三的身份证11010119900307731X长度对但校验位是错的这类脏数据一旦进入台账后续家庭成员关联、银行打款全部出问题。按 GB 11643 校验位算法写一个工具函数入库前拦截def validate_id_card(id_no: str) - bool: if len(id_no) ! 18: return False weights [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] check_chars 10X98765432 try: total sum(int(id_no[i]) * weights[i] for i in range(17)) return check_chars[total % 11] id_no[17].upper() except ValueError: return False这个函数的关键在第 17 位校验码计算最后一位是数字或大写 X必须统一转大写再比较。另外实测面积和证载面积差超过 15% 时台账状态强制进入复核中避免把测量误差直接带进补偿计算。这两个校验都不复杂但能挡掉后续大半的数据对不上问题。5.2 定时回滚任务要可手动暂停选房锁定回滚的定时任务必须有手动开关。上线初期业务流程还没跑顺经常出现用户以为选了但实际没锁定或者反过来一键暂停回滚任务比改代码重启快得多。这个开关可以放在后台管理系统的参数配置页而不是写死在配置文件里。5.3 流程卡住时先看 flow_log 再看附件当用户反馈协议一直停在待签不要先翻业务表先查 flow_log 里这条 business_id 的最后一条日志。如果流转时间正常而前台没显示大概率是前端状态缓存问题如果连日志都没有那就是提交接口压根没调用成功。实际项目里状态卡在待签最常见的原因是前端漏传了身份证附件协议提交接口抛校验异常页面却没给用户提示。最后补一个运维细节flow_log 表按created_at做分区或归档这套系统跑几年后日志量会非常大但不建议为了省事直接清表——审计随时会来调三年前的记录。分区键选created_at按月分区旧数据自动进冷分区查询直接走分区裁剪比加索引更稳。本文还有配套的精品资源点击获取
返回列表