package com.xly.tool;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xly.agent.AgentIdentity;
import com.xly.service.ErpClient;
import com.xly.service.FormResolverService;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* FormCollect 工具(架构 §5 #5)——在对话里渲染一张 ERP 表单,让用户一次填齐 N 个参数,
* 而不是逐字段追问。字段/类型/必填/下拉/默认来自 ERP 表单元数据({@code gdsconfigformslave})。
*
*
工具返回结构化 schema(marker {@code type=form_collect});{@code AgentChatController} 侦测到后推
* SSE {@code form_collect} 事件,前端渲染表单;用户填完提交,前端把收集到的字段拼成后续对话消息发回,
* agent 再据此走 {@code proposeCreate}(人在环写入)。适合报价这类字段多的新建场景。
*
*
由 {@code AgentFactory} 按请求身份新建(非 @Component):携带 {@link AgentIdentity} 做表单级授权。
*/
public class FormCollectTool {
private static final int MAX_FIELDS = 40;
private final ErpClient erp;
private final JdbcTemplate jdbc;
private final FormResolverService resolver;
private final AgentIdentity identity;
private final ObjectMapper mapper;
public FormCollectTool(ErpClient erp, JdbcTemplate jdbc, FormResolverService resolver,
AgentIdentity identity, ObjectMapper mapper) {
this.erp = erp;
this.jdbc = jdbc;
this.resolver = resolver;
this.identity = identity;
this.mapper = mapper;
}
@Tool("在对话里弹出一张 ERP 表单让用户一次性填齐多个字段(而不是逐个追问)。用于字段较多的新建/录入场景"
+ "(如新建报价、新建客户)。入参 = 实体/单据类型(如 报价 / 客户)。用户填完提交后,你再用 proposeCreate 生成待确认的新增。")
public String collectForm(@P("要新建的实体/单据类型,如 报价 / 客户 / 物料") String entityKeyword) {
if (entityKeyword == null || entityKeyword.isBlank()) {
return err("缺少实体类型。");
}
Map form = resolver.resolveMasterForm(entityKeyword.trim());
if (form == null) {
return err("找不到「" + entityKeyword + "」对应的可新建表单。");
}
String formId = String.valueOf(form.get("sFormId"));
String moduleId = String.valueOf(form.get("sModuleId"));
if (!identity.canAccessModule(moduleId)) {
return err("你没有新建「" + entityKeyword + "」的权限。");
}
List