fix(C2): 审核台显示文案质量分(总分+7维明细)
审核要能判断,原审核队列接口不返回分数=组长盲审。 - review.py _fmt_queue_item: 解析selected_text.score_json,复用现成 _score_array_to_obj(tasks.py)算总分+透传维度,绝不读eval_score(留NULL) - dto.tasks.ts: ReviewQueueItem.selected_text 加 score?:TextScore|null - ReviewCard.tsx: 复用现成ScoreDimBars组件,passLine=80(合格线红线, 不用组件默认85) 端到端验:task40审核队列返回total=83+5维明细,新旧维度兼容。tsc EXIT0。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,7 @@ def review_queue(
|
|||||||
def _fmt_queue_item(t: GenerationTask, db: Session) -> dict:
|
def _fmt_queue_item(t: GenerationTask, db: Session) -> dict:
|
||||||
import json
|
import json
|
||||||
from app.models.product import Product
|
from app.models.product import Product
|
||||||
|
from app.api.v1.tasks import _score_array_to_obj
|
||||||
product = db.query(Product).filter(Product.id == t.product_id).first()
|
product = db.query(Product).filter(Product.id == t.product_id).first()
|
||||||
operator = db.query(User).filter(User.id == t.operator_id).first()
|
operator = db.query(User).filter(User.id == t.operator_id).first()
|
||||||
selected_text = db.query(TextCandidate).filter(
|
selected_text = db.query(TextCandidate).filter(
|
||||||
@@ -67,6 +68,14 @@ def _fmt_queue_item(t: GenerationTask, db: Session) -> dict:
|
|||||||
except (json.JSONDecodeError, ValueError):
|
except (json.JSONDecodeError, ValueError):
|
||||||
text_parsed = {"content": selected_text.content}
|
text_parsed = {"content": selected_text.content}
|
||||||
|
|
||||||
|
# 质量分:解析 score_json 明细数组算总分+透传维度(绝不读 eval_score,设计留NULL)
|
||||||
|
text_score = None
|
||||||
|
if selected_text and selected_text.score_json:
|
||||||
|
try:
|
||||||
|
text_score = _score_array_to_obj(json.loads(selected_text.score_json))
|
||||||
|
except (json.JSONDecodeError, ValueError):
|
||||||
|
text_score = None
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"task_id": t.id,
|
"task_id": t.id,
|
||||||
"product_name": product.name if product else None,
|
"product_name": product.name if product else None,
|
||||||
@@ -79,6 +88,7 @@ def _fmt_queue_item(t: GenerationTask, db: Session) -> dict:
|
|||||||
"title": text_parsed.get("title", ""),
|
"title": text_parsed.get("title", ""),
|
||||||
"content": text_parsed.get("content", ""), # 纯正文
|
"content": text_parsed.get("content", ""), # 纯正文
|
||||||
"tags": text_parsed.get("tags", []),
|
"tags": text_parsed.get("tags", []),
|
||||||
|
"score": text_score, # 审核显分:总分+7维明细(C2)
|
||||||
} if selected_text else None,
|
} if selected_text else None,
|
||||||
"selected_image": {
|
"selected_image": {
|
||||||
"candidate_id": selected_image.id,
|
"candidate_id": selected_image.id,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* 通过(+5) / 打回(-3,必填原因)
|
* 通过(+5) / 打回(-3,必填原因)
|
||||||
*/
|
*/
|
||||||
import { ReviewQueueItem } from '@/types/index';
|
import { ReviewQueueItem } from '@/types/index';
|
||||||
|
import { ScoreDimBars } from '@/components/tasks/ScoreDimBars';
|
||||||
|
|
||||||
interface ReviewCardProps {
|
interface ReviewCardProps {
|
||||||
item: ReviewQueueItem;
|
item: ReviewQueueItem;
|
||||||
@@ -30,6 +31,10 @@ export function ReviewCard({ item, onApprove, onReject }: ReviewCardProps) {
|
|||||||
{item.selected_text.content}
|
{item.selected_text.content}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
{/* 质量分:审核可判断(C2)。合格线80=红线,不用组件默认85 */}
|
||||||
|
{item.selected_text?.score && (
|
||||||
|
<ScoreDimBars score={item.selected_text.score} passLine={80} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{item.selected_image && (
|
{item.selected_image && (
|
||||||
<img src={item.selected_image.url} alt="已选图预览"
|
<img src={item.selected_image.url} alt="已选图预览"
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export interface ReviewQueueItem {
|
|||||||
theme: string;
|
theme: string;
|
||||||
submitted_at: string;
|
submitted_at: string;
|
||||||
operator_name: string;
|
operator_name: string;
|
||||||
selected_text: { candidate_id: number; angle_label: string; content: string; };
|
selected_text: { candidate_id: number; angle_label: string; title?: string; content: string; tags?: string[]; score?: TextScore | null; };
|
||||||
selected_image: { candidate_id: number; strategy: 'A' | 'B' | 'C'; url: string; };
|
selected_image: { candidate_id: number; strategy: 'A' | 'B' | 'C'; url: string; };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user