front/docs/总体结论.md
2026-06-04 19:15:28 +08:00

458 lines
15 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.

我会对照方案读取现有接口保存、参数实体和转发组装代码,判断改造影响面与风险点。
Created 4 todos
Searched for files matching `**/src/InterfaceForward.Repositories/**/*.cs`, 80 matches
我会并行读取关键实体、DTO、保存查询服务和转发构建代码,形成可行性判断。
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Repositories/Parameter/Entities/ParameterEntity.cs)
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Repositories/Parameter/Entities/FormParameterEntity.cs)
Searched for files matching `**/src/**/FixedParameter*.cs`, 5 matches
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Repositories/Parameter/Entities/FixedParameterEntity.cs)
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application.Contracts/Dtos/Interface/SaveInterfaceInput.cs)
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application.Contracts/Dtos/Interface/ParameterInput.cs)
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application.Contracts/Dtos/Interface/SaveParameterMapsInput.cs)
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application.Contracts/Dtos/Interface/ParameterParseOutput.cs)
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application.Contracts/Dtos/ServiceProvider/FixedParameterInput.cs)
我已读取实体和 DTO,下一步查看保存/查询接口与转发上下文构建,判断方案 B 的改动点是否闭环。
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application/Services/Interface/InterfaceService.cs#1-1), lines 1 to 260
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application/Services/Interface/InterfaceService.cs#260-260), lines 260 to 334
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application/Services/Parameter/ParameterService.cs#1-1), lines 1 to 260
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application/Services/Parameter/ParameterService.cs#260-260), lines 260 to 560
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application/Services/Parameter/FormParameterService.cs)
我继续读取上下文构建和映射查询代码,确认方案里 `InParamTreeList` 来源切换的实现难度。
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application/Services/InterfaceForwardCommon.cs#1-1), lines 1 to 260
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Application/Services/InterfaceForwardCommon.cs#260-260), lines 260 to 420
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Repositories/InterfaceForwardQuery.cs)
关键转发查询显示目前仍把下游所有 `IsInPara=true` 当映射树,且 Form KV 未区分 Query/Header/Body;我再查看 DTO/枚举常量后给出结论。
Searched for regex `enum FieldPosition|enum ContentType|FromBody|FromMappingBody|FormFieldList|FixedFieldList` (`**/src/**`), 79 results
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Domain.Shared/Enum/FieldPosition.cs)
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Domain.Shared/Enum/ContentType.cs)
已有 `FieldPosition` 和 `ContentType` 枚举基本符合方案,但 `t_parameter_form` 实体缺 `FieldPosition`,`t_parameter` 缺 `ParaKind`,这是数据库层主要增量。
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Domain.Shared/GlobalConst.cs)
Read [](file:///d%3A/my/itfx/itfx/src/InterfaceForward.Domain.Shared/Dtos/ForwardCoreContextCache.cs)
Completed: *梳理现有数据模型* (1/4)
可行,但这是**中大型重构**,不是小改。方案 B 和当前代码方向一致,主要是把现在“下游入参树 + 表单参数 + 固定参数”混用的问题拆清楚。建议可以做,但要按阶段推进。
## 总体结论
**可行性:高。**
**改造成本:中高。**
**主要风险:映射保存/发布缓存/转发组装三处需要同步改,否则容易出现保存成功但转发错误。**
方案 B 的核心改动和现有代码冲突点主要有 3 个:
1. 当前下游统一使用 `InParameterList` 作为映射树。
2. 当前 `t_parameter_form` 没有 `FieldPosition`,无法区分 Query / Header / Body。
3. 当前转发时 FormUrlEncoded 用 `$FromBody`,方案要求改成 `$FromMappingBody`。
---
## 当前代码现状
### 1. `t_parameter` 当前只有 `IsInPara`
实体在 ParameterEntity.cs:
```csharp
public bool IsInPara { get; set; }
```
目前语义是:
- `IsInPara = true`:入参
- `IsInPara = false`:出参
但方案 B 需要进一步区分:
- 上游入参
- 下游 Json/Xml RequestBody
- 下游 FormUrlEncoded MappingBody
- 出参
所以需要新增:
```csharp
public ParameterParaKind ParaKind { get; set; }
```
或类似枚举:
```csharp
public enum ParameterParaKind
{
Normal = 0,
MappingBody = 1
}
```
### 2. `t_parameter_form` 当前没有 `FieldPosition`
实体在 FormParameterEntity.cs,当前只有:
```csharp
public string Name { get; set; }
public string Value { get; set; }
public string Description { get; set; }
```
方案 B 要它承载:
- Query KV
- Header KV
- Body KV
所以必须新增:
```csharp
public FieldPosition FieldPosition { get; set; }
```
现有 `FieldPosition` 枚举已经存在于 FieldPosition.cs,可直接复用。
### 3. `SaveInterfaceInput` 当前字段不够
当前 SaveInterfaceInput.cs 只有:
```csharp
public List<ParameterInput> InParameterList { get; set; }
public List<ParameterInput> OutParameterList { get; set; }
public List<FormParameterInput> FormParameterList { get; set; }
```
方案 B 要改成:
```csharp
public List<FormParameterInput> QueryFormParameterList { get; set; }
public List<FormParameterInput> HeaderFormParameterList { get; set; }
public List<FormParameterInput> BodyFormParameterList { get; set; }
public List<ParameterInput> InParameterList { get; set; }
public List<ParameterInput> RequestBodyParameterList { get; set; }
public List<ParameterInput> MappingBodyParameterList { get; set; }
public List<ParameterInput> OutParameterList { get; set; }
```
不做旧字段兼容的话,这个改动是合理的。
---
## 转发逻辑可行性
### 当前链路
当前构建转发上下文在 InterfaceForwardQuery.cs:
```csharp
var inParaMaps = await GetParameterMapListAsync(mapIds, true);
...
InParamTreeList = JsonHelper.BuildTreeList(items)
FormFieldList = await GetFormFieldListAsync(targetInterface.Id)
FixedFieldList = fixedFieldList
```
当前问题是:
- 下游所有 `IsInPara=true` 都被当成映射目标。
- FormUrlEncoded 和 Json 的映射树没有语义区分。
- Query/Header 主要还依赖 `FixedFieldList` 或旧 `FormFieldList`。
方案 B 的调整是可落地的:
| ContentType | `InParamTreeList` 来源 |
| -------------- | -------------------------- |
| Json / Xml | `requestBodyParameterList` |
| FormUrlEncoded | `mappingBodyParameterList` |
| 上游 | `inParameterList` |
这需要改 `GetParameterMapListAsync()` 查询条件:
- Json/Xml:查 `t_parameter.IsInPara = true AND ParaKind = Normal`
- FormUrlEncoded:查 `t_parameter.IsInPara = true AND ParaKind = MappingBody`
- 出参:仍查 `IsInPara = false`
---
## HTTP 组装改造可行性
当前 DefaultForwardFlow.cs 已经有这些能力:
- Query 拼接
- Header 拼接
- FormUrlEncoded Body 组装
- Json/XML Body 序列化
- 占位符替换
所以不是推倒重来,而是调整来源。
### 当前 FormUrlEncoded
当前逻辑大致是:
```csharp
if (context.FormFieldList.Count != 0)
{
var field = context.FormFieldList.FirstOrDefault(x => x.Value == GlobalConst.FromBody);
if (field != null) field.Value = body;
nameValueCollection = context.FormFieldList.ToDictionary(x => x.Name, x => x.Value);
}
```
方案 B 要改为:
```csharp
$FromMappingBody
```
并且 `FormFieldList` 只取 `FieldPosition = Body`。
Query/Header 不应该混在 `FixedFieldList` 的接口级配置里,而应来自:
```csharp
queryFormParameterList
headerFormParameterList
```
---
## 数据库改造建议
需要新增字段:
### `t_parameter_form`
```sql
ALTER TABLE t_parameter_form
ADD FieldPosition INT NOT NULL DEFAULT 2;
```
默认 `2 = Body`,这样老数据如果不迁移也能先当 Body。
### `t_parameter`
```sql
ALTER TABLE t_parameter
ADD ParaKind INT NOT NULL DEFAULT 0;
```
默认 `0 = Normal`。
如果真的“不做旧字段兼容,全量重构”,可以不迁移旧语义;但数据库字段还是要加。
---
## 主要影响面
### 必改
| 模块 | 文件/区域 | 影响 |
| ---------------- | ----------------------- | ---------------------------------------------- |
| DTO | `SaveInterfaceInput` | 入参结构重构 |
| DTO | `FormParameterInput` | 新增 `FieldPosition` |
| DTO | `ParameterInput` | 新增 `ParaKind` |
| Entity | `FormParameterEntity` | 新增 `FieldPosition` |
| Entity | `ParameterEntity` | 新增 `ParaKind` |
| SaveInterface | `InterfaceService` | 按 ContentType 互斥保存 |
| GetInterfaceById | `InterfaceService` | 按 ContentType 拆分返回 |
| 参数服务 | `ParameterService` | 保存/查询支持 `ParaKind` |
| 表单服务 | `FormParameterService` | 保存/查询支持 `FieldPosition` |
| 转发查询 | `InterfaceForwardQuery` | 映射树按 ContentType 选择 |
| 转发执行 | `DefaultForwardFlow` | `$FromMappingBody`、Query/Header/Form 来源调整 |
### 可能要改
| 模块 | 原因 |
| ---------------------------- | --------------------------------------------------------- |
| `InterfaceMapService` | 映射页面可能依赖下游 `InParameterList` |
| `InterfaceMapPublishService` | 发布缓存构建依赖参数树 |
| `FixedParameterService` | 方案要求删除接口级 Fixed 维护 |
| 导入导出 | 如果导出接口配置,需要更新结构 |
| 脚本助手 | 需要支持 `$FromMappingBody` 和新的 Query/Header/Body 结构 |
---
## 最大风险点
### 1. 映射页面风险最高
当前映射保存结构在 SaveParameterMapsInput.cs。
它的 `ParaId` 指向下游参数。
方案 B 后:
- Json/Xml 下游:`ParaId` 指向 `requestBodyParameterList`
- FormUrlEncoded 下游:`ParaId` 指向 `mappingBodyParameterList`
- Header/Query/BodyForm KV 不参与普通参数映射,除非值为 `$FromMappingBody`
这个规则必须前后端统一,否则映射会乱。
### 2. 缓存风险
转发上下文会缓存:
```csharp
ForwardContext:up_{upStreamCode}:sp_{serviceProviderCode}
```
重构后发布接口/保存接口必须清理或重建缓存,否则会拿旧结构转发。
### 3. FormUrlEncoded 行为变化
旧逻辑用 `$FromBody`,新逻辑用 `$FromMappingBody`。
如果现有表单配置里已经有 `$FromBody`,全量重构可以不兼容,但测试环境必须重新配置。
### 4. 接口级 Fixed 删除要谨慎
`t_parameter_fixed` 当前支持:
```csharp
ServiceProviderId
InterfaceId
```
方案要求删除接口级 Fixed 维护,但代码里 InterfaceForwardQuery.cs 仍会查:
```csharp
a.ServiceProviderId == serviceProviderId || a.InterfaceId == interfaceId
```
如果彻底删除接口级 Fixed,需要改成只查服务商级:
```csharp
a.ServiceProviderId == serviceProviderId
```
否则旧数据仍会生效。
---
## 推荐实施顺序
### 第一阶段:数据模型和 DTO
1. 新增 `ParameterParaKind` 枚举。
2. `ParameterEntity` 新增 `ParaKind`。
3. `ParameterInput` 新增 `ParaKind`。
4. `FormParameterEntity` 新增 `FieldPosition`。
5. `FormParameterInput` / `FormParameterItem` 新增 `FieldPosition`。
6. `SaveInterfaceInput` 拆分字段。
### 第二阶段:保存/查询接口
改 InterfaceService.cs:
- 上游:只保存 `inParameterList`
- 下游 Json/Xml:只保存 `requestBodyParameterList`
- 下游 FormUrlEncoded:保存 `bodyFormParameterList` + `mappingBodyParameterList`
- 所有类型:保存 `queryFormParameterList` + `headerFormParameterList`
- 所有类型:保存 `outParameterList`
并加入互斥校验。
### 第三阶段:转发查询
改 InterfaceForwardQuery.cs:
- `GetParameterMapListAsync()` 支持 `ParaKind`
- `GetFormFieldListAsync()` 改成按 `FieldPosition` 获取
- 构建 `TargetInterfaceSummary` 时区分:
- `QueryFieldList`
- `HeaderFieldList`
- `BodyFormFieldList`
- `InParamTreeList`
### 第四阶段:转发执行
改 DefaultForwardFlow.cs:
- `ReplacePlaceholder()` 支持 `$FromMappingBody`
- Query 从 Query KV 来
- Header 从 Header KV 来
- FormUrlEncoded Body 从 Body KV 来
- Json/Xml Body 保持序列化 `OriginalInterfaceMappedInput`
### 第五阶段:映射与发布
重点改:
- 映射详情查询
- 映射保存
- 发布缓存
- 缓存清理
### 第六阶段:测试
建议新增测试覆盖:
1. 下游 Json:`requestBodyParameterList` 映射并序列化为 JSON。
2. 下游 Xml:`requestBodyParameterList` 映射并序列化为 XML。
3. FormUrlEncoded:`mappingBodyParameterList` 映射,`bodyFormParameterList` 中 `$FromMappingBody` 被替换。
4. Query:所有 ContentType 都能拼 Query。
5. Header:所有 ContentType 都能加 Header。
6. 上游:仍只使用 `inParameterList`。
7. 接口级 Fixed 不再生效。
8. 服务商级 Fixed 仍生效。
---
## 可行性评级
| 项 | 评级 |
| ---------------------- | ---------------------------- |
| 技术可行性 | 高 |
| 代码改动量 | 中高 |
| 数据库改动风险 | 中 |
| 前端联动成本 | 高 |
| 转发链路风险 | 中高 |
| 是否建议做 | 建议做 |
| 是否适合一次性全量重构 | 可以,但必须有测试和联调环境 |
---
## 最终建议
方案 B 是正确方向,尤其解决了当前这几个长期隐患:
- Form 参数和 Query/Header 混用。
- 下游 `InParameterList` 语义不清。
- Json Body 和 Form Mapping Body 混用。
- `$FromBody` 表达不准确。
- 接口级 Fixed 和接口参数配置职责重叠。
建议按**全量重构**执行,但不要边改边猜。最好先做后端闭环:
```text
DB 字段 → DTO → Save/Get → ForwardContext → ForwardFlow → Tests
```
等后端测试跑通后,再让前端按方案 B 调整页面。