这个在线招标投标系统是我去年为一个建筑行业协会开发的实战项目,核心目标是解决传统纸质招投标流程效率低下、透明度不足的问题。系统上线后,成功将招投标周期从平均28天缩短到7天,投标方参与成本降低60%。下面我会从技术选型到具体实现,完整还原这个Django项目的开发过程。
选择Django作为后端框架主要基于三个实际考量:
前端采用Bootstrap+Vue.js混合架构:
MySQL表设计特别注意了以下约束:
sql复制CREATE TABLE bid_projects (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
project_no VARCHAR(32) UNIQUE NOT NULL COMMENT '项目编号规则:年+月+类型+序号',
title VARCHAR(200) NOT NULL,
budget DECIMAL(12,2) CHECK (budget >= 0),
deadline DATETIME NOT NULL,
status ENUM('draft','published','bidding','evaluating','completed') NOT NULL DEFAULT 'draft',
creator_id BIGINT NOT NULL,
FOREIGN KEY (creator_id) REFERENCES auth_user(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
招标发布的关键代码逻辑:
python复制class ProjectPublishView(LoginRequiredMixin, View):
def post(self, request):
form = ProjectForm(request.POST, request.FILES)
if form.is_valid():
project = form.save(commit=False)
project.creator = request.user
project.project_no = generate_project_no()
# 文件加密存储
if 'attachment' in request.FILES:
project.attachment = encrypt_upload(
request.FILES['attachment'],
key=settings.FILE_ENCRYPT_KEY
)
project.save()
# 异步生成招标文件水印版本
add_watermark_task.delay(project.id)
return JsonResponse({'code': 0})
return JsonResponse({'code': 1, 'errors': form.errors})
投标文件处理采用双重保障:
python复制def validate_bid_submission(bid):
if bid.project.status != 'bidding':
raise ValidationError("当前不在投标期")
if bid.bidder.balance < bid.project.deposit:
raise ValidationError("保证金不足")
if datetime.now() > bid.project.deadline:
raise ValidationError("已超过投标截止时间")
采用分层加密策略:
加密工具类示例:
python复制from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
class FileEncryptor:
def __init__(self, key):
self.key = hashlib.sha256(key.encode()).digest()
def encrypt_file(self, file):
iv = os.urandom(16)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return iv + cipher.encrypt(pad(file.read(), AES.block_size))
def decrypt_file(self, encrypted):
iv = encrypted[:16]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(encrypted[16:]), AES.block_size)
针对开标时的高并发场景:
python复制DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'master.db.example.com',
...
},
'replica': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'slave.db.example.com',
...
}
}
基于Django Guardian实现细粒度权限:
python复制@permission_required('bid.change_project', (Project, 'id', 'pk'))
def edit_project(request, pk):
project = get_object_or_404(Project, pk=pk)
...
自定义数据库日志处理器:
python复制class DatabaseLogHandler(logging.Handler):
def emit(self, record):
try:
AuditLog.objects.create(
user=getattr(record, 'user', None),
ip=getattr(record, 'ip', ''),
action=record.getMessage(),
extra=record.__dict__
)
except Exception:
pass
Nginx关键配置:
nginx复制location /protected/ {
internal;
alias /var/encrypted_files/;
# 文件下载限速
limit_rate 500k;
# 授权检查
auth_request /auth-check;
}
使用Prometheus+Grafana监控:
解决方案:
原始代码问题:
python复制# 错误示例:存在时间差
if datetime.now() < project.deadline:
accept_bid()
修复方案:
python复制# 使用数据库原子操作
with transaction.atomic():
project = Project.objects.select_for_update().get(pk=pid)
if datetime.now() < project.deadline:
accept_bid()
这个项目让我深刻体会到,招投标系统的核心不是技术复杂度,而是对业务规则的理解和实现。特别是在时间控制、文件安全等方面,必须与法律要求保持完全一致。建议开发类似系统时,最好有法务人员全程参与评审。