Commit 874883c2 authored by 关振斌's avatar 关振斌

update

parent f0d1c0ef
PODS: PODS:
- alipay_kit_ios (5.0.0):
- alipay_kit_ios/utdid (= 5.0.0)
- alipay_kit_ios/vendor (= 5.0.0)
- Flutter
- alipay_kit_ios/utdid (5.0.0):
- Flutter
- alipay_kit_ios/vendor (5.0.0):
- Flutter
- babstrap_settings_screen (0.0.1): - babstrap_settings_screen (0.0.1):
- Flutter - Flutter
- connectivity_plus (0.0.1): - connectivity_plus (0.0.1):
...@@ -138,6 +146,7 @@ PODS: ...@@ -138,6 +146,7 @@ PODS:
- Flutter - Flutter
DEPENDENCIES: DEPENDENCIES:
- alipay_kit_ios (from `.symlinks/plugins/alipay_kit_ios/ios`)
- babstrap_settings_screen (from `.symlinks/plugins/babstrap_settings_screen/ios`) - babstrap_settings_screen (from `.symlinks/plugins/babstrap_settings_screen/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`)
...@@ -183,6 +192,8 @@ SPEC REPOS: ...@@ -183,6 +192,8 @@ SPEC REPOS:
- Toast - Toast
EXTERNAL SOURCES: EXTERNAL SOURCES:
alipay_kit_ios:
:path: ".symlinks/plugins/alipay_kit_ios/ios"
babstrap_settings_screen: babstrap_settings_screen:
:path: ".symlinks/plugins/babstrap_settings_screen/ios" :path: ".symlinks/plugins/babstrap_settings_screen/ios"
connectivity_plus: connectivity_plus:
...@@ -235,6 +246,7 @@ EXTERNAL SOURCES: ...@@ -235,6 +246,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios" :path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
alipay_kit_ios: bfa484b12d4690cc48a803f39ed5fb58fa774d2e
babstrap_settings_screen: 535097da0fa521a47fef6f6678ff2b464ee15937 babstrap_settings_screen: 535097da0fa521a47fef6f6678ff2b464ee15937
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
C059CC5B29B6DFCC0068B7F5 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C059CC5A29B6DFCC0068B7F5 /* StoreKit.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
...@@ -46,6 +47,8 @@ ...@@ -46,6 +47,8 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C059CC5929B6DFA10068B7F5 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = "<group>"; };
C059CC5A29B6DFCC0068B7F5 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
C08A8E50299A2161008F4DB8 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; }; C08A8E50299A2161008F4DB8 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
C0C4655B29A3007E00C47A11 /* RunnerProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerProfile.entitlements; sourceTree = "<group>"; }; C0C4655B29A3007E00C47A11 /* RunnerProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerProfile.entitlements; sourceTree = "<group>"; };
D2718D25F9034030E31B924F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; D2718D25F9034030E31B924F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
...@@ -57,6 +60,7 @@ ...@@ -57,6 +60,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
8B8F5CAD6B019351870A46AE /* Pods_Runner.framework in Frameworks */, 8B8F5CAD6B019351870A46AE /* Pods_Runner.framework in Frameworks */,
C059CC5B29B6DFCC0068B7F5 /* StoreKit.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -66,6 +70,7 @@ ...@@ -66,6 +70,7 @@
36FEE18528C617843FAFC14B /* Frameworks */ = { 36FEE18528C617843FAFC14B /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C059CC5A29B6DFCC0068B7F5 /* StoreKit.framework */,
5A7A6DEAB487D7E066FC9441 /* Pods_Runner.framework */, 5A7A6DEAB487D7E066FC9441 /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
...@@ -114,6 +119,7 @@ ...@@ -114,6 +119,7 @@
97C146F01CF9000F007C117D /* Runner */ = { 97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C059CC5929B6DFA10068B7F5 /* RunnerDebug.entitlements */,
C0C4655B29A3007E00C47A11 /* RunnerProfile.entitlements */, C0C4655B29A3007E00C47A11 /* RunnerProfile.entitlements */,
C08A8E50299A2161008F4DB8 /* Runner.entitlements */, C08A8E50299A2161008F4DB8 /* Runner.entitlements */,
97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FA1CF9000F007C117D /* Main.storyboard */,
...@@ -490,7 +496,7 @@ ...@@ -490,7 +496,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = Z99J24WADU; DEVELOPMENT_TEAM = Z99J24WADU;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
......
...@@ -10,7 +10,5 @@ ...@@ -10,7 +10,5 @@
<array> <array>
<string>applinks:www.fusiontech.cn/</string> <string>applinks:www.fusiontech.cn/</string>
</array> </array>
<key>com.apple.developer.in-app-payments</key>
<array/>
</dict> </dict>
</plist> </plist>
<?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>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:www.fusiontech.cn/</string>
</array>
</dict>
</plist>
...@@ -10,7 +10,5 @@ ...@@ -10,7 +10,5 @@
<array> <array>
<string>applinks:www.fusiontech.cn/</string> <string>applinks:www.fusiontech.cn/</string>
</array> </array>
<key>com.apple.developer.in-app-payments</key>
<array/>
</dict> </dict>
</plist> </plist>
import 'package:chart/common/entities/classFyDetail.dart'; import 'package:chart/common/entities/classFyDetail.dart';
import 'package:chart/common/entities/entities.dart'; import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/entities/good.dart';
import 'package:chart/common/utils/utils.dart'; import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/values/values.dart'; import 'package:chart/common/values/values.dart';
...@@ -24,6 +25,12 @@ class NewsAPI { ...@@ -24,6 +25,12 @@ class NewsAPI {
return response['data']; return response['data'];
} }
static Future<String> doPay(Map<String, String> params) async {
var response = await HttpUtil().post('/pay/doPay', data: params);
return response['data'];
}
// /api/pay/doPay
static Future<String> sendMessageByDetailId( static Future<String> sendMessageByDetailId(
dynamic params, String detailId) async { dynamic params, String detailId) async {
var response = var response =
...@@ -31,6 +38,20 @@ class NewsAPI { ...@@ -31,6 +38,20 @@ class NewsAPI {
return response['data']; return response['data'];
} }
static Future<List<GoodEntity>> getGoodsList() async {
var response = await HttpUtil().get(
'/goods/goodsList',
);
// json['data'].forEach((v) {
// _data!.add(new Data.fromJson(v));
// });
return goodEntityFromList(response['data']);
// GoodEntity.fromJson(response['data']);
// searchRecordEntityFromList(response.data);
}
// /api/goods/goodsList
// /api/openAi/aiAnswer/{detailId} // /api/openAi/aiAnswer/{detailId}
// /// 翻页 // /// 翻页
......
List<GoodEntity> goodEntityFromList(List data) =>
List<GoodEntity>.from(data.map((x) => GoodEntity.fromJson(x)));
class GoodEntity {
int? _id;
String? _goodsName;
String? _goodsDesc;
double? _amount;
int? _integral;
String? _createTime;
String? _updateTime;
String? _appleProductId;
int? _isShelf;
int? _goodsType;
int? _count;
GoodEntity(
{int? id,
String? goodsName,
String? goodsDesc,
double? amount,
int? integral,
String? createTime,
String? updateTime,
String? appleProductId,
int? isShelf,
int? goodsType,
int? count}) {
if (id != null) {
this._id = id;
}
if (goodsName != null) {
this._goodsName = goodsName;
}
if (goodsDesc != null) {
this._goodsDesc = goodsDesc;
}
if (amount != null) {
this._amount = amount;
}
if (integral != null) {
this._integral = integral;
}
if (createTime != null) {
this._createTime = createTime;
}
if (updateTime != null) {
this._updateTime = updateTime;
}
if (appleProductId != null) {
this._appleProductId = appleProductId;
}
if (isShelf != null) {
this._isShelf = isShelf;
}
if (goodsType != null) {
this._goodsType = goodsType;
}
if (count != null) {
this._count = count;
}
}
int? get id => _id;
set id(int? id) => _id = id;
String? get goodsName => _goodsName;
set goodsName(String? goodsName) => _goodsName = goodsName;
String? get goodsDesc => _goodsDesc;
set goodsDesc(String? goodsDesc) => _goodsDesc = goodsDesc;
double? get amount => _amount;
set amount(double? amount) => _amount = amount;
int? get integral => _integral;
set integral(int? integral) => _integral = integral;
String? get createTime => _createTime;
set createTime(String? createTime) => _createTime = createTime;
String? get updateTime => _updateTime;
set updateTime(String? updateTime) => _updateTime = updateTime;
String? get appleProductId => _appleProductId;
set appleProductId(String? appleProductId) =>
_appleProductId = appleProductId;
int? get isShelf => _isShelf;
set isShelf(int? isShelf) => _isShelf = isShelf;
int? get goodsType => _goodsType;
set goodsType(int? goodsType) => _goodsType = goodsType;
int? get count => _count;
set count(int? count) => _count = count;
GoodEntity.fromJson(Map<String, dynamic> json) {
_id = json['id'];
_goodsName = json['goodsName'];
_goodsDesc = json['goodsDesc'];
_amount = json['amount'];
_integral = json['integral'];
_createTime = json['createTime'];
_updateTime = json['updateTime'];
_appleProductId = json['appleProductId'];
_isShelf = json['isShelf'];
_goodsType = json['goodsType'];
_count = json['count'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this._id;
data['goodsName'] = this._goodsName;
data['goodsDesc'] = this._goodsDesc;
data['amount'] = this._amount;
data['integral'] = this._integral;
data['createTime'] = this._createTime;
data['updateTime'] = this._updateTime;
data['appleProductId'] = this._appleProductId;
data['isShelf'] = this._isShelf;
data['goodsType'] = this._goodsType;
data['count'] = this._count;
return data;
}
}
// GoodEntity.fromJson(Map<String, dynamic> json) {
// _status = json['status'];
// _message = json['message'];
// if (json['data'] != null) {
// _data = <Data>[];
// json['data'].forEach((v) {
// _data!.add(new Data.fromJson(v));
// });
// }
// _timestamp = json['timestamp'];
// }
\ No newline at end of file
...@@ -10,6 +10,7 @@ class AppRoutes { ...@@ -10,6 +10,7 @@ class AppRoutes {
static const PRODUCT_PAGE = '/product'; static const PRODUCT_PAGE = '/product';
static const TEMPLATE_PAGE = '/template'; static const TEMPLATE_PAGE = '/template';
static const PAY_LIST = '/pay'; static const PAY_LIST = '/pay';
static const AN_PAY_LIST = '/an_pay';
static const PRIVACT = '/privacy'; static const PRIVACT = '/privacy';
static const USER_PRIVACT = '/user_privacy'; static const USER_PRIVACT = '/user_privacy';
static const WILL_COME = '/will_come'; static const WILL_COME = '/will_come';
......
import 'package:chart/pages/chat/view.dart'; import 'package:chart/pages/chat/view.dart';
import 'package:chart/pages/frame/android_pay_list/view.dart';
import 'package:chart/pages/frame/notfound/index.dart'; import 'package:chart/pages/frame/notfound/index.dart';
import 'package:chart/pages/frame/pay_list/view.dart'; import 'package:chart/pages/frame/pay_list/view.dart';
import 'package:chart/pages/privacy/index.dart'; import 'package:chart/pages/privacy/index.dart';
...@@ -17,6 +18,7 @@ import 'package:chart/pages/frame/notfound/index.dart'; ...@@ -17,6 +18,7 @@ import 'package:chart/pages/frame/notfound/index.dart';
// import 'package:chart/pages/home/home_page.dart'; // import 'package:chart/pages/home/home_page.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../pages/frame/android_pay_list/index.dart';
import '../../pages/frame/pay_list/bindings.dart'; import '../../pages/frame/pay_list/bindings.dart';
import 'routes.dart'; import 'routes.dart';
...@@ -96,6 +98,13 @@ class AppPages { ...@@ -96,6 +98,13 @@ class AppPages {
binding: PayListBinding(), binding: PayListBinding(),
), ),
GetPage(
name: AppRoutes.AN_PAY_LIST,
page: () => AndroidPayListPage(),
binding: AndroidPayListBinding(),
),
// AN_PAY_LIST
GetPage( GetPage(
name: AppRoutes.SIGN_IN, name: AppRoutes.SIGN_IN,
page: () => SignInPage(), page: () => SignInPage(),
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// const SERVER_API_URL = 'https://yapi.baidu.com/mock/41008'; // const SERVER_API_URL = 'https://yapi.baidu.com/mock/41008';
// const SERVER_API_URL = 'https://yapi.ducafecat.tech/mock/11'; // const SERVER_API_URL = 'https://yapi.ducafecat.tech/mock/11';
const SERVER_API_URL = 'http://101.34.153.228:8083/api';//线上 const SERVER_API_URL = 'http://101.34.153.228:8083/api';//线上
// const SERVER_API_URL = 'http://192.168.120.23:8083/api';
// http://192.168.110.25:8083/
// const SERVER_API_URL = 'http://192.168.2.178:8083/api'; // const SERVER_API_URL = 'http://192.168.2.178:8083/api';
// const SERVER_API_URL = 'http://192.168.110.57:8083/api'; // const SERVER_API_URL = 'http://192.168.110.57:8083/api';
// //
......
...@@ -3,12 +3,25 @@ import 'package:flutter/services.dart'; ...@@ -3,12 +3,25 @@ import 'package:flutter/services.dart';
import 'package:chart/common/services/services.dart'; import 'package:chart/common/services/services.dart';
import 'package:chart/common/store/store.dart'; import 'package:chart/common/store/store.dart';
import 'package:chart/common/utils/utils.dart'; import 'package:chart/common/utils/utils.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
/// 全局静态数据 /// 全局静态数据
class Global { class Global {
/// 初始化 /// 初始化
static Future init() async { static Future init() async {
EasyLoading.instance
..maskType = EasyLoadingMaskType.black
..displayDuration = const Duration(milliseconds: 2000)
..indicatorType = EasyLoadingIndicatorType.fadingCircle
..loadingStyle = EasyLoadingStyle.dark
..indicatorSize = 45.0
..radius = 10.0
..backgroundColor = Colors.green
..indicatorColor = Colors.yellow
..textColor = Colors.yellow
..maskColor = Colors.blue.withOpacity(0.5);
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
Get.updateLocale(Locale("zh", "CN")); Get.updateLocale(Locale("zh", "CN"));
......
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:chart/models/app_model.dart';
import 'package:provider/provider.dart';
import 'package:chart/router/routers.dart';
import 'package:chart/router/application.dart';
import 'package:flutter/services.dart' as services;
// import 'package:chart/constant/app_colors.dart';
import 'package:chart/constant/app_strings.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; //国际化
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
// import 'package:firebase_phone_auth_handler/firebase_phone_auth_handler.dart';
// import 'package:firebase_core/firebase_core.dart';
// import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:ui';
import 'models/user_model.dart';
// ignore: non_constant_identifier_names
// WidgetsFlutterBinding.ensureInitialized();
// await Firebase.initializeApp();
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// await Firebase.initializeApp();
var appModel = AppModel();
var userViewModel = UserModel();
userViewModel.refreshData();
// appModel.getClassFyList();
// var appModel = AppModel();
// var userViewModel = UserModel();
// var userSubscribeModel = UserSubscribeModel();
// var serverModel = ServerModel();
// var userSubscribeModel = UserSubscribeModel();
// var serverModel = ServerModel();
// var planModel = PlanModel();
runApp(MultiProvider(providers: [
ChangeNotifierProvider<AppModel>.value(value: appModel),
ChangeNotifierProvider<UserModel>.value(value: userViewModel),
// ChangeNotifierProvider<UserSubscribeModel>.value(value: userSubscribeModel),
// ChangeNotifierProvider<ServerModel>.value(value: serverModel),
// ChangeNotifierProvider<PlanModel>.value(value: planModel)
], child: ChartApp()));
configLoading();
}
class ChartApp extends StatelessWidget {
ChartApp({Key? key}) : super(key: key) {
final router = FluroRouter();
// Routers.configureRoutes(router);
Application.router = router;
}
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
services.SystemChrome.setPreferredOrientations([
services.DeviceOrientation.portraitUp,
services.DeviceOrientation.portraitDown
]);
return MaterialApp(
// <--- /!\ Add the builder
title: AppStrings.appName,
navigatorKey: Application.navigatorKey,
debugShowCheckedModeBanner: false,
onGenerateRoute: Application.router?.generator,
localizationsDelegates: const [
// 本地化的代理类
RefreshLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate //复制
],
builder: EasyLoading.init(),
supportedLocales: const [
Locale('en', 'US'), // 美国英语
Locale('zh', 'CN'), // 中文简体
//其它Locales
],
theme: ThemeData(
// Color(0xff9182F9)
primarySwatch: createMaterialColor(const Color(0xff9182F9)),
// AppColors.themeColorGreen,
visualDensity: VisualDensity.adaptivePlatformDensity),
);
}
}
//调用的时候需要把hex改一下,比如#223344 needs change to 0xFF223344
//即把#换成0xFF即可
MaterialColor createMaterialColor(Color color) {
List strengths = <double>[.05];
Map<int, Color> swatch = {};
final int r = color.red, g = color.green, b = color.blue;
for (int i = 1; i < 10; i++) {
strengths.add(0.1 * i);
}
strengths.forEach((strength) {
final double ds = 0.5 - strength;
swatch[(strength * 1000).round()] = Color.fromRGBO(
r + ((ds < 0 ? r : (255 - r)) * ds).round(),
g + ((ds < 0 ? g : (255 - g)) * ds).round(),
b + ((ds < 0 ? b : (255 - b)) * ds).round(),
1,
);
});
return MaterialColor(color.value, swatch);
}
void configLoading() {
EasyLoading
.instance
// ..displayDuration = const Duration(milliseconds: 2000)
// ..indicatorType = EasyLoadingIndicatorType.fadingCircle
// ..loadingStyle = EasyLoadingStyle.dark
// ..indicatorSize = 45.0
// ..radius = 10.0
// ..progressColor = Colors.yellow
// ..backgroundColor = Colors.green
// ..indicatorColor = Colors.yellow
// ..textColor = Colors.yellow
// ..maskColor = Colors.blue.withOpacity(0.5)
// ..userInteractions = false
.userInteractions = false;
// ..customAnimation = CustomAnimation();
}
...@@ -52,50 +52,9 @@ class ChatApp extends StatelessWidget { ...@@ -52,50 +52,9 @@ class ChatApp extends StatelessWidget {
enableLog: true, enableLog: true,
logWriterCallback: Logger.write, logWriterCallback: Logger.write,
)); ));
// GetMaterialApp(
// debugShowCheckedModeBanner: false,
// enableLog: true,
// logWriterCallback: Logger.write,
// initialRoute: AppPages.INITIAL,
// getPages: AppPages.routes,
// locale: TranslationService.locale,
// fallbackLocale: TranslationService.fallbackLocale,
// translations: TranslationService(),
// );
} }
} }
// () => RefreshConfiguration(
// headerBuilder: () => ClassicHeader(),
// footerBuilder: () => ClassicFooter(),
// hideFooterWhenNotFull: true,
// headerTriggerDistance: 80,
// maxOverScrollExtent: 100,
// footerTriggerDistance: 150,
// child: GetMaterialApp(
// title: 'News',
// theme: AppTheme.light,
// debugShowCheckedModeBanner: false,
// initialRoute: AppPages.INITIAL,
// getPages: AppPages.routes,
// builder: EasyLoading.init(),
// translations: TranslationService(),
// navigatorObservers: [AppPages.observer],
// localizationsDelegates: [
// GlobalMaterialLocalizations.delegate,
// GlobalWidgetsLocalizations.delegate,
// GlobalCupertinoLocalizations.delegate,
// ],
// supportedLocales: ConfigStore.to.languages,
// locale: ConfigStore.to.locale,
// fallbackLocale: Locale('en', 'US'),
// enableLog: true,
// logWriterCallback: Logger.write,
// ),
// ),
/// 所有的Binding层
class AllControllerBinding extends Bindings { class AllControllerBinding extends Bindings {
@override @override
void dependencies() { void dependencies() {
......
import 'package:flutter/material.dart';
// import 'package:sail/adapters/leaf_ffi/config.dart';
// import 'package:sail/channels/vpn_manager.dart';
// import 'package:sail/constant/app_strings.dart';
import 'package:chart/models/base_model.dart';
import "package:chart/service/plan_service.dart";
import '../entity/plan_entity.dart';
// import 'package:sail/models/server_model.dart';
// import 'package:sail/models/user_model.dart';
// import 'package:sail/utils/common_util.dart';
class AppModel extends BaseModel {
List<ClassifyEntity> _classFyList = [];
List<ClassifyEntity> get classFyList => _classFyList;
// VpnManager vpnManager = VpnManager();
bool isOn = false;
PageController pageController = PageController(initialPage: 0);
String appTitle = 'Sail';
// Config config = Config();
getClassFyList() async {
print("appTitle,$appTitle");
try {
List<ClassifyEntity>? list = await PlanService().getClassifyList();
_classFyList = list!;
} catch (e) {
print(e);
}
}
// AppModel() {
// // General general = General(
// // loglevel: 'info',
// // logoutput: '{{leafLogFile}}',
// // dnsServer: ['223.5.5.5', '114.114.114.114'],
// // tunFd: '{{tunFd}}',
// // routingDomainResolve: true);
// // List<Rule> rules = [];
// // // rules.add(Rule(typeField: 'EXTERNAL', target: 'Direct', filter: 'site:cn'));
// // rules.add(Rule(typeField: 'FINAL', target: 'Direct'));
// // config.general = general;
// // config.rules = rules;
// }
// final Map _tabMap = {
// 0: AppStrings.appName,
// 1: '套餐',
// 2: '节点',
// 3: '我的',
// };
void jumpToPage(int page) {
// pageController.jumpToPage(page);
// appTitle = _tabMap[page];
// notifyListeners();
}
void getStatus() async {
// isOn = await vpnManager.getStatus();
// print("status: $isOn");
// notifyListeners();
}
void togglePowerButton() async {
// await vpnManager.toggle();
// isOn = !isOn;
// notifyListeners();
}
void getTunnelLog() async {
// var log = await vpnManager.getTunnelLog();
// print("log: $log");
}
void getTunnelConfiguration() async {
// var conf = await vpnManager.getTunnelConfiguration();
// print("config: $conf");
}
// void setConfigProxies(UserModel userModel, ServerModel serverModel) async {
// List<Proxy> proxies = [];
// List<ProxyGroup> proxyGroups = [];
// List<String> actors = [];
// serverModel.serverEntityList?.forEach((server) {
// Proxy proxy = Proxy(
// tag: server.name,
// protocol: server.type,
// address: server.host,
// port: server.port,
// encryptMethod: server.cipher,
// password: userModel.userEntity!.uuid);
// proxies.add(proxy);
// actors.add(server.name);
// });
// if (actors.isNotEmpty) {
// proxyGroups.add(ProxyGroup(
// tag: "UrlTest",
// protocol: 'url-test',
// actors: actors,
// checkInterval: 600));
// config.rules?.last.target = "UrlTest";
// }
// config.proxies = proxies;
// config.proxyGroups = proxyGroups;
// print("-----------------config-----------------");
// print(config);
// print("-----------------config-----------------");
// vpnManager.setTunnelConfiguration(config.toString());
// }
void setConfigRule(String tag) async {
// var proxy = config.proxies?.where((proxies) => proxies.tag == tag);
//
// if (proxy == null || proxy.isEmpty) {
// return;
// }
//
// config.rules?.last.target = tag;
//
// print("-----------------config-----------------");
// print(config);
// print("-----------------config-----------------");
//
// vpnManager.setTunnelConfiguration(config.toString());
}
}
import 'package:flutter/material.dart';
import 'package:chart/models/page_state.dart';
// import 'package:chart/utils/common_util.dart';
class BaseModel extends ChangeNotifier {
PageState pageState = PageState.loading;
bool _isDispose = false;
late String errorMessage;
bool get isDispose => _isDispose;
@override
void notifyListeners() {
print("view model notifyListeners");
if (!_isDispose) {
super.notifyListeners();
}
}
void errorNotify(String error) {
pageState = PageState.error;
errorMessage = error;
notifyListeners();
}
@override
void dispose() {
_isDispose = true;
print("view model dispose");
super.dispose();
}
}
enum PageState {
loading, //加载中
hasData, //有数据
empty, //无数据
error, //加载失败
}
import 'package:chart/constant/app_strings.dart';
import 'package:chart/entity/login_entity.dart';
import 'package:chart/entity/user_entity.dart';
import 'package:chart/models/base_model.dart';
import 'package:chart/utils/navigator_util.dart';
import 'package:chart/utils/shared_preferences_util.dart';
import "package:chart/service/user_service.dart";
import '../entity/plan_entity.dart';
import '../service/plan_service.dart';
// import '';
class UserModel extends BaseModel {
late String _token;
late String _authData;
late UserEntity? _userEntity;
late bool _isFirstOpen;
bool _isLogin = false;
late IntegralEntity? _integralEntity;
final UserService _userService = UserService();
late List<ClassifyEntity> _classFyList;
String get token => _token;
String get authData => _authData;
UserEntity? get userEntity => _userEntity;
bool get isFirstOpen => _isFirstOpen;
bool get isLogin => _isLogin;
IntegralEntity? get integralEntity => _integralEntity;
List<ClassifyEntity>? get classFyList => _classFyList;
Future<void> checkHasLogin(context, Function callback) async {
if (!isLogin) {
NavigatorUtil.goLogin(context);
} else {
return callback();
}
}
refreshData() async {
_integralEntity = IntegralEntity(id: 1, username: '', token: "");
_classFyList = [];
_isFirstOpen = await SharedPreferencesUtil.getInstance()
?.getBool(AppStrings.isFirstOpen) ??
true;
String token = await SharedPreferencesUtil.getInstance()
?.getString(AppStrings.token) ??
'';
// String authData = await SharedPreferencesUtil.getInstance()
// ?.getString(AppStrings.authData) ??
// '';
if (token != null && token.isNotEmpty) {
_isLogin = true;
_token = token;
// _authData = authData;
// Map<String, dynamic> userEntityMap =
// await SharedPreferencesUtil.getInstance()
// ?.getMap(AppStrings.userInfo) ??
// <String, dynamic>{};
// _userEntity = UserEntity.fromMap(userEntityMap);
// notifyListeners();
}
}
logout() {
SharedPreferencesUtil? sharedPreferencesUtil =
SharedPreferencesUtil.getInstance();
sharedPreferencesUtil?.clear();
setIsFirstOpen(false);
refreshData();
}
_saveIsFirstOpen() {
SharedPreferencesUtil.getInstance()
?.setBool(AppStrings.isFirstOpen, _isFirstOpen);
}
_saveUserToken(LoginEntity loginEntity) async {
SharedPreferencesUtil? sharedPreferencesUtil =
SharedPreferencesUtil.getInstance();
await sharedPreferencesUtil?.setString(AppStrings.token, loginEntity.token);
}
_setUserAuthData(LoginEntity loginEntity) async {
SharedPreferencesUtil? sharedPreferencesUtil =
SharedPreferencesUtil.getInstance();
await sharedPreferencesUtil?.setString(
AppStrings.authData, loginEntity.username);
}
_saveUserInfo() async {
SharedPreferencesUtil? sharedPreferencesUtil =
SharedPreferencesUtil.getInstance();
await sharedPreferencesUtil?.setMap(
AppStrings.userInfo, _userEntity?.toMap());
}
setIsFirstOpen(bool isFirstOpen) {
_isFirstOpen = isFirstOpen;
_saveIsFirstOpen();
}
setToken(LoginEntity loginEntity) async {
_token = loginEntity.token;
// _authData = loginEntity.authData;
_isLogin = true;
await setIntegralInfo();
_saveUserToken(loginEntity);
_setUserAuthData(loginEntity);
}
setUserInfo(UserEntity? userEntity) {
_userEntity = userEntity;
_saveUserInfo();
}
setIntegralInfo() async {
final integralEntity = await _userService.getUserIntegral();
if (integralEntity!.token.isNotEmpty) {
_saveUserToken(LoginEntity(
username: integralEntity!.username,
id: integralEntity.id,
token: integralEntity.token));
print("integralEntity$integralEntity");
_integralEntity = integralEntity;
} else {
//TODO
// print('integralEntityintegralEntity${integralEntity.token}');
}
}
getClassFyList() async {
try {
List<ClassifyEntity>? list = await PlanService().getClassifyList();
_classFyList = list!;
} catch (e) {
print(e);
}
}
}
import 'package:chart/utils/common_util.dart'; // import 'package:chart/utils/common_util.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:chart/common/entities/entities.dart'; import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/utils/utils.dart'; import 'package:chart/common/utils/utils.dart';
......
...@@ -7,7 +7,6 @@ import 'package:flutter_chat_types/flutter_chat_types.dart' as types; ...@@ -7,7 +7,6 @@ import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import '../../common/store/user.dart'; import '../../common/store/user.dart';
import 'index.dart'; import 'index.dart';
import 'package:chart/service/message_service.dart';
class ChatPageController extends GetxController { class ChatPageController extends GetxController {
ChatPageController(); ChatPageController();
......
import 'package:get/get.dart';
import 'controller.dart';
class AndroidPayListBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<AndroidPayListController>(() => AndroidPayListController());
}
}
import 'dart:async';
import 'dart:convert';
import 'package:alipay_kit/alipay_kit.dart';
import 'package:chart/common/apis/apis.dart';
import 'package:chart/common/entities/good.dart';
import 'package:chart/common/store/user.dart';
import 'package:chart/pages/frame/android_pay_list/unsafe_alipay_kit.dart';
// import 'package:chart/common/routers/routes.dart';
// import 'package:chart/common/store/store.dart';
// import 'package:chart/entity/user_entity.dart';
// import 'package:chart/pages/application/index.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
// import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
// import 'package:flutter_inapp_purchase/modules.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:get/get.dart';
import 'index.dart';
class AndroidPayListController extends GetxController {
AndroidPayListController();
final state = AndroidPayListState();
// Platform messages may fail, so we use a try/catch PlatformException.
// prepare
/// 成员变量
/// 事件
// tap
void handleTap(int index) {
Get.snackbar(
"标题",
"消息",
);
}
/// 生命周期
///在 widget 内存中分配后立即调用。
///你可以用它来为控制器初始化 initialize 一些东西。
@override
void onInit() async {
super.onInit();
await initializedPlugins();
await _getProduct();
// EasyLoading.dismiss();
// await initializedPlugins();
// new 对象
// 初始静态数据
}
Future initializedPlugins() async {
await AlipayKitPlatform.instance.isInstalled();
}
Future _getProduct() async {
EasyLoading.show(status: "正在获取套餐中...");
try {
List<GoodEntity> goodsList = await NewsAPI.getGoodsList();
// print(goodsList);
state.items.addAll(goodsList);
EasyLoading.dismiss();
} catch (e) {
print(e);
EasyLoading.dismiss();
}
// try {
// List<IAPItem> items =
// await FlutterInappPurchase.instance.getProducts(_productLists);
// state.items.addAll(items);
// // for (var item in items) {
// // // print('${item.toString()}');
// // // this._items.add(item);
// // }
// } catch (e) {
// print("_getProductError$e");
// }
}
void requestPurchase() async {
Vibrate.feedback(FeedbackType.selection);
// print("${item.productId}");
EasyLoading.show(status: '支付中...');
// List<String> newList = list.where((element) => element.compareTo('b') > 0).toList(); // ['c', 'd']
final actSelected = state.items
.firstWhere((element) => element.appleProductId == state.selected);
String orderInfo = await NewsAPI.doPay({
"goodsId": "${actSelected.id}",
"type": '1',
"userId": "${UserStore.to.profile.id}"
});
AlipayKitPlatform.instance.pay(orderInfo: orderInfo);
EasyLoading.dismiss();
// actSelected
// selected
// await NewsAPI.doPay({"goodsId": 0, "type": 0, "userId": 0});
// final Map<String, dynamic> bizContent = <String, dynamic>{
// 'timeout_express': '30m',
// 'product_code': 'QUICK_MSECURITY_PAY',
// 'total_amount': '0.01',
// 'subject': '1',
// 'body': '我是测试数据',
// 'out_trade_no': '123456789',
// };
// final Map<String, dynamic> orderInfo = <String, dynamic>{
// 'app_id': "2021003176601601",
// 'biz_content': json.encode(bizContent),
// 'charset': 'utf-8',
// 'method': 'alipay.trade.app.pay',
// 'timestamp': '2016-07-29 16:55:53',
// 'version': '1.0',
// };
// IAPItem item
// FlutterInappPurchase.instance.requestPurchase(state.selected);
}
///在 onInit() 之后调用 1 帧。这是进入的理想场所
///导航事件,例如 snackbar、对话框或新route,或
///async 异步请求。
@override
void onReady() {
super.onReady();
// async 拉取数据
}
///在 [onDelete] 方法之前调用。 [onClose] 可能用于
///处理控制器使用的资源。就像 closing events 一样,
///或在控制器销毁之前的流。
///或者处置可能造成一些内存泄漏的对象,
///像 TextEditingControllers、AnimationControllers。
///将一些数据保存在磁盘上也可能很有用。
@override
void onClose() {
super.onClose();
// 1 stop & close 关闭对象
// 2 save 持久化数据
}
///dispose 释放内存
@override
void dispose() {
// _purchaseUpdatedSubscription.cancel();
// _purchaseErrorSubscription.cancel();
// _conectionSubscription.cancel();
super.dispose();
// dispose 释放对象
}
}
library notfound;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/pointycastle.dart';
import 'package:pointycastle/signers/rsa_signer.dart';
class RsaKeyParser {
const RsaKeyParser._();
static RSAPublicKey parsePublic(String key) {
final List<String> rows = key.split('\n');
final String header = rows.first;
if (header == '-----BEGIN RSA PUBLIC KEY-----') {
return _parsePublic(_parseSequence(rows));
}
if (header == '-----BEGIN PUBLIC KEY-----') {
return _parsePublic(_pkcs8PublicSequence(_parseSequence(rows)));
}
throw UnsupportedError('PEMKey($key) is unsupported');
}
static RSAPrivateKey parsePrivate(String key) {
final List<String> rows = key.split('\n');
final String header = rows.first;
if (header == '-----BEGIN RSA PRIVATE KEY-----') {
return _parsePrivate(_parseSequence(rows));
}
if (header == '-----BEGIN PRIVATE KEY-----') {
return _parsePrivate(_pkcs8PrivateSequence(_parseSequence(rows)));
}
throw UnsupportedError('PEMKey($key) is unsupported');
}
static RSAPublicKey _parsePublic(ASN1Sequence sequence) {
final BigInt modulus = (sequence.elements![0] as ASN1Integer).integer!;
final BigInt exponent = (sequence.elements![1] as ASN1Integer).integer!;
return RSAPublicKey(modulus, exponent);
}
static RSAPrivateKey _parsePrivate(ASN1Sequence sequence) {
final BigInt modulus = (sequence.elements![1] as ASN1Integer).integer!;
final BigInt exponent = (sequence.elements![3] as ASN1Integer).integer!;
final BigInt? p = (sequence.elements?[4] as ASN1Integer?)?.integer;
final BigInt? q = (sequence.elements?[5] as ASN1Integer?)?.integer;
return RSAPrivateKey(modulus, exponent, p, q);
}
static ASN1Sequence _parseSequence(List<String> rows) {
final String keyText = rows
.skipWhile((String row) => row.startsWith('-----BEGIN'))
.takeWhile((String row) => !row.startsWith('-----END'))
.map((String row) => row.trim())
.join('');
final Uint8List keyBytes = Uint8List.fromList(base64.decode(keyText));
final ASN1Parser asn1Parser = ASN1Parser(keyBytes);
return asn1Parser.nextObject() as ASN1Sequence;
}
static ASN1Sequence _pkcs8PublicSequence(ASN1Sequence sequence) {
final ASN1Object object = sequence.elements![1];
final List<int> bytes = object.valueBytes!.sublist(1);
final ASN1Parser parser = ASN1Parser(Uint8List.fromList(bytes));
return parser.nextObject() as ASN1Sequence;
}
static ASN1Sequence _pkcs8PrivateSequence(ASN1Sequence sequence) {
final ASN1Object object = sequence.elements![2];
final Uint8List bytes = object.valueBytes!;
final ASN1Parser parser = ASN1Parser(bytes);
return parser.nextObject() as ASN1Sequence;
}
}
class RsaSigner {
const RsaSigner(RSASigner rsaSigner, RSAPrivateKey privateKey)
: _rsaSigner = rsaSigner,
_privateKey = privateKey;
final RSASigner _rsaSigner;
final RSAPrivateKey _privateKey;
List<int> sign(List<int> message) {
_rsaSigner
..reset()
..init(true, PrivateKeyParameter<RSAPrivateKey>(_privateKey));
final RSASignature signature =
_rsaSigner.generateSignature(Uint8List.fromList(message));
return signature.bytes;
}
static RsaSigner sha1Rsa(String privateKey) {
return RsaSigner(Signer('SHA-1/RSA') as RSASigner,
RsaKeyParser.parsePrivate(privateKey));
}
static RsaSigner sha256Rsa(String privateKey) {
return RsaSigner(Signer('SHA-256/RSA') as RSASigner,
RsaKeyParser.parsePrivate(privateKey));
}
}
class RsaVerifier {
const RsaVerifier(RSASigner rsaSigner, RSAPublicKey publicKey)
: _rsaSigner = rsaSigner,
_publicKey = publicKey;
final RSASigner _rsaSigner;
final RSAPublicKey _publicKey;
bool verify(List<int> message, List<int> signature) {
_rsaSigner
..reset()
..init(false, PublicKeyParameter<RSAPublicKey>(_publicKey));
return _rsaSigner.verifySignature(Uint8List.fromList(message),
RSASignature(Uint8List.fromList(signature)));
}
static RsaVerifier sha1Rsa(String publicKey) {
return RsaVerifier(
Signer('SHA-1/RSA') as RSASigner, RsaKeyParser.parsePublic(publicKey));
}
static RsaVerifier sha256Rsa(String publicKey) {
return RsaVerifier(Signer('SHA-256/RSA') as RSASigner,
RsaKeyParser.parsePublic(publicKey));
}
}
import 'package:chart/common/entities/good.dart';
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
import 'package:get/get.dart';
class AndroidPayListState {
// title
final _title = "".obs;
set title(value) => this._title.value = value;
get title => this._title.value;
final _selected = "com.wudi.app.60stars".obs;
set selected(value) => _selected.value = value;
get selected => _selected.value;
RxList<GoodEntity> items = <GoodEntity>[].obs;
}
import 'dart:convert';
import 'package:alipay_kit/alipay_kit.dart';
import 'package:chart/pages/frame/android_pay_list/rsa.dart';
extension UnsafeAlipayKitPlatform on AlipayKitPlatform {
static const String SIGNTYPE_RSA = 'RSA';
static const String SIGNTYPE_RSA2 = 'RSA2';
static const String AUTHTYPE_AUTHACCOUNT = 'AUTHACCOUNT';
static const String AUTHTYPE_LOGIN = 'LOGIN';
/// 支付
Future<void> unsafePay({
required Map<String, dynamic> orderInfo,
String signType = SIGNTYPE_RSA2,
required String privateKey,
bool isShowLoading = true,
}) {
final String? charset = orderInfo['charset'] as String?;
final Encoding encoding = Encoding.getByName(charset) ?? utf8;
final Map<String, dynamic> clone = <String, dynamic>{
...orderInfo,
'sign_type': signType,
};
final String param = _param(clone, encoding);
final String sign = _sign(clone, signType, privateKey);
return AlipayKitPlatform.instance.pay(
orderInfo:
'$param&sign=${Uri.encodeQueryComponent(sign, encoding: encoding)}',
isShowLoading: isShowLoading,
);
}
/// 登录
Future<void> unsafeAuth({
required String appId, // 支付宝分配给开发者的应用ID
required String pid, // 签约的支付宝账号对应的支付宝唯一用户号,以2088开头的16位纯数字组成
required String targetId, // 商户标识该次用户授权请求的ID,该值在商户端应保持唯一
String authType =
AUTHTYPE_AUTHACCOUNT, // 标识授权类型,取值范围:AUTHACCOUNT 代表授权;LOGIN 代表登录
String signType =
SIGNTYPE_RSA2, // 商户生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA ,推荐使用 RSA2
required String privateKey,
bool isShowLoading = true,
}) {
assert(authType == AUTHTYPE_AUTHACCOUNT || authType == AUTHTYPE_LOGIN);
final Map<String, dynamic> authInfo = <String, dynamic>{
'apiname': 'com.alipay.account.auth',
'method': 'alipay.open.auth.sdk.code.get',
'app_id': appId,
'app_name': 'mc',
'biz_type': 'openservice',
'pid': pid,
'product_id': 'APP_FAST_LOGIN',
'scope': 'kuaijie',
'target_id': targetId,
'auth_type': authType,
};
authInfo['sign_type'] = signType;
const Encoding encoding = utf8; // utf-8
final String param = _param(authInfo, encoding);
final String sign = _sign(authInfo, signType, privateKey);
return AlipayKitPlatform.instance.auth(
authInfo:
'$param&sign=${Uri.encodeQueryComponent(sign, encoding: encoding)}',
isShowLoading: isShowLoading,
);
}
static String _param(Map<String, dynamic> map, Encoding encoding) {
return map.entries
.map((MapEntry<String, dynamic> e) =>
'${e.key}=${Uri.encodeQueryComponent('${e.value}', encoding: encoding)}')
.join('&');
}
static String _sign(
Map<String, dynamic> map, String signType, String privateKey) {
// 参数排序
final List<String> keys = map.keys.toList();
keys.sort();
final String content = keys.map((String e) => '$e=${map[e]}').join('&');
String sign;
switch (signType) {
case SIGNTYPE_RSA:
sign = base64
.encode(RsaSigner.sha1Rsa(privateKey).sign(utf8.encode(content)));
break;
case SIGNTYPE_RSA2:
sign = base64
.encode(RsaSigner.sha256Rsa(privateKey).sign(utf8.encode(content)));
break;
default:
throw UnsupportedError('Alipay sign_type($signType) is not supported!');
}
return sign;
}
}
\ No newline at end of file
import 'package:chart/common/routers/routes.dart';
import 'package:chart/common/values/colors.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'index.dart';
import 'widgets/widgets.dart';
// android_pay_list
class AndroidPayListPage extends GetView<AndroidPayListController> {
// 内容页
Widget _buildView() {
// return PayItemWidget();
return PayItemWidget();
}
@override
Widget build(BuildContext context) {
final c = Get.put(AndroidPayListController());
return Scaffold(
// appBar: transparentAppBar(
// title: Text(
// "套餐选择",
// style: TextStyle(
// color: AppColors.primaryElementText,
// fontFamily: 'Montserrat',
// fontSize: 18,
// fontWeight: FontWeight.w600,
// ),
// ),
// leading: IconButton(
// tooltip: '返回上一页',
// icon: const Icon(
// Icons.arrow_back,
// color: AppColors.primaryElementText,
// ),
// onPressed: () async {
// // Get.back();
// // Get.offAll(ApplicationPage());
// // await Get.off(ApplicationPage());
// // Get.toNamed(AppRoutes.Application);
// Get.back();
// // await Get.toNamed();
// // Navigator.of(context).pop();
// //_nextPage(-1);
// },
// ),
// ),
// _buildView
body: Container(
width: double.infinity,
height: double.infinity,
// padding: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg1.png").image,
fit: BoxFit.cover),
),
child: _buildView()),
);
}
}
// import 'dart:async';
// import 'package:chart/common/store/store.dart';
// import 'package:chart/entity/user_entity.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter_easyloading/flutter_easyloading.dart';
// import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
// import 'package:get/get.dart';
// import 'package:glassmorphism/glassmorphism.dart';
// import '../../../../common/apis/apis.dart';
// import '../index.dart';
// class PayItemWidget extends StatefulWidget {
// const PayItemWidget({Key? key}) : super(key: key);
// @override
// GoodsPageState createState() => GoodsPageState();
// }
// class GoodsPageState extends State<PayItemWidget> {
// late StreamSubscription _purchaseUpdatedSubscription;
// late StreamSubscription _purchaseErrorSubscription;
// late StreamSubscription _conectionSubscription;
// @override
// void initState() {
// initializedPlugins();
// // TODO: implement initState
// super.initState();
// }
// initializedPlugins() async {
// String platformVersion;
// // Platform messages may fail, so we use a try/catch PlatformException.
// // prepare
// var result = await FlutterInappPurchase.instance.initialize();
// print('result: $result');
// // If the widget was removed from the tree while the asynchronous platform
// // message was in flight, we want to discard the reply rather than calling
// // setState to update our non-existent appearance.
// if (!mounted) return;
// _conectionSubscription =
// FlutterInappPurchase.connectionUpdated.listen((connected) {
// print('connected: $connected');
// });
// _purchaseUpdatedSubscription =
// FlutterInappPurchase.purchaseUpdated.listen((productItem) async {
// // print(a);
// ApplePayEntity? res = await UserAPI.notifyApplePay({
// 'receipt': productItem?.transactionReceipt,
// 'userId': UserStore.to.profile.id,
// "chooseEnv": false
// });
// print(
// "productItemproductItemproductItemproductItemproductItemproductItemproductItemproductItem");
// if (res?.status == 200) {
// await FlutterInappPurchase.instance.clearTransactionIOS();
// EasyLoading.showSuccess('${res?.message}');
// EasyLoading.dismiss();
// } else {
// EasyLoading.showError("${res?.message}}");
// EasyLoading.dismiss();
// }
// });
// _purchaseErrorSubscription =
// FlutterInappPurchase.purchaseError.listen((purchaseError) {
// // print('purchase-error: $purchaseError');
// EasyLoading.showError('支付订单失败');
// EasyLoading.dismiss();
// });
// }
// @override
// dispose() {
// _purchaseUpdatedSubscription.cancel();
// _purchaseErrorSubscription.cancel();
// _conectionSubscription.cancel();
// super.dispose();
// }
// @override
// Widget build(BuildContext context) {
// var count = 0.obs;
// // ProductController c = Get.put(ProductController());
// // ProductController c = Get.put(ProductController());
// AndroidPayListController c = Get.find();
// // initDataList
// return Column(
// children: c.state.items
// .map((item) => GlassmorphicContainer(
// borderRadius: 16,
// margin: EdgeInsets.only(top: 16),
// blur: 14,
// alignment: Alignment.bottomCenter,
// border: 2,
// linearGradient: LinearGradient(
// begin: Alignment.topLeft,
// end: Alignment.bottomRight,
// colors: [
// const Color(0xFF0FFFF).withOpacity(0.2),
// const Color(0xFF0FFFF).withOpacity(0.2),
// ],
// ),
// borderGradient: LinearGradient(
// begin: Alignment.topLeft,
// end: Alignment.bottomRight,
// colors: [
// const Color(0xFF0FFFF).withOpacity(1),
// const Color(0xFFFFFFF),
// const Color(0xFF0FFFF).withOpacity(1),
// ],
// ),
// height: 173,
// width: double.infinity,
// // margin: EdgeInsets.symmetric(vertical: 10.0),
// child: Container(
// child: Column(
// children: <Widget>[
// Container(
// padding: EdgeInsets.all(16.0),
// width: double.infinity,
// // height: 200,
// child: Column(children: [
// Row(
// children: [
// const Text(
// "项目名称:",
// style: TextStyle(color: Colors.white),
// ),
// SizedBox(
// width: 10,
// ),
// Text(
// item.title!,
// style: TextStyle(color: Colors.white),
// )
// ],
// ),
// Row(
// children: [
// const Text(
// "项目价格:",
// style: TextStyle(color: Colors.white),
// ),
// SizedBox(
// width: 10,
// ),
// Text(
// item.localizedPrice!,
// style: TextStyle(color: Colors.white),
// )
// ],
// ),
// Row(
// children: [
// const Text(
// "项目描述:",
// style: TextStyle(color: Colors.white),
// ),
// SizedBox(
// width: 10,
// ),
// Expanded(
// child: Text(
// maxLines: 3,
// item.description!,
// style: TextStyle(
// color: Colors.white,
// ),
// ))
// ],
// ),
// Row(children: [
// ElevatedButton(
// // color: Colors.orange,
// onPressed: () {
// EasyLoading.show(status: '提交订单中...');
// c.requestPurchase();
// // c()
// },
// child: Text('购买套餐'),
// ),
// ])
// ]),
// // child: ,
// ),
// ],
// ),
// ),
// ))
// .toList());
// }
// }
import 'package:flutter/material.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:get/get.dart';
import 'package:glassy/glassy_button.dart';
import 'package:glassy/glassy_card.dart';
import 'package:glassy/glassy_config.dart';
import 'package:gradient_widgets/gradient_widgets.dart';
import '../index.dart';
const color = Color(0xff8AFBFF);
/// hellowrod
class PayItemWidget extends GetView<AndroidPayListController> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 40, bottom: 40),
child: Column(
children: [
Container(
// padding: EdgeInsets.all(0),
// color: Colors.red,
height: Get.mediaQuery.size.height * 0.35,
child: Stack(
// ignore: prefer_const_literals_to_create_immutables
children: [
Align(
alignment: Alignment.topRight,
child: InkWell(
onTap: () => Get.back(),
child: Container(
// color: Colors.amber,
padding: EdgeInsets.symmetric(
horizontal: 20, vertical: 20),
child: Icon(
Icons.close_outlined,
color: Colors.white,
),
)),
),
// ignore: prefer_const_constructors
Align(
alignment: Alignment.centerLeft,
child: Image(
image: AssetImage("assets/images/left.png"),
width: Get.mediaQuery.size.height * 0.17,
),
// child: Container(
// width: getRelativeHeight(0.13),
// height: getRelativeHeight(0.13),
// decoration: BoxDecoration(
// border:
// Border.all(width: 15, color: circleColor.withOpacity(0.6)),
// shape: BoxShape.circle,
// ),
// ),
),
Align(
alignment: Alignment.center,
child: Image(
image: AssetImage("assets/images/center.png"),
width: Get.mediaQuery.size.height * 0.21,
),
// child: Container(
// width: getRelativeHeight(0.11),
// height: getRelativeHeight(0.11),
// decoration: BoxDecoration(
// border:
// Border.all(width: 15, color: circleColor.withOpacity(0.25)),
// shape: BoxShape.circle,
// ),
// ),
),
Align(
alignment: Alignment.centerRight,
child: Image(
image: AssetImage("assets/images/you.png"),
width: Get.mediaQuery.size.height * 0.17,
),
// child: Container(
// width: getRelativeHeight(0.11),
// height: getRelativeHeight(0.11),
// decoration: BoxDecoration(
// border:
// Border.all(width: 15, color: circleColor.withOpacity(0.17)),
// shape: BoxShape.circle,
// ),
// ),
),
],
)),
Expanded(
child: Container(
padding: EdgeInsets.all(10),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(Icons.send, color: color),
Text(" 选择自己需要的套餐",
style: TextStyle(color: color, fontSize: 20))
],
),
Container(
margin: EdgeInsets.only(top: 20),
padding: EdgeInsets.only(left: 10),
height: Get.mediaQuery.size.height * 0.14,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Obx(() => controller.state.selected ==
'com.wudi.app.60stars'
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
Row(
// crossAxisAlignment
children: [
Icon(Icons.check, color: color),
Text("30次提问机会",
style: TextStyle(
color: color, fontSize: 16))
],
),
// Row(
// children: [
// Icon(Icons.check, color: color),
// Text("无广告",
// style: TextStyle(
// color: color, fontSize: 16))
// ],
// ),
Row(
children: [
Icon(Icons.check, color: color),
Text("解锁所有高级功能",
style: TextStyle(
color: color, fontSize: 16))
],
)
],
)
: controller.state.selected ==
'com.wudi.app.monthly_pass'
? Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
Row(
// crossAxisAlignment
children: [
Icon(Icons.check, color: color),
Text("月卡会员",
style: TextStyle(
color: color, fontSize: 16))
],
),
Row(
children: [
Icon(Icons.check, color: color),
Text("无限聊天",
style: TextStyle(
color: color, fontSize: 16))
],
),
Row(
children: [
Icon(Icons.check, color: color),
Text("解锁所有高级功能",
style: TextStyle(
color: color, fontSize: 16))
],
)
],
)
: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
Row(
// crossAxisAlignment
children: [
Icon(Icons.check, color: color),
Text("周卡会员",
style: TextStyle(
color: color, fontSize: 16))
],
),
Row(
children: [
Icon(Icons.check, color: color),
Text("无限聊天",
style: TextStyle(
color: color, fontSize: 16))
],
),
Row(
children: [
Icon(Icons.check, color: color),
Text("解锁所有高级功能",
style: TextStyle(
color: color, fontSize: 16))
],
)
],
)),
Image(
image: AssetImage("assets/images/center-1.png"),
width: Get.mediaQuery.size.height * 0.17,
),
],
),
),
Obx(() => Container(
margin: EdgeInsets.only(top: 20),
child: Row(
// final String? productId;
// final String? price;
// final String? currency;
// final String? localizedPrice;
// final String? title;
// final String? description;
// final String? introductoryPrice;
children: controller.state.items
.asMap()
.keys
.map(
(item) => Expanded(
child: InkWell(
onTap: () {
Vibrate.feedback(
FeedbackType.selection);
controller.state.selected = controller
.state
.items[item]
.appleProductId!;
//
// c.requestPurchase(item);
},
child: GlassyCard(
config: GlassyConfig(
backgroundColor: controller
.state
.items[item]
.appleProductId! ==
controller.state.selected
? color
: Colors.grey),
child: Container(
height: 100,
padding: EdgeInsets.only(
top: 16,
left: 16,
right: 16,
bottom: 16),
// color: Colors.pink,
child: Column(
mainAxisAlignment:
MainAxisAlignment
.spaceAround,
children: [
Text(
'${controller.state.items[item].amount!}',
style: TextStyle(
color: Colors.white),
),
Text(
"${item == 0 ? '30次提问卡' : item == 1 ? '月卡' : '周卡'}",
maxLines: 2,
overflow: TextOverflow.clip,
style: TextStyle(
color: Colors.white),
)
],
)),
))),
)
.toList(),
),
)),
// GlassyButton(onPressed: () {}, child: Text("GradientButton"))
Expanded(
child: Container(
margin: EdgeInsets.only(top: 20),
child: GradientButton(
child: Text('订阅'),
increaseHeightBy: 15.00,
increaseWidthBy: 200.00,
callback: controller.requestPurchase,
gradient: Gradients.cosmicFusion,
shadowColor:
Gradients.backToFuture.colors.last.withOpacity(0.25),
),
))
// Container(
// padding: EdgeInsets.symmetric(horizontal: 40, vertical: 20),
// width: double.infinity,
// child:
// )
],
),
),
)
],
),
);
// Center(
// child:
// Obx(() => Text(
// "${controller.state.items.length}",
// style: TextStyle(color: Colors.amber, fontSize: 40),
// )),
// );
}
}
library widgets;
export 'helloword.dart';
...@@ -58,8 +58,9 @@ class PayListController extends GetxController { ...@@ -58,8 +58,9 @@ class PayListController extends GetxController {
void onInit() async { void onInit() async {
super.onInit(); super.onInit();
await initializedPlugins(); await initializedPlugins();
EasyLoading.show(status: "正在获取套餐中...");
await _getProduct(); await _getProduct();
EasyLoading.dismiss();
// await initializedPlugins(); // await initializedPlugins();
// new 对象 // new 对象
// 初始静态数据 // 初始静态数据
......
...@@ -183,7 +183,7 @@ class GoodsPageState extends State<PayItemWidget> { ...@@ -183,7 +183,7 @@ class GoodsPageState extends State<PayItemWidget> {
// color: Colors.orange, // color: Colors.orange,
onPressed: () { onPressed: () {
EasyLoading.show(status: '提交订单中...'); EasyLoading.show(status: '提交订单中...');
c.requestPurchase(item); c.requestPurchase();
// c() // c()
}, },
child: Text('购买套餐'), child: Text('购买套餐'),
......
...@@ -100,7 +100,7 @@ class PayItemWidget extends GetView<PayListController> { ...@@ -100,7 +100,7 @@ class PayItemWidget extends GetView<PayListController> {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Icon(Icons.send, color: color), Icon(Icons.send, color: color),
Text("升级 AI写作大师 Premium", Text(" 选择自己需要的套餐",
style: TextStyle(color: color, fontSize: 20)) style: TextStyle(color: color, fontSize: 20))
], ],
), ),
...@@ -111,38 +111,111 @@ class PayItemWidget extends GetView<PayListController> { ...@@ -111,38 +111,111 @@ class PayItemWidget extends GetView<PayListController> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Column( Obx(() => controller.state.selected ==
'com.wudi.app.60stars'
? Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [ children: [
Row( Row(
// crossAxisAlignment // crossAxisAlignment
children: [ children: [
Icon(Icons.check, color: color), Icon(Icons.check, color: color),
Text("无限聊天", Text("30次提问机会",
style: style: TextStyle(
TextStyle(color: color, fontSize: 16)) color: color, fontSize: 16))
],
),
// Row(
// children: [
// Icon(Icons.check, color: color),
// Text("无广告",
// style: TextStyle(
// color: color, fontSize: 16))
// ],
// ),
Row(
children: [
Icon(Icons.check, color: color),
Text("解锁所有高级功能",
style: TextStyle(
color: color, fontSize: 16))
],
)
],
)
: controller.state.selected ==
'com.wudi.app.monthly_pass'
? Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
Row(
// crossAxisAlignment
children: [
Icon(Icons.check, color: color),
Text("月卡会员",
style: TextStyle(
color: color, fontSize: 16))
], ],
), ),
Row( Row(
children: [ children: [
Icon(Icons.check, color: color), Icon(Icons.check, color: color),
Text("无广告", Text("无限聊天",
style: style: TextStyle(
TextStyle(color: color, fontSize: 16)) color: color, fontSize: 16))
], ],
), ),
Row( Row(
children: [ children: [
Icon(Icons.check, color: color), Icon(Icons.check, color: color),
Text("解锁所有高级功能", Text("解锁所有高级功能",
style: style: TextStyle(
TextStyle(color: color, fontSize: 16)) color: color, fontSize: 16))
], ],
) )
], ],
)
: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
Row(
// crossAxisAlignment
children: [
Icon(Icons.check, color: color),
Text("周卡会员",
style: TextStyle(
color: color, fontSize: 16))
],
),
Row(
children: [
Icon(Icons.check, color: color),
Text("无限聊天",
style: TextStyle(
color: color, fontSize: 16))
],
), ),
Row(
children: [
Icon(Icons.check, color: color),
Text("解锁所有高级功能",
style: TextStyle(
color: color, fontSize: 16))
],
)
],
)),
Image( Image(
image: AssetImage("assets/images/center-1.png"), image: AssetImage("assets/images/center-1.png"),
width: Get.mediaQuery.size.height * 0.17, width: Get.mediaQuery.size.height * 0.17,
......
...@@ -175,6 +175,7 @@ class ProductController extends GetxController { ...@@ -175,6 +175,7 @@ class ProductController extends GetxController {
} }
handleNextText() async { handleNextText() async {
try {
final a = final a =
state.messageQueenItemQueen.map((element) => element.text).join(""); state.messageQueenItemQueen.map((element) => element.text).join("");
...@@ -189,8 +190,15 @@ class ProductController extends GetxController { ...@@ -189,8 +190,15 @@ class ProductController extends GetxController {
element.isFinish = false; element.isFinish = false;
}); });
EasyLoading.dismiss(); EasyLoading.dismiss();
state.messageQueenItemQueen state.messageQueenItemQueen.add(
.add(MessageQueenItem(text: result, isFinish: false, isWhiteIng: true)); MessageQueenItem(text: result, isFinish: false, isWhiteIng: true));
} catch (e) {
EasyLoading.showError("网络异常");
EasyLoading.dismiss();
state.loading = false;
state.isWhite = false;
}
;
} }
handleFinished() { handleFinished() {
......
...@@ -170,15 +170,14 @@ class ProductPage extends GetView<ProductController> { ...@@ -170,15 +170,14 @@ class ProductPage extends GetView<ProductController> {
) )
], ],
) )
: Markdown(data: "${idx.text}"); : Text(
// Text( "${idx.text}",
// "${idx.text}", style: TextStyle(
// style: TextStyle( fontSize: 18,
// fontSize: 18, color: Colors.white,
// color: Colors.white, // fontWeight: FontWeight.bold
// // fontWeight: FontWeight.bold ),
// ), );
// );
return text; return text;
}).toList(), }).toList(),
......
import 'package:chart/models/user_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// import '../size_confige.dart';
class DoctorAppBar extends StatelessWidget {
const DoctorAppBar(
this.userModel, {
Key? key,
}) : super(key: key);
final UserModel userModel;
// late final UserModel _userModel;
// @override
// didChangeDependencies() {
// super.didChangeDependencies();
// _userModel = Provider.of<UserModel>(context);
// }
@override
Widget build(BuildContext context) {
// UserModel userViewModel = Provider.of<UserModel>(context);
// final text = Provider.of<String>(context);
// _userModel = Provider.of<UserModel>(context);
// ${userViewModel.integralEntity?.username}
// print(userViewModel.integralEntity);
return Container(
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(left: 20, top: 60, right: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
// ignore: prefer_const_literals_to_create_immutables
children: [
// ignore: prefer_const_constructors
Text(
"Hi,32121",
// ignore: prefer_const_constructors
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w800,
fontSize: 20),
),
SizedBox(height: 30),
// ignore: prefer_const_constructors
Text(
"欢迎使用AI写作大师,你可以收获很多",
style: TextStyle(color: Colors.white, fontSize: 12),
),
],
),
GestureDetector(
onTap: () => {Navigator.of(context).pushNamed('/goods')},
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
// boxShadow: [
// BoxShadow(
// blurRadius: 3,
// offset: Offset(0, 4),
// color: Colors.black54,
// )
// ],
// color: Color(0xffA295FD),
borderRadius: BorderRadius.circular(5)),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.asset("assets/images/dingyue.png")),
),
)
],
),
),
);
}
}
...@@ -76,130 +76,165 @@ class BannerPageWidget extends GetView<MainController> { ...@@ -76,130 +76,165 @@ class BannerPageWidget extends GetView<MainController> {
), ),
height: 270, height: 270,
width: double.infinity, width: double.infinity,
child: Center(
child: Column( child: Column(
children: [ mainAxisAlignment: MainAxisAlignment.center,
Row(
children: [
Expanded(
// width: double.infinity,
// height: 400,
child: Stack(
children: [ children: [
Container( Container(
width: 300, width: 300,
height: 130, height: 130,
padding: padding: EdgeInsets.only(top: 16),
EdgeInsets.only(top: 16),
child: Image.network( child: Image.network(
'${controller.state.bannerPage![index].icon}', '${controller.state.bannerPage![index].icon}',
fit: BoxFit.contain, fit: BoxFit.contain,
width: double.infinity, width: double.infinity,
// height: double.infinity,
), ),
// controller.state.bannerPage![index]
// .classifyDesc,
// Image.asset(
// doctorsList[index].image,
// fit: BoxFit.contain,
// width: double.infinity,
// height: double.infinity,
// ),
),
],
), ),
),
// SizedBox(width: 40)
],
),
Container(
// ignore: prefer_const_constructors
decoration: BoxDecoration(
// circular(24)
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(16),
bottomRight: Radius.circular(16),
),
// color: Colors.white,
),
//
// color: Colors.white,
height: 132,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 20, horizontal: 20),
child: Center(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text( Text(
controller controller
.state .state.bannerPage![index].classifyName,
.bannerPage![index] textAlign: TextAlign.left,
.classifyName,
style: TextStyle( style: TextStyle(
fontWeight: fontWeight: FontWeight.bold,
FontWeight.bold,
color: Colors.white, color: Colors.white,
fontSize: 24), fontSize: 24),
), ),
SizedBox(height: 5),
Text( Text(
controller controller
.state .state.bannerPage![index].classifyDesc,
.bannerPage![index]
.classifyDesc,
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white, fontSize: 16),
fontSize: 16), ),
SizedBox(
height: 5,
), ),
SizedBox(height: 5),
Row(
children: [
RatingBar.builder( RatingBar.builder(
unratedColor: Colors unratedColor: Colors.grey.withOpacity(0.5),
.grey
.withOpacity(0.5),
itemSize: 15, itemSize: 15,
initialRating: initialRating:
doctorsList[index] doctorsList[index].reviewScore.toDouble(),
.reviewScore
.toDouble(),
minRating: 0, minRating: 0,
allowHalfRating: true, allowHalfRating: true,
direction: direction: Axis.horizontal,
Axis.horizontal, itemPadding:
itemPadding: EdgeInsets EdgeInsets.symmetric(horizontal: 5),
.symmetric(
horizontal: 5),
itemCount: 5, itemCount: 5,
updateOnDrag: false, updateOnDrag: false,
itemBuilder: itemBuilder: (context, _) => Icon(
(context, _) =>
Icon(
Icons.star, Icons.star,
color: Colors.orange, color: Colors.orange,
), ),
onRatingUpdate: onRatingUpdate: (value) {},
(value) {},
), ),
SizedBox(width: 1), SizedBox(height: 5),
Text( Text(
"(103个用户使用过)", "(103个用户使用过)",
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white, fontSize: 12),
fontSize: 12),
) )
], ],
), ),
], // child: Center(
), // child: Column(
))), // children: [
], // Row(
// children: [
// Expanded(
// // width: double.infinity,
// // height: 400,
// child: Stack(
// children: [
// ],
// ),
// ),
// // SizedBox(width: 40)
// ],
// ),
// Container(
// decoration: BoxDecoration(
// borderRadius: const BorderRadius.only(
// bottomLeft: Radius.circular(16),
// bottomRight: Radius.circular(16),
// ),
// ),
// height: 132,
// child: Padding(
// padding: EdgeInsets.symmetric(
// vertical: 20, horizontal: 20),
// child: Center(
// child: Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// controller
// .state
// .bannerPage![index]
// .classifyName,
// style: TextStyle(
// fontWeight:
// FontWeight.bold,
// color: Colors.white,
// fontSize: 24),
// ),
// SizedBox(height: 5),
// Text(
// controller
// .state
// .bannerPage![index]
// .classifyDesc,
// style: TextStyle(
// color: Colors.white,
// fontSize: 16),
// ),
// SizedBox(height: 5),
// Row(
// children: [
// RatingBar.builder(
// unratedColor: Colors
// .grey
// .withOpacity(0.5),
// itemSize: 15,
// initialRating:
// doctorsList[index]
// .reviewScore
// .toDouble(),
// minRating: 0,
// allowHalfRating: true,
// direction:
// Axis.horizontal,
// itemPadding: EdgeInsets
// .symmetric(
// horizontal: 5),
// itemCount: 5,
// updateOnDrag: false,
// itemBuilder:
// (context, _) =>
// Icon(
// Icons.star,
// color: Colors.orange,
// ),
// onRatingUpdate:
// (value) {},
// ),
// SizedBox(width: 1),
// Text(
// "(103个用户使用过)",
// style: TextStyle(
// color: Colors.white,
// fontSize: 12),
// )
// ],
// ),
// ],
// ),
// ))),
// ],
// ),
// ),
), ),
)),
), ),
); );
// return controller.state.bannerPage![index % pages.length]; // return controller.state.bannerPage![index % pages.length];
......
...@@ -4,7 +4,7 @@ import 'package:chart/common/values/values.dart'; ...@@ -4,7 +4,7 @@ import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart'; import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:platform/platform.dart';
import '../../../common/store/user.dart'; import '../../../common/store/user.dart';
import '../index.dart'; import '../index.dart';
...@@ -91,7 +91,14 @@ class NewsCategoriesWidget extends GetView<MainController> { ...@@ -91,7 +91,14 @@ class NewsCategoriesWidget extends GetView<MainController> {
// AppRoutes.SIGN_IN // AppRoutes.SIGN_IN
Vibrate.feedback(FeedbackType.impact); Vibrate.feedback(FeedbackType.impact);
if (userC.isLogin) { if (userC.isLogin) {
// _platform
if (GetPlatform.isAndroid) {
Get.toNamed(AppRoutes.AN_PAY_LIST);
} else {
Get.toNamed(AppRoutes.PAY_LIST); Get.toNamed(AppRoutes.PAY_LIST);
}
// AN_PAY_LIST
} else { } else {
Get.toNamed(AppRoutes.SIGN_IN); Get.toNamed(AppRoutes.SIGN_IN);
} }
......
...@@ -111,6 +111,76 @@ class SiperBannerWidget extends GetView<MainController> { ...@@ -111,6 +111,76 @@ class SiperBannerWidget extends GetView<MainController> {
createdAt: DateTime.now(), createdAt: DateTime.now(),
)); ));
}, },
child: Container(
height: 70,
child: Row(
children: [
Container(
padding: const EdgeInsets.all(14),
margin: const EdgeInsets.only(right: 14),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
kCategoriesPrimaryColor[index],
kCategoriesSecondryColor[index],
],
),
borderRadius: BorderRadius.circular(16)),
child: const Icon(
Icons.headset_mic,
size: 20,
color: Colors.white,
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
message.question,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
maxLines: 1,
// ignore: prefer_const_constructors
style: TextStyle(
fontSize: 14,
decoration: TextDecoration.none,
color: Colors.white,
),
// softWrap: true,
// textAlign: TextAlign.left,
// overflow: TextOverflow.ellipsis,
// maxLines: 1,
// style: TextStyle(
// color: Colors.black.withOpacity(0.48), fontSize: 12),
),
Text(
"${message.resp}",
softWrap: true,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
maxLines: 1,
// ignore: prefer_const_constructors
style: TextStyle(
fontSize: 14,
decoration: TextDecoration.none,
color: Colors.white,
),
// softWrap: true,
// textAlign: TextAlign.left,
// overflow: TextOverflow.ellipsis,
// maxLines: 1,
// style: TextStyle(
// color: Colors.black.withOpacity(0.48), fontSize: 12),
)
]),
)
],
),
)
// child: Expanded( // child: Expanded(
// child: Row( // child: Row(
// mainAxisAlignment: MainAxisAlignment.center, // mainAxisAlignment: MainAxisAlignment.center,
......
...@@ -56,8 +56,8 @@ class UserDetailPage extends GetView<UserDetailController> { ...@@ -56,8 +56,8 @@ class UserDetailPage extends GetView<UserDetailController> {
children: [ children: [
// ignore: prefer_const_constructors // ignore: prefer_const_constructors
Container( Container(
width: 100, width: 80,
height: 100, height: 80,
margin: EdgeInsets.all(20), margin: EdgeInsets.all(20),
// color: Colors.black, // color: Colors.black,
padding: EdgeInsets.all(0), padding: EdgeInsets.all(0),
...@@ -146,7 +146,7 @@ class UserDetailPage extends GetView<UserDetailController> { ...@@ -146,7 +146,7 @@ class UserDetailPage extends GetView<UserDetailController> {
height: 20, height: 20,
), ),
Text( Text(
"会员日期至:${c.profile.expireTime.year}-${c.profile.expireTime.month}-${c.profile.expireTime.day}", " 会员日期至:${c.profile.expireTime.year}-${c.profile.expireTime.month}-${c.profile.expireTime.day}",
style: TextStyle( style: TextStyle(
color: Color.fromRGBO( color: Color.fromRGBO(
255, 255, 255, 1)), 255, 255, 255, 1)),
...@@ -163,7 +163,7 @@ class UserDetailPage extends GetView<UserDetailController> { ...@@ -163,7 +163,7 @@ class UserDetailPage extends GetView<UserDetailController> {
height: 20, height: 20,
), ),
Text( Text(
"积分剩余:", " 积分剩余:",
style: TextStyle( style: TextStyle(
color: Color.fromRGBO( color: Color.fromRGBO(
255, 255, 255, 1)), 255, 255, 255, 1)),
...@@ -383,7 +383,11 @@ class UserDetailPage extends GetView<UserDetailController> { ...@@ -383,7 +383,11 @@ class UserDetailPage extends GetView<UserDetailController> {
onTap: () { onTap: () {
Vibrate.feedback(FeedbackType.impact); Vibrate.feedback(FeedbackType.impact);
if (c.isLogin) { if (c.isLogin) {
if (GetPlatform.isAndroid) {
Get.toNamed(AppRoutes.AN_PAY_LIST);
} else {
Get.toNamed(AppRoutes.PAY_LIST); Get.toNamed(AppRoutes.PAY_LIST);
}
} else { } else {
Get.toNamed(AppRoutes.SIGN_IN); Get.toNamed(AppRoutes.SIGN_IN);
} }
......
import 'package:chart/utils/common_util.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:chart/common/entities/entities.dart'; import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/utils/utils.dart'; import 'package:chart/common/utils/utils.dart';
......
import 'package:chart/constant/app_colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:flutter_chat_types/flutter_chat_types.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_strings.dart';
import 'package:chart/models/app_model.dart';
import 'package:chart/models/user_model.dart';
import 'package:chart/widgets/sail_app_bar.dart';
import 'package:uuid/uuid.dart';
import 'package:mime/mime.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/services.dart';
import 'package:chart/service/message_service.dart';
// import 'package:chart/pages/webview_widget.dart';
import 'package:bubble/bubble.dart';
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:fluttertoast/fluttertoast.dart';
// import 'package:open_filex/open_filex.dart';
// import 'package:file_picker/file_picker.dart';
// import 'package:open_filex/open_filex.dart';
// import 'dart:convert';
// import 'dart:io';
// import 'package:path_provider/path_provider.dart';
// import 'package:glassmorphism/glassmorphism.dart';
// final _user = const types.User(
// id: '82091008-a484-4a89-ae75-a22bf8d6f3ac',
// );
// final _user1 = const types.User(
// id: '82091008-a4aa-4a89-ae75-a22bf8d6f3aa',
// );
// final receiveUser = const types.User(
// id: '82091008-a484-4a89-ae75-a22bf8d6f3aa',
// firstName: "GPT",
// lastName: '大师',
// imageUrl:
// "https://imgb15.photophoto.cn/20201124/jiqirentupian-39852917_3.jpg"
// // imageUrl: "assets/images/300.jpg",
// );
class ChatPage extends StatefulWidget {
const ChatPage({Key? key}) : super(key: key);
@override
HomePageState createState() => HomePageState();
}
class HomePageState extends State<ChatPage> {
final PageController _pageController = PageController(initialPage: 0);
late AppModel _appModel;
// late ServerModel _serverModel;
late UserModel _userModel;
// late UserSubscribeModel _userSubscribeModel;
bool _isLoadingData = false;
String _appTitle = 'AI写作大师';
// int _loadingIndex = 0;
// ignore: prefer_final_fields
// _userModel.setUserInfo(userEntity);
List<types.Message> _messages = [];
final Map _tabMap = {
0: AppStrings.appName,
1: "login",
2: '节点',
3: '我的',
};
@override
void initState() {
super.initState();
// _userModel.setIntegralInfo();
// _loadMessages();
}
@override
void didChangeDependencies() async {
super.didChangeDependencies();
_appModel = Provider.of<AppModel>(context);
_userModel = Provider.of<UserModel>(context);
// _userModel.setIntegralInfo();
_loadMessages();
// print("_userModel_userModel_userModel_userModel$_userModel");
}
void jumpToPage(int page) {
setState(() {
_pageController.jumpToPage(page);
_appTitle = _tabMap[page];
print("_appTitle: $_appTitle");
});
}
@override
Widget build(BuildContext context) {
// WebViewWidget(
// name: "title",
// url: "https://mp.weixin.qq.com/s/AJCPG0b72g4mB3ODM555Cw");
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
// _appModel.isOn
// ? SystemUiOverlayStyle.dark
// : SystemUiOverlayStyle.light,
child: Scaffold(
appBar: AppBar(
title: Text("AI写作大师"),
backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
),
// SailAppBar(
// appTitle: _appTitle,
// // rgba(41, 45, 62, 1.00)
// backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
// textColor: Colors.white
// //rgba(41, 45, 62, 1.00)
// ),
// extendBody: true,
// backgroundColor: Colors.amber,
// _appModel.isOn ? AppColors.yellowColor : AppColors.grayColor,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
// color: Color.fromRGBO(30, 28, 57, 1),
child: Chat(
onAttachmentPressed: _handleAttachmentPressed,
bubbleBuilder: _bubbleBuilder,
theme: const DefaultChatTheme(
// #1e1c39//#1e1c39#1e1c39#1e1c39
// rgba(30, 28, 57, 1.00)
backgroundColor: Color.fromRGBO(30, 28, 57, 0),
// inputBackgroundColor: Colors.red,
),
messages: _messages,
// onAttachmentPressed: _handleAttachmentPressed,
onMessageTap: _handleMessageTap,
onPreviewDataFetched: _handlePreviewDataFetched,
onSendPressed: _handleSendPressed,
showUserAvatars: true,
showUserNames: true,
user: _user,
l10n: const ChatL10nEn(
inputPlaceholder: '请输入你的问题,并寻求解答...',
attachmentButtonAccessibilityLabel: '继续',
emptyChatPlaceholder: '暂无聊天信息',
sendButtonAccessibilityLabel: '发送'),
)),
// floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
),
);
}
void _addMessage(types.Message message) {
setState(() {
_messages.insert(0, message);
});
}
void _cancelLoading() {
var data;
// _messages.forEach((element) {
// print(element.props);
// });
data = _messages.firstWhere((element) => element.status == Status.sending);
// _messages.where((mess)=>"${mess.}" === "loading");
setState(() {
_messages.remove(data);
});
}
void _handleAttachmentPressed() {
// var clonedArr = List.from(_messages).reversed.toList();
// final a = clonedArr.firstWhere((e) => e.id == receiveUser.id);
// // print();
// // final li = _messages.lastWhere((element) => element.id == receiveUser.id);
// print("lililililili$a");
// showModalBottomSheet<void>(
// context: context,
// builder: (BuildContext context) => SafeArea(
// child: SizedBox(
// height: 144,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: <Widget>[
// TextButton(
// onPressed: () {
// Navigator.of(context).pushNamed('/login');
// },
// child: const Align(
// alignment: AlignmentDirectional.centerStart,
// child: Text(''),
// ),
// ),
// TextButton(
// onPressed: () {
// Navigator.pop(context);
// _handleFileSelection();
// },
// child: const Align(
// alignment: AlignmentDirectional.centerStart,
// child: Text('File'),
// ),
// ),
// TextButton(
// onPressed: () => Navigator.pop(context),
// child: const Align(
// alignment: AlignmentDirectional.centerStart,
// child: Text('Cancel'),
// ),
// ),
// ],
// ),
// ),
// ),
// );
}
void _handleFileSelection() async {
// final result = await FilePicker.platform.pickFiles(
// type: FileType.any,
// );
// if (result != null && result.files.single.path != null) {
// final message = types.FileMessage(
// author: _user,
// createdAt: DateTime.now().millisecondsSinceEpoch,
// id: const Uuid().v4(),
// mimeType: lookupMimeType(result.files.single.path!),
// name: result.files.single.name,
// size: result.files.single.size,
// uri: result.files.single.path!,
// );
// _addMessage(message);
// }
}
void _handleImageSelection() async {
// final result = await ImagePicker().pickImage(
// imageQuality: 70,
// maxWidth: 1440,
// source: ImageSource.gallery,
// );
// if (result != null) {
// final bytes = await result.readAsBytes();
// final image = await decodeImageFromList(bytes);
// final message = types.ImageMessage(
// author: _user,
// createdAt: DateTime.now().millisecondsSinceEpoch,
// height: image.height.toDouble(),
// id: const Uuid().v4(),
// name: result.name,
// size: bytes.length,
// uri: result.path,
// width: image.width.toDouble(),
// );
// _addMessage(message);
// }
}
void _handleMessageTap(BuildContext _, types.Message message) async {
// print("$message");
// if (message is types.FileMessage) {
// var localPath = message.uri;
// if (message.uri.startsWith('http')) {
// try {
// final index =
// _messages.indexWhere((element) => element.id == message.id);
// final updatedMessage =
// (_messages[index] as types.FileMessage).copyWith(
// isLoading: true,
// );
// setState(() {
// _messages[index] = updatedMessage;
// });
// final client = http.Client();
// final request = await client.get(Uri.parse(message.uri));
// final bytes = request.bodyBytes;
// final documentsDir = (await getApplicationDocumentsDirectory()).path;
// localPath = '$documentsDir/${message.name}';
// if (!File(localPath).existsSync()) {
// final file = File(localPath);
// await file.writeAsBytes(bytes);
// }
// } finally {
// final index =
// _messages.indexWhere((element) => element.id == message.id);
// final updatedMessage =
// (_messages[index] as types.FileMessage).copyWith(
// isLoading: null,
// );
// setState(() {
// _messages[index] = updatedMessage;
// });
// }
// }
// await OpenFilex.open(localPath);
// }
}
void _handlePreviewDataFetched(
types.TextMessage message,
types.PreviewData previewData,
) {
final index = _messages.indexWhere((element) => element.id == message.id);
final updatedMessage = (_messages[index] as types.TextMessage).copyWith(
previewData: previewData,
);
setState(() {
_messages[index] = updatedMessage;
});
}
void _handleSendPressed(types.PartialText message) async {
print("messagemessagemessagemessagemessage$message");
var data = false;
// _messages.forEach((element) {
// print(element.props);
// });
if (_messages.isNotEmpty) {
data = !_messages.every((element) => element.status != Status.sending);
}
print("data-----------${data}");
if (data) {
Fluttertoast.showToast(
msg: "操作太快了 你上个问题还没问完呢",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
return;
}
final textMessage = types.TextMessage(
author: _user,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: message.text,
);
final loadingMessage = types.TextMessage(
author: receiveUser,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: "loading",
status: Status.sending,
// "sending",
);
_addMessage(textMessage);
_addMessage(loadingMessage);
try {
String? result = await MessageService().getMessage(
{"question": message.text, "id": _userModel.integralEntity?.id});
_cancelLoading();
final receiveMessage = types.TextMessage(
author: receiveUser,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: "$result",
);
_addMessage(receiveMessage);
} catch (e) {
print("eeeeeeee$e");
_cancelLoading();
final receiveErrorMessage = types.TextMessage(
author: receiveUser,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: "当前用户太多了,请稍等再试",
);
_addMessage(receiveErrorMessage);
}
}
void _viewMessage(String value) {
final textMessage1 = types.TextMessage(
author: _user1,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: value,
);
_addMessage(textMessage1);
// // print(value);
// print(value); //msg value: Hello, World!
}
void _loadMessages() {
try {
Map<String, dynamic> routeParams =
ModalRoute.of(context)!.settings?.arguments as Map<String, dynamic>;
if (routeParams['question'].toString().isNotEmpty) {
print("routeParamsrouteParamsrouteParams${routeParams}");
_handleSendPressed(PartialText(text: routeParams['question']));
}
} catch (e) {
print("${e.toString()}");
}
// _handleSendPressed
// routeParams.question
// final arguments = ModalRoute.of(context)!.settings.arguments;
// print("${arguments},argumentsargumentsargumentsarguments");
// a = arguments?.questions;
// final response = `""`
// final messages = (jsonDecode(response) as List)
// .map((e) => types.Message.fromJson(e as Map<String, dynamic>))
// .toList();
// setState(() {
// _messages = messages;
// });
}
}
Widget _bubbleBuilder(Widget child,
{required message, required nextMessageInGroup, r}) =>
Bubble(
style: BubbleStyle(
// borderColor: Colors.red,
),
stick: true,
// onMessage:()=>{},
// ignore: sort_child_properties_last
child: Column(children: [
AnimatedTextKit(
onFinished: () => {},
totalRepeatCount: 1,
animatedTexts: identical(message.status, Status.sending)
? [
TypewriterAnimatedText('正在思考中...'),
TypewriterAnimatedText('正在使劲思考中......'),
TypewriterAnimatedText('正在拼命思考中......'),
TypewriterAnimatedText('您的问题太有深度,请稍等......'),
]
: [
TypewriterAnimatedText(
message.text,
speed: const Duration(milliseconds: 100),
)
],
),
// GestureDetector(
// onTap: () => {
// print(message)
// // child.
// // widget _handleSendPressed(PartialText(text: routeParams['question']));
// // print("message")
// },
// child: Text("继续"),
// )
]),
color: _user.id != message.author.id ||
message.type == types.MessageType.image
// rgba(149, 236, 105, 1.00)
? const Color(0xfff5f5f7)
: const Color.fromRGBO(149, 236, 105, 1),
margin: nextMessageInGroup
? const BubbleEdges.symmetric(horizontal: 6)
: null,
nip: nextMessageInGroup
? BubbleNip.no
: _user.id != message.author.id
? BubbleNip.leftBottom
: BubbleNip.rightBottom,
);
import 'dart:async';
import 'dart:io';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:chart/entity/user_entity.dart';
import 'package:flutter/material.dart';
import 'package:chart/service/user_service.dart';
// import 'package:glass_kit/glass_kit.dart';
import 'package:glassmorphism/glassmorphism.dart';
// import './pay_test.dart';
// import 'package:responsive_grid_list/responsive_grid_list.dart';
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
import 'package:provider/provider.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import '../../models/user_model.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
class GoodsPage extends StatefulWidget {
const GoodsPage({Key? key}) : super(key: key);
@override
GoodsPageState createState() => GoodsPageState();
}
class GoodsPageState extends State<GoodsPage> {
late StreamSubscription _purchaseUpdatedSubscription;
late StreamSubscription _purchaseErrorSubscription;
late StreamSubscription _conectionSubscription;
late UserModel _userModel;
final List<String> _productLists = [
"com.wudi.app.weekly_pass",
"com.wudi.app.monthly_pass",
"com.wudi.app.60stars"
// "com.wudi.app.prod_id_002",
// "com.wudi.app.prod_id_003",
// "com.wudi.app.prod_id_004"
];
// Platform.isAndroid ? [] : ["com.wudi.app.prod_id_003"];
String _platformVersion = 'Unknown';
List<IAPItem> _items = [];
List<PurchasedItem> _purchases = [];
// var guides = [AppImages.guide1, AppImages.guide2, AppImages.guide3];
// var _showButton = false;
// final FocusNode focusNode = FocusNode();
// @override
// Future<void> initState() async {
// // TODO: implement initState
// super.initState();
// // _getGoods();
// // ResponseResult<List<AppleProduct>> response = await OrderService.getInstance().getAppleProduct();
// // if (response.isSuccess) {
// // /// 步骤2
// // _initStoreInfo(response.data);
// // }
// // List<IAPItem> items =
// // await FlutterInappPurchase.instance.getProducts( ['0001', '0002', '0003'] );
// }
@override
void didChangeDependencies() async {
super.didChangeDependencies();
_userModel = Provider.of<UserModel>(context);
await _getProduct();
// await _getPurchases();
}
@override
initState() {
initPlatformState();
}
// _getProduct
Future _getPurchases() async {
List<PurchasedItem>? items =
await FlutterInappPurchase.instance.getAvailablePurchases();
for (var item in items!) {
print('${item.toString()}');
this._purchases.add(item);
}
setState(() {
this._items = [];
this._purchases = items;
});
}
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// prepare
var result = await FlutterInappPurchase.instance.initialize();
print('result: $result');
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
// print("$platformVersion");
// setState(() {
// _platformVersion = platformVersion;
// });
// refresh items for android
try {
String msg = await FlutterInappPurchase.instance.consumeAll();
print('consumeAllItems: $msg');
} catch (err) {
print('consumeAllItems error: $err');
}
_conectionSubscription =
FlutterInappPurchase.connectionUpdated.listen((connected) {
print('connected: $connected');
});
_purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen((productItem) async {
// print(a);
ApplePayEntity? res = await UserService().applePayCallBack({
'receipt': productItem?.transactionReceipt,
'userId': _userModel.integralEntity?.id,
"chooseEnv": false
});
if (res?.status == 200) {
await FlutterInappPurchase.instance.clearTransactionIOS();
EasyLoading.showSuccess('${res?.message}');
EasyLoading.dismiss();
} else {
EasyLoading.showError("${res?.message}}");
EasyLoading.dismiss();
}
// print(res,'resres')
//
// print("EasyLoadingEasyLoading${EasyLoading.isShow}");
// EasyLoading.showProgress(0.3,
// status: 'downloading...');
// EasyLoading.showSuccess('Great Success!');
// EasyLoading.showError('Failed with Error');
// EasyLoading.showInfo('Useful Information.');
// EasyLoading.showToast('Toast');
// EasyLoading.dismiss();
// print("---------- Buy Item Button Pressed");
});
_purchaseErrorSubscription =
FlutterInappPurchase.purchaseError.listen((purchaseError) {
// print('purchase-error: $purchaseError');
EasyLoading.showError('支付订单失败');
EasyLoading.dismiss();
});
}
@override
dispose() {
_purchaseUpdatedSubscription.cancel();
_purchaseErrorSubscription.cancel();
_conectionSubscription.cancel();
super.dispose();
}
Future _getProduct() async {
try {
List<IAPItem> items =
await FlutterInappPurchase.instance.getProducts(_productLists);
for (var item in items) {
print('${item.toString()}');
this._items.add(item);
}
setState(() {
this._items = items;
this._purchases = [];
});
} catch (e) {
print("_getProductError$e");
}
}
// Future getPurchaseHistory() async {
// List<IAPItem> items =
// await FlutterInappPurchase.instance.getProducts(_productLists);
// _requestPurchase(items[0]);
// // print("23132132");
// // try {
// // String msg = await FlutterInappPurchase.instance.consumeAll();
// // print('${Platform.isIOS}-$msg');
// // } catch (err) {
// // print('consumeAllItems error: $err');
// // }
// // try {
// // List<PurchasedItem>? items =
// // await FlutterInappPurchase.instance.getPurchaseHistory();
// // for (var item in items!) {
// // print('${item.toString()}');
// // // purchasesList.add(item);
// // }
// // } catch (e) {
// // print(e.toString());
// // }
// }
void _requestPurchase(IAPItem item) {
FlutterInappPurchase.instance.requestPurchase(item.productId!);
}
_getGoods() async {
// List<goodEntity>? goodsList = await UserService().getGoodsList();
}
// Future<void> initPlatformState() async {
// var result = (await FlutterInappPurchase.instance.initialize());
// _conectionSubscription =
// FlutterInappPurchase.connectionUpdated.listen((connected) {
// print('connected: $connected');
// });
// // print("initialize${result}");
// }
List<Widget> _renderInApps() {
List<Widget> widgets = _items
.map((item) => GlassmorphicContainer(
borderRadius: 16,
margin: EdgeInsets.only(top: 16),
blur: 14,
alignment: Alignment.bottomCenter,
border: 2,
linearGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF0FFFF).withOpacity(0.2),
const Color(0xFF0FFFF).withOpacity(0.2),
],
),
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF0FFFF).withOpacity(1),
const Color(0xFFFFFFF),
const Color(0xFF0FFFF).withOpacity(1),
],
),
height: 173,
width: double.infinity,
// margin: EdgeInsets.symmetric(vertical: 10.0),
child: Container(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(16.0),
width: double.infinity,
// height: 200,
child: Column(children: [
Row(
children: [
const Text(
"项目名称:",
style: TextStyle(color: Colors.white),
),
SizedBox(
width: 10,
),
Text(
item.title!,
style: TextStyle(color: Colors.white),
)
],
),
Row(
children: [
const Text(
"项目价格:",
style: TextStyle(color: Colors.white),
),
SizedBox(
width: 10,
),
Text(
item.localizedPrice!,
style: TextStyle(color: Colors.white),
)
],
),
Row(
children: [
const Text(
"项目描述:",
style: TextStyle(color: Colors.white),
),
SizedBox(
width: 10,
),
Expanded(
child: Text(
maxLines: 3,
item.description!,
style: TextStyle(
color: Colors.white,
),
))
],
),
Row(children: [
ElevatedButton(
// color: Colors.orange,
onPressed: () {
EasyLoading.show(status: '提交订单中...');
this._requestPurchase(item);
},
child: Text('购买套餐'),
),
])
]),
// child: ,
),
],
),
),
))
.toList();
return widgets;
}
List<Widget> _renderPurchases() {
List<Widget> widgets = this
._purchases
.map((item) => Container(
margin: EdgeInsets.symmetric(vertical: 10.0),
child: Container(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 5.0),
child: Text(
item.toString(),
style: TextStyle(
fontSize: 18.0,
color: Colors.black,
),
),
)
],
),
),
))
.toList();
return widgets;
}
final spinkit = SpinKitFadingCircle(
itemBuilder: (BuildContext context, int index) {
return DecoratedBox(
decoration: BoxDecoration(
color: index.isEven ? Colors.red : Colors.green,
),
);
},
);
@override
Widget build(BuildContext context) {
// UserModel().setIsFirstOpen(false);
return Scaffold(
backgroundColor: const Color(0xFFF4F4F4),
appBar: AppBar(
title: Text("套餐"),
backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
),
body: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: ListView(
children: [
Container(
// color: Colors.black,
child: Column(
// ignore: prefer_const_literals_to_create_immutables
children: [
Row(
// ignore: prefer_const_literals_to_create_immutables
children: [
const Text(
"丰富您的使用体验感",
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: 24,
height: 2.5,
fontWeight: FontWeight.w500),
)
],
),
Row(children: const [
Text(
"解锁更多权限",
textAlign: TextAlign.left,
style: TextStyle(
// rgba(137, 137, 138, 1.00)
color: Color.fromRGBO(228, 228, 242, 1),
fontSize: 16,
// #89898a
),
)
])
],
)),
GlassmorphicContainer(
borderRadius: 16,
margin: EdgeInsets.only(top: 16),
blur: 14,
alignment: Alignment.bottomCenter,
border: 2,
linearGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF0FFFF).withOpacity(0.2),
const Color(0xFF0FFFF).withOpacity(0.2),
],
),
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF0FFFF).withOpacity(1),
const Color(0xFFFFFFF),
const Color(0xFF0FFFF).withOpacity(1),
],
),
height: 200,
width: double.infinity,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
verticalDirection: VerticalDirection.up,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(children: const [
Icon(Icons.list, size: 30, color: Colors.white),
SizedBox(
width: 10,
),
Text("无限制AI消息回复", style: TextStyle(color: Colors.white))
]),
Row(children: const [
Icon(Icons.list, size: 30, color: Colors.white),
SizedBox(
width: 10,
),
Text("与先进的机器人聊天互动",
style: TextStyle(color: Colors.white))
]),
Row(children: const [
Icon(Icons.list, size: 30, color: Colors.white),
SizedBox(
width: 10,
),
Text("AI只能续写&生成文章",
style: TextStyle(color: Colors.white))
]),
Row(children: const [
Icon(Icons.list, size: 30, color: Colors.white),
SizedBox(
width: 10,
),
Text("100%不受广告弹出限制",
style: TextStyle(color: Colors.white))
])
],
),
),
),
Container(
margin: EdgeInsets.only(top: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Tap to view the ",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
// FlutterInappPurchase.instance.requestPurchase(item.productId);
GestureDetector(
onTap: () => {
// print("object")
// getPurchaseHistory()
// FlutterInappPurchase.instance
// .requestPurchase("Prod_ID_001")
},
child: Text(
"EULA",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.amber),
),
),
],
)),
Column(
children: _renderInApps(),
),
// Column(
// children: _renderPurchases(),
// ),
// PayApp()
// GridView(
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 5,
// ),
// children: []),
// // Container()
],
),
),
),
);
}
}
// import 'package:flutter/material.dart';
// import 'dart:async';
// import 'dart:io';
// import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
// void main() => runApp(new MyApp());
// class MyApp extends StatelessWidget {
// @override
// Widget build(BuildContext context) {
// return MaterialApp(
// title: 'Flutter Demo',
// home: Scaffold(
// appBar: AppBar(
// title: Text('Flutter Inapp Plugin by dooboolab'),
// ),
// body: InApp()),
// );
// }
// }
// class InApp extends StatefulWidget {
// @override
// _InAppState createState() => new _InAppState();
// }
// class _InAppState extends State<InApp> {
// late StreamSubscription _purchaseUpdatedSubscription;
// late StreamSubscription _purchaseErrorSubscription;
// late StreamSubscription _conectionSubscription;
// final List<String> _productLists = Platform.isAndroid
// ? [
// 'android.test.purchased',
// 'point_1000',
// '5000_point',
// 'android.test.canceled',
// ]
// : ['com.cooni.point1000', 'com.cooni.point5000'];
// String _platformVersion = 'Unknown';
// List<IAPItem> _items = [];
// List<PurchasedItem> _purchases = [];
// @override
// void initState() {
// super.initState();
// initPlatformState();
// }
// @override
// void dispose() {
// if (_conectionSubscription != null) {
// _conectionSubscription.cancel();
// _conectionSubscription = null;
// }
// super.dispose();
// }
// // Platform messages are asynchronous, so we initialize in an async method.
// Future<void> initPlatformState() async {
// String platformVersion;
// // Platform messages may fail, so we use a try/catch PlatformException.
// // prepare
// var result = await FlutterInappPurchase.instance.initialize();
// print('result: $result');
// // If the widget was removed from the tree while the asynchronous platform
// // message was in flight, we want to discard the reply rather than calling
// // setState to update our non-existent appearance.
// if (!mounted) return;
// setState(() {
// _platformVersion = platformVersion;
// });
// // refresh items for android
// try {
// String msg = await FlutterInappPurchase.instance.consumeAll();
// print('consumeAllItems: $msg');
// } catch (err) {
// print('consumeAllItems error: $err');
// }
// _conectionSubscription =
// FlutterInappPurchase.connectionUpdated.listen((connected) {
// print('connected: $connected');
// });
// _purchaseUpdatedSubscription =
// FlutterInappPurchase.purchaseUpdated.listen((productItem) {
// print('purchase-updated: $productItem');
// });
// _purchaseErrorSubscription =
// FlutterInappPurchase.purchaseError.listen((purchaseError) {
// print('purchase-error: $purchaseError');
// });
// }
// void _requestPurchase(IAPItem item) {
// FlutterInappPurchase.instance.requestPurchase(item.productId);
// }
// Future _getProduct() async {
// List<IAPItem> items =
// await FlutterInappPurchase.instance.getProducts(_productLists);
// for (var item in items) {
// print('${item.toString()}');
// this._items.add(item);
// }
// setState(() {
// this._items = items;
// this._purchases = [];
// });
// }
// Future _getPurchases() async {
// List<PurchasedItem>? items =
// await FlutterInappPurchase.instance.getAvailablePurchases();
// for (var item in items!) {
// print('${item.toString()}');
// this._purchases.add(item);
// }
// setState(() {
// this._items = [];
// this._purchases = items;
// });
// }
// Future _getPurchaseHistory() async {
// List<PurchasedItem>? items =
// await FlutterInappPurchase.instance.getPurchaseHistory();
// for (var item in items!) {
// print('${item.toString()}');
// this._purchases.add(item);
// }
// setState(() {
// this._items = [];
// this._purchases = items;
// });
// }
// List<Widget> _renderInApps() {
// List<Widget> widgets = this
// ._items
// .map((item) => Container(
// margin: EdgeInsets.symmetric(vertical: 10.0),
// child: Container(
// child: Column(
// children: <Widget>[
// Container(
// margin: EdgeInsets.only(bottom: 5.0),
// child: Text(
// item.toString(),
// style: TextStyle(
// fontSize: 18.0,
// color: Colors.black,
// ),
// ),
// ),
// FlatButton(
// color: Colors.orange,
// onPressed: () {
// print("---------- Buy Item Button Pressed");
// this._requestPurchase(item);
// },
// child: Row(
// children: <Widget>[
// Expanded(
// child: Container(
// height: 48.0,
// alignment: Alignment(-1.0, 0.0),
// child: Text('Buy Item'),
// ),
// ),
// ],
// ),
// ),
// ],
// ),
// ),
// ))
// .toList();
// return widgets;
// }
// List<Widget> _renderPurchases() {
// List<Widget> widgets = this
// ._purchases
// .map((item) => Container(
// margin: EdgeInsets.symmetric(vertical: 10.0),
// child: Container(
// child: Column(
// children: <Widget>[
// Container(
// margin: EdgeInsets.only(bottom: 5.0),
// child: Text(
// item.toString(),
// style: TextStyle(
// fontSize: 18.0,
// color: Colors.black,
// ),
// ),
// )
// ],
// ),
// ),
// ))
// .toList();
// return widgets;
// }
// @override
// Widget build(BuildContext context) {
// double screenWidth = MediaQuery.of(context).size.width - 20;
// double buttonWidth = (screenWidth / 3) - 20;
// return Container(
// padding: EdgeInsets.all(10.0),
// child: ListView(
// children: <Widget>[
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start,
// children: <Widget>[
// Container(
// child: Text(
// 'Running on: $_platformVersion\n',
// style: TextStyle(fontSize: 18.0),
// ),
// ),
// Column(
// children: <Widget>[
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: <Widget>[
// Container(
// width: buttonWidth,
// height: 60.0,
// margin: EdgeInsets.all(7.0),
// child: FlatButton(
// color: Colors.amber,
// padding: EdgeInsets.all(0.0),
// onPressed: () async {
// print("---------- Connect Billing Button Pressed");
// await FlutterInappPurchase.instance.initialize();
// },
// child: Container(
// padding: EdgeInsets.symmetric(horizontal: 20.0),
// alignment: Alignment(0.0, 0.0),
// child: Text(
// 'Connect Billing',
// style: TextStyle(
// fontSize: 16.0,
// ),
// ),
// ),
// ),
// ),
// Container(
// width: buttonWidth,
// height: 60.0,
// margin: EdgeInsets.all(7.0),
// child: FlatButton(
// color: Colors.amber,
// padding: EdgeInsets.all(0.0),
// onPressed: () async {
// print("---------- End Connection Button Pressed");
// await FlutterInappPurchase.instance.finalize();
// if (_purchaseUpdatedSubscription != null) {
// _purchaseUpdatedSubscription.cancel();
// _purchaseUpdatedSubscription = null;
// }
// if (_purchaseErrorSubscription != null) {
// _purchaseErrorSubscription.cancel();
// _purchaseErrorSubscription = null;
// }
// setState(() {
// this._items = [];
// this._purchases = [];
// });
// },
// child: Container(
// padding: EdgeInsets.symmetric(horizontal: 20.0),
// alignment: Alignment(0.0, 0.0),
// child: Text(
// 'End Connection',
// style: TextStyle(
// fontSize: 16.0,
// ),
// ),
// ),
// ),
// ),
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: <Widget>[
// Container(
// width: buttonWidth,
// height: 60.0,
// margin: EdgeInsets.all(7.0),
// child: FlatButton(
// color: Colors.green,
// padding: EdgeInsets.all(0.0),
// onPressed: () {
// print("---------- Get Items Button Pressed");
// this._getProduct();
// },
// child: Container(
// padding: EdgeInsets.symmetric(horizontal: 20.0),
// alignment: Alignment(0.0, 0.0),
// child: Text(
// 'Get Items',
// style: TextStyle(
// fontSize: 16.0,
// ),
// ),
// ),
// )),
// Container(
// width: buttonWidth,
// height: 60.0,
// margin: EdgeInsets.all(7.0),
// child: FlatButton(
// color: Colors.green,
// padding: EdgeInsets.all(0.0),
// onPressed: () {
// print(
// "---------- Get Purchases Button Pressed");
// this._getPurchases();
// },
// child: Container(
// padding: EdgeInsets.symmetric(horizontal: 20.0),
// alignment: Alignment(0.0, 0.0),
// child: Text(
// 'Get Purchases',
// style: TextStyle(
// fontSize: 16.0,
// ),
// ),
// ),
// )),
// Container(
// width: buttonWidth,
// height: 60.0,
// margin: EdgeInsets.all(7.0),
// child: FlatButton(
// color: Colors.green,
// padding: EdgeInsets.all(0.0),
// onPressed: () {
// print(
// "---------- Get Purchase History Button Pressed");
// this._getPurchaseHistory();
// },
// child: Container(
// padding: EdgeInsets.symmetric(horizontal: 20.0),
// alignment: Alignment(0.0, 0.0),
// child: Text(
// 'Get Purchase History',
// style: TextStyle(
// fontSize: 16.0,
// ),
// ),
// ),
// )),
// ]),
// ],
// ),
// Column(
// children: this._renderInApps(),
// ),
// Column(
// children: this._renderPurchases(),
// ),
// ],
// ),
// ],
// ),
// );
// }
// }
import 'package:flutter/material.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:chart/constant/app_dimens.dart';
import 'package:chart/constant/app_images.dart';
import 'package:chart/constant/app_strings.dart';
import 'package:chart/models/user_model.dart';
import 'package:chart/utils/navigator_util.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:card_swiper/card_swiper.dart';
class GuidePage extends StatefulWidget {
const GuidePage({Key? key}) : super(key: key);
@override
GuidePageState createState() => GuidePageState();
}
class GuidePageState extends State<GuidePage> {
var guides = [AppImages.guide1, AppImages.guide2, AppImages.guide3];
var _showButton = false;
@override
Widget build(BuildContext context) {
UserModel().setIsFirstOpen(false);
return Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: [
_guideWidget(),
Positioned(
right: ScreenUtil().setWidth(30),
bottom: ScreenUtil().setHeight(30),
child: Offstage(
offstage: !_showButton,
child: Center(
child: TextButton(
style: TextButton.styleFrom(
primary: AppColors.themeColor,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30))),
),
onPressed: () {
NavigatorUtil.goHomePage(context);
},
child: const Text(AppStrings.openDoor,
style: TextStyle(fontSize: AppDimens.bigTextSize)),
)),
)),
],
));
}
Widget _guideWidget() {
return Swiper(
itemCount: guides.length,
//item数量
scrollDirection: Axis.horizontal,
//滚动方向 设置为Axis.vertical如果需要垂直滚动
itemBuilder: (BuildContext context, int index) {
return Image.asset(
guides[index],
fit: BoxFit.fill,
width: double.infinity,
height: double.infinity,
);
},
autoplay: true,
//自动滚动
loop: false,
//循环滚动
pagination: const SwiperPagination(
alignment: Alignment.bottomCenter,
builder: DotSwiperPaginationBuilder(
activeColor: Color(0xFFFF5722), //选中的颜色
color: Color(0xFF999999), //非选中的颜色
)),
onIndexChanged: ((value) {
//图片数组下标变化监听
if (value == guides.length - 1) {
setState(() {
_showButton = true;
});
} else if (_showButton && value != guides.length - 1) {
//减少非必要的setState 只有当滑动到最后一张图片然后向做滑动的时候触发
setState(() {
_showButton = false;
});
}
}),
);
}
}
// import 'dart:convert';
// import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:flutter_chat_types/flutter_chat_types.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_strings.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
// import 'package:chart/constant/app_dimens.dart';
// import 'package:intl/date_symbol_data_local.dart';
// import 'package:file_picker/file_picker.dart';
// import 'package:image_picker/image_picker.dart';
import 'package:chart/models/app_model.dart';
import 'package:chart/models/user_model.dart';
import 'package:chart/widgets/sail_app_bar.dart';
import 'package:uuid/uuid.dart';
// import 'package:mime/mime.dart';
import 'package:flutter/services.dart';
import 'package:chart/service/message_service.dart';
// import 'package:chart/pages/webview_widget.dart';
import 'package:bubble/bubble.dart';
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:chart/pages/dashboard/dashboard_page.dart';
import 'package:chart/pages/user/user_page.dart';
import 'package:chart/pages/square/square_page.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
final _user = const types.User(
id: '82091008-a484-4a89-ae75-a22bf8d6f3ac',
);
final _user1 = const types.User(
id: '82091008-a4aa-4a89-ae75-a22bf8d6f3aa',
);
final receiveUser = const types.User(
id: '82091008-a484-4a89-ae75-a22bf8d6f3aa',
firstName: "GPT",
lastName: '大师',
imageUrl:
"https://imgb15.photophoto.cn/20201124/jiqirentupian-39852917_3.jpg"
// imageUrl: "assets/images/300.jpg",
);
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
final PageController _pageController = PageController(initialPage: 0);
late AppModel _appModel;
GlobalKey<CurvedNavigationBarState> _bottomNavigationKey = GlobalKey();
var subscription;
final _pageList = [DashBoardPage(), SquarePage(), UserPage()];
// late ServerModel _serverModel;
late UserModel _userModel;
String _connectionStatus = 'Unknown';
// late UserSubscribeModel _userSubscribeModel;
bool _isLoadingData = false;
String _appTitle = 'AI写作大师';
dynamic _selectedIndex = 0;
final Connectivity _connectivity = Connectivity();
// int _loadingIndex = 0;
// ignore: prefer_final_fields
List<types.Message> _messages = [];
final Map _tabMap = {
0: AppStrings.appName,
1: "login",
2: '节点',
3: '我的',
};
@override
void initState() {
super.initState();
_loadMessages();
subscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) {
// Navigator.pop();
// await _userModel.setIntegralInfo();
setState(() => _connectionStatus = result.toString());
print("resultresultresultresultresultresult$result");
// Got a new connectivity status!
});
}
Future<Null> initConnectivity() async {
String connectionStatus;
//平台消息可能会失败,因此我们使用Try/Catch PlatformException。
try {
connectionStatus = (await _connectivity.checkConnectivity()).toString();
} on PlatformException catch (e) {
print(e.toString());
connectionStatus = 'Failed to get connectivity.';
}
// 如果在异步平台消息运行时从树中删除了该小部件,
// 那么我们希望放弃回复,而不是调用setstate来更新我们不存在的外观。
if (!mounted) {
return;
}
setState(() {
_connectionStatus = connectionStatus;
});
}
@override
dispose() {
subscription.cancel();
super.dispose();
}
// @override
// initState() {
// super.initState();
// subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
// // Got a new connectivity status!
// });
// }
@override
void didChangeDependencies() async {
super.didChangeDependencies();
_appModel = Provider.of<AppModel>(context);
_userModel = Provider.of<UserModel>(context);
await _userModel.setIntegralInfo();
await _userModel.getClassFyList();
}
void jumpToPage(int page) {
setState(() {
_pageController.jumpToPage(page);
_appTitle = _tabMap[page];
print("_appTitle: $_appTitle");
});
}
@override
Widget build(BuildContext context) {
print(
"_connectionStatus_connectionStatus_connectionStatus$_connectionStatus");
// WebViewWidget(
// name: "title",
// url: "https://mp.weixin.qq.com/s/AJCPG0b72g4mB3ODM555Cw");
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark,
// _appModel.isOn
// ? SystemUiOverlayStyle.dark
// : SystemUiOverlayStyle.light,
child: Scaffold(
appBar: _selectedIndex == 0
? null
: SailAppBar(
appTitle: _appTitle,
backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
),
// extendBody: true,
// backgroundColor:
// _appModel.isOn ? AppColors.yellowColor : AppColors.grayColor,
body: _pageList[_selectedIndex],
bottomNavigationBar: CurvedNavigationBar(
key: _bottomNavigationKey,
index: 0,
height: 70.0,
items: <Widget>[
// Container(
// width: 50,
// height: 50,
// // width: double.infinity,
// // height: 100,
// decoration: BoxDecoration(
// // color: Colors.white,
// gradient: LinearGradient(
// begin: Alignment.topCenter,
// end: Alignment.bottomCenter,
// colors: [Color(0xffB8ACFF), Color(0xff9182F9)],
// ),
// borderRadius: BorderRadius.circular(8.0),
// boxShadow: [
// BoxShadow(
// color: Colors.red,
// offset: Offset(0.0, 15.0), //阴影xy轴偏移量
// blurRadius: 15.0, //阴影模糊程度
// spreadRadius: 1.0 //阴影扩散程度
// )
// ]),
// child: Icon(Icons.add, size: 30),
// ),
Icon(Icons.add, size: 30),
Icon(Icons.list, size: 30),
Icon(Icons.compare_arrows, size: 30),
// Icon(Icons.call_split, size: 30),
// Icon(Icons.perm_identity, size: 30),
],
color: Colors.white,
// rgba(238, 242, 248, 1.00)
buttonBackgroundColor: Color.fromRGBO(238, 242, 248, 1.00),
backgroundColor: Color(0xff9182F9),
animationCurve: Curves.easeInOut,
animationDuration: Duration(milliseconds: 600),
onTap: (index) {
setState(() {
_selectedIndex = index;
});
},
letIndexChange: (index) => true,
),
floatingActionButton: FloatingActionButton(
// elevation: 6.0,
// highlightElevation: 12.0,
child: Icon(Icons.add),
onPressed: () {
print('不要啊~'); //await _userModel.setIntegralInfo();
Navigator.of(context).pushNamed('/chat');
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
));
}
void _onItemTapped(dynamic actMenu) {
setState(() {
_selectedIndex = actMenu;
});
}
void _addMessage(types.Message message) {
setState(() {
_messages.insert(0, message);
});
}
void _cancelLoading() {
var data;
// _messages.forEach((element) {
// print(element.props);
// });
data = _messages.firstWhere((element) => element.status == Status.sending);
// _messages.where((mess)=>"${mess.}" === "loading");
setState(() {
_messages.remove(data);
});
}
void _handleFileSelection() async {
// final result = await FilePicker.platform.pickFiles(
// type: FileType.any,
// );
// if (result != null && result.files.single.path != null) {
// final message = types.FileMessage(
// author: _user,
// createdAt: DateTime.now().millisecondsSinceEpoch,
// id: const Uuid().v4(),
// mimeType: lookupMimeType(result.files.single.path!),
// name: result.files.single.name,
// size: result.files.single.size,
// uri: result.files.single.path!,
// );
// _addMessage(message);
// }
}
void _handleImageSelection() async {
// final result = await ImagePicker().pickImage(
// imageQuality: 70,
// maxWidth: 1440,
// source: ImageSource.gallery,
// );
// if (result != null) {
// final bytes = await result.readAsBytes();
// final image = await decodeImageFromList(bytes);
// final message = types.ImageMessage(
// author: _user,
// createdAt: DateTime.now().millisecondsSinceEpoch,
// height: image.height.toDouble(),
// id: const Uuid().v4(),
// name: result.name,
// size: bytes.length,
// uri: result.path,
// width: image.width.toDouble(),
// );
// _addMessage(message);
// }
}
void _handleMessageTap(BuildContext _, types.Message message) async {
// if (message is types.FileMessage) {
// var localPath = message.uri;
// if (message.uri.startsWith('http')) {
// try {
// final index =
// _messages.indexWhere((element) => element.id == message.id);
// final updatedMessage =
// (_messages[index] as types.FileMessage).copyWith(
// isLoading: true,
// );
// setState(() {
// _messages[index] = updatedMessage;
// });
// final client = http.Client();
// final request = await client.get(Uri.parse(message.uri));
// final bytes = request.bodyBytes;
// final documentsDir = (await getApplicationDocumentsDirectory()).path;
// localPath = '$documentsDir/${message.name}';
// if (!File(localPath).existsSync()) {
// final file = File(localPath);
// await file.writeAsBytes(bytes);
// }
// } finally {
// final index =
// _messages.indexWhere((element) => element.id == message.id);
// final updatedMessage =
// (_messages[index] as types.FileMessage).copyWith(
// isLoading: null,
// );
// setState(() {
// _messages[index] = updatedMessage;
// });
// }
// }
// await OpenFilex.open(localPath);
// }
}
void _handlePreviewDataFetched(
types.TextMessage message,
types.PreviewData previewData,
) {
final index = _messages.indexWhere((element) => element.id == message.id);
final updatedMessage = (_messages[index] as types.TextMessage).copyWith(
previewData: previewData,
);
setState(() {
_messages[index] = updatedMessage;
});
}
// void _handleSendPressed(types.PartialText message) async {
// var data = false;
// // _messages.forEach((element) {
// // print(element.props);
// // });
// if (_messages.isNotEmpty) {
// data = !_messages.every((element) => element.status != Status.sending);
// }
// print("data-----------${data}");
// if (data) {
// Fluttertoast.showToast(
// msg: "操作太快了 你上个问题还没问完呢",
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// timeInSecForIosWeb: 1,
// backgroundColor: Colors.red,
// textColor: Colors.white,
// fontSize: 16.0);
// return;
// }
// final textMessage = types.TextMessage(
// author: _user,
// createdAt: DateTime.now().millisecondsSinceEpoch,
// id: const Uuid().v4(),
// text: message.text,
// );
// final loadingMessage = types.TextMessage(
// author: receiveUser,
// createdAt: DateTime.now().millisecondsSinceEpoch,
// id: const Uuid().v4(),
// text: "loading",
// status: Status.sending,
// // "sending",
// );
// _addMessage(textMessage);
// _addMessage(loadingMessage);
// String? result = await MessageService().getMessage(message.text);
// _cancelLoading();
// final receiveMessage = types.TextMessage(
// author: receiveUser,
// createdAt: DateTime.now().millisecondsSinceEpoch,
// id: const Uuid().v4(),
// text: "$result",
// );
// _addMessage(receiveMessage);
// }
void _viewMessage(String value) {
final textMessage1 = types.TextMessage(
author: _user1,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: value,
);
_addMessage(textMessage1);
// // print(value);
// print(value); //msg value: Hello, World!
}
void _loadMessages() {
// final response = `""`
// final messages = (jsonDecode(response) as List)
// .map((e) => types.Message.fromJson(e as Map<String, dynamic>))
// .toList();
// setState(() {
// _messages = messages;
// });
}
}
Widget _bubbleBuilder(
Widget child, {
required message,
required nextMessageInGroup,
}) =>
Bubble(
child: AnimatedTextKit(
totalRepeatCount: 1,
animatedTexts: identical(message.status, Status.sending)
? [
WavyAnimatedText('正在思考中...'),
WavyAnimatedText('正在使劲思考中......'),
WavyAnimatedText('正在拼命思考中......'),
WavyAnimatedText('您的问题太有深度,回答很困难,如果不想等待,请问下一个问题......'),
]
: [TypewriterAnimatedText(message.text)],
onTap: () {
print("Tap Event");
},
),
color: _user.id != message.author.id ||
message.type == types.MessageType.image
? const Color(0xfff5f5f7)
: const Color(0xff6f61e8),
margin: nextMessageInGroup
? const BubbleEdges.symmetric(horizontal: 6)
: null,
nip: nextMessageInGroup
? BubbleNip.no
: _user.id != message.author.id
? BubbleNip.leftBottom
: BubbleNip.rightBottom,
);
// return Scaffold(
// bottomNavigationBar:
// body: Container(
// color: Colors.blueAccent,
// child: Center(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// Text(_page.toString(), textScaleFactor: 10.0),
// ElevatedButton(
// child: Text('Go To Page of index 1'),
// onPressed: () {
// final CurvedNavigationBarState? navBarState =
// _bottomNavigationKey.currentState;
// navBarState?.setPage(1);
// },
// )
// ],
// ),
// ),
// )
// );
\ No newline at end of file
// import 'package:flutter/cupertino.dart';
// import 'package:chart/constant/app_dimens.dart';
// import 'package:chart/pages/guide/guide_page.dart';
// import 'package:chart/models/user_model.dart';
// import 'package:flutter_screenutil/flutter_screenutil.dart';
// import 'package:provider/provider.dart';
// import 'home_page.dart';
// class MainPage extends StatefulWidget {
// const MainPage({Key? key}) : super(key: key);
// @override
// MainPageState createState() => MainPageState();
// }
// class MainPageState extends State<MainPage> {
// @override
// Widget build(BuildContext context) {
// UserModel userViewModel = Provider.of<UserModel>(context);
// ScreenUtil.init(context,
// designSize: const Size(AppDimens.maxWidth, AppDimens.maxHeight));
// return userViewModel.isFirstOpen
// ? const GuidePage()
// : const HomePage(
// title: "hello world",
// );
// }
// }
import 'dart:async';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/link.dart';
import 'package:url_launcher/url_launcher.dart';
// import 'package:flutter_screenutil/flutter_screenutil.dart';
// import 'package:provider/provider.dart';
// import 'package:sail/constant/app_colors.dart';
// import 'package:sail/constant/app_dimens.dart';
// import 'package:sail/models/app_model.dart';
// import 'package:sail/models/plan_model.dart';
// import 'package:sail/models/server_model.dart';
// import 'package:sail/models/user_model.dart';
// import 'package:sail/models/user_subscribe_model.dart';
// import 'package:sail/pages/my_profile.dart';
// import 'package:sail/pages/plan/plan_page.dart';
// import 'package:sail/pages/server_list.dart';
// import 'package:sail/widgets/home_widget.dart';
// import 'package:sail/widgets/power_btn.dart';
// import 'package:sail/widgets/sail_app_bar.dart';
//声明参数用于回调使用
// late final StreamSubscription<AlipayResp> _alipaySubs; //用于支付
// late final StreamSubscription<AlipayResp>
// _alipayAuthSubs; //用于授权登陆// import 'package:sail/utils/common_util.dart';
class LoginBackPage extends StatefulWidget {
const LoginBackPage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<LoginBackPage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<LoginBackPage> {
bool _hasCallSupport = false;
Future<void>? _launched;
String _phone = '';
@override
void initState() {
super.initState();
// Check for phone call support.
canLaunchUrl(Uri(scheme: 'tel', path: '123')).then((bool result) {
setState(() {
_hasCallSupport = result;
});
});
}
Future<void> _launchInBrowser(Uri url) async {
if (!await launchUrl(
url,
mode: LaunchMode.externalApplication,
)) {
throw Exception('Could not launch $url');
}
}
Future<void> _launchInWebViewOrVC(Uri url) async {
if (!await launchUrl(
url,
mode: LaunchMode.inAppWebView,
webViewConfiguration: const WebViewConfiguration(
headers: <String, String>{'my_header_key': 'my_header_value'}),
)) {
throw Exception('Could not launch $url');
}
}
Future<void> _launchInWebViewWithoutJavaScript(Uri url) async {
if (!await launchUrl(
url,
mode: LaunchMode.inAppWebView,
webViewConfiguration: const WebViewConfiguration(enableJavaScript: false),
)) {
throw Exception('Could not launch $url');
}
}
Future<void> _launchInWebViewWithoutDomStorage(Uri url) async {
if (!await launchUrl(
url,
mode: LaunchMode.inAppWebView,
webViewConfiguration: const WebViewConfiguration(enableDomStorage: false),
)) {
throw Exception('Could not launch $url');
}
}
Future<void> _launchUniversalLinkIos(Uri url) async {
final bool nativeAppLaunchSucceeded = await launchUrl(
url,
mode: LaunchMode.externalNonBrowserApplication,
);
if (!nativeAppLaunchSucceeded) {
await launchUrl(
url,
mode: LaunchMode.inAppWebView,
);
}
}
Widget _launchStatus(BuildContext context, AsyncSnapshot<void> snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return const Text('');
}
}
Future<void> _makePhoneCall(String phoneNumber) async {
final Uri launchUri = Uri(
scheme: 'tel',
path: phoneNumber,
);
await launchUrl(launchUri);
}
@override
Widget build(BuildContext context) {
// onPressed calls using this URL are not gated on a 'canLaunch' check
// because the assumption is that every device can launch a web URL.
final Uri toLaunch =
Uri(scheme: 'https', host: 'www.cylog.org', path: 'headers/');
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
onChanged: (String text) => _phone = text,
decoration: const InputDecoration(
hintText: 'Input the phone number to launch')),
),
ElevatedButton(
onPressed: _hasCallSupport
? () => setState(() {
_launched = _makePhoneCall(_phone);
})
: null,
child: _hasCallSupport
? const Text('Make phone call')
: const Text('Calling not supported'),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(toLaunch.toString()),
),
ElevatedButton(
onPressed: () => setState(() {
_launched = _launchInBrowser(toLaunch);
}),
child: const Text('Launch in browser'),
),
const Padding(padding: EdgeInsets.all(16.0)),
ElevatedButton(
onPressed: () => setState(() {
_launched = _launchInWebViewOrVC(toLaunch);
}),
child: const Text('Launch in app'),
),
ElevatedButton(
onPressed: () => setState(() {
_launched = _launchInWebViewWithoutJavaScript(toLaunch);
}),
child: const Text('Launch in app (JavaScript OFF)'),
),
ElevatedButton(
onPressed: () => setState(() {
_launched = _launchInWebViewWithoutDomStorage(toLaunch);
}),
child: const Text('Launch in app (DOM storage OFF)'),
),
const Padding(padding: EdgeInsets.all(16.0)),
ElevatedButton(
onPressed: () => setState(() {
_launched = _launchUniversalLinkIos(toLaunch);
}),
child: const Text(
'Launch a universal link in a native app, fallback to Safari.(Youtube)'),
),
const Padding(padding: EdgeInsets.all(16.0)),
ElevatedButton(
onPressed: () => setState(() {
_launched = _launchInWebViewOrVC(toLaunch);
Timer(const Duration(seconds: 5), () {
closeInAppWebView();
});
}),
child: const Text('Launch in app + close after 5 seconds'),
),
const Padding(padding: EdgeInsets.all(16.0)),
Link(
uri: Uri.parse(
'https://pub.dev/documentation/url_launcher/latest/link/link-library.html'),
target: LinkTarget.blank,
builder: (BuildContext ctx, FollowLink? openLink) {
return TextButton.icon(
onPressed: openLink,
label: const Text('Link Widget documentation'),
icon: const Icon(Icons.read_more),
);
},
),
const Padding(padding: EdgeInsets.all(16.0)),
FutureBuilder<void>(future: _launched, builder: _launchStatus),
],
),
],
),
);
}
// int _counter = 0;
// String _wx = "alipayqr://platformapi/startapp?saId=10000007";
// String url =
// "https://openapi.alipay.com/gateway.do?charset=UTF-8&biz_content=%7B%22out_trade_no%22%3A%22062d1030001%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%2250%E7%A7%AF%E5%88%86%22%2C%22timeout_express%22%3A%225m%22%2C%22goods_type%22%3A%220%22%2C%22product_code%22%3A%22QUICK_WAP_WAY%22%2C%22body%22%3A%2250%E7%A7%AF%E5%88%86%22%7D&method=alipay.trade.wap.pay&format=JSON&sign=Xz25Ds%2FB4D53oXHQv0LiFkOFBOrvzVUVkuznhRJuk8Tc%2FOgw97PDq99XdoDTmhUac5EO3apjIjMUcStSXHzkUiC%2Br3IBv60dckvoYJrfmS3PyzwtRg0S4QVRX00Kw2nfDlrqwjaMlpJM97hrBmDIqDYUCE593ps5Yd%2FannImTkuko2OvJIXYO5J9C6EJ3y61uxxNZxZoM1EGFeIXjJ1DQlFVpl8%2FIYH9xt6oMtXWaSYYQWJJyi%2BV7ikvVlJ7xvkHCGZaUfGYbfyL0B%2BSFd7SBnrME01trcc4NY5epLAuMp5ZsDZMIGcKNSLXcOO%2Boxj8G2NhJh6Qhs0Wf8yqON8wnQ%3D%3D&notify_url=http%3A%2F%2Feh5uvd.natappfree.cc%2Fpay%2Fnotify&app_id=2021003176617083&version=1.0&sign_type=RSA2&timestamp=2023-02-13+10%3A13%3A40";
// void _incrementCounter() async {
// // ignore: deprecated_member_use
// if (await canLaunch(_wx)) {
// // ignore: deprecated_member_use
// await launch(_wx);
// } else {
// throw 'Could not launch $_wx';
// }
// // final isInstall = await Alipay.instance.isInstalled();
// // if (!isInstall) {
// // print("未安装支付宝app");
// // return;
// // } else {
// // Alipay.instance.pay(
// // orderInfo:
// // "https://mclient.alipay.com/h5pay/h5RouteAppSenior/index.html?server_param=emlkPTI5O25kcHQ9ZTBmZjtjYz15&contextId=RZ42CwfLyKesfHEekRRGmum1lDLW7Cmobileclientgw29RZ42&pageToken=&refreshNoAuth=Y");
// // registerAlipayResp();
// // }
// // setState(() {
// // // This call to setState tells the Flutter framework that something has
// // // changed in this State, which causes it to rerun the build method below
// // // so that the display can reflect the updated values. If we changed
// // // _counter without calling setState(), then the build method would not be
// // // called again, and so nothing would appear to happen.
// // _counter++;
// // });
// }
// // @override
// // void initState() async {
// // // TODO: implement initState
// // super.initState();
// // // final isInstall = await Alipay.instance.isInstalled();
// // // if (!isInstall) {
// // // print("未安装支付宝app");
// // // return;
// // // }
// // }
// @override
// Widget build(BuildContext context) {
// // This method is rerun every time setState is called, for instance as done
// // by the _incrementCounter method above.
// //
// // The Flutter framework has been optimized to make rerunning build methods
// // fast, so that you can just rebuild anything that needs updating rather
// // than having to individually change instances of widgets.
// return Scaffold(
// appBar: AppBar(
// // Here we take the value from the MyHomePage object that was created by
// // the App.build method, and use it to set our appbar title.
// title: Text(widget.title),
// ),
// body: Center(
// // Center is a layout widget. It takes a single child and positions it
// // in the middle of the parent.
// child: Column(
// // Column is also a layout widget. It takes a list of children and
// // arranges them vertically. By default, it sizes itself to fit its
// // children horizontally, and tries to be as tall as its parent.
// //
// // Invoke "debug painting" (press "p" in the console, choose the
// // "Toggle Debug Paint" action from the Flutter Inspector in Android
// // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// // to see the wireframe for each widget.
// //
// // Column has various properties to control how it sizes itself and
// // how it positions its children. Here we use mainAxisAlignment to
// // center the children vertically; the main axis here is the vertical
// // axis because Columns are vertical (the cross axis would be
// // horizontal).
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// const Text(
// 'You have pushed the button this many times:',
// ),
// Text(
// '$_counter',
// style: Theme.of(context).textTheme.headline4,
// ),
// ],
// ),
// ),
// floatingActionButton: FloatingActionButton(
// onPressed: _incrementCounter,
// tooltip: 'Increment',
// child: const Icon(Icons.add),
// ), // This trailing comma makes auto-formatting nicer for build methods.
// );
// }
}
//注册支付宝支付和授权结果回调
// void registerAlipayResp() {
// _alipaySubs = Alipay.instance.payResp().listen(listenAlipayPay);
// _alipayAuthSubs = Alipay.instance.authResp().listen(_listenAlipayAuth);
// }
// //支付成功或者失败回调
// void listenAlipayPay(AlipayResp resp) {
// final String content = 'pay: ${resp.resultStatus} - ${resp.result}';
// print(content);
// }
// //收取那登陆成功或者失败回调
// void _listenAlipayAuth(AlipayResp resp) {
// final String content = 'auth: ${resp.resultStatus} - ${resp.result}';
// print(content);
// }
import 'dart:async';
import 'package:chart/entity/user_entity.dart';
import 'package:chart/pages/dashboard/dashboard_page.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:glassmorphism/glassmorphism.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/link.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:pinput/pinput.dart';
import "package:chart/service/user_service.dart";
import 'package:gradient_widgets/gradient_widgets.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
@override
State<LoginPage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<LoginPage> {
TextEditingController controller = TextEditingController();
// final pinController = TextEditingController();
// final focusNode = FocusNode();
final formKey = GlobalKey<FormState>();
@override
void dispose() {
// pinController.dispose();
// focusNode.dispose();
super.dispose();
}
// bool _hasCallSupport = false;
// Future<void>? _launched;
// String _phone = '';
@override
void initState() {
super.initState();
// Check for phone call support.
// canLaunchUrl(Uri(scheme: 'tel', path: '123')).then((bool result) {
// setState(() {
// _hasCallSupport = result;
// });
// });
}
_getCode() async {
if (controller.text.length < 11) {
return EasyLoading.showError("手机号码输入有误!");
}
EasyLoading.show(status: "发送验证码...");
var phone = controller.text
.replaceAll("+", "")
.replaceAll(new RegExp(r"\s+\b|\b\s"), "");
try {
MsmEntity? res = await UserService().sendSms({"phone": phone});
print("$res");
if (res?.status == 200) {
EasyLoading.showSuccess('验证码发送正确');
Navigator.of(context)
.pushNamed('/ms-code', arguments: {"phone": phone});
// Navigator.of(context).pushNamed("/chat",
// arguments: {"phone": message.question})
} else {
EasyLoading.showError("${res?.message}");
}
EasyLoading.dismiss();
} catch (e) {
EasyLoading.showError("发送验证码频率过快");
EasyLoading.dismiss();
}
}
@override
Widget build(BuildContext context) {
// onPressed calls using this URL are not gated on a 'canLaunch' check
// because the assumption is that every device can launch a web URL.
final Uri toLaunch =
Uri(scheme: 'https', host: 'www.cylog.org', path: 'headers/');
const focusedBorderColor = Color.fromRGBO(23, 171, 144, 1);
const fillColor = Color.fromRGBO(243, 246, 249, 0);
const borderColor = Color.fromRGBO(23, 171, 144, 0.4);
final defaultPinTheme = PinTheme(
width: 56,
height: 56,
textStyle: const TextStyle(
fontSize: 22,
color: Color.fromRGBO(30, 60, 87, 1),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(19),
border: Border.all(color: borderColor),
),
);
return Scaffold(
// appBar: AppBar(),
body: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
// decoration: const BoxDecoration(
// gradient: LinearGradient(
// colors: <Color>[
// CustomTheme.loginGradientStart,
// CustomTheme.loginGradientEnd
// ],
// begin: FractionalOffset(0.0, 0.0),
// end: FractionalOffset(1.0, 1.0),
// stops: <double>[0.0, 1.0],
// tileMode: TileMode.clamp),
// ),
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
padding: EdgeInsets.symmetric(horizontal: 40),
// color: Colors.red,
// width: double.infinity,
// height: double.infinity,
child:
// Container(
// width: double.infinity,
// color: Colors.red,
// height: 300,
// child: Text(""),
// ),
Column(
children: [
Container(
padding:
EdgeInsets.symmetric(horizontal: 16, vertical: 80),
// height: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"AI写作大师",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 30,
),
)
]),
),
Center(
child: GlassmorphicContainer(
width: MediaQuery.of(context).size.width * .9,
height: 280.0,
borderRadius: 16,
padding: EdgeInsets.only(bottom: 16),
blur: 14,
alignment: Alignment.bottomCenter,
border: 2,
child: Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
autofocus: true,
controller: controller,
keyboardType: TextInputType.phone,
style: const TextStyle(
color: Colors.white, fontSize: 16),
decoration: InputDecoration(
labelStyle: TextStyle(
color: Colors.white.withOpacity(1)),
hintStyle: TextStyle(
color: Colors.grey,
textBaseline: TextBaseline.ideographic,
),
labelText: '电话号码',
border: OutlineInputBorder(
borderSide: const BorderSide(),
),
enabledBorder: OutlineInputBorder(
///设置边框四个角的弧度
borderRadius:
BorderRadius.all(Radius.circular(20)),
///用来配置边框的样式
borderSide: BorderSide(
///设置边框的颜色
color: Colors.white.withOpacity(.2),
///设置边框的粗细
width: 2.0,
),
),
focusedBorder: OutlineInputBorder(
///设置边框四个角的弧度
borderRadius:
BorderRadius.all(Radius.circular(20)),
///用来配置边框的样式
borderSide: BorderSide(
///设置边框的颜色
color: Colors.white.withOpacity(1),
///设置边框的粗细
width: 2.0,
),
),
),
textInputAction: TextInputAction.done,
inputFormatters: <TextInputFormatter>[
LengthLimitingTextInputFormatter(13)
],
// decoration: InputDecoration(
// filled: true,
// enabledBorder: OutlineInputBorder(
// borderSide: BorderSide(color: Color(0x00FF0000)),
// borderRadius: BorderRadius.all(
// Radius.circular(100),
// ),
// ),
// focusedBorder: OutlineInputBorder(
// borderSide: BorderSide(color: Color(0x00000000)),
// borderRadius: BorderRadius.all(
// Radius.circular(100),
// ),
// ),
// contentPadding: EdgeInsets.all(10),
// prefixIcon: Icon(Icons.lock),
// // fillColor: Colors.blue,
// hintText: "请输入密码",
// ),
// ),
onChanged: (v) => _splitPhoneNumber(v),
),
SizedBox(
height: 20,
),
Container(
width: double.infinity,
margin: EdgeInsets.only(top: 30),
// col
// child: GradientButton(
// child: Text('Gradient'),
// callback: () {},
// gradient: Gradients.ali,
// shadowColor: Gradients.backToFuture.colors.last
// .withOpacity(0.25),
// ),
child: MaterialButton(
shape: RoundedRectangleBorder(
// 圆角矩形
borderRadius: BorderRadius.all(
Radius.circular(10)),
),
padding:
EdgeInsets.symmetric(vertical: 12),
child: Text('确定'),
color: Theme.of(context).primaryColor,
textColor: Colors.white,
onPressed: _getCode),
)
],
),
),
linearGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(0.2),
Color(0xFF0FFFF).withOpacity(0.2),
],
),
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(1),
Color(0xFFFFFFF),
Color(0xFF0FFFF).withOpacity(1),
],
),
),
),
],
)),
)));
}
int inputLength = 0;
void _splitPhoneNumber(String text) {
if (text.length > inputLength) {
//输入
if (text.length == 4 || text.length == 9) {
text = text.substring(0, text.length - 1) +
" " +
text.substring(text.length - 1, text.length);
controller.text = text;
controller.selection = TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream, offset: text.length));
}
} else {
//删除
if (text.length == 4 || text.length == 9) {
text = text.substring(0, text.length - 1);
controller.text = text;
controller.selection = TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream, offset: text.length));
}
}
inputLength = text.length;
}
}
class CustomTheme {
const CustomTheme();
static const Color loginGradientStart = Color(0xFFfbab66);
static const Color loginGradientEnd = Color(0xFFf7418c);
static const Color white = Color(0xFFFFFFFF);
static const Color black = Color(0xFF000000);
static const LinearGradient primaryGradient = LinearGradient(
colors: <Color>[loginGradientStart, loginGradientEnd],
stops: <double>[0.0, 1.0],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
);
}
import 'dart:async';
import 'package:chart/entity/login_entity.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:glassmorphism/glassmorphism.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/link.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:pinput/pinput.dart';
import "package:chart/service/user_service.dart";
import '../../models/user_model.dart';
// import 'package:flutter_screenutil/flutter_screenutil.dart';
// import 'package:provider/provider.dart';
// import 'package:sail/constant/app_colors.dart';
// import 'package:sail/constant/app_dimens.dart';
// import 'package:sail/models/app_model.dart';
// import 'package:sail/models/plan_model.dart';
// import 'package:sail/models/server_model.dart';
// import 'package:sail/models/user_model.dart';
// import 'package:sail/models/user_subscribe_model.dart';
// import 'package:sail/pages/my_profile.dart';
// import 'package:sail/pages/plan/plan_page.dart';
// import 'package:sail/pages/server_list.dart';
// import 'package:sail/widgets/home_widget.dart';
// import 'package:sail/widgets/power_btn.dart';
// import 'package:sail/widgets/sail_app_bar.dart';
//声明参数用于回调使用
// late final StreamSubscription<AlipayResp> _alipaySubs; //用于支付
// late final StreamSubscription<AlipayResp>
// _alipayAuthSubs; //用于授权登陆// import 'package:sail/utils/common_util.dart';
class MsmPage extends StatefulWidget {
const MsmPage({super.key});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
@override
State<MsmPage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MsmPage> {
TextEditingController controller = TextEditingController();
final pinController = TextEditingController();
final focusNode = FocusNode();
final formKey = GlobalKey<FormState>();
// final pinputFocusNode = FocusNode();
late UserModel _userModel;
/// Focus pinput
// pinputFocusNode.requestFocus();
//
/// UnFocus pinput
// pinputFocusNode.unfocus();
/// Don't call requestFocus, unfocus in build method, this is just illustration.
///
///
///
///
@override
void dispose() {
pinController.dispose();
focusNode.dispose();
super.dispose();
}
// bool _hasCallSupport = false;
// Future<void>? _launched;
// String _phone = '';
// @override
// void didUpdateWidget(covariant MsmPage oldWidget) {
// // TODO: implement didUpdateWidget
// focusNode.requestFocus();
// super.didUpdateWidget(oldWidget);
// // focusNode: pinputFocusNode,
// }
@override
void initState() {
super.initState();
focusNode.requestFocus();
// setToken
// Check for phone call support.
// canLaunchUrl(Uri(scheme: 'tel', path: '123')).then((bool result) {
// setState(() {
// _hasCallSupport = result;
// });
// });
}
_doLogin(String pin) async {
EasyLoading.show(status: '登录中...');
Map<String, dynamic> routeParams =
ModalRoute.of(context)!.settings?.arguments as Map<String, dynamic>;
try {
LoginEntity? res = await UserService().register({
"smsCode": pin,
"username": routeParams['phone'],
"id": _userModel.integralEntity?.id
});
if (res?.token != null) {
_userModel.setToken(res!);
EasyLoading.showSuccess("登录成功!");
Navigator.of(context).pushNamed('/');
} else {
EasyLoading.showError("登录失败");
}
EasyLoading.dismiss();
} catch (e) {
EasyLoading.showError("登录失败");
EasyLoading.dismiss();
}
}
final defaultPinTheme = PinTheme(
width: 60,
height: 64,
textStyle: TextStyle(
fontSize: 20,
color: const Color.fromRGBO(255, 255, 255, 1),
),
decoration: BoxDecoration(
color: const Color.fromRGBO(255, 255, 255, .5),
borderRadius: BorderRadius.circular(8),
boxShadow: const [
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.05999999865889549),
offset: Offset(0, 3),
blurRadius: 16,
)
],
),
);
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
_userModel = Provider.of<UserModel>(context);
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
// onPressed calls using this URL are not gated on a 'canLaunch' check
// because the assumption is that every device can launch a web URL.
final Uri toLaunch =
Uri(scheme: 'https', host: 'www.cylog.org', path: 'headers/');
return Scaffold(
appBar: AppBar(
title: Text('验证码'),
backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
// p
padding: EdgeInsets.symmetric(horizontal: 16),
// color: Colors.red,
width: double.infinity,
height: double.infinity,
child: Center(
child: GlassmorphicContainer(
// flex: 1,
width: double.infinity,
height: 200,
borderRadius: 16,
padding: EdgeInsets.only(bottom: 16),
blur: 14,
alignment: Alignment.bottomCenter,
border: 2,
linearGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(0.2),
Color(0xFF0FFFF).withOpacity(0.2),
],
),
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(1),
Color(0xFFFFFFF),
Color(0xFF0FFFF).withOpacity(1),
]),
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Directionality(
// Specify direction if desired
textDirection: TextDirection.ltr,
child: Pinput(
length: 6,
controller: pinController,
focusNode: focusNode,
androidSmsAutofillMethod:
AndroidSmsAutofillMethod.smsUserConsentApi,
listenForMultipleSmsOnAndroid: true,
defaultPinTheme: defaultPinTheme,
validator: (value) {
// register
// return value == '2222' ? null : 'Pin is incorrect';
},
// onClipboardFound: (value) {
// debugPrint('onClipboardFound: $value');
// pinController.setText(value);
// },
hapticFeedbackType:
HapticFeedbackType.lightImpact,
onCompleted: (pin) {
_doLogin(pin);
},
onChanged: (value) {
debugPrint('onChanged: $value');
},
cursor: Align(
alignment: Alignment.bottomCenter,
child: Container(
width: 21,
height: 1,
margin: const EdgeInsets.only(bottom: 12),
decoration: BoxDecoration(
color:
const Color.fromRGBO(137, 146, 160, 1),
borderRadius: BorderRadius.circular(8),
),
),
),
focusedPinTheme: defaultPinTheme.copyWith(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: const [
BoxShadow(
color: Color.fromRGBO(
0, 0, 0, 0.05999999865889549),
offset: Offset(0, 3),
blurRadius: 16,
)
],
),
),
// focusedPinTheme: defaultPinTheme.copyWith(
// decoration:
// defaultPinTheme.decoration!.copyWith(
// borderRadius: BorderRadius.circular(8),
// border: Border.all(color: focusedBorderColor),
// ),
// ),
// submittedPinTheme: defaultPinTheme.copyWith(
// decoration:
// defaultPinTheme.decoration!.copyWith(
// color: fillColor,
// borderRadius: BorderRadius.circular(19),
// border: Border.all(color: focusedBorderColor),
// ),
// ),
// errorPinTheme: defaultPinTheme.copyBorderWith(
// border: Border.all(color: Colors.redAccent),
// ),
),
),
// TextButton(
// onPressed: () {
// focusNode.unfocus();
// formKey.currentState!.validate();
// },
// child: const Text('Validate'),
// ),
],
),
),
)),
)));
}
}
import 'package:chart/constant/app_colors.dart';
// import 'package:chart/pages/dashboard/components/list.dart';
import 'package:flutter/material.dart';
// import 'package:chart/constant/app_colors.dart';
import 'package:chart/constant/app_dimens.dart';
import 'package:chart/constant/app_images.dart';
// import 'package:chart/constant/app_strings.dart';
import 'package:chart/models/user_model.dart';
import 'package:babstrap_settings_screen/babstrap_settings_screen.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:chart/service/square_service.dart';
import 'package:glassmorphism/glassmorphism.dart';
import '../../entity/square_entity.dart';
// import 'package:chart/utils/navigator_util.dart';
// import 'package:flutter_screenutil/flutter_screenutil.dart';
class SquarePage extends StatefulWidget {
const SquarePage({Key? key}) : super(key: key);
@override
SquarePageState createState() => SquarePageState();
}
class SquarePageState extends State<SquarePage> {
var guides = [AppImages.guide1, AppImages.guide2, AppImages.guide3];
var _showButton = false;
List<String> items = [];
int _current = 1;
int _total = 0;
int _size = 10;
bool _isDown = false;
List<SearchRecordEntity> _records = [];
RefreshController _refreshController =
RefreshController(initialRefresh: false);
void _onRefresh() async {
setState(() {
_current = 1;
});
await _getRecord(_current, _size);
// monitor network fetch
// await Future.delayed(Duration(milliseconds: 1000));
// if failed,use refreshFailed()
_refreshController.refreshCompleted();
}
_onLoading() async {
// if (_isDown) {
// print('131321');
// setState(() {
// _records = _records;
// });
// if (mounted) _refreshController.loadComplete();
// return;
// }
List<SearchRecordEntity>? records =
await SquareService().getSearchRecord(_current, _size);
// print("_curr $_current");
// setState(() {
// _current = _current + 1;
// });
// _getRecord(_current, _size);
// setState({
// _current = 2;
// });
// _getRecord(_current, _size);
// monitor network fetch
// await _getRecord(_current, _size);
// await Future.delayed(Duration(milliseconds: 1000));
// if failed,use loadFailed(),if no data return,use LoadNodata()
// _records.add();
records?.forEach((element) {
_records.add(element);
});
if (records!.length!! < 10) {
setState(() {
_isDown = true;
});
Fluttertoast.showToast(
msg: "已全部加载完毕",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: AppColors.color8,
textColor: Colors.white,
fontSize: 16.0);
}
if (mounted) {
setState(() {
_current = _current + 1;
});
}
_refreshController.loadComplete();
}
@override
void initState() {
// TODO: implement initState
super.initState();
_getRecord(_current, _size);
// MessageService().getMessage
// getSearchRecord
}
_getRecord(int page, int size) async {
List<SearchRecordEntity>? records =
await SquareService().getSearchRecord(page, size);
setState(() {
_records = records!;
_current = _current + 1;
});
// print("records11111$records");
// List<SearchRecordEntity>? li = (await SquareService()
// .getSearchRecord(1, 10)) as List<SearchRecordEntity>?;
// print('__________$li');
// int _current = 1;
// int _total = 0;
// int _size = 10;
// List<SearchRecordEntity> records = [];
// SearchRecordEntity.fromMap(result['data']
// print("--------------------------------li${li}");
// setState(() {
// // _current = li!.current;
// // _records = li.records;
// // _total = li.total;
// // _size = li.size;
// });
// print("lllllllll----$li");
// List<SearchRecordEntity> li = (await )
// as List<SearchRecordEntity>;
}
@override
Widget build(BuildContext context) {
UserModel().setIsFirstOpen(false);
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
// padding: EdgeInsets.only(top: 10),
child: SmartRefresher(
enablePullDown: true,
enablePullUp: _isDown ? false : true,
header: WaterDropHeader(),
controller: _refreshController,
onRefresh: _isDown ? null : _onRefresh,
onLoading: _onLoading,
child: ListView.builder(
// itemBuilder: (c, i) => Card(child: Center(child: Text(items[i]))),
itemBuilder: (c, i) => Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Container(
// color: Colors.black,
margin: EdgeInsets.only(top: 10),
padding: const EdgeInsets.symmetric(horizontal: 16),
// padding: EdgeInsets.all(16),
// flex: 1,
child: Column(children: [
SizedBox(height: 0),
glassCard(context, i, _records)
]),
)
// BigUserCard(
// // cardColor: Colors.red,
// userName: "Babacar Ndon222g",
// userProfilePic: AssetImage("assets/images/logo.png"),
// cardActionWidget: SettingsItem(
// icons: Icons.edit,
// iconStyle: IconStyle(
// withBackground: true,
// borderRadius: 50,
// backgroundColor: Colors.yellow[600],
// ),
// title: "${_records[i].question}",
// subtitle: _records[i].createTime,
// onTap: () {
// print("OK");
// },
// ),
// ),
),
itemExtent: 240.0,
itemCount: _records.length,
),
),
);
}
}
Widget glassCard(var context, int i, List<SearchRecordEntity> records) {
double textScaleFactor = MediaQuery.textScaleFactorOf(context);
return GlassmorphicFlexContainer(
// flex: 1,
borderRadius: 16,
padding: EdgeInsets.only(bottom: 16),
blur: 14,
alignment: Alignment.bottomCenter,
border: 2,
linearGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(0.2),
Color(0xFF0FFFF).withOpacity(0.2),
],
),
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(1),
Color(0xFFFFFFF),
Color(0xFF0FFFF).withOpacity(1),
],
),
child: Column(key: UniqueKey(),
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// ignore: prefer_const_literals_to_create_immutables
children: [
// ignore: prefer_const_constructors
Container(
// color: Colors.red,
height: 50,
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text(
"${records[i].question}",
style: const TextStyle(
color: Colors.white,
height: 2,
fontSize: 20,
fontWeight: FontWeight.w600),
)),
// ignore: prefer_const_constructors
Container(
// color: Colors.red,
padding: EdgeInsets.symmetric(horizontal: 16),
width: double.infinity,
height: 150,
child: SingleChildScrollView(
child: Text(
records[i].answer,
style: TextStyle(color: Colors.white, fontSize: 12
// height: 0.8
),
// height: 2,
// fontSize: 20,
maxLines: 7,
),
),
),
]));
}
import 'package:flutter/material.dart';
import 'package:babstrap_settings_screen/babstrap_settings_screen.dart';
import 'package:provider/provider.dart';
import '../../models/user_model.dart';
class UserPage extends StatefulWidget {
@override
UserPageState createState() => UserPageState();
}
class UserPageState extends State<UserPage> {
// final List<BankCardModel> cards = [
// BankCardModel('assets/images/bg_red_card.png', 'Hoang Cuu Long',
// '4221 5168 7464 2283', '08/20', 10000000),
// BankCardModel('assets/images/bg_blue_circle_card.png', 'Hoang Cuu Long',
// '4221 5168 7464 2283', '08/20', 10000000),
// BankCardModel('assets/images/bg_purple_card.png', 'Hoang Cuu Long',
// '4221 5168 7464 2283', '08/20', 10000000),
// BankCardModel('assets/images/bg_blue_card.png', 'Hoang Cuu Long',
// '4221 5168 7464 2283', '08/20', 10000000),
// ];
@override
Widget build(BuildContext context) {
UserModel _userModel = Provider.of<UserModel>(context);
// TODO: implement build
print("${_userModel.isLogin}");
// appBar: AppBar(
// title: Text("AI写作大师"),
// backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
// ),
// // SailAppBar(
// // appTitle: _appTitle,
// // // rgba(41, 45, 62, 1.00)
// // backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
// // textColor: Colors.white
// // //rgba(41, 45, 62, 1.00)
// // ),
// // extendBody: true,
// // backgroundColor: Colors.amber,
// // _appModel.isOn ? AppColors.yellowColor : AppColors.grayColor,
// body: Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image: Image.asset("assets/images/bg.png").image,
// fit: BoxFit.cover),
// ),
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
child: Padding(
padding: const EdgeInsets.all(10),
child: ListView(
children: [
// User card
BigUserCard(
// cardColor: Colors.red,
userName: "Babacar Ndong",
userProfilePic: AssetImage("assets/images/logo.png"),
cardActionWidget: SettingsItem(
icons: Icons.edit,
iconStyle: IconStyle(
withBackground: true,
borderRadius: 50,
backgroundColor: Colors.yellow[600],
),
title: "Modify",
subtitle: "Tap to change your data",
onTap: () {
print("OK");
},
),
),
SettingsGroup(
items: [
SettingsItem(
onTap: () {},
icons: Icons.exit_to_app_rounded,
iconStyle: IconStyle(),
title: 'Appearance',
subtitle: "Make Ziar'App yours",
),
SettingsItem(
onTap: () {},
icons: Icons.dark_mode_rounded,
iconStyle: IconStyle(
iconsColor: Colors.white,
withBackground: true,
backgroundColor: Colors.red,
),
title: 'Dark mode',
subtitle: "Automatic",
trailing: Switch.adaptive(
value: false,
onChanged: (value) {},
),
),
],
),
SettingsGroup(
items: [
SettingsItem(
onTap: () {},
icons: Icons.info_rounded,
iconStyle: IconStyle(
backgroundColor: Colors.purple,
),
title: 'About',
subtitle: "Learn more about Ziar'App",
),
],
),
// You can add a settings title
SettingsGroup(
items: [
SettingsItem(
onTap: () {
Navigator.of(context).pushNamed('/login');
},
icons: Icons.exit_to_app_rounded,
title: "${_userModel.isLogin}",
),
SettingsItem(
onTap: () {},
icons: Icons.exit_to_app_rounded,
title: "Delete account",
titleStyle: TextStyle(
color: Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
),
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:babstrap_settings_screen/babstrap_settings_screen.dart';
import 'package:provider/provider.dart';
import 'package:json_dynamic_form/JsonDynamicForm.dart';
import 'package:json_dynamic_form/models/Autogenerated.dart';
import 'package:json_dynamic_form/models/Values.dart';
import 'package:json_dynamic_form/utils/DynamicFormConstants.dart';
import '../../models/user_model.dart';
class UserPage extends StatefulWidget {
@override
UserPageState createState() => UserPageState();
}
class UserPageState extends State<UserPage> {
List<dynamic> data = [
{
"type": "text",
"label": "Text",
"description": "Enter your name",
"placeholder": "Enter your name",
"regex": "",
"errorText": "",
"required": true,
"name": "text-1622684775448"
},
{
"type": "email",
"label": "Email",
"description": "Enter your email",
"placeholder": "Enter your email",
"regex": "",
"errorText": "Please enter a valid email",
"required": true,
"name": "email-1622684776606"
},
{
"type": "phone",
"label": "Phone",
"description": "Enter your phone",
"placeholder": "Enter your phone",
"regex": "",
"errorText": "Please enter a valid phone number",
"required": false,
"name": "phone-1622684777910"
},
{
"type": "checkbox",
"label": "Checkbox",
"description": "Checkbox",
"values": [
{"label": "Option 1", "value": "option-1"},
{"label": "Option 2", "value": "option-2"}
],
"name": "checkbox-1622684784550"
},
{
"type": "radio",
"label": "Radio",
"description": "Radio boxes",
"values": [
{"label": "Option 1", "value": "option-1"},
{"label": "Option 2", "value": "option-2"}
],
"name": "radio-1622684785878"
},
{
"type": "number",
"label": "Number",
"description": "Age",
"placeholder": "Enter your age",
"min": 12,
"max": 90,
"name": "number-1622684779623"
},
{
"type": "autocomplete",
"label": "Select",
"description": "Select",
"placeholder": "Select",
"values": [
{"label": "Option 1", "value": "option-1"},
{"label": "Option 2", "value": "option-2"},
{"label": "Option 3", "value": "option-3"}
],
"name": "autocomplete-1622684787710"
},
{
"type": "autocomplete",
"label": "Select",
"description": "Select",
"placeholder": "Select",
"values": [
{"label": "Option 4", "value": "option-4"},
{"label": "Option 5", "value": "option-5"},
{"label": "Option 6", "value": "option-6"}
],
"name": "autocomplete-prueba"
}
];
//library variables
late JsonDynamicForm jsonDynamicForm;
List<Widget> fields = List<Widget>.empty(growable: true);
@override
void initState() {
super.initState();
jsonDynamicForm = JsonDynamicForm(data: data, setState: setState);
fields = jsonDynamicForm.generateFields()!;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(children: [
Column(crossAxisAlignment: CrossAxisAlignment.start, children: fields),
TextButton(onPressed: getData, child: Text("Get the data!"))
]),
);
}
getData() {
print(json.encode(jsonDynamicForm.printData()));
}
}
import 'package:flutter/material.dart';
import 'package:chart/constant/app_strings.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewWidget extends StatefulWidget {
final String? url;
final String? name;
const WebViewWidget({Key? key, this.url, this.name}) : super(key: key);
@override
WebViewWidgetState createState() => WebViewWidgetState();
}
class WebViewWidgetState extends State<WebViewWidget> {
late WebViewController controller;
final String _javaScript = '''
const styles = `
#page-header {
display: none;
}
#main-container {
padding-top: 0 !important;
}
`
const styleSheet = document.createElement("style")
styleSheet.innerText = styles
document.head.appendChild(styleSheet)
''';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.name!),
centerTitle: true,
),
body: WebView(
initialUrl: "http://1.12.240.104:8081/",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) => this.controller = controller,
onPageFinished: (url) {
print('url=$url');
controller.runJavascript(_javaScript);
},
),
);
}
}
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
class Application {
static FluroRouter? router;
static GlobalKey<NavigatorState> navigatorKey = GlobalKey();
}
// import 'package:fluro/fluro.dart';
// import 'package:flutter/material.dart';
// import 'package:chart/pages/home/home_page.dart';
// // import 'package:sail/pages/404/not_find_page.dart';
// import 'package:chart/pages/login/login_page.dart';
// import 'package:chart/pages/chat/chat_page.dart';
// import 'package:chart/pages/goods/goods_page.dart';
// import 'package:chart/pages/login/msm_page.dart';
// // import 'package:/chart/pages/goods/goods_page.dart';
// // import 'package:sail/pages/plan/plan_page.dart';
// // import 'package:sail/pages/server_list.dart';
// // import 'package:sail/pages/webview_widget.dart';
// // import 'package:chart/pages/home/main_page.dart';
// // import 'dart:convert';
// /// 入口
// // Handler rootHandler = Handler(
// // handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// // return const MainPage();
// // });
// Handler msgCodeHandler = Handler(
// handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// return const MsmPage();
// });
// /// 登录页
// Handler loginHandler = Handler(
// handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// return const LoginPage();
// });
// /// 首页
// Handler homeHandler = Handler(
// handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// return const HomePage();
// });
// /// goods
// Handler goodsHandler = Handler(
// handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// return const GoodsPage();
// });
// /// 404页面
// // Handler notFindHandler = Handler(
// // handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// // return const NotFindPage();
// // });
// // 聊天
// Handler chatHandle = Handler(
// handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// return const ChatPage();
// });
// /// 服务器节点页
// // Handler serverListHandler = Handler(
// // handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// // return const ServerListPage();
// // });
// /// WebView页
// // Handler webViewHandler = Handler(
// // handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
// // var title = jsonDecode(parameters["titleName"]!.first);
// // var url = jsonDecode(parameters["url"]!.first);
// // return WebViewWidget(name: title, url: url);
// // });
// import 'package:fluro/fluro.dart';
// import 'package:chart/router/router_handlers.dart';
// class Routers {
// static String home = "/";
// static String login = "/login";
// static String plan = "/plan";
// static String serverList = '/server-list';
// static String webView = "/web-view";
// static String chat = "/chat";
// static String goods = "/goods";
// static String msgCode = "/ms-code";
// static void configureRoutes(FluroRouter router) {
// // router.notFoundHandler = notFindHandler;
// router.define(home, handler: homeHandler);
// router.define(login, handler: loginHandler);
// router.define(chat, handler: chatHandle);
// router.define(goods, handler: goodsHandler);
// router.define(msgCode, handler: msgCodeHandler);
// // router.define(serverList, handler: serverListHandler);
// // router.define(webView, handler: webViewHandler);
// }
// }
import 'package:chart/constant/app_urls.dart';
import 'package:chart/entity/plan_entity.dart';
import 'package:chart/utils/http_util.dart';
// data
// :
// "\n\nvOU2HR bbc com male dating services in st john jalandharwali KIDbT0 A9JmEG N8fEjw\n\ngfCRx1 seek com au adult dating and browse sites ‘arabkhel 2M2Qja\n\nYco4nZ 4c6V5a\n\nbjU6q5 espn com dating discussion board gbessavassou dYTPpW fGxmi7 lPpCmr\n\niyI1fQ commbank com au dating people online in lansing michigan n'tamana SECab7 h27lyd nvV8rl\n\n2SKO51 auspost com au adult singles dating juliette georgia kirkham rE2Uv3\n\n5LtaNf Lg9ClR\n\nRibGpH google ca flirt with women in sherbrooke chilongozi ConGpl swazsg yrivXK\n\nEx1q3d 9news com au adult singles dating marquette iowa xizhongtaidong 5bTdfT 7XfJBG X92AxF\n\n0ocF78 weather com dating dude omaha kolpino Oi08sn\n\nebLtGk SpGHKd\n\nAvUNRS xvideos com adult dating search oxnard sampiranpur suLHAy 5XeyzB OovFcO\n\nOLHfmu news yahoo co jp find adult friends burlington niufulu S2kXV7 Hvfdyn 09E90V\n\nKESxlr indeed co uk private fick treffen in deutschland 6 terriatui Anogru\n\nwkVgLF oEA5x6\n\nU6E"
// message
// :
// "操作成功"
// status
// :
// 200
// timestamp
// :
// 1675887721437
// class MessageEntity {
// late final String data;
// late final String message;
// late final int status;
// late final int timestamp;
// }
class MessageSendParameter {
MessageSendParameter({
required this.message,
});
final String message;
Map<String, dynamic> toMap() => {
"message": message,
};
}
class MessageService {
// ?question=321321
// static const String message = '$baseApiUrl/openAi/aiAnswer';
Future<String>? getMessage(Map<String, dynamic> parameters) {
// /getQuickLoginUrl({'redirect': "/plan/${widget.id}"})?
return HttpUtil.instance
?.post("${AppUrls.message}", parameters: parameters)
.then((result) {
return result['data'];
});
}
Future<List<MessageEntity>>? getMessageList() {
return HttpUtil.instance?.get(AppUrls.getMessageList).then((result) {
// return result['data'];
return messageEntityFromList(result['data']);
});
}
}
import 'package:chart/constant/app_urls.dart';
import 'package:chart/entity/plan_entity.dart';
import 'package:chart/utils/http_util.dart';
class PlanService {
Future<List<PlanEntity>>? getMessage() {
return HttpUtil.instance?.get(AppUrls.message).then((result) {
return planEntityFromList(result['data']);
});
}
Future<List<PlanEntity>>? getMessageList() {
return HttpUtil.instance?.get(AppUrls.getMessageList).then((result) {
return planEntityFromList(result['data']);
});
}
Future<List<ClassifyEntity>>? getClassifyList() {
return HttpUtil.instance?.get(AppUrls.getClassifyList).then((result) {
return classifyEntityFromList(result['data']);
});
}
}
// getClassifyList
import 'package:chart/constant/app_urls.dart';
import 'package:chart/entity/server_entity.dart';
import 'package:chart/utils/http_util.dart';
class ServerService {
Future<List<ServerEntity>>? server() {
// return HttpUtil.instance?.get(AppUrls.server).then((result) {
// return serverEntityFromList(result['data']);
// });
}
}
import 'package:chart/constant/app_urls.dart';
// import 'package:chart/entity/login_entity.dart';
import 'package:chart/entity/square_entity.dart';
// import 'package:chart/entity/user_subscribe_entity.dart';
import 'package:chart/utils/http_util.dart';
import '../pages/square/square_page.dart';
class SquareService {
// Future<LoginEntity>? login(Map<String, dynamic> parameters) {
// return HttpUtil.instance
// ?.post(AppUrls.login, parameters: parameters)
// .then((result) {
// return LoginEntity.fromMap(result['data']);
// });
// }
// Future<String>? getQuickLoginUrl(Map<String, dynamic> parameters) {
// return HttpUtil.instance
// ?.post(AppUrls.getQuickLoginUrl, parameters: parameters)
// .then((result) {
// return result['data'];
// });
// }
// Future<bool>? register(parameters) {
// return HttpUtil.instance
// ?.post(AppUrls.register, parameters: parameters)
// .then((result) {
// return result['data'];
// });
// }
// Future<UserSubscribeEntity>? userSubscribe() {
// return HttpUtil.instance?.get(AppUrls.userSubscribe).then((result) {
// return UserSubscribeEntity.fromMap(result['data']);
// });
// }
Future<List<SearchRecordEntity>>? getSearchRecord(int page, int size) {
return HttpUtil.instance
?.get('${AppUrls.getSearchRecord}/$page/$size')
.then((result) {
return searchRecordEntityFromList(result['data']['records']);
});
}
}
import 'package:chart/constant/app_urls.dart';
import 'package:chart/entity/login_entity.dart';
import 'package:chart/entity/user_entity.dart';
import 'package:chart/entity/user_subscribe_entity.dart';
import 'package:chart/utils/http_util.dart';
class UserService {
// Future<LoginEntity>? login(Map<String, dynamic> parameters) {
// return HttpUtil.instance
// ?.post(AppUrls.login, parameters: parameters)
// .then((result) {
// return LoginEntity.fromMap(result['data']);
// });
// }
// Future<String>? getQuickLoginUrl(Map<String, dynamic> parameters) {
// return HttpUtil.instance
// ?.post(AppUrls.getQuickLoginUrl, parameters: parameters)
// .then((result) {
// return result['data'];
// });
// }
// Future<bool>? register(parameters) {
// return HttpUtil.instance
// ?.post(AppUrls.register, parameters: parameters)
// .then((result) {
// return result['data'];
// });
// }
// Future<UserSubscribeEntity>? userSubscribe() {
// return HttpUtil.instance?.get(AppUrls.userSubscribe).then((result) {
// return UserSubscribeEntity.fromMap(result['data']);
// });
// }
Future<IntegralEntity>? getUserIntegral() {
return HttpUtil.instance?.get(AppUrls.getUserIntegral).then((result) {
return IntegralEntity.fromMap(result['data']);
});
}
Future<List<goodEntity>>? getGoodsList() {
return HttpUtil.instance?.get(AppUrls.getGoodsList).then((result) {
return goodEntityFromList(result['data']);
});
}
Future<ApplePayEntity>? applePayCallBack(Map<String, dynamic> parameters) {
return HttpUtil.instance
?.post(AppUrls.applePayCallBack, parameters: parameters)
.then((result) {
return ApplePayEntity.fromMap(result['data']);
});
}
Future<MsmEntity>? sendSms(Map<String, dynamic> parameters) {
return HttpUtil.instance
?.get(AppUrls.sendSms, parameters: parameters)
.then((result) {
return MsmEntity.fromMap(result);
});
}
Future<LoginEntity>? register(Map<String, dynamic> parameters) {
return HttpUtil.instance
?.post(AppUrls.register, parameters: parameters)
.then((result) {
return LoginEntity.fromMap(result['data']);
});
}
}
// getGoodsList
import 'dart:core' as core;
import 'package:flutter/foundation.dart';
void print(core.Object object) {
if (kDebugMode) {
core.print(object);
}
}
import 'package:firebase_phone_auth_handler/firebase_phone_auth_handler.dart';
import 'package:flutter/material.dart';
class Globals {
const Globals._();
static final auth = FirebaseAuth.instance;
static User? get firebaseUser => auth.currentUser;
static final scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
}
import 'dart:developer' as devtools show log;
import 'package:flutter/material.dart';
import 'package:chart/utils/globals.dart';
void showSnackBar(
String text, {
Duration duration = const Duration(seconds: 2),
}) {
Globals.scaffoldMessengerKey.currentState
?..clearSnackBars()
..showSnackBar(
SnackBar(content: Text(text), duration: duration),
);
}
bool isNullOrBlank(String? data) => data?.trim().isEmpty ?? true;
void log(
String screenId, {
dynamic msg,
dynamic error,
StackTrace? stackTrace,
}) =>
devtools.log(
msg.toString(),
error: error,
name: screenId,
stackTrace: stackTrace,
);
import 'package:dio/dio.dart';
import 'package:chart/constant/app_strings.dart';
import 'package:chart/router/application.dart';
import 'package:chart/router/routers.dart';
import 'package:chart/utils/common_util.dart';
import 'package:chart/utils/shared_preferences_util.dart';
class HttpUtil {
// 工厂模式
static HttpUtil? get instance => _getInstance();
static HttpUtil? _httpUtil;
late Dio dio;
static HttpUtil? _getInstance() {
_httpUtil ??= HttpUtil();
return _httpUtil;
}
HttpUtil() {
BaseOptions options = BaseOptions(
connectTimeout: 30000,
receiveTimeout: 30000,
);
dio = Dio(options);
dio.interceptors
.add(InterceptorsWrapper(onRequest: (options, handler) async {
print("========================请求数据===================");
print("url=${options.uri.toString()}");
print("headers=${options.headers}");
print("params=${options.data}");
// options.headers["appVersionName"]="V 4.0.6";
//如果token存在在请求参数加上token
await SharedPreferencesUtil.getInstance()
?.getString(AppStrings.token)
.then((token) {
if (token != null && token.isNotEmpty) {
options.headers['Authorization'] = token;
// ["Authorization"] = token;
print("token=$token");
}
});
//如果auth_data存在在请求参数加上auth_data
await SharedPreferencesUtil.getInstance()
?.getString(AppStrings.authData)
.then((authData) {
if (authData != null) {
options.queryParameters[AppStrings.authData] = authData;
print("authData=$authData");
}
});
return handler.next(options);
}, onResponse: (response, handler) {
print("========================请求数据===================");
print("code=${response.statusCode}");
print("response=${response.data}");
// if (response.statusCode! < 200 || response.statusCode! >= 300) {
// if (response.statusCode == 403) {
// Application.navigatorKey.currentState?.pushNamed(Routers.login);
// }
// return handler.reject(DioError(
// requestOptions: response.requestOptions,
// response: response,
// type: DioErrorType.response));
// }
return handler.next(response);
}, onError: (error, handler) {
print("========================请求错误===================");
print("message =${error.message}");
print("code=${error.response?.statusCode}");
print("response=${error.response?.data}");
return handler.next(error);
}));
}
//get请求
Future get(String url,
{Map<String, dynamic>? parameters, Options? options}) async {
Response response;
if (parameters != null && options != null) {
response =
await dio.get(url, queryParameters: parameters, options: options);
} else if (parameters != null && options == null) {
response = await dio.get(url, queryParameters: parameters);
} else if (parameters == null && options != null) {
response = await dio.get(url, options: options);
} else {
response = await dio.get(url);
}
return response.data;
}
//post请求
Future post(String url,
{Map<String, dynamic>? parameters, Options? options}) async {
Response response;
if (parameters != null && options != null) {
response = await dio.post(url, data: parameters, options: options);
} else if (parameters != null && options == null) {
response = await dio.post(url, data: parameters);
} else if (parameters == null && options != null) {
response = await dio.post(url, options: options);
} else {
response = await dio.post(url);
}
return response.data;
}
//put请求
Future put(String url,
{Map<String, dynamic>? parameters, Options? options}) async {
Response response;
if (parameters != null && options != null) {
response = await dio.put(url, data: parameters, options: options);
} else if (parameters != null && options == null) {
response = await dio.put(url, data: parameters);
} else if (parameters == null && options != null) {
response = await dio.put(url, options: options);
} else {
response = await dio.put(url);
}
return response.data;
}
//delete请求
Future delete(String url,
{Map<String, dynamic>? parameters, Options? options}) async {
Response response;
if (parameters != null && options != null) {
response = await dio.delete(url, data: parameters, options: options);
} else if (parameters != null && options == null) {
response = await dio.delete(url, data: parameters);
} else if (parameters == null && options != null) {
response = await dio.delete(url, options: options);
} else {
response = await dio.delete(url);
}
return response.data;
}
}
import 'dart:convert';
import 'package:fluro/fluro.dart';
import 'package:flutter/cupertino.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
// import 'package:chart/pages/crisp_page.dart';
// import 'package:chart/pages/plan/plan_page.dart';
// import 'package:chart/pages/server_list.dart';
import 'package:chart/router/application.dart';
import 'package:chart/router/routers.dart';
class NavigatorUtil {
// static goMainPage(BuildContext context) {
// Application.router?.navigateTo(context, Routers.root,
// transition: TransitionType.inFromRight, replace: true);
// }
// static goGuidePage(BuildContext context) {
// Application.router?.navigateTo(context, Routers.guide,
// transition: TransitionType.inFromRight, replace: true);
// }
static goHomePage(BuildContext context) {
Application.router?.navigateTo(context, Routers.home,
transition: TransitionType.inFromRight, replace: true);
}
static goLogin(BuildContext context) {
Application.router?.navigateTo(context, Routers.login,
transition: TransitionType.inFromRight, replace: true);
}
static goPlan(BuildContext context) {
// showCupertinoModalBottomSheet(
// context: context,
// builder: (context) => const PlanPage()
// );
// Application.router.navigateTo(context, Routers.plan,
// transition: TransitionType.inFromRight);
}
static goServerList(BuildContext context) {
// showCupertinoModalBottomSheet(
// context: context,
// builder: (context) => const ServerListPage()
// );
// Application.router.navigateTo(context, Routers.serverList,
// transition: TransitionType.inFromRight);
}
static goToCrisp(BuildContext context) {
// showCupertinoModalBottomSheet(
// context: context,
// builder: (context) => const CrispPage()
// );
}
static goWebView(BuildContext context, String titleName, String url) {
String encodeUrl = Uri.encodeComponent(jsonEncode(url));
String encodeTitleName = Uri.encodeComponent(jsonEncode(titleName));
return Application.router?.navigateTo(
context, "${Routers.webView}?titleName=$encodeTitleName&url=$encodeUrl",
transition: TransitionType.inFromRight);
}
static goBack(BuildContext context) {
Application.router?.pop(context);
}
}
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class SharedPreferencesUtil {
SharedPreferencesUtil._();
static SharedPreferencesUtil? _instance;
late SharedPreferences sharedPreferences;
static SharedPreferencesUtil? getInstance() {
_instance ??= SharedPreferencesUtil._();
return _instance;
}
static saveData<T>(String key, T value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
switch (T) {
case String:
prefs.setString(key, value as String);
break;
case int:
prefs.setInt(key, value as int);
break;
case bool:
prefs.setBool(key, value as bool);
break;
case double:
prefs.setDouble(key, value as double);
break;
}
}
static Future<T?> getData<T>(String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
T? res;
switch (T) {
case String:
res = prefs.getString(key) as T;
break;
case int:
res = prefs.getInt(key) as T;
break;
case bool:
res = prefs.getBool(key) as T;
break;
case double:
res = prefs.getDouble(key) as T;
break;
}
return res;
}
Future<bool> setBool(String tag, bool isFirst) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return sharedPreferences.setBool(tag, isFirst);
}
Future<bool> setString(String tag, String data) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return sharedPreferences.setString(tag, data);
}
Future<bool> setMap(String tag, Map<String, dynamic>? data) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return sharedPreferences.setString(tag, jsonEncode(data));
}
Future<bool> setList(String tag, List<dynamic>? data) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return sharedPreferences.setString(tag, jsonEncode(data));
}
Future<bool?> getBool(String tag) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return sharedPreferences.getBool(tag);
}
Future<String?> getString(String tag) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return sharedPreferences.getString(tag);
}
Future<Map<String, dynamic>> getMap(String tag) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return jsonDecode(sharedPreferences.getString(tag) ?? '{}');
}
Future<List<dynamic>> getList(String tag) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return jsonDecode(sharedPreferences.getString(tag) ?? '[]');
}
Future<bool> clear() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return sharedPreferences.clear();
}
}
class TransferUtil {
double _transfer = 0;
int _level = 0;
List suffix = [
'B',
'KB',
'MB',
'GB',
'TB',
'PB'
];
String toHumanReadable(int transfer) {
_transfer = transfer.toDouble();
handleTransfer();
return '${_transfer.toStringAsFixed(2)} ${suffix[_level]}';
}
handleTransfer() {
if (_transfer > 1024) {
_transfer = _transfer / 1024;
++_level;
handleTransfer();
}
}
}
import 'package:flutter/material.dart';
class BankCard extends StatelessWidget {
final BankCardModel card;
BankCard({required this.card});
@override
Widget build(BuildContext context) {
return Container(
height: 150.0,
width: 252.0,
decoration: BoxDecoration(
image:
DecorationImage(image: AssetImage(card.bgAsset), fit: BoxFit.cover),
),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0, right: 16.0),
child: Text(
'BALANCE',
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.white,
fontSize: 10.0,
fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Text(
'\$ ${card.balance}',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
],
),
],
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Text(
card.accountNumber,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 4.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'VALID\nTHRU',
textAlign: TextAlign.left,
style: TextStyle(
color: card.bgAsset ==
'assets/images/bg_purple_card.png' ||
card.bgAsset ==
'assets/images/bg_blue_card.png'
? Colors.grey
: Colors.black,
fontSize: 10.0,
fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
card.validDate,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold),
),
)
],
),
),
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 4.0),
child: Text(
card.name,
textAlign: TextAlign.left,
style: TextStyle(
color: card.bgAsset == 'assets/images/bg_purple_card.png' ||
card.bgAsset == 'assets/images/bg_blue_card.png'
? Colors.grey
: Color(0xFF253C70),
fontSize: 12.0,
fontWeight: FontWeight.bold,
),
),
),
],
))
],
),
);
}
}
class SmallBankCard extends StatelessWidget {
final BankCardModel card;
final double screenWidth;
SmallBankCard({required this.card, required this.screenWidth});
@override
Widget build(BuildContext context) {
final bool isLargeScreen = screenWidth > 320;
final double topPadding = isLargeScreen ? 14.0 : 24.0;
final EdgeInsets inset = EdgeInsets.only(left: 16.0, top: topPadding);
return Container(
decoration: BoxDecoration(
image:
DecorationImage(image: AssetImage(card.bgAsset), fit: BoxFit.cover),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: inset,
child: Text(
card.accountNumber,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: isLargeScreen ? 10.0 : 18.0,
fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 2.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'VALID\nTHRU',
textAlign: TextAlign.left,
style: TextStyle(
color: card.bgAsset ==
'assets/images/bg_purple_card.png' ||
card.bgAsset ==
'assets/images/bg_blue_card.png'
? Colors.grey
: Colors.black,
fontSize: isLargeScreen ? 6.0 : 12.0,
fontWeight: FontWeight.bold),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
card.validDate,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: isLargeScreen ? 10.0 : 20.0,
fontWeight: FontWeight.bold),
),
)
],
),
),
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 2.0),
child: Text(
card.name,
textAlign: TextAlign.left,
style: TextStyle(
color: card.bgAsset ==
'assets/images/bg_purple_card.png' ||
card.bgAsset ==
'assets/images/bg_blue_card.png'
? Colors.grey
: Color(0xFF253C70),
fontSize: isLargeScreen ? 9.0 : 13.0,
fontWeight: FontWeight.bold),
),
),
],
)),
],
),
),
GestureDetector(
child: Container(
child: Image.asset('assets/images/ico_delete_card.png'),
),
),
],
),
);
}
}
class BankCardModel {
final String bgAsset;
final int balance;
final String name;
final String validDate;
final String accountNumber;
BankCardModel(
this.bgAsset,
this.name,
this.accountNumber,
this.validDate,
this.balance,
);
}
import 'package:flutter/material.dart';
// import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:chart/models/user_model.dart';
import 'package:chart/utils/navigator_util.dart';
class ConnectionStats extends StatefulWidget {
const ConnectionStats({Key? key}) : super(key: key);
@override
ConnectionStatsState createState() => ConnectionStatsState();
}
class ConnectionStatsState extends State<ConnectionStats> {
late UserModel _userModel;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_userModel = Provider.of<UserModel>(context);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
const Text("00:15:02",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 40,
color: AppColors.grayColor,
)),
Padding(
padding: EdgeInsets.symmetric(horizontal: ScreenUtil().setWidth(75)),
child: TextButton(
onPressed: () => _userModel.checkHasLogin(
context, () => NavigatorUtil.goServerList(context)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
// Icon(MaterialCommunityIcons.map_marker,
// color: AppColors.grayColor, size: 20),
Text("其他节点",
style: TextStyle(
fontSize: 12, color: AppColors.grayColor)),
Icon(Icons.chevron_right,
color: AppColors.grayColor, size: 20)
])),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(75), vertical: 10),
child: Row(
children: [
// Download Stats
Row(children: [
// Download Icon
Container(
decoration: BoxDecoration(
boxShadow: const [
BoxShadow(
color: Color(0xffff0000),
blurRadius: 13,
spreadRadius: -2)
],
color: const Color(0xffff0000),
borderRadius: BorderRadius.circular(13)),
padding: const EdgeInsets.all(5),
child: const Icon(
Icons.arrow_downward,
color: Colors.white,
),
),
// Labels
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"下行速度",
style: TextStyle(
color: AppColors.grayColor,
fontWeight: FontWeight.w500),
),
RichText(
text: const TextSpan(
style: TextStyle(
color: AppColors.grayColor,
fontWeight: FontWeight.w900),
children: [
TextSpan(text: "75.9"),
TextSpan(
text: " KB/s",
style:
TextStyle(fontWeight: FontWeight.normal)),
]),
)
],
),
)
]),
Expanded(child: Container()),
// Upload Stats
Row(children: [
// Upload Icon
Container(
decoration: BoxDecoration(
boxShadow: const [
BoxShadow(
color: Color(0xff03a305),
blurRadius: 13,
spreadRadius: -2)
],
color: const Color(0xff03a305),
borderRadius: BorderRadius.circular(13)),
padding: const EdgeInsets.all(5),
child: const Icon(
Icons.arrow_upward,
color: Colors.white,
),
),
// Labels
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"上行速度",
style: TextStyle(
color: AppColors.grayColor,
fontWeight: FontWeight.w500),
),
RichText(
text: const TextSpan(
style: TextStyle(
color: AppColors.grayColor,
fontWeight: FontWeight.w900),
children: [
TextSpan(text: "29.6"),
TextSpan(
text: " KB/s",
style:
TextStyle(fontWeight: FontWeight.normal)),
]),
)
],
),
)
]),
],
),
)
],
);
}
}
import 'package:flutter/material.dart';
class CustomLoader extends StatelessWidget {
static const id = 'CustomLoader';
final Color? color;
final double radius;
final double padding;
const CustomLoader({
Key? key,
this.color,
this.radius = 15,
this.padding = 5,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(padding),
child: Center(
child: SizedBox(
height: radius * 2,
width: radius * 2,
child: CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation<Color>(
color ?? Theme.of(context).colorScheme.secondary,
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:chart/entity/plan_entity.dart';
import 'package:chart/models/app_model.dart';
import 'package:chart/models/user_model.dart';
// import 'package:chart/models/user_subscribe_model.dart';
import 'package:chart/service/plan_service.dart';
import 'package:chart/widgets/connection_stats.dart';
import 'package:chart/widgets/logo_bar.dart';
import 'package:chart/widgets/my_subscribe.dart';
import 'package:chart/widgets/plan_list.dart';
import 'package:chart/widgets/select_location.dart';
class HomeWidget extends StatefulWidget {
const HomeWidget({Key? key}) : super(key: key);
@override
HomeWidgetState createState() => HomeWidgetState();
}
class HomeWidgetState extends State<HomeWidget>
with AutomaticKeepAliveClientMixin {
late AppModel _appModel;
late UserModel _userModel;
// late UserSubscribeModel _userSubscribeModel;
List<PlanEntity> _planEntityList = [];
@override
void initState() {
super.initState();
PlanService().getMessage()?.then((planEntityList) {
setState(() {
_planEntityList = planEntityList;
});
});
}
@override
bool get wantKeepAlive => true;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_appModel = Provider.of<AppModel>(context);
_userModel = Provider.of<UserModel>(context);
// _userSubscribeModel = Provider.of<UserSubscribeModel>(context);
}
@override
Widget build(BuildContext context) {
super.build(context);
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
children: [
// Logo bar
Padding(
padding: EdgeInsets.only(
left: ScreenUtil().setWidth(75),
right: ScreenUtil().setWidth(75)),
child: LogoBar(
isOn: _appModel.isOn,
),
),
// Padding(
// padding: EdgeInsets.only(top: ScreenUtil().setWidth(30)),
// child: MySubscribe(
// isLogin: _userModel.isLogin,
// isOn: _appModel.isOn,
// userSubscribeEntity: _userSubscribeModel.userSubscribeEntity!,
// ),
// ),
// Padding(
// padding:
// EdgeInsets.symmetric(vertical: ScreenUtil().setWidth(30)),
// child: PlanList(
// isOn: _appModel.isOn,
// boughtPlanId:
// _userSubscribeModel.userSubscribeEntity?.planId ?? 0,
// plans: _planEntityList,
// ),
// ),
Container(
padding:
EdgeInsets.symmetric(horizontal: ScreenUtil().setWidth(75)),
child: Stack(alignment: Alignment.center, children: [
Image.asset(
"assets/map.png",
scale: 3,
color: _appModel.isOn
? const Color(0x15000000)
: AppColors.darkSurfaceColor,
),
])),
_appModel.isOn ? const ConnectionStats() : const SelectLocation(),
],
));
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:chart/models/user_model.dart';
// import 'package:chart/models/user_subscribe_model.dart';
import 'package:chart/utils/navigator_util.dart';
class LogoBar extends StatelessWidget {
const LogoBar({
Key? key,
required this.isOn,
}) : super(key: key);
final bool isOn;
@override
Widget build(BuildContext context) {
UserModel userModel = Provider.of<UserModel>(context);
// UserSubscribeModel userSubscribeModel = Provider.of<UserSubscribeModel>(context);
return Container(
margin: EdgeInsets.only(top: ScreenUtil().setWidth(60)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Sail",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: ScreenUtil().setSp(60),
color: isOn ? AppColors.grayColor : Colors.white,
),
),
Row(
children: [
Material(
color:
isOn ? const Color(0x66000000) : AppColors.darkSurfaceColor,
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(30)),
child: InkWell(
borderRadius:
BorderRadius.circular(ScreenUtil().setWidth(30)),
onTap: () => NavigatorUtil.goToCrisp(context),
child: Container(
padding: EdgeInsets.symmetric(
vertical: ScreenUtil().setWidth(10),
horizontal: ScreenUtil().setWidth(30)),
child: Text(
"客服",
style: TextStyle(
fontSize: ScreenUtil().setSp(32),
color: Colors.white,
fontWeight: FontWeight.w500),
),
),
),
),
Padding(
padding: EdgeInsets.only(left: ScreenUtil().setWidth(15))),
// Material(
// color: isOn ? const Color(0x66000000) : AppColors.darkSurfaceColor,
// borderRadius: BorderRadius.circular(ScreenUtil().setWidth(30)),
// child: InkWell(
// borderRadius: BorderRadius.circular(ScreenUtil().setWidth(30)),
// onTap: () {},
// child: Container(
// padding: EdgeInsets.symmetric(
// vertical: ScreenUtil().setWidth(10), horizontal: ScreenUtil().setWidth(30)),
// child: Text(
// userSubscribeModel?.userSubscribeEntity?.email ?? "欢迎光临",
// style:
// TextStyle(fontSize: ScreenUtil().setSp(32), color: Colors.white, fontWeight: FontWeight.w500),
// ),
// ),
// ),
// ),
userModel.isLogin
? Padding(
padding: EdgeInsets.only(left: ScreenUtil().setWidth(15)))
: Container(),
userModel.isLogin
? Material(
color: isOn
? const Color(0x66000000)
: AppColors.darkSurfaceColor,
borderRadius:
BorderRadius.circular(ScreenUtil().setWidth(30)),
child: InkWell(
borderRadius:
BorderRadius.circular(ScreenUtil().setWidth(30)),
onTap: () {
userModel.logout();
NavigatorUtil.goLogin(context);
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: ScreenUtil().setWidth(10),
horizontal: ScreenUtil().setWidth(30)),
child: Text(
'退出',
style: TextStyle(
fontSize: ScreenUtil().setSp(32),
color: Colors.white,
fontWeight: FontWeight.w500),
),
),
),
)
: Container(),
],
)
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:intl/intl.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:chart/entity/user_subscribe_entity.dart';
import 'package:chart/utils/transfer_util.dart';
class MySubscribe extends StatefulWidget {
const MySubscribe(
{Key? key,
required this.isLogin,
required this.isOn,
required this.userSubscribeEntity})
: super(key: key);
final bool isLogin;
final bool isOn;
final UserSubscribeEntity userSubscribeEntity;
@override
MySubscribeState createState() => MySubscribeState();
}
class MySubscribeState extends State<MySubscribe> {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.only(left: ScreenUtil().setWidth(75)),
child: Text(
"我的订阅",
style: TextStyle(
fontSize: ScreenUtil().setSp(32),
color: widget.isOn ? AppColors.grayColor : Colors.grey[400],
fontWeight: FontWeight.w500),
),
),
SizedBox(height: ScreenUtil().setWidth(30)),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: EdgeInsets.only(bottom: ScreenUtil().setWidth(10)),
child: widget?.userSubscribeEntity?.plan == null
? _emptyWidget()
: _buildConnections(),
)
],
);
}
Widget _emptyWidget() {
return Container(
width: ScreenUtil().setWidth(1080),
height: ScreenUtil().setWidth(200),
padding: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(75),
vertical: ScreenUtil().setWidth(0)),
child: Material(
elevation: widget.isOn ? 3 : 0,
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(30)),
color: widget.isOn ? Colors.white : AppColors.darkSurfaceColor,
child: Container(
alignment: Alignment.center,
child: Text(
!widget.isLogin ? '请先登陆' : '请先订阅下方套餐',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: ScreenUtil().setWidth(40),
color: widget.isOn ? Colors.black : Colors.white),
),
),
),
);
}
Widget _buildConnections() {
return Container(
width: ScreenUtil().setWidth(1080),
height: ScreenUtil().setWidth(240),
padding: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(75),
vertical: ScreenUtil().setWidth(0)),
child: Material(
elevation: widget.isOn ? 3 : 0,
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(30)),
color: widget.isOn ? Colors.white : AppColors.darkSurfaceColor,
child: Container(
padding: EdgeInsets.symmetric(
vertical: ScreenUtil().setWidth(30),
horizontal: ScreenUtil().setWidth(40)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.userSubscribeEntity.plan.name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: ScreenUtil().setSp(35),
color: widget.isOn ? Colors.black : Colors.white),
),
Padding(
padding: EdgeInsets.only(
left: ScreenUtil().setWidth(15))),
Text(
widget.userSubscribeEntity?.expiredAt != null
? '${DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.fromMillisecondsSinceEpoch(widget.userSubscribeEntity.expiredAt * 1000))}过期'
: '长期有效',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: ScreenUtil().setSp(35),
color: widget.isOn ? Colors.black : Colors.white),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: ScreenUtil().setWidth(480),
padding: EdgeInsets.only(
bottom: ScreenUtil().setWidth(15)),
child: LinearProgressIndicator(
backgroundColor:
widget.isOn ? Colors.black : Colors.white,
valueColor:
AlwaysStoppedAnimation(Colors.yellow[600]),
value: double.parse(((widget
.userSubscribeEntity.u ??
0 + widget.userSubscribeEntity.d ??
0) /
widget.userSubscribeEntity
.transferEnable ??
1)
.toStringAsFixed(2)),
),
),
Text(
'已用 ${TransferUtil().toHumanReadable(widget.userSubscribeEntity.u + widget.userSubscribeEntity.d)} / 总计 ${TransferUtil().toHumanReadable(widget.userSubscribeEntity.transferEnable)}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: ScreenUtil().setSp(26),
color: widget.isOn ? Colors.black : Colors.white),
)
],
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
// Container(
// width: ScreenUtil().setWidth(160),
// height: ScreenUtil().setWidth(75),
// margin: EdgeInsets.only(right: ScreenUtil().setWidth(10)),
// child: FlatButton(
// color: Colors.yellow,
// highlightColor: Colors.yellow[700],
// colorBrightness: Brightness.dark,
// splashColor: Colors.grey,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(20.0)),
// onPressed: () {},
// child: Text(
// '续费',
// style: TextStyle(
// color: Colors.black87,
// fontSize: ScreenUtil().setSp(24)),
// ),
// ),
// ),
// SizedBox(
// width: ScreenUtil().setWidth(160),
// height: ScreenUtil().setWidth(75),
// child: FlatButton(
// color: Colors.yellow,
// highlightColor: Colors.yellow[700],
// colorBrightness: Brightness.dark,
// splashColor: Colors.grey,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(20.0)),
// onPressed: () {},
// child: Text(
// '重置',
// style: TextStyle(
// color: Colors.black87,
// fontSize: ScreenUtil().setSp(24)),
// ),
// ),
// )
],
)
],
),
),
));
}
}
import 'package:flutter/material.dart';
import 'package:pinput/pinput.dart';
class PinInputField extends StatefulWidget {
final int length;
final void Function(bool)? onFocusChange;
final void Function(String) onSubmit;
const PinInputField({
Key? key,
this.length = 6,
this.onFocusChange,
required this.onSubmit,
}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_PinInputFieldState createState() => _PinInputFieldState();
}
class _PinInputFieldState extends State<PinInputField> {
late final TextEditingController _pinPutController;
late final FocusNode _pinPutFocusNode;
late final int _length;
Size _findContainerSize(BuildContext context) {
// full screen width
double width = MediaQuery.of(context).size.width * 0.85;
// using left-over space to get width of each container
width /= _length;
return Size.square(width);
}
@override
void initState() {
_pinPutController = TextEditingController();
_pinPutFocusNode = FocusNode();
if (widget.onFocusChange != null) {
_pinPutFocusNode.addListener(() {
widget.onFocusChange!(_pinPutFocusNode.hasFocus);
});
}
_length = widget.length;
super.initState();
}
@override
void dispose() {
_pinPutController.dispose();
_pinPutFocusNode.dispose();
super.dispose();
}
PinTheme _getPinTheme(
BuildContext context, {
required Size size,
}) {
return PinTheme(
height: size.height,
width: size.width,
textStyle: const TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(7.5),
),
);
}
static const _focusScaleFactor = 1.15;
@override
Widget build(BuildContext context) {
final size = _findContainerSize(context);
final defaultPinTheme = _getPinTheme(context, size: size);
return SizedBox(
height: size.height * _focusScaleFactor,
child: Pinput(
length: _length,
defaultPinTheme: defaultPinTheme,
focusedPinTheme: defaultPinTheme.copyWith(
height: size.height * _focusScaleFactor,
width: size.width * _focusScaleFactor,
decoration: defaultPinTheme.decoration!.copyWith(
border: Border.all(color: Theme.of(context).colorScheme.secondary),
),
),
errorPinTheme: defaultPinTheme.copyWith(
decoration: BoxDecoration(
color: Theme.of(context).errorColor,
borderRadius: BorderRadius.circular(8),
),
),
focusNode: _pinPutFocusNode,
controller: _pinPutController,
onCompleted: widget.onSubmit,
pinAnimationType: PinAnimationType.scale,
// submittedFieldDecoration: _pinPutDecoration,
// selectedFieldDecoration: _pinPutDecoration,
// followingFieldDecoration: _pinPutDecoration,
// textStyle: const TextStyle(
// color: Colors.black,
// fontSize: 20.0,
// fontWeight: FontWeight.w600,
// ),
),
);
}
}
import 'package:flutter/material.dart';
// import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:chart/entity/plan_entity.dart';
import 'package:chart/models/user_model.dart';
import 'package:chart/utils/navigator_util.dart';
class PlanList extends StatefulWidget {
const PlanList(
{Key? key,
required this.isOn,
required this.boughtPlanId,
required this.plans})
: super(key: key);
final bool isOn;
final int boughtPlanId;
final List<PlanEntity> plans;
@override
PlanListState createState() => PlanListState();
}
class PlanListState extends State<PlanList> with AutomaticKeepAliveClientMixin {
late UserModel _userModel;
@override
bool get wantKeepAlive => true;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_userModel = Provider.of<UserModel>(context);
}
@override
Widget build(BuildContext context) {
super.build(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.only(left: ScreenUtil().setWidth(75)),
child: Text(
"订阅套餐",
style: TextStyle(
fontSize: ScreenUtil().setSp(32),
color: widget.isOn ? AppColors.grayColor : Colors.grey[400],
fontWeight: FontWeight.w500),
),
),
SizedBox(height: ScreenUtil().setWidth(30)),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: EdgeInsets.only(bottom: ScreenUtil().setWidth(10)),
child: Row(children: _buildConnections()),
)
],
);
}
List<Widget> _buildConnections() {
List<Widget> list =
List.generate(widget.plans.length * 2 + 1, (i) => Container());
list[0] = SizedBox(width: ScreenUtil().setWidth(75));
for (var i = 1; i < list.length; i++) {
list[i] = Material(
elevation: widget.isOn
? widget.plans[i ~/ 2].id == widget.boughtPlanId
? 3
: 0
: 0,
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(30)),
color: widget.isOn
? widget.plans[i ~/ 2].id == widget.boughtPlanId
? Colors.white
: const Color(0x15000000)
: AppColors.darkSurfaceColor,
child: InkWell(
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(30)),
onTap: widget.isOn && widget.plans[i ~/ 2].id == widget.boughtPlanId
? null
: () => _userModel.checkHasLogin(
context, () => NavigatorUtil.goPlan(context)),
child: Container(
// width: ScreenUtil().setWidth(300),
height: ScreenUtil().setWidth(200),
padding: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(40),
vertical: ScreenUtil().setWidth(30)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Country name
Text(
widget.plans[i ~/ 2].name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: ScreenUtil().setSp(32),
color: widget.isOn
? widget.plans[i ~/ 2].id == widget.boughtPlanId
? Colors.black
: AppColors.grayColor
: Colors.white),
),
// Connection status
Padding(
padding: EdgeInsets.only(top: ScreenUtil().setWidth(40)),
child: widget.plans[i ~/ 2].id == widget.boughtPlanId
? Row(
children: [
// Icon(
// MaterialCommunityIcons.shield_check_outline,
// size: ScreenUtil().setWidth(32),
// color: const Color(0xFF1abb1d),
// ),
Text(
"已订阅",
style: TextStyle(
fontSize: ScreenUtil().setSp(32),
color: const Color(0xFF1abb1d),
fontWeight: FontWeight.bold),
)
],
)
: Text("选购",
style: TextStyle(
fontSize: ScreenUtil().setSp(32),
fontWeight: FontWeight.w500,
color: widget.isOn
? Colors.black
: Colors.yellow[700])),
)
],
))),
);
list[++i] = SizedBox(width: ScreenUtil().setWidth(30));
}
return list;
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:chart/models/app_model.dart';
// import 'package:chart/models/server_model.dart';
import 'package:chart/models/user_model.dart';
class PowerButton extends StatefulWidget {
const PowerButton({Key? key}) : super(key: key);
@override
PowerButtonState createState() => PowerButtonState();
}
class PowerButtonState extends State<PowerButton> {
late AppModel _appModel;
late UserModel _userModel;
// late ServerModel _serverModel;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_appModel = Provider.of<AppModel>(context);
_userModel = Provider.of<UserModel>(context);
// _serverModel = Provider.of<ServerModel>(context);
}
Future<void> pressConnectBtn() async {
// if (_serverModel.selectServerEntity == null) {
// Fluttertoast.showToast(
// msg: "请选择服务器节点",
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// timeInSecForIosWeb: 2,
// textColor: Colors.white,
// fontSize: 14.0);
// return;
// }
// _appModel.togglePowerButton();
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color:
_appModel.isOn ? const Color(0x20000000) : const Color(0xff606060),
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(120)),
),
child: Material(
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(100)),
color: _appModel.isOn ? AppColors.themeColor : Colors.grey,
child: InkWell(
splashColor: AppColors.yellowColor,
onTap: () => _userModel.checkHasLogin(context, pressConnectBtn),
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(100)),
child: Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: Icon(
Icons.power_settings_new,
size: ScreenUtil().setWidth(100),
color: Colors.white,
)),
),
),
);
}
}
import 'package:flutter/material.dart';
class ProfileWidget extends StatelessWidget {
const ProfileWidget({Key? key, required this.userName, this.avatar, required this.onTap}) : super(key: key);
final String? avatar;
final String userName;
final void Function() onTap;
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.only(right: 24, left: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
avatar != null
? Row(
children: <Widget>[
ClipOval(child: Image(image: NetworkImage(avatar!), width: 40, height: 40)),
Padding(
padding: const EdgeInsets.only(left: 12),
child: Text(
userName,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500, color: Colors.black),
),
)
],
)
: Text(
userName,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500, color: Colors.black),
),
avatar != null
? Material(
color: const Color(0x66000000),
borderRadius: BorderRadius.circular(30),
child: InkWell(
onTap: onTap,
child: Container(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
child: const Text(
'退出',
style: TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500),
),
),
),
)
: Container(),
],
),
);
}
}
import 'dart:math' as math;
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:chart/constant/app_colors.dart';
double minHeight = ScreenUtil().setHeight(260);
const double iconStartSize = 44;
const double iconEndSize = 120;
const double iconStartMarginTop = 36;
const double iconEndMarginTop = 80;
const double iconsVerticalSpacing = 24;
const double iconsHorizontalSpacing = 16;
class RecentConnectionBottomSheet extends StatefulWidget {
const RecentConnectionBottomSheet({Key? key}) : super(key: key);
@override
RecentConnectionBottomSheetState createState() =>
RecentConnectionBottomSheetState();
}
class RecentConnectionBottomSheetState
extends State<RecentConnectionBottomSheet>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
double get maxHeight => MediaQuery.of(context).size.height;
double? get headerTopMargin =>
lerp(20, 20 + MediaQuery.of(context).padding.top);
double? get headerFontSize => lerp(14, 24);
double? get itemBorderRadius => lerp(8, 24);
double? get iconLeftBorderRadius => itemBorderRadius;
double? get iconRightBorderRadius => lerp(8, 0);
double? get iconSize => lerp(iconStartSize, iconEndSize);
double? iconTopMargin(int index) =>
lerp(iconStartMarginTop,
iconEndMarginTop + index * (iconsVerticalSpacing + iconEndSize))! +
headerTopMargin!;
double? iconLeftMargin(int index) =>
lerp(index * (iconsHorizontalSpacing + iconStartSize), 0);
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 600),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
double? lerp(double min, double max) =>
lerpDouble(min, max, _controller.value);
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Positioned(
height: lerp(minHeight, maxHeight),
left: 0,
right: 0,
bottom: 0,
child: GestureDetector(
onTap: _toggle,
onVerticalDragUpdate: _handleDragUpdate,
onVerticalDragEnd: _handleDragEnd,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 32),
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [AppColors.themeColor, Colors.pink],
begin: Alignment.topLeft,
end: Alignment.bottomRight),
borderRadius: BorderRadius.vertical(top: Radius.circular(32)),
),
child: Stack(
children: <Widget>[
const MenuButton(),
SheetHeader(
fontSize: headerFontSize,
topMargin: headerTopMargin,
),
for (Event event in events) _buildFullItem(event),
for (Event event in events) _buildIcon(event),
],
),
),
),
);
},
);
}
Widget _buildIcon(Event event) {
int index = events.indexOf(event);
return Positioned(
height: iconSize,
width: iconSize,
top: iconTopMargin(index),
left: iconLeftMargin(index),
child: ClipRRect(
borderRadius: BorderRadius.horizontal(
left: Radius.circular(iconLeftBorderRadius!),
right: Radius.circular(iconRightBorderRadius!),
),
child: Image.asset(
'assets/${event.assetName}',
fit: BoxFit.cover,
alignment: Alignment(lerp(1, 0)!, 0),
),
),
);
}
Widget _buildFullItem(Event event) {
int index = events.indexOf(event);
return ExpandedEventItem(
topMargin: iconTopMargin(index),
leftMargin: iconLeftMargin(index),
height: iconSize,
isVisible: _controller.status == AnimationStatus.completed,
borderRadius: itemBorderRadius,
title: event.title,
date: event.date,
);
}
void _toggle() {
final bool isOpen = _controller.status == AnimationStatus.completed;
_controller.fling(velocity: isOpen ? -2 : 2);
}
void _handleDragUpdate(DragUpdateDetails details) {
_controller.value -= details.primaryDelta! / maxHeight;
}
void _handleDragEnd(DragEndDetails details) {
if (_controller.isAnimating ||
_controller.status == AnimationStatus.completed) return;
final double flingVelocity =
details.velocity.pixelsPerSecond.dy / maxHeight;
if (flingVelocity < 0.0) {
_controller.fling(velocity: math.max(2.0, -flingVelocity));
} else if (flingVelocity > 0.0) {
_controller.fling(velocity: math.min(-2.0, -flingVelocity));
} else {
_controller.fling(velocity: _controller.value < 0.5 ? -2.0 : 2.0);
}
}
}
class ExpandedEventItem extends StatelessWidget {
final double? topMargin;
final double? leftMargin;
final double? height;
final bool isVisible;
final double? borderRadius;
final String title;
final String date;
const ExpandedEventItem(
{Key? key,
required this.topMargin,
required this.height,
required this.isVisible,
required this.borderRadius,
required this.title,
required this.date,
required this.leftMargin})
: super(key: key);
@override
Widget build(BuildContext context) {
return Positioned(
top: topMargin,
left: leftMargin,
right: 0,
height: height,
child: AnimatedOpacity(
opacity: isVisible ? 1 : 0,
duration: const Duration(milliseconds: 200),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius!),
color: Colors.white,
),
padding: EdgeInsets.only(left: height!).add(const EdgeInsets.all(8)),
child: _buildContent(),
),
),
);
}
Widget _buildContent() {
return Column(
children: <Widget>[
Text(title, style: const TextStyle(fontSize: 16)),
const SizedBox(height: 8),
Row(
children: <Widget>[
Text(
'1 ticket',
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 12,
color: Colors.grey.shade600,
),
),
const SizedBox(width: 8),
Text(
date,
style: const TextStyle(
fontWeight: FontWeight.w300,
fontSize: 12,
color: Colors.grey,
),
),
],
),
const Spacer(),
Row(
children: <Widget>[
Icon(Icons.place, color: Colors.grey.shade400, size: 16),
Text(
'Science Park 10 25A',
style: TextStyle(color: Colors.grey.shade400, fontSize: 13),
)
],
)
],
);
}
}
final List<Event> events = [
Event('steve-johnson.jpeg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'),
Event('efe-kurnaz.jpg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'),
Event('rodion-kutsaev.jpeg', 'Dawan District Guangdong Hong Kong', '4.28-31'),
];
class Event {
final String assetName;
final String title;
final String date;
Event(this.assetName, this.title, this.date);
}
class SheetHeader extends StatelessWidget {
final double? fontSize;
final double? topMargin;
const SheetHeader({Key? key, required this.fontSize, required this.topMargin})
: super(key: key);
@override
Widget build(BuildContext context) {
return Positioned(
top: topMargin,
child: Text(
'最近连接节点',
style: TextStyle(
color: Colors.grey[100],
fontSize: fontSize,
fontWeight: FontWeight.w500,
),
),
);
}
}
class MenuButton extends StatelessWidget {
const MenuButton({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Positioned(
right: 0,
bottom: 24,
child: Icon(
Icons.menu,
color: Colors.white,
size: 28,
),
);
}
}
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_colors.dart';
import 'package:chart/models/app_model.dart';
class SailAppBar extends AppBar {
SailAppBar({
Key? key,
required this.appTitle,
required this.backgroundColor,
}) : super(key: key);
final String appTitle;
final Color backgroundColor;
@override
SailAppBarState createState() => SailAppBarState();
}
class SailAppBarState extends State<SailAppBar> {
late AppModel _appModel;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_appModel = Provider.of<AppModel>(context);
}
@override
Widget build(BuildContext context) {
return AppBar(
title: Text(
widget.appTitle,
style: const TextStyle(
color: Color.fromRGBO(255, 255, 255, 1.00), fontSize: 16),
),
// rgba(246, 248, 247, 1.00)
backgroundColor: widget.backgroundColor,
// backgroundColor:
// _appModel.isOn ? AppColors.grayColor : AppColors.themeColor,
// shape: const RoundedRectangleBorder(
// borderRadius: BorderRadius.only(
// bottomRight: Radius.circular(25),
// bottomLeft: Radius.circular(25)),
// )
);
}
}
import 'package:flutter/material.dart';
// import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:chart/constant/app_colors.dart';
// import 'package:chart/models/server_model.dart';
import 'package:chart/models/user_model.dart';
import 'package:chart/utils/navigator_util.dart';
class SelectLocation extends StatefulWidget {
const SelectLocation({
Key? key,
}) : super(key: key);
@override
SelectLocationState createState() => SelectLocationState();
}
class SelectLocationState extends State<SelectLocation> {
// late ServerModel _serverModel;
late UserModel _userModel;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_userModel = Provider.of<UserModel>(context);
}
@override
Widget build(BuildContext context) {
// _serverModel = Provider.of<ServerModel>(context);
return Padding(
padding: EdgeInsets.symmetric(
vertical: 20, horizontal: ScreenUtil().setWidth(75)),
child: Material(
borderRadius: BorderRadius.circular(20),
color: Colors.yellow[600],
child: InkWell(
onTap: () => _userModel.checkHasLogin(
context, () => NavigatorUtil.goServerList(context)),
splashColor: Colors.grey,
borderRadius: BorderRadius.circular(20),
child: Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: AppColors.yellowColor.withAlpha(200),
blurRadius: 20,
spreadRadius: -6,
offset: const Offset(
0.0,
3.0,
),
)
]),
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 25),
child: Row(
children: [
// const Icon(MaterialCommunityIcons.server_network),
Padding(
padding: EdgeInsets.only(left: ScreenUtil().setWidth(10))),
// Text(
// _serverModel.selectServerEntity?.name ?? "选择连接节点",
// style: const TextStyle(
// fontSize: 15, fontWeight: FontWeight.bold),
// ),
Expanded(child: Container()),
const Icon(Icons.chevron_right)
],
),
),
),
),
);
}
}
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:chart/entity/plan_entity.dart';
import 'package:chart/models/user_model.dart';
import 'package:chart/service/plan_service.dart';
import 'package:chart/service/user_service.dart';
import 'package:chart/utils/navigator_util.dart';
class SlidingCardsView extends StatefulWidget {
const SlidingCardsView({Key? key}) : super(key: key);
@override
SlidingCardsViewState createState() => SlidingCardsViewState();
}
class SlidingCardsViewState extends State<SlidingCardsView> {
late PageController pageController;
double pageOffset = 0;
List<PlanEntity> _planEntityList = [];
@override
void initState() {
super.initState();
pageController = PageController(viewportFraction: 0.8);
pageController.addListener(() {
setState(() => pageOffset = pageController.page!);
});
// PlanService().plan()?.then((planEntityList) {
// setState(() {
// _planEntityList = planEntityList;
// });
// });
}
@override
void dispose() {
pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.55,
child: PageView(
controller: pageController,
children: List.from(_planEntityList.map((e) => SlidingCard(
id: e.id,
name: e.name,
date: e.createdAt?.toIso8601String(),
onetimePrice: (e.onetimePrice ?? 0.0) / 100,
monthPrice: (e.monthPrice ?? 0.0) / 100,
quarterPrice: (e.quarterPrice ?? 0.0) / 100,
halfYearPrice: (e.halfYearPrice ?? 0.0) / 100,
yearPrice: (e.yearPrice ?? 0.0) / 100,
twoYearPrice: (e.twoYearPrice) ?? 0.0 / 100,
threeYearPrice: (e.threeYearPrice) ?? 0.0 / 100,
assetName: 'steve-johnson.jpeg',
offset: pageOffset)))),
);
}
}
class SlidingCard extends StatelessWidget {
final int id;
final String name;
final String? date;
final String assetName;
final double offset;
final double onetimePrice;
final double monthPrice;
final double quarterPrice;
final double halfYearPrice;
final double yearPrice;
final double twoYearPrice;
final double threeYearPrice;
const SlidingCard({
Key? key,
required this.id,
required this.name,
required this.date,
required this.assetName,
required this.offset,
required this.onetimePrice,
required this.monthPrice,
required this.quarterPrice,
required this.halfYearPrice,
required this.yearPrice,
required this.twoYearPrice,
required this.threeYearPrice,
}) : super(key: key);
double lowestPrice() {
List<double> list = [
onetimePrice,
monthPrice,
quarterPrice,
halfYearPrice,
yearPrice,
twoYearPrice,
threeYearPrice,
];
double min = double.maxFinite;
for (int i = 0; i < list.length; i++) {
if ((list[i] < min) && list[i] > 0) {
min = list[i];
}
}
return min;
}
@override
Widget build(BuildContext context) {
double gauss = math.exp(-(math.pow((offset.abs() - 0.5), 2) / 0.08));
return Transform.translate(
offset: Offset(-32 * gauss * offset.sign, 0),
child: Card(
margin: const EdgeInsets.only(left: 8, right: 8, bottom: 24),
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(32)),
child: Column(
children: <Widget>[
ClipRRect(
borderRadius:
const BorderRadius.vertical(top: Radius.circular(32)),
child: Image.asset(
'assets/$assetName',
height: MediaQuery.of(context).size.height * 0.3,
alignment: Alignment(-offset.abs(), 0),
fit: BoxFit.none,
),
),
const SizedBox(height: 8),
Expanded(
child: CardContent(
id: id,
name: name,
date: date,
offset: gauss,
lowestPrice: lowestPrice(),
),
),
],
),
),
);
}
}
class CardContent extends StatefulWidget {
final int id;
final String name;
final String? date;
final double offset;
final double lowestPrice;
const CardContent(
{Key? key,
required this.id,
required this.name,
required this.date,
required this.offset,
required this.lowestPrice})
: super(key: key);
@override
CardContentState createState() => CardContentState();
}
class CardContentState extends State<CardContent> {
late UserModel _userModel;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_userModel = Provider.of<UserModel>(context);
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Transform.translate(
offset: Offset(8 * widget.offset, 0),
child: Text(widget.name, style: const TextStyle(fontSize: 20)),
),
const SizedBox(height: 8),
Transform.translate(
offset: Offset(32 * widget.offset, 0),
child: Text(
widget.date!,
style: const TextStyle(color: Colors.grey),
),
),
const Spacer(),
Row(
children: <Widget>[
Transform.translate(
offset: Offset(48 * widget.offset, 0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.yellow,
onPrimary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(32),
),
),
onPressed: () => {},
// onPressed: () => _userModel.checkHasLogin(
// context,
// () => UserService().getQuickLoginUrl({
// 'redirect': "/plan/${widget.id}"
// })?.then((value) {
// NavigatorUtil.goWebView(context, "配置订阅", value);
// })),
child: Transform.translate(
offset: Offset(24 * widget.offset, 0),
child: Text('购买',
style: TextStyle(
color: Colors.black87,
fontSize: ScreenUtil().setSp(36))),
),
),
),
const Spacer(),
Transform.translate(
offset: Offset(32 * widget.offset, 0),
child: Text(
${widget.lowestPrice} 起',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
const SizedBox(width: 16),
],
)
],
),
);
}
}
...@@ -8,6 +8,27 @@ packages: ...@@ -8,6 +8,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.13" version: "1.0.13"
alipay_kit:
dependency: "direct main"
description:
name: alipay_kit
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
alipay_kit_android:
dependency: transitive
description:
name: alipay_kit_android
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
alipay_kit_ios:
dependency: "direct main"
description:
name: alipay_kit_ios
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
animated_text_kit: animated_text_kit:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -141,6 +162,13 @@ packages: ...@@ -141,6 +162,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.7.0" version: "4.7.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
cookie_jar: cookie_jar:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -882,6 +910,13 @@ packages: ...@@ -882,6 +910,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.3" version: "2.1.3"
pointycastle:
dependency: "direct main"
description:
name: pointycastle
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.2"
process: process:
dependency: transitive dependency: transitive
description: description:
......
...@@ -111,6 +111,9 @@ dependencies: ...@@ -111,6 +111,9 @@ dependencies:
flutter_vibrate: ^1.3.0 flutter_vibrate: ^1.3.0
social_login_buttons: ^1.0.7 social_login_buttons: ^1.0.7
flutter_markdown: ^0.6.14 flutter_markdown: ^0.6.14
alipay_kit: 5.0.0
alipay_kit_ios: 5.0.0
pointycastle: ^3.1.1
# package:bubble/bubble.dart # package:bubble/bubble.dart
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment