package com.ys.zhenlian.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.ys.zhenlian.bean.*;
import com.ys.zhenlian.entity.*;
import com.ys.zhenlian.service.AccessTokenService;
import com.ys.zhenlian.service.TeacherService;
import com.ys.zhenlian.service.UserService;
import com.ys.zhenlian.service.ZhenLianService;
import com.ys.zhenlian.util.*;
import com.ys.zhenlian.util.voiceTools.entity.TranslateResult;
import com.ys.zhenlian.util.voiceTools.entity.XunfeiRequest;
import com.ys.zhenlian.util.voiceTools.tools.Consts;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.util.*;
/**
* 微信验证,获取token控制器
* Created by DELL on 2017/11/30.
*/
@Controller
@RequestMapping("/service/weixin")
public class WeiXinValidateController extends BaseController {
private final Logger log = LoggerFactory.getLogger(this.getClass());
// public long timeLose;
@Value("${accessTokenVersion}")
private Integer accessTokenVersion;
@Value("${baseUrl}")
private String baseUrl;
@Value("${voicePath}")
private String voicePath;
@Value("${picturePath}")
private String picturePath;
@Value("${appid}")
private String appid;
@Value("${secret}")
private String secret;
/*打分接口 header参数*/
@Value("${authorization}")
private String token;
/*打分接口 请求Url*/
@Value("${reqUrl}")
private String reqUrl;
@Resource
private UserService userService;
@Resource
private TeacherService teacherService;
@Resource
private ZhenLianService zhenLianService;
@Resource
private AccessTokenService accessTokenService;
private static final Map<String, String> htmlUrl = new HashMap<String, String>();
/**
* 微信网页授权验证
*
* @param response
* @throws Exception
*/
@RequestMapping("/getAuthorize")
public void getAuthorize(HttpServletRequest request, HttpServletResponse response) throws Exception {
String rUrl = StringUtils.trim(request.getParameter("url"));
if(rUrl != null) {
rUrl = rUrl.replace("?from=singlemessage", "").replace("&isappinstalled=0", "");
}
// rUrl = rUrl.replace("?from=singlemessage", "").replace("&isappinstalled=0", "");
String uid = UUID.randomUUID().toString();
if (StringUtils.isNotEmpty(rUrl)){
htmlUrl.put(uid, rUrl);
}
//第一步:用户同意授权,获取code
String cbUrl = URLEncoder.encode(baseUrl + "/service/weixin/" + uid + "/index.do", "utf-8");
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=" + appid + //公众号的唯一标识
//授权后重定向的回调链接地址,请使用urlEncode对链接进行处理,应当使用https链接来确保授权code的安全性
"&redirect_uri=" + cbUrl +
"&response_type=code" +//返回类型,请填写code
//应用授权作用域:
// 1.snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid)
// 2.snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
"&scope=snsapi_userinfo" +
//非必须字段,重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
"&state=STATE" +
//无论直接打开还是做页面302重定向时候,必须带此参数
"#wechat_redirect";
//重定向至微信验证地址
response.sendRedirect(url);
}
/**
* 根据code获取用户登陆accesstoken
* 获取用户信息
* 初始化教师信息
*
* @param request
* @return
* @throws Exception
*/
@ResponseBody
@RequestMapping("/{uid}/index")
public Msg getToken(HttpServletRequest request, HttpServletResponse response, @PathVariable("uid")String uid) {
try {
String code = request.getParameter("code");
if (code == null || code.isEmpty()) {
log.error("获取code失败");
return new Msg(400, "获取code失败");
}
log.info("获取code成功,code=" + code);
//第二步:通过code换取网页授权access_token
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=" + appid +
"&secret=" + secret +
"&code=" + code +
"&grant_type=authorization_code";
WeiXinTokenResult tokenResult;
String token_result = HttpUtil.sendGet(url);
if (token_result.contains("errcode")) {
log.error("用户token获取失败," + token_result);
return new Msg(400, "用户token获取失败," + token_result);
}
Gson gson = new Gson();
tokenResult = gson.fromJson(token_result, WeiXinTokenResult.class);
log.info("token获取成功,token=" + tokenResult.getAccess_token());
request.getSession().setAttribute("user_token", tokenResult);
//第三部:获取用户信息
UserInfo userInfo = getUser(tokenResult);
if (userInfo == null) {
log.error("用户信息获取失败");
return new Msg(400, "用户信息获取失败");
}
//根据opeaId查询用户
List<UserInfo> userList = userService.selectByOpeaId(userInfo.getOpenid());
if (userList == null || userList.size() <= 0) {
log.info("用户信息不存在,第一次登陆,开始保存用户信息");
//保存到数据库
int result = userService.insertByUserInfo(userInfo);
if (result != 1) {
log.error("用户信息保存失败");
return new Msg(400, "用户信息保存失败");
}
} else {
log.info(userInfo.toString());
//更新数据库
int result = userService.updateByOpenid(userInfo);
if (result != 1) {
log.error("用户信息更新失败");
return new Msg(400, "用户信息更新失败");
}
}
userList = userService.selectByOpeaId(userInfo.getOpenid());
if (userList.size() != 1) {
log.error("用户信息保存更新失败");
return new Msg(400, "用户信息保存更新失败");
}
request.getSession().setAttribute("user_info", userList.get(0));
//初始化教师信息
List<Teacher> list = teacherService.getTeacherList();
if (list.size() == 0) {
log.error("获取老师信息失败");
return new Msg(400, "获取老师信息失败");
}
request.getSession().setAttribute("teacher_List", list);
log.info("教师信息初始化成功");
String rUrl = htmlUrl.get(uid);
if (StringUtils.isEmpty(rUrl)){
//重定向到前台html
response.sendRedirect(baseUrl + "/index.html");
} else {
htmlUrl.remove(uid);
response.sendRedirect(rUrl);
}
return new Msg(200, "登陆成功");
} catch (Exception ex) {
log.info("登陆错误," + ex.getMessage());
return new Msg(400, "登陆错误," + ex.getMessage());
}
}
/**
* 刷新网页token
*/
@ResponseBody
@RequestMapping("/refreshToken")
public Msg refreshToken(HttpServletRequest request) {
try {
WeiXinTokenResult tokenResult = (WeiXinTokenResult) request.getSession().getAttribute("user_token");
String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token" +
"?appid=" + appid +
"&grant_type=refresh_token" +
"&refresh_token=" + tokenResult.getRefresh_token();
String refresh_result = HttpUtil.sendGet(url);
if (!refresh_result.contains("errcode")) {
log.error("token刷新失败" + refresh_result);
return new Msg(400, "token刷新失败" + refresh_result);
}
Gson gson = new Gson();
tokenResult = gson.fromJson(refresh_result, WeiXinTokenResult.class);
request.getSession().setAttribute("user_token", tokenResult);
log.info("token刷新成功,token=" + tokenResult.getAccess_token());
return new Msg(200, "", "token刷新成功");
} catch (JsonSyntaxException e) {
e.printStackTrace();
log.error("token刷新错误," + e.getMessage());
return new Msg(400, "token刷新错误," + e.getMessage());
}
}
/**
* 返回用户信息
*/
@ResponseBody
@RequestMapping("/getUserInfo")
public Msg getUserInfo(HttpServletRequest request) {
try {
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user_info");
if (userInfo == null) {
log.error("用户信息获取失败");
return new Msg(400, "用户信息获取失败");
}
return new Msg(200, userInfo);
} catch (Exception e) {
e.printStackTrace();
log.error("用户信息获取错误," + e.getMessage());
return new Msg(400, "用户信息获取错误," + e.getMessage());
}
}
/**
* 返回用户微信信息
*/
@ResponseBody
@RequestMapping("/getWeixinUser")
public Msg getWeixinUser(HttpServletRequest request) {
try {
WeiXinTokenResult tokenResult = (WeiXinTokenResult) request.getSession().getAttribute("user_token");
if (tokenResult == null) {
log.error("用户没有授权,无法获取用户微信信息");
return new Msg(400, "用户没有授权,无法获取用户微信信息");
}
UserInfo userInfo = getUser(tokenResult);
return new Msg(200, userInfo);
} catch (Exception e) {
e.printStackTrace();
log.error("获取错误," + e.getMessage());
return new Msg(400, "获取错误," + e.getMessage());
}
}
/**
* 登陆接口(测试使用)
*
* @param request
* @return
*/
@ResponseBody
@RequestMapping("/login")
public Msg loginTest(HttpServletRequest request) {
//取openid
List<UserInfo> userInfos = userService.getOpenId();
WeiXinTokenResult tokenResult = new WeiXinTokenResult();
tokenResult.setOpenid(userInfos.get(0).getOpenid());
request.getSession().setAttribute("user_token", tokenResult);
request.getSession().setAttribute("user_info", userInfos.get(0));
List<Teacher> list = teacherService.getTeacherList();
if (list.size() == 0) {
log.error("获取老师信息失败");
return new Msg(400, "获取老师信息失败");
}
request.getSession().setAttribute("teacher_List", list);
System.out.println(Charset.defaultCharset());
log.info("登陆成功");
return new Msg(200, "登陆成功");
}
/**
* 下载用户音频,返回微信下载地址
*
* @param request
* @param media_id
* @return
*/
@ResponseBody
@RequestMapping("/downloadVoice")
public Msg downloadVoice(HttpServletRequest request, Integer dialog_id, String media_id) {
if (request.getSession().getAttribute("user_info") == null)
return new Msg(201, "没有用户信息");
if (dialog_id == null || dialog_id == 0)
return new Msg(201, "缺少dialog_id参数");
if (media_id == null || media_id.isEmpty())
return new Msg(201, "缺少media_id参数");
log.info("成功获得media_id,media_id为:" + media_id);
try {
//获取accessToken
//需要配置(1,old;2,new)
AccessToken accessToken = accessTokenService.getAccessToken(accessTokenVersion);
String tokenStr = accessToken.getAccessToken();
log.info("成功获得tokenStr,tokenStr为:" + tokenStr);
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user_info");
//根据dialog_id,获取保存路径
String voiceSavePath = zhenLianService.getVoicePath(dialog_id);
if (voiceSavePath == null || voiceSavePath.isEmpty()) {
log.error("找不到对话保存路径");
return new Msg(400, "找不到对话保存路径");
}
//得到用户语音保存地址
StringBuilder sb = new StringBuilder();
voiceSavePath = sb.append(voiceSavePath).insert("download".length() + 1, "/userVoice/" + userInfo.getId()).toString();
voiceSavePath = voiceSavePath.substring(0, voiceSavePath.lastIndexOf("/") + 1) + System.currentTimeMillis() + ".speex";
log.info("得到用户语音保存地址:" + voiceSavePath);
//微信下载音频url
String url = "https://api.weixin.qq.com/cgi-bin/media/get/jssdk" +
"?access_token=" + tokenStr +
"&media_id=" + media_id;
String path = new File(voicePath).getCanonicalPath() + voiceSavePath;
File file = FileDownloadUtil.saveUrlAs(url, path);
if (file == null) {
log.error("下载失败!");
return new Msg(400, "下载失败!");
}
//speex转wav
String wavPath = path.replace(".speex", ".wav");
VoiceUtil.speex2wav(path, wavPath);
//获取音频时长
int lengh = VoiceUtil.getVoiceLenWav(wavPath);
// int lengh = VoiceUtil.getVoiceLenWavNew(wavPath);
//音频相对路径
String substring = voicePath.substring(voicePath.lastIndexOf("/") + 1);
String returnPath = wavPath.substring(wavPath.lastIndexOf(substring) + substring.length());
//保存用户音频
log.info("保存音频前dialog_id为:"+dialog_id);
DialogVoiceUser voiceUser = new DialogVoiceUser(dialog_id, userInfo.getOpenid(), returnPath, lengh);
zhenLianService.insertDialogVoiceUser(voiceUser);
//获取语音评分
// Score score = getSpeechScore(returnPath,dialog_id);
//获取音频路径
String voice_path = voicePath+returnPath;
//根据dialog_id查询语音话题ConEn
SubjectDialog subjectDialog=zhenLianService.getSubjectDialogById(dialog_id);
log.info("音频地址为:"+voice_path);
log.info("文本信息为:"+subjectDialog.getConEn());
// JSONObject score = this.getSpeechScoreData(reqUrl,voice_path,subjectDialog.getConEn());
//TODO,获取teacher_en,直接数据库获取
String teacher_en = "";
teacher_en = zhenLianService.getTeacherEnByDialog(subjectDialog.getId());
log.info("获取到老师翻译的音频为:----->"+teacher_en);
//
//模拟数据
// String voice_path = "E:\\wavFile\\Joey.wav";
//如果teacher_en是"",则采用con_en请求打分接口,否则用teacher_en
JSONObject score = new JSONObject();
if (teacher_en == null || "".equals(teacher_en)){
score = this.getSpeechScoreData(reqUrl,voice_path,subjectDialog.getConEn());
log.info("获取con_en值为:----->"+subjectDialog.getConEn());
log.info("根据con_en获取的打分结果为:----->"+score.toString());
}else {
score = this.getSpeechScoreData(reqUrl,voice_path,teacher_en);
}
//获取语音评分
BigDecimal speechScore=BigDecimal.ZERO;//语音评分
//用于存放语音打分数据
String speech_score_msg = "";
log.info("打分详情信息为:"+score);
log.info("请求之前音频得分为:------"+score.get("score"));
if(null != score){
// speechScore=new BigDecimal(score.getFinalScore()*100);
//如果err_code不等于空,这段音频则为无效数据
if(score.get("err_code") != null && !"".equals(score.get("err_code").toString())){
log.info("无效数据!或者声音太小");
log.info("接口数据返回为:----"+score.toString());
return new Msg(401, "无效音频文件,请重新录入!");
}
//分数由十分制改为百分制。author(袁勋)
if(score.get("score") != null && !"".equals(score.get("score").toString())){
log.info("请求之后音频得分为:------"+score.get("score").toString());
speechScore=new BigDecimal(Double.parseDouble(score.get("score").toString())*10);
if(speechScore.compareTo(BigDecimal.ZERO) <= 0){//小于等于0,得0随机分
// Random random=new Random();
// speechScore=new BigDecimal(random.nextInt(10)+30);
speechScore = new BigDecimal(0);
}
// else if(speechScore.compareTo(new BigDecimal(96))>0){//大于96,得96分
// speechScore=new BigDecimal(96);
// }
}else{
// Random random=new Random();
// speechScore=new BigDecimal(random.nextInt(10)+30);
speechScore = new BigDecimal(0);
}
speechScore=speechScore.setScale(3,BigDecimal.ROUND_UP);//格式化返回0.000
// JSONObject resultObject=JSON.parseObject(score.toString());
// resultObject.remove("DetailResponse");//移除DetailResponse 响应详情
// resultObject.remove("BestMatch");//移除BestMatch 批量处理详情
// speechScoreMsg=resultObject.toJSONString();//返回评分消息
//如果该JSON字符串字节长度超过1024,则不存入到数据库。author(袁勋)注:将该字段类型转换为text
// if (score.toString().getBytes().length>1024){
// speechScoreMsg = "";
// }
speech_score_msg = score.toString();
}else {
log.error("打分接口无数据返回");
log.info("返回的打分数据为:--->"+score.toString());
speech_score_msg = "";
return new Msg(400, "测评失败,请联系服务商!");
}
//低于30分再加30分
// if(speechScore.compareTo(new BigDecimal(30))<0){
// speechScore=speechScore.add(new BigDecimal(30));
// }
System.out.println("计算语音评分--得分:"+speechScore);
log.info("dialog_id为:"+dialog_id);
//保存用户对话记录
int resultNumber = zhenLianService.saveUserDialogRecord(dialog_id, userInfo.getOpenid(), returnPath, lengh,speechScore,speech_score_msg);
if (resultNumber == 0){
System.out.println("====>>>>>>> 保存用户对话记录失败 <<<<<<<<====");
}
VoiceResult voiceResult = new VoiceResult(returnPath, lengh,speechScore);
log.info("下载成功!用户音频地址为:" + returnPath);
return new Msg(200, "", voiceResult);
} catch (Exception ex) {
ex.printStackTrace();
log.error("下载错误!" + ex.getMessage());
return new Msg(400, "下载错误!" + ex.getMessage());
}
}
private String getTeacherConEn(String voiceSavePath) {
//定义课程英语翻译
String con_en= "";
// String reqPath = voicePath + voiceSavePath;
String reqPath = voiceSavePath;
//请求xunfei参数设置
XunfeiRequest xfReq = new XunfeiRequest();
xfReq.setLanguage(Consts.Language.ENGLISH);
xfReq.setPath(reqPath);
//请求讯飞翻译接口
TranslateResult translateResult = TranslateUtils.xunfei(xfReq);
log.info("downloadVoice()---获取讯飞翻译结果translateResult :"+ translateResult.getText());
if (translateResult.isSuccess()){
con_en = translateResult.getText().replace("[", "").replace("]", "").replace(",", "").replace("\"", "");
}else {
con_en = "Error,this dialog is not exist !";
}
return con_en;
}
/**
* 获取用户的语音平均评分
*
* @param request
* @param lesson_id 主题ID
* @return
*/
@ResponseBody
@RequestMapping("/getSpeechAvgScore")
public Msg getSpeechAvgScore(HttpServletRequest request, Integer lesson_id) {
if (request.getSession().getAttribute("user_info") == null)
return new Msg(201, "没有用户信息");
if (lesson_id == null || lesson_id == 0)
return new Msg(201, "缺少lesson_id参数");
try {
//获取accessToken
//需要配置(1,old;2,new)
AccessToken accessToken = accessTokenService.getAccessToken(accessTokenVersion);
String tokenStr = accessToken.getAccessToken();
log.info("成功获得tokenStr,tokenStr为:" + tokenStr);
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user_info");
//保存用户对话记录
BigDecimal speechScore = zhenLianService.getSpeechAvgScore(lesson_id, userInfo.getOpenid());
//百分比(超过百分之几的人)
BigDecimal percentScore=BigDecimal.ZERO;
if(speechScore != null){
BigDecimal seventy=new BigDecimal(70);
BigDecimal hundred=new BigDecimal(100);
//scoreNumber=(平均分-70)*100/70
BigDecimal scoreNumber=speechScore.subtract(seventy).multiply(hundred).divide(seventy,3);
//scoreNumber=50+scoreNumber
scoreNumber=new BigDecimal(50).add(scoreNumber);
//如果百分比小于0,则按照0显示
if(scoreNumber.compareTo(BigDecimal.ZERO)>0){
percentScore=scoreNumber;
}
}
JSONObject result=new JSONObject();
result.put("speechScore",speechScore);
result.put("lesson_id",lesson_id);
result.put("percentScore",percentScore);
log.info(userInfo.getOpenid()+"用户语音平均评分为:" + speechScore);
return new Msg(200, "", result);
} catch (Exception ex) {
log.error("获取用户语音评分错误:",ex);
return new Msg(400, "获取用户语音平均评分错误!" + ex.getMessage());
}
}
/**
* 生成微信前端接口权限
*
* @param url
* @return
* @throws NoSuchAlgorithmException
*/
@ResponseBody
@RequestMapping("/getJsConfig")
public String getJsConfig(String url) {
if (url == null || url.isEmpty())
return "wx.config(缺少url参数);";
log.info("url获取成功,url:" + url);
try {
//第一步获取AccessToken
String tokenStr;
//获取accessToken
AccessToken accessToken = accessTokenService.getAccessToken(accessTokenVersion);
if (accessToken != null && System.currentTimeMillis() - accessToken.getLastTime().getTime() < 7200000) {
tokenStr = accessToken.getAccessToken();
} else {
log.info("accessToken不存在,或者已过期,开始获取accessToken");
tokenStr = getAccessToken();
if (tokenStr.isEmpty() || tokenStr.contains("失败")) {
log.error("access_token获取失败," + tokenStr);
return "wx.config(获取access_token信息失败);";
}
log.info("accessToken获取成功,accessToken:" + tokenStr);
}
//第二步,获取jsTicket(相同的accesstoken,得到的ticket是不变的)
String getUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket" +
"?access_token=" + tokenStr +
"&type=jsapi";
String jsTicket_result = HttpUtil.sendGet(getUrl);
if (!jsTicket_result.contains("ticket")) {
log.error("获取jsTicket失败," + jsTicket_result);
return "wx.config(获取jsTicket失败);";
}
Gson gson = new Gson();
JsTicket jsTicket = gson.fromJson(jsTicket_result, JsTicket.class);
String ticket = jsTicket.getTicket();
log.info("jsTicket获取成功,jsTicket:" + ticket);
//第三步,生成JS-SDK权限验证的签名
String noncestr = WXSignatureUtil.getRandomString(16);
log.info("noncestr获取成功,noncestr:" + noncestr);
// String timestamp = String.valueOf(System.currentTimeMillis());
//当前时间戳(单位秒)(去掉后三位)
Date date = new Date();
String timestampTemp = String.valueOf(date.getTime());
int length = timestampTemp.length();
String timestamp = timestampTemp.substring(0, length - 3);
log.info("timestamp获取成功,timestamp:" + timestamp);
//按照参数名排序,拼接成str
String str = "jsapi_ticket=" + ticket +
"&noncestr=" + noncestr +
"×tamp=" + timestamp +
"&url=" + url;
//生成签名(签名算法)
String signature = WXSignatureUtil.SHA1(str);
log.info("签名:" + signature);
//前端使用接口集合
List<String> jsApiList = new ArrayList<>();
jsApiList.add("onMenuShareTimeline");
jsApiList.add("onMenuShareAppMessage");
jsApiList.add("onMenuShareQQ");
jsApiList.add("onMenuShareWeibo");
jsApiList.add("previewImage");
jsApiList.add("downloadImage");
jsApiList.add("chooseImage");
jsApiList.add("uploadImage");
jsApiList.add("checkJsApi");
jsApiList.add("startRecord");
jsApiList.add("stopRecord");
jsApiList.add("onVoiceRecordEnd");
jsApiList.add("playVoice");
jsApiList.add("pauseVoice");
jsApiList.add("stopVoice");
jsApiList.add("onVoicePlayEnd");
jsApiList.add("uploadVoice");
jsApiList.add("downloadVoice");
jsApiList.add("translateVoice");
jsApiList.add("hideOptionMenu");
jsApiList.add("showOptionMenu");
jsApiList.add("hideMenuItems");
jsApiList.add("showMenuItems");
jsApiList.add("hideAllNonBaseMenuItem");
jsApiList.add("showAllNonBaseMenuItem");
WXsignature wXsignature = new WXsignature(false, appid, timestamp, noncestr, signature, jsApiList);
log.info("wx.config获取成功,wx.config:" + "wx.config(" + gson.toJson(wXsignature) + ");");
return "wx.config(" + gson.toJson(wXsignature) + ");";
} catch (Exception e) {
log.error("wx.config(获取权限错误," + e.getMessage() + ");");
return "wx.config(获取权限错误," + e.getMessage() + ");";
}
}
/**
* 提交用户预约
*
* @return
*/
@ResponseBody
@RequestMapping("/saveUserReservation")
public Msg userReservation(@ModelAttribute("json") JSONObject jsonObject) {
if (jsonObject == null || jsonObject.size() == 0) {
log.error("缺少UserReservation对象参数");
return new Msg(201, "缺少UserReservation对象参数");
}
UserReservation userReservation = JSON.toJavaObject(jsonObject, UserReservation.class);
try {
int result = userService.saveUserReservation(userReservation);
if (result != 1) {
log.error("用户预约失败");
return new Msg(400, "用户预约失败");
}
log.info("用户预约成功");
return new Msg(200, "用户预约成功");
} catch (Exception ex) {
log.error("用户预约错误," + ex.getMessage());
return new Msg(400, "用户预约错误," + ex.getMessage());
}
}
/**
* 获取、刷新accessToken
*/
// private String getAccessToken() {
// try {
// String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
// "&appid=" + appid + //公众号的唯一标识;
// "&secret=" + secret;
// String token_result = HttpUtil.sendGet(url);
// if (token_result.contains("errcode")) {
// log.error("获取、刷新accessToken失败,原因:" + token_result);
// return token_result;
// }
// Gson gson = new Gson();
// AccessTokenResult accessToken = gson.fromJson(token_result, AccessTokenResult.class);
// String access_token = accessToken.getAccess_token();
// log.info("获取、刷新accessToken成功,access_token:" + access_token);
// //封装条件
// Map<String, Object> condition = new HashMap<>();
// condition.put("accessTokenVersion", accessTokenVersion);
// condition.put("access_token", access_token);
// //保存access_token(存在刷新,不存在添加)
// accessTokenService.saveAccessToken(condition);
// return access_token;
// } catch (JsonSyntaxException e) {
// e.printStackTrace();
// log.error("获取、刷新accessToken错误," + e.getMessage());
// return "获取、刷新accessToken错误," + e.getMessage();
// }
// }
private String getAccessToken() {
try {
//返回值初始化
String access_token = "";
//根据accessTokenVersion查询access_token
AccessToken accessToken = accessTokenService.getAccessToken(accessTokenVersion);
access_token = accessToken.getAccessToken();
log.info("获取的access_token为:------"+access_token);
return access_token;
}catch (Exception e){
e.printStackTrace();
log.error("获取、刷新accessToken错误," + e.getMessage());
return "获取、刷新accessToken错误," + e.getMessage();
}
}
/**
* 获取用户信息
*
* @param tokenResult
* @return
*/
private UserInfo getUser(WeiXinTokenResult tokenResult) {
String url = "https://api.weixin.qq.com/sns/userinfo" +
"?access_token=" + tokenResult.getAccess_token() +
"&openid=" + tokenResult.getOpenid() +
"&lang=zh_CN";
String info_result = HttpUtil.sendGet(url);
if (info_result.contains("errcode")) {
log.error("用户信息获取失败,原因" + info_result);
return null;
}
Gson gson = new Gson();
UserInfo userInfo = gson.fromJson(info_result, UserInfo.class);
log.info("用户信息获取成功");
return userInfo;
}
/**
*根据语音文本进行语音评分
* @param returnPath 文件路径
* @param dialog_id 对话ID
* @return score 评分
* */
// private Score getSpeechScore(String returnPath,Integer dialog_id){
// try {
// SubjectDialog subjectDialog=zhenLianService.getSubjectDialogById(dialog_id);
// if(subjectDialog==null){
// return null;
// }
// File file=new File(voicePath+returnPath);
// InputStream stream = new FileInputStream(file);
// String fileName = System.nanoTime() + ".wav";
// //获取打分
//// Score score = SpeechScoreApp.getScore(subjectDialog.getConEn(), stream, fileName);
// return score;
// } catch (Exception ex) {
// log.error("获取用户语音评分错误:",ex);
// return null;
// }
// }
/**
* 用户音频打分接口
*
* @param request
* @param dialog_id
* @return
*/
@ResponseBody
@RequestMapping("/getUserSpeechScoreInfo")
public Msg getUserSpeechScoreInfo(HttpServletRequest request, Integer dialog_id) {
if (dialog_id == null || dialog_id == 0)
return new Msg(201, "缺少dialog_id参数");
log.info("dialog_id,dialog_id为:" + dialog_id);
if (request.getSession().getAttribute("user_info") == null)
return new Msg(201, "没有用户信息");
try {
//获取accessToken
//需要配置(1,old;2,new)
AccessToken accessToken = accessTokenService.getAccessToken(accessTokenVersion);
String tokenStr = accessToken.getAccessToken();
log.info("成功获得tokenStr,tokenStr为:" + tokenStr);
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user_info");
//返回结果初始化
JSONObject json = new JSONObject();
//根据user的openId、dialogId查询用户音频数据
Map<String,Object> userDialogRecord = zhenLianService.getUserDialogRecordById(dialog_id,userInfo.getOpenid());
//获取用户音频text
SubjectDialog subjectDialog = zhenLianService.getSubjectDialogById(dialog_id);
json.put("speech_dialog",subjectDialog.getConEn());
//获取用户音频的打分数据
if (userDialogRecord != null && userDialogRecord.size() > 0){
//获取音频得分
BigDecimal speechScore = new BigDecimal(userDialogRecord.get("speech_score").toString());
speechScore=speechScore.setScale(0,BigDecimal.ROUND_UP);//格式化返回0
json.put("score",speechScore);
//根据得分判断返回话术
String speechMsg = "";
if (speechScore.compareTo(new BigDecimal(60)) < 0){
speechMsg = "学习不易,再接再厉!";
}
if (speechScore.compareTo(new BigDecimal(60)) >= 0 && speechScore.compareTo(new BigDecimal(90)) < 0){
speechMsg = "很不错,继续加油!";
}
if (speechScore.compareTo(new BigDecimal(90)) >= 0){
speechMsg = "非常赞!";
}
json.put("speech_msg",speechMsg);
String wavPath = userDialogRecord.get("voice_url").toString();
String returnPath = wavPath;
json.put("voice_path",returnPath);
JSONObject voiceData = new JSONObject();
//标红单词列表初始化
JSONArray errArray = new JSONArray();
//TODO,获取teacher_en,直接数据库获取
String teacher_en = "";
teacher_en = zhenLianService.getTeacherEnByDialog(subjectDialog.getId());
//如果音频数据不为空,则取数据返回
if(userDialogRecord.get("speech_score_msg") != null && !"".equals(userDialogRecord.get("speech_score_msg"))){
String speechJson = userDialogRecord.get("speech_score_msg").toString();
log.info("获取的userDialogJson数据为:-------"+speechJson);
if (teacher_en != null){
json.put("teachen_cn",teacher_en);//返回老师的音频翻译
}else {
json.put("teachen_cn","");
}
voiceData = JSONObject.parseObject(speechJson);
//如果err_code不等于空,这段音频则为无效数据
if(voiceData.get("err_code") != null && !"".equals(voiceData.get("err_code").toString())){
log.info("无效数据!或者声音太小");
log.info("接口数据返回为:----"+voiceData.toString());
return new Msg(401, "无效音频文件,请重新录入!");
}
getErrorWordsJarray(voiceData, errArray);
}else {
//如果用户的返回数据为空,则请求打分接口获取数据返回
//获取音频路径
String voice_path = voicePath+wavPath;
//根据dialog_id,获取保存路径
String teacher_voice = "";
if (teacher_en != null){
json.put("teachen_cn",teacher_en);//返回老师的音频翻译
}else {
json.put("teachen_cn","");
}
//模拟数据
// String voice_path = "E:\\wavFile\\Joey.wav";
//请求声讯科技打分接口
// JSONObject speech_score_data = this.getSpeechScoreData(reqUrl,voice_path,subjectDialog.getConEn());
//如果老师翻译文本不为空则根据老师音频打分
JSONObject speech_score_data = new JSONObject();
if (teacher_en == null || "".equals(teacher_en)){
speech_score_data = this.getSpeechScoreData(reqUrl,voice_path,subjectDialog.getConEn());
log.info("获取con_en值为:----->"+subjectDialog.getConEn());
log.info("根据con_en获取的打分结果为:----->"+speech_score_data.toString());
}else {
speech_score_data = this.getSpeechScoreData(reqUrl,voice_path,teacher_en);
}
if (speech_score_data == null){
return new Msg(400,"打分异常,无法解析到打分结果!");
}else {
//如果err_code不等于空,这段音频则为无效数据
if(speech_score_data.get("err_code") != null && !"".equals(speech_score_data.get("err_code").toString())){
log.info("无效数据!或者声音太小");
log.info("接口数据返回为:----"+speech_score_data.toString());
return new Msg(401, "无效音频文件,请重新录入!");
}
}
log.info("获取的userDialogJson数据为:-------"+speech_score_data.toString());
getErrorWordsJarray(speech_score_data, errArray);
}
json.put("err_words",errArray);
}else{
return new Msg(400,"没有用户音频记录");
}
log.info("返回的Json数据为:----->"+json.toString());
return new Msg(200, "", json);
} catch (Exception ex) {
log.error("获取用户语音评分错误:",ex);
return new Msg(400, "获取用户语音评分信息错误!" + ex.getMessage());
}
}
private void getErrorWordsJarray(JSONObject voiceData, JSONArray errArray) throws Exception {
if (voiceData.get("words") != null && !"".equals(voiceData.get("words").toString())){
JSONArray wordsArray = JSONArray.parseArray(voiceData.get("words").toString());
if (wordsArray != null && wordsArray.size() > 0){
for (int i = 0; i < wordsArray.size();i++){
JSONObject wordObject = wordsArray.getJSONObject(i);
log.info("获取打分结果的单词信息:----->"+wordObject.toString());
if (wordObject != null && !"".equals(wordObject)){
//获取读错的单词列表
JSONObject word = new JSONObject();
BigDecimal wordScore = new BigDecimal(Double.parseDouble(wordObject.get("score").toString())*10);
if (wordScore.compareTo(new BigDecimal(60)) < 0){
word.put("word_name",wordObject.get("name").toString());
JSONArray syllables = JSONArray.parseArray(wordObject.get("syllables").toString());
String dict = "";//正确音标
String rec = "";//用户发音音标
if (syllables != null && syllables.size() >0 ){
for(int s = 0;s < syllables.size();s++){
JSONObject syllables_view = syllables.getJSONObject(s);
//获取单词音标组phones
if (syllables_view != null && !"".equals(syllables_view)){
JSONArray phones = JSONObject.parseArray(syllables_view.get("phones").toString());
if(phones !=null && phones.size() > 0){
for(int p = 0;p < phones.size(); p++){
JSONObject phone = phones.getJSONObject(p);
if (phone != null && !"".equals(phone)){
String dictCode = phone.get("dict").toString();//正确音标组件
String recCode = phone.get("rec").toString();//用户音标组件
//音标转换
dictCode = EnglishToPhoneticUtil.phoneticValue(dictCode);
recCode = EnglishToPhoneticUtil.phoneticValue(recCode);
//拼接成音标
dict += dictCode;
rec += recCode;
}
}
}
}
}
}
//将单词的音标存入words数组里
word.put("word_dict",dict.trim());
word.put("word_rec",rec.trim());
//生成单词的正确读音音频文件
String word_name = wordObject.get("name").toString();
//用户单词音频的开始时间,
word.put("rec_start",wordObject.get("start"));//单位:毫秒
word.put("rec_end",wordObject.get("end"));//单位:毫秒
word.put("word_score",wordScore);//单词的得分
errArray.add(word);
}
log.info("错词详细信息为:----->"+word.toString());
}
}
}
}
}
/**
* 请求打分接口
* @param
* @param
* @param
*/
public JSONObject getSpeechScoreData(String reqUrl,String filePath,String text)throws IOException{
File file = new File(filePath);
MultipartUtility multipartUtility = new MultipartUtility(reqUrl,"UTF-8",token);
multipartUtility.addFilePart("myWavfile",file);
multipartUtility.addFormField("word_name",text);
List<String> pListResponse = multipartUtility.finish();
String voiceData = pListResponse.get(0);
JSONObject voiceObt = com.alibaba.fastjson.JSONObject.parseObject(voiceData);
return voiceObt;
}
/**
* 请求打分接口
* @param
* @param
* @param
*/
@RequestMapping("/test")
public JSONObject text()throws IOException{
File file = new File("F:\\workspace\\zhenlianService\\src\\main\\resources\\1542878441365.wav");
MultipartUtility multipartUtility = new MultipartUtility(reqUrl,"UTF-8",token);
multipartUtility.addFilePart("myWavfile",file);
multipartUtility.addFormField("word_name","111");
List<String> pListResponse = multipartUtility.finish();
String voiceData = pListResponse.get(0);
JSONObject voiceObt = com.alibaba.fastjson.JSONObject.parseObject(voiceData);
return voiceObt;
}
}