chore: initialize migration workspace
This commit is contained in:
266
working1/01-项目功能内容.md
Normal file
266
working1/01-项目功能内容.md
Normal 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、数据库、耗时、结果。
|
||||
526
working1/02-项目程序开发详细步骤.md
Normal file
526
working1/02-项目程序开发详细步骤.md
Normal 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
126
working1/03-推进台账.md
Normal 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`、解决方案和项目文件。
|
||||
91
working1/04-任务矩阵.md
Normal file
91
working1/04-任务矩阵.md
Normal 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
296
working1/05-验收证据.md
Normal 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
384
working1/06-决策记录.md
Normal 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
86
working1/README.md
Normal 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。
|
||||
Reference in New Issue
Block a user