API v4 계약 반영하고 보고서·입출고 화면 실연동 강화

This commit is contained in:
JiWoong Sul
2025-10-16 14:57:07 +09:00
parent 7e0f7b1c55
commit d5c99627db
34 changed files with 1767 additions and 327 deletions

View File

@@ -0,0 +1,15 @@
import 'dart:typed_data';
import 'file_saver_stub.dart' if (dart.library.html) 'file_saver_web.dart';
/// 바이트 데이터를 로컬 파일로 저장한다.
Future<void> saveFileBytes({
required Uint8List bytes,
required String filename,
required String mimeType,
}) async {
assert(filename.isNotEmpty, 'filename은 비어 있을 수 없습니다.');
assert(bytes.isNotEmpty, 'bytes는 비어 있을 수 없습니다.');
await saveFileBytesImpl(bytes: bytes, filename: filename, mimeType: mimeType);
}

View File

@@ -0,0 +1,10 @@
import 'dart:typed_data';
/// 웹 외 플랫폼에서 파일 저장이 호출되면 예외를 발생시킨다.
Future<void> saveFileBytesImpl({
required Uint8List bytes,
required String filename,
required String mimeType,
}) async {
throw UnsupportedError('현재 플랫폼에서는 파일 저장을 지원하지 않습니다.');
}

View File

@@ -0,0 +1,20 @@
import 'dart:typed_data';
import 'package:web/web.dart' as web;
/// 웹 환경에서 Anchor 요소를 사용해 파일 저장을 트리거한다.
Future<void> saveFileBytesImpl({
required Uint8List bytes,
required String filename,
required String mimeType,
}) async {
final dataUrl = Uri.dataFromBytes(bytes, mimeType: mimeType).toString();
final anchor = web.document.createElement('a') as web.HTMLAnchorElement
..href = dataUrl
..download = filename;
anchor.style.display = 'none';
web.document.body?.append(anchor);
anchor.click();
anchor.remove();
}