UNPKG

bixi

Version:

企业级中后台前端解决方案

93 lines (82 loc) 2.93 kB
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, NgZone, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; import { isNullOrUndefined } from '@bixi/core/utils'; import dayjs, { Dayjs } from 'dayjs'; import { NzSafeAny } from 'ng-zorro-antd/core/types'; import { interval, Subject, Subscription } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; export interface IBixiTimeProps { format?: string; relative?: boolean; radio?: number; timeout?: number; duration?: number; } const numberReg = /^[0-9]*$/; @Component({ selector: 'bixi-time', exportAs: 'bixiTime', host: { '[class.bixi-time]': 'true' }, templateUrl: './time.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class BixiTimeComponent implements OnChanges, OnDestroy { constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) { } relativeTime = ''; absoluteTime: dayjs.Dayjs | null = null; private destroy$ = new Subject<void>(); @Input() time: number | string | Date = 0; @Input() format = 'YYYY/MM/DD HH:mm'; @Input() relative = true; // 是否显示相对时间 @Input() radio = 1; // 当传入是秒时,需要格式化为秒 @Input() timeout = 24 * 60; @Input() duration = 1; timer$ = new Subscription(); init() { if (!this.time) return; this.absoluteTime = null; let date: Dayjs; if (typeof this.time === 'number') { date = dayjs(Number(this.time) * this.radio); } else if (typeof this.time === 'string' && numberReg.test(this.time)) { date = dayjs(Number(this.time) * this.radio); } else { date = dayjs(this.time); } if (!date.isValid()) return; const currentTime = date as NzSafeAny; if (!currentTime.fromNow) { console.warn('[@bixi/core] bixi-time(need plugin): 缺少 dayjs/plugin/relativeTime'); return; } this.relativeTime = currentTime.fromNow(); if (dayjs().diff(date, 'second') < this.timeout) { this.timer$.unsubscribe(); this.ngZone.runOutsideAngular(() => { // 定时刷新 this.timer$ = interval((Number(this.duration) || 1) * 1000) .pipe( takeUntil(this.destroy$), filter(() => this.relativeTime !== currentTime.fromNow()) ) .subscribe(() => { this.relativeTime = currentTime.fromNow(); this.cdr.detectChanges(); }); }); } this.absoluteTime = date; this.cdr.detectChanges(); } ngOnChanges(changes: SimpleChanges) { const { time, radio, format, relative } = changes; if (time) this.time = time.currentValue; if (radio) this.radio = radio.currentValue; if (format) this.format = format.currentValue; if (!isNullOrUndefined(relative)) this.relative = relative.currentValue; this.init(); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } }