signature_page.dart 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import 'dart:typed_data';
  2. import 'dart:ui';
  3. import 'package:cpt_form/modules/apply/vm/apply_view_model.dart';
  4. import 'package:cs_resources/generated/l10n.dart';
  5. import 'package:cs_resources/theme/app_colors_theme.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:auto_route/auto_route.dart';
  8. import 'package:flutter_hooks/flutter_hooks.dart';
  9. import 'package:hooks_riverpod/hooks_riverpod.dart';
  10. import 'package:plugin_basic/provider/user_config/user_config_service.dart';
  11. import 'package:plugin_platform/engine/toast/toast_engine.dart';
  12. import 'package:router/ext/auto_router_extensions.dart';
  13. import 'package:shared/utils/date_time_utils.dart';
  14. import 'package:shared/utils/log_utils.dart';
  15. import 'package:widgets/ext/ex_widget.dart';
  16. import 'package:widgets/my_appbar.dart';
  17. import 'package:widgets/my_button.dart';
  18. import 'package:widgets/my_load_image.dart';
  19. import 'package:widgets/my_text_view.dart';
  20. import 'package:widgets/widget_export.dart';
  21. import '../../router/page/form_page_router.dart';
  22. @RoutePage()
  23. class SignaturePage extends HookConsumerWidget {
  24. const SignaturePage({Key? key}) : super(key: key);
  25. //启动当前页面
  26. static void startInstance({BuildContext? context}) {
  27. if (context != null) {
  28. context.router.push(const SignaturePageRoute());
  29. } else {
  30. appRouter.push(const SignaturePageRoute());
  31. }
  32. }
  33. @override
  34. Widget build(BuildContext context, WidgetRef ref) {
  35. final viewModel = ref.watch(applyViewModelProvider.notifier);
  36. final state = ref.watch(applyViewModelProvider);
  37. //签名版配置
  38. final HandSignatureControl handSignatureControl = useMemoized(() {
  39. return HandSignatureControl(
  40. threshold: 3.0,
  41. smoothRatio: 190 / 345,
  42. velocityRange: 2.0,
  43. );
  44. });
  45. useEffect(() {
  46. //赋值State的值
  47. Future.microtask(() {});
  48. return () {
  49. // 组件卸载时执行
  50. handSignatureControl.dispose();
  51. };
  52. }, []);
  53. return WillPopScope(
  54. child: Scaffold(
  55. appBar: MyAppBar.appBar(context, state.detailPage?['title']),
  56. backgroundColor: context.appColors.backgroundWhite,
  57. body: Column(
  58. crossAxisAlignment: CrossAxisAlignment.start,
  59. children: [
  60. SingleChildScrollView(
  61. scrollDirection: Axis.vertical,
  62. physics: const BouncingScrollPhysics(),
  63. child: Container(
  64. margin: const EdgeInsets.symmetric(horizontal: 15),
  65. width: double.infinity,
  66. child: Column(
  67. mainAxisSize: MainAxisSize.max,
  68. crossAxisAlignment: CrossAxisAlignment.start,
  69. children: [
  70. MyTextView(
  71. S.current.signature,
  72. fontSize: 17,
  73. marginTop: 30,
  74. isFontMedium: true,
  75. textColor: context.appColors.textBlack,
  76. ),
  77. //签名的说明文本
  78. MyTextView(
  79. state.detailPage?['detail_data']['signature_txt'],
  80. fontSize: 15,
  81. marginTop: 26,
  82. marginBottom: 21,
  83. isFontRegular: true,
  84. textColor: context.appColors.textBlack,
  85. ),
  86. //签名框
  87. Stack(
  88. children: [
  89. //签名
  90. Center(
  91. child: Container(
  92. width: 345,
  93. height: 190,
  94. color: context.appColors.imgGrayBg,
  95. child: state.enableEdit
  96. ? HandSignature(
  97. control: handSignatureControl,
  98. color: context.appColors.textBlack,
  99. width: 1.0,
  100. maxWidth: 3.5,
  101. type: SignatureDrawType.shape,
  102. )
  103. : MyLoadImage(
  104. state.formContentDetail.signature,
  105. width: 345,
  106. height: 190,
  107. ),
  108. ),
  109. ),
  110. //清除签名
  111. Align(
  112. alignment: Alignment.bottomRight,
  113. child: Visibility(
  114. visible: state.enableEdit,
  115. child: MyTextView(
  116. S.current.clean,
  117. fontSize: 12,
  118. textColor: Colors.white,
  119. cornerRadius: 10.37,
  120. backgroundColor: context.appColors.btnBgDefault,
  121. paddingTop: 4,
  122. paddingBottom: 4,
  123. paddingLeft: 11,
  124. paddingRight: 11,
  125. margin: 10,
  126. onClick: () {
  127. handSignatureControl.clear();
  128. },
  129. ),
  130. ),
  131. ),
  132. ],
  133. ).constrained(
  134. width: 345,
  135. height: 190,
  136. ),
  137. //同意协议富文本
  138. RichText(
  139. text: TextSpan(
  140. style: TextStyle(fontSize: 15, fontWeight: FontWeight.w400, color: context.appColors.textBlack),
  141. children: <TextSpan>[
  142. TextSpan(
  143. text: S.current.signed_and_agreed_by,
  144. ),
  145. TextSpan(
  146. text: " ${UserConfigService.getState().userName ?? "-"} \n",
  147. style: TextStyle(color: context.appColors.textPrimary),
  148. ),
  149. TextSpan(
  150. text: DateTimeUtils.formatNowDateStr(format: 'dd MMM yyyy HH:mm'),
  151. ),
  152. ],
  153. ),
  154. ).marginOnly(top: 21, bottom: 21),
  155. ],
  156. ),
  157. ),
  158. ).expanded(),
  159. //底部按钮
  160. MyButton(
  161. onPressed: () async {
  162. final isFilled = handSignatureControl.isFilled;
  163. if (!isFilled) {
  164. ToastEngine.show("Please sign first");
  165. return;
  166. }
  167. var byteData = await handSignatureControl.toImage(
  168. format: ImageByteFormat.png,
  169. border: 0,
  170. width: 345,
  171. height: 190,
  172. background: Colors.white,
  173. ) as ByteData;
  174. //存入本表单数据
  175. viewModel.updateFormContentDetail((content) {
  176. content.signatureByteData = byteData;
  177. });
  178. viewModel.submitForm();
  179. },
  180. text: S.current.submit,
  181. textColor: Colors.white,
  182. backgroundColor: context.appColors.btnBgDefault,
  183. fontWeight: FontWeight.w500,
  184. enable: state.enableEdit,
  185. disabledBackgroundColor: context.appColors.disEnableGray,
  186. type: ClickType.throttle,
  187. fontSize: 16,
  188. minHeight: 50,
  189. radius: 0,
  190. ),
  191. ],
  192. )),
  193. onWillPop: () async {
  194. viewModel.handlePopAction();
  195. return true;
  196. });
  197. }
  198. }