diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/ImAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/ImAppController.java index 45a52183..e0a778ca 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/ImAppController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/ImAppController.java @@ -31,4 +31,6 @@ public class ImAppController { ImResp resp = imService.sendMessage(LoginHelper.getUserId(), imMessageDTO); return R.ok(resp); } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/YxNotifyController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/YxNotifyController.java new file mode 100644 index 00000000..7c1e5ae5 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/YxNotifyController.java @@ -0,0 +1,56 @@ +package com.ruoyi.web.controller.cai.app; + +import cn.dev33.satoken.annotation.SaIgnore; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.yunxin.manager.YunxinManager; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StreamUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +@RestController +@RequestMapping("/api/yx/im") +@Tag(name = "Yunxin相关的接口") +@Slf4j +public class YxNotifyController { + + @Autowired + private YunxinManager yunxinManager; + + @PostMapping("/notify") + @Operation(hidden = true) + @SaIgnore + public R notifyYx(HttpServletRequest request) throws IOException { + String appKey = request.getHeader("AppKey"); + String curTime = request.getHeader("CurTime"); + String md5 = request.getHeader("MD5"); + String checkSum = request.getHeader("CheckSum"); + log.info("request headers: AppKey = {}, CurTime = {}, " + + "MD5 = {}, CheckSum = {}", appKey, curTime, md5, checkSum); + String requestBody = readBody(request); + log.info("request body = {}", requestBody); + boolean check = yunxinManager.checkNotify(requestBody, curTime); + if(!check){ + log.info("检验失败!"); + return R.fail("500",null); + } + return R.ok(); + } + + private String readBody(HttpServletRequest request) throws IOException { + if (request.getContentLength() > 0) { + byte[] bytes = StreamUtils.copyToByteArray(request.getInputStream()); + return new String(bytes, StandardCharsets.UTF_8); + } else + return null; + + } +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserCallAppVo.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserCallAppVo.java index d287eef2..b2ed2fdf 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserCallAppVo.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserCallAppVo.java @@ -18,6 +18,13 @@ public class UserCallAppVo { private Integer status; @Schema(description = "通话状态文字") private String statusText; + + @Schema(description = "通话时长") + private Long callTime = 0L; + @Schema(description = "通话金额") + private Long callAmount = 0L; + @Schema(description = "主播通话收益") + private Long callIncome = 0L; @Schema(description = "通话对方的用户ID") private Long userId; @Schema(description = "通话对方的用户蜜瓜号") diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/UserCallServiceImpl.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/UserCallServiceImpl.java index 230caaf8..5b22c855 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/UserCallServiceImpl.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/UserCallServiceImpl.java @@ -141,6 +141,9 @@ public class UserCallServiceImpl extends ServiceImpl i }if(status > RoomStatusEnums.STATUS_REFUSE.getCode()){ // 6 vo.setStatus(4); vo.setStatusText("已接通"); + vo.setCallTime(record.getCallTime()); + vo.setCallAmount(record.getCallAmount()); + vo.setCallIncome(record.getCallIncome()); } if(record.getBeginTime() != null){ vo.setCreateTime(record.getBeginTime()); diff --git a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/manager/YunxinManager.java b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/manager/YunxinManager.java new file mode 100644 index 00000000..f45b7b02 --- /dev/null +++ b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/manager/YunxinManager.java @@ -0,0 +1,28 @@ +package com.ruoyi.yunxin.manager; + +import com.ruoyi.yunxin.config.YunxinProperties; +import com.ruoyi.yunxin.util.CheckSumBuilder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class YunxinManager { + + @Autowired + private YunxinProperties yunxinProperties; + + public boolean checkNotify(String body,String curTime){ + try { + String appSecret = yunxinProperties.getAppSecret(); + String verifyMD5 = CheckSumBuilder.getMD5(body); + String verifyChecksum = CheckSumBuilder.getCheckSum(appSecret, verifyMD5, curTime); + return verifyMD5 != null && verifyMD5.equals(verifyChecksum); + }catch (Exception e){ + log.info("检查云信回调数据失败",e); + return false; + } + } + +} diff --git a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/util/CheckSumBuilder.java b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/util/CheckSumBuilder.java new file mode 100644 index 00000000..9612b444 --- /dev/null +++ b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/util/CheckSumBuilder.java @@ -0,0 +1,44 @@ +package com.ruoyi.yunxin.util; + +import java.security.MessageDigest; + +public class CheckSumBuilder { + + // 计算并获取CheckSum + public static String getCheckSum(String appSecret, String nonce, String curTime) { + return encode("sha1", appSecret + nonce + curTime); + } + + // 计算并获取md5值 + public static String getMD5(String requestBody) { + return encode("md5", requestBody); + } + + private static String encode(String algorithm, String value) { + if (value == null) { + return null; + } + try { + MessageDigest messageDigest = MessageDigest.getInstance(algorithm); + messageDigest.update(value.getBytes()); + return getFormattedText(messageDigest.digest()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private static String getFormattedText(byte[] bytes) { + int len = bytes.length; + StringBuilder buf = new StringBuilder(len * 2); + for (int j = 0; j < len; j++) { + buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]); + buf.append(HEX_DIGITS[bytes[j] & 0x0f]); + } + return buf.toString(); + + } + + private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; +}