diff --git a/license-service/src/main/java/com/xuqm/license/controller/LicensePublicController.java b/license-service/src/main/java/com/xuqm/license/controller/LicensePublicController.java index 4de8b17..c9af7eb 100644 --- a/license-service/src/main/java/com/xuqm/license/controller/LicensePublicController.java +++ b/license-service/src/main/java/com/xuqm/license/controller/LicensePublicController.java @@ -2,6 +2,7 @@ package com.xuqm.license.controller; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; import com.xuqm.common.model.ApiResponse; import com.xuqm.license.service.DeviceService; import jakarta.validation.Valid; @@ -32,7 +33,8 @@ public class LicensePublicController { req.deviceName(), req.deviceModel(), req.deviceVendor(), - req.osVersion()); + req.osVersion(), + req.userInfo()); Map data = new java.util.LinkedHashMap<>(); data.put("success", result.success()); data.put("token", result.token()); @@ -44,7 +46,7 @@ public class LicensePublicController { @PostMapping("/verify") public ResponseEntity>> verify(@Valid @RequestBody VerifyRequest req) { - DeviceService.VerifyResult result = deviceService.verify(req.companyId(), req.deviceId(), req.token()); + DeviceService.VerifyResult result = deviceService.verify(req.companyId(), req.deviceId(), req.token(), req.userInfo()); Map data = new java.util.LinkedHashMap<>(); data.put("valid", result.valid()); if (result.error() != null) { @@ -59,12 +61,14 @@ public class LicensePublicController { @JsonProperty("deviceName") @JsonAlias("device_name") String deviceName, @JsonProperty("deviceModel") @JsonAlias("device_model") String deviceModel, @JsonProperty("deviceVendor") @JsonAlias("device_vendor") String deviceVendor, - @JsonProperty("osVersion") @JsonAlias("os_version") String osVersion + @JsonProperty("osVersion") @JsonAlias("os_version") String osVersion, + @JsonProperty("userInfo") @JsonAlias("user_info") JsonNode userInfo ) {} public record VerifyRequest( @NotBlank @JsonProperty("companyId") @JsonAlias("company_id") String companyId, @NotBlank @JsonProperty("deviceId") @JsonAlias("device_id") String deviceId, - @NotBlank String token + @NotBlank String token, + @JsonProperty("userInfo") @JsonAlias("user_info") JsonNode userInfo ) {} } diff --git a/license-service/src/main/java/com/xuqm/license/entity/DeviceEntity.java b/license-service/src/main/java/com/xuqm/license/entity/DeviceEntity.java index 4bc9e59..e4fbee6 100644 --- a/license-service/src/main/java/com/xuqm/license/entity/DeviceEntity.java +++ b/license-service/src/main/java/com/xuqm/license/entity/DeviceEntity.java @@ -32,6 +32,21 @@ public class DeviceEntity { @Column(name = "os_version", length = 255) private String osVersion; + @Column(name = "user_id", length = 255) + private String userId; + + @Column(name = "user_name", length = 255) + private String userName; + + @Column(name = "user_email", length = 255) + private String userEmail; + + @Column(name = "user_phone", length = 64) + private String userPhone; + + @Column(name = "user_info_json", columnDefinition = "TEXT") + private String userInfoJson; + @Column(nullable = false, name = "token_hash", length = 512) private String tokenHash; @@ -71,6 +86,21 @@ public class DeviceEntity { public String getOsVersion() { return osVersion; } public void setOsVersion(String osVersion) { this.osVersion = osVersion; } + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } + + public String getUserName() { return userName; } + public void setUserName(String userName) { this.userName = userName; } + + public String getUserEmail() { return userEmail; } + public void setUserEmail(String userEmail) { this.userEmail = userEmail; } + + public String getUserPhone() { return userPhone; } + public void setUserPhone(String userPhone) { this.userPhone = userPhone; } + + public String getUserInfoJson() { return userInfoJson; } + public void setUserInfoJson(String userInfoJson) { this.userInfoJson = userInfoJson; } + public String getTokenHash() { return tokenHash; } public void setTokenHash(String tokenHash) { this.tokenHash = tokenHash; } diff --git a/license-service/src/main/java/com/xuqm/license/service/DeviceService.java b/license-service/src/main/java/com/xuqm/license/service/DeviceService.java index 2ecf01b..6751420 100644 --- a/license-service/src/main/java/com/xuqm/license/service/DeviceService.java +++ b/license-service/src/main/java/com/xuqm/license/service/DeviceService.java @@ -1,6 +1,8 @@ package com.xuqm.license.service; import com.xuqm.common.exception.BusinessException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.xuqm.license.entity.CompanyEntity; import com.xuqm.license.entity.DeviceEntity; import com.xuqm.license.repository.DeviceRepository; @@ -22,11 +24,14 @@ public class DeviceService { private final DeviceRepository deviceRepository; private final CompanyService companyService; private final LicenseAuthService licenseAuthService; + private final ObjectMapper objectMapper; - public DeviceService(DeviceRepository deviceRepository, CompanyService companyService, LicenseAuthService licenseAuthService) { + public DeviceService(DeviceRepository deviceRepository, CompanyService companyService, + LicenseAuthService licenseAuthService, ObjectMapper objectMapper) { this.deviceRepository = deviceRepository; this.companyService = companyService; this.licenseAuthService = licenseAuthService; + this.objectMapper = objectMapper; } public Optional findByDeviceId(String deviceId) { @@ -39,7 +44,8 @@ public class DeviceService { @Transactional public RegisterResult register(String companyId, String deviceId, String deviceName, - String deviceModel, String deviceVendor, String osVersion) { + String deviceModel, String deviceVendor, String osVersion, + JsonNode userInfo) { // Check if device already registered Optional existingOpt = findByDeviceId(deviceId); if (existingOpt.isPresent()) { @@ -54,6 +60,7 @@ public class DeviceService { existing.setDeviceModel(firstNonBlank(deviceModel, existing.getDeviceModel())); existing.setDeviceVendor(firstNonBlank(deviceVendor, existing.getDeviceVendor())); existing.setOsVersion(firstNonBlank(osVersion, existing.getOsVersion())); + applyUserInfo(existing, userInfo); existing.setTokenHash(tokenHash); existing.setLastVerifiedAt(LocalDateTime.now()); existing.setUpdatedAt(LocalDateTime.now()); @@ -83,6 +90,7 @@ public class DeviceService { device.setDeviceModel(deviceModel); device.setDeviceVendor(deviceVendor); device.setOsVersion(osVersion); + applyUserInfo(device, userInfo); device.setTokenHash(tokenHash); device.setRegisteredAt(LocalDateTime.now()); device.setIsActive(true); @@ -96,7 +104,7 @@ public class DeviceService { } @Transactional - public VerifyResult verify(String companyId, String deviceId, String token) { + public VerifyResult verify(String companyId, String deviceId, String token, JsonNode userInfo) { if (!licenseAuthService.verifyTokenPayload(token, companyId, deviceId)) { return new VerifyResult(false, "Token mismatch"); } @@ -116,6 +124,7 @@ public class DeviceService { } device.setLastVerifiedAt(LocalDateTime.now()); + applyUserInfo(device, userInfo); device.setUpdatedAt(LocalDateTime.now()); deviceRepository.save(device); @@ -156,6 +165,26 @@ public class DeviceService { return value == null || value.isBlank() ? fallback : value; } + private void applyUserInfo(DeviceEntity device, JsonNode userInfo) { + if (userInfo == null || userInfo.isNull() || !userInfo.isObject()) { + return; + } + device.setUserId(firstNonBlank(text(userInfo, "userId"), device.getUserId())); + device.setUserName(firstNonBlank(text(userInfo, "name"), device.getUserName())); + device.setUserEmail(firstNonBlank(text(userInfo, "email"), device.getUserEmail())); + device.setUserPhone(firstNonBlank(text(userInfo, "phone"), device.getUserPhone())); + try { + device.setUserInfoJson(objectMapper.writeValueAsString(userInfo)); + } catch (Exception ignored) { + // Ignore malformed optional metadata and keep core license check available. + } + } + + private static String text(JsonNode node, String field) { + JsonNode value = node.get(field); + return value == null || value.isNull() ? null : value.asText(null); + } + public record RegisterResult(boolean success, String token, String message) {} public record VerifyResult(boolean valid, String error) {} }