feat(ledger): 预种份额在流水明细中显示合并合同下载按钮

- 移除硬编码"预种无合同"逻辑
- PPL 份额点击详情时,查找是否有对应的已签署合并记录
- 有签署合同则显示查看/下载按钮,调用预种合并合同 PDF 接口
- 同时新增 _viewMergeContractPdf / _downloadMergeContractPdf 方法

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-28 11:19:27 -08:00
parent 1431c89684
commit a904c8bd42
1 changed files with 110 additions and 4 deletions

View File

@ -8,6 +8,7 @@ import 'package:flutter_pdfview/flutter_pdfview.dart';
import '../../../../core/di/injection_container.dart';
import '../../../../core/services/wallet_service.dart';
import '../../../../core/services/reward_service.dart';
import '../../../../core/services/pre_planting_service.dart';
import '../../../../core/utils/date_utils.dart';
/// -
@ -1116,18 +1117,40 @@ class _LedgerDetailPageState extends ConsumerState<LedgerDetailPage>
Future<void> _showTransactionDetail(LedgerEntry entry) async {
if (entry.refOrderId == null) return;
// PPL
final bool isPrePlanting = entry.refOrderId!.startsWith('PPL');
// PPL
String? signedMergeNo;
if (isPrePlanting) {
try {
final merges = await ref.read(prePlantingServiceProvider).getMyMerges();
final matched = merges.where(
(m) => m.isSigned && m.sourceOrderNos.contains(entry.refOrderId),
);
if (matched.isNotEmpty) signedMergeNo = matched.first.mergeNo;
} catch (_) {
//
}
}
if (!mounted) return;
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => _TransactionDetailSheet(
entry: entry,
showContractButtons: !isPrePlanting,
onViewContract: isPrePlanting ? null : () => _viewContractPdf(entry.refOrderId!),
onDownloadContract: isPrePlanting ? null : () => _downloadContractPdf(entry.refOrderId!),
showContractButtons: !isPrePlanting || signedMergeNo != null,
onViewContract: signedMergeNo != null
? () => _viewMergeContractPdf(signedMergeNo!)
: isPrePlanting
? null
: () => _viewContractPdf(entry.refOrderId!),
onDownloadContract: signedMergeNo != null
? () => _downloadMergeContractPdf(signedMergeNo!)
: isPrePlanting
? null
: () => _downloadContractPdf(entry.refOrderId!),
),
);
}
@ -1230,6 +1253,89 @@ class _LedgerDetailPageState extends ConsumerState<LedgerDetailPage>
);
}
}
/// PDF
Future<void> _viewMergeContractPdf(String mergeNo) async {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
),
),
);
try {
final prePlantingService = ref.read(prePlantingServiceProvider);
final pdfBytes = await prePlantingService.downloadMergeContractPdf(mergeNo);
final tempDir = await getTemporaryDirectory();
final pdfFile = File('${tempDir.path}/merge_contract_$mergeNo.pdf');
await pdfFile.writeAsBytes(pdfBytes);
if (!mounted) return;
Navigator.of(context).pop();
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => _ContractPdfViewerPage(
pdfPath: pdfFile.path,
contractNo: mergeNo,
),
),
);
} catch (e) {
if (!mounted) return;
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('加载合同失败: $e'),
backgroundColor: Colors.red,
),
);
}
}
/// PDF
Future<void> _downloadMergeContractPdf(String mergeNo) async {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
),
),
);
try {
final prePlantingService = ref.read(prePlantingServiceProvider);
final pdfBytes = await prePlantingService.downloadMergeContractPdf(mergeNo);
final directory = await getApplicationDocumentsDirectory();
final fileName = 'merge_contract_$mergeNo.pdf';
final pdfFile = File('${directory.path}/$fileName');
await pdfFile.writeAsBytes(pdfBytes);
if (!mounted) return;
Navigator.of(context).pop();
await Share.shareXFiles(
[XFile(pdfFile.path)],
subject: '预种合并合同 - $mergeNo',
);
} catch (e) {
if (!mounted) return;
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('下载合同失败: $e'),
backgroundColor: Colors.red,
),
);
}
}
}
///