用友 BIP 高级版 API接口调用
一、技能维护边界(最高优先级)
本技能的定位是接口测试——基于已获取的 BIP 高级版 OpenAPI 接口清单,在客户提供接口环境信息的前提下,进行接口调用测试。
不沉淀以下内容(铁律):
- 接口获取的方式(如何从开发者社区抓取接口清单 / 数据字典的方法论、脚本、鉴权细节)。
- 接口地址、接口密钥等凭证信息(BASE_URL、client_secret、signature 等由客户提供,不写入技能)。
- 具体的客户信息(客户名称、集团编码、业务单元 code、数据量等)。
接口清单与数据字典已获取并存档于「扩展数据包」,不内嵌于技能包,由技能首次被调用时自动拉取(见第三章)。获取方式不在本技能范围内。使用时由用户提供接口环境信息(服务地址、应用凭证、集团 / 组织编码等)。
> 本规则优先级高于下方所有章节。红线只在此声明一次。
二、何时使用
- 「查某版本接口的请求路径 / 参数 / 返回结构」
- 「调 BIP 高级版接口拉取业务数据(供应商 / 客户 / 用户 / 组织等主数据)」
- 「接口联调测试」
- 「查某字段什么意思(pk_supplier / enablestate / dr)」
- 接口路径形如
/nccloud/api/uapbd/...
三、扩展数据自动就位(强制前置检查 · 先于一切执行)
本技能未内嵌重型离线数据(三版本接口清单 + 2312 数据字典)。这些离线数据由「扩展数据包」提供,被分享人无需手动操作——由本指令驱动 agent 在首次调用技能时自动拉取。
执行铁律(agent 每次响应涉及本技能的任务时,第一步必做):
- 先用
python <技能>/scripts/fetch_ext_pack.py --ensure做一次幂等检查。
- 若返回「离线检索数据已就位」,跳过、继续正常任务;
- 若检测到缺失,脚本会自动调用用友网盘接口换取最新免登录直链并下载合并(全程无需登录、无需浏览器、无需被分享人干预)。 - 仅当用户任务纯属接口联调测试(
nc_call.py/nc_supplier_query.py,且用户已自带环境凭证)而不需要查接口清单 / 数据字典时,可跳过此检查——但首次执行api_search.py/dd_search.py前必须先跑--ensure。
> 设计目标:被分享人安装技能后,第一次用技能查接口或查字段时,数据自动到位,零人工操作。 --ensure 模式已做幂等保护,数据已存在时静默跳过、绝不重复下载。
四、已获取的接口清单(数据由「扩展数据包」提供,首次调用后自动落盘到 api_data/)
4.0 清单数据本体与检索
接口清单由「扩展数据包」提供(三版本,均已脱敏、不含客户信息),不内嵌于技能包。技能首次被调用涉及接口检索时,会自动拉取并落盘到技能 api_data/ 目录(见第三章);若已落盘,则直接复用、不再下载。落盘后结构如下:
api_data/
├── API版本入口索引.md # 三版本总入口(版本对照 / 接口总数 / 交付物说明)
├── BIP2505/ # 1519 个接口,11 模块
│ ├── API接口详情总览.md # 本版模块统计 + 分模块入口
│ └── modules/ # 按模块拆分的接口详情(财资/UAP/供应链/财务会计/...md)
├── BIP2312/ # 1445 个接口,11 模块
└── BIP2207/ # 1309 个接口,10 模块
检索工具 scripts/api_search.py(按编码 / 名称 / 请求地址片段,跨三版本):
python scripts/api_search.py supplierbaseinfoquery --detail # 三版本全查,含请求方式/描述
python scripts/api_search.py 部门 --version BIP2505 # 限定版本
输出:[版本] 接口编码 接口名 + 请求地址 + 所在文件与行号,打开对应 md 即见完整请求 / 返回参数表与示例。
人工查看入口(首次调用技能自动拉取数据后可用):api_data/API版本入口索引.md → 选版本 → API接口详情总览.md → 模块 md。
4.1 版本对照
| 版本 | versionNum |
|---|---|
| BIP2505 | BIP 高级版(R6_2505_1) |
| BIP2312 | BIP 高级版(R5_2312_1) |
| BIP2207 | BIP 高级版(R1_2207_1) |
4.2 接口详情字段结构
每条接口包含以下关键字段:
| 字段 | 说明 |
|---|---|
requestType |
请求方式(POST / GET) |
requestExample |
请求地址 |
describe |
功能描述 |
useCase |
使用场景 |
requestParams |
请求参数数组(可嵌套 children) |
returnParams |
返回参数数组(可嵌套 children) |
requestParamsExample |
请求示例 JSON 字符串 |
returnParamsExample |
返回示例 JSON 字符串 |
参数对象字段:
| 字段 | 说明 |
|---|---|
code |
参数名 |
paramType |
参数类型 |
isMust |
是否必填(1=是,0=否) |
describe |
参数说明 |
exampleValue |
示例值 |
children |
子参数数组 |
4.3 模块映射(fieldId → 模块)
接口清单中每条接口带 fieldId,映射到所属模块(见 references/fieldid_module_map_2505.json)。清单 md 已按模块拆分文件(文件名即模块名),一般无需再查 fieldId:
| fieldId | 模块 |
|---|---|
| 200 | 财务会计 |
| 201 | 财资 |
| 202 | 资金 |
| 203 | 供应链 |
| 204 | 管理会计 |
| 205 | 性能优化 |
| 206 | 共享服务 |
| 207 | 资产 |
| 208 | 预算报表 |
| 210 | UAP |
| 212 | UAP |
| 2101 | 制造 |
五、调用 BIP 高级版业务接口
5.0 调用「按条件查询」类接口前,先发「最小参数探针」反推真实必填项
接口文档里 pk_group / pk_org 等常被列为「查询条件」,但不代表目标租户强制校验——部分单集团租户不带 pk_group 也能直接返回全量数据。
铁律(调用任何「按条件查询」类接口前必做):
- 先做授权探测——调用应用对接口路径是逐个授权的。把本次要用到的全部查询路径先批量试调一遍,识别未授权项(典型报错
-32000 第三方应用【X】没有【路径】的权限,不要误判为地址写错);未授权路径所需的编码 / 参数一次性向用户索要,避免研究或复测跑到一半卡住。 - 再发一次最小参数探针——仅必要鉴权 +
data为空{}(不带任何文档声明的筛选项),调用该接口。 - 看返回判定:
- 返回数据 → 这些筛选项非必填,无需向用户索要,直接进入全量拉取(data仍可不带)。
- 返回空 / 报错(如1000000001业务单元数据为空)→ 这些筛选项必填,再向用户索要对应编码。 - 探针已内置:通用调用器
nc_call.py --probe(纯探针,只读 1 页),以及各成品脚本(如nc_supplier_query.py)的全量模式里作为自动前置步骤(无需手写临时脚本)。
> 探针是「只读」操作(不增删改),对任何客户环境都安全、低成本(仅 1 页)。该纪律对所有按条件查询类接口通用,不限于 uapbd / 供应商。
> AI 仅发只读查询请求(硬纪律):本技能只负责对查询类接口发测试请求(GET / 只读 POST 探针),用于验证返回结构与字段;任何会落库 / 改状态的写操作(新增 / 修改 / 删除 / 审核 / 提交 / 过账等)未经用户逐次明确授权不得调用。禁止直连应用服务器做 sftp.put/remove、部署 / 重启等写操作(本技能仅发只读查询请求,任何落库 / 改状态写操作均不在本技能职责内)。
5.1 取 access_token(每次调用前都重取)
POST {BASE_URL}/nccloud/opm/accesstoken- 参数(请求 BODY,
application/x-www-form-urlencoded表单):client_id、client_secret(含 CRLF 换行,原值 URL 编码)、biz_center、signature、grant_type=client_credentials。不放 query string(放 query 会报Missing grant_type parameter value) - GET 会 405,必须 POST
- 返回
data.access_token(约 1000000ms 自动刷新;每次重取防过期,属规范做法)
> 调用顺序铁律:任何业务接口调用前,必须先用本接口取一次 access_token,再把它作为 access_token 小写请求头传入业务接口。先取 token,后用 token,不可省略或颠倒。脚本(nc_call.py / nc_supplier_query.py)已在 main 入口自动执行此顺序,无需手动分步;若他人用 curl / Postman 手动调,必须严格遵循该顺序。
> BASE_URL、client_id、client_secret、biz_center、signature 均由客户提供,经「环境变量(优先、不落盘)或脚本配置区常量」注入使用,不沉淀在技能知识中。
5.2 关键调用约定(必须遵循)
> 业务接口必带头(铁律 · 单一权威来源 = nc_call.py 的 REQUIRED_HEADERS / build_biz_headers)
> 任何业务接口调用,请求头【必须】且【仅】包含以下小写头,缺任一【禁止发出】:
>
> > access_token # = 取到的 token(小写头,不是 Bearer / 不是 query)
> client_id # = appid,缺报「appid 缺失」
> ucg_flag = Y
> repeat_check = Y
> signature # = 客户提供的 signature
>
>
> - 业务调用一律走 nc_call.py:它已内置上述全套头(改头只改 REQUIRED_HEADERS 一处)。标准 ufinterface 接口直接 python nc_call.py --path <requestPath>;非 ufinterface 包装的自定义接口用 python nc_call.py --path <requestPath> --flat-body --data '<resource 要求的 JSON>'。脚本在发出前会自检必带头,缺头直接报错、绝不带缺头发请求。
> - 禁止手写请求头:确需脱离脚本时,必须 from nc_call import build_biz_headers 复用,或逐字照搬上表;不得自创 / 删减头名。漏 ucg_flag / repeat_check 的典型报错是 1000000010 Failed to verify signature for call api(不是缺参提示、极易误判为签名算法问题),详见 references/faq.md。
- 自定义请求头名必须用【小写】
access_token / client_id / ucg_flag / repeat_check / signature - 统一用
http.client/curl发请求(脚本已用http.client):不要用urllib.request,它会把头名转成 Title-Case(Access_Token…),网关大小写敏感 → 识别不到小写头 → 报JSONString:null(code 1000000003)。取 token 同样走http.client(body 表单,无自定义头名)。 access_token必须放 header(不是 Bearer、不是 query)client_id头即 appid,缺它会报 appid 缺失;需后台对该接口路径授权
> 调用报错与排查见 references/faq.md(技能问题题库);接口联调笔记见 references/api_notes.md。
5.3 业务接口调用约定
- Body 统一包装:
{"ufinterface":{"sender":"default","data":{...},"pageInfo":{"pageIndex":"0","pageSize":"10"}}} - 查询条件写
data: pk_group:集团编码。注意:部分单集团租户实际不强制校验(见 5.0 探针),缺省时可先不带、由探针决定是否向用户索要,不要默认把它当硬必填。pk_org:业务单元编码数组。调用户 / 客户等接口常需它。根业务单元 code 由客户提供。ts:按「≥ 起始日期」过滤,非精确等于- 分页:供应商类按
pageInfo正常翻页;用户 / 客户类分页坏(忽略pageSize、单次全量)。脚本循环多页会因去重自动收敛 - 少数接口(如组织查询
riaorg/orgmanage/org/queryOrgByPk_group、自定义 OpenAPI 资源类)不使用ufinterface包装,data直接作为顶层 body 发出:脚本用--flat-body开关处理(如--flat-body --data '{"pageIndex":0,"pageSize":20}');其请求头仍由nc_call.py统一注入全套必带头(见 5.2 铁律)
5.4 报错排查
接口调用报错与踩坑排查见 references/faq.md(技能问题题库);联调事实笔记(接口 / 请求头 / 回包形状 / 分页行为 / 示例片段)见 references/api_notes.md。
六、接口清单 → 调用的衔接(核心价值)
- 先用
scripts/api_search.py <关键词>在清单中定位目标接口,拿到 requestPath 与请求参数表(哪个参数必填、什么类型一目了然),再按下述步骤调用。 - 接口清单里的
requestPath(或requestExample)= 调用时拼到{BASE_URL}/后面的路径。 - 例:清单中供应商接口
requestPath = nccloud/api/uapbd/supplierquery/supplierbaseinfo/supplierbaseinfoquery
→ 调用即POST {BASE_URL}/nccloud/api/uapbd/supplierquery/supplierbaseinfo/supplierbaseinfoquery,
Body 用{"ufinterface":{"sender":"default","data":{"pk_group":"<客户提供>"},"pageInfo":{...}}}。 - 用
scripts/nc_call.py(通用调用器)把requestPath直接当--path传入即可,鉴权 / 头名 / 翻页 / 去重 / 探针都已封装:
```bash
# 探针(任何接口通用):空 data 发一次,反推本租户是否强制 pk_group/pk_org 等筛选项(只读 1 页)
python scripts/nc_call.py --path nccloud/api/uapbd/supplierquery/supplierbaseinfo/supplierbaseinfoquery --probe
# 供应商(ufinterface 包装,默认):--max-pages 0 = 翻到末页(本页<pageSize 即止),pk_group 缺省时由探针自动判定
python scripts/nc_call.py --path nccloud/api/uapbd/supplierquery/supplierbaseinfo/supplierbaseinfoquery \
--data '{}' --max-pages 0 --out-json supp.json --out-csv supp.csv
# 用户(必须传业务单元 code,根业务单元 code 覆盖全量用户)
python scripts/nc_call.py --path nccloud/api/uapbd/usermanager/userquery/queryUsersByCondition \
--data '{"pk_org":["<业务单元code>"]}' --out-json users.json --drop-sensitive
# 客户
python scripts/nc_call.py --path nccloud/api/uapbd/customermanage/querycustomerinfo/queryCustomerBaseInfo \
--data '{"pk_group":"<集团编码>","enablestate":"2"}' --out-json custs.json
# 业务单元/组织(平铺 body 接口,须 --flat-body,data 即顶层 body)
python scripts/nc_call.py --path nccloud/api/riaorg/orgmanage/org/queryOrgByPk_group \
--data '{"pk_group":"<集团UFID>","version":"2"}' --flat-body --out-json orgs.json
```
--probe:见 5.0,调用前先用空 data 探一下,避免「文档写了必填就信必填」的误索要。--max-pages 0:翻到末页(本页条数 < pageSize 即视为到头),不再依赖异常兜底,正好对应「多次脚本 → 1 次脚本」的优化。--flat-body:少数接口(如组织查询)不使用ufinterface包装,--data直接作为顶层 body 发出。其余uapbd/*查询接口都用ufinterface包装,不用此开关。
scripts/nc_supplier_query.py是供应商查询的成品示例(自建 token / 头,等价于 nc_call 的供应商特例),已内置--probe探针反推必填 + 单次调用完成「探针 → 结构 → 翻页 → 完整性校验」全链路,--pk_group可选;可参考其结构按需修改。- 应用路径授权注意:部分文档路径(如
suppliermanage)对调用应用无权限,需改supplierquery(见报错表)。
> 凭据注入双路径(nc_call.py 与 nc_supplier_query.py 一致;环境变量优先,未设置项回落常量):① 环境变量 NC_HOST / NC_PORT / NC_USE_HTTPS / NC_CLIENT_ID / NC_BIZ_CENTER / NC_SIGNATURE,client_secret 走 NC_CLIENT_SECRET_ENC(URL 编码值,含换行时推荐);② 脚本配置区常量直填。两者均缺时脚本明确报缺失并退出。脚本内已用占位符标注。
七、数据字典本地检索(辅助工具)
接口返回的字段含义可参考已获取的数据字典(2312 版 7,543 表 / 301,662 字段)。该字典由「扩展数据包」提供,不内嵌于技能包,技能首次被调用涉及字段检索时自动落盘到 scripts/_dd2312/tables_uniq.jsonl(见第三章)。本地检索工具 scripts/dd_search.py 读取该文件,支持:
python scripts/dd_search.py table <关键词> # 按表名/中文名找表(如 供应商 / bd_supplier)
python scripts/dd_search.py show <表名> # 看某表全部字段(含枚举值域 scope)
python scripts/dd_search.py field <字段名> # 全库反查字段含义(如 enablestate 出现在 519 张表)
python scripts/dd_search.py md <表名>... # 导出 Markdown 字段表
- 检索加速:首次检索会在字典同目录自动建一份
.sqlite索引(一次性数秒),此后按字典的 mtime + size 校验复用,单次检索由数秒降到秒内;索引文件可随时删除,会按需重建。字典变更(重新落盘)后索引自动重建,无需手工干预。 - 切换版本数据:用
--data <路径>或环境变量DD_DATA指定其它版本的tables_uniq.jsonl(数据路径按--data→DD_DATA→ 技能内_dd2312/→ 当前工作目录_dd2312/依次查找)。
7.1 通用字段速查
| 字段 | 含义 | 要点 |
|---|---|---|
ts |
时间戳 | 并发控制,非业务时间 |
dr |
删除标志 | 0=有效,1=已删,查数必须过滤 |
pk_group / pk_org |
所属集团 / 组织 | char(20) UFID |
enablestate |
启用状态 | 2=启用,3=停用 |
def1~def20 |
自定义项 | 客户化扩展,各项目含义不同 |
creator / creationtime |
创建人 / 时间 | 时间是 char(19) 字符串 |
modifier / modifiedtime |
修改人 / 时间 |
命名规律:pk_*=主键 / 外键(char(20) UFID);code=编码(唯一);name=名称(MultiLangText 多语);is*/*flag=布尔(char(1))。
7.2 外键解析:用【引用模型 ref】,不要全表扫描试 join
数据字典每个字段都带 ref(引用模型),它才是权威外键元数据。解析外键必须读 ref,绝不能「扫描所有含 ORG/SUPPLIER 的表逐个试 join」。
- 字段元数据里
ref形如组织_业务单元_财务组织 (financeorg):括号内 token=financeorg → 引用表org_financeorg;关联键 = 该引用表的主键(字典中pk=True的字段)。 - 通用 token→表映射:financeorg→org_financeorg、corp→org_corp、dept→org_dept、supplier→bd_supplier、customer→bd_customer、psndoc→sm_user。
八、脚本与资源
接口清单检索(第四章)
scripts/api_search.py— 清单检索工具(编码 / 名称 / 请求地址片段,支持--version/--detail)。- 三版本接口详情存档(BIP2505 / BIP2312 / BIP2207)不在本技能包内,由「扩展数据包」提供,见第九章。
调用侧(第六章)
scripts/nc_call.py— 通用 BIP 高级版调用器(接 requestPath 直接调,推荐)。内置--probe最小参数探针(见 5.0),--max-pages 0翻到末页。凭据经环境变量或配置区常量注入;响应体gzip由传输层统一解压(调用方无须自行处理)。scripts/nc_supplier_query.py— 供应商查询成品示例(含--probe探针反推必填 + 单次调用完成全链路,--pk_group可选)。references/api_notes.md— 调用联调事实笔记(接口 / 请求头 / 回包形状 / 分页行为 / 示例片段);踩坑与教训归references/faq.md。references/fieldid_module_map_2505.json— fieldId→模块映射。
数据字典检索(第七章 · 辅助工具)
scripts/dd_search.py— 数据字典本地检索工具(table / show / field / md)。- 2312 版数据字典
tables_uniq.jsonl不在本技能包内,由「扩展数据包」提供。
扩展数据包获取(获取重型数据用)
scripts/fetch_ext_pack.py— 一键获取扩展数据包(免登录实时换直链 → 下载 → 合并到技能目录,仅依赖 Python 标准库)。被分享人装技能后跑一条命令即可补全离线检索数据,详见第九章。
> 提示:脚本内配置区标注了需要由客户提供的环境参数(也可改用 NC_* 环境变量注入,见第六章);使用时替换为实际值即可运行。
九、扩展数据包获取指引
本技能未内嵌重型数据(三版本接口详情 + 2312 数据字典)。安装技能后,这些离线数据由 fetch_ext_pack.py --ensure 在首次调用技能时自动拉取(见第三章),被分享人无需手动执行任何命令。
9.1 自动获取(默认行为,被分享人零操作)
技能第三章的「扩展数据自动就位」已要求 agent 在涉及接口清单 / 数据字典检索的任务前,自动运行:
python <技能目录>/scripts/fetch_ext_pack.py --ensure
--ensure 为幂等模式:数据已就位则静默跳过;缺失则自动完成。
下载缓存:扩展包 zip 落在用户级缓存 ~/.workbuddy/.ext_pack_cache/(不落在技能目录、不随包外发);同一台机器上的多个技能共用该缓存,同一分享包只会真正下载一次。需要强制重新下载时加 --refresh。
文件清单
yonyou-js-djw-api-pre/
├── SKILL.md 本文件:维护边界 / 何时使用 / 扩展数据自动就位 / 接口清单检索 / 接口调用 / 清单衔接 / 数据字典 / 脚本资源 / 扩展包指引
├── api_data/ 扩展数据包(首次调用自动拉取,不进技能包):三版本接口清单 + 2312 数据字典
├── references/
│ ├── api_notes.md 接口联调事实笔记 + 产品类只读定位(接口 / 头 / 回包形状 / 分页行为 / CFR 反编译;踩坑归 faq.md)
│ ├── fieldid_module_map_2505.json fieldId → 模块映射
│ └── faq.md 技能问题题库(试错归此,正文不重述)
└── scripts/
├── api_search.py 接口清单检索工具(编码/名称/请求地址片段)
├── dd_search.py 数据字典本地检索工具(table/show/field/md)
├── fetch_ext_pack.py 一键获取扩展数据包(幂等、免登录)
├── nc_call.py 通用 BIP 高级版调用器(接 requestPath 直接调,含 --probe 探针与 gzip 解压)
└── nc_supplier_query.py 供应商查询成品示例(含 --probe 探针反推必填 + 单次全链路)