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);
|
}
|
}
|