为了满足数字档案管理办法中对元数据管理、权限控制及日志审计的严格要求,我们将采用Python Flask作为后端框架,Vue.js作为前端框架,MySQL作为核心数据存储。这套组合轻量且成熟,适合快速落地。
在终端中执行以下命令,创建项目目录并安装核心依赖包。请确保你的系统已安装Python 3.8及以上版本。
创建项目文件夹
mkdir digital_archive_system
cd digital_archive_system
创建并激活虚拟环境
python -m venv venv
source venv/bin/activate Windows用户使用 venv\Scripts\activate
安装后端核心依赖
pip install flask flask-sqlalchemy flask-cors pymysql python-dotopen
在项目根目录下创建requirements.txt,内容如下,以便后续复现环境:
flask==2.3.2
flask-sqlalchemy==3.0.5
flask-cors==4.0.0
pymysql==1.1.0
python-dotopen==1.0.0
cryptography==41.0.0
数字档案管理办法要求数据不可丢失且结构严谨。请确保本地已安装MySQL服务,执行以下SQL语句创建专用数据库:
CREATE DATABASE digital_archive_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
根据档案管理标准,我们需要设计包含“档案实体”、“分类元数据”和“操作日志”的数据模型。在根目录下创建app.py文件,并写入以下完整代码。
这部分代码定义了档案的核心字段,包括档号、题名、责任者、保管期限等关键元数据,确保符合归档规范。
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from datetime import datetime
import os
app = Flask(__name__)
CORS(app) 允许跨域请求
配置数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:你的密码@localhost/digital_archive_db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['UPLOAD_FOLDER'] = './uploads'
确保上传目录存在
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
db = SQLAlchemy(app)
档案分类模型(符合管理办法中的实体分类要求)
class Category(db.Model):
__tablename__ = 'categories'
id = db.Column(db.Integer, primary_key=True)
code = db.Column(db.String(50), unique=True, nullable=False) 分类代码
name = db.Column(db.String(100), nullable=False) 分类名称
数字档案实体模型
class Archive(db.Model):
__tablename__ = 'archives'
id = db.Column(db.Integer, primary_key=True)
archive_code = db.Column(db.String(50), unique=True, nullable=False) 档号
title = db.Column(db.String(200), nullable=False) 题名
responsible_person = db.Column(db.String(100)) 责任者
category_code = db.Column(db.String(50), db.ForeignKey('categories.code')) 关联分类
retention_period = db.Column(db.String(20)) 保管期限(永久/长期/短期)
security_level = db.Column(db.String(20)) 密级(公开/内部/机密)
file_path = db.Column(db.String(255)) 电子文件存储路径
created_at = db.Column(db.DateTime, default=datetime.now) 归档日期
操作日志模型(管理办法要求的全过程审计)
class AuditLog(db.Model):
__tablename__ = 'audit_logs'
id = db.Column(db.Integer, primary_key=True)
user_name = db.Column(db.String(50))
action = db.Column(db.String(50)) 操作类型:上传/查阅/下载/销毁
target_id = db.Column(db.Integer) 操作对象ID
timestamp = db.Column(db.DateTime, default=datetime.now)
初始化数据库表
with app.app_context():
db.create_all()
此接口处理文件流接收、元数据校验及数据库入库。这是系统最核心的写入操作。
@app.route('/api/upload', methods=['POST'])
def upload_archive():
try:
获取表单数据
file = request.files['file']
metadata = request.form
基础校验
if not file or not metadata.get('archive_code'):
return jsonify({'error': '缺少文件或档号'}), 400
保存文件
filename = f"{metadata['archive_code']}_{file.filename}"
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(file_path)
写入数据库
new_archive = Archive(
archive_code=metadata['archive_code'],
title=metadata['title'],
responsible_person=metadata['responsible_person'],
category_code=metadata['category_code'],
retention_period=metadata['retention_period'],
security_level=metadata['security_level'],
file_path=file_path
)
db.session.add(new_archive)
记录审计日志
log = AuditLog(user_name='admin', action='UPLOAD', target_id=new_archive.id)
db.session.add(log)
db.session.commit()
return jsonify({'message': '归档成功', 'id': new_archive.id}), 201
except Exception as e:
db.session.rollback()
return jsonify({'error': str(e)}), 500
提供基于关键词和分类的组合查询功能,并自动记录查阅日志以满足审计要求。

@app.route('/api/archives', methods=['GET'])
def get_archives():
keyword = request.args.get('keyword', '')
category = request.args.get('category', '')
query = Archive.query
if keyword:
query = query.filter(Archive.title.like(f'%{keyword}%'))
if category:
query = query.filter(Archive.category_code == category)
results = query.all()
序列化结果
data = [{
'id': r.id,
'archive_code': r.archive_code,
'title': r.title,
'responsible_person': r.responsible_person,
'created_at': r.created_at.strftime('%Y-%m-%d %H:%M:%S')
} for r in results]
return jsonify(data), 200
if __name__ == '__main__':
app.run(debug=True, port=5000)
为了实现零门槛操作,我们将使用Vue 3构建一个简洁的上传和检索界面。请在项目根目录下创建frontend目录并初始化。
cd frontend
npm create vue@latest . -- --typescript false --jsx false
npm install
npm install axios element-plus 安装HTTP库和UI组件库
修改frontend/src/App.vue,直接替换为以下代码。该代码集成了Element Plus的表单和上传组件,实现了文件拖拽上传和元数据填写。
数字档案归档系统
档案录入
点击或拖拽文件到此处上传
档案检索
查询
修改frontend/src/main.js,确保Element Plus被正确全局引入,否则上述UI组件无法显示。
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
)
至此,所有代码已编写完毕。现在启动服务进行全流程验证。
在项目根目录下打开终端,激活虚拟环境并运行Flask应用。
确保在 digital_archive_system 目录下
source venv/bin/activate Windows: venv\Scripts\activate
python app.py
当终端显示Running on http://127.0.0.1:5000时,表示后端API已就绪,且数据库表已自动创建。
在frontend目录下打开新的终端窗口,启动Vue开发服务器。
cd frontend
npm run dev
终端会输出一个Local地址,通常是http://localhost:5173。使用浏览器访问该地址。
在浏览器界面中进行以下操作,验证系统是否符合数字档案管理办法的业务闭环:
audit_logs表,确认是否有对应的“UPLOAD”操作记录,确保满足管理办法对留痕的要求。-- 数据库审计查询SQL
SELECT FROM digital_archive_db.audit_logs ORDER BY timestamp DESC;