一、技术栈选型与核心依赖
针对文书档案系统招标中普遍要求的高可用性、全文检索及OCR识别能力,我们采用Spring Boot 3 + Vue 3 + MinIO + Tesseract的标准技术组合。该组合完全满足等保三级要求且组件均为开源免费。
创建Spring Boot项目,在pom.xml中引入以下核心依赖。请确保JDK版本为17及以上。
```xml
org.springframework.boot
spring-boot-starter-web
com.baomidou
mybatis-plus-boot-starter
3.5.5
mysql
mysql-connector-java
8.0.33
io.minio
minio
8.5.7
net.sourceforge.tess4j
tess4j
5.4.0
org.projectlombok
lombok
true
```
二、数据库表结构设计
文书档案系统的核心在于对文件元数据及OCR识别结果的存储。请在MySQL 8.0数据库中执行以下SQL脚本,建立doc_archive表。该表包含文件基础信息、存储路径及全文检索字段。
```sql
CREATE DATABASE IF NOT EXISTS archive_system DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE archive_system;
CREATE TABLE doc_archive (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
title VARCHAR(255) NOT NULL COMMENT '文书标题',
doc_no VARCHAR(100) COMMENT '文号',
category VARCHAR(50) COMMENT '档案分类',
original_filename VARCHAR(255) NOT NULL COMMENT '原始文件名',
file_size BIGINT COMMENT '文件大小(字节)',
file_type VARCHAR(20) COMMENT '文件类型(pdf, png等)',
bucket_name VARCHAR(100) COMMENT 'MinIO存储桶名称',
object_name VARCHAR(255) COMMENT 'MinIO对象名称',
ocr_content TEXT COMMENT 'OCR识别后的全文内容',
status TINYINT DEFAULT 1 COMMENT '状态: 1-归档, 0-草稿',
created_by VARCHAR(50) COMMENT '创建人',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_category (category),
FULLTEXT INDEX idx_fulltext (title, ocr_content) WITH PARSER ngram
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='文书档案主表';
```
三、后端核心配置与实现
在src/main/resources/application.yml中配置数据库连接、MinIO文件服务器地址及OCR训练数据路径。注意:MinIO默认端口9000,OCR数据路径需指向你存放chi_sim.traineddata的文件夹。
```yaml
server:
port: 8080
spring:
application:
name: archive-service
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/archive_system?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123456
MinIO配置
minio:
endpoint: http://127.0.0.1:9000
accessKey: minioadmin
secretKey: minioadmin
bucketName: archive-docs
OCR配置
tesseract:
dataPath: D:/tessdata Windows示例,Linux下为 /usr/share/tesseract-ocr/4.00/tessdata
language: chi_sim+eng
```
接下来是核心服务类ArchiveService.java,实现文件上传、MinIO存储及OCR识别的完整流程。
```java
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.InputStream;
import java.util.UUID;
@Service
public class ArchiveService {
@Value("${minio.endpoint}")
private String minioEndpoint;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Value("${minio.bucketName}")
private String bucketName;
@Value("${tesseract.dataPath}")
private String tessDataPath;
@Value("${tesseract.language}")
private String tessLanguage;
private MinioClient minioClient;
private ITesseract tesseract;
@PostConstruct
public void init() {
try {
// 初始化MinIO客户端
minioClient = MinioClient.builder()
.endpoint(minioEndpoint)
.credentials(accessKey, secretKey)
.build();
// 初始化OCR引擎
tesseract = new Tesseract();
tesseract.setDatapath(tessDataPath);
tesseract.setLanguage(tessLanguage);
} catch (Exception e) {
throw new RuntimeException("系统初始化失败", e);
}
}
/
上传文件并进行OCR归档
/
public String uploadAndArchive(MultipartFile file, String title, String category) throws Exception {
// 1. 生成唯一文件名
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = UUID.randomUUID().toString() + suffix;
// 2. 上传至MinIO
InputStream inputStream = file.getInputStream();
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(inputStream, file.getSize(), -1)
.contentType(file.getContentType())
.build()
);
// 3. 执行OCR识别 (仅对图片或PDF有效,此处演示通用逻辑)
File tempFile = File.createTempFile("ocr-", suffix);
file.transferTo(tempFile);
String ocrResult = tesseract.doOCR(tempFile);
tempFile.delete(); // 删除临时文件
// 4. 构建数据库实体并保存 (此处省略Mapper调用,实际开发需注入Mapper)
DocArchive archive = new DocArchive();
archive.setTitle(title);
archive.setCategory(category);
archive.setOriginalFilename(originalFilename);
archive.setFileSize(file.getSize());
archive.setBucketName(bucketName);
archive.setObjectName(objectName);
archive.setOcrContent(ocrResult);
// archiveMapper.insert(archive); // 需自行实现Mapper
return "归档成功,识别文字长度: " + ocrResult.length();
}
}
```
四、前端上传与展示组件
前端使用Vue 3配合Element Plus组件库。首先安装依赖:npm install element-plus axios。以下是完整的文件上传组件代码,包含拖拽上传和进度条显示。
```html
<
拖拽文件到此处或 点击上传
支持 pdf/png/jpg 文件,且不超过 100MB
```
五、基于Docker的快速部署

为了实现交付时的零环境配置,我们使用Docker Compose编排MySQL、MinIO和应用服务。在项目根目录创建docker-compose.yml文件。
```yaml
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: archive_mysql
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: archive_system
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql 自动执行建表SQL
minio:
image: minio/minio:latest
container_name: archive_minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_data:/data
app:
build: .
container_name: archive_app
depends_on:
- mysql
- minio
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/archive_system?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
MINIO_ENDPOINT: http://minio:9000
volumes:
mysql_data:
minio_data:
```
同时,在项目根目录创建Dockerfile用于构建后端应用镜像:
```dockerfile
FROM openjdk:17-slim
WORKDIR /app
COPY target/archive-system.jar app.jar
将本地的tessdata文件夹复制到镜像中,解决OCR依赖问题
RUN mkdir -p /usr/share/tesseract-ocr/4.00/tessdata
COPY ./tessdata /usr/share/tesseract-ocr/4.00/tessdata
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
```
执行以下命令启动整套系统:
1. 将项目打包:mvn clean package -DskipTests
2. 启动容器:docker-compose up -d
3. 访问MinIO控制台:http://localhost:9001 (账号密码均为minioadmin),手动创建名为archive-docs的Bucket,并设置Policy为Public。