view.dart 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import 'package:fis_common/extensions/date.dart';
  2. import 'package:fis_jsonrpc/rpc.dart';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_inappwebview/flutter_inappwebview.dart';
  6. import 'package:get/get.dart';
  7. import 'package:vitalapp/architecture/utils/prompt_box.dart';
  8. import 'package:vitalapp/components/appbar.dart';
  9. import 'package:vitalapp/components/button.dart';
  10. import 'package:vitalapp/components/dialog_input.dart';
  11. import 'package:vitalapp/pages/contract/contract_record_html/controller.dart';
  12. import 'package:webviewx/webviewx.dart';
  13. class ContractRecordsHtmlPage extends GetView<ContractRecordsHtmlController> {
  14. const ContractRecordsHtmlPage({Key? key}) : super(key: key);
  15. @override
  16. Widget build(BuildContext context) {
  17. return Scaffold(
  18. appBar: VAppBar(
  19. titleWidget: const Text(
  20. "合同",
  21. style: TextStyle(fontSize: 24),
  22. ),
  23. ),
  24. body: Stack(
  25. children: [
  26. _buildWebView(context),
  27. Positioned(
  28. top: 0,
  29. left: 0,
  30. right: 0,
  31. child: Obx(() {
  32. final dto = controller.state.contractRecordDTO;
  33. return _ServiceTimeEffectRow(
  34. startDate: dto.serviceStartDate,
  35. endDate: dto.serviceEndDate,
  36. );
  37. }),
  38. ),
  39. Obx(
  40. () {
  41. return controller.state.contractRecordDTO.contractState !=
  42. ContractStateEnum.Cancelled
  43. ? Positioned(
  44. bottom: 8,
  45. left: 200,
  46. right: 200,
  47. child: Row(
  48. mainAxisAlignment: MainAxisAlignment.spaceAround,
  49. children: [
  50. VButton(
  51. label: "解 约",
  52. onTap: () async {
  53. var result = await const VDialogInput(
  54. title: '解约原因',
  55. showCancel: true,
  56. ).show();
  57. if (result != null) {
  58. var uplateResult = await controller
  59. .updateContractRecordStateAsync(result);
  60. if (uplateResult) {
  61. PromptBox.toast('解约成功');
  62. Get.back();
  63. }
  64. }
  65. },
  66. ),
  67. ],
  68. ),
  69. )
  70. : SizedBox();
  71. },
  72. ),
  73. ],
  74. ),
  75. );
  76. }
  77. Widget _buildAppWebView() {
  78. return Obx(
  79. () => InAppWebView(
  80. key: UniqueKey(),
  81. initialData: InAppWebViewInitialData(
  82. data:
  83. '<body style="padding: 100px;">${controller.state.contractRecordDTO.contractedFileUrl ?? ''}</body>',
  84. mimeType: 'text/html',
  85. encoding: 'utf-8',
  86. ),
  87. initialOptions: InAppWebViewGroupOptions(
  88. crossPlatform: InAppWebViewOptions(
  89. useShouldOverrideUrlLoading: true,
  90. mediaPlaybackRequiresUserGesture: false,
  91. disableVerticalScroll: false,
  92. ),
  93. android: AndroidInAppWebViewOptions(
  94. //设置为 true 以启用混合组合
  95. useHybridComposition: true,
  96. ),
  97. ),
  98. onWebViewCreated: (InAppWebViewController controller) {
  99. // _webViewController = controller;
  100. },
  101. onLoadHttpError: (controller, url, statusCode, description) {
  102. // ignore: avoid_print
  103. print("InAppWebView onLoadHttpError: $description");
  104. },
  105. ),
  106. );
  107. }
  108. Widget _buildWebwebview(BuildContext context) {
  109. return Obx(
  110. () => FutureBuilder<String>(
  111. key: UniqueKey(),
  112. future: _loadLocalHtml(context,
  113. '<body style="padding: 100px;">${controller.state.contractRecordDTO.contractedFileUrl ?? ''}</body>'),
  114. builder: (context, snapshot) {
  115. if (!snapshot.hasData) {
  116. return const Center(child: CircularProgressIndicator());
  117. // return FCenter(child: FText("${i18nBook.common.loading.t}..."));
  118. } else {
  119. return WebViewX(
  120. height: MediaQuery.of(Get.context!).size.height,
  121. width: MediaQuery.of(Get.context!).size.width,
  122. initialSourceType: SourceType.html,
  123. initialContent: snapshot.data!,
  124. javascriptMode: JavascriptMode.unrestricted,
  125. onWebResourceError: (p0) {},
  126. onWebViewCreated: (controller) {
  127. // webviewControllerManager.initWebviewController(controller);
  128. },
  129. );
  130. }
  131. },
  132. ),
  133. );
  134. }
  135. Widget _buildWebView(BuildContext context) {
  136. if (kIsWeb) {
  137. return _buildWebwebview(context);
  138. } else {
  139. return _buildAppWebView();
  140. }
  141. }
  142. Future<String> _loadLocalHtml(BuildContext context, String assetKey) async {
  143. // await Future.delayed(const Duration(milliseconds: 200));
  144. // final start = DateTime.now();
  145. // final content = await DefaultAssetBundle.of(context).loadString(assetKey);
  146. // final end = DateTime.now();
  147. // await controller.getContractRecordDetailAsync();
  148. return assetKey;
  149. }
  150. }
  151. /// 服务时效
  152. class _ServiceTimeEffectRow extends StatelessWidget {
  153. final DateTime? startDate;
  154. final DateTime? endDate;
  155. const _ServiceTimeEffectRow({
  156. required this.startDate,
  157. required this.endDate,
  158. });
  159. @override
  160. Widget build(BuildContext context) {
  161. if (startDate == null || endDate == null) {
  162. return const SizedBox();
  163. }
  164. final content = "${startDate!.formatDate()} 至 ${endDate!.formatDate()}";
  165. return Container(
  166. alignment: Alignment.center,
  167. padding: EdgeInsets.symmetric(vertical: 8),
  168. color: Colors.black.withOpacity(.1),
  169. child: RichText(
  170. text: TextSpan(
  171. style: TextStyle(fontSize: 20, color: Colors.black),
  172. children: [
  173. TextSpan(text: "服务时限:"),
  174. TextSpan(text: content),
  175. ],
  176. ),
  177. ),
  178. );
  179. }
  180. }