package com.xly.tool;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xly.agent.AgentIdentity;
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.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* FormCollect 工具(架构 §5 #5)——在对话里渲染一张 ERP 表单,让用户一次填齐 N 个参数,
* 而不是逐字段追问。
*
*
字段来源优先 {@link FormResolverService#businessFields}(精选映射 + 字段字典,即"真正要填的业务参数"),
* 每个字段带控件类型 {@code fkselect|select|number|date|text};外键字段的下拉选项由前端另调
* {@code GET /api/agent/form/options} 从来源表实时取。只有该表在字段字典里没有映射时,才退回
* ERP 界面元数据 {@code gdsconfigformslave} 的可见可写字段。
*
*
工具返回结构化 schema(marker {@code type=form_collect});{@code AgentChatController} 侦测到后推
* SSE {@code form_collect} 事件,前端渲染表单;用户填完提交,前端把收集到的字段拼成后续对话消息发回,
* agent 再据此走 {@code proposeWrite(action=create)}(人在环写入)。适合报价这类字段多的新建场景。
*
*
由 {@code AgentFactory} 按请求身份新建(非 @Component):携带 {@link AgentIdentity} 做表单级授权。
*/
public class FormCollectTool {
private static final int MAX_FIELDS = 40;
private final JdbcTemplate jdbc;
private final FormResolverService resolver;
private final AgentIdentity identity;
private final ObjectMapper mapper;
public FormCollectTool(JdbcTemplate jdbc, FormResolverService resolver,
AgentIdentity identity, ObjectMapper mapper) {
this.jdbc = jdbc;
this.resolver = resolver;
this.identity = identity;
this.mapper = mapper;
}
@Tool("在对话里弹出一张 ERP 表单让用户一次性填齐多个字段(而不是逐个追问、更不是自己猜)。用于字段较多的新建/录入场景"
+ "(尤其**新建报价**)。entityKeyword = 单据类型(如 报价 / 客户);knownFieldsJson = 用户已说的字段(中文名->值)用于预填"
+ "(如 {\"产品名称\":\"纸盒\",\"数量\":\"1000\",\"长(L)\":\"50\"})。客户/产品/物料会渲染成下拉让用户从真实数据里选。"
+ "用户填完提交后,你再用 proposeWrite(action=create) 生成待确认的新增。")
public String collectForm(
@P("要新建的实体/单据类型,如 报价 / 客户 / 物料") String entityKeyword,
@P(value = "可选:用户已说的字段 JSON(中文名->值),用于预填表单,如 {\"产品名称\":\"纸盒\",\"数量\":\"1000\"}",
required = false) String knownFieldsJson) {
if (entityKeyword == null || entityKeyword.isBlank()) {
return err("缺少实体类型。");
}
Map known = parseKnown(knownFieldsJson);
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 + "」的权限。");
}
String table = String.valueOf(form.get("sDataSource"));
List