| `processWebmTranscode()` 异步返回值无效 | 移除 `@Async` 注解 |
| `deleteSfxByIds()` 未加载标签 | 新增 `findByIdInWithTags()` 方法 |
| `removeTagFromSfx()` 缺少关联清理 | 添加 setSfx(null) 和 setTag(null) |
| `batchUpdate()` 循环内多次 save | 新增私有方法,统一 save |
---
## 2026-03-16 SfxService音效和标签增删改查逻辑修复
### 问题描述
检查SfxService的音效和标签增删查改逻辑,发现以下脏数据风险:
| 优先级 | 问题 | 位置 |
|--------|------|------|
| P0 | decrementUsageCount无边界检查,会产生负数 | TagService.java:172-184 |
| P0 | deleteSfxAllTags未清理中间表SfxTag | SfxService.java:726-741 |
| P1 | batchUpdate循环内标签计数重复递增 | SfxService.java:845-875 |
| P1 | deleteSfxTag索引更新顺序不当 | SfxService.java:700-724 |
| P2 | clearNotApproved未加载标签关联 | SfxService.java:950-972 |
### 修复内容
#### 1. TagService.decrementUsageCount 添加负数检查
```java
if (tagStats.getUsageCount() > 0) {
tagStats.setUsageCount(tagStats.getUsageCount() - 1);
tagStatsRepository.save(tagStats);
}
```
#### 2. SfxService.deleteSfxAllTags 添加中间表清理
```java
sfx.getSfxTags().clear();
sfxTagRepository.deleteBySfxId(sfxId); // 新增
```
#### 3. SfxService.batchUpdate 使用Set收集标签统一递增
```java
Set<String> addedTags = new HashSet<>();
// 循环中添加到Set
addedTags.add(tagName);
// 循环后统一递增
for(String tagName : addedTags) {
tagService.incrementUsageCount(tag, SfxCategory.SFX);
}
```
#### 4. SfxService.deleteSfxTag 优化索引更新
```java
if (sfx != null) {
audioEffectService.indexAudioEffect(sfx);
}
invalidateCache();
```
#### 5. SfxRepository 新增 findByStatusNotWithTags
```java
@EntityGraph(attributePaths = {"sfxTags", "sfxTags.tag"})
Page<Sfx> findByStatusNotWithTags(int approvedStatus, Pageable pageable);
```
