@@ -2,18 +2,29 @@ package com.iformall.controller; | |||
import com.alibaba.fastjson.JSON; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.google.code.kaptcha.Producer; | |||
import com.iformall.annotation.AuthIgnore; | |||
import com.iformall.common.ErrorCode; | |||
import com.iformall.common.ResultData; | |||
import com.iformall.domain.po.WxCUserBasicInfo; | |||
import com.iformall.domain.po.WxCVideoTable; | |||
import com.iformall.domain.po.sm.PhotoSpeakVideo; | |||
import com.iformall.domain.po.sm.PreviewParam; | |||
import com.iformall.domain.po.sm.VoiceInfo; | |||
import com.iformall.domain.vo.WxCLiveLoginVo; | |||
import com.iformall.enums.EnumVideoStatus; | |||
import com.iformall.exception.MallinkException; | |||
import com.iformall.service.*; | |||
import com.iformall.service.sm.VoiceInfoService; | |||
import com.iformall.sm.AiPreviewParam; | |||
import com.iformall.utils.Constant; | |||
import com.iformall.utils.PasswordHelper; | |||
import com.iformall.utils.RedisCacheUtils; | |||
import io.swagger.annotations.Api; | |||
import io.swagger.annotations.ApiImplicitParam; | |||
import io.swagger.annotations.ApiOperation; | |||
import lombok.SneakyThrows; | |||
import org.apache.commons.io.IOUtils; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.slf4j.Logger; | |||
@@ -26,9 +37,16 @@ import springfox.documentation.spring.web.json.Json; | |||
import javax.imageio.ImageIO; | |||
import javax.servlet.ServletOutputStream; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import java.awt.image.BufferedImage; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.net.URL; | |||
import java.net.URLEncoder; | |||
import java.nio.charset.StandardCharsets; | |||
import java.util.*; | |||
@RestController | |||
@@ -59,6 +77,8 @@ public class UserLiveController extends BaseController { | |||
@Autowired | |||
private WxCUserAuthorityService wxCUserAuthorityService; | |||
@Autowired | |||
private VoiceInfoService voiceInfoService; | |||
@AuthIgnore | |||
@@ -251,4 +271,115 @@ public class UserLiveController extends BaseController { | |||
return wxCUserAuthorityService.getAuthor(id, code, type, resourceId); | |||
} | |||
@AuthIgnore | |||
@ApiOperation(value = "tts", notes = "{\"username\",\"string\",\"gen_txt\",\"string\",\"voice_id\",\"string\",\"voice_style\",\"string\",\"speed\",\"int\"}") | |||
@PostMapping("/audiotts") | |||
public Map<String,Object> voicePreview(@RequestBody Map<String, String> params) { | |||
logger.debug("[" + getIpAddr() + "] UserLiveController::voicePreview"); | |||
String phone = params.get("username"); | |||
WxCUserBasicInfo infoByPhone = wxCUserBasicInfoService.findInfoByPhone(getTenantInfo(), phone); | |||
Long id = infoByPhone.getId(); | |||
AiPreviewParam param = new AiPreviewParam(); | |||
if (params.get("voice_id") == null) { | |||
Map<String,Object> status = new HashMap<>(); | |||
status.put("code",ErrorCode.SYS_SERVER_ERROR.getCode()); | |||
status.put("msg","音色ID不能为空"); | |||
return status; | |||
// return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), "音色ID不能为空"); | |||
} | |||
if (StringUtils.isBlank(params.get("gen_txt"))) { | |||
Map<String,Object> status = new HashMap<>(); | |||
status.put("code",ErrorCode.SYS_SERVER_ERROR.getCode()); | |||
status.put("msg","需要生成的文字不能为空"); | |||
return status; | |||
//return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), "需要生成的文字不能为空"); | |||
}if (Integer.parseInt(params.get("speed"))==-1){ | |||
param.setSpeed(0); | |||
} | |||
param.setSpeed(Integer.parseInt(params.get("speed"))); | |||
param.setVoice_id(params.get("voice_id")); | |||
param.setVoice_style(params.get("voice_style")); | |||
param.setGen_txt(params.get("gen_txt")); | |||
Map<String, Object> resultMap = wxCVoiceService.voicePreview(param); | |||
Map<String,Object> info = new HashMap<>(); | |||
info.put("log_id",id); | |||
info.put("server_type","audio tts"); | |||
resultMap.put("info",info); | |||
return resultMap; | |||
} | |||
@AuthIgnore | |||
@SneakyThrows | |||
@ApiOperation(value = "tts", notes = "{\"username\",\"string\",\"gen_txt\",\"string\",\"voice_id\",\"string\",\"voice_style\",\"string\",\"speed\",\"int\"}") | |||
@GetMapping("exportVideo") | |||
public void exportVideo(@RequestBody Map<String, String> params , HttpServletRequest request, HttpServletResponse response) { | |||
logger.debug("[" + getIpAddr() + "] UserLiveController::exportVideo"); | |||
response.reset(); | |||
File tmpFile = null; | |||
OutputStream outputStream = null; | |||
WxCUserBasicInfo infoByPhone = wxCUserBasicInfoService.findInfoByPhone(getTenantInfo(), params.get("username")); | |||
Long id = infoByPhone.getId(); | |||
try { | |||
outputStream = response.getOutputStream(); | |||
} catch (IOException e) { | |||
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR); | |||
} | |||
try{ | |||
if(id == null){ | |||
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
} | |||
WxCVideoTable videoTable = wxCVideoService.selectOne(id,Long.parseLong(params.get("resource_id"))); | |||
//获取响应的输出流 | |||
InputStream inputStream = new URL(videoTable.getDemo()).openStream(); | |||
response.setHeader("Content-Disposition", "attachment; filename=" | |||
+ URLEncoder.encode(videoTable.getId()+".mp4", "UTF-8")); | |||
//解决编码问题 | |||
response.setCharacterEncoding("UTF-8"); | |||
response.setHeader("Content-Type","application/octet-stream"); | |||
byte[] cache = new byte[1024 * 300]; | |||
int flag; | |||
while ((flag = inputStream.read(cache))!=-1){ | |||
outputStream.write(cache, 0, flag); | |||
} | |||
// } | |||
}catch(MallinkException e){ | |||
ResultData resultData = new ResultData(e.getErrorCode(), e.getMessage()); | |||
//解决编码问题 | |||
response.setCharacterEncoding("UTF-8"); | |||
response.setHeader("Content-Type","application/json"); | |||
outputStream.write(JSONObject.toJSONString(resultData).getBytes(StandardCharsets.UTF_8)); | |||
}finally { | |||
if (tmpFile != null) { | |||
tmpFile.delete(); | |||
} | |||
outputStream.flush(); | |||
outputStream.close(); | |||
} | |||
} | |||
@AuthIgnore | |||
@ApiOperation("选择声音选择风格") | |||
@GetMapping("/chooseType") | |||
@ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true) | |||
public ResultData chooseType(Long id) { | |||
logger.debug("[" + getIpAddr() + "] MouldPatchController::chooseType"); | |||
List<VoiceInfo> voiceInfos = wxCVoiceService.chooseType(id); | |||
System.out.println("voiceInfos = " + voiceInfos); | |||
return new ResultData(wxCVoiceService.chooseType(id)); | |||
} | |||
} |
@@ -5,7 +5,10 @@ import com.baomidou.mybatisplus.annotation.TableName; | |||
import lombok.Data; | |||
import lombok.ToString; | |||
@TableName(value = "wx_c_voice") | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
@TableName(value = "voice_info") | |||
@Data | |||
@ToString(callSuper = true) | |||
public class WxCVoiceTable { | |||
@@ -23,17 +26,25 @@ public class WxCVoiceTable { | |||
@io.swagger.annotations.ApiModelProperty(value = "地区显示名称", name = "local_display_name") | |||
private String localDisPlayName; | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹ID", name = "voice_id") | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹ID", name = "id") | |||
private int voiceId; | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹名称(用于调微软接口)", name = "voice_name") | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹名称(用于调微软接口)", name = "local_name") | |||
private String voiceName; | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹展示名称", name = "voice_display_name") | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹展示名称", name = "display_name") | |||
private String voiceDisplayName; | |||
@io.swagger.annotations.ApiModelProperty(value = "性别(男1 女0)", name = "gender") | |||
@io.swagger.annotations.ApiModelProperty(value = "性别(男1 女0)", name = "sex") | |||
private int gender; | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹类型 共享:0 定制:1", name = "class") | |||
private int voiceType; | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹列表", name = "mould_sm_id") | |||
private String MouldSmId; | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹列表", name = "style_list") | |||
private String styleList ; | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹风格名称(用于微软接口)", name = "style_name") | |||
private String styleName; | |||
@io.swagger.annotations.ApiModelProperty(value = "声纹风格展示名称", name = "style_display_name") | |||
@@ -8,4 +8,6 @@ public class PreviewParam { | |||
private String voiceId; | |||
private String voiceStyle; | |||
private String gender; | |||
} | |||
private int speed; | |||
} |
@@ -12,5 +12,5 @@ public interface WxCVideoMapper extends CommonMapper<WxCVideoTable, String> { | |||
List<WxCVideoTable> getById(Long id); | |||
WxCVideoTable selectOne(Long id, long resource_id); | |||
} |
@@ -9,4 +9,6 @@ public interface WxCVideoService { | |||
Map<String,Object> getById(Long id); | |||
WxCVideoTable selectOne(Long id, long resource_id); | |||
} |
@@ -1,9 +1,16 @@ | |||
package com.iformall.service; | |||
import com.iformall.common.ResultData; | |||
import com.iformall.domain.po.sm.VoiceInfo; | |||
import com.iformall.sm.AiPreviewParam; | |||
import java.util.List; | |||
import java.util.Map; | |||
public interface WxCVoiceService { | |||
Map<String,Object> getById(Long id); | |||
List<VoiceInfo> chooseType(Long id); | |||
Map<String,Object> voicePreview(AiPreviewParam aiPreviewParam); | |||
} |
@@ -71,6 +71,12 @@ public class WxCVideoServiceImpl implements WxCVideoService,IExcelExportServer { | |||
return avatarVos; | |||
} | |||
@Override | |||
public WxCVideoTable selectOne(Long id, long resource_id) { | |||
return wxCVideoMapper.selectOne(id,resource_id); | |||
} | |||
@Override | |||
public List<Object> selectListForExcelExport(Object queryParams, int page) { | |||
WxCUserBasicInfo basicInfo = (WxCUserBasicInfo) queryParams; | |||
@@ -1,12 +1,26 @@ | |||
package com.iformall.service.impl; | |||
import com.alibaba.fastjson.JSON; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.google.common.collect.Lists; | |||
import com.iformall.common.ErrorCode; | |||
import com.iformall.common.ResultData; | |||
import com.iformall.domain.po.WxCVideoTable; | |||
import com.iformall.domain.po.WxCVoiceTable; | |||
import com.iformall.domain.po.sm.VoiceInfo; | |||
import com.iformall.domain.vo.VoiceInfoVo; | |||
import com.iformall.enums.EnumClassType; | |||
import com.iformall.enums.EnumSpeakType; | |||
import com.iformall.mapper.VoiceMapper; | |||
import com.iformall.mapper.WxCVoiceMapper; | |||
import com.iformall.service.WxCVoiceService; | |||
import com.iformall.sm.AiPreviewParam; | |||
import com.iformall.sm.AiPreviewResult; | |||
import com.iformall.sm.AiVideoHelper; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import org.springframework.util.ObjectUtils; | |||
import java.util.*; | |||
@@ -16,6 +30,13 @@ public class WxCVoiceServiceImpl implements WxCVoiceService { | |||
@Autowired | |||
WxCVoiceMapper wxCVoiceMapper; | |||
@Autowired | |||
VoiceMapper voiceMapper; | |||
private final static String str = "\uD83D\uDD57"; | |||
private final static String url = "https://suimang.oss-accelerate.aliyuncs.com/builtin/tts_all_sample/"; | |||
private final static String end = ".wav"; | |||
@Override | |||
public Map<String,Object> getById(Long id) { | |||
@@ -28,7 +49,7 @@ public class WxCVoiceServiceImpl implements WxCVoiceService { | |||
for (WxCVoiceTable wxCVoiceTable : resultList) { | |||
HashMap<String, Object> audio = new HashMap<>(); | |||
HashMap<String, Object> voice = new HashMap<>(); | |||
HashMap<String, Object> style = new HashMap<>(); | |||
data.put("username", wxCVoiceTable.getUserName()); | |||
data.put("current_time", new Date(System.currentTimeMillis())); | |||
audioList.add(audio); | |||
@@ -43,17 +64,42 @@ public class WxCVoiceServiceImpl implements WxCVoiceService { | |||
voice.put("voiceid", wxCVoiceTable.getVoiceId()); | |||
voice.put("expire_time", wxCVoiceTable.getExpireTime()); | |||
voice.put("voicename", wxCVoiceTable.getVoiceName()); | |||
voice.put("voicetype", wxCVoiceTable.getVoiceType()); | |||
voice.put("voicetype", EnumClassType.SHARE.getCode()); | |||
voice.put("displayname", wxCVoiceTable.getVoiceDisplayName()); | |||
voice.put("gender", wxCVoiceTable.getGender()); | |||
List styleList = new ArrayList(); | |||
styleList.add(style); | |||
List<String> strings = JSON.parseArray(wxCVoiceTable.getStyleList(), String.class); | |||
for (String y : strings) { | |||
// List list = new ArrayList<>(); | |||
HashMap<String, Object> style = new HashMap<>(); | |||
style.put("stylename", y); | |||
style.put("displayname", EnumSpeakType.getEnum(y).getMessage()); | |||
style.put("styledemo", url + wxCVoiceTable.getMouldSmId() + "_" + y + end); | |||
//list.add(style); | |||
styleList.add(style); | |||
} | |||
// for (String s : Arrays.asList(wxCVoiceTable.getStyleList())) { | |||
//// VoiceInfoVo infoVo = new VoiceInfoVo(); | |||
//// infoVo.setName(EnumSpeakType.getEnum(s).getMessage()); | |||
//// infoVo.setEngName(s); | |||
//// infoVo.setUrl(url + wxCVoiceTable.getMouldSmId() + "_" + s + end); | |||
// style.put("stylename", s); | |||
// style.put("displayname", EnumSpeakType.getEnum(s).getMessage()); | |||
// style.put("styledemo", url + wxCVoiceTable.getMouldSmId() + "_" + s + end); | |||
// styleList.add(style); | |||
// } | |||
// styleList.add(style); | |||
voice.put("styleList", styleList); | |||
style.put("stylename", wxCVoiceTable.getStyleName()); | |||
style.put("displayname", wxCVoiceTable.getStyleDisplayName()); | |||
style.put("styledemo", wxCVoiceTable.getStyleDemo()); | |||
// style.put("stylename", wxCVoiceTable.getStyleName()); | |||
// style.put("displayname", wxCVoiceTable.getStyleDisplayName()); | |||
// style.put("styledemo", wxCVoiceTable.getStyleDemo()); | |||
} | |||
@@ -71,4 +117,75 @@ public class WxCVoiceServiceImpl implements WxCVoiceService { | |||
result.put("status",status); | |||
return result; | |||
} | |||
@Override | |||
public Map<String,Object> voicePreview(AiPreviewParam aiPreviewParam) { | |||
VoiceInfo voiceInfo = voiceMapper.selectOne(new LambdaQueryWrapper<VoiceInfo>().eq(VoiceInfo::getIsDel, 0).eq(VoiceInfo::getId, aiPreviewParam.getVoice_id())); | |||
if (ObjectUtils.isEmpty(voiceInfo)){ | |||
Map<String,Object> status = new HashMap<>(); | |||
status.put("code",ErrorCode.SYS_SERVER_ERROR.getCode()); | |||
status.put("msg","声音信息不存在"); | |||
return status; | |||
// return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), "声音信息不存在"); | |||
} | |||
AiPreviewParam param = new AiPreviewParam(); | |||
param.setGen_txt(aiPreviewParam.getGen_txt().replaceAll(str,"[*]")); | |||
param.setVoice_id(voiceInfo.getMouldSmId()); | |||
param.setVoice_style(StringUtils.isBlank(aiPreviewParam.getVoice_style()) ? EnumSpeakType.default_0.getMessage() : aiPreviewParam.getVoice_style()); | |||
param.setGender(voiceInfo.getSex() == 1 ? "male" : "female"); | |||
AiPreviewResult result = AiVideoHelper.voicePreview(param); | |||
// if (result.isSuccess()){ | |||
// Map<String,Object> status = new HashMap<>(); | |||
// status.put("data",new ResultData(result.getTime())); | |||
// | |||
// return status; | |||
// //return new ResultData(result.getTime()); | |||
// } | |||
Map<String,Object> resultMap = new HashMap<>(); | |||
Map<String,Object> data = new HashMap<>(); | |||
data.put("ttsurl",result.getUrl()); | |||
Map<String,Object> status = new HashMap<>(); | |||
status.put("code",1000); | |||
status.put("msg","success"); | |||
resultMap.put("data",data); | |||
resultMap.put("status",status); | |||
return resultMap; | |||
//return new ResultData(result.getCode(), result.getMsgInfo(result.getCode(),result.getMsg())); | |||
} | |||
@Override | |||
public List<VoiceInfo> chooseType(Long id) { | |||
List<VoiceInfo> voiceInfos = voiceMapper.selectList( | |||
new LambdaQueryWrapper<VoiceInfo>().eq(VoiceInfo::getLanguageId, id).orderByAsc(VoiceInfo::getAgeType).orderByAsc(VoiceInfo::getDisplayName)); | |||
voiceInfos.forEach(x -> { | |||
if (StringUtils.isNotEmpty(x.getStyleList())) { | |||
List<String> strings = JSON.parseArray(x.getStyleList(), String.class); | |||
List<VoiceInfoVo> list = new ArrayList<>(); | |||
strings.forEach(y->{ | |||
VoiceInfoVo infoVo = new VoiceInfoVo(); | |||
infoVo.setName(EnumSpeakType.getEnum(y).getMessage()); | |||
infoVo.setEngName(y); | |||
infoVo.setUrl(url + x.getMouldSmId() + "_" + y + end); | |||
list.add(infoVo); | |||
}); | |||
VoiceInfoVo infoVo = new VoiceInfoVo(); | |||
infoVo.setName(EnumSpeakType.getEnum(0).getMessage()); | |||
infoVo.setUrl(url + x.getMouldSmId() + "_" + "default" + end); | |||
infoVo.setEngName("default"); | |||
list.add(infoVo); | |||
x.setStyle(list); | |||
} else { | |||
List<VoiceInfoVo> list = Lists.newArrayList(); | |||
VoiceInfoVo infoVo = new VoiceInfoVo(); | |||
infoVo.setName(EnumSpeakType.getEnum(0).getMessage()); | |||
infoVo.setEngName("default"); | |||
infoVo.setUrl(url + x.getMouldSmId() + "_" + "default" + end); | |||
list.add(infoVo); | |||
x.setStyle(list); | |||
} | |||
}); | |||
return voiceInfos; | |||
} | |||
} |
@@ -8,5 +8,6 @@ public class AiPreviewParam { | |||
private String voice_id; | |||
private String voice_style; | |||
private String gender; | |||
private int speed; | |||
} |
@@ -26,6 +26,12 @@ left join wx_c_avatar wcav on wcav.id =wca.resource_id | |||
where wca.resource_id | |||
in (select wca.resource_id from wx_c_author wca WHERE wca.user_id =#{id} AND wca.type = 0 ) | |||
</select> | |||
<select id="selectOne" resultType="com.iformall.domain.po.WxCVideoTable"> | |||
SELECT wca.user_name,expire_time,wcav.id,wcav.name,wcav.image,wcav.model,wcav.preinfo,wcav.demo | |||
from wx_c_author wca | |||
left join wx_c_avatar wcav on wcav.id =wca.resource_id | |||
where wca.resource_id =#{resource_id} and wca.user_id = #{id} | |||
</select> | |||
</mapper> |
@@ -5,13 +5,18 @@ | |||
<resultMap id="BaseResultMap" type="com.iformall.domain.po.WxCVoiceTable"> | |||
<result column="user_name" jdbcType="VARCHAR" property="userName"/> | |||
<result column="local_name" jdbcType="VARCHAR" property="localelName"/> | |||
<result column="local_display_name" jdbcType="VARCHAR" property="localDisPlayName"/> | |||
<result column="voice_id" jdbcType="INTEGER" property="voiceId"/> | |||
<result column="name" jdbcType="VARCHAR" property="localelName"/> | |||
<result column="chinese_name" jdbcType="VARCHAR" property="localDisPlayName"/> | |||
<result column="id" jdbcType="INTEGER" property="voiceId"/> | |||
<result column="class" jdbcType="INTEGER" property="voiceType"/> | |||
<result column="voice_name" jdbcType="VARCHAR" property="voiceName"/> | |||
<result column="voice_display_name" jdbcType="VARCHAR" property="voiceDisplayName"/> | |||
<result column="gender" jdbcType="INTEGER" property="gender"/> | |||
<result column="local_name" jdbcType="VARCHAR" property="voiceName"/> | |||
<result column="display_name" jdbcType="VARCHAR" property="voiceDisplayName"/> | |||
<result column="sex" jdbcType="INTEGER" property="gender"/> | |||
<result column="style_list" jdbcType="VARCHAR" property="styleList"/> | |||
<result column="mould_sm_id" jdbcType="VARCHAR" property="MouldSmId"/> | |||
<result column="style_name" jdbcType="VARCHAR" property="styleName"/> | |||
<result column="style_display_name" jdbcType="VARCHAR" property="styleDisplayName"/> | |||
<result column="style_demo" jdbcType="VARCHAR" property="styleDemo"/> | |||
@@ -19,13 +24,21 @@ | |||
</resultMap> | |||
<!-- <select id="getById" resultMap="BaseResultMap">--> | |||
<!--select wca.user_name,wca.resource_id,wca.expire_time,wcv.id, wcv.localel_id ,wcv.id ,wcv.voice_name,wcv.voice_display_name ,wcv.gender , wcv.class , wcvl.id,wcvl.local_name,wcvl.local_display_name,wcvs.id,wcvs.voice_id,wcvs.style_name,wcvs.style_display_name,wcvs.style_demo--> | |||
<!--from wx_c_author wca--> | |||
<!--INNER JOIN wx_c_voice wcv on wca.resource_id = wcv.id--> | |||
<!--and wca.type = 1--> | |||
<!--join wx_c_voice_local wcvl on wcv.localel_id = wcvl.id--> | |||
<!--join wx_c_voice_style wcvs on wcv.id=wcvs.voice_id where wca.user_id = #{id}--> | |||
<!-- </select> --> | |||
<select id="getById" resultMap="BaseResultMap"> | |||
select wca.user_name,wca.resource_id,wca.expire_time,wcv.id, wcv.localel_id ,wcv.id ,wcv.voice_name,wcv.voice_display_name ,wcv.gender , wcv.class , wcvl.id,wcvl.local_name,wcvl.local_display_name,wcvs.id,wcvs.voice_id,wcvs.style_name,wcvs.style_display_name,wcvs.style_demo | |||
from wx_c_author wca | |||
INNER JOIN wx_c_voice wcv on wca.resource_id = wcv.id | |||
and wca.type = 1 | |||
join wx_c_voice_local wcvl on wcv.localel_id = wcvl.id | |||
join wx_c_voice_style wcvs on wcv.id=wcvs.voice_id where wca.user_id = #{id} | |||
select wca.user_name,wca.resource_id,wca.expire_time,vi.id,vi.language_id,vi.sex,vi.display_name,vi.local_name,vi.style_list, | |||
vl.name,vl.chinese_name | |||
FROM wx_c_author wca | |||
join voice_info vi on wca.resource_id = vi.id | |||
join voice_language vl on vi.language_id =vl.id | |||
WHERE wca.user_id=#{id} | |||
</select> | |||