fix: get_session_project_id产线不匹配不再删除项目指针

根因: _valid只返回空串,调用方无法区分'项目已删'(应清理自愈)和
'跨产线合法上下文'(必须保留)。原实现产线不匹配也删全局/会话指针——
平台页点一次「工作空间」就把用户在投标页的当前项目清掉(复现脚本实锤)。
修复: _valid返回(vpid, reason), gone才清理, cross只视为无项目回退
This commit is contained in:
ymq 2026-09-02 19:01:18 +08:00
parent 19c7d05105
commit 9d40816fac

View File

@ -152,13 +152,13 @@ async def get_session_project_id(sor, uid, session_id='', pipeline_id=''):
return '' return ''
async def _valid(pid): async def _valid(pid):
"""pid 存在(且产线匹配,若指定)则返回 pid;否则 ''。""" """返回 (vpid, reason):vpid 有效则返回;否则 '' + 原因('gone'=项目已删, 'cross'=跨产线)。"""
pl = await _project_pipeline(pid) pl = await _project_pipeline(pid)
if pl is None: if pl is None:
return '' return '', 'gone'
if pipeline_id and pl and pl != pipeline_id: if pipeline_id and pl and pl != pipeline_id:
return '' return '', 'cross'
return pid return pid, ''
if session_id: if session_id:
try: try:
@ -169,18 +169,21 @@ async def get_session_project_id(sor, uid, session_id='', pipeline_id=''):
if recs: if recs:
pid = getattr(recs[0], 'current_project_id', '') or '' pid = getattr(recs[0], 'current_project_id', '') or ''
if pid: if pid:
vpid = await _valid(pid) vpid, reason = await _valid(pid)
if vpid: if vpid:
return vpid return vpid
# 悬空引用:清掉死记录,回退全局 if reason == 'gone':
try: # 悬空引用:项目已删除 → 清掉死记录(自愈),回退全局
await sor.sqlExe( try:
"DELETE FROM pipeline_session_settings " await sor.sqlExe(
"WHERE user_id=${u}$ AND session_id=${s}$", "DELETE FROM pipeline_session_settings "
{"u": uid, "s": session_id}) "WHERE user_id=${u}$ AND session_id=${s}$",
await sor.sqlExe("COMMIT", {}) {"u": uid, "s": session_id})
except Exception: await sor.sqlExe("COMMIT", {})
pass except Exception:
pass
# reason == 'cross':跨产线的合法上下文,不删除(删除会让用户
# 在该产线页面丢失当前项目),只视为本会话无项目继续回退
except Exception: except Exception:
pass pass
try: try:
@ -189,16 +192,21 @@ async def get_session_project_id(sor, uid, session_id='', pipeline_id=''):
{"u": uid}) {"u": uid})
pid = getattr(recs[0], 'current_project_id', '') if recs else '' pid = getattr(recs[0], 'current_project_id', '') if recs else ''
if pid: if pid:
vpid = await _valid(pid) vpid, reason = await _valid(pid)
if vpid: if vpid:
return vpid return vpid
try: if reason == 'gone':
await sor.sqlExe( # 悬空引用:项目已删除 → 清全局指针(自愈)
"UPDATE pipeline_agent_settings SET current_project_id='' " try:
"WHERE user_id=${u}$", {"u": uid}) await sor.sqlExe(
await sor.sqlExe("COMMIT", {}) "UPDATE pipeline_agent_settings SET current_project_id='' "
except Exception: "WHERE user_id=${u}$", {"u": uid})
pass await sor.sqlExe("COMMIT", {})
except Exception:
pass
# reason == 'cross':全局项目属于另一产线的合法上下文,不删除
# (2026-09-02 修复:原实现产线不匹配也删全局指针,平台页点一次
# 「工作空间」就把用户在投标页的当前项目清掉)
return '' return ''
except Exception: except Exception:
return '' return ''