添加代码 问答功能代码

main
xueqingkun 11 months ago
parent e0845801a2
commit 17fa2255cb

@ -0,0 +1,37 @@
package com.supervision.controller;
import com.supervision.dto.RobotTalkDTO;
import com.supervision.service.RobotTalkService;
import com.supervision.vo.talk.RobotTalkReq;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@Slf4j
@Api(tags = "机器人对话服务")
@RestController
@RequestMapping("/robot")
@RequiredArgsConstructor
public class RobotTalkController {
private final RobotTalkService robotTalkService;
@ApiOperation("机器人对话服务(文字)")
@GetMapping("/textTalk2Robot")
public RobotTalkDTO textTalk2Robot(RobotTalkReq robotTalkReq) {
return robotTalkService.textTalk2Robot(robotTalkReq.getSessionId(), robotTalkReq.getMessage());
}
@ApiOperation("机器人对话服务(语音)")
@GetMapping("/videoTalk2Robot")
public RobotTalkDTO videoTalk2Robot(@RequestParam("file") MultipartFile multipartFile,
@ApiParam("对话id") @RequestParam(value = "sessionId",required = false) String sessionId) {
return robotTalkService.videoTalk2Robot(sessionId, multipartFile);
}
}

@ -1,16 +1,15 @@
package com.supervision.controller;
import com.supervision.domain.IrRobotConfig;
import com.supervision.dto.QueryProcessDTO;
import com.supervision.service.IrRobotConfigService;
import com.supervision.service.QueryTemplateProcessor;
import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List;
@ -32,8 +31,9 @@ public class TestController {
}
@GetMapping("process")
public String process(String templateId,String sessionId) throws TemplateException, IOException {
return queryTemplateProcessor.process(templateId, sessionId);
public String process(String templateId,String sessionId) {
QueryProcessDTO process = queryTemplateProcessor.process(templateId, sessionId);
return process.getStringContent();
}

@ -1,6 +1,5 @@
package com.supervision.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@ -11,7 +10,7 @@ import lombok.Data;
*
* @TableName ir_file
*/
@TableName(value ="ir_file")
@TableName(value ="ir_file",schema = "interro_robot")
@Data
public class IrFile implements Serializable {
/**
@ -28,7 +27,7 @@ public class IrFile implements Serializable {
/**
*
*/
private Object fileByte;
private byte[] fileByte;
/**
*

@ -11,7 +11,7 @@ import lombok.Data;
*
* @TableName ir_voice
*/
@TableName(value ="ir_voice")
@TableName(value ="ir_voice",schema = "interro_robot")
@Data
public class IrVoice implements Serializable {
/**

@ -0,0 +1,85 @@
package com.supervision.dto;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import java.util.List;
import java.util.Objects;
@Data
@Builder
public class QueryProcessDTO {
/**
* 0 1 2
*/
private Integer state;
/**
* 1-2-3-4-5-
*/
private Integer contentType;
/**
*
*/
private String stringContent;
/**
*
*/
private byte[] byteContent;
/**
*
*/
private List<ParamCheckDTO> paramCheckList;
/**
*
* @param paramName
* @param value
* @param errorMsgTemplate
* @param <T>
*/
public <T> void notNullParam(String paramName, T value, String errorMsgTemplate){
if(Objects.isNull(value)){
this.state = 1;
this.paramCheckList.add(new ParamCheckDTO(paramName, errorMsgTemplate,1));
}
}
/**
*
* @param paramName
* @param value
* @param errorMsgTemplate
* @param <T>
*/
public <T extends CharSequence> void notEmptyParam(String paramName, T value, String errorMsgTemplate){
if(StrUtil.isEmpty(value)){
this.state = 1;
this.paramCheckList.add(new ParamCheckDTO(paramName, errorMsgTemplate,2));
}
}
@Data
@AllArgsConstructor
static class ParamCheckDTO {
private String paramName;
private String paramDesc;
/**
* 1 2 3
*/
private Integer errorType;
}
}

@ -0,0 +1,51 @@
package com.supervision.dto;
import lombok.Data;
/**
* DTO
*/
@Data
public class RobotTalkDTO {
/**
* id
*/
private String sessionId;
/**
* id
*/
private String askId;
/**
* 1-2-3-4-5-
*/
private Integer askContentType;
/**
*
*/
private String askMessage;
/**
* 1-2-3-4-5-
*/
private Integer answerContentType;
/**
*
*/
private String answerMessage;
/**
* id
*/
private String answerVoiceBaseId;
/**
* id
*/
private String answerByteId;
}

@ -1,8 +1,7 @@
package com.supervision.service;
import freemarker.template.TemplateException;
import com.supervision.dto.QueryProcessDTO;
import java.io.IOException;
/**
*
@ -15,9 +14,7 @@ public interface QueryTemplateProcessor {
* @param templateId id
* @param sessionId id
* @return
* @throws TemplateException
* @throws IOException
*/
String process(String templateId,String sessionId) throws TemplateException, IOException;
QueryProcessDTO process(String templateId, String sessionId);
}

@ -0,0 +1,12 @@
package com.supervision.service;
import com.supervision.dto.RobotTalkDTO;
import org.springframework.web.multipart.MultipartFile;
public interface RobotTalkService {
RobotTalkDTO textTalk2Robot(String sessionId, String message);
RobotTalkDTO videoTalk2Robot(String sessionId, MultipartFile multipartFile);
}

@ -1,6 +1,8 @@
package com.supervision.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
@ -76,8 +78,9 @@ public class MatchToolServiceImpl implements MatchToolService {
public List<MatchQuestionAnswerDTO> execMatch(String question) {
log.info("开始调用talkQaSimilarity,问题:{}", question);
try {
TimeInterval timer = DateUtil.timer();
String post = HttpUtil.post(matchToolUrl + "/matchQuestion", JSONUtil.toJsonStr(new QuestionReqDTO(question, Double.valueOf(scoreThreshold))));
log.info("相似度匹配答案:{}", post);
log.info("相似度匹配答案:{},耗时:{} 毫秒", post,timer.intervalMs());
TypeReference<GlobalResult<List<MatchQuestionAnswerDTO>>> globalResultTypeReference = new TypeReference<GlobalResult<List<MatchQuestionAnswerDTO>>>() {
};
GlobalResult<List<MatchQuestionAnswerDTO>> result = JSONUtil.toBean(post, globalResultTypeReference.getType(), true);

@ -2,9 +2,11 @@ package com.supervision.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.supervision.domain.IrKnowledge;
import com.supervision.domain.IrSessionParam;
import com.supervision.domain.IrSqlParam;
import com.supervision.dto.QueryProcessDTO;
import com.supervision.service.IrKnowledgeService;
import com.supervision.service.IrSessionParamService;
import com.supervision.service.IrSqlParamService;
@ -16,6 +18,8 @@ import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.util.*;
@ -34,43 +38,91 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
private final RowSqlMapper rowSqlMapper;
@Override
public String process(String templateId,String sessionId) throws TemplateException, IOException {
//note:重新构建一个事务,与调用方事务隔离
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public QueryProcessDTO process(String templateId, String sessionId) {
Assert.notEmpty(templateId, "模板ID不能为空");
// 根据模板ID查询查询sql模板和结果模板
IrKnowledge knowledge = knowledgeService.getById(templateId);
Assert.notNull(knowledge, "知识不存在!");
Assert.notEmpty(knowledge.getSqlTemplate(), "模板内容不能为空");
Assert.notEmpty(knowledge.getResultTemplate(), "结果模板不能为空");
Assert.notNull(knowledge.getResultType(), "结果类型不能为空");
// 查询必填的参数
List<IrSqlParam> paramsList = sqlParamService.lambdaQuery().eq(IrSqlParam::getKnowledgeId, templateId).list();
// 校验必要参数
QueryProcessDTO queryProcessDTO = QueryProcessDTO.builder().state(0).build();
queryProcessDTO.notNullParam(null, knowledge, "未查询到意图信息");
queryProcessDTO.notEmptyParam("sqlTemplate", knowledge.getSqlTemplate(), "模板内容不能为空");
queryProcessDTO.notEmptyParam("resultTemplate", knowledge.getResultTemplate(), "结果模板不能为空");
queryProcessDTO.notNullParam("resultType", knowledge.getResultType(), "结果类型不能为空");
if (Integer.valueOf(1).equals(queryProcessDTO.getState())) {
// 参数校验不通过,返回结果
return queryProcessDTO;
}
// 校验必填参数
// 查询知识查询sql需要的参数
List<IrSqlParam> paramsList = sqlParamService.lambdaQuery().eq(IrSqlParam::getKnowledgeId, templateId).list();
// 校验知识查询sql必填参数
List<IrSessionParam> sessionParams = sessionParamService.lambdaQuery().eq(IrSessionParam::getSessionId, sessionId).list();
Set<String> sessionParamsNames = sessionParams.stream().map(IrSessionParam::getParamName).collect(Collectors.toSet());
paramsList.stream().filter(param -> Integer.valueOf(1).equals(param.getParamRequire()))
.forEach(param -> Assert.isTrue(sessionParamsNames.contains(param.getParamName()), "参数["+param.getParamName()+"]未设置!"));
paramsList.stream().filter(param -> Integer.valueOf(1).equals(param.getParamRequire())).forEach(param -> {
queryProcessDTO.notNullParam(param.getParamName(),
sessionParamsNames.contains(param.getParamName()) ? true : null, "参数[" + param.getParamName() + "]未设置!");
});
if (Integer.valueOf(1).equals(queryProcessDTO.getState())) {
// 参数校验不通过,返回结果
return queryProcessDTO;
}
// 执行查询sql
List<Map<String, Object>> maps = rowSqlMapper.selectList(knowledge.getSqlTemplate(), getParams(paramsList, sessionParams));
List<Map<String, Object>> maps = null;
try {
maps = rowSqlMapper.selectList(knowledge.getSqlTemplate(), getParams(paramsList, sessionParams));
} catch (Exception e) {
log.error("执行查询sql失败", e);
queryProcessDTO.setState(2);
return queryProcessDTO;
}
// 组装返回结果
if (Integer.valueOf(1).equals(knowledge.getResultType())){
return StringTemplateConfig.getInstance().process(knowledge.getResultTemplate(), CollUtil.getFirst(maps));
wrapperSqlResult(knowledge, maps, queryProcessDTO);
return queryProcessDTO;
}
private void wrapperSqlResult(IrKnowledge knowledge, List<Map<String, Object>> maps, QueryProcessDTO queryProcessDTO) {
if (Integer.valueOf(1).equals(knowledge.getResultType())) {
try {
String process = StringTemplateConfig.getInstance().process(knowledge.getResultTemplate(), CollUtil.getFirst(maps));
queryProcessDTO.setStringContent(process);
queryProcessDTO.setContentType(1);
} catch (IOException | TemplateException e) {
log.error("执行结果模板失败", e);
queryProcessDTO.setState(2);
}
}
if (Integer.valueOf(2).equals(knowledge.getResultType())){
return StringTemplateConfig.getInstance().process(knowledge.getResultTemplate(), maps);
if (Integer.valueOf(2).equals(knowledge.getResultType())) {
try {
String process = StringTemplateConfig.getInstance().process(knowledge.getResultTemplate(), maps);
queryProcessDTO.setStringContent(process);
queryProcessDTO.setContentType(1);
} catch (IOException | TemplateException e) {
log.error("执行结果模板失败", e);
queryProcessDTO.setState(2);
}
}
// todo:字节类型暂不支持
if (Integer.valueOf(3).equals(knowledge.getResultType())){
return null;
if (Integer.valueOf(3).equals(knowledge.getResultType())) {
// 如果存在byte类型的数据数据key统一命名为 byteContent
queryProcessDTO.setByteContent((byte[]) CollUtil.getFirst(maps).get("byteContent"));
queryProcessDTO.setContentType(3);
}
// 去除回响应字符串中的特殊字符
if (StrUtil.isNotEmpty(queryProcessDTO.getStringContent())){
queryProcessDTO.setStringContent(StrUtil.cleanBlank(queryProcessDTO.getStringContent()));
}
return null;
}
private Map<String, Object> getParams(List<IrSqlParam> paramsList, List<IrSessionParam> sessionParams) {
Map<String, Object> params = new HashMap<>();
ParamTypeConverter converter = ParamTypeConverter.getInstance();

@ -0,0 +1,179 @@
package com.supervision.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.supervision.domain.IrFile;
import com.supervision.domain.IrRobotConfig;
import com.supervision.domain.IrSessionHistory;
import com.supervision.domain.IrVoice;
import com.supervision.dto.MatchQuestionAnswerDTO;
import com.supervision.dto.QueryProcessDTO;
import com.supervision.dto.RobotTalkDTO;
import com.supervision.service.*;
import com.supervision.util.UserUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service
@RequiredArgsConstructor
public class RobotTalkServiceImpl implements RobotTalkService {
private final QueryTemplateProcessor queryTemplateProcessor;
private final MatchToolService matchToolService;
private final VoiceService voiceService;
private final IrRobotConfigService irRobotConfigService;
private final IrSessionHistoryService sessionService;
private final IrVoiceService irVoiceService;
private final IrFileService irFileService;
@Override
@Transactional(rollbackFor = Exception.class)
public RobotTalkDTO textTalk2Robot(String sessionId, String message) {
Assert.notEmpty(sessionId, "sessionId不能为空");
TimeInterval timeInterval = new TimeInterval();
timeInterval.start("all");
log.info("textTalk2Robot:开始问答,sessionId:{},message:{}",sessionId,message);
RobotTalkDTO robotTalkDTO = new RobotTalkDTO();
robotTalkDTO.setSessionId(sessionId);
robotTalkDTO.setAskMessage(message);
// 设置问答类型为文本
robotTalkDTO.setAskContentType(1);
robotTalkDTO.setAnswerContentType(2);
List<MatchQuestionAnswerDTO> matchQuestionAnswerDTOS = null;
if (StrUtil.isNotEmpty(message)){
// 如果消息为空,则没必要进行意图匹配
try {
matchQuestionAnswerDTOS = matchToolService.execMatch(message);
log.info("问题:{} 匹配到的意图:{}",message, JSONUtil.toJsonStr(matchQuestionAnswerDTOS));
} catch (Exception e) {
log.error("textTalk2Robot:内容:{} 相似度匹配失败",message,e);
}
}
// 获取机器人配置
IrRobotConfig config = irRobotConfigService.lambdaQuery().one();
String answerText = null;
if (CollUtil.isEmpty(matchQuestionAnswerDTOS)){
// 未匹配到查询意图,设置默认错误语
log.info("问题:{}未匹配到意图",message);
answerText = config.getErrorLanguage();
robotTalkDTO.setAnswerMessage(config.getErrorLanguage());
}
// 匹配到查询意图,用第一个意图
QueryProcessDTO process = QueryProcessDTO.builder().state(2).build();
MatchQuestionAnswerDTO matchQuestionAnswerDTO = CollUtil.getFirst(matchQuestionAnswerDTOS);
if (Objects.nonNull(matchQuestionAnswerDTO)){
process = queryTemplateProcessor.process(matchQuestionAnswerDTO.getMatchQuestionCode(), sessionId);
}
// 查询结果类型为字节数组
if (Integer.valueOf(0).equals(process.getState()) &&
Integer.valueOf(3).equals(process.getContentType())){
// 返回的结果是字节,保存到文件表
IrFile irFile = process2File(process);
irFileService.save(irFile);
robotTalkDTO.setAnswerContentType(3);
robotTalkDTO.setAnswerByteId(irFile.getId());
}else {
answerText = decideAnswer(process, config);
}
// 组装日志信息
IrSessionHistory irSessionHistory = talk2SessionHistory(sessionId, message,
CollUtil.getFirst(matchQuestionAnswerDTOS));
// todo:语音倍速设置
// 保存回答音频文件
if (StrUtil.isNotEmpty(answerText)){
String audioBase = voiceService.textToVoice(answerText);
IrVoice irVoice = new IrVoice();
irVoice.setVoiceBase64(audioBase);
irVoiceService.save(irVoice);
robotTalkDTO.setAnswerVoiceBaseId(irVoice.getId());
irSessionHistory.setAnswerVoiceId(irVoice.getId());
}
// 写入对话日志
sessionService.save(irSessionHistory);
robotTalkDTO.setAnswerMessage(answerText);
robotTalkDTO.setAskId(irSessionHistory.getId());
log.info("textTalk2Robot:结束问答,耗时:{}ms",timeInterval.interval("all"));
return robotTalkDTO;
}
private static String decideAnswer(QueryProcessDTO process, IrRobotConfig config) {
// 正确查询出结果
if (Integer.valueOf(0).equals(process.getState())
&& Integer.valueOf(1).equals(process.getContentType())){
// 查询结果类型为字符串
return process.getStringContent();
}
// 参数异常或查询结果异常
if (Integer.valueOf(1).equals(process.getState())
|| Integer.valueOf(2).equals(process.getState())){
return config.getUnrecognizedOne();
}
return null;
}
private static IrFile process2File(QueryProcessDTO process) {
byte[] byteContent = process.getByteContent();
IrFile irFile = new IrFile();
irFile.setFileByte(byteContent);
irFile.setFileSize(byteContent.length);
irFile.setFileName("answer");
irFile.setFileType("F");
return irFile;
}
private IrSessionHistory talk2SessionHistory(String sessionId, String message,
MatchQuestionAnswerDTO matchQuestionAnswerDTO) {
IrSessionHistory sessionHistory = new IrSessionHistory();
sessionHistory.setSessionId(sessionId);
sessionHistory.setUserQuestion(message);
sessionHistory.setCreateUserId(UserUtil.getUser().getId());
if (Objects.nonNull(matchQuestionAnswerDTO)){
sessionHistory.setMatchKnowledgeId(matchQuestionAnswerDTO.getMatchQuestionCode());
sessionHistory.setThreshold(BigDecimal.valueOf(matchQuestionAnswerDTO.getMatchScore()));
}
return sessionHistory;
}
@Override
@Transactional(rollbackFor = Exception.class)
public RobotTalkDTO videoTalk2Robot(String sessionId, MultipartFile multipartFile) {
Assert.notEmpty(sessionId, "sessionId不能为空");
Assert.notNull(multipartFile, "multipartFile不能为空");
String message = null;
try {
message = voiceService.voiceToText(multipartFile, sessionId);
} catch (IOException e) {
log.error("语音转文字失败", e);
}
RobotTalkDTO robotTalkDTO = this.textTalk2Robot(sessionId, message);
robotTalkDTO.setAskContentType(2);
return robotTalkDTO;
}
}

@ -1,12 +1,10 @@
package com.supervision.service.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.supervision.service.VoiceService;
import com.supervision.util.AsrUtil;
import com.supervision.util.TtsUtil;
import com.supervision.vo.voice.VoiceReqVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -22,13 +20,19 @@ public class VoiceServiceImpl implements VoiceService {
@Override
public String voiceToText(MultipartFile file, String sessionId) throws IOException {
log.info("语音转文字开始");
return AsrUtil.asrTransformByBytes(file.getBytes());
TimeInterval timeInterval = DateUtil.timer();
String transform = AsrUtil.asrTransformByBytes(file.getBytes());
log.info("语音转文字结束,耗时:{}", timeInterval.interval());
return transform;
}
@Override
public String textToVoice(String text) {
log.info("文字转语音开始");
return TtsUtil.ttsTransform(text);
TimeInterval timeInterval = DateUtil.timer();
String transform = TtsUtil.ttsTransform(text);
log.info("文字转语音结束,耗时:{}", timeInterval.interval());
return transform;
}
}

@ -58,14 +58,14 @@ public class StringTemplateConfig {
return true;
}
public String process(String content, List<Map<String, Object>> data) throws IOException, TemplateException {
public <T extends List<Map<String, Object>>> String process(String content, List<Map<String, Object>> data) throws IOException, TemplateException {
Map<String, Object> dataModel = new HashMap<String, Object>(){};
dataModel.put("dataList", data);
return process(content, dataModel);
}
public String process(String content, Map<String, Object> dataModel) throws IOException, TemplateException {
public <T extends Map<String, Object>> String process(String content, Map<String, Object> dataModel) throws IOException, TemplateException {
log.info("StringTemplateConfig.process:入参data:{} , content:{}", JSONUtil.toJsonStr(dataModel),content);

@ -0,0 +1,11 @@
package com.supervision.vo.talk;
import lombok.Data;
@Data
public class RobotTalkReq {
private String sessionId;
private String message;
}

@ -7,7 +7,7 @@
<resultMap id="BaseResultMap" type="com.supervision.domain.IrFile">
<id property="id" column="id" jdbcType="VARCHAR"/>
<result property="fileName" column="file_name" jdbcType="VARCHAR"/>
<result property="fileByte" column="file_byte" jdbcType="OTHER"/>
<result property="fileByte" column="file_byte" jdbcType="BINARY"/>
<result property="fileType" column="file_type" jdbcType="VARCHAR"/>
<result property="fileSize" column="file_size" jdbcType="INTEGER"/>
</resultMap>

@ -6,7 +6,7 @@
<resultMap id="BaseResultMap" type="com.supervision.domain.IrVoice">
<id property="id" column="id" jdbcType="VARCHAR"/>
<result property="voiceBase64" column="voice_base_64" jdbcType="VARCHAR"/>
<result property="voiceBase64" column="voice_base64" jdbcType="VARCHAR"/>
<result property="length" column="length" jdbcType="INTEGER"/>
</resultMap>

@ -1,5 +1,8 @@
package com.supervision;
import com.supervision.domain.IrFile;
import com.supervision.dto.QueryProcessDTO;
import com.supervision.service.IrFileService;
import com.supervision.service.IrKnowledgeService;
import com.supervision.service.QueryTemplateProcessor;
import com.supervision.util.mybatis.RowSqlMapper;
@ -96,13 +99,29 @@ class AskApplicationTests {
@Autowired
private QueryTemplateProcessor queryTemplateProcessor;
@Test
void QueryTemplateProcessorProcessTest() throws IOException, TemplateException {
void QueryTemplateProcessorProcessTest() {
String process = queryTemplateProcessor.process("1770984442920292354","123");
QueryProcessDTO process = queryTemplateProcessor.process("1770984442920292354", "123");
System.out.println(process);
}
@Autowired
private IrFileService irFileService;
@Test
void fileByteSaveTest() {
IrFile irFile = new IrFile();
irFile.setFileName("ddd");
irFile.setFileType("dddaa");
irFile.setFileSize(100);
irFile.setFileByte("ddd".getBytes());
irFileService.save(irFile);
}
@Test
void fileByteGetTest() {
IrFile byId = irFileService.getById("1772822158139199490");
System.out.println(byId.getFileName());
}
}

Loading…
Cancel
Save