package com.xly.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xly.agent.Intent;
import org.springframework.stereotype.Service;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 新增单据的**确定性槽位映射**:把意图门已抽好的「带角色实体」+ 正则解析的尺寸/数量,
* 按表单真实字段落位,产出 collectForm 的预填 JSON。
*
*
为什么不用 LLM 做这步:实测 qwen3:14b 能可靠区分「产品 vs 客户」(意图门已给出角色),
* 但对「长和宽50cm,高5cm」这类**尺寸拆分**始终出错(塞进备注/单价)。这类窄任务用 Java 正则 +
* 角色映射远比让模型受约束填槽可靠——把不确定的判断交给能确定处理的代码,是治『不智能』的关键手法之一。
*/
@Service
public class SlotFillService {
private final ObjectMapper mapper;
public SlotFillService(ObjectMapper mapper) {
this.mapper = mapper;
}
// 标注式尺寸:"长和宽50"、"高5cm"、"长:50"
private static final Pattern DIM_LABELED =
Pattern.compile("([长宽高厚深](?:[和与、,,及/][长宽高厚深])*)\\s*[::是为]?\\s*(\\d+(?:\\.\\d+)?)");
// 位置式尺寸:"50*30*5"、"50x30x5"、"50×30×5"
private static final Pattern DIM_POS =
Pattern.compile("(\\d+(?:\\.\\d+)?)\\s*[*xX×]\\s*(\\d+(?:\\.\\d+)?)(?:\\s*[*xX×]\\s*(\\d+(?:\\.\\d+)?))?");
/**
* 依据意图门的角色实体 + 正则,确定性地构建新增表单的预填字段(中文字段名 -> 值)。
*
* @param utterance 用户原话(用于解析尺寸)
* @param entity 单据/实体类型(如 报价 / 客户)
* @param fields {@code FormResolverService.businessFields}(含 label/fk/type)
* @param it 意图门结果(提供带角色的实体)
*/
public Map buildCreateFields(String utterance, String entity,
List