front/public/skills/itfx-prefix-script/SKILL.md
2026-06-04 19:15:28 +08:00

140 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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<ForwardCoreContext>` 的 Natasha 模板入参,不是 `context`)
- 写法:仅方法体语句(不要 `class`、不要 `namespace`、不要 `void Main`)
- 同步:默认;含 `await` 或首行 `//async` 时走异步委托
### 命名空间(必做,否则 CS0246)
Natasha 的 `NDelegate.Action<T>()` **只接收方法体**,不能写 `using System;` 这类文件级指令(写了会报 **`Identifier expected`**)。
类型必须使用 **全限定名**:`System.Text.Encoding.UTF8`、`Newtonsoft.Json.JsonConvert`
### 参数名(必做,否则 CS0246)
`Action<ForwardCoreContext>` 对应系统委托 `Action<T>(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)`