feat: 成片 duplicate_rate 百分比 + 素材高频使用自动排除 (#1573)
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 3s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 4m51s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 5m35s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 5m34s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 6m15s
AI Code Review / AI Code Review (pull_request) Failing after 6m40s
CI/CD Pipeline / Check push changed paths (push) Successful in 7m8s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 8m31s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m54s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m46s
CI/CD Pipeline / Build Staging API Image (push) Successful in 1m46s
CI/CD Pipeline / CI Gate (pull_request) Successful in 30s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m36s
CI/CD Pipeline / Retag skipped Staging Web Image (push) Successful in 34s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 10m14s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m14s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 12m59s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 2m31s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 4m14s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 6m14s
CI/CD Pipeline / Integration Tests (push) Successful in 5m41s
CI/CD Pipeline / Unit Tests (push) Successful in 19m12s
CI/CD Pipeline / Production Browser E2E (push) Failing after 382h9m8s
CI/CD Pipeline / Deploy Production (push) Failing after 382h9m9s
CI/CD Pipeline / CI Gate (push) Failing after 382h9m10s
CI/CD Pipeline / Build Production API Image (push) Failing after 382h9m10s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 382h9m10s
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Failing after 382h17m52s
CI/CD Pipeline / Production Browser E2E (pull_request) Failing after 382h18m18s
CI/CD Pipeline / Retag skipped Staging API Image (push) Failing after 382h17m53s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 382h18m26s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 382h19m12s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 382h18m28s
CI/CD Pipeline / Build Staging Web Image (push) Failing after 382h19m32s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 382h19m46s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 382h19m14s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 382h19m50s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 382h19m16s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 382h20m18s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 382h20m39s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 382h20m45s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 382h20m41s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 382h21m40s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 382h25m18s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 382h25m22s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Failing after 382h25m52s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 382h25m56s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 382h25m58s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 382h26m4s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 382h26m0s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 382h26m2s
CI/CD Pipeline / PR Build Web Image (push) Failing after 382h26m6s
CI/CD Pipeline / Frontend Lint (push) Failing after 382h27m31s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Failing after 382h28m27s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 382h28m28s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 382h28m29s
CI/CD Pipeline / Canary Release to Production (push) Failing after 382h43m22s
CI/CD Pipeline / Build Production Web Image (push) Failing after 382h43m22s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 382h54m0s
CI/CD Pipeline / Integration Tests (pull_request) Failing after 382h54m55s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 382h59m32s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Failing after 383h0m6s
CI/CD Pipeline / PR Build API Image (push) Failing after 383h0m20s

Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
This commit was merged in pull request #1573.
This commit is contained in:
2026-08-31 16:56:52 +08:00
committed by auto-approve-bot
parent 42939a557f
commit afe78fb25f
12 changed files with 506 additions and 1 deletions
+33 -1
View File
@@ -26,7 +26,7 @@ from app.schemas.asset import (
UpdateAssetReviewRequest,
)
from app.schemas.tag import TagAssetsRequest
from app.services.asset_segment_tracker import compute_asset_availability
from app.services.asset_segment_tracker import compute_asset_availability, get_asset_recent_use_counts
from fastapi import APIRouter, Depends, HTTPException, Query, Response
from packages.domain.smart_match import smart_select_assets
@@ -608,6 +608,38 @@ def smart_match_assets(
continue
filtered_results.append(r)
# 高频使用排除:同一素材在最近 5 个视频中出现超过 3 次则排除
MAX_RECENT_USE_COUNT = 3
if filtered_results:
asset_ids = [getattr(r.asset, "id", "") for r in filtered_results if getattr(r.asset, "id", "")]
if asset_ids:
try:
use_counts = get_asset_recent_use_counts(
db=asset_repository.session,
asset_ids=asset_ids,
recent_video_count=5,
)
high_use_excluded = set()
for r in filtered_results:
aid = getattr(r.asset, "id", "")
count = use_counts.get(aid, 0)
if count > MAX_RECENT_USE_COUNT:
logger.info(
"smart-match 排除高频使用素材: asset_id=%s use_count=%d limit=%d",
aid, count, MAX_RECENT_USE_COUNT,
)
high_use_excluded.add(id(r))
else:
pass
# 如果排除后不够 limit,放宽到不限制
remaining = [r for r in filtered_results if id(r) not in high_use_excluded]
if len(remaining) >= request.limit:
filtered_results = remaining
else:
logger.info("smart-match 高频排除后素材不足(%d<%d),保留全部", len(remaining), request.limit)
except Exception:
logger.warning("smart-match 高频使用查询失败,跳过排除", exc_info=True)
# 扁平结构:SmartMatchItem 继承 AssetResponse,素材字段直接在条目顶层,
# 前端无需解析 item.asset 包装层,item.id / item.usable / 余量字段直接可读
items = [
+1
View File
@@ -52,6 +52,7 @@ def _to_video_response(item, storage: OSSStorageService | None = None) -> VideoI
generation_params=item.generation_params,
download_url=download_url,
generated_at=format_utc_datetime(item.generated_at) if hasattr(item, "generated_at") else "",
duplicate_rate=getattr(item, "duplicate_rate", None),
)