diff --git a/pom.xml b/pom.xml index 33fd4b9eb..4605f52ca 100644 --- a/pom.xml +++ b/pom.xml @@ -146,6 +146,10 @@ okhttp 4.9.0 + diff --git a/src/main/java/club/joylink/rtss/RtssApplication.java b/src/main/java/club/joylink/rtss/RtssApplication.java index 0b6d2f049..313ebf25c 100644 --- a/src/main/java/club/joylink/rtss/RtssApplication.java +++ b/src/main/java/club/joylink/rtss/RtssApplication.java @@ -10,6 +10,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling @EnableCaching @MapperScan(basePackages = {"club.joylink.rtss.dao"}) +//@EnableRetry public class RtssApplication { public static void main(String[] args) { diff --git a/src/main/java/club/joylink/rtss/controller/paper/PagerQuestionBankController.java b/src/main/java/club/joylink/rtss/controller/paper/PagerQuestionBankController.java index 7883d4a8c..125901166 100644 --- a/src/main/java/club/joylink/rtss/controller/paper/PagerQuestionBankController.java +++ b/src/main/java/club/joylink/rtss/controller/paper/PagerQuestionBankController.java @@ -1,13 +1,14 @@ package club.joylink.rtss.controller.paper; -import club.joylink.rtss.services.papger.PagerQuestionService; +import club.joylink.rtss.services.paper.PagerQuestionService; import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.LoginUserInfoVO; import club.joylink.rtss.vo.client.PageVO; import club.joylink.rtss.vo.client.pager.question.PagerLableQueryVO; import club.joylink.rtss.vo.client.pager.question.PaperQuestionVO; -import club.joylink.rtss.vo.client.question.QuestionQueryVO; + +import club.joylink.rtss.vo.client.pager.question.QuestionQueryVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -17,10 +18,10 @@ import java.util.List; /** - * 题库管理接口 + * 题库教师管理接口 */ @RestController -@RequestMapping(path = "/api/pager_question") +@RequestMapping(path = "/api/question/org") public class PagerQuestionBankController { @@ -32,8 +33,8 @@ public class PagerQuestionBankController { */ @GetMapping(path = "/paging") public PageVO pagingQueryQuestions(@RequestAttribute LoginUserInfoVO loginInfo, QuestionQueryVO queryVO) { - queryVO.setProjectCode(loginInfo.getProject()); - return questionBankService.pagingQueryQuestions(queryVO); + queryVO.setCompanyId(loginInfo.getTopOrgId()); + return questionBankService.pagingQueryQuestions(queryVO,false); } /** @@ -41,8 +42,9 @@ public class PagerQuestionBankController { */ @GetMapping(path = "") public List queryQuestions(@RequestAttribute LoginUserInfoVO loginInfo, QuestionQueryVO queryVO) { - queryVO.setProjectCode(loginInfo.getProject()); - return questionBankService.queryQuestions(queryVO); + + queryVO.setCompanyId(loginInfo.getTopOrgId()); + return questionBankService.queryQuestions(queryVO,false); } /** @@ -59,7 +61,7 @@ public class PagerQuestionBankController { @PostMapping(path = "") public void addQuestion(@Validated @RequestBody PaperQuestionVO questionVO, @RequestAttribute LoginUserInfoVO loginInfo, @RequestAttribute AccountVO user) { - questionVO.setProjectCode(loginInfo.getProject()); + questionVO.setCompanyId(loginInfo.getTopOrgId()); questionBankService.saveOrUpdate(questionVO, user); } @@ -68,7 +70,7 @@ public class PagerQuestionBankController { */ @PostMapping(path = "/import") public void importProjectQuestion(@Validated @RequestBody List questions, @RequestAttribute LoginUserInfoVO loginInfo, - @RequestAttribute AccountVO user, @RequestParam(required = false, name = "id") Long companyId) { + @RequestAttribute AccountVO user, @RequestParam( name = "id") Long companyId) { questionBankService.importProjectQuestion(questions, loginInfo.getProject(), companyId, user); } @@ -80,7 +82,7 @@ public class PagerQuestionBankController { */ @GetMapping(path = "/lable") public Collection findAllLable(@RequestAttribute LoginUserInfoVO loginInfo /*@PathVariable Long companyId*/) { - return this.questionBankService.findAllLable(loginInfo.getProject()); + return this.questionBankService.findAllLable(loginInfo.getTopOrgId()); } /** @@ -89,10 +91,10 @@ public class PagerQuestionBankController { * @param queryVO * @return */ -// @PostMapping(path="/{companyId}/question") @PostMapping(path = "/lable/question") public List findByLable(@RequestAttribute LoginUserInfoVO loginInfo, @RequestBody PagerLableQueryVO queryVO) { - return this.questionBankService.queryQuestionsForRaceLable(loginInfo.getProject(), queryVO, false); + + return this.questionBankService.queryQuestionsForRaceLable(loginInfo.getTopOrgId(),queryVO, false); } @@ -107,7 +109,7 @@ public class PagerQuestionBankController { @PutMapping(path = "/{questionId}") public void updateQuestion(@PathVariable Long questionId, @RequestAttribute LoginUserInfoVO loginInfo, @RequestBody PaperQuestionVO questionVO, @RequestAttribute AccountVO user) { questionVO.setId(questionId); - questionVO.setProjectCode(loginInfo.getProject()); + questionVO.setCompanyId(loginInfo.getTopOrgId()); questionBankService.saveOrUpdate(questionVO, user); } @@ -119,9 +121,4 @@ public class PagerQuestionBankController { questionBankService.deleteQuestion(questionId); } - -/* @PostMapping(path = "answer/{questionId}") - public void answer(@PathVariable Long questionId,@RequestBody List answer){ - this.questionBankService.answer(questionId,answer); - }*/ } diff --git a/src/main/java/club/joylink/rtss/controller/paper/PagerQuestionBankManageController.java b/src/main/java/club/joylink/rtss/controller/paper/PagerQuestionBankManageController.java new file mode 100644 index 000000000..f204ad68d --- /dev/null +++ b/src/main/java/club/joylink/rtss/controller/paper/PagerQuestionBankManageController.java @@ -0,0 +1,40 @@ +package club.joylink.rtss.controller.paper; + + +import club.joylink.rtss.services.paper.PagerQuestionService; +import club.joylink.rtss.vo.AccountVO; +import club.joylink.rtss.vo.LoginUserInfoVO; +import club.joylink.rtss.vo.client.PageVO; +import club.joylink.rtss.vo.client.pager.question.PagerLableQueryVO; +import club.joylink.rtss.vo.client.pager.question.PaperQuestionVO; +import club.joylink.rtss.vo.client.pager.question.QuestionQueryVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Collection; +import java.util.List; + + +/** + * 题库管理接口 + */ +@RestController +@RequestMapping(path = "/api/question/manage") +public class PagerQuestionBankManageController { + + + @Autowired + private PagerQuestionService questionBankService; + + /** + * 分页查询题目 + */ + @GetMapping(path = "/paging") + public PageVO pagingQueryQuestions(QuestionQueryVO queryVO) { + queryVO.setCompanyId(queryVO.getCompanyId()); + return questionBankService.pagingQueryQuestions(queryVO,true); + } + + +} diff --git a/src/main/java/club/joylink/rtss/controller/paper/PaperApiTestController.java b/src/main/java/club/joylink/rtss/controller/paper/PaperApiTestController.java new file mode 100644 index 000000000..d369f0401 --- /dev/null +++ b/src/main/java/club/joylink/rtss/controller/paper/PaperApiTestController.java @@ -0,0 +1,82 @@ +package club.joylink.rtss.controller.paper; + +import club.joylink.rtss.util.JsonUtils; +import club.joylink.rtss.vo.paper.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@RestController +@RequestMapping("/api/v2/test/paper") +public class PaperApiTestController { + + public static void createPaperCompositionReqVo(){ + CreatePaperCompositionReqVo rt = new CreatePaperCompositionReqVo(); + rt.setName("测试试卷1"); + rt.setProfile("XX单位用于测试CMM的试题"); + rt.setCompanyId("1"); + System.out.println(JsonUtils.writeValueAsString(rt)); + } + public static void paperCompositionBasicVo(){ + PaperCompositionBasicVo rt = new PaperCompositionBasicVo(); + rt.setId(1L); + rt.setName("测试试卷1"); + rt.setProfile("XX单位用于测试CMM的试题"); + rt.setCompanyId("1"); + System.out.println(JsonUtils.writeValueAsString(rt)); + } + public static void paperCompositionDetailVo(){ + PaperCompositionDetailVo rt = new PaperCompositionDetailVo(); + rt.setId(1L); + rt.setPassScore(60); + rt.setValidDuration(120); + rt.setStartTime(LocalDateTime.now().plusDays(20)); + rt.setEndTime(LocalDateTime.now().plusDays(30)); + System.out.println(JsonUtils.writeValueAsString(rt)); + } + public static void findPaperCompositionPageReqVo(){ + FindPaperCompositionPageReqVo rt = new FindPaperCompositionPageReqVo(); + rt.setName("2"); + System.out.println(JsonUtils.writeValueAsString(rt)); + } + public static void createPaperRuleReqVo(){ + CreatePaperRuleReqVo rt = new CreatePaperRuleReqVo(); + rt.setPcId(1L); + rt.setScore(2); + rt.setType(PaperQType.GroupType.Common); + rt.setSubtype(PaperQType.SubType.Select); + rt.setSum(10); + List tags = new ArrayList<>(); + tags.add("6"); + tags.add("8"); + rt.setTags(tags); + System.out.println(JsonUtils.writeValueAsString(rt)); + } + public static void paperRuleVo(){ + PaperRuleVo rt = new PaperRuleVo(); + rt.setId(4L); + rt.setPcId(1L); + rt.setScore(2); + rt.setType(PaperQType.GroupType.Common); + rt.setSubtype(PaperQType.SubType.Select); + rt.setSum(10); + List tags = new ArrayList<>(); + tags.add("6"); + tags.add("8"); + rt.setTags(tags); + System.out.println(JsonUtils.writeValueAsString(rt)); + } + public static void main(String[]args){ + createPaperCompositionReqVo(); + paperCompositionBasicVo(); + paperCompositionDetailVo(); + findPaperCompositionPageReqVo(); + createPaperRuleReqVo(); + paperRuleVo(); + } +} diff --git a/src/main/java/club/joylink/rtss/controller/paper/PaperUserController.java b/src/main/java/club/joylink/rtss/controller/paper/PaperUserController.java index c83dcda89..baecdde75 100644 --- a/src/main/java/club/joylink/rtss/controller/paper/PaperUserController.java +++ b/src/main/java/club/joylink/rtss/controller/paper/PaperUserController.java @@ -81,6 +81,9 @@ public class PaperUserController { /** * 用户提交答案 + *

+ * 对于理论题:用户完成一道题提交一道题的答案;
+ * 对于实训题:用户完成实训操作后,由实训系统自己评判实训是否成功完成,前端提交实训是否成功完成的结果即可。 */ @PostMapping("/user/question/answer") public PaperSubmitAnswerRspVo submitAnswer(@RequestBody PaperSubmitAnswerReqVo req, @RequestAttribute AccountVO user) { diff --git a/src/main/java/club/joylink/rtss/controller/test/TestController.java b/src/main/java/club/joylink/rtss/controller/test/TestController.java index 882f78999..20be77cb2 100644 --- a/src/main/java/club/joylink/rtss/controller/test/TestController.java +++ b/src/main/java/club/joylink/rtss/controller/test/TestController.java @@ -1,14 +1,19 @@ package club.joylink.rtss.controller.test; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import club.joylink.rtss.services.voice.AbstractVoiceService; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/test") public class TestController { + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService voiceService; + @PostMapping("/thirdsync/usr") public void thirdSyncSimulationRecord(@RequestBody String json) { System.out.println(json); @@ -18,5 +23,10 @@ public class TestController { public void thirdSyncExamRecord(@RequestBody String json) { System.out.println(json); } - +/* @PostMapping("synthesis") + public void testSynthesis(@RequestParam("msg") String msg){ + BaseVoiceSynthesisVO.SynthesisBaidu vo = new BaseVoiceSynthesisVO.SynthesisBaidu(msg); + vo.setDeaultParam(true); + this.voiceService.synthesis(vo); + }*/ } diff --git a/src/main/java/club/joylink/rtss/controller/voice/VoiceController.java b/src/main/java/club/joylink/rtss/controller/voice/VoiceController.java index 604f1376e..adb0d3abd 100644 --- a/src/main/java/club/joylink/rtss/controller/voice/VoiceController.java +++ b/src/main/java/club/joylink/rtss/controller/voice/VoiceController.java @@ -4,7 +4,7 @@ import club.joylink.rtss.services.voice.IVoiceTrainingService; import club.joylink.rtss.services.voice.baidu.TokenHolder; import club.joylink.rtss.vo.client.PageQueryVO; import club.joylink.rtss.vo.client.PageVO; -import club.joylink.rtss.vo.client.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; import club.joylink.rtss.vo.client.competition.VoiceErrorVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/club/joylink/rtss/dao/paper/PaperQuestionDAO.java b/src/main/java/club/joylink/rtss/dao/paper/PaperQuestionDAO.java index 9c7cc1d50..ac11d71ca 100644 --- a/src/main/java/club/joylink/rtss/dao/paper/PaperQuestionDAO.java +++ b/src/main/java/club/joylink/rtss/dao/paper/PaperQuestionDAO.java @@ -16,15 +16,19 @@ import java.util.List; public interface PaperQuestionDAO { @Select("") - List findFromAndRaceLable(String projectCode, int isDelete, List lable, List types); + List findFromAndRaceLable(Long companyId,int isDelete, List lable, List types); long countByExample(PaperQuestionExample example); int deleteByExample(PaperQuestionExample example); diff --git a/src/main/java/club/joylink/rtss/services/audio/AudioResourcesServiceImpl.java b/src/main/java/club/joylink/rtss/services/audio/AudioResourcesServiceImpl.java index 2fa5ba0fb..fb41dd694 100644 --- a/src/main/java/club/joylink/rtss/services/audio/AudioResourcesServiceImpl.java +++ b/src/main/java/club/joylink/rtss/services/audio/AudioResourcesServiceImpl.java @@ -3,10 +3,13 @@ package club.joylink.rtss.services.audio; import club.joylink.rtss.dao.AudioResourcesDAO; import club.joylink.rtss.entity.AudioResources; import club.joylink.rtss.entity.AudioResourcesExample; -import club.joylink.rtss.services.voice.IVoiceService; +import club.joylink.rtss.services.voice.AbstractVoiceService; + import club.joylink.rtss.vo.client.PageVO; import club.joylink.rtss.vo.client.audio.AudioResourcesQueryVO; import club.joylink.rtss.vo.client.audio.AudioResourcesVO; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; +import club.joylink.rtss.vo.client.voice.VoiceCompose; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import org.springframework.beans.factory.annotation.Autowired; @@ -23,10 +26,13 @@ import java.util.List; public class AudioResourcesServiceImpl implements AudioResourcesService { @Autowired private AudioResourcesDAO audioResourcesDAO; - @Autowired + /*@Autowired @Qualifier("baiDuVoiceService") private IVoiceService iVoiceService; - + */ + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; @Override public void create(AudioResourcesVO vo) { AudioResources entity = vo.convert2DB4Create(); @@ -89,9 +95,13 @@ public class AudioResourcesServiceImpl implements AudioResourcesService { @Override public void generate(AudioResourcesVO vo) { - String filePath = iVoiceService.synthesis(vo.getDesc()); - vo.setUrl(filePath); + BaseVoiceSynthesisVO vo2 = new BaseVoiceSynthesisVO(vo.getDesc()); + VoiceCompose vc = iVoiceService.synthesis(vo2); + vo.setUrl(vc.getFilePath()); create(vo); + /* String filePath = iVoiceService.synthesis(vo.getDesc()); + vo.setUrl(filePath); + create(vo);*/ } private AudioResources getEntity(long id) { diff --git a/src/main/java/club/joylink/rtss/services/completition/CompetitionPracticalService.java b/src/main/java/club/joylink/rtss/services/completition/CompetitionPracticalService.java index 68ce3aa71..fffefb3b7 100644 --- a/src/main/java/club/joylink/rtss/services/completition/CompetitionPracticalService.java +++ b/src/main/java/club/joylink/rtss/services/completition/CompetitionPracticalService.java @@ -31,7 +31,7 @@ import club.joylink.rtss.util.VoiceFileUtils; import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.LoginUserInfoVO; import club.joylink.rtss.vo.client.PageVO; -import club.joylink.rtss.vo.client.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; import club.joylink.rtss.vo.client.competition.*; import club.joylink.rtss.vo.client.order.OrderCreateVO; import club.joylink.rtss.vo.client.order.OrderDetailCreateVO; diff --git a/src/main/java/club/joylink/rtss/services/iscs/interactive/IscsInteractiveService.java b/src/main/java/club/joylink/rtss/services/iscs/interactive/IscsInteractiveService.java index 0713d87e0..1e48431e2 100644 --- a/src/main/java/club/joylink/rtss/services/iscs/interactive/IscsInteractiveService.java +++ b/src/main/java/club/joylink/rtss/services/iscs/interactive/IscsInteractiveService.java @@ -2,7 +2,7 @@ package club.joylink.rtss.services.iscs.interactive; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.services.audio.AudioResourcesService; -import club.joylink.rtss.services.voice.IVoiceService; +import club.joylink.rtss.services.voice.AbstractVoiceService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.SimulationIscsDataRepository; @@ -20,6 +20,7 @@ import club.joylink.rtss.vo.client.iscs.RemoveTimedPlayParamVO; import club.joylink.rtss.vo.client.iscs.TimedPlayParamVO; import club.joylink.rtss.vo.client.iscs.device.IscsDeviceVO; import club.joylink.rtss.vo.client.iscs.systemRes.IscsSystemResourcesVO; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -35,14 +36,20 @@ public class IscsInteractiveService { @Autowired private AudioResourcesService audioResourcesService; - @Autowired + /*@Autowired @Qualifier("baiDuVoiceService") private IVoiceService iVoiceService; +*/ + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; public void paPlay(Simulation simulation, PlayParamVO param) { AudioResourcesVO resourceVO; if (IscsSystemResourcesVO.Type.REAL_TIME.equals(param.getType())) { - String url = iVoiceService.synthesis(param.getContent()); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(param.getContent()); + String url = iVoiceService.synthesis(vo).getFilePath(); +// String url = iVoiceService.synthesis(param.getContent()); resourceVO = new AudioResourcesVO(param.getName(), param.getContent(), url); } else { BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(param.getResourceId(), "资源id不能为null"); @@ -117,7 +124,9 @@ public class IscsInteractiveService { } else { BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertHasText(param.getName(), "实时消息名称不能为空"); BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertHasText(param.getContent(), "实时消息内容不能为空"); - String url = iVoiceService.synthesis(param.getContent()); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(param.getContent()); + String url = iVoiceService.synthesis(vo).getFilePath(); +// String url = iVoiceService.synthesis(param.getContent()); resourceVO = new AudioResourcesVO(param.getName(), param.getContent(), url); } SimulationDataRepository repository = simulation.getRepository(); diff --git a/src/main/java/club/joylink/rtss/services/papger/PagerQuestionService.java b/src/main/java/club/joylink/rtss/services/paper/PagerQuestionService.java similarity index 81% rename from src/main/java/club/joylink/rtss/services/papger/PagerQuestionService.java rename to src/main/java/club/joylink/rtss/services/paper/PagerQuestionService.java index f581e13c4..ea7ad2395 100644 --- a/src/main/java/club/joylink/rtss/services/papger/PagerQuestionService.java +++ b/src/main/java/club/joylink/rtss/services/paper/PagerQuestionService.java @@ -1,19 +1,17 @@ -package club.joylink.rtss.services.papger; +package club.joylink.rtss.services.paper; import club.joylink.rtss.constants.BusinessConsts; - import club.joylink.rtss.dao.paper.PaperQuestionDAO; import club.joylink.rtss.entity.paper.question.PaperQuestion; import club.joylink.rtss.entity.paper.question.PaperQuestionExample; import club.joylink.rtss.entity.paper.question.PaperQuestionWithBLOBs; -import club.joylink.rtss.entity.project.Project; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.client.PageVO; import club.joylink.rtss.vo.client.pager.question.PagerLableQueryVO; import club.joylink.rtss.vo.client.pager.question.PaperQuestionOptionVO2; import club.joylink.rtss.vo.client.pager.question.PaperQuestionVO; -import club.joylink.rtss.vo.client.question.QuestionQueryVO; +import club.joylink.rtss.vo.client.pager.question.QuestionQueryVO; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.google.common.base.Joiner; @@ -38,7 +36,9 @@ public class PagerQuestionService { @Resource private PaperQuestionDAO questionDAO; - private Object queryQuestions(QuestionQueryVO queryVO,boolean isPaging){ + private Object queryQuestions(QuestionQueryVO queryVO, boolean isPaging,boolean companyIdCanNull){ + boolean check = Objects.equals(false,companyIdCanNull) && Objects.isNull(queryVO.getCompanyId()); + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(check,"题目答案不能为空"); if(isPaging){ PageHelper.startPage(queryVO.getPageNum(), queryVO.getPageSize()); } @@ -50,18 +50,11 @@ public class PagerQuestionService { if (StringUtils.hasText(queryVO.getType())) { criteria.andTypeEqualTo(queryVO.getType()); } - criteria.andIsDelEqualTo(BusinessConsts.DBLogicDelete.NORMAL.ordinal()); - boolean isDefault = Project.isDefault(queryVO.getProjectCode()); - if (isDefault) { - criteria.andProjectCodeIsNull(); - if (Objects.nonNull(queryVO.getCompanyId())) { - criteria.andCompanyIdEqualTo(queryVO.getCompanyId()); - } /*else { - criteria.andCompanyIdIsNull(); - }*/ - } else { - criteria.andProjectCodeEqualTo(queryVO.getProjectCode()); + + if(Objects.nonNull(queryVO.getCompanyId())){ + criteria.andCompanyIdEqualTo(queryVO.getCompanyId()); } + criteria.andIsDelEqualTo(BusinessConsts.DBLogicDelete.NORMAL.ordinal()); return questionDAO.selectByExampleWithBLOBs(example); } @@ -70,8 +63,8 @@ public class PagerQuestionService { * @param queryVO * @return */ - public PageVO pagingQueryQuestions(QuestionQueryVO queryVO) { - Page page = (Page) this.queryQuestions(queryVO,true); + public PageVO pagingQueryQuestions(QuestionQueryVO queryVO,boolean companyIdCanNull) { + Page page = (Page) this.queryQuestions(queryVO,true,companyIdCanNull); List questionVOS = PaperQuestionVO.convert2VOList(page.getResult()); return PageVO.convert(page, questionVOS); } @@ -82,8 +75,8 @@ public class PagerQuestionService { * @param queryVO * @return */ - public List queryQuestions(QuestionQueryVO queryVO) { - List list = (List) this.queryQuestions(queryVO,false); + public List queryQuestions(QuestionQueryVO queryVO,boolean companyIdCanNull) { + List list = (List) this.queryQuestions(queryVO,false,companyIdCanNull); List questionVOS = PaperQuestionVO.convert2VOList(list); return questionVOS; } @@ -146,16 +139,16 @@ public class PagerQuestionService { * 获取所有公司组织下的标签 * */ - public Collection findAllLable(String projectCode){ + public Collection findAllLable(Long companyId){ + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(Objects.isNull(companyId),"组织id不能为空"); PaperQuestionExample example = new PaperQuestionExample(); PaperQuestionExample.Criteria criteria = example.createCriteria(); - boolean isDefault = Project.isDefault(projectCode); -// criteria.andCompanyIdEqualTo(companyId); - if(isDefault){ - criteria.andProjectCodeIsNull(); - }else{ - criteria.andProjectCodeEqualTo(projectCode); - } + /*boolean isDefault = Project.isDefault(projectCode); + if(Objects.equals(false,isDefault)){ + List ids = this.queryFromProjectCode(projectCode); + criteria.andCompanyIdIn(ids); + }*/ + criteria.andCompanyIdEqualTo(companyId); criteria.andIsDelEqualTo(BusinessConsts.DBLogicDelete.NORMAL.ordinal()); List lableList = this.questionDAO.selectByExample(example); if(CollectionUtils.isEmpty(lableList)){ @@ -173,10 +166,16 @@ public class PagerQuestionService { * @param random * @return */ - public List queryQuestionsForRaceLable(String projectCode, PagerLableQueryVO queryVO, boolean random) { + public List queryQuestionsForRaceLable(Long companyId, PagerLableQueryVO queryVO, boolean random) { + /*boolean isDefault = Project.isDefault(projectCode); + List idList = null; + if(Objects.equals(false,isDefault)){ + idList = this.queryFromProjectCode(projectCode); + }*/ + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(Objects.isNull(companyId),"组织id不能为空"); BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(queryVO.allNotNullOrEmpty(),"查询内容不能为空"); int isDel = BusinessConsts.DBLogicDelete.NORMAL.ordinal(); - List list = this.questionDAO.findFromAndRaceLable(projectCode,isDel,queryVO.getLables(),queryVO.getTypes()); + List list = this.questionDAO.findFromAndRaceLable(companyId,isDel,queryVO.getLables(),queryVO.getTypes()); List questionVOS = PaperQuestionVO.convert2VOList(list); return questionVOS; } @@ -186,9 +185,7 @@ public class PagerQuestionService { * @param accountVO */ public void saveOrUpdate(PaperQuestionVO questionVO, AccountVO accountVO) { - /*BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue((Objects.equals(BusinessConsts.TheoryType.select.name(),questionVO.getType()) - || Objects.equals(BusinessConsts.TheoryType.judge.name(),questionVO.getType()) || Objects.equals(BusinessConsts.TheoryType.multi.name(),questionVO.getType())) - ,"题库目前只支持单选,多选和判断");*/ + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(Objects.isNull(questionVO.getCompanyId()),"组织id不能为空"); this.checkQuestionType(questionVO,"题库目前只支持单选,多选和判断"); if (questionVO.isSelect() || questionVO.isJudge()) { this.checkQuestionTypeForSelectAndJudge(questionVO,"单选或判断题正确答案有且只有一个!"); @@ -198,14 +195,13 @@ public class PagerQuestionService { PaperQuestionWithBLOBs question = questionVO.convert2DB(); question.setCreateUserId(accountVO.getId()); question.setCreateTime(LocalDateTime.now()); -// question.setIsDel(BusinessConsts.DBLogicDelete.NORMAL.ordinal()); if(Objects.nonNull(questionVO.getId())){ PaperQuestionExample example = new PaperQuestionExample(); PaperQuestionExample.Criteria criteria = example.createCriteria(); criteria.andIdEqualTo(questionVO.getId()); criteria.andIsDelEqualTo(BusinessConsts.DBLogicDelete.NORMAL.ordinal()); Long exist = this.questionDAO.countByExample(example); - if(Objects.isNull(exist) || exist <= 0){ + if(exist <= 0){ BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertNotTrue(true, "未找到要修改的数据!"); } @@ -234,7 +230,7 @@ public class PagerQuestionService { @Transactional public void importProjectQuestion(List questions, String projectCode, Long companyId, AccountVO accountVO) { - + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(Objects.isNull(companyId),"组织id不能为空"); questions.forEach(questionVO -> { String topic = questionVO.getQuestion(); this.checkQuestionType(questionVO,String.format("题库目前只支持单选,多选和判断,题序[%s]",questionVO.getId())); @@ -245,11 +241,26 @@ public class PagerQuestionService { } }); - boolean isDefault = Project.isDefault(projectCode); +// boolean isDefault = Project.isDefault(projectCode); //默认项目导入题考虑是否有单位关联 PaperQuestionExample example = new PaperQuestionExample(); PaperQuestionExample.Criteria criteria = example.createCriteria(); - if (isDefault) { + + criteria.andCompanyIdEqualTo(companyId); + + questionDAO.deleteByExample(example); + questions.forEach(questionVO -> { + questionVO.setProjectCode(projectCode); + PaperQuestionWithBLOBs question = questionVO.convert2DB(); +// question.setProjectCode(null); + question.setCompanyId(companyId); + question.setCreateUserId(accountVO.getId()); + question.setCreateTime(LocalDateTime.now()); + question.setCompanyId(companyId); + questionDAO.insert(question); + }); + + /* if (isDefault) { criteria.andProjectCodeIsNull(); if (Objects.nonNull(companyId)) { criteria.andCompanyIdEqualTo(companyId); @@ -260,7 +271,8 @@ public class PagerQuestionService { questions.forEach(questionVO -> { questionVO.setProjectCode(projectCode); PaperQuestionWithBLOBs question = questionVO.convert2DB(); - question.setProjectCode(null); +// question.setProjectCode(null); + question.setCompanyId(null); question.setCreateUserId(accountVO.getId()); question.setCreateTime(LocalDateTime.now()); question.setCompanyId(companyId); @@ -279,12 +291,12 @@ public class PagerQuestionService { question.setCreateTime(LocalDateTime.now()); questionDAO.insert(question); }); - } + }*/ } /** * 删除 逻辑删除 - * @param questionId + * @param questionId 文本id */ public void deleteQuestion(List questionId) { PaperQuestionExample example = new PaperQuestionExample(); diff --git a/src/main/java/club/joylink/rtss/services/paper/PaperCompositionService.java b/src/main/java/club/joylink/rtss/services/paper/PaperCompositionService.java index 00d824a3a..c8f06fab0 100644 --- a/src/main/java/club/joylink/rtss/services/paper/PaperCompositionService.java +++ b/src/main/java/club/joylink/rtss/services/paper/PaperCompositionService.java @@ -188,21 +188,14 @@ public class PaperCompositionService { PaperCompositionExample.Criteria pcExCriteria = pcEx.createCriteria(); if (null != req.getName()) { if (req.getNameLike()) { - pcExCriteria.andNameLike(req.getName()); + pcExCriteria.andNameLike(String.format("%%%s%%",req.getName())); } else { pcExCriteria.andNameEqualTo(req.getName()); } } - if (null != req.getCompanyId()) { - if (req.getProjectCodeLike()) { - pcExCriteria.andCompanyIdLike(String.format("%%%s%%",req.getCompanyId())); - } else { - pcExCriteria.andCompanyIdEqualTo(req.getCompanyId()); - } - } if (null != req.getProfile()) { if (req.getProfileLike()) { - pcExCriteria.andProfileLike(req.getProfile()); + pcExCriteria.andProfileLike(String.format("%%%s%%",req.getProfile())); } else { pcExCriteria.andProfileEqualTo(req.getProfile()); } diff --git a/src/main/java/club/joylink/rtss/services/paper/PaperRuleService.java b/src/main/java/club/joylink/rtss/services/paper/PaperRuleService.java index 8624845ed..f3ef8512f 100644 --- a/src/main/java/club/joylink/rtss/services/paper/PaperRuleService.java +++ b/src/main/java/club/joylink/rtss/services/paper/PaperRuleService.java @@ -44,6 +44,8 @@ public class PaperRuleService { */ @Transactional(rollbackFor = Exception.class) public void createPaperCompositionRule(CreatePaperRuleReqVo req, AccountVO user) { + // + PaperQType.assertPaperSubTypeMatchGroupType(req.getSubtype(),req.getType()); // assertPaperCompositionRuleNotExist(req.getPcId(),req.getSubtype()); compositionService.assertPaperCompositionCanModify(req.getPcId()); @@ -68,6 +70,8 @@ public class PaperRuleService { */ @Transactional(rollbackFor = Exception.class) public void updatePaperCompositionRule(PaperRuleVo req, AccountVO user) { + // + PaperQType.assertPaperSubTypeMatchGroupType(req.getSubtype(),req.getType()); // assertPaperCompositionRuleCanModify(req.getId()); // diff --git a/src/main/java/club/joylink/rtss/services/paper/PaperUserSubmitAnswerService.java b/src/main/java/club/joylink/rtss/services/paper/PaperUserSubmitAnswerService.java index b6db61cc5..319555ff5 100644 --- a/src/main/java/club/joylink/rtss/services/paper/PaperUserSubmitAnswerService.java +++ b/src/main/java/club/joylink/rtss/services/paper/PaperUserSubmitAnswerService.java @@ -48,9 +48,9 @@ public class PaperUserSubmitAnswerService { //用户试卷 final PaperUser pu = paperUserDAO.selectByPrimaryKey(req.getPuId()); //生成试卷的试卷蓝图 - final PaperComposition pc =paperCompositionDAO.selectByPrimaryKey(pu.getPcId()); + final PaperComposition pc = paperCompositionDAO.selectByPrimaryKey(pu.getPcId()); //校验 - this.assertCanSubmitAnswer(pc,pu,puq,user); + this.assertCanSubmitAnswer(pc, pu, puq, user); // final PaperSubmitAnswerRspVo rsp = new PaperSubmitAnswerRspVo(); rsp.setPuId(req.getPuId()); @@ -78,12 +78,12 @@ public class PaperUserSubmitAnswerService { /** * 校验用户此时能否提交答案 */ - private void assertCanSubmitAnswer(PaperComposition pc, PaperUser pu,PaperUserQuestion puq,AccountVO user) { + private void assertCanSubmitAnswer(PaperComposition pc, PaperUser pu, PaperUserQuestion puq, AccountVO user) { final LocalDateTime now = LocalDateTime.now(); final LocalDateTime start = pu.getStartTime(); final LocalDateTime dead = start.plusMinutes(pc.getValidDuration()); //校验时间 - BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotTrue(now.isAfter(dead),"剩余答题时间为0"); + BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotTrue(now.isAfter(dead), "剩余答题时间为0"); //校验重复做题 BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(PaperQuestionState.Undo.equals(PaperQuestionState.getItem(puq.getState())), "只有未做的题才能提交答案"); } @@ -92,8 +92,8 @@ public class PaperUserSubmitAnswerService { * 处理实训题答案 */ private PaperQuestionState submitTrainingAnswer(PaperUserQuestion puq, PaperSubmitAnswerReqVo req) { - //todo - return PaperQuestionState.Wrong; + + return req.getTrainingSuccess() ? PaperQuestionState.Right : PaperQuestionState.Wrong; } /** diff --git a/src/main/java/club/joylink/rtss/services/voice/AbstractVoiceService.java b/src/main/java/club/joylink/rtss/services/voice/AbstractVoiceService.java new file mode 100644 index 000000000..23db13581 --- /dev/null +++ b/src/main/java/club/joylink/rtss/services/voice/AbstractVoiceService.java @@ -0,0 +1,57 @@ +package club.joylink.rtss.services.voice; + +import club.joylink.rtss.configuration.MinioClientConfig; +import club.joylink.rtss.services.voice.baidu.VoiceAsrResult; +import club.joylink.rtss.simulation.cbtc.exception.SimulationException; +import club.joylink.rtss.util.MinioClientUtil; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; +import club.joylink.rtss.vo.client.voice.VoiceCompose; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionVO; +import lombok.extern.slf4j.Slf4j; + +import java.util.Objects; + +@Slf4j +public abstract class AbstractVoiceService implements IVoiceService2 { + + private final MinioClientUtil voiceSynthesisUtil; + private final MinioClientUtil voiceRecognitionUtil; + private final static String SYNTHESIS_FOLDER = "synthesis"; + private final static String RECOGNITION_FOLDER = "recognition"; + public AbstractVoiceService(MinioClientConfig minioClientConfig){ + this.voiceSynthesisUtil = MinioClientUtil.getInstance(minioClientConfig,SYNTHESIS_FOLDER); + this.voiceRecognitionUtil = MinioClientUtil.getInstance(minioClientConfig,RECOGNITION_FOLDER); + } + + public VoiceRecognitionResult voiceRecognition(VoiceRecognitionVO vo){ + String fileName = String.format("%s.wav",System.currentTimeMillis()); + this.uploadFile(vo.getData(),fileName,RECOGNITION_FOLDER); + String filePath = this.voiceSynthesisUtil.getDownLoadPath(fileName); + VoiceAsrResult voiceResult = this.recognition(vo); + return new VoiceRecognitionResult(filePath,voiceResult.getResult().get(0)); + } + + public VoiceCompose synthesis(BaseVoiceSynthesisVO vo){ + String md5Code = vo.md5Code(); + String fileName = String.format("%s.wav",md5Code); + if(Objects.equals(false,this.voiceSynthesisUtil.checkFileIsExist(fileName))){ + byte[] data = this.voiceSynthesis(vo); + this.uploadFile(data,fileName,SYNTHESIS_FOLDER); + } + String filePath = this.voiceSynthesisUtil.getDownLoadPath(fileName); + return new VoiceCompose(filePath,md5Code,vo.getMessage()); + } + + private void uploadFile(byte[] data,String fileName,String folder){ + try{ + this.voiceSynthesisUtil.uploadBytes(data,fileName); + }catch (SimulationException e){ + log.error("文件上传失败 folder:{},文件名:{} errmsg:{}",folder,fileName,e.getMessage(),e); + throw e; + } + + + } + +} diff --git a/src/main/java/club/joylink/rtss/services/voice/IVoiceService.java b/src/main/java/club/joylink/rtss/services/voice/IVoiceService.java index b5b480c2a..ce7625e71 100644 --- a/src/main/java/club/joylink/rtss/services/voice/IVoiceService.java +++ b/src/main/java/club/joylink/rtss/services/voice/IVoiceService.java @@ -1,6 +1,6 @@ package club.joylink.rtss.services.voice; -import club.joylink.rtss.vo.client.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; import org.springframework.web.multipart.MultipartFile; public interface IVoiceService { diff --git a/src/main/java/club/joylink/rtss/services/voice/IVoiceService2.java b/src/main/java/club/joylink/rtss/services/voice/IVoiceService2.java new file mode 100644 index 000000000..b89d15172 --- /dev/null +++ b/src/main/java/club/joylink/rtss/services/voice/IVoiceService2.java @@ -0,0 +1,20 @@ +package club.joylink.rtss.services.voice; + +import club.joylink.rtss.services.voice.baidu.VoiceAsrResult; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionVO; +import org.springframework.web.multipart.MultipartFile; + +public interface IVoiceService2 { + + /** + * 识别服务器收到的语音文件 + */ + VoiceAsrResult recognition(VoiceRecognitionVO vo); + + /** + * 语音合成,返回文件路径 + */ + byte[] voiceSynthesis(BaseVoiceSynthesisVO vo); +} diff --git a/src/main/java/club/joylink/rtss/services/voice/IVoiceTrainingService.java b/src/main/java/club/joylink/rtss/services/voice/IVoiceTrainingService.java index 15bc58b86..4d2704d4c 100644 --- a/src/main/java/club/joylink/rtss/services/voice/IVoiceTrainingService.java +++ b/src/main/java/club/joylink/rtss/services/voice/IVoiceTrainingService.java @@ -2,8 +2,8 @@ package club.joylink.rtss.services.voice; import club.joylink.rtss.vo.client.PageQueryVO; import club.joylink.rtss.vo.client.PageVO; -import club.joylink.rtss.vo.client.VoiceRecognitionResult; import club.joylink.rtss.vo.client.competition.VoiceErrorVO; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; import org.springframework.web.multipart.MultipartFile; /** diff --git a/src/main/java/club/joylink/rtss/services/voice/VoiceTrainingService.java b/src/main/java/club/joylink/rtss/services/voice/VoiceTrainingService.java index c003a3734..c85586a56 100644 --- a/src/main/java/club/joylink/rtss/services/voice/VoiceTrainingService.java +++ b/src/main/java/club/joylink/rtss/services/voice/VoiceTrainingService.java @@ -5,8 +5,9 @@ import club.joylink.rtss.entity.CompetitionErrorSet; import club.joylink.rtss.simulation.cbtc.conversation.SimulationVoiceHandler; import club.joylink.rtss.vo.client.PageQueryVO; import club.joylink.rtss.vo.client.PageVO; -import club.joylink.rtss.vo.client.VoiceRecognitionResult; import club.joylink.rtss.vo.client.competition.VoiceErrorVO; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionVO; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import org.springframework.beans.factory.annotation.Autowired; @@ -23,9 +24,13 @@ public class VoiceTrainingService implements IVoiceTrainingService { @Autowired private CompetitionErrorSetDAO competitionErrorSetDAO; - @Autowired +/* @Autowired @Qualifier("baiDuVoiceService") - private IVoiceService iVoiceService; + private IVoiceService iVoiceService;*/ + + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; @Autowired private SimulationVoiceHandler simulationVoiceHandler; @@ -41,14 +46,18 @@ public class VoiceTrainingService implements IVoiceTrainingService { @Override public VoiceRecognitionResult voiceRecognition(MultipartFile file) { - VoiceRecognitionResult result = this.iVoiceService.voiceRecognition(file, ""); + VoiceRecognitionVO vo = VoiceRecognitionVO.load(file); + VoiceRecognitionResult result = this.iVoiceService.voiceRecognition(vo); +// VoiceRecognitionResult result = this.iVoiceService.voiceRecognition(file, ""); result.setResult(simulationVoiceHandler.handle(result.getResult())); return result; } @Override public VoiceRecognitionResult voiceRecognition(byte[] bytes, String filePath) { - VoiceRecognitionResult result = this.iVoiceService.voiceRecognition(bytes, filePath); + VoiceRecognitionVO vo = new VoiceRecognitionVO(bytes); + VoiceRecognitionResult result = this.iVoiceService.voiceRecognition(vo); +// VoiceRecognitionResult result = this.iVoiceService.voiceRecognition(bytes, filePath); result.setResult(simulationVoiceHandler.handle(result.getResult())); return result; } diff --git a/src/main/java/club/joylink/rtss/services/voice/baidu/BaiduVoiceServiceImpl.java b/src/main/java/club/joylink/rtss/services/voice/baidu/BaiduVoiceServiceImpl.java index 6e0f2c5bd..f9b341aa3 100644 --- a/src/main/java/club/joylink/rtss/services/voice/baidu/BaiduVoiceServiceImpl.java +++ b/src/main/java/club/joylink/rtss/services/voice/baidu/BaiduVoiceServiceImpl.java @@ -3,7 +3,7 @@ package club.joylink.rtss.services.voice.baidu; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.services.voice.IVoiceService; import club.joylink.rtss.util.VoiceFileUtils; -import club.joylink.rtss.vo.client.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/club/joylink/rtss/services/voice/baidu/TokenHolder.java b/src/main/java/club/joylink/rtss/services/voice/baidu/TokenHolder.java index 683886404..fc6506999 100644 --- a/src/main/java/club/joylink/rtss/services/voice/baidu/TokenHolder.java +++ b/src/main/java/club/joylink/rtss/services/voice/baidu/TokenHolder.java @@ -14,7 +14,7 @@ import java.util.Map; */ @Slf4j public class TokenHolder { - static final String APP_ID = "17048486"; + public static final String APP_ID = "17048486"; static final String API_KEY = "owDE3FR55ZXpZzAATbBlwKZZ"; static final String SECRET_KEY = "oFjGfwXFkIGCrK8OntwfuxgzNK4k0oNH"; private static final String SCOPE = "brain_enhanced_asr"; diff --git a/src/main/java/club/joylink/rtss/services/voice/v2/baidu/AsrService.java b/src/main/java/club/joylink/rtss/services/voice/v2/baidu/AsrService.java new file mode 100644 index 000000000..13d3659fa --- /dev/null +++ b/src/main/java/club/joylink/rtss/services/voice/v2/baidu/AsrService.java @@ -0,0 +1,54 @@ +package club.joylink.rtss.services.voice.v2.baidu; + +import club.joylink.rtss.services.voice.baidu.ConnUtil; +import club.joylink.rtss.services.voice.baidu.TokenHolder; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * 百度语音识别服务调用(当前为极速版) + */ +@Component("asrService2") +public class AsrService { + + // 文件格式, 支持pcm/wav/amr 格式,极速版额外支持m4a 格式 + private final String FORMAT = "wav"; + // 采样率固定值 + private final int RATE = 16000; + private String ASR_URL; + private static final int DEV_PID = 80001; + +// // 普通版 参数 +// { +// URL = "http://vop.baidu.com/server_api"; // 可以改为https +// // 1537 表示识别普通话,使用输入法模型。 其它语种参见文档 +// DEV_PID = 1537; +// SCOPE = "audio_voice_assistant_get"; +// } + + // 极速版 参数 + { + ASR_URL = "http://vop.baidu.com/pro_api"; // 可以改为https + } + + public String runJsonPostMethod(String token, byte[] content) throws IOException { + StringBuilder sb = new StringBuilder(ASR_URL); + sb.append("?cuid=").append(TokenHolder.APP_ID); + sb.append("&token=").append(token); + sb.append("&dev_pid=").append(DEV_PID); + + HttpURLConnection conn = (HttpURLConnection) new URL(sb.toString()).openConnection(); + conn.setConnectTimeout(10000); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "audio/wav; rate=16000"); + conn.setDoOutput(true); + conn.getOutputStream().write(content); + conn.getOutputStream().close(); + String result = ConnUtil.getResponseString(conn); + return result; + } + +} diff --git a/src/main/java/club/joylink/rtss/services/voice/v2/baidu/BaiduVoiceServiceImpl.java b/src/main/java/club/joylink/rtss/services/voice/v2/baidu/BaiduVoiceServiceImpl.java new file mode 100644 index 000000000..5d9617236 --- /dev/null +++ b/src/main/java/club/joylink/rtss/services/voice/v2/baidu/BaiduVoiceServiceImpl.java @@ -0,0 +1,174 @@ +package club.joylink.rtss.services.voice.v2.baidu; + +import club.joylink.rtss.configuration.MinioClientConfig; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.services.voice.AbstractVoiceService; +import club.joylink.rtss.services.voice.baidu.ConnUtil; +import club.joylink.rtss.services.voice.baidu.TokenHolder; +import club.joylink.rtss.services.voice.baidu.VoiceAsrResult; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionVO; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.io.PrintWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Map; + +/** + * 百度语音识别合成服务 + */ +@Slf4j +@Service("baiDuVoiceService2") +public class BaiduVoiceServiceImpl extends AbstractVoiceService { + + @Autowired + @Qualifier("asrService2") + private AsrService asrService; + + public BaiduVoiceServiceImpl(MinioClientConfig minioClientConfig) { + super(minioClientConfig); + } + +/* @Autowired + private TtsService ttsService;*/ + + + /** + * 错误码 用户输入/服务端 含义 一般解决方法 + * 3300 用户输入错误 输入参数不正确 请参考技术文档及demo,核对输入参数 + * 3301 用户输入错误 音频质量过差或没有清晰语音 请上传包含语音的清晰音频 + * 3302 用户输入错误 鉴权失败 token字段校验失败。请使用正确的API_KEY 和 SECRET_KEY生成。或并发、调用量超出限额。或音频采样率不正确(可尝试更换为16k采样率)。 + * 3303 服务端问题 百度服务器后端繁忙 有可能是原始音频质量过差。可以将api返回结果和原始音频反馈至工单、论坛或者QQ群 + * 3304 用户请求超限 用户的请求并发超限 请降低识别api请求频率(账号内所有应用APPID共用并发限额) + * 3305 用户请求超限 用户的日调用量(日请求量)超限 请开通付费,购买调用量资源(账号内所有应用APPID共用调用量限额) + * 3307 服务端问题 语音服务器后端识别出错问题 有可能是原始音频质量过差。可以将api返回结果和原始音频反馈至论坛或者QQ群 + * 3308 用户输入错误 音频过长 音频时长不超过60s或音频base64后超过2MB,请将音频时长截取为更短的音频 + * 3309 用户输入错误 音频数据问题 服务端无法将音频转为pcm格式,可能是长度问题,音频格式问题等。 请将输入的音频时长截取为60s以下,并核对下音频的编码,采样率16000,单声道,小端序,16bits + * 3310 用户输入错误 输入的音频文件过大 语音文件共有3种输入方式: json 里的speech 参数(base64后); 直接post 二进制数据;callback参数里url。 分别对应三种情况:json超过10M;直接post的语音文件超过10M;callback里回调url的音频文件超过10M + * 3311 用户输入错误 采样率rate参数不在选项里 目前rate参数仅支持16000,填写其他值即会有此错误。 + * 3312 用户输入错误 音频格式format参数不在选项里 目前格式仅仅支持pcm、wav、amr、m4a,如填写mp3即会有此错误 + * 3313 服务端问题 语音服务器解析超时 请将api返回结果反馈至工单、论坛或者QQ群 + * 3314 用户输入错误 音频长度过短 音频长度的len参数不能小于等于4 + * 3315 服务端问题 语音服务器处理超时 请将api返回结果反馈至工单、论坛或者QQ群 + * 3316 用户输入错误 音频转为pcm失败 使用pcm格式,或者确认wav和amr的采样率16000,单声道。 wav文件需要是pcm编码,小端序,16bits + * + * @param errCode + * @return + */ + private String handleErrMsg(Integer errCode) { + String errMsg = "未知错误"; + switch (errCode) { + case 3300: + case 3302: + case 3311: + case 3312: + case 3313: + case 3315: + errMsg = "参数错误或语音服务异常"; + break; + case 3301: + case 3303: + case 3307: + errMsg = "音频质量过差或没有清晰语音或识别异常"; + break; + case 3304: + log.error("百度语音识别请求并发超限"); + errMsg = "参数错误或语音服务异常"; + break; + case 3308: + case 3310: + case 3314: + errMsg = "音频时长过长或过短"; + break; + case 3309: + case 3316: + errMsg = "音频格式错误"; + break; + } + return errMsg; + } + + + @Override + public VoiceAsrResult recognition(VoiceRecognitionVO vo) { + try{ + String json = this.asrService.runJsonPostMethod(TokenHolder.getInstance().getToken(),vo.getData()); + log.info(String.format("百度语音识别结果:[%s]", json)); + VoiceAsrResult result = VoiceAsrResult.fromJson(json); + BusinessExceptionAssertEnum.THIRD_SERVICE_CALL_EXCEPTION + .assertTrue(result.getErr_no() == 0, + handleErrMsg(result.getErr_no())); + return result; + }catch (IOException e){ + throw new RuntimeException(e); + } + + } + /** + * spd 选填 语速,取值0-15,默认为5中语速 + * pit 选填 音调,取值0-15,默认为5中语调 + * vol 选填 音量,取值0-15,默认为5中音量(取值为0时为音量最小值,并非为无声) + * per(基础音库) 选填 度小宇=1,度小美=0,度逍遥(基础)=3,度丫丫=4 + * per(精品音库) 选填 度逍遥(精品)=5003,度小鹿=5118,度博文=106,度小童=110,度小萌=111,度米朵=103,度小娇=5 + * aue 选填 3为mp3格式(默认); 4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k); 注意aue=4或者6是语音识别要求的格式,但是音频内容不是语音识别要求的自然人发音,所以识别效果会受影响。 + */ + +// private String aue = "6"; + + private Map toMapParam(BaseVoiceSynthesisVO vo) { + Map dataMap = Maps.newHashMap(); + vo.checkBaiduParam(); + dataMap.put("spd",vo.getSpd()); + dataMap.put("pit",vo.getPit()); + dataMap.put("vol",vo.getVol()); + dataMap.put("pre",vo.getPer()); + dataMap.put("aue","6"); + return dataMap; + } + + @Override + public byte[] voiceSynthesis(BaseVoiceSynthesisVO vo) { + try { + byte[] data = this.run(vo, TokenHolder.getInstance().getToken()); + return data; + } catch (IOException e) { + throw BusinessExceptionAssertEnum.THIRD_SERVICE_CALL_EXCEPTION.exception(); + } + } + + public final static String TEXT_VOICE_URL = "http://tsn.baidu.com/text2audio"; // 可以使用https + + private byte[] run(BaseVoiceSynthesisVO vo, String token) throws IOException { + StringBuilder sb = new StringBuilder("tex="); + // 此处2次urlencode, 确保特殊字符被正确编码 + sb.append(ConnUtil.urlEncode(ConnUtil.urlEncode(vo.getMessage()))); + Map dataMap = toMapParam(vo); + dataMap.forEach((k,v)->{ + sb.append("&").append(k).append("=").append(v); + }); + sb.append("&cuid=").append(TokenHolder.APP_ID); + sb.append("&tok=").append(token); + sb.append("&lan=zh&ctp=1"); + HttpURLConnection conn = (HttpURLConnection) new URL(TEXT_VOICE_URL).openConnection(); + conn.setDoInput(true); + conn.setDoOutput(true); + conn.setConnectTimeout(9000); + PrintWriter printWriter = new PrintWriter(conn.getOutputStream()); + printWriter.write(sb.toString()); + printWriter.close(); + String contentType = conn.getContentType(); + if (contentType.contains("audio/")) { + return ConnUtil.getResponseBytes(conn); + } else { + String res = ConnUtil.getResponseString(conn); + throw new RuntimeException(String.format("百度语音合成失败:%s",res)); + } + } + +} diff --git a/src/main/java/club/joylink/rtss/services/voice/xunfei/XunFeiVoiceService.java b/src/main/java/club/joylink/rtss/services/voice/xunfei/XunFeiVoiceService.java index 6dc580e4a..dc344ed39 100644 --- a/src/main/java/club/joylink/rtss/services/voice/xunfei/XunFeiVoiceService.java +++ b/src/main/java/club/joylink/rtss/services/voice/xunfei/XunFeiVoiceService.java @@ -3,7 +3,7 @@ package club.joylink.rtss.services.voice.xunfei; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.services.voice.IVoiceService; import club.joylink.rtss.util.VoiceFileUtils; -import club.joylink.rtss.vo.client.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; import okhttp3.OkHttpClient; import okhttp3.Request; import org.springframework.stereotype.Service; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/rail/dcmd/data/DisCmdDb.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/rail/dcmd/data/DisCmdDb.java index aca14c932..f4e16dea1 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/rail/dcmd/data/DisCmdDb.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/rail/dcmd/data/DisCmdDb.java @@ -174,8 +174,8 @@ public class DisCmdDb { case TrainSrmSent: case TrainSrmReceived:r.setSrmStationCode(cp.getTransStationCode());break; case Signed:r.setRcCpCode(member.getDevice().getCode()); - case ProxySigned:r.setSignedBy(member.getName());break; - case Rejected:r.setRejectBy(member.getName());break; + case ProxySigned:r.setSignedBy(member.getId());break; + case Rejected:r.setRejectBy(member.getId());break; } // return r; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/rail/dcmd/data/DisCmdReceipt.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/rail/dcmd/data/DisCmdReceipt.java index b2842e060..7e7bbc25d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/rail/dcmd/data/DisCmdReceipt.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/rail/dcmd/data/DisCmdReceipt.java @@ -34,11 +34,11 @@ public class DisCmdReceipt { */ private String rcCpCode; /** - * 签收人(仿真角色名称) + * 签收人(仿真角色id) */ private String signedBy; /** - * 拒签人(仿真角色名称) + * 拒签人(仿真角色id) */ private String rejectBy; /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ISCS/OnBoardPisService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ISCS/OnBoardPisService.java index e8cf070c2..44aae3f31 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ISCS/OnBoardPisService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ISCS/OnBoardPisService.java @@ -1,10 +1,11 @@ package club.joylink.rtss.simulation.cbtc.ISCS; -import club.joylink.rtss.services.voice.IVoiceService; +import club.joylink.rtss.services.voice.AbstractVoiceService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.vo.client.iscs.Ats2PisMsg; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -14,10 +15,13 @@ import org.springframework.stereotype.Component; */ @Component public class OnBoardPisService { - @Autowired + /*@Autowired @Qualifier("baiDuVoiceService") - private IVoiceService iVoiceService; + private IVoiceService iVoiceService;*/ + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; public void play(Simulation simulation, Ats2PisMsg msg) { String content; if (msg.isArrivalMsg()) { @@ -26,7 +30,9 @@ public class OnBoardPisService { } else { content = "本次列车开往" + msg.getTerminalStation().getName() + "方向,下一站" + msg.getStation().getName(); } - String path = iVoiceService.synthesis(content); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(content); + String path = iVoiceService.synthesis(vo).getFilePath(); +// String path = iVoiceService.synthesis(content); SimulationDataRepository repository = simulation.getRepository(); VirtualRealityTrain train = repository.getOnlineTrainBy(msg.getGroupNumber()); train.getVrAudio().updateUrl(path); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/competition/CompetitionAndScriptManager.java b/src/main/java/club/joylink/rtss/simulation/cbtc/competition/CompetitionAndScriptManager.java index ea890974e..777bf5d1e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/competition/CompetitionAndScriptManager.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/competition/CompetitionAndScriptManager.java @@ -2,7 +2,7 @@ package club.joylink.rtss.simulation.cbtc.competition; import club.joylink.rtss.dao.CompetitionErrorSetDAO; import club.joylink.rtss.entity.CompetitionErrorSet; -import club.joylink.rtss.services.voice.IVoiceService; +import club.joylink.rtss.services.voice.AbstractVoiceService; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.SimulationLifeCycleService; @@ -25,6 +25,7 @@ import club.joylink.rtss.util.JsonUtils; import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.client.competition.OperationIndexStatistic; import club.joylink.rtss.vo.client.competition.OperationStatisticVO; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -57,10 +58,12 @@ public class CompetitionAndScriptManager { @Autowired private ConversationManagerService conversationManagerService; - @Autowired +/* @Autowired @Qualifier("baiDuVoiceService") - private IVoiceService iVoiceService; - + private IVoiceService iVoiceService;*/ + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; @Autowired private CompetitionErrorSetDAO competitionErrorSetDAO; @@ -264,7 +267,9 @@ public class CompetitionAndScriptManager { SimulationMember otherMember = conversation.findOtherMember(conversationMessageMember); if (otherMember != null) { String reply = "什么意思?"; - String path = iVoiceService.synthesis(reply, "0"); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(reply); + String path = iVoiceService.synthesis(vo).getFilePath(); +// String path = iVoiceService.synthesis(reply, "0"); conversationManagerService.chat(simulation, conversation, otherMember, reply, path); } log.info(String.format("竞赛[%s]用户[%s]演练时,于不正确的时机发送消息", @@ -311,7 +316,9 @@ public class CompetitionAndScriptManager { SimulationMember otherMember = conversation.findOtherMember(conversationMessageMember); if (otherMember != null) { String reply = "请重复"; - String path = iVoiceService.synthesis(reply, "0"); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(reply); + String path = iVoiceService.synthesis(vo).getFilePath(); +// String path = iVoiceService.synthesis(reply, "0"); conversationManagerService.chat(simulation, conversation, otherMember, reply, path); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/competition/ScriptExecuteService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/competition/ScriptExecuteService.java index 6fca8595a..36aa5782b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/competition/ScriptExecuteService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/competition/ScriptExecuteService.java @@ -1,7 +1,7 @@ package club.joylink.rtss.simulation.cbtc.competition; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; -import club.joylink.rtss.services.voice.IVoiceService; +import club.joylink.rtss.services.voice.AbstractVoiceService; import club.joylink.rtss.simulation.cbtc.ATS.operation.AtsOperationDispatcher; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.Simulation; @@ -19,6 +19,7 @@ import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.script.ScriptActionBO; import club.joylink.rtss.simulation.cbtc.script.ScriptBO; import club.joylink.rtss.util.StrUtils; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -43,9 +44,13 @@ public class ScriptExecuteService { @Autowired private ConversationManagerService conversationManagerService; - @Autowired + /*@Autowired @Qualifier("baiDuVoiceService") - private IVoiceService iVoiceService; + private IVoiceService iVoiceService;*/ + + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; @Autowired private ApplicationContext applicationContext; @@ -89,8 +94,11 @@ public class ScriptExecuteService { Pattern pattern = Pattern.compile("([0-9]+)(发音:([幺两三四五六拐八九洞]*))"); Matcher matcher = pattern.matcher(content); content = matcher.replaceAll("$2"); + String tmpContent = content.replaceAll("行调", "行吊"); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(tmpContent); - String path = iVoiceService.synthesis(content.replaceAll("行调", "行吊"), "0"); + String path = iVoiceService.synthesis(vo).getFilePath(); +// String path = iVoiceService.synthesis(content.replaceAll("行调", "行吊"), "0"); String messageId = conversationManagerService.chat(simulation, conversation, member, content, path); action.setConversationMessageId(messageId); break; @@ -186,7 +194,9 @@ public class ScriptExecuteService { for (ConversationMember conversationMember : conversation.getMemberList()) { SimulationMember otherMember = conversationMember.getMember(); if (!Objects.equals(otherMember.getId(), member.getId())) { - String path = iVoiceService.synthesis("我没听懂", "0"); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO("我没听懂"); + String path = iVoiceService.synthesis(vo).getFilePath(); +// String path = iVoiceService.synthesis("我没听懂", "0"); conversationManagerService.chat(simulation, conversation, otherMember, "我没听懂", path); return; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/ConversationManagerService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/ConversationManagerService.java index 4e385cbbc..16c19279b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/ConversationManagerService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/ConversationManagerService.java @@ -1,6 +1,6 @@ package club.joylink.rtss.simulation.cbtc.conversation; -import club.joylink.rtss.services.voice.IVoiceService; +import club.joylink.rtss.services.voice.AbstractVoiceService; import club.joylink.rtss.simulation.cbtc.GroupSimulationCache; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.competition.ScriptExecuteService; @@ -13,9 +13,11 @@ import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.member.SimulationUser; import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.client.SocketMessageVO; -import club.joylink.rtss.vo.client.VoiceRecognitionResult; import club.joylink.rtss.vo.client.WebSocketMessageType; import club.joylink.rtss.vo.client.factory.SocketMessageFactory; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; +import club.joylink.rtss.vo.client.voice.VoiceRecognitionVO; import club.joylink.rtss.websocket.StompMessageService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -40,10 +42,12 @@ public class ConversationManagerService { @Autowired private GroupSimulationCache groupSimulationCache; - @Autowired +/* @Autowired @Qualifier("baiDuVoiceService") - private IVoiceService iVoiceService; - + private IVoiceService iVoiceService;*/ + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; @Autowired private SimulationVoiceHandler simulationVoiceHandler; @@ -264,7 +268,10 @@ public class ConversationManagerService { Simulation simulation = groupSimulationCache.getSimulationByGroup(group); Conversation conversation = simulation.getSimulationConversationById(conversationId); SimulationMember member = simulation.getSimulationMemberByUserId(accountVO.getId()); - VoiceRecognitionResult recognitionResult = iVoiceService.voiceRecognition(file, ""); + VoiceRecognitionVO vo = VoiceRecognitionVO.load(file); + + VoiceRecognitionResult recognitionResult = iVoiceService.voiceRecognition(vo); +// VoiceRecognitionResult recognitionResult = iVoiceService.voiceRecognition(file, ""); String upperCaseResult = recognitionResult.getResult().toUpperCase(); String handledContent = simulationVoiceHandler.handle(upperCaseResult); chat(simulation, conversation, member, handledContent, recognitionResult.getFilePath()); @@ -299,7 +306,9 @@ public class ConversationManagerService { throw new SimulationException(SimulationExceptionType.System_Fault, String.format("会话[%s]不包含该成员[%s]", id, member.getId())); } String content = text.getContent(); - String path = iVoiceService.synthesis(content, "0"); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(content); + String path = iVoiceService.synthesis(vo).getFilePath(); +// String path = iVoiceService.synthesis(content, "0"); chat(simulation, conversation, member, content, path); } @@ -367,7 +376,9 @@ public class ConversationManagerService { } String path = audioPath; if (StringUtils.isEmpty(audioPath)) { - path = iVoiceService.synthesis(content, "0"); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(content); + path = iVoiceService.synthesis(vo).getFilePath(); +// path = iVoiceService.synthesis(content, "0"); } chat(simulation, conversation, member, content, path); } @@ -397,7 +408,9 @@ public class ConversationManagerService { * 文件BASE64编码 */ public ConversationMessageVO conversationChat(Simulation simulation, SimulationMember member, String fileBase64Str) { - VoiceRecognitionResult recognitionResult = iVoiceService.voiceRecognition(fileBase64Str); + VoiceRecognitionVO vo = VoiceRecognitionVO.load(fileBase64Str); + VoiceRecognitionResult recognitionResult = iVoiceService.voiceRecognition(vo); +// VoiceRecognitionResult recognitionResult = iVoiceService.voiceRecognition(fileBase64Str); String upperCaseResult = recognitionResult.getResult().toUpperCase(); String handledContent = simulationVoiceHandler.handle(upperCaseResult); ConversationMessage conversationMessage = new ConversationMessage(simulation.getIdGenerator().nextConversationMessageId(), diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotBehaviorActuator.java b/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotBehaviorActuator.java index fe9c4d970..7318842ce 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotBehaviorActuator.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotBehaviorActuator.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.cbtc.robot; +import club.joylink.rtss.services.voice.AbstractVoiceService; import club.joylink.rtss.simulation.cbtc.ATS.operation.AtsOperationDispatcher; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.Simulation; @@ -7,7 +8,6 @@ import club.joylink.rtss.simulation.cbtc.command.Command; import club.joylink.rtss.simulation.cbtc.command.OperationMessage; import club.joylink.rtss.simulation.cbtc.conversation.ConversationManagerService; import club.joylink.rtss.simulation.cbtc.member.SimulationMember; -import club.joylink.rtss.services.voice.IVoiceService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -22,9 +22,13 @@ import java.util.Objects; @Slf4j public class RobotBehaviorActuator { - @Autowired + /*@Autowired @Qualifier("baiDuVoiceService") private IVoiceService iVoiceService; + */ + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; @Autowired private AtsOperationDispatcher atsOperationDispatcher; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotListenerHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotListenerHandler.java index ea82d86a2..6f0d182f8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotListenerHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotListenerHandler.java @@ -1,6 +1,6 @@ package club.joylink.rtss.simulation.cbtc.robot; -import club.joylink.rtss.services.voice.IVoiceService; +import club.joylink.rtss.services.voice.AbstractVoiceService; import club.joylink.rtss.simulation.cbtc.GroupSimulationService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.command.CommandBO; @@ -16,6 +16,7 @@ import club.joylink.rtss.simulation.cbtc.event.SimulationConversationExitEvent; import club.joylink.rtss.simulation.cbtc.event.SimulationOperationMessageEvent; import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService; +import club.joylink.rtss.vo.client.voice.BaseVoiceSynthesisVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -44,9 +45,13 @@ public class RobotListenerHandler { @Autowired private ATOService ATOService; - @Autowired + /*@Autowired @Qualifier("baiDuVoiceService") - private IVoiceService iVoiceService; + private IVoiceService iVoiceService;*/ + + @Autowired + @Qualifier("baiDuVoiceService2") + private AbstractVoiceService iVoiceService; @Autowired private GroupSimulationService groupSimulationService; @@ -111,7 +116,9 @@ public class RobotListenerHandler { } if (conversation.getSimulationMemberList().stream().anyMatch(member1 -> Objects.equals(member1.getId(), receiver.getId()))) { String reply = voiceCommandBO.buildReply(matcher); - String path = iVoiceService.synthesis(reply, "0"); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(reply); + String path = iVoiceService.synthesis(vo).getFilePath(); +// String path = iVoiceService.synthesis(reply, "0"); conversationManagerService.chat(simulation, conversation, receiver, reply, path); CommandBO.CommandType commandType = voiceCommandBO.getCommand(); if (commandType != null) { @@ -121,7 +128,9 @@ public class RobotListenerHandler { } return; } - String path = iVoiceService.synthesis(unrecognized, "0"); + BaseVoiceSynthesisVO vo = new BaseVoiceSynthesisVO(unrecognized); + String path = iVoiceService.synthesis(vo).getFilePath(); +// String path = iVoiceService.synthesis(unrecognized, "0"); for (ConversationMember conversationMember : conversation.getMemberList()) { if (!Objects.equals(conversationMember.getMember(), member) && conversationMember.isConnect() && conversationMember.isRobot()) { conversationManagerService.chat(simulation, conversation, conversationMember.getMember(), unrecognized, path); diff --git a/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java b/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java index 3e0b9fa44..79d0ce532 100644 --- a/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java +++ b/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java @@ -15,26 +15,6 @@ public enum WebSocketMessageType { * 订单支付结果 */ Order_Pay_Result, - /** - * 综合演练室-房间消息 - */ - JointTraining_Room, - /** - * 综合演练室-房间邀请消息 - */ - JointTraining_Room_Invite, - /** - * 综合演练室-用户消息 - */ - JointTraining_User, - /** - * 综合演练-设备消息 - */ - JointTraining_Device, - /** - * 综合演练室-群聊消息 - */ - JointTraining_Chat, /** * 被登出消息 */ @@ -158,26 +138,14 @@ public enum WebSocketMessageType { * 仿真-控制权转换申请回复 */ Simulation_ControlTransfer_Reply, - /** - * 仿真-回放会话消息 - */ - Simulation_PlayBack_Conversation, /** * 仿真-结束消息 */ Simulation_Over, - /** - * 仿真-权限用完 - */ - Simulation_Permission_Over, /** * 仿真-任务已加载 */ Simulation_Quest_Loaded, - /** - * 仿真-任务完成 - */ - Simulation_Quest_Finish, /** * 仿真-退出任务 */ @@ -200,10 +168,6 @@ public enum WebSocketMessageType { * 仿真-退出剧本 */ Simulation_Script_Quit, - /** - * 仿真-剧本完成 - */ - Simulation_Script_Finish, /** * 仿真-竞赛实操完成 */ @@ -229,10 +193,6 @@ public enum WebSocketMessageType { * 仿真-暂停/开始消息 */ Simulation_Control_Pause, - /** - * 仿真回放完成消息 - */ - Simulation_PlayBack_Finish, /** * 仿真驾驶数据路由 */ diff --git a/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java b/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java index 4bb581d85..7ac06b1a6 100644 --- a/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java +++ b/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java @@ -70,23 +70,11 @@ public class SocketMessageFactory { } case BROADCAST: case Order_Pay_Result: - case JointTraining_Room_Invite: case Be_Logged_Out: case Simulation_Invite: { topicList.add(WebSocketSubscribeTopic.Common); break; } - case JointTraining_Room: - case JointTraining_Device: - case JointTraining_Chat: { - topicList.add(SimulationSubscribeTopic.Room.buildDestination(group)); - break; - } - case JointTraining_User: { - topicList.add(SimulationSubscribeTopic.Room.buildDestination(group)); - topicList.add(SimulationSubscribeTopic.WeChatMini.buildDestination(group)); - break; - } case Simulation_Time_Sync: case Simulation_User: case Simulation_Member: @@ -98,14 +86,10 @@ public class SocketMessageFactory { case Simulation_RunAsPlan_Start: case Simulation_RunFact: case Simulation_ApplyHandle: - case Simulation_PlayBack_Conversation: case Simulation_Control_Pause: - case Simulation_Permission_Over: case Simulation_Run_Plan_Reload: case Simulation_Trip_Plan_Change: case Simulation_Scenes_Reload: - case Simulation_Quest_Finish: - case Simulation_PlayBack_Finish: case Competition_Practical: case SIMULATION_RAIL_TICKET: case Simulation_Alarm: { @@ -139,7 +123,6 @@ public class SocketMessageFactory { case Simulation_Script_Action_Tip: case Simulation_Script_Action_Finish: case Simulation_Script_Action_Error: - case Simulation_Script_Finish: case Simulation_Competition_Practice_Finish: case Simulation_Script_Action: case Simulation_Driver_Change: diff --git a/src/main/java/club/joylink/rtss/vo/client/pager/question/QuestionQueryVO.java b/src/main/java/club/joylink/rtss/vo/client/pager/question/QuestionQueryVO.java new file mode 100644 index 000000000..653325f98 --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/client/pager/question/QuestionQueryVO.java @@ -0,0 +1,18 @@ +package club.joylink.rtss.vo.client.pager.question; + +import club.joylink.rtss.vo.client.PageQueryVO; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class QuestionQueryVO extends PageQueryVO { + + private String topic; + + private String type; + +// private String projectCode; + private Long companyId; + +} diff --git a/src/main/java/club/joylink/rtss/vo/client/voice/BaseVoiceSynthesisVO.java b/src/main/java/club/joylink/rtss/vo/client/voice/BaseVoiceSynthesisVO.java new file mode 100644 index 000000000..3fb5a4243 --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/client/voice/BaseVoiceSynthesisVO.java @@ -0,0 +1,116 @@ +package club.joylink.rtss.vo.client.voice; + +import club.joylink.rtss.util.EncryptUtil; +import lombok.Data; + +@Data + +public class BaseVoiceSynthesisVO { + /** + * 消息 + */ + private String message; + /** + * 语速 + */ + private int spd; + /** + * 音调 + */ + private int pit; + /** + * 音量 + */ + private int vol; + /** + * 语音样式 + */ + private String per; + /** + * 是否启用默认参数 + */ + private boolean defaultParam = true; + + public BaseVoiceSynthesisVO(String message){ + this.message = message; + + } + public BaseVoiceSynthesisVO(String message,boolean defaultParam){ + this.message = message; + this.defaultParam = defaultParam; + } + + /** + * spd 选填 语速,取值0-15,默认为5中语速 + * pit 选填 音调,取值0-15,默认为5中语调 + * vol 选填 音量,取值0-15,默认为5中音量(取值为0时为音量最小值,并非为无声) + * per(基础音库) 选填 度小宇=1,度小美=0,度逍遥(基础)=3,度丫丫=4 + * per(精品音库) 选填 度逍遥(精品)=5003,度小鹿=5118,度博文=106,度小童=110,度小萌=111,度米朵=103,度小娇=5 + * aue 选填 3为mp3格式(默认); 4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k); 注意aue=4或者6是语音识别要求的格式,但是音频内容不是语音识别要求的自然人发音,所以识别效果会受影响。 + */ + public void checkBaiduParam(){ + if(this.spd <0 || this.spd > 15){ + this.spd = 5; + } + if(this.pit < 0 || this.pit > 15){ + this.pit = 5; + } + if(this.vol < 0 || this.vol> 15){ + this.vol = 5; + } + if(this.defaultParam){ + this.spd = 5; + this.pit = 5; + this.vol = 10; + } + } + +/* public SynthesisXunFei toBuildXunFei(){ + if(this.spd <0 || this.spd > 100){ + this.spd = 50; + } + if(this.pit < 0 || this.pit > 100){ + this.pit = 50; + } + if(this.vol < 0 || this.vol> 100){ + this.vol = 50; + } + SynthesisXunFei fei = new SynthesisXunFei(this.message); + return fei; + }*/ + + public String md5Code(){ + String msgStr = String.format("%s:%s:%s:%s:%s",this.per,this.spd,this.pit,this.vol,this.message); + String md5Code = EncryptUtil.md5(msgStr); + return md5Code; + } + + /* public static class SynthesisXunFei extends BaseVoiceSynthesisVO { + *//** + * voice_name 合成发音人 合成所需发音人,对应发音人参数可在控制台"发音人授权管理"查看。 + * speed 语速 通过此参数,设置合成返回音频的语速。默认值:50,取值范围:[0,100]。 + * volume 音量 通过此参数,设置合成返回音频的音量。默认值:50,取值范围:[0,100]。 + * pitch 语调 通过此参数,设置合成返回音频的语调。默认值:50,取值范围:[0,100]。 + * sample_rate 采样率 音频的采样率是音频属性的其中一个,一般来说,采样率越高音频的质量越好,识别的匹配率越高,但上传带宽消耗也越大。 默认:16KHZ,取值{8KHZ,16KHZ}。 + * tts_audio_path 合成录音保存路径 通过此参数,可以在合成完成后在本地保存一个音频文件 。 + * engine_type 引擎类型 设置使用的引擎类型:在线、离线、混合。在线合成设置参数为:"cloud" 。 + * + *//* + + private String engine_type = "cloud"; + public SynthesisXunFei(String message) { + super(message); + } + + @Override + public Map toMapParam() { + Map dataMap = Maps.newHashMap(); + dataMap.put("speed",this.getSpd()); + dataMap.put("volume",this.getVol()); + dataMap.put("pitch",this.getPit()); + dataMap.put("voice_name",this.getPer()); + dataMap.put("engine_type",this.engine_type); + return dataMap; + } + }*/ +} diff --git a/src/main/java/club/joylink/rtss/vo/client/voice/VoiceCompose.java b/src/main/java/club/joylink/rtss/vo/client/voice/VoiceCompose.java new file mode 100644 index 000000000..f3f51a15a --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/client/voice/VoiceCompose.java @@ -0,0 +1,19 @@ +package club.joylink.rtss.vo.client.voice; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class VoiceCompose { + + private String filePath; + private String identity; + private String message; + + public VoiceCompose(String filePath, String identity, String message) { + this.filePath = filePath; + this.identity = identity; + this.message = message; + } +} diff --git a/src/main/java/club/joylink/rtss/vo/client/VoiceRecognitionResult.java b/src/main/java/club/joylink/rtss/vo/client/voice/VoiceRecognitionResult.java similarity index 76% rename from src/main/java/club/joylink/rtss/vo/client/VoiceRecognitionResult.java rename to src/main/java/club/joylink/rtss/vo/client/voice/VoiceRecognitionResult.java index e867d3b50..d331a7081 100644 --- a/src/main/java/club/joylink/rtss/vo/client/VoiceRecognitionResult.java +++ b/src/main/java/club/joylink/rtss/vo/client/voice/VoiceRecognitionResult.java @@ -1,5 +1,6 @@ -package club.joylink.rtss.vo.client; +package club.joylink.rtss.vo.client.voice; +import club.joylink.rtss.services.voice.baidu.VoiceAsrResult; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -13,8 +14,10 @@ public class VoiceRecognitionResult { private String result; + public VoiceRecognitionResult(String filePath, String result) { this.filePath = filePath; this.result = result; + } } diff --git a/src/main/java/club/joylink/rtss/vo/client/voice/VoiceRecognitionVO.java b/src/main/java/club/joylink/rtss/vo/client/voice/VoiceRecognitionVO.java index a2b50787e..e7d48f142 100644 --- a/src/main/java/club/joylink/rtss/vo/client/voice/VoiceRecognitionVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/voice/VoiceRecognitionVO.java @@ -11,35 +11,40 @@ import java.util.Base64; @Slf4j public class VoiceRecognitionVO { private byte[] data; - private String filePath; + private String fileContentType; - public VoiceRecognitionVO(String filePath){ - this.filePath = filePath; + public VoiceRecognitionVO(byte[] data){ + this.data = data; + this.fileContentType = "audio/wav"; } - public VoiceRecognitionVO(String filePath,MultipartFile file){ - this(filePath); - this.load(file); + public VoiceRecognitionVO(byte[] data,String contentType){ + this.data = data; + this.fileContentType = contentType; } - public VoiceRecognitionVO(String filePath,String base64Str){ - this(filePath); - this.load(base64Str); - } - public VoiceRecognitionVO(String filePath,byte[] bb){ - this(filePath); - this.data = bb; - } - private void load(MultipartFile file){ + + + + + public static VoiceRecognitionVO load(MultipartFile file){ try { - this.data = file.getBytes(); + VoiceRecognitionVO vo = new VoiceRecognitionVO(file.getBytes(),file.getContentType()); + return vo; } catch (IOException e) { - log.error("加载数据失败 file{}",file.getOriginalFilename() + " errMsg:{}",e.getMessage(),e); - this.data = new byte[0]; + log.error("加载数据失败 file{}",file.getOriginalFilename() + " errMsg:{}",file.getOriginalFilename(),e.getMessage(),e); + throw new RuntimeException(e); } } - - private void load(String base64Str){ - String base64 = base64Str.substring(base64Str.indexOf("base64,") + "base64,".length()); + public static VoiceRecognitionVO load(String base64Str){ + int index = base64Str.indexOf("base64,"); + String base64 = base64Str.substring(index + "base64,".length()); byte[] bytes = Base64.getDecoder().decode(base64.trim()); - this.data = bytes; + + int dataIndex = base64Str.indexOf("data:"); + String fileContentType = null; + if(dataIndex >= 0){ + fileContentType = base64Str.substring( + "data:".length(),index -1 ); + } + return new VoiceRecognitionVO(bytes,fileContentType); } + } diff --git a/src/main/java/club/joylink/rtss/vo/paper/FindPaperCompositionPageReqVo.java b/src/main/java/club/joylink/rtss/vo/paper/FindPaperCompositionPageReqVo.java index 99c059fa1..ec74e7e1f 100644 --- a/src/main/java/club/joylink/rtss/vo/paper/FindPaperCompositionPageReqVo.java +++ b/src/main/java/club/joylink/rtss/vo/paper/FindPaperCompositionPageReqVo.java @@ -31,16 +31,6 @@ public class FindPaperCompositionPageReqVo extends PageQueryVO { * 选填
*/ private Boolean nameLike = true; - /** - * 组织id
- * 选填
- */ - private String companyId; - /** - * 项目code--是否模糊查询,默认false
- * 选填
- */ - private Boolean projectCodeLike = false; /** * 试卷蓝图简介
* 选填
diff --git a/src/main/java/club/joylink/rtss/vo/paper/PaperQType.java b/src/main/java/club/joylink/rtss/vo/paper/PaperQType.java index a7c6e7f53..c243416e0 100644 --- a/src/main/java/club/joylink/rtss/vo/paper/PaperQType.java +++ b/src/main/java/club/joylink/rtss/vo/paper/PaperQType.java @@ -1,5 +1,6 @@ package club.joylink.rtss.vo.paper; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; @@ -10,6 +11,15 @@ import java.util.Map; * 试卷试题子类型 */ public class PaperQType { + + public static void assertPaperSubTypeMatchGroupType(SubType sub,GroupType type){ + boolean match = false; + switch (type){ + case Training:match= sub.getValue()>=4;break; + case Common:match=sub.getValue()<=3;break; + } + BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(match,"试卷试题小类型["+sub.name()+"]与大类型["+type.name()+"]不匹配"); + } /** * 试卷试题大类型:1-理论题,2-实训题 */ @@ -53,6 +63,7 @@ public class PaperQType { Select(1), Multi(2), Judge(3), + ////////////// Single(4), Scene(5), ; diff --git a/src/main/java/club/joylink/rtss/vo/paper/PaperSubmitAnswerReqVo.java b/src/main/java/club/joylink/rtss/vo/paper/PaperSubmitAnswerReqVo.java index 6c23e8813..bcb5e882b 100644 --- a/src/main/java/club/joylink/rtss/vo/paper/PaperSubmitAnswerReqVo.java +++ b/src/main/java/club/joylink/rtss/vo/paper/PaperSubmitAnswerReqVo.java @@ -32,7 +32,11 @@ public class PaperSubmitAnswerReqVo { @NotNull private PaperQType.SubType subType; /** - * 答案 + * 理论试题答案 */ private List answer; + /** + * 实训题完成结果,true-实训题成功完成,false-实训题未成功完成 + */ + private Boolean trainingSuccess; }