@@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper ;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl ;
import com.volvo.ai.analytic.center.constant.Constant ;
import com.volvo.ai.analytic.center.dto.PageDto ;
import com.volvo.ai.analytic.center.dto.corpus.OdsVdqwMessageOTD ;
import com.volvo.ai.analytic.center.dto.req.DiFyReq ;
import com.volvo.ai.analytic.center.dto.req.RunMaskingRuleInput ;
@@ -20,6 +21,7 @@ import com.volvo.ai.analytic.center.service.DataMaskingRuleService;
import com.volvo.ai.analytic.center.service.DiFyService ;
import com.volvo.ai.analytic.center.service.TmOdsVdqwMessagearchivingService ;
import com.volvo.ai.analytic.center.service.TmTelephoneCorpusService ;
import com.volvo.ai.analytic.center.utils.ConstantStr ;
import com.volvo.ai.analytic.center.utils.FlowResultSplitUtil ;
import lombok.extern.slf4j.Slf4j ;
import org.apache.commons.collections.CollectionUtils ;
@@ -29,14 +31,19 @@ import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.beans.factory.annotation.Value ;
import org.springframework.cloud.context.config.annotation.RefreshScope ;
import org.springframework.messaging.support.MessageBuilder ;
import org.springframework.stereotype.Service ;
import javax.annotation.Resource ;
import java.time.LocalDate ;
import java.util.Arrays ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.concurrent.CompletableFuture ;
import java.util.concurrent.ExecutorService ;
import java.util.concurrent.Executors ;
/**
@@ -44,6 +51,7 @@ import java.util.Map;
* @author rz
* @date 2025-03-04
*/
@RefreshScope
@Slf4j
@Service
public class TmOdsVdqwMessagearchivingServiceImpl extends ServiceImpl < TmOdsVdqwMessagearchivingMapper , TmOdsVdqwMessagearchiving > implements TmOdsVdqwMessagearchivingService {
@@ -62,9 +70,13 @@ public class TmOdsVdqwMessagearchivingServiceImpl extends ServiceImpl<TmOdsVdqwM
@Resource
private RocketMQTemplate rocketMqTemplate ;
@Value ( " ${rocketmq.corpusTelephone .topic} " )
@Value ( " ${rocketmq.producer.corpus .topic} " )
private String topic ;
@Value ( " ${dify.corpus.qiweiToken} " )
private String qiweiToken ;
@Value ( " ${batch.size} " )
public int pageSize = 100 ;
@Autowired
private RemoteCarModelClient remoteCarModelClient ;
@@ -74,94 +86,132 @@ public class TmOdsVdqwMessagearchivingServiceImpl extends ServiceImpl<TmOdsVdqwM
@Autowired
private TmTelephoneCorpusService tmTelephoneCorpusService ;
@Override
public void runQiWeiCorpusDify ( ) {
String statTime = " 2025-03-01 " ;
String endTime = " 2025-03-02 " ;
List < OdsVdqwMessageOTD > messageList = tmOdsVdqwMessagearchivingMapper . queryOdsVdqwMessageByData ( statTime , endTime ) ;
messageList . stream ( ) . forEach ( item - > {
log . info ( " 企微语料内容: FromUserId: {}, AcceptUserId: {} " , item . getFromUserId ( ) , item . getAcceptUserId ( ) ) ;
// 1, vdqw_workuserinfo 这个表对应是 B端认证中心userI d
// 2, vdqw_externalcontact 这个表对应是 企微客户unionId
String unionId = getUnionId ( Arrays . asList ( item . getFromUserId ( ) , i tem . getAcceptUserId ( ) ) ) ;
String userId = getUserId ( Arrays . asList ( item . getFromUserId ( ) , item . getAcceptUserId ( ) ) ) ;
log . info ( " 企微查询信息为空: unionId: {}, userId: {} " , unionId , userId ) ;
if ( StringUtils . isEmpty ( unionId ) | | StringUtils . isNotBlank ( userId ) ) {
log . info ( " 企微查询信息为空 " ) ;
return ;
public void runQiWeiCorpusDify ( String paramJson ) {
log . info ( " runQiWeiCorpusDify paramJson {} " , paramJson ) ;
// 获取当前日期
LocalDate today = LocalDate . now ( ) ;
// 获取前一天日期
LocalDate yesterday = today . minusDays ( 1 ) ;
// 格式化输出
String formattedDate = yesterday . toString ( ) ; // 默认格式为 yyyy-MM-d d
String statTime = formattedDate . concat ( " 00:00:00 " ) ;
String endTime = formattedDa te. concat ( " 23:59:59 " ) ;
if ( StringUtils . isNotBlank ( paramJson ) ) {
JSONObject paramJsonObj = JSONObject . parseObject ( paramJson ) ;
if ( null ! = paramJsonObj & & paramJsonObj . containsKey ( " statTime " ) & & paramJsonObj . containsKey ( " endTime " ) ) {
statTime = paramJsonObj . getString ( " statTime " ) ;
endTime = paramJsonObj . getString ( " endTime " ) ;
}
}
String finalStatTime = statTime ;
String finalEndTime = endTime ;
if ( StringUtils . isNotBlank ( item . getFromUserId ( ) ) & & StringUtils . isNotBlank ( item . getAcceptUserId ( ) ) ) {
Integer total = tmOdsVdqwMessagearchivingMapper . countOdsVdqwMessageByData ( statTime , endTime ) ;
int totalPages = PageDto . getTotalPages ( total , pageSize ) ;
// 获取消息列表
int optimalThreadPoolSize = Runtime . getRuntime ( ) . availableProcessors ( ) + 1 ;
log . info ( " 获取的线程数:{} " , optimalThreadPoolSize ) ;
// 创建线程池
ExecutorService executor = Executors . newFixedThreadPool ( optimalThreadPoolSize ) ; // 根据需求调整线程池大小
List < OdsVdqwMessageOTD > contetnList = tmOdsVdqwMessagearchivingMapper . queryOdsVdqwMessageByFromUserIdAndAcceptUserId ( statTime , endTime , Arrays . asList ( item . getFromUserId ( ) , item . getAcceptUserId ( ) ) ) ;
OdsVdqwMessageOTD maxMsgTimeItem = contetnList . stream ( )
. max ( ( o1 , o2 ) - > o1 . getMsgTime ( ) . compareTo ( o2 . getMsgTime ( ) ) )
. orElse ( null ) ;
contetnList . stream ( ) . forEach ( contentItem - > {
for ( int i = 1 ; i < = totalPages ; i+ + ) {
int offset = ( i - 1 ) * pageSize ;
List < OdsVdqwMessageOTD > messageList = tmOdsVdqwMessagearchivingMapper . queryOdsVdqwMessageByData ( statTime , endTime , offset , pageSize ) ;
// 处理查询到的数据
// 使用 CompletableFuture 并行处理
CompletableFuture < ? > [ ] futures = messageList . stream ( )
. map ( item - > CompletableFuture . runAsync ( ( ) - > {
try {
processItem ( item , finalStatTime , finalEndTime ) ;
} catch ( Exception e ) {
log . error ( " 处理消息失败: FromUserId={}, AcceptUserId={}, 异常: {} " ,
item . getFromUserId ( ) , item . getAcceptUserId ( ) , e . getMessage ( ) , e ) ;
}
} , executor ) )
. toArray ( CompletableFuture [ ] : : new ) ;
// 等待所有任务完成
CompletableFuture . allOf ( futures ) . join ( ) ;
}
// 关闭线程池
executor . shutdown ( ) ;
Map < String , Object > inputMap = new HashMap ( ) ;
DiFyReq diFyImageReq = new DiFyReq ( ) ;
diFyImageReq . setUser ( " 11111 " ) ;
diFyImageReq . setFlowId ( " app-peJXSjHjVKdkYxjdOUuPnZ5b " ) ;
}
JSONObject contentJson = JSONObject . parseObject ( contentItem . getContent ( ) ) ;
String content = contentJson . getString ( " content " ) ;
List < DataMaskingRule > maskingRuleItems = dataMaskingRuleService . getDataMaskingRuleListByApplicationChannel ( Constant . CHANNEL_DCC ) ;
private void processItem ( OdsVdqwMessageOTD item , String statTime , String endTime ) {
log . info ( " 企微语料内容: FromUserId: {}, AcceptUserId: {} " , item . getFromUserId ( ) , item . getAcceptUserId ( ) ) ;
// 1, vdqw_workuserinfo 这个表对应是 B端认证中心userId
// 2, vdqw_externalcontact 这个表对应是 企微客户unionId
String unionId = getUnionId ( Arrays . asList ( item . getFromUserId ( ) , item . getAcceptUserId ( ) ) ) ;
String userId = getUserId ( Arrays . asList ( item . getFromUserId ( ) , item . getAcceptUserId ( ) ) ) ;
log . info ( " 企微查询信息: unionId: {}, userId: {} " , unionId , userId ) ;
if ( StringUtils . isEmpty ( unionId ) | | StringUtils . isNotBlank ( userId ) ) {
log . info ( " 企微查询信息为空 " ) ;
return ;
}
RunMaskingRuleInput runMaskingRuleInput = new RunMaskingRuleInput ( ) ;
runMaskingRuleInput . setDataMaskingRules ( maskingRuleItems ) ;
// 拼接 role 和 text
String chat = contentItem . getFromUserId ( ) . concat ( " : " ) . concat ( content ) ;
runMaskingRuleInput . setOldStr ( chat ) ;
String corpusChat = dataMaskingRuleService . runMaskingRule ( runMaskingRuleInput ) ;
if ( StringUtils . isNotBlank ( item . getFromUserId ( ) ) & & StringUtils . isNotBlank ( item . getAcceptUserId ( ) ) ) {
List < OdsVdqwMessageOTD > contetnList = tmOdsVdqwMessagearchivingMapper . queryOdsVdqwMessageByFromUserIdAndAcceptUserId ( statTime , endTime , Arrays . asList ( item . getFromUserId ( ) , item . getAcceptUserId ( ) ) ) ;
OdsVdqwMessageOTD maxMsgTimeItem = contetnList . stream ( )
. max ( ( o1 , o2 ) - > o1 . getMsgTime ( ) . compareTo ( o2 . getMsgTime ( ) ) )
. orElse ( null ) ;
contetnList . forEach ( contentItem - > {
Map < String , Object > inputMap = new HashMap < > ( ) ;
DiFyReq diFyImageReq = new DiFyReq ( ) ;
diFyImageReq . setUser ( ConstantStr . corpus_user ) ;
diFyImageReq . setFlowId ( qiweiToken ) ;
inputMap . put ( " chat " , corpusChat ) ;
JSONObject contentJson = JSONObject . parseObject ( contentItem . getContent ( ) ) ;
String content = contentJson . getString ( " content " ) ;
List < DataMaskingRule > maskingRuleItems = dataMaskingRuleService . getDataMaskingRuleListByApplicationChannel ( Constant . CHANNEL_DCC ) ;
inputMap . put ( " model " , tmTelephoneCorpusService . getCarModelLis t( ) ) ;
diFyImageReq . setInputs ( inputMap ) ;
RunMaskingRuleInput runMaskingRuleInput = new RunMaskingRuleInpu t( ) ;
runMaskingRuleInput . setDataMaskingRules ( maskingRuleItems ) ;
// 拼接 role 和 text
String chat = contentItem . getFromUserId ( ) . concat ( " : " ) . concat ( content ) ;
runMaskingRuleInput . setOldStr ( chat ) ;
String corpusChat = dataMaskingRuleService . runMaskingRule ( runMaskingRuleInput ) ;
// 获取配置
JSONObject execDifyFlow = diFyService . executeDifyFlow ( diFyImageReq , BusinessTypeEnum . SMART_ASSISTANT . getCode ( ) ) ;
log . info ( " runDify execDifyFlow {} " , execDifyFlow ) ;
if ( null ! = execDifyFlow & & execDifyFlow . get ( " status " ) . equals ( " succeeded " ) ) {
inputMap . put ( " chat " , corpusChat ) ;
String text = execDifyFlow . getJSONObject ( " outputs " ) . getString ( " text " ) ;
String resultStrOne = FlowResultSplitUtil . flowOutputTextSplit ( text , " 任务1 " , " 任务2 " ) ;
String resultStrTwo = FlowResultSplitUtil . flowOutputTextSplit ( text , " 任务2 " , null ) ;
Map < String , String > ltoMap = new HashMap ( ) ;
ltoMap . put ( " analysisRecordId " , execDifyFlow . getString ( " aiAnalysisRequestId " ) ) ;
ltoMap . put ( " analysisScene " , " 1 " ) ;
ltoMap . put ( " unionId " , unionId ) ;
ltoMap . put ( " consultantId " , userId ) ;
ltoMap . put ( " communicateDate " , DateUtil . format ( maxMsgTimeItem . getMsgTime ( ) , DatePattern . NORM_DATETIME_PATTERN ) ) ;
ltoMap . put ( " analysisResult " , resultStrOne ) ;
ltoMap . put ( " analysisDetail " , resultStrTwo ) ;
// 发送MQ
inputMap . put ( " model " , tmTelephoneCorpusService . getCarModelList ( ) ) ;
diFyImageReq . setInputs ( inputMap ) ;
log . info ( " send mq {} " , ltoMap ) ;
rocketMqTemplate . asyncSend ( topic , MessageBuilder . withPayload ( JSON . toJSONString ( ltoMap ) ) . build ( ),
new SendCallback ( ) {
@Override
public void onSuccess ( SendResult sendResult ) {
log . info ( " 企微语料发送MQ成功 消息体:{} " , JSON . toJSONString ( ltoMap ) ) ;
}
@Override
public void onException ( Throwable e ) {
log . error ( " 企微语料发送MQ异常 消息体:{}, 异常: " , JSON . toJSONString ( ltoMap ) , e ) ;
}
} , 10000 ) ;
}
} ) ;
}
} ) ;
// 获取配置
JSONObject execDifyFlow = diFyService . executeDifyFlow ( diFyImageReq , BusinessTypeEnum . SMART_ASSISTANT . getCode ( ) ) ;
log . info ( " runDify execDifyFlow {} " , execDifyFlow ) ;
if ( null ! = execDifyFlow & & execDifyFlow . get ( " status " ) . equals ( " succeeded " ) ) {
String text = execDifyFlow . getJSONObject ( " outputs " ) . getString ( " text " ) ;
String resultStrOne = FlowResultSplitUtil . flowOutputTextSplit ( text , " 任务1 " , " 任务2 " ) ;
String resultStrTwo = FlowResultSplitUtil . flowOutputTextSplit ( text , " 任务2 " , null ) ;
Map < String , String > ltoMap = new HashMap < > ( ) ;
ltoMap . put ( " analysisRecordId " , execDifyFlow . getString ( " aiAnalysisRequestId " ) ) ;
ltoMap . put ( " analysisScene " , " 1 " ) ;
ltoMap . put ( " unionId " , unionId ) ;
ltoMap . put ( " consultantId " , userId ) ;
ltoMap . put ( " communicateDate " , DateUtil . format ( maxMsgTimeItem . getMsgTime ( ) , DatePattern . NORM_DATETIME_PATTERN ) ) ;
ltoMap . put ( " analysisResult " , resultStrOne ) ;
ltoMap . put ( " analysisDetail " , resultStrTwo ) ;
// 发送MQ
log . info ( " send mq {} " , ltoMap ) ;
rocketMqTemplate . asyncSend ( topic , MessageBuilder . withPayload ( JSON . toJSONString ( ltoMap ) ) . build ( ) ,
new SendCallback ( ) {
@Override
public void onSuccess ( SendResult sendResult ) {
log . info ( " 企微语料发送MQ成功 消息体:{} " , JSON . toJSONString ( ltoMap ) ) ;
}
@Override
public void onException ( Throwable e ) {
log . error ( " 企微语料发送MQ异常 消息体:{}, 异常: " , JSON . toJSONString ( ltoMap ) , e ) ;
}
} , 10000 ) ;
}
} ) ;
}
}
private String getUnionId ( List < String > userIds ) {