import 'dart:io'; import 'dart:typed_data'; import 'package:autosos_flutter/provider/providers.dart'; import 'package:autosos_flutter/util/toast.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:path_provider/path_provider.dart'; import 'package:signature/signature.dart'; import 'package:uuid/uuid.dart'; /// 客户签字页(对应 Android AutographActivity) class AutographPage extends ConsumerStatefulWidget { final int orderId; const AutographPage({super.key, required this.orderId}); @override ConsumerState createState() => _AutographPageState(); } class _AutographPageState extends ConsumerState { late final SignatureController _sigCtrl; bool _submitting = false; @override void initState() { super.initState(); _sigCtrl = SignatureController( penStrokeWidth: 3, penColor: Colors.black, exportBackgroundColor: Colors.white, ); } @override void dispose() { _sigCtrl.dispose(); super.dispose(); } Future _submit() async { if (_sigCtrl.isEmpty) { Toast.error('请先签名'); return; } setState(() => _submitting = true); EasyLoading.show(status: '上传中…'); try { // 1) 导出 PNG 字节 final Uint8List? bytes = await _sigCtrl.toPngBytes(); if (bytes == null) throw '导出签名失败'; // 2) 落盘到缓存 final dir = await getTemporaryDirectory(); final file = File( '${dir.path}/sig_${const Uuid().v4()}.png', ); await file.writeAsBytes(bytes, flush: true); // 3) 走七牛 final url = await ref.read(uploadServiceProvider).upload(file.path); // 4) 通知后端 final resp = await ref .read(orderApiProvider) .uploadSignature(widget.orderId, url); EasyLoading.dismiss(); if (!resp.isSuccess) { Toast.error(resp.message ?? '保存失败'); return; } Toast.success('签字已保存'); if (mounted) context.pop(true); } catch (e) { EasyLoading.dismiss(); Toast.error('上传失败:$e'); } finally { if (mounted) setState(() => _submitting = false); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('客户签字'), actions: [ TextButton( onPressed: () => _sigCtrl.clear(), child: const Text('清除', style: TextStyle(color: Colors.white)), ), ], ), body: Column( children: [ Container( color: Colors.amber.shade50, padding: const EdgeInsets.all(12), width: double.infinity, child: const Text( '请客户在下方手写签字,确认本次救援服务内容与费用', style: TextStyle(color: Colors.brown, fontSize: 13), ), ), Expanded( child: Container( color: Colors.white, margin: const EdgeInsets.all(12), child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Signature( controller: _sigCtrl, backgroundColor: Colors.white, ), ), ), ), Padding( padding: const EdgeInsets.all(12), child: SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _submitting ? null : _submit, style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, minimumSize: const Size.fromHeight(48), ), child: Text(_submitting ? '提交中…' : '确认提交签字'), ), ), ), ], ), ); } }