package com.ruoyi.template.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.service.IConfigService;
import com.ruoyi.template.mapper.IvrLibaTargetMapper;
import com.ruoyi.template.mapper.IvrLibaTargetTagMapper;
import com.ruoyi.template.mapper.IvrLibaTargetoptionMapper;
import com.ruoyi.template.service.IIvrLibaTargetService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Array;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.ruoyi.template.domain.IvrTaskTemplateTargetoption;
import com.ruoyi.common.core.service.SubtaskOptionMatchApi;
import org.springframework.beans.factory.ObjectProvider;
import com.ruoyi.template.domain.IvrLibaTarget;
import com.ruoyi.template.domain.IvrLibaTargetTag;
import com.ruoyi.template.domain.IvrLibaTargetVO;
import com.ruoyi.template.domain.IvrLibaTargetoption;
/**
* 指标选项库Service业务层处理
*
* @author ruoyi
* @date 2023-12-14
*/
@Slf4j
@Service
public class IvrLibaTargetServiceImpl implements IIvrLibaTargetService {
@Autowired
private IvrLibaTargetMapper ivrLibaTargetMapper;
/**
* AI 选项匹配能力(原 smartor 的 IServiceSubtaskService#matchOptionIndex)。
*
* ⚠️ 用 ObjectProvider 惰性取,并必须降级:取不到时返回 -1("未匹配"),
* 绝不能让模板模块因为契约实现缺失而抛异常。
*/
@Autowired
private ObjectProvider optionMatchApiProvider;
@Autowired
private IvrLibaTargetTagMapper ivrLibaTargetTagMapper;
@Autowired
private IvrLibaTargetoptionMapper ivrLibaTargetoptionMapper;
/**
* 参数配置读取。
*
* ⚠️ 原注入的是 {@code com.ruoyi.system.service.ISysConfigService}(ruoyi-system),
* 而本模块只依赖 ruoyi-common —— 引 ruoyi-system 会让模块依赖链变重且方向不清。
* 改用 ruoyi-common 已下沉的 {@link IConfigService}:它的
* {@code selectConfigByKey(String)} 与原接口同名同签名,
* smartor 侧已有实现({@code SysConfigServiceImpl}),调用点一行未改。
*/
@Autowired
private IConfigService configService;
/**
* 查询指标选项库
*
* @param id 指标选项库主键
* @return 指标选项库
*/
@Override
public IvrLibaTarget selectIvrLibaTargetByTargetID(Long id) {
return ivrLibaTargetMapper.selectIvrLibaTargetByTargetID(id);
}
/**
* 查询指标选项库列表
*
* @param ivrLibaTarget 指标选项库
* @return 指标选项库
*/
@Override
public List selectIvrLibaTargetList(IvrLibaTarget ivrLibaTarget) {
return ivrLibaTargetMapper.selectIvrLibaTargetList(ivrLibaTarget);
}
@Override
public List targetInfo(IvrLibaTarget ivrLibaTarget) {
List ivrLibaTargets = ivrLibaTargetMapper.selectIvrLibaTargetList(ivrLibaTarget);
List ivrLibaTargetVOS = DtoConversionUtils.sourceToTarget(ivrLibaTargets, IvrLibaTargetVO.class);
for (IvrLibaTargetVO ivrLibaTarget1 : ivrLibaTargetVOS) {
ivrLibaTarget1.setSuitWayList(JSONArray.parseArray(ivrLibaTarget1.getSuitWay(), String.class));
IvrLibaTargetoption ivrLibaTargetoption = new IvrLibaTargetoption();
ivrLibaTargetoption.setTargetid(ivrLibaTarget1.getId());
//获取该指标的选项
List ivrLibaTargetoptions = ivrLibaTargetoptionMapper.selectIvrLibaTargetoptionList(ivrLibaTargetoption);
if (CollectionUtils.isNotEmpty(ivrLibaTargetoptions)) {
for (IvrLibaTargetoption ivrLibaTargetoption1 : ivrLibaTargetoptions) {
ObjectMapper objectMapper = new ObjectMapper();
try {
if (StringUtils.isNotEmpty(ivrLibaTargetoption1.getDynamiccruxsJson()))
ivrLibaTargetoption1.setDynamiccruxs(objectMapper.readValue(ivrLibaTargetoption1.getDynamiccruxsJson(), List.class));
if (StringUtils.isNotEmpty(ivrLibaTargetoption1.getNodynamiccruxsJson()))
ivrLibaTargetoption1.setNodynamiccruxs(objectMapper.readValue(ivrLibaTargetoption1.getNodynamiccruxsJson(), List.class));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
ivrLibaTarget1.setTargetoptionList(ivrLibaTargetoptions);
}
//获取该指标的标签
IvrLibaTargetTag ivrLibaTargetTag = new IvrLibaTargetTag();
ivrLibaTargetTag.setTargetid(ivrLibaTarget1.getId());
List ivrLibaTargetTags = ivrLibaTargetTagMapper.selectIvrLibaTargetTagList(ivrLibaTargetTag);
ivrLibaTarget1.setIvrLibaTargetTagList(ivrLibaTargetTags);
}
//判断入参条件中,tagName是否有值,如果有值,则需要根据给的值进行标签过滤
if (StringUtils.isNotEmpty(ivrLibaTarget.getTagName())) {
List ivrLibaTargetVOList = new ArrayList<>();
aa:
for (IvrLibaTargetVO ivrLibaTarget1 : ivrLibaTargetVOS) {
for (IvrLibaTargetTag ivrLibaTargetTag1 : ivrLibaTarget1.getIvrLibaTargetTagList()) {
if (ivrLibaTargetTag1.getTagname().contains(ivrLibaTarget.getTagName().trim())) {
ivrLibaTargetVOList.add(ivrLibaTarget1);
continue aa;
}
}
}
ivrLibaTargetVOS = ivrLibaTargetVOList;
}
//下面用左外感觉有点问题,where中的option的del会导致左边的查询不全,先不用吧
// ivrLibaTargetMapper.targetInfo(ivrLibaTarget)
return ivrLibaTargetVOS;
}
/**
* 新增指标选项库
*
* @param ivrLibaTargetVO 指标选项库
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int insertIvrLibaTarget(IvrLibaTargetVO ivrLibaTargetVO) {
//新增指标信息
IvrLibaTarget ivrLibaTarget = DtoConversionUtils.sourceToTarget(ivrLibaTargetVO, IvrLibaTarget.class);
ivrLibaTarget.setCreateTime(DateUtils.getNowDate());
ivrLibaTargetMapper.insertIvrLibaTarget(ivrLibaTarget);
//新增该指标对应的标签信息
for (IvrLibaTargetTag ivrLibaTargetTag : ivrLibaTargetVO.getIvrLibaTargetTagList()) {
ivrLibaTargetTag.setTargetid(ivrLibaTarget.getId());
ivrLibaTargetTag.setGuid(ivrLibaTargetVO.getGuid());
ivrLibaTargetTag.setOrgid(ivrLibaTargetVO.getOrgid());
ivrLibaTargetTagMapper.insertIvrLibaTargetTag(ivrLibaTargetTag);
}
//新增该指标对应的指标选项信息
for (IvrLibaTargetoption targetoption : ivrLibaTargetVO.getTargetoptionList()) {
if (ObjectUtils.isEmpty(targetoption)) continue;
log.info("targetoption的数据为:{}", targetoption);
targetoption.setTargetid(ivrLibaTarget.getId());
targetoption.setGuid(ivrLibaTargetVO.getGuid());
targetoption.setOrgid(ivrLibaTargetVO.getOrgid());
ivrLibaTargetoptionMapper.insertIvrLibaTargetoption(targetoption);
}
log.info("指标id为:{}", ivrLibaTarget.getId().intValue());
return ivrLibaTarget.getId().intValue();
}
/**
* 新增或修改指标选项库
*
* @param ivrLibaTargetVO 指标选项库
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int saveOrupdateIvrLibaTarget(IvrLibaTargetVO ivrLibaTargetVO) {
IvrLibaTarget ivrLibaTarget = DtoConversionUtils.sourceToTarget(ivrLibaTargetVO, IvrLibaTarget.class);
if (ObjectUtils.isNotEmpty(ivrLibaTargetVO.getSuitWayList()))
ivrLibaTarget.setSuitWay(JSON.toJSONString(ivrLibaTargetVO.getSuitWayList()));
ivrLibaTarget.setUpdateTime(DateUtils.getNowDate());
if (ivrLibaTargetVO.getIsoperation() != null && ivrLibaTargetVO.getIsoperation() == 1) {
//新增
ivrLibaTarget.setCreateTime(new Date());
ivrLibaTarget.setUpdateTime(new Date());
ivrLibaTargetMapper.insertIvrLibaTarget(ivrLibaTarget);
} else if (ivrLibaTargetVO.getIsoperation() != null && ivrLibaTargetVO.getIsoperation() == 2) {
//修改
ivrLibaTarget.setUpdateTime(new Date());
ivrLibaTargetMapper.updateIvrLibaTarget(ivrLibaTarget);
}
if (CollectionUtils.isNotEmpty(ivrLibaTargetVO.getIvrLibaTargetTagList())) {
for (IvrLibaTargetTag ivrLibaTargetTag : ivrLibaTargetVO.getIvrLibaTargetTagList()) {
ivrLibaTargetTag.setGuid(ivrLibaTargetVO.getGuid());
ivrLibaTargetTag.setOrgid(ivrLibaTargetVO.getOrgid());
if (ivrLibaTargetTag.getId() == null) {
//新增
ivrLibaTargetTag.setTargetid(ivrLibaTarget.getId());
ivrLibaTargetTagMapper.insertIvrLibaTargetTag(ivrLibaTargetTag);
} else if (ivrLibaTargetTag.getId() != null) {
//前端页面应该没有修改
ivrLibaTargetTagMapper.updateIvrLibaTargetTag(ivrLibaTargetTag);
}
}
}
if (CollectionUtils.isNotEmpty(ivrLibaTargetVO.getTargetoptionList()) && ivrLibaTargetVO.getScriptType().equals("1") || CollectionUtils.isNotEmpty(ivrLibaTargetVO.getTargetoptionList()) && ivrLibaTargetVO.getScriptType().equals("2")) {
//选项处理
for (IvrLibaTargetoption ivrLibaTargetoption : ivrLibaTargetVO.getTargetoptionList()) {
if (CollectionUtils.isNotEmpty(ivrLibaTargetoption.getNodynamiccruxs())) {
ivrLibaTargetoption.setNodynamiccruxsJson(new Gson().toJson(ivrLibaTargetoption.getNodynamiccruxs()));
}
if (CollectionUtils.isNotEmpty(ivrLibaTargetoption.getDynamiccruxs())) {
ivrLibaTargetoption.setDynamiccruxsJson(new Gson().toJson(ivrLibaTargetoption.getDynamiccruxs()));
}
//指标库排序
ivrLibaTargetoption.setSortid(ivrLibaTargetoption.getGuid());
ivrLibaTargetoption.setGuid(ivrLibaTargetVO.getGuid());
ivrLibaTargetoption.setOrgid(ivrLibaTargetVO.getOrgid());
if (ivrLibaTargetoption.getIsoperation() != null && ivrLibaTargetoption.getIsoperation() == 1) {
//新增
ivrLibaTargetoption.setTargetid(ivrLibaTarget.getId());
ivrLibaTargetoptionMapper.insertIvrLibaTargetoption(ivrLibaTargetoption);
} else if (ivrLibaTargetoption.getIsoperation() != null && ivrLibaTargetoption.getIsoperation() == 2) {
//修改
ivrLibaTargetoptionMapper.updateIvrLibaTargetoption(ivrLibaTargetoption);
} else if (ivrLibaTargetoption.getIsoperation() != null && ivrLibaTargetoption.getIsoperation() == 3) {
// 删除
ivrLibaTargetoptionMapper.deleteIvrLibaTargetoptionByTargetoptionid(ivrLibaTargetoption.getTargetoptionid());
}
}
} else if (ivrLibaTargetVO.getScriptType().equals("3") || ivrLibaTargetVO.getScriptType().equals("4")) {
//这里先等等
}
return ivrLibaTarget.getId().intValue();
}
/**
* 批量删除指标选项库
*
* @return 结果
*/
@Override
public int deleteIvrLibaTargetByTargetIDs(Long[] ids) {
return ivrLibaTargetMapper.deleteIvrLibaTargetByTargetIDs(ids);
}
/**
* 删除指标选项库信息
*
* @return 结果
*/
@Override
public int deleteIvrLibaTargetByTargetID(Long id) {
return ivrLibaTargetMapper.deleteIvrLibaTargetByTargetID(id);
}
/**
* 指标测试问题匹配
*/
@Override
public String targetQuesMate(IvrLibaTargetVO ivrLibaTargetVO) {
//1-AI识别
String url = configService.selectConfigByKey("sys.voice.match.ai.url");
if (ObjectUtils.isNotEmpty(url)) {
String matchedText = "";
String questionText = ivrLibaTargetVO.getQuestionText();
String voiceText = ivrLibaTargetVO.getContent();
List options = DtoConversionUtils.sourceToTarget(ivrLibaTargetVO.getTargetoptionList(), IvrTaskTemplateTargetoption.class);
//1-AI识别
// ⚠️ 契约实现可能缺失(模块单独部署 / 非 Spring 环境)—— 显式降级为 null,
// 后续 ObjectUtils.isNotEmpty(matched) 判空后按"未匹配"走,不改变主流程。
SubtaskOptionMatchApi optionMatchApi = optionMatchApi();
Integer matched = optionMatchApi == null ? null
: optionMatchApi.matchOptionIndex(url, questionText, voiceText, options, "1");
if (ObjectUtils.isNotEmpty(matched)) {
if (matched >= 0) {
matchedText = options.get(matched).getTargetvalue();
}
}
log.info("ai匹配成功,匹配结果是:" + matchedText);
return matchedText;
}
for (IvrLibaTargetoption ivrLibaTargetoption : ivrLibaTargetVO.getTargetoptionList()) {
Matcher matcher = null;
if (StringUtils.isNotEmpty(ivrLibaTargetoption.getTargetregex())) {
Pattern pattern = Pattern.compile(ivrLibaTargetoption.getTargetregex());
matcher = pattern.matcher(ivrLibaTargetVO.getContent());
}
//不包含
Matcher matcher2 = null;
if (StringUtils.isNotEmpty(ivrLibaTargetoption.getTargetregex2())) {
Pattern pattern2 = Pattern.compile(ivrLibaTargetoption.getTargetregex2());
matcher2 = pattern2.matcher(ivrLibaTargetVO.getContent());
}
if (StringUtils.isNotEmpty(ivrLibaTargetoption.getTargetregex2()) && matcher2.matches() && StringUtils.isNotEmpty(ivrLibaTargetoption.getTargetregex()) && matcher.matches() || StringUtils.isEmpty(ivrLibaTargetoption.getTargetregex2()) && StringUtils.isNotEmpty(ivrLibaTargetoption.getTargetregex()) && matcher.matches()) {
return ivrLibaTargetoption.getTargetvalue();
}
}
return null;
}
/**
* 取 AI 选项匹配契约;取不到返回 null(调用方按"未匹配"处理)。
*/
private SubtaskOptionMatchApi optionMatchApi() {
if (optionMatchApiProvider == null) {
return null;
}
try {
return optionMatchApiProvider.stream().findFirst().orElse(null);
} catch (Exception e) {
log.warn("【模板】获取 SubtaskOptionMatchApi 失败,按不可用处理:{}", e.toString());
return null;
}
}
}