当你发现标准版档案管理系统功能不足时,直接更换核心系统成本高昂且风险大。更务实的技术路径是:在现有系统基础上进行扩展。这通常源于三个核心需求:数据字段不匹配、业务流程无法自定义、或缺少特定报表与集成接口。
你需要明确扩展的边界:
针对这些需求,我们采用“外挂式扩展”方案,即不直接修改标准版核心代码,而是通过建立独立的扩展应用,通过API与数据库视图与原系统交互。这样做的好处是:不影响原系统升级、技术栈可自由选择、风险隔离。
我们以最常见的场景为例:为标准版档案系统增加“借阅到期自动提醒”和“自定义档案标签”功能。技术栈选用Python + Django(后端)与Vue.js(前端),因其生态丰富、上手快。
在服务器上创建独立的工作目录,与原系统分开部署。
创建并进入项目目录
mkdir archive_extension && cd archive_extension
创建Python虚拟环境
python -m venv venv
source venv/bin/activate Linux/macOS
或 venv\Scripts\activate Windows
安装核心依赖
pip install django django-rest-framework celery psycopg2
绝大多数标准版系统使用关系型数据库。你需要从原系统运维人员处获取只读数据库用户权限和连接信息。在Django的`settings.py`中配置数据库连接:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql', 根据实际情况修改
'NAME': 'original_archive_db',
'USER': 'readonly_user', 务必使用只读账号
'PASSWORD': 'your_secure_password',
'HOST': '192.168.1.100', 原数据库地址
'PORT': '5432',
},
'extension': {
'ENGINE': 'django.db.backends.sqlite3', 扩展数据存本地
'NAME': BASE_DIR / 'db.sqlite3',
}
}
关键点:使用只读账号连接原库,所有新增、修改数据都写入本地`extension`库,通过API回写原系统,保证数据安全。
在Django应用中创建`models.py`,定义扩展数据表。这里假设原系统档案主表名为`archive_document`。
from django.db import models
class CustomTag(models.Model):
"""自定义标签表,独立存储"""
name = models.CharField(max_length=50, unique=True)
color = models.CharField(max_length=7, default='007bff') 颜色代码
class DocumentTagRelation(models.Model):
"""档案与标签关联表,关键字段是原系统档案ID"""
original_document_id = models.IntegerField() 对应原系统archive_document.id
tag = models.ForeignKey(CustomTag, on_delete=models.CASCADE)
created_time = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('original_document_id', 'tag') 防止重复关联
由于不能直接修改原表,我们通过Django的ORM管理原表映射,并关联扩展数据。
使用Django的`inspectdb`工具基于原数据库表生成模型(仅供参考,不用于迁移):

python manage.py inspectdb --database=default archive_document > reference_models.py
创建自定义的管理器,实现联合查询。在`views.py`中:
from django.db import connections
from rest_framework.views import APIView
from rest_framework.response import Response
import json
class EnhancedDocumentList(APIView):
"""获取档案列表,并附加上自定义标签"""
def get(self, request):
1. 从原系统查询档案基础信息(使用原始SQL或配置的ORM)
with connections['default'].cursor() as cursor:
cursor.execute("""
SELECT id, title, file_number, creator, create_date
FROM archive_document
WHERE status = 'active'
ORDER BY create_date DESC
LIMIT 100
""")
columns = [col[0] for col in cursor.description]
original_docs = [dict(zip(columns, row)) for row in cursor.fetchall()]
2. 从扩展库查询这些档案的标签
doc_ids = [doc['id'] for doc in original_docs]
这里假设已导入DocumentTagRelation模型
from .models import DocumentTagRelation
tag_relations = DocumentTagRelation.objects.filter(
original_document_id__in=doc_ids
).select_related('tag')
3. 合并数据
tag_map = {}
for rel in tag_relations:
doc_id = rel.original_document_id
if doc_id not in tag_map:
tag_map[doc_id] = []
tag_map[doc_id].append({'name': rel.tag.name, 'color': rel.tag.color})
for doc in original_docs:
doc['custom_tags'] = tag_map.get(doc['id'], [])
return Response(original_docs)
首先配置Celery。在项目根目录创建`celery.py`:
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'archive_extension.settings')
app = Celery('archive_extension')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
在`settings.py`末尾添加:
Celery配置
CELERY_BROKER_URL = 'redis://localhost:6379/0' 需要安装Redis
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_BEAT_SCHEDULE = {
'check-borrow-due-everyday-9am': {
'task': 'your_app.tasks.check_borrow_due',
'schedule': crontab(hour=9, minute=0), 每天上午9点执行
},
}
创建任务文件`tasks.py`:
from celery import shared_task
from django.core.mail import send_mail
from django.db import connections
@shared_task
def check_borrow_due():
"""查询即将到期的借阅记录并发送邮件提醒"""
1. 查询原系统借阅表(假设表名为archive_borrow)
with connections['default'].cursor() as cursor:
cursor.execute("""
SELECT b.id, d.title, b.borrower_email, b.due_date
FROM archive_borrow b
JOIN archive_document d ON b.document_id = d.id
WHERE b.status = 'borrowed'
AND b.due_date BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL '2 days'
""")
columns = [col[0] for col in cursor.description]
due_soon_records = [dict(zip(columns, row)) for row in cursor.fetchall()]
2. 发送提醒邮件
for record in due_soon_records:
subject = f"档案借阅到期提醒:{record['title']}"
message = f"""
您好,
您借阅的档案《{record['title']}》即将到期。
到期日期:{record['due_date'].strftime('%Y-%m-%d')}
请及时归还或办理续借。
档案管理系统
"""
send_mail(
subject,
message,
'noreply@yourcompany.com',
[record['borrower_email']],
fail_silently=False,
)
return f"已处理 {len(due_soon_records)} 条到期提醒"
启动Celery:在项目目录下打开两个终端,分别执行:
终端1:启动Worker
celery -A archive_extension worker --loglevel=info
终端2:启动定时任务调度器
celery -A archive_extension beat --loglevel=info
创建前端组件`TagManager.vue`,用于管理档案标签:
档案自定义标签管理
{{ doc.title }}
{{ tag.name }}
在后端为这个前端组件提供对应的API接口(使用Django REST Framework),代码略。
完成开发后,将扩展应用部署到与原系统网络联通的服务器。
DATABASES['default']['CONN_MAX_AGE'] = 300 连接保持300秒当扩展应用需要修改原系统数据时(如更新档案状态),必须通过原系统提供的官方API(如果有)。若没有,则在原系统数据库中创建专用的存储过程或API,由扩展应用调用,切勿直接写表。
在扩展应用中集成日志记录,监控任务执行状态和API调用情况。
settings.py 日志配置
LOGGING = {
'version': 1,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/var/log/archive_extension.log',
},
},
'loggers': {
'your_app': {
'handlers': ['file'],
'level': 'INFO',
},
},
}
遵循以上步骤,你可以在不触碰标准版档案系统核心代码的前提下,经济、安全、可控地实现功能扩展。所有新增功能都存在于独立的应用中,维护和升级互不干扰,真正实现“缺什么,补什么”。