chore: initialize migration workspace

This commit is contained in:
2026-07-02 10:38:13 +08:00
commit 705aec6ab2
44 changed files with 5988 additions and 0 deletions

View File

@@ -0,0 +1,266 @@
# 01-项目功能内容
## 1. 项目目标
建设一个替代当前 `MES_Manage/submit/MESCommonBase.ashx` 的通用 WebAPI 服务,运行在 Linux 操作系统上,面向前台提供统一接口,并支持以下数据库:
- SQL Server
- PostgreSQL
- MySQL
新项目不是简单把 `ashx` 改成 WebAPI而是把旧项目中“前台通过 `Type/Name/Param` 驱动 SQL 和存储过程”的模式改造成:
```text
前台调用 WebAPI
-> 后端按 actionId 或 legacy type 找白名单
-> Provider 层选择 SQL Server / PostgreSQL / MySQL
-> 统一参数、统一鉴权、统一响应、统一日志
```
### 1.1 目标 SDK 与目录基线
- 新项目目标 SDK 固定为 `.NET 10`
- 新项目目标 `TargetFramework` 固定为 `net10.0`
- 新代码根目录固定为 `MesUniversalApi/`
- `working/` 仅保留分析资料,`working1/` 仅保留项目管理文档。
-`.NET 10 SDK` 安装到位前,只进行文档、目录、资产盘点和接口梳理,不以 `net9.0` 临时创建正式项目。
## 2. 旧系统核心能力
旧系统入口:
```text
MES_Manage/submit/MESCommonBase.ashx
```
旧系统主要能力:
| 能力 | 旧 Type | 说明 |
| --- | --- | --- |
| Excel 导出 | `2001` | 调用 `MESDownloadExcel.ExcelWebCall.ExcelFile` |
| PDF 导出 | `2002` | 调用 `ExcelWebCall.ExcelFilePdf` |
| Excel 图片或指定扩展名导出 | `2003` | 读取 Form 第一项,生成下载文件 |
| 数据库文件下载 | `2004` | 调用 `DataLink.ExePROCEDURE_Type2004` |
| 文件上传 | `15` | 读取 `Request.Files[0]`,调用 `ExePROCEDURE_Type15` |
| 数据库文件下载 | `16` | 调用 `ExePROCEDURE_Type16` |
| IP 查询 | `4000` | 返回请求 IP |
| 通用 SQL/存储过程调用 | default | 调用 `DataLink.SqlWebCall(type,jsonData,dataobj)` |
`SqlWebCall` 的二次分发能力:
| 能力 | 旧 Type |
| --- | --- |
| 加密、注册、登录 | `8888/5001/5002` |
| 旧协议存储过程 | `1/2/5` |
| 新协议存储过程 | `11/111/12/13/21` |
| 直接 SQL 查询或执行 | `3/4/22/1001/1002/3001` |
| 动态建表导入 | `7` |
## 3. 新项目功能范围
### 3.1 WebAPI 基础能力
新项目必须提供:
- HTTP JSON API。
- OpenAPI/Swagger 文档。
- JWT 鉴权。
- CORS 配置。
- 健康检查接口。
- 统一异常处理中间件。
- 统一响应结构。
- 结构化日志和审计日志。
- Linux 部署能力。
### 3.2 多数据库执行能力
新项目必须支持:
- SQL Server 连接和执行。
- PostgreSQL 连接和执行。
- MySQL 连接和执行。
- 参数绑定。
- 查询返回动态结果集。
- 非查询执行。
- 存储过程或函数调用。
- 分页查询。
- 文件二进制上传和下载。
数据库访问不允许散落在 Controller 中,必须通过 Provider 抽象:
```text
IDatabaseProvider
|-- SqlServerProvider
|-- PostgreSqlProvider
|-- MySqlProvider
```
### 3.3 旧协议兼容能力
新项目应提供短期兼容接口:
```http
POST /api/v1/legacy/execute
```
兼容字段:
- `type`
- `name`
- `param`
- `token`
- `pageSize`
- `pageList`
- `Pagination`
兼容原则:
- 兼容不等于完全放开。
- `name` 必须命中白名单。
- 高风险 Type 默认不开放。
- 旧接口只作为迁移过渡,不作为长期推荐接口。
### 3.4 新 actionId 接口
新业务推荐使用:
```http
POST /api/v1/actions/{actionId}/execute
```
例如:
```http
POST /api/v1/actions/quality.line.query/execute
```
好处:
- 前台不再传 SQL。
- 前台不再传存储过程名。
- 后端可按 actionId 做权限、参数、数据库命令和审计控制。
### 3.5 文件接口
上传:
```http
POST /api/v1/files/{actionId}/upload
```
下载:
```http
GET /api/v1/files/{actionId}/download
```
文件功能要求:
- 支持 multipart 上传。
- 支持文件大小限制。
- 支持扩展名白名单。
- 支持下载文件名 UTF-8 编码。
- 支持跨域读取 `Content-Disposition`
- 支持数据库 BLOB 或外部文件存储。
### 3.6 报表导出
`2001/2002/2003` 迁移为报表 action。
建议接口:
```http
POST /api/v1/reports/{reportId}/export
```
输出格式:
- Excel
- PDF
- 后续可扩展 CSV
## 4. 不在首期范围内的内容
首期不建议做:
- 一次性把所有 SQL Server 存储过程自动翻译成 MySQL/PostgreSQL。
- 继续开放任意 SQL 执行给前台。
- 重写全部前端。
- 重写所有 Excel 模板。
- 建立复杂低代码平台。
首期重点应是:
```text
WebAPI 化 + SQL Server 兼容 + 白名单治理 + Provider 抽象
```
## 5. 旧 Type 到新功能映射
| 旧 Type | 新项目目标功能 | 首期策略 |
| --- | --- | --- |
| `2001` | Excel 导出 | 转报表 action |
| `2002` | PDF 导出 | 转报表 action |
| `2003` | 扩展导出 | 评估后转报表 action |
| `2004` | 文件下载 | 转文件下载 action |
| `15` | 文件上传 | 转文件上传 action |
| `16` | 文件下载 | 转文件下载 action |
| `4000` | IP 查询 | 独立诊断接口 |
| `1/2/5` | 旧协议存储过程 | 兼容但必须白名单 |
| `11/111/12/13/21` | 新协议存储过程 | 优先兼容 |
| `8888/5001/5002` | 加密、注册、登录 | 迁移到 Auth API |
| `3/4/7/22/1001/1002/3001` | 直接 SQL 或建表 | 默认禁用或仅管理端审计开放 |
## 6. 目标质量属性
### 6.1 安全
- 所有执行业务接口默认要求登录。
- action 必须白名单。
- 参数必须按定义校验。
- 禁止前台任意传 SQL。
- 文件上传必须校验大小和类型。
- 连接字符串不进入代码仓库。
### 6.2 可移植
- 运行在 Linux。
- 支持 Docker。
- 支持 systemd。
- 不依赖 IIS。
- 不依赖 .NET Framework。
### 6.3 可观测
- 每次执行有 traceId。
- 每个 action 记录耗时。
- 记录数据库类型和数据源。
- 记录错误摘要。
- 支持健康检查。
### 6.4 可维护
- Controller 只负责 HTTP 协议。
- 业务编排在 Application 层。
- 数据库差异在 Infrastructure Provider 层。
- 任务推进受 `04-任务矩阵.md` 控制。
### 6.5 目录边界
- 不在 `MES_Manage/``02DataLinkMesWork/` 中直接展开新 WebAPI 开发。
- 不把新项目证据散落到旧项目目录。
- 新项目代码、测试、部署、工具和附件统一进入 `MesUniversalApi/`
- `working1/05-验收证据.md` 负责证据索引,原始附件优先放到 `MesUniversalApi/evidence/`
## 7. 首批验收目标
首批可验收功能:
1. WebAPI 项目可在 Linux 启动。
2. Swagger 可打开。
3. JWT 登录和鉴权可用。
4. SQL Server Provider 可执行旧 `Type=11` 查询。
5. Legacy 接口可接收旧格式请求。
6. actionId 接口可执行一个白名单查询。
7. 文件下载可返回正确文件名和二进制。
8. 审计日志可记录用户、action、数据库、耗时、结果。

View File

@@ -0,0 +1,526 @@
# 02-项目程序开发详细步骤
## 1. 开发总路线
项目推荐按以下顺序推进:
```text
准备阶段
-> 建立 WebAPI 骨架
-> 建立通用契约和响应
-> 建立数据库 Provider 抽象
-> 实现 SQL Server Provider
-> 实现 Legacy 兼容入口
-> 加入 actionId 白名单
-> 实现文件上传下载
-> 实现 PostgreSQL Provider
-> 实现 MySQL Provider
-> Linux 部署和回归测试
```
## 2. 技术栈
推荐:
- 语言C#
- 框架ASP.NET Core Web API
- 运行时:.NET 10 LTS
- 数据访问ADO.NET + Provider 策略;必要时配合 Dapper
- SQL Server 驱动:`Microsoft.Data.SqlClient`
- PostgreSQL 驱动:`Npgsql`
- MySQL 驱动:`MySqlConnector`
- 部署Linux + Docker 或 systemd
- 反向代理Nginx
- 文档OpenAPI/Swagger
- 日志Serilog 或 Microsoft.Extensions.Logging + OpenTelemetry
## 3. 新项目结构
建议结构:
```text
MesUniversalApi/
src/
MesUniversalApi.Api/
MesUniversalApi.Application/
MesUniversalApi.Contracts/
MesUniversalApi.Domain/
MesUniversalApi.Infrastructure/
tests/
MesUniversalApi.Tests/
MesUniversalApi.IntegrationTests/
```
当前移植根目录已先行创建为:
```text
MesUniversalApi/
src/
tests/
deploy/
docker/
systemd/
docs/
tools/
evidence/
```
职责:
| 项目 | 职责 |
| --- | --- |
| `Api` | Controller、鉴权、Swagger、过滤器、中间件 |
| `Application` | ActionService、LegacyTypeRouter、FileService、AuthService |
| `Contracts` | 请求和响应 DTO |
| `Domain` | ActionDefinition、DataSourceDefinition、业务模型 |
| `Infrastructure` | 数据库 Provider、日志、配置、JWT |
| `Tests` | 单元测试和集成测试 |
### 3.1 开工前置条件
开始 `T002 新 WebAPI 项目骨架创建` 之前,必须满足以下条件:
1. 开发机已安装 `.NET 10 SDK`
2. `dotnet --list-sdks` 输出中包含 `10.0.x`
3.`MesUniversalApi/` 根目录创建 `global.json`,锁定实际安装的 `10.0.x`
4. 不以 `net9.0` 或更低版本临时创建正式项目骨架。
5. 旧系统目录只用于盘点和对照,新增代码只进入 `MesUniversalApi/`
截至 2026-07-02当前机器仅检测到 `.NET SDK 9.0.311`,因此本轮只完成目录和文档准备,不执行 `net10.0` 项目生成。
## 4. 第一步:创建 WebAPI 骨架
建议命令:
```bash
cd MesUniversalApi
dotnet new globaljson --sdk-version 10.0.xxx
dotnet new sln -n MesUniversalApi
dotnet new webapi -f net10.0 -n MesUniversalApi.Api -o src/MesUniversalApi.Api
dotnet new classlib -f net10.0 -n MesUniversalApi.Application -o src/MesUniversalApi.Application
dotnet new classlib -f net10.0 -n MesUniversalApi.Contracts -o src/MesUniversalApi.Contracts
dotnet new classlib -f net10.0 -n MesUniversalApi.Domain -o src/MesUniversalApi.Domain
dotnet new classlib -f net10.0 -n MesUniversalApi.Infrastructure -o src/MesUniversalApi.Infrastructure
dotnet sln add src/**/*.csproj
```
说明:
- `10.0.xxx` 需替换为开发机实际安装的 `.NET 10 SDK` 版本号。
- 以上命令在 `.NET 10 SDK` 安装完成后执行。
- 当前轮次不以 `net9.0` 代替 `net10.0` 创建正式骨架。
依赖关系:
```text
Api -> Application -> Domain
Api -> Contracts
Application -> Contracts
Application -> Infrastructure abstractions
Infrastructure -> Domain / Contracts
```
## 5. 第二步:统一响应和异常处理
定义响应:
```csharp
public sealed class ApiResponse<T>
{
public string Code { get; init; } = "200";
public string Message { get; init; } = "";
public T? Data { get; init; }
public string TraceId { get; init; } = "";
}
```
分页响应:
```csharp
public sealed class PageResult
{
public IReadOnlyList<IDictionary<string, object?>> Rows { get; init; } = [];
public long Total { get; init; }
public int PageIndex { get; init; }
public int PageSize { get; init; }
}
```
错误中间件:
```text
ExceptionHandlingMiddleware
-> 捕获异常
-> 记录 traceId/user/action
-> 返回 ApiResponse<object>
```
## 6. 第三步:配置数据源
配置模型:
```csharp
public sealed class DataSourceDefinition
{
public string Name { get; init; } = "";
public DatabaseKind Kind { get; init; }
public string ConnectionStringName { get; init; } = "";
}
```
配置示例:
```json
{
"Database": {
"DefaultDataSource": "mes-main",
"DataSources": {
"mes-main": {
"Kind": "SqlServer",
"ConnectionStringName": "MES_SQLSERVER"
},
"mes-pg": {
"Kind": "PostgreSql",
"ConnectionStringName": "MES_POSTGRES"
},
"mes-mysql": {
"Kind": "MySql",
"ConnectionStringName": "MES_MYSQL"
}
}
}
}
```
连接字符串用环境变量:
```bash
ConnectionStrings__MES_SQLSERVER="Server=...;Database=...;User Id=...;Password=...;TrustServerCertificate=True"
ConnectionStrings__MES_POSTGRES="Host=...;Database=...;Username=...;Password=..."
ConnectionStrings__MES_MYSQL="Server=...;Database=...;User ID=...;Password=..."
```
## 7. 第四步:实现 Provider 抽象
核心接口:
```csharp
public interface IDatabaseProvider
{
DatabaseKind Kind { get; }
Task<QueryResult> QueryAsync(DbExecutionContext context, CancellationToken ct);
Task<NonQueryResult> ExecuteAsync(DbExecutionContext context, CancellationToken ct);
Task<ScalarResult> ScalarAsync(DbExecutionContext context, CancellationToken ct);
}
```
执行上下文:
```csharp
public sealed class DbExecutionContext
{
public string DataSourceName { get; init; } = "";
public DatabaseKind DatabaseKind { get; init; }
public CommandKind CommandKind { get; init; }
public string CommandText { get; init; } = "";
public IReadOnlyList<DbParameterValue> Parameters { get; init; } = [];
public PageRequest? Page { get; init; }
public int CommandTimeoutSeconds { get; init; } = 60;
}
```
Provider 实现顺序:
1. `SqlServerProvider`
2. `PostgreSqlProvider`
3. `MySqlProvider`
## 8. 第五步SQL Server Provider
先支持 SQL Server原因
- 当前旧系统以 SQL Server 存储过程为主。
- 先迁移入口,降低一次性风险。
实现能力:
- Text 查询。
- Text 非查询。
- StoredProcedure 查询。
- StoredProcedure 非查询。
- 输出参数。
- DataSet/DataTable 动态 JSON。
- 文件二进制。
关键点:
- 使用 `Microsoft.Data.SqlClient`
- `CommandType.StoredProcedure` 用于旧存储过程。
- 参数名前缀统一由 Provider 处理。
- 命令超时不要照搬 `0`,默认建议 60 秒,可按 action 配置。
## 9. 第六步Legacy 兼容入口
Controller
```http
POST /api/v1/legacy/execute
```
流程:
```text
LegacyController
-> 接收 type/name/param
-> LegacyTypeRouter
-> 白名单检查
-> LegacyParamParser
-> DbExecutionContext
-> Provider 执行
-> ApiResponse
```
优先兼容:
- `11`
- `111`
- `12`
- `13`
- `15`
- `16`
- `2004`
高风险 Type 先禁用:
- `3`
- `4`
- `7`
- `22`
- `1001`
- `1002`
- `3001`
## 10. 第七步actionId 白名单
新增接口:
```http
POST /api/v1/actions/{actionId}/execute
```
动作定义:
```csharp
public sealed class ActionDefinition
{
public string ActionId { get; init; } = "";
public string Module { get; init; } = "";
public bool Enabled { get; init; }
public string[] RequiredRoles { get; init; } = [];
public IReadOnlyList<ParameterDefinition> Parameters { get; init; } = [];
public IReadOnlyDictionary<DatabaseKind, ProviderCommandDefinition> Commands { get; init; }
= new Dictionary<DatabaseKind, ProviderCommandDefinition>();
}
```
执行流程:
```text
ActionController
-> ActionService
-> 读取 ActionDefinition
-> 校验权限
-> 校验参数
-> 根据 dataSource 选择 DatabaseKind
-> 根据 DatabaseKind 选择 CommandDefinition
-> Provider 执行
-> 统一响应
```
## 11. 第八步:文件上传下载
上传接口:
```http
POST /api/v1/files/{actionId}/upload
```
下载接口:
```http
GET /api/v1/files/{actionId}/download
```
开发步骤:
1. 定义文件 action。
2. 实现上传大小限制。
3. 实现扩展名白名单。
4. 实现 MIME 校验。
5. 实现数据库二进制写入。
6. 实现下载响应头。
7. 写文件 hash 校验测试。
二进制类型:
| 数据库 | 类型 |
| --- | --- |
| SQL Server | `varbinary(max)` |
| PostgreSQL | `bytea` |
| MySQL | `longblob` |
## 12. 第九步PostgreSQL Provider
实现内容:
- `NpgsqlConnection`
- 参数转换。
- Text 查询。
- Function 查询。
- 非查询执行。
- `bytea` 文件读写。
- `LIMIT/OFFSET` 分页。
迁移建议:
- SQL Server 查询型存储过程迁移为 PostgreSQL function。
- 输出参数尽量改为返回列或 JSON。
- 不做简单字符串替换,按 action 重写 SQL。
## 13. 第十步MySQL Provider
实现内容:
- `MySqlConnection`
- 参数转换。
- Text 查询。
- `CALL procedure(...)`
- 非查询执行。
- `longblob` 文件读写。
- `LIMIT/OFFSET` 分页。
注意:
- MySQL procedure 输出参数处理与 SQL Server 不同。
- 同一个 action 可为 MySQL 配置单独 SQL。
- 不要求 SQL Server 存储过程原样迁移。
## 14. 第十一步:鉴权与授权
实现:
- JWT 登录。
- `[Authorize]` 保护执行类接口。
- action 级权限。
- 用户角色映射。
- token 过期。
不沿用旧模式:
```text
token 非空才校验
```
新模式:
```text
除登录和健康检查外,默认必须鉴权
```
## 15. 第十二步:日志与审计
每次执行记录:
- traceId
- userId
- clientIp
- actionId
- legacyType
- legacyName
- dataSource
- databaseKind
- commandKind
- durationMs
- rowsAffected
- resultCode
- errorSummary
日志不记录明文密码和大二进制。
## 16. 第十三步Linux 部署
Docker
```bash
dotnet publish -c Release -o publish
docker build -t mes-universal-api:1.0.0 .
docker run -d -p 8080:8080 --env-file .env mes-universal-api:1.0.0
```
systemd
```ini
[Service]
WorkingDirectory=/opt/mes-api
ExecStart=/usr/bin/dotnet /opt/mes-api/MesUniversalApi.Api.dll
Restart=always
Environment=ASPNETCORE_URLS=http://0.0.0.0:8080
```
Nginx 反代:
```nginx
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
```
## 17. 第十四步:测试
单元测试:
- 参数解析。
- 类型转换。
- action 白名单。
- 权限校验。
- 响应包装。
集成测试:
- SQL Server 查询。
- SQL Server 存储过程。
- PostgreSQL 查询。
- MySQL 查询。
- 文件上传下载。
- JWT 成功和失败。
回归测试:
```text
旧 ashx 响应
vs
新 legacy/execute 响应
```
性能测试:
- 大查询。
- 分页。
- 文件上传下载。
- 长存储过程。
- 连接池。
## 18. 首轮开发建议
第一轮只做最小闭环:
1. 安装并验证 `.NET 10 SDK`
2. 新建 WebAPI 项目。
3. 加统一响应。
4. 加 Swagger。
5. 加 SQL Server Provider。
6. 加一个 actionId 查询。
7. 加一个 legacy Type=11 查询。
8. Linux 本地或 Docker 启动。
9. 记录验收证据。

126
working1/03-推进台账.md Normal file
View File

@@ -0,0 +1,126 @@
# 03-推进台账
本台账记录每轮推进做了什么、改了哪些文件、验证了什么、下一步是什么。
## 记录规则
每轮新增一条记录,格式如下:
```text
轮次:
日期:
目标:
完成内容:
改动文件:
验证证据:
遗留问题:
下一步:
```
## R001 - 分析资料整理与项目移植文档框架建立
日期2026-07-02
目标:
- 根据 `working` 中对 `MESCommonBase.ashx` 的分析资料,建立 `working1` 项目移植文档。
- 形成后续可持续推进的 README、功能、开发步骤、台账、任务矩阵、验收证据、决策记录。
完成内容:
- 盘点 `working` 目录已有分析资料。
- 确认 `working1` 目录存在且为空。
- 编写项目文档索引。
- 编写项目功能内容。
- 编写程序开发详细步骤。
- 编写推进台账。
- 编写任务矩阵。
- 编写验收证据。
- 编写决策记录。
改动文件:
- `working1/README.md`
- `working1/01-项目功能内容.md`
- `working1/02-项目程序开发详细步骤.md`
- `working1/03-推进台账.md`
- `working1/04-任务矩阵.md`
- `working1/05-验收证据.md`
- `working1/06-决策记录.md`
验证证据:
- 已读取 `working/MES通用WebAPI多数据库迁移技术路线.md`
- 已列出 `working` 目录文件。
- 已确认 `working1` 原为空目录。
- 已通过文件清单检查确认文档写入。
遗留问题:
- 尚未创建真实 WebAPI 项目代码。
- 尚未盘点所有前台实际调用的旧 Type/Name/Param。
- 尚未连接任何真实数据库。
- 尚未确定首批迁移的业务 action。
下一步:
1. 执行 `T001 旧接口资产盘点`
2. 执行 `T002 新 WebAPI 项目骨架创建`
3. 执行 `T003 数据源配置模型设计`
4. 明确首批 SQL Server 兼容接口。
## R002 - 固定 .NET 10 目标基线并创建新移植目录
日期2026-07-02
目标:
- 固定新项目目标 SDK 为 `.NET 10`
- 完善 `working1` 文档中的移植前准备内容。
- 创建独立的新移植目录,避免与旧系统代码混做。
完成内容:
- 确认目标 SDK 固定为 `.NET 10`,目标框架固定为 `net10.0`
- 确认当前开发机仅安装 `.NET SDK 9.0.311`,尚未具备生成 `net10.0` 项目的条件。
- 在仓库根目录创建 `MesUniversalApi/` 及其 `src/``tests/``deploy/``docs/``tools/``evidence/` 目录骨架。
- 补充 `working1` 中关于目录分工、前置条件、SDK 基线、启动规则和目录边界的文档内容。
- 为新移植目录创建说明文件和占位文件,明确后续代码、测试、部署和证据落点。
改动文件:
- `working1/README.md`
- `working1/01-项目功能内容.md`
- `working1/02-项目程序开发详细步骤.md`
- `working1/03-推进台账.md`
- `working1/04-任务矩阵.md`
- `working1/05-验收证据.md`
- `working1/06-决策记录.md`
- `MesUniversalApi/README.md`
- `MesUniversalApi/.gitignore`
- `MesUniversalApi/src/README.md`
- `MesUniversalApi/tests/README.md`
- `MesUniversalApi/docs/README.md`
- `MesUniversalApi/deploy/README.md`
- `MesUniversalApi/deploy/docker/README.md`
- `MesUniversalApi/deploy/systemd/README.md`
- `MesUniversalApi/tools/README.md`
- `MesUniversalApi/evidence/README.md`
验证证据:
- `dotnet --list-sdks` 输出仅包含 `9.0.311`
- `Get-ChildItem -LiteralPath 'MesUniversalApi' -Recurse -Depth 2` 已确认目录骨架创建成功。
遗留问题:
- `.NET 10 SDK` 尚未安装,当前还不能执行 `T002` 生成 `net10.0` 项目。
- 尚未进行 `T001` 旧接口资产盘点明细输出。
- 尚未建立新项目 git 仓库。
下一步:
1. 安装并验证 `.NET 10 SDK`
2. 执行 `T001 旧接口资产盘点`
3.`MesUniversalApi/` 下执行 `T002 新 WebAPI 项目骨架创建`
4. 补充 `global.json`、解决方案和项目文件。

View File

@@ -0,0 +1,91 @@
# 04-任务矩阵
状态说明:
- `未开始`:尚未实施。
- `进行中`:正在实施。
- `已完成`:已完成并有验收证据。
- `阻塞`:存在外部条件阻塞。
- `取消`:明确不再执行。
## 1. 总任务表
| 编号 | 任务 | 状态 | 优先级 | 验收标准 |
| --- | --- | --- | --- | --- |
| `T000` | 移植前基线准备 | 已完成 | P0 | 目标 SDK 固定为 `.NET 10``working1` 文档补齐;`MesUniversalApi/` 目录骨架创建;当前开发环境约束已记录 |
| `T001` | 旧接口资产盘点 | 未开始 | P0 | 输出旧 Type/Name/Param 调用清单标出文件、SQL、存储过程和高风险接口 |
| `T002` | 新 WebAPI 项目骨架创建 | 未开始 | P0 | 项目可启动Swagger 可访问,健康检查通过 |
| `T003` | 数据源配置模型设计 | 未开始 | P0 | 支持 SQL Server/PostgreSQL/MySQL 三类数据源配置 |
| `T004` | 统一响应与异常处理中间件 | 未开始 | P0 | 所有 JSON 接口返回 `{code,message,data,traceId}` |
| `T005` | JWT 鉴权和 action 授权 | 未开始 | P0 | 未登录不能执行业务接口action 权限可配置 |
| `T006` | Provider 抽象接口 | 未开始 | P0 | 定义 `IDatabaseProvider``DbExecutionContext`、结果模型 |
| `T007` | SQL Server Provider | 未开始 | P0 | 可执行 Text 查询、非查询、StoredProcedure、输出参数 |
| `T008` | Legacy Type=11 兼容 | 未开始 | P0 | 旧格式请求可通过白名单执行 SQL Server 存储过程并返回 JSON |
| `T009` | Legacy Type=111 分页兼容 | 未开始 | P1 | 可追加分页参数并返回 `rows/total` |
| `T010` | Legacy Type=12/13/21 兼容 | 未开始 | P1 | 执行型、DataSet、新结构响应均可用 |
| `T011` | 文件上传 Type=15 迁移 | 未开始 | P1 | multipart 上传成功,支持大小和扩展名校验 |
| `T012` | 文件下载 Type=16/2004 迁移 | 未开始 | P1 | 返回二进制、文件名和正确响应头 |
| `T013` | actionId 白名单执行接口 | 未开始 | P0 | 前台可通过 actionId 执行一个配置动作 |
| `T014` | PostgreSQL Provider | 未开始 | P1 | 可执行 Text 查询、Function、非查询、bytea 文件 |
| `T015` | MySQL Provider | 未开始 | P1 | 可执行 Text 查询、CALL procedure、非查询、longblob 文件 |
| `T016` | 报表导出接口 | 未开始 | P2 | 可按 reportId 导出 Excel/PDF |
| `T017` | 审计日志 | 未开始 | P0 | 记录用户、action、数据库、耗时、结果 |
| `T018` | Linux Docker 部署 | 未开始 | P0 | Docker 容器在 Linux 启动并通过健康检查 |
| `T019` | systemd 部署文档 | 未开始 | P2 | 具备 systemd service 配置和启动说明 |
| `T020` | 集成测试环境 | 未开始 | P1 | docker compose 可启动 API + 三类数据库测试环境 |
| `T021` | 旧接口回归对比 | 未开始 | P0 | 选定旧接口与新接口输出一致或差异有说明 |
| `T022` | 高风险 Type 退场方案 | 未开始 | P0 | `3/4/7/22/1001/1002/3001` 有明确禁用或替代方案 |
| `T023` | OpenAPI 与前台对接文档 | 未开始 | P1 | 前台可按文档调用新接口 |
| `T024` | 性能压测 | 未开始 | P2 | 有查询、分页、文件上传下载压测报告 |
| `T025` | 云仓库初始化与首次提交 | 进行中 | P1 | 云端仓库创建成功;`main` 分支首次提交完成;仓库只包含迁移资料与新移植目录 |
## 2. 当前优先队列
第一批建议执行:
1. `T001` 旧接口资产盘点。
2. `T002` 新 WebAPI 项目骨架创建。
3. `T003` 数据源配置模型设计。
4. `T004` 统一响应与异常处理中间件。
5. `T006` Provider 抽象接口。
6. `T007` SQL Server Provider。
7. `T008` Legacy Type=11 兼容。
## 3. 任务依赖
```text
T000 -> T001/T002/T003/T018/T020
T001 -> T008/T009/T010/T011/T012/T021/T022
T002 -> T003/T004/T005/T006/T018
T006 -> T007/T014/T015
T007 -> T008/T009/T010/T011/T012/T013
T013 -> T014/T015/T023
T017 -> T021/T024
```
## 4. 防重复规则
- 所有新工作必须先在本矩阵中找到或新增任务编号。
- 新增代码、测试、部署文件和工具脚本只进入 `MesUniversalApi/`,不回写到旧系统目录。
- 同一能力不得同时以 legacy 和 actionId 两条线重复开发,除非明确是兼容过渡。
- 已完成任务如果返工,必须在 `03-推进台账.md` 写明原因。
- 验收证据必须写入 `05-验收证据.md` 后才能标记 `已完成`
## 5. 高风险任务说明
### T022 高风险 Type 退场方案
必须处理的旧 Type
- `3`:直接 SQL 查询。
- `4`:直接 SQL 非查询。
- `7`:动态建表,含 DROP/CREATE。
- `22`:直接 SQL 返回新结构。
- `1001`:客户端传 SQL 增删改。
- `1002`:客户端传 SQL 查询。
- `3001`SQL 命令执行入口。
验收标准:
- 每个 Type 都有处置策略:禁用、仅内网管理、替换为 actionId、保留但强审计。
- 默认生产环境不可被普通前台调用。

296
working1/05-验收证据.md Normal file
View File

@@ -0,0 +1,296 @@
# 05-验收证据
本文件记录项目推进过程中的可复核证据包括命令、文件、页面、job_id、report_id、PDF、截图和接口响应。
## 1. 当前资料证据
### E001 - `working` 分析资料清单
日期2026-07-02
命令:
```powershell
Get-ChildItem -LiteralPath 'E:\通讯服务器20251217\通讯服务器20251217\working' -Force |
Select-Object Name,Length,LastWriteTime |
Sort-Object Name
```
关键输出:
```text
MESCommonBase程序梳理.md
MESCommonBase流程图.mmd
MESCommonBase流程图.png
MESCommonBase响应输出与SqlWebCall默认分支详细文档.md
MESCommonBase响应输出与SqlWebCall主流程图.mmd
MESCommonBase响应输出与SqlWebCall主流程图.png
MESCommonBase响应输出与SqlWebCall次流程图.mmd
MESCommonBase响应输出与SqlWebCall次流程图.png
MES通用WebAPI多数据库迁移技术路线.md
MESCommonBase迁移分析资料包.pptx
```
结论:
- `working` 已具备源程序梳理、流程图、默认分支详细文档和迁移技术路线。
### E002 - 技术路线文档读取
日期2026-07-02
命令:
```powershell
Get-Content -LiteralPath 'E:\通讯服务器20251217\通讯服务器20251217\working\MES通用WebAPI多数据库迁移技术路线.md' -TotalCount 80
```
结论:
- 技术路线文档确认了目标Linux WebAPI、MySQL/PostgreSQL/SQL Server、多数据库 Provider、actionId 白名单、旧协议兼容。
### E003 - `working1` 目录状态
日期2026-07-02
命令:
```powershell
Get-ChildItem -LiteralPath 'E:\通讯服务器20251217\通讯服务器20251217\working1' -Force
```
结论:
- 文档创建前 `working1` 为空,可安全写入项目移植文档。
### E004 - `working1` 文档写入
日期2026-07-02
新增文件:
```text
working1/README.md
working1/01-项目功能内容.md
working1/02-项目程序开发详细步骤.md
working1/03-推进台账.md
working1/04-任务矩阵.md
working1/05-验收证据.md
working1/06-决策记录.md
```
验收方式:
```powershell
Get-ChildItem -LiteralPath 'E:\通讯服务器20251217\通讯服务器20251217\working1' -Force |
Select-Object Name,Length,LastWriteTime |
Sort-Object Name
```
预期:
- 以上 7 个文件均存在。
### E005 - 当前开发机 .NET SDK 状态
日期2026-07-02
命令:
```powershell
dotnet --list-sdks
```
关键输出:
```text
9.0.311 [C:\Program Files\dotnet\sdk]
```
结论:
- 目标 SDK 虽已确定为 `.NET 10`,但当前开发机尚未安装 `.NET 10 SDK`
- 本轮只做文档、目录和基线准备,不执行 `net10.0` 项目脚手架创建。
### E006 - 新移植目录 `MesUniversalApi` 骨架创建
日期2026-07-02
命令:
```powershell
Get-ChildItem -LiteralPath 'E:\通讯服务器20251217\通讯服务器20251217\MesUniversalApi' -Recurse -Depth 2 |
Select-Object FullName, PSIsContainer
```
关键输出摘要:
```text
MesUniversalApi\src
MesUniversalApi\tests
MesUniversalApi\deploy
MesUniversalApi\deploy\docker
MesUniversalApi\deploy\systemd
MesUniversalApi\docs
MesUniversalApi\tools
MesUniversalApi\evidence
```
结论:
- 新移植项目目录已独立创建,后续源码、测试、部署和证据文件有明确落点。
## 2. 后续开发证据模板
### API 启动证据模板
任务编号:
命令:
```bash
dotnet run --project src/MesUniversalApi.Api
```
证据:
```text
Now listening on: http://localhost:xxxx
Application started.
```
页面:
```text
http://localhost:xxxx/swagger
```
结论:
### 健康检查证据模板
任务编号:
命令:
```bash
curl http://localhost:8080/health
```
响应:
```json
{
"status": "Healthy"
}
```
结论:
### 数据库连接证据模板
任务编号:
数据库:
命令或接口:
```bash
curl -H "Authorization: Bearer ..." http://localhost:8080/api/v1/admin/datasources/mes-main/test
```
响应:
```json
{
"code": "200",
"message": "",
"data": {
"connected": true,
"databaseKind": "SqlServer"
}
}
```
结论:
### Legacy 接口回归证据模板
任务编号:
旧请求:
```json
{
"type": "11",
"name": "...",
"param": "..."
}
```
旧接口响应摘要:
```text
行数:
字段:
关键值:
```
新接口响应摘要:
```text
行数:
字段:
关键值:
```
结论:
### 文件下载证据模板
任务编号:
命令:
```bash
curl -OJ -H "Authorization: Bearer ..." "http://localhost:8080/api/v1/files/xxx/download?fileId=123"
```
证据:
```text
文件名:
大小:
SHA256
Content-Disposition
```
结论:
### 截图/PDF/报告证据模板
任务编号:
文件:
```text
working1/evidence/...
```
说明:
结论:
## 3. 任务证据跟踪
| 任务编号 | 证据项 | 状态 |
| --- | --- | --- |
| `T000` | SDK 基线与新移植目录骨架 | 已补充 |
| `T001` | 旧接口资产盘点表 | 待补充 |
| `T002` | 新 WebAPI 启动截图或命令输出 | 待补充 |
| `T003` | 三类数据源配置样例 | 待补充 |
| `T007` | SQL Server Provider 连接测试 | 待补充 |
| `T008` | Legacy Type=11 回归响应 | 待补充 |
| `T014` | PostgreSQL Provider 连接测试 | 待补充 |
| `T015` | MySQL Provider 连接测试 | 待补充 |
| `T018` | Linux Docker 启动证据 | 待补充 |

384
working1/06-决策记录.md Normal file
View File

@@ -0,0 +1,384 @@
# 06-决策记录
本文件记录关键技术决策。格式参考 ADR。
状态说明:
- `已采纳`
- `待确认`
- `废弃`
## ADR-001 - 使用 C# 与 ASP.NET Core Web API
状态:已采纳
日期2026-07-02
背景:
- 当前系统为 C#/.NET Framework + `.ashx`
- 目标系统要求运行在 Linux。
- 前台通过 WebAPI 调用。
决策:
- 新项目使用 C#。
- Web 框架使用 ASP.NET Core Web API。
- 运行时优先使用 .NET 10 LTS。
原因:
- 与现有代码和团队知识体系最接近。
- ASP.NET Core 可跨平台运行。
- WebAPI、Swagger、JWT、HealthCheck、日志、Docker 支持成熟。
影响:
-`.ashx` 不直接迁移,改为 Controller。
-`.NET Framework` 依赖需要替换为 .NET 跨平台库。
## ADR-002 - 使用 Provider 策略支持多数据库
状态:已采纳
日期2026-07-02
背景:
- 目标支持 SQL Server、PostgreSQL、MySQL。
- 三种数据库在参数、分页、存储过程、函数、二进制字段、标识符引用方面存在差异。
决策:
- 定义 `IDatabaseProvider` 抽象。
- 分别实现 `SqlServerProvider``PostgreSqlProvider``MySqlProvider`
- 数据库差异只允许在 Provider 层处理。
原因:
- 避免 Controller 和业务层散落数据库判断。
- 允许同一个 actionId 对不同数据库配置不同 SQL 或函数。
- 便于单独测试每种数据库。
影响:
- 首期要设计好 `DbExecutionContext` 和参数模型。
- 不追求三种数据库完全共用同一段 SQL。
## ADR-003 - 使用 actionId 白名单替代前台任意传 SQL/存储过程名
状态:已采纳
日期2026-07-02
背景:
- 旧系统 `Name/name` 可由前台传入。
- `Name/name` 可能是存储过程名、SQL 文本或表名。
- 存在较高安全风险。
决策:
- 新接口以 `actionId` 作为业务动作标识。
- actionId 在后端白名单中配置 SQL、存储过程、参数、权限。
- legacy 接口也必须经过白名单。
原因:
- 降低 SQL 注入和越权执行风险。
- 便于审计。
- 便于多数据库为同一个 action 配置不同实现。
影响:
- 需要建设 action 配置。
- 前台后续要逐步从 `type/name/param` 迁移到 `actionId/parameters`
## ADR-004 - 保留 Legacy 接口作为迁移过渡
状态:已采纳
日期2026-07-02
背景:
- 现有前台可能大量依赖 `Type/Name/Param`
- 一次性改前台和后端风险较大。
决策:
- 新项目提供 `/api/v1/legacy/execute`
- 兼容旧字段,但不允许任意执行。
- 高风险 Type 默认禁用或限制。
原因:
- 降低迁移成本。
- 可逐个业务回归。
- 为前台改造争取时间。
影响:
- 需要实现 `LegacyTypeRouter``LegacyParamParser`
- 需要维护旧 Type 到 action 的映射。
## ADR-005 - SQL Server 优先落地,再扩展 PostgreSQL 和 MySQL
状态:已采纳
日期2026-07-02
背景:
- 当前系统主要依赖 SQL Server。
- 直接同步完成三类数据库会扩大风险。
决策:
- 第一阶段先实现 SQL Server Provider。
- 在 SQL Server 上跑通 legacy 兼容和 actionId。
- 再实现 PostgreSQL Provider。
- 再实现 MySQL Provider。
原因:
- 先保证现有业务迁移可行。
- Provider 抽象可在 SQL Server 实战中校准。
- 后续数据库迁移按 action 渐进完成。
影响:
- 多数据库不是第一天全部完成。
- 任务矩阵需要把三类数据库分开验收。
## ADR-006 - 不自动翻译全部 SQL Server 存储过程
状态:已采纳
日期2026-07-02
背景:
- SQL Server、PostgreSQL、MySQL 语法和过程语义差异明显。
- 自动翻译容易造成隐性错误。
决策:
- 不做全量自动 SQL 翻译。
- 按 actionId 逐个迁移。
- 每个 action 针对不同数据库配置独立 command。
原因:
- 便于测试。
- 便于控制风险。
- 避免假兼容。
影响:
- 迁移周期会按业务 action 分批推进。
- 需要建立回归测试样本。
## ADR-007 - 统一 JSON 响应格式
状态:已采纳
日期2026-07-02
背景:
- 旧接口返回格式混杂:数组 JSON、`result=1/0``{code,message,data}`、文本、空响应、`NULL`
决策:
- 新 JSON API 统一返回:
```json
{
"code": "200",
"message": "",
"data": {},
"traceId": ""
}
```
原因:
- 前台处理更简单。
- 错误更清晰。
- 审计和排障更方便。
影响:
- legacy 兼容接口可短期保留旧格式,但新接口必须统一格式。
## ADR-008 - 强制鉴权而不是 token 非空才校验
状态:已采纳
日期2026-07-02
背景:
- 旧代码中很多方法只在 `token` 非空时校验。
- 不传 token 时可能继续执行。
决策:
- 新系统除登录、健康检查等公开接口外,默认都要求 JWT 鉴权。
- action 再做权限校验。
原因:
- 明确安全边界。
- 防止前台漏传 token 导致绕过。
- 便于统一审计用户身份。
影响:
- 前台必须接入登录和 Bearer Token。
- legacy 接口也默认要求 JWT。
## ADR-009 - 高风险 Type 默认禁用或治理后开放
状态:已采纳
日期2026-07-02
背景:
旧系统以下 Type 风险较高:
- `3`
- `4`
- `7`
- `22`
- `1001`
- `1002`
- `3001`
决策:
- 生产环境默认禁用。
- 如确需保留,必须在管理端、内网、强审计、白名单条件下开放。
原因:
- 这些 Type 涉及直接 SQL、动态建表、命令执行。
- 多数据库迁移后风险会扩大。
影响:
- 需要逐个找替代 action。
- 需要和前台确认是否仍在使用。
## ADR-010 - 文件存储优先支持数据库二进制,后续可扩展对象存储
状态:待确认
日期2026-07-02
背景:
- 旧系统文件上传下载通过数据库存取 byte[]。
- 新系统需要兼容旧业务。
- 大文件放数据库可能影响性能和备份。
决策:
- 首期兼容数据库二进制。
- 设计 `FileService` 时预留对象存储或文件系统扩展。
原因:
- 首期降低迁移成本。
- 后续可按文件大小和业务类型分流。
待确认:
- 是否有大文件场景。
- 是否已有对象存储、NAS 或 MinIO。
- 是否要求文件加密和病毒扫描。
## ADR-011 - 新移植代码目录独立使用 `MesUniversalApi`
状态:已采纳
日期2026-07-02
背景:
- 当前仓库根目录同时包含旧 WebSite、旧类库、分析资料和管理文档。
- 如果直接在旧系统目录中混合创建新 WebAPI 代码,后续盘点、验收和回归会变得混乱。
决策:
- 新移植项目统一放在 `MesUniversalApi/`
- `working/` 继续保留旧系统分析资料。
- `working1/` 继续保留项目管理文档。
原因:
- 代码边界清晰。
- 旧系统可继续作为回归基线。
- 便于后续单独初始化 git 仓库、部署和验收。
影响:
- `T002` 及后续所有新代码、测试、部署和工具脚本都从 `MesUniversalApi/` 开始。
- 不在 `MES_Manage/``02DataLinkMesWork/` 等旧目录中直接展开新 WebAPI 开发。
## ADR-012 - 在 .NET 10 SDK 到位前只做基线准备,不用低版本临时落地
状态:已采纳
日期2026-07-02
背景:
- 新项目目标运行时已确定为 `.NET 10`
- 当前开发机仅检测到 `.NET SDK 9.0.311`
决策:
-`.NET 10 SDK` 安装到位前,只做文档、目录、任务、证据和资产盘点准备。
- 不以 `net9.0` 或更低版本临时创建正式项目骨架。
-`.NET 10 SDK` 安装后,再在 `MesUniversalApi/` 中创建 `global.json` 和正式项目文件。
原因:
- 避免先建低版本项目再返工升级。
- 避免把环境缺口误判为代码问题。
- 保持目标技术基线一致。
影响:
- 当前轮次不会生成可编译的 `net10.0` 项目代码。
- `T002` 的执行前置条件明确依赖 `.NET 10 SDK` 安装完成。
## ADR-013 - 云仓库只提交迁移资料和新移植目录
状态:已采纳
日期2026-07-02
背景:
- 当前本地根目录同时包含旧系统源码、IDE 状态、二进制产物、压缩包、分析资料和新移植目录。
- 用户要求把当前迁移工作提交到云仓库。
决策:
- 云仓库只跟踪 `working/``working1/``MesUniversalApi/`
- 不把旧系统全量源码、`.vs/`、本地压缩包、凭据文件和其他本地产物推送到云仓库。
原因:
- 保持仓库聚焦于迁移工作本身。
- 降低无关大文件和本地状态污染。
- 避免把本地凭据文件一并入库。
影响:
- 云仓库是迁移工作仓库,不是旧系统完整备份仓库。
- 如果后续确需纳入某部分旧代码,应单独评估并更新范围控制规则。

86
working1/README.md Normal file
View File

@@ -0,0 +1,86 @@
# MES 通用 WebAPI 多数据库迁移项目文档索引
本文档目录用于承接 `working` 中对 `MESCommonBase.ashx``DataLink.SqlWebCall`、响应输出、流程图和多数据库迁移路线的分析,形成后续项目推进时可持续维护的项目移植资料。
## 文档清单
| 编号 | 文档 | 用途 |
| --- | --- | --- |
| 01 | [01-项目功能内容.md](./01-项目功能内容.md) | 定义新项目要实现的功能范围、旧系统能力映射和目标边界 |
| 02 | [02-项目程序开发详细步骤.md](./02-项目程序开发详细步骤.md) | 按阶段说明从建项目到多数据库落地的开发方法 |
| 03 | [03-推进台账.md](./03-推进台账.md) | 记录每轮做了什么、改了哪些文件、验证了什么、下一步是什么 |
| 04 | [04-任务矩阵.md](./04-任务矩阵.md) | 汇总任务编号、状态、验收标准,防止重复做 |
| 05 | [05-验收证据.md](./05-验收证据.md) | 存放命令、文件、截图、报告、页面、job_id、report_id 等证据索引 |
| 06 | [06-决策记录.md](./06-决策记录.md) | 记录关键技术决策和原因,避免后续重复争论 |
## 目录分工
- `working`:保留旧系统分析资料、流程图、路线文档和演示材料,不放新项目代码。
- `working1`:保留项目管理文档、任务矩阵、推进台账、验收证据和决策记录。
- `MesUniversalApi`:新移植项目根目录,承载后续 WebAPI 源码、测试、部署文件、工具脚本和证据附件。
## 来源资料
本目录内容基于 `working` 目录中的分析资料整理:
- `working/MESCommonBase程序梳理.md`
- `working/MESCommonBase流程图.mmd`
- `working/MESCommonBase流程图.png`
- `working/MESCommonBase响应输出与SqlWebCall默认分支详细文档.md`
- `working/MESCommonBase响应输出与SqlWebCall主流程图.mmd`
- `working/MESCommonBase响应输出与SqlWebCall主流程图.png`
- `working/MESCommonBase响应输出与SqlWebCall次流程图.mmd`
- `working/MESCommonBase响应输出与SqlWebCall次流程图.png`
- `working/MES通用WebAPI多数据库迁移技术路线.md`
- `working/MESCommonBase迁移分析资料包.pptx`
## 后续推进规则
1. 新增任务先写入 `04-任务矩阵.md`,获得编号后再实施。
2. 每轮完成后更新 `03-推进台账.md`,记录改动、验证和下一步。
3. 所有可复核结果写入 `05-验收证据.md`,包括命令、文件路径、截图、报告和接口响应。
4. 影响架构、技术选型、安全边界、数据兼容的决定写入 `06-决策记录.md`
5. 需求范围、功能边界或旧 Type 映射变化时,同步更新 `01-项目功能内容.md`
6. 开发步骤、脚手架、部署或测试方法变化时,同步更新 `02-项目程序开发详细步骤.md`
## 当前环境基线
- 目标 SDK`.NET 10`
- 目标 `TargetFramework``net10.0`
- 新移植代码目录:`MesUniversalApi/`
- 当前开发机实际 SDK 状态2026-07-02仅检测到 `.NET SDK 9.0.311`
- 本轮处理原则:先完成文档、目录、任务和证据基线准备;待 `.NET 10 SDK` 安装完成后,再在 `MesUniversalApi/` 内执行 `T002` 创建项目骨架并锁定 `global.json`
## 当前推荐主线
```text
资产盘点
-> ASP.NET Core WebAPI 项目骨架
-> SQL Server Provider 优先兼容
-> Legacy Type 兼容入口
-> actionId 白名单
-> PostgreSQL Provider
-> MySQL Provider
-> 高风险 Type 退场
-> Linux 部署与验收
```
## 当前状态
截至本目录创建时,已完成:
-`MESCommonBase.ashx` 程序梳理。
- 响应输出与 `DataLink.SqlWebCall` 默认分支详细分析。
- 主流程图和次流程图。
- 通用 WebAPI 多数据库迁移技术路线。
- 本目录的项目移植管理文档框架。
- 目标 SDK 已固定为 `.NET 10`
- 新移植目录 `MesUniversalApi/` 已创建基础骨架。
- 当前开发机尚未安装 `.NET 10 SDK`,还不能开始 `net10.0` 项目脚手架生成。
下一步建议:
- 安装并验证 `.NET 10 SDK`
-`04-任务矩阵.md``T001 旧接口资产盘点` 开始推进。
-`MesUniversalApi/` 下执行 `T002 新 WebAPI 项目骨架创建`
- 明确首批迁移 Type 和首批业务 action。