--- name: itfx-prefix-script description: >- Generates InterfaceForward (接口通/itfx) PrefixScript C# snippets for InterfaceMap that compute API signatures (MD5/SHA/HMAC) and write to Header/Query/Body. Use when the user asks for 前置脚本, 签名脚本, PrefixScript, InterfaceMap script, itfx signature, or Natasha forward script. --- # itfx 接口映射前置脚本生成 为 **InterfaceForward / 接口通** 的 **InterfaceMap → PrefixScript** 生成可在 Natasha 运行时直接执行的 C# 脚本。 ## 何时使用 - 用户要生成/修改 **前置脚本**(非后置 PostfixScript) - 第三方 API 需要 **签名、鉴权头、动态 token** - 在 OMS「接口映射」页面保存 `prefixScript` 字段 ## 执行时机(必须遵守) 单次转发流水线: ``` InParamRestructure(参数树映射) → ReplacePlaceholder($TimeStamp / $FromAccount / $token 等) → PrefixScript 执行 ← 本 Skill 产出代码在此运行 → SerializationBody → HTTP 请求 → PostfixScript ``` **结论:** | 可用 | 不可用 | |------|--------| | `obj.OriginalInterfaceMappedInput`(映射后 JToken) | `obj.TargetInterfaceInput`(尚未序列化) | | `obj.FixedFieldList` / `obj.FormFieldList` | `obj.TargetInterfaceOutput` | | `obj.GetAccountFieldValueOrNull(...)` | 改映射树配置本身 | ## 脚本技术约束 - 语言:**C#**,由 **DotNetCore.Natasha** 动态编译 - 参数名固定:**`obj`**(`Action` 的 Natasha 模板入参,不是 `context`) - 写法:仅方法体语句(不要 `class`、不要 `namespace`、不要 `void Main`) - 同步:默认;含 `await` 或首行 `//async` 时走异步委托 ### 命名空间(必做,否则 CS0246) Natasha 的 `NDelegate.Action()` **只接收方法体**,不能写 `using System;` 这类文件级指令(写了会报 **`Identifier expected`**)。 类型必须使用 **全限定名**:`System.Text.Encoding.UTF8`、`Newtonsoft.Json.JsonConvert` ### 参数名(必做,否则 CS0246) `Action` 对应系统委托 `Action(T obj)`,Natasha 模板参数名是 **`obj`**,不是 `context`、不是 `arg1`。 ```csharp // ✅ 正确 string secret = obj.GetAccountFieldValueOrNull("appSecret"); // ❌ 错误 → Identifier expected(using)或 CS0103(context) using System; var secret = context.GetAccountFieldValueOrNull("appSecret"); ``` ## context API 速查 | 成员 | 用途 | |------|------| | `OriginalInterfaceMappedInput` | 映射后请求体 `JToken`,改 body 内字段用 | | `FixedFieldList` | 固定参数(Header/Query/Url/Body) | | `FormFieldList` | `application/x-www-form-urlencoded` 表单键值 | | `AccountFieldList` | 服务商账户字段(密钥、客户号等) | | `GetAccountFieldValueOrNull(name)` | 按字段名取账户值(忽略大小写) | | `GetFixedFieldValueOrNull(name)` | 取固定参数当前值 | | `AddHeader(key, value)` | 新增 Header(已存在同名 Header 则失败) | | `TargetInterface` | 下游接口 URL、Method、ContentType 等 | **FieldPosition:** `Header=1`, `Body`, `Query`, `Url` **占位符(在固定参数配置,脚本执行前已替换):** `$TimeStamp`, `$DateTime`, `$FromAccount`, `$FromBody`, `$Url`, `$token` ## 签名写入方式(按目标位置选) ### 1. Header 签名(最常见) 先在接口固定参数里配置 Header 字段名(如 `sign`),脚本里赋值: ```csharp string sign = "..."; for (int i = 0; i < obj.FixedFieldList.Count; i++) { if (obj.FixedFieldList[i].FieldPosition == 1 && obj.FixedFieldList[i].FieldName == "sign") { obj.FixedFieldList[i].FieldValue = sign; break; } } ``` ### 2. Query 签名 遍历 `obj.FixedFieldList` 找到 Query 位置字段并赋值。 ### 3. Body JSON 字段 ```csharp obj.OriginalInterfaceMappedInput["sign"] = sign; ``` ### 4. FormUrlEncoded ```csharp for (int i = 0; i < obj.FormFieldList.Count; i++) { if (obj.FormFieldList[i].Name == "sign") { obj.FormFieldList[i].Value = sign; break; } } ``` ## 生成工作流 1. **收集需求**:签名算法、参与字段及排序、密钥来源、输出位置、编码规则 2. **对照 InterfaceMap 配置**:固定参数、账户字段名、ContentType 3. **生成脚本** → 仅输出 C# 方法体 4. **自检**:仅用 `obj`、无 `using`、全限定名、无 class/namespace ## 输出要求 只输出一个 ```csharp 代码块,内容为可直接粘贴到编辑器的 Natasha 脚本方法体,不要额外解释。 ## 禁止事项 - 不要用 `HttpClient` 在脚本里再发请求 - 不要修改 `InParamTreeList` / `OutParamTreeList` - 不要用 `TargetInterfaceInput` 做签名字符串 - 不要输出 Python/JavaScript - 不要在脚本里写 `using` 指令 - 不要用 `context` 作参数名,要用 `obj` - FormUrlEncoded 时签名字符串用 `JsonConvert.SerializeObject(obj.OriginalInterfaceMappedInput)`