support filtering transactions by amount in import transaction dialog

This commit is contained in:
MaysWind
2025-11-27 01:25:34 +08:00
parent 3fe51dce63
commit 17f604b6aa
2 changed files with 162 additions and 8 deletions
+75 -7
View File
@@ -440,26 +440,94 @@ export class AmountFilterType {
private static readonly allInstances: AmountFilterType[] = [];
private static readonly allInstancesByType: Record<string, AmountFilterType> = {};
public static readonly GreaterThan = new AmountFilterType('gt', 'Greater than', 1);
public static readonly LessThan = new AmountFilterType('lt', 'Less than', 1);
public static readonly EqualTo = new AmountFilterType('eq', 'Equal to', 1);
public static readonly NotEqualTo = new AmountFilterType('ne', 'Not equal to', 1);
public static readonly Between = new AmountFilterType('bt', 'Between', 2);
public static readonly NotBetween = new AmountFilterType('nb', 'Not between', 2);
public static readonly GreaterThan = new AmountFilterType('gt', 'Greater than', 1,
(amount: number, ...params: number[]) => {
return params && params.length > 0 && amount > (params[0] as number);
}
);
public static readonly LessThan = new AmountFilterType('lt', 'Less than', 1,
(amount: number, ...params: number[]) => {
return params && params.length > 0 && amount < (params[0] as number);
}
);
public static readonly EqualTo = new AmountFilterType('eq', 'Equal to', 1,
(amount: number, ...params: number[]) => {
return params && params.length > 0 && amount === (params[0] as number);
}
);
public static readonly NotEqualTo = new AmountFilterType('ne', 'Not equal to', 1,
(amount: number, ...params: number[]) => {
return params && params.length > 0 && amount !== (params[0] as number);
}
);
public static readonly Between = new AmountFilterType('bt', 'Between', 2,
(amount: number, ...params: number[]) => {
return params && params.length > 1 && amount >= (params[0] as number) && amount <= (params[1] as number);
}
);
public static readonly NotBetween = new AmountFilterType('nb', 'Not between', 2,
(amount: number, ...params: number[]) => {
return params && params.length > 1 && (amount < (params[0] as number) || amount > (params[1] as number));
}
);
public readonly type: string;
public readonly name: string;
public readonly paramCount: number;
private readonly matchFn: (amount: number, ...params: number[]) => boolean;
private constructor(type: string, name: string, paramCount: number) {
private constructor(type: string, name: string, paramCount: number, matchFn: (amount: number, ...params: number[]) => boolean) {
this.type = type;
this.name = name;
this.paramCount = paramCount;
this.matchFn = matchFn;
AmountFilterType.allInstances.push(this);
AmountFilterType.allInstancesByType[type] = this;
}
public toTextualFilter(...params: number[]): string {
if (this.paramCount === 1) {
return `${this.type}:${params[0] ?? ''}`;
} else if (this.paramCount === 2) {
return `${this.type}:${params[0] ?? ''}:${params[1] ?? ''}`;
} else {
return '';
}
}
public static match(filter: string, amount: number): boolean {
const parts = filter.split(':');
if (parts.length < 2) {
return false;
}
const filterType = AmountFilterType.valueOf(parts[0] as string);
if (!filterType) {
return false;
}
if (parts.length - 1 !== filterType.paramCount) {
return false;
}
const params: number[] = [];
for (let i = 1; i < parts.length; i++) {
const param = parseInt(parts[i] as string);
if (Number.isNaN(param)) {
return false;
}
params.push(param);
}
return filterType.matchFn(amount, ...params);
}
public static values(): AmountFilterType[] {
return AmountFilterType.allInstances;
}