feat(borrow): 新增「待我接收」转交数量接口

GET /api/v1/transactions/borrow/transfer/pending-count -> { count: X }

用途:双向握手引入后,发起方提交了转交,接收人若不来借还记录页主动查看就
完全处于盲区 —— 物品挂着「待接收」,责任悬空。该接口供前端做全局强提醒。

设计
----
· 刻意做成极轻量:一次 count,不联表、不解析物料名。轮询接口必须便宜,
  否则会从「提醒」变成「后台噪音」。
· 无 permission_required:接收人可能是普通员工,待办提醒必须人人可见
  (与 accept/reject 同级 —— 员工处置自己名下资产,非库管职权)。
· user_id 为 None / 非法时返回 0 而不是抛错:提醒类接口不该因边界输入 500。

路由无冲突
----
「transfer」匹配不了 <int:borrow_id>,「pending-count」也匹配不了
<int:transfer_id>,Werkzeug 按转换器精确分派。实测:
  GET /borrow/transfer/pending-count -> 401(已注册且受 JWT 保护)
  GET /borrow/11/transfer            -> 405(路径命中但方法不符,证无冲突)

验证(9 项断言全通过)
----
发起后接收人计数 +1、非接收人不变;拒绝/接收后均回落;
None 与非法 user_id 返回 0 不报错;库存零副作用、数据零残留。
This commit is contained in:
yueli
2026-09-17 10:30:07 +08:00
parent 4bd6765ab4
commit 1c58789fd9
2 changed files with 45 additions and 0 deletions

View File

@ -737,6 +737,33 @@ def reject_borrow_transfer(transfer_id):
return jsonify({'code': 500, 'msg': f'服务器内部错误: {str(e)}'}), 500
# --- 待我接收的转交数量(全局待办提醒)---
@trans_bp.route('/borrow/transfer/pending-count', methods=['GET'])
@jwt_required()
def get_pending_transfer_count():
"""
待我接收的转交数量,供前端全局待办强提醒使用。
★ 无 permission_required接收人可能是普通员工待办提醒必须人人可见
(与 accept/reject 同级的理由 —— 这是员工处置自己名下资产,非库管职权)。
★ 路由不与 /borrow/<int:borrow_id>/transfer 等冲突:
「transfer」无法匹配 <int:borrow_id>「pending-count」也无法匹配
<int:transfer_id>Werkzeug 会按转换器精确分派。
"""
try:
count = TransService.count_pending_transfers(get_jwt_identity())
return jsonify({
'code': 200,
'msg': 'success',
'count': count,
'data': {'count': count},
}), 200
except Exception as e:
traceback.print_exc()
return jsonify({'code': 500, 'msg': f'服务器内部错误: {str(e)}'}), 500
# --- 借出单的流转历史(转交链 + 逐次归还)---
@trans_bp.route('/borrow/<int:borrow_id>/history', methods=['GET'])
@jwt_required()

View File

@ -726,6 +726,24 @@ class TransService:
raise e
return transfer
@staticmethod
def count_pending_transfers(user_id):
"""
「待我接收」的转交数量 —— 供全局待办提醒在初始化与轮询时调用。
★ 刻意做成极轻量:一次 count不联表、不解析物料名。
轮询接口必须便宜,否则会从「提醒」变成「后台噪音」。
"""
if user_id is None:
return 0
try:
return TransBorrowTransfer.query.filter(
TransBorrowTransfer.to_user_id == int(user_id),
TransBorrowTransfer.status == TRANSFER_STATUS_PENDING,
).count()
except (TypeError, ValueError):
return 0
@staticmethod
def get_transfer_history(borrow_id):
"""某条借出记录的转交历史(按时间正序,便于还原 A→B→C 链路)"""