diff --git a/cmvr-iot-admin/pom.xml b/cmvr-iot-admin/pom.xml
index f9b6aa2..8d72ab6 100644
--- a/cmvr-iot-admin/pom.xml
+++ b/cmvr-iot-admin/pom.xml
@@ -60,6 +60,12 @@
cmvr-iot-device
+
+
+ com.cmvr
+ cmvr-iot-vi
+
+
dev
diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViCorpusController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViCorpusController.java
new file mode 100644
index 0000000..bd90e29
--- /dev/null
+++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViCorpusController.java
@@ -0,0 +1,99 @@
+package com.cmvr.web.controller.vi;
+
+import com.cmvr.common.core.controller.BaseController;
+import com.cmvr.common.core.domain.AjaxResult;
+import com.cmvr.common.core.page.TableDataInfo;
+import com.cmvr.vi.model.domain.ViCorpus;
+import com.cmvr.vi.service.IViCorpusService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 语料库Controller
+ *
+ * @author cmvr-iot
+ */
+@Api(tags = "语音交互--语料库")
+@RestController
+@RequestMapping("/vi/corpus")
+@RequiredArgsConstructor
+public class ViCorpusController extends BaseController {
+
+ private final IViCorpusService viCorpusService;
+
+ /**
+ * 查询语料库列表
+ */
+ @ApiOperation("查询语料库列表")
+ @PreAuthorize("@ss.hasPermi('vi:corpus:list')")
+ @GetMapping("/list")
+ public TableDataInfo list(ViCorpus viCorpus) {
+ startPage();
+ List list = viCorpusService.selectViCorpusList(viCorpus);
+ return getDataTable(list);
+ }
+
+// /**
+// * 导出语料库列表
+// */
+// @ApiOperation("查询语料库列表")
+// @PreAuthorize("@ss.hasPermi('vi:corpus:export')")
+// @PostMapping("/export")
+// public void export(HttpServletResponse response, ViCorpus viCorpus) {
+// List list = viCorpusService.selectViCorpusList(viCorpus);
+// ExcelUtil util = new ExcelUtil(ViCorpus.class);
+// util.exportExcel(response, list, "语料库数据");
+// }
+
+ /**
+ * 获取语料库详细信息
+ */
+ @ApiOperation("根据id获取语料库详细信息")
+ @PreAuthorize("@ss.hasPermi('vi:corpus:query')")
+ @GetMapping(value = "/{corpusId}")
+ public AjaxResult getInfo(@PathVariable("corpusId") Long corpusId) {
+ return success(viCorpusService.selectViCorpusByCorpusId(corpusId));
+ }
+
+ /**
+ * 新增语料库
+ */
+ @ApiOperation("新增语料库")
+ @PreAuthorize("@ss.hasPermi('vi:corpus:add')")
+ @PostMapping
+ public AjaxResult add(@RequestBody ViCorpus viCorpus) {
+ return toAjax(viCorpusService.insertViCorpus(viCorpus));
+ }
+
+ /**
+ * 修改语料库
+ */
+ @ApiOperation("修改语料库")
+ @PreAuthorize("@ss.hasPermi('vi:corpus:edit')")
+ @PutMapping
+ public AjaxResult edit(@RequestBody ViCorpus viCorpus) {
+ return toAjax(viCorpusService.updateViCorpus(viCorpus));
+ }
+
+ /**
+ * 删除语料库
+ */
+ @ApiOperation("删除语料库")
+ @PreAuthorize("@ss.hasPermi('vi:corpus:remove')")
+ @DeleteMapping("/{corpusIds}")
+ public AjaxResult remove(@PathVariable Long[] corpusIds) {
+ return toAjax(viCorpusService.deleteViCorpusByCorpusIds(corpusIds));
+ }
+}
diff --git a/cmvr-iot-vi/pom.xml b/cmvr-iot-vi/pom.xml
new file mode 100644
index 0000000..e5c2a34
--- /dev/null
+++ b/cmvr-iot-vi/pom.xml
@@ -0,0 +1,28 @@
+
+
+ 4.0.0
+
+ com.cmvr
+ cmvr-iot
+ 3.8.9
+
+
+ cmvr-iot-vi
+
+
+ 语音交互模块
+
+
+
+
+
+
+ com.cmvr
+ cmvr-iot-common
+
+
+
+
+
\ No newline at end of file
diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/mapper/ViCorpusMapper.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/mapper/ViCorpusMapper.java
new file mode 100644
index 0000000..ad1f5ee
--- /dev/null
+++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/mapper/ViCorpusMapper.java
@@ -0,0 +1,12 @@
+package com.cmvr.vi.mapper;
+
+import com.cmvr.vi.model.domain.ViCorpus;
+import com.github.yulichang.base.MPJBaseMapper;
+
+/**
+ * 语料库Mapper接口
+ *
+ * @author cmvr-iot
+ */
+public interface ViCorpusMapper extends MPJBaseMapper {
+}
diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViCorpus.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViCorpus.java
new file mode 100644
index 0000000..40d5355
--- /dev/null
+++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViCorpus.java
@@ -0,0 +1,91 @@
+package com.cmvr.vi.model.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.cmvr.common.annotation.Excel;
+import com.cmvr.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 语料库对象 vi_corpus
+ *
+ * @author cmvr-iot
+ */
+@Data
+@ApiModel("语料库对象")
+public class ViCorpus extends BaseEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 语料ID
+ */
+ @ApiModelProperty("语料ID")
+ @TableId(type = IdType.AUTO)
+ private Long corpusId;
+
+ /**
+ * 语料名称
+ */
+ @Excel(name = "语料名称")
+ @ApiModelProperty("语料名称")
+ private String corpusName;
+
+ /**
+ * 语料类型(WAKEUP唤醒 / TEST测试)
+ */
+ @Excel(name = "语料类型", readConverterExp = "WAKEUP唤醒,TEST测试")
+ @ApiModelProperty("语料类型")
+ private String type;
+
+ /**
+ * 语音对应的文本
+ */
+ @Excel(name = "语音对应的文本")
+ @ApiModelProperty("语音对应的文本")
+ private String textContent;
+
+ /**
+ * 语音文件存放路径
+ */
+ @Excel(name = "语音文件存放路径")
+ @ApiModelProperty("语音文件存放路径")
+ private String audioPath;
+
+ /**
+ * 音色
+ */
+ @Excel(name = "音色")
+ @ApiModelProperty("音色")
+ private String voiceType;
+
+ /**
+ * 方言
+ */
+ @Excel(name = "方言")
+ @ApiModelProperty("方言")
+ private String dialect;
+
+ /**
+ * 预期结果(预留)
+ */
+// @Excel(name = "预期结果(预留)")
+ @ApiModelProperty("预期结果(预留)")
+ private String expectedResult;
+
+ /**
+ * 同一父语料下的顺序
+ */
+ @Excel(name = "同一父语料下的顺序")
+ @ApiModelProperty("同一父语料下的顺序")
+ private Integer sortOrder;
+
+ /**
+ * 状态(0正常 1停用)
+ */
+ @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
+ @ApiModelProperty(value = "状态", notes = "0=正常,1=停用")
+ private String status;
+}
diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViCorpusService.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViCorpusService.java
new file mode 100644
index 0000000..cf76bf9
--- /dev/null
+++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViCorpusService.java
@@ -0,0 +1,54 @@
+package com.cmvr.vi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cmvr.vi.model.domain.ViCorpus;
+
+import java.util.List;
+
+/**
+ * 语料库Service接口
+ *
+ * @author cmvr-iot
+ */
+public interface IViCorpusService extends IService {
+ /**
+ * 查询语料库
+ *
+ * @param corpusId 语料库主键
+ * @return 语料库
+ */
+ public ViCorpus selectViCorpusByCorpusId(Long corpusId);
+
+ /**
+ * 查询语料库列表
+ *
+ * @param viCorpus 语料库
+ * @return 语料库集合
+ */
+ public List selectViCorpusList(ViCorpus viCorpus);
+
+ /**
+ * 新增语料库
+ *
+ * @param viCorpus 语料库
+ * @return 结果
+ */
+ public int insertViCorpus(ViCorpus viCorpus);
+
+ /**
+ * 修改语料库
+ *
+ * @param viCorpus 语料库
+ * @return 结果
+ */
+ public int updateViCorpus(ViCorpus viCorpus);
+
+ /**
+ * 批量删除语料库
+ *
+ * @param corpusIds 需要删除的语料库主键集合
+ * @return 结果
+ */
+ public int deleteViCorpusByCorpusIds(Long[] corpusIds);
+
+}
diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/impl/IViCorpusServiceImpl.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/impl/IViCorpusServiceImpl.java
new file mode 100644
index 0000000..3726bdb
--- /dev/null
+++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/impl/IViCorpusServiceImpl.java
@@ -0,0 +1,79 @@
+package com.cmvr.vi.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cmvr.vi.mapper.ViCorpusMapper;
+import com.cmvr.vi.model.domain.ViCorpus;
+import com.cmvr.vi.service.IViCorpusService;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 语料库Service业务层处理
+ *
+ * @author cmvr-iot
+ */
+@Service
+public class IViCorpusServiceImpl extends ServiceImpl implements IViCorpusService {
+
+ /**
+ * 查询语料库
+ *
+ * @param corpusId 语料库主键
+ * @return 语料库
+ */
+ @Override
+ public ViCorpus selectViCorpusByCorpusId(Long corpusId) {
+ return this.getById(corpusId);
+ }
+
+ /**
+ * 查询语料库列表
+ *
+ * @param viCorpus 语料库
+ * @return 语料库
+ */
+ @Override
+ public List selectViCorpusList(ViCorpus viCorpus) {
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.eq(ViCorpus::getType, viCorpus.getType());
+ return this.list(wrapper);
+ }
+
+ /**
+ * 新增语料库
+ *
+ * @param viCorpus 语料库
+ * @return 结果
+ */
+ @Override
+ public int insertViCorpus(ViCorpus viCorpus) {
+ return this.baseMapper.insert(viCorpus);
+ }
+
+ /**
+ * 修改语料库
+ *
+ * @param viCorpus 语料库
+ * @return 结果
+ */
+ @Override
+ public int updateViCorpus(ViCorpus viCorpus) {
+ return this.baseMapper.updateById(viCorpus);
+ }
+
+ /**
+ * 批量删除语料库
+ *
+ * @param corpusIds 需要删除的语料库主键
+ * @return 结果
+ */
+ @Override
+ public int deleteViCorpusByCorpusIds(Long[] corpusIds) {
+ return this.baseMapper.deleteBatchIds(Arrays.asList(corpusIds));
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 742dca4..3faa4ad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -260,6 +260,13 @@
${cmvr-iot.version}
+
+
+ com.cmvr
+ cmvr-iot-vi
+ ${cmvr-iot.version}
+
+
com.cmvr
@@ -314,6 +321,7 @@
cmvr-iot-device
cmvr-iot-test
cmvr-iot-api
+ cmvr-iot-vi
pom