diff --git a/lib/constants/api.dart b/lib/constants/api.dart index 9d28e97..0e7f5f9 100644 --- a/lib/constants/api.dart +++ b/lib/constants/api.dart @@ -166,6 +166,9 @@ class UserApi { ///注销账号 static const String deleteAccount = "/v1/users/profile/userDestroy"; + + ///会员信息 + static const String userInfo = '/v2/app/command/user/info'; } class GoodsApi { diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index 024b983..8a398e7 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -11,10 +11,12 @@ import 'dart:collection'; import 'dart:convert'; import 'dart:io'; import 'package:amap_location_fluttify/amap_location_fluttify.dart'; +import 'package:clipboard_listener/clipboard_listener.dart'; import 'package:dio/dio.dart'; import 'package:extended_image/extended_image.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:recook/base/base_store_state.dart'; @@ -49,6 +51,7 @@ import 'package:recook/utils/app_router.dart'; import 'package:recook/utils/color_util.dart'; import 'package:recook/utils/custom_route.dart'; import 'package:recook/utils/permission_tool.dart'; +import 'package:recook/utils/rui_code_util.dart'; import 'package:recook/utils/share_tool.dart'; import 'package:recook/widgets/alert.dart'; import 'package:recook/widgets/banner.dart'; @@ -136,6 +139,81 @@ class _HomePageState extends BaseStoreState _handleOpenInstallEvents(); } + ///监听剪切板 + _clipboardListener() async { + String rawData = (await Clipboard.getData(Clipboard.kTextPlain)).text; + bool isRUICode = RUICodeUtil.isCode(rawData); + RUICodeModel model = RUICodeUtil.decrypt(rawData); + //瑞口令 + if (isRUICode) { + showDialog( + context: context, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Material( + color: Colors.transparent, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(rSize(9)), + ), + margin: EdgeInsets.symmetric(horizontal: rSize(50)), + padding: EdgeInsets.all(rSize(10)), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [], + ), + // FadeInImage.assetNetwork( + // placeholder: R.ASSETS_PLACEHOLDER_NEW_1X1_A_PNG, + // image: '', + // height: rSize(256), + // fit: BoxFit.cover, + // ), + Text( + '给你分享了商品', + style: TextStyle( + color: Color(0xFF666666), + fontSize: rSP(12), + ), + ), + MaterialButton( + shape: StadiumBorder(), + onPressed: () { + CRoute.pushReplace( + context, + CommodityDetailPage( + arguments: CommodityDetailPage.setArguments( + model.goodsId, + ), + )); + }, + height: rSize(36), + minWidth: rSize(235), + padding: EdgeInsets.zero, + color: Color(0xFFDB2D2D), + child: Text( + '查看详情', + style: TextStyle( + color: Colors.white, + ), + ), + ), + ], + ), + ), + ), + Icon(CupertinoIcons.clear_circled), + ], + ), + ), + ); + } + } + @override void initState() { super.initState(); @@ -146,6 +224,8 @@ class _HomePageState extends BaseStoreState // meiqia注册 MQManager.initial(); ShareTool.init(); + //监听剪切板 + ClipboardListener.addListener(_clipboardListener); // _backgroundColor = AppColor.themeColor; _homeCountdownController = HomeCountdownController(); @@ -240,6 +320,7 @@ class _HomePageState extends BaseStoreState void dispose() { _tabController.dispose(); WidgetsBinding.instance.removeObserver(this); + ClipboardListener.removeListener(_clipboardListener); super.dispose(); } diff --git a/lib/pages/tabBar/TabbarWidget.dart b/lib/pages/tabBar/TabbarWidget.dart index 3b4acd1..347869f 100644 --- a/lib/pages/tabBar/TabbarWidget.dart +++ b/lib/pages/tabBar/TabbarWidget.dart @@ -7,7 +7,9 @@ * ==================================================== */ import 'package:extended_text/extended_text.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:oktoast/oktoast.dart'; import 'package:recook/constants/api.dart'; import 'package:recook/constants/config.dart'; @@ -15,7 +17,10 @@ import 'package:recook/constants/header.dart'; import 'package:recook/constants/styles.dart'; import 'package:recook/manager/http_manager.dart'; import 'package:recook/manager/user_manager.dart'; +import 'package:recook/models/goods_detail_model.dart'; import 'package:recook/pages/agreements/live_agreement_page.dart'; +import 'package:recook/pages/home/classify/commodity_detail_page.dart'; +import 'package:recook/pages/home/classify/mvp/goods_detail_model_impl.dart'; import 'package:recook/pages/home/home_page.dart'; import 'package:recook/pages/home/widget/goods_hot_list_page.dart'; import 'package:recook/pages/live/functions/live_function.dart'; @@ -32,11 +37,13 @@ import 'package:recook/utils/app_router.dart'; import 'package:recook/utils/custom_route.dart'; import 'package:recook/utils/permission_tool.dart'; import 'package:recook/utils/print_util.dart'; +import 'package:recook/utils/rui_code_util.dart'; import 'package:recook/utils/versionInfo/version_tool.dart'; import 'package:recook/widgets/alert.dart'; import 'package:recook/widgets/cache_tab_bar_view.dart'; import 'package:recook/widgets/custom_image_button.dart'; import 'package:recook/widgets/tabbarWidget/ace_bottom_navigation_bar.dart'; +import 'package:recook/widgets/toast.dart'; class TabBarWidget extends StatefulWidget { @override @@ -294,6 +301,186 @@ class BottomBar extends StatefulWidget { class _BottomBarState extends State { Color selectedColor = AppColor.themeColor; Color unSelectedColor = Colors.black; + Future _getDetail(int goodsId) async { + GoodsDetailModel _goodsDetail = await GoodsDetailModelImpl.getDetailInfo( + goodsId, UserManager.instance.user.info.id); + if (_goodsDetail.code != HttpStatus.SUCCESS) { + Toast.showError(_goodsDetail.msg); + return null; + } + return _goodsDetail; + } + + Future _getUserInfo(int id) async { + return await HttpManager.post(UserApi.userInfo, {'userId': id}); + } + + _clipboardListener() async { + String rawData = (await Clipboard.getData(Clipboard.kTextPlain)).text; + bool isRUICode = RUICodeUtil.isCode(rawData); + GoodsDetailModel goodsDetailModel; + + //瑞口令 + if (isRUICode) { + RUICodeModel model = RUICodeUtil.decrypt(rawData); + + goodsDetailModel = await _getDetail(model.goodsId); + //user info + String userImg = ''; + String userName = ''; + ResultData resultData = await _getUserInfo(model.userId); + if (resultData.data != null && resultData.data['data'] != null) { + userImg = resultData.data['data']['headImgUrl']; + userName = resultData.data['data']['nickname']; + } + if (goodsDetailModel != null) + showDialog( + context: context, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Material( + color: Colors.transparent, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(rSize(9)), + ), + margin: EdgeInsets.symmetric(horizontal: rSize(50)), + padding: EdgeInsets.all(rSize(10)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Material( + clipBehavior: Clip.antiAlias, + color: Colors.white, + borderRadius: BorderRadius.circular(rSize(17)), + child: FadeInImage.assetNetwork( + placeholder: R.ASSETS_PLACEHOLDER_NEW_1X1_A_PNG, + image: Api.getImgUrl(userImg), + height: rSize(34), + width: rSize(34), + fit: BoxFit.cover, + ), + ), + rWBox(8), + Expanded( + child: Text( + userName ?? '', + style: TextStyle( + color: Colors.black, + fontSize: rSP(14), + ), + ), + ), + ], + ), + rHBox(4), + Text( + '给你分享了商品', + style: TextStyle( + color: Color(0xFF666666), + fontSize: rSP(12), + ), + ), + rHBox(4), + Material( + color: Colors.black12, + borderRadius: BorderRadius.circular(rSize(8)), + child: FadeInImage.assetNetwork( + placeholder: R.ASSETS_PLACEHOLDER_NEW_1X1_A_PNG, + image: Api.getImgUrl( + goodsDetailModel.data.mainPhotos.first.url), + height: rSize(256), + fit: BoxFit.cover, + ), + ), + rHBox(10), + Row( + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + Text( + '¥', + style: TextStyle( + color: Color(0xFFE13327), + fontSize: rSP(14), + ), + ), + Text( + '${goodsDetailModel.data.price.max.discountPrice.toStringAsFixed(2)}', + style: TextStyle( + color: Color(0xFFE13327), + fontSize: rSP(18), + ), + ), + Text( + '/赚${goodsDetailModel.data.price.max.commission.toStringAsFixed(1)}', + style: TextStyle( + color: Color(0xFFE13327), + fontSize: rSP(10), + ), + ), + ], + ), + rHBox(4), + Text( + goodsDetailModel.data.goodsName, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(), + ), + Center( + child: MaterialButton( + elevation: 0, + shape: StadiumBorder(), + onPressed: () { + CRoute.pushReplace( + context, + CommodityDetailPage( + arguments: CommodityDetailPage.setArguments( + model.goodsId, + ), + )); + }, + height: rSize(36), + minWidth: rSize(235), + padding: EdgeInsets.zero, + color: Color(0xFFDB2D2D), + child: Text( + '查看详情', + style: TextStyle( + color: Colors.white, + ), + ), + ), + ), + ], + ), + ), + ), + rHBox(30), + GestureDetector( + onTap: () => Navigator.pop(context), + child: Material( + color: Colors.transparent, + child: Icon( + CupertinoIcons.clear_circled, + size: rSize(40), + color: Colors.white, + ), + ), + ), + ], + ), + ), + ); + } + } @override void initState() { @@ -374,6 +561,9 @@ class _BottomBarState extends State { ) ], onTabChangedListener: (index) { + if (index == 0) { + _clipboardListener(); + } print(" $index"); if (widget.tabChangeListener != null) { // if ((index == 4 || index == 5) && !UserManager.instance.haveLogin) { diff --git a/lib/utils/rui_code_util.dart b/lib/utils/rui_code_util.dart index e2758ee..2f65512 100644 --- a/lib/utils/rui_code_util.dart +++ b/lib/utils/rui_code_util.dart @@ -19,12 +19,12 @@ class RUICodeUtil { } static bool isCode(String value) { - return value.contains(RegExp('¥¥[a-zA-z0-9]*¥¥瑞库客')); + return value.contains(RegExp('¥¥[a-zA-z0-9]*¥¥')); } ///瑞口令解密 static RUICodeModel decrypt(String value) { - String temp = value.split('¥¥')[value.indexOf('¥¥') + 1]; + String temp = value.split('¥¥')[1]; List raw = temp.split(RegExp('(Z|X|C|V|B|N|M)')); int goodsId = _string2Num(raw[0]); int userId = _string2Num(raw[1]); @@ -54,8 +54,8 @@ class RUICodeUtil { List tempList = value.split(''); int count = 0; while (tempList.isNotEmpty) { + result += secureStr.indexOf(tempList.last) * pow(secureStr.length, count); count++; - result += secureStr.indexOf(tempList.last) * count * secureStr.length; tempList.removeLast(); } return result; diff --git a/lib/utils/share_tool.dart b/lib/utils/share_tool.dart index c80a183..c3878c1 100644 --- a/lib/utils/share_tool.dart +++ b/lib/utils/share_tool.dart @@ -300,6 +300,7 @@ class ShareTool { ), itemClick: () async { Navigator.pop(context); + print(goodsId); String code = '【$miniTitle】复制这段描述,打开瑞库客,购全球好物${RUICodeUtil.encrypt( int.parse(goodsId), UserManager.instance.user.info.id, diff --git a/pubspec.lock b/pubspec.lock index 66f9dd2..6272a75 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -162,6 +162,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" + clipboard_listener: + dependency: "direct main" + description: + name: clipboard_listener + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.0" clock: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4bcce29..b1941d9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -221,6 +221,7 @@ dependencies: pin_input_text_field: ^3.3.0 device_info: ^1.0.0 + clipboard_listener: ^1.0.0 dev_dependencies: flutter_test: