feat: Redis幂等锁 + 关键端点防重复提交
## decorators.py
- 新增 @prevent_double_submit(lock_timeout=5) 装饰器
Redis key: idem:{user_id}:{path}:{MD5(body)}
锁存在→409, 不存在→setex→执行业务→delete
Redis不可用时fail-open降级放行
## purchase.py
- POST /purchase (创建): +@prevent_double_submit
- PATCH /purchase/<id>/approve (审批): +@prevent_double_submit
## outbound.py
- POST /outbound (出库): +@prevent_double_submit
## transactions.py
- POST /borrow/dispatch (借库扣减): +@prevent_double_submit
This commit is contained in:
@ -2,7 +2,7 @@ import traceback
|
||||
from flask import Blueprint, request, jsonify, current_app
|
||||
from flask_jwt_extended import jwt_required, get_jwt, get_jwt_identity
|
||||
from app.services.purchase_service import PurchaseService
|
||||
from app.utils.decorators import permission_required
|
||||
from app.utils.decorators import permission_required, prevent_double_submit
|
||||
|
||||
purchase_bp = Blueprint('purchase', __name__, url_prefix='/api/v1/purchase')
|
||||
|
||||
@ -70,6 +70,7 @@ def get_purchase_list():
|
||||
# --------------------------------------------------------
|
||||
@purchase_bp.route('', methods=['POST'])
|
||||
@jwt_required()
|
||||
@prevent_double_submit(lock_timeout=5)
|
||||
def create_purchase_request():
|
||||
"""创建采购申请(任何登录用户可提交)"""
|
||||
try:
|
||||
@ -138,6 +139,7 @@ def get_purchase_detail(purchase_id):
|
||||
# --------------------------------------------------------
|
||||
@purchase_bp.route('/<int:purchase_id>/approve', methods=['PATCH'])
|
||||
@jwt_required()
|
||||
@prevent_double_submit(lock_timeout=5)
|
||||
@permission_required('inbound_purchase:operation')
|
||||
def approve_purchase_request(purchase_id):
|
||||
"""审批采购申请:必须有操作权限(inbound_purchase:operation)"""
|
||||
|
||||
Reference in New Issue
Block a user