档案管理系统按验收次数收费功能的实操开发指南
一、技术选型与数据库表结构设计
在开发档案管理系统的计费模块时,为了确保系统的高并发处理能力和数据的一致性,本指南采用 Spring Boot 2.7 + MyBatis Plus + MySQL 8.0 作为核心技术栈。核心逻辑在于将“验收”动作与“费用计算”强绑定,确保每一次验收操作都能准确触发计费。
我们需要在 MySQL 中设计三张核心表:档案项目表(t_project)、计费规则表(t_billing_rule)以及验收记录表(t_acceptance_record)。请直接执行以下 SQL 脚本完成数据库初始化:
```sql -- 创建档案项目表,用于存储项目基础信息及当前的验收状态 CREATE TABLE `t_project` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '项目ID', `project_name` varchar(100) NOT NULL COMMENT '项目名称', `total_acceptance_count` int(11) DEFAULT '0' COMMENT '累计验收次数', `accumulated_fee` decimal(10,2) DEFAULT '0.00' COMMENT '累计产生费用', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='档案项目表'; -- 创建计费规则表,定义按次收费的单价 CREATE TABLE `t_billing_rule` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '规则ID', `rule_name` varchar(50) NOT NULL COMMENT '规则名称', `unit_price` decimal(10,2) NOT NULL COMMENT '单次验收单价(元)', `is_active` tinyint(1) DEFAULT '1' COMMENT '是否生效:1-生效,0-失效', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='计费规则表'; -- 插入一条默认计费规则:每次验收收费 50.00 元 INSERT INTO `t_billing_rule` (`rule_name`, `unit_price`, `is_active`) VALUES ('默认按次收费', 50.00, 1); -- 创建验收记录表,用于记录每一次验收的流水,支持对账 CREATE TABLE `t_acceptance_record` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '记录ID', `project_id` bigint(20) NOT NULL COMMENT '关联的项目ID', `acceptance_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '验收时间', `current_count` int(11) NOT NULL COMMENT '当前是第几次验收', `fee_generated` decimal(10,2) NOT NULL COMMENT '本次产生的费用', PRIMARY KEY (`id`), KEY `idx_project_id` (`project_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='验收记录表'; ```二、Spring Boot 项目构建与依赖配置
创建一个名为 archive-billing-system 的 Spring Boot 项目。在 pom.xml 中引入必要的依赖。为了简化代码量,我们使用 Lombok 来减少 Getter/Setter 的编写,使用 MyBatis Plus 来简化 CRUD 操作。
请确保你的 pom.xml 包含以下核心依赖:
接下来,配置 application.yml 文件,连接到刚才创建的数据库。请将 username 和 password 替换为你本地的数据库账号密码。
三、实体类与 Mapper 层代码实现
我们需要创建对应的实体类(Entity)和数据访问层(Mapper)。为了节省篇幅,这里直接展示核心代码。请在 com.example.archive.entity 包下创建以下类:
1. Project.java (项目实体)
```java package com.example.archive.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; @Data @TableName("t_project") public class Project { @TableId(type = IdType.AUTO) private Long id; private String projectName; private Integer totalAcceptanceCount; private BigDecimal accumulatedFee; private LocalDateTime createTime; } ```2. BillingRule.java (计费规则实体)
```java package com.example.archive.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; @Data @TableName("t_billing_rule") public class BillingRule { @TableId(type = IdType.AUTO) private Long id; private String ruleName; private BigDecimal unitPrice; private Integer isActive; } ```3. AcceptanceRecord.java (验收记录实体)
```java package com.example.archive.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; @Data @TableName("t_acceptance_record") public class AcceptanceRecord { @TableId(type = IdType.AUTO) private Long id; private Long projectId; private LocalDateTime acceptanceTime; private Integer currentCount; private BigDecimal feeGenerated; } ```接着,在 com.example.archive.mapper 包下创建对应的 Mapper 接口,只需继承 BaseMapper 即可获得基础 CRUD 能力:
四、按验收次数计费核心业务逻辑开发
这是本系统的核心部分。我们需要编写一个服务,当用户点击“验收”按钮时,系统自动执行以下步骤:
- 加锁查询项目信息:防止并发验收导致计数错误。
- 查询生效的计费规则:获取当前的单价。
- 计算费用:累计次数 +1,累计费用 = 原费用 + 单价。
- 更新数据库:更新项目表,并插入一条验收记录。

在 com.example.archive.service 包下创建 AcceptanceService.java:
注意: 在高并发场景下,上述代码中的 selectById 可能会导致脏读。如果是生产环境,建议修改 Mapper 方法使用 SELECT FROM t_project WHERE id = {id} FOR UPDATE 来实现数据库层面的悲观锁,或者使用 Redis 的 SETNX 实现分布式锁。本示例为了保持代码清晰,使用了 @Transactional 保证原子性。
五、接口层实现与功能验证
我们需要提供一个 RESTful API 供前端调用。创建 AcceptanceController.java:
至此,代码编写完毕。现在我们进行功能验证。假设数据库中 t_project 表已有一条 ID 为 1 的数据。
1. 启动项目
运行 Spring Boot 主类,确保端口 8080 启动成功,无报错。
2. 模拟验收请求
使用 Postman 或 curl 发送 POST 请求。我们将连续调用两次,观察计费是否累加。
```bash 第一次验收 curl -X POST "http://localhost:8080/api/acceptance/execute/1" 预期返回 {"code":200,"message":"验收成功,费用已结算"} ```3. 数据库验证
执行完第一次请求后,查询数据库:
```sql SELECT FROM t_project WHERE id = 1; SELECT FROM t_acceptance_record WHERE project_id = 1; ```你应该能看到 t_project 表中 total_acceptance_count 变为 1,accumulated_fee 变为 50.00。t_acceptance_record 表中新增了一条记录。
再次执行 curl 命令进行第二次验收。再次查询数据库,total_acceptance_count 应变为 2,accumulated_fee 应变为 100.00。这证明了按次数累加计费逻辑已成功落地。