档案管理系统社区案例:SpringBoot+Vue前后端分离实战指南

一、项目环境与工具准备

我们将基于SpringBoot 2.7.15和Vue 3.3.4构建一个包含用户管理、档案分类、文件上传与检索功能的社区档案管理系统。

1.1 开发环境安装

首先安装以下核心工具,所有命令在Ubuntu 22.04或Windows WSL2下执行:

  • JDK 17:sudo apt install openjdk-17-jdk
  • Maven 3.8+:sudo apt install maven
  • Node.js 18+:curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - && sudo apt install nodejs

验证安装:java -version 应显示17.x,node -v 应显示18.x。

1.2 数据库初始化

使用MySQL 8.0创建数据库,执行以下SQL:

```sql CREATE DATABASE archive_community DEFAULT CHARSET utf8mb4; USE archive_community; CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, real_name VARCHAR(50), role ENUM('admin', 'user') DEFAULT 'user', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE archive_category ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, parent_id INT DEFAULT 0, sort_order INT DEFAULT 0, FOREIGN KEY (parent_id) REFERENCES archive_category(id) ON DELETE CASCADE ); CREATE TABLE archive_files ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(200) NOT NULL, category_id INT, file_path VARCHAR(500) NOT NULL, uploader_id INT, keywords TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (category_id) REFERENCES archive_category(id), FOREIGN KEY (uploader_id) REFERENCES users(id) ); ```

二、后端SpringBoot服务搭建

2.1 项目初始化与依赖配置

使用Spring Initializr创建项目,或直接复制以下pom.xml核心依赖:

```xml org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java 8.0.33 org.projectlombok lombok true org.springframework.boot spring-boot-starter-security io.jsonwebtoken jjwt-api 0.11.5 ```

2.2 数据库与文件存储配置

application.yml中配置:

```yaml server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/archive_community?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true servlet: multipart: max-file-size: 50MB max-request-size: 100MB archive: upload-dir: /data/archive_files/ ```

2.3 核心实体类与JWT认证

创建用户实体类User.java

```java @Entity @Data @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(unique = true, nullable = false) private String username; @Column(nullable = false) private String password; private String realName; @Enumerated(EnumType.STRING) private UserRole role; @CreationTimestamp private LocalDateTime createdAt; } ```

创建JWT工具类JwtUtil.java

```java @Component public class JwtUtil { private final String SECRET_KEY = "your-256-bit-secret-key-change-in-production"; public String generateToken(String username) { return Jwts.builder() .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + 1000 60 60 24)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } public boolean validateToken(String token) { try { Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } } ```

2.4 文件上传控制器实现

创建FileUploadController.java

```java @RestController @RequestMapping("/api/archive") public class FileUploadController { @Value("${archive.upload-dir}") private String uploadDir; @PostMapping("/upload") public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("categoryId") Integer categoryId, @RequestParam("keywords") String keywords) { try { // 创建上传目录 File uploadPath = new File(uploadDir); if (!uploadPath.exists()) { uploadPath.mkdirs(); } // 生成唯一文件名 String originalFilename = file.getOriginalFilename(); String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); String uniqueFilename = UUID.randomUUID().toString() + fileExtension; // 保存文件 Path filePath = Paths.get(uploadDir + uniqueFilename); Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING); // 保存到数据库 ArchiveFile archiveFile = new ArchiveFile(); archiveFile.setTitle(originalFilename); archiveFile.setFilePath(uniqueFilename); archiveFile.setCategoryId(categoryId); archiveFile.setKeywords(keywords); archiveFile.setUploaderId(getCurrentUserId()); archiveFileRepository.save(archiveFile); return ResponseEntity.ok(Map.of("message", "文件上传成功", "fileId", archiveFile.getId())); } catch (IOException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(Map.of("error", "文件上传失败: " + e.getMessage())); } } @GetMapping("/download/{fileId}") public ResponseEntity downloadFile(@PathVariable Integer fileId) { ArchiveFile file = archiveFileRepository.findById(fileId).orElseThrow(); Path filePath = Paths.get(uploadDir + file.getFilePath()); Resource resource = new FileSystemResource(filePath); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getTitle() + "\"") .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource); } } ```

三、前端Vue管理系统开发

3.1 Vue项目初始化与依赖

创建Vue项目并安装必要依赖:

```bash npm create vue@latest archive-frontend cd archive-frontend npm install axios element-plus vue-router@4 pinia ```

档案管理系统社区案例:SpringBoot+Vue前后端分离实战指南

配置main.js

```javascript import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import router from './router' import { createPinia } from 'pinia' const app = createApp(App) app.use(ElementPlus) app.use(router) app.use(createPinia()) app.mount('app') ```

3.2 路由与状态管理配置

创建路由文件router/index.js

```javascript import { createRouter, createWebHistory } from 'vue-router' const routes = [ { path: '/', component: () => import('@/views/Login.vue') }, { path: '/dashboard', component: () => import('@/views/Dashboard.vue'), meta: { requiresAuth: true } }, { path: '/archive/upload', component: () => import('@/views/UploadArchive.vue'), meta: { requiresAuth: true } } ] const router = createRouter({ history: createWebHistory(), routes }) // 路由守卫:检查登录状态 router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (to.meta.requiresAuth && !token) { next('/') } else { next() } }) export default router ```

3.3 文件上传组件实现

创建UploadArchive.vue组件:

```vue ```

3.4 API请求封装

创建utils/axios.js

```javascript import axios from 'axios' import { ElMessage } from 'element-plus' const instance = axios.create({ baseURL: 'http://localhost:8080/api', timeout: 10000 }) // 请求拦截器:添加token instance.interceptors.request.use( config => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }, error => { return Promise.reject(error) } ) // 响应拦截器:统一处理错误 instance.interceptors.response.use( response => { return response.data }, error => { if (error.response?.status === 401) { localStorage.removeItem('token') window.location.href = '/' ElMessage.error('登录已过期,请重新登录') } else { ElMessage.error(error.response?.data?.message || '请求失败') } return Promise.reject(error) } ) export default instance ```

四、系统部署与优化

4.1 后端打包与部署

在SpringBoot项目根目录执行:

```bash mvn clean package -DskipTests ```

生成target/archive-system-0.0.1-SNAPSHOT.jar后,使用以下命令启动:

```bash nohup java -jar archive-system-0.0.1-SNAPSHOT.jar \ --spring.profiles.active=prod \ --server.port=8080 \ > app.log 2>&1 & ```

4.2 前端构建与Nginx配置

构建前端生产版本:

```bash npm run build ```

配置Nginx/etc/nginx/sites-available/archive

```nginx server { listen 80; server_name archive.yourdomain.com; location / { root /var/www/archive-frontend/dist; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /uploads/ { alias /data/archive_files/; expires 30d; } } ```

4.3 数据库索引优化

为提升查询性能,添加以下索引:

```sql -- 档案文件查询优化 CREATE INDEX idx_archive_category ON archive_files(category_id); CREATE INDEX idx_archive_uploader ON archive_files(uploader_id); CREATE FULLTEXT INDEX idx_archive_keywords ON archive_files(keywords); -- 用户登录优化 CREATE INDEX idx_user_username ON users(username); ```

4.4 文件存储安全配置

创建文件上传安全策略类FileSecurityConfig.java

```java @Configuration public class FileSecurityConfig { @Bean public ServletRegistrationBean fileServlet() { ServletRegistrationBean bean = new ServletRegistrationBean<>(new DefaultServlet(), "/uploads/"); bean.setLoadOnStartup(1); return bean; } @Bean public FilterRegistrationBean fileFilter() { FilterRegistrationBean bean = new FilterRegistrationBean<>(); bean.setFilter(new FileSecurityFilter()); bean.addUrlPatterns("/uploads/"); return bean; } } ```
AI咨询
热线电话

028-85154420

15388110056

全国售前咨询电话

扫码咨询
安答联动微信公众号二维码

微信扫码关注安答联动

申请试用
热线电话
申请试用

安答联动档案管理系统