feat:调通微信支付

This commit is contained in:
anfe 2024-06-07 11:12:45 +08:00
parent e7d5fa9f13
commit ed12b39f5b
9 changed files with 97 additions and 116 deletions

View File

@ -14,6 +14,7 @@ import 'package:star_lock/tools/appFirstEnterHandle.dart';
import 'package:star_lock/tools/app_manager.dart'; import 'package:star_lock/tools/app_manager.dart';
import 'package:star_lock/tools/bindings/app_binding.dart'; import 'package:star_lock/tools/bindings/app_binding.dart';
import 'package:star_lock/tools/customer_tool.dart'; import 'package:star_lock/tools/customer_tool.dart';
import 'package:star_lock/tools/pay/wx_pay_tool.dart';
import 'package:star_lock/tools/storage.dart'; import 'package:star_lock/tools/storage.dart';
import 'package:star_lock/translations/app_dept.dart'; import 'package:star_lock/translations/app_dept.dart';
@ -117,7 +118,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
getPages: AppRouters.routePages, getPages: AppRouters.routePages,
builder: EasyLoading.init(), builder: EasyLoading.init(),
initialBinding: AppBindings(), initialBinding: AppBindings(),
initialRoute: initialRoute ); initialRoute: initialRoute);
} }
@override @override
@ -178,4 +179,5 @@ Future<void> getAgreePrivacyShowUpdate() async {
Future<void> getAppInfo() async { Future<void> getAppInfo() async {
final GetAppInfo entity = await ApiRepository.to.getAppInfo(); final GetAppInfo entity = await ApiRepository.to.getAppInfo();
CustomerTool.init(entity.data?.wechatServiceUrl ?? ''); CustomerTool.init(entity.data?.wechatServiceUrl ?? '');
} WxPayTool.associationUrl = entity.data?.appSiteUrl ?? '';
}

View File

@ -28,13 +28,16 @@ class GetAppInfo {
class Data { class Data {
Data.fromJson(Map<String, dynamic> json) { Data.fromJson(Map<String, dynamic> json) {
wechatServiceUrl = json['wechat_service_url']; wechatServiceUrl = json['wechat_service_url'];
appSiteUrl = json['app_site_url'];
} }
String? wechatServiceUrl; String? wechatServiceUrl;
String? appSiteUrl;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
data['wechat_service_url'] = wechatServiceUrl; data['wechat_service_url'] = wechatServiceUrl;
data['app_site_url'] = appSiteUrl;
return data; return data;
} }
} }

View File

@ -33,7 +33,7 @@ class StarLockMainPage extends StatefulWidget {
State<StarLockMainPage> createState() => _StarLockMainPageState(); State<StarLockMainPage> createState() => _StarLockMainPageState();
} }
class _StarLockMainPageState extends State<StarLockMainPage> with BaseWidget { class _StarLockMainPageState extends State<StarLockMainPage> with BaseWidget ,AutomaticKeepAliveClientMixin {
final logic = Get.put(LockMainLogic()); final logic = Get.put(LockMainLogic());
final state = Get.find<LockMainLogic>().state; final state = Get.find<LockMainLogic>().state;
@ -265,8 +265,10 @@ class _StarLockMainPageState extends State<StarLockMainPage> with BaseWidget {
@override @override
void dispose() { void dispose() {
// TODO: implement dispose
super.dispose(); super.dispose();
_teamEvent.cancel(); _teamEvent.cancel();
} }
@override
bool get wantKeepAlive => true;
} }

View File

@ -26,6 +26,7 @@ class StarLockMainXHJPage extends StatefulWidget {
class _StarLockMainXHJPageState extends State<StarLockMainXHJPage> class _StarLockMainXHJPageState extends State<StarLockMainXHJPage>
with BaseWidget { with BaseWidget {
PageController _pageController = PageController();
@override @override
void initState() { void initState() {
@ -44,109 +45,70 @@ class _StarLockMainXHJPageState extends State<StarLockMainXHJPage>
builder: (LockMainXHJLogic logic) { builder: (LockMainXHJLogic logic) {
return Scaffold( return Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
body: Stack( body: PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(), //
children: <Widget>[ children: <Widget>[
pageView( StarLockMainPage(
widget: StarLockMainPage( showAppBar: false,
showDrawer: false,
),
SafeArea(
bottom: false,
child: LockMallPage(
allowReturn: false,
),
),
SafeArea(
bottom: false,
child: MessageListXHJPage(
showAppBar: false, showAppBar: false,
showDrawer: false,
), ),
logic: logic,
index: 0,
), ),
pageView( SafeArea(
widget: SafeArea( bottom: false,
bottom: false, child: MineSetPage(
child: LockMallPage( showAppBar: false,
allowReturn: false, showAbout: true,
),
), ),
logic: logic,
index: 1,
),
pageView(
widget: SafeArea(
bottom: false,
child: MessageListXHJPage(
showAppBar: false,
),
),
logic: logic,
index: 2,
),
pageView(
widget: SafeArea(
bottom: false,
child: MineSetPage(
showAppBar: false,
showAbout: true,
),
),
logic: logic,
index: 3,
), ),
], ],
), ),
bottomNavigationBar: Container( bottomNavigationBar: buildBottomNavigationBar(logic),
padding: EdgeInsets.only(
top: 20.h, bottom: GetPlatform.isAndroid ? 20.h : 0),
decoration: const BoxDecoration(
color: Colors.transparent,
border: Border(
top: BorderSide(
color: Colors.black, //
width: 0.3, //
),
),
),
child: SafeArea(
top: false,
child: Row(
children: <Widget>[
navigationBarItem(Icons.key,
TranslationLoader.lanKeys!.device!.tr, logic, 0, () {
logic.setIndex(0);
}),
navigationBarItem(Icons.shopping_cart, '商城'.tr, logic, 1,
() {
logic.setIndex(1);
}),
navigationBarItem(Icons.message,
TranslationLoader.lanKeys!.message!.tr, logic, 2, () {
logic.setIndex(2);
}),
navigationBarItem(Icons.account_circle, '我的'.tr, logic, 3,
() {
logic.setIndex(3);
}),
],
),
),
),
); );
}); });
} }
// Widget buildBottomNavigationBar(LockMainXHJLogic logic) {
Widget pageView( return Container(
{required Widget widget, padding:
required LockMainXHJLogic logic, EdgeInsets.only(top: 20.h, bottom: GetPlatform.isAndroid ? 20.h : 0),
required int index}) { decoration: const BoxDecoration(
return Positioned.fill( color: Colors.transparent,
child: Offstage( border: Border(top: BorderSide(color: Colors.black, width: 0.3)),
offstage: logic.state.index != index, ),
child: widget, child: SafeArea(
top: false,
child: Row(
children: <Widget>[
navigationBarItem(logic, Icons.key, '设备'.tr, 0),
navigationBarItem(logic, Icons.shopping_cart, '商城'.tr, 1),
navigationBarItem(logic, Icons.message, '消息'.tr, 2),
navigationBarItem(logic, Icons.account_circle, '我的'.tr, 3),
],
),
), ),
); );
} }
// Widget navigationBarItem(
Widget navigationBarItem(IconData icon, String text, LockMainXHJLogic logic, LockMainXHJLogic logic, IconData icon, String text, int index) {
int index, GestureTapCallback? onTop) {
final bool check = logic.state.index == index;
return Expanded( return Expanded(
child: GestureDetector( child: GestureDetector(
onTap: onTop, onTap: () {
_pageController.jumpToPage(index);
logic.setIndex(index);
},
child: Container( child: Container(
color: Colors.transparent, color: Colors.transparent,
child: Column( child: Column(
@ -157,16 +119,18 @@ class _StarLockMainXHJPageState extends State<StarLockMainXHJPage>
child: Icon( child: Icon(
icon, icon,
size: 32.r, size: 32.r,
color: color: logic.state.index == index
check ? AppColors.mainColor : AppColors.darkGrayTextColor, ? AppColors.mainColor
: AppColors.darkGrayTextColor,
), ),
), ),
Text( Text(
text, text,
style: TextStyle( style: TextStyle(
fontSize: 16.sp, fontSize: 16.sp,
color: color: logic.state.index == index
check ? AppColors.mainColor : AppColors.darkGrayTextColor, ? AppColors.mainColor
: AppColors.darkGrayTextColor,
), ),
), ),
], ],

View File

@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:fluwx/fluwx.dart'; import 'package:fluwx/fluwx.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -25,13 +26,12 @@ class LockMallLogic extends BaseGetXController {
// //
Future<void> getMallURLRequest() async { Future<void> getMallURLRequest() async {
LockMallDataEntity entity = await ApiRepository.to.getMallURLData(); final LockMallDataEntity entity = await ApiRepository.to.getMallURLData();
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
state.lockMallUrl.value = entity.data!.url!; state.lockMallUrl.value = entity.data!.url!;
state.mallWebView.setNavigationDelegate( state.mallWebView.setNavigationDelegate(
NavigationDelegate( NavigationDelegate(
onProgress: (int progress) { onProgress: (int progress) {
// Update loading bar.
state.webProgress.value = progress / 100; state.webProgress.value = progress / 100;
}, },
onPageStarted: (String url) { onPageStarted: (String url) {
@ -40,6 +40,7 @@ class LockMallLogic extends BaseGetXController {
onPageFinished: (String url) { onPageFinished: (String url) {
state.webProgress.value = 1.0; state.webProgress.value = 1.0;
refreshGoBack(); refreshGoBack();
update();
}, },
onWebResourceError: (WebResourceError error) {}, onWebResourceError: (WebResourceError error) {},
onNavigationRequest: (NavigationRequest request) async { onNavigationRequest: (NavigationRequest request) async {
@ -53,27 +54,24 @@ class LockMallLogic extends BaseGetXController {
), ),
); );
state.mallWebView.loadRequest(Uri.parse(state.lockMallUrl.value)); state.mallWebView.loadRequest(Uri.parse(state.lockMallUrl.value));
// FlutterBridge.postMessage({action:'',data:'{}',callFun:'回调给js的方法'})
state.mallWebView.addJavaScriptChannel( state.mallWebView.addJavaScriptChannel(
"FlutterBridge", 'FlutterBridge',
onMessageReceived: (JavaScriptMessage message) async { onMessageReceived: (JavaScriptMessage message) async {
flutterBridge(message); flutterBridge(message);
}, },
); );
// onMessageReceived
} }
} }
//webview的调用 //webview的调用
Future<void> flutterBridge(JavaScriptMessage message) async { Future<void> flutterBridge(JavaScriptMessage message) async {
final dynamic obj = json.decode(message.message); final dynamic obj = json.decode(message.message);
AppLog.log(obj.toString());
if (obj is! Map && obj['action'] is String) { if (obj is! Map && obj['action'] is String) {
return; return;
} }
String action = obj['action']; final String action = obj['action'];
dynamic data = obj['data']; final dynamic data = obj['data'];
String? callFun = obj['callFun']; final String? callFun = obj['callFun'];
switch (action) { switch (action) {
case 'WechatPayParams': case 'WechatPayParams':
// //
@ -84,9 +82,9 @@ class LockMallLogic extends BaseGetXController {
// //
Future<void> wxPay(dynamic data, String? callFun) async { Future<void> wxPay(dynamic data, String? callFun) async {
WxPayTool.pay(WxPayTool.mapToPayment(data), (response) { WxPayTool.pay(WxPayTool.mapToPayment(data), (WeChatResponse response) {
if (response is WeChatPaymentResponse) { if (response is WeChatPaymentResponse) {
Map data = { final Map data = <String, dynamic>{
'type': response.type, 'type': response.type,
'extData': response.extData, 'extData': response.extData,
'errCode': response.errCode, 'errCode': response.errCode,
@ -101,7 +99,7 @@ class LockMallLogic extends BaseGetXController {
//webview 退退 //webview 退退
Future<bool> canGoBack(bool didPop) async { Future<bool> canGoBack(bool didPop) async {
bool canGoBack = await state.mallWebView.canGoBack(); final bool canGoBack = await state.mallWebView.canGoBack();
bool isMall = true; bool isMall = true;
if (Get.isRegistered<LockMainXHJLogic>() && F.isXHJ) { if (Get.isRegistered<LockMainXHJLogic>() && F.isXHJ) {
isMall = Get.find<LockMainXHJLogic>().isMall; isMall = Get.find<LockMainXHJLogic>().isMall;
@ -131,7 +129,7 @@ class LockMallLogic extends BaseGetXController {
if (state.allowReturn) { if (state.allowReturn) {
return; return;
} }
state.mallWebView.canGoBack().then((value) { state.mallWebView.canGoBack().then((bool value) {
state.canGoBack = value; state.canGoBack = value;
update(); update();
}); });

View File

@ -17,7 +17,7 @@ class LockMallPage extends StatefulWidget {
State<LockMallPage> createState() => _LockMallPageState(); State<LockMallPage> createState() => _LockMallPageState();
} }
class _LockMallPageState extends State<LockMallPage> { class _LockMallPageState extends State<LockMallPage> with AutomaticKeepAliveClientMixin {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -25,8 +25,8 @@ class _LockMallPageState extends State<LockMallPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// FIXME //
// FIXME url应该使用接口获取 /mall/getUrl POST请求 // url应该使用接口获取 /mall/getUrl POST请求
// String url = 'https://ge.mall.star-lock.cn/quick_login?id=4&key=1ffb9d37109b8351ebb04ccfcca02c8e'; // String url = 'https://ge.mall.star-lock.cn/quick_login?id=4&key=1ffb9d37109b8351ebb04ccfcca02c8e';
return GetBuilder<LockMallLogic>( return GetBuilder<LockMallLogic>(
init: LockMallLogic(allowReturn: widget.allowReturn), init: LockMallLogic(allowReturn: widget.allowReturn),
@ -55,7 +55,7 @@ class _LockMallPageState extends State<LockMallPage> {
PopScope( PopScope(
onPopInvoked: logic.canGoBack, onPopInvoked: logic.canGoBack,
canPop: false, canPop: false,
child: SizedBox(), child: const SizedBox(),
), ),
Container( Container(
padding: EdgeInsets.only(bottom: 10.w), padding: EdgeInsets.only(bottom: 10.w),
@ -76,10 +76,13 @@ class _LockMallPageState extends State<LockMallPage> {
} }
String getWebTitle(LockMallLogic logic) { String getWebTitle(LockMallLogic logic) {
String webTitleStr = "配件商城".tr; String webTitleStr = '配件商城'.tr;
logic.state.mallWebView.getTitle().then((result) { logic.state.mallWebView.getTitle().then((result) {
webTitleStr = result!; webTitleStr = result!;
}); });
return webTitleStr; return webTitleStr;
} }
@override
bool get wantKeepAlive => true;
} }

View File

@ -25,7 +25,7 @@ class MessageListXHJPage extends StatefulWidget {
} }
class _MessageListXHJPageState extends State<MessageListXHJPage> class _MessageListXHJPageState extends State<MessageListXHJPage>
with TickerProviderStateMixin { with TickerProviderStateMixin ,AutomaticKeepAliveClientMixin {
final MessageListLogic logic = Get.put(MessageListLogic()); final MessageListLogic logic = Get.put(MessageListLogic());
final MessageListState state = Get.find<MessageListLogic>().state; final MessageListState state = Get.find<MessageListLogic>().state;
@ -257,4 +257,7 @@ class _MessageListXHJPageState extends State<MessageListXHJPage>
), ),
); );
} }
@override
bool get wantKeepAlive => true;
} }

View File

@ -29,7 +29,8 @@ class MineSetPage extends StatefulWidget {
State<MineSetPage> createState() => _MineSetPageState(); State<MineSetPage> createState() => _MineSetPageState();
} }
class _MineSetPageState extends State<MineSetPage> with WidgetsBindingObserver { class _MineSetPageState extends State<MineSetPage>
with WidgetsBindingObserver, AutomaticKeepAliveClientMixin {
final MineSetLogic logic = Get.put(MineSetLogic()); final MineSetLogic logic = Get.put(MineSetLogic());
final MineSetState state = Get.find<MineSetLogic>().state; final MineSetState state = Get.find<MineSetLogic>().state;
@ -590,4 +591,7 @@ class _MineSetPageState extends State<MineSetPage> with WidgetsBindingObserver {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
super.dispose(); super.dispose();
} }
@override
bool get wantKeepAlive => true;
} }

View File

@ -5,8 +5,10 @@ import 'package:fluwx/fluwx.dart';
/// ///
/// ///
class WxPayTool { class WxPayTool {
static bool isInit = false;
static Fluwx fluwx = Fluwx(); static Fluwx fluwx = Fluwx();
static bool isInit = false;
static String associationUrl = '';
static init(String appId, String universalLink) { static init(String appId, String universalLink) {
fluwx.registerApi(appId: appId, universalLink: universalLink); fluwx.registerApi(appId: appId, universalLink: universalLink);
@ -15,7 +17,7 @@ class WxPayTool {
static Future<void> pay(Payment payment, WeChatResponseSubscriber listener) async { static Future<void> pay(Payment payment, WeChatResponseSubscriber listener) async {
if (!isInit) { if (!isInit) {
isInit = true; isInit = true;
await init(payment.appId, 'https://lock.skychip.top/apple-app-site-association.json'); await init(payment.appId, associationUrl);
// //
responseListener(WeChatResponse response) { responseListener(WeChatResponse response) {
if (response is WeChatPaymentResponse) { if (response is WeChatPaymentResponse) {
@ -30,7 +32,7 @@ class WxPayTool {
} }
static Payment mapToPayment(dynamic data) { static Payment mapToPayment(dynamic data) {
Payment payment = Payment( final Payment payment = Payment(
appId: data['appId'], appId: data['appId'],
partnerId: data['partnerId'], partnerId: data['partnerId'],
prepayId: data['prepayId'], prepayId: data['prepayId'],