网站首页/ 信息中心/ 档案百科/

鹰潭数字档案馆系统从零搭建:基于开源技术的完整实操指南

发布时间:2026年09月01日 10:35:14 浏览量:0

一、系统架构设计与技术选型

鹰潭数字档案馆系统的核心需求包括:电子文件长期保存、元数据管理、全文检索、权限控制和访问审计。我们采用微服务架构,确保系统可扩展性和维护性。

1.1 基础技术栈

操作系统:Ubuntu Server 22.04 LTS

数据库:PostgreSQL 14 + TimescaleDB(用于时间序列数据)

文件存储:MinIO 对象存储

搜索引擎:Elasticsearch 8.11

后端框架:Spring Boot 3.1 + Java 17

前端框架:Vue 3 + Element Plus

容器化:Docker 24.0 + Docker Compose 2.20

1.2 目录结构规划

/opt/digital-archive/
├── docker-compose.yml
├── config/
│   ├── application.yml
│   ├── nginx.conf
│   └── elasticsearch.yml
├── data/
│   ├── postgres/
│   ├── minio/
│   └── elasticsearch/
└── scripts/
└── init-database.sql

二、环境部署与配置

2.1 服务器环境准备

使用SSH连接到服务器,执行以下命令:

更新系统
sudo apt update && sudo apt upgrade -y
安装必要工具
sudo apt install -y curl wget git vim net-tools
安装Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

2.2 Docker Compose配置

创建/opt/digital-archive/docker-compose.yml文件:

version: '3.8'
services:
postgres:
image: timescale/timescaledb:2.11-pg14
container_name: archive-postgres
environment:
POSTGRES_DB: digital_archive
POSTGRES_USER: archive_admin
POSTGRES_PASSWORD: YourSecurePassword123!
volumes:
- ./data/postgres:/var/lib/postgresql/data
- ./scripts/init-database.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
networks:
- archive-network
minio:
image: minio/minio:RELEASE.2023-10 25.16
container_name: archive-minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: YourMinioPassword123!
volumes:
- ./data/minio:/data
ports:
- "9000:9000"
- "9001:9001"
networks:
- archive-network
elasticsearch:
image: elasticsearch:8.11.0
container_name: archive-elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms2g -Xmx2g"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./data/elasticsearch:/usr/share/elasticsearch/data
ports:
- "9200:9200"
networks:
- archive-network
networks:
archive-network:
driver: bridge

2.3 数据库初始化

创建/opt/digital-archive/scripts/init-database.sql:

鹰潭数字档案馆系统从零搭建:基于开源技术的完整实操指南

-- 创建扩展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "timescaledb";
-- 档案元数据表
CREATE TABLE archive_metadata (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
file_name VARCHAR(500) NOT NULL,
file_size BIGINT NOT NULL,
mime_type VARCHAR(100),
original_path VARCHAR(1000),
storage_path VARCHAR(1000) NOT NULL,
checksum VARCHAR(64) NOT NULL,
create_time TIMESTAMPTZ DEFAULT NOW(),
modify_time TIMESTAMPTZ DEFAULT NOW(),
retention_years INTEGER DEFAULT 30,
status VARCHAR(20) DEFAULT 'ACTIVE'
);
-- 创建时间序列超表
SELECT create_hypertable('archive_metadata', 'create_time');
-- 访问日志表
CREATE TABLE access_log (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id VARCHAR(100),
action VARCHAR(50),
target_id UUID REFERENCES archive_metadata(id),
ip_address INET,
user_agent TEXT,
access_time TIMESTAMPTZ DEFAULT NOW()
);
-- 创建索引
CREATE INDEX idx_metadata_filename ON archive_metadata(file_name);
CREATE INDEX idx_metadata_checksum ON archive_metadata(checksum);
CREATE INDEX idx_access_log_time ON access_log(access_time);

三、核心服务实现

3.1 Spring Boot应用配置

创建application.yml配置文件:

server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/digital_archive
username: archive_admin
password: YourSecurePassword123!
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: validate
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
minio:
endpoint: http://localhost:9000
accessKey: minioadmin
secretKey: YourMinioPassword123!
bucket: digital-archive
elasticsearch:
uris: http://localhost:9200

3.2 文件上传服务实现

创建FileStorageService.java:

@Service
public class FileStorageService {
@Value("${minio.bucket}")
private String bucketName;
@Autowired
private MinioClient minioClient;
public ArchiveFile uploadFile(MultipartFile file,
String originalPath) throws Exception {
// 生成文件唯一标识
String fileId = UUID.randomUUID().toString();
String objectName = fileId + "/" + file.getOriginalFilename();
// 计算文件哈希值
String checksum = calculateSHA256(file);
// 上传到MinIO
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(file.getInputStream(),
file.getSize(), -1)
.contentType(file.getContentType())
.build()
);
// 保存元数据到数据库
ArchiveMetadata metadata = new ArchiveMetadata();
metadata.setFileName(file.getOriginalFilename());
metadata.setFileSize(file.getSize());
metadata.setMimeType(file.getContentType());
metadata.setOriginalPath(originalPath);
metadata.setStoragePath(objectName);
metadata.setChecksum(checksum);
// 保存到数据库
metadataRepository.save(metadata);
// 索引到Elasticsearch
indexToElasticsearch(metadata);
return new ArchiveFile(metadata,
minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(objectName)
.expiry(3600)
.build()
)
);
}
private String calculateSHA256(MultipartFile file)
throws IOException, NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(file.getBytes());
return Hex.encodeHexString(hash);
}
}

3.3 全文检索服务

创建SearchService.java:

@Service
public class SearchService {
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
public List search(String keyword,
int page,
int size) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keyword)
.field("fileName", 3.0f)
.field("content", 1.0f)
.type(MultiMatchQueryBuilder.Type.BEST_FIELDS))
.withPageable(PageRequest.of(page, size))
.build();
SearchHits hits =
elasticsearchTemplate.search(searchQuery,
ArchiveMetadata.class);
return hits.stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
}
public void indexToElasticsearch(ArchiveMetadata metadata) {
elasticsearchTemplate.save(metadata);
}
}

四、前端界面开发

4.1 文件上传组件

创建FileUpload.vue组件:



4.2 检索界面组件

创建SearchPanel.vue组件:


五、系统部署与运维

5.1 应用打包与部署

创建Dockerfile:

FROM openjdk:17-jdk-slim
WORKDIR /app
复制构建文件
COPY target/digital-archive.jar app.jar
COPY config/application.yml config/
设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
暴露端口
EXPOSE 8080
启动应用
ENTRYPOINT ["java", "-jar", "app.jar", \
"--spring.config.location=file:/app/config/application.yml"]

构建并启动应用:

构建Docker镜像
docker build -t digital-archive:1.0 .
启动所有服务
cd /opt/digital-archive
docker-compose up -d
查看服务状态
docker-compose ps
查看日志
docker-compose logs -f

5.2 Nginx反向代理配置

创建nginx.conf:

server {
listen 80;
server_name archive.yuantan.gov.cn;
前端静态文件
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
后端API代理
location /api/ {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
文件上传超时设置
client_max_body_size 100m;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
MinIO控制台
location /minio/ {
proxy_pass http://localhost:9001/;
}
访问日志
access_log /var/log/nginx/archive_access.log;
error_log /var/log/nginx/archive_error.log;
}

5.3 数据备份脚本

创建backup.sh:

!/bin/bash
BACKUP_DIR="/backup/archive"
DATE=$(date +%Y%m%d_%H%M%S)
创建备份目录
mkdir -p $BACKUP_DIR/$DATE
备份PostgreSQL数据库
docker exec archive-postgres pg_dump -U archive_admin \
digital_archive > $BACKUP_DIR/$DATE/database.sql
备份MinIO数据(使用mc客户端)
docker run --rm -v $BACKUP_DIR/$DATE:/backup \
minio/mc mirror minio/digital-archive /backup/minio
备份Elasticsearch索引
curl -X GET "localhost:9200/_snapshot/backup_repo/snapshot_$DATE?wait_for_completion=true"
压缩备份文件
cd $BACKUP_DIR
tar -czf archive_$DATE.tar.gz $DATE
删除7天前的备份
find $BACKUP_DIR -name ".tar.gz" -mtime +7 -delete
echo "备份完成: $BACKUP_DIR/archive_$DATE.tar.gz"

5.4 监控与告警配置

创建prometheus.yml:

global:
scrape_interval: 15s
scrape_configs:
- job_name: 'archive-service'
static_configs:
- targets: ['localhost:8080']
labels:
service: 'digital-archive'
- job_name: 'postgres'
static_configs:
- targets: ['localhost:9187']
- job_name: 'elasticsearch'
static_configs:
- targets: ['localhost:9114']

六、系统验证与测试

6.1 功能测试脚本

创建test-api.sh:

!/bin/bash
API_BASE="http://localhost:8080/api"
echo "1. 测试健康检查接口"
curl -s $API_BASE/health | jq .
echo "2. 测试文件上传"
curl -X POST $API_BASE/archive/upload \
-H "Authorization: Bearer $TOKEN" \
-F "file=@test.pdf" \
-        
2024档案数字化资质申请全攻略:办理条件、流程及材料汇总
2024档案数字化资质申请全攻略:办理条件、流程及材料汇总
很多想要承接档案馆、企事业单位数字化加工项目的服务商,都知道资质是必备的入场门槛,第一次办理很容易踩材料不全、条件不达标的坑。本文整理了业内通用的办理要求,从申请条件到流程注意事项都说得明明白白,不管...
2026年09月01日 10:35:14
档案诉讼管理软件:找卷宗再也不用翻3小时了
档案诉讼管理软件:找卷宗再也不用翻3小时了
上周跟做商事律师的发小撸串,他把啤酒灌得哗哗响,说上周开庭差点凉了——找2022年那桩合同纠纷案的关键证据卷,去档案室翻了3小时,最后在领导办公桌底的纸箱子里摸到,那纸箱子上还落了一层灰。这种事儿估计...
2026年09月01日 10:35:14
神农架林区档案管理系统 盘活山林特色档案数字化管理新方案
神农架林区档案管理系统 盘活山林特色档案数字化管理新方案
说真的,前两年我帮神农架林区做文旅配套的发小擦了小半年的档案“屁股”,说出来你都不信,之前他们管档案跟守着个没通电的藏宝洞似的,各种林权证、金丝猴观测记录、薅草锣鼓的非遗录音、护林员的巡山日志,散在各...
2026年09月01日 10:35:14
微信咨询
电话联系
QQ客服
微信咨询一对一服务
服务热线: 028-8744 4417
QQ客服: 2305721818