package com.ruoyi.common.core.service;
|
|
import java.util.List;
|
|
/**
|
* 「AI 选项匹配」的对外契约。
|
*
|
* <h3>它是什么</h3>
|
* 原 {@code IServiceSubtaskService#matchOptionIndex}(smartor):
|
* 把「用户问题 + 语音识别结果 + 候选选项」序列化成 JSON,<b>POST 到一个外部 AI 服务</b>,
|
* 把返回的数字解析为命中的选项下标(解析失败或 url 为空返回 {@code -1})。
|
*
|
* <h3>为什么要下沉成契约</h3>
|
* 模板模块的 {@code IvrLibaTargetServiceImpl} 需要调它,但它是 smartor 的方法。
|
* 模板模块**绝不能依赖 smartor**(smartor 已依赖模板模块 → 会成环,Maven 直接构建失败)。
|
* 所以按既有手法({@link VisitTaskCreateApi} / {@link ServiceTaskMatchApi} 等):
|
* 接口放 ruoyi-common,smartor 侧提供过渡实现。
|
*
|
* <h3>⚠️ 入参为什么用<b>泛型</b> {@code List<T>} 而不是模板实体</h3>
|
* 原方法签名是 {@code List<IvrTaskTemplateTargetoption>},而那个类型已搬进
|
* {@code ruoyi-template}。若契约直接写具体类型,ruoyi-common 就得依赖 ruoyi-template ——
|
* 方向不对。
|
* <p>
|
* 也不能简单写成 {@code List<Object>}:调用方拿到返回值后要
|
* {@code options.get(matched).getOptiondesc()} —— 参数若是 {@code List<Object>},
|
* {@code get()} 返回 {@code Object},那行就编译不过。用泛型 {@code <T>} 可以让
|
* 调用点的类型保持原样,而 ruoyi-common 无需知道 {@code T} 是什么。
|
* <p>
|
* 语义上也安全:原方法对 options **只做一件事 —— {@code jsonObject.put("options", options)}**
|
* 然后整体序列化,从不读它的字段,所以 {@code T} 具体是什么都不影响结果。
|
*
|
* <h3>实现方必须保持的行为</h3>
|
* <ul>
|
* <li>{@code url} 为空 → 不发请求,返回 {@code -1};</li>
|
* <li>请求抛异常 → 打日志后返回 {@code -1}(<b>吞异常</b>,原实现如此);</li>
|
* <li>响应非纯整数(允许前导负号)→ 返回 {@code -1}。</li>
|
* </ul>
|
*/
|
public interface SubtaskOptionMatchApi {
|
|
/**
|
* 调外部 AI 服务做选项匹配。
|
*
|
* @param url AI 服务地址(原 {@code ivrTaskTemplate.url});为空则直接返回 -1
|
* @param questionText 用户问题
|
* @param voiceText 语音识别结果
|
* @param options 候选选项(原为 {@code List<IvrTaskTemplateTargetoption>});
|
* 仅用于 JSON 序列化,故用泛型承载
|
* @param uuid 本次会话 uuid
|
* @param <T> 选项元素类型(调用方决定,实现方不需要知道)
|
* @return 命中的下标;无法匹配返回 {@code -1}
|
*/
|
<T> Integer matchOptionIndex(String url, String questionText, String voiceText,
|
List<T> options, String uuid);
|
}
|