feat(B2): 附件引用模型-cms_attachment 增 ref_type/ref_id,消灭孤儿误报

- 实体/双 SQL 加列+idx_att_ref;upload 增 scene 白名单(banner/link/site)
- AttachmentService 新增 markUsed/release/markSiteConfigUsed(webUrl 反查,幂等)
- 未使用=articleId 与 refType 均空;page 返回 unusedCount(前后端同步改名无兼容别名)
- Banner/Link 保存先解引用再回写(换图旧图回未使用);Site 配置 logo/favicon 引用回写(@Lazy 解循环依赖)
- 新增13例(Attachment6/Banner3/Link2/Site2)+既有语义断言更新;mvn -o test 全绿
This commit is contained in:
chenxing
2026-09-07 19:40:14 +08:00
parent 52676f592a
commit b4822a7f38
15 changed files with 466 additions and 42 deletions
@@ -10,14 +10,17 @@ import javax.persistence.Table;
/**
* CMS 附件(正文图片 + 文档附件 + 轮播图/友链 Logo 复用同一上传链路,方案 §7.3)。
* 文章删除时附件记录保留、article_id 置空成"孤儿",由附件管理页清理。
* 引用模型(B2):articleId 仅服务文章编辑器回填链路;非文章场景(轮播/友链/站点配置)
* 用 refType/refId 标记。未使用 = 无文章引用且无场景引用(articleId 与 refType 均空);
* 文章删除仅 article_id 置空,场景引用由各保存点按 webUrl 反查回写/解引用。
*/
@Getter
@Setter
@Entity
@Table(name = "cms_attachment", indexes = {
@Index(name = "idx_att_article", columnList = "article_id"),
@Index(name = "idx_att_site", columnList = "site_id")})
@Index(name = "idx_att_site", columnList = "site_id"),
@Index(name = "idx_att_ref", columnList = "ref_type, ref_id")})
public class CmsAttachment extends BaseEntity {
/** 所属站点 */
@@ -28,6 +31,14 @@ public class CmsAttachment extends BaseEntity {
@Column(name = "article_id")
private Integer articleId;
/** 场景引用类型(B2):banner=轮播 / link=友链 / site=站点配置;空=无场景引用 */
@Column(name = "ref_type", length = 16)
private String refType;
/** 场景引用对象 ID(轮播/友链/站点各自业务主键) */
@Column(name = "ref_id")
private Integer refId;
/** 原始文件名 */
@Column(name = "file_name", nullable = false, length = 255)
private String fileName;