自己的烂笔头 他人看不懂 莫看
main 入口
runApp(const MyApp());
修改为
FairApp.runApplication(
FairApp(
// generated: g.AppGeneratedModule(),
generated: AppGeneratedModule(),
delegate: <String, FairDelegateBuilder>{
'TestPage': (context, data) => TestPageFairDelegate(),
'HotUpdateIssue': (context, data) => HotUpdateIssueDelegate(),
'HotUpdate': (context, data) => HotUpdateDelegate(),
},
dynamicWidgetBuilder: [
(proxyMirror, page, bound, {bundle}) => CustomDynamicWidgetBuilder(proxyMirror, page, bound, bundle: bundle)
],
child: MyApp(),
// httpDecoder:DefaultHttpDecoder(),
),
plugins: <String, IFairPlugin>{'FairCommonPlugin': FairCommonPlugin()});
自定义的js解析器
///生成项目组件的映射 g.AppGeneratedModule()
@FairBinding(packages: [
'package:cses_saas/widgets/button/radius_inkwell_widget.dart',
'package:cses_saas/modules/mutualism/task/create_task/widget/item_priority.dart',
])
void main() async {
FairJSDecoder.resolve = (String? jsPath) async {
return CustomFairJSDecoder().decode(jsPath);
};
}
自定义的解析器 json 和 js 和
import 'dart:convert';
import 'package:cses_saas/cses_saas.dart';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:dio/dio.dart';
import 'dart:io';
import 'package:fair/src/internal/bundle_provider.dart';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
import 'package:fair/src/internal/fair_decoder.dart';
///自定义的解析json
class CustomDynamicWidgetBuilder extends DynamicWidgetBuilder {
CustomDynamicWidgetBuilder(
super.proxyMirror,
super.page,
super.bound, {
super.bundle,
});
@override
dynamic convert(BuildContext context, Map map, Map? methodMap, {Domain? domain}) {
var name = map[tag];
///tag的本质是传入的className
if (name == "data") {
print("=====================api${map}========================");
return;
}
if (name == "Tab") {
print("=====================api${Tab}========================");
return;
}
print(
"解析的 methodMap$methodMap =========map$map========== ${name}=========================== ${domain}===================");
return super.convert(context, map, methodMap, domain: domain);
}
}
Map<String?, String> _cache = <String?, String>{};
Map<String?, Map?> _cacheJson = <String?, Map?>{};
/// 自定义 js 获取方式
class CustomFairJSDecoder with FairBundlePathCheck {
factory CustomFairJSDecoder() => _customFairJSDecoder;
CustomFairJSDecoder._();
static final CustomFairJSDecoder _customFairJSDecoder = CustomFairJSDecoder._();
static const BYTES_LIMIT = 10 * 1024;
static const STRING_LIMIT = 10 * 1024 / 8;
Future<String> _decode(String? url) async {
var start = DateTime.now().millisecondsSinceEpoch;
// var response = await HttpManager().get(Uri.parse(url??''));
var response = await Dio().get(url ?? '');
var end = DateTime.now().millisecondsSinceEpoch;
print('end1 ${end - start}');
if (response.statusCode != 200) {
throw FlutterError('加载JS网络路径Code =${response.statusCode},RemoteUrl: $url');
}
var end2 = DateTime.now().millisecondsSinceEpoch;
print('end ${end2 - start}');
var data = response.data;
if (data == null) {
throw FlutterError('bodyBytes=null, RemoteUrl : $url');
}
//解析字节流
return _resolveResult(data);
}
Future<String> _resolveResult(dynamic data) async {
String result;
if (data is Uint8List) {
if (data.lengthInBytes < BYTES_LIMIT) {
result = utf8.decode(data);
} else {
result = await compute(_toString, data, debugLabel: 'json decode');
}
} else {
result = data as String;
}
return result;
}
String _toString(Uint8List data) {
return utf8.decode(data);
}
Future<String> _resolveAssert(String? assertPath) async {
if (isExternalStoragePath(assertPath)) {
var file = File(assertPath ?? '');
return await file.readAsString();
}
return rootBundle.loadString(assertPath ?? '');
}
Future<String> _resolve(String? path) async {
if (path?.startsWith('http') == true) {
return await _decode(path);
} else {
//10kb以上资源,会通过isolate的方式去实现,无需额外去操作
//10KB takes about 3ms to parse on a Pixel 2 XL.
return _resolveAssert(path);
}
}
Future<String> decode(String? jsPath) => _resolve(jsPath);
}
//自定义的资源加载
class CustomFairBundleLoader extends FairBundleProvider {
@override
Future<Map?> onLoad(
String? path,
FairDecoder decoder, {
bool cache = true,
Map<String, String>? h,
}) async {
//
// var byteData = null;
// if (byteData != null) {
// //
// }
// else
// {
// 根据自身的情况来,这个也可能从其他地方获取
// 缓存的是 path 对应的 map
return _cacheJson[path] ??= await super.onLoad(
path,
decoder,
cache: cache,
h: h,
);
}
//}
}
//}
插件部分
assest 下添加 fair_basic_config.json 名字不可改
{
"plugin": {
"fair_common_plugin": "assets/plugin/fair_common_plugin.js"
}
}
在plugin下添加与js的插件
此部分与dart中一一对应
let FairCommonPlugin = function () {
return {
http: function (resp) {
fairCommonPluginRequest(resp, 'http');
},
showMessageToast: function (resp) {
fairCommonPluginRequest(resp, 'showMessageToast');
},
remove: function (resp) {
fairCommonPluginRequest(resp, 'remove');
},
getTitle: function (resp) {
fairCommonPluginRequest(resp, 'getTitle');
},
}
}
dart 中
/// 跟 js 交互的方法类
class FairCommonPlugin extends IFairPlugin with HttpPlugin, ToastPlugin, BaseInfoPlugin {
factory FairCommonPlugin() => _fairCommonPlugin;
FairCommonPlugin._();
static final FairCommonPlugin _fairCommonPlugin = FairCommonPlugin._();
@override
Map<String, Function> getRegisterMethods() {
return <String, Function>{
'showMessageToast': showMessageToast,
'http': http,
'remove': remove,
'getTitle': getTitle,
};
}
}
mixin HttpPlugin implements FairCommonPluginMixin {
Future<dynamic> http(dynamic map) => request(
map,
(dynamic requestMap) async {
final method = requestMap['method'];
final url = requestMap['url'];
final headers = requestMap['headers'];
final body = requestMap['body'];
Map<String, dynamic>? params = {};
params.addAll(headers);
params.addAll(body);
switch (method) {
case 'POST':
final Response result = await HttpManager().post(
url,
params: params,
) as Response;
return {
'json': jsonDecode(result.body),
'statusCode': result.statusCode,
};
default:
}
print("调用了http方法");
return null;
},
);
}
mixin ToastPlugin implements FairCommonPluginMixin {
Future<dynamic> showMessageToast(dynamic map) => request(
map,
(dynamic requestMap) async {
final msg = requestMap['msg'];
showToast(text: msg);
return null;
},
);
}
mixin BaseInfoPlugin implements FairCommonPluginMixin {
Future<dynamic> remove(dynamic map) => request(
map,
(dynamic requestMap) async {
var index = requestMap['index'];
Get.find<CreateTaskLogic>(tag: TaskType.issue.toString()).removeIssueTasks(index);
return null;
},
);
Future<dynamic> getTitle(dynamic map) async {
print(map);
Map params = json.decode(map);
Map<String, dynamic> request = params["request"] ?? {};
var index = request['index'] ?? 0;
final String title = Get.find<CreateTaskLogic>(tag: TaskType.issue.toString()).issueTasks[index].title ?? "";
var resp = {"title": title};
print("title$title ======================================");
return Future.value(jsonEncode(resp));
}
}
逻辑层的写法与绑定
class HotUpdateDelegate extends FairDelegate {
CreateTaskLogic get logic => Get.find<CreateTaskLogic>(tag: TaskType.issue.toString());
late ScrollPhysics scrollPhysics;
@override
void initState() {
super.initState();
onLoad();
}
void onLoad() {
scrollPhysics = const NeverScrollableScrollPhysics();
}
@override
Map<String, PropertyValue> bindValue() {
return {
...super.bindValue(),
// key 跟页面上面的名字一致
"scrollPhysics": () => scrollPhysics,
'logic': () => logic,
'taskType': () => TaskType.issue,
'showLinkTask': () => logic.issueTasks.isNotEmpty
};
}
@override
Map<String, Function> bindFunction() {
return {
...super.bindFunction(),
'createIssueTask': createIssueTask,
'onTapLinkTask': onTapLinkTask,
'issueTaskCount': issueTaskCount,
'priorityText': priorityText,
};
}
void onTapLinkTask() async {
FocusScope.of(context).requestFocus(FocusNode());
Get.bottomSheet(const IssueTasksDialog(),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(20.r), topRight: Radius.circular(20.r))))
.then((value) {
if (value != null) logic.addAssociationIssue(value);
setState(() {});
});
}
int issueTaskCount() {
return logic.issueTasks.length;
}
void createIssueTask() {
logic.createIssueTask();
}
String priorityText(index) {
return logic.issueTasks[index].priorityText ?? '';
}
Color priorityColor(index) {
return logic.issueTasks[index].priorityColor;
}
}