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; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; 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 @RequestMapping("/api/live") @Api(description = "直播相关接口") public class UserLiveController extends BaseController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private Producer producer; @Autowired @Qualifier("objectCommonRedisTemplate") RedisTemplate redisTemplate; @Autowired private WxCUserBasicInfoService wxCUserBasicInfoService; @Autowired private WxCLiveUserBasicInfoService wxCLiveUserBasicInfoService; @Autowired private WxCVideoService wxCVideoService; @Autowired private WxCVoiceService wxCVoiceService; @Autowired private WxCUserAuthorityService wxCUserAuthorityService; @Autowired private VoiceInfoService voiceInfoService; @AuthIgnore @PostMapping("/login") @ApiOperation(value = "用户登录", notes = "{\"username\":\"string\",\"password\":\"string\",\"code\":\"string\",\"status\":\"int\"}") public Map login(@RequestBody Map map, HttpServletResponse response) { String ipAddr = getIpAddr(); logger.debug("[" + ipAddr + "] WxUserGrantController::login"); Map resultMap = new HashMap<>(); HashMap status = new HashMap<>(); String code = map.get("code"); String phone = map.get("username"); String password = map.get("password"); if (StringUtils.isBlank(phone) || StringUtils.isBlank(password)) { status.put("code", ErrorCode.SYS_PARAMETER_ERROR.getCode()); status.put("message", "手机号或密码为空"); resultMap.put("status", status); return resultMap; } WxCUserBasicInfo basicInfo = wxCUserBasicInfoService.findInfoByPhone(getTenantInfo(), phone); if (basicInfo == null) { status.put("code", ErrorCode.USER_IS_EMPTY); status.put("message", "用户不存在"); resultMap.put("status", status); return resultMap; } String encryptPassword = new PasswordHelper().encryptPassword(password); if (!encryptPassword.equals(basicInfo.getPassword())) { status.put("code", ErrorCode.USER_PASSWD_ERR.getCode()); status.put("message", "手机号或密码错误"); resultMap.put("status", status); return resultMap; } int statu = Integer.parseInt(map.get("status")); if (statu == 0) { WxCUserBasicInfo basicLiveInfo = wxCLiveUserBasicInfoService.getById(basicInfo.getId()); if (basicLiveInfo.getCode() != null && !basicLiveInfo.getCode().equals(code)) { status.put("code", ErrorCode.USER_ALREADY_LOGIN.getCode()); status.put("message", "用户已在其他设备登录"); resultMap.put("status", status); return resultMap; } if (basicLiveInfo.getCode() == null) { wxCLiveUserBasicInfoService.updateCode(basicInfo.getId(), map.get("code")); } } if (statu == -1) { wxCLiveUserBasicInfoService.updateCode(basicInfo.getId(), null); basicInfo.setStatus(-2); status.put("code", ErrorCode.USER_CANCEL_MCODE.getCode()); status.put("message", "设备已注销"); resultMap.put("status", status); return resultMap; } wxCUserBasicInfoService.handleLoginUser(basicInfo); WxCUserBasicInfo basicLiveInfo = wxCLiveUserBasicInfoService.getById(basicInfo.getId()); Map data = new HashMap(); data.put("username",basicInfo.getPhone()); data.put("status", 0); data.put("version", basicLiveInfo.getVersion()); data.put("current_time", new Date(System.currentTimeMillis() / 1000)); data.put("expire_time", basicLiveInfo.getExpireTime().getTime() / 1000); data.put("token", basicInfo.getToken()); resultMap.put("data", data); status.put("code", 1000); status.put("message", "success"); resultMap.put("status", status); return resultMap; } /** * 视频模板列表 */ @PostMapping("/avatarList") @ApiOperation(value = "视频模板列表", notes = "{\"username\",\"string\",\"code\",\"string\"}") public Map avatarList(@RequestBody Map params) throws Exception { String ipaddress = getIpAddr(); logger.debug("[" + ipaddress + "] WxUserGrantController::getAvatarList"); Map resultMap = new HashMap<>(); HashMap status = new HashMap<>(); String code = params.get("code"); Long userId = getMemberId(); //鉴权 WxCUserBasicInfo basicLiveInfo = wxCLiveUserBasicInfoService.getById(userId); if (basicLiveInfo.getCode() != null && !basicLiveInfo.getCode().equals(code)) { status.put("code", ErrorCode.USER_ALREADY_LOGIN.getCode()); status.put("message", "用户已在其他设备登录"); resultMap.put("status", status); return resultMap; } Map data = wxCVideoService.getById(userId); resultMap.put("data", data); status.put("code", 1000); status.put("msg", "success"); resultMap.put("status", status); return resultMap; } /** * 音频模板列表 */ @PostMapping("/audioList") @ApiOperation(value = "音频模板列表", notes = "{\"username\",\"string\",\"code\",\"string\"}") public Map audioList(@RequestBody Map params) { String ipaddress = getIpAddr(); logger.debug("[" + ipaddress + "] WxUserGrantController::getAudioList"); Map resultMap = new HashMap<>(); HashMap status = new HashMap<>(); String code = params.get("code"); Long userId = getMemberId(); WxCUserBasicInfo basicLiveInfo = wxCLiveUserBasicInfoService.getById(userId); if (basicLiveInfo.getCode() != null && !basicLiveInfo.getCode().equals(code)) { status.put("code", ErrorCode.USER_ALREADY_LOGIN.getCode()); status.put("message", "用户已在其他设备登录"); resultMap.put("status", status); return resultMap; } Map data = wxCVoiceService.getById(userId); resultMap.put("data", data); status.put("code", 1000); status.put("msg", "success"); resultMap.put("status", status); return resultMap; } /** * 资源权限查询 */ @ApiOperation(value = "资源权限查询", notes = "{\"username\",\"string\",\"code\",\"string\",\"type\",\"int\",\"resource_id\",\"long\"}") @PostMapping("/author") public Map getAuthor(@RequestBody Map params) { String ipaddress = getIpAddr(); logger.debug("[" + ipaddress + "] WxUserGrantController::getAuthor"); Map resultMap = new HashMap<>(); HashMap status = new HashMap<>(); String code = params.get("code"); Integer type = Integer.parseInt(params.get("type")); Long resourceId = Long.valueOf(params.get("resource_id")); if(type == null){ status.put("code", ErrorCode.SYS_PARAMETER_NOT_NULL.getCode()); status.put("message", "type 为空"); resultMap.put("status", status); return resultMap; } if(resourceId == null){ status.put("code", ErrorCode.SYS_PARAMETER_NOT_NULL.getCode()); status.put("message", "资源ID 为空"); resultMap.put("status", status); return resultMap; } Long userId = getMemberId(); WxCUserBasicInfo basicLiveInfo = wxCLiveUserBasicInfoService.getById(userId); if (basicLiveInfo.getCode() != null && !basicLiveInfo.getCode().equals(code)) { status.put("code", ErrorCode.USER_ALREADY_LOGIN.getCode()); status.put("message", "用户已在其他设备登录"); resultMap.put("status", status); return resultMap; } Map data = wxCUserAuthorityService.getAuthor(userId, code, type, resourceId); if(data != null){ resultMap.put("data", data); status.put("code", 1000); status.put("msg", "success"); resultMap.put("status", status); return resultMap; } status.put("code", ErrorCode.SYS_NULLPOINTER_ERROR.getCode()); status.put("msg", "未查询到资源权限"); resultMap.put("status", status); return resultMap; } @ApiOperation(value = "tts", notes = "{\"username\",\"string\",\"gen_txt\",\"string\",\"voice_id\",\"string\",\"voice_style\",\"string\",\"speed\",\"int\"}") @PostMapping("/audiotts") public Map voicePreview(@RequestBody Map params) { logger.debug("[" + getIpAddr() + "] UserLiveController::voicePreview"); Map resultMap = new HashMap<>(); HashMap status = new HashMap<>(); String voice_id = params.get("voice_id"); String voiceStyle = params.get("voice_style"); if (StringUtils.isBlank(voice_id)) { status.put("code", ErrorCode.SYS_PARAMETER_NOT_NULL.getCode()); status.put("msg", "音色ID不能为空"); resultMap.put("status", status); return resultMap; } Long voiceId = null; try{ voiceId = Long.parseLong(voice_id); }catch(Exception e){ status.put("code", ErrorCode.SYS_PARAMETER_ERROR.getCode()); status.put("msg", "音色ID参数异常"); resultMap.put("status", status); return resultMap; } String text = params.get("gen_txt"); if (StringUtils.isBlank(text)) { resultMap.put("code", ErrorCode.SYS_PARAMETER_NOT_NULL.getCode()); resultMap.put("msg", "需要生成的文字不能为空"); return resultMap; } String speedStr = params.get("speed"); Integer speed = null; try{ speed = Integer.parseInt(speedStr); }catch(Exception e){} Map data = wxCVoiceService.voicePreview(voiceId,voiceStyle,text,speed); if(data != null){ resultMap.put("data", data); status.put("code", 1000); status.put("msg", "success"); resultMap.put("status", status); return resultMap; } status.put("code", ErrorCode.SYS_PARAMETER_NOT_NULL.getCode()); status.put("msg", "获取tts 异常"); resultMap.put("status", status); return resultMap; } @AuthIgnore @SneakyThrows @ApiOperation(value = "模板下载接口", notes = "{\"username\",\"string\",\"gen_txt\",\"string\",\"voice_id\",\"string\",\"voice_style\",\"string\",\"speed\",\"int\"}") @GetMapping("exportVideo") public void exportVideo(@RequestBody Map 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 voiceInfos = wxCVoiceService.chooseType(id); return new ResultData(voiceInfos); } }