fix(bidding): 模版确认门加固(E2E实测)——confirm_tech_template权限改复用引擎_check_confirm_operator(同机构+超管/创建者,与flow_plan_confirm语义一致,原自写'仅同机构'丢了超管语义实测误拒admin);确认重落守卫:已有非pending章节拒绝重新确认(防毁已写内容)
This commit is contained in:
parent
cc87340398
commit
87ecf3ee72
@ -445,15 +445,25 @@ async def confirm_tech_template(human_task_id, decision, comment="",
|
||||
if ht.get("status") != "pending":
|
||||
return False, "待办已处理(当前 %s)" % ht.get("status")
|
||||
project_id = ht.get("project_id") or ""
|
||||
# 同机构校验
|
||||
prec = await sor.sqlExe("SELECT org_id FROM sd_projects WHERE id=${p}$",
|
||||
{"p": project_id})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
proj_org = getattr(prec[0], "org_id", "") if prec else ""
|
||||
from pipeline_service.human_task_capability import _get_user_org
|
||||
user_org = await _get_user_org(sor, operator_id)
|
||||
if proj_org and user_org != proj_org:
|
||||
return False, "仅同机构用户可确认该项目模版"
|
||||
# 确认权限:复用引擎 _check_confirm_operator(同机构 + owner.superuser/项目创建者)——
|
||||
# 与 flow_plan_confirm 确认门语义完全一致,不自己另写一套校验(2026-09-15 E2E 实测
|
||||
# 发现自写「仅同机构」把超管/创建者语义丢了)。
|
||||
try:
|
||||
from pipeline_service.flow_plan_capability import _check_confirm_operator
|
||||
ok_op, err_op = await _check_confirm_operator(
|
||||
sor, {"project_id": project_id}, operator_id)
|
||||
if not ok_op:
|
||||
return False, err_op or "无权确认该项目模版"
|
||||
except ImportError:
|
||||
# 引擎不可用(理论不发生):兜底同机构校验
|
||||
prec = await sor.sqlExe("SELECT org_id FROM sd_projects WHERE id=${p}$",
|
||||
{"p": project_id})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
proj_org = getattr(prec[0], "org_id", "") if prec else ""
|
||||
from pipeline_service.human_task_capability import _get_user_org
|
||||
user_org = await _get_user_org(sor, operator_id)
|
||||
if proj_org and user_org != proj_org:
|
||||
return False, "仅同机构用户可确认该项目模版"
|
||||
|
||||
if decision == "confirm":
|
||||
schema = json_loads(ht.get("form_schema"), {}) or {}
|
||||
@ -462,7 +472,17 @@ async def confirm_tech_template(human_task_id, decision, comment="",
|
||||
chapters = schema.get("chapters") or []
|
||||
if not chapters:
|
||||
return False, "待办里没有骨架数据(form_schema.chapters 空),无法落库"
|
||||
# 幂等:已有骨架先清(驳回重提后再确认的场景)
|
||||
# 幂等重落守卫:仅当既有章节全部未开写(pending)时清旧骨架——
|
||||
# 已有 writing/written/approved 章节说明流程已推进,重新确认会毁掉
|
||||
# 已写内容,拒绝并提示走驳回/人工处置(2026-09-15 加固)。
|
||||
busy = await sor.sqlExe(
|
||||
"SELECT COUNT(*) AS c FROM bid_chapters WHERE project_id=${p}$ "
|
||||
"AND status<>${s}$", {"p": project_id, "s": CH_PENDING})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
if to_int(getattr(busy[0], "c", 0) if busy else 0) > 0:
|
||||
return False, ("项目已有开写/已完成的章节,不能重新确认骨架(会毁掉已写内容)。"
|
||||
"如需换骨架请先驳回或在章节管理页人工处置既有章节。")
|
||||
# 幂等:清掉此前确认落库但尚未开写的旧骨架(驳回重提后再确认的场景)
|
||||
await sor.sqlExe(
|
||||
"DELETE FROM bid_chapters WHERE project_id=${p}$", {"p": project_id})
|
||||
n = 0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user