/// 单据附件模型(对应 MgrServer MongoDB erp_bill_atts 文档) class BillAttachment { final String id; final String bilId; final String bilNo; final int srcItm; // 0=表头附件, >0=表身行号 final int itm; // 附件序号 final String fileName; final String ext; final String fileId; // GridFS 文件 ID final int tag; final String effDd; final String usr; const BillAttachment({ required this.id, required this.bilId, required this.bilNo, required this.srcItm, required this.itm, required this.fileName, required this.ext, required this.fileId, required this.tag, required this.effDd, required this.usr, }); factory BillAttachment.fromJson(Map json) { return BillAttachment( id: (json['_id'] is Map ? (json['_id']['\$oid'] as String?) : json['_id'] as String?) ?? '', bilId: json['BIL_ID'] as String? ?? '', bilNo: json['BIL_NO'] as String? ?? '', srcItm: json['SRCITM'] as int? ?? 0, itm: json['ITM'] as int? ?? 1, fileName: json['FILENAME'] as String? ?? '', ext: json['EXT'] as String? ?? '', fileId: (json['FILEID'] is Map ? (json['FILEID']['\$oid'] as String?) : json['FILEID'] as String?) ?? '', tag: json['TAG'] as int? ?? 1, effDd: json['EFF_DD'] as String? ?? '', usr: json['USR'] as String? ?? '', ); } /// 是否是表头附件 bool get isHeader => srcItm == 0; /// 是否是表身附件 bool get isBody => srcItm > 0; /// 文件图标(根据扩展名) String get fileIcon { switch (ext.toLowerCase()) { case 'pdf': return 'pdf'; case 'doc': case 'docx': return 'doc'; case 'xls': case 'xlsx': return 'xls'; case 'jpg': case 'jpeg': case 'png': case 'gif': case 'bmp': return 'image'; default: return 'file'; } } }