• 微信开发


    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 +
                        "&timestamp=" + 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;
        }
    }
  • 相关阅读:
    sql 语句系列(加减乘除与平均)[八百章之第十四章]
    并发系列64章(并发概要)第一章
    redis 一百二十篇(简单介绍)之第一篇
    sql 语句系列(分割ip)[八百章之第十四章]
    sql 语句系列(字符串之裂开)[八百章之第十三章]
    sql 语句系列(字符串之父与子之间)[八百章之第十二章]
    sql 语句系列(字符串的遍历嵌入删除与统计)[八百章之第十一章]
    sql 语句系列(用魔法打败魔法)[八百章之第十章]
    sql 语句系列(列举非索引外键)[八百章之第九章]
    sql 语句系列(列举系列)[八百章之第八章]
  • 原文地址:https://www.cnblogs.com/wujf/p/11101255.html
Copyright © 2020-2023  润新知