语音指令
This commit is contained in:
parent
2445287f8c
commit
a23bf72997
@ -10,8 +10,6 @@ import club.joylink.rtss.services.voice.IVoiceDataService;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.operate.HandleType;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.operate.OperateEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.VoiceConfigData;
|
||||
import club.joylink.rtss.util.JsonUtils;
|
||||
import club.joylink.rtss.vo.LoginUserInfoVO;
|
||||
import club.joylink.rtss.vo.client.PageVO;
|
||||
import club.joylink.rtss.vo.voice.VoiceConfigVO;
|
||||
@ -50,8 +48,8 @@ public class VoiceDataService implements IVoiceDataService, IVoiceCommandDataSer
|
||||
|
||||
private void checkData(VoiceConfigVO dataVO){
|
||||
BusinessExceptionAssertEnum.DATA_INVALID.assertTrue(Objects.nonNull(dataVO.getWakeUpKw()),String.format("缺少类型匹配"));
|
||||
BusinessExceptionAssertEnum.DATA_INVALID.assertTrue(ArrayUtils.isNotEmpty(dataVO.getWakeUpKw().getSourceMatch()),String.format("类型匹配需要关键字"));
|
||||
OperateConfigData configData = dataVO.getConfig().stream().filter(d->ArrayUtils.isEmpty(d.getSourceMatch())).findFirst().orElse(null);
|
||||
BusinessExceptionAssertEnum.DATA_INVALID.assertTrue(ArrayUtils.isNotEmpty(dataVO.getWakeUpKw().getActionMatch()),String.format("类型匹配需要关键字"));
|
||||
OperateConfigData configData = dataVO.getConfig().stream().filter(d->ArrayUtils.isEmpty(d.getActionMatch())).findFirst().orElse(null);
|
||||
BusinessExceptionAssertEnum.DATA_INVALID.assertNotTrue(Objects.nonNull(configData),String.format("操作数据关键字不能为空"));
|
||||
Map<OperateEnum,List<OperateConfigData>> mapList = dataVO.getConfig().stream().collect(Collectors.groupingBy(OperateConfigData::getOperate));
|
||||
for (List<OperateConfigData> value : mapList.values()) {
|
||||
|
@ -8,10 +8,13 @@ import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.WorkResult;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.work.VoiceCommandAnalyseWork;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.util.PinYinUtil;
|
||||
import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult;
|
||||
import club.joylink.rtss.vo.voice.VoiceConfigVO;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ansj.library.DicLibrary;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@ -38,6 +41,7 @@ public class DeviceVoiceCommandService{
|
||||
private VoiceCommandAnalyseWork analyseWork;
|
||||
|
||||
private List<VoiceConfigVO> findVoiceConfig(Simulation simulation){
|
||||
|
||||
Long mapId = simulation.getBuildParams().getMap().getId();
|
||||
List<VoiceConfigVO> configVOList = this.commandDataService.findData(mapId);
|
||||
BusinessExceptionAssertEnum.VOICE_COMMAND_CONFIG_NULL.assertTrue(!CollectionUtils.isEmpty(configVOList),"未找到语音配置的相关信息");
|
||||
|
@ -7,6 +7,7 @@ import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -19,8 +20,10 @@ public class VoiceCommandMatchHandler {
|
||||
public List<DeviceVoiceCommand> matcher(List<VoiceConfigVO> configVOList, String msg){
|
||||
List<DeviceVoiceCommand> findParseDataList = Lists.newArrayList();
|
||||
for (VoiceConfigVO configVO : configVOList) {
|
||||
Optional<List<DeviceVoiceCommand>> optional = commandMatcher.matchCommand(configVO,msg);
|
||||
optional.ifPresent(findParseDataList::addAll);
|
||||
List<DeviceVoiceCommand> commandList = commandMatcher.matchCommand(configVO,msg);
|
||||
if(!CollectionUtils.isEmpty(commandList)){
|
||||
findParseDataList.addAll(commandList);
|
||||
}
|
||||
}
|
||||
return findParseDataList;
|
||||
}
|
||||
|
@ -1,54 +1,86 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.analyse;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.operate.HandleType;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.util.PinYinUtil;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.ansj.domain.Result;
|
||||
import org.ansj.domain.Term;
|
||||
import org.ansj.library.DicLibrary;
|
||||
import org.ansj.splitWord.analysis.DicAnalysis;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class PinYinSplitWordAnalyse implements VoiceCommandAnalyse {
|
||||
@Override
|
||||
public synchronized List<String> parseCommandDescribe(DeviceVoiceCommand command) {
|
||||
this.initDic(command);
|
||||
String pinyinStr = PinYinUtil.toPinYinSplitBlankSpace(command.getSourceDescrbe());
|
||||
|
||||
@Override
|
||||
public synchronized CommandParse parseCommandDescribe(Simulation simulation, DeviceVoiceCommand command) {
|
||||
this.initDic(simulation,command);
|
||||
String pinyinStr = PinYinUtil.toPinYinSplitBlankSpace(command.getSourceDescrbe());
|
||||
Result reslut = DicAnalysis.parse(pinyinStr);
|
||||
List<String> resultList = Lists.newArrayList();
|
||||
List<ParseDetail> resultList = Lists.newArrayList();
|
||||
CommandParse commandParse = new CommandParse(command.getSourceDescrbe(),pinyinStr);
|
||||
commandParse.setDetail(resultList);
|
||||
for (Term term : reslut) {
|
||||
String name = term.getName().toUpperCase();
|
||||
String nature = term.getNatureStr();
|
||||
if(Objects.nonNull(nature) && !StringUtils.startsWith(nature,"w")){
|
||||
if(!StringUtils.equalsIgnoreCase(nature,"userDefine")){
|
||||
// command.appendCommandDescribe(name);
|
||||
resultList.add(name);
|
||||
}/*else{
|
||||
command.appendCommandDescribe(name);
|
||||
}*/
|
||||
if(Objects.nonNull(nature) && StringUtils.isNotEmpty(name) && !StringUtils.startsWith(nature,"w")){
|
||||
if(!StringUtils.equalsIgnoreCase(nature,DicLibrary.DEFAULT_NATURE)){
|
||||
resultList.add(new ParseDetail(name,nature,term.getOffe(), term.toValue()));
|
||||
}
|
||||
// commandList.add(command);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
return commandParse;
|
||||
}
|
||||
|
||||
/* @Override
|
||||
public HandleType handleType() {
|
||||
return HandleType.PINYIN;
|
||||
}*/
|
||||
|
||||
private void initDic(DeviceVoiceCommand command){
|
||||
|
||||
private void initDic(Simulation simulation,DeviceVoiceCommand command){
|
||||
DicLibrary.clear(DicLibrary.DEFAULT);
|
||||
for (Station station : simulation.getRepository().getStationList()) {
|
||||
String pinYinTmp = PinYinUtil.toPinYinSplitBlankSpace(station.getName()).toLowerCase();
|
||||
List<String> pinyin = Splitter.onPattern("\\s").omitEmptyStrings().splitToList(pinYinTmp);
|
||||
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,pinYinTmp,VoiceCommandAnalyse.DESCRIBE_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
List<List<String>> subPinYinList = Lists.partition(pinyin,2);
|
||||
for (List<String> strings : subPinYinList) {
|
||||
String t = Joiner.on(" ").skipNulls().join(strings);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,t,VoiceCommandAnalyse.DESCRIBE_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
}
|
||||
subPinYinList = Lists.partition(pinyin,3);
|
||||
for (List<String> strings : subPinYinList) {
|
||||
String t = Joiner.on(" ").skipNulls().join(strings);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,t,VoiceCommandAnalyse.DESCRIBE_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (String s : command.getTranslateWakeUpKW()) {
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,s,DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,s.toLowerCase(),DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
}
|
||||
for (String s : command.getMatchCommandKW()) {
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,s,DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
|
||||
for (String s : command.getOperateConfigData().getTranslateActionMatch()) {
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,s.toLowerCase(),DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
}
|
||||
|
||||
if(ArrayUtils.isNotEmpty(command.getOperateConfigData().getTranslateNatureKW())){
|
||||
for (String s : command.getOperateConfigData().getTranslateNatureKW()) {
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,s.toLowerCase(),VoiceCommandAnalyse.DESCRIBE_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
}
|
||||
}
|
||||
|
||||
/* if(ArrayUtils.isNotEmpty(command.getOperateConfigData().getTranslateDescribeKW())){
|
||||
for (String s : command.getOperateConfigData().getTranslateDescribeKW()) {
|
||||
DicLibrary.insert(DicLibrary.DEFAULT,s.toLowerCase(),DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.analyse;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface VoiceCommandAnalyse {
|
||||
|
||||
String DESCRIBE_NATURE = "nature";
|
||||
/**
|
||||
* 解析命令
|
||||
* @param Command 命令原文
|
||||
* @return 解析后的数据
|
||||
*/
|
||||
List<String> parseCommandDescribe(DeviceVoiceCommand Command);
|
||||
CommandParse parseCommandDescribe(Simulation simulation, DeviceVoiceCommand Command);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.match;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.vo.voice.VoiceConfigVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface IMatchFilter {
|
||||
List<DeviceVoiceCommand> filter();
|
||||
|
||||
Optional<List<DeviceVoiceCommand>> matchCommand(VoiceConfigVO configVOList, String msg);
|
||||
|
||||
}
|
@ -1,15 +1,13 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.match;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.operate.HandleType;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.vo.voice.VoiceConfigVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface IVoiceCommandMatcher {
|
||||
|
||||
|
||||
Optional<List<DeviceVoiceCommand>> matchCommand(VoiceConfigVO configVOList, String msg);
|
||||
List<DeviceVoiceCommand> matchCommand(VoiceConfigVO configVOList, String msg);
|
||||
// HandleType handleType();
|
||||
}
|
||||
|
@ -4,43 +4,48 @@ import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData;
|
||||
import club.joylink.rtss.util.PinYinUtil;
|
||||
import club.joylink.rtss.vo.voice.VoiceConfigVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class PinYinViolenceMatchHandler implements IVoiceCommandMatcher {
|
||||
@Override
|
||||
public Optional<List<DeviceVoiceCommand>> matchCommand(VoiceConfigVO configVO, String sourceMsg) {
|
||||
public List<DeviceVoiceCommand> matchCommand(VoiceConfigVO configVO, String sourceMsg) {
|
||||
String tmpPinYinContent = PinYinUtil.toPinYinSplitBlankSpace(sourceMsg);
|
||||
List<DeviceVoiceCommand> commandList = this.match(configVO,sourceMsg,tmpPinYinContent);
|
||||
commandList = commandList.stream().filter(d->Objects.nonNull(d.getDeviceType())
|
||||
&& ArrayUtils.isNotEmpty(d.getMatchCommandKW())
|
||||
&& Objects.nonNull(d.getOperateConfigData())
|
||||
&& ArrayUtils.isNotEmpty(d.getTranslateWakeUpKW())
|
||||
).collect(Collectors.toList());
|
||||
if(CollectionUtils.isEmpty(commandList)){
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(commandList);
|
||||
return commandList;
|
||||
}
|
||||
|
||||
private List<DeviceVoiceCommand> match(VoiceConfigVO configVO,String sourceMsg, String pinyinStr){
|
||||
List<DeviceVoiceCommand> commandList = new ArrayList<>();
|
||||
for (OperateConfigData configData : configVO.getConfig()) {
|
||||
DeviceVoiceCommand command = new DeviceVoiceCommand(configVO.getHandleType());
|
||||
if(StringUtils.containsAny(pinyinStr,configVO.getWakeUpKw().getTranslateMatch())){
|
||||
if(StringUtils.containsAny(pinyinStr,configVO.getWakeUpKw().getTranslateActionMatch())){
|
||||
command.setDeviceType(configVO.getDeviceType());
|
||||
command.setTranslateWakeUpKW(configVO.getWakeUpKw().getTranslateMatch());
|
||||
command.setTranslateWakeUpKW(configVO.getWakeUpKw().getTranslateActionMatch());
|
||||
}
|
||||
if(StringUtils.containsAny(pinyinStr,configData.getTranslateMatch())){
|
||||
if(StringUtils.containsAny(pinyinStr,configData.getTranslateActionMatch())){
|
||||
if(configData.isForceMatchNature()){
|
||||
if(ArrayUtils.isEmpty(configData.getTranslateNatureKW())){
|
||||
log.error("强制匹配属性,但是属性为空 config id[{}]",configVO.getId());
|
||||
return Collections.emptyList();
|
||||
}else if(StringUtils.containsAny(pinyinStr,configData.getTranslateNatureKW())){
|
||||
command.setOperateConfigData(configData);
|
||||
command.setMatchCommandKW(configData.getTranslateMatch());
|
||||
}
|
||||
}else{
|
||||
command.setOperateConfigData(configData);
|
||||
}
|
||||
}
|
||||
command.setSourceDescrbe(sourceMsg);
|
||||
commandList.add(command);
|
||||
|
@ -1,12 +0,0 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.operate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public enum OperateDeviceEnum {
|
||||
SWITCH();
|
||||
private OperateEnum[] operates;
|
||||
|
||||
OperateDeviceEnum(OperateEnum... operates) {
|
||||
this.operates = operates;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.operate;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiSwitchControlService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
@ -11,24 +12,69 @@ import lombok.Getter;
|
||||
public enum OperateEnum {
|
||||
SWITCH_DINGWEI(MapElement.DeviceType.SWITCH,"定位"){
|
||||
@Override
|
||||
public void handle(Simulation simulation,CiSwitchControlService service, MapElement device) {
|
||||
public void handle(Simulation simulation,Object objectService, MapElement device) {
|
||||
Switch aswitch = (Switch)device;
|
||||
service.turn2NormalPosition(simulation,aswitch);
|
||||
CiSwitchControlService controlService = (CiSwitchControlService) objectService;
|
||||
controlService.turn2NormalPosition(simulation,aswitch);
|
||||
}
|
||||
},
|
||||
SWITCH_FANWEI(MapElement.DeviceType.SWITCH,"反位"){
|
||||
@Override
|
||||
public void handle(Simulation simulation, CiSwitchControlService service, MapElement device) {
|
||||
public void handle(Simulation simulation, Object objectService, MapElement device) {
|
||||
Switch aswitch = (Switch)device;
|
||||
service.turn2ReversePosition(simulation,aswitch);
|
||||
CiSwitchControlService controlService = (CiSwitchControlService) objectService;
|
||||
controlService.turn2ReversePosition(simulation,aswitch);
|
||||
}
|
||||
},
|
||||
STAND_HOLD_TRAIN(MapElement.DeviceType.STAND,"扣车"){
|
||||
@Override
|
||||
public void handle(Simulation simulation, Object objectService, MapElement device) {
|
||||
AtsStandService standService = (AtsStandService) objectService;
|
||||
standService.holdTrain(simulation,device.getCode());
|
||||
}
|
||||
},
|
||||
STAND_CANCEL_HOLD_TRAIN(MapElement.DeviceType.STAND,"取消扣车"){
|
||||
@Override
|
||||
public void handle(Simulation simulation, Object objectService, MapElement device) {
|
||||
AtsStandService standService = (AtsStandService) objectService;
|
||||
standService.cancelHoldTrain(simulation,device.getCode());
|
||||
}
|
||||
},
|
||||
STAND_UP_HOLD_TRAIN(MapElement.DeviceType.STAND,"上行扣车"){
|
||||
@Override
|
||||
public void handle(Simulation simulation, Object objectService, MapElement device) {
|
||||
AtsStandService standService = (AtsStandService) objectService;
|
||||
standService.holdTrain(simulation,device.getCode());
|
||||
}
|
||||
},
|
||||
STAND_DOWN_HOLD_TRAIN(MapElement.DeviceType.STAND,"下行扣车"){
|
||||
@Override
|
||||
public void handle(Simulation simulation, Object objectService, MapElement device) {
|
||||
AtsStandService standService = (AtsStandService) objectService;
|
||||
standService.holdTrain(simulation,device.getCode());
|
||||
}
|
||||
},
|
||||
STAND_CANCEL_UP_HOLD_TRAIN(MapElement.DeviceType.STAND,"上行取消扣车"){
|
||||
@Override
|
||||
public void handle(Simulation simulation, Object objectService, MapElement device) {
|
||||
AtsStandService standService = (AtsStandService) objectService;
|
||||
standService.cancelHoldTrain(simulation,device.getCode());
|
||||
}
|
||||
},
|
||||
STAND_CANCEL_DOWN_HOLD_TRAIN(MapElement.DeviceType.STAND,"下行取消扣车"){
|
||||
@Override
|
||||
public void handle(Simulation simulation, Object objectService, MapElement device) {
|
||||
AtsStandService standService = (AtsStandService) objectService;
|
||||
standService.cancelHoldTrain(simulation,device.getCode());
|
||||
}
|
||||
},
|
||||
|
||||
;
|
||||
private MapElement.DeviceType deviceType;
|
||||
@Getter
|
||||
private String describe;
|
||||
|
||||
public abstract void handle(Simulation simulation,CiSwitchControlService service, MapElement device);
|
||||
public abstract void handle(Simulation simulation,Object objectService, MapElement device);
|
||||
|
||||
OperateEnum(MapElement.DeviceType deviceType, String describe) {
|
||||
this.deviceType = deviceType;
|
||||
|
@ -0,0 +1,31 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class CommandParse {
|
||||
private String descrbeCommand;
|
||||
private String translateDescrbeCommand;
|
||||
|
||||
private List<ParseDetail> detail;
|
||||
|
||||
public CommandParse(String descrbeCommand, String translateDescrbeCommand) {
|
||||
this.descrbeCommand = descrbeCommand;
|
||||
this.translateDescrbeCommand = translateDescrbeCommand;
|
||||
}
|
||||
|
||||
public List<ParseDetail> findNatureDetail(String nature){
|
||||
return this.detail.stream().filter(d-> StringUtils.equalsIgnoreCase(d.getNature(), nature)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<ParseDetail> findNotNatureDetail(String nature){
|
||||
return this.detail.stream().filter(d->!StringUtils.equalsIgnoreCase(d.getNature(),nature)).collect(Collectors.toList());
|
||||
|
||||
}
|
||||
}
|
@ -26,17 +26,10 @@ public class DeviceVoiceCommand {
|
||||
/**
|
||||
* 匹配的命令关键字
|
||||
*/
|
||||
private String[] matchCommandKW;
|
||||
private String matchCommandDescribe;
|
||||
// private String[] matchCommandKW;
|
||||
// private String matchCommandDescribe;
|
||||
|
||||
public void appendCommandDescribe(String d){
|
||||
if(Objects.isNull(this.matchCommandDescribe)){
|
||||
this.matchCommandDescribe = d;
|
||||
}else{
|
||||
this.matchCommandDescribe = this.matchCommandDescribe.concat(d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
|
@ -9,6 +9,22 @@ import lombok.NoArgsConstructor;
|
||||
public class OperateConfigData extends VoiceConfigData {
|
||||
private OperateEnum operate;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
// private String[] describeKW;
|
||||
// private String[] translateDescribeKW;
|
||||
/**
|
||||
* 属性关键字
|
||||
*/
|
||||
private String[] natureKW;
|
||||
private String[] translateNatureKW;
|
||||
|
||||
/**
|
||||
* 是否强制匹配属性关键字
|
||||
*/
|
||||
private boolean forceMatchNature;
|
||||
|
||||
public OperateConfigData(OperateEnum operate) {
|
||||
this.operate = operate;
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class ParseDetail {
|
||||
private String name;
|
||||
private String nature;
|
||||
private int index;
|
||||
private int end;
|
||||
|
||||
public ParseDetail(String name, String meta, int index, int end) {
|
||||
this.name = name;
|
||||
this.nature = meta;
|
||||
this.index = index;
|
||||
this.end = end;
|
||||
}
|
||||
}
|
@ -4,7 +4,10 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class VoiceConfigData {
|
||||
private String[] sourceMatch;
|
||||
private String[] translateMatch;
|
||||
/**
|
||||
* 激活匹配关键字
|
||||
*/
|
||||
private String[] actionMatch;
|
||||
private String[] translateActionMatch;
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.work;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.WorkResult;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement;
|
||||
@ -11,8 +13,22 @@ import java.util.Optional;
|
||||
|
||||
public interface IDeviceWork {
|
||||
|
||||
Optional<MapNamedElement> findDevice(Simulation simulation, List<String> matchCommandDescribe);
|
||||
WorkResult work(Simulation simulation, DeviceVoiceCommand command, MapElement device);
|
||||
/**
|
||||
* 根据分析出的数据查找对应的设备
|
||||
* @param simulation
|
||||
* @param matchCommandDescribe
|
||||
* @return
|
||||
*/
|
||||
Optional<? extends MapNamedElement> findDevice(Simulation simulation, CommandParse commandParse, OperateConfigData configData);
|
||||
|
||||
/**
|
||||
* 执行对应的操作
|
||||
* @param simulation
|
||||
* @param command
|
||||
* @param device
|
||||
* @return
|
||||
*/
|
||||
void work(Simulation simulation, DeviceVoiceCommand command, MapElement device);
|
||||
MapElement.DeviceType deviceType();
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package club.joylink.rtss.simulation.cbtc.command.voice.work;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.analyse.VoiceCommandAnalyse;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.WorkResult;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
@ -31,12 +33,18 @@ public class VoiceCommandAnalyseWork {
|
||||
return deviceWork;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析语音指令的描述,并返回查找对应的设备
|
||||
* @param simulation
|
||||
* @param command
|
||||
* @return
|
||||
*/
|
||||
public Optional<MapNamedElement> analyse(Simulation simulation, DeviceVoiceCommand command) {
|
||||
IDeviceWork deviceWork = this.findDeviceWork(command.getDeviceType());
|
||||
List<String> findDeviceNames = this.commandAnalyse.parseCommandDescribe(command);
|
||||
command.setMatchCommandDescribe(Joiner.on(",").join(findDeviceNames));
|
||||
Optional<MapNamedElement> optional = deviceWork.findDevice(simulation,findDeviceNames);
|
||||
return optional;
|
||||
CommandParse commandParse = this.commandAnalyse.parseCommandDescribe(simulation,command);
|
||||
// command.setMatchCommandDescribe(Joiner.on(",").join(findDeviceNames));
|
||||
Optional<? extends MapNamedElement> optional = deviceWork.findDevice(simulation,commandParse,command.getOperateConfigData());
|
||||
return (Optional<MapNamedElement>) optional;
|
||||
}
|
||||
|
||||
public WorkResult work(Simulation simulation, DeviceVoiceCommand command, MapNamedElement device){
|
||||
|
@ -0,0 +1,71 @@
|
||||
package club.joylink.rtss.simulation.cbtc.command.voice.work.device;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.analyse.VoiceCommandAnalyse;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.operate.OperateEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.work.IDeviceWork;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.util.PinYinUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.similarity.JaroWinklerSimilarity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class StandWork implements IDeviceWork {
|
||||
@Autowired
|
||||
private AtsStandService atsStandService;
|
||||
|
||||
|
||||
private String findStationCode(Simulation simulation, CommandParse commandParse){
|
||||
List<ParseDetail> findCommandParse = commandParse.findNotNatureDetail(VoiceCommandAnalyse.DESCRIBE_NATURE);
|
||||
JaroWinklerSimilarity similarity = new JaroWinklerSimilarity();
|
||||
Map<Double,String> similarityMaper = new HashMap<>();
|
||||
for (Station station : simulation.getRepository().getStationList()) {
|
||||
String stationName = station.getName();
|
||||
String pinYinStation = PinYinUtil.toPinYinSplitBlankSpace(stationName);
|
||||
for (ParseDetail cp : findCommandParse) {
|
||||
double scope = similarity.apply(pinYinStation,cp.getName());
|
||||
similarityMaper.put(scope,station.getCode());
|
||||
}
|
||||
}
|
||||
if(similarityMaper.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
double max = similarityMaper.keySet().stream().mapToDouble(d->d).max().getAsDouble();
|
||||
return similarityMaper.get(max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<? extends MapNamedElement> findDevice(Simulation simulation, CommandParse commandParse, OperateConfigData configData) {
|
||||
String stationCode = this.findStationCode(simulation,commandParse);
|
||||
if(StringUtils.isEmpty(stationCode)){
|
||||
return Optional.empty();
|
||||
}
|
||||
OperateEnum configOperateEnum = configData.getOperate();
|
||||
final boolean isRight = (configOperateEnum == OperateEnum.STAND_DOWN_HOLD_TRAIN || configOperateEnum == OperateEnum.STAND_CANCEL_DOWN_HOLD_TRAIN) ? false : true;
|
||||
Optional<Stand> stand = simulation.getRepository().getStandList().stream().filter(d->d.isRight() == isRight && StringUtils.equalsIgnoreCase(d.getStation().getCode(),stationCode)).findFirst();
|
||||
return stand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void work(Simulation simulation, DeviceVoiceCommand command, MapElement device) {
|
||||
command.getOperateConfigData().getOperate().handle(simulation,this.atsStandService,device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapElement.DeviceType deviceType() {
|
||||
return MapElement.DeviceType.STAND;
|
||||
}
|
||||
}
|
@ -2,7 +2,9 @@ package club.joylink.rtss.simulation.cbtc.command.voice.work.device;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiSwitchControlService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.WorkResult;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand;
|
||||
import club.joylink.rtss.simulation.cbtc.command.voice.work.IDeviceWork;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
@ -24,13 +26,13 @@ public class SwitchWork implements IDeviceWork {
|
||||
private CiSwitchControlService ciSwitchControlService;
|
||||
|
||||
@Override
|
||||
public Optional<MapNamedElement> findDevice(Simulation simulation, List<String> matchCommandDescribe) {
|
||||
public Optional<MapNamedElement> findDevice(Simulation simulation, CommandParse commandParse, OperateConfigData configData) {
|
||||
JaroWinklerSimilarity similarity = new JaroWinklerSimilarity();
|
||||
Map<Double,String> similarityMaper = new HashMap<>();
|
||||
for (Switch aSwitch : simulation.getRepository().getSwitchList()) {
|
||||
String switchName = aSwitch.getName();
|
||||
for (String findDeviceName : matchCommandDescribe) {
|
||||
double scope = similarity.apply(switchName.toUpperCase(),findDeviceName);
|
||||
for (ParseDetail cp : commandParse.getDetail()) {
|
||||
double scope = similarity.apply(switchName.toUpperCase(),cp.getName());
|
||||
similarityMaper.put(scope,aSwitch.getCode());
|
||||
}
|
||||
}
|
||||
@ -45,9 +47,9 @@ public class SwitchWork implements IDeviceWork {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkResult work(Simulation simulation, DeviceVoiceCommand command, MapElement device) {
|
||||
public void work(Simulation simulation, DeviceVoiceCommand command, MapElement device) {
|
||||
command.getOperateConfigData().getOperate().handle(simulation,this.ciSwitchControlService,device);
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,11 +1,14 @@
|
||||
package club.joylink.rtss.util;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import net.sourceforge.pinyin4j.PinyinHelper;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
|
||||
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PinYinUtil {
|
||||
|
||||
private final static HanyuPinyinOutputFormat PIN_YIN_FORMAT = new HanyuPinyinOutputFormat();
|
||||
@ -37,6 +40,11 @@ public class PinYinUtil {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<String> toPinyinList(String sourceMsg){
|
||||
String tmpPinyinStr = toPinYinSplitBlankSpace(sourceMsg);
|
||||
return Splitter.onPattern("\\s").omitEmptyStrings().splitToList(tmpPinyinStr);
|
||||
}
|
||||
public static String toPinYinSplitBlankSpace(String sourceMsg){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(char c : sourceMsg.toCharArray()){
|
||||
|
@ -16,7 +16,6 @@ import org.springframework.util.StringUtils;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -73,14 +72,20 @@ public class VoiceConfigVO implements Serializable {
|
||||
VoiceDeviceConfig vc = new VoiceDeviceConfig();
|
||||
if(Objects.nonNull(this.wakeUpKw)){
|
||||
if(this.handleType == HandleType.PINYIN){
|
||||
this.wakeUpKw.setTranslateMatch(PinYinUtil.toPinYins(this.wakeUpKw.getSourceMatch()));
|
||||
this.wakeUpKw.setTranslateActionMatch(PinYinUtil.toPinYins(this.wakeUpKw.getActionMatch()));
|
||||
}
|
||||
vc.setWakeUpKw(JsonUtils.writeValueAsString(this.wakeUpKw));
|
||||
}
|
||||
if(!CollectionUtils.isEmpty(this.config)){
|
||||
for (OperateConfigData configData : this.config) {
|
||||
if(this.handleType == HandleType.PINYIN){
|
||||
configData.setTranslateMatch(PinYinUtil.toPinYins(configData.getSourceMatch()));
|
||||
configData.setTranslateActionMatch(PinYinUtil.toPinYins(configData.getActionMatch()));
|
||||
if(ArrayUtils.isNotEmpty(configData.getDescribeKW())){
|
||||
configData.setTranslateDescribeKW(PinYinUtil.toPinYins(configData.getDescribeKW()));
|
||||
}
|
||||
if(ArrayUtils.isNotEmpty(configData.getNatureKW())){
|
||||
configData.setTranslateNatureKW(PinYinUtil.toPinYins(configData.getNatureKW()));
|
||||
}
|
||||
}
|
||||
}
|
||||
vc.setConfig(JsonUtils.writeValueAsString(this.config));
|
||||
|
@ -1,27 +1,37 @@
|
||||
package club.joylink.rtss.services.util;
|
||||
|
||||
import club.joylink.rtss.util.PinYinUtil;
|
||||
import org.ansj.domain.Result;
|
||||
import org.ansj.domain.Term;
|
||||
import org.ansj.library.DicLibrary;
|
||||
import org.ansj.splitWord.analysis.DicAnalysis;
|
||||
import org.nlpcn.commons.lang.tire.domain.Forest;
|
||||
|
||||
public class SplitWordTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "dao cha", DicLibrary.DEFAULT_NATURE, 1);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "ding wei", DicLibrary.DEFAULT_NATURE, 1);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "fan wei", DicLibrary.DEFAULT_NATURE, 1);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "ban li", DicLibrary.DEFAULT_NATURE, 1);
|
||||
|
||||
// print("1234asdfa");
|
||||
// print("BAN LI|p0707|daochadingwei|");
|
||||
print("BAN LI p0707 dao cha ding wei");
|
||||
// DicLibrary.insert(DicLibrary.DEFAULT, "dao cha", DicLibrary.DEFAULT_NATURE, 1);
|
||||
// DicLibrary.insert(DicLibrary.DEFAULT, "ding wei", DicLibrary.DEFAULT_NATURE, 1);
|
||||
// DicLibrary.insert(DicLibrary.DEFAULT, "fan wei", DicLibrary.DEFAULT_NATURE, 1);
|
||||
// DicLibrary.insert(DicLibrary.DEFAULT, "ban li", DicLibrary.DEFAULT_NATURE, 1);
|
||||
// DicLibrary.put("user",null);
|
||||
// DicLibrary.put("user", "user", new Forest());
|
||||
// DicLibrary.insert("user", PinYinUtil.toPinYinSplitBlankSpace("车险").toLowerCase(),"user",1000);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "zhan tai", DicLibrary.DEFAULT_NATURE, 1);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "zhan", "xxxws", 1);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "zhan", "user", 1);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "shang xing", DicLibrary.DEFAULT_NATURE, 1);
|
||||
DicLibrary.insert(DicLibrary.DEFAULT, "kou che", DicLibrary.DEFAULT_NATURE, 1);
|
||||
String source = "车险 车站01上行站台扣车";
|
||||
String pinyin = PinYinUtil.toPinYinSplitBlankSpace(source);
|
||||
print(pinyin);
|
||||
}
|
||||
private static void print(String s) throws Exception {
|
||||
// print(BaseAnalysis.parse(s));
|
||||
// print(ToAnalysis.parse(s));
|
||||
|
||||
// print(IndexAnalysis.parse(s));
|
||||
print(DicAnalysis.parse(s));
|
||||
print(DicAnalysis.parse(s,DicLibrary.get("user")));
|
||||
// print(NlpAnalysis.parse(s));
|
||||
// print(DicAnalysis.parse(s));
|
||||
}
|
||||
|
@ -95,4 +95,15 @@ public class SimulationVoiceTest {
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void newTestStand(){
|
||||
LoginUserInfoVO userInfoVO = this.getInfo();
|
||||
String simKey = simulationService.createSimulation(10642L,userInfoVO);
|
||||
Simulation simulation = (Simulation)this.simulationManager.getById(simKey);
|
||||
List<WorkResult> results = this.commandService.voiceCommand(simulation,"办理车站十上行站台扣车");
|
||||
// List<WorkResult> results = this.commandService.voiceCommand(simulation,"办理车站1上行站台扣车");
|
||||
for (WorkResult result : results) {
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,19 +50,45 @@ public class VoiceDataManageTest {
|
||||
configVO.setDeviceType(MapElement.DeviceType.SWITCH);
|
||||
configVO.setMapId(50L);
|
||||
VoiceConfigData config = new VoiceConfigData();
|
||||
config.setSourceMatch(new String[]{"道岔"});
|
||||
config.setActionMatch(new String[]{"道岔"});
|
||||
configVO.setWakeUpKw(config);
|
||||
List<OperateConfigData> configDataList = Lists.newArrayList();
|
||||
OperateConfigData configData = new OperateConfigData(OperateEnum.SWITCH_DINGWEI);
|
||||
configData.setSourceMatch(new String[]{"定位"});
|
||||
configData.setActionMatch(new String[]{"定位"});
|
||||
configDataList.add(configData);
|
||||
configData = new OperateConfigData(OperateEnum.SWITCH_FANWEI);
|
||||
configData.setSourceMatch(new String[]{"反位"});
|
||||
configData.setActionMatch(new String[]{"反位"});
|
||||
configDataList.add(configData);
|
||||
configVO.setConfig(configDataList);
|
||||
this.dataService.saveOrUpdate(configVO,userInfoVO);
|
||||
}
|
||||
@Test
|
||||
// @Rollback
|
||||
public void insertDataStand(){
|
||||
LoginUserInfoVO userInfoVO = this.getInfo();
|
||||
VoiceConfigVO configVO = new VoiceConfigVO();
|
||||
configVO.setId(11L);
|
||||
configVO.setHandleType(HandleType.PINYIN);
|
||||
configVO.setDescribe("测试站台");
|
||||
configVO.setDeviceType(MapElement.DeviceType.STAND);
|
||||
configVO.setMapId(63L);
|
||||
VoiceConfigData config = new VoiceConfigData();
|
||||
config.setActionMatch(new String[]{"站台"});
|
||||
configVO.setWakeUpKw(config);
|
||||
List<OperateConfigData> configDataList = Lists.newArrayList();
|
||||
OperateConfigData configData = new OperateConfigData(OperateEnum.STAND_UP_HOLD_TRAIN);
|
||||
configData.setActionMatch(new String[]{"扣车"});
|
||||
configData.setNatureKW(new String[]{"上行","上"});
|
||||
// configData.setDescribeKW(new String[]{"站"});
|
||||
configDataList.add(configData);
|
||||
configData = new OperateConfigData(OperateEnum.STAND_CANCEL_UP_HOLD_TRAIN);
|
||||
configData.setActionMatch(new String[]{"取消扣车","取消"});
|
||||
configData.setNatureKW(new String[]{"上行","上"});
|
||||
// configData.setDescribeKW(new String[]{"站"});
|
||||
configDataList.add(configData);
|
||||
configVO.setConfig(configDataList);
|
||||
this.dataService.saveOrUpdate(configVO,userInfoVO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findData(){
|
||||
VoiceConfigVO vo1 = this.dataService.byId(7L);
|
||||
|
Loading…
Reference in New Issue
Block a user