Pu Zhibing
2025-05-09 8580866e175ad0050ee9c5ea3f757856fc242c39
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.stylefeng.guns.modular.system.util;
 
import cn.hutool.json.JSONObject;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
 
public class SignVerificationUtil {
 
    private static final String accessKeySecret = "cda9983a-91c1-414b-bed7-9d307ec584af";
 
    public static Boolean signVerification(String appKey,String ts,String signature,JSONObject body) {
        // 商⼾对应秘钥,由平台⽅提供
        /**
         * Body信息
         * {
         * "answerTime":1663838323949173,
         * "audioPath":"https://cc.v-call.cn/obc/api/file/download/0e2c6b4c-6a4d-474c-a0d
         4-xxxxx",
         * "callTime":1663838323949173,
         * "duration":37,
         * "hangupCauseReason":"正常结束",
         * "hangupTime":1663838360949096,
         * "ivrNodeAudioList":[
         * {
         * "id":"6qxrfoofya",
         * "name":"留⾔1",
         * "downloadUrl":"https://cc.v-call.cn/obc/api/file/ivrNode/download/0e2c6b4c
         -6a4d-474c-a0d4-5bf3902ca713/xxxxx"
         * }
         * ],
         * "outputParam":"
         {\"area\":\"2\",\"pushUrl\":\"https://www.baidu.com\",\"account\":\"test\"}",
         * "phone":"18888888888",
         * "ringTime":0
         * }
         * **/
        CallInfoDTO dto = new CallInfoDTO();
        dto.setPhone(body.getStr("phone"));
        JSONObject outputParam = body.getJSONObject("outputParam");
        dto.setOutputParam(outputParam.toString());
        dto.setCallTime(body.getLong("callTime"));
        dto.setRingTime(body.getLong("ringTime"));
        dto.setAnswerTime(body.getLong("answerTime"));
        dto.setHangupTime(body.getLong("hangupTime"));
        dto.setHangupCauseReason(body.getStr("hangupCauseReason"));
        dto.setDuration(body.getInt("duration"));
 
        ArrayList<IvrNodeAudio> nodeList = new ArrayList<IvrNodeAudio>();
        body.getJSONArray("ivrNodeAudioList").forEach(item -> {
            JSONObject jsonObject = (JSONObject) item;
            IvrNodeAudio nodeAudio = new IvrNodeAudio(jsonObject.getStr("id"),jsonObject.getStr("name"),jsonObject.getStr("downloadUrl"));
            nodeList.add(nodeAudio);
        });
        dto.setIvrNodeAudioList(nodeList);
        dto.setAudioPath(body.getStr("audioPath"));
 
        Map<String,Object> bodyMap = new JSONObject(dto);
        // 1. remove sign parameter
        bodyMap.entrySet().removeIf(entry -> entry.getValue() == null);
        // 2. 把字典按Key的字⺟顺序排序
        Map<String, Object> treeMap = new TreeMap<>(bodyMap);
        // 3. 把参数串起来
        StringBuffer secretString = new StringBuffer(accessKeySecret).append("appKey").append(appKey);
        treeMap.forEach((key, value) -> secretString.append(key).append(value));
        secretString.append("ts").append(ts);
        String sign = MD5AndKL.MD5(secretString.toString()).toUpperCase();
        // 验签
        if(!signature.equals(sign)){
            System.out.println("验签失败");
            return false;
        }
    // 成功
        System.out.println("验签成功,继续执⾏业务逻辑");
        return true;
    }
    @Data
    public static class CallInfoDTO {
        private String audioPath;
        private String phone;
        private String outputParam;
        private Long callTime;
        private Long ringTime;
        private Long answerTime;
        private Long hangupTime;
        private String hangupCauseReason;
        private Integer duration;
        private List<IvrNodeAudio> ivrNodeAudioList;
    }
    @Data
    public static class IvrNodeAudio {
        private String id;
        private String name;
        private String downloadUrl;
        public IvrNodeAudio(String id, String name, String downloadUrl) {
            this.id = id;
            this.name = name;
            this.downloadUrl = downloadUrl;
        }
        public IvrNodeAudio() {
        }
    }
}