XuqmGroup-Server/xuqm-bugcollect-service/src/main/java/com/xuqm/bugcollect/entity/LogIssueUserEntity.java

58 行
1.7 KiB
Java

fix(bugcollect): 修复 BugCollect-API-v1-Review 全量37项问题 服务端: - IssueResponse 移除 isResolved,统一使用 status 字段 - IssueEventResponse 重构为 ExceptionInfo 嵌套结构,breadcrumbs/tags/device 序列化为 Object - IssueResponse 新增 affectedUsers 字段,通过 log_issue_users 去重计数 - WebhookResponse 将 secret 替换为 hasSecret boolean - WebhookRequest 新增 secret 字段 - LogWebhookEntity 新增 secret 列 - 新增 LogIssueUserEntity / LogIssueUserRepository 实现 affectedUsers 去重 - LogIssueRepository.findByFilters 新增 assignee、environment 过滤 - LogService.queryIssues 新增 assignee、environment 参数 - LogService.toIssueResponse 修正 IssueResponse 构造(移除 isResolved) - LogService.toIssueEventResponse 修正 ExceptionInfo 构造,JSON 字段反序列化为 Object - LogController:assign 改为 @RequestBody;GET /issues 新增 assignee/environment 参数;upload 新增 bundleVersion 参数 - WebhookService:事件类型匹配改为 issue.created/issue.fatal/issue.error/issue.warning/issue.updated;新增 HMAC-SHA256 X-BugCollect-Signature 签名;toResponse 修正为 hasSecret - SourcemapService:按平台生成正确后缀(.android.bundle.map/.ios.bundle.map);新增 bundleVersion 参数;200MB 大小限制;.map 扩展名校验 - V4 迁移 SQL:log_issue_users 表、log_webhooks.secret 列、log_sessions 表、event_id 索引 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 09:26:12 +08:00
package com.xuqm.bugcollect.entity;
import jakarta.persistence.*;
import java.time.LocalDateTime;
/**
* 记录每个 Issue 影响的唯一用户用于正确计算 affectedUsers去重
* 通过联合主键 (issue_id, user_id) 保证唯一性
*/
@Entity
@Table(name = "log_issue_users")
@IdClass(LogIssueUserEntity.IssueUserId.class)
public class LogIssueUserEntity {
@Id
@Column(nullable = false)
private Long issueId;
@Id
@Column(nullable = false, length = 128)
private String userId;
@Column(nullable = false)
private LocalDateTime firstSeenAt;
public Long getIssueId() { return issueId; }
public void setIssueId(Long issueId) { this.issueId = issueId; }
public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; }
public LocalDateTime getFirstSeenAt() { return firstSeenAt; }
public void setFirstSeenAt(LocalDateTime firstSeenAt) { this.firstSeenAt = firstSeenAt; }
public static class IssueUserId implements java.io.Serializable {
private Long issueId;
private String userId;
public IssueUserId() {}
public IssueUserId(Long issueId, String userId) {
this.issueId = issueId;
this.userId = userId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof IssueUserId that)) return false;
return java.util.Objects.equals(issueId, that.issueId) && java.util.Objects.equals(userId, that.userId);
}
@Override
public int hashCode() {
return java.util.Objects.hash(issueId, userId);
}
}
}