27 changed files with 1333 additions and 28 deletions
@ -0,0 +1,36 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
|
<plist version="1.0"> |
||||
|
<dict> |
||||
|
<key>CLIENT_ID</key> |
||||
|
<string>907754492821-oc9e77svgmmlgouo0op7vv00e1hb8278.apps.googleusercontent.com</string> |
||||
|
<key>REVERSED_CLIENT_ID</key> |
||||
|
<string>com.googleusercontent.apps.907754492821-oc9e77svgmmlgouo0op7vv00e1hb8278</string> |
||||
|
<key>ANDROID_CLIENT_ID</key> |
||||
|
<string>907754492821-9jakqvathu61e6b8g95i41ssi7o4dnka.apps.googleusercontent.com</string> |
||||
|
<key>API_KEY</key> |
||||
|
<string>AIzaSyAvyBQcOXuO_q851vevqZIufsPRTMCe808</string> |
||||
|
<key>GCM_SENDER_ID</key> |
||||
|
<string>907754492821</string> |
||||
|
<key>PLIST_VERSION</key> |
||||
|
<string>1</string> |
||||
|
<key>BUNDLE_ID</key> |
||||
|
<string>com.yunqiinnovation.deepsound</string> |
||||
|
<key>PROJECT_ID</key> |
||||
|
<string>deepsound-e0e3d</string> |
||||
|
<key>STORAGE_BUCKET</key> |
||||
|
<string>deepsound-e0e3d.firebasestorage.app</string> |
||||
|
<key>IS_ADS_ENABLED</key> |
||||
|
<false></false> |
||||
|
<key>IS_ANALYTICS_ENABLED</key> |
||||
|
<false></false> |
||||
|
<key>IS_APPINVITE_ENABLED</key> |
||||
|
<true></true> |
||||
|
<key>IS_GCM_ENABLED</key> |
||||
|
<true></true> |
||||
|
<key>IS_SIGNIN_ENABLED</key> |
||||
|
<true></true> |
||||
|
<key>GOOGLE_APP_ID</key> |
||||
|
<string>1:907754492821:ios:246794fc44b23174145c9c</string> |
||||
|
</dict> |
||||
|
</plist> |
||||
@ -0,0 +1,47 @@ |
|||||
|
{ |
||||
|
"project_info": { |
||||
|
"project_number": "907754492821", |
||||
|
"project_id": "deepsound-e0e3d", |
||||
|
"storage_bucket": "deepsound-e0e3d.firebasestorage.app" |
||||
|
}, |
||||
|
"client": [ |
||||
|
{ |
||||
|
"client_info": { |
||||
|
"mobilesdk_app_id": "1:907754492821:android:2deffc5aa1037ae2145c9c", |
||||
|
"android_client_info": { |
||||
|
"package_name": "com.yunqiinnovation.deepsound" |
||||
|
} |
||||
|
}, |
||||
|
"oauth_client": [ |
||||
|
{ |
||||
|
"client_id": "907754492821-9jakqvathu61e6b8g95i41ssi7o4dnka.apps.googleusercontent.com", |
||||
|
"client_type": 1, |
||||
|
"android_info": { |
||||
|
"package_name": "com.yunqiinnovation.deepsound", |
||||
|
"certificate_hash": "5a9520045bc16fb4f09fb97668a8b0fc4babd376" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"client_id": "907754492821-15btgolbd7thaa8fpt7s8hs8hq3jl0lg.apps.googleusercontent.com", |
||||
|
"client_type": 3 |
||||
|
} |
||||
|
], |
||||
|
"api_key": [ |
||||
|
{ |
||||
|
"current_key": "AIzaSyAj0_-nS3ygc8VFe1azotSE3-HGZYClkTs" |
||||
|
} |
||||
|
], |
||||
|
"services": { |
||||
|
"appinvite_service": { |
||||
|
"other_platform_oauth_client": [ |
||||
|
{ |
||||
|
"client_id": "907754492821-15btgolbd7thaa8fpt7s8hs8hq3jl0lg.apps.googleusercontent.com", |
||||
|
"client_type": 3 |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
"configuration_version": "1" |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
storePassword=13071376716 |
||||
|
keyPassword=13071376716 |
||||
|
keyAlias=DeepSound |
||||
|
storeFile=sign/DeepSound.keystore |
||||
@ -0,0 +1,6 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<resources> |
||||
|
<string name="facebook_app_id">3829022037361855</string> |
||||
|
<string name="fb_login_protocol_scheme">fb3829022037361855</string> |
||||
|
<string name="facebook_client_token">193d0a2b1757c41cfa557ea8e8f21c33</string> |
||||
|
</resources> |
||||
@ -0,0 +1 @@ |
|||||
|
{"flutter":{"platforms":{"android":{"default":{"projectId":"deepsound-e0e3d","appId":"1:907754492821:android:2deffc5aa1037ae2145c9c","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"deepsound-e0e3d","configurations":{"android":"1:907754492821:android:2deffc5aa1037ae2145c9c","ios":"1:907754492821:ios:8c1d7d1b583aec22145c9c","macos":"1:907754492821:ios:8c1d7d1b583aec22145c9c","web":"1:907754492821:web:99451e7efd7d120a145c9c","windows":"1:907754492821:web:e3e8040111db6871145c9c"}}}}}} |
||||
@ -0,0 +1,92 @@ |
|||||
|
// File generated by FlutterFire CLI. |
||||
|
// ignore_for_file: type=lint |
||||
|
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; |
||||
|
import 'package:flutter/foundation.dart' |
||||
|
show defaultTargetPlatform, kIsWeb, TargetPlatform; |
||||
|
|
||||
|
/// Default [FirebaseOptions] for use with your Firebase apps. |
||||
|
/// |
||||
|
/// Example: |
||||
|
/// ```dart |
||||
|
/// import 'firebase_options.dart'; |
||||
|
/// // ... |
||||
|
/// await Firebase.initializeApp( |
||||
|
/// options: DefaultFirebaseOptions.currentPlatform, |
||||
|
/// ); |
||||
|
/// ``` |
||||
|
class DefaultFirebaseOptions { |
||||
|
static FirebaseOptions get currentPlatform { |
||||
|
if (kIsWeb) { |
||||
|
return web; |
||||
|
} |
||||
|
switch (defaultTargetPlatform) { |
||||
|
case TargetPlatform.android: |
||||
|
return android; |
||||
|
case TargetPlatform.iOS: |
||||
|
return ios; |
||||
|
case TargetPlatform.macOS: |
||||
|
return macos; |
||||
|
case TargetPlatform.windows: |
||||
|
return windows; |
||||
|
case TargetPlatform.linux: |
||||
|
throw UnsupportedError( |
||||
|
'DefaultFirebaseOptions have not been configured for linux - ' |
||||
|
'you can reconfigure this by running the FlutterFire CLI again.', |
||||
|
); |
||||
|
default: |
||||
|
throw UnsupportedError( |
||||
|
'DefaultFirebaseOptions are not supported for this platform.', |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static const FirebaseOptions web = FirebaseOptions( |
||||
|
apiKey: 'AIzaSyBJXQTXsEmY_XA7ZEOusxG6VF5CaKtjHCA', |
||||
|
appId: '1:907754492821:web:99451e7efd7d120a145c9c', |
||||
|
messagingSenderId: '907754492821', |
||||
|
projectId: 'deepsound-e0e3d', |
||||
|
authDomain: 'deepsound-e0e3d.firebaseapp.com', |
||||
|
storageBucket: 'deepsound-e0e3d.firebasestorage.app', |
||||
|
measurementId: 'G-ETX6DF35J3', |
||||
|
); |
||||
|
|
||||
|
static const FirebaseOptions android = FirebaseOptions( |
||||
|
apiKey: 'AIzaSyAj0_-nS3ygc8VFe1azotSE3-HGZYClkTs', |
||||
|
appId: '1:907754492821:android:2deffc5aa1037ae2145c9c', |
||||
|
messagingSenderId: '907754492821', |
||||
|
projectId: 'deepsound-e0e3d', |
||||
|
storageBucket: 'deepsound-e0e3d.firebasestorage.app', |
||||
|
); |
||||
|
|
||||
|
static const FirebaseOptions ios = FirebaseOptions( |
||||
|
apiKey: 'AIzaSyAvyBQcOXuO_q851vevqZIufsPRTMCe808', |
||||
|
appId: '1:907754492821:ios:8c1d7d1b583aec22145c9c', |
||||
|
messagingSenderId: '907754492821', |
||||
|
projectId: 'deepsound-e0e3d', |
||||
|
storageBucket: 'deepsound-e0e3d.firebasestorage.app', |
||||
|
androidClientId: '907754492821-9jakqvathu61e6b8g95i41ssi7o4dnka.apps.googleusercontent.com', |
||||
|
iosClientId: '907754492821-ej6j6pfto66jfhpj47b9bjs9amvo9dde.apps.googleusercontent.com', |
||||
|
iosBundleId: 'com.example.client', |
||||
|
); |
||||
|
|
||||
|
static const FirebaseOptions macos = FirebaseOptions( |
||||
|
apiKey: 'AIzaSyAvyBQcOXuO_q851vevqZIufsPRTMCe808', |
||||
|
appId: '1:907754492821:ios:8c1d7d1b583aec22145c9c', |
||||
|
messagingSenderId: '907754492821', |
||||
|
projectId: 'deepsound-e0e3d', |
||||
|
storageBucket: 'deepsound-e0e3d.firebasestorage.app', |
||||
|
androidClientId: '907754492821-9jakqvathu61e6b8g95i41ssi7o4dnka.apps.googleusercontent.com', |
||||
|
iosClientId: '907754492821-ej6j6pfto66jfhpj47b9bjs9amvo9dde.apps.googleusercontent.com', |
||||
|
iosBundleId: 'com.example.client', |
||||
|
); |
||||
|
|
||||
|
static const FirebaseOptions windows = FirebaseOptions( |
||||
|
apiKey: 'AIzaSyBJXQTXsEmY_XA7ZEOusxG6VF5CaKtjHCA', |
||||
|
appId: '1:907754492821:web:e3e8040111db6871145c9c', |
||||
|
messagingSenderId: '907754492821', |
||||
|
projectId: 'deepsound-e0e3d', |
||||
|
authDomain: 'deepsound-e0e3d.firebaseapp.com', |
||||
|
storageBucket: 'deepsound-e0e3d.firebasestorage.app', |
||||
|
measurementId: 'G-SKGXEK5TJM', |
||||
|
); |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
import 'package:firebase_auth/firebase_auth.dart'; |
||||
|
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
|
||||
|
class Facebook { |
||||
|
String token = ''; |
||||
|
// FaceBook登录 |
||||
|
// 修改后的 signInWithFacebook |
||||
|
Future<bool> signInWithFacebook() async { |
||||
|
try { |
||||
|
print("开始 Facebook 登录"); |
||||
|
final LoginResult result = await FacebookAuth.instance.login(); |
||||
|
print("Facebook 登录结果:$result"); |
||||
|
|
||||
|
if (result.status == LoginStatus.success) { |
||||
|
token = result.accessToken!.tokenString; |
||||
|
print("Facebook Token: $token"); |
||||
|
|
||||
|
final credential = FacebookAuthProvider.credential(token); |
||||
|
print("Facebook Token: $credential"); |
||||
|
final userData = await FacebookAuth.instance.getUserData(); |
||||
|
print("user login facebook ${userData..values}"); |
||||
|
|
||||
|
return true; |
||||
|
} else { |
||||
|
print("登录失败,状态:${result.status},消息:${result.message}"); |
||||
|
return false; |
||||
|
} |
||||
|
} catch (e) { |
||||
|
print("Facebook 登录异常:$e"); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 退出Google登录 |
||||
|
Future<void> signOutFacebook() async { |
||||
|
await FacebookAuth.instance.logOut(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,72 @@ |
|||||
|
import 'package:firebase_auth/firebase_auth.dart'; |
||||
|
import 'package:google_sign_in/google_sign_in.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
|
||||
|
class Google { |
||||
|
String? token = ''; |
||||
|
String? email = ''; |
||||
|
String? displayName = ''; |
||||
|
String? id = ''; |
||||
|
String? accessToken = ''; |
||||
|
|
||||
|
// 登录并返回 |
||||
|
Future<bool> signInWithGoogle() async { |
||||
|
try { |
||||
|
// 确保用户已经登录,并获取当前用户的身份验证令牌 |
||||
|
final currentUser = FirebaseAuth.instance.currentUser; |
||||
|
print('Future响应数据: $currentUser'); |
||||
|
if (currentUser != null) { |
||||
|
// 这里处理您需要使用这个JWT令牌的逻辑,例如将它存储到本地存储中作为凭据。 |
||||
|
|
||||
|
token != await currentUser.getIdToken(); |
||||
|
|
||||
|
print('Future响应数据tokenResult: $token'); |
||||
|
|
||||
|
return true; |
||||
|
} else { |
||||
|
UserCredential userCredential = await loginGoogle(); |
||||
|
if (token != "") { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// logger.d("user login google: ${userCredential.user?.displayName}"); |
||||
|
} |
||||
|
} catch (e) { |
||||
|
print("Google 登录异常:$e"); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Google登录 |
||||
|
Future<UserCredential> loginGoogle() async { |
||||
|
print('loginGoogle:'); |
||||
|
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn(); |
||||
|
email = googleUser?.email; |
||||
|
id = googleUser?.id; |
||||
|
displayName = googleUser?.displayName; |
||||
|
print('loginGoogle: $googleUser'); |
||||
|
// Obtain the auth details from the request |
||||
|
final GoogleSignInAuthentication? googleAuth = |
||||
|
await googleUser?.authentication; |
||||
|
accessToken = googleAuth?.accessToken; |
||||
|
token = googleAuth?.idToken; |
||||
|
print('loginGoogle:googleAuth?.idToken= ${token}'); |
||||
|
print('loginGoogle:googleAuth?.accessToken= ${accessToken}'); |
||||
|
// Create a new credential, |
||||
|
final credential = GoogleAuthProvider.credential( |
||||
|
accessToken: googleAuth?.accessToken, |
||||
|
idToken: googleAuth?.idToken, |
||||
|
); |
||||
|
|
||||
|
// Once signed in, return the UserCredential |
||||
|
return await FirebaseAuth.instance.signInWithCredential(credential); |
||||
|
} |
||||
|
|
||||
|
// 退出Google登录 |
||||
|
Future<void> signOutGoogle() async { |
||||
|
await FirebaseAuth.instance.signOut(); |
||||
|
await GoogleSignIn().signOut(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,889 @@ |
|||||
|
import 'dart:async'; |
||||
|
import 'dart:convert'; |
||||
|
import 'dart:io'; |
||||
|
import 'dart:typed_data'; |
||||
|
import 'package:fluwx/fluwx.dart'; |
||||
|
export 'package:fluwx/fluwx.dart'; |
||||
|
import 'package:http/http.dart' as http; |
||||
|
import 'package:get/get.dart'; |
||||
|
|
||||
|
typedef FlWeChatResponseCallback = void Function(WeChatResponse response); |
||||
|
|
||||
|
/// 支持成功 |
||||
|
typedef FlWeChatPayResponseResultCallback = void Function(); |
||||
|
|
||||
|
/// 支付结果回调 |
||||
|
typedef FlWeChatPayResponseCallback = void Function( |
||||
|
WeChatPaymentResponse response); |
||||
|
|
||||
|
/// LaunchFromWX 回调 |
||||
|
typedef FlWeChatLaunchFromWXRequestCallback = void Function( |
||||
|
WeChatLaunchFromWXRequest response); |
||||
|
|
||||
|
/// OpenBusinessWebView 回调 |
||||
|
typedef FlWeChatOpenBusinessWebViewResponseCallback = void Function( |
||||
|
WeChatOpenBusinessWebviewResponse response); |
||||
|
|
||||
|
/// WeChatOpenBusinessView 回调 |
||||
|
typedef FlWeChatOpenBusinessViewResponseCallback = void Function( |
||||
|
WeChatOpenBusinessViewResponse response); |
||||
|
|
||||
|
/// Share 回调 |
||||
|
typedef FlWeChatShareResponseCallback = void Function( |
||||
|
WeChatShareResponse response); |
||||
|
|
||||
|
/// Auth 回调 |
||||
|
typedef FlWeChatAuthResponseCallback = Function(WeChatAuthResponse response); |
||||
|
|
||||
|
/// Auth token 回调 |
||||
|
typedef FlWeChatAuthResponseTokenCallback = Function( |
||||
|
WeChatAuthResponse response, WXTokenModel token); |
||||
|
|
||||
|
/// Auth userinfo 回调 |
||||
|
typedef FlWeChatAuthResponseUserinfoCallback = Function( |
||||
|
WeChatAuthResponse response, |
||||
|
WXTokenModel token, |
||||
|
WXUserModel userInfo, |
||||
|
); |
||||
|
|
||||
|
/// 显示 toast |
||||
|
typedef FlWXToastCallback = void Function(String msg); |
||||
|
|
||||
|
/// 日志 打印 |
||||
|
typedef FlWXLogCallback = void Function(String msg); |
||||
|
|
||||
|
/// http 请求 |
||||
|
typedef FlWXHTTPCallback = Future<String?> Function(String url); |
||||
|
|
||||
|
class FlWX { |
||||
|
factory FlWX() => _singleton ??= FlWX._(); |
||||
|
|
||||
|
FlWX._(); |
||||
|
|
||||
|
static FlWX? _singleton; |
||||
|
|
||||
|
final Fluwx fluwx = Fluwx(); |
||||
|
|
||||
|
String? _appId; |
||||
|
|
||||
|
/// 获取当前设置的 appId |
||||
|
String? get appId => _appId; |
||||
|
|
||||
|
String? _appSecret; |
||||
|
|
||||
|
/// 获取当前设置的 appSecret |
||||
|
String? get appSecret => _appSecret; |
||||
|
|
||||
|
String _appName = ''; |
||||
|
String token = ''; |
||||
|
String refresh_token = ''; |
||||
|
String openid = ''; |
||||
|
// 参数 说明 |
||||
|
// access_token 接口调用凭证 |
||||
|
// expires_in access_token 接口调用凭证超时时间,单位(秒) |
||||
|
// refresh_token 用户刷新 access_token |
||||
|
// openid 授权用户唯一标识 |
||||
|
// scope 用户授权的作用域(snsapi_userinfo) |
||||
|
// unionid 当且仅当该移动应用已获得该用户的 userinfo 授权时,才会出现该字段 |
||||
|
/// callback params |
||||
|
FlWXCallbackParams? _params; |
||||
|
|
||||
|
/// 分享时的缩略图 |
||||
|
Uint8List? _shareThumbnail; |
||||
|
|
||||
|
/// register |
||||
|
bool _isRegister = false; |
||||
|
|
||||
|
Future<bool> register({ |
||||
|
required String appId, |
||||
|
required FlWXCallbackParams params, |
||||
|
String? universalLink, |
||||
|
bool doOnIOS = true, |
||||
|
bool doOnAndroid = true, |
||||
|
|
||||
|
/// 用于获取用户信息 |
||||
|
String? appSecret, |
||||
|
|
||||
|
/// app名称(用于分享时使用) |
||||
|
String appName = '', |
||||
|
|
||||
|
/// 分享时的缩略图 |
||||
|
Uint8List? shareThumbnail, |
||||
|
}) { |
||||
|
assert(appId.isNotEmpty); |
||||
|
if (universalLink != null) assert(universalLink.isNotEmpty); |
||||
|
if (appSecret != null) { |
||||
|
assert(appSecret.isNotEmpty); |
||||
|
} |
||||
|
_isRegister = true; |
||||
|
_appId = appId; |
||||
|
_appSecret = appSecret; |
||||
|
_appName = appName; |
||||
|
_shareThumbnail = shareThumbnail; |
||||
|
_params = params; |
||||
|
return fluwx.registerApi( |
||||
|
appId: appId, |
||||
|
doOnAndroid: doOnAndroid, |
||||
|
doOnIOS: doOnIOS, |
||||
|
universalLink: universalLink, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 获取微信 用户token |
||||
|
String _getTokenUrl(String code) { |
||||
|
print("_getTokenUrl 数据获取${_appId},${_appSecret}"); |
||||
|
assert( |
||||
|
_appId != null && |
||||
|
_appId!.isNotEmpty && |
||||
|
_appSecret != null && |
||||
|
_appSecret!.isNotEmpty, |
||||
|
); |
||||
|
return 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=$_appId&secret=$_appSecret&code=$code&grant_type=authorization_code'; |
||||
|
} |
||||
|
|
||||
|
/// 获取微信 用户token |
||||
|
String _getRefreshTokenUrl(String code) { |
||||
|
print("_getRefreshTokenUrl 数据获取${_appId},${_appSecret}"); |
||||
|
assert( |
||||
|
_appId != null && |
||||
|
_appId!.isNotEmpty && |
||||
|
_appSecret != null && |
||||
|
_appSecret!.isNotEmpty, |
||||
|
); |
||||
|
return 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=$_appId&grant_type=refresh_token&&refresh_token=$refresh_token'; |
||||
|
} |
||||
|
|
||||
|
// GET请求示例 |
||||
|
Future<Map<String, dynamic>> fetchData(String Url) async { |
||||
|
try { |
||||
|
final response = await http.get(Uri.parse(Url)); |
||||
|
|
||||
|
if (response.statusCode == 200) { |
||||
|
final data = jsonDecode(response.body) as Map<String, dynamic>; |
||||
|
print('GET响应数据: $data'); |
||||
|
|
||||
|
return data; |
||||
|
} else { |
||||
|
print('GET请求失败,状态码: ${response.statusCode}'); |
||||
|
return {}; |
||||
|
} |
||||
|
} catch (e) { |
||||
|
print('GET请求异常: $e'); |
||||
|
return {}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// POST请求示例 |
||||
|
Future<bool> postData() async { |
||||
|
try { |
||||
|
final response = await http.post( |
||||
|
Uri.parse('https://jsonplaceholder.typicode.com/posts'), |
||||
|
headers: { |
||||
|
'Content-Type': 'application/json', |
||||
|
}, // 设置请求头:ml-citation{ref="6" data="citationList"} |
||||
|
body: jsonEncode({ |
||||
|
// 编码JSON数据:ml-citation{ref="3" data="citationList"} |
||||
|
'title': 'foo', |
||||
|
'body': 'bar', |
||||
|
'userId': 1, |
||||
|
}), |
||||
|
); |
||||
|
|
||||
|
if (response.statusCode == 201) { |
||||
|
final data = jsonDecode(response.body); |
||||
|
print('POST响应数据: $data'); |
||||
|
return true; |
||||
|
} else { |
||||
|
print('POST请求失败,状态码: ${response.statusCode}'); |
||||
|
return false; |
||||
|
} |
||||
|
} catch (e) { |
||||
|
print('POST请求异常: $e'); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 获取微信 用户信息 |
||||
|
String _getUserInfoUrl({required String openId, required String token}) => |
||||
|
'https://api.weixin.qq.com/sns/userinfo?access_token=$token&openid=$openId'; |
||||
|
//检验授权凭证(access_token)是否有效 |
||||
|
String _getUserTokenEffertive({ |
||||
|
required String openId, |
||||
|
required String token, |
||||
|
}) => |
||||
|
'https://api.weixin.qq.com/sns/auth?access_token=$token&openid=$openId'; |
||||
|
|
||||
|
/// 是否安装微信 |
||||
|
Future<bool> get isInstalled async { |
||||
|
assert(_isRegister, '请先调用 FlWX().register()'); |
||||
|
final installed = await fluwx.isWeChatInstalled; |
||||
|
if (!installed) _params!.onToast?.call('该服务需要先安装微信'); |
||||
|
return installed; |
||||
|
} |
||||
|
|
||||
|
/// isSupportOpenBusinessView |
||||
|
Future<bool> get isSupportOpenBusinessView async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return await fluwx.isSupportOpenBusinessView; |
||||
|
} |
||||
|
|
||||
|
/// 添加移除监听 |
||||
|
FluwxCancelable _onListener(FlWeChatResponseCallback onResponse) { |
||||
|
late FluwxCancelable cancelable; |
||||
|
subscriber(response) { |
||||
|
onResponse(response); |
||||
|
Future.delayed(const Duration(milliseconds: 500), () { |
||||
|
cancelable.cancel(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return cancelable = fluwx.addSubscriber(subscriber); |
||||
|
} |
||||
|
|
||||
|
Future<String?> getExtMsg() async { |
||||
|
if (!await isInstalled) return null; |
||||
|
return await fluwx.getExtMsg(); |
||||
|
} |
||||
|
|
||||
|
Future<void> attemptToResumeMsgFromWx({ |
||||
|
Function(WeChatShowMessageFromWXRequest response)? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return; |
||||
|
await fluwx.attemptToResumeMsgFromWx(); |
||||
|
if (onResponse != null) { |
||||
|
_onListener((response) { |
||||
|
if (response is WeChatShowMessageFromWXRequest) onResponse(response); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 调用微信登录 |
||||
|
Future<bool> authBy( |
||||
|
AuthType which, { |
||||
|
/// 原始数据回调 |
||||
|
FlWeChatAuthResponseCallback? onResponse, |
||||
|
|
||||
|
/// 获取token回调 |
||||
|
FlWeChatAuthResponseTokenCallback? onToken, |
||||
|
|
||||
|
/// 获取userinfo回调 |
||||
|
FlWeChatAuthResponseUserinfoCallback? onUserinfo, |
||||
|
bool getUserInfo = false, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) async { |
||||
|
if (response is WeChatAuthResponse) { |
||||
|
onResponse?.call(response); |
||||
|
print( |
||||
|
"用户点击事件${response.isSuccessful},${response.code},${response.lang},${response.state},${response.country}", |
||||
|
); |
||||
|
if (response.isSuccessful && response.code != null) { |
||||
|
print("数据获取失败${onToken},${onUserinfo}"); |
||||
|
// if (onToken != null || onUserinfo != null) { |
||||
|
try { |
||||
|
var Istoken = await fetchData( |
||||
|
_getTokenUrl(response.code!), |
||||
|
); // 触发GET请求 |
||||
|
//token有效期是30天,30天后需要重新授权,需要看看API文档 |
||||
|
print("数据获取fetchData${Istoken}"); |
||||
|
|
||||
|
if (Istoken != {}) { |
||||
|
token = Istoken["access_token"].toString(); |
||||
|
refresh_token = Istoken["refresh_token"].toString(); |
||||
|
openid = Istoken["openid"].toString(); |
||||
|
print("数据获取token=${token}"); |
||||
|
print("数据获取openid=${openid}"); |
||||
|
print("数据获取refresh_token=${refresh_token}"); |
||||
|
Istoken = await fetchData(_getRefreshTokenUrl(response.code!)); |
||||
|
print("数据获取_getUserTokenEffertive${Istoken}"); |
||||
|
Istoken = await fetchData( |
||||
|
_getUserTokenEffertive(openId: openid, token: token), |
||||
|
); // 触发GET请求 |
||||
|
print("数据获取_getUserTokenEffertive${Istoken}"); |
||||
|
Istoken = await fetchData( |
||||
|
_getUserInfoUrl(openId: openid, token: token), |
||||
|
); // 触发GET请求 |
||||
|
print("数据获取_getUserInfoUrl${Istoken}"); |
||||
|
} |
||||
|
} catch (e) { |
||||
|
_params!.onLog?.call('数据解析失败 $e'); |
||||
|
} |
||||
|
// } |
||||
|
} |
||||
|
} else if (response is WeChatAuthByQRCodeFinishedResponse) {} |
||||
|
}); |
||||
|
final result = await fluwx.authBy(which: which); |
||||
|
print("authBy数据获取${result}"); |
||||
|
if (!result) { |
||||
|
cancelable.cancel(); |
||||
|
_params!.onToast?.call('微信授权失败'); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
Future<bool> autoDeduct( |
||||
|
AutoDeduct data, { |
||||
|
FlWeChatResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
final cancelable = _onListener((response) { |
||||
|
onResponse?.call(response); |
||||
|
}); |
||||
|
final result = await fluwx.autoDeduct(data: data); |
||||
|
if (!result) { |
||||
|
cancelable.cancel(); |
||||
|
_params!.onToast?.call('微信签约失败'); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/// 调用微信支付 |
||||
|
Future<bool> pay( |
||||
|
PayType which, { |
||||
|
FlWeChatPayResponseResultCallback? onSuccess, |
||||
|
FlWeChatPayResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatPaymentResponse) { |
||||
|
onResponse?.call(response); |
||||
|
_params!.onLog?.call('微信支付 result code: ${response.errCode} '); |
||||
|
if (response.errCode == 0) { |
||||
|
_params!.onToast?.call('支付成功'); |
||||
|
onSuccess?.call(); |
||||
|
} else if (response.errCode == -2) { |
||||
|
_params!.onToast?.call('已取消支付'); |
||||
|
} else { |
||||
|
_params!.onToast?.call('支付失败'); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
final result = await fluwx.pay(which: which); |
||||
|
if (!result) { |
||||
|
cancelable.cancel(); |
||||
|
_params!.onToast?.call('支付失败'); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/// ****************** open ****************** /// |
||||
|
|
||||
|
Future<bool> open(OpenType target) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return fluwx.open(target: target); |
||||
|
} |
||||
|
|
||||
|
Future<bool> openWeChatApp({ |
||||
|
FlWeChatLaunchFromWXRequestCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatLaunchFromWXRequest) onResponse?.call(response); |
||||
|
}); |
||||
|
final result = await fluwx.open(target: WeChatApp()); |
||||
|
if (!result) cancelable.cancel(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
Future<bool> openBrowser( |
||||
|
String url, { |
||||
|
FlWeChatOpenBusinessWebViewResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatOpenBusinessWebviewResponse) { |
||||
|
onResponse?.call(response); |
||||
|
} |
||||
|
}); |
||||
|
final result = await fluwx.open(target: Browser(url)); |
||||
|
if (!result) cancelable.cancel(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
Future<bool> openRankList() async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return fluwx.open(target: RankList()); |
||||
|
} |
||||
|
|
||||
|
Future<bool> openBusinessView({ |
||||
|
required String businessType, |
||||
|
required String query, |
||||
|
FlWeChatOpenBusinessViewResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatOpenBusinessViewResponse) { |
||||
|
onResponse?.call(response); |
||||
|
} |
||||
|
}); |
||||
|
final result = await fluwx.open( |
||||
|
target: BusinessView(businessType: businessType, query: query), |
||||
|
); |
||||
|
if (!result) cancelable.cancel(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
Future<bool> openInvoice({ |
||||
|
required String appId, |
||||
|
required String cardType, |
||||
|
String locationId = '', |
||||
|
String cardId = '', |
||||
|
String canMultiSelect = '', |
||||
|
Function(WeChatOpenInvoiceResponse response)? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatOpenInvoiceResponse) onResponse?.call(response); |
||||
|
}); |
||||
|
final result = await fluwx.open( |
||||
|
target: Invoice( |
||||
|
appId: appId, |
||||
|
cardType: cardType, |
||||
|
locationId: locationId, |
||||
|
cardId: cardId, |
||||
|
canMultiSelect: canMultiSelect, |
||||
|
), |
||||
|
); |
||||
|
if (!result) cancelable.cancel(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
Future<bool> openCustomerServiceChat({ |
||||
|
required String corpId, |
||||
|
required String url, |
||||
|
Function(WeChatOpenCustomerServiceChatResponse response)? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatOpenCustomerServiceChatResponse) { |
||||
|
onResponse?.call(response); |
||||
|
} |
||||
|
}); |
||||
|
final result = await fluwx.open( |
||||
|
target: CustomerServiceChat(corpId: corpId, url: url), |
||||
|
); |
||||
|
if (!result) cancelable.cancel(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
Future<bool> openMiniProgram( |
||||
|
String username, { |
||||
|
String? path, |
||||
|
Function(WeChatLaunchMiniProgramResponse response)? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatLaunchMiniProgramResponse) { |
||||
|
onResponse?.call(response); |
||||
|
} |
||||
|
}); |
||||
|
final result = await fluwx.open( |
||||
|
target: MiniProgram(username: username, path: path), |
||||
|
); |
||||
|
if (!result) { |
||||
|
cancelable.cancel(); |
||||
|
_params?.onToast?.call('小程序打开失败'); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
Future<bool> openSubscribeMessage({ |
||||
|
required String appId, |
||||
|
required int scene, |
||||
|
required String templateId, |
||||
|
String? reserved, |
||||
|
Function(WeChatSubscribeMsgResponse response)? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatSubscribeMsgResponse) onResponse?.call(response); |
||||
|
}); |
||||
|
final result = await fluwx.open( |
||||
|
target: SubscribeMessage( |
||||
|
appId: appId, |
||||
|
scene: scene, |
||||
|
templateId: templateId, |
||||
|
reserved: reserved, |
||||
|
), |
||||
|
); |
||||
|
if (!result) cancelable.cancel(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/// ****************** share ****************** /// |
||||
|
|
||||
|
Future<bool> share( |
||||
|
WeChatShareModel what, { |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return _shareResponse(fluwx.share(what), onResponse: onResponse); |
||||
|
} |
||||
|
|
||||
|
Future<bool> shareText( |
||||
|
String source, { |
||||
|
String? title, |
||||
|
String? description, |
||||
|
WeChatScene scene = WeChatScene.session, |
||||
|
String? messageExt, |
||||
|
String? messageAction, |
||||
|
String? mediaTagName, |
||||
|
String? msgSignature, |
||||
|
Uint8List? thumbData, |
||||
|
String? thumbDataHash, |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return _shareResponse( |
||||
|
fluwx.share( |
||||
|
WeChatShareTextModel( |
||||
|
source, |
||||
|
title: title ?? _appName, |
||||
|
description: description ?? _appName, |
||||
|
scene: scene, |
||||
|
messageExt: messageExt, |
||||
|
messageAction: messageAction, |
||||
|
mediaTagName: mediaTagName, |
||||
|
msgSignature: msgSignature, |
||||
|
thumbData: thumbData ?? _shareThumbnail, |
||||
|
thumbDataHash: thumbDataHash, |
||||
|
), |
||||
|
), |
||||
|
onResponse: onResponse, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Future<bool> shareMiniProgram( |
||||
|
String webPage, { |
||||
|
required String webPageUrl, |
||||
|
WXMiniProgramType miniProgramType = WXMiniProgramType.release, |
||||
|
required String userName, |
||||
|
String path = "/", |
||||
|
String? title, |
||||
|
String? description, |
||||
|
bool withShareTicket = false, |
||||
|
String? messageExt, |
||||
|
String? messageAction, |
||||
|
String? mediaTagName, |
||||
|
String? msgSignature, |
||||
|
Uint8List? thumbData, |
||||
|
String? thumbDataHash, |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return _shareResponse( |
||||
|
fluwx.share( |
||||
|
WeChatShareMiniProgramModel( |
||||
|
webPageUrl: webPageUrl, |
||||
|
userName: userName, |
||||
|
title: title ?? _appName, |
||||
|
description: description ?? _appName, |
||||
|
messageExt: messageExt, |
||||
|
messageAction: messageAction, |
||||
|
mediaTagName: mediaTagName, |
||||
|
msgSignature: msgSignature, |
||||
|
thumbData: thumbData ?? _shareThumbnail, |
||||
|
thumbDataHash: thumbDataHash, |
||||
|
), |
||||
|
), |
||||
|
onResponse: onResponse, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Future<bool> shareImage( |
||||
|
WeChatImageToShare source, { |
||||
|
String? title, |
||||
|
String? description, |
||||
|
WeChatScene scene = WeChatScene.session, |
||||
|
String? messageExt, |
||||
|
String? messageAction, |
||||
|
String? mediaTagName, |
||||
|
String? msgSignature, |
||||
|
Uint8List? thumbData, |
||||
|
String? thumbDataHash, |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return _shareResponse( |
||||
|
fluwx.share( |
||||
|
WeChatShareImageModel( |
||||
|
source, |
||||
|
title: title ?? _appName, |
||||
|
description: description ?? _appName, |
||||
|
scene: scene, |
||||
|
messageExt: messageExt, |
||||
|
messageAction: messageAction, |
||||
|
mediaTagName: mediaTagName, |
||||
|
msgSignature: msgSignature, |
||||
|
thumbData: thumbData ?? _shareThumbnail, |
||||
|
thumbDataHash: thumbDataHash, |
||||
|
), |
||||
|
), |
||||
|
onResponse: onResponse, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Future<bool> shareMusic({ |
||||
|
String? musicUrl, |
||||
|
String? musicDataUrl, |
||||
|
String? musicLowBandUrl, |
||||
|
String? musicLowBandDataUrl, |
||||
|
String? title, |
||||
|
String? description, |
||||
|
WeChatScene scene = WeChatScene.session, |
||||
|
String? messageExt, |
||||
|
String? messageAction, |
||||
|
String? mediaTagName, |
||||
|
String? msgSignature, |
||||
|
Uint8List? thumbData, |
||||
|
String? thumbDataHash, |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return _shareResponse( |
||||
|
fluwx.share( |
||||
|
WeChatShareMusicModel( |
||||
|
musicUrl: musicUrl, |
||||
|
musicDataUrl: musicDataUrl, |
||||
|
musicLowBandUrl: musicLowBandUrl, |
||||
|
musicLowBandDataUrl: musicLowBandDataUrl, |
||||
|
title: title ?? _appName, |
||||
|
description: description ?? _appName, |
||||
|
scene: scene, |
||||
|
messageExt: messageExt, |
||||
|
messageAction: messageAction, |
||||
|
mediaTagName: mediaTagName, |
||||
|
msgSignature: msgSignature, |
||||
|
thumbData: thumbData ?? _shareThumbnail, |
||||
|
thumbDataHash: thumbDataHash, |
||||
|
), |
||||
|
), |
||||
|
onResponse: onResponse, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Future<bool> shareVideo( |
||||
|
String videoUrl, { |
||||
|
String? title, |
||||
|
String? description, |
||||
|
WeChatScene scene = WeChatScene.session, |
||||
|
String? messageExt, |
||||
|
String? messageAction, |
||||
|
String? mediaTagName, |
||||
|
String? msgSignature, |
||||
|
Uint8List? thumbData, |
||||
|
String? thumbDataHash, |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return _shareResponse( |
||||
|
fluwx.share( |
||||
|
WeChatShareVideoModel( |
||||
|
title: title ?? _appName, |
||||
|
videoUrl: videoUrl, |
||||
|
description: description ?? _appName, |
||||
|
scene: scene, |
||||
|
messageExt: messageExt, |
||||
|
messageAction: messageAction, |
||||
|
mediaTagName: mediaTagName, |
||||
|
msgSignature: msgSignature, |
||||
|
thumbData: thumbData ?? _shareThumbnail, |
||||
|
thumbDataHash: thumbDataHash, |
||||
|
), |
||||
|
), |
||||
|
onResponse: onResponse, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Future<bool> shareWebPage( |
||||
|
String webPage, { |
||||
|
String? title, |
||||
|
String? description, |
||||
|
WeChatScene scene = WeChatScene.session, |
||||
|
String? messageExt, |
||||
|
String? messageAction, |
||||
|
String? mediaTagName, |
||||
|
String? msgSignature, |
||||
|
Uint8List? thumbData, |
||||
|
String? thumbDataHash, |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return _shareResponse( |
||||
|
fluwx.share( |
||||
|
WeChatShareWebPageModel( |
||||
|
webPage, |
||||
|
title: title ?? _appName, |
||||
|
description: description ?? _appName, |
||||
|
scene: scene, |
||||
|
messageExt: messageExt, |
||||
|
messageAction: messageAction, |
||||
|
mediaTagName: mediaTagName, |
||||
|
msgSignature: msgSignature, |
||||
|
thumbData: thumbData ?? _shareThumbnail, |
||||
|
thumbDataHash: thumbDataHash, |
||||
|
), |
||||
|
), |
||||
|
onResponse: onResponse, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Future<bool> shareFile( |
||||
|
File source, { |
||||
|
required String suffix, |
||||
|
String? title, |
||||
|
String? description, |
||||
|
WeChatScene scene = WeChatScene.session, |
||||
|
String? messageExt, |
||||
|
String? messageAction, |
||||
|
String? mediaTagName, |
||||
|
String? msgSignature, |
||||
|
Uint8List? thumbData, |
||||
|
String? thumbDataHash, |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
if (!await isInstalled) return false; |
||||
|
return _shareResponse( |
||||
|
fluwx.share( |
||||
|
WeChatShareFileModel( |
||||
|
WeChatFile.file(source, suffix: suffix), |
||||
|
title: title ?? _appName, |
||||
|
description: description ?? _appName, |
||||
|
scene: scene, |
||||
|
messageExt: messageExt, |
||||
|
messageAction: messageAction, |
||||
|
mediaTagName: mediaTagName, |
||||
|
msgSignature: msgSignature, |
||||
|
thumbData: thumbData ?? _shareThumbnail, |
||||
|
thumbDataHash: thumbDataHash, |
||||
|
), |
||||
|
), |
||||
|
onResponse: onResponse, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Future<bool> _shareResponse( |
||||
|
Future<bool> share, { |
||||
|
FlWeChatShareResponseCallback? onResponse, |
||||
|
}) async { |
||||
|
final cancelable = _onListener((response) { |
||||
|
if (response is WeChatShareResponse) onResponse?.call(response); |
||||
|
}); |
||||
|
final result = await share; |
||||
|
if (!result) cancelable.cancel(); |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class FlWXCallbackParams { |
||||
|
FlWXCallbackParams({this.onToast, this.onLog, this.onHttp}); |
||||
|
|
||||
|
/// toast 显示 |
||||
|
final FlWXToastCallback? onToast; |
||||
|
|
||||
|
/// 日志 打印 |
||||
|
final FlWXLogCallback? onLog; |
||||
|
|
||||
|
/// http 请求 返回 json |
||||
|
final FlWXHTTPCallback? onHttp; |
||||
|
} |
||||
|
|
||||
|
class WXUserModel { |
||||
|
final String? openid; |
||||
|
final String? nickname; |
||||
|
final int? sex; |
||||
|
final String? language; |
||||
|
final String? city; |
||||
|
final String? province; |
||||
|
final String? country; |
||||
|
final String? headImgUrl; |
||||
|
final List<dynamic>? privilege; |
||||
|
final String? unionId; |
||||
|
|
||||
|
WXUserModel.fromJson(Map<String, dynamic> json) |
||||
|
: openid = json['openid'] as String?, |
||||
|
nickname = json['nickname'] as String?, |
||||
|
sex = json['sex'] as int?, |
||||
|
language = json['language'] as String?, |
||||
|
city = json['city'] as String?, |
||||
|
province = json['province'] as String?, |
||||
|
country = json['country'] as String?, |
||||
|
headImgUrl = json['headimgurl'] as String?, |
||||
|
privilege = json['privilege'] as List<dynamic>?, |
||||
|
unionId = json['unionid'] as String?; |
||||
|
|
||||
|
Map<String, dynamic> toMap() => { |
||||
|
'openid': openid, |
||||
|
'unionId': unionId, |
||||
|
'nickname': nickname, |
||||
|
'sex': sex, |
||||
|
'headImgUrl': headImgUrl, |
||||
|
'privilege': privilege, |
||||
|
'language': language, |
||||
|
'city': city, |
||||
|
'province': province, |
||||
|
'country': country, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
class WXTokenModel { |
||||
|
final String? accessToken; |
||||
|
final int? expiresIn; |
||||
|
final String? refreshToken; |
||||
|
final String? openid; |
||||
|
final String? scope; |
||||
|
final String? unionId; |
||||
|
|
||||
|
WXTokenModel.fromJson(Map<String, dynamic> json) |
||||
|
: accessToken = json['access_token'] as String?, |
||||
|
expiresIn = json['expires_in'] as int?, |
||||
|
refreshToken = json['refresh_token'] as String?, |
||||
|
openid = json['openid'] as String?, |
||||
|
scope = json['scope'] as String?, |
||||
|
unionId = json['unionid'] as String?; |
||||
|
|
||||
|
Map<String, dynamic> toMap() => { |
||||
|
'openid': openid, |
||||
|
'unionId': unionId, |
||||
|
'accessToken': accessToken, |
||||
|
'expiresIn': expiresIn, |
||||
|
'refreshToken': refreshToken, |
||||
|
'scope': scope, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
extension ExtensionMap on Map { |
||||
|
Payment? toPayment() { |
||||
|
try { |
||||
|
final appId = (this['appId'] ?? this['appid']); |
||||
|
final partnerId = (this['partnerId'] ?? |
||||
|
this['partnerid'] ?? |
||||
|
this['partner']) as String?; |
||||
|
final prepayId = (this['prepayId'] ?? this['prepayid'] ?? this['prepay']); |
||||
|
final packageValue = |
||||
|
(this['packageValue'] ?? this['packagevalue'] ?? this['package']); |
||||
|
final nonceStr = (this['nonceStr'] ?? this['noncestr'] ?? this['nonce']); |
||||
|
final timestamp = (this['timestamp'] ?? this['timeStamp']); |
||||
|
final sign = this['sign']; |
||||
|
if (appId != null && |
||||
|
partnerId != null && |
||||
|
prepayId != null && |
||||
|
packageValue != null && |
||||
|
nonceStr != null && |
||||
|
timestamp != null && |
||||
|
sign != null) { |
||||
|
return Payment( |
||||
|
appId: appId.toString(), |
||||
|
partnerId: partnerId.toString(), |
||||
|
prepayId: prepayId.toString(), |
||||
|
packageValue: packageValue.toString(), |
||||
|
nonceStr: nonceStr.toString(), |
||||
|
timestamp: int.parse(timestamp!.toString()), |
||||
|
sign: sign.toString(), |
||||
|
); |
||||
|
} |
||||
|
} catch (e) { |
||||
|
FlWX()._params?.onLog?.call(e.toString()); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue