jjsos_autosos_flutter/lib/pages/order/autograph_page.dart

137 lines
4.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 ? '提交中…' : '确认提交签字'),
),
),
),
],
),
);
}
}