基础库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

283 lines
11 KiB

  1. import 'dart:io';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter_alibc/alibc_model.dart';
  4. import 'package:flutter_alibc/flutter_alibc.dart';
  5. import 'package:fluttertoast/fluttertoast.dart';
  6. import 'package:jdsdk/jdsdk.dart';
  7. import 'package:url_launcher/url_launcher.dart';
  8. import 'package:zhiying_comm/models/user/user_info_model.dart';
  9. import 'package:zhiying_comm/util/dialog/loading/loading.dart';
  10. import 'package:zhiying_comm/util/empty_util.dart';
  11. import 'package:zhiying_comm/util/global_config.dart';
  12. import 'package:zhiying_comm/util/log/let_log.dart';
  13. import 'package:zhiying_comm/util/net_util.dart';
  14. import 'package:zhiying_comm/util/taobao/taobao_auth.dart';
  15. import 'package:zhiying_comm/util/turn_chain/turn_chain_dialog_repository.dart';
  16. import 'package:zhiying_comm/util/turn_chain/turn_chain_style_model.dart';
  17. import '../router_util.dart';
  18. import 'turn_chain_dialog.dart';
  19. import 'package:zhiying_comm/util/shared_prefe_util.dart';
  20. class TurnChainUtil {
  21. ///
  22. /// 跳转app或者打开url进行领券
  23. /// userInfoModel: 用户登陆的带有token 与 淘宝是否授权的 model类
  24. /// provider: 商品的渠道
  25. /// data: 转链需要的请求参数
  26. ///
  27. /// 一些常用的APP的 URL scheme:
  28. /// 来源:https://blog.csdn.net/jdazy/article/details/79208754
  29. /// QQ: mqq://
  30. /// 微信: weixin://
  31. /// 京东: openapp.jdmobile://
  32. /// 淘宝: taobao://
  33. /// 美团: imeituan://
  34. /// 点评: dianping://
  35. /// 1号店: wccbyihaodian://
  36. /// 支付宝: alipay://
  37. /// 微博: sinaweibo://
  38. /// 腾讯微博: TencentWeibo://
  39. /// weico微博: weico://
  40. /// 知乎: zhihu://
  41. /// 豆瓣fm: doubanradio://
  42. /// 网易公开课: ntesopen://
  43. /// Chrome: googlechrome://
  44. /// QQ浏览器: mqqbrowser://
  45. /// uc浏览器: ucbrowser://
  46. /// 搜狗浏览器: SogouMSE://
  47. /// 百度地图: baidumap:// bdmap://
  48. /// 优酷: youku://
  49. /// 人人: renren://
  50. /// 我查查: wcc://
  51. /// 有道词典: yddictproapp://
  52. /// 微盘: sinavdisk://
  53. /// 名片全能王: camcard://
  54. ///
  55. static Future<void> openReceiveCoupon(BuildContext context, UserInfoModel userInfoModel, String goodsId, String provider, Map<String, dynamic> data, {bool isFree = false}) async {
  56. ///iOS 审核状态
  57. String is_ios_review = await SharedPreferencesUtil.getStringValue(GlobalConfig.IS_IOS_REVIEW, defaultVal: '0');
  58. /// 1、先判断是否登陆
  59. if (EmptyUtil.isEmpty(userInfoModel) || EmptyUtil.isEmpty(userInfoModel?.token)) {
  60. RouterUtil.goLogin(context);
  61. return;
  62. }
  63. /// 2、如果是淘宝或者天猫,判断是否授权
  64. if ((provider == GlobalConfig.PROVIDER_TB || provider == GlobalConfig.PROVIDER_TM )&& !userInfoModel.isTBAuth) {
  65. TaobaoAuth.auth(context);
  66. return;
  67. }
  68. /// 3、获取转链,进行跳转
  69. Map<String, dynamic> result = await getTurnChainResult(context, goodsId, provider, data, isShare: false, isFree: isFree);
  70. if (!EmptyUtil.isEmpty(result)) {
  71. String openAppUrl = result['open_app_url'];
  72. String appUrl = result['app_url'];
  73. String webUrl = result['no_open_app_url'];
  74. /// 4、根据渠道进行不同的跳转
  75. switch (provider) {
  76. case GlobalConfig.PROVIDER_TB:
  77. case GlobalConfig.PROVIDER_TM:
  78. if (!EmptyUtil.isEmpty(openAppUrl)) {
  79. TradeResult tradeResult;
  80. if (Platform.isAndroid) {
  81. // print("跳转链接"+openAppUrl);
  82. tradeResult = await FlutterAlibc.openByUrl(url: openAppUrl, backUrl: "alisdk://");
  83. } else if (Platform.isIOS) {
  84. if (is_ios_review == '1') {
  85. print('iOS审核:' + is_ios_review);
  86. RouterUtil.openWebview(webUrl, context);
  87. } else {
  88. tradeResult = await FlutterAlibc.openByUrl(url: openAppUrl);
  89. }
  90. }
  91. Logger.debug('taobao result = ${tradeResult.errorCode} ${tradeResult.errorMessage} ');
  92. } else if (!EmptyUtil.isEmpty(webUrl)) {
  93. RouterUtil.openWebview(webUrl, context);
  94. } else {
  95. Fluttertoast.cancel();
  96. Fluttertoast.showToast(msg: '购买链接不存在');
  97. }
  98. break;
  99. case GlobalConfig.PROVIDER_JD:
  100. String tempURLScheme1 = 'openapp.jdmobile://virtual?params=%';
  101. String tempURLScheme2 = 'openapp.jdmobile://';
  102. if (!EmptyUtil.isEmpty(openAppUrl) && await canLaunch(tempURLScheme1) || await canLaunch(tempURLScheme2)) {
  103. Jdsdk.openUrl(url: openAppUrl);
  104. } else if (!EmptyUtil.isEmpty(webUrl)) {
  105. RouterUtil.openWebview(webUrl, context);
  106. } else {
  107. Fluttertoast.cancel();
  108. Fluttertoast.showToast(msg: '购买链接不存在');
  109. }
  110. break;
  111. case GlobalConfig.PROVIDER_KL:
  112. case GlobalConfig.PROVIDER_PDD:
  113. case GlobalConfig.PROVIDER_SN:
  114. bool launchable = await canLaunch(appUrl);
  115. if (Platform.isIOS) {
  116. launchable = await launch(appUrl);
  117. }
  118. if (launchable) {
  119. if (!Platform.isIOS) {
  120. if (appUrl.startsWith("suning")) {
  121. RouterUtil.openWebview(webUrl, context);
  122. } else {
  123. RouterUtil.openWebview(webUrl, context);
  124. }
  125. }
  126. } else if (!EmptyUtil.isEmpty(webUrl)) {
  127. Logger.log('打开${provider} webUrl, url = ${webUrl}');
  128. RouterUtil.openWebview(webUrl, context);
  129. } else {
  130. Fluttertoast.cancel();
  131. Fluttertoast.showToast(msg: '购买链接不存在');
  132. }
  133. break;
  134. case GlobalConfig.PROVIDER_VIP:
  135. bool launchable = await canLaunch(appUrl);
  136. if (Platform.isIOS) {
  137. launchable = await launch(appUrl);
  138. }
  139. if (launchable) {
  140. if (!Platform.isIOS) {
  141. await launch(appUrl);
  142. }
  143. } else if (!EmptyUtil.isEmpty(webUrl)) {
  144. Logger.log('打开${provider} webUrl, url = ${webUrl}');
  145. RouterUtil.openWebview(webUrl, context);
  146. } else {
  147. Fluttertoast.cancel();
  148. Fluttertoast.showToast(msg: '购买链接不存在');
  149. }
  150. break;
  151. default:
  152. if (!EmptyUtil.isEmpty(openAppUrl)) {
  153. bool launchable = await canLaunch(appUrl);
  154. if (launchable) {
  155. launchable = await launch(appUrl);
  156. }
  157. if (launchable) {
  158. if (!Platform.isIOS) {
  159. RouterUtil.openWebview(webUrl, context);
  160. }
  161. } else if (!EmptyUtil.isEmpty(webUrl)) {
  162. Logger.log('打开${provider} webUrl, url = ${webUrl}');
  163. RouterUtil.openWebview(webUrl, context);
  164. } else {
  165. Fluttertoast.cancel();
  166. Fluttertoast.showToast(msg: '购买链接不存在');
  167. }
  168. } else {
  169. Fluttertoast.cancel();
  170. Fluttertoast.showToast(msg: '购买链接不存在');
  171. }
  172. break;
  173. }
  174. } else {
  175. Fluttertoast.cancel();
  176. Fluttertoast.showToast(msg: '购买链接不存在');
  177. }
  178. }
  179. ///
  180. /// 获取分享的转链
  181. /// userInfoModel: 用户登陆的带有token 与 淘宝是否授权的 model类
  182. /// provider: 商品的渠道
  183. /// data: 转链需要的请求参数
  184. ///
  185. /// 返回参数: 只需要获取返回结果的 open_app_url 值即可。
  186. /// 例如: Map<String, dynamic> result = await getShareTurnChain(context, _user, provider, data);
  187. /// String buyUrl = result['open_app_url']
  188. ///
  189. static Future<Map<String, dynamic>> getShareTurnChain(BuildContext context, UserInfoModel userInfoModel, String goodsId, String provider, Map<String, dynamic> data) async {
  190. /// 1、先判断是否登陆
  191. if (EmptyUtil.isEmpty(userInfoModel) || EmptyUtil.isEmpty(userInfoModel?.token)) {
  192. RouterUtil.goLogin(context);
  193. return null;
  194. }
  195. /// 2、如果是淘宝,判断是否授权
  196. if (provider == GlobalConfig.PROVIDER_TB && !userInfoModel.isTBAuth) {
  197. TaobaoAuth.auth(context);
  198. return null;
  199. }
  200. /// 3、获取转链的结果
  201. Map<String, dynamic> result = await getTurnChainResult(context, goodsId, provider, data, isShare: true);
  202. if (!EmptyUtil.isEmpty(result) && !EmptyUtil.isEmpty(result['open_app_url'])) {
  203. return result;
  204. }
  205. Fluttertoast.cancel();
  206. Fluttertoast.showToast(msg: '购买链接不存在');
  207. return null;
  208. }
  209. ///
  210. /// 获取跳转的dialog样式
  211. ///
  212. static Future<dynamic> getCacheTurnChainDialogStyle(String goodsId, String provider, String commission, String coupon) async {
  213. TurnChainDialogRepository repository = TurnChainDialogRepository();
  214. var result = await repository.fetchCacheData(goodsId, provider, commission, coupon);
  215. if (!EmptyUtil.isEmpty(result)) {
  216. return result;
  217. }
  218. return null;
  219. }
  220. ///
  221. /// 缓存跳转的dialog样式
  222. ///
  223. static Future<bool> cacheTurnChainDialogStyle(String goodsId, String provider, String commission, String coupon) async {
  224. TurnChainDialogRepository repository = TurnChainDialogRepository();
  225. bool result = await repository.cacheData(goodsId, provider, commission, coupon);
  226. return result;
  227. }
  228. ///
  229. /// 接口文档:https://www.showdoc.com.cn/1003739271891029?page_id=5760575662067820
  230. /// 根据商品id等信息,获取领券或者分享的转链接
  231. ///
  232. ///
  233. static Future<Map<String, dynamic>> getTurnChainResult(BuildContext context, String goodsId, String provider, Map<String, dynamic> data,
  234. {bool isShare = false, bool isFree = false}) async {
  235. try {
  236. TurnChainDialogRepository repository = TurnChainDialogRepository();
  237. if (!EmptyUtil.isEmpty(context) && !EmptyUtil.isEmpty(provider) && !EmptyUtil.isEmpty(data) && !EmptyUtil.isEmpty('gid')) {
  238. TurnChainStyleModel model = await repository.fetchCacheData(goodsId, provider, data['commission'], data['coupon_price']);
  239. // 设置是否分享还是转链
  240. data['is_share'] = isShare ? '1' : '0';
  241. ///1为免单,0为普通
  242. data['is_free'] = (isFree ?? false) ? "1" : "0";
  243. (isFree ?? false) ? print("免单") : print("普通");
  244. if (EmptyUtil.isEmpty(model)) {
  245. // 开启loading
  246. Loading.show(context);
  247. } else {
  248. TurnChainLoading.show(context, model);
  249. }
  250. var result = await NetUtil.post('/api/v1/convert/$provider', params: data, method: NetMethod.POST);
  251. if (EmptyUtil.isEmpty(model)) {
  252. // 关闭loading
  253. Loading.dismiss();
  254. } else {
  255. TurnChainLoading.dismiss();
  256. }
  257. if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
  258. return result[GlobalConfig.HTTP_RESPONSE_KEY_DATA];
  259. }
  260. }
  261. } catch (e, s) {
  262. Logger.error(e, s);
  263. }
  264. return null;
  265. }
  266. }