|
@@ -19,8 +19,10 @@ export class MemberCreditAccountComponent implements OnChanges {
|
|
|
private host=inject(ElementRef<HTMLElement>);private operations=inject(OperationsService);loading=signal(false);private serial=0;data=signal<CreditAccounts|null>(null);error=signal('');message=signal('');saving=signal(false);preview=signal<CreditPreview|null>(null);
|
|
private host=inject(ElementRef<HTMLElement>);private operations=inject(OperationsService);loading=signal(false);private serial=0;data=signal<CreditAccounts|null>(null);error=signal('');message=signal('');saving=signal(false);preview=signal<CreditPreview|null>(null);
|
|
|
ledger=signal<LedgerPage|null>(null);ledgerBusy=signal(false);exporting=signal(false);ledgerError=signal('');private ledgerSerial=0;lessonId='';
|
|
ledger=signal<LedgerPage|null>(null);ledgerBusy=signal(false);exporting=signal(false);ledgerError=signal('');private ledgerSerial=0;lessonId='';
|
|
|
account:TeachingCreditAccount='Purse';amount=0;direction='add';sourceId='';method='';reason='';adjustSign='deduct';adjustMode='paired';evidence='';private fingerprint='';private key='';private previewFingerprint='';
|
|
account:TeachingCreditAccount='Purse';amount=0;direction='add';sourceId='';method='';reason='';adjustSign='deduct';adjustMode='paired';evidence='';private fingerprint='';private key='';private previewFingerprint='';
|
|
|
|
|
+ readonly expandedLedger=signal(new Set<string>());
|
|
|
|
|
+ toggleLedger(groupId:string){this.expandedLedger.update(current=>{const next=new Set(current);if(next.has(groupId))next.delete(groupId);else next.add(groupId);return next;});}
|
|
|
filterAccount='';filterKind='';dateFrom='';dateTo='';page=1;pageSize=20;
|
|
filterAccount='';filterKind='';dateFrom='';dateTo='';page=1;pageSize=20;
|
|
|
- ngOnChanges(){this.preview.set(null);void this.load();if(!this.store)void this.loadLedger();}
|
|
|
|
|
|
|
+ ngOnChanges(){this.expandedLedger.set(new Set());this.preview.set(null);void this.load();if(!this.store)void this.loadLedger();}
|
|
|
async load(){if(!this.objectId)return;const serial=++this.serial;this.loading.set(true);this.error.set('');try{const result=await this.operations.request<CreditAccounts>(this.store?'ops/stores/credit-accounts':'ops/users/credit-accounts',{objectId:this.objectId});if(serial===this.serial)this.data.set(result);}catch(e){if(serial===this.serial){this.data.set(null);this.error.set(e instanceof Error?e.message:'账户加载失败');}}finally{if(serial===this.serial)this.loading.set(false);}}
|
|
async load(){if(!this.objectId)return;const serial=++this.serial;this.loading.set(true);this.error.set('');try{const result=await this.operations.request<CreditAccounts>(this.store?'ops/stores/credit-accounts':'ops/users/credit-accounts',{objectId:this.objectId});if(serial===this.serial)this.data.set(result);}catch(e){if(serial===this.serial){this.data.set(null);this.error.set(e instanceof Error?e.message:'账户加载失败');}}finally{if(serial===this.serial)this.loading.set(false);}}
|
|
|
label(account:string){return this.data()?.accounts.find(a=>a.account===account)?.label||account;}
|
|
label(account:string){return this.data()?.accounts.find(a=>a.account===account)?.label||account;}
|
|
|
kindLabel(kind:string){return ({fund:'总部入账',transfer:'门店充值',refund:'原单扣回',adjust:'差错调整',lesson:'完课扣减',recharge:'历史充值',deduction:'历史扣减'} as Record<string,string>)[kind]||kind;}
|
|
kindLabel(kind:string){return ({fund:'总部入账',transfer:'门店充值',refund:'原单扣回',adjust:'差错调整',lesson:'完课扣减',recharge:'历史充值',deduction:'历史扣减'} as Record<string,string>)[kind]||kind;}
|
|
@@ -34,7 +36,7 @@ export class MemberCreditAccountComponent implements OnChanges {
|
|
|
async submit(){if(this.saving()||this.loading()||!this.valid())return;this.error.set('');this.message.set('');const payload=this.payload(),fingerprint=JSON.stringify([this.objectId,payload,this.reason]);if(!this.store&&(!this.preview()||fingerprint!==this.previewFingerprint)){this.preview.set(null);this.error.set('请先预览本次账户变动');return;}if(fingerprint!==this.fingerprint){this.fingerprint=fingerprint;this.key=crypto.randomUUID();}
|
|
async submit(){if(this.saving()||this.loading()||!this.valid())return;this.error.set('');this.message.set('');const payload=this.payload(),fingerprint=JSON.stringify([this.objectId,payload,this.reason]);if(!this.store&&(!this.preview()||fingerprint!==this.previewFingerprint)){this.preview.set(null);this.error.set('请先预览本次账户变动');return;}if(fingerprint!==this.fingerprint){this.fingerprint=fingerprint;this.key=crypto.randomUUID();}
|
|
|
this.saving.set(true);try{await this.operations.mutate(this.store?'ops/stores/credit-post':'ops/users/adjust-balance',this.objectId,this.reason,payload,this.preview()?.version||'',this.key);this.amount=0;this.reason='';this.key='';this.fingerprint='';this.preview.set(null);this.message.set('课时业务已完成,余额和流水已更新');await this.load();if(!this.store)await this.loadLedger();this.changed.emit();}catch(e){this.error.set(e instanceof Error?e.message:'课时业务失败');}finally{this.saving.set(false);}}
|
|
this.saving.set(true);try{await this.operations.mutate(this.store?'ops/stores/credit-post':'ops/users/adjust-balance',this.objectId,this.reason,payload,this.preview()?.version||'',this.key);this.amount=0;this.reason='';this.key='';this.fingerprint='';this.preview.set(null);this.message.set('课时业务已完成,余额和流水已更新');await this.load();if(!this.store)await this.loadLedger();this.changed.emit();}catch(e){this.error.set(e instanceof Error?e.message:'课时业务失败');}finally{this.saving.set(false);}}
|
|
|
params(){return{objectId:this.objectId,account:this.filterAccount,kind:this.filterKind,dateFrom:this.dateFrom,dateTo:this.dateTo,page:this.page,pageSize:this.pageSize};}
|
|
params(){return{objectId:this.objectId,account:this.filterAccount,kind:this.filterKind,dateFrom:this.dateFrom,dateTo:this.dateTo,page:this.page,pageSize:this.pageSize};}
|
|
|
- async loadLedger(){const serial=++this.ledgerSerial;this.ledgerBusy.set(true);this.ledgerError.set('');try{const result=await this.operations.request<LedgerPage>('ops/users/credit-ledger',this.params());if(serial===this.ledgerSerial)this.ledger.set(result);}catch(e){if(serial===this.ledgerSerial)this.ledgerError.set(e instanceof Error?e.message:'流水加载失败');}finally{if(serial===this.ledgerSerial)this.ledgerBusy.set(false);}}
|
|
|
|
|
|
|
+ async loadLedger(){const serial=++this.ledgerSerial;this.ledgerBusy.set(true);this.ledgerError.set('');try{const result=await this.operations.request<LedgerPage>('ops/users/credit-ledger',this.params());if(serial===this.ledgerSerial){this.ledger.set(result);this.expandedLedger.set(new Set());}}catch(e){if(serial===this.ledgerSerial)this.ledgerError.set(e instanceof Error?e.message:'流水加载失败');}finally{if(serial===this.ledgerSerial)this.ledgerBusy.set(false);}}
|
|
|
query(clear=false){if(clear){this.filterAccount='';this.filterKind='';this.dateFrom='';this.dateTo='';}this.page=1;void this.loadLedger();}
|
|
query(clear=false){if(clear){this.filterAccount='';this.filterKind='';this.dateFrom='';this.dateTo='';}this.page=1;void this.loadLedger();}
|
|
|
turn(delta:number){this.page+=delta;void this.loadLedger();}
|
|
turn(delta:number){this.page+=delta;void this.loadLedger();}
|
|
|
async importHistory(){if(this.saving())return;this.saving.set(true);this.error.set('');try{const r=await this.operations.request<{created:number}>('ops/users/import-ledger',{objectId:this.objectId,runId:crypto.randomUUID()});this.message.set('旧系统核验完成,补齐 '+r.created+' 条流水;现有余额未改变');await this.load();await this.loadLedger();}catch(e){this.error.set(e instanceof Error?e.message:'历史核验失败,请稍后重试');}finally{this.saving.set(false);}}
|
|
async importHistory(){if(this.saving())return;this.saving.set(true);this.error.set('');try{const r=await this.operations.request<{created:number}>('ops/users/import-ledger',{objectId:this.objectId,runId:crypto.randomUUID()});this.message.set('旧系统核验完成,补齐 '+r.created+' 条流水;现有余额未改变');await this.load();await this.loadLedger();}catch(e){this.error.set(e instanceof Error?e.message:'历史核验失败,请稍后重试');}finally{this.saving.set(false);}}
|