| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 |
- import { CommonModule } from '@angular/common';
- import { ChangeDetectionStrategy, Component, inject, OnDestroy, OnInit, signal } from '@angular/core';
- import { FormsModule } from '@angular/forms';
- import { ActivatedRoute } from '@angular/router';
- import { firstValueFrom } from 'rxjs';
- import { ApiService } from '../../core/api.service';
- import { SessionService } from '../../core/session.service';
- import { buildFormSubmission } from '../../core/form-payload';
- import { PAGE_BY_PATH } from '../../core/page-catalog';
- import { DropdownDirective } from '../../shared/dropdown.directive';
- interface Reply {id:string;title:string;content:string;kind:string;submittedAt:string;status:string;response:string;handledAt:string;unread:boolean;readAt:string;}
- interface Inbox {items:Reply[];total:number;unread:number;}
- @Component({selector:'app-support-center',standalone:true,imports:[CommonModule,FormsModule,DropdownDirective],templateUrl:'./support-center.component.html',styleUrl:'./support-center.component.scss',changeDetection:ChangeDetectionStrategy.OnPush})
- export class SupportCenterComponent implements OnInit,OnDestroy {
- private readonly api=inject(ApiService);
- private readonly session=inject(SessionService);
- readonly history=signal(inject(ActivatedRoute).snapshot.queryParamMap.get('view')==='history');
- readonly inbox=signal<Inbox|null>(null);
- readonly loading=signal(false);readonly sending=signal(false);readonly error=signal('');readonly submitError=signal('');readonly message=signal('');readonly readError=signal('');readonly reading=signal('');readonly expanded=signal('');
- name='';content='';requestType='feedback';page=1;readonly pageSize=10;readonly Math=Math;
- private revision=0;private timer?: ReturnType<typeof setInterval>;
- private readonly refresh=()=>{if(document.visibilityState==='visible'&&!this.reading()&&!this.sending())void this.load(false);};
- ngOnInit():void {this.name=this.session.user()?.honeyName||this.session.user()?.userName||'';void this.load();this.timer=setInterval(this.refresh,30000);window.addEventListener('focus',this.refresh);document.addEventListener('visibilitychange',this.refresh);}
- ngOnDestroy():void {this.revision++;clearInterval(this.timer);window.removeEventListener('focus',this.refresh);document.removeEventListener('visibilitychange',this.refresh);}
- statusLabel(status:string):string{return ({pending:'待处理',processed:'已处理',approved:'已同意休假',rejected:'未同意休假'} as Record<string,string>)[status]||'待处理';}
- async load(foreground=true):Promise<void>{
- const revision=++this.revision,token=this.session.token();
- if(foreground)this.loading.set(true);
- try{const {result}=await firstValueFrom(this.api.post<Inbox>('app_support_requests_list',{page:this.page,pageSize:this.pageSize}));if(revision!==this.revision||token!==this.session.token())return;this.inbox.set(result);this.error.set('');}
- catch(e){if(revision===this.revision&&token===this.session.token())this.error.set(e instanceof Error?e.message:'回复暂时无法加载,请重试');}
- finally{if(revision===this.revision)this.loading.set(false);}
- }
- showHistory():void{this.history.set(true);void this.load();}
- changePage(page:number):void{this.page=page;this.expanded.set('');void this.load();}
- async submit():Promise<void>{
- if(this.sending())return;
- if(!this.name.trim()||!this.content.trim()){this.submitError.set('请填写姓名和内容');return;}
- const payload=buildFormSubmission(PAGE_BY_PATH.get('pages/member/feedback')!,{name:this.name,content:this.content.trim(),requestType:this.requestType},{uid:this.session.user()?.userId})!;
- this.sending.set(true);this.submitError.set('');this.message.set('');
- try{await firstValueFrom(this.api.post(payload.action,payload.payload));this.content='';this.message.set('提交成功,管理员处理后会在这里回复。');this.history.set(true);this.page=1;await this.load();}
- catch(e){this.submitError.set(e instanceof Error?e.message:'提交失败,请重试');}finally{this.sending.set(false);}
- }
- async viewReply(row:Reply):Promise<void>{
- this.expanded.set(row.id);this.readError.set('');if(!row.unread||this.reading())return;
- this.revision++;this.loading.set(false);this.reading.set(row.id);const token=this.session.token();
- try{await firstValueFrom(this.api.post('app_support_request_read',{id:row.id}));if(token!==this.session.token())return;this.inbox.update(d=>d?{...d,unread:Math.max(0,d.unread-(d.items.some(r=>r.id===row.id&&r.unread)?1:0)),items:d.items.map(r=>r.id===row.id?{...r,unread:false}:r)}:d);}
- catch(e){this.readError.set(e instanceof Error?e.message:'已读状态未保存,可重试');}finally{this.reading.set('');}
- }
- }
|