feat: add translation billing stats and remove Export/Settings pages

- Add TranslationLog model to track translation API usage per task
- Integrate Dify API actual price (total_price) into translation stats
- Display translation statistics in admin dashboard with per-task costs
- Remove unused Export and Settings pages to simplify frontend
- Add GET /api/v2/admin/translation-stats endpoint

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-12 17:38:12 +08:00
parent d20751d56b
commit 65abd51d60
21 changed files with 682 additions and 662 deletions

View File

@@ -232,6 +232,8 @@ class TranslationService:
self._jobs_lock = threading.Lock()
self._total_tokens = 0
self._total_latency = 0.0
self._total_price = 0.0
self._currency = "USD"
def _load_raw_ocr_regions(
self,
@@ -459,6 +461,9 @@ class TranslationService:
self._total_tokens += response.total_tokens
self._total_latency += response.latency
self._total_price += response.total_price
if response.currency:
self._currency = response.currency
# Map translations back to items
translated_items = []
@@ -524,6 +529,9 @@ class TranslationService:
self._total_tokens += response.total_tokens
self._total_latency += response.latency
self._total_price += response.total_price
if response.currency:
self._currency = response.currency
return TranslatedItem(
element_id=item.element_id,
@@ -555,7 +563,9 @@ class TranslationService:
total_elements: int,
processing_time: float,
batch_count: int,
processing_track: str = 'direct'
processing_track: str = 'direct',
total_price: float = 0.0,
currency: str = 'USD'
) -> Dict:
"""
Build the translation result JSON structure.
@@ -613,6 +623,8 @@ class TranslationService:
'total_characters': total_chars,
'processing_time_seconds': round(processing_time, 2),
'total_tokens': self._total_tokens,
'total_price': round(total_price, 6),
'currency': currency,
'batch_count': batch_count
},
'translations': {}, # Empty for OCR Track
@@ -656,6 +668,8 @@ class TranslationService:
'total_characters': total_chars,
'processing_time_seconds': round(processing_time, 2),
'total_tokens': self._total_tokens,
'total_price': round(total_price, 6),
'currency': currency,
'batch_count': batch_count
},
'translations': translations
@@ -687,6 +701,8 @@ class TranslationService:
start_time = time.time()
self._total_tokens = 0
self._total_latency = 0.0
self._total_price = 0.0
self._currency = "USD"
logger.info(
f"Starting translation: task_id={task_id}, target={target_lang}"
@@ -752,7 +768,9 @@ class TranslationService:
total_elements=total_elements,
processing_time=processing_time,
batch_count=len(batches),
processing_track=processing_track
processing_track=processing_track,
total_price=self._total_price,
currency=self._currency
)
# Save result