初始提交:QuickTeam 工单接口导入工具
用「WCF + 通用存储过程网关」接口替代 Selenium(D://Learning//Python//工单自动化)导入工单: 单 Sprint 12 个项目 175s 跑完(旧方案 25~35 分钟),失败可断点续跑且不重复建单。 - 分层:transport(HTTP/协议)/ api(存储过程语义)/ domain(纯规则)/ workflow(阶段编排)/ store(SQLite 台账)/ report / CLI - 幂等:台账驱动断点续跑;dry-run 与跳过行不污染进度;--rollback-on-fail 清理半成品 - 命令:plan / apply / report / status,真实写入需 --yes - tools:只读探针、存储过程源码导出(sp_helptext)、导入诊断 - docs:调研与设计文档(含联调踩到的 5 个坑)+ 6 个关键存储过程源码 实测:Sprint 2026 Sprint 10 的 12 个项目全部完成建单→导入→确认→推送 TFS, 工单 225134–225145,35 个功能模块,重跑 plan 全部 skip-pushed。69 个单测通过。
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
"""只读工具:导出 QuickTeam 存储过程源码。
|
||||
|
||||
网关 `ExecTable` 可以直接执行 `sys.sp_helptext`,因此无需数据库账号即可读到
|
||||
SP 定义 —— 排查参数语义、确认字段来源时比猜快得多。
|
||||
|
||||
用法:
|
||||
python tools/sp_source.py usp_VerifyWorkSheetById
|
||||
python tools/sp_source.py usp_InsertWorkSheet usp_UpdateWorkSheetById --out docs/sp
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, ".")
|
||||
|
||||
from qtimport.config import Config # noqa: E402
|
||||
from qtimport.transport import Transport # noqa: E402
|
||||
|
||||
|
||||
def fetch(transport: Transport, name: str) -> str:
|
||||
rows = transport.exec_table("QuickTeam", "sys.sp_helptext", [("objname", name, "string")], op="helptext")
|
||||
if not isinstance(rows, list) or not rows:
|
||||
return ""
|
||||
return "".join(str(row.get("Text", "")) for row in rows)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("names", nargs="+")
|
||||
parser.add_argument("--config", default="config/config.json")
|
||||
parser.add_argument("--out", default="")
|
||||
args = parser.parse_args()
|
||||
|
||||
cfg = Config.load(args.config)
|
||||
transport = Transport(cfg.base_url, timeout=60, retries=1)
|
||||
if args.out:
|
||||
os.makedirs(args.out, exist_ok=True)
|
||||
|
||||
for name in args.names:
|
||||
full = name if name.startswith("QuickTeam.") else f"QuickTeam.{name}"
|
||||
text = fetch(transport, full)
|
||||
if not text.strip():
|
||||
print(f"[空] {full}(不存在或无权读取)")
|
||||
continue
|
||||
print(f"===== {full} =====")
|
||||
print(text)
|
||||
if args.out:
|
||||
path = os.path.join(args.out, f"{name.split('.')[-1]}.sql")
|
||||
with open(path, "w", encoding="utf-8") as handle:
|
||||
handle.write(text)
|
||||
print(f"→ 已保存 {path}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user