Files
xiaoqu_mcp_service/xiaoqu-agent-service/doc/install-order-mcp-tool-design.md
T

134 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 装机工单 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`)。