第一步:开发环境准备与依赖安装
本系统基于Python Flask框架开发,轻量级且易于部署,适合作为企业内部档案管理工具。首先确保你的系统中已安装Python 3.8及以上版本。
打开终端或命令提示符,执行以下命令创建项目目录并安装核心依赖库。Flask用于Web服务,Flask-SQLAlchemy用于数据库操作,Flask-WTF用于表单验证。
```bash
mkdir license_archive_system
cd license_archive_system
pip install flask flask-sqlalchemy flask-wtf python-dateutil
```
安装完成后,在项目根目录下创建以下文件夹结构,用于规范代码组织:
- static/:存放CSS、JS及上传的许可证扫描件。
- templates/:存放HTML模板文件。
- uploads/:专门用于存储用户上传的附件。
- app.py:主程序入口文件。
- config.py:配置文件。
第二步:数据库模型设计与配置
使用SQLite作为数据库,无需额外安装数据库服务,文件即数据库。创建config.py文件,写入以下配置代码,定义数据库路径和上传文件夹路径:
```python
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
设置SQLite数据库URI
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'licenses.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
禁止CSRF保护以简化API测试,生产环境建议开启
SECRET_KEY = 'dev-secret-key-change-in-production'
文件上传配置
UPLOAD_FOLDER = os.path.join(basedir, 'uploads')
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'pdf'}
```
接下来在app.py中初始化数据库并定义数据模型。我们需要存储许可证编号、制作单位名称、有效期、发证机关以及扫描件路径。
```python
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import os
from config import Config
app = Flask(__name__)
app.config.from_object(Config)
确保上传目录存在
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
db = SQLAlchemy(app)
定义数据库模型
class License(db.Model):
id = db.Column(db.Integer, primary_key=True)
license_no = db.Column(db.String(50), unique=True, nullable=False) 许可证编号
company_name = db.Column(db.String(100), nullable=False) 制作单位
scope = db.Column(db.Text, nullable=True) 经营范围
issue_date = db.Column(db.Date, nullable=True) 发证日期
expire_date = db.Column(db.Date, nullable=True) 有效期至
issuer = db.Column(db.String(100), nullable=True) 发证机关
file_path = db.Column(db.String(200), nullable=True) 扫描件路径
created_at = db.Column(db.DateTime, default=datetime.now) 档案录入时间
def __repr__(self):
return f'
'
```
第三步:核心业务逻辑实现
在app.py中继续添加辅助函数和路由逻辑。我们需要实现文件上传校验、许可证的增删改查(CRUD)功能。
首先添加文件上传校验函数和数据库初始化命令:
```python
辅助函数:校验文件扩展名
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
路由:首页,显示所有许可证列表
@app.route('/')
def index():
licenses = License.query.order_by(License.expire_date.desc()).all()
return render_template('index.html', licenses=licenses)
路由:新增/编辑页面
@app.route('/form', methods=['GET', 'POST'])
@app.route('/form/', methods=['GET', 'POST'])
def form(id=None):
license = License.query.get(id) if id else None
if request.method == 'POST':
获取表表单数据
license_no = request.form.get('license_no')
company_name = request.form.get('company_name')
scope = request.form.get('scope')
issue_date = datetime.strptime(request.form.get('issue_date'), '%Y-%m-%d').date() if request.form.get('issue_date') else None
expire_date = datetime.strptime(request.form.get('expire_date'), '%Y-%m-%d').date() if request.form.get('expire_date') else None
issuer = request.form.get('issuer')
处理文件上传
file_path = license.file_path if license else None
if 'file' in request.files:
file = request.files['file']
if file and allowed_file(file.filename):
filename = f"{license_no}_{file.filename}"
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
file_path = filename
if license:
更新逻辑
license.license_no = license_no
license.company_name = company_name
license.scope = scope
license.issue_date = issue_date
license.expire_date = expire_date
license.issuer = issuer
license.file_path = file_path
flash('档案更新成功')
else:
新增逻辑
new_license = License(
license_no=license_no,
company_name=company_name,
scope=scope,
issue_date=issue_date,
expire_date=expire_date,
issuer=issuer,
file_path=file_path
)
db.session.add(new_license)
flash('档案添加成功')
db.session.commit()
return redirect(url_for('index'))
return render_template('form.html', license=license)
路由:删除档案
@app.route('/delete/')
def delete(id):
license = License.query.get(id)
if license:
删除关联文件
if license.file_path and os.path.exists(os.path.join(app.config['UPLOAD_FOLDER'], license.file_path)):
os.remove(os.path.join(app.config['UPLOAD_FOLDER'], license.file_path))
db.session.delete(license)
db.session.commit()
flash('档案已删除')
return redirect(url_for('index'))
if __name__ == '__main__':
with app.app_context():
db.create_all() 自动创建数据库表
app.run(debug=True, port=5000)
```
第四步:前端页面模板开发

在templates目录下创建base.html作为基础模板,引入Bootstrap 5以保证界面整洁。不需要编写复杂的CSS,直接使用Bootstrap类名即可。
```html
广电许可证档案管理系统
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
{{ message }}
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
```
创建index.html用于展示档案列表。包含一个“新增档案”按钮和展示所有记录的表格,表格中包含编辑和删除操作。
```html
{% extends "base.html" %}
{% block content %}
| 许可证编号 |
制作单位 |
有效期至 |
发证机关 |
扫描件 |
操作 |
{% for item in licenses %}
| {{ item.license_no }} |
{{ item.company_name }} |
{{ item.expire_date.strftime('%Y-%m-%d') if item.expire_date else '-' }}
{% if item.expire_date and item.expire_date < today() %}
已过期
{% endif %}
|
{{ item.issuer }} |
{% if item.file_path %}
查看文件
{% else %}
无
{% endif %}
|
编辑
删除
|
{% else %}
| 暂无档案数据 |
{% endfor %}
{% endblock %}
```
创建form.html用于录入和编辑信息。使用HTML5的input type="date"来方便选择日期,使用input type="file"上传附件。
```html
{% extends "base.html" %}
{% block content %}
{{ '编辑档案' if license else '新增档案' }}
{% endblock %}
```
第五步:系统运行与功能验证
所有代码文件就绪后,回到终端执行以下命令启动系统:
```bash
python app.py
```
看到输出Running on http://127.0.0.1:5000即代表启动成功。打开浏览器访问该地址。
验证步骤:
- 点击右上角“+ 新增档案”,输入完整的许可证信息,上传一张测试图片,点击保存。
- 确认页面跳转回列表页,且新数据正确显示在表格中。
- 点击“查看文件”链接,确认能正确打开上传的图片。
- 点击“编辑”,修改有效期并保存,确认数据已更新。
- 点击“删除”,确认记录及关联文件被移除。
此时,一个轻量级、零成本、功能完备的广播电视节目制作经营许可证档案管理系统已搭建完成。数据存储在本地licenses.db文件中,扫描件存储在uploads文件夹中,完全满足中小企业对于敏感资质档案的本地化管理需求。