技术选型与架构设计

采用Java作为后端开发语言,Spring Boot框架简化配置和开发流程。MySQL作为数据库存储健康码状态、用户信息和登记记录。前端可使用Vue.js或React构建管理界面,通过RESTful API与后端交互。

开发环境建议JDK 8+、MySQL 5.7+、Maven 3.6+。采用分层架构:Controller层处理HTTP请求,Service层实现业务逻辑,DAO层操作数据库,Entity层定义数据模型。

数据库设计

核心表结构设计如下:

  1. 用户表(user)
CREATE TABLE `user` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `id_card` varchar(18) NOT NULL,
  `phone` varchar(11) NOT NULL,
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_id_card` (`id_card`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

  1. 健康码表(health_code)
CREATE TABLE `health_code` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `user_id` bigint NOT NULL,
  `status` tinyint NOT NULL COMMENT '0-红码 1-黄码 2-绿码',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `reason` varchar(255) DEFAULT NULL COMMENT '状态变更原因',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`),
  CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

  1. 登记记录表(registration)
CREATE TABLE `registration` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `user_id` bigint NOT NULL,
  `location` varchar(100) NOT NULL,
  `temperature` decimal(3,1) DEFAULT NULL,
  `register_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`),
  CONSTRAINT `fk_reg_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

后端核心功能实现

实体类定义(HealthCode.java)

@Entity
@Table(name = "health_code")
public class HealthCode {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @OneToOne
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    private User user;
    
    private Integer status; // 0:红码 1:黄码 2:绿码
    private String reason;
    private Date updateTime;
    
    // getters and setters
}

健康码状态更新接口

@RestController
@RequestMapping("/api/health-code")
public class HealthCodeController {
    @Autowired
    private HealthCodeService healthCodeService;

    @PutMapping("/{userId}")
    public ResponseEntity<?> updateHealthCodeStatus(
            @PathVariable Long userId,
            @RequestParam Integer status,
            @RequestParam(required = false) String reason) {
        
        return healthCodeService.updateStatus(userId, status, reason)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
}

健康码状态变更服务逻辑

@Service
public class HealthCodeServiceImpl implements HealthCodeService {
    @Autowired
    private HealthCodeRepository healthCodeRepo;
    
    @Transactional
    public Optional<HealthCode> updateStatus(Long userId, Integer status, String reason) {
        return healthCodeRepo.findByUserId(userId).map(code -> {
            code.setStatus(status);
            code.setReason(reason);
            code.setUpdateTime(new Date());
            return healthCodeRepo.save(code);
        });
    }
}

业务规则实现

状态变更验证逻辑

public boolean validateStatusChange(Integer currentStatus, Integer newStatus) {
    // 红码只能由管理员修改
    if (currentStatus == 0 && newStatus != 0) {
        return hasAdminPermission();
    }
    
    // 黄码转绿码需满足条件
    if (currentStatus == 1 && newStatus == 2) {
        return checkYellowToGreenConditions(userId);
    }
    
    // 其他状态转换规则
    return true;
}

定时任务自动转码

@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
public void autoUpdateHealthStatus() {
    // 查找需要自动转码的记录
    List<HealthCode> yellowCodes = healthCodeRepo
            .findByStatusAndUpdateTimeBefore(1, getThresholdDate());
    
    yellowCodes.forEach(code -> {
        if (meetGreenCodeConditions(code.getUserId())) {
            code.setStatus(2);
            code.setReason("自动转绿码");
            healthCodeRepo.save(code);
        }
    });
}

系统安全与优化

接口鉴权

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/api/admin/**").hasRole("ADMIN")
            .antMatchers("/api/health-code/**").authenticated()
            .anyRequest().permitAll()
            .and()
            .addFilter(new JwtAuthenticationFilter(authenticationManager()))
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

数据库索引优化

-- 添加复合索引提高查询效率
ALTER TABLE `health_code` ADD INDEX `idx_status_time` (`status`, `update_time`);
ALTER TABLE `registration` ADD INDEX `idx_location_time` (`location`, `register_time`);

数据统计与分析

健康码状态统计

@Repository
public interface HealthCodeRepository extends JpaRepository<HealthCode, Long> {
    @Query("SELECT h.status, COUNT(h) FROM HealthCode h GROUP BY h.status")
    List<Object[]> countByStatusGroup();
}

高风险区域识别

public List<String> identifyHighRiskLocations(Date start, Date end) {
    return registrationRepo.findHighRiskLocations(start, end, 37.3);
}

系统扩展性考虑

  1. 预留接口对接核酸检测系统
  2. 设计健康码状态变更审批流程
  3. 考虑大数据量下的分表策略(按地区或时间分表)
  4. 实现多级缓存(Redis + LocalCache)提升查询性能
  5. 准备数据库读写分离方案应对高并发场景

部署方案

  1. 使用Docker容器化部署应用和MySQL
  2. 配置Nginx负载均衡和静态资源服务
  3. 设置Prometheus + Grafana监控系统健康状态
  4. 实现ELK日志收集和分析
  5. 制定数据库定期备份策略

此系统设计涵盖了疫情防控登记的核心功能,包括用户管理、健康码状态变更、场所登记记录等。通过合理的数据库设计和接口规范,可满足不同场景下的疫情防控需求。系统可根据实际业务需要进一步扩展功能模块,如对接疫苗数据、行程信息等。

更多推荐