fix(stocktake): enforce session_id in resume, make missing generation idempotent, update UI to show SN, and fix excel time offset

This commit is contained in:
DXC
2026-04-03 09:42:51 +08:00
parent 43e1d0aa55
commit 0d8f697df4
3 changed files with 28 additions and 9 deletions

View File

@ -804,13 +804,13 @@ def export_stocktake():
return str(user_id)
def to_beijing_time(dt):
"""转换为北京时间(+8小时"""
"""直接使用数据库中存储的标准时间(服务器时区已正确"""
if not dt:
return ''
try:
if isinstance(dt, str):
return dt[:19]
return (dt + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
return dt.strftime('%Y-%m-%d %H:%M:%S')
except:
return str(dt)[:19]
@ -1130,9 +1130,13 @@ def export_stocktake():
@permission_required('inventory_stocktake:operation')
def generate_missing_stocktake():
"""
生成漏盘数据:
生成漏盘数据(幂等性)
找出所有真实库存 > 0但未被当前会话盘点扫描到的物料
自动生成盘点草稿,标记为盘亏(实盘=0差异=-库存数)
幂等性保护:在重新计算差集之前,先删除当前 session 下所有
由系统自动生成的漏盘记录quantity==0, user_id=='system'
保证该接口多次调用结果一致。
"""
try:
# ★ 获取 session_id 参数,用于隔离当前会话
@ -1142,6 +1146,16 @@ def generate_missing_stocktake():
if not session_id:
return jsonify({'code': 400, 'msg': '缺少 session_id 参数'}), 400
# ★ 幂等性保护:先删除当前 session 下系统自动生成的漏盘记录
# 特征user_id == 'system' (表示由系统自动生成)
deleted_count = StocktakeDraft.query.filter(
StocktakeDraft.session_id == session_id,
StocktakeDraft.user_id == 'system'
).delete()
if deleted_count > 0:
db.session.commit()
print(f"[generate_missing] 已清理 {deleted_count} 条历史漏盘记录")
# 1. 获取当前会话已有盘点记录的 (source_table, stock_id) 集合
existing_records = db.session.query(
StocktakeDraft.source_table,
@ -1192,11 +1206,11 @@ def generate_missing_stocktake():
if key not in scanned_keys:
# 生成漏盘草稿
draft = StocktakeDraft(
user_id='system',
user_id='system', # ★ 标记为系统自动生成,用于幂等性清理
uuid=f'MISSING-{stock["source_table"]}-{stock["stock_id"]}',
quantity=0, # 实盘数为0
scan_time=beijing_time(),
session_id='AUTO_GENERATED',
session_id=session_id, # ★ 使用传入的 session_id
source_table=stock['source_table'],
stock_id=stock['stock_id'],
stock_qty=stock['stock_qty'],