53 lines
1.7 KiB
Dart
53 lines
1.7 KiB
Dart
import '../utils/date_util.dart';
|
||
import 'json_util.dart';
|
||
|
||
/// 账单(对应后端 BillResponse)
|
||
///
|
||
/// 注意:amount 后端恒返回正数,收支方向看 [type]。
|
||
class Bill {
|
||
final int id;
|
||
final int categoryId;
|
||
final String categoryName;
|
||
final String categoryIcon;
|
||
final double amount;
|
||
final String description;
|
||
final String billDate; // yyyy-MM-dd
|
||
final String? imageUrl;
|
||
final int type; // 1=支出 2=收入
|
||
final String? createTime;
|
||
final String? updateTime;
|
||
|
||
const Bill({
|
||
required this.id,
|
||
required this.categoryId,
|
||
required this.categoryName,
|
||
required this.categoryIcon,
|
||
required this.amount,
|
||
required this.description,
|
||
required this.billDate,
|
||
this.imageUrl,
|
||
required this.type,
|
||
this.createTime,
|
||
this.updateTime,
|
||
});
|
||
|
||
bool get isExpense => type == 1;
|
||
|
||
double get absAmount => amount.abs();
|
||
|
||
factory Bill.fromJson(Map<String, dynamic> json) => Bill(
|
||
id: asInt(json['id']),
|
||
categoryId: asInt(json['categoryId']),
|
||
categoryName: asNonEmpty(json['categoryName'], '未分类'),
|
||
categoryIcon: asNonEmpty(json['categoryIcon'], '📦'),
|
||
amount: asDouble(json['amount']),
|
||
description: asString(json['description']),
|
||
billDate: parseBillDate(asString(json['billDate'])),
|
||
imageUrl: json['imageUrl'] == null ? null : asString(json['imageUrl']),
|
||
// 后端可能返回 null,缺省按支出处理
|
||
type: asInt(json['type'], fallback: 1) == 2 ? 2 : 1,
|
||
createTime: json['createTime'] == null ? null : asString(json['createTime']),
|
||
updateTime: json['updateTime'] == null ? null : asString(json['updateTime']),
|
||
);
|
||
}
|