import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterLink } from '@angular/router'; import type { ListingDimension, ListingOverviewDirection, ListingOverviewRow, ListingOverviewSort } from '../../models/listing-ai.models'; @Component({ selector: 'app-listing-overview-table', standalone: true, imports: [CommonModule, RouterLink], templateUrl: './listing-overview-table.component.html', styleUrl: './listing-overview-table.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, }) export class ListingOverviewTableComponent { @Input() items: ListingOverviewRow[] = []; @Input() loading = false; @Input() nextCursor: string | null = null; @Input() currentCursor: string | undefined; @Input() sort: ListingOverviewSort = 'improvementPotential'; @Input() direction: ListingOverviewDirection = 'desc'; @Input() returnTo = '/listing-ai/overview'; @Output() nextPage = new EventEmitter(); @Output() firstPage = new EventEmitter(); @Output() sortChange = new EventEmitter<{ sort: ListingOverviewSort; direction: ListingOverviewDirection }>(); @Output() detailOpen = new EventEmitter(); readonly dimensions: Array<{ key: ListingDimension; label: string }> = [ { key: 'title', label: '标题' }, { key: 'selling_points', label: '卖点' }, { key: 'images', label: '图片' }, { key: 'description', label: '详情' }, { key: 'specifications', label: '规格' }, ]; readonly dimensionLabels: Record = { title: '商品标题', selling_points: '核心卖点', images: '图片资产', description: '商品详情', specifications: '规格与履约', }; toggleSort(sort: ListingOverviewSort): void { this.sortChange.emit({ sort, direction: this.sort === sort && this.direction === 'desc' ? 'asc' : 'desc' }); } sortIndicator(sort: ListingOverviewSort): string { return this.sort === sort ? (this.direction === 'asc' ? '↑' : '↓') : ''; } overallText(item: ListingOverviewRow): string { if (item.overallScore !== null) return `${item.overallScore}`; return item.scoreNature === 'unscored' ? '未评分' : '总分缺失'; } dimensionText(item: ListingOverviewRow, key: ListingDimension): string { const dimension = item.dimensions[key]; return dimension.score === null ? '空维度' : `${dimension.score}/${dimension.maxScore}`; } rateText(rate: number | null): string { return rate === null ? '得分率未知' : `${Math.round(rate * 1000) / 10}%`; } }