喻忠伟 2 years ago
commit 7dc8c0e9a7
  1. 2
      ant-design-vue-jeecg/src/components/jeecg/modal/JPopupOnlReport.vue
  2. 222
      ant-design-vue-jeecg/src/components/jeecgbiz/JSelectUserByDep.vue
  3. 2
      ant-design-vue-jeecg/src/components/jeecgbiz/modal/JSelectUserByDepModal.vue
  4. 2
      ant-design-vue-jeecg/src/views/device/modules/ZyDeviceForm.vue
  5. 4
      ant-design-vue-jeecg/src/views/productplan/ZyProductPlanList.vue
  6. 2
      ant-design-vue-jeecg/src/views/productplan/modules/ZyProductPlanForm.vue
  7. 13
      ant-design-vue-jeecg/src/views/system/Depart3List.vue
  8. 13
      ant-design-vue-jeecg/src/views/system/modules/DepartModal.vue
  9. 29
      jeecg-boot/jeecg-boot-module-system/pom.xml
  10. 19
      jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/productplan/controller/ZyProductPlanController.java
  11. 17
      jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysDepart.java
  12. 28
      jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/model/SysDepartTreeModel.java
  13. 137
      jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tts/JacobSpeakController.java
  14. BIN
      jeecg-boot/jeecg-boot-module-system/src/main/resources/static/jacob-1.18-x64.rar
  15. BIN
      jeecg-boot/text.wav

@ -119,7 +119,7 @@
total: 0 total: 0
} }
}, },
cgRpConfigId:"", cgRpConfigId:"1610839316058812417",
modalWidth:MODAL_WIDTH, modalWidth:MODAL_WIDTH,
tableScroll:{x:true}, tableScroll:{x:true},
dynamicParam:{}, dynamicParam:{},

@ -1,111 +1,145 @@
<template> <template>
<div> <div>
<a-input-search <!-- <a-input
v-model="userNames" v-model="userNames"
placeholder="请选择用户" placeholder="请点击选择用户"
readOnly readOnly
unselectable="on" unselectable="on"
@search="onSearchDepUser"> @search="onSearchDepUser"
:disabled="disabled"
@click="onSearchDepUser"
>
<a-icon slot="enterButton" type="cluster" title="部门选择控件" />
</a-input> -->
<a-input-search v-model="userNames" placeholder="请先选择用户" readOnly unselectable="on" @search="onSearchDepUser">
<a-button slot="enterButton" :disabled="disabled">选择用户</a-button> <a-button slot="enterButton" :disabled="disabled">选择用户</a-button>
</a-input-search> </a-input-search>
<j-select-user-by-dep-modal ref="selectModal" :modal-width="modalWidth" :multi="multi" @ok="selectOK" :user-ids="value" @initComp="initComp"/> <j-select-user-by-dep-modal
ref="selectModal"
:modal-width="modalWidth"
:multi="multi"
@ok="selectOK"
:user-ids="value"
@initComp="initComp"
/>
<!-- :user-ids="value" -->
</div> </div>
</template> </template>
<script> <script>
import JSelectUserByDepModal from './modal/JSelectUserByDepModal' import JSelectUserByDepModal from './modal/JSelectUserByDepModal'
export default { export default {
name: 'JSelectUserByDep', name: 'JSelectUserByDep',
components: {JSelectUserByDepModal}, components: { JSelectUserByDepModal },
props: { props: {
modalWidth: { modalWidth: {
type: Number, type: Number,
default: 1250, default: 1250,
required: false required: false,
}, },
value: { value: {
type: String, type: String,
required: false required: false,
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
required: false, required: false,
default: false default: false,
}, },
multi: { multi: {
type: Boolean, type: Boolean,
default: true, default: false,
required: false required: false,
}, },
backUser: { backUser: {
type: Boolean, type: Boolean,
default: false, default: false,
required: false required: false,
} },
}, },
data() { data() {
return { return {
userIds: "", userIds: '',
userNames: "" userNames: '',
}
},
mounted() {
this.userIds = this.value
},
watch: {
value(val) {
this.userIds = val
}
},
model: {
prop: 'value',
event: 'change'
},
methods: {
initComp(userNames) {
this.userNames = userNames
},
//
backDeparInfo(){
if(this.backUser===true){
if(this.userIds && this.userIds.length>0){
let arr1 = this.userIds.split(',')
let arr2 = this.userNames.split(',')
let info = []
for(let i=0;i<arr1.length;i++){
info.push({
value: arr1[i],
text: arr2[i]
})
} }
this.$emit('back', info) },
} mounted() {
} this.userIds = this.value
}, },
onSearchDepUser() { watch: {
this.$refs.selectModal.showModal() value(val) {
}, this.userIds = val
selectOK(rows, idstr) { },
console.log("当前选中用户", rows) },
console.log("当前选中用户ID", idstr) // model: {
if (!rows) { // prop: 'value',
this.userNames = '' // event: 'change',
this.userIds = '' // },
} else { methods: {
let temp = '' initComp(userNames) {
for (let item of rows) { this.userNames = userNames
temp += ',' + item.realname },
} //
this.userNames = temp.substring(1) backDeparInfo() {
this.userIds = idstr if (this.backUser === true) {
} if (this.userIds && this.userIds.length > 0) {
this.$emit("change", this.userIds) let arr1 = this.userIds.split(',')
} let arr2 = this.userNames.split(',')
let info = []
for (let i = 0; i < arr1.length; i++) {
info.push({
value: arr1[i],
text: arr2[i],
})
}
this.$emit('back', info)
}
}
},
onSearchDepUser() {
this.$refs.selectModal.showModal()
},
selectOK(rows, idstr) {
//
let temp = ''
console.log('当前选中用户', rows)
console.log('当前选中用户ID', idstr)
//if(!rows)
if (!rows && rows.length <= 0) {
this.userNames = ''
this.userIds = ''
} else {
// let temp = ''
//
for (let item of rows) {
//
console.log(item)
// temp += item.realname
console.log(temp)
//
temp += ' ' + item.realname
}
// this.userNames = temp.substring(1)
this.userNames = temp
console.log(this.userNames)
this.userIds = idstr
console.log(rows)
}
this.$emit('change', this.userIds)
//
// this.$emit('change', this.userNames)
this.backDeparInfo()
},
},
model: {
prop: 'userNames',
event: 'change',
},
} }
}
</script> </script>
<style scoped> <style scoped></style>
</style>

@ -275,7 +275,7 @@
this.selectUserRows.push(row) this.selectUserRows.push(row)
} }
} }
this.selectUserIds = this.selectUserRows.map(row => row.username).join(',') this.selectUserIds = this.selectUserRows.map(row => row.id).join(',')
}, },
// , // ,
onDepSelect(selectedDepIds) { onDepSelect(selectedDepIds) {

@ -61,7 +61,7 @@
</a-col> </a-col>
<a-col :span="24"> <a-col :span="24">
<a-form-model-item label="管理人" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="administrator"> <a-form-model-item label="管理人" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="administrator">
<j-select-user-by-dep v-model="model.administrator" /> <j-select-user-by-dep v-model="model.administrator" />
</a-form-model-item> </a-form-model-item>
</a-col> </a-col>
<a-col :span="24"> <a-col :span="24">

@ -262,7 +262,7 @@ export default {
url: { url: {
list: "/org.jeecg.modules.productplan/zyProductPlan/list", list: "/org.jeecg.modules.productplan/zyProductPlan/list",
paiweitu: "/org.jeecg.modules.productplan/zyProductPlan/paiweitu", paiweitu: "/org.jeecg.modules.productplan/zyProductPlan/paiweitu",
updateStatus: "/org.jeecg.modules.productplan/zyProductPlan/edit", updateStatus: "/org.jeecg.modules.productplan/zyProductPlan/updateStatus",
delete: "/org.jeecg.modules.productplan/zyProductPlan/delete", delete: "/org.jeecg.modules.productplan/zyProductPlan/delete",
deleteBatch: "/org.jeecg.modules.productplan/zyProductPlan/deleteBatch", deleteBatch: "/org.jeecg.modules.productplan/zyProductPlan/deleteBatch",
exportXlsUrl: "/org.jeecg.modules.productplan/zyProductPlan/exportXls", exportXlsUrl: "/org.jeecg.modules.productplan/zyProductPlan/exportXls",
@ -315,7 +315,7 @@ export default {
// alert(JSON.stringify(record)); // alert(JSON.stringify(record));
getAction(this.url.paiweitu, record).then((res) => { getAction(this.url.paiweitu, record).then((res) => {
if (res.success) { if (res.success) {
// console.log("the paiweitu----------" + JSON.stringify(res.result)); console.log("the paiweitu----------" + JSON.stringify(res.result));
// alert(JSON.stringify(res.result)); // alert(JSON.stringify(res.result));
} else { } else {
this.$message.warning(res.message) this.$message.warning(res.message)

@ -186,7 +186,7 @@ export default {
}, },
// //
getEnterprisesManagerValChange() { getEnterprisesManagerValChange() {
// this.teamLeaderVal = "sys_user,realname,id,id=(select enterprises_manager from groupx where id='" + this.model.teamId + "')"; this.teamLeaderVal = "sys_user,realname,id,id=(select enterprises_manager from groupx where id='" + this.model.teamId + "')";
let that = this; let that = this;
let param = { let param = {
"id": that.model.teamId, "id": that.model.teamId,

@ -121,6 +121,13 @@
label="排序"> label="排序">
<a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/> <a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/>
</a-form-item> </a-form-item>
<a-form-model-item label="图片" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="goodsPicture">
<j-image-upload isMultiple v-model="model.goodsPicture" ></j-image-upload>
</a-form-model-item>
<a-form-model-item label="视频" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="goodsVideo">
<j-upload v-model="model.goodsVideo" ></j-upload>
<video v-if="model.goodsVideo" :src="video" style="border:1px solid #d9d9d9;width:100%;" :autoplay="autoplay"/>
</a-form-model-item>
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
@ -266,6 +273,7 @@
}, },
data() { data() {
return { return {
autoplay:true,
iExpandedKeys: [], iExpandedKeys: [],
loading: false, loading: false,
autoExpandParent: true, autoExpandParent: true,
@ -328,7 +336,10 @@
computed: { computed: {
importExcelUrl: function () { importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`; return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
} },
video(){
return `${window._CONFIG['domianURL']}/sys/common/static/${this.model.goodsVideo}`
},
}, },
methods: { methods: {
loadData() { loadData() {

@ -43,6 +43,13 @@
label="缩写"> label="缩写">
<a-input placeholder="请输入缩写" v-decorator="['departNameAbbr', validatorRules.departNameAbbr ]"/> <a-input placeholder="请输入缩写" v-decorator="['departNameAbbr', validatorRules.departNameAbbr ]"/>
</a-form-item> </a-form-item>
<a-form-model-item label="图片" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="goodsPicture">
<j-image-upload isMultiple v-model="model.goodsPicture" ></j-image-upload>
</a-form-model-item>
<a-form-model-item label="视频" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="goodsVideo">
<j-upload v-model="model.goodsVideo" ></j-upload>
<video v-if="model.goodsVideo" :src="video" style="border:1px solid #d9d9d9;width:100%;" :autoplay="autoplay"/>
</a-form-model-item>
<template v-if="orgCategoryDisabled"> <template v-if="orgCategoryDisabled">
<a-form-item <a-form-item
@ -124,6 +131,7 @@
components: {ATextarea}, components: {ATextarea},
data() { data() {
return { return {
autoplay:true,
departTree: [], departTree: [],
orgTypeData: [], orgTypeData: [],
phoneWarning: '', phoneWarning: '',
@ -163,6 +171,11 @@
}, },
created() { created() {
}, },
computed: {
video(){
return `${window._CONFIG['domianURL']}/sys/common/static/${this.model.goodsVideo}`
},
},
methods: { methods: {
loadTreeData() { loadTreeData() {
var that = this; var that = this;

@ -135,9 +135,34 @@
<version>5.2.4.RELEASE</version> <version>5.2.4.RELEASE</version>
</dependency> </dependency>
<!-- 引入定时任务依赖 --> <!-- 引入定时任务依赖 -->
<!-- <dependency>-->
<!-- <groupId>org.jeecgframework.boot</groupId>-->
<!-- <artifactId>jeecg-boot-starter-job</artifactId>-->
<!-- </dependency>-->
<!-- https://mvnrepository.com/artifact/com.jacob/jacob 语音合成 -->
<dependency> <dependency>
<groupId>org.jeecgframework.boot</groupId> <groupId>com.hynnet</groupId>
<artifactId>jeecg-boot-starter-job</artifactId> <artifactId>jacob</artifactId>
<version>1.18</version>
</dependency>
<!-- 播放MP3音乐 -->
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.5.4</version>
</dependency>
<!-- 如果需要解码播放flac文件则引入这个jar包 -->
<dependency>
<groupId>org.jflac</groupId>
<artifactId>jflac-codec</artifactId>
<version>1.5.2</version>
</dependency>
<!--播放音乐 使用第三方解决方案 (jaudiotagger.jar)-->
<dependency>
<groupId>org</groupId>
<artifactId>jaudiotagger</artifactId>
<version>2.0.3</version>
</dependency> </dependency>
</dependencies> </dependencies>

@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.exception.JeecgBootException;
@ -16,23 +15,16 @@ import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.productplan.entity.ZyProductPlan; import org.jeecg.modules.productplan.entity.ZyProductPlan;
import org.jeecg.modules.productplan.entity.vo.PaiWeiTuVo; import org.jeecg.modules.productplan.entity.vo.PaiWeiTuVo;
import org.jeecg.modules.productplan.enums.ProductPlanStatusEnum;
import org.jeecg.modules.productplan.service.IZyProductPlanService; import org.jeecg.modules.productplan.service.IZyProductPlanService;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserService; import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.team.entity.Station;
import org.jeecg.modules.workorder.entity.WorkOrder; import org.jeecg.modules.workorder.entity.WorkOrder;
import org.jeecg.modules.workorder.enums.WorkOrderStatusEnum; import org.jeecg.modules.workorder.enums.WorkOrderStatusEnum;
import org.jeecg.modules.workorder.service.IWorkOrderService; import org.jeecg.modules.workorder.service.IWorkOrderService;
import org.jeecg.modules.workproduct.entity.ZyProduct;
import org.jeecg.modules.workproduct.service.IZyProductService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import javax.jws.Oneway;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.Arrays; import java.util.Arrays;
@ -107,7 +99,7 @@ public class ZyProductPlanController extends JeecgController<ZyProductPlan, IZyP
* @param zyProductPlan * @param zyProductPlan
* @return * @return
*/ */
@AutoLog(value = "生产计划-编辑") // @AutoLog(value = "生产计划-编辑")
@ApiOperation(value = "生产计划-编辑", notes = "生产计划-编辑") @ApiOperation(value = "生产计划-编辑", notes = "生产计划-编辑")
@PutMapping(value = "/edit") @PutMapping(value = "/edit")
public Result<?> edit(@RequestBody ZyProductPlan zyProductPlan) { public Result<?> edit(@RequestBody ZyProductPlan zyProductPlan) {
@ -117,6 +109,15 @@ public class ZyProductPlanController extends JeecgController<ZyProductPlan, IZyP
return Result.OK("编辑成功!"); return Result.OK("编辑成功!");
} }
@ApiOperation(value = "生产计划-撤销", notes = "生产计划-撤销")
@PutMapping(value = "/updateStatus")
public Result<?> updateStatus(@RequestBody ZyProductPlan zyProductPlan) {
ZyProductPlan productPlan = this.zyProductPlanService.getById(zyProductPlan.getId());
Optional.ofNullable(productPlan).orElseThrow(() -> new JeecgBootException(zyProductPlan.getId() + ":不存在!"));
zyProductPlanService.updateById(zyProductPlan);
return Result.OK("编辑成功!");
}
/** /**
* 通过id删除 * 通过id删除
* *

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import org.jeecg.common.aspect.annotation.Dict; import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel; import org.jeecgframework.poi.excel.annotation.Excel;
@ -86,6 +87,16 @@ public class SysDepart implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime; private Date updateTime;
/**图片*/
@Excel(name = "图片", width = 15)
@ApiModelProperty(value = "图片")
private java.lang.String goodsPicture;
/**视频*/
@Excel(name = "视频", width = 15)
@ApiModelProperty(value = "视频")
private java.lang.String goodsVideo;
/** /**
* 重写equals方法 * 重写equals方法
*/ */
@ -120,7 +131,9 @@ public class SysDepart implements Serializable {
Objects.equals(createBy, depart.createBy) && Objects.equals(createBy, depart.createBy) &&
Objects.equals(createTime, depart.createTime) && Objects.equals(createTime, depart.createTime) &&
Objects.equals(updateBy, depart.updateBy) && Objects.equals(updateBy, depart.updateBy) &&
Objects.equals(updateTime, depart.updateTime); Objects.equals(updateTime, depart.updateTime) &&
Objects.equals(goodsPicture, depart.goodsPicture) &&
Objects.equals(goodsVideo, depart.goodsVideo);
} }
/** /**
@ -132,6 +145,6 @@ public class SysDepart implements Serializable {
return Objects.hash(super.hashCode(), id, parentId, departName, return Objects.hash(super.hashCode(), id, parentId, departName,
departNameEn, departNameAbbr, departOrder, description,orgCategory, departNameEn, departNameAbbr, departOrder, description,orgCategory,
orgType, orgCode, mobile, fax, address, memo, status, orgType, orgCode, mobile, fax, address, memo, status,
delFlag, createBy, createTime, updateBy, updateTime); delFlag, createBy, createTime, updateBy, updateTime,goodsPicture,goodsVideo);
} }
} }

@ -77,6 +77,10 @@ public class SysDepartTreeModel implements Serializable{
private Date updateTime; private Date updateTime;
private java.lang.String goodsPicture;
private java.lang.String goodsVideo;
private List<SysDepartTreeModel> children = new ArrayList<>(); private List<SysDepartTreeModel> children = new ArrayList<>();
@ -109,6 +113,8 @@ public class SysDepartTreeModel implements Serializable{
this.createTime = sysDepart.getCreateTime(); this.createTime = sysDepart.getCreateTime();
this.updateBy = sysDepart.getUpdateBy(); this.updateBy = sysDepart.getUpdateBy();
this.updateTime = sysDepart.getUpdateTime(); this.updateTime = sysDepart.getUpdateTime();
this.goodsPicture = sysDepart.getGoodsPicture();
this.goodsVideo = sysDepart.getGoodsVideo();
} }
public boolean getIsLeaf() { public boolean getIsLeaf() {
@ -176,6 +182,22 @@ public class SysDepartTreeModel implements Serializable{
this.parentId = parentId; this.parentId = parentId;
} }
public String getGoodsPicture() {
return goodsPicture;
}
public void setGoodsPicture(String goodsPicture) {
this.goodsPicture = goodsPicture;
}
public String getGoodsVideo() {
return goodsVideo;
}
public void setGoodsVideo(String goodsVideo) {
this.goodsVideo = goodsVideo;
}
public static long getSerialVersionUID() { public static long getSerialVersionUID() {
return serialVersionUID; return serialVersionUID;
} }
@ -367,7 +389,9 @@ public class SysDepartTreeModel implements Serializable{
Objects.equals(createTime, model.createTime) && Objects.equals(createTime, model.createTime) &&
Objects.equals(updateBy, model.updateBy) && Objects.equals(updateBy, model.updateBy) &&
Objects.equals(updateTime, model.updateTime) && Objects.equals(updateTime, model.updateTime) &&
Objects.equals(children, model.children); Objects.equals(children, model.children)&&
Objects.equals(goodsPicture, model.goodsPicture)&&
Objects.equals(goodsVideo, model.goodsVideo);
} }
/** /**
@ -379,7 +403,7 @@ public class SysDepartTreeModel implements Serializable{
return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr, return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr,
departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address, departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address,
memo, status, delFlag, qywxIdentifier, createBy, createTime, updateBy, updateTime, memo, status, delFlag, qywxIdentifier, createBy, createTime, updateBy, updateTime,
children); children,goodsPicture,goodsVideo);
} }
} }

@ -0,0 +1,137 @@
package org.jeecg.modules.tts;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
*
*/
@Api(tags = "文本转语言-语音合成")
@RestController
@RequestMapping("/tts")
@Slf4j
public class JacobSpeakController {
@ApiOperation(value = "语音合成", notes = "语音合成")
@GetMapping(value = "/speak")
public Result speak(@RequestParam(name = "text") String text) {
ActiveXComponent ax = null;
try {
ax = new ActiveXComponent("Sapi.SpVoice");
// 运行时输出语音内容
Dispatch spVoice = ax.getObject();
// 音量 0-100
ax.setProperty("Volume", new Variant(100));
// 语音朗读速度 -10 到 +10
ax.setProperty("Rate", new Variant(-2));
// 执行朗读
Dispatch.call(spVoice, "Speak", new Variant(text));
// 下面是构建文件流把生成语音文件
ax = new ActiveXComponent("Sapi.SpFileStream");
Dispatch spFileStream = ax.getObject();
ax = new ActiveXComponent("Sapi.SpAudioFormat");
Dispatch spAudioFormat = ax.getObject();
// 设置音频流格式
Dispatch.put(spAudioFormat, "Type", new Variant(22));
// 设置文件输出流格式
Dispatch.putRef(spFileStream, "Format", spAudioFormat);
// 调用输出 文件流打开方法,创建一个.wav文件
Dispatch.call(spFileStream, "Open", new Variant("./text.wav"), new Variant(3), new Variant(true));
// 设置声音对象的音频输出流为输出文件对象
Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
// 设置音量 0到100
Dispatch.put(spVoice, "Volume", new Variant(100));
// 设置朗读速度
Dispatch.put(spVoice, "Rate", new Variant(-2));
// 开始朗读
Dispatch.call(spVoice, "Speak", new Variant(text));
// 关闭输出文件
Dispatch.call(spFileStream, "Close");
Dispatch.putRef(spVoice, "AudioOutputStream", null);
spAudioFormat.safeRelease();
spFileStream.safeRelease();
spVoice.safeRelease();
ax.safeRelease();
} catch (Exception e) {
e.printStackTrace();
log.info("{}>> 转换异常:{}", text, e.getMessage());
return Result.error(text + "转换异常" + e.getMessage());
}
return Result.OK();
}
/**
* 语音转文字并播放
*
* @param text
*/
public static void textToSpeech(String text) {
ActiveXComponent ax = null;
try {
ax = new ActiveXComponent("Sapi.SpVoice");
// 运行时输出语音内容
Dispatch spVoice = ax.getObject();
// 音量 0-100
ax.setProperty("Volume", new Variant(100));
// 语音朗读速度 -10 到 +10
ax.setProperty("Rate", new Variant(-2));
// 执行朗读
Dispatch.call(spVoice, "Speak", new Variant(text));
// 下面是构建文件流把生成语音文件
ax = new ActiveXComponent("Sapi.SpFileStream");
Dispatch spFileStream = ax.getObject();
ax = new ActiveXComponent("Sapi.SpAudioFormat");
Dispatch spAudioFormat = ax.getObject();
// 设置音频流格式
Dispatch.put(spAudioFormat, "Type", new Variant(22));
// 设置文件输出流格式
Dispatch.putRef(spFileStream, "Format", spAudioFormat);
// 调用输出 文件流打开方法,创建一个.wav文件
Dispatch.call(spFileStream, "Open", new Variant("./text.wav"), new Variant(3), new Variant(true));
// 设置声音对象的音频输出流为输出文件对象
Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
// 设置音量 0到100
Dispatch.put(spVoice, "Volume", new Variant(100));
// 设置朗读速度
Dispatch.put(spVoice, "Rate", new Variant(-2));
// 开始朗读
Dispatch.call(spVoice, "Speak", new Variant(text));
// 关闭输出文件
Dispatch.call(spFileStream, "Close");
Dispatch.putRef(spVoice, "AudioOutputStream", null);
spAudioFormat.safeRelease();
spFileStream.safeRelease();
spVoice.safeRelease();
ax.safeRelease();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
textToSpeech("测试语音测试语音测试语音");
}
}

Binary file not shown.
Loading…
Cancel
Save