feat(push): 添加 romVersion 字段及设备 Token 查询接口

- DeviceTokenEntity: 新增 rom_version 字段(厂商系统版本)
- PushController: register 接口添加可选 romVersion 参数
- PushDispatcher: 注册时保存 romVersion
- PushDiagnosticsService.DeviceInfo: 返回 romVersion
- PushManagementController: 新增 GET /admin/devices/{id}/token 接口(管理端查完整 token)
- PushSchemaMigrationService: 添加 v20260626_add_rom_version 迁移

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-06-26 12:24:45 +08:00
父节点 0b1b4af8b3
当前提交 83ca8c0f49
共有 6 个文件被更改,包括 46 次插入4 次删除

查看文件

@ -32,12 +32,13 @@ public class PushController {
@RequestParam(required = false) String brand,
@RequestParam(required = false) String model,
@RequestParam(required = false) String osVersion,
@RequestParam(required = false) String appVersion) {
@RequestParam(required = false) String appVersion,
@RequestParam(required = false) String romVersion) {
requireNonBlank(appKey, "appKey");
requireNonBlank(userId, "userId");
requireNonNull(vendor, "vendor");
requireNonBlank(token, "token");
pushDispatcher.registerToken(appKey, userId, vendor, token, platform, deviceId, brand, model, osVersion, appVersion);
pushDispatcher.registerToken(appKey, userId, vendor, token, platform, deviceId, brand, model, osVersion, appVersion, romVersion);
return ResponseEntity.ok(ApiResponse.ok());
}

查看文件

@ -2,7 +2,9 @@ package com.xuqm.push.controller;
import com.xuqm.common.model.ApiResponse;
import com.xuqm.push.entity.DeviceLoginLogEntity;
import com.xuqm.push.entity.DeviceTokenEntity;
import com.xuqm.push.entity.PushUserEntity;
import com.xuqm.push.repository.DeviceTokenRepository;
import com.xuqm.push.service.PushAccountService;
import com.xuqm.push.service.PushDiagnosticsService;
import com.xuqm.push.service.PushOperationLogService;
@ -31,13 +33,16 @@ public class PushManagementController {
private final PushDiagnosticsService diagnosticsService;
private final PushAccountService accountService;
private final PushOperationLogService opLogService;
private final DeviceTokenRepository tokenRepository;
public PushManagementController(PushDiagnosticsService diagnosticsService,
PushAccountService accountService,
PushOperationLogService opLogService) {
PushOperationLogService opLogService,
DeviceTokenRepository tokenRepository) {
this.diagnosticsService = diagnosticsService;
this.accountService = accountService;
this.opLogService = opLogService;
this.tokenRepository = tokenRepository;
}
// ---- user account management ----
@ -159,6 +164,16 @@ public class PushManagementController {
return ResponseEntity.ok(ApiResponse.success(result));
}
@GetMapping("/devices/{id}/token")
public ResponseEntity<ApiResponse<Map<String, String>>> getDeviceToken(
@PathVariable String id,
@RequestParam String appKey) {
return tokenRepository.findById(id)
.filter(e -> appKey.equals(e.getAppKey()))
.map(e -> ResponseEntity.ok(ApiResponse.success(Map.of("token", e.getToken()))))
.orElseGet(() -> ResponseEntity.ok(ApiResponse.error(404, "设备不存在")));
}
public record UpdateUserRequest(String appKey, String nickname, String avatar, String gender) {}
public record UserStatusRequest(String appKey, String status) {}
public record ImportUserRequest(String appKey, String userId, String nickname,

查看文件

@ -49,6 +49,9 @@ public class DeviceTokenEntity {
@Column(length = 64)
private String osVersion;
@Column(length = 64)
private String romVersion;
@Column(length = 64)
private String appVersion;
@ -94,6 +97,9 @@ public class DeviceTokenEntity {
public String getOsVersion() { return osVersion; }
public void setOsVersion(String osVersion) { this.osVersion = osVersion; }
public String getRomVersion() { return romVersion; }
public void setRomVersion(String romVersion) { this.romVersion = romVersion; }
public String getAppVersion() { return appVersion; }
public void setAppVersion(String appVersion) { this.appVersion = appVersion; }

查看文件

@ -156,6 +156,7 @@ public class PushDiagnosticsService {
String brand,
String model,
String osVersion,
String romVersion,
String appVersion,
boolean receivePush,
LocalDateTime lastLoginAt,
@ -170,6 +171,7 @@ public class PushDiagnosticsService {
entity.getBrand(),
entity.getModel(),
entity.getOsVersion(),
entity.getRomVersion(),
entity.getAppVersion(),
entity.isReceivePush(),
entity.getLastLoginAt(),

查看文件

@ -243,7 +243,8 @@ public class PushDispatcher {
String brand,
String model,
String osVersion,
String appVersion) {
String appVersion,
String romVersion) {
String resolvedDeviceId = normalizeDeviceId(deviceId, vendor, token);
Optional<DeviceTokenEntity> existing = tokenRepository.findByAppKeyAndUserIdAndDeviceId(appKey, userId, resolvedDeviceId);
if (existing.isEmpty() && (deviceId == null || deviceId.isBlank())) {
@ -266,6 +267,7 @@ public class PushDispatcher {
entity.setBrand(blankToNull(brand));
entity.setModel(blankToNull(model));
entity.setOsVersion(blankToNull(osVersion));
entity.setRomVersion(blankToNull(romVersion));
entity.setAppVersion(blankToNull(appVersion));
entity.setReceivePush(true);
entity.setLastLoginAt(now);

查看文件

@ -37,6 +37,7 @@ public class PushSchemaMigrationService {
migrate_v20260527_create_push_operation_log(emit);
migrate_v20260626_remove_app_id(emit);
migrate_v20260626_add_rom_version(emit);
emit.accept("数据库迁移检查完成");
}
@ -161,4 +162,19 @@ public class PushSchemaMigrationService {
log.error("migration {} failed", id, e);
}
}
private void migrate_v20260626_add_rom_version(Consumer<String> emit) {
final String id = "v20260626_add_rom_version";
if (migrationApplied(id)) { emit.accept("[已应用] " + id); return; }
try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
if (!columnExists(conn, "push_device_token", "rom_version")) {
stmt.execute("ALTER TABLE push_device_token ADD COLUMN rom_version VARCHAR(64) NULL AFTER os_version");
}
emit.accept("[已迁移] " + id + ": 添加 rom_version 字段");
recordMigration(id, "在 push_device_token 添加厂商 ROM 版本字段 rom_version");
} catch (Exception e) {
emit.accept("[错误] " + id + ": " + e.getMessage());
log.error("migration {} failed", id, e);
}
}
}