longz
2026-08-11 2a3c3cdbf2398695d61633e072f98ee2757e9e27
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
108
package com.sinata.appointment.service;
 
import static org.assertj.core.api.Assertions.assertThat;
 
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sinata.appointment.config.HikvisionQrcodeProperties;
import com.sinata.appointment.entity.AppointmentOrder;
import com.sinata.appointment.entity.AppointmentVisitor;
import com.sinata.appointment.entity.MpUser;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.junit.jupiter.api.Test;
 
class IntegrationHikvisionServiceTest {
 
    private static final String AES_KEY = "WwXxYyZz1234!@#$";
    private static final String AES_IV = "AaBbCcDd1234!@#$";
    private final ObjectMapper objectMapper = new ObjectMapper();
 
    @Test
    void encryptedQrcodePayloadCanBeDecrypted() throws Exception {
        IntegrationHikvisionService service = newService(true);
        String plainJson = "{\"visitorName\":\"张燕\",\"visitorIdCard\":\"51090219960705552X\",\"visitorIdCardType\":\"111\",\"visitorPhone\":\"19382531220\",\"workUnit\":\"喜望\",\"beVisitorPhone\":\"14725836905\",\"startTime\":\"20260727000000\",\"endTime\":\"20260728235959\",\"areas\":\"A区域\",\"beVisitorName\":\"张强\",\"date\":\"260727000000.000\",\"validTime\":\"m4320\",\"codeId\":\"177\"}";
 
        String encrypted = service.encryptQrcodePayload(plainJson);
//        String encrypted = "nVMz8HLX4TKP8NSYbHAmhXUurZyGWAte2fsf5W/mqu63c1cAhDOg/VhbdtZx0ceMtkOo1qdL5JBdIEJ6J0LPcg6K9vJwcKPVtsDwllxAsnNyKK+JYBry7WOhGYSqys07OsPpXKOEFcS3WfUdq0JZATHr/A5f6Bev1GM6Ge4a3CRXszqaptZavZI7zAxEFnPMnpkuU6JozYmYZh4i7tKuJ43Y7WC6SHLBK//yFo1nQzym+FMHXyIAJCril1S2MhnWz7CdcSjd+I85NVW+5jKU88oFQ4OtxncG4bnjzfJAroDRaqGfLL1vhYOvnSa0ijwYNhuRloJN5P6pM5ZDJ1SBymF012tljU0jMkWu5kM28sqChQrERXq9A2xyZ7DZ5gaTDVZvFvztnZO/QdGMDqcj15427236BTES2Oti+2moZ2smZsbQTbOjJ1AwvXIsyQjUu13wxS8q2WMo9KCO+1aXxw==";
        System.out.println(encrypted);
        System.out.println(decrypt(encrypted));
//
//        assertThat(encrypted).isNotEqualTo(plainJson);
//        assertThat(decrypt(encrypted)).isEqualTo(plainJson);
    }
 
    @Test
    void encryptQrcodePayloadKeepsPlainJsonWhenEncryptionDisabled() {
        IntegrationHikvisionService service = newService(false);
        String plainJson = "{\"codeId\":\"TICKET-002\"}";
 
        String result = service.encryptQrcodePayload(plainJson);
 
        assertThat(result).isEqualTo(plainJson);
    }
 
    @Test
    void buildPlainQrcodePayloadOmitsEmptyCustomFieldsAndUsesGivenCodeId() throws Exception {
        IntegrationHikvisionService service = newService(false);
        AppointmentOrder order = new AppointmentOrder();
        order.setId(1L);
        order.setVisitedUserName("李医生");
        order.setVisitorOrg("测试单位");
        order.setVisitStartDate(LocalDate.of(2026, 7, 9));
        order.setVisitEndDate(LocalDate.of(2026, 7, 9));
        AppointmentVisitor visitor = new AppointmentVisitor();
        visitor.setName("张三");
        visitor.setMobile("13800000000");
        MpUser visitedUser = new MpUser();
        visitedUser.setStaffNo("STAFF-001");
        visitedUser.setMobile("13900000000");
        visitedUser.setNickName("李医生");
 
        String plain =
                service.buildPlainQrcodePayload(
                        order,
                        visitor,
                        null,
                        visitedUser,
                        "来访",
                        "行政楼",
                        LocalDateTime.of(2026, 7, 9, 10, 0),
                        LocalDateTime.of(2026, 7, 9, 23, 59),
                        60,
                        "CODE-001",
                        "500101199001011234");
 
        Map<?, ?> payload = objectMapper.readValue(plain, Map.class);
        assertThat(payload.get("codeId")).isEqualTo("CODE-001");
        assertThat(payload.containsKey("jobNo")).isFalse();
        assertThat(payload.containsKey("customa")).isFalse();
        assertThat(payload.containsKey("customb")).isFalse();
        assertThat(payload.containsKey("customc")).isFalse();
        assertThat(payload.get("visitorPhone")).isEqualTo("13800000000");
        assertThat(payload.containsKey("workUnit")).isFalse();
        assertThat(payload.containsKey("visitPurpose")).isFalse();
    }
 
    private IntegrationHikvisionService newService(boolean encryptEnabled) {
        HikvisionQrcodeProperties properties = new HikvisionQrcodeProperties();
        properties.setEncryptEnabled(encryptEnabled);
        properties.setAesKey(AES_KEY);
        properties.setAesIv(AES_IV);
        return new IntegrationHikvisionService(new ObjectMapper(), properties);
    }
 
    private String decrypt(String encrypted) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(AES_IV.getBytes(StandardCharsets.UTF_8));
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encrypted));
        return new String(decrypted, StandardCharsets.UTF_8);
    }
}