mop-flutter-sdk/lib/mop.dart

1279 lines
39 KiB
Dart
Raw Normal View History

2020-02-27 17:21:45 +08:00
import 'dart:async';
import 'package:flutter/foundation.dart';
2020-02-27 17:21:45 +08:00
import 'package:flutter/services.dart';
2020-04-26 14:57:08 +08:00
import 'package:mop/api.dart';
2020-02-27 17:21:45 +08:00
typedef MopEventCallback = void Function(dynamic event);
typedef MopEventErrorCallback = void Function(dynamic event);
2023-01-11 14:55:08 +08:00
typedef ExtensionApiHandler = Future<Map<String, dynamic>> Function(
dynamic params);
2022-11-15 22:50:41 +08:00
typedef MopAppletHandler = Future Function(dynamic params);
2020-04-26 14:57:08 +08:00
class FinStoreConfig {
2021-12-22 14:38:24 +08:00
///创建应用时生成的SDK Key
String sdkKey;
///创建应用时生成的SDK secret
String sdkSecret;
///服务器地址,客户部署的后台地址
String apiServer;
///apm统计服务器的地址,如果不填则默认与apiServer一致
String apmServer;
///网络接口加密类型默认为MD5 国密SM
String cryptType;
///SDK指纹 证联环境(https://open.fdep.cn/) 时必填,其他环境的不用填
String? fingerprint;
///是否需要接口加密验证初始化多服务器时使用默认为不开启当设置为YES时开启接口返回加密数据并处理
bool encryptServerData;
2021-12-22 14:35:51 +08:00
FinStoreConfig(this.sdkKey, this.sdkSecret, this.apiServer, this.apmServer,
{this.cryptType = "MD5",
this.fingerprint,
this.encryptServerData = false});
Map<String, dynamic> toMap() {
return {
2021-12-28 20:26:23 +08:00
"sdkKey": sdkKey,
2021-12-22 14:35:51 +08:00
"sdkSecret": sdkSecret,
"apiServer": apiServer,
"apmServer": apmServer,
"cryptType": cryptType,
"fingerprint": fingerprint,
"encryptServerData": encryptServerData
};
}
}
class FATConfig {
/**
*/
List<FinStoreConfig> storeConfigs;
/**
id->->id
userId
//退
userId
*/
String? currentUserId;
/**
finclipfinogeeksuserAgentfinogeeks
*/
String? productIdentification;
/**
SDK
trueSDK使api
*/
bool disableAuthorize = false;
/**
true
*/
bool appletAutoAuthorize = false;
/**
SDKAPIfalse
trueSDKAPI
*/
bool disableGetSuperviseInfo = false;
/**
webviewfalse,
trueHttps
*/
bool ignoreWebviewCertAuth = false;
/**
SDKwifi使x
0~5003
*/
int appletIntervalUpdateLimit = 3;
/**
apm
*/
Map<String, String>? apmExtension;
/** Crashfalse(iOS)
UnrecognizedSelectorKVONotificationTimerContainer(nil)String (nil)
便
*/
bool startCrashProtection = false;
Map? theme;
/**
*
* false
*/
bool enableApmDataCompression = false;
/**
使
YES
*/
bool encryptServerData = false;
/**
debug
FATBOOLStateUndefinedapp.json debug:true vconsole
FATBOOLStateTruevconsole
FATBOOLStateFalse
FATBOOLStateForbiddenvconsoleapi
*/
FATBOOLState enableAppletDebug = FATBOOLState.FATBOOLStateUndefined;
/**
*/
bool enableWatermark = false;
/**
*/
ConfigPriority watermarkPriority = ConfigPriority.ConfigGlobalPriority;
/**
FATBaseLoadingView
swiftSwiftDemo.FCloadingViewSwiftDemoFCloadingView
*/
String? baseLoadingViewClass;
/**
FATBaseLoadFailedView
swiftSwiftDemo.FCloadingViewSwiftDemoFCloadingView
*/
String? baseLoadFailedViewClass;
/**
header
apikey
ft.requestft.downloadFileft.uploadFile
*/
Map<String, dynamic>? header;
/**
header
*/
ConfigPriority headerPriority = ConfigPriority.ConfigGlobalPriority;
/**
H5hook
宿app http httpsH5request bodySDKhook request
body宿App宿Apprequestbody
URLProtocolbody
*/
bool enableH5AjaxHook = false;
/**
enableH5AjaxHookhook requestrequest url FinClipHookBridge-RequestId=xxx
Key FinClip-RequestIdFinClip-RequestId=xxx
*/
String? h5AjaxHookRequestKey;
/**
0
55navigateTo 4
*/
int pageCountLimit = 0;
/**
scheme
*/
List<String> schemes = [];
FATConfig(this.storeConfigs);
Map<String, dynamic> toMap() {
List<Map<String, dynamic>>? finStoreConfigs =
storeConfigs.map((e) => e.toMap()).toList();
return {
"storeConfigs": finStoreConfigs,
"currentUserId": currentUserId,
"productIdentification": productIdentification,
"disableAuthorize": disableAuthorize,
"appletAutoAuthorize": appletAutoAuthorize,
"disableGetSuperviseInfo": disableGetSuperviseInfo,
"ignoreWebviewCertAuth": ignoreWebviewCertAuth,
"appletIntervalUpdateLimit": appletIntervalUpdateLimit,
"apmExtension": apmExtension,
"enableApmDataCompression": enableApmDataCompression,
"encryptServerData": encryptServerData,
"enableAppletDebug": enableAppletDebug.index,
"enableWatermark": enableWatermark,
"watermarkPriority": watermarkPriority.index,
"baseLoadingViewClass": baseLoadingViewClass,
"baseLoadFailedViewClass": baseLoadFailedViewClass,
"header": header,
"headerPriority": headerPriority.index,
"enableH5AjaxHook": enableH5AjaxHook,
"pageCountLimit": pageCountLimit,
"schemes": schemes,
};
}
}
2021-12-22 14:35:51 +08:00
class UIConfig {
Map<String, dynamic>? navigationTitleTextAttributes; //导航栏的标题样式目前支持了font
//导航栏的高度(不含状态栏高度)默认值为44
double navigationBarHeight = 44;
//导航栏的标题颜色(深色主题),默认值为白色
int navigationBarTitleLightColor = 0xffffffff;
//导航栏的标题颜色(明亮主题),默认值为黑色
int navigationBarTitleDarkColor = 0xff000000;
//导航栏的返回按钮颜色(深色主题),默认值为白色
int navigationBarBackBtnLightColor = 0xffffffff;
//导航栏的返回按钮颜色(明亮主题),默认值为黑色
int navigationBarBackBtnDarkColor = 0xff000000;
// int? navigationBackImage;
//弹出的菜单视图的样式 0:默认 1:
int moreMenuStyle = 0;
//隐藏导航栏返回首页按钮的优先级设置,默认全局配置优先 不支持FATConfigAppletFilePriority
ConfigPriority hideBackToHomePriority = ConfigPriority.ConfigGlobalPriority;
///当导航栏为默认导航栏时,是否始终显示返回按钮 ios未发现该属性
2021-12-22 14:35:51 +08:00
bool isAlwaysShowBackInDefaultNavigationBar = false;
///是否清除导航栏导航按钮的背景 ios未发现该属性
2021-12-22 14:35:51 +08:00
bool isClearNavigationBarNavButtonBackground = false;
///是否隐藏"更多"菜单中的"反馈与投诉"菜单入口
bool isHideFeedbackAndComplaints = false;
///是否隐藏"更多"菜单中的"返回首页"菜单入口
bool isHideBackHome = false;
//隐藏...弹出菜单中的 【转发】 的菜单默认为false
2021-12-22 14:35:51 +08:00
bool isHideForwardMenu = false;
//隐藏...弹出菜单中的 【分享】 的菜单默认为true
bool isHideShareAppletMenu = true;
//隐藏...弹出菜单中的 【重新进入小程序】 的菜单默认为false
bool isHideRefreshMenu = false;
//隐藏...弹出菜单中的 【设置】 的菜单默认为false
bool isHideSettingMenu = false;
2021-12-22 14:35:51 +08:00
/// 胶囊按钮配置
CapsuleConfig? capsuleConfig;
//返回首页按钮的配置
NavHomeConfig? navHomeConfig;
2021-12-22 14:35:51 +08:00
FloatWindowConfig? floatWindowConfig;
//权限弹窗UI配置
AuthViewConfig? authViewConfig;
2021-12-22 17:32:18 +08:00
//iOS中独有的设置属性
//小程序里加载H5页面时进度条的颜色 格式 0xFFFFAA00
int? progressBarColor;
2022-01-17 15:19:11 +08:00
//隐藏小程序里加载H5时进度条默认为false
bool hideWebViewProgressBar = false;
2021-12-22 17:32:18 +08:00
//是否自适应暗黑模式。如果设置为true则更多页面、关于等原生页面会随着手机切换暗黑也自动调整为暗黑模式
bool autoAdaptDarkMode = true;
2022-01-17 15:19:11 +08:00
//要拼接的userAgent字符串
String? appendingCustomUserAgent;
/**
FATTranstionStyleUp
api
1. scheme
2. universal link
3. navigateToMiniprogram
*/
TranstionStyle transtionStyle = TranstionStyle.TranstionStyleUp;
/// 加载小程序过程中小程序Service层还未加载成功基础库还没有向SDK传递小程序配置信息是否隐藏导航栏的关闭按钮
bool hideTransitionCloseButton = false;
/**
NO
*/
bool disableSlideCloseAppletGesture = false;
2021-12-22 17:32:18 +08:00
//注入小程序统称appletText字符串默认为“小程序”。
String? appletText;
2021-12-22 14:35:51 +08:00
Map<String, dynamic> toMap() {
return {
"navigationTitleTextAttributes": navigationTitleTextAttributes,
"navigationBarHeight": navigationBarHeight,
"navigationBarTitleLightColor": navigationBarTitleLightColor,
"navigationBarTitleDarkColor": navigationBarTitleDarkColor,
"navigationBarBackBtnLightColor": navigationBarBackBtnLightColor,
"navigationBarBackBtnDarkColor": navigationBarBackBtnDarkColor,
2021-12-22 14:35:51 +08:00
"isAlwaysShowBackInDefaultNavigationBar":
isAlwaysShowBackInDefaultNavigationBar,
"isClearNavigationBarNavButtonBackground":
isClearNavigationBarNavButtonBackground,
"isHideFeedbackAndComplaints": isHideFeedbackAndComplaints,
"isHideBackHome": isHideBackHome,
"isHideForwardMenu": isHideForwardMenu,
"isHideRefreshMenu": isHideRefreshMenu,
"isHideShareAppletMenu": isHideShareAppletMenu,
"isHideSettingMenu": isHideSettingMenu,
2021-12-22 14:35:51 +08:00
"hideTransitionCloseButton": hideTransitionCloseButton,
"capsuleConfig": capsuleConfig?.toMap(),
"navHomeConfig": navHomeConfig?.toMap(),
"authViewConfig": authViewConfig?.toMap(),
2021-12-22 14:35:51 +08:00
"floatWindowConfig": floatWindowConfig?.toMap(),
2021-12-22 17:32:18 +08:00
"progressBarColor": progressBarColor,
"hideWebViewProgressBar": hideWebViewProgressBar,
"moreMenuStyle": moreMenuStyle,
"hideBackToHomePriority": hideBackToHomePriority.index,
2021-12-22 17:32:18 +08:00
"autoAdaptDarkMode": autoAdaptDarkMode,
"appendingCustomUserAgent": appendingCustomUserAgent,
"transtionStyle": transtionStyle.index,
"disableSlideCloseAppletGesture": disableSlideCloseAppletGesture,
2021-12-22 17:32:18 +08:00
"appletText": appletText
2021-12-22 14:35:51 +08:00
};
}
}
2021-12-22 14:35:51 +08:00
/// 胶囊按钮配置
class CapsuleConfig {
/// 上角胶囊视图的宽度默认值为88
double capsuleWidth = 88;
///上角胶囊视图的高度默认值为32
double capsuleHeight = 32;
///右上角胶囊视图的右边距
double capsuleRightMargin = 7;
///右上角胶囊视图的圆角半径默认值为5
double capsuleCornerRadius = 5;
///右上角胶囊视图的边框宽度默认值为0.8
double capsuleBorderWidth = 1;
///胶囊背景颜色浅色
int capsuleBgLightColor = 0x33000000;
///胶囊背景颜色深色
int capsuleBgDarkColor = 0x80ffffff;
/// 右上角胶囊视图的边框浅色颜色
int capsuleBorderLightColor = 0x80ffffff;
///右上角胶囊视图的边框深色颜色
int capsuleBorderDarkColor = 0x26000000;
///胶囊分割线浅色颜色
int capsuleDividerLightColor = 0x80ffffff;
///胶囊分割线深色颜色
int capsuleDividerDarkColor = 0x26000000;
///胶囊里的浅色更多按钮的图片对象,如果不传,会使用默认图标
int? moreLightImage;
///胶囊里的深色更多按钮的图片对象,如果不传,会使用默认图标
int? moreDarkImage;
2021-12-22 14:35:51 +08:00
///胶囊里的更多按钮的宽度,高度与宽度相等
double moreBtnWidth = 32;
///胶囊里的更多按钮的左边距
double moreBtnLeftMargin = 6;
///胶囊里的浅色更多按钮的图片对象,如果不传,会使用默认图标
int? closeLightImage;
///胶囊里的深色更多按钮的图片对象,如果不传,会使用默认图标
int? closeDarkImage;
///胶囊里的关闭按钮的宽度,高度与宽度相等
double closeBtnWidth = 32;
///胶囊里的关闭按钮的左边距
double closeBtnLeftMargin = 6;
Map<String, dynamic> toMap() {
return {
"capsuleWidth": capsuleWidth,
"capsuleHeight": capsuleHeight,
"capsuleRightMargin": capsuleRightMargin,
"capsuleCornerRadius": capsuleCornerRadius,
"capsuleBorderWidth": capsuleBorderWidth,
"capsuleBgLightColor": capsuleBgLightColor,
"capsuleBgDarkColor": capsuleBgDarkColor,
"capsuleBorderLightColor": capsuleBorderLightColor,
"capsuleBorderDarkColor": capsuleBorderDarkColor,
"capsuleDividerLightColor": capsuleDividerLightColor,
"capsuleDividerDarkColor": capsuleDividerDarkColor,
"moreLightImage": moreLightImage,
"moreDarkImage": moreDarkImage,
"moreBtnWidth": moreBtnWidth,
"moreBtnLeftMargin": moreBtnLeftMargin,
"closeLightImage": closeLightImage,
"closeDarkImage": closeDarkImage,
"closeBtnWidth": closeBtnWidth,
"closeBtnLeftMargin": closeBtnLeftMargin,
};
}
}
class FloatWindowConfig {
bool floatMode = false;
int x;
int y;
int width;
int height;
FloatWindowConfig(this.floatMode, this.x, this.y, this.width, this.height);
Map<String, dynamic> toMap() {
return {
"floatMode": floatMode,
"x": x,
"y": y,
"width": width,
"height": height
};
}
}
class NavHomeConfig {
/**
*/
double width;
/**
*/
double height;
/**
10
*/
double leftMargin = 10;
/**
5
*/
double cornerRadius = 5;
/**
0.8
*/
double borderWidth = 0.8;
/**
*/
int borderLightColor;
/**
*/
int borderDarkColor;
/**
*/
int bgLightColor;
/**
*/
int bgDarkColor;
NavHomeConfig(this.width, this.height, this.borderLightColor,
this.borderDarkColor, this.bgLightColor, this.bgDarkColor);
Map<String, dynamic> toMap() {
return {
"width": width,
"height": height,
"leftMargin": leftMargin,
"cornerRadius": cornerRadius,
"borderWidth": borderWidth,
"borderLightColor": borderLightColor,
"borderDarkColor": borderDarkColor,
"bgLightColor": bgLightColor,
"bgDarkColor": bgDarkColor,
};
}
}
class AuthViewConfig {
/**
PingFangSC-Regular16
*/
int appletNameFont = 16;
/**
#202020
*/
int appletNameLightColor = 0xff202020;
/**
#D0D0D0
*/
int appletNameDarkColor = 0xffd0d0d0;
/**
PingFangSC-Medium17
使PingFangSC-Regular
*/
int authorizeTitleFont = 17;
/**
#202020
使
*/
int authorizeTitleLightColor = 0xff202020;
/**
#D0D0D0
使
*/
int authorizeTitleDarkColor = 0xffd0d0d0;
/**
PingFangSC-Regular14
*/
int authorizeDescriptionFont = 14;
/**
#666666
*/
int authorizeDescriptionLightColor = 0xff666666;
/**
#8C8C8C
*/
int authorizeDescriptionDarkColor = 0xff8c8c8c;
/**
PingFangSC-Regular16
*/
int agreementTitleFont = 16;
/**
#202020
*/
int agreementTitleLightColor = 0xff202020;
/**
#D0D0D0
*/
int agreementTitleDarkColor = 0xffd0d0d0;
/**
PingFangSC-Regular14
*/
int agreementDescriptionFont = 14;
/**
#202020
*/
int agreementDescriptionLightColor = 0xff202020;
/**
#D0D0D0
*/
int agreementDescriptionDarkColor = 0xffd0d0d0;
/**
#409EFF
*/
int linkLightColor = 0xff409eff;
/**
#368CE4
*/
int linkDarkColor = 0xff368ce4;
/**
4
#4285F4
#4285F4
#FFFFFF
#3B77DB
#3B77DB
#FFFFFF
*/
AuthButtonConfig? allowButtonLightConfig;
/**
4
#4285F4
#4285F4
#FFFFFF
#5E97F5
#5E97F5
#FFFFFF
*/
AuthButtonConfig? allowButtonDarkConfig;
/**
4
#FFFFFF
#E2E2E2
#222222
#D8D8D8
#D8D8D8
#222222
*/
AuthButtonConfig? rejectButtonLightConfig;
/**
4
#2C2C2C
#2C2C2C
#D0D0D0
#414141
#414141
#D0D0D0
*/
AuthButtonConfig? rejectButtonDarkConfig;
Map<String, dynamic> toMap() {
return {
"appletNameFont": appletNameFont,
"appletNameLightColor": appletNameLightColor,
"appletNameDarkColor": appletNameDarkColor,
"authorizeTitleFont": authorizeTitleFont,
"authorizeTitleLightColor": authorizeTitleLightColor,
"authorizeTitleDarkColor": authorizeTitleDarkColor,
"authorizeDescriptionFont": authorizeDescriptionFont,
"authorizeDescriptionLightColor": authorizeDescriptionLightColor,
"authorizeDescriptionDarkColor": authorizeDescriptionDarkColor,
"agreementTitleFont": agreementTitleFont,
"agreementTitleLightColor": agreementTitleLightColor,
"agreementTitleDarkColor": agreementTitleDarkColor,
"agreementDescriptionFont": agreementDescriptionFont,
"agreementDescriptionDarkColor": agreementDescriptionDarkColor,
"linkLightColor": linkLightColor,
"linkDarkColor": linkDarkColor,
"allowButtonLightConfig": allowButtonLightConfig?.toMap(),
"allowButtonDarkConfig": allowButtonDarkConfig?.toMap(),
"rejectButtonLightConfig": rejectButtonLightConfig?.toMap(),
"rejectButtonDarkConfig": rejectButtonDarkConfig?.toMap(),
};
}
}
class AuthButtonConfig {
/**
*/
double cornerRadius;
/**
*/
int normalBackgroundColor;
/**
*/
int pressedBackgroundColor;
/**
*/
int normalTextColor;
/**
*/
int pressedTextColor;
/**
*/
int normalBorderColor;
/**
*/
int pressedBorderColor;
AuthButtonConfig(
this.cornerRadius,
this.normalBackgroundColor,
this.pressedBackgroundColor,
this.normalTextColor,
this.pressedTextColor,
this.normalBorderColor,
this.pressedBorderColor);
Map<String, dynamic> toMap() {
return {
"cornerRadius": cornerRadius,
"normalBackgroundColor": normalBackgroundColor,
"pressedBackgroundColor": pressedBackgroundColor,
"normalTextColor": normalTextColor,
"pressedTextColor": pressedTextColor,
"normalBorderColor": normalBorderColor,
"pressedBorderColor": pressedBorderColor
};
}
}
2022-07-29 22:31:56 +08:00
class BaseAppletRequest {
// 服务器地址,必填
String apiServer;
// 小程序id必填
String appletId;
// 小程序的启动参数,非必填
Map<String, String>? startParams;
// iOS端打开小程序时是否显示动画默认为true。
bool? animated;
2022-09-28 14:49:41 +08:00
// 是否以单进程模式运行仅限android默认为false
bool isSingleProcess;
2022-07-29 22:31:56 +08:00
BaseAppletRequest({
2022-09-28 14:49:41 +08:00
required this.apiServer,
2022-07-29 22:31:56 +08:00
required this.appletId,
this.startParams,
this.animated = true,
2022-09-28 14:49:41 +08:00
this.isSingleProcess = false,
2023-01-11 14:55:08 +08:00
});
2022-07-29 22:31:56 +08:00
Map<String, dynamic> toMap() {
return {
"apiServer": apiServer,
"appletId": appletId,
"startParams": startParams,
2022-09-28 14:49:41 +08:00
"animated": animated,
"isSingleProcess": isSingleProcess,
2022-07-29 22:31:56 +08:00
};
}
}
class RemoteAppletRequest {
// 服务器地址,必填
String apiServer;
// 小程序id必填
String appletId;
// 小程序的启动参数,非必填
Map<String, String>? startParams;
// 小程序的索引,(审核小程序时必填)
int? sequence;
// 离线小程序压缩包路径,非必填
String? offlineMiniprogramZipPath;
// 离线基础库压缩包路径,非必填
String? offlineFrameworkZipPath;
// iOS端打开小程序时是否显示动画默认为true。
bool animated;
2022-09-28 14:49:41 +08:00
// 是否以单进程模式运行仅限android默认为false
bool isSingleProcess;
2022-07-29 22:31:56 +08:00
RemoteAppletRequest({
2022-09-28 14:49:41 +08:00
required this.apiServer,
2022-07-29 22:31:56 +08:00
required this.appletId,
this.startParams,
this.sequence,
this.offlineMiniprogramZipPath,
this.offlineFrameworkZipPath,
this.animated = true,
2022-09-28 14:49:41 +08:00
this.isSingleProcess = false,
2023-01-11 14:55:08 +08:00
});
2022-07-29 22:31:56 +08:00
@override
Map<String, dynamic> toMap() {
Map<String, dynamic> result = {
"apiServer": apiServer,
"appletId": appletId,
2022-09-28 14:49:41 +08:00
"animated": animated,
"isSingleProcess": isSingleProcess,
2022-07-29 22:31:56 +08:00
};
if (startParams != null) result["startParams"] = startParams;
2023-01-11 14:55:08 +08:00
if (offlineMiniprogramZipPath != null)
result["offlineMiniprogramZipPath"] = offlineMiniprogramZipPath;
if (offlineFrameworkZipPath != null)
result["offlineFrameworkZipPath"] = offlineFrameworkZipPath;
2022-07-29 22:31:56 +08:00
if (sequence != null) result["sequence"] = sequence;
return result;
}
}
class QRCodeAppletRequest {
// 二维码内容
String qrCode;
// 是否显示打开动画
bool animated = true;
2022-09-28 14:49:41 +08:00
// 是否以单进程模式运行仅限android默认为false
bool isSingleProcess;
2022-07-29 22:31:56 +08:00
2022-09-28 14:49:41 +08:00
QRCodeAppletRequest(this.qrCode, {this.isSingleProcess = false});
2022-07-29 22:31:56 +08:00
Map<String, dynamic> toMap() {
return {
"apiServer": qrCode,
2022-09-28 14:49:41 +08:00
"animated": animated,
"isSingleProcess": isSingleProcess,
2022-07-29 22:31:56 +08:00
};
}
}
2021-12-22 14:35:51 +08:00
enum Anim {
SlideFromLeftToRightAnim,
SlideFromRightToLeftAnim,
SlideFromTopToBottomAnim,
SlideFromBottomToTopAnim,
FadeInAnim,
NoneAnim
}
enum ConfigPriority {
ConfigGlobalPriority, //全局配置优先
ConfigSpecifiedPriority, // 单个配置优先
ConfigAppletFilePriority, // 小程序配置文件优先小程序app.ext.json文件中配置
}
enum TranstionStyle {
TranstionStyleUp, // 页面从下往上弹出类似present效果
TranstionStylePush, // 页面从右往左弹出类似push效果
}
enum FATBOOLState {
FATBOOLStateUndefined, // 未设置
FATBOOLStateTrue, // 所有版本强制开启vconsole且不可调api关闭更多面板不展示打开、关闭调试菜单
FATBOOLStateFalse, // 正式版更多面板不展示打开、关闭调试菜单非正式版更多面板展示打开、关闭调试菜单所有版本均可调setEnableDebug开启vconsole。
FATBOOLStateForbidden, // 所有版本强制关闭vconsole且不可调api开启多面板不展示打开、关闭调试菜单
}
2020-02-27 17:21:45 +08:00
class Mop {
static final Mop _instance = new Mop._internal();
2021-08-18 22:10:15 +08:00
late MethodChannel _channel;
late EventChannel _mopEventChannel;
late int eventId = 0;
2021-10-10 23:50:23 +08:00
final List<Map<String, dynamic>> _mopEventQueye = <Map<String, dynamic>>[];
2020-04-01 14:44:01 +08:00
2022-11-15 22:50:41 +08:00
final Map<String, MopAppletHandler> _appletHandlerApis = {};
2021-10-10 23:50:23 +08:00
final Map<String, ExtensionApiHandler> _extensionApis = {};
2020-04-26 14:57:08 +08:00
Map<String, ExtensionApiHandler> _webExtensionApis = {};
2020-04-26 14:57:08 +08:00
2020-02-27 17:21:45 +08:00
factory Mop() {
return _instance;
}
2020-04-01 14:44:01 +08:00
2020-02-27 17:21:45 +08:00
Mop._internal() {
2021-10-10 23:50:23 +08:00
debugPrint('mop: _internal');
2020-02-27 17:21:45 +08:00
// init
2021-10-10 23:50:23 +08:00
_channel = const MethodChannel('mop');
2020-04-26 14:57:08 +08:00
_channel.setMethodCallHandler(_handlePlatformMethodCall);
2021-12-22 14:35:51 +08:00
_mopEventChannel =
const EventChannel('plugins.mop.finogeeks.com/mop_event');
2020-02-27 17:21:45 +08:00
_mopEventChannel.receiveBroadcastStream().listen((dynamic value) {
2021-10-10 23:50:23 +08:00
debugPrint('matrix: receiveBroadcastStream $value');
2020-02-27 17:21:45 +08:00
for (Map m in _mopEventQueye) {
if (m['event'] == value['event']) {
m['MopEventCallback'](value['body']);
}
}
}, onError: (dynamic value) {
// failure(value);
});
}
2020-04-01 14:44:01 +08:00
2020-02-27 17:21:45 +08:00
static Mop get instance => _instance;
Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
2020-04-26 14:57:08 +08:00
Future<dynamic> _handlePlatformMethodCall(MethodCall call) async {
2021-10-10 23:50:23 +08:00
debugPrint("_handlePlatformMethodCall: method:${call.method}");
2020-04-26 14:57:08 +08:00
if (call.method.startsWith("extensionApi:")) {
final name = call.method.substring("extensionApi:".length);
final handler = _extensionApis[name];
2022-05-18 11:00:32 +08:00
debugPrint("name:$name,handler:$handler");
2020-04-26 14:57:08 +08:00
if (handler != null) {
return await handler(call.arguments);
}
2023-01-11 14:55:08 +08:00
2022-11-15 22:50:41 +08:00
final apiHandler = _appletHandlerApis[name];
2023-01-11 14:55:08 +08:00
if (apiHandler != null) {
2022-11-15 22:50:41 +08:00
return await apiHandler(call.arguments);
}
} else if (call.method.startsWith("webExtentionApi:")) {
final name = call.method.substring("webExtentionApi:".length);
final handler = _webExtensionApis[name];
if (handler != null) {
return await handler(call.arguments);
}
}
2020-04-26 14:57:08 +08:00
}
2020-02-27 17:21:45 +08:00
///
///
/// initialize mop miniprogram engine.
/// 初始化小程序
2021-12-22 14:35:51 +08:00
/// [sdkkey] is required. it can be getted from api.finclip.com
2021-01-12 15:24:37 +08:00
/// [secret] is required. it can be getted from api.finclip.com
2020-02-27 17:21:45 +08:00
/// [apiServer] is optional. the mop server address. default is https://mp.finogeek.com
/// [apiPrefix] is optional. the mop server prefix. default is /api/v1/mop
2020-05-19 16:42:10 +08:00
/// [cryptType] is optional. cryptType, should be MD5/SM
2020-07-27 09:13:55 +08:00
/// [disablePermission] is optional.
2021-12-22 14:35:51 +08:00
/// [encryptServerData] 是否对服务器数据进行加密,需要服务器支持
/// [userId] 用户id
/// [finStoreConfigs] 多服务配置
/// [uiConfig] UI配置
/// [config] 小程序相关配置
2021-12-22 14:35:51 +08:00
/// [debug] 设置debug模式影响调试和日志
/// [customWebViewUserAgent] 设置自定义webview ua
/// [appletIntervalUpdateLimit] 设置小程序批量更新周期
/// [maxRunningApplet] 设置最大同时运行小程序个数
2020-02-27 17:21:45 +08:00
///
2021-12-22 14:35:51 +08:00
Future<Map> initialize(
String sdkkey,
String secret, {
String? apiServer,
String? apiPrefix,
String? cryptType,
bool encryptServerData = false,
bool disablePermission = false,
String? userId,
bool debug = false,
bool bindAppletWithMainProcess = false,
2022-05-11 14:58:49 +08:00
int? pageCountLimit = 0,
2021-12-22 14:35:51 +08:00
List<FinStoreConfig>? finStoreConfigs,
UIConfig? uiConfig,
String? customWebViewUserAgent,
2022-01-05 15:24:31 +08:00
int? appletIntervalUpdateLimit,
int? maxRunningApplet,
2021-12-22 14:35:51 +08:00
}) async {
2021-12-28 20:26:23 +08:00
List<Map<String, dynamic>>? storeConfigs =
finStoreConfigs?.map((e) => e.toMap()).toList();
2020-02-27 17:21:45 +08:00
final Map ret = await _channel.invokeMethod('initialize', {
2021-12-22 14:35:51 +08:00
'appkey': sdkkey,
2020-02-27 17:21:45 +08:00
'secret': secret,
'apiServer': apiServer,
2020-05-19 16:42:10 +08:00
'apiPrefix': apiPrefix,
2020-07-27 09:13:55 +08:00
'cryptType': cryptType,
2021-12-22 14:35:51 +08:00
"encryptServerData": encryptServerData,
2021-06-02 11:33:07 +08:00
'disablePermission': disablePermission,
'userId': userId,
2021-08-25 22:03:04 +08:00
"debug": debug,
2021-12-22 14:35:51 +08:00
"bindAppletWithMainProcess": bindAppletWithMainProcess,
2022-05-11 14:58:49 +08:00
"pageCountLimit": pageCountLimit,
2021-12-28 20:26:23 +08:00
"finStoreConfigs": storeConfigs,
2021-12-22 14:35:51 +08:00
"uiConfig": uiConfig?.toMap(),
"customWebViewUserAgent": customWebViewUserAgent,
"appletIntervalUpdateLimit": appletIntervalUpdateLimit,
"maxRunningApplet": maxRunningApplet
2020-02-27 17:21:45 +08:00
});
return ret;
}
Future<Map> initSDK(FATConfig config, {UIConfig? uiConfig}) async {
final Map ret = await _channel.invokeMethod('initSDK', {
'config': config.toMap(),
'uiConfig': uiConfig?.toMap(),
});
return ret;
}
2020-02-27 17:21:45 +08:00
/// open the miniprogram [appId] from the mop server.
/// 打开小程序
/// [appId] is required.
/// [path] is miniprogram open path. example /pages/index/index
/// [query] is miniprogram query parameters. example key1=value1&key2=value2
2020-12-04 09:09:53 +08:00
/// [sequence] is miniprogram sequence. example 0,1.2.3,4,5...
/// [apiServer] is optional. the mop server address. default is https://mp.finogeek.com
/// [apiPrefix] is optional. the mop server prefix. default is /api/v1/mop
/// [fingerprint] is optional. the mop sdk fingerprint. is nullable
/// [cryptType] is optional. cryptType, should be MD5/SM
Future<Map> openApplet(
final String appId, {
2021-12-22 14:35:51 +08:00
final String? path,
final String? query,
final int? sequence,
final String? apiServer,
final String? scene,
2022-09-28 14:49:41 +08:00
final bool isSingleProcess = false,
}) async {
2020-04-26 14:57:08 +08:00
Map<String, Object> params = {'appId': appId};
Map param = {};
if (path != null) param["path"] = path;
if (query != null) param["query"] = query;
if (param.length > 0) params["params"] = param;
2020-04-01 14:44:01 +08:00
if (sequence != null) params["sequence"] = sequence;
if (apiServer != null) params["apiServer"] = apiServer;
2021-07-27 10:39:26 +08:00
if (scene != null) param["scene"] = scene;
2022-09-28 14:49:41 +08:00
params["isSingleProcess"] = isSingleProcess;
2020-02-27 17:21:45 +08:00
final Map ret = await _channel.invokeMethod('openApplet', params);
return ret;
}
2020-04-26 14:57:08 +08:00
2022-07-29 22:31:56 +08:00
Future<Map> startApplet(RemoteAppletRequest request) async {
Map<String, dynamic> params = request.toMap();
final Map ret = await _channel.invokeMethod('startApplet', params);
return ret;
}
2020-04-26 14:57:08 +08:00
///
/// get current using applet
/// 获取当前正在使用的小程序信息
/// {appId,name,icon,description,version,thumbnail}
///
///
Future<Map<String, dynamic>> currentApplet() async {
final ret = await _channel.invokeMapMethod("currentApplet");
2021-08-18 22:10:15 +08:00
return Map<String, dynamic>.from(ret!);
2020-04-26 14:57:08 +08:00
}
2022-05-22 17:37:26 +08:00
Future<Map<String, dynamic>> changeUserId(String userId) async {
Map<String, Object> params = {'userId': userId};
final ret = await _channel.invokeMapMethod("changeUserId", params);
return Map<String, dynamic>.from(ret!);
}
2020-04-26 14:57:08 +08:00
///
/// close all running applets
/// 关闭当前打开的所有小程序
///
Future closeAllApplets() async {
return await _channel.invokeMethod("closeAllApplets");
}
///
/// clear applets cache
/// 清除缓存的小程序
///
Future clearApplets() async {
return await _channel.invokeMethod("clearApplets");
}
/// 清除指定的小程序本体缓存
Future removeUsedApplet(String appId) async {
Map<String, Object> params = {'appId': appId};
return await _channel.invokeMethod("removeUsedApplet", params);
}
2022-05-19 17:09:22 +08:00
/// 清除所有小程序缓存
Future removeAllUsedApplets() async {
Map<String, Object> params = {};
return await _channel.invokeMethod("removeAllUsedApplets", params);
}
2020-07-22 15:30:54 +08:00
///
/// 获取运行时版本号
///
Future<String> sdkVersion() async {
return await _channel
.invokeMapMethod("sdkVersion")
2021-08-18 22:10:15 +08:00
.then((value) => value?["data"]);
2020-07-22 15:30:54 +08:00
}
2021-06-07 18:53:00 +08:00
///
/// (扫码后)解密-鉴权-打开小程序
///
2022-09-28 14:49:41 +08:00
Future scanOpenApplet(String info, {bool isSingleProcess = false}) async {
Map<String, Object> params = {
'info': info,
'isSingleProcess': isSingleProcess,
};
return await _channel.invokeMapMethod("scanOpenApplet", params);
2021-06-07 18:53:00 +08:00
}
2022-01-17 15:19:11 +08:00
///
/// 通过二维码打开小程序
/// [qrcode] 二维码内容
///
2022-09-28 14:49:41 +08:00
Future qrcodeOpenApplet(String qrcode, {bool isSingleProcess = false}) async {
Map<String, Object> params = {
'qrcode': qrcode,
'isSingleProcess': isSingleProcess,
};
2021-12-29 10:11:50 +08:00
return await _channel.invokeMapMethod("qrcodeOpenApplet", params);
}
///
/// 根据微信QrCode信息解析小程序信息
///
Future<Map<String, dynamic>> parseAppletInfoFromWXQrCode(
String qrCode, String apiServer) async {
final ret = await _channel.invokeMapMethod("parseAppletInfoFromWXQrCode",
{"qrCode": qrCode, "apiServer": apiServer});
2021-08-18 22:10:15 +08:00
return Map<String, dynamic>.from(ret!);
}
2021-06-07 18:53:00 +08:00
2020-04-26 14:57:08 +08:00
///
/// register handler to provide custom info or behaviour
/// 注册小程序事件处理
///
void registerAppletHandler(AppletHandler handler) {
2022-11-15 22:50:41 +08:00
_appletHandlerApis["forwardApplet"] = (params) async {
2020-11-27 17:15:32 +08:00
handler.forwardApplet(Map<String, dynamic>.from(params));
2020-04-26 14:57:08 +08:00
};
2022-11-15 22:50:41 +08:00
_appletHandlerApis["getUserInfo"] = (params) {
2020-04-26 14:57:08 +08:00
return handler.getUserInfo();
};
2022-11-15 22:50:41 +08:00
_appletHandlerApis["getCustomMenus"] = (params) async {
2020-04-26 14:57:08 +08:00
final res = await handler.getCustomMenus(params["appId"]);
2021-03-02 14:04:51 +08:00
List<Map<String, dynamic>> list = [];
2021-08-18 22:19:26 +08:00
res.forEach((element) {
2021-03-02 14:04:51 +08:00
Map<String, dynamic> map = Map();
map["menuId"] = element.menuId;
map["image"] = element.image;
map["title"] = element.title;
map["type"] = element.type;
list.add(map);
});
2021-10-10 23:50:23 +08:00
debugPrint("registerAppletHandler getCustomMenus list $list");
2021-03-02 14:04:51 +08:00
return list;
2020-04-26 14:57:08 +08:00
};
2022-11-15 22:50:41 +08:00
_appletHandlerApis["onCustomMenuClick"] = (params) async {
2021-03-02 14:04:51 +08:00
return handler.onCustomMenuClick(
2023-01-11 14:55:08 +08:00
params["appId"],
params["path"],
params["menuId"],
params["appInfo"],
);
2020-04-26 14:57:08 +08:00
};
2022-11-15 22:50:41 +08:00
_appletHandlerApis["appletDidOpen"] = (params) async {
return handler.appletDidOpen(params["appId"]);
};
2022-11-15 22:50:41 +08:00
_appletHandlerApis["getPhoneNumber"] = (params) async {
2022-05-18 11:00:32 +08:00
return handler.getMobileNumber((params0) =>
{_channel.invokeMethod("getPhoneNumberResult", params0)});
};
2020-04-26 14:57:08 +08:00
_channel.invokeMethod("registerAppletHandler");
}
///
/// register extension api
/// 注册拓展api
///
void registerExtensionApi(String name, ExtensionApiHandler handler) {
_extensionApis[name] = handler;
_channel.invokeMethod("registerExtensionApi", {"name": name});
}
2021-04-21 21:19:48 +08:00
/// 获取国密加密
Future<String> getSMSign(String plainText) async {
var result =
await _channel.invokeMapMethod("smsign", {'plainText': plainText});
2021-08-18 22:10:15 +08:00
var data = result?['data']['data'];
2021-10-10 23:50:23 +08:00
debugPrint(data);
2021-04-21 21:19:48 +08:00
return data;
}
/// WKWebView的弹性设置
void webViewBounces(bool bounces) async {
await _channel.invokeMapMethod("webViewBounces", {'bounces': bounces});
return;
}
2022-01-17 15:19:11 +08:00
///
/// 关闭小程序 小程序会在内存中存在
///
Future<void> closeApplet(String appletId, bool animated) async {
await _channel.invokeMethod(
"closeApplet", {"appletId": appletId, "animated": animated});
return;
}
2022-01-17 15:19:11 +08:00
///
/// 结束小程序 小程序会从内存中清除
///
Future<void> finishRunningApplet(String appletId, bool animated) async {
await _channel.invokeMethod(
"finishRunningApplet", {"appletId": appletId, "animated": animated});
return;
}
2022-01-17 15:19:11 +08:00
///
/// 设置小程序切换动画 安卓
///
2021-12-22 14:35:51 +08:00
Future setActivityTransitionAnim(Anim anim) async {
2023-01-11 14:55:08 +08:00
await _channel.invokeMethod("setActivityTransitionAnim", {"anim": ""});
return;
}
2022-05-18 11:00:32 +08:00
2022-01-17 15:19:11 +08:00
///
/// 原生发送事件给小程序
/// [appId] 小程序id
/// [eventData] 事件对象
2021-12-22 14:35:51 +08:00
Future<void> sendCustomEvent(
String appId, Map<String, dynamic> eventData) async {
await _channel.invokeMethod(
"sendCustomEvent", {"appId": appId, "eventData": eventData});
return;
}
2022-01-17 15:19:11 +08:00
///
/// 原生调用webview中的js方法
/// [appId] 小程序id
/// [eventName] 方法名
/// [nativeViewId] webviewId
/// [eventData] 参数
///
2021-12-22 14:35:51 +08:00
Future<void> callJS(String appId, String eventName, String nativeViewId,
Map<String, dynamic> eventData) async {
await _channel.invokeMethod("callJS", {
2021-12-22 14:35:51 +08:00
"appId": appId,
"eventName": eventName,
"nativeViewId": nativeViewId,
"eventData": eventData
});
return;
}
2022-01-17 15:19:11 +08:00
///
/// register webview extension api
/// 注册webview拓展api
///
void addWebExtentionApi(String name, ExtensionApiHandler handler) {
_webExtensionApis[name] = handler;
_channel.invokeMethod("addWebExtentionApi", {"name": name});
}
///
/// 将当前正在运行的最后一个打开的小程序移至任务栈前台
///
void moveCurrentAppletToFront() async {
return await _channel.invokeMethod("moveCurrentAppletToFront");
}
2020-02-27 17:21:45 +08:00
}