| 12345678910111213141516171819202122232425262728293031323334353637 |
- import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';
- import { CommonModule } from '@angular/common';
- import { FormsModule } from '@angular/forms';
- import { ActivatedRoute, Router, RouterLink } from '@angular/router';
- import { RUNTIME_CONFIG } from '../../../../app/core/config/runtime-config';
- import { PageHeaderComponent } from '../../../shared/components/page-header/page-header.component';
- import { SummaryMetricCardComponent } from '../../../shared/components/summary-metric-card/summary-metric-card.component';
- import { ContentCardComponent } from '../../../shared/components/content-card/content-card.component';
- import { ListingAiApiService } from '../../services/listing-ai-api.service';
- import { ListingAiWorkbenchStore } from '../../services/listing-ai-workbench.store';
- @Component({selector:'app-listing-ai-workbench',standalone:true,imports:[CommonModule,FormsModule,RouterLink,PageHeaderComponent,SummaryMetricCardComponent,ContentCardComponent],providers:[ListingAiWorkbenchStore],changeDetection:ChangeDetectionStrategy.OnPush,templateUrl:'./listing-ai-workbench.component.html',styleUrl:'../../listing-ai.shared.scss'})
- export class ListingAiWorkbenchComponent implements OnInit{
- readonly store=inject(ListingAiWorkbenchStore);private readonly api=inject(ListingAiApiService);private readonly route=inject(ActivatedRoute);private readonly router=inject(Router);readonly workspaceId=RUNTIME_CONFIG.domesticWorkspaceId;
- search='';scoreStatus='';coverageStatus='';sort='productId';readonly creating=signal(false);readonly actionError=signal('');readonly selected=new Set<string>();
- ngOnInit():void{const query=this.route.snapshot.queryParamMap;this.search=query.get('search')??'';this.scoreStatus=query.get('scoreStatus')??'';this.coverageStatus=query.get('coverageStatus')??'';this.sort=query.get('sort')??'productId';this.apply(false);}
- apply(updateUrl=true):void{this.store.patchFilters({search:this.search,scoreStatus:this.scoreStatus||undefined,coverageStatus:this.coverageStatus||undefined,sort:this.sort});if(updateUrl)void this.router.navigate([],{relativeTo:this.route,queryParams:{search:this.search||null,scoreStatus:this.scoreStatus||null,coverageStatus:this.coverageStatus||null,sort:this.sort==='productId'?null:this.sort},queryParamsHandling:'merge',replaceUrl:true});this.store.load(this.workspaceId);}
- toggle(id:string,checked:boolean):void{checked?this.selected.add(id):this.selected.delete(id);}
- runAiScore():void{
- if(!this.selected.size)return;
- if(this.selected.size>10){this.actionError.set('本轮 Listing AI 评分最多支持 10 个商品,请减少选择数量。');return;}
- this.creating.set(true);
- this.actionError.set('');
- const scope={mode:'selected' as const,productIds:[...this.selected]};
- this.api.createScoreJob(this.workspaceId,scope,'ai').subscribe({
- next:({job})=>void this.router.navigate(['/listing-ai/tasks',job.id]),
- error:(error)=>{
- this.creating.set(false);
- const code=error?.error?.error;
- this.actionError.set(code==='listing_ai_budget_exceeded'?'本轮 Listing AI 评分最多支持 10 个商品。':code||'任务创建失败');
- },
- complete:()=>this.creating.set(false),
- });
- }
- score(value:number|null):string{return value===null?'—':String(value);}
- scoreSource(score:{scoreKind?:string;rubricVersion:string}|null):string{return score?.scoreKind==='hybrid_ai'||score?.rubricVersion.startsWith('listing-jd-ai-')?'AI评分':'规则评分';}
- }
|