From f51e41a1896aa7fd5b9cdccc618f5b560c195ea1 Mon Sep 17 00:00:00 2001 From: my_local_kimi_dev2 Date: Wed, 16 Sep 2026 14:39:11 +0800 Subject: [PATCH] slark WIP snapshot (fence 1789540747913) --- .../doc/install-order-mcp-tool-design.md | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 xiaoqu-agent-service/doc/install-order-mcp-tool-design.md diff --git a/xiaoqu-agent-service/doc/install-order-mcp-tool-design.md b/xiaoqu-agent-service/doc/install-order-mcp-tool-design.md new file mode 100644 index 0000000..1b56702 --- /dev/null +++ b/xiaoqu-agent-service/doc/install-order-mcp-tool-design.md @@ -0,0 +1,133 @@ +# 装机工单 MCP 工具设计(install.order.list.query / install.order.detail.query) + +> 状态:已评审(2026-09-16 王恒确认) | 对应老接口:`POST /installOrder/pageList`、`POST /installOrder/lookDetails`(xiaoqu-franchisee `InstallOrderController.java:2004` / `:229`) +> 只读工具,不改老系统数据;数据源 m2(业务库)为主,详情聚合 m1(商城订单/地址)。 + +## 1. 工具清单 + +| 工具名 | category | kind | 用途 | +|---|---|---|---| +| `install.order.list.query` | workorder | read | 分页查询装机工单列表 | +| `install.order.detail.query` | workorder | read | 按 id 或装机单号查询工单详情(主单+明细+人员+流程) | + +## 2. install.order.list.query + +### 2.1 入参 + +对齐老 pageList,命名转 camelCase,匹配方式保持老语义(String 模糊、数字精确、时间区间): + +| 参数 | 类型 | 必填 | 匹配 | 说明 | +|---|---|---|---|---| +| installOrderNo | string | 否 | 模糊 | 装机单号 | +| mallOrderNo | string | 否 | 模糊 | 商城销售订单号 | +| deliveryOrderNo | string | 否 | 模糊 | 送货工单号 | +| pickupOrderNo | string | 否 | 模糊 | 取货工单号 | +| scheduleTransferOrder | string | 否 | 模糊 | 待办划转单号 | +| installType | int | 否 | 精确 | 0=正式装机 1=测试装机 | +| agentId | int | 否 | 精确 | 所属代理公司 id | +| districtName | string | 否 | 模糊 | 项目/站点名称 | +| applyUserName | string | 否 | 模糊 | 申请人 | +| maintenanceUserName | string | 否 | 模糊 | 运维人员 | +| cooperateUserName | string | 否 | 模糊 | 协同人员 | +| orderState | int | 否 | 精确 | 0待审核 1被驳回 2调度中 3待出库 4待送货 5作业中 6待取回 7已结束 8已取消 | +| applyTimeFrom / applyTimeTo | string | 否 | 区间 | 申请时间,yyyy-MM-dd(To 含当天,服务端补 23:59:59) | +| page | int | 否 | — | 默认 1 | +| rows | int | 否 | — | 默认 20,上限 100,超出截断并在 notice 提示 | + +裁剪说明(已评审确认):老接口的 7 组时间区间(finish/audit/dispatch/allocation/signature/pickup/warehousing)使用频率低,首版**只保留申请时间一组**;如确有需要再扩展。老接口的 `sidx/sord` 自由排序存在 SQL 注入面,**不移植**,固定排序 `apply_time DESC, id DESC`。 + +### 2.2 返回 + +沿用 MCP 统一分页结构: + +```json +{ + "total": 123, "page": 1, "rows": 20, + "notice": "rows 超过上限已截断为 100(仅超限时出现)", + "records": [ { "id": 1, "installOrderNo": "...", "installType": 0, "installTypeText": "正式装机", + "orderState": 5, "orderStateText": "作业中", + "agentId": 1, "agentName": "...", "propertyId": 1, "propertyName": "...", + "districtId": 1, "districtName": "...", "projectAddress": "...", + "applyUserName": "...", "maintenanceUserName": "...", "cooperateUserName": "...", + "hopeInstallDate": "...", "trueInstallDate": "...", + "applyTime": "yyyy-MM-dd HH:mm:ss", "finishDate": "...", + "mallOrderNo": "...", "deliveryOrderNo": "...", "pickupOrderNo": "...", + "totalInstallCount": 3 } ] +} +``` + +`totalInstallCount` 同老接口:按 `install_order_details` 汇总 install_count(分页记录逐条汇总,与老行为一致)。`orderStateText/installTypeText` 为附带文案,免查字典。 + +### 2.3 行级权限(新增 `PermissionService.applyInstallOrderRowFilter`) + +老逻辑在 `xiaoqu-franchisee utils/WrapperUtils.java:127-264`(`getWorkOrderAuth`,pageList 传 `propertyFlag=true, className=property_id, orderNoName=install_order_no, type=0`),1:1 移植: + +1. **总部**(权限组 `isagent != 1`):不过滤,看全部。 +2. **代理销售非负责人**(Redis 字典 authDeptId 含本部门且不含负责人岗位,复用现有 `isSalesNonLeader` 语义):`property_id IN(自己创建的物业 ∪ 被授权代管公司名下的物业)`,集合为空则 `IN (0)`;命中后互斥 return,不进规则 3。 +3. **其他代理用户**: + - `ids = 自己 agentId ∪ warehouse_agent_auth(user_id=自己).manager_agent_id`(本人 + 授权代管公司,**不含下级代理**,与现有 `visibleAgentIds` 不同,不可复用); + - 参与者单号 `orderNos = install_order_process(user_id=自己) ∪ install_order_user(user_id=自己)`(让运维/协同人员在调度阶段即可见工单); + - 代管物业 `propertyIds = agent_manage_district_auth(manage_agent_id IN ids).property_id`; + - 最终:`AND (apply_agent_id IN ids OR agent_id IN ids OR property_id IN propertyIds[如有] OR install_order_no IN orderNos[如有])`。 +4. 未配置权限组的用户按现有约定直接拒绝(同 `isAgentAuthority`)。 + +## 3. install.order.detail.query + +对齐老 `/installOrder/lookDetails`(`InstallOrderController.java:229`),返回 `InstallOrderApplyLookOutput` 的 MCP 版。商城订单聚合已评审确认**首版即带**(跨 m1 库)。 + +### 3.1 入参 + +| 参数 | 类型 | 必填 | 说明 | +|---|---|---|---| +| id | int | 二选一 | 工单主键,>0 优先 | +| installOrderNo | string | 二选一 | 装机单号,精确匹配 | +| includeProcess | bool | 否 | 是否返回流程记录,默认 true | +| processLimit | int | 否 | 流程记录上限,默认 100,最大 500 | + +### 3.2 返回 + +- `record`:主单全字段(同列表字段 + `customerContact/contactMobile/projectMemo/auditTime/dispatchTime/...` 等完整时间链与经手人); +- `details`:`install_order_details` 明细(物料、数量、安装位置等); +- `maintenanceUsers` / `cooperateUsers`:`install_order_user`(userType 0/1); +- `addressInfo`:收货地址(m1 `mall_shipping_address`,addressId 非空时); +- `mallOrder`:商城订单+订单明细+物料(m1,mallOrderNo 非空时); +- `processes`:流程记录,`schedule_state=2`(已办)、排除抄送(operationTheme!=12),按 `operation_time` 升序;调度/配发节点附人员,配发节点附 SN(`install_distribute_details`),出入库节点附 `install_to_out_warehouse` 记录与图片凭证 OSS URL(m1 `mall_logistics_pic` / m2 `warehouse_in_out_pic`)。 + +### 3.3 权限与防枚举 + +与列表**复用同一 `applyInstallOrderRowFilter`**:先按 id/单号查出主单,再套上同一个行级过滤 wrapper 校验可见性;不可见与不存在统一返回 `record=null` + `notice="工单不存在或无权查看"`,防止枚举越权工单(与 warehouse.out.detail.query 同一约定)。 + +## 4. 实现范围(变更文件清单) + +新增(xiaoqu-agent-service): + +- `entity/m2/InstallOrder.java`、`InstallOrderDetails.java`、`InstallOrderProcess.java`、`InstallOrderUser.java`、`InstallDistributeDetails.java`、`InstallToOutWarehouse.java`(只保留查询需要的字段) +- `mapper/m2/InstallOrderMapper.java` 等对应 Mapper(m2 分包已被 `M2DataSourceConfig` 扫描) +- `mcp/tool/InstallOrderTools.java`(两个 `@XqTool(category="workorder", kind="read")` 方法) +- `permission/PermissionService.java` 新增 `applyInstallOrderRowFilter` +- m1 侧复用现有商城订单/地址/物流 Mapper(warehouse.out.detail 已引入则直接复用,缺则新增) +- codegen 表白名单 `CodeGenerator.java` 登记新表 +- 测试:`InstallOrderToolsTest`(结构/分页/排序/schema 发布)+ `PermissionServiceInstallOrderRowFilterTest`(总部/销售/代理三角色) +- 文档:`doc/agent-mcp-tools-reference.md` 新增章节、README 工具表登记 + +不改:老系统任何代码与数据;svc 库表结构(tool 表由 ToolSyncService 启动自动同步)。 + +## 5. 边界与性能 + +- 列表 `selectCount + LIMIT` 手写分页;固定排序,无注入面。 +- 不做无界聚合;装机统计(数量/状态分布)如有需要,后续独立设计 `install.order.summary.query`。 +- 详情的子表均按主单单号/id 精确查询,processLimit 兜底;图片只回传 OSS URL,不内嵌内容。 +- 时间统一 `yyyy-MM-dd HH:mm:ss`,Asia/Shanghai。 + +## 6. 测试与验收 + +1. 单测全量通过(现有 236 + 新增)。 +2. 三角色权限用例:总部无过滤;代理只见 自己+代管公司+代管物业+本人参与 的工单;销售非负责人只见 自己创建物业+代管物业;越权查详情返回 record=null 且提示与不存在一致。 +3. rows=500 截断为 100 且带 notice;installOrderNo 模糊、orderState 精确、applyTime 区间生效。 +4. 发布:合并 main → `deploy/deploy.sh remote-deploy` → 健康检查 POST /mcp 401 → svc 库 tool 表出现两个新工具 → 给目标 scope 绑定 scope_tool → 线上 tools/list 可见性验证。 + +## 7. 评审结论(2026-09-16 王恒确认) + +1. 时间区间只保留申请时间一组(applyTimeFrom/To),其余 7 组不移植。 +2. 详情首版即带商城订单聚合(跨 m1 库)。 +3. category 用 `workorder`(不新建 `install`,也不并入 `warehouse`)。