vehicle_info_page.dart 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. import 'package:cpt_form/modules/apply/vm/apply_view_model.dart';
  2. import 'package:cs_resources/generated/l10n.dart';
  3. import 'package:cs_resources/theme/app_colors_theme.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:auto_route/auto_route.dart';
  6. import 'package:flutter_hooks/flutter_hooks.dart';
  7. import 'package:hooks_riverpod/hooks_riverpod.dart';
  8. import 'package:plugin_platform/engine/toast/toast_engine.dart';
  9. import 'package:router/ext/auto_router_extensions.dart';
  10. import 'package:shared/utils/util.dart';
  11. import 'package:widgets/ext/ex_widget.dart';
  12. import 'package:widgets/my_appbar.dart';
  13. import 'package:widgets/my_button.dart';
  14. import 'package:widgets/my_text_field.dart';
  15. import 'package:widgets/my_text_view.dart';
  16. import 'package:widgets/shatter/form_require_text.dart';
  17. import 'package:widgets/shatter/picker_container.dart';
  18. import 'package:widgets/widget_export.dart';
  19. import '../../router/page/form_page_router.dart';
  20. @RoutePage()
  21. class VehicleInfoPage extends HookConsumerWidget {
  22. const VehicleInfoPage({Key? key}) : super(key: key);
  23. //启动当前页面
  24. static void startInstance({BuildContext? context}) {
  25. if (context != null) {
  26. context.router.push(const VehicleInfoPageRoute());
  27. } else {
  28. appRouter.push(const VehicleInfoPageRoute());
  29. }
  30. }
  31. @override
  32. Widget build(BuildContext context, WidgetRef ref) {
  33. final viewModel = ref.watch(applyViewModelProvider.notifier);
  34. final state = ref.watch(applyViewModelProvider);
  35. // 使用 useState 来持久化 TextEditingController 和 FocusNode
  36. final TextEditingController vehicleNumController = useTextEditingController();
  37. final TextEditingController iuNumController = useTextEditingController();
  38. final TextEditingController vehicleInfoController = useTextEditingController();
  39. final FocusNode vehicleNumFocusNode = useFocusNode();
  40. final FocusNode iuNumFocusNode = useFocusNode();
  41. final FocusNode vehicleInfoFocusNode = useFocusNode();
  42. useEffect(() {
  43. //赋值State的值
  44. Future.microtask(() {
  45. vehicleNumController.text = state.formContentDetail.vehicleNumber ?? "";
  46. iuNumController.text = state.formContentDetail.iuNumber ?? "";
  47. vehicleInfoController.text = state.formContentDetail.vehicleMakeModelColour ?? "";
  48. });
  49. return () {};
  50. }, []);
  51. return WillPopScope(
  52. child: Scaffold(
  53. appBar: MyAppBar.appBar(context, state.detailPage?['title']),
  54. backgroundColor: context.appColors.backgroundWhite,
  55. body: Column(
  56. crossAxisAlignment: CrossAxisAlignment.start,
  57. children: [
  58. SingleChildScrollView(
  59. scrollDirection: Axis.vertical,
  60. physics: const BouncingScrollPhysics(),
  61. child: Container(
  62. width: double.infinity,
  63. child: Column(
  64. mainAxisSize: MainAxisSize.max,
  65. crossAxisAlignment: CrossAxisAlignment.start,
  66. children: [
  67. //下拉选 - Type类型
  68. FormRequireText(
  69. text: S.current.type_of_application,
  70. textColor: context.appColors.textBlack,
  71. fontSize: 17,
  72. fontWeight: FontWeight.w500,
  73. ).marginOnly(top: 30, bottom: 16, left: 15, right: 15),
  74. PickerContainer(
  75. hint: S.current.choose_an_option,
  76. enable: state.enableEdit,
  77. content: state.formContentDetail.typeOfApplication,
  78. onClick: () {
  79. viewModel.pickOption(true);
  80. },
  81. ).marginOnly(left: 15, right: 15),
  82. //下拉选 - 所有权状态
  83. FormRequireText(
  84. text: S.current.ownership_status,
  85. textColor: context.appColors.textBlack,
  86. fontSize: 17,
  87. fontWeight: FontWeight.w500,
  88. ).marginOnly(top: 14, bottom: 16, left: 15, right: 15),
  89. PickerContainer(
  90. hint: S.current.choose_an_option,
  91. enable: state.enableEdit,
  92. content: state.formContentDetail.ownershipStatus,
  93. onClick: () {
  94. viewModel.pickOption(false);
  95. },
  96. ).marginOnly(left: 15, right: 15),
  97. //输入框 - 车牌号
  98. FormRequireText(
  99. text: S.current.vehicle_number,
  100. textColor: context.appColors.textBlack,
  101. fontSize: 17,
  102. fontWeight: FontWeight.w500,
  103. ).marginOnly(top: 14, bottom: 16, left: 15, right: 15),
  104. // 表单
  105. _buildInputLayout(
  106. context,
  107. "vehicle_num",
  108. enable: state.enableEdit,
  109. textInputType: TextInputType.text,
  110. textInputAction: TextInputAction.next,
  111. controller: vehicleNumController,
  112. focusNode: vehicleNumFocusNode,
  113. onSubmit: (formKey, value) {
  114. vehicleNumFocusNode.unfocus();
  115. FocusScope.of(context).requestFocus(iuNumFocusNode);
  116. },
  117. ),
  118. //输入框 - IU 号
  119. MyTextView(
  120. S.current.iu_number,
  121. fontSize: 17,
  122. marginTop: 14,
  123. marginLeft: 15,
  124. marginRight: 15,
  125. marginBottom: 16,
  126. isFontMedium: true,
  127. textColor: context.appColors.textBlack,
  128. ),
  129. // 表单
  130. _buildInputLayout(
  131. context,
  132. "iu_num",
  133. enable: state.enableEdit,
  134. textInputType: TextInputType.text,
  135. textInputAction: TextInputAction.next,
  136. controller: iuNumController,
  137. focusNode: iuNumFocusNode,
  138. onSubmit: (formKey, value) {
  139. iuNumFocusNode.unfocus();
  140. FocusScope.of(context).requestFocus(vehicleInfoFocusNode);
  141. },
  142. ),
  143. //输入框 - 车辆信息
  144. FormRequireText(
  145. text: S.current.vehicle_make_model_colour,
  146. textColor: context.appColors.textBlack,
  147. fontSize: 17,
  148. fontWeight: FontWeight.w500,
  149. ).marginOnly(top: 14, bottom: 16, left: 15, right: 15),
  150. // 表单
  151. _buildInputLayout(
  152. context,
  153. "vehicle_info",
  154. enable: state.enableEdit,
  155. textInputType: TextInputType.text,
  156. textInputAction: TextInputAction.done,
  157. controller: vehicleInfoController,
  158. focusNode: vehicleInfoFocusNode,
  159. onSubmit: (formKey, value) {
  160. vehicleInfoFocusNode.unfocus();
  161. },
  162. ),
  163. ],
  164. ),
  165. ),
  166. ).expanded(),
  167. //底部按钮
  168. MyButton(
  169. onPressed: () {
  170. vehicleNumFocusNode.unfocus();
  171. iuNumFocusNode.unfocus();
  172. vehicleInfoFocusNode.unfocus();
  173. if (state.enableEdit) {
  174. String? vehicleNumber = vehicleNumController.text;
  175. String? iuNumber = iuNumController.text;
  176. String? vehicleMakeModelColour = vehicleInfoController.text;
  177. //校验数据
  178. final typeOfApplication = state.formContentDetail.typeOfApplication;
  179. final ownershipStatus = state.formContentDetail.ownershipStatus;
  180. if (Utils.isEmpty(typeOfApplication)) {
  181. ToastEngine.show("Select Type Of Application");
  182. return;
  183. }
  184. if (Utils.isEmpty(ownershipStatus)) {
  185. ToastEngine.show("Select Ownership Status");
  186. return;
  187. }
  188. if (Utils.isEmpty(vehicleNumber)) {
  189. ToastEngine.show("Enter vehicle number");
  190. return;
  191. }
  192. if (Utils.isEmpty(vehicleMakeModelColour)) {
  193. ToastEngine.show("Enter vehicle make/model/ colour");
  194. return;
  195. }
  196. //存入本表单数据
  197. viewModel.updateFormContentDetail((content) {
  198. content.vehicleNumber = vehicleNumber;
  199. content.vehicleMakeModelColour = vehicleMakeModelColour;
  200. content.iuNumber = iuNumber;
  201. });
  202. }
  203. viewModel.gotoNextPage();
  204. },
  205. text: S.current.next,
  206. textColor: Colors.white,
  207. backgroundColor: context.appColors.btnBgDefault,
  208. fontWeight: FontWeight.w500,
  209. type: ClickType.throttle,
  210. fontSize: 16,
  211. minHeight: 50,
  212. radius: 0,
  213. ),
  214. ],
  215. )),
  216. onWillPop: () async {
  217. viewModel.handlePopAction();
  218. return true;
  219. });
  220. }
  221. Widget _buildInputLayout(
  222. BuildContext context,
  223. String key, {
  224. double marginTop = 0,
  225. bool? showRightIcon = false, //是否展示右侧的布局
  226. Widget? rightWidget, //右侧的布局
  227. TextInputType textInputType = TextInputType.text,
  228. String? errorText,
  229. bool obscureText = false,
  230. required TextEditingController controller,
  231. required FocusNode focusNode,
  232. bool enable = true,
  233. TextInputAction textInputAction = TextInputAction.done,
  234. Function? onSubmit,
  235. }) {
  236. return IgnoreKeyboardDismiss(
  237. child: MyTextField(
  238. key,
  239. fillBackgroundColor: context.appColors.authFiledBG,
  240. "",
  241. hintStyle: TextStyle(
  242. color: context.appColors.authFiledHint,
  243. fontSize: 16.0,
  244. fontWeight: FontWeight.w500,
  245. ),
  246. controller: controller,
  247. focusNode: focusNode,
  248. margin: EdgeInsets.only(top: marginTop, left: 15, right: 15),
  249. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
  250. showDivider: false,
  251. height: 44,
  252. enabled: enable,
  253. style: TextStyle(
  254. color: context.appColors.authFiledText,
  255. fontSize: 16.0,
  256. fontWeight: FontWeight.w500,
  257. ),
  258. inputType: textInputType,
  259. textInputAction: textInputAction,
  260. onSubmit: onSubmit,
  261. cursorColor: context.appColors.authFiledText,
  262. obscureText: obscureText,
  263. errorText: errorText,
  264. showLeftIcon: true,
  265. showRightIcon: showRightIcon,
  266. rightWidget: rightWidget,
  267. ),
  268. );
  269. }
  270. }