This commit is contained in:
Marsway 2026-01-05 17:37:28 +08:00
parent 14d9136a3b
commit d1f335d6a2
2 changed files with 126 additions and 0 deletions

View File

@ -77,4 +77,42 @@ class SeeyonClient(BaseClient):
return super().request(method, path, headers=headers, **kwargs) return super().request(method, path, headers=headers, **kwargs)
raise raise
def export_cap4_form_soap(
self,
*,
templateCode: str,
senderLoginName: str | None = None,
rightId: str | None = None,
doTrigger: str | bool | None = None,
param: str | None = None,
extra: dict[str, Any] | None = None,
) -> httpx.Response:
"""
无流程表单导出CAP4
POST /seeyon/rest/cap4/form/soap/export
返回 httpx.Response调用方可自行读取 resp.text / resp.headers 等信息
"""
body: dict[str, Any] = {"templateCode": templateCode}
if senderLoginName:
body["senderLoginName"] = senderLoginName
if rightId:
body["rightId"] = rightId
if doTrigger is not None:
body["doTrigger"] = doTrigger
if param is not None:
body["param"] = param
if extra:
# 兜底扩展字段:仅当 key 不冲突时注入,避免覆盖已显式指定的参数
for k, v in extra.items():
if k not in body:
body[k] = v
return self.request(
"POST",
"/seeyon/rest/cap4/form/soap/export",
json=body,
headers={"Content-Type": "application/json"},
)

View File

@ -56,3 +56,91 @@ class SyncOAToDidiTokenJob(BaseJob):
return {"token_masked": masked, "loginName": login_name or "", "base_url": base_url} return {"token_masked": masked, "loginName": login_name or "", "base_url": base_url}
class SyncOAToDidiExportFormJob(BaseJob):
"""
无流程表单导出CAP4
- 调用POST /seeyon/rest/cap4/form/soap/export
- base_url 不包含 /seeyon/rest例如 https://oa.example.com:8090
public_cfg:
- base_url: "https://oa.example.com:8090"
- templateCode: "employee"
- senderLoginName: "xxx" (可选)
- rightId: "xxx" (可选)
- doTrigger: "true" (可选)
- param: "0" (可选)
- extra: {...} (可选兜底扩展字段)
secret_cfg (解密后):
- rest_user
- rest_password
- loginName (可选)
"""
job_id = "sync_oa_to_didi.export_form_soap"
def run(self, params: dict[str, Any], secrets: dict[str, Any]) -> dict[str, Any]:
base_url = str(params.get("base_url") or "").strip()
if not base_url:
raise ValueError("public_cfg.base_url is required")
template_code = str(params.get("templateCode") or "").strip()
if not template_code:
raise ValueError("public_cfg.templateCode is required")
sender_login_name = params.get("senderLoginName")
sender_login_name = str(sender_login_name).strip() if sender_login_name else None
right_id = params.get("rightId")
right_id = str(right_id).strip() if right_id else None
do_trigger = params.get("doTrigger")
param = params.get("param")
param = str(param) if param is not None else None
extra = params.get("extra")
if extra is not None and not isinstance(extra, dict):
raise ValueError("public_cfg.extra must be a JSON object (dict) if provided")
rest_user = str(secrets.get("rest_user") or "").strip()
rest_password = str(secrets.get("rest_password") or "").strip()
login_name = secrets.get("loginName")
login_name = str(login_name).strip() if login_name else None
if not rest_user or not rest_password:
raise ValueError("secret_cfg.rest_user and secret_cfg.rest_password are required")
client = SeeyonClient(base_url=base_url, rest_user=rest_user, rest_password=rest_password, loginName=login_name)
try:
resp = client.export_cap4_form_soap(
templateCode=template_code,
senderLoginName=sender_login_name,
rightId=right_id,
doTrigger=do_trigger,
param=param,
extra=extra,
)
raw_text = resp.text or ""
content_type = resp.headers.get("content-type", "") if getattr(resp, "headers", None) else ""
finally:
client.close()
# 避免把 raw_text 打到日志或 run_log会被截断且污染 JobLog
logger.info(
"Seeyon export_form_soap done templateCode=%s content_length=%s content_type=%s base_url=%s",
template_code,
len(raw_text),
content_type,
base_url,
)
return {
"raw": raw_text,
"meta": {
"templateCode": template_code,
"content_length": len(raw_text),
"content_type": content_type,
},
}