123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- import 'dart:convert';
- import 'dart:io';
- import 'package:archive/archive.dart';
- import 'package:dio/adapter.dart';
- import 'package:dio/dio.dart';
- import 'package:fis_common/env/env.dart';
- import 'package:fis_common/helpers/http.dart';
- import 'package:fis_common/logger/logger.dart';
- import 'package:fis_jsonrpc/exception.dart';
- import 'package:fis_jsonrpc/request.dart';
- import 'package:flutter/foundation.dart';
- import 'package:flutter/services.dart';
- import 'package:path_provider/path_provider.dart';
- import 'theme.dart';
- import 'consts.dart';
- abstract class FThemeLoader {
-
- final String name;
- FThemeLoader(this.name);
-
- Future<FThemeManifestInfo?> load() async {
- bool isDefault = FTheme.ins.defaultName == this.name;
- if (!isDefault) {
- bool pkgLoaded = await _loadPackage();
- if (!pkgLoaded) {
- logger.w("加载主题包失败");
- return null;
- }
- }
- String? manifestJson =
- isDefault ? await _getDefaultManifestJson() : await _getManifestJson();
- if (manifestJson == null) {
- logger.w("主题清单json为空");
- return null;
- }
- try {
- Map<String, dynamic> json = jsonDecode(manifestJson);
- FThemeManifestInfo manifestInfo = FThemeManifestInfo.fromJson(json);
- return manifestInfo;
- } catch (e) {
- logger.e("解析主题清单Json失败", e);
- }
- return null;
- }
-
- Future<bool> _loadPackage();
-
- Future<String?> _getManifestJson();
-
- Future<String?> _getDefaultManifestJson() async {
- try {
- String assetPath =
- "packages/${FisUIConsts.themePackageName}/assets/${FisUIConsts.manifestFileName}";
- String jsonString = await (FResourceBundle.assetBundle ?? rootBundle)
- .loadString(assetPath, cache: false);
- return jsonString;
- } catch (e) {
- logger.e("读取默认主题清单Json失败", e);
- }
- return null;
- }
- }
- class FThemeLoaderNative extends FThemeLoader {
- FThemeLoaderNative(String name) : super(name);
- Directory? _storageDirectory;
- @override
- Future<bool> _loadPackage() async {
- try {
- final String storagePath = await _getStoragePath();
- final String pkgFileName = "$storagePath/themes/${this.name}.zip";
- if (!await File(pkgFileName).exists()) {
- final String url = _getPackageUrl();
- final Dio dio = Dio(BaseOptions(connectTimeout: 10 * 1000));
- (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
- (client) {
-
- client.badCertificateCallback =
- (X509Certificate cert, String host, int port) => true;
- };
- var response = await dio.download(url, pkgFileName);
- if (response.statusCode == null ||
- response.statusCode != HttpStatus.ok) {
- logger.w("下载主题包失败, Http code - ${response.statusCode}");
- return false;
- }
- }
- final zipBytes = await File(pkgFileName).readAsBytes();
- final archive = ZipDecoder().decodeBytes(zipBytes);
- for (final file in archive) {
- final filePath = "$storagePath/themes/${this.name}/${file.name}";
- if (file.isFile) {
- final data = file.content as List<int>;
- File fileInfo = File(filePath);
- await fileInfo.create(recursive: true);
- await fileInfo.writeAsBytes(data);
- } else {
- await Directory(filePath).create(recursive: true);
- }
- }
- return true;
- } catch (e) {
- print(e);
- logger.e("加载主题包异常", e);
- }
- return false;
- }
- @override
- Future<String?> _getManifestJson() async {
- try {
- final String storagePath = await _getStoragePath();
- String filePath =
- "$storagePath/themes/${this.name}/${FisUIConsts.manifestFileName}";
- String json = await File(filePath).readAsString();
- return json;
- } catch (e) {
- logger.e("读取主题清单Json异常", e);
- }
- return null;
- }
-
- Future<String> _getStoragePath() async {
- if (_storageDirectory == null) {
- _storageDirectory = await getApplicationDocumentsDirectory();
- }
- return _storageDirectory!.path;
- }
-
- String _getPackageUrl() => "${fRootBundle.resourcePath}/${this.name}.zip";
- }
- class FThemeLoaderWeb extends FThemeLoader {
- FThemeLoaderWeb(String name) : super(name);
- @override
- Future<String?> _getManifestJson() async {
- try {
- String url =
- "${getUrlRoot()}/${this.name}/${FisUIConsts.manifestFileName}";
- String? json = await FHttpHelper.downloadString(url);
- return json;
- } catch (e) {
- logger.e("读取主题清单Json异常", e);
- }
- return null;
- }
- @override
- Future<bool> _loadPackage() async => true;
-
- @protected
- String getUrlRoot() => fRootBundle.resourcePath;
- }
- class FThemeLoaderShellWeb extends FThemeLoaderWeb {
- FThemeLoaderShellWeb(String name) : super(name);
- @override
- Future<bool> _loadPackage() async {
- try {
- final url = "http://platform.fis.plus/IPlatformService";
- final rpcRequest = JsonRpcRequest("LoadTheme", name);
- final String package = jsonEncode(rpcRequest.toJson());
- final dio = Dio();
- dio.options.sendTimeout = 30 * 1000;
- dio.options.contentType = Headers.jsonContentType;
- dio.options.responseType = ResponseType.json;
- final response = await dio.post(url, data: package);
- if (response.statusCode == HttpStatus.ok && response.data != null) {
- var resp = response.data;
- if (resp.containsKey('error')) {
- throw JsonRpcServerError.fromJson(resp['error']);
- }
- return resp['result'];
- }
- } catch (e) {
- logger.e("加载主题包异常", e);
- }
- return false;
- }
- @override
- String getUrlRoot() => "http://resource.fis.plus/themes";
- }
- FThemeLoader getThemeLoader(String name) {
- switch (FPlatform.current) {
- case FPlatformEnum.android:
- case FPlatformEnum.iOS:
- return FThemeLoaderNative(name);
- case FPlatformEnum.web:
- return FThemeLoaderWeb(name);
- case FPlatformEnum.webOnWin:
- case FPlatformEnum.webOnMac:
- return FThemeLoaderShellWeb(name);
- }
- }
|