2025-08-21 10:50:38 +08:00
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
|
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
|
|
|
|
import 'package:fluwx/fluwx.dart';
|
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
|
import 'package:loopin/IM/controller/im_user_info_controller.dart';
|
|
|
|
|
import 'package:loopin/IM/im_service.dart';
|
|
|
|
|
import 'package:loopin/api/common_api.dart';
|
2025-09-22 14:41:47 +08:00
|
|
|
|
import 'package:loopin/pages/my/merchant/balance/controller.dart';
|
2025-08-21 10:50:38 +08:00
|
|
|
|
import 'package:loopin/service/http.dart';
|
|
|
|
|
|
|
|
|
|
class Wxsdk {
|
|
|
|
|
static bool _inited = false;
|
|
|
|
|
|
|
|
|
|
static final Fluwx fluwx = Fluwx();
|
|
|
|
|
|
|
|
|
|
static Future<bool> init() async {
|
|
|
|
|
if (_inited) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
_inited = true;
|
|
|
|
|
final initRes = await fluwx.registerApi(
|
|
|
|
|
appId: 'wxebcdaea31881caab',
|
|
|
|
|
doOnAndroid: true,
|
|
|
|
|
doOnIOS: true,
|
|
|
|
|
universalLink: 'https://wuzhongjie.com.cn/',
|
|
|
|
|
);
|
|
|
|
|
if (initRes) {
|
|
|
|
|
logger.i('微信sdk初始化成功');
|
|
|
|
|
// 全局监听授权回调
|
|
|
|
|
fluwx.addSubscriber(
|
|
|
|
|
(res) async {
|
|
|
|
|
//授权
|
|
|
|
|
if (res is WeChatAuthResponse) {
|
|
|
|
|
if (res.isSuccessful) {
|
|
|
|
|
final code = res.code;
|
|
|
|
|
logger.i('微信回调,code: $code,类型:${res.state}');
|
|
|
|
|
if (res.state == 'getOpenId') {
|
|
|
|
|
// TODO: 使用 code 向后台换取 access_token、unionid
|
|
|
|
|
final serverRes = await Http.post(CommonApi.wxLogin, data: {
|
|
|
|
|
"source": "wechat_open",
|
|
|
|
|
"socialCode": "${res.code}",
|
|
|
|
|
"socialState": "1",
|
|
|
|
|
"clientId": "428a8310cd442757ae699df5d894f051",
|
|
|
|
|
"grantType": "social"
|
|
|
|
|
});
|
|
|
|
|
final info = Get.find<ImUserInfoController>();
|
|
|
|
|
info.customInfo['openId'] = serverRes['data']['openId'];
|
|
|
|
|
info.updateOpenId();
|
|
|
|
|
info.customInfo.refresh();
|
|
|
|
|
logger.w(serverRes['data']['openId']);
|
|
|
|
|
}
|
2025-09-22 14:41:47 +08:00
|
|
|
|
//
|
2025-08-21 10:50:38 +08:00
|
|
|
|
} else {
|
|
|
|
|
logger.w('微信授权失败: ${res.errStr}-类型:${res.state}');
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-22 14:41:47 +08:00
|
|
|
|
// 支付
|
|
|
|
|
if (res is WeChatPaymentResponse) {
|
|
|
|
|
logger.e(res);
|
|
|
|
|
if (res.isSuccessful) {
|
|
|
|
|
logger.i("微信支付成功");
|
|
|
|
|
// 获取新的数据
|
|
|
|
|
final ctl = Get.find<BalanceController>();
|
|
|
|
|
// 刷新记录
|
|
|
|
|
ctl.getData(reset: true);
|
|
|
|
|
} else {
|
|
|
|
|
if (res.errCode == -2) {
|
|
|
|
|
logger.w("用户取消支付");
|
|
|
|
|
} else {
|
|
|
|
|
logger.e("微信支付失败: code=${res.errCode}, msg=${res.errStr}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-08-21 10:50:38 +08:00
|
|
|
|
// 分享
|
|
|
|
|
if (res is WeChatShareResponse) {
|
|
|
|
|
logger.w(res.isSuccessful);
|
|
|
|
|
// 这里只能确保打开了微信,是取消了还是确认了没办法知道
|
|
|
|
|
if (res.isSuccessful) {}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
logger.i('微信SDK初始化失败:$initRes');
|
|
|
|
|
}
|
|
|
|
|
return initRes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 调用微信登录
|
|
|
|
|
static Future<void> login() async {
|
|
|
|
|
final result = await fluwx.authBy(
|
|
|
|
|
which: NormalAuth(
|
|
|
|
|
scope: 'snsapi_userinfo',
|
|
|
|
|
state: 'getOpenId',
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
if (!result) {
|
|
|
|
|
logger.e('微信授权请求发送失败');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///分享好友
|
|
|
|
|
static Future<bool> shareToFriend({
|
|
|
|
|
required String title,
|
|
|
|
|
required String description,
|
|
|
|
|
required String webpageUrl,
|
|
|
|
|
String thumbnailAssetPath = 'assets/images/logo/logo.png',
|
|
|
|
|
}) async {
|
|
|
|
|
Uint8List? thumbData;
|
|
|
|
|
thumbData = await _loadLocalThumbnail(thumbnailAssetPath);
|
|
|
|
|
final model = WeChatShareWebPageModel(
|
|
|
|
|
webpageUrl,
|
|
|
|
|
title: title,
|
|
|
|
|
description: description,
|
|
|
|
|
thumbData: thumbData,
|
|
|
|
|
scene: WeChatScene.session,
|
|
|
|
|
);
|
|
|
|
|
return Fluwx().share(model);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///分享到朋友圈
|
|
|
|
|
static Future<bool> shareToTimeline({
|
|
|
|
|
required String title,
|
|
|
|
|
required String webpageUrl,
|
|
|
|
|
String thumbnailAssetPath = 'assets/images/logo/logo.png',
|
|
|
|
|
}) async {
|
|
|
|
|
Uint8List? thumbData;
|
|
|
|
|
thumbData = await _loadLocalThumbnail(thumbnailAssetPath);
|
|
|
|
|
final model = WeChatShareWebPageModel(
|
|
|
|
|
webpageUrl,
|
|
|
|
|
title: title,
|
|
|
|
|
thumbData: thumbData,
|
|
|
|
|
scene: WeChatScene.timeline,
|
|
|
|
|
);
|
|
|
|
|
return Fluwx().share(model);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Future<Uint8List> _loadLocalThumbnail(String assetPath) async {
|
|
|
|
|
final byteData = await rootBundle.load(assetPath);
|
|
|
|
|
final originBytes = byteData.buffer.asUint8List();
|
|
|
|
|
|
|
|
|
|
final compressedBytes = await FlutterImageCompress.compressWithList(
|
|
|
|
|
originBytes,
|
|
|
|
|
minWidth: 120, // 微信要求120X120且小于32kb
|
|
|
|
|
minHeight: 120,
|
|
|
|
|
quality: 80, // 控制质量
|
|
|
|
|
format: CompressFormat.jpeg, // 转为 JPEG
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
logger.i("thumbData size: ${compressedBytes.length} bytes");
|
|
|
|
|
|
|
|
|
|
return compressedBytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 跳转小程序
|
|
|
|
|
static Future<void> openMiniApp({required orderId}) async {
|
|
|
|
|
var miniProgram = MiniProgram(
|
|
|
|
|
username: "gh_2ffaecc5508e", // 小程序原始ID
|
|
|
|
|
path: "/pages/index/index?id=$orderId", // 打开时带的路径参数
|
2025-09-03 10:39:38 +08:00
|
|
|
|
miniProgramType: WXMiniProgramType.preview,
|
2025-08-21 10:50:38 +08:00
|
|
|
|
);
|
|
|
|
|
Fluwx().open(target: miniProgram);
|
|
|
|
|
}
|
2025-09-22 14:41:47 +08:00
|
|
|
|
|
|
|
|
|
/// 微信支付
|
|
|
|
|
/// [appId] 微信开放平台申请的 appId
|
|
|
|
|
/// [partnerId] 商户号
|
|
|
|
|
/// [prepayId] 预支付交易会话ID
|
|
|
|
|
/// [packageValue] 固定值:Sign=WXPay
|
|
|
|
|
/// [nonceStr] 随机字符串
|
|
|
|
|
/// [timestamp] 时间戳(秒级,int 类型)
|
|
|
|
|
/// [sign] 签名
|
|
|
|
|
/// [signType] 非必传,默认 MD5
|
|
|
|
|
/// [extData] 业务自定义
|
|
|
|
|
static Future<void> payWithWx({
|
|
|
|
|
required String appId,
|
|
|
|
|
required String partnerId,
|
|
|
|
|
required String prepayId,
|
|
|
|
|
required String packageValue,
|
|
|
|
|
required String nonceStr,
|
|
|
|
|
required int timestamp,
|
|
|
|
|
required String sign,
|
|
|
|
|
String? signType,
|
|
|
|
|
String? extData,
|
|
|
|
|
}) async {
|
|
|
|
|
try {
|
|
|
|
|
final payParams = Payment(
|
|
|
|
|
appId: appId,
|
|
|
|
|
partnerId: partnerId,
|
|
|
|
|
prepayId: prepayId,
|
|
|
|
|
packageValue: packageValue,
|
|
|
|
|
nonceStr: nonceStr,
|
|
|
|
|
timestamp: timestamp,
|
|
|
|
|
sign: sign,
|
|
|
|
|
signType: signType,
|
|
|
|
|
extData: extData,
|
|
|
|
|
);
|
|
|
|
|
logger.e(payParams.arguments);
|
|
|
|
|
final result = await fluwx.pay(which: payParams);
|
|
|
|
|
|
|
|
|
|
logger.i("调用微信支付结果: $result");
|
|
|
|
|
} catch (e) {
|
|
|
|
|
logger.e("调用微信支付失败: $e");
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-08-21 10:50:38 +08:00
|
|
|
|
}
|