Store license check user info

这个提交包含在:
XuqmGroup 2026-05-15 21:29:48 +08:00
父节点 d5b8f03996
当前提交 4f59fead0a
共有 3 个文件被更改,包括 70 次插入7 次删除

查看文件

@ -2,6 +2,7 @@ package com.xuqm.license.controller;
import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import com.xuqm.common.model.ApiResponse; import com.xuqm.common.model.ApiResponse;
import com.xuqm.license.service.DeviceService; import com.xuqm.license.service.DeviceService;
import jakarta.validation.Valid; import jakarta.validation.Valid;
@ -32,7 +33,8 @@ public class LicensePublicController {
req.deviceName(), req.deviceName(),
req.deviceModel(), req.deviceModel(),
req.deviceVendor(), req.deviceVendor(),
req.osVersion()); req.osVersion(),
req.userInfo());
Map<String, Object> data = new java.util.LinkedHashMap<>(); Map<String, Object> data = new java.util.LinkedHashMap<>();
data.put("success", result.success()); data.put("success", result.success());
data.put("token", result.token()); data.put("token", result.token());
@ -44,7 +46,7 @@ public class LicensePublicController {
@PostMapping("/verify") @PostMapping("/verify")
public ResponseEntity<ApiResponse<Map<String, Object>>> verify(@Valid @RequestBody VerifyRequest req) { public ResponseEntity<ApiResponse<Map<String, Object>>> 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<String, Object> data = new java.util.LinkedHashMap<>(); Map<String, Object> data = new java.util.LinkedHashMap<>();
data.put("valid", result.valid()); data.put("valid", result.valid());
if (result.error() != null) { if (result.error() != null) {
@ -59,12 +61,14 @@ public class LicensePublicController {
@JsonProperty("deviceName") @JsonAlias("device_name") String deviceName, @JsonProperty("deviceName") @JsonAlias("device_name") String deviceName,
@JsonProperty("deviceModel") @JsonAlias("device_model") String deviceModel, @JsonProperty("deviceModel") @JsonAlias("device_model") String deviceModel,
@JsonProperty("deviceVendor") @JsonAlias("device_vendor") String deviceVendor, @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( public record VerifyRequest(
@NotBlank @JsonProperty("companyId") @JsonAlias("company_id") String companyId, @NotBlank @JsonProperty("companyId") @JsonAlias("company_id") String companyId,
@NotBlank @JsonProperty("deviceId") @JsonAlias("device_id") String deviceId, @NotBlank @JsonProperty("deviceId") @JsonAlias("device_id") String deviceId,
@NotBlank String token @NotBlank String token,
@JsonProperty("userInfo") @JsonAlias("user_info") JsonNode userInfo
) {} ) {}
} }

查看文件

@ -32,6 +32,21 @@ public class DeviceEntity {
@Column(name = "os_version", length = 255) @Column(name = "os_version", length = 255)
private String osVersion; 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) @Column(nullable = false, name = "token_hash", length = 512)
private String tokenHash; private String tokenHash;
@ -71,6 +86,21 @@ public class DeviceEntity {
public String getOsVersion() { return osVersion; } public String getOsVersion() { return osVersion; }
public void setOsVersion(String osVersion) { this.osVersion = 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 String getTokenHash() { return tokenHash; }
public void setTokenHash(String tokenHash) { this.tokenHash = tokenHash; } public void setTokenHash(String tokenHash) { this.tokenHash = tokenHash; }

查看文件

@ -1,6 +1,8 @@
package com.xuqm.license.service; package com.xuqm.license.service;
import com.xuqm.common.exception.BusinessException; 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.CompanyEntity;
import com.xuqm.license.entity.DeviceEntity; import com.xuqm.license.entity.DeviceEntity;
import com.xuqm.license.repository.DeviceRepository; import com.xuqm.license.repository.DeviceRepository;
@ -22,11 +24,14 @@ public class DeviceService {
private final DeviceRepository deviceRepository; private final DeviceRepository deviceRepository;
private final CompanyService companyService; private final CompanyService companyService;
private final LicenseAuthService licenseAuthService; 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.deviceRepository = deviceRepository;
this.companyService = companyService; this.companyService = companyService;
this.licenseAuthService = licenseAuthService; this.licenseAuthService = licenseAuthService;
this.objectMapper = objectMapper;
} }
public Optional<DeviceEntity> findByDeviceId(String deviceId) { public Optional<DeviceEntity> findByDeviceId(String deviceId) {
@ -39,7 +44,8 @@ public class DeviceService {
@Transactional @Transactional
public RegisterResult register(String companyId, String deviceId, String deviceName, 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 // Check if device already registered
Optional<DeviceEntity> existingOpt = findByDeviceId(deviceId); Optional<DeviceEntity> existingOpt = findByDeviceId(deviceId);
if (existingOpt.isPresent()) { if (existingOpt.isPresent()) {
@ -54,6 +60,7 @@ public class DeviceService {
existing.setDeviceModel(firstNonBlank(deviceModel, existing.getDeviceModel())); existing.setDeviceModel(firstNonBlank(deviceModel, existing.getDeviceModel()));
existing.setDeviceVendor(firstNonBlank(deviceVendor, existing.getDeviceVendor())); existing.setDeviceVendor(firstNonBlank(deviceVendor, existing.getDeviceVendor()));
existing.setOsVersion(firstNonBlank(osVersion, existing.getOsVersion())); existing.setOsVersion(firstNonBlank(osVersion, existing.getOsVersion()));
applyUserInfo(existing, userInfo);
existing.setTokenHash(tokenHash); existing.setTokenHash(tokenHash);
existing.setLastVerifiedAt(LocalDateTime.now()); existing.setLastVerifiedAt(LocalDateTime.now());
existing.setUpdatedAt(LocalDateTime.now()); existing.setUpdatedAt(LocalDateTime.now());
@ -83,6 +90,7 @@ public class DeviceService {
device.setDeviceModel(deviceModel); device.setDeviceModel(deviceModel);
device.setDeviceVendor(deviceVendor); device.setDeviceVendor(deviceVendor);
device.setOsVersion(osVersion); device.setOsVersion(osVersion);
applyUserInfo(device, userInfo);
device.setTokenHash(tokenHash); device.setTokenHash(tokenHash);
device.setRegisteredAt(LocalDateTime.now()); device.setRegisteredAt(LocalDateTime.now());
device.setIsActive(true); device.setIsActive(true);
@ -96,7 +104,7 @@ public class DeviceService {
} }
@Transactional @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)) { if (!licenseAuthService.verifyTokenPayload(token, companyId, deviceId)) {
return new VerifyResult(false, "Token mismatch"); return new VerifyResult(false, "Token mismatch");
} }
@ -116,6 +124,7 @@ public class DeviceService {
} }
device.setLastVerifiedAt(LocalDateTime.now()); device.setLastVerifiedAt(LocalDateTime.now());
applyUserInfo(device, userInfo);
device.setUpdatedAt(LocalDateTime.now()); device.setUpdatedAt(LocalDateTime.now());
deviceRepository.save(device); deviceRepository.save(device);
@ -156,6 +165,26 @@ public class DeviceService {
return value == null || value.isBlank() ? fallback : value; 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 RegisterResult(boolean success, String token, String message) {}
public record VerifyResult(boolean valid, String error) {} public record VerifyResult(boolean valid, String error) {}
} }