Преглед изворни кода

1、商品详情跳转的过渡

tags/0.0.2+8
PH2 пре 4 година
родитељ
комит
e80e15f214
4 измењених фајлова са 386 додато и 58 уклоњено
  1. +124
    -48
      lib/util/turn_chain/turn_chain_dialog.dart
  2. +47
    -0
      lib/util/turn_chain/turn_chain_dialog_repository.dart
  3. +172
    -0
      lib/util/turn_chain/turn_chain_style_model.dart
  4. +43
    -10
      lib/util/turn_chain/turn_chain_util.dart

+ 124
- 48
lib/util/turn_chain/turn_chain_dialog.dart Прегледај датотеку

@@ -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),
);
}
}

+ 47
- 0
lib/util/turn_chain/turn_chain_dialog_repository.dart Прегледај датотеку

@@ -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;
}
}

+ 172
- 0
lib/util/turn_chain/turn_chain_style_model.dart Прегледај датотеку

@@ -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;
}
}

+ 43
- 10
lib/util/turn_chain/turn_chain_util.dart Прегледај датотеку

@@ -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];
}


Loading…
Откажи
Сачувај