137 lines
4.0 KiB
Dart
137 lines
4.0 KiB
Dart
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<AutographPage> createState() => _AutographPageState();
|
||
}
|
||
|
||
class _AutographPageState extends ConsumerState<AutographPage> {
|
||
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<void> _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 ? '提交中…' : '确认提交签字'),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
}
|