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

淄博档案管理软件:手把手教你从零搭建本地化数字档案系统

发布时间:2026年08月30日 14:20:10 浏览量:0

一、环境准备与系统选型

淄博地区档案管理通常涉及文书、基建、设备、人事等多类档案,我们选择基于Python+Django+PostgreSQL的技术栈,这套组合成熟稳定且完全免费。

1.1 基础环境安装

在Ubuntu 20.04系统上执行以下命令:

```bash sudo apt update sudo apt install python3.8 python3-pip postgresql postgresql-contrib sudo apt install nginx supervisor ```

创建数据库用户和数据库:

```bash sudo -u postgres psql CREATE USER zibo_archive WITH PASSWORD 'YourSecurePassword123!'; CREATE DATABASE zibo_archive_db OWNER zibo_archive; \q ```

1.2 Django项目初始化

创建项目目录并安装依赖:

```bash mkdir -p /opt/zibo_archive cd /opt/zibo_archive python3 -m venv venv source venv/bin/activate pip install django==3.2.16 psycopg2-binary==2.9.5 django-crispy-forms==1.14.0 django-admin startproject archive_system . ```

二、核心数据模型设计

根据《淄博市档案管理条例》要求,设计符合地方规范的档案模型。

2.1 档案分类模型

在archive_system/archive/models.py中创建基础模型:

```python from django.db import models from django.contrib.auth.models import User class ArchiveCategory(models.Model): """淄博档案分类标准""" CATEGORY_TYPES = [ ('WS', '文书档案'), ('JJ', '基建档案'), ('SB', '设备档案'), ('RS', '人事档案'), ('KY', '科研档案'), ('CW', '财务档案'), ] code = models.CharField(max_length=10, unique=True, verbose_name='分类代码') name = models.CharField(max_length=100, verbose_name='分类名称') category_type = models.CharField(max_length=2, choices=CATEGORY_TYPES, verbose_name='档案类型') retention_years = models.IntegerField(verbose_name='保管期限(年)') description = models.TextField(blank=True, verbose_name='分类说明') class Meta: verbose_name = '档案分类' verbose_name_plural = '档案分类' ordering = ['code'] def __str__(self): return f"{self.code} - {self.name}" class ArchiveFile(models.Model): """档案文件核心模型""" STATUS_CHOICES = [ ('DRAFT', '草稿'), ('ACTIVE', '在用'), ('ARCHIVED', '已归档'), ('DESTROYED', '已销毁'), ] file_number = models.CharField(max_length=50, unique=True, verbose_name='档案编号') title = models.CharField(max_length=200, verbose_name='档案标题') category = models.ForeignKey(ArchiveCategory, on_delete=models.PROTECT, verbose_name='所属分类') keywords = models.CharField(max_length=300, verbose_name='关键词') abstract = models.TextField(verbose_name='内容摘要') create_date = models.DateField(verbose_name='形成日期') archive_date = models.DateField(auto_now_add=True, verbose_name='归档日期') retention_until = models.DateField(verbose_name='保管至') status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='DRAFT') created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name='created_files') last_modified = models.DateTimeField(auto_now=True) class Meta: verbose_name = '档案文件' verbose_name_plural = '档案文件' indexes = [ models.Index(fields=['file_number']), models.Index(fields=['category', 'create_date']), ] ```

2.2 文件存储模型

添加文件附件管理:

```python import os from django.conf import settings def archive_file_path(instance, filename): """按分类/年份/月份组织文件存储路径""" date = instance.archive_file.create_date return f"archives/{instance.archive_file.category.code}/{date.year}/{date.month:02d}/{filename}" class FileAttachment(models.Model): """档案附件""" archive_file = models.ForeignKey(ArchiveFile, on_delete=models.CASCADE, related_name='attachments') file = models.FileField(upload_to=archive_file_path, verbose_name='文件') original_name = models.CharField(max_length=255, verbose_name='原始文件名') file_size = models.BigIntegerField(verbose_name='文件大小(字节)') upload_time = models.DateTimeField(auto_now_add=True) description = models.CharField(max_length=500, blank=True, verbose_name='附件说明') def save(self, args, kwargs): if not self.original_name: self.original_name = os.path.basename(self.file.name) if not self.file_size and self.file: self.file_size = self.file.size super().save(args, kwargs) ```

三、业务功能实现

3.1 档案录入表单

创建archive_system/archive/forms.py:

```python from django import forms from .models import ArchiveFile, ArchiveCategory, FileAttachment from django.core.exceptions import ValidationError import datetime class ArchiveFileForm(forms.ModelForm): """档案录入表单""" attachments = forms.FileField( required=False, widget=forms.ClearableFileInput(attrs={'multiple': True}), label='附件上传' ) class Meta: model = ArchiveFile fields = ['file_number', 'title', 'category', 'keywords', 'abstract', 'create_date', 'retention_until'] widgets = { 'create_date': forms.DateInput(attrs={'type': 'date'}), 'retention_until': forms.DateInput(attrs={'type': 'date'}), 'abstract': forms.Textarea(attrs={'rows': 4}), } def clean_file_number(self): """验证档案编号唯一性""" file_number = self.cleaned_data['file_number'] if ArchiveFile.objects.filter(file_number=file_number).exists(): raise ValidationError('该档案编号已存在') return file_number def clean_retention_until(self): """验证保管期限""" create_date = self.cleaned_data.get('create_date') retention_until = self.cleaned_data.get('retention_until') if create_date and retention_until: category = self.cleaned_data.get('category') if category: expected_date = create_date + datetime.timedelta(days=category.retention_years365) if retention_until > expected_date: raise ValidationError(f'保管期限不能超过分类规定的{category.retention_years}年') return retention_until ```

3.2 视图处理逻辑

创建archive_system/archive/views.py:

```python from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from django.contrib import messages from django.db import transaction from .forms import ArchiveFileForm from .models import ArchiveFile, FileAttachment import os @login_required def create_archive(request): """创建档案""" if request.method == 'POST': form = ArchiveFileForm(request.POST, request.FILES) if form.is_valid(): try: with transaction.atomic(): archive = form.save(commit=False) archive.created_by = request.user archive.status = 'ACTIVE' archive.save() 处理附件 files = request.FILES.getlist('attachments') for file in files: FileAttachment.objects.create( archive_file=archive, file=file, original_name=file.name, file_size=file.size ) messages.success(request, f'档案 {archive.file_number} 创建成功') return redirect('archive_detail', pk=archive.pk) except Exception as e: messages.error(request, f'创建失败: {str(e)}') else: form = ArchiveFileForm() return render(request, 'archive/create.html', {'form': form}) @login_required def search_archive(request): """档案检索""" query = request.GET.get('q', '') category_id = request.GET.get('category', '') start_date = request.GET.get('start_date', '') end_date = request.GET.get('end_date', '') archives = ArchiveFile.objects.filter(status='ACTIVE') if query: archives = archives.filter( models.Q(title__icontains=query) | models.Q(keywords__icontains=query) | models.Q(abstract__icontains=query) | models.Q(file_number__icontains=query) ) if category_id: archives = archives.filter(category_id=category_id) if start_date: archives = archives.filter(create_date__gte=start_date) if end_date: archives = archives.filter(create_date__lte=end_date) return render(request, 'archive/search.html', { 'archives': archives, 'query': query }) ```

四、系统配置与部署

4.1 Django配置优化

修改archive_system/settings.py:

淄博档案管理软件:手把手教你从零搭建本地化数字档案系统

```python import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = 'django-insecure-your-secret-key-here' 生产环境必须更换 DEBUG = False 生产环境设为False ALLOWED_HOSTS = ['your-domain.com', 'localhost', '127.0.0.1'] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'zibo_archive_db', 'USER': 'zibo_archive', 'PASSWORD': 'YourSecurePassword123!', 'HOST': 'localhost', 'PORT': '5432', } } STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 文件上传限制 DATA_UPLOAD_MAX_MEMORY_SIZE = 10485760 10MB FILE_UPLOAD_MAX_MEMORY_SIZE = 10485760 10MB 会话配置 SESSION_COOKIE_AGE = 7200 2小时 SESSION_SAVE_EVERY_REQUEST = True 安全配置 SECURE_BROWSER_XSS_FILTER = True X_FRAME_OPTIONS = 'DENY' SECURE_CONTENT_TYPE_NOSNIFF = True ```

4.2 Nginx配置

创建/etc/nginx/sites-available/zibo_archive:

```nginx server { listen 80; server_name your-domain.com; location /static/ { alias /opt/zibo_archive/staticfiles/; expires 30d; } location /media/ { alias /opt/zibo_archive/media/; expires 30d; } location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; 文件上传超时设置 proxy_connect_timeout 300s; proxy_send_timeout 300s; proxy_read_timeout 300s; client_max_body_size 100m; } 限制访问频率 limit_req_zone $binary_remote_addr zone=archive:10m rate=10r/s; location ~ ^/api/ { limit_req zone=archive burst=20 nodelay; } } ```

4.3 Supervisor进程管理

创建/etc/supervisor/conf.d/zibo_archive.conf:

```ini [program:zibo_archive] command=/opt/zibo_archive/venv/bin/gunicorn archive_system.wsgi:application --bind 127.0.0.1:8000 --workers 3 directory=/opt/zibo_archive user=www-data autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/log/zibo_archive.log environment=PYTHONPATH="/opt/zibo_archive",DJANGO_SETTINGS_MODULE="archive_system.settings" ```

启动服务:

```bash sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start zibo_archive sudo systemctl restart nginx ```

五、数据备份与维护

5.1 自动化备份脚本

创建/opt/zibo_archive/backup.sh:

```bash !/bin/bash BACKUP_DIR="/backup/archive" DATE=$(date +%Y%m%d_%H%M%S) DB_BACKUP="$BACKUP_DIR/db_$DATE.sql" MEDIA_BACKUP="$BACKUP_DIR/media_$DATE.tar.gz" mkdir -p $BACKUP_DIR 备份数据库 sudo -u postgres pg_dump zibo_archive_db > $DB_BACKUP gzip $DB_BACKUP 备份媒体文件 tar -czf $MEDIA_BACKUP /opt/zibo_archive/media/ 删除7天前的备份 find $BACKUP_DIR -type f -mtime +7 -delete 记录日志 echo "$(date): Backup completed" >> /var/log/archive_backup.log ```

添加到crontab每天凌晨2点执行:

```bash 0 2 /bin/bash /opt/zibo_archive/backup.sh ```

5.2 定期维护任务

创建Django管理命令archive_system/archive/management/commands/archive_maintenance.py:

```python from django.core.management.base import BaseCommand from django.utils import timezone from archive.models import ArchiveFile import datetime class Command(BaseCommand): help = '执行档案系统定期维护任务' def handle(self, args, options): 标记过期档案 expired_count = ArchiveFile.objects.filter( status='ACTIVE', retention_until__lt=timezone.now().date() ).update(status='ARCHIVED') 清理临时文件(示例) self.stdout.write( self.style.SUCCESS( f'成功标记 {expired_count} 份过期档案' ) ) ```

添加到crontab每月1号执行:

```bash 0 3 1 /opt/zibo_archive/venv/bin/python manage.py archive_maintenance ```

六、权限控制与审计

6.1 基于角色的权限控制

在models.py中添加:

```python from django.contrib.auth.models import Group, Permission from django.db.models.signals import post_migrate from django.dispatch import receiver @receiver(post_migrate) def setup_default_groups(sender, kwargs): """创建默认用户组和权限""" groups_permissions = { '档案录入员': [ 'add_archivefile', 'change_archivefile', 'view_archivefile', ], '档案管理员': [ 'add_archivefile', 'change_archivefile', 'delete_archivefile', 'view_archivefile', 'add_archivecategory', 'change_archivecategory', ], '系统管理员': [ 'add_user', 'change_user', 'delete_user', 'view_user', ] } for group_name, perm_codenames in groups_permissions.items(): group, created = Group.objects.get_or_create(name=group_name) for codename in perm_codenames: try: perm = Permission.objects.get(codename=codename) group.permissions.add(perm) except Permission.DoesNotExist: continue group.save() ```

6.2 操作日志记录

创建操作日志模型:

```python class OperationLog(models.Model): """操作审计日志""" ACTION_CHOICES = [ ('CREATE', '创建'), ('UPDATE', '修改'), ('DELETE', '删除'), ('VIEW', '查看'), ('DOWNLOAD', '下载'), ] user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) action = models.CharField(max_length=20, choices=ACTION_CHOICES) model_name = models.CharField(max_length=100) object_id = models.CharField(max_length=100, blank=True) description = models.TextField() ip_address = models.GenericIPAddressField(null=True) timestamp = models.DateTimeField(auto_now_add=True) class Meta: verbose_name = '操作日志' verbose_name_plural = '操作日志' indexes = [ models.Index(fields=['user', 'timestamp']), models.Index(fields=['model_name', 'object_id']), ] def __str__(self): return f"{self.user} {self.action

工程企业技术档案管理乱?教你选对好用的技术档案管理软件
工程企业技术档案管理乱?教你选对好用的技术档案管理软件
做工程的朋友应该都有体会,技术档案管起来太头疼:纸质图纸发霉丢页,电子档散存在不同员工U盘、电脑里,项目验收要找资料的时候翻半天找不到,错拿旧版本图纸还容易出安全事故。现在越来越多企业开始用数字化工具...
2026年08月30日 14:20:10
档案软件培训讲师:教你从青铜到王者的通关秘籍
档案软件培训讲师:教你从青铜到王者的通关秘籍
嘿,朋友,最近是不是被“档案软件”这四个字搞得头大?感觉它就像个藏在深山里的武林秘籍,字都认识,连起来就懵圈?别慌,今天咱不整那些虚头巴脑的官方说明书,我就以一个过来人的身份,跟你唠唠怎么从看见“归档...
2026年08月30日 14:20:10
用好档案管理系统 帮企业打通可持续发展的任督二脉
用好档案管理系统 帮企业打通可持续发展的任督二脉
实不相瞒,我前5年在珠三角某中型制造企业当行政主管的时候,跟档案打了不下百次架,从一开始觉得“档案管理就是个没人管的边角活”,到现在逢人就说档案管理系统能促进可持续发展,中间踩的坑能绕公司库房三圈,今...
2026年08月30日 14:20:10
呼伦贝尔档案软件哪个好用?2024本地适配功能及选型避坑指南
呼伦贝尔档案软件哪个好用?2024本地适配功能及选型避坑指南
不少呼伦贝尔本地企事业单位、机关单位的档案管理岗人员,都吐槽过踩过通用档案软件的坑:要么不贴合牧区、边境单位的特色档案归集要求,二次开发成本高,要么售后没有本地团队,出问题好几天没人上门解决。本文结合...
2026年08月30日 14:20:10
微信咨询
电话联系
QQ客服
微信咨询一对一服务
服务热线: 028-8744 4417
QQ客服: 2305721818