feat(purchase): 采购批次号支持,同一批提交的记录可分组查看/统计

背景: 循环提交把一批物品生成多条独立申请,无法识别'哪些是同一批采购'

后端:
- purchase_request 模型新增 batch_no 字段(同一批提交共享)
- create 接口接收 batch_no,无则自动生成 BATCH-yyyyMMdd-HHmm-随机
- 新增 GET /purchase/batch/<batch_no> 按批次查询所有记录
- 批量审批接口支持按 batch_no 一键审批整批

前端:
- 提交时生成 batch_no 共享给所有行
- 列表新增批次号列(可点击)
- 新增'整批查看'弹窗:显示同批次所有记录 + 一键批量通过本批
- 操作列新增'整批'按钮

数据库需执行: ALTER TABLE purchase_request ADD COLUMN batch_no VARCHAR(100);
This commit is contained in:
yueli
2026-08-31 13:46:46 +08:00
parent 4b62c81baa
commit 664127ee30
5 changed files with 183 additions and 6 deletions

View File

@ -157,6 +157,38 @@ def get_purchase_detail(purchase_id):
return jsonify({'code': 500, 'msg': str(e)}), 500
# --------------------------------------------------------
# 3.5 按批次查询采购申请(同一批提交的多条记录)
# GET /api/v1/purchase/batch/<batch_no>
# --------------------------------------------------------
@purchase_bp.route('/batch/<path:batch_no>', methods=['GET'])
@jwt_required()
def get_purchase_by_batch(batch_no):
"""按批次号查询同一批提交的所有采购申请记录"""
try:
from app.models.purchase import PurchaseRequest
records = PurchaseRequest.query.filter(
PurchaseRequest.batch_no == batch_no
).order_by(PurchaseRequest.id.asc()).all()
user_id = get_current_user_id()
has_perm = _user_has_purchase_perm()
items = []
for r in records:
d = r.to_dict()
# 非本人且无权限时,价格字段剥离
if d['requester_id'] != user_id and not has_perm:
for k in ('unit_price', 'total_price', 'tax_rate'):
d.pop(k, None)
items.append(d)
return jsonify({'code': 200, 'msg': '获取成功', 'data': {'batch_no': batch_no, 'items': items}}), 200
except Exception as e:
traceback.print_exc()
return jsonify({'code': 500, 'msg': str(e)}), 500
# --------------------------------------------------------
# 4. 审批采购申请
# PATCH /api/v1/purchase/<id>/approve
@ -214,7 +246,9 @@ def batch_approve_purchase():
请求体:
{
"ids": [1, 2, 3],
"ids": [1, 2, 3], // 按 ID 列表审批
或
"batch_no": "BATCH-xxx", // 按批次号审批整批(同一批提交的记录)
"action": "approve" | "reject",
"reject_reason": "驳回原因(reject 时必填)"
}
@ -223,11 +257,23 @@ def batch_approve_purchase():
user_id = get_current_user_id()
data = request.get_json() or {}
ids = data.get('ids', [])
batch_no = data.get('batch_no')
action = data.get('action', 'approve')
reject_reason = data.get('reject_reason')
# 若传 batch_no,则查出该批次的所有待审批记录 ID
if batch_no:
from app.models.purchase import PurchaseRequest
records = PurchaseRequest.query.filter(
PurchaseRequest.batch_no == batch_no,
PurchaseRequest.status == 0
).all()
ids = [r.id for r in records]
if not ids:
return jsonify({'code': 400, 'msg': '该批次没有待审批的记录'}), 400
if not ids or not isinstance(ids, list):
return jsonify({'code': 400, 'msg': 'ids 不能为空'}), 400
return jsonify({'code': 400, 'msg': 'ids 或 batch_no 不能为空'}), 400
if action not in ('approve', 'reject'):
return jsonify({'code': 400, 'msg': '无效的审批操作'}), 400
if action == 'reject' and not reject_reason: