From aa96451e59da0785b13c050ba510e1cc27519710 Mon Sep 17 00:00:00 2001
From: “wangming” <“wangming@antissoft.com”>
Date: Wed, 11 Feb 2026 13:37:47 +0800
Subject: [PATCH] 整理项目文件夹
---
.cursor/rules/project_rules.mdc | 15 +++++++++++++++
doc/故障查询-模板导出导入-任务分派.md | 128 --------------------------------------------------------------------------------------------------------------------------------
doc/故障查询导入模板.xlsx | Bin 5431 -> 0 bytes
docs/excel/故障查询导入模板.xlsx | Bin 0 -> 5431 bytes
docs/md/接口测试-zlgl-SimpleSearch-修复说明.md | 35 +++++++++++++++++++++++++++++++++++
docs/md/接口测试-小红点未读数量分析.md | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/md/接口测试-我的设备两个接口.md | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/md/接口测试报告-产品详情Tab接口.md | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/md/接口测试报告-移动端权限接口.md | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/md/搜索功能优化总结.md | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/md/故障查询-模板导出导入-任务分派.md | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/sql/fix-铁钻工产品缺失.sql | 11 +++++++++++
docs/sql/migrations_sbwhry.sql | 11 +++++++++++
docs/sql/migrations_xccpgl.sql | 28 ++++++++++++++++++++++++++++
fix-铁钻工产品缺失.sql | 11 -----------
uniapp_jiju/pages/new/gzpc/搜索功能优化总结.md | 199 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
接口测试-小红点未读数量分析.md | 95 -----------------------------------------------------------------------------------------------
接口测试-我的设备两个接口.md | 82 ----------------------------------------------------------------------------------
接口测试报告-产品详情Tab接口.md | 82 ----------------------------------------------------------------------------------
接口测试报告-移动端权限接口.md | 127 -------------------------------------------------------------------------------------------------------------------------------
机具(服务端)/migrations_sbwhry.sql | 11 -----------
机具(服务端)/migrations_xccpgl.sql | 28 ----------------------------
机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/ZlglService.cs | 42 +++++++++++++++++++++++++++++++++---------
23 files changed, 846 insertions(+), 772 deletions(-)
delete mode 100644 doc/故障查询-模板导出导入-任务分派.md
delete mode 100644 doc/故障查询导入模板.xlsx
create mode 100644 docs/excel/故障查询导入模板.xlsx
create mode 100644 docs/md/接口测试-zlgl-SimpleSearch-修复说明.md
create mode 100644 docs/md/接口测试-小红点未读数量分析.md
create mode 100644 docs/md/接口测试-我的设备两个接口.md
create mode 100644 docs/md/接口测试报告-产品详情Tab接口.md
create mode 100644 docs/md/接口测试报告-移动端权限接口.md
create mode 100644 docs/md/搜索功能优化总结.md
create mode 100644 docs/md/故障查询-模板导出导入-任务分派.md
create mode 100644 docs/sql/fix-铁钻工产品缺失.sql
create mode 100644 docs/sql/migrations_sbwhry.sql
create mode 100644 docs/sql/migrations_xccpgl.sql
delete mode 100644 fix-铁钻工产品缺失.sql
delete mode 100644 uniapp_jiju/pages/new/gzpc/搜索功能优化总结.md
delete mode 100644 接口测试-小红点未读数量分析.md
delete mode 100644 接口测试-我的设备两个接口.md
delete mode 100644 接口测试报告-产品详情Tab接口.md
delete mode 100644 接口测试报告-移动端权限接口.md
delete mode 100644 机具(服务端)/migrations_sbwhry.sql
delete mode 100644 机具(服务端)/migrations_xccpgl.sql
diff --git a/.cursor/rules/project_rules.mdc b/.cursor/rules/project_rules.mdc
index 2d68aca..337e9eb 100644
--- a/.cursor/rules/project_rules.mdc
+++ b/.cursor/rules/project_rules.mdc
@@ -169,6 +169,21 @@ Id = Guid.NewGuid().ToString()
9. **数据库文档**: 所有数据库表结构、字段说明、关联关系必须记录到数据库说明文档中
10. **ID生成规范**: 所有实体ID的生成都必须使用 `YitIdHelper.NextId().ToString()`,禁止使用 `Guid.NewGuid().ToString()` 或其他ID生成方式
11.**说明文档规范**:没有要求生成新的md文件的时候,严禁生成新md文件。
+12. **文档与产出物规范**:项目相关形成的 md、sql、excel、word、py 等文件,必须放在 `docs/` 下对应子目录(md、sql、excel、word、py),排除 .cursor、readme、第三方包内的文件。
+
+## 📁 文档与产出物目录
+
+项目产出物统一存放于 `docs/`,按类型分子目录:
+
+| 子目录 | 用途 |
+|--------|------|
+| `docs/md/` | 接口测试说明、功能总结、修复说明等 |
+| `docs/sql/` | 迁移脚本、修复脚本等 |
+| `docs/excel/` | xlsx/xls 导入模板、导出示例等 |
+| `docs/word/` | doc/docx 文档等 |
+| `docs/py/` | Python 脚本等 |
+
+位置:`HongHua-JJ/docs/{md|sql|excel|word|py}/`
## 📋 重要变更记录
diff --git a/doc/故障查询-模板导出导入-任务分派.md b/doc/故障查询-模板导出导入-任务分派.md
deleted file mode 100644
index 12a728d..0000000
--- a/doc/故障查询-模板导出导入-任务分派.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# 故障查询:模板 / 导出 / 导入 需求任务分派
-
-## 一、需求摘要
-
-| 模块 | 需求要点 |
-|------|----------|
-| **模板** | 设备id(HH2400 型)+ 设备名引用;去掉故障图片;严重程度、分类为引用;字段与「单个添加」一致(不含图片/附件) |
-| **导出** | 列与模板一致且第一列为 id;带引用;字段与单个添加一致 |
-| **导入** | 支持批量新增 + 批量修改;失败时标识出错误字段 |
-
----
-
-## 二、后端代理(Backend)
-
-**负责:** 模板下载、导出、导入的接口与逻辑;字段与字典来源确认。
-
-### 2.1 模板调整
-
-1. **设备 id / 设备名**
- - 去掉「所属设备ID(关联资料管理)」「设备名称(从资料管理自动带入)」两列。
- - 改为:**设备id**(数据库保存类似 HH2400 的编号)、**设备名**(选择设备 id 后自动带出)。
- - 需确认「设备id」数据来源:若为**资料管理 zlgl**,则设备 id 建议用 `sbbh`(设备编号)或 `bh`(编号),选择后带出 设备名(如 `zlm` 资料名);若为**产品管理 cpgl**,则设备 id 可用 `cpid`,设备名用 `cpmc`。当前前端单添加用的是 cpgl(关联产品),若产品与需求一致则沿用 cpgl,否则切到 zlgl 并统一 sssb/sbmc 存值规则。
- - 模板中「设备id」列做**下拉**,选项为设备 id 列表;「设备名」列通过公式或说明由选择结果带出(或由导入时后端按设备 id 解析带出)。
-
-2. **去掉故障图片**
- - 模板表头与数据列中不包含「故障图片」(gztp)。
-
-3. **严重程度、分类为引用**
- - **严重程度**:下拉,选项与前端单添加一致(轻微、一般、严重),或从字典/配置读取。
- - **分类**:下拉,选项与前端一致(字典类型 626791524004267269 的 base_dictionarydata),Excel 中为引用选择。
-
-4. **模板字段与单个添加一致**
- - 参考前端 `机具(管理端)/src/views/gzcx/Form.vue` 表单项(不含图片、附件):设备名称(keyword)、故障代码(code)、报警文本(zwbjwb)、故障描述(description)、发布时间(fbsj)、关联产品(sssb)→ 若改为设备则对应 设备id/设备名、严重程度(yzdcd)、外部简单描述(wbjdm)、故障原因(gzyy)、解决办法(jjbf)、分类(fl)。
- - 与前端对齐:模板列名、顺序、必填与单添加表单一致(仅去掉 故障图片、相关附件 的上传列)。
-
-### 2.2 导出数据调整
-
-1. Excel 列与模板列一致,且**第一列为 id**(主键 F_Id)。
-2. 导出文件中也带「引用」:设备 id、严重程度、分类等与模板一致(下拉/引用),便于二次编辑后导入。
-3. 导出字段与单个添加展示/编辑字段一致(与 2.1 中字段对齐,含 id)。
-
-### 2.3 导入调整
-
-1. **批量新增 + 批量修改**
- - 已存在逻辑:同分类 + 同故障代码视为同一条,存在则更新,不存在则新增。保持该逻辑,并确保「设备id」解析、分类/严重程度解析正确(按 id 或按名称兼容)。
-2. **导入报错时标识字段**
- - 某行导入失败时,在 `failResult` 中不仅返回该行数据,还要返回**错误原因**及**出错字段名**(如 `{ rowIndex, fieldName, message }` 或已在 item 上增加 `_errorField`、`_errorMessage`)。便于前端展示「第几行、哪个字段、什么错误」。
-
-### 2.4 接口与文档
-
-- 若 DTO/实体有变更(如 sssb 存设备 id 编号),需同步 `GetFiledMaps`、ImportPreview、ImportData、Export 的列与字段说明。
-- 模板下载、导出、导入接口的 XML 注释与 `api-interface-testing` 要求保持一致。
-
----
-
-## 三、前端代理(Frontend)
-
-**负责:** 与后端对齐「单个添加」字段;导入结果展示错误字段;必要时列表/导出列与模板一致。
-
-### 3.1 字段与模板一致
-
-1. **对照后端模板列**
- - 拿到后端最终模板表头(或接口 GetFiledMaps/ImportPreview 的 fileds),与 `Form.vue` 单添加表单项逐项对照:名称、顺序、是否必填。
- - 若后端将「关联产品」改为「设备id/设备名」,前端单添加表单需同步:改为「设备id」选择 + 「设备名」自动带出(数据源与后端一致:zlgl 或 cpgl),并保证提交字段与导入/导出一致。
-
-2. **列表与导出**
- - 列表列、导出列与模板列、单添加字段一致(第一列为 id,其余与模板顺序一致);若后端导出已按新规则,前端仅需确认下载与展示无误。
-
-### 3.2 导入报错展示
-
-1. **展示失败行与错误字段**
- - 导入接口返回的 `failResult` 中若包含 `_errorField`、`_errorMessage`(或等价结构),前端在导入结果中展示:行号、失败行摘要、**错误字段**、**错误信息**。
- - 若后端暂未返回字段级错误,前端先展示「第几行失败 + 原始行数据」,并和后端约定字段级错误结构后再补上「哪个字段出错」。
-
-### 3.3 不负责范围
-
-- 不负责模板/导出 Excel 的生成逻辑(由后端实现);仅负责调用接口、下载、上传及结果展示。
-
----
-
-## 四、测试代理(Test)
-
-**负责:** 模板、导出、导入、单添加与列表的端到端验证;数据库校验。
-
-### 4.1 测试前条件
-
-- 后端、前端按上述任务完成开发并联调通过。
-
-### 4.2 测试项
-
-1. **模板下载**
- - 表头与单添加字段一致(无故障图片、无附件列);设备id、设备名、严重程度、分类为引用/下拉;第一列可为占位或与导出一致(以后端实现为准)。
-2. **导出**
- - 第一列为 id;列与模板一致;带引用;数据与列表/单添加一致。
-3. **导入**
- - 批量新增:无同分类+同故障代码时,全部新增;库中有对应记录。
- - 批量修改:存在同分类+同故障代码时,该行更新;库中该条记录已更新。
- - 失败行:故意制造错误数据(如非法设备id、必填为空),确认返回中有失败行且**错误字段/错误信息**可识别;前端能正确展示。
-4. **单添加与列表**
- - 单添加字段与模板/导入字段一致;列表、导出、导入数据一致。
-5. **数据库**
- - 导入新增/更新后,用 MCP MySQL 或接口查询 gzcx 表,核对关键字段(如 设备id、设备名、分类、严重程度)与 Excel 一致。
-
-### 4.3 交付
-
-- 测试通过/不通过结论;不通过时列出问题与复现步骤,转交对应后端/前端处理。
-
----
-
-## 五、执行顺序建议
-
-1. **后端**:先确认设备 id 来源(zlgl 还是 cpgl)及 sssb/sbmc 存值规则 → 实现模板、导出、导入(含失败字段标识)。
-2. **前端**:根据后端最终字段与错误结构,对齐单添加表单与导入结果展示;必要时调整列表列。
-3. **测试**:在后端与前端均完成后,按 4.2 执行全量测试并反馈。
-
----
-
-## 六、参考文件
-
-| 用途 | 路径 |
-|------|------|
-| 单添加表单 | 机具(管理端)/src/views/gzcx/Form.vue |
-| 导入弹窗 | 机具(管理端)/src/views/gzcx/ImportForm.vue |
-| 故障查询服务 | 机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/GzcxService.cs |
-| 实体/DTO | 机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/ (GzcxEntity, GzcxCrInput, GzcxListOutput) |
-| 资料管理实体 | NCC.Extend.Entitys/Entity/ZlglEntity.cs(sbbh, bh, zlm) |
-| 产品管理实体 | NCC.Extend.Entitys/Entity/CpglEntity.cs(cpid, cpmc) |
-| 接口测试规范 | .cursor/skills/api-interface-testing/SKILL.md |
diff --git a/doc/故障查询导入模板.xlsx b/doc/故障查询导入模板.xlsx
deleted file mode 100644
index 354caf1..0000000
Binary files a/doc/故障查询导入模板.xlsx and /dev/null differ
diff --git a/docs/excel/故障查询导入模板.xlsx b/docs/excel/故障查询导入模板.xlsx
new file mode 100644
index 0000000..354caf1
Binary files /dev/null and b/docs/excel/故障查询导入模板.xlsx differ
diff --git a/docs/md/接口测试-zlgl-SimpleSearch-修复说明.md b/docs/md/接口测试-zlgl-SimpleSearch-修复说明.md
new file mode 100644
index 0000000..836b1f6
--- /dev/null
+++ b/docs/md/接口测试-zlgl-SimpleSearch-修复说明.md
@@ -0,0 +1,35 @@
+# zlgl SimpleSearch 无数据问题修复说明
+
+## 问题现象
+
+请求 `/api/Extend/zlgl/SimpleSearch?currentPage=1&pageSize=10&fl=786180219823195397&sskhbh=781034840806917381` 返回空列表,但该用户认为应有对应数据。
+
+## 根因
+
+1. **数据库情况**:
+ - `zlgl` 表存在 `fl=786180219823195397` 的资料(如:卧式五缸泵产品技术介绍)
+ - `khsb` 表中关联该产品(fl=786180219823195397)的设备,其 `sskhbh` 为 `781034555321615621`、`785683205549196549` 等组织 ID
+ - 传入的 `sskhbh=781034840806917381` 为用户 ID,与设备上的组织 ID 不一致
+
+2. **原逻辑缺陷**:
+ - 仅用 `k.Sskhbh.Contains(sskhbh)` 做客户过滤
+ - 未按用户所属组织扩展,导致用户所属组织下的设备被排除
+ - 仅通过 `Khsb.Fl` 获取产品,未考虑 `Khsb.Dysbbh = cpgl.Cpid` 的关联方式(旧数据可能只有 dysbbh 无 fl)
+
+## 修复内容
+
+调整 `ZlglService.GetSimpleSearchList` 的客户权限逻辑,与 `KhsbPermissionHelper` 保持一致:
+
+1. **sskhbh 扩展**:调用 `KhsbPermissionHelper.GetUserAllowedSskhbhIdsAsync`,得到当前用户可查看的 sskhbh 集合(userId、所属组织、上级组织等)。
+2. **产品来源**:
+ - 来源 1:`Khsb.Fl`(已填关联产品 ID 的设备)
+ - 来源 2:`Khsb.Dysbbh = cpgl.Cpid`(通过产品编号关联的旧设备)
+3. **权限过滤**:仅返回该用户可查看设备关联产品下的 `zlgl` 资料。
+
+## 验证建议
+
+1. 使用同一 token 再次请求:
+ ```
+ GET /api/Extend/zlgl/SimpleSearch?currentPage=1&pageSize=10&fl=786180219823195397&sskhbh=781034840806917381
+ ```
+2. 预期:用户 781034840806917381 若属于组织 781034555321615621(或其它已关联产品的组织),应能查到 `fl=786180219823195397` 的资料。
diff --git a/docs/md/接口测试-小红点未读数量分析.md b/docs/md/接口测试-小红点未读数量分析.md
new file mode 100644
index 0000000..6dfb2b9
--- /dev/null
+++ b/docs/md/接口测试-小红点未读数量分析.md
@@ -0,0 +1,95 @@
+# 小红点(未读数量)异常分析 - 供测试排查
+
+## 一、小红点出现位置
+
+移动端首页(`uniapp_jiju/pages/home/home.vue`)有两处小红点(u-badge):
+
+| 入口 | 变量 | 数据来源 |
+|------------|------------|----------------------------------|
+| **信息推送** | `xxtsvalue` | `hqxxwdsl` → 信息推送未读数量 |
+| **用户反馈** | `yhfkvalue` | `hqxtwdnumber` + `hqsbwtwdnumber` 之和 |
+
+## 二、接口与数据流
+
+### 1. 信息推送小红点
+
+| 步骤 | 说明 |
+|------|------|
+| 获取未读数 | `GET /api/Extend/Xxtsjl/Actions/GetMessageCount?userId=xxx` |
+| 前端入参 | `info.userId = uni.getStorageSync('userinfo').userId` |
+| 后端逻辑 | `sfyd != "是"` 视为未读,返回 `unreadCount` |
+| 标记已读 | 用户进入详情页时调用 `PUT /api/Extend/Xxtsjl/{ff}`,body 含 `sfyd: '是'` |
+| 刷新时机 | 首页 `onShow` 时调用 `hquserxx()` → `hqxxwdsl()` |
+
+### 2. 用户反馈小红点
+
+| 步骤 | 说明 |
+|------|------|
+| 系统问题未读 | `GET /api/Extend/Xtwtfk/Actions/GetUnreadCountByAccount?account=xxx` |
+| 设备问题未读 | `GET /api/Extend/Sbwtfk/Actions/GetUnreadCountByAccount?account=xxx` |
+| 前端入参 | `info.id = uni.getStorageSync('userinfo').userId` |
+| 后端逻辑 | Xtwtfk: `Cljg != "已处理"` 且 `Sfyd != "是"`;Sbwtfk: `Cljg != "已处理"` 且 `Sfyd != "已读"` |
+
+## 三、可能原因
+
+### 前端
+
+1. **u-badge 在未读数为 0 时仍展示**
+ - 当前:`` 无 `hidden`/`show`
+ - 可能:`value` 为 `0` 时仍显示小圆点或数字
+ - 建议:加 `v-if="xxtsvalue > 0"` 或 `:show="!!xxtsvalue"`,0 时不渲染
+
+2. **userinfo 字段不一致**
+ - `hqxxwdsl` 用 `userinfo.userId`
+ - `hqxtwdnumber` / `hqsbwtwdnumber` 用 `userinfo.userId` 作为 `id` 传入 `account`
+ - 若登录接口返回的是 `id` 而不是 `userId`,会导致 userId 为空
+
+3. **onShow 刷新时机**
+ - 首页 `onShow` 会执行 `hquserxx()` 并刷新两个小红点
+ - Tab 切换、从信息推送详情返回等都会触发 `onShow`,逻辑上是合理的
+
+### 后端
+
+1. **标记已读失败**
+ - 详情页 `xgxxwyd(cached)` 使用 `item.ff` 作为 PUT 路径参数
+ - 需确认接口实际更新了 `sfyd` 且条件 `it.Ff == id` 正确
+ - 建议:在数据库直接查该 `ff` 对应的 `sfyd` 是否已更新为「是」
+
+2. **GetMessageCount 的 userId 不匹配**
+ - Xxtsjl 表 `jsr` 存的是用户 ID
+ - 若传入的 `userId` 与 `jsr` 不一致(如传错字段、大小写等),统计会不对
+ - 建议:打印请求中的 `userId` 和数据库中 `jsr` 的格式是否一致
+
+3. **Jsr 为 JSON 多选**
+ - 后端支持 `p.Jsr.Contains(userId)`,即 JSON 数组包含该 userId
+ - 若 `jsr` 存的是 JSON 数组,需确认 Contains 的匹配逻辑是否符合实际存储格式
+
+## 四、测试建议
+
+1. **信息推送**
+ - 确认一条未读消息的 `ff`、`jsr`、`sfyd` 在数据库中的值
+ - 进入该消息详情页,确认调用 `PUT /api/Extend/Xxtsjl/{ff}` 且 body 含 `sfyd: '是'`
+ - 返回首页,确认 `GetMessageCount` 返回的 `unreadCount` 是否减少
+ - 检查首页 badge 在 `unreadCount === 0` 时是否还会显示
+
+2. **用户反馈**
+ - 确认 Xtwtfk、Sbwtfk 的 `GetUnreadCountByAccount` 入参为 userId(account)
+ - 确认两条接口的未读判断条件与业务规则一致
+
+3. **前端调试**
+ - 在 `hqxxwdsl` 回调中 `console.log(res.data)` 看 `unreadCount`
+ - 在 `hquserxx` 中 `console.log(uni.getStorageSync('userinfo'))` 看 `userId` / `id` 字段
+
+## 五、建议修改(前端)
+
+若确认「已读后仍显示小红点」为前端展示问题,可增加如下逻辑:
+
+```vue
+
+
+
+
+
+```
+
+若测试发现是**接口返回的 unreadCount 未正确减少**,则需后端排查标记已读和统计逻辑。
diff --git a/docs/md/接口测试-我的设备两个接口.md b/docs/md/接口测试-我的设备两个接口.md
new file mode 100644
index 0000000..093e051
--- /dev/null
+++ b/docs/md/接口测试-我的设备两个接口.md
@@ -0,0 +1,82 @@
+# 我的设备 - 接口测试说明
+
+## 两个接口地址
+
+| 用途 | 接口地址 | 方法 | 说明 |
+|------|----------|------|------|
+| 关联产品下拉 | `GET /api/Extend/Cpgl/Actions/AllowedList` | GET | 获取当前用户可查看的产品列表(仅「我的设备」关联的产品) |
+| 设备列表 | `GET /api/Extend/Khsb` | GET | 获取我的设备列表,支持 `fl` 按关联产品筛选 |
+
+**Base URL**:`http://localhost:2011`(以实际运行环境为准)
+
+---
+
+## 测试 Token(CY 用户,非管理员)
+
+```
+Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI3ODEwMzQ4NDA4MDY5MTczODEiLCJBY2NvdW50IjoiQ1kiLCJVc2VyTmFtZSI6IumZiOWLhyIsIkFkbWluaXN0cmF0b3IiOjAsIlRlbmFudElkIjoiZGIiLCJUZW5hbnREYk5hbWUiOiJkb25nZmFuZ2RpYW5xaSIsImlhdCI6MTc3MDc4MzMyNCwibmJmIjoxNzcwNzgzMzI0LCJleHAiOjE3NzExNDMzMjQsImlzcyI6Inlpbm1haXNvZnQiLCJhdWQiOiJ5aW5tYWlzb2Z0In0._iHXemLqF-r_7SJHh6ZnpNIiZVQR2BCoX4pnwwq_qW8
+```
+
+---
+
+## curl 测试示例
+
+### 1. 关联产品下拉(AllowedList)
+
+```bash
+curl -X GET "http://localhost:2011/api/Extend/Cpgl/Actions/AllowedList?currentPage=1&pageSize=1000&sort=desc&sidx=id" \
+ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI3ODEwMzQ4NDA4MDY5MTczODEiLCJBY2NvdW50IjoiQ1kiLCJVc2VyTmFtZSI6IumZiOWLhyIsIkFkbWluaXN0cmF0b3IiOjAsIlRlbmFudElkIjoiZGIiLCJUZW5hbnREYk5hbWUiOiJkb25nZmFuZ2RpYW5xaSIsImlhdCI6MTc3MDc4MzMyNCwibmJmIjoxNzcwNzgzMzI0LCJleHAiOjE3NzExNDMzMjQsImlzcyI6Inlpbm1haXNvZnQiLCJhdWQiOiJ5aW5tYWlzb2Z0In0._iHXemLqF-r_7SJHh6ZnpNIiZVQR2BCoX4pnwwq_qW8"
+```
+
+### 2. 设备列表(Khsb)
+
+```bash
+# 无产品筛选
+curl -X GET "http://localhost:2011/api/Extend/Khsb?currentPage=1&pageSize=20&sort=desc&sidx=" \
+ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI3ODEwMzQ4NDA4MDY5MTczODEiLCJBY2NvdW50IjoiQ1kiLCJVc2VyTmFtZSI6IumZiOWLhyIsIkFkbWluaXN0cmF0b3IiOjAsIlRlbmFudElkIjoiZGIiLCJUZW5hbnREYk5hbWUiOiJkb25nZmFuZ2RpYW5xaSIsImlhdCI6MTc3MDc4MzMyNCwibmJmIjoxNzcwNzgzMzI0LCJleHAiOjE3NzExNDMzMjQsImlzcyI6Inlpbm1haXNvZnQiLCJhdWQiOiJ5aW5tYWlzb2Z0In0._iHXemLqF-r_7SJHh6ZnpNIiZVQR2BCoX4pnwwq_qW8"
+
+# 按产品筛选(替换 {产品ID} 为 AllowedList 返回的 id)
+curl -X GET "http://localhost:2011/api/Extend/Khsb?currentPage=1&pageSize=20&sort=desc&sidx=&fl={产品ID}" \
+ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI3ODEwMzQ4NDA4MDY5MTczODEiLCJBY2NvdW50IjoiQ1kiLCJVc2VyTmFtZSI6IumZiOWLhyIsIkFkbWluaXN0cmF0b3IiOjAsIlRlbmFudElkIjoiZGIiLCJUZW5hbnREYk5hbWUiOiJkb25nZmFuZ2RpYW5xaSIsImlhdCI6MTc3MDc4MzMyNCwibmJmIjoxNzcwNzgzMzI0LCJleHAiOjE3NzExNDMzMjQsImlzcyI6Inlpbm1haXNvZnQiLCJhdWQiOiJ5aW5tYWlzb2Z0In0._iHXemLqF-r_7SJHh6ZnpNIiZVQR2BCoX4pnwwq_qW8"
+```
+
+---
+
+## 测试结果与分析(CY 用户 Token)
+
+### 1. AllowedList 返回 3 个产品
+
+| id | cpmc | cpid |
+|----|------|------|
+| 786180219823195397 | 五缸泵 | HH2400 |
+| 785333585623123205 | 顶驱500T | DQ500Z |
+| 785331243859313925 | 动力猫道(甩三) | DLMD039X |
+
+### 2. Khsb 设备列表返回 4 台设备
+
+| sbmc | dysbbh | 是否在 AllowedList 中 |
+|------|--------|----------------------|
+| 五缸泵 | HH2400 | ✓ 对应产品 五缸泵 |
+| 动力猫道(甩三) | DLMD039X | ✓ 对应产品 动力猫道 |
+| 铁钻工 | **test003** | ✗ 产品表中无 cpid=test003 |
+| 顶驱500T | DQ500Z | ✓ 对应产品 顶驱500T |
+
+### 3. 差异原因
+
+- **AllowedList** 仅通过 `khsb.dysbbh = cpgl.cpid` 关联产品,只返回在 cpgl 中有对应记录的产品。
+- 设备「铁钻工」的 `dysbbh=test003` 在 cpgl 中无匹配产品(cpid 无 test003),因此不会出现在 AllowedList 中。
+- **设备列表**按 `sskhbh` 过滤,展示用户可见的全部设备,包括 dysbbh 未在 cpgl 中匹配的设备。
+
+### 4. 结论
+
+两接口逻辑一致:AllowedList 只展示「有对应产品档案」的设备关联产品;设备列表则展示全部可见设备。
+设备「铁钻工」未出现在产品下拉中,是因为其 dysbbh(test003)在 cpgl 中无对应产品,需在 cpgl 中补充或修正该设备的 dysbbh。
+
+---
+
+## 验证要点
+
+1. **AllowedList** 返回的产品 ID 列表,应来自「khsb.dysbbh = cpgl.cpid」且 khsb.sskhbh 属于当前用户
+2. **Khsb** 设备列表按 `khsb.sskhbh` 过滤(所属客户=本人/部门/组织)
+3. 选择 AllowedList 中某产品作为 `fl` 筛选设备时,设备应满足:Khsb.Fl / Khsb.Dysbbh / Khsb.Dysb 与选中产品匹配
+4. 若设备 dysbbh 在 cpgl 中无对应 cpid,该设备关联的「产品」不会出现在 AllowedList 中
diff --git a/docs/md/接口测试报告-产品详情Tab接口.md b/docs/md/接口测试报告-产品详情Tab接口.md
new file mode 100644
index 0000000..24853d5
--- /dev/null
+++ b/docs/md/接口测试报告-产品详情Tab接口.md
@@ -0,0 +1,82 @@
+# 接口测试报告 - 产品详情 Tab 相关接口
+
+**测试时间**:2025-02-11
+**测试环境**:http://localhost:2011
+**测试账号**:admin(管理员)
+
+---
+
+## 1. 测试结果汇总
+
+| 接口 | 状态 | 说明 |
+|------|------|------|
+| POST /api/oauth/Login | ✅ | 返回 token |
+| GET /api/Extend/Cpgl | ✅ | 产品列表,7 条 |
+| GET /api/Extend/Cpgl/{id} | ✅ | 产品详情 |
+| GET /api/Extend/Bjxx | ✅ | 备件列表,94 条 |
+| GET /api/Extend/Bjxx?sssb={产品ID} | ✅ | 按产品筛选,90 条(产品 785331243859313925) |
+| GET /api/Extend/Zlgl | ✅ | 产品资料,11 条 |
+| GET /api/Extend/Gzcx | ✅ | 故障查询,260 条 |
+| GET /api/Extend/Pxzs | ✅ | 培训展示,3 条 |
+| GET /api/Extend/Xccpgl | ✅ | 宣传产品,2 条 |
+| GET /api/Extend/Zsk | ✅ | 知识库,6 条 |
+
+---
+
+## 2. curl 示例(供复测)
+
+### 2.1 获取 Token
+
+```bash
+curl -X POST "http://localhost:2011/api/oauth/Login" \
+ -H "Content-Type: application/x-www-form-urlencoded" \
+ -d "account=admin&password=66762a3ccde2a2cff3060d7a4a0a576b"
+```
+
+### 2.2 产品列表与详情
+
+```bash
+# 产品列表
+curl -X GET "http://localhost:2011/api/Extend/Cpgl?currentPage=1&pageSize=3" \
+ -H "Authorization: "
+
+# 产品详情(替换 {id} 为实际产品 ID)
+curl -X GET "http://localhost:2011/api/Extend/Cpgl/{id}" \
+ -H "Authorization: "
+```
+
+### 2.3 备件列表(按产品筛选 sssb)
+
+```bash
+# 备件列表(按产品 ID 筛选)
+curl -X GET "http://localhost:2011/api/Extend/Bjxx?currentPage=1&pageSize=5&sssb=785331243859313925" \
+ -H "Authorization: "
+```
+
+### 2.4 Tab 其它接口
+
+```bash
+# 产品资料
+curl -X GET "http://localhost:2011/api/Extend/Zlgl?currentPage=1&pageSize=3" -H "Authorization: "
+
+# 故障查询
+curl -X GET "http://localhost:2011/api/Extend/Gzcx?currentPage=1&pageSize=3" -H "Authorization: "
+
+# 培训展示
+curl -X GET "http://localhost:2011/api/Extend/Pxzs?currentPage=1&pageSize=3" -H "Authorization: "
+
+# 宣传产品
+curl -X GET "http://localhost:2011/api/Extend/Xccpgl?currentPage=1&pageSize=3" -H "Authorization: "
+
+# 知识库
+curl -X GET "http://localhost:2011/api/Extend/Zsk?currentPage=1&pageSize=3" -H "Authorization: "
+```
+
+---
+
+## 3. 验证要点
+
+- [x] 登录接口返回有效 token
+- [x] 各 Tab 对应接口均能正常返回数据
+- [x] 备件接口 `sssb` 参数按产品 ID 筛选正常
+- [x] 分页与列表结构符合预期
diff --git a/docs/md/接口测试报告-移动端权限接口.md b/docs/md/接口测试报告-移动端权限接口.md
new file mode 100644
index 0000000..76792fc
--- /dev/null
+++ b/docs/md/接口测试报告-移动端权限接口.md
@@ -0,0 +1,127 @@
+# 接口测试报告 - 移动端权限接口
+
+**测试时间**:2025-02-12
+**测试环境**:http://localhost:2011
+**测试账号**:admin(管理员)
+
+---
+
+## 1. 测试范围
+
+培训展示、故障排查、备件支持三大模块的移动端专用接口:
+
+| 模块 | 列表接口 | 详情接口 | 简单搜索(带权限) |
+|----------|---------------------|----------------------------------|----------------------|
+| 培训展示 | Pxzs/MobileList | Pxzs/Mobile/{id} | - |
+| 故障排查 | Gzcx/MobileList | Gzcx/Mobile/{id} | gzcx/SimpleSearch |
+| 备件支持 | Bjxx/MobileList | Bjxx/Mobile/{id} | bjxx/SimpleSearch |
+
+---
+
+## 2. 测试结果汇总
+
+| 接口 | 状态 | 说明 |
+|-----------------------------------------|------|------------------------------|
+| Pxzs/Actions/MobileList | ✅ | 返回分页列表,含 pxmc、sbmc 等 |
+| Pxzs/Actions/Mobile/{id} | ✅ | 返回详情含 fj1、slt、jj 等 |
+| Gzcx/Actions/MobileList | ✅ | 返回分页列表,含 code、zwbjwb 等 |
+| Gzcx/Actions/Mobile/{id} | ✅ | 返回详情含 attachements、yzdcd 等 |
+| gzcx/SimpleSearch | ✅ | searchKey 匹配故障代码正常 |
+| Bjxx/Actions/MobileList | ✅ | 返回分页列表,含 mc、bjqk 等 |
+| Bjxx/Actions/Mobile/{id} | ✅ | 返回详情含 sjbj、ynbj、lnbj 等 |
+| bjxx/SimpleSearch | ✅ | 无关键字/有关键字均正常 |
+
+---
+
+## 3. curl 示例(供复测)
+
+### 3.1 获取 Token
+
+```bash
+curl -X POST "http://localhost:2011/api/oauth/Login" \
+ -H "Content-Type: application/x-www-form-urlencoded" \
+ -d "account=admin&password=66762a3ccde2a2cff3060d7a4a0a576b"
+```
+
+### 3.2 培训展示列表
+
+```bash
+curl -X GET "http://localhost:2011/api/Extend/Pxzs/Actions/MobileList?currentPage=1&pageSize=5&sidx=id&sort=desc" \
+ -H "Authorization: "
+```
+
+### 3.3 培训展示详情
+
+```bash
+curl -X GET "http://localhost:2011/api/Extend/Pxzs/Actions/Mobile/<培训ID>" \
+ -H "Authorization: "
+```
+
+### 3.4 故障排查列表
+
+```bash
+curl -X GET "http://localhost:2011/api/Extend/Gzcx/Actions/MobileList?currentPage=1&pageSize=5" \
+ -H "Authorization: "
+```
+
+### 3.5 故障排查 SimpleSearch
+
+```bash
+curl -X GET "http://localhost:2011/api/Extend/gzcx/SimpleSearch?currentPage=1&pageSize=5&searchKey=2026001" \
+ -H "Authorization: "
+```
+
+### 3.6 备件支持列表
+
+```bash
+curl -X GET "http://localhost:2011/api/Extend/Bjxx/Actions/MobileList?currentPage=1&pageSize=5" \
+ -H "Authorization: "
+```
+
+### 3.7 备件支持 SimpleSearch(中文需 URL 编码)
+
+```bash
+curl -G "http://localhost:2011/api/Extend/bjxx/SimpleSearch" \
+ --data-urlencode "currentPage=1" \
+ --data-urlencode "pageSize=5" \
+ --data-urlencode "searchKey=拉线" \
+ -H "Authorization: "
+```
+
+---
+
+## 4. 权限逻辑说明
+
+- **管理员**:可查看全部数据(allowedSskhbhIds = null)
+- **非管理员**:仅可查看 `sskhbh` 为本人、所属部门或所属组织的设备相关数据
+- 权限过滤由 `KhsbPermissionHelper` 实现,MobileList/Mobile 接口及 SimpleSearch 均已接入
+
+---
+
+## 5. 非管理员账号测试(CY,UserId=781034840806917381)
+
+**权限逻辑(已调整为 khsb.dysbbh = cpgl.cpid)**:
+- 通过 `khsb.dysbbh`(对应设备编号)匹配 `cpgl.cpid`(产品编号),得到用户可查看的产品 ID(cpgl.F_Id)
+- 培训、故障:`sssb` 关联产品 ID,仅返回用户设备对应产品的数据
+- 备件:来源1 khsb.bjxx + 来源2 bjxx 通过 zlgl.fl 关联到用户产品
+
+| 接口 | 非管理员 CY | 管理员 admin | 说明 |
+|------|-------------|--------------|------|
+| Pxzs/MobileList | total=1 | total=3 | 动力猫道、顶驱等设备对应产品可见 |
+| Gzcx/MobileList | total=13 | total=249 | 泥浆泵、顶驱等故障可见 |
+| gzcx/SimpleSearch | total=1 | - | 关键字搜索正常 |
+| Bjxx/MobileList | total=0 | total=94 | 用户产品下无关联备件 |
+| 培训详情(有权) | 200 | - | 动力猫道作业流程可查看 |
+| 培训详情(无权限) | 500 | - | 铁钻工培训无权限(用户设备 dysbbh=test003 未匹配 cpgl) |
+
+---
+
+## 6. 建议后续验证
+
+1. **无效 ID**:传入不存在的 ID 调用详情接口,当前返回 500,建议后端统一返回 404 或友好错误码
+2. **无 Token**:当前无 Token 时部分接口仍返回 200,若需强制登录可检查 JWT 中间件配置
+3. **数据配置**:为非管理员可见,需在 `khsb` 中为设备配置 `fl`、`bjxx`
+
+---
+
+**结论**:接口功能正常,权限过滤生效;非管理员 CY 返回 0 条,与其设备未配置 `fl`/`bjxx` 相符。
diff --git a/docs/md/搜索功能优化总结.md b/docs/md/搜索功能优化总结.md
new file mode 100644
index 0000000..7184bad
--- /dev/null
+++ b/docs/md/搜索功能优化总结.md
@@ -0,0 +1,199 @@
+# 故障排查页面搜索功能优化总结
+
+## 优化概述
+本次优化主要针对 `/pages/new/gzpc/gzpc` 页面的搜索功能进行了多项改进,提升了用户体验和搜索准确性。
+
+---
+
+## 一、功能增强
+
+### 1. 添加"故障分类"筛选功能
+**需求**:在搜索框旁边增加"故障分类"筛选,对应后台故障查询管理中的"分类"字段。
+
+**实现**:
+- 前端添加了分类选择器(`u-picker`)
+- 通过 `getflOptions()` 方法获取分类数据
+- 使用 `flConfirm()` 处理分类选择
+- 分类变化时自动触发搜索
+
+**相关文件**:
+- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
+- `uniapp_jiju/pages/new/gzpc/index.scss`
+
+---
+
+### 2. 扩展搜索字段范围
+**需求**:搜索应匹配故障名称、故障代码、所属设备、报警文本。
+
+**实现**:
+- 后端创建了新的简单搜索API:`/api/Extend/gzcx/SimpleSearch`
+- 创建了 `GzcxSimpleSearchInput.cs` DTO
+- 搜索逻辑仅匹配以下字段:
+ - `Code`(故障代码)
+ - `Keyword`(故障名称)
+ - `Sbmc`(所属设备)
+ - `Zwbjwb`(报警文本)
+- 更新了搜索框占位符文本
+
+**相关文件**:
+- `机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/GzcxSimpleSearchInput.cs`
+- `机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/GzcxService.cs`
+- `uniapp_jiju/apis/modules/oauth.js`
+- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
+
+---
+
+## 二、性能优化
+
+### 3. 添加搜索防抖功能
+**问题**:用户快速输入时,每次输入都会触发搜索请求,导致:
+- 多个请求同时发出
+- 旧的请求可能在新的请求之后返回,显示旧结果
+- 搜索不准确
+
+**解决方案**:
+- 添加了 `searchTimer` 定时器变量
+- 在 `watch` 中实现防抖逻辑:用户停止输入500ms后才触发搜索
+- 分类筛选保持即时响应(不需要防抖)
+- 在 `onUnload` 中清理定时器,避免内存泄漏
+
+**相关代码**:
+```javascript
+watch: {
+ 'form.keyword'(newVal, oldVal) {
+ // 清除之前的定时器
+ if(this.searchTimer) {
+ clearTimeout(this.searchTimer);
+ this.searchTimer = null;
+ }
+ // 重置分页和列表
+ this.form.pageSize = 10;
+ this.form.currentPage = 1;
+ this.list = [];
+ // 设置防抖,500ms后执行搜索
+ this.searchTimer = setTimeout(() => {
+ this.gzpclist();
+ this.searchTimer = null;
+ }, 500);
+ }
+}
+```
+
+**相关文件**:
+- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
+
+---
+
+## 三、UI/UX优化
+
+### 4. 固定搜索框位置
+**需求**:搜索框固定在顶部,不随内容滚动,方便用户随时修改搜索条件。
+
+**实现**:
+- 将搜索框设置为 `position: fixed`
+- 设置 `top: 80px`(标题栏下方)
+- 使用 `left: 7px` 和 `right: 7px` 保持与页面padding一致
+- 给内容区域添加 `padding-top: 146px` 避免被遮挡
+- 添加阴影效果增强视觉层次
+
+**相关文件**:
+- `uniapp_jiju/pages/new/gzpc/index.scss`
+- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
+
+---
+
+### 5. 优化搜索框和筛选按钮宽度比例
+**需求**:搜索框占整行宽度的70%,筛选按钮占30%。
+
+**实现**:
+- 搜索框宽度设置为 `70%`
+- 筛选按钮宽度设置为 `30%`
+- 简化HTML结构,使用flex布局
+
+**相关文件**:
+- `uniapp_jiju/pages/new/gzpc/index.scss`
+- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
+
+---
+
+## 四、样式优化
+
+### 6. 美化分类选择器样式
+**需求**:分类下拉框样式与整体界面风格保持一致。
+
+**实现**:
+- 添加了全局样式覆盖 `u-picker` 组件
+- 自定义了遮罩、工具栏、选项的样式
+- 使用主题色(蓝色)突出选中项
+
+**相关文件**:
+- `uniapp_jiju/pages/new/gzpc/index.scss`
+
+---
+
+## 五、代码结构优化
+
+### 7. 重构页面结构
+**优化**:
+- 创建了 `.page-container` 作为最外层容器
+- 将固定定位的元素(标题栏、搜索框)移到页面顶层
+- 优化了SCSS文件结构,修复了语法错误
+
+**相关文件**:
+- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
+- `uniapp_jiju/pages/new/gzpc/index.scss`
+
+---
+
+## 六、修改文件清单
+
+### 前端文件
+1. `uniapp_jiju/pages/new/gzpc/gzpc.vue` - 主页面组件
+2. `uniapp_jiju/pages/new/gzpc/index.scss` - 页面样式
+3. `uniapp_jiju/apis/modules/oauth.js` - API定义
+
+### 后端文件
+1. `机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/GzcxSimpleSearchInput.cs` - 新建DTO
+2. `机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/GzcxService.cs` - 服务类
+
+---
+
+## 七、关键改进点总结
+
+1. ✅ **搜索准确性**:限制搜索字段范围,避免无关结果
+2. ✅ **搜索性能**:添加防抖,减少不必要的请求
+3. ✅ **用户体验**:固定搜索框,方便随时修改条件
+4. ✅ **功能完整性**:支持分类筛选和多字段搜索
+5. ✅ **界面美观**:优化宽度比例和样式一致性
+
+---
+
+## 八、测试建议
+
+1. **搜索功能测试**:
+ - 测试快速输入时的防抖效果
+ - 验证搜索字段匹配准确性
+ - 测试分类筛选功能
+
+2. **UI测试**:
+ - 验证搜索框固定定位
+ - 检查宽度比例是否正确
+ - 测试滚动时搜索框是否保持固定
+
+3. **兼容性测试**:
+ - 不同设备屏幕尺寸
+ - 不同浏览器/小程序平台
+
+---
+
+## 九、后续优化建议
+
+1. 可以考虑添加搜索历史记录
+2. 可以添加热门搜索关键词
+3. 可以考虑添加高级搜索功能(多条件组合)
+4. 可以优化搜索结果为空时的提示
+
+---
+
+**优化完成时间**:2026年1月26日
+**优化状态**:✅ 已完成并测试通过
diff --git a/docs/md/故障查询-模板导出导入-任务分派.md b/docs/md/故障查询-模板导出导入-任务分派.md
new file mode 100644
index 0000000..12a728d
--- /dev/null
+++ b/docs/md/故障查询-模板导出导入-任务分派.md
@@ -0,0 +1,128 @@
+# 故障查询:模板 / 导出 / 导入 需求任务分派
+
+## 一、需求摘要
+
+| 模块 | 需求要点 |
+|------|----------|
+| **模板** | 设备id(HH2400 型)+ 设备名引用;去掉故障图片;严重程度、分类为引用;字段与「单个添加」一致(不含图片/附件) |
+| **导出** | 列与模板一致且第一列为 id;带引用;字段与单个添加一致 |
+| **导入** | 支持批量新增 + 批量修改;失败时标识出错误字段 |
+
+---
+
+## 二、后端代理(Backend)
+
+**负责:** 模板下载、导出、导入的接口与逻辑;字段与字典来源确认。
+
+### 2.1 模板调整
+
+1. **设备 id / 设备名**
+ - 去掉「所属设备ID(关联资料管理)」「设备名称(从资料管理自动带入)」两列。
+ - 改为:**设备id**(数据库保存类似 HH2400 的编号)、**设备名**(选择设备 id 后自动带出)。
+ - 需确认「设备id」数据来源:若为**资料管理 zlgl**,则设备 id 建议用 `sbbh`(设备编号)或 `bh`(编号),选择后带出 设备名(如 `zlm` 资料名);若为**产品管理 cpgl**,则设备 id 可用 `cpid`,设备名用 `cpmc`。当前前端单添加用的是 cpgl(关联产品),若产品与需求一致则沿用 cpgl,否则切到 zlgl 并统一 sssb/sbmc 存值规则。
+ - 模板中「设备id」列做**下拉**,选项为设备 id 列表;「设备名」列通过公式或说明由选择结果带出(或由导入时后端按设备 id 解析带出)。
+
+2. **去掉故障图片**
+ - 模板表头与数据列中不包含「故障图片」(gztp)。
+
+3. **严重程度、分类为引用**
+ - **严重程度**:下拉,选项与前端单添加一致(轻微、一般、严重),或从字典/配置读取。
+ - **分类**:下拉,选项与前端一致(字典类型 626791524004267269 的 base_dictionarydata),Excel 中为引用选择。
+
+4. **模板字段与单个添加一致**
+ - 参考前端 `机具(管理端)/src/views/gzcx/Form.vue` 表单项(不含图片、附件):设备名称(keyword)、故障代码(code)、报警文本(zwbjwb)、故障描述(description)、发布时间(fbsj)、关联产品(sssb)→ 若改为设备则对应 设备id/设备名、严重程度(yzdcd)、外部简单描述(wbjdm)、故障原因(gzyy)、解决办法(jjbf)、分类(fl)。
+ - 与前端对齐:模板列名、顺序、必填与单添加表单一致(仅去掉 故障图片、相关附件 的上传列)。
+
+### 2.2 导出数据调整
+
+1. Excel 列与模板列一致,且**第一列为 id**(主键 F_Id)。
+2. 导出文件中也带「引用」:设备 id、严重程度、分类等与模板一致(下拉/引用),便于二次编辑后导入。
+3. 导出字段与单个添加展示/编辑字段一致(与 2.1 中字段对齐,含 id)。
+
+### 2.3 导入调整
+
+1. **批量新增 + 批量修改**
+ - 已存在逻辑:同分类 + 同故障代码视为同一条,存在则更新,不存在则新增。保持该逻辑,并确保「设备id」解析、分类/严重程度解析正确(按 id 或按名称兼容)。
+2. **导入报错时标识字段**
+ - 某行导入失败时,在 `failResult` 中不仅返回该行数据,还要返回**错误原因**及**出错字段名**(如 `{ rowIndex, fieldName, message }` 或已在 item 上增加 `_errorField`、`_errorMessage`)。便于前端展示「第几行、哪个字段、什么错误」。
+
+### 2.4 接口与文档
+
+- 若 DTO/实体有变更(如 sssb 存设备 id 编号),需同步 `GetFiledMaps`、ImportPreview、ImportData、Export 的列与字段说明。
+- 模板下载、导出、导入接口的 XML 注释与 `api-interface-testing` 要求保持一致。
+
+---
+
+## 三、前端代理(Frontend)
+
+**负责:** 与后端对齐「单个添加」字段;导入结果展示错误字段;必要时列表/导出列与模板一致。
+
+### 3.1 字段与模板一致
+
+1. **对照后端模板列**
+ - 拿到后端最终模板表头(或接口 GetFiledMaps/ImportPreview 的 fileds),与 `Form.vue` 单添加表单项逐项对照:名称、顺序、是否必填。
+ - 若后端将「关联产品」改为「设备id/设备名」,前端单添加表单需同步:改为「设备id」选择 + 「设备名」自动带出(数据源与后端一致:zlgl 或 cpgl),并保证提交字段与导入/导出一致。
+
+2. **列表与导出**
+ - 列表列、导出列与模板列、单添加字段一致(第一列为 id,其余与模板顺序一致);若后端导出已按新规则,前端仅需确认下载与展示无误。
+
+### 3.2 导入报错展示
+
+1. **展示失败行与错误字段**
+ - 导入接口返回的 `failResult` 中若包含 `_errorField`、`_errorMessage`(或等价结构),前端在导入结果中展示:行号、失败行摘要、**错误字段**、**错误信息**。
+ - 若后端暂未返回字段级错误,前端先展示「第几行失败 + 原始行数据」,并和后端约定字段级错误结构后再补上「哪个字段出错」。
+
+### 3.3 不负责范围
+
+- 不负责模板/导出 Excel 的生成逻辑(由后端实现);仅负责调用接口、下载、上传及结果展示。
+
+---
+
+## 四、测试代理(Test)
+
+**负责:** 模板、导出、导入、单添加与列表的端到端验证;数据库校验。
+
+### 4.1 测试前条件
+
+- 后端、前端按上述任务完成开发并联调通过。
+
+### 4.2 测试项
+
+1. **模板下载**
+ - 表头与单添加字段一致(无故障图片、无附件列);设备id、设备名、严重程度、分类为引用/下拉;第一列可为占位或与导出一致(以后端实现为准)。
+2. **导出**
+ - 第一列为 id;列与模板一致;带引用;数据与列表/单添加一致。
+3. **导入**
+ - 批量新增:无同分类+同故障代码时,全部新增;库中有对应记录。
+ - 批量修改:存在同分类+同故障代码时,该行更新;库中该条记录已更新。
+ - 失败行:故意制造错误数据(如非法设备id、必填为空),确认返回中有失败行且**错误字段/错误信息**可识别;前端能正确展示。
+4. **单添加与列表**
+ - 单添加字段与模板/导入字段一致;列表、导出、导入数据一致。
+5. **数据库**
+ - 导入新增/更新后,用 MCP MySQL 或接口查询 gzcx 表,核对关键字段(如 设备id、设备名、分类、严重程度)与 Excel 一致。
+
+### 4.3 交付
+
+- 测试通过/不通过结论;不通过时列出问题与复现步骤,转交对应后端/前端处理。
+
+---
+
+## 五、执行顺序建议
+
+1. **后端**:先确认设备 id 来源(zlgl 还是 cpgl)及 sssb/sbmc 存值规则 → 实现模板、导出、导入(含失败字段标识)。
+2. **前端**:根据后端最终字段与错误结构,对齐单添加表单与导入结果展示;必要时调整列表列。
+3. **测试**:在后端与前端均完成后,按 4.2 执行全量测试并反馈。
+
+---
+
+## 六、参考文件
+
+| 用途 | 路径 |
+|------|------|
+| 单添加表单 | 机具(管理端)/src/views/gzcx/Form.vue |
+| 导入弹窗 | 机具(管理端)/src/views/gzcx/ImportForm.vue |
+| 故障查询服务 | 机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/GzcxService.cs |
+| 实体/DTO | 机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/ (GzcxEntity, GzcxCrInput, GzcxListOutput) |
+| 资料管理实体 | NCC.Extend.Entitys/Entity/ZlglEntity.cs(sbbh, bh, zlm) |
+| 产品管理实体 | NCC.Extend.Entitys/Entity/CpglEntity.cs(cpid, cpmc) |
+| 接口测试规范 | .cursor/skills/api-interface-testing/SKILL.md |
diff --git a/docs/sql/fix-铁钻工产品缺失.sql b/docs/sql/fix-铁钻工产品缺失.sql
new file mode 100644
index 0000000..91057c5
--- /dev/null
+++ b/docs/sql/fix-铁钻工产品缺失.sql
@@ -0,0 +1,11 @@
+-- 修复:设备「铁钻工」的 dysbbh=test003 在 cpgl 中无对应产品,导致关联产品下拉不显示
+-- 执行后,「铁钻工」将出现在关联产品下拉中,与设备列表数据一致
+
+-- 若 cpid=test003 已存在则跳过;否则新增产品
+INSERT INTO cpgl (F_Id, cpid, cpmc, cpxh, cpgg)
+SELECT '791001000000000001', 'test003', '铁钻工', '', ''
+FROM (SELECT 1) t
+WHERE NOT EXISTS (SELECT 1 FROM cpgl WHERE cpid = 'test003');
+
+-- 备选:若上面报错,可直接执行(若已存在会主键冲突,可忽略)
+-- INSERT INTO cpgl (F_Id, cpid, cpmc, cpxh, cpgg) VALUES ('791001000000000001', 'test003', '铁钻工', '', '');
diff --git a/docs/sql/migrations_sbwhry.sql b/docs/sql/migrations_sbwhry.sql
new file mode 100644
index 0000000..6c47923
--- /dev/null
+++ b/docs/sql/migrations_sbwhry.sql
@@ -0,0 +1,11 @@
+-- sbwhry 表结构迁移(执行前请备份)
+-- 为设备维护人员表添加 gh、glcp、clfw 列,用于列表展示工号、关联产品、处理范围
+
+-- 工号
+ALTER TABLE sbwhry ADD COLUMN gh varchar(255) NULL COMMENT '工号';
+
+-- 关联产品(若表结构中无此列)
+ALTER TABLE sbwhry ADD COLUMN glcp varchar(500) NULL COMMENT '关联产品';
+
+-- 处理范围(若表结构中无此列)
+ALTER TABLE sbwhry ADD COLUMN clfw varchar(500) NULL COMMENT '处理范围(设备问题、系统问题,多选逗号分隔)';
diff --git a/docs/sql/migrations_xccpgl.sql b/docs/sql/migrations_xccpgl.sql
new file mode 100644
index 0000000..5a29158
--- /dev/null
+++ b/docs/sql/migrations_xccpgl.sql
@@ -0,0 +1,28 @@
+-- xccpgl 表结构迁移(执行前请备份)
+-- 若已执行过某条,可跳过该条
+
+-- 1. 封面图片
+ALTER TABLE xccpgl ADD COLUMN fmtp varchar(500) NULL COMMENT '封面图片(单张,JSON格式)';
+
+-- 2. 新闻正文
+ALTER TABLE xccpgl ADD COLUMN xwzw longtext NULL COMMENT '新闻正文(超文本)';
+
+-- 3. 系统问题反馈(问题)分类字典
+-- 字典类型:xtwtfk_qxgn,用于管理端和移动端下拉选项
+-- 若已存在该 EnCode 的字典类型,可跳过
+INSERT INTO base_dictionarytype (F_Id, F_ParentId, F_FullName, F_EnCode, F_IsTree, F_SortCode, F_CreatorTime, F_EnabledMark, F_DeleteMark)
+SELECT '626798200000000001', '0', '系统问题反馈-问题分类', 'xtwtfk_qxgn', 0, 0, NOW(), 1, 0
+FROM DUAL
+WHERE NOT EXISTS (SELECT 1 FROM base_dictionarytype WHERE F_EnCode = 'xtwtfk_qxgn');
+
+-- 字典数据(系统缺陷、功能缺失、显示异常、优化建议、功能新增)
+INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
+SELECT '626798200000000011', '0', '系统缺陷', 'xt1', 1, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '系统缺陷');
+INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
+SELECT '626798200000000012', '0', '功能缺失', 'xt2', 2, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '功能缺失');
+INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
+SELECT '626798200000000013', '0', '显示异常', 'xt3', 3, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '显示异常');
+INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
+SELECT '626798200000000014', '0', '优化建议', 'xt4', 4, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '优化建议');
+INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
+SELECT '626798200000000015', '0', '功能新增', 'xt5', 5, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '功能新增');
diff --git a/fix-铁钻工产品缺失.sql b/fix-铁钻工产品缺失.sql
deleted file mode 100644
index 91057c5..0000000
--- a/fix-铁钻工产品缺失.sql
+++ /dev/null
@@ -1,11 +0,0 @@
--- 修复:设备「铁钻工」的 dysbbh=test003 在 cpgl 中无对应产品,导致关联产品下拉不显示
--- 执行后,「铁钻工」将出现在关联产品下拉中,与设备列表数据一致
-
--- 若 cpid=test003 已存在则跳过;否则新增产品
-INSERT INTO cpgl (F_Id, cpid, cpmc, cpxh, cpgg)
-SELECT '791001000000000001', 'test003', '铁钻工', '', ''
-FROM (SELECT 1) t
-WHERE NOT EXISTS (SELECT 1 FROM cpgl WHERE cpid = 'test003');
-
--- 备选:若上面报错,可直接执行(若已存在会主键冲突,可忽略)
--- INSERT INTO cpgl (F_Id, cpid, cpmc, cpxh, cpgg) VALUES ('791001000000000001', 'test003', '铁钻工', '', '');
diff --git a/uniapp_jiju/pages/new/gzpc/搜索功能优化总结.md b/uniapp_jiju/pages/new/gzpc/搜索功能优化总结.md
deleted file mode 100644
index 7184bad..0000000
--- a/uniapp_jiju/pages/new/gzpc/搜索功能优化总结.md
+++ /dev/null
@@ -1,199 +0,0 @@
-# 故障排查页面搜索功能优化总结
-
-## 优化概述
-本次优化主要针对 `/pages/new/gzpc/gzpc` 页面的搜索功能进行了多项改进,提升了用户体验和搜索准确性。
-
----
-
-## 一、功能增强
-
-### 1. 添加"故障分类"筛选功能
-**需求**:在搜索框旁边增加"故障分类"筛选,对应后台故障查询管理中的"分类"字段。
-
-**实现**:
-- 前端添加了分类选择器(`u-picker`)
-- 通过 `getflOptions()` 方法获取分类数据
-- 使用 `flConfirm()` 处理分类选择
-- 分类变化时自动触发搜索
-
-**相关文件**:
-- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
-- `uniapp_jiju/pages/new/gzpc/index.scss`
-
----
-
-### 2. 扩展搜索字段范围
-**需求**:搜索应匹配故障名称、故障代码、所属设备、报警文本。
-
-**实现**:
-- 后端创建了新的简单搜索API:`/api/Extend/gzcx/SimpleSearch`
-- 创建了 `GzcxSimpleSearchInput.cs` DTO
-- 搜索逻辑仅匹配以下字段:
- - `Code`(故障代码)
- - `Keyword`(故障名称)
- - `Sbmc`(所属设备)
- - `Zwbjwb`(报警文本)
-- 更新了搜索框占位符文本
-
-**相关文件**:
-- `机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/GzcxSimpleSearchInput.cs`
-- `机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/GzcxService.cs`
-- `uniapp_jiju/apis/modules/oauth.js`
-- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
-
----
-
-## 二、性能优化
-
-### 3. 添加搜索防抖功能
-**问题**:用户快速输入时,每次输入都会触发搜索请求,导致:
-- 多个请求同时发出
-- 旧的请求可能在新的请求之后返回,显示旧结果
-- 搜索不准确
-
-**解决方案**:
-- 添加了 `searchTimer` 定时器变量
-- 在 `watch` 中实现防抖逻辑:用户停止输入500ms后才触发搜索
-- 分类筛选保持即时响应(不需要防抖)
-- 在 `onUnload` 中清理定时器,避免内存泄漏
-
-**相关代码**:
-```javascript
-watch: {
- 'form.keyword'(newVal, oldVal) {
- // 清除之前的定时器
- if(this.searchTimer) {
- clearTimeout(this.searchTimer);
- this.searchTimer = null;
- }
- // 重置分页和列表
- this.form.pageSize = 10;
- this.form.currentPage = 1;
- this.list = [];
- // 设置防抖,500ms后执行搜索
- this.searchTimer = setTimeout(() => {
- this.gzpclist();
- this.searchTimer = null;
- }, 500);
- }
-}
-```
-
-**相关文件**:
-- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
-
----
-
-## 三、UI/UX优化
-
-### 4. 固定搜索框位置
-**需求**:搜索框固定在顶部,不随内容滚动,方便用户随时修改搜索条件。
-
-**实现**:
-- 将搜索框设置为 `position: fixed`
-- 设置 `top: 80px`(标题栏下方)
-- 使用 `left: 7px` 和 `right: 7px` 保持与页面padding一致
-- 给内容区域添加 `padding-top: 146px` 避免被遮挡
-- 添加阴影效果增强视觉层次
-
-**相关文件**:
-- `uniapp_jiju/pages/new/gzpc/index.scss`
-- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
-
----
-
-### 5. 优化搜索框和筛选按钮宽度比例
-**需求**:搜索框占整行宽度的70%,筛选按钮占30%。
-
-**实现**:
-- 搜索框宽度设置为 `70%`
-- 筛选按钮宽度设置为 `30%`
-- 简化HTML结构,使用flex布局
-
-**相关文件**:
-- `uniapp_jiju/pages/new/gzpc/index.scss`
-- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
-
----
-
-## 四、样式优化
-
-### 6. 美化分类选择器样式
-**需求**:分类下拉框样式与整体界面风格保持一致。
-
-**实现**:
-- 添加了全局样式覆盖 `u-picker` 组件
-- 自定义了遮罩、工具栏、选项的样式
-- 使用主题色(蓝色)突出选中项
-
-**相关文件**:
-- `uniapp_jiju/pages/new/gzpc/index.scss`
-
----
-
-## 五、代码结构优化
-
-### 7. 重构页面结构
-**优化**:
-- 创建了 `.page-container` 作为最外层容器
-- 将固定定位的元素(标题栏、搜索框)移到页面顶层
-- 优化了SCSS文件结构,修复了语法错误
-
-**相关文件**:
-- `uniapp_jiju/pages/new/gzpc/gzpc.vue`
-- `uniapp_jiju/pages/new/gzpc/index.scss`
-
----
-
-## 六、修改文件清单
-
-### 前端文件
-1. `uniapp_jiju/pages/new/gzpc/gzpc.vue` - 主页面组件
-2. `uniapp_jiju/pages/new/gzpc/index.scss` - 页面样式
-3. `uniapp_jiju/apis/modules/oauth.js` - API定义
-
-### 后端文件
-1. `机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/GzcxSimpleSearchInput.cs` - 新建DTO
-2. `机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/GzcxService.cs` - 服务类
-
----
-
-## 七、关键改进点总结
-
-1. ✅ **搜索准确性**:限制搜索字段范围,避免无关结果
-2. ✅ **搜索性能**:添加防抖,减少不必要的请求
-3. ✅ **用户体验**:固定搜索框,方便随时修改条件
-4. ✅ **功能完整性**:支持分类筛选和多字段搜索
-5. ✅ **界面美观**:优化宽度比例和样式一致性
-
----
-
-## 八、测试建议
-
-1. **搜索功能测试**:
- - 测试快速输入时的防抖效果
- - 验证搜索字段匹配准确性
- - 测试分类筛选功能
-
-2. **UI测试**:
- - 验证搜索框固定定位
- - 检查宽度比例是否正确
- - 测试滚动时搜索框是否保持固定
-
-3. **兼容性测试**:
- - 不同设备屏幕尺寸
- - 不同浏览器/小程序平台
-
----
-
-## 九、后续优化建议
-
-1. 可以考虑添加搜索历史记录
-2. 可以添加热门搜索关键词
-3. 可以考虑添加高级搜索功能(多条件组合)
-4. 可以优化搜索结果为空时的提示
-
----
-
-**优化完成时间**:2026年1月26日
-**优化状态**:✅ 已完成并测试通过
diff --git a/接口测试-小红点未读数量分析.md b/接口测试-小红点未读数量分析.md
deleted file mode 100644
index 6dfb2b9..0000000
--- a/接口测试-小红点未读数量分析.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# 小红点(未读数量)异常分析 - 供测试排查
-
-## 一、小红点出现位置
-
-移动端首页(`uniapp_jiju/pages/home/home.vue`)有两处小红点(u-badge):
-
-| 入口 | 变量 | 数据来源 |
-|------------|------------|----------------------------------|
-| **信息推送** | `xxtsvalue` | `hqxxwdsl` → 信息推送未读数量 |
-| **用户反馈** | `yhfkvalue` | `hqxtwdnumber` + `hqsbwtwdnumber` 之和 |
-
-## 二、接口与数据流
-
-### 1. 信息推送小红点
-
-| 步骤 | 说明 |
-|------|------|
-| 获取未读数 | `GET /api/Extend/Xxtsjl/Actions/GetMessageCount?userId=xxx` |
-| 前端入参 | `info.userId = uni.getStorageSync('userinfo').userId` |
-| 后端逻辑 | `sfyd != "是"` 视为未读,返回 `unreadCount` |
-| 标记已读 | 用户进入详情页时调用 `PUT /api/Extend/Xxtsjl/{ff}`,body 含 `sfyd: '是'` |
-| 刷新时机 | 首页 `onShow` 时调用 `hquserxx()` → `hqxxwdsl()` |
-
-### 2. 用户反馈小红点
-
-| 步骤 | 说明 |
-|------|------|
-| 系统问题未读 | `GET /api/Extend/Xtwtfk/Actions/GetUnreadCountByAccount?account=xxx` |
-| 设备问题未读 | `GET /api/Extend/Sbwtfk/Actions/GetUnreadCountByAccount?account=xxx` |
-| 前端入参 | `info.id = uni.getStorageSync('userinfo').userId` |
-| 后端逻辑 | Xtwtfk: `Cljg != "已处理"` 且 `Sfyd != "是"`;Sbwtfk: `Cljg != "已处理"` 且 `Sfyd != "已读"` |
-
-## 三、可能原因
-
-### 前端
-
-1. **u-badge 在未读数为 0 时仍展示**
- - 当前:`` 无 `hidden`/`show`
- - 可能:`value` 为 `0` 时仍显示小圆点或数字
- - 建议:加 `v-if="xxtsvalue > 0"` 或 `:show="!!xxtsvalue"`,0 时不渲染
-
-2. **userinfo 字段不一致**
- - `hqxxwdsl` 用 `userinfo.userId`
- - `hqxtwdnumber` / `hqsbwtwdnumber` 用 `userinfo.userId` 作为 `id` 传入 `account`
- - 若登录接口返回的是 `id` 而不是 `userId`,会导致 userId 为空
-
-3. **onShow 刷新时机**
- - 首页 `onShow` 会执行 `hquserxx()` 并刷新两个小红点
- - Tab 切换、从信息推送详情返回等都会触发 `onShow`,逻辑上是合理的
-
-### 后端
-
-1. **标记已读失败**
- - 详情页 `xgxxwyd(cached)` 使用 `item.ff` 作为 PUT 路径参数
- - 需确认接口实际更新了 `sfyd` 且条件 `it.Ff == id` 正确
- - 建议:在数据库直接查该 `ff` 对应的 `sfyd` 是否已更新为「是」
-
-2. **GetMessageCount 的 userId 不匹配**
- - Xxtsjl 表 `jsr` 存的是用户 ID
- - 若传入的 `userId` 与 `jsr` 不一致(如传错字段、大小写等),统计会不对
- - 建议:打印请求中的 `userId` 和数据库中 `jsr` 的格式是否一致
-
-3. **Jsr 为 JSON 多选**
- - 后端支持 `p.Jsr.Contains(userId)`,即 JSON 数组包含该 userId
- - 若 `jsr` 存的是 JSON 数组,需确认 Contains 的匹配逻辑是否符合实际存储格式
-
-## 四、测试建议
-
-1. **信息推送**
- - 确认一条未读消息的 `ff`、`jsr`、`sfyd` 在数据库中的值
- - 进入该消息详情页,确认调用 `PUT /api/Extend/Xxtsjl/{ff}` 且 body 含 `sfyd: '是'`
- - 返回首页,确认 `GetMessageCount` 返回的 `unreadCount` 是否减少
- - 检查首页 badge 在 `unreadCount === 0` 时是否还会显示
-
-2. **用户反馈**
- - 确认 Xtwtfk、Sbwtfk 的 `GetUnreadCountByAccount` 入参为 userId(account)
- - 确认两条接口的未读判断条件与业务规则一致
-
-3. **前端调试**
- - 在 `hqxxwdsl` 回调中 `console.log(res.data)` 看 `unreadCount`
- - 在 `hquserxx` 中 `console.log(uni.getStorageSync('userinfo'))` 看 `userId` / `id` 字段
-
-## 五、建议修改(前端)
-
-若确认「已读后仍显示小红点」为前端展示问题,可增加如下逻辑:
-
-```vue
-
-
-
-
-
-```
-
-若测试发现是**接口返回的 unreadCount 未正确减少**,则需后端排查标记已读和统计逻辑。
diff --git a/接口测试-我的设备两个接口.md b/接口测试-我的设备两个接口.md
deleted file mode 100644
index 093e051..0000000
--- a/接口测试-我的设备两个接口.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# 我的设备 - 接口测试说明
-
-## 两个接口地址
-
-| 用途 | 接口地址 | 方法 | 说明 |
-|------|----------|------|------|
-| 关联产品下拉 | `GET /api/Extend/Cpgl/Actions/AllowedList` | GET | 获取当前用户可查看的产品列表(仅「我的设备」关联的产品) |
-| 设备列表 | `GET /api/Extend/Khsb` | GET | 获取我的设备列表,支持 `fl` 按关联产品筛选 |
-
-**Base URL**:`http://localhost:2011`(以实际运行环境为准)
-
----
-
-## 测试 Token(CY 用户,非管理员)
-
-```
-Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI3ODEwMzQ4NDA4MDY5MTczODEiLCJBY2NvdW50IjoiQ1kiLCJVc2VyTmFtZSI6IumZiOWLhyIsIkFkbWluaXN0cmF0b3IiOjAsIlRlbmFudElkIjoiZGIiLCJUZW5hbnREYk5hbWUiOiJkb25nZmFuZ2RpYW5xaSIsImlhdCI6MTc3MDc4MzMyNCwibmJmIjoxNzcwNzgzMzI0LCJleHAiOjE3NzExNDMzMjQsImlzcyI6Inlpbm1haXNvZnQiLCJhdWQiOiJ5aW5tYWlzb2Z0In0._iHXemLqF-r_7SJHh6ZnpNIiZVQR2BCoX4pnwwq_qW8
-```
-
----
-
-## curl 测试示例
-
-### 1. 关联产品下拉(AllowedList)
-
-```bash
-curl -X GET "http://localhost:2011/api/Extend/Cpgl/Actions/AllowedList?currentPage=1&pageSize=1000&sort=desc&sidx=id" \
- -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI3ODEwMzQ4NDA4MDY5MTczODEiLCJBY2NvdW50IjoiQ1kiLCJVc2VyTmFtZSI6IumZiOWLhyIsIkFkbWluaXN0cmF0b3IiOjAsIlRlbmFudElkIjoiZGIiLCJUZW5hbnREYk5hbWUiOiJkb25nZmFuZ2RpYW5xaSIsImlhdCI6MTc3MDc4MzMyNCwibmJmIjoxNzcwNzgzMzI0LCJleHAiOjE3NzExNDMzMjQsImlzcyI6Inlpbm1haXNvZnQiLCJhdWQiOiJ5aW5tYWlzb2Z0In0._iHXemLqF-r_7SJHh6ZnpNIiZVQR2BCoX4pnwwq_qW8"
-```
-
-### 2. 设备列表(Khsb)
-
-```bash
-# 无产品筛选
-curl -X GET "http://localhost:2011/api/Extend/Khsb?currentPage=1&pageSize=20&sort=desc&sidx=" \
- -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI3ODEwMzQ4NDA4MDY5MTczODEiLCJBY2NvdW50IjoiQ1kiLCJVc2VyTmFtZSI6IumZiOWLhyIsIkFkbWluaXN0cmF0b3IiOjAsIlRlbmFudElkIjoiZGIiLCJUZW5hbnREYk5hbWUiOiJkb25nZmFuZ2RpYW5xaSIsImlhdCI6MTc3MDc4MzMyNCwibmJmIjoxNzcwNzgzMzI0LCJleHAiOjE3NzExNDMzMjQsImlzcyI6Inlpbm1haXNvZnQiLCJhdWQiOiJ5aW5tYWlzb2Z0In0._iHXemLqF-r_7SJHh6ZnpNIiZVQR2BCoX4pnwwq_qW8"
-
-# 按产品筛选(替换 {产品ID} 为 AllowedList 返回的 id)
-curl -X GET "http://localhost:2011/api/Extend/Khsb?currentPage=1&pageSize=20&sort=desc&sidx=&fl={产品ID}" \
- -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI3ODEwMzQ4NDA4MDY5MTczODEiLCJBY2NvdW50IjoiQ1kiLCJVc2VyTmFtZSI6IumZiOWLhyIsIkFkbWluaXN0cmF0b3IiOjAsIlRlbmFudElkIjoiZGIiLCJUZW5hbnREYk5hbWUiOiJkb25nZmFuZ2RpYW5xaSIsImlhdCI6MTc3MDc4MzMyNCwibmJmIjoxNzcwNzgzMzI0LCJleHAiOjE3NzExNDMzMjQsImlzcyI6Inlpbm1haXNvZnQiLCJhdWQiOiJ5aW5tYWlzb2Z0In0._iHXemLqF-r_7SJHh6ZnpNIiZVQR2BCoX4pnwwq_qW8"
-```
-
----
-
-## 测试结果与分析(CY 用户 Token)
-
-### 1. AllowedList 返回 3 个产品
-
-| id | cpmc | cpid |
-|----|------|------|
-| 786180219823195397 | 五缸泵 | HH2400 |
-| 785333585623123205 | 顶驱500T | DQ500Z |
-| 785331243859313925 | 动力猫道(甩三) | DLMD039X |
-
-### 2. Khsb 设备列表返回 4 台设备
-
-| sbmc | dysbbh | 是否在 AllowedList 中 |
-|------|--------|----------------------|
-| 五缸泵 | HH2400 | ✓ 对应产品 五缸泵 |
-| 动力猫道(甩三) | DLMD039X | ✓ 对应产品 动力猫道 |
-| 铁钻工 | **test003** | ✗ 产品表中无 cpid=test003 |
-| 顶驱500T | DQ500Z | ✓ 对应产品 顶驱500T |
-
-### 3. 差异原因
-
-- **AllowedList** 仅通过 `khsb.dysbbh = cpgl.cpid` 关联产品,只返回在 cpgl 中有对应记录的产品。
-- 设备「铁钻工」的 `dysbbh=test003` 在 cpgl 中无匹配产品(cpid 无 test003),因此不会出现在 AllowedList 中。
-- **设备列表**按 `sskhbh` 过滤,展示用户可见的全部设备,包括 dysbbh 未在 cpgl 中匹配的设备。
-
-### 4. 结论
-
-两接口逻辑一致:AllowedList 只展示「有对应产品档案」的设备关联产品;设备列表则展示全部可见设备。
-设备「铁钻工」未出现在产品下拉中,是因为其 dysbbh(test003)在 cpgl 中无对应产品,需在 cpgl 中补充或修正该设备的 dysbbh。
-
----
-
-## 验证要点
-
-1. **AllowedList** 返回的产品 ID 列表,应来自「khsb.dysbbh = cpgl.cpid」且 khsb.sskhbh 属于当前用户
-2. **Khsb** 设备列表按 `khsb.sskhbh` 过滤(所属客户=本人/部门/组织)
-3. 选择 AllowedList 中某产品作为 `fl` 筛选设备时,设备应满足:Khsb.Fl / Khsb.Dysbbh / Khsb.Dysb 与选中产品匹配
-4. 若设备 dysbbh 在 cpgl 中无对应 cpid,该设备关联的「产品」不会出现在 AllowedList 中
diff --git a/接口测试报告-产品详情Tab接口.md b/接口测试报告-产品详情Tab接口.md
deleted file mode 100644
index 24853d5..0000000
--- a/接口测试报告-产品详情Tab接口.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# 接口测试报告 - 产品详情 Tab 相关接口
-
-**测试时间**:2025-02-11
-**测试环境**:http://localhost:2011
-**测试账号**:admin(管理员)
-
----
-
-## 1. 测试结果汇总
-
-| 接口 | 状态 | 说明 |
-|------|------|------|
-| POST /api/oauth/Login | ✅ | 返回 token |
-| GET /api/Extend/Cpgl | ✅ | 产品列表,7 条 |
-| GET /api/Extend/Cpgl/{id} | ✅ | 产品详情 |
-| GET /api/Extend/Bjxx | ✅ | 备件列表,94 条 |
-| GET /api/Extend/Bjxx?sssb={产品ID} | ✅ | 按产品筛选,90 条(产品 785331243859313925) |
-| GET /api/Extend/Zlgl | ✅ | 产品资料,11 条 |
-| GET /api/Extend/Gzcx | ✅ | 故障查询,260 条 |
-| GET /api/Extend/Pxzs | ✅ | 培训展示,3 条 |
-| GET /api/Extend/Xccpgl | ✅ | 宣传产品,2 条 |
-| GET /api/Extend/Zsk | ✅ | 知识库,6 条 |
-
----
-
-## 2. curl 示例(供复测)
-
-### 2.1 获取 Token
-
-```bash
-curl -X POST "http://localhost:2011/api/oauth/Login" \
- -H "Content-Type: application/x-www-form-urlencoded" \
- -d "account=admin&password=66762a3ccde2a2cff3060d7a4a0a576b"
-```
-
-### 2.2 产品列表与详情
-
-```bash
-# 产品列表
-curl -X GET "http://localhost:2011/api/Extend/Cpgl?currentPage=1&pageSize=3" \
- -H "Authorization: "
-
-# 产品详情(替换 {id} 为实际产品 ID)
-curl -X GET "http://localhost:2011/api/Extend/Cpgl/{id}" \
- -H "Authorization: "
-```
-
-### 2.3 备件列表(按产品筛选 sssb)
-
-```bash
-# 备件列表(按产品 ID 筛选)
-curl -X GET "http://localhost:2011/api/Extend/Bjxx?currentPage=1&pageSize=5&sssb=785331243859313925" \
- -H "Authorization: "
-```
-
-### 2.4 Tab 其它接口
-
-```bash
-# 产品资料
-curl -X GET "http://localhost:2011/api/Extend/Zlgl?currentPage=1&pageSize=3" -H "Authorization: "
-
-# 故障查询
-curl -X GET "http://localhost:2011/api/Extend/Gzcx?currentPage=1&pageSize=3" -H "Authorization: "
-
-# 培训展示
-curl -X GET "http://localhost:2011/api/Extend/Pxzs?currentPage=1&pageSize=3" -H "Authorization: "
-
-# 宣传产品
-curl -X GET "http://localhost:2011/api/Extend/Xccpgl?currentPage=1&pageSize=3" -H "Authorization: "
-
-# 知识库
-curl -X GET "http://localhost:2011/api/Extend/Zsk?currentPage=1&pageSize=3" -H "Authorization: "
-```
-
----
-
-## 3. 验证要点
-
-- [x] 登录接口返回有效 token
-- [x] 各 Tab 对应接口均能正常返回数据
-- [x] 备件接口 `sssb` 参数按产品 ID 筛选正常
-- [x] 分页与列表结构符合预期
diff --git a/接口测试报告-移动端权限接口.md b/接口测试报告-移动端权限接口.md
deleted file mode 100644
index 76792fc..0000000
--- a/接口测试报告-移动端权限接口.md
+++ /dev/null
@@ -1,127 +0,0 @@
-# 接口测试报告 - 移动端权限接口
-
-**测试时间**:2025-02-12
-**测试环境**:http://localhost:2011
-**测试账号**:admin(管理员)
-
----
-
-## 1. 测试范围
-
-培训展示、故障排查、备件支持三大模块的移动端专用接口:
-
-| 模块 | 列表接口 | 详情接口 | 简单搜索(带权限) |
-|----------|---------------------|----------------------------------|----------------------|
-| 培训展示 | Pxzs/MobileList | Pxzs/Mobile/{id} | - |
-| 故障排查 | Gzcx/MobileList | Gzcx/Mobile/{id} | gzcx/SimpleSearch |
-| 备件支持 | Bjxx/MobileList | Bjxx/Mobile/{id} | bjxx/SimpleSearch |
-
----
-
-## 2. 测试结果汇总
-
-| 接口 | 状态 | 说明 |
-|-----------------------------------------|------|------------------------------|
-| Pxzs/Actions/MobileList | ✅ | 返回分页列表,含 pxmc、sbmc 等 |
-| Pxzs/Actions/Mobile/{id} | ✅ | 返回详情含 fj1、slt、jj 等 |
-| Gzcx/Actions/MobileList | ✅ | 返回分页列表,含 code、zwbjwb 等 |
-| Gzcx/Actions/Mobile/{id} | ✅ | 返回详情含 attachements、yzdcd 等 |
-| gzcx/SimpleSearch | ✅ | searchKey 匹配故障代码正常 |
-| Bjxx/Actions/MobileList | ✅ | 返回分页列表,含 mc、bjqk 等 |
-| Bjxx/Actions/Mobile/{id} | ✅ | 返回详情含 sjbj、ynbj、lnbj 等 |
-| bjxx/SimpleSearch | ✅ | 无关键字/有关键字均正常 |
-
----
-
-## 3. curl 示例(供复测)
-
-### 3.1 获取 Token
-
-```bash
-curl -X POST "http://localhost:2011/api/oauth/Login" \
- -H "Content-Type: application/x-www-form-urlencoded" \
- -d "account=admin&password=66762a3ccde2a2cff3060d7a4a0a576b"
-```
-
-### 3.2 培训展示列表
-
-```bash
-curl -X GET "http://localhost:2011/api/Extend/Pxzs/Actions/MobileList?currentPage=1&pageSize=5&sidx=id&sort=desc" \
- -H "Authorization: "
-```
-
-### 3.3 培训展示详情
-
-```bash
-curl -X GET "http://localhost:2011/api/Extend/Pxzs/Actions/Mobile/<培训ID>" \
- -H "Authorization: "
-```
-
-### 3.4 故障排查列表
-
-```bash
-curl -X GET "http://localhost:2011/api/Extend/Gzcx/Actions/MobileList?currentPage=1&pageSize=5" \
- -H "Authorization: "
-```
-
-### 3.5 故障排查 SimpleSearch
-
-```bash
-curl -X GET "http://localhost:2011/api/Extend/gzcx/SimpleSearch?currentPage=1&pageSize=5&searchKey=2026001" \
- -H "Authorization: "
-```
-
-### 3.6 备件支持列表
-
-```bash
-curl -X GET "http://localhost:2011/api/Extend/Bjxx/Actions/MobileList?currentPage=1&pageSize=5" \
- -H "Authorization: "
-```
-
-### 3.7 备件支持 SimpleSearch(中文需 URL 编码)
-
-```bash
-curl -G "http://localhost:2011/api/Extend/bjxx/SimpleSearch" \
- --data-urlencode "currentPage=1" \
- --data-urlencode "pageSize=5" \
- --data-urlencode "searchKey=拉线" \
- -H "Authorization: "
-```
-
----
-
-## 4. 权限逻辑说明
-
-- **管理员**:可查看全部数据(allowedSskhbhIds = null)
-- **非管理员**:仅可查看 `sskhbh` 为本人、所属部门或所属组织的设备相关数据
-- 权限过滤由 `KhsbPermissionHelper` 实现,MobileList/Mobile 接口及 SimpleSearch 均已接入
-
----
-
-## 5. 非管理员账号测试(CY,UserId=781034840806917381)
-
-**权限逻辑(已调整为 khsb.dysbbh = cpgl.cpid)**:
-- 通过 `khsb.dysbbh`(对应设备编号)匹配 `cpgl.cpid`(产品编号),得到用户可查看的产品 ID(cpgl.F_Id)
-- 培训、故障:`sssb` 关联产品 ID,仅返回用户设备对应产品的数据
-- 备件:来源1 khsb.bjxx + 来源2 bjxx 通过 zlgl.fl 关联到用户产品
-
-| 接口 | 非管理员 CY | 管理员 admin | 说明 |
-|------|-------------|--------------|------|
-| Pxzs/MobileList | total=1 | total=3 | 动力猫道、顶驱等设备对应产品可见 |
-| Gzcx/MobileList | total=13 | total=249 | 泥浆泵、顶驱等故障可见 |
-| gzcx/SimpleSearch | total=1 | - | 关键字搜索正常 |
-| Bjxx/MobileList | total=0 | total=94 | 用户产品下无关联备件 |
-| 培训详情(有权) | 200 | - | 动力猫道作业流程可查看 |
-| 培训详情(无权限) | 500 | - | 铁钻工培训无权限(用户设备 dysbbh=test003 未匹配 cpgl) |
-
----
-
-## 6. 建议后续验证
-
-1. **无效 ID**:传入不存在的 ID 调用详情接口,当前返回 500,建议后端统一返回 404 或友好错误码
-2. **无 Token**:当前无 Token 时部分接口仍返回 200,若需强制登录可检查 JWT 中间件配置
-3. **数据配置**:为非管理员可见,需在 `khsb` 中为设备配置 `fl`、`bjxx`
-
----
-
-**结论**:接口功能正常,权限过滤生效;非管理员 CY 返回 0 条,与其设备未配置 `fl`/`bjxx` 相符。
diff --git a/机具(服务端)/migrations_sbwhry.sql b/机具(服务端)/migrations_sbwhry.sql
deleted file mode 100644
index 6c47923..0000000
--- a/机具(服务端)/migrations_sbwhry.sql
+++ /dev/null
@@ -1,11 +0,0 @@
--- sbwhry 表结构迁移(执行前请备份)
--- 为设备维护人员表添加 gh、glcp、clfw 列,用于列表展示工号、关联产品、处理范围
-
--- 工号
-ALTER TABLE sbwhry ADD COLUMN gh varchar(255) NULL COMMENT '工号';
-
--- 关联产品(若表结构中无此列)
-ALTER TABLE sbwhry ADD COLUMN glcp varchar(500) NULL COMMENT '关联产品';
-
--- 处理范围(若表结构中无此列)
-ALTER TABLE sbwhry ADD COLUMN clfw varchar(500) NULL COMMENT '处理范围(设备问题、系统问题,多选逗号分隔)';
diff --git a/机具(服务端)/migrations_xccpgl.sql b/机具(服务端)/migrations_xccpgl.sql
deleted file mode 100644
index 5a29158..0000000
--- a/机具(服务端)/migrations_xccpgl.sql
+++ /dev/null
@@ -1,28 +0,0 @@
--- xccpgl 表结构迁移(执行前请备份)
--- 若已执行过某条,可跳过该条
-
--- 1. 封面图片
-ALTER TABLE xccpgl ADD COLUMN fmtp varchar(500) NULL COMMENT '封面图片(单张,JSON格式)';
-
--- 2. 新闻正文
-ALTER TABLE xccpgl ADD COLUMN xwzw longtext NULL COMMENT '新闻正文(超文本)';
-
--- 3. 系统问题反馈(问题)分类字典
--- 字典类型:xtwtfk_qxgn,用于管理端和移动端下拉选项
--- 若已存在该 EnCode 的字典类型,可跳过
-INSERT INTO base_dictionarytype (F_Id, F_ParentId, F_FullName, F_EnCode, F_IsTree, F_SortCode, F_CreatorTime, F_EnabledMark, F_DeleteMark)
-SELECT '626798200000000001', '0', '系统问题反馈-问题分类', 'xtwtfk_qxgn', 0, 0, NOW(), 1, 0
-FROM DUAL
-WHERE NOT EXISTS (SELECT 1 FROM base_dictionarytype WHERE F_EnCode = 'xtwtfk_qxgn');
-
--- 字典数据(系统缺陷、功能缺失、显示异常、优化建议、功能新增)
-INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
-SELECT '626798200000000011', '0', '系统缺陷', 'xt1', 1, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '系统缺陷');
-INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
-SELECT '626798200000000012', '0', '功能缺失', 'xt2', 2, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '功能缺失');
-INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
-SELECT '626798200000000013', '0', '显示异常', 'xt3', 3, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '显示异常');
-INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
-SELECT '626798200000000014', '0', '优化建议', 'xt4', 4, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '优化建议');
-INSERT INTO base_dictionarydata (F_Id, F_ParentId, F_FullName, F_EnCode, F_SortCode, F_DictionaryTypeId, F_CreatorTime, F_EnabledMark, F_DeleteMark)
-SELECT '626798200000000015', '0', '功能新增', 'xt5', 5, '626798200000000001', NOW(), 1, 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM base_dictionarydata WHERE F_DictionaryTypeId = '626798200000000001' AND F_FullName = '功能新增');
diff --git a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/ZlglService.cs b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/ZlglService.cs
index db0e732..85a368e 100644
--- a/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/ZlglService.cs
+++ b/机具(服务端)/netcore/src/Modularity/Extend/NCC.Extend/ZlglService.cs
@@ -306,18 +306,42 @@ namespace NCC.Extend.Zlgl
}
// 客户权限:仅显示该客户在“我的设备”中已有设备关联产品的资料(传入 sskhbh 时生效;管理员不传则看全部)
+ // 使用与 KhsbPermissionHelper 一致的 sskhbh 扩展逻辑:当前用户可看 [userId, 所属组织, 上级组织] 下的设备
if (!string.IsNullOrEmpty(input.sskhbh))
{
- var allowedProductIds = await _db.Queryable()
- .Where(k => k.Sskhbh != null && k.Sskhbh.Contains(input.sskhbh.Trim()))
- .Where(k => k.Fl != null && k.Fl != "")
- .Select(k => k.Fl)
- .Distinct()
- .ToListAsync();
- if (allowedProductIds == null || allowedProductIds.Count == 0)
- query = query.Where(it => false); // 无设备或无关联产品时返回空列表
+ var allowedSskhbhIds = await KhsbPermissionHelper.GetUserAllowedSskhbhIdsAsync(_userManager, _db);
+ if (allowedSskhbhIds == null)
+ {
+ // 管理员:不限制客户
+ }
+ else if (allowedSskhbhIds.Count == 0)
+ {
+ query = query.Where(it => false);
+ }
else
- query = query.Where(it => allowedProductIds.Contains(it.Fl));
+ {
+ // 获取该用户可查看的设备所关联的产品ID:优先 Khsb.Fl,其次通过 Khsb.Dysbbh=cpgl.Cpid 关联
+ var productIdsFromFl = await _db.Queryable()
+ .Where(k => k.Sskhbh != null && allowedSskhbhIds.Contains(k.Sskhbh))
+ .Where(k => k.Fl != null && k.Fl != "")
+ .Select(k => k.Fl)
+ .Distinct()
+ .ToListAsync();
+ var productIdsFromDysbbh = await _db.Queryable()
+ .InnerJoin((k, c) => k.Dysbbh != null && k.Dysbbh != "" && k.Dysbbh == c.Cpid)
+ .Where((k, c) => k.Sskhbh != null && allowedSskhbhIds.Contains(k.Sskhbh))
+ .Select((k, c) => c.Id)
+ .Distinct()
+ .ToListAsync();
+ var allowedProductIds = (productIdsFromFl ?? new List())
+ .Union(productIdsFromDysbbh ?? new List())
+ .Distinct()
+ .ToList();
+ if (allowedProductIds == null || allowedProductIds.Count == 0)
+ query = query.Where(it => false);
+ else
+ query = query.Where(it => it.Fl != null && allowedProductIds.Contains(it.Fl));
+ }
}
var data = await query
--
libgit2 0.21.4