bixi
Version:
企业级中后台前端解决方案
93 lines (82 loc) • 2.93 kB
text/typescript
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]*$/;
export class BixiTimeComponent implements OnChanges, OnDestroy {
constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) { }
relativeTime = '';
absoluteTime: dayjs.Dayjs | null = null;
private destroy$ = new Subject<void>();
time: number | string | Date = 0;
format = 'YYYY/MM/DD HH:mm';
relative = true; // 是否显示相对时间
radio = 1; // 当传入是秒时,需要格式化为秒
timeout = 24 * 60;
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();
}
}