From bb87363d6be8f60b1e23d23a7ee92683cd8de315 Mon Sep 17 00:00:00 2001 From: “wangming” <“wangming@antissoft.com”> Date: Tue, 17 Feb 2026 23:36:27 +0800 Subject: [PATCH] 添加设备查看会话记录功能,包括开始和结束记录的接口实现,更新相关实体和文档,确保接口测试流程的规范化。 --- .cursor/agents/backend-developer.md | 2 +- .cursor/rules/project_rules.mdc | 2 +- .cursor/skills/api-interface-testing/SKILL.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/SbRecordsEntity.cs | 14 +++++++++++++- 机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/NCC.Extend.Entitys.xml | 10 ++++++++++ 机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ISbRecordsService.cs | 20 +++++++++++++++++++- 机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/SbRecordsService.cs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 161 insertions(+), 4 deletions(-) diff --git a/.cursor/agents/backend-developer.md b/.cursor/agents/backend-developer.md index e930cf0..3179144 100644 --- a/.cursor/agents/backend-developer.md +++ b/.cursor/agents/backend-developer.md @@ -58,7 +58,7 @@ model: fast - 分页参数与逻辑在统计与列表间保持一致 ### 数据库与文档 -- **表命名**:业务前缀 + 功能名(如 `lq_`);字段驼峰;时间用 DateTime +- **表命名**:业务前缀 + 功能名;字段驼峰;时间用 DateTime - **统计类 SQL**:提交前用 MCP MySQL 工具执行验证,确认语法、字段、JOIN、统计逻辑正确后再写入代码 ### API 与接口 diff --git a/.cursor/rules/project_rules.mdc b/.cursor/rules/project_rules.mdc index 337e9eb..c8e061f 100644 --- a/.cursor/rules/project_rules.mdc +++ b/.cursor/rules/project_rules.mdc @@ -87,7 +87,7 @@ Id = Guid.NewGuid().ToString() ## 🗄️ 数据库规范 ### 命名规范 -- **表命名**: 业务前缀 + 功能名称 (如: lq_) +- **表命名**: 业务前缀 + 功能名称 - **字段命名**: 驼峰化 - **时间字段**: 统一使用 DateTime 类型 diff --git a/.cursor/skills/api-interface-testing/SKILL.md b/.cursor/skills/api-interface-testing/SKILL.md index ee331c0..6dec21a 100644 --- a/.cursor/skills/api-interface-testing/SKILL.md +++ b/.cursor/skills/api-interface-testing/SKILL.md @@ -11,11 +11,21 @@ description: 按项目规范执行接口测试,包含获取 Token、使用 cur - 用户明确要求进行接口测试或提供测试示例 - 提交代码前确认接口符合「必须测试」规范 +## 执行方式(必须按此执行) + +当用户本地 API 已启动(如 `http://localhost:2011`)时,**必须直接使用 Shell 执行 curl 命令**进行接口测试,而不是只给出 curl 示例让用户自己执行。 + +1. **登录获取 Token**:用 Shell 执行登录 curl,从返回 JSON 中解析 `data.token` +2. **调用目标接口**:用 Shell 依次执行 curl,请求头带上 `Authorization: {data.token}` +3. **数据库验证**:涉及增删改的接口,**必须**用 MCP MySQL 工具执行 SELECT 查库验证(遵循 `mcp-mysql-and-sql-validation` skill) +4. **输出测试报告**:汇总 HTTP 状态、返回值、数据库校验结果,给出通过/不通过结论 + ## 测试流程 1. **获取 Token**:先调用登录接口拿到 `data.token` 2. **调用目标接口**:请求头带上 `Authorization: {data.token}` 3. **验证结果**:按下方清单检查返回值与行为 +4. **查库验证**:对新增/修改/删除类接口,用 MCP 执行 SQL 验证数据是否正确落库 ## 获取 Token @@ -69,3 +79,36 @@ curl -X POST "http://localhost:2011/api/xxx/YourAction" \ ## 工具 可使用 curl、Postman、Swagger 等;给出示例时优先提供 **curl**,便于在终端直接执行。 + +## 完整执行示例(Shell + MCP 查库) + +以下为 SbRecords StartViewRecord / EndViewRecord 接口的实测流程,**以后接口测试均按此方式执行**: + +1. **Shell 执行登录**,获取 token: + ```bash + curl -s -X POST "http://localhost:2011/api/oauth/Login" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "account=admin&password=66762a3ccde2a2cff3060d7a4a0a576b" + ``` + 从返回 JSON 中提取 `data.token`,后续请求头使用 `Authorization: $TOKEN` + +2. **Shell 执行目标接口**(如 StartViewRecord): + ```bash + curl -s -X POST "http://localhost:2011/api/Extend/SbRecords/Actions/StartViewRecord" \ + -H "Authorization: $TOKEN" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "reId=xxx&type=查看设备" + ``` + 记录返回的 `data`(如 recordId) + +3. **Shell 执行后续接口**(如 EndViewRecord): + ```bash + curl -s -X POST "http://localhost:2011/api/Extend/SbRecords/Actions/EndViewRecord" \ + -H "Authorization: $TOKEN" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "recordId=xxx" + ``` + +4. **MCP 查库验证**:调用 `mcp_HongHua-JJ-my-sql-db_query` 执行 SELECT,校验关键字段(如 F_LeaveTime、F_DurationSeconds)是否正确写入 + +5. **输出测试报告**:表格汇总各用例的预期 vs 实际、数据库校验结果,给出「通过/不通过」结论 diff --git a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/SbRecordsEntity.cs b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/SbRecordsEntity.cs index 44840eb..e419647 100644 --- a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/SbRecordsEntity.cs +++ b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/SbRecordsEntity.cs @@ -1,4 +1,4 @@ -using NCC.Common.Const; +using NCC.Common.Const; using SqlSugar; using System; @@ -28,6 +28,18 @@ namespace NCC.Extend.Entitys /// [SugarColumn(ColumnName = "F_AddTime")] public DateTime? AddTime { get; set; } + + /// + /// 离开时间 + /// + [SugarColumn(ColumnName = "F_LeaveTime")] + public DateTime? LeaveTime { get; set; } + + /// + /// 停留时长(秒) + /// + [SugarColumn(ColumnName = "F_DurationSeconds")] + public long DurationSeconds { get; set; } /// /// 查看用户 diff --git a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/NCC.Extend.Entitys.xml b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/NCC.Extend.Entitys.xml index d19ddb2..bdeea26 100644 --- a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/NCC.Extend.Entitys.xml +++ b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/NCC.Extend.Entitys.xml @@ -8728,6 +8728,16 @@ 记录时间 + + + 离开时间 + + + + + 停留时长(秒) + + 查看用户 diff --git a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ISbRecordsService.cs b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ISbRecordsService.cs index ec34379..eaebcad 100644 --- a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ISbRecordsService.cs +++ b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ISbRecordsService.cs @@ -1,6 +1,24 @@ -namespace NCC.Extend.Interfaces.SbRecords +using System.Threading.Tasks; + +namespace NCC.Extend.Interfaces.SbRecords { public interface ISbRecordsService { + /// + /// 开始一条设备查看会话记录(进入页面时调用)。 + /// + /// 关联记录 Id,一般为设备 Id。 + /// 记录类型,例如“查看设备”。 + /// 备用字段1,可选。 + /// 备用字段2,可选。 + /// 返回新建记录的 Id(后续结束会话时使用)。 + Task StartViewRecordAsync(string reId, string type, string item1 = null, string item2 = null); + + /// + /// 结束一条设备查看会话记录(离开页面时调用),并计算停留时长。 + /// + /// 开始会话时返回的记录 Id。 + /// 返回是否更新成功。 + Task EndViewRecordAsync(string recordId); } } \ No newline at end of file diff --git a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/SbRecordsService.cs b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/SbRecordsService.cs index 9a90715..3600689 100644 --- a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/SbRecordsService.cs +++ b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/SbRecordsService.cs @@ -50,6 +50,80 @@ namespace NCC.Extend.SbRecords } /// + /// 开始一条设备查看会话记录(进入页面时调用)。 + /// + /// 关联记录 Id,一般为设备 Id。 + /// 记录类型,例如“查看设备”。 + /// 备用字段1,可选。 + /// 备用字段2,可选。 + /// 返回新建记录的 Id(后续结束会话时使用)。 + [HttpPost("Actions/StartViewRecord")] + public async Task StartViewRecordAsync(string reId, string type, string item1 = null, string item2 = null) + { + var now = DateTime.Now; + var entity = new SbRecordsEntity + { + Id = YitIdHelper.NextId().ToString(), + ReId = reId, + AddTime = now, + LeaveTime = null, + DurationSeconds = 0, + AddUser = _userManager.UserId, + Enable = true, + Item1 = item1, + Item2 = item2, + Type = type + }; + + var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync(); + if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1000); + + return entity.Id; + } + + /// + /// 结束一条设备查看会话记录(离开页面时调用),并计算停留时长。 + /// + /// 开始会话时返回的记录 Id。 + /// 返回是否更新成功。 + [HttpPost("Actions/EndViewRecord")] + public async Task EndViewRecordAsync(string recordId) + { + var now = DateTime.Now; + + var entity = await _db.Queryable().FirstAsync(p => p.Id == recordId); + if (entity == null) + { + return false; + } + + if (entity.AddTime == null) + { + entity.AddTime = now; + } + + if (entity.LeaveTime != null) + { + return true; + } + + entity.LeaveTime = now; + var seconds = (now - entity.AddTime.Value).TotalSeconds; + if (seconds < 0) + { + seconds = 0; + } + + entity.DurationSeconds = (long)Math.Round(seconds, MidpointRounding.AwayFromZero); + + var result = await _db.Updateable(entity) + .UpdateColumns(x => new { x.LeaveTime, x.DurationSeconds }) + .ExecuteCommandAsync(); + + return result > 0; + } + + /// /// 获取查看历史记录 /// /// 参数 -- libgit2 0.21.4