199 行
8.1 KiB
Java
199 行
8.1 KiB
Java
package com.xuqm.update.entity;
|
|
|
|
import jakarta.persistence.Column;
|
|
import jakarta.persistence.Entity;
|
|
import jakarta.persistence.EnumType;
|
|
import jakarta.persistence.Enumerated;
|
|
import jakarta.persistence.Id;
|
|
import jakarta.persistence.Table;
|
|
import java.time.LocalDateTime;
|
|
|
|
/**
|
|
* 一个经过平台签名的 RN 插件发布物。
|
|
*
|
|
* <p>身份字段全部来自 ZIP 内的 rn-manifest.json,发布、灰度和下线只能改变发布状态,
|
|
* 不能修改这些不可变字段。历史旧记录缺少 archiveSha256/signature,永远不会进入候选集。</p>
|
|
*/
|
|
@Entity
|
|
@Table(name = "update_rn_bundle")
|
|
public class RnBundleEntity {
|
|
|
|
public enum Platform { ANDROID, IOS }
|
|
public enum ModuleType { COMMON, APP, BUZ }
|
|
public enum PublishStatus { DRAFT, PUBLISHED, DEPRECATED }
|
|
public enum GrayMode { PERCENT, MEMBERS }
|
|
|
|
@Id
|
|
private String id;
|
|
|
|
@Column(nullable = false, length = 64)
|
|
private String appKey;
|
|
|
|
@Column(nullable = false, length = 256)
|
|
private String packageName;
|
|
|
|
@Column(nullable = false, length = 64)
|
|
private String moduleId;
|
|
|
|
@Enumerated(EnumType.STRING)
|
|
@Column(nullable = false, length = 16)
|
|
private ModuleType moduleType;
|
|
|
|
@Enumerated(EnumType.STRING)
|
|
@Column(nullable = false, length = 16)
|
|
private Platform platform;
|
|
|
|
@Column(nullable = false, length = 64)
|
|
private String version;
|
|
|
|
@Column(nullable = false, length = 128)
|
|
private String appVersionRange;
|
|
|
|
@Column(nullable = false, length = 128)
|
|
private String builtAgainstNativeBaselineId;
|
|
|
|
@Column(nullable = false, length = 128)
|
|
private String buildId;
|
|
|
|
@Column(nullable = false, length = 32)
|
|
private String bundleFormat;
|
|
|
|
@Column(length = 128)
|
|
private String commonVersionRange;
|
|
|
|
@Column(nullable = false)
|
|
private Integer minNativeApiLevel;
|
|
|
|
/** ZIP 内真实 JS/Hermes Bundle 的 SHA-256。 */
|
|
@Column(nullable = false, length = 64)
|
|
private String bundleSha256;
|
|
|
|
/** 客户端实际下载并校验的整个 .xuqm.zip 的 SHA-256。 */
|
|
@Column(nullable = false, length = 64)
|
|
private String archiveSha256;
|
|
|
|
@Column(nullable = false, length = 512)
|
|
private String bundleUrl;
|
|
|
|
/** Ed25519 签名覆盖的规范 JSON,必须与上面的身份字段逐项一致。 */
|
|
@Column(nullable = false, columnDefinition = "TEXT")
|
|
private String signedManifest;
|
|
|
|
@Column(nullable = false, length = 64)
|
|
private String signingKeyId;
|
|
|
|
@Column(nullable = false, length = 256)
|
|
private String signature;
|
|
|
|
@Column(length = 512)
|
|
private String note;
|
|
|
|
@Enumerated(EnumType.STRING)
|
|
@Column(nullable = false, length = 16)
|
|
private PublishStatus publishStatus;
|
|
|
|
@Column(length = 16)
|
|
private String publishMode = "MANUAL";
|
|
|
|
private LocalDateTime scheduledPublishAt;
|
|
|
|
@Column(nullable = false)
|
|
private boolean grayEnabled;
|
|
|
|
@Column(nullable = false)
|
|
private int grayPercent;
|
|
|
|
@Enumerated(EnumType.STRING)
|
|
@Column(nullable = false, length = 24)
|
|
private GrayMode grayMode = GrayMode.PERCENT;
|
|
|
|
@Column(columnDefinition = "TEXT")
|
|
private String grayMemberIds;
|
|
|
|
@Column(columnDefinition = "TEXT")
|
|
private String grayGroupNames;
|
|
|
|
@Column(columnDefinition = "TEXT")
|
|
private String extraMemberIds;
|
|
|
|
@Column(nullable = false)
|
|
private LocalDateTime createdAt;
|
|
|
|
public boolean hasTerminalIdentity() {
|
|
return hasText(packageName) && moduleType != null && hasText(appVersionRange)
|
|
&& hasText(builtAgainstNativeBaselineId) && hasText(buildId) && hasText(bundleFormat)
|
|
&& minNativeApiLevel != null && minNativeApiLevel > 0 && isSha256(bundleSha256)
|
|
&& isSha256(archiveSha256) && hasText(signedManifest) && hasText(signingKeyId)
|
|
&& hasText(signature);
|
|
}
|
|
|
|
private static boolean hasText(String value) {
|
|
return value != null && !value.isBlank();
|
|
}
|
|
|
|
private static boolean isSha256(String value) {
|
|
return value != null && value.matches("(?i)[a-f0-9]{64}");
|
|
}
|
|
|
|
public String getId() { return id; }
|
|
public void setId(String id) { this.id = id; }
|
|
public String getAppKey() { return appKey; }
|
|
public void setAppKey(String appKey) { this.appKey = appKey; }
|
|
public String getPackageName() { return packageName; }
|
|
public void setPackageName(String packageName) { this.packageName = packageName; }
|
|
public String getModuleId() { return moduleId; }
|
|
public void setModuleId(String moduleId) { this.moduleId = moduleId; }
|
|
public ModuleType getModuleType() { return moduleType; }
|
|
public void setModuleType(ModuleType moduleType) { this.moduleType = moduleType; }
|
|
public Platform getPlatform() { return platform; }
|
|
public void setPlatform(Platform platform) { this.platform = platform; }
|
|
public String getVersion() { return version; }
|
|
public void setVersion(String version) { this.version = version; }
|
|
public String getAppVersionRange() { return appVersionRange; }
|
|
public void setAppVersionRange(String value) { this.appVersionRange = value; }
|
|
public String getBuiltAgainstNativeBaselineId() { return builtAgainstNativeBaselineId; }
|
|
public void setBuiltAgainstNativeBaselineId(String value) { this.builtAgainstNativeBaselineId = value; }
|
|
public String getBuildId() { return buildId; }
|
|
public void setBuildId(String buildId) { this.buildId = buildId; }
|
|
public String getBundleFormat() { return bundleFormat; }
|
|
public void setBundleFormat(String bundleFormat) { this.bundleFormat = bundleFormat; }
|
|
public String getCommonVersionRange() { return commonVersionRange; }
|
|
public void setCommonVersionRange(String value) { this.commonVersionRange = value; }
|
|
public Integer getMinNativeApiLevel() { return minNativeApiLevel; }
|
|
public void setMinNativeApiLevel(Integer value) { this.minNativeApiLevel = value; }
|
|
public String getBundleSha256() { return bundleSha256; }
|
|
public void setBundleSha256(String value) { this.bundleSha256 = value; }
|
|
public String getArchiveSha256() { return archiveSha256; }
|
|
public void setArchiveSha256(String value) { this.archiveSha256 = value; }
|
|
public String getBundleUrl() { return bundleUrl; }
|
|
public void setBundleUrl(String bundleUrl) { this.bundleUrl = bundleUrl; }
|
|
public String getSignedManifest() { return signedManifest; }
|
|
public void setSignedManifest(String value) { this.signedManifest = value; }
|
|
public String getSigningKeyId() { return signingKeyId; }
|
|
public void setSigningKeyId(String value) { this.signingKeyId = value; }
|
|
public String getSignature() { return signature; }
|
|
public void setSignature(String value) { this.signature = value; }
|
|
public String getNote() { return note; }
|
|
public void setNote(String note) { this.note = note; }
|
|
public PublishStatus getPublishStatus() { return publishStatus; }
|
|
public void setPublishStatus(PublishStatus value) { this.publishStatus = value; }
|
|
public String getPublishMode() { return publishMode; }
|
|
public void setPublishMode(String value) { this.publishMode = value; }
|
|
public LocalDateTime getScheduledPublishAt() { return scheduledPublishAt; }
|
|
public void setScheduledPublishAt(LocalDateTime value) { this.scheduledPublishAt = value; }
|
|
public boolean isGrayEnabled() { return grayEnabled; }
|
|
public void setGrayEnabled(boolean value) { this.grayEnabled = value; }
|
|
public int getGrayPercent() { return grayPercent; }
|
|
public void setGrayPercent(int value) { this.grayPercent = value; }
|
|
public GrayMode getGrayMode() { return grayMode; }
|
|
public void setGrayMode(GrayMode value) { this.grayMode = value; }
|
|
public String getGrayMemberIds() { return grayMemberIds; }
|
|
public void setGrayMemberIds(String value) { this.grayMemberIds = value; }
|
|
public String getGrayGroupNames() { return grayGroupNames; }
|
|
public void setGrayGroupNames(String value) { this.grayGroupNames = value; }
|
|
public String getExtraMemberIds() { return extraMemberIds; }
|
|
public void setExtraMemberIds(String value) { this.extraMemberIds = value; }
|
|
public LocalDateTime getCreatedAt() { return createdAt; }
|
|
public void setCreatedAt(LocalDateTime value) { this.createdAt = value; }
|
|
}
|