扬州档案管理系统:从零到一构建企业级数字档案平台实操指南
一、系统架构设计与技术选型
本系统采用前后端分离架构,前端使用Vue 3 + Element Plus,后端采用Spring Boot + MyBatis Plus,数据库使用MySQL 8.0,文件存储采用MinIO。以下是具体版本要求:
1.1 环境版本要求
- JDK 17或更高版本
- Node.js 18.18.0或更高版本
- MySQL 8.0.33或更高版本
- MinIO RELEASE.2024-01-06T15-19-31Z或更高版本
1.2 项目结构规划
创建项目根目录结构:
``` yangzhou-archive/ ├── backend/ Spring Boot后端 ├── frontend/ Vue 3前端 ├── docker-compose.yml Docker编排 └── README.md 项目说明 ```二、后端服务搭建
2.1 创建Spring Boot项目
使用Spring Initializr创建项目,或直接使用以下Maven配置:
```2.2 数据库表结构设计
创建数据库yangzhou_archive,执行以下SQL:
``` CREATE DATABASE yangzhou_archive DEFAULT CHARACTER SET utf8mb4; USE yangzhou_archive; -- 档案分类表 CREATE TABLE archive_category ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL COMMENT '分类名称', parent_id BIGINT DEFAULT 0 COMMENT '父分类ID', sort_order INT DEFAULT 0 COMMENT '排序', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_parent_id (parent_id) ) COMMENT='档案分类表'; -- 档案主表 CREATE TABLE archive ( id BIGINT PRIMARY KEY AUTO_INCREMENT, archive_no VARCHAR(50) UNIQUE NOT NULL COMMENT '档案编号', title VARCHAR(200) NOT NULL COMMENT '档案标题', category_id BIGINT NOT NULL COMMENT '分类ID', keywords VARCHAR(500) COMMENT '关键词', description TEXT COMMENT '档案描述', security_level TINYINT DEFAULT 1 COMMENT '密级:1-公开,2-内部,3-秘密', storage_year INT COMMENT '保管期限(年)', status TINYINT DEFAULT 1 COMMENT '状态:1-在库,2-借出,3-销毁', created_by BIGINT NOT NULL COMMENT '创建人', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (category_id) REFERENCES archive_category(id), INDEX idx_archive_no (archive_no), INDEX idx_category (category_id), INDEX idx_status (status) ) COMMENT='档案主表'; -- 档案文件表 CREATE TABLE archive_file ( id BIGINT PRIMARY KEY AUTO_INCREMENT, archive_id BIGINT NOT NULL COMMENT '档案ID', file_name VARCHAR(255) NOT NULL COMMENT '文件名', file_path VARCHAR(500) NOT NULL COMMENT '存储路径', file_size BIGINT NOT NULL COMMENT '文件大小(字节)', file_type VARCHAR(50) COMMENT '文件类型', md5_hash VARCHAR(32) UNIQUE COMMENT '文件MD5', upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (archive_id) REFERENCES archive(id) ON DELETE CASCADE, INDEX idx_archive_id (archive_id), INDEX idx_md5 (md5_hash) ) COMMENT='档案文件表'; ```2.3 核心配置文件
创建application.yml配置文件:
``` server: port: 8080 servlet: context-path: /api spring: datasource: url: jdbc:mysql://localhost:3306/yangzhou_archive?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password_here driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 20 minimum-idle: 5 jpa: hibernate: ddl-auto: validate show-sql: true servlet: multipart: max-file-size: 500MB max-request-size: 500MB minio: endpoint: http://localhost:9000 accessKey: minioadmin secretKey: minioadmin bucketName: yangzhou-archive mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 ```2.4 文件上传服务实现
创建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 FileStorageService { @Autowired private MinioClient minioClient; @Value("${minio.bucketName}") private String bucketName; @PostConstruct public void init() throws Exception { boolean exists = minioClient.bucketExists( BucketExistsArgs.builder().bucket(bucketName).build() ); if (!exists) { minioClient.makeBucket( MakeBucketArgs.builder().bucket(bucketName).build() ); } } public String uploadFile(MultipartFile file) throws Exception { String originalFilename = file.getOriginalFilename(); String fileExtension = originalFilename.substring( originalFilename.lastIndexOf(".") ); String objectName = UUID.randomUUID().toString() + fileExtension; minioClient.putObject( PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build() ); return objectName; } } ```三、前端界面开发
3.1 创建Vue 3项目

使用Vite创建项目:
``` npm create vue@latest yangzhou-archive-frontend cd yangzhou-archive-frontend npm install ```安装必要依赖:
``` npm install element-plus axios vue-router pinia npm install @element-plus/icons-vue npm install sass --save-dev ```3.2 档案管理主界面
创建档案列表组件:
```
档案管理
新增档案
3.3 档案上传组件
创建多文件上传组件:
```
拖拽文件到此处或 点击上传
支持上传PDF、Word、Excel、图片等格式,单个文件不超过500MB
四、系统部署与配置
4.1 使用Docker Compose部署
创建docker-compose.yml文件:
``` version: '3.8' services: mysql: image: mysql:8.0 container_name: yangzhou-mysql environment: MYSQL_ROOT_PASSWORD: Archive@2024 MYSQL_DATABASE: yangzhou_archive ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql - ./init.sql:/docker-entrypoint-initdb.d/init.sql command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci minio: image: minio/minio:latest container_name: yangzhou-minio ports: - "9000:9000" - "9001:9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin volumes: - minio_data:/data command: server /data --console-address ":9001" backend: build: ./backend container_name: yangzhou-backend ports: - "8080:8080" depends_on: - mysql - minio environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/yangzhou_archive SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: Archive@2024 MINIO_ENDPOINT: http://minio:9000 MINIO_ACCESSKEY: minioadmin MINIO_SECRETKEY: minioadmin frontend: build: ./frontend container_name: yangzhou-frontend ports: - "80:80" depends_on: - backend volumes: mysql_data: minio_data: ```4.2 后端Dockerfile
创建backend/Dockerfile:
``` FROM openjdk:17-jdk-slim WORKDIR /app COPY target/archive-backend-1.0.0.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"] ```4.3 前端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;"] ```4.4 Nginx配置
创建frontend/nginx.conf:
``` events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://backend:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } } ```