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

8.8 KiB
Raw Blame History

装机工单 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 统一分页结构:

{
  "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)。