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

科研教学档案管理系统:从零搭建的全栈实操指南

发布时间:2026年08月22日 05:35:25 浏览量:0

一、技术选型与环境准备

本系统采用前后端分离架构,前端使用Vue 3 + Element Plus,后端使用Spring Boot 2.7,数据库使用MySQL 8.0,文件存储采用MinIO。

1.1 开发环境安装

安装Node.js 18.17.0:

``` curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt-get install -y nodejs ```

安装Java 17:

``` sudo apt update sudo apt install openjdk-17-jdk ```

安装MySQL 8.0:

``` sudo apt install mysql-server-8.0 sudo mysql_secure_installation ```

1.2 数据库初始化

创建数据库和用户:

``` mysql -u root -p CREATE DATABASE research_archive CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'archive_admin'@'localhost' IDENTIFIED BY 'YourPassword123!'; GRANT ALL PRIVILEGES ON research_archive. TO 'archive_admin'@'localhost'; FLUSH PRIVILEGES; ```

创建核心表结构:

``` USE research_archive; CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, real_name VARCHAR(100) NOT NULL, department VARCHAR(200), role ENUM('admin', 'teacher', 'researcher', 'student') NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_username (username), INDEX idx_department (department) ); CREATE TABLE research_projects ( id INT PRIMARY KEY AUTO_INCREMENT, project_code VARCHAR(50) UNIQUE NOT NULL, project_name VARCHAR(500) NOT NULL, principal_id INT NOT NULL, funding_source VARCHAR(200), start_date DATE NOT NULL, end_date DATE, status ENUM('planning', 'ongoing', 'completed', 'archived') DEFAULT 'planning', FOREIGN KEY (principal_id) REFERENCES users(id) ON DELETE CASCADE, INDEX idx_project_code (project_code), INDEX idx_status (status) ); CREATE TABLE archive_files ( id INT PRIMARY KEY AUTO_INCREMENT, file_uuid VARCHAR(36) UNIQUE NOT NULL, original_name VARCHAR(500) NOT NULL, storage_path VARCHAR(1000) NOT NULL, file_size BIGINT NOT NULL, mime_type VARCHAR(100), project_id INT NOT NULL, uploader_id INT NOT NULL, category ENUM('proposal', 'report', 'data', 'paper', 'other') NOT NULL, upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, description TEXT, FOREIGN KEY (project_id) REFERENCES research_projects(id) ON DELETE CASCADE, FOREIGN KEY (uploader_id) REFERENCES users(id) ON DELETE CASCADE, INDEX idx_project_category (project_id, category), INDEX idx_upload_time (upload_time) ); ```

二、后端服务搭建

2.1 Spring Boot项目初始化

使用Spring Initializr创建项目:

``` curl https://start.spring.io/starter.zip \ -d type=maven-project \ -d language=java \ -d bootVersion=2.7.15 \ -d baseDir=research-archive-backend \ -d groupId=com.example \ -d artifactId=archive \ -d name=research-archive \ -d description="Research Archive Management System" \ -d packageName=com.example.archive \ -d packaging=jar \ -d javaVersion=17 \ -d dependencies=web,data-jpa,mysql,security,validation \ -o archive-backend.zip unzip archive-backend.zip ```

2.2 核心配置文件

application.yml配置:

``` server: port: 8080 servlet: context-path: /api spring: datasource: url: jdbc:mysql://localhost:3306/research_archive?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: archive_admin password: YourPassword123! driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true dialect: org.hibernate.dialect.MySQL8Dialect minio: endpoint: http://localhost:9000 accessKey: minioadmin secretKey: minioadmin bucket: research-archive jwt: secret: your-jwt-secret-key-at-least-256-bits-long-here expiration: 86400000 ```

2.3 文件上传服务实现

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 @Slf4j public class FileStorageService { @Value("${minio.bucket}") private String bucketName; @Autowired private MinioClient minioClient; public String uploadFile(MultipartFile file, String category) throws Exception { String originalFilename = file.getOriginalFilename(); String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = UUID.randomUUID().toString() + fileExtension; // 确保存储桶存在 boolean found = minioClient.bucketExists(BucketExistsArgs.builder() .bucket(bucketName).build()); if (!found) { minioClient.makeBucket(MakeBucketArgs.builder() .bucket(bucketName).build()); } // 上传文件 minioClient.putObject( PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build() ); return objectName; } public InputStream downloadFile(String objectName) throws Exception { return minioClient.getObject( GetObjectArgs.builder() .bucket(bucketName) .object(objectName) .build() ); } } ```

2.4 权限控制实现

JWT工具类:

``` @Component public class JwtTokenUtil { @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; public String generateToken(UserDetails userDetails) { Map claims = new HashMap<>(); return Jwts.builder() .setClaims(claims) .setSubject(userDetails.getUsername()) .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + expiration)) .signWith(SignatureAlgorithm.HS256, secret) .compact(); } public Boolean validateToken(String token, UserDetails userDetails) { final String username = getUsernameFromToken(token); return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); } } ```

三、前端界面开发

3.1 Vue项目初始化

创建Vue项目:

``` npm create vue@latest research-archive-frontend cd research-archive-frontend npm install ```

安装依赖:

``` npm install element-plus axios vue-router pinia npm install @element-plus/icons-vue npm install vue-axios ```

3.2 项目文件结构

创建以下目录结构:

``` src/ ├── api/ API接口 ├── components/ 公共组件 ├── router/ 路由配置 ├── store/ 状态管理 ├── utils/ 工具函数 └── views/ 页面组件 ```

3.3 用户登录页面

Login.vue实现:

``` ```

3.4 文件上传组件

FileUpload.vue实现:

``` ```

四、系统部署与配置

4.1 MinIO对象存储部署

科研教学档案管理系统:从零搭建的全栈实操指南

使用Docker部署MinIO:

``` docker run -d \ -p 9000:9000 \ -p 9001:9001 \ --name minio \ -v /mnt/data:/data \ -e "MINIO_ROOT_USER=minioadmin" \ -e "MINIO_ROOT_PASSWORD=minioadmin" \ minio/minio server /data --console-address ":9001" ```

访问 http://localhost:9001 使用minioadmin/minioadmin登录,创建research-archive存储桶。

4.2 后端服务部署

打包Spring Boot应用:

``` cd research-archive-backend mvn clean package -DskipTests ```

创建Dockerfile:

``` FROM openjdk:17-jdk-slim WORKDIR /app COPY target/archive-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"] ```

构建并运行:

``` docker build -t research-archive-backend . docker run -d -p 8080:8080 --name archive-backend research-archive-backend ```

4.3 前端服务部署

构建前端应用:

``` cd research-archive-frontend npm run build ```

创建nginx配置文件:

``` server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://archive-backend:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ```

使用Docker部署:

``` docker run -d \ -p 80:80 \ --name archive-frontend \ -v $(pwd)/dist:/usr/share/nginx/html \ -v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf \ nginx:alpine ```

4.4 系统初始化配置

创建管理员账户:

``` INSERT INTO users (username, password_hash, real_name, role) VALUES ('admin', '$2a$10$YourBcryptHashHere', '系统管理员', 'admin'); ```

注意:password_hash需要使用BCrypt加密,可以使用在线工具生成或通过注册功能创建。

五、系统使用与维护

5.1 日常备份策略

创建数据库备份脚本:

``` !/bin/bash BACKUP_DIR="/backup/research-archive" DATE=$(date +%Y%m%d_%H%M%S) DB_NAME="research_archive" mkdir -p $BACKUP_DIR 备份数据库 mysqldump -u archive_admin -pYourPassword123! $DB_NAME > $BACKUP_DIR/${DB_NAME}_${DATE}.sql 备份MinIO数据(需要安装mc客户端) mc mirror --overwrite minio/research-archive $BACKUP_DIR/minio-backup/ 保留最近7天的备份 find $BACKUP_DIR -name ".sql" -mtime +7 -delete ```

设置定时任务:

``` crontab -e 每天凌晨2点执行备份 0 2 /path/to/backup_script.sh ```

5.2 日志监控配置

Spring Boot日志配置:

``` logging: level: com.example.archive: DEBUG file: name: logs/archive.log logback: rollingpolicy: max-file-size: 10MB max-history: 30 ```

使用logrotate管理日志:

``` /etc/logrotate.d/research-archive /var/log/research-archive/.log { daily rotate 30 compress delaycompress missingok notifempty create 644 root root postrotate systemctl reload research-archive endscript } ```

5.3 性能优化建议

MySQL性能优化配置:

``` /etc/mysql/my.cnf [mysqld] innodb_buffer_pool_size = 1G innodb_log_file_size = 256M innodb_flush_log_at_trx_commit = 2 query_cache_type = 1 query_cache_size = 64M max_connections = 200 ```

Nginx缓存配置:

``` location ~ \.(jpg|j
档案制度建设少走弯路 实战教育手把手带你全流程落地
档案制度建设少走弯路 实战教育手把手带你全流程落地
家人们谁懂啊,我去年帮3个小微企业搭档案制度的时候,踩的坑能绕公司前台的奶茶堆三圈。那时候我还是个抱着《档案管理学》啃的理论党,总觉得不就是归个纸嘛有啥难的,直到把公司攒了5年的合同翻得乱七八糟找不到...
2026年08月22日 05:35:25
档案整理规范服务收费标准,这钱花得明白不肉疼
档案整理规范服务收费标准,这钱花得明白不肉疼
哎,哥们儿姐们儿,今儿咱不聊虚的,就唠唠“档案整理规范服务收费标准”这档子事儿。你别一听“规范”、“标准”就头大,觉得又是啥高深莫测、价格云里雾里的服务。我跟你讲,这玩意儿就跟咱家里大扫除一个理儿,只...
2026年08月22日 05:35:25
水利普查档案数字化全流程指南:合规归档+效率提升实操方案
水利普查档案数字化全流程指南:合规归档+效率提升实操方案
不少水利系统的朋友最近都在问,存量水利普查档案转数字化怎么才能符合归档要求,还能少踩坑?毕竟很多单位攒了十几年的普查档案,既有纸质的河湖勘测表、工程台账,也有老的光盘存储数据,整理起来头都大。这篇我就...
2026年08月22日 05:35:25
微信咨询
电话联系
QQ客服
微信咨询一对一服务
服务热线: 028-8744 4417
QQ客服: 2305721818