package com.xly.tool; import com.fasterxml.jackson.databind.ObjectMapper; import com.xly.service.FormResolverService; import dev.langchain4j.agent.tool.P; import dev.langchain4j.agent.tool.Tool; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; /** * FormCollect(表单呈现)—— 在对话框里渲染一张动态表单,让用户一次填多个字段(如新增记录时)。 * *

字段来自 ERP 配置的知识图谱({@code viw_kg_field_dict} 里该主表最常用的可填字段), * 前端把它们渲染成输入框;用户填完提交后,前端把「字段=值」拼成一条消息发回,agent 再走 * proposeCreate 生成待确认提议。整套 UI 在 xlyAi 自己的聊天前端完成,无需 ERP 前端配合。 */ @Component public class FormCollectTool { private final FormResolverService resolver; private final JdbcTemplate jdbc; private final ObjectMapper mapper; public FormCollectTool(FormResolverService resolver, JdbcTemplate jdbc, ObjectMapper mapper) { this.resolver = resolver; this.jdbc = jdbc; this.mapper = mapper; } @Tool("在对话框里**渲染一张可填写的表单**,让用户一次性填写某实体的多个字段(用于新增记录时收集信息)。" + "调用后前端会显示表单;用户填完提交,你再据其内容用 proposeCreate 生成新增提议。") public String showForm(@P("实体类型,如 客户 / 物料") String entityKeyword) { if (entityKeyword == null || entityKeyword.isBlank()) { return "{\"error\":\"缺少实体类型\"}"; } Map form = resolver.resolveMasterForm(entityKeyword.trim()); if (form == null) { return "{\"error\":\"找不到「" + entityKeyword + "」的主表\"}"; } String table = String.valueOf(form.get("sDataSource")); List fields = new ArrayList<>(); Set seen = new HashSet<>(); try { List> rows = jdbc.queryForList( "SELECT sChinese, sField, MAX(iFormUses) u FROM viw_kg_field_dict WHERE sTable=? " + "AND sField NOT LIKE '%Id' AND sField NOT LIKE 'b%' AND sField<>'sToken' AND sField<>'sMakePerson' " + "AND CHAR_LENGTH(sChinese)>=2 GROUP BY sChinese, sField ORDER BY u DESC LIMIT 10", table); for (Map r : rows) { Object zh = r.get("sChinese"); if (zh != null && seen.add(zh.toString()) && fields.size() < 8) { fields.add(zh.toString()); } } } catch (Exception ignore) { } if (fields.isEmpty()) { return "{\"error\":\"该实体没有可填字段\"}"; } Map out = new LinkedHashMap<>(); out.put("formCollect", true); out.put("entity", entityKeyword.trim()); out.put("fields", fields); out.put("message", "已在下方为你打开填写表单,请填好后点提交。"); try { return mapper.writeValueAsString(out); } catch (Exception e) { return "{\"error\":\"内部错误\"}"; } } }