import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { NzMessageService } from 'ng-zorro-antd/message'; import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal'; import { NzUploadFile } from 'ng-zorro-antd/upload'; import { delay, firstValueFrom, Observable, of } from 'rxjs'; import { ArtStatus } from './art-status.component'; import { ArtService } from './art.service'; import { ArtRefuseReasonComponent } from './art-refuse-reason.component'; import { NzImageService } from 'ng-zorro-antd/image'; import { ScoreDetailComponent } from '../score/score-detail.component'; @Component({ selector: 'art-detail', templateUrl: './detail.component.html', styles: [ ` .thumb{ border:1px solid #999; } .clickable{ cursor: pointer; } div.thumb-item{ width:100%; aspect-ratio: 1 / 1; overflow:hidden; background-color:#fefefe; } .trash{ background: transparent; position: absolute; left: 50%; top: 50%; transform: translate(-50%); } img.thumb{ height:100%; } :host ::ng-deep .thumb-uploader > .ant-upload { width: 100%; height:100%; aspect-ratio: 1 / 1; } ` ] }) export class DetailComponent implements OnInit { id: string; art: any; aiPrompt: string; headers: any; headerHash: any; constructor( public artService: ArtService, private activatedRoute: ActivatedRoute, public message: NzMessageService, public modal: NzModalService, private nzImageService: NzImageService, private router: Router, private viewContainerRef: ViewContainerRef, ) { this.id = this.activatedRoute.snapshot.params['id']; this.loadData(); this.artService.getHeaders() .subscribe(resp => { this.headers = resp; this.headerHash = this.headers.reduce((hash, cur) => { hash[cur.data] = cur; return hash; }, {}); }) } error: HttpErrorResponse; isLoading: boolean = false; loadData() { this.isLoading = true; this.artService.get(this.id).subscribe({ next: (resp: any) => { this.art = resp; this.aiPrompt = this.art.aiPrompt; this.error = null; }, error: (err) => { this.error = err; this.isLoading = false; }, complete: () => { this.isLoading = false } }) } ngOnInit(): void { this.activatedRoute.params.subscribe(params => { let id = params['id']; if (this.id != id) { this.id = id; this.loadData(); } }) } title(key: string): any { return this.headerHash && this.headerHash[key] ? this.headerHash[key]?.title || key : key; } drop() { return this.artService.drop(this.id, 'xx') } recover() { return this.artService.recover(this.id) } deleteSpecial() { return this.artService.deleteSpecial(this.id) } lock() { return this.artService.lock(this.id, true) } unlock() { return this.artService.lock(this.id, false) } selftest() { return this.artService.selftest(this.id); } refuse() { const modalRef = this.modal.create({ nzTitle: $localize`确认拒稿么?`, nzFooter: null, nzContent: ArtRefuseReasonComponent, }); modalRef.getContentComponent().onSuccess.subscribe(reason => { modalRef.close(); firstValueFrom(this.artService.refuse(this.id, reason)) .then((resp: any) => { this.loadData(); }).catch(err => { this.message.error(err.error?.message || err.message); }); }) } artStatus = ArtStatus; getStatusOperation(status: number) { return () => { return this.artService.status(this.id, status); } } // selftest() { // return () => { // return this.artService.selftest(this.id); // } // } // selftestModal: NzModalRef; // onSelfTestDoing(isloading) { // if (isloading) { // this.selftestModal = this.modal.info({ // nzTitle: $localize`提交自测`, // nzContent: $localize`正在生成测试数据,请稍候...`, // nzOkText: null, // }); // } // } // onSelfTestSuccess() { // if (this.selftestModal) { // this.selftestModal.close(); // } // this.modal.success({ // nzTitle: $localize`提交自测`, // nzContent: $localize`生成测试数据成功,可以在APP进行测试`, // }); // } // onSelfTestFailed() { // if (this.selftestModal) { // this.selftestModal.close(); // } // this.modal.error({ // nzTitle: $localize`提交自测`, // nzContent: $localize`生成测试数据失败,请检查`, // }); // } onMarkPreview() { const images = [{ src: `/napi/web/art/${this.art.id}/bin/markImg` }]; this.nzImageService.preview(images); } modalTitle(key: string) { let title = ''; switch (key) { case 'meta': title = $localize`作品信息`; break; default: break; } return title; } openModal(content: TemplateRef, title: string) { this.modal.create({ nzContent: content, nzTitle: title, nzFooter: null, }); } canView(bin): boolean { if (!this.art) return false; if (this.art.auth.isPageAdmin) return true; else if (['page', 'raw', 'special', 'work', 'rawColored', 'svgv1', 'svgall', 'svgv2'].includes(bin.type)) return true; else return false; } getOperation(): Observable { return of(1).pipe(delay(2000)); //return new Observable(sub => { // setTimeout(() => { // sub.error(new Error('test error')) // }, 2000); //}) } onClickTag(tag) { let filters = JSON.stringify({ tags: [tag] }); this.router.navigateByUrl(`/pages/all?filters=${filters}`) } onClickEpg(epg) { let filters = JSON.stringify({ epgs: [epg] }); this.router.navigateByUrl(`/pages/all?filters=${filters}`) } onClickUser(user) { let filters = JSON.stringify({ user: [user] }); this.router.navigateByUrl(`/pages/all?filters=${filters}`) } // 点击查看评分详情 onClickScoreInfo(art: any) { const modal = this.modal.create({ // nzTitle: $localize`评分详情`, nzCentered: true, nzWidth: 800, nzFooter: null, nzContent: ScoreDetailComponent, nzViewContainerRef: this.viewContainerRef, nzComponentParams: { art, }, }); modal.getContentComponent().onScoreSuccess.subscribe(e => { this.loadData(); }) } //////////////////////// special thumb upload //////////////////////// uploading: boolean = false; beforeSpecialThumbUpload = (file: NzUploadFile): boolean => { const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; if (!isJpgOrPng) { this.message.error($localize`不支持的图片格式`); return false; } const isLt2M = file.size! / 1024 / 1024 < 2; if (!isLt2M) { this.message.error($localize`图片大小超过限制`); return false; } this.handleSpecailThumbUpload(file); return false; }; handleSpecailThumbUpload(file: NzUploadFile): void { console.log(file); const formData = new FormData(); formData.set("specialThumb", file as unknown as File); // formData.append('files[]', file); formData.set("workId", this.art._id); this.uploading = true; firstValueFrom(this.artService.uploadSpecialThumb(formData)) .then((resp: any) => { this.uploading = false; this.loadData(); }).catch(err => { this.uploading = false; this.message.error(err.error?.message || err.message); }); } // 删除上传缩略图 removeSpecialThumb() { firstValueFrom(this.artService.deleteSpecialThumb(this.art._id)) .then((resp: any) => { this.loadData(); }).catch(err => { this.message.error(err.error?.message || err.message); }); } // 切换special缩略图 onSpecialThumbChange(value: number) { firstValueFrom(this.artService.useSpecialThumb(this.art._id, value)) .then((resp: any) => { this.loadData(); }).catch(err => { this.message.error(err.error?.message || err.message); }); } // 设置神秘图开关 onMysteryChange(value: boolean) { firstValueFrom(this.artService.setMystery(this.art._id, value)) .then((resp: any) => { this.loadData(); }).catch(err => { this.message.error(err.error?.message || err.message); }); } // 设置AI参考图开关 onAiChange(value: boolean) { firstValueFrom(this.artService.setAi(this.art._id, value)) .then((resp: any) => { this.loadData(); }).catch(err => { this.message.error(err.error?.message || err.message); }); } // 删除AI参考图 removeAiImage() { firstValueFrom(this.artService.deleteAiImage(this.art._id)) .then((resp: any) => { this.loadData(); }).catch(err => { this.message.error(err.error?.message || err.message); }); } // 更新AI关键字 updateAiPrompt() { if (this.aiPrompt === undefined || this.aiPrompt == this.art.aiPrompt) return; // 没有变更 firstValueFrom(this.artService.setAiPrompt(this.art._id, this.aiPrompt)) .then(resp => this.loadData()) .catch(err => this.message.error(err.error?.message || err.message)) } cancelAiPrompt() { this.aiPrompt = this.art.aiPrompt; } // 设置AI参考图开关 onUseChange(value: string) { firstValueFrom(this.artService.setUse(this.art._id, value)) .then((resp: any) => { this.loadData(); }).catch(err => { this.message.error(err.error?.message || err.message); }); } //////////////////////// ai image upload //////////////////////// beforeAiUpload = (file: NzUploadFile): boolean => { const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; if (!isJpgOrPng) { this.message.error($localize`不支持的图片格式`); return false; } const isLt5M = file.size! / 1024 / 1024 < 5; if (!isLt5M) { this.message.error($localize`图片大小超过限制`); return false; } this.handleAiUpload(file); return false; }; handleAiUpload(file: NzUploadFile): void { console.log(file); const formData = new FormData(); formData.set("aiImage", file as unknown as File); // formData.append('files[]', file); formData.set("workId", this.art._id); this.uploading = true; firstValueFrom(this.artService.uploadAiImage(formData)) .then((resp: any) => { this.uploading = false; this.loadData(); }).catch(err => { this.uploading = false; this.message.error(err.error?.message || err.message); }); } }