@@ -24,7 +24,7 @@ class UserInfoModel { | |||
mobile = json['mobile']; | |||
perms = json['perms']?.cast<String>(); | |||
registerInviteCodeEnable = json['register_invite_code_enable']; | |||
isTBAuth = json['isTBAuth']; | |||
isTBAuth = json['isTBAuth'] ?? false; | |||
} | |||
Map<String, dynamic> toJson() { | |||
@@ -0,0 +1,43 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'loading_dialog.dart'; | |||
// loading弹窗 | |||
class Loading { | |||
static OverlayEntry _overlayEntry; | |||
static Future show( | |||
BuildContext context, { | |||
String msg, | |||
}) async { | |||
dismiss(); | |||
_overlayEntry = new OverlayEntry(builder: (context) { | |||
return GestureDetector( | |||
onTap: dismiss, | |||
child: Container( | |||
color: Colors.black.withOpacity(0.3), | |||
child: LoadingDialog( | |||
message: msg, | |||
), | |||
), | |||
); | |||
}); | |||
try { | |||
//插入到 Overlay中显示 OverlayEntry | |||
Overlay.of(context).insert(_overlayEntry); | |||
}catch(e, s){ | |||
Logger.error(e, s); | |||
} | |||
} | |||
static dismiss() { | |||
try { | |||
_overlayEntry?.remove(); | |||
_overlayEntry = null; | |||
}catch(e, s){ | |||
Logger.error(e, s); | |||
} | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:loading_indicator/loading_indicator.dart'; | |||
import 'loading.dart'; | |||
class LoadingDialog extends StatelessWidget { | |||
final String message; | |||
const LoadingDialog({Key key, this.message}) : super(key: key); | |||
@override | |||
Widget build(BuildContext context) { | |||
return GestureDetector( | |||
onTap: () { | |||
Loading.dismiss(); | |||
}, | |||
child: Scaffold( | |||
backgroundColor: Colors.transparent, | |||
body: Center( | |||
child: UnconstrainedBox( | |||
child: Container( | |||
padding: EdgeInsets.all(10), | |||
decoration: BoxDecoration( | |||
color: Colors.transparent, borderRadius: BorderRadius.circular(8)), | |||
child: Column( | |||
crossAxisAlignment: CrossAxisAlignment.center, | |||
mainAxisAlignment: MainAxisAlignment.center, | |||
children: <Widget>[ | |||
Container( | |||
width: 40, | |||
height: 40, | |||
child: LoadingIndicator( | |||
indicatorType: Indicator.ballSpinFadeLoader, | |||
color: Colors.white, | |||
), | |||
), | |||
message == null || message == '' | |||
? Container() | |||
: Container( | |||
margin: EdgeInsets.only(top: 8), | |||
child: Text( | |||
message, | |||
style: TextStyle(fontSize: 14), | |||
), | |||
), | |||
], | |||
), | |||
), | |||
), | |||
), | |||
), | |||
); | |||
} | |||
} |
@@ -11,13 +11,13 @@ class GlobalConfig { | |||
static final String SKIP_IDENTIFIER = 'skip_identifier'; | |||
/// ====================== 各个渠道的key ====================== /// | |||
static final String PROVIDER_TB = 'taobao'; // 淘宝 | |||
static final String PROVIDER_TM = 'tianmao'; // 天猫 | |||
static final String PROVIDER_JD = 'jd'; // 京东 | |||
static final String PROVIDER_KL = 'kaola'; // 考拉 | |||
static final String PROVIDER_VIP = 'vip'; // 唯品会 | |||
static final String PROVIDER_SN = 'suning'; // 苏宁 | |||
static final String PROVIDER_PDD = 'pdd'; // 拼多多 | |||
static const String PROVIDER_TB = 'taobao'; // 淘宝 | |||
static const String PROVIDER_TM = 'tianmao'; // 天猫 | |||
static const String PROVIDER_JD = 'jd'; // 京东 | |||
static const String PROVIDER_KL = 'kaola'; // 考拉 | |||
static const String PROVIDER_VIP = 'vip'; // 唯品会 | |||
static const String PROVIDER_SN = 'suning'; // 苏宁 | |||
static const String PROVIDER_PDD = 'pdd'; // 拼多多 | |||
/// ====================== Shared_prefe_key ====================== /// | |||
/// 用户token | |||
@@ -8,54 +8,67 @@ typedef Widget CreatePage(Map<String, dynamic> model); | |||
class PageFactory { | |||
static Map<String, CreatePage> pageCreater = Map(); | |||
/** | |||
* @description: 注册路由 | |||
/** | |||
* @description: 注册路由 | |||
* @param {name} SkipUIIdentifier | |||
* @return: | |||
* @return: | |||
*/ | |||
static void regist(String name, CreatePage creater) { | |||
if (pageCreater.containsKey(name)) { | |||
return; | |||
} | |||
pageCreater[name] = creater; | |||
} | |||
/** | |||
* @description: 创建页面 | |||
* @param {String} name注册的SkipUIIdentifier | |||
* @return: | |||
* @return: | |||
*/ | |||
static Widget create(String name, Map<String, dynamic> model) { | |||
if (pageCreater.containsKey(name)) { | |||
return pageCreater[name](model); | |||
} | |||
// ⚠️ 由于使用了跳转标志带有后缀,所以需要判断是否带有后缀,如果带有并且是数字,则清除后缀获取page | |||
String tempName = _getSkipSuffix(name); | |||
if (!EmptyUtil.isEmpty(tempName) && pageCreater.containsKey(tempName)) { | |||
return pageCreater[tempName](model); | |||
} | |||
return EmptyPage(); | |||
} | |||
// ⚠️ 由于使用了跳转标志带有后缀,所以需要判断是否带有后缀,如果带有并且是数字,则清除后缀获取page | |||
static String _getSkipSuffix(String name) { | |||
String tempName; | |||
try{ | |||
try { | |||
String suffixStr = name.substring(name.lastIndexOf('.') + 1, name.length); | |||
tempName = name.substring(0, name.lastIndexOf('.')); | |||
Logger.log('sufix = $suffixStr , prefix = $tempName'); | |||
int suffixNum = int.parse(suffixStr); | |||
Logger.log('suffixNum = $suffixNum}'); | |||
}catch(e){ | |||
} catch (e) { | |||
tempName = null; | |||
Logger.debug(e); | |||
} | |||
if(!EmptyUtil.isEmpty(tempName) && pageCreater.containsKey(tempName)){ | |||
return pageCreater[tempName](model); | |||
} | |||
return EmptyPage(); | |||
return tempName; | |||
} | |||
/** | |||
/** | |||
* @description: 是否注册页面 | |||
* @param {bool} | |||
* @return: | |||
* @param {bool} | |||
* @return: | |||
*/ | |||
static bool hasRegisted(String name) { | |||
return pageCreater.containsKey(name); | |||
if (pageCreater.containsKey(name)) { | |||
return true; | |||
} | |||
String tempName = _getSkipSuffix(name); | |||
if (pageCreater.containsKey(tempName)) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
} |
@@ -0,0 +1,150 @@ | |||
import 'dart:io'; | |||
import 'package:flutter/cupertino.dart'; | |||
import 'package:flutter_alibc/alibc_model.dart'; | |||
import 'package:flutter_alibc/flutter_alibc.dart'; | |||
import 'package:jdsdk/jdsdk.dart'; | |||
import 'package:url_launcher/url_launcher.dart'; | |||
import 'package:zhiying_comm/models/user/user_info_model.dart'; | |||
import 'package:zhiying_comm/util/dialog/loading/loading.dart'; | |||
import 'package:zhiying_comm/util/empty_util.dart'; | |||
import 'package:zhiying_comm/util/global_config.dart'; | |||
import 'package:zhiying_comm/util/log/let_log.dart'; | |||
import 'package:zhiying_comm/util/net_util.dart'; | |||
import 'package:zhiying_comm/util/taobao/taobao_auth.dart'; | |||
import 'package:fluttertoast/fluttertoast.dart'; | |||
import '../router_util.dart'; | |||
class TurnChainUtil { | |||
/// | |||
/// 跳转app或者打开url进行领券 | |||
/// userInfoModel: 用户登陆的带有token 与 淘宝是否授权的 model类 | |||
/// provider: 商品的渠道 | |||
/// data: 转链需要的请求参数 | |||
/// | |||
static Future<void> openReceiveCoupon(BuildContext context, UserInfoModel userInfoModel, String provider, Map<String, dynamic> data) async { | |||
/// 1、先判断是否登陆 | |||
if (EmptyUtil.isEmpty(userInfoModel) || EmptyUtil.isEmpty(userInfoModel?.token)) { | |||
RouterUtil.goLogin(context); | |||
return; | |||
} | |||
/// 2、如果是淘宝,判断是否授权 | |||
if (provider == GlobalConfig.PROVIDER_TB && !userInfoModel.isTBAuth) { | |||
TaobaoAuth.auth(context); | |||
return; | |||
} | |||
/// 3、获取转链,进行跳转 | |||
Map<String, dynamic> result = await getTurnChainResult(context, provider, data, isShare: false); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
String openAppUrl = result['open_app_url']; | |||
String appUrl = result['app_url']; | |||
String webUrl = result['no_open_app_url']; | |||
/// 4、根据渠道进行不同的跳转 | |||
switch (provider) { | |||
case GlobalConfig.PROVIDER_TB: | |||
case GlobalConfig.PROVIDER_TM: | |||
if (!EmptyUtil.isEmpty(openAppUrl)) { | |||
TradeResult tradeResult; | |||
if (Platform.isAndroid) { | |||
tradeResult = await FlutterAlibc.openByUrl(url: openAppUrl, backUrl: "alisdk://"); | |||
} else if (Platform.isIOS) { | |||
tradeResult = await FlutterAlibc.openByUrl(url: openAppUrl); | |||
} | |||
Logger.debug('taobao result = ${tradeResult.errorCode} ${tradeResult.errorMessage} '); | |||
} else if (!EmptyUtil.isEmpty(webUrl)) { | |||
RouterUtil.openWebview(webUrl, context); | |||
} else { | |||
Fluttertoast.showToast(msg: '购买链接不存在'); | |||
} | |||
break; | |||
case GlobalConfig.PROVIDER_JD: | |||
if (!EmptyUtil.isEmpty(openAppUrl) && !EmptyUtil.isEmpty(appUrl) && await canLaunch(appUrl)) { | |||
Jdsdk.openUrl(url: openAppUrl); | |||
} else if (!EmptyUtil.isEmpty(webUrl)) { | |||
RouterUtil.openWebview(webUrl, context); | |||
} else { | |||
Fluttertoast.showToast(msg: '购买链接不存在'); | |||
} | |||
break; | |||
case GlobalConfig.PROVIDER_KL: | |||
case GlobalConfig.PROVIDER_PDD: | |||
case GlobalConfig.PROVIDER_SN: | |||
case GlobalConfig.PROVIDER_VIP: | |||
if (!EmptyUtil.isEmpty(appUrl) && await canLaunch(appUrl)) { | |||
Logger.log('打开${provider} app, url = ${appUrl}'); | |||
launch(appUrl); | |||
} else if (!EmptyUtil.isEmpty(webUrl)) { | |||
Logger.log('打开${provider} webUrl, url = ${webUrl}'); | |||
RouterUtil.openWebview(webUrl, context); | |||
} else { | |||
Fluttertoast.showToast(msg: '购买链接不存在'); | |||
} | |||
break; | |||
} | |||
} else { | |||
Fluttertoast.showToast(msg: '购买链接不存在'); | |||
} | |||
} | |||
/// | |||
/// 获取分享的转链 | |||
/// userInfoModel: 用户登陆的带有token 与 淘宝是否授权的 model类 | |||
/// provider: 商品的渠道 | |||
/// data: 转链需要的请求参数 | |||
/// | |||
/// 返回参数: 只需要获取返回结果的 open_app_url 值即可。 | |||
/// 例如: Map<String, dynamic> result = await getShareTurnChain(context, _user, provider, data); | |||
/// String buyUrl = result['open_app_url'] | |||
/// | |||
static Future<Map<String, dynamic>> getShareTurnChain(BuildContext context, UserInfoModel userInfoModel, String provider, Map<String, dynamic> data) async { | |||
/// 1、先判断是否登陆 | |||
if (EmptyUtil.isEmpty(userInfoModel) || EmptyUtil.isEmpty(userInfoModel?.token)) { | |||
RouterUtil.goLogin(context); | |||
return null; | |||
} | |||
/// 2、如果是淘宝,判断是否授权 | |||
if (provider == GlobalConfig.PROVIDER_TB && !userInfoModel.isTBAuth) { | |||
TaobaoAuth.auth(context); | |||
return null; | |||
} | |||
/// 3、获取转链的结果 | |||
Map<String, dynamic> result = await getTurnChainResult(context, provider, data, isShare: true); | |||
if (!EmptyUtil.isEmpty(result) && !EmptyUtil.isEmpty(result['open_app_url'])) { | |||
return result; | |||
} | |||
Fluttertoast.showToast(msg: '购买链接不存在'); | |||
return null; | |||
} | |||
/// | |||
/// 接口文档:https://www.showdoc.com.cn/1003739271891029?page_id=5760575662067820 | |||
/// 根据商品id等信息,获取领券或者分享的转链接 | |||
/// | |||
/// | |||
static Future<Map<String, dynamic>> getTurnChainResult(BuildContext context, String provider, Map<String, dynamic> data, {bool isShare = false}) async { | |||
try { | |||
if (!EmptyUtil.isEmpty(context) && !EmptyUtil.isEmpty(provider) && !EmptyUtil.isEmpty(data) && !EmptyUtil.isEmpty('gid')) { | |||
// 设置是否分享还是转链 | |||
data['is_share'] = isShare ? '1' : '0'; | |||
// 开启loading | |||
Loading.show(context); | |||
var result = await NetUtil.post('/api/v1/convert/$provider', params: data, method: NetMethod.POST); | |||
// 关闭loading | |||
Loading.dismiss(); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
return result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]; | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
} |
@@ -44,6 +44,7 @@ dependencies: | |||
ref: 0.0.3 | |||
url: http://192.168.0.138:3000/FnuoOS_ZhiYing/zhiying_flutter_alibc.git | |||
url_launcher: ^5.6.0 | |||
loading_indicator: ^1.2.0 | |||
dev_dependencies: | |||