一、技术栈选型与环境准备
为了构建一个高可用、符合档案行业标准的培训资质管理系统,我们将采用Spring Boot 2.7.x作为核心框架,MySQL 8.0作为数据存储。在开始编码前,必须确保本地开发环境已严格配置以下版本,避免因版本不兼容导致依赖冲突。
- JDK 17:执行命令
java -version 确认版本,未安装请使用 sudo apt install openjdk-17-jdk (Ubuntu) 或下载官方安装包。
- Maven 3.6+:执行命令
mvn -v 确认。
- MySQL 8.0:确保服务已启动,默认端口3306未被占用。
二、数据库设计与初始化脚本
针对“档案培训服务资质”的核心业务,我们需要设计一张主表来存储证书信息。该表设计必须包含证书编号、颁发机构、有效期及关联的档案人员ID。请在MySQL客户端执行以下SQL脚本完成数据库与表的构建。
```sql
-- 创建数据库
CREATE DATABASE IF NOT EXISTS digital_archive_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE digital_archive_db;
-- 创建档案培训资质表
CREATE TABLE IF NOT EXISTS archive_training_qualification (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
user_id BIGINT NOT NULL COMMENT '关联的档案系统用户ID',
cert_name VARCHAR(100) NOT NULL COMMENT '资质证书名称,如:数字档案管理员培训证',
cert_number VARCHAR(50) NOT NULL UNIQUE COMMENT '证书编号,唯一索引',
issuing_authority VARCHAR(100) NOT NULL COMMENT '颁发机构,如:国家档案局培训中心',
issue_date DATE NOT NULL COMMENT '颁发日期',
expiry_date DATE NOT NULL COMMENT '过期日期',
cert_status TINYINT DEFAULT 1 COMMENT '状态:1-有效,0-失效',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_user_id (user_id),
INDEX idx_cert_number (cert_number)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='档案培训服务资质表';
```
三、Maven依赖配置
创建名为 archive-qualification-service 的Maven项目,并在 pom.xml 中引入必要的依赖。这里必须包含Web、JPA、MySQL驱动以及Lombok以减少样板代码。请直接复制以下完整的 dependencies 节点覆盖原有配置。
```xml
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
8.0.33
runtime
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-validation
```
四、后端核心实体类构建
在 src/main/java/com/archive/entity 目录下创建实体类 Qualification.java。该类映射到数据库表,必须严格使用JPA注解,并添加审计字段。特别注意 expiryDate 字段,后续将用于自动判断资质是否过期。
```java
package com.archive.entity;
import lombok.Data;
import javax.persistence.;
import java.time.LocalDate;
@Data
@Entity
@Table(name = "archive_training_qualification")
public class Qualification {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_id", nullable = false)
private Long userId;
@Column(name = "cert_name", nullable = false, length = 100)
private String certName;
@Column(name = "cert_number", nullable = false, unique = true, length = 50)
private String certNumber;
@Column(name = "issuing_authority", nullable = false, length = 100)
private String issuingAuthority;
@Column(name = "issue_date", nullable = false)
private LocalDate issueDate;
@Column(name = "expiry_date", nullable = false)
private LocalDate expiryDate;
@Column(name = "cert_status")
private Integer certStatus = 1;
}
```
五、业务逻辑层实现
在 src/main/java/com/archive/service 下创建 QualificationService.java。此层不仅负责数据持久化,还包含核心的业务校验逻辑:在保存资质前,必须校验证书编号的唯一性以及颁发日期不能晚于过期日期。
```java
package com.archive.service;
import com.archive.entity.Qualification;
import com.archive.repository.QualificationRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class QualificationService {
@Autowired
private QualificationRepository repository;
public Qualification addQualification(Qualification qualification) {
// 业务校验:颁发日期不能晚于过期日期
if (qualification.getIssueDate().isAfter(qualification.getExpiryDate())) {
throw new RuntimeException("操作失败:颁发日期不能晚于过期日期");
}
// 业务校验:检查证书编号是否已存在(虽然数据库有唯一索引,但需提前抛出友好提示)
if (repository.existsByCertNumber(qualification.getCertNumber())) {
throw new RuntimeException("操作失败:证书编号 [" + qualification.getCertNumber() + "] 已存在");
}
return repository.save(qualification);
}
public List
getQualificationsByUserId(Long userId) {
return repository.findByUserId(userId);
}
// 检查资质是否有效(用于系统其他模块调用)
public boolean isUserQualified(Long userId, String requiredCertName) {
List list = repository.findByUserId(userId);
LocalDate now = LocalDate.now();
for (Qualification q : list) {
if (q.getCertName().contains(requiredCertName)
&& q.getCertStatus() == 1
&& q.getExpiryDate().isAfter(now)) {
return true;
}
}
return false;
}
}
```
同时,不要忘记创建 QualificationRepository.java 接口:
```java
package com.archive.repository;
import com.archive.entity.Qualification;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface QualificationRepository extends JpaRepository {
List findByUserId(Long userId);
boolean existsByCertNumber(String certNumber);
}
```
六、控制层接口开发

在 src/main/java/com/archive/controller 下创建 QualificationController.java。我们需要提供两个核心接口:录入资质和查询用户资质。接口必须遵循RESTful风格,并返回统一的JSON结构。
```java
package com.archive.controller;
import com.archive.entity.Qualification;
import com.archive.service.QualificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/v1/qualifications")
public class QualificationController {
@Autowired
private QualificationService qualificationService;
@PostMapping("/add")
public ResponseEntity