海事部门数字档案馆系统:从零搭建到上线的全栈实操指南
一、系统架构设计与技术选型
本系统采用前后端分离架构,后端使用Java Spring Boot,前端使用Vue 3,数据库使用PostgreSQL 14,文件存储使用MinIO。
1.1 开发环境准备
安装以下软件,版本必须严格匹配:
- JDK 17.0.8
- Node.js 18.17.0
- PostgreSQL 14.9
- MinIO RELEASE.2023-10-25T06-33-25Z
1.2 项目初始化
创建项目目录结构:
``` mkdir maritime-archive-system cd maritime-archive-system mkdir backend frontend ```二、后端服务搭建
2.1 Spring Boot项目创建
使用Spring Initializr创建项目:
``` curl https://start.spring.io/starter.zip \ -d type=maven-project \ -d language=java \ -d bootVersion=3.1.4 \ -d baseDir=backend \ -d groupId=com.maritime \ -d artifactId=archive \ -d name=MaritimeArchive \ -d packageName=com.maritime.archive \ -d packaging=jar \ -d javaVersion=17 \ -d dependencies=web,data-jpa,security,validation \ -o backend.zip unzip backend.zip -d backend ```2.2 数据库配置
在application.yml中配置数据库连接:
``` spring: datasource: url: jdbc:postgresql://localhost:5432/maritime_archive username: archive_admin password: Archive@2024! driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true ```2.3 核心实体类定义
创建档案实体类:
``` @Entity @Table(name = "archive_documents") public class ArchiveDocument { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String documentNumber; @Column(nullable = false) private String title; @Column(length = 1000) private String description; @Column(nullable = false) private String filePath; @Column(nullable = false) private String fileType; @Column(nullable = false) private Long fileSize; @Column(nullable = false) @Enumerated(EnumType.STRING) private SecurityLevel securityLevel; @Column(nullable = false) private LocalDateTime uploadTime; @ManyToOne @JoinColumn(name = "category_id") private DocumentCategory category; // getters and setters } ```2.4 文件上传服务实现
创建FileStorageService:
``` @Service public class FileStorageService { @Value("${file.upload-dir}") private String uploadDir; public String storeFile(MultipartFile file, String documentNumber) { String fileName = documentNumber + "_" + System.currentTimeMillis() + "_" + file.getOriginalFilename(); Path targetLocation = Paths.get(uploadDir).resolve(fileName); try { Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING); return fileName; } catch (IOException e) { throw new RuntimeException("文件存储失败: " + e.getMessage()); } } } ```三、前端界面开发
3.1 Vue项目初始化
在frontend目录下创建项目:
``` cd frontend npm create vue@latest . 选择以下配置: ✔ Add TypeScript? Yes ✔ Add Vue Router for Single Page Application? Yes ✔ Add Pinia for state management? Yes ✔ Add Vitest for Unit Testing? No ✔ Add an End-to-End Testing Solution? No ✔ Add ESLint for code quality? Yes ```3.2 档案上传组件开发
创建ArchiveUpload.vue组件:
```3.3 API接口封装
创建archive.js API文件:
``` import axios from 'axios' const apiClient = axios.create({ baseURL: 'http://localhost:8080/api', timeout: 30000 }) export const uploadArchive = (formData) => { return apiClient.post('/archives/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) } export const searchArchives = (params) => { return apiClient.get('/archives/search', { params }) } export const downloadArchive = (id) => { return apiClient.get(`/archives/${id}/download`, { responseType: 'blob' }) } ```四、文件存储系统配置
4.1 MinIO安装与配置
使用Docker安装MinIO:
``` docker run -d \ -p 9000:9000 \ -p 9001:9001 \ --name minio \ -v /data/minio/data:/data \ -v /data/minio/config:/root/.minio \ minio/minio server /data --console-address ":9001" ```访问http://localhost:9001,使用以下默认凭证登录:
- 用户名:minioadmin
- 密码:minioadmin
4.2 创建存储桶
在MinIO控制台执行以下操作:
- 点击Create Bucket
- 输入Bucket Name:maritime-archives
- 点击Create Bucket完成创建
4.3 Spring Boot集成MinIO

添加依赖:
```配置MinIO客户端:
``` @Configuration public class MinioConfig { @Value("${minio.endpoint}") private String endpoint; @Value("${minio.access-key}") private String accessKey; @Value("${minio.secret-key}") private String secretKey; @Bean public MinioClient minioClient() { return MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); } } ```五、全文检索功能实现
5.1 PostgreSQL全文搜索配置
创建全文搜索索引:
``` CREATE INDEX idx_archive_search ON archive_documents USING gin(to_tsvector('simple', title || ' ' || description)); ```5.2 搜索服务实现
创建搜索方法:
``` @Repository public interface ArchiveRepository extends JpaRepository六、权限控制系统
6.1 用户角色定义
创建角色枚举:
``` public enum UserRole { ARCHIVIST, // 档案管理员 DEPARTMENT_USER, // 部门用户 AUDITOR, // 审计员 SYSTEM_ADMIN // 系统管理员 } ```6.2 安全配置
配置Spring Security:
``` @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeHttpRequests(auth -> auth .requestMatchers("/api/auth/").permitAll() .requestMatchers("/api/archives/upload").hasRole("ARCHIVIST") .requestMatchers("/api/archives/download").hasAnyRole("ARCHIVIST", "DEPARTMENT_USER") .requestMatchers("/api/archives/delete").hasRole("ARCHIVIST") .anyRequest().authenticated() ) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } } ```七、系统部署与运维
7.1 Docker容器化部署
创建docker-compose.yml:
``` version: '3.8' services: postgres: image: postgres:14.9 environment: POSTGRES_DB: maritime_archive POSTGRES_USER: archive_admin POSTGRES_PASSWORD: Archive@2024! volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" minio: image: minio/minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin volumes: - minio_data:/data ports: - "9000:9000" - "9001:9001" backend: build: ./backend depends_on: - postgres - minio environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/maritime_archive SPRING_DATASOURCE_USERNAME: archive_admin SPRING_DATASOURCE_PASSWORD: Archive@2024! MINIO_ENDPOINT: http://minio:9000 ports: - "8080:8080" frontend: build: ./frontend ports: - "80:80" volumes: postgres_data: minio_data: ```7.2 前端Dockerfile
frontend/Dockerfile:
``` FROM node:18-alpine as build WORKDIR /app COPY package.json ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine COPY --from=build /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ```7.3 启动系统
执行以下命令启动所有服务:
``` docker-compose up -d ```系统启动后,访问以下地址:
- 前端界面:http://localhost
- 后端API:http://localhost:8080
- MinIO控制台:http://localhost:9001
八、数据备份策略
8.1 数据库自动备份
创建备份脚本backup.sh:
``` !/bin/bash BACKUP_DIR="/backup/$(date +%Y%m%d)" mkdir -p $BACKUP_DIR pg_dump -h localhost -U archive_admin maritime_archive > \ $BACKUP_DIR/maritime_archive_$(date +%H%M%S).sql 保留最近7天的备份 find /backup -type d -mtime +7 -exec rm -rf {} \; ```8.2 设置定时任务
每天凌晨2点执行备份:
``` 0 2 /usr/local/bin/backup.sh ```九、系统监控配置
9.1 应用健康检查
Spring Boot Actuator配置:
``` management: endpoints: web: exposure: include: health,metrics,info endpoint: health: show-details: always ```9.2 日志配置
logback-spring.xml配置:
```