javascript_handler.dart 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:app_settings/app_settings.dart';
  4. import 'package:device_info_plus/device_info_plus.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter/services.dart';
  7. import 'package:flutter_inappwebview/flutter_inappwebview.dart';
  8. import 'package:get/get.dart' as my_get;
  9. import 'package:get/get.dart';
  10. import 'package:o2oa_all_platform/common/extension/index.dart';
  11. import 'package:share_plus/share_plus.dart';
  12. import 'package:url_launcher/url_launcher.dart';
  13. import '../../pages/apps/process/process_picker/index.dart';
  14. import '../../pages/common/create_form/index.dart';
  15. import '../../pages/common/inner_webview/index.dart';
  16. import '../../pages/common/portal/index.dart';
  17. import '../../pages/common/scan/index.dart';
  18. import '../../pages/home/contact/contact_picker/index.dart';
  19. import '../../pages/home/contact/org_person_list/index.dart';
  20. import '../../pages/home/contact/person/index.dart';
  21. import '../../pages/home/im/im_chat/index.dart';
  22. import '../../pages/home/im/instant_chat/index.dart';
  23. import '../../pages/home/im/speech_assistant_chat/index.dart';
  24. import '../api/index.dart';
  25. import '../models/index.dart';
  26. import '../routers/index.dart';
  27. import '../services/index.dart';
  28. import '../values/o2.dart';
  29. import '../widgets/index.dart';
  30. import 'geolocator_helper.dart';
  31. import 'javascript_navigation_interface.dart';
  32. import 'loading.dart';
  33. import 'log_util.dart';
  34. import 'o2_api_manager.dart';
  35. import 'o2_contact_permission_manager.dart';
  36. import 'o2_file_path_util.dart';
  37. import 'o2_utils.dart';
  38. typedef O2ScanCallback = void Function(String result);
  39. ///
  40. /// webview js api 注入
  41. ///
  42. class O2JavascriptHandler {
  43. // webview 的 controller 必须注入
  44. InAppWebViewController? webviewController;
  45. // 操作窗口相关的接口 必须注入
  46. JsNavigationInterface? jsNavigationInterface;
  47. // 输入的 controller
  48. TextEditingController? _inputController;
  49. O2JavascriptHandlerData o2mNotification() {
  50. return O2JavascriptHandlerData(
  51. key: "o2mNotification",
  52. callback: (arguments) {
  53. if (arguments.isNotEmpty) {
  54. _notification((arguments[0] as String?) ?? "");
  55. }
  56. return true;
  57. });
  58. }
  59. O2JavascriptHandlerData o2mUtil() {
  60. return O2JavascriptHandlerData(
  61. key: "o2mUtil",
  62. callback: (arguments) {
  63. if (arguments.isNotEmpty) {
  64. _util((arguments[0] as String?) ?? '');
  65. }
  66. return true;
  67. });
  68. }
  69. O2JavascriptHandlerData o2mBiz() {
  70. return O2JavascriptHandlerData(
  71. key: "o2mBiz",
  72. callback: (arguments) {
  73. if (arguments.isNotEmpty) {
  74. _biz((arguments[0] as String?) ?? '');
  75. }
  76. return true;
  77. });
  78. }
  79. /// o2mBiz 模块处理
  80. _biz(String msg) {
  81. OLogger.d("执行 Biz , 命令:$msg");
  82. if (msg.isEmpty == true) {
  83. return;
  84. }
  85. final jsMessage = JsMessage.fromJson(O2Utils.parseStringToJson(msg));
  86. switch (jsMessage.type) {
  87. case 'contact.departmentPicker':
  88. _departmentPicker(jsMessage);
  89. break;
  90. case 'contact.identityPicker':
  91. _identityPicker(jsMessage);
  92. break;
  93. case 'contact.groupPicker':
  94. _groupPicker(jsMessage);
  95. break;
  96. case 'contact.personPicker':
  97. _personPicker(jsMessage);
  98. break;
  99. case 'contact.complexPicker':
  100. _complexPicker(jsMessage);
  101. break;
  102. case 'contact.searchPage':
  103. _searchPage(jsMessage);
  104. break;
  105. case 'contact.personInfoPage':
  106. _personInfoPage(jsMessage);
  107. case 'contact.orgInfoPage':
  108. _orgInfoPage(jsMessage);
  109. break;
  110. case 'settings.openMyProfile':
  111. _settingOpenMyProfile(jsMessage);
  112. break;
  113. case 'settings.safeAndAccount':
  114. _settingOpenSafeAndAccount(jsMessage);
  115. break;
  116. case 'settings.skin':
  117. _settingOpenAppSkin(jsMessage);
  118. break;
  119. case 'settings.notice':
  120. _settingOpenAppNotice(jsMessage);
  121. break;
  122. case 'settings.common':
  123. _settingOpenAppCommon(jsMessage);
  124. break;
  125. case 'settings.about':
  126. _settingOpenAppAbout(jsMessage);
  127. break;
  128. case 'settings.logout':
  129. _settingLogout(jsMessage);
  130. break;
  131. case 'im.openConversation':
  132. _openImConversation(jsMessage);
  133. break;
  134. case 'im.openChatWithPerson':
  135. _openImChatWithSomeone(jsMessage);
  136. break;
  137. case 'im.openInstantChat':
  138. _openImInstantChat(jsMessage);
  139. break;
  140. case 'im.startSingleChat':
  141. _startSingleChat(jsMessage);
  142. break;
  143. case 'im.startGroupChat':
  144. _startGroupChat(jsMessage);
  145. break;
  146. default:
  147. OLogger.e('错误的类型 ${jsMessage.type}');
  148. break;
  149. }
  150. }
  151. /// o2mUtil 模块处理
  152. _util(String msg) {
  153. OLogger.d("执行 Util , 命令:$msg");
  154. if (msg.isEmpty == true) {
  155. return;
  156. }
  157. final jsMessage = JsMessage.fromJson(O2Utils.parseStringToJson(msg));
  158. switch (jsMessage.type) {
  159. case 'date.datePicker':
  160. _datePicker(jsMessage);
  161. break;
  162. case 'date.timePicker':
  163. _timePicker(jsMessage);
  164. break;
  165. case 'calendar.chooseOneDay':
  166. _datePicker(jsMessage);
  167. break;
  168. case 'calendar.chooseDateTime':
  169. _dateTimePicker(jsMessage);
  170. break;
  171. case 'date.dateTimePicker':
  172. _dateTimePicker(jsMessage);
  173. break;
  174. case 'calendar.chooseInterval':
  175. _chooseInterval(jsMessage);
  176. break;
  177. case 'device.rotate':
  178. _rotate(jsMessage);
  179. break;
  180. case 'device.getPhoneInfo':
  181. _getPhoneInfo(jsMessage);
  182. break;
  183. case 'device.scan':
  184. _scan(jsMessage);
  185. break;
  186. case 'device.location':
  187. _location(jsMessage);
  188. break;
  189. case 'device.localAuth':
  190. _localAuth(jsMessage);
  191. break;
  192. case 'navigation.setTitle':
  193. _navigationSetTitle(jsMessage);
  194. break;
  195. case 'navigation.close':
  196. _navigationClose(jsMessage);
  197. break;
  198. case 'navigation.goBack':
  199. _navigationGoBack(jsMessage);
  200. break;
  201. case 'navigation.openInnerApp':
  202. _openInnerApp(jsMessage);
  203. break;
  204. case 'navigation.openOtherApp':
  205. _openOtherApp(jsMessage);
  206. break;
  207. case 'navigation.openWindow':
  208. _openWindow(jsMessage);
  209. break;
  210. case 'navigation.openInBrowser':
  211. _openCurrentPageInBrowser(jsMessage);
  212. break;
  213. case 'navigation.clearCache':
  214. _clearCache(jsMessage);
  215. break;
  216. case 'navigation.share':
  217. _share(jsMessage);
  218. break;
  219. case 'settings.openMyProfile':
  220. _settingOpenMyProfile(jsMessage);
  221. break;
  222. case 'settings.safeAndAccount':
  223. _settingOpenSafeAndAccount(jsMessage);
  224. break;
  225. case 'settings.skin':
  226. _settingOpenAppSkin(jsMessage);
  227. break;
  228. case 'settings.notice':
  229. _settingOpenAppNotice(jsMessage);
  230. break;
  231. case 'settings.common':
  232. _settingOpenAppCommon(jsMessage);
  233. break;
  234. case 'settings.about':
  235. _settingOpenAppAbout(jsMessage);
  236. break;
  237. case 'settings.logout':
  238. _settingLogout(jsMessage);
  239. break;
  240. default:
  241. OLogger.e('错误的类型 ${jsMessage.type}');
  242. break;
  243. }
  244. }
  245. /// o2mNotification 模块处理
  246. _notification(String msg) {
  247. OLogger.d("执行 Notification , 命令:$msg");
  248. if (msg.isEmpty == true) {
  249. return;
  250. }
  251. final jsMessage = JsMessage.fromJson(O2Utils.parseStringToJson(msg));
  252. switch (jsMessage.type) {
  253. case 'alert':
  254. _alert(jsMessage);
  255. break;
  256. case 'confirm':
  257. _confirm(jsMessage);
  258. break;
  259. case 'prompt':
  260. _prompt(jsMessage);
  261. break;
  262. case 'vibrate':
  263. _vibrate(jsMessage);
  264. break;
  265. case 'toast':
  266. _toast(jsMessage);
  267. break;
  268. case 'actionSheet':
  269. _actionSheet(jsMessage);
  270. break;
  271. case 'showLoading':
  272. _showLoading(jsMessage);
  273. break;
  274. case 'hideLoading':
  275. _hideLoading(jsMessage);
  276. break;
  277. default:
  278. OLogger.e('错误的类型 ${jsMessage.type}');
  279. break;
  280. }
  281. }
  282. /// alert 提示框
  283. _alert(JsMessage jsMessage) {
  284. final context = my_get.Get.context;
  285. JsNotificationAlertMessage alertMessage =
  286. JsNotificationAlertMessage.fromJson(jsMessage.data ?? {});
  287. String callback = jsMessage.callback ?? '';
  288. if (alertMessage.message == null || alertMessage.message?.isEmpty == true) {
  289. Loading.showError('没有传入内容!');
  290. return;
  291. }
  292. O2UI.showAlert(context, alertMessage.message!,
  293. title: alertMessage.title, okText: alertMessage.buttonName);
  294. if (callback.isNotEmpty) {
  295. webviewController?.evaluateJavascript(source: "$callback()");
  296. }
  297. }
  298. /// confirm 确认框
  299. _confirm(JsMessage jsMessage) {
  300. final context = my_get.Get.context;
  301. JsNotificationConfirmMessage confirmMessage =
  302. JsNotificationConfirmMessage.fromJson(jsMessage.data ?? {});
  303. String callback = jsMessage.callback ?? '';
  304. if (confirmMessage.message == null ||
  305. confirmMessage.message?.isEmpty == true) {
  306. Loading.showError('args_error'.tr);
  307. return;
  308. }
  309. var buttons = confirmMessage.buttonLabels ?? [];
  310. if (buttons.length != 2) {
  311. buttons = ['confirm'.tr, 'cancel'.tr];
  312. }
  313. O2UI.showConfirm(context, confirmMessage.message!,
  314. title: confirmMessage.title,
  315. okText: buttons[0],
  316. cancelText: buttons[1], okPressed: () {
  317. if (callback.isNotEmpty) {
  318. webviewController?.evaluateJavascript(source: "$callback(0)");
  319. }
  320. }, cancelPressed: () {
  321. if (callback.isNotEmpty) {
  322. webviewController?.evaluateJavascript(source: "$callback(1)");
  323. }
  324. });
  325. }
  326. /// sheet 底部按钮选择器
  327. _actionSheet(JsMessage jsMessage) {
  328. final context = my_get.Get.context;
  329. if (context == null) {
  330. OLogger.e('没有 context, 无法打开 actionSheet');
  331. return;
  332. }
  333. JsNotificationActionSheetMessage sheetMsg =
  334. JsNotificationActionSheetMessage.fromJson(jsMessage.data ?? {});
  335. String callback = jsMessage.callback ?? '';
  336. if (sheetMsg.otherButtons == null ||
  337. sheetMsg.otherButtons?.isEmpty == true) {
  338. Loading.showError('args_error'.tr);
  339. return;
  340. }
  341. final buttons = sheetMsg.otherButtons ?? [];
  342. final title = sheetMsg.title ?? '';
  343. bool tooManyButtons = sheetMsg.tooManyButtons ?? false;
  344. List<Widget> widgets = buttons.mapWithIndex((e, i) {
  345. return ListTile(
  346. onTap: () {
  347. Navigator.pop(context);
  348. if (callback.isNotEmpty) {
  349. webviewController?.evaluateJavascript(source: "$callback($i)");
  350. }
  351. },
  352. title: Align(
  353. alignment: Alignment.center,
  354. child: Text(e, style: Theme.of(context).textTheme.bodyMedium),
  355. ),
  356. );
  357. }).toList();
  358. if (widgets.length > 6 ) {
  359. tooManyButtons = true;
  360. }
  361. if (tooManyButtons) {
  362. O2UI.showBottomSheetLongList(context, widgets,
  363. title: title, cancelText: sheetMsg.cancelButton, cancelPressed: () {
  364. if (callback.isNotEmpty) {
  365. webviewController?.evaluateJavascript(source: "$callback(-1)");
  366. }
  367. });
  368. } else {
  369. O2UI.showBottomSheetWithCancel(context, widgets,
  370. title: title, cancelText: sheetMsg.cancelButton, cancelPressed: () {
  371. if (callback.isNotEmpty) {
  372. webviewController?.evaluateJavascript(source: "$callback(-1)");
  373. }
  374. });
  375. }
  376. }
  377. /// prompt 输入框
  378. _prompt(JsMessage jsMessage) async {
  379. JsNotificationConfirmMessage confirmMessage =
  380. JsNotificationConfirmMessage.fromJson(jsMessage.data ?? {});
  381. String callback = jsMessage.callback ?? '';
  382. var buttons = confirmMessage.buttonLabels ?? [];
  383. if (buttons.length != 2) {
  384. buttons = ['confirm'.tr, 'cancel'.tr];
  385. }
  386. String content = confirmMessage.message ?? '';
  387. String title = confirmMessage.title ?? 'alert'.tr;
  388. _inputController = TextEditingController(text: content);
  389. var result = await O2UI.showCustomDialog(
  390. my_get.Get.context,
  391. title,
  392. TextField(
  393. controller: _inputController,
  394. maxLines: 1,
  395. keyboardType: TextInputType.text,
  396. textInputAction: TextInputAction.done,
  397. ),
  398. positiveBtnText: buttons[0],
  399. cancelBtnText: buttons[1]);
  400. if (result == O2DialogAction.positive) {
  401. var jsonBack =
  402. '{buttonIndex: 0, value: "${_inputController?.text ?? ''}"}';
  403. if (callback.isNotEmpty) {
  404. webviewController?.evaluateJavascript(source: "$callback('$jsonBack')");
  405. }
  406. } else if (result == O2DialogAction.cancel) {
  407. var jsonBack =
  408. '{buttonIndex: 1, value: "${_inputController?.text ?? ''}"}';
  409. if (callback.isNotEmpty) {
  410. webviewController?.evaluateJavascript(source: "$callback('$jsonBack')");
  411. }
  412. }
  413. }
  414. /// 震动
  415. _vibrate(JsMessage jsMessage) async {
  416. String callback = jsMessage.callback ?? '';
  417. HapticFeedback.mediumImpact();
  418. if (callback.isNotEmpty) {
  419. webviewController?.evaluateJavascript(source: "$callback()");
  420. }
  421. }
  422. /// toast 消息
  423. _toast(JsMessage jsMessage) async {
  424. String callback = jsMessage.callback ?? '';
  425. JsNotificationToastMessage toastMessage =
  426. JsNotificationToastMessage.fromJson(jsMessage.data ?? {});
  427. if (toastMessage.message != null &&
  428. toastMessage.message?.isNotEmpty == true) {
  429. Loading.toast(toastMessage.message!);
  430. }
  431. if (callback.isNotEmpty) {
  432. webviewController?.evaluateJavascript(source: "$callback()");
  433. }
  434. }
  435. /// loading 层显示
  436. _showLoading(JsMessage jsMessage) async {
  437. String callback = jsMessage.callback ?? '';
  438. JsNotificationLoadingMessage loadingMessage =
  439. JsNotificationLoadingMessage.fromJson(jsMessage.data ?? {});
  440. Loading.show(text: loadingMessage.text);
  441. if (callback.isNotEmpty) {
  442. webviewController?.evaluateJavascript(source: "$callback()");
  443. }
  444. }
  445. /// 关闭 loading 层
  446. _hideLoading(JsMessage jsMessage) async {
  447. String callback = jsMessage.callback ?? '';
  448. Loading.dismiss();
  449. if (callback.isNotEmpty) {
  450. webviewController?.evaluateJavascript(source: "$callback()");
  451. }
  452. }
  453. /// 日期选择器
  454. _datePicker(JsMessage jsMessage) async {
  455. final context = my_get.Get.context;
  456. if (context == null) {
  457. OLogger.e('没有 context, 无法打开 _datePicker');
  458. return;
  459. }
  460. String callback = jsMessage.callback ?? '';
  461. JsUtilDatePickerMessage message =
  462. JsUtilDatePickerMessage.fromJson(jsMessage.data ?? {});
  463. DateTime? initDate;
  464. if (message.value != null && message.value?.isNotEmpty == true) {
  465. initDate = DateTime.tryParse(message.value!);
  466. }
  467. initDate ??= DateTime.now();
  468. final result = await showDatePicker(
  469. context: context,
  470. initialDate: initDate,
  471. firstDate: initDate.addYears(-100),
  472. lastDate: initDate.addYears(100));
  473. if (result != null) {
  474. final date = result.ymd();
  475. OLogger.d('选择日期 $date');
  476. if (callback.isNotEmpty) {
  477. webviewController?.evaluateJavascript(
  478. source: '$callback(\'{"value": "$date"}\')');
  479. }
  480. }
  481. }
  482. /// 时间选择器
  483. _timePicker(JsMessage jsMessage) async {
  484. final context = my_get.Get.context;
  485. if (context == null) {
  486. OLogger.e('没有 context, 无法打开 _timePicker');
  487. return;
  488. }
  489. String callback = jsMessage.callback ?? '';
  490. JsUtilTimePickerMessage message =
  491. JsUtilTimePickerMessage.fromJson(jsMessage.data ?? {});
  492. DateTime? initDate;
  493. if (message.value != null && message.value?.isNotEmpty == true) {
  494. initDate = DateTime.tryParse(message.value!);
  495. }
  496. initDate ??= DateTime.now();
  497. TimeOfDay initTime =
  498. TimeOfDay(hour: initDate.hour, minute: initDate.minute);
  499. final startTime =
  500. await showTimePicker(context: context, initialTime: initTime);
  501. if (startTime != null) {
  502. final startHour =
  503. startTime.hour > 9 ? '${startTime.hour}' : '0${startTime.hour}';
  504. final startMinute =
  505. startTime.minute > 9 ? '${startTime.minute}' : '0${startTime.minute}';
  506. final time = '$startHour:$startMinute';
  507. OLogger.d('选择时间 $time');
  508. if (callback.isNotEmpty) {
  509. webviewController?.evaluateJavascript(
  510. source: '$callback(\'{"value": "$time"}\')');
  511. }
  512. }
  513. }
  514. /// 日期时间选择器
  515. _dateTimePicker(JsMessage jsMessage) async {
  516. final context = my_get.Get.context;
  517. if (context == null) {
  518. OLogger.e('没有 context, 无法打开 _timePicker');
  519. return;
  520. }
  521. String callback = jsMessage.callback ?? '';
  522. JsUtilTimePickerMessage message =
  523. JsUtilTimePickerMessage.fromJson(jsMessage.data ?? {});
  524. DateTime? initDate;
  525. if (message.value != null && message.value?.isNotEmpty == true) {
  526. initDate = DateTime.tryParse(message.value!);
  527. }
  528. initDate ??= DateTime.now();
  529. TimeOfDay initTime =
  530. TimeOfDay(hour: initDate.hour, minute: initDate.minute);
  531. final result = await showDatePicker(
  532. context: context,
  533. initialDate: initDate,
  534. firstDate: initDate.addYears(-100),
  535. lastDate: initDate.addYears(100));
  536. if (result != null) {
  537. var date = result.ymd();
  538. OLogger.d('选择日期 $date');
  539. // ignore: use_build_context_synchronously
  540. if (!context.mounted) {
  541. return;
  542. }
  543. final startTime =
  544. await showTimePicker(context: context, initialTime: initTime);
  545. if (startTime != null) {
  546. final startHour =
  547. startTime.hour > 9 ? '${startTime.hour}' : '0${startTime.hour}';
  548. final startMinute = startTime.minute > 9
  549. ? '${startTime.minute}'
  550. : '0${startTime.minute}';
  551. date = '$date $startHour:$startMinute';
  552. OLogger.d('选择时间 $date');
  553. }
  554. if (callback.isNotEmpty) {
  555. webviewController?.evaluateJavascript(
  556. source: '$callback(\'{"value": "$date"}\')');
  557. }
  558. }
  559. }
  560. /// 日期间隔选择器
  561. _chooseInterval(JsMessage jsMessage) async {
  562. final context = my_get.Get.context;
  563. if (context == null) {
  564. OLogger.e('没有 context, 无法打开 _timePicker');
  565. return;
  566. }
  567. String callback = jsMessage.callback ?? '';
  568. JsUtilDateIntervalPickerMessage message =
  569. JsUtilDateIntervalPickerMessage.fromJson(jsMessage.data ?? {});
  570. DateTime? startDate;
  571. DateTime? endDate;
  572. if (message.startDate != null && message.startDate?.isNotEmpty == true) {
  573. startDate = DateTime.tryParse(message.startDate!);
  574. }
  575. startDate ??= DateTime.now();
  576. if (message.endDate != null && message.endDate?.isNotEmpty == true) {
  577. endDate = DateTime.tryParse(message.endDate!);
  578. }
  579. endDate ??= DateTime.now();
  580. final result = await showDatePicker(
  581. context: context,
  582. initialDate: startDate,
  583. firstDate: startDate.addYears(-100),
  584. lastDate: startDate.addYears(100));
  585. if (result != null) {
  586. final start = result.ymd();
  587. OLogger.d('选择开始日期 $start');
  588. // ignore: use_build_context_synchronously
  589. if (!context.mounted) {
  590. return;
  591. }
  592. final resultEnd = await showDatePicker(
  593. context: context,
  594. initialDate: endDate,
  595. firstDate: endDate.addYears(-100),
  596. lastDate: endDate.addYears(100));
  597. if (resultEnd != null) {
  598. final end = resultEnd.ymd();
  599. OLogger.d('选择结束日期 $end');
  600. if (callback.isNotEmpty) {
  601. webviewController?.evaluateJavascript(
  602. source:
  603. '$callback(\'{ "startDate": "$start", "endDate": "$end" }\')');
  604. }
  605. }
  606. }
  607. }
  608. /// 屏幕旋转
  609. _rotate(JsMessage jsMessage) async {
  610. final context = my_get.Get.context;
  611. if (context == null) {
  612. OLogger.e('没有 context, 无法打开 _rotate');
  613. return;
  614. }
  615. final callback = jsMessage.callback ?? '';
  616. if (MediaQuery.of(context).orientation == Orientation.landscape) {
  617. await SystemChrome.setPreferredOrientations(
  618. [DeviceOrientation.landscapeRight]);
  619. } else {
  620. await SystemChrome.setPreferredOrientations(
  621. [DeviceOrientation.portraitUp]);
  622. }
  623. if (callback.isNotEmpty) {
  624. webviewController?.evaluateJavascript(source: '$callback()');
  625. }
  626. }
  627. /// 获取手机信息
  628. _getPhoneInfo(JsMessage jsMessage) async {
  629. final context = my_get.Get.context;
  630. if (context == null) {
  631. OLogger.e('没有 context, 无法打开 _getPhoneInfo');
  632. return;
  633. }
  634. final callback = jsMessage.callback ?? '';
  635. var brand = '';
  636. var model = '';
  637. var version = '';
  638. final width = MediaQuery.of(context).size.width;
  639. final height = MediaQuery.of(context).size.height;
  640. OLogger.d('屏幕 width $width height $height');
  641. final deviceInfoPlugin = DeviceInfoPlugin();
  642. if (Platform.isAndroid) {
  643. final android = await deviceInfoPlugin.androidInfo;
  644. brand = android.brand;
  645. model = android.model;
  646. version = '${android.version.baseOS ?? ''} ${android.version.sdkInt}';
  647. } else {
  648. final ios = await deviceInfoPlugin.iosInfo;
  649. brand = ios.utsname.machine;
  650. model = ios.model;
  651. version = '${ios.systemName} ${ios.systemVersion}';
  652. }
  653. if (callback.isNotEmpty) {
  654. final res = JsDevicePhoneInfoResponse(
  655. screenWidth: "$width",
  656. screenHeight: "$height",
  657. brand: brand,
  658. model: model,
  659. version: version,
  660. netInfo: '',
  661. operatorType: '');
  662. webviewController?.evaluateJavascript(
  663. source: '$callback(\'${json.encode(res.toJson())}\')');
  664. }
  665. }
  666. /// 扫二维码
  667. _scan(JsMessage jsMessage) async {
  668. final callback = jsMessage.callback ?? '';
  669. ScanPage.o2ScanBiz(callback: (result) {
  670. if (callback.isNotEmpty) {
  671. webviewController?.evaluateJavascript(
  672. source: '$callback(\'${result.o2SimpleString()}\')');
  673. }
  674. });
  675. }
  676. /// 定位
  677. _location(JsMessage jsMessage) async {
  678. final callback = jsMessage.callback ?? '';
  679. final helper = GeolocatorHelper(
  680. isSingleLocation: true,
  681. callback: (position) {
  682. OLogger.d('定位返回结果 ${position.latitude} ${position.longitude}');
  683. final res = JsDeviceLocationResponse(
  684. latitude: '${position.latitude}',
  685. longitude: '${position.longitude}',
  686. address: '${position.address}');
  687. if (callback.isNotEmpty) {
  688. webviewController?.evaluateJavascript(
  689. source: '$callback(\'${json.encode(res.toJson())}\')');
  690. }
  691. });
  692. helper.startLocation();
  693. // final helper = BaiduLocationHelper(
  694. // callback: (result) {
  695. // OLogger.d('定位返回结果 ${result.latitude} ${result.longitude}');
  696. // final res = JsDeviceLocationResponse(
  697. // latitude: '${result.latitude}',
  698. // longitude: '${result.longitude}',
  699. // address: '${result.address}');
  700. // if (callback.isNotEmpty) {
  701. // webviewController?.evaluateJavascript(
  702. // source: '$callback(\'${json.encode(res.toJson())}\')');
  703. // }
  704. // },
  705. // isSingleLocation: true);
  706. // helper.initLocationAndStartRequest();
  707. }
  708. /// 手机生物识别认证
  709. _localAuth(JsMessage jsMessage) async {
  710. final callback = jsMessage.callback ?? '';
  711. if (callback.isNotEmpty) {
  712. final result = await O2Utils.bioAuth();
  713. final res = {"value": result};
  714. webviewController?.evaluateJavascript(
  715. source: '$callback(\'${json.encode(res)}\')');
  716. } else {
  717. OLogger.e('_localAuth, 没有回调函数!');
  718. }
  719. }
  720. /// 设置标题
  721. _navigationSetTitle(JsMessage jsMessage) async {
  722. final callback = jsMessage.callback ?? '';
  723. JsUtilNavigationMessage message =
  724. JsUtilNavigationMessage.fromJson(jsMessage.data ?? {});
  725. if (message.title?.isNotEmpty == true) {
  726. jsNavigationInterface?.setNavigationTitle(message.title!);
  727. if (callback.isNotEmpty) {
  728. webviewController?.evaluateJavascript(source: '$callback()');
  729. }
  730. } else {
  731. OLogger.e('传入的标题内容为空!');
  732. }
  733. }
  734. /// 关闭当前窗口
  735. _navigationClose(JsMessage jsMessage) async {
  736. final callback = jsMessage.callback ?? '';
  737. jsNavigationInterface?.closeWindow();
  738. if (callback.isNotEmpty) {
  739. webviewController?.evaluateJavascript(source: '$callback()');
  740. }
  741. }
  742. /// 返回上一页
  743. _navigationGoBack(JsMessage jsMessage) async {
  744. final callback = jsMessage.callback ?? '';
  745. jsNavigationInterface?.goBack();
  746. if (callback.isNotEmpty) {
  747. webviewController?.evaluateJavascript(source: '$callback()');
  748. }
  749. }
  750. /// 分享图片, 目前只支持 base64
  751. Future<void> _share(JsMessage jsMessage) async {
  752. final callback = jsMessage.callback ?? '';
  753. final base64String = jsMessage.data?['base64'];
  754. // final subject = jsMessage.data?['subject'];
  755. // final text = jsMessage.data?['text'];
  756. if (base64String != null && base64String is String) {
  757. final filePath = await _base64ToImage(base64String);
  758. if (filePath != null && filePath.isNotEmpty) {
  759. _shareImage(filePath);
  760. }
  761. } else {
  762. OLogger.e('错误的参数传入!');
  763. }
  764. if (callback.isNotEmpty) {
  765. webviewController?.evaluateJavascript(source: '$callback()');
  766. }
  767. }
  768. /// baes64 转图片后 分享
  769. Future<String?> _base64ToImage(String base64) async {
  770. try {
  771. final bytes = base64Decode(base64);
  772. //图片临时存储
  773. final timeString =
  774. 'share_base64_image_${DateTime.now().millisecondsSinceEpoch}';
  775. var dir = await O2FilePathUtil.getTempFolderWithUrl(timeString);
  776. if (dir == null || dir.isEmpty) {
  777. OLogger.e('本地文件目录生成失败! url: $timeString');
  778. Loading.showError('common_image_generate_fail'.tr);
  779. return null;
  780. }
  781. String filePath = '$dir/$timeString.png';
  782. File file = File(filePath);
  783. file.writeAsBytesSync(bytes);
  784. OLogger.i('保存图片完成,path:$filePath');
  785. return filePath;
  786. } catch (e) {
  787. OLogger.e('图片生成失败!', e);
  788. Loading.showError('common_image_generate_fail'.tr);
  789. return null;
  790. }
  791. }
  792. /// 分享图片
  793. Future<void> _shareImage(String filePath) async {
  794. final context = Get.context;
  795. if (context == null) {
  796. OLogger.e('context 为空!');
  797. return;
  798. }
  799. final box = context.findRenderObject() as RenderBox?;
  800. final result = await Share.shareXFiles([XFile(filePath)],
  801. sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
  802. if (result.status != ShareResultStatus.success) {
  803. OLogger.i('分享失败,${result.status}');
  804. return;
  805. }
  806. Loading.toast('common_share_success'.tr);
  807. }
  808. /// 打开内部原生应用
  809. _openInnerApp(JsMessage jsMessage) async {
  810. final callback = jsMessage.callback ?? '';
  811. JsUtilOpenInnerAppMessage message =
  812. JsUtilOpenInnerAppMessage.fromJson(jsMessage.data ?? {});
  813. final appKey = message.appKey;
  814. final appDisplayName = message.appDisplayName;
  815. final portalFlag = message.portalFlag;
  816. final portalTitle = message.portalTitle;
  817. final portalPage = message.portalPage;
  818. final parameters = message.parameters ?? {};
  819. if (appKey?.isNotEmpty == true) {
  820. // 门户处理
  821. if (appKey == 'portal') {
  822. if (portalFlag?.isEmpty == true) {
  823. Loading.showError('args_error'.tr);
  824. OLogger.e('门户没有传入参数 portalFlag');
  825. return;
  826. }
  827. final portalParameters = parameters['portalParameters'];
  828. PortalPage.open(portalFlag!,
  829. title: portalTitle ?? '',
  830. pageId: portalPage,
  831. portalParameters: portalParameters);
  832. } else if (appKey == 'startProcess') {
  833. //启动流程
  834. await _startProcess();
  835. } else if (appKey == 'speechAssistant') {
  836. // 语音助手
  837. SpeechAssistantChatPage.open();
  838. } else {
  839. String flutterPath = '';
  840. if (appKey == O2NativeAppEnum.task.key) {
  841. flutterPath = O2OARoutes.appTask;
  842. } else if (appKey == O2NativeAppEnum.taskcompleted.key) {
  843. flutterPath = O2OARoutes.appTaskcompleted;
  844. } else if (appKey == O2NativeAppEnum.read.key) {
  845. flutterPath = O2OARoutes.appRead;
  846. } else if (appKey == O2NativeAppEnum.readcompleted.key) {
  847. flutterPath = O2OARoutes.appReadcompleted;
  848. } else if (appKey == O2NativeAppEnum.meeting.key) {
  849. flutterPath = O2OARoutes.appMeeting;
  850. } else if (appKey == O2NativeAppEnum.bbs.key) {
  851. flutterPath = O2OARoutes.appBBS;
  852. } else if (appKey == O2NativeAppEnum.yunpan.key ||
  853. appKey == 'clouddisk') {
  854. flutterPath = FileAssembleService.to.isV3()
  855. ? O2OARoutes.appCloudDiskV3
  856. : O2OARoutes.appYunpan;
  857. } else if (appKey == O2NativeAppEnum.attendance.key) {
  858. flutterPath = O2OARoutes.appAttendance;
  859. } else if (appKey == O2NativeAppEnum.attendanceOld.key) {
  860. flutterPath = O2OARoutes.appAttendanceOld;
  861. } else if (appKey == O2NativeAppEnum.cms.key) {
  862. flutterPath = O2OARoutes.appCms;
  863. } else if (appKey == O2NativeAppEnum.calendar.key) {
  864. flutterPath = O2OARoutes.appCalendar;
  865. } else if (appKey == O2NativeAppEnum.mindMap.key) {
  866. flutterPath = O2OARoutes.appMindMap;
  867. }
  868. if (flutterPath.isNotEmpty) {
  869. if (O2OARoutes.appAttendance == flutterPath ||
  870. O2OARoutes.appAttendanceOld == flutterPath) {
  871. FastCheckInService.instance.stop(); // 进入考勤 先关闭极速打卡
  872. }
  873. if (appDisplayName?.trim().isNotEmpty == true) {
  874. if (flutterPath.contains('?')) {
  875. flutterPath += '&displayName=$appDisplayName';
  876. } else {
  877. flutterPath += '?displayName=$appDisplayName';
  878. }
  879. }
  880. my_get.Get.toNamed(flutterPath);
  881. } else {
  882. Loading.showError('args_error'.tr);
  883. OLogger.e('错误的 appkey $appKey');
  884. }
  885. }
  886. if (callback.isNotEmpty) {
  887. webviewController?.evaluateJavascript(source: '$callback()');
  888. }
  889. } else {
  890. OLogger.e('没传入 appKey ');
  891. Loading.showError('args_error'.tr);
  892. }
  893. }
  894. // 选择启动流程
  895. Future<void> _startProcess() async {
  896. var result = await ProcessPickerPage.startPicker(ProcessPickerMode.process);
  897. if (result != null && result is ProcessData) {
  898. CreateFormPage.startProcess(true, process: result);
  899. }
  900. }
  901. /// 打开外部应用
  902. _openOtherApp(JsMessage jsMessage) async {
  903. final callback = jsMessage.callback ?? '';
  904. JsUtilOtherAppMessage message =
  905. JsUtilOtherAppMessage.fromJson(jsMessage.data ?? {});
  906. if (message.schema?.isNotEmpty == true) {
  907. final uri = Uri.parse(message.schema!);
  908. bool can = await canLaunchUrl(uri);
  909. if (!can) {
  910. Loading.showError(
  911. 'common_error_open_other_app'.trArgs([message.schema!]));
  912. return;
  913. }
  914. await launchUrl(uri, mode: LaunchMode.externalApplication);
  915. if (callback.isNotEmpty) {
  916. webviewController?.evaluateJavascript(source: '$callback()');
  917. }
  918. } else {
  919. OLogger.e('没传入 schema ');
  920. }
  921. }
  922. /// 打开新窗口
  923. _openWindow(JsMessage jsMessage) async {
  924. final callback = jsMessage.callback ?? '';
  925. JsUtilOpenWindowMessage message =
  926. JsUtilOpenWindowMessage.fromJson(jsMessage.data ?? {});
  927. if (message.url?.isNotEmpty == true) {
  928. InnerWebviewPage.open(message.url!);
  929. if (callback.isNotEmpty) {
  930. webviewController?.evaluateJavascript(source: '$callback()');
  931. }
  932. } else {
  933. OLogger.e('没有传入 url');
  934. }
  935. }
  936. /// 当前页面在手机默认浏览器打开
  937. _openCurrentPageInBrowser(JsMessage jsMessage) async {
  938. final callback = jsMessage.callback ?? '';
  939. final uri = await webviewController?.getUrl();
  940. if (uri != null) {
  941. if (await canLaunchUrl(uri)) {
  942. final result = await launchUrl(
  943. uri,
  944. mode: LaunchMode.externalApplication,
  945. webViewConfiguration: WebViewConfiguration(headers: <String, String>{
  946. O2ApiManager.instance.tokenName:
  947. O2ApiManager.instance.o2User?.token ?? ''
  948. }),
  949. );
  950. if (!result) {
  951. OLogger.e('打开 url ${uri.toString()} 失败!');
  952. }
  953. } else {
  954. OLogger.e('uri 不正确,${uri.toString()}');
  955. }
  956. }
  957. if (callback.isNotEmpty) {
  958. webviewController?.evaluateJavascript(source: '$callback()');
  959. }
  960. }
  961. /// 清除缓存并刷新页面
  962. _clearCache(JsMessage jsMessage) async {
  963. final callback = jsMessage.callback ?? '';
  964. //TODO 清除缓存
  965. if (callback.isNotEmpty) {
  966. webviewController?.evaluateJavascript(source: '$callback()');
  967. }
  968. }
  969. /// 组织选择器
  970. _departmentPicker(JsMessage jsMessage) async {
  971. final callback = jsMessage.callback ?? '';
  972. JsBizPickerMessage message =
  973. JsBizPickerMessage.fromJson(jsMessage.data ?? {});
  974. final result = await ContactPickerPage.startPicker(
  975. [ContactPickMode.departmentPicker],
  976. topUnitList: message.topList,
  977. unitType: message.orgType,
  978. maxNumber: message.maxNumber,
  979. multiple: message.multiple,
  980. initDeptList: message.pickedDepartments);
  981. if (result is ContactPickerResult) {
  982. if (callback.isNotEmpty) {
  983. webviewController?.evaluateJavascript(
  984. source: '$callback(\'${json.encode(result.toJson())}\')');
  985. }
  986. }
  987. }
  988. /// 身份选择器
  989. _identityPicker(JsMessage jsMessage) async {
  990. final callback = jsMessage.callback ?? '';
  991. JsBizPickerMessage message =
  992. JsBizPickerMessage.fromJson(jsMessage.data ?? {});
  993. final result = await ContactPickerPage.startPicker(
  994. [ContactPickMode.identityPicker],
  995. topUnitList: message.topList,
  996. maxNumber: message.maxNumber,
  997. multiple: message.multiple,
  998. dutyList: message.duty,
  999. initIdList: message.pickedIdentities);
  1000. if (result is ContactPickerResult) {
  1001. if (callback.isNotEmpty) {
  1002. webviewController?.evaluateJavascript(
  1003. source: '$callback(\'${json.encode(result.toJson())}\')');
  1004. }
  1005. }
  1006. }
  1007. /// 人员选择器
  1008. _personPicker(JsMessage jsMessage) async {
  1009. final callback = jsMessage.callback ?? '';
  1010. JsBizPickerMessage message =
  1011. JsBizPickerMessage.fromJson(jsMessage.data ?? {});
  1012. final result = await ContactPickerPage.startPicker(
  1013. [ContactPickMode.personPicker],
  1014. maxNumber: message.maxNumber,
  1015. multiple: message.multiple,
  1016. initUserList: message.pickedUsers);
  1017. if (result is ContactPickerResult) {
  1018. if (callback.isNotEmpty) {
  1019. webviewController?.evaluateJavascript(
  1020. source: '$callback(\'${json.encode(result.toJson())}\')');
  1021. }
  1022. }
  1023. }
  1024. /// 组合选择器
  1025. _complexPicker(JsMessage jsMessage) async {
  1026. final callback = jsMessage.callback ?? '';
  1027. JsBizPickerMessage message =
  1028. JsBizPickerMessage.fromJson(jsMessage.data ?? {});
  1029. final pickModes = message.pickMode ?? [];
  1030. if (pickModes.isEmpty) {
  1031. Loading.showError('args_error'.tr);
  1032. OLogger.e('pickMode 不能为空');
  1033. return;
  1034. }
  1035. final result = await ContactPickerPage.startPicker(_pickModeList(pickModes),
  1036. topUnitList: message.topList,
  1037. maxNumber: message.maxNumber,
  1038. multiple: message.multiple,
  1039. unitType: message.orgType,
  1040. dutyList: message.duty,
  1041. initDeptList: message.pickedDepartments,
  1042. initIdList: message.pickedIdentities,
  1043. initGroupList: message.pickedGroups,
  1044. initUserList: message.pickedUsers);
  1045. if (result is ContactPickerResult) {
  1046. if (callback.isNotEmpty) {
  1047. webviewController?.evaluateJavascript(
  1048. source: '$callback(\'${json.encode(result.toJson())}\')');
  1049. }
  1050. }
  1051. }
  1052. ///
  1053. List<ContactPickMode> _pickModeList(List<String> pickModes) {
  1054. return pickModes
  1055. .map((e) {
  1056. switch (e) {
  1057. case 'departmentPicker':
  1058. return ContactPickMode.departmentPicker;
  1059. case 'identityPicker':
  1060. return ContactPickMode.identityPicker;
  1061. case 'groupPicker':
  1062. return ContactPickMode.groupPicker;
  1063. case 'personPicker':
  1064. return ContactPickMode.personPicker;
  1065. default:
  1066. return null;
  1067. }
  1068. })
  1069. .where((element) => element != null)
  1070. .map((e) => e!)
  1071. .toList();
  1072. }
  1073. /// 群组选择器
  1074. _groupPicker(JsMessage jsMessage) async {
  1075. final callback = jsMessage.callback ?? '';
  1076. JsBizPickerMessage message =
  1077. JsBizPickerMessage.fromJson(jsMessage.data ?? {});
  1078. final result = await ContactPickerPage.startPicker(
  1079. [ContactPickMode.groupPicker],
  1080. maxNumber: message.maxNumber,
  1081. multiple: message.multiple,
  1082. initGroupList: message.pickedGroups);
  1083. if (result is ContactPickerResult) {
  1084. if (callback.isNotEmpty) {
  1085. webviewController?.evaluateJavascript(
  1086. source: '$callback(\'${json.encode(result.toJson())}\')');
  1087. }
  1088. }
  1089. }
  1090. /// 打开我的页面
  1091. _settingOpenMyProfile(JsMessage jsMessage) async {
  1092. final callback = jsMessage.callback ?? '';
  1093. Get.toNamed(O2OARoutes.homeSettingsMyProfile);
  1094. if (callback.isNotEmpty) {
  1095. webviewController?.evaluateJavascript(source: '$callback()');
  1096. }
  1097. }
  1098. _settingOpenSafeAndAccount(JsMessage jsMessage) async {
  1099. final callback = jsMessage.callback ?? '';
  1100. Get.toNamed(O2OARoutes.homeSettingsAccountSafe);
  1101. if (callback.isNotEmpty) {
  1102. webviewController?.evaluateJavascript(source: '$callback()');
  1103. }
  1104. }
  1105. _settingOpenAppSkin(JsMessage jsMessage) async {
  1106. final callback = jsMessage.callback ?? '';
  1107. Get.toNamed(O2OARoutes.homeSettingsSkin);
  1108. if (callback.isNotEmpty) {
  1109. webviewController?.evaluateJavascript(source: '$callback()');
  1110. }
  1111. }
  1112. _settingOpenAppNotice(JsMessage jsMessage) async {
  1113. final callback = jsMessage.callback ?? '';
  1114. if (GetPlatform.isMobile) {
  1115. AppSettings.openNotificationSettings();
  1116. }
  1117. if (callback.isNotEmpty) {
  1118. webviewController?.evaluateJavascript(source: '$callback()');
  1119. }
  1120. }
  1121. _settingOpenAppCommon(JsMessage jsMessage) async {
  1122. final callback = jsMessage.callback ?? '';
  1123. Get.toNamed(O2OARoutes.homeSettingsCommon);
  1124. if (callback.isNotEmpty) {
  1125. webviewController?.evaluateJavascript(source: '$callback()');
  1126. }
  1127. }
  1128. _settingOpenAppAbout(JsMessage jsMessage) async {
  1129. final callback = jsMessage.callback ?? '';
  1130. Get.toNamed(O2OARoutes.homeSettingsAbout);
  1131. if (callback.isNotEmpty) {
  1132. webviewController?.evaluateJavascript(source: '$callback()');
  1133. }
  1134. }
  1135. Future<void> _settingLogout(JsMessage jsMessage) async {
  1136. final callback = jsMessage.callback ?? '';
  1137. O2Utils.logout();
  1138. if (callback.isNotEmpty) {
  1139. webviewController?.evaluateJavascript(source: '$callback()');
  1140. }
  1141. }
  1142. /// 人员组织搜索页面
  1143. Future<void> _searchPage(JsMessage jsMessage) async {
  1144. final callback = jsMessage.callback ?? '';
  1145. if (O2ContactPermissionManager.instance.isCurrentPersonCannotQueryAll() ||
  1146. O2ContactPermissionManager.instance.isCurrentPersonCannotQueryOuter()) {
  1147. OLogger.i('当前用户没有权限搜索通讯录');
  1148. Loading.toast('contact_no_permission'.tr);
  1149. } else {
  1150. Get.toNamed(O2OARoutes.homeContactSearch);
  1151. }
  1152. if (callback.isNotEmpty) {
  1153. webviewController?.evaluateJavascript(source: '$callback()');
  1154. }
  1155. }
  1156. /// 人员详情页面
  1157. _personInfoPage(JsMessage jsMessage) async {
  1158. final callback = jsMessage.callback ?? '';
  1159. final personDn = jsMessage.data?['personDn'];
  1160. if (personDn != null && personDn is String) {
  1161. PersonPage.open(personDn);
  1162. }
  1163. if (callback.isNotEmpty) {
  1164. webviewController?.evaluateJavascript(source: '$callback()');
  1165. }
  1166. }
  1167. /// 根据组织dn打开 下级组织和人员页面
  1168. Future<void> _orgInfoPage(JsMessage jsMessage) async {
  1169. final callback = jsMessage.callback ?? '';
  1170. final orgDn = jsMessage.data?['orgDn'];
  1171. final orgName = jsMessage.data?['orgName'];
  1172. if (orgDn != null && orgDn is String) {
  1173. OrgPersonListPage.open(
  1174. top: O2Unit(
  1175. distinguishedName: orgDn,
  1176. name: (orgName != null && orgName is String) ? orgName : ''));
  1177. }
  1178. if (callback.isNotEmpty) {
  1179. webviewController?.evaluateJavascript(source: '$callback()');
  1180. }
  1181. }
  1182. /// 打开IM会话
  1183. Future<void> _openImConversation(JsMessage jsMessage) async {
  1184. final callback = jsMessage.callback ?? '';
  1185. final conversationId = jsMessage.data?['conversationId'];
  1186. if (conversationId == null || conversationId is String) {
  1187. ImChatPage.open((conversationId as String));
  1188. }
  1189. if (callback.isNotEmpty) {
  1190. webviewController?.evaluateJavascript(source: '$callback()');
  1191. }
  1192. }
  1193. /// 跟某人聊天
  1194. Future<void> _openImChatWithSomeone(JsMessage jsMessage) async {
  1195. final callback = jsMessage.callback ?? '';
  1196. final person = jsMessage.data?['person'];
  1197. if (person == null || person is String) {
  1198. await _createConversation(
  1199. O2.imConversationTypeSingle, [(person as String)]);
  1200. }
  1201. if (callback.isNotEmpty) {
  1202. webviewController?.evaluateJavascript(source: '$callback()');
  1203. }
  1204. }
  1205. /// 打开系统消息会话
  1206. Future<void> _openImInstantChat(JsMessage jsMessage) async {
  1207. final callback = jsMessage.callback ?? '';
  1208. InstantChatPage.open();
  1209. if (callback.isNotEmpty) {
  1210. webviewController?.evaluateJavascript(source: '$callback()');
  1211. }
  1212. }
  1213. /// 选择人员创建单聊
  1214. Future<void> _startSingleChat(JsMessage jsMessage) async {
  1215. final callback = jsMessage.callback ?? '';
  1216. var result =
  1217. await ContactPickerPage.startPicker([ContactPickMode.personPicker]);
  1218. if (result is ContactPickerResult) {
  1219. if (result.users != null && result.users!.isNotEmpty) {
  1220. if (result.users![0].distinguishedName! ==
  1221. O2ApiManager.instance.o2User?.distinguishedName) {
  1222. Loading.toast('im_msg_create_conversation_not_with_self'.tr);
  1223. if (callback.isNotEmpty) {
  1224. webviewController?.evaluateJavascript(source: '$callback()');
  1225. }
  1226. return;
  1227. }
  1228. await _createConversation(
  1229. O2.imConversationTypeSingle, [result.users![0].distinguishedName!]);
  1230. }
  1231. }
  1232. if (callback.isNotEmpty) {
  1233. webviewController?.evaluateJavascript(source: '$callback()');
  1234. }
  1235. }
  1236. /// 选择人员创建群聊
  1237. Future<void> _startGroupChat(JsMessage jsMessage) async {
  1238. final callback = jsMessage.callback ?? '';
  1239. var result = await ContactPickerPage.startPicker(
  1240. [ContactPickMode.personPicker],
  1241. multiple: true);
  1242. if (result is ContactPickerResult) {
  1243. List<String> personList = [];
  1244. result.users?.forEach((element) {
  1245. personList.add(element.distinguishedName!);
  1246. });
  1247. await _createConversation(O2.imConversationTypeGroup, personList);
  1248. }
  1249. if (callback.isNotEmpty) {
  1250. webviewController?.evaluateJavascript(source: '$callback()');
  1251. }
  1252. }
  1253. Future<void> _createConversation(String type, List<String> personList) async {
  1254. if (type.isEmpty || personList.isEmpty) {
  1255. return;
  1256. }
  1257. final conv = await MessageCommunicationService.to
  1258. .createConversation(type, personList);
  1259. if (conv != null && conv.id != null) {
  1260. ImChatPage.open(conv.id!);
  1261. }
  1262. }
  1263. }