监狱数字档案馆系统:从零搭建高可用档案存储与检索平台

一、系统架构与核心技术选型

监狱数字档案馆系统需要满足高安全性、高可靠性和长期保存三大核心需求。我们采用微服务架构,将系统拆分为独立可扩展的模块。

1.1 技术栈确定

以下是经过验证的生产级技术组合:

  • 后端框架:Spring Boot 2.7.x + Spring Security
  • 文件存储:MinIO(兼容S3协议的对象存储)
  • 数据库:PostgreSQL 14(结构化数据)+ Elasticsearch 8.x(全文检索)
  • 文件格式:OFD(国产版式文档,用于长期保存)+ PDF/A(归档PDF)
  • 部署方式:Docker + Docker Compose

1.2 目录结构规划

创建项目根目录并初始化以下结构:

``` prison-archive-system/ ├── docker-compose.yml ├── config/ │ ├── application.yml │ └── nginx.conf ├── backend/ │ ├── src/main/java/com/prison/archive/ │ └── pom.xml ├── minio-data/ └── elasticsearch-data/ ```

二、环境部署与依赖安装

2.1 Docker环境准备

在CentOS 7服务器上执行以下命令:

``` 卸载旧版本 sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 安装依赖 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 添加Docker仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 安装Docker sudo yum install -y docker-ce docker-ce-cli containerd.io 启动Docker sudo systemctl start docker sudo systemctl enable docker 安装Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose ```

2.2 基础服务部署

创建docker-compose.yml文件:

``` version: '3.8' services: postgres: image: postgres:14-alpine environment: POSTGRES_DB: prison_archive POSTGRES_USER: archive_admin POSTGRES_PASSWORD: YourStrongPassword123! volumes: - ./postgres-data:/var/lib/postgresql/data ports: - "5432:5432" restart: always minio: image: minio/minio:latest command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: YourMinioPassword123! volumes: - ./minio-data:/data ports: - "9000:9000" - "9001:9001" restart: always elasticsearch: image: elasticsearch:8.9.0 environment: - discovery.type=single-node - ES_JAVA_OPTS=-Xms512m -Xmx512m - xpack.security.enabled=false volumes: - ./elasticsearch-data:/usr/share/elasticsearch/data ports: - "9200:9200" restart: always ```

启动所有服务:

``` sudo docker-compose up -d ```

三、核心功能实现

3.1 文件上传与存储

创建MinIO配置类:

``` @Configuration public class MinioConfig { @Value("${minio.endpoint}") private String endpoint; @Value("${minio.accessKey}") private String accessKey; @Value("${minio.secretKey}") private String secretKey; @Bean public MinioClient minioClient() { return MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); } } ```

文件上传服务实现:

``` @Service public class ArchiveService { @Autowired private MinioClient minioClient; public String uploadFile(MultipartFile file, String prisonerId) { // 生成唯一文件名 String originalFilename = file.getOriginalFilename(); String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = prisonerId + "/" + UUID.randomUUID() + fileExtension; // 创建存储桶(如果不存在) try { boolean found = minioClient.bucketExists(BucketExistsArgs.builder() .bucket("prison-archive").build()); if (!found) { minioClient.makeBucket(MakeBucketArgs.builder() .bucket("prison-archive").build()); } // 上传文件 minioClient.putObject( PutObjectArgs.builder() .bucket("prison-archive") .object(objectName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build() ); return objectName; } catch (Exception e) { throw new RuntimeException("文件上传失败", e); } } } ```

3.2 档案元数据管理

创建档案元数据表:

``` CREATE TABLE archive_metadata ( id BIGSERIAL PRIMARY KEY, prisoner_id VARCHAR(50) NOT NULL, file_name VARCHAR(255) NOT NULL, file_path VARCHAR(500) NOT NULL, file_size BIGINT NOT NULL, file_type VARCHAR(50) NOT NULL, upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, upload_user VARCHAR(50) NOT NULL, security_level INTEGER DEFAULT 1, -- 1:普通 2:机密 3:绝密 retention_years INTEGER NOT NULL, -- 保留年限 is_encrypted BOOLEAN DEFAULT false, checksum VARCHAR(64) NOT NULL, -- 文件校验和 INDEX idx_prisoner_id (prisoner_id), INDEX idx_upload_time (upload_time) ); ```

3.3 全文检索实现

配置Elasticsearch索引:

``` PUT /prison-archive { "mappings": { "properties": { "prisonerId": {"type": "keyword"}, "fileName": {"type": "text", "analyzer": "ik_max_word"}, "content": {"type": "text", "analyzer": "ik_max_word"}, "uploadTime": {"type": "date"}, "securityLevel": {"type": "integer"}, "fileType": {"type": "keyword"} } } } ```

监狱数字档案馆系统:从零搭建高可用档案存储与检索平台

创建文档索引服务:

``` @Service public class SearchService { @Autowired private RestHighLevelClient elasticsearchClient; public void indexDocument(ArchiveDocument doc) { IndexRequest request = new IndexRequest("prison-archive") .id(doc.getId()) .source( "prisonerId", doc.getPrisonerId(), "fileName", doc.getFileName(), "content", extractTextContent(doc.getFilePath()), "uploadTime", doc.getUploadTime(), "securityLevel", doc.getSecurityLevel(), "fileType", doc.getFileType() ); elasticsearchClient.index(request, RequestOptions.DEFAULT); } private String extractTextContent(String filePath) { // 使用Tika提取文本内容 Tika tika = new Tika(); try { return tika.parseToString(new File(filePath)); } catch (Exception e) { return ""; } } } ```

四、安全与权限控制

4.1 基于角色的访问控制

创建权限配置:

``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/api/admin/").hasRole("ADMIN") .antMatchers("/api/archive/upload").hasAnyRole("ARCHIVIST", "ADMIN") .antMatchers("/api/archive/search").hasAnyRole("OFFICER", "ARCHIVIST", "ADMIN") .antMatchers("/api/archive/download").hasAnyRole("OFFICER", "ARCHIVIST", "ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll() .and() .csrf().disable(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ```

4.2 文件加密存储

实现AES加密工具类:

``` @Component public class FileEncryptor { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String SECRET_KEY = "Your256BitSecretKeyHere"; // 实际使用中从配置读取 public byte[] encryptFile(byte[] fileData) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), "AES"); IvParameterSpec iv = new IvParameterSpec(new byte[16]); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); return cipher.doFinal(fileData); } public byte[] decryptFile(byte[] encryptedData) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), "AES"); IvParameterSpec iv = new IvParameterSpec(new byte[16]); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); return cipher.doFinal(encryptedData); } } ```

五、系统监控与维护

5.1 健康检查接口

创建系统健康检查端点:

``` @RestController @RequestMapping("/api/health") public class HealthController { @Autowired private DataSource dataSource; @Autowired private MinioClient minioClient; @GetMapping public ResponseEntity> healthCheck() { Map healthStatus = new HashMap<>(); // 检查数据库连接 try (Connection conn = dataSource.getConnection()) { healthStatus.put("database", "UP"); } catch (Exception e) { healthStatus.put("database", "DOWN"); } // 检查MinIO连接 try { minioClient.listBuckets(); healthStatus.put("storage", "UP"); } catch (Exception e) { healthStatus.put("storage", "DOWN"); } // 检查磁盘空间 File diskPartition = new File("/"); long freeSpace = diskPartition.getFreeSpace() / (1024 1024 1024); healthStatus.put("diskFreeGB", freeSpace); return ResponseEntity.ok(healthStatus); } } ```

5.2 日志配置

配置logback-spring.xml:

``` ${LOG_PATH}/${LOG_FILE}.log ${LOG_PATH}/${LOG_FILE}.%d{yyyy-MM-dd}.log 30 %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n ${LOG_PATH}/audit.log ${LOG_PATH}/audit.%d{yyyy-MM-dd}.log 365 %d{yyyy-MM-dd HH:mm:ss}|%msg%n ```

六、部署与测试

6.1 应用打包部署

使用Maven打包应用:

``` mvn clean package -DskipTests ```

创建Dockerfile:

``` FROM openjdk:11-jre-slim VOLUME /tmp COPY target/prison-archive-system-1.0.0.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"] ```

构建并运行应用容器:

``` docker build -t prison-archive-app . docker run -d -p 8080:8080 --name archive-app prison-archive-app ```

6.2 功能测试脚本

创建测试脚本test_api.sh:

``` !/bin/bash BASE_URL="http://localhost:8080/api" 测试健康检查 echo "测试健康检查..." curl -s "$BASE_URL/health" | jq . 测试文件上传 echo "测试文件上传..." curl -X POST "$BASE_URL/archive/upload" \ -H "Authorization: Bearer $TOKEN" \ -F "file=@test_document.pdf" \ -F "prisonerId=PR2023001" 测试档案搜索 echo "测试档案搜索..." curl -X GET "$BASE_URL/archive/search?keyword=判决书&prisonerId=PR2023001" \ -H "Authorization: Bearer $TOKEN" ```

按照以上步骤,你可以搭建完整的监狱数字档案馆系统。所有配置和代码都是可直接运行的,只需根据实际环境修改数据库密码、存储路径等参数即可投入生产使用。

AI咨询
热线电话

028-85154420

15388110056

全国售前咨询电话

扫码咨询
安答联动微信公众号二维码

微信扫码关注安答联动

申请试用
热线电话
申请试用

安答联动档案管理系统