@@ -1,47 +1,91 @@ | |||
import 'dart:math'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:loading_indicator/loading_indicator.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
/// | |||
/// 转链的过渡动画 | |||
/// | |||
class TurnChainDialog extends StatefulWidget { | |||
@override | |||
_TurnChainDialogState createState() => _TurnChainDialogState(); | |||
import 'turn_chain_style_model.dart'; | |||
class TurnChainLoading { | |||
static OverlayEntry _overlayEntry; | |||
static Future show( | |||
BuildContext context, | |||
TurnChainStyleModel model, | |||
) async { | |||
dismiss(); | |||
_overlayEntry = new OverlayEntry(builder: (context) { | |||
return GestureDetector( | |||
onTap: dismiss, | |||
child: Container( | |||
color: Colors.black.withOpacity(0.3), | |||
child: TurnChainDialogWidget(model), | |||
), | |||
); | |||
}); | |||
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); | |||
} | |||
} | |||
} | |||
class _TurnChainDialogState extends State<TurnChainDialog> { | |||
class TurnChainDialogWidget extends StatelessWidget { | |||
TurnChainStyleModel model; | |||
TurnChainDialogWidget(this.model); | |||
@override | |||
Widget build(BuildContext context) { | |||
return Scaffold( | |||
backgroundColor: Colors.transparent, | |||
body: Center( | |||
child: Container( | |||
height: 250, | |||
width: 260, | |||
// margin: const EdgeInsets.symmetric(horizontal: 70), | |||
padding: const EdgeInsets.all(20), | |||
decoration: BoxDecoration(color: HexColor.fromHex('#FEFFFE'), borderRadius: BorderRadius.circular(13)), | |||
child: Column( | |||
mainAxisAlignment: MainAxisAlignment.center, | |||
crossAxisAlignment: CrossAxisAlignment.center, | |||
children: <Widget>[ | |||
/// 跳转图标 | |||
_buildTransitionIconWidget(), | |||
/// 正在跳转提示文字 | |||
Padding(padding: const EdgeInsets.only(top: 12), child: _buildJumpTipWidget()), | |||
/// 返利和券 | |||
Padding(padding: const EdgeInsets.only(top: 13), child: _buildCouponAndRebateWidget()), | |||
// /// 共省提示 | |||
Padding(padding: const EdgeInsets.only(top: 14), child: _buildSaveMoneyTipWidget()), | |||
/// 注意提示文字 | |||
Padding(padding: const EdgeInsets.only(top: 8, left: 9.5, right: 9.5), child: _buildNoticeWidget()), | |||
], | |||
)), | |||
return WillPopScope( | |||
onWillPop: () { | |||
return Future.value(false); | |||
}, | |||
child: Scaffold( | |||
backgroundColor: HexColor.fromHex('#54555555'), | |||
body: Center( | |||
child: Container( | |||
height: 250, | |||
width: 260, | |||
// margin: const EdgeInsets.symmetric(horizontal: 70), | |||
padding: const EdgeInsets.all(20), | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex('#FEFFFE'), | |||
borderRadius: BorderRadius.circular(13), | |||
), | |||
child: Column( | |||
mainAxisAlignment: MainAxisAlignment.center, | |||
crossAxisAlignment: CrossAxisAlignment.center, | |||
children: <Widget>[ | |||
/// 跳转图标 | |||
_buildTransitionIconWidget(), | |||
/// 正在跳转提示文字 | |||
Padding(padding: const EdgeInsets.only(top: 12), child: _buildJumpTipWidget()), | |||
/// 返利和券 | |||
Padding(padding: const EdgeInsets.only(top: 13), child: _buildCouponAndRebateWidget()), | |||
// /// 共省提示 | |||
Padding(padding: const EdgeInsets.only(top: 14), child: _buildSaveMoneyTipWidget()), | |||
/// 注意提示文字 | |||
Padding(padding: const EdgeInsets.only(top: 8, left: 9.5, right: 9.5), child: _buildNoticeWidget()), | |||
], | |||
)), | |||
), | |||
), | |||
); | |||
} | |||
@@ -58,7 +102,9 @@ class _TurnChainDialogState extends State<TurnChainDialog> { | |||
margin: const EdgeInsets.only(right: 8), | |||
width: 50, | |||
height: 50, | |||
color: Colors.red, | |||
child: CachedNetworkImage( | |||
imageUrl: model?.appLogo ?? '', | |||
), | |||
), | |||
Container( | |||
height: 10, | |||
@@ -77,17 +123,33 @@ class _TurnChainDialogState extends State<TurnChainDialog> { | |||
margin: const EdgeInsets.only(left: 8), | |||
width: 50, | |||
height: 50, | |||
color: Colors.red, | |||
// color: Colors.red, | |||
child: CachedNetworkImage( | |||
imageUrl: _getProviderIcon(), | |||
), | |||
), | |||
], | |||
), | |||
); | |||
} | |||
String _getProviderIcon() { | |||
int length = model?.style?.providerIcons?.length ?? 0; | |||
String result = ''; | |||
if (length > 0) { | |||
model.style.providerIcons.forEach((element) { | |||
if (element.type == model.provider) { | |||
result = element?.img ?? ''; | |||
} | |||
}); | |||
} | |||
return result; | |||
} | |||
/// 跳转文字提示 | |||
Widget _buildJumpTipWidget() { | |||
return Text( | |||
'正在跳转淘宝', | |||
'${model?.style?.text}${model.providerName}', | |||
style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 15, fontWeight: FontWeight.bold), | |||
); | |||
} | |||
@@ -99,9 +161,21 @@ class _TurnChainDialogState extends State<TurnChainDialog> { | |||
child: Row( | |||
mainAxisAlignment: MainAxisAlignment.center, | |||
children: <Widget>[ | |||
_buildCustomButtonWidget(text: '返利', textColor: '#FEFFFE', number: '¥ 23.99', numberColor: '#FEFFFE', bgColor: '#FF2020'), | |||
_buildCustomButtonWidget( | |||
text: model?.style?.leftBtnText ?? '返利', | |||
textColor: model?.style?.leftBtnTextColor ?? '#FEFFFE', | |||
number: !EmptyUtil.isEmpty(model?.commission) ? model?.commission : '0.00', | |||
numberColor: model?.style?.leftBtnTextColor ?? '#FEFFFE', | |||
bgColor: model?.style?.leftBtnColor ?? '#FF2020', | |||
bgImg: model?.style?.leftBtnImg ?? ''), | |||
const SizedBox(width: 8), | |||
_buildCustomButtonWidget(text: '券', textColor: '#FEFFFE', number: '¥ 15.00', numberColor: '#FEFFFE', bgColor: '#FF2020'), | |||
_buildCustomButtonWidget( | |||
text: model?.style?.rightBtnText ?? '券', | |||
textColor: model?.style?.rightBtnTextColor ?? '#FEFFFE', | |||
number: !EmptyUtil.isEmpty(model?.coupon) ? model?.coupon : '0.00', | |||
numberColor: model?.style?.rightBtnTextColor ?? '#FEFFFE', | |||
bgColor: model?.style?.rightBtnColor ?? '#FF2020', | |||
bgImg: model?.style?.rightBtnImg ?? ''), | |||
], | |||
), | |||
); | |||
@@ -124,11 +198,11 @@ class _TurnChainDialogState extends State<TurnChainDialog> { | |||
text: TextSpan(children: [ | |||
TextSpan( | |||
text: text ?? '', | |||
style: TextStyle(color: HexColor.fromHex(textColor)), | |||
style: TextStyle(color: HexColor.fromHex(textColor), fontSize: 13), | |||
), | |||
TextSpan( | |||
text: number ?? '', | |||
style: TextStyle(color: HexColor.fromHex(numberColor)), | |||
style: TextStyle(color: HexColor.fromHex(numberColor), fontFamily: 'Din', package: 'zhiying_base_widget', fontSize: 13), | |||
), | |||
]), | |||
)); | |||
@@ -138,9 +212,11 @@ class _TurnChainDialogState extends State<TurnChainDialog> { | |||
Widget _buildSaveMoneyTipWidget() { | |||
return RichText( | |||
text: TextSpan(children: [ | |||
TextSpan(text: '共省 ¥', style: TextStyle(color: HexColor.fromHex('#FF2020'), fontSize: 13)), | |||
TextSpan(text: '38', style: TextStyle(color: HexColor.fromHex('#FF2020'), fontSize: 18)), | |||
TextSpan(text: '.99', style: TextStyle(color: HexColor.fromHex('#FF2020'), fontSize: 13)), | |||
TextSpan(text: model?.style?.saveMomenyText ?? '共省 ¥', style: TextStyle(color: HexColor.fromHex(model?.style?.saveMomenyColor ?? '#FF2020'), fontSize: 13)), | |||
TextSpan( | |||
text: model?.totalSave ?? '0.00', | |||
style: TextStyle(color: HexColor.fromHex(model?.style?.saveMomenyColor ?? '#FF2020'), fontSize: 18, fontFamily: 'Din', package: 'zhiying_base_widget')), | |||
// TextSpan(text: '.99', style: TextStyle(color: HexColor.fromHex(model?.style?.saveMomenyColor ?? '#FF2020'), fontSize: 13, fontFamily: 'Din', package: 'zhiying_base_widget')), | |||
]), | |||
); | |||
} | |||
@@ -148,11 +224,11 @@ class _TurnChainDialogState extends State<TurnChainDialog> { | |||
/// 注意提示文字提示 | |||
Widget _buildNoticeWidget() { | |||
return Text( | |||
'注意:使用红包下单,会导致收益变少,或没有收益!', | |||
model?.style?.tipText ?? '注意:使用红包下单,会导致收益变少,或没有收益!', | |||
textAlign: TextAlign.center, | |||
maxLines: 2, | |||
overflow: TextOverflow.ellipsis, | |||
style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 11), | |||
style: TextStyle(color: HexColor.fromHex(model?.style?.tipColor ?? '#999999'), fontSize: 11), | |||
); | |||
} | |||
} |
@@ -0,0 +1,47 @@ | |||
import 'package:zhiying_comm/util/turn_chain/turn_chain_style_model.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class TurnChainDialogRepository { | |||
/// | |||
/// 缓存style Data | |||
/// 多加一个goods_id 用于区分数据 | |||
Future<bool> cacheData(String goodsId, String provider, String commission, String coupon) async { | |||
try { | |||
var result = await NetUtil.post( | |||
'/api/v1/detail_transition', | |||
params: {'provider': provider, 'commission': commission, 'coupon_price': coupon, 'goods_id': goodsId}, | |||
method: NetMethod.POST, | |||
cache: true, | |||
); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
Logger.debug('缓存跳转样式成功'); | |||
return true; | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return false; | |||
} | |||
/// | |||
/// 获取缓存的data | |||
/// 多加一个goods_id 用于区分数据 | |||
/// | |||
Future<TurnChainStyleModel> fetchCacheData(String goodsId, String provider, String commission, String coupon) async { | |||
try { | |||
var result = await NetUtil.getRequestCachedData( | |||
'/api/v1/detail_transition', | |||
params: {'provider': provider, 'commission': commission, 'coupon_price': coupon, 'goods_id': goodsId}, | |||
); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
TurnChainStyleModel model = TurnChainStyleModel.fromJson(result); | |||
if (!EmptyUtil.isEmpty(model)) { | |||
return model; | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,172 @@ | |||
import 'dart:convert'; | |||
class TurnChainStyleModel { | |||
String appLogo; | |||
String commission; | |||
String provider; | |||
String providerName; | |||
String coupon; | |||
String totalSave; | |||
// String style; | |||
Style style; | |||
TurnChainStyleModel({ | |||
this.appLogo, | |||
this.commission, | |||
this.provider, | |||
this.providerName, | |||
this.coupon, | |||
this.totalSave, | |||
this.style, | |||
}); | |||
TurnChainStyleModel.fromJson(Map<String, dynamic> json) { | |||
appLogo = json['app_logo']; | |||
commission = json['commission']; | |||
provider = json['provider']; | |||
providerName = json['provider_name']; | |||
coupon = json['coupon']; | |||
totalSave = json['total_save']; | |||
if (null != json['style']) { | |||
style = json['style'] is String ? Style.fromJson(jsonDecode(json['style'])) : Style.fromJson(json['style']); | |||
} | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['app_logo'] = this.appLogo; | |||
data['commission'] = this.commission; | |||
data['provider'] = this.provider; | |||
data['provider_name'] = this.providerName; | |||
data['coupon'] = this.coupon; | |||
data['total_save'] = this.totalSave; | |||
// data['style'] = this.style; | |||
if (null != this.style) { | |||
data['style'] = style.toJson(); | |||
} | |||
return data; | |||
} | |||
} | |||
class Style { | |||
String pointColor; | |||
String point2Color; | |||
String point3Color; | |||
String text; | |||
String textColor; | |||
String leftBtnType; | |||
String leftBtnText; | |||
String leftBtnTextColor; | |||
String leftBtnColor; | |||
String leftBtnImg; | |||
String rightBtnType; | |||
String rightBtnText; | |||
String rightBtnTextColor; | |||
String rightBtnColor; | |||
String rightBtnImg; | |||
String saveMomenyText; | |||
String saveMomenyColor; | |||
String tipText; | |||
String tipColor; | |||
List<ProviderIcons> providerIcons; | |||
Style( | |||
{this.pointColor, | |||
this.point2Color, | |||
this.point3Color, | |||
this.text, | |||
this.textColor, | |||
this.leftBtnType, | |||
this.leftBtnText, | |||
this.leftBtnTextColor, | |||
this.leftBtnColor, | |||
this.leftBtnImg, | |||
this.rightBtnType, | |||
this.rightBtnText, | |||
this.rightBtnTextColor, | |||
this.rightBtnColor, | |||
this.rightBtnImg, | |||
this.saveMomenyText, | |||
this.saveMomenyColor, | |||
this.tipText, | |||
this.tipColor, | |||
this.providerIcons}); | |||
Style.fromJson(Map<String, dynamic> json) { | |||
pointColor = json['point_color']; | |||
point2Color = json['point2_color']; | |||
point3Color = json['point3_color']; | |||
text = json['text']; | |||
textColor = json['text_color']; | |||
leftBtnType = json['left_btn_type']; | |||
leftBtnText = json['left_btn_text']; | |||
leftBtnTextColor = json['left_btn_text_color']; | |||
leftBtnColor = json['left_btn_color']; | |||
leftBtnImg = json['left_btn_img']; | |||
rightBtnType = json['right_btn_type']; | |||
rightBtnText = json['right_btn_text']; | |||
rightBtnTextColor = json['right_btn_text_color']; | |||
rightBtnColor = json['right_btn_color']; | |||
rightBtnImg = json['right_btn_img']; | |||
saveMomenyText = json['save_momeny_text']; | |||
saveMomenyColor = json['save_momeny_color']; | |||
tipText = json['tip_text']; | |||
tipColor = json['tip_color']; | |||
if (json['provider_icons'] != null) { | |||
providerIcons = new List<ProviderIcons>(); | |||
json['provider_icons'].forEach((v) { | |||
providerIcons.add(new ProviderIcons.fromJson(v)); | |||
}); | |||
} | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['point_color'] = this.pointColor; | |||
data['point2_color'] = this.point2Color; | |||
data['point3_color'] = this.point3Color; | |||
data['text'] = this.text; | |||
data['text_color'] = this.textColor; | |||
data['left_btn_type'] = this.leftBtnType; | |||
data['left_btn_text'] = this.leftBtnText; | |||
data['left_btn_text_color'] = this.leftBtnTextColor; | |||
data['left_btn_color'] = this.leftBtnColor; | |||
data['left_btn_img'] = this.leftBtnImg; | |||
data['right_btn_type'] = this.rightBtnType; | |||
data['right_btn_text'] = this.rightBtnText; | |||
data['right_btn_text_color'] = this.rightBtnTextColor; | |||
data['right_btn_color'] = this.rightBtnColor; | |||
data['right_btn_img'] = this.rightBtnImg; | |||
data['save_momeny_text'] = this.saveMomenyText; | |||
data['save_momeny_color'] = this.saveMomenyColor; | |||
data['tip_text'] = this.tipText; | |||
data['tip_color'] = this.tipColor; | |||
if (this.providerIcons != null) { | |||
data['provider_icons'] = this.providerIcons.map((v) => v.toJson()).toList(); | |||
} | |||
return data; | |||
} | |||
} | |||
class ProviderIcons { | |||
String type; | |||
String name; | |||
String img; | |||
ProviderIcons({this.type, this.name, this.img}); | |||
ProviderIcons.fromJson(Map<String, dynamic> json) { | |||
type = json['type']; | |||
name = json['name']; | |||
img = json['img']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['type'] = this.type; | |||
data['name'] = this.name; | |||
data['img'] = this.img; | |||
return data; | |||
} | |||
} |
@@ -13,8 +13,11 @@ 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:zhiying_comm/util/turn_chain/turn_chain_dialog_repository.dart'; | |||
import 'package:zhiying_comm/util/turn_chain/turn_chain_style_model.dart'; | |||
import '../router_util.dart'; | |||
import 'turn_chain_dialog.dart'; | |||
class TurnChainUtil { | |||
/// | |||
@@ -51,7 +54,7 @@ class TurnChainUtil { | |||
/// 微盘: sinavdisk:// | |||
/// 名片全能王: camcard:// | |||
/// | |||
static Future<void> openReceiveCoupon(BuildContext context, UserInfoModel userInfoModel, String provider, Map<String, dynamic> data) async { | |||
static Future<void> openReceiveCoupon(BuildContext context, UserInfoModel userInfoModel, String goodsId, String provider, Map<String, dynamic> data) async { | |||
/// 1、先判断是否登陆 | |||
if (EmptyUtil.isEmpty(userInfoModel) || EmptyUtil.isEmpty(userInfoModel?.token)) { | |||
RouterUtil.goLogin(context); | |||
@@ -65,7 +68,7 @@ class TurnChainUtil { | |||
} | |||
/// 3、获取转链,进行跳转 | |||
Map<String, dynamic> result = await getTurnChainResult(context, provider, data, isShare: false); | |||
Map<String, dynamic> result = await getTurnChainResult(context, goodsId, provider, data, isShare: false); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
String openAppUrl = result['open_app_url']; | |||
String appUrl = result['app_url']; | |||
@@ -140,7 +143,7 @@ class TurnChainUtil { | |||
/// 例如: 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 { | |||
static Future<Map<String, dynamic>> getShareTurnChain(BuildContext context, UserInfoModel userInfoModel, String goodsId, String provider, Map<String, dynamic> data) async { | |||
/// 1、先判断是否登陆 | |||
if (EmptyUtil.isEmpty(userInfoModel) || EmptyUtil.isEmpty(userInfoModel?.token)) { | |||
RouterUtil.goLogin(context); | |||
@@ -154,7 +157,7 @@ class TurnChainUtil { | |||
} | |||
/// 3、获取转链的结果 | |||
Map<String, dynamic> result = await getTurnChainResult(context, provider, data, isShare: true); | |||
Map<String, dynamic> result = await getTurnChainResult(context, goodsId, provider, data, isShare: true); | |||
if (!EmptyUtil.isEmpty(result) && !EmptyUtil.isEmpty(result['open_app_url'])) { | |||
return result; | |||
} | |||
@@ -163,22 +166,52 @@ class TurnChainUtil { | |||
return null; | |||
} | |||
/// | |||
/// 获取跳转的dialog样式 | |||
/// | |||
static Future<dynamic> getCacheTurnChainDialogStyle(String goodsId, String provider, String commission, String coupon) async { | |||
TurnChainDialogRepository repository = TurnChainDialogRepository(); | |||
var result = await repository.fetchCacheData(goodsId, provider, commission, coupon); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
return result; | |||
} | |||
return null; | |||
} | |||
/// | |||
/// 缓存跳转的dialog样式 | |||
/// | |||
static Future<bool> cacheTurnChainDialogStyle(String goodsId, String provider, String commission, String coupon) async { | |||
TurnChainDialogRepository repository = TurnChainDialogRepository(); | |||
bool result = await repository.cacheData(goodsId, provider, commission, coupon); | |||
return result; | |||
} | |||
/// | |||
/// 接口文档: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 { | |||
static Future<Map<String, dynamic>> getTurnChainResult(BuildContext context, String goodsId, String provider, Map<String, dynamic> data, {bool isShare = false}) async { | |||
try { | |||
TurnChainDialogRepository repository = TurnChainDialogRepository(); | |||
if (!EmptyUtil.isEmpty(context) && !EmptyUtil.isEmpty(provider) && !EmptyUtil.isEmpty(data) && !EmptyUtil.isEmpty('gid')) { | |||
TurnChainStyleModel model = await repository.fetchCacheData(goodsId, provider, data['commission'], data['coupon_price']); | |||
// 设置是否分享还是转链 | |||
data['is_share'] = isShare ? '1' : '0'; | |||
// 开启loading | |||
Loading.show(context); | |||
if (EmptyUtil.isEmpty(model)) { | |||
// 开启loading | |||
Loading.show(context); | |||
} else { | |||
TurnChainLoading.show(context, model); | |||
} | |||
var result = await NetUtil.post('/api/v1/convert/$provider', params: data, method: NetMethod.POST); | |||
// 关闭loading | |||
Loading.dismiss(); | |||
if (EmptyUtil.isEmpty(model)) { | |||
// 关闭loading | |||
Loading.dismiss(); | |||
} else { | |||
TurnChainLoading.dismiss(); | |||
} | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
return result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]; | |||
} | |||