政府版档案管理系统对数据安全性、追溯性及稳定性要求极高。本指南采用 Spring Boot 2.7 + Vue 2.6 + MySQL 5.7 架构,这套组合经过长期验证,适合快速落地且符合信创环境基本要求。在开始编码前,必须严格统一开发环境版本,避免因依赖冲突导致启动失败。
首先检查本地环境,打开终端执行以下命令确认版本:
若环境未就绪,请直接下载并解压对应安装包。配置 Maven 的 settings.xml,添加阿里云镜像源以确保依赖下载速度:
```xml数据库设计必须符合等保要求,包含基础信息表、安全日志表及文件存储表。登录 MySQL 客户端,执行以下脚本创建数据库及核心表结构。请务必使用 UTF8MB4 字符集以支持特殊字符及生僻字存储。
```sql CREATE DATABASE IF NOT EXISTS gov_archive_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE gov_archive_db; -- 档案主表 CREATE TABLE `sys_archive` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `archive_no` varchar(64) NOT NULL COMMENT '档案编号,唯一索引', `title` varchar(255) NOT NULL COMMENT '档案标题', `category` varchar(50) NOT NULL COMMENT '档案分类', `security_level` tinyint(2) NOT NULL DEFAULT '1' COMMENT '密级:1-公开,2-内部,3-秘密,4-机密', `file_path` varchar(500) DEFAULT NULL COMMENT '物理存储路径', `file_size` bigint(20) DEFAULT '0' COMMENT '文件大小(字节)', `creator` varchar(50) NOT NULL COMMENT '创建人', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_archive_no` (`archive_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='档案信息主表'; -- 操作审计日志表(政府版必备) CREATE TABLE `sys_audit_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `module` varchar(50) NOT NULL COMMENT '操作模块', `operation_type` varchar(20) NOT NULL COMMENT '操作类型:UPLOAD/DOWNLOAD/DELETE', `user_name` varchar(50) NOT NULL COMMENT '操作人', `ip_address` varchar(50) NOT NULL COMMENT '来源IP', `status` tinyint(2) NOT NULL COMMENT '状态:0-失败,1-成功', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='安全审计日志'; ```使用 Spring Initializr 生成项目,勾选 Web, MyBatis, MySQL Driver, Lombok。在 pom.xml 中追加文件上传及通用工具包依赖:
```xml配置 application.yml,这是系统运行的神经中枢,必须精确配置文件大小限制和数据库连接参数:
```yaml server: port: 8080 spring: servlet: multipart: max-file-size: 500MB max-request-size: 500MB enabled: true datasource: url: jdbc:mysql://localhost:3306/gov_archive_db?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/.xml type-aliases-package: com.gov.archive.entity ```
创建实体类 SysArchive.java,使用 Lombok 注解简化代码。重点在于 Controller 层的实现,这里需要处理文件流、生成唯一编号以及记录审计日志。
在 src/main/resources/mapper 下创建 SysArchiveMapper.xml:
```xml编写 ArchiveController.java,实现文件上传接口。注意,政府版系统必须对上传文件进行重命名处理,防止路径遍历攻击:
```java @RestController @RequestMapping("/api/archive") public class ArchiveController { @Value("${upload.path:/tmp/gov_archive}") private String uploadPath; @Autowired private SysArchiveMapper archiveMapper; @PostMapping("/upload") public Map前端使用 Vue 2 配合 Element UI,能够快速构建符合政府审美风格的界面。初始化项目后,在 main.js 中引入 Element UI:
```javascript import Vue from 'vue' import App from './App.vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import axios from 'axios' Vue.prototype.$http = axios Vue.use(ElementUI) new Vue({ render: h => h(App) }).$mount('app') ```编写 ArchiveUpload.vue 组件。核心在于利用 Element UI 的 el-upload 组件,并将 http-request 属性覆盖为自定义的 Axios 上传方法,以便携带额外的业务参数(如密级、标题):
```html普通文件系统只需存取即可,政府版必须实现防篡改与水印溯源。在下载文件时,后端应动态添加水印。
在 ArchiveController 中增加下载接口,使用 Hutool 的 ImgUtil 或 PDF 处理工具为文件添加用户名水印:
```java @GetMapping("/download/{id}") public void download(@PathVariable Long id, HttpServletResponse response, HttpServletRequest request) { // 1. 查询档案信息 SysArchive archive = archiveMapper.selectById(id); if (archive == null) return; // 2. 验证权限(此处省略具体权限校验代码) String currentUser = "admin"; // 模拟当前用户 try { File file = new File(archive.getFilePath()); // 3. 政府版特性:下载前生成带水印的临时文件 File watermarkedFile = applyWatermark(file, currentUser); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=" + new String(archive.getTitle().getBytes("UTF-8"), "ISO-8859-1")); // 4. 流式输出 ServletOutputStream out = response.getOutputStream(); out.write(FileUtils.readFileToByteArray(watermarkedFile)); out.flush(); // 5. 记录日志 saveLog("DOWNLOAD", currentUser, request.getRemoteAddr(), 1); // 清理临时文件 if(watermarkedFile.exists()) watermarkedFile.delete(); } catch (IOException e) { e.printStackTrace(); } } private File applyWatermark(File sourceFile, String user) throws IOException { // 简单示例:实际需判断文件类型,PDF使用PdfBox,图片使用ImgUtil String destPath = sourceFile.getAbsolutePath() + ".tmp"; // 模拟水印处理逻辑... return new File(destPath); } ```