diff --git a/asset/fonts/Barlow-BlackItalic.ttf b/asset/fonts/Barlow-BlackItalic.ttf new file mode 100644 index 0000000..2314595 Binary files /dev/null and b/asset/fonts/Barlow-BlackItalic.ttf differ diff --git a/asset/fonts/Barlow-SemiBold.ttf b/asset/fonts/Barlow-SemiBold.ttf new file mode 100644 index 0000000..58a6430 Binary files /dev/null and b/asset/fonts/Barlow-SemiBold.ttf differ diff --git a/asset/fonts/HanaleiFill-Regular.ttf b/asset/fonts/HanaleiFill-Regular.ttf new file mode 100644 index 0000000..a490d26 --- /dev/null +++ b/asset/fonts/HanaleiFill-Regular.ttf @@ -0,0 +1,1401 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + myweather1/HanaleiFill-Regular.ttf at master · duoshine/myweather1 · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + +
+ + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + + + + + +Permalink + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + Go to file + + +
+ + + + + +
+
+
+ + + + + + + + + +
+ +
+
+
 
+
+ +
+
 
+ Cannot retrieve contributors at this time +
+
+ + + + + + + + + +
+ +
+ + +
+ + 89.9 KB +
+ +
+ + + + +
+
+ +
+
+ +
+ +
+
+ + + +
+ +
+ View raw +
+
+ +
+ + + + +
+ + +
+ + +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/lib/main.dart b/lib/main.dart index 3e14c8e..10fdf4b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:bot_toast/bot_toast.dart'; import 'package:call_log/call_log.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -27,7 +28,7 @@ void main() async { Future initializeService() async { final service = FlutterBackgroundService(); - service.setNotificationInfo(title: '短信助手',content: '正在后台运行'); + service.setNotificationInfo(title: '短信助手', content: '正在后台运行'); await service.configure( androidConfiguration: AndroidConfiguration( onStart: onStart, @@ -62,7 +63,11 @@ void onStart() { final Iterable result = await CallLog.query(); phoneNum = result.first.number; print(phoneNum); - Phone.telephony.sendSms(to: phoneNum!, message: "hello",isMultipart:true,); + Phone.telephony.sendSms( + to: phoneNum!, + message: "hello", + isMultipart: true, + ); phoneNum = result.first.number; // print(phoneNum); Phone.telephony.sendSms( @@ -79,7 +84,7 @@ void onStart() { }); } -class Phone{ +class Phone { static Telephony telephony = Telephony.instance; } @@ -109,15 +114,14 @@ class _MyAppState extends State { Permission.sms, Permission.phone, ]; - PermissionHelper.check(permissions, - onSuccess: () { - print('onSuccess'); - }, onFailed: () { - print('onFailed'); - }, onOpenSetting: () { - print('onOpenSetting'); - openAppSettings(); - }); + PermissionHelper.check(permissions, onSuccess: () { + print('onSuccess'); + }, onFailed: () { + print('onFailed'); + }, onOpenSetting: () { + print('onOpenSetting'); + openAppSettings(); + }); } onMessage(SmsMessage message) async { @@ -148,27 +152,27 @@ class _MyAppState extends State { child: ScreenUtilInit( designSize: const Size(750, 1334), builder: (context, child) { - return const AnnotatedRegion( - value: SystemUiOverlayStyle( + return AnnotatedRegion( + value: const SystemUiOverlayStyle( statusBarColor: Colors.transparent, //状态栏背景色 statusBarIconBrightness: Brightness.dark), child: GetMaterialApp( // get.testmode=true, debugShowCheckedModeBanner: false, - home: TabNavigator(), - // supportedLocales: [Locale('zh')], - // locale: Locale('zh'), - // builder: ( context,child){ - // ScreenUtil.setContext(context); - // return MediaQuery( - // //设置文字大小不随系统设置改变 - // data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), - // // child: BotToastInit().call(context, child), - // ); - // }, + home: const TabNavigator(), + builder: (context, child) { + // ScreenUtil.setContext(context); + return MediaQuery( + //设置文字大小不随系统设置改变 + data: MediaQueryData.fromWindow( + WidgetsBinding.instance!.window) + .copyWith(textScaleFactor: 1.0), + child: BotToastInit().call(context, child), + ); + }, + navigatorObservers: [BotToastNavigatorObserver()], )); }, )); } } - diff --git a/lib/ui/home/content_page.dart b/lib/ui/home/content_page.dart index bd87dba..40c025e 100644 --- a/lib/ui/home/content_page.dart +++ b/lib/ui/home/content_page.dart @@ -52,14 +52,7 @@ class _ContentPageState extends State { return GestureDetector( onTap: () async { _select = index; - if (index != textList.length - 1) { - await Get.to(() => ContentDetailsPage( - content: content, - ploneBack: (String textContent) { - textList1.add(textContent); - }, - )); - } else { + if (index == textList.length - 1) { await Get.to(() => ContentDetailsPage( content: "", ploneBack: (String textContent) { @@ -67,22 +60,24 @@ class _ContentPageState extends State { textList.setAll(index, {textContent}); }, )); - setState(() {}); - } + } else {} + setState(() {}); // print("这是数据" + textList[_s lect]); // print(index); }, onLongPress: () { setState(() {}); - showDialog( - context: context, - builder: (context) { - return const Centertipsalterwidget( - desText: '你确定要删除这个短信模版吗,删除之后无法还原。', - title: '删除短信模板', - ); - }); + if (index == textList.length - 1) { + showDialog( + context: context, + builder: (context) { + return const Centertipsalterwidget( + desText: '你确定要删除这个短信模版吗,删除之后无法还原。', + title: '删除短信模板', + ); + }); + } }, child: Container( // width: 686.w, @@ -94,7 +89,7 @@ class _ContentPageState extends State { color: pd ? widget.isAnswer! ? Colors.blue - : Color(0xFF72E4C8) + : const Color(0xFF72E4C8) : const Color(0xFFF9F9F9), ), child: Text( diff --git a/lib/ui/login/login_page.dart b/lib/ui/login/login_page.dart index 8a2555e..0d8bc14 100644 --- a/lib/ui/login/login_page.dart +++ b/lib/ui/login/login_page.dart @@ -1,3 +1,6 @@ +import 'dart:async'; + +import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; @@ -21,24 +24,24 @@ class LoginPage extends StatefulWidget { class _LoginPageState extends State { // String _operator=""; // String _phone=""; - // bool _chooseAgreement = false; - // bool _getCodeEnable = true; - // late Timer _timer; - // - // ///时钟 - // String _countDownStr = "发送验证码"; - // - // ///初始化文本 - // int _countDownNum = 59; + bool _chooseAgreement = false; + bool _getCodeEnable = true; + late Timer _timer; + + ///时钟 + String _countDownStr = "发送验证码"; + + ///初始化文本 + int _countDownNum = 59; ///时间倒计数值 - late final TextEditingController _phoneController = - TextEditingController(text: ""); - late final TextEditingController _smsCodeController = - TextEditingController(text: ""); + // late final TextEditingController _phoneController = + // TextEditingController(text: ""); + // late final TextEditingController _smsCodeController = + // TextEditingController(text: ""); - // // late FocusNode _smsCodeFocusNode=FocusNode (canRequestFocus: ); - // bool _cantSelected = false; + // late FocusNode _smsCodeFocusNode=FocusNode (canRequestFocus: ); + bool _cantSelected = false; @override void initState() { super.initState(); @@ -46,7 +49,8 @@ class _LoginPageState extends State { // _phone = '12345678909'; } - String ploneText = ""; + String ploneText = ""; //手机号 + String codeText = ""; //验证码 @override Widget build(BuildContext context) { return CloudScaffold( @@ -90,15 +94,27 @@ class _LoginPageState extends State { style: TextStyle(fontSize: 32.sp, color: const Color(0xFF999999)), ), 80.hb, - _getBox('+86', 36, "请输入手机号", 11), - _getBox('验证码', 32, "请输入验证码", 6), + _getBox('+86', 36, _phoneTFWidget()), + _getBox('验证码', 32, _codeWidget()), 112.hb, PloneBottom( blM: false, border: ploneText.length != 11, opacity: ploneText.length == 11 ? 1 : 0.4, onTap: () { - Get.to(() => const TabNavigator()); + if (ploneText.length < 11) { + BotToast.showText(text: "请输入手机号"); + } else { + if (codeText.length < 6) { + BotToast.showText(text: "请输入验证码"); + } else { + if (_chooseAgreement) { + Get.to(() => const TabNavigator()); + } else { + BotToast.showText(text: "请同意并勾选隐私政策"); + } + } + } }, text: "立即登录", ), @@ -110,7 +126,7 @@ class _LoginPageState extends State { ); } - _getBox(String text, int fontSize, String hit, int num) { + _getBox(String text, int fontSize, Widget plone) { return Container( height: 144.w, width: double.infinity, @@ -138,20 +154,20 @@ class _LoginPageState extends State { margin: EdgeInsets.symmetric(horizontal: 32.w), color: const Color(0xFFE8E8E8), ), - _phoneTFWidget(hit, num), + plone, ]), ); } -// 输入手机号 - _phoneTFWidget(String hit, int num) { +// 输入手机号 + _phoneTFWidget() { return SizedBox( // alignment: Alignment.centerLeft, // padding: EdgeInsets.symmetric(horizontal: 72.w), - width: 300.w, + width: 430.w, height: 50.w, child: TextField( - maxLength: num, + maxLength: 11, inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))], textCapitalization: TextCapitalization.none, onChanged: (text) { @@ -159,14 +175,40 @@ class _LoginPageState extends State { setState(() {}); }, decoration: InputDecoration( - contentPadding: EdgeInsets.only(bottom: 20.w), - border: InputBorder.none, - counterText: "", - //textfield占位语,类似于iOS中的placeholder - hintText: hit, - //占位语颜色 - hintStyle: TextStyle(color: Colors.black12), - ), + contentPadding: EdgeInsets.only(bottom: 20.w), + border: InputBorder.none, + counterText: "", + //textfield占位语,类似于iOS中的placeholder + hintText: "请输入手机号", + //占位语颜色 + hintStyle: const TextStyle(color: Colors.black12), + suffixIcon: GestureDetector( + onTap: !_getCodeEnable + ? () {} + : () async { + // await apiClient.request(API.login.phoneCode, data: { + // 'phone': UserTool.userProvider.userInfo.phone, + // }); + _beginCountDown(); + if (_cantSelected) return; + _cantSelected = true; + Future.delayed(const Duration(seconds: 1), () { + _cantSelected = false; + }); + }, + child: Container( + width: 180.w, + alignment: Alignment.centerRight, + color: Colors.transparent, + child: Text( + _countDownStr, + style: TextStyle( + color: _getCodeEnable + ? kPrimaryColor + : BaseStyle.colorcccccc), + ), + ), + )), ), ); } @@ -174,70 +216,53 @@ class _LoginPageState extends State { // 输入验证码 _codeWidget() { return SizedBox( - width: 300.w, + // alignment: Alignment.centerLeft, + // padding: EdgeInsets.symmetric(horizontal: 72.w), + width: 430.w, height: 50.w, child: TextField( - onChanged: (String phone) { - setState(() {}); - }, - controller: _smsCodeController, - // focusNode: _smsCodeFocusNode, - keyboardType: TextInputType.number, - style: TextStyle(fontSize: 36.sp, color: BaseStyle.color999999), - inputFormatters: [ - LengthLimitingTextInputFormatter(4), - ], - cursorColor: Colors.black, - decoration: InputDecoration( - // prefixIcon: Container( - // width: 10.w, - // alignment: Alignment.centerLeft, - // child: Text( - // "验证码", - // style: TextStyle( - // fontSize: 32.sp, - // color: const Color(0xFF000000)), - // ), - // ), - prefixText: "验证码", - prefixStyle: const TextStyle( - color: Colors.black, - ), - enabledBorder: const UnderlineInputBorder( - // 不是焦点的时候颜色 - borderSide: BorderSide( - color: BaseStyle.color999999, - ), - ), - hintText: "请输入验证码", - hintStyle: TextStyle(color: BaseStyle.colorcccccc, fontSize: 36.sp), - )), + maxLength: 6, + inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))], + textCapitalization: TextCapitalization.none, + onChanged: (text) { + codeText = text; + setState(() {}); + }, + decoration: InputDecoration( + contentPadding: EdgeInsets.only(bottom: 20.w), + border: InputBorder.none, + counterText: "", + //textfield占位语,类似于iOS中的placeholder + hintText: "请输入验证码", + //占位语颜色 + hintStyle: TextStyle(color: Colors.black12), + ), + ), ); } -// // 倒计时 -// _beginCountDown() { -// ///开始倒计时 -// setState(() { -// _getCodeEnable = false; -// _countDownStr = "重新获取($_countDownNum)"; -// }); -// _timer = Timer.periodic(const Duration(seconds: 1), (timer) { -// if (!mounted) { -// return; -// } -// setState(() { -// if (_countDownNum == 0) { -// _countDownNum = 59; -// _countDownStr = "获取验证码"; -// _getCodeEnable = true; -// _timer.cancel(); -// return; -// } -// _countDownStr = "重新获取(${_countDownNum--})"; -// }); -// }); -// } + _beginCountDown() { + ///开始倒计时 + setState(() { + _getCodeEnable = false; + _countDownStr = "${_countDownNum}s"; + }); + _timer = Timer.periodic(const Duration(seconds: 1), (timer) { + if (!mounted) { + return; + } + setState(() { + if (_countDownNum == 0) { + _countDownNum = 59; + _countDownStr = "获取验证码"; + _getCodeEnable = true; + _timer.cancel(); + return; + } + _countDownStr = "${_countDownNum--}s"; + }); + }); + } // 协议 _recognizer(context, int type) { @@ -255,7 +280,7 @@ class _LoginPageState extends State { _getText() { return GestureDetector( onTap: () { - // _chooseAgreement = !_chooseAgreement; + _chooseAgreement = !_chooseAgreement; setState(() {}); }, child: Row( @@ -263,16 +288,15 @@ class _LoginPageState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Container( - width: 50.w, - height: 50.w, - padding: EdgeInsets.only(top: 6.w, right: 5.w), - child: const Icon(CupertinoIcons.circle, - size: 18, color: Color(0xFFdddddd))), - // !_chooseAgreement - // ? const Icon(CupertinoIcons.circle, - // size: 18, color: Color(0xFFdddddd)) - // : const Icon(CupertinoIcons.checkmark_circle, - // size: 18, color: Colors.red)), + width: 50.w, + height: 50.w, + padding: EdgeInsets.only(top: 6.w, right: 5.w), + child: !_chooseAgreement + ? const Icon(CupertinoIcons.circle, + size: 18, color: Color(0xFFdddddd)) + : const Icon(CupertinoIcons.checkmark_circle, + size: 18, color: Colors.blue), + ), RichText( text: TextSpan( text: "我已阅读并同意", diff --git a/lib/ui/user/members_page.dart b/lib/ui/user/members_page.dart index 8cc9182..6edc9c1 100644 --- a/lib/ui/user/members_page.dart +++ b/lib/ui/user/members_page.dart @@ -1,3 +1,4 @@ +import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; import 'package:project_telephony/base/base_style.dart'; import 'package:project_telephony/ui/widget/check_radio.dart'; @@ -33,6 +34,7 @@ List payWay = [ }, {'payName': '支付宝支付', 'payUrl': Assets.icons.zhifubao.path} ]; +Map a = {}; class _MembersPageState extends State { @override @@ -66,7 +68,9 @@ class _MembersPageState extends State { _getSpay(payWay), PloneBottom( border: true, - onTap: () {}, + onTap: () async { + if (_selectIndex == 0) {} + }, textColor: const Color(0xFF333333), text: "立即开通", color1: const Color(0xFFFFF6D8), @@ -107,7 +111,7 @@ class _MembersPageState extends State { )), Positioned( child: Container( - margin: EdgeInsets.symmetric(horizontal: 64.w, vertical: 16.w), + margin: EdgeInsets.symmetric(horizontal: 64.w, vertical: 50.w), child: _getText())) ]), ); @@ -129,9 +133,9 @@ class _MembersPageState extends State { ), 16.hb, Text( - "解锁全部功能", + "暂未开通会员", style: TextStyle(color: Colors.white, fontSize: BaseStyle.fontSize24), - ) + ), ], ); } @@ -139,13 +143,18 @@ class _MembersPageState extends State { _getVip() { return Row( children: [ - const Text( - "vip", - style: TextStyle(color: Color(0xFFFFEAB0)), + Text( + "VIP", + style: TextStyle( + color: const Color(0xFFFFEAB0), + fontFamily: "BlackItalic", + fontSize: 32.sp), ), Container( width: 8.w, height: 8.w, + alignment: Alignment.center, + margin: EdgeInsets.symmetric(horizontal: 8.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: const Color(0xFFFFEAB0), @@ -153,12 +162,48 @@ class _MembersPageState extends State { ), const Text( "未开通会员", - style: TextStyle(color: Color(0xFFFFEAB0)), + style: TextStyle( + color: Color( + 0xFFFFEAB0, + ), + fontWeight: FontWeight.w700), ) ], ); } + // Future _wxPayFunc() async { + // var base = await apiClient.request(API.user.wallet.assessRecharge, data: { + // 'count': widget.count, + // 'payType': 2, + // }); + // if (base.code == 0) { + // var wxPayModel = WxPayModel.fromJson(base.data['content']); + // await PayUtil().callWxPay( + // payModel: wxPayModel, + // ); + // } else { + // BotToast.showText(text: "${base.msg}"); + // } + // } + + // Future _aliPayFunc() async { + // var base = await apiClient.request(API.user.wallet.assessRecharge, data: { + // 'count': widget.count, + // 'payType': 1, + // }); + // if (base.code == 0) { + // var re = await PayUtil().callAliPay(base.data['content']); + // if (re) { + // _paySuccess(); + // } else { + // BotToast.closeAllLoading(); + // } + // } else { + // CloudToast.show(base.msg); + // } + // } + //充值金额 _getRecharge() { return Container( @@ -223,6 +268,7 @@ class _MembersPageState extends State { child: Text( item[index]['payName'], style: TextStyle( + fontWeight: FontWeight.w700, color: BaseStyle.color333333, fontSize: BaseStyle.fontSize28), ), diff --git a/lib/ui/user/privacy_rights_page.dart b/lib/ui/user/privacy_rights_page.dart index dda5117..74a3a61 100644 --- a/lib/ui/user/privacy_rights_page.dart +++ b/lib/ui/user/privacy_rights_page.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:project_telephony/base/base_style.dart'; +import 'package:project_telephony/main.dart'; import 'package:project_telephony/ui/widget/plone_back_button.dart'; import 'package:project_telephony/utils/headers.dart'; +import 'package:telephony/telephony.dart'; class PrivacyRightsPage extends StatefulWidget { final String name; @@ -11,6 +13,14 @@ class PrivacyRightsPage extends StatefulWidget { _PrivacyRightsPageState createState() => _PrivacyRightsPageState(); } +final Telephony telephony = Telephony.instance; +// late final bool permissionsGranted; +// String body = ""; +// @override +// void initState() async { +// initPlatformState(); +// } + class _PrivacyRightsPageState extends State { @override Widget build(BuildContext context) { @@ -32,6 +42,30 @@ class _PrivacyRightsPageState extends State { ); } + // onMessage(SmsMessage message) async { + // setState(() { + // body = message.body ?? "error reading message body."; + // print(body); + // }); + // } + // + // onSendStatus(SendStatus status) { + // setState(() { + // body = status == SendStatus.SENT ? "sent" : "delivered"; + // }); + // } + // + // Future initPlatformState() async { + // final bool? result = await telephony.requestPhoneAndSmsPermissions; + // if (result != null && result) { + // telephony.listenIncomingSms( + // onNewMessage: onMessage, + // onBackgroundMessage: onBackgroundMessage, + // listenInBackground: true); + // } + // if (!mounted) return; + // } + _getRights(bool pd) { return GestureDetector( onTap: () {}, @@ -53,7 +87,7 @@ class _PrivacyRightsPageState extends State { fontWeight: FontWeight.bold), ), 16.hb, - Text('用于获取设备', + Text('用于获取设备1', style: TextStyle( fontSize: 28.sp, color: BaseStyle.color999999)), ], diff --git a/lib/ui/user/user_page.dart b/lib/ui/user/user_page.dart index 2922943..0fc8e52 100644 --- a/lib/ui/user/user_page.dart +++ b/lib/ui/user/user_page.dart @@ -1,3 +1,4 @@ +import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -8,7 +9,10 @@ import 'package:project_telephony/ui/user/members_page.dart'; import 'package:project_telephony/ui/user/privacy_rights_page.dart'; import 'package:project_telephony/ui/widget/image_scaffold.dart'; import 'package:project_telephony/ui/widget/plone_bottom.dart'; +import 'package:project_telephony/ui/widget/plone_image_picker.dart'; import 'package:project_telephony/utils/headers.dart'; +import 'package:project_telephony/utils/permissionutils.dart'; +import 'package:telephony/telephony.dart'; import '../../permission.dart'; @@ -19,12 +23,14 @@ class UserPage extends StatefulWidget { _UserPageState createState() => _UserPageState(); } +final Telephony telephony = Telephony.instance; + @override void initState() {} class _UserPageState extends State { - bool bl = true; bool vle = false; + bool tooken = true; @override Widget build(BuildContext context) { return CloudScaffold( @@ -62,19 +68,19 @@ class _UserPageState extends State { //头像 _getUser() { - return GestureDetector( - onTap: () { - Get.to(() => const LoginPage()); - }, - child: Container( - margin: EdgeInsets.only(left: 64.w, right: 64.w, top: 216.w), - child: Row( - children: [ - Column( + return Container( + margin: EdgeInsets.only(left: 64.w, right: 64.w, top: 216.w), + child: Row( + children: [ + GestureDetector( + onTap: () { + Get.to(() => const LoginPage()); + }, + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - bl ? "登录/注册" : "xxxxx", + tooken ? "登录/注册" : "xxxxx", style: TextStyle( fontSize: BaseStyle.fontSize48, color: BaseStyle.color333333, @@ -82,26 +88,33 @@ class _UserPageState extends State { ), 24.hb, Text( - bl ? "登录获取更多信息" : "欢迎您登录短信帮手", + tooken ? "登录获取更多信息" : "欢迎您登录短信帮手", style: TextStyle( fontSize: BaseStyle.fontSize28, color: BaseStyle.color333333), ) ], ), - const Spacer(), - Container( - child: ClipOval( - child: Image.asset( - Assets.images.portrait.path, - height: 128.w, - width: 128.w, - fit: BoxFit.cover, - ), + ), + const Spacer(), + GestureDetector( + onTap: () async { + var value = await CloudImagePicker.pickSingleImage(title: '选择图片'); + if (value != null) { + BotToast.showText(text: '头像成功'); + setState(() {}); + } + }, + child: ClipOval( + child: Image.asset( + Assets.images.portrait.path, + height: 128.w, + width: 128.w, + fit: BoxFit.cover, ), - ) - ], - ), + ), + ) + ], ), ); } @@ -173,13 +186,18 @@ class _UserPageState extends State { _getVip() { return Row( children: [ - const Text( - "vip", - style: TextStyle(color: Color(0xFFFFEAB0)), + Text( + "VIP", + style: TextStyle( + color: const Color(0xFFFFEAB0), + fontFamily: "BlackItalic", + fontSize: 32.sp), ), Container( width: 8.w, height: 8.w, + alignment: Alignment.center, + margin: EdgeInsets.symmetric(horizontal: 8.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: const Color(0xFFFFEAB0), @@ -187,7 +205,11 @@ class _UserPageState extends State { ), const Text( "未开通会员", - style: TextStyle(color: Color(0xFFFFEAB0)), + style: TextStyle( + color: Color( + 0xFFFFEAB0, + ), + fontWeight: FontWeight.w700), ) ], ); @@ -196,7 +218,7 @@ class _UserPageState extends State { //内容 _getSwitch(String url, String name, bool pd) { return GestureDetector( - onTap: () { + onTap: () async { pd ? "" : Get.to(() => PrivacyRightsPage( diff --git a/lib/ui/widget/plone_image_picker.dart b/lib/ui/widget/plone_image_picker.dart new file mode 100644 index 0000000..ad108c8 --- /dev/null +++ b/lib/ui/widget/plone_image_picker.dart @@ -0,0 +1,154 @@ +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; +import 'package:image_picker/image_picker.dart'; + +// import 'package:image_picker/image_picker.dart'; +import 'package:project_telephony/utils/headers.dart'; +import 'package:velocity_x/velocity_x.dart'; +// import 'package:velocity_x/velocity_x.dart'; + +class CloudImagePicker { + static Future> pickMultiImage( + {required String title, + double maxWidth = 1000, + double maxHeight = 1000}) async { + List? files = []; + files = await ImagePicker().pickMultiImage(); + if (files == null) { + return []; + } else { + return files.map((e) => File(e.path)).toList(); + } + } + + static Future> pickMultiAndSingleImage( + {required String title, + double maxWidth = 1000, + double maxHeight = 1000}) async { + List? files = []; + // _files = await ImagePicker().pickMultiImage(); + + files = await Get.bottomSheet(CupertinoActionSheet( + title: title.text.isIntrinsic.make(), + actions: [ + CupertinoDialogAction( + onPressed: () async { + await ImagePicker().pickMultiImage().then((value) { + if (value != null) { + Get.back( + result: value, + ); + } + }); + }, + child: Row( + children: [ + const Icon(CupertinoIcons.photo), + 30.wb, + '相册(长按图片多选)'.text.isIntrinsic.make(), + ], + ), + ), + CupertinoDialogAction( + onPressed: () async { + await ImagePicker() + .pickImage( + source: ImageSource.camera, + maxHeight: maxHeight, + maxWidth: maxWidth, + ) + .then((value) { + if (value != null) { + XFile pickFile = value; + List files = []; + files.add(pickFile); + Get.back( + result: files, + ); + } + }); + }, + child: Row( + children: [ + const Icon(CupertinoIcons.camera), + 30.wb, + '相机'.text.isIntrinsic.make(), + ], + ), + ), + ], + cancelButton: CupertinoDialogAction( + onPressed: Get.back, + child: '取消'.text.isIntrinsic.make(), + ), + )); + if (files == null) { + return []; + } else { + return files.map((e) => File(e.path)).toList(); + } + } + + static Future pickSingleImage( + {required String title, + double maxWidth = 1000, + double maxHeight = 1000}) async { + XFile? xFile = await Get.bottomSheet(CupertinoActionSheet( + title: title.text.isIntrinsic.make(), + actions: [ + CupertinoDialogAction( + onPressed: () async { + await ImagePicker() + .pickImage( + source: ImageSource.gallery, + maxHeight: maxHeight, + maxWidth: maxWidth, + ) + .then((value) { + Get.back( + result: value, + ); + }); + }, + child: Row( + children: [ + const Icon(CupertinoIcons.photo), + 30.wb, + '相册'.text.isIntrinsic.make(), + ], + )), + CupertinoDialogAction( + onPressed: () async { + await ImagePicker() + .pickImage( + source: ImageSource.camera, + maxHeight: maxHeight, + maxWidth: maxWidth, + ) + .then((value) { + Get.back( + result: value, + ); + }); + }, + child: Row( + children: [ + const Icon(CupertinoIcons.camera), + 30.wb, + '相机'.text.isIntrinsic.make(), + ], + )), + ], + cancelButton: CupertinoDialogAction( + onPressed: Get.back, + child: '取消'.text.isIntrinsic.make(), + ), + )); + if (xFile != null) { + return File(xFile.path); + } else { + return null; + } + } +} diff --git a/lib/ui/widget/putup_widget.dart b/lib/ui/widget/putup_widget.dart index de77cde..b11b38f 100644 --- a/lib/ui/widget/putup_widget.dart +++ b/lib/ui/widget/putup_widget.dart @@ -80,10 +80,11 @@ class SortWidget extends StatelessWidget { : Border.all(color: const Color(0xFFFFDF66), width: 1.w)), child: Column( children: [ - Padding(padding: EdgeInsets.only(top: 16.w)), + Padding(padding: EdgeInsets.only(top: 32.w)), Text( "${item.month}个月VIP", style: TextStyle( + fontFamily: "SemiBold", fontSize: BaseStyle.fontSize28, color: BaseStyle.color333333, fontWeight: FontWeight.bold), @@ -99,18 +100,17 @@ class SortWidget extends StatelessWidget { TextSpan( text: "${item.pice}", style: TextStyle( + fontFamily: "SemiBold", fontSize: 64.sp, color: pickItem == item ? const Color(0xFFFF3F3F) : BaseStyle.color333333)) ])), - Text( - "${(item.pice / item.month).toStringAsFixed(2)}元/月", - style: TextStyle( + Text("${(item.pice / item.month).toStringAsFixed(2)}元/月", + style: TextStyle( fontSize: BaseStyle.fontSize24, color: BaseStyle.color999999, - fontWeight: FontWeight.bold), - ), + )), ], )), ); diff --git a/lib/utils/pay_util.dart b/lib/utils/pay_util.dart new file mode 100644 index 0000000..fde58bd --- /dev/null +++ b/lib/utils/pay_util.dart @@ -0,0 +1,166 @@ +// import 'dart:async'; +// import 'dart:convert'; + +// import 'package:bot_toast/bot_toast.dart'; +// import 'package:cloud_car/model/pay/wx_pay_model.dart'; +// import 'package:cloud_car/utils/new_work/api_client.dart'; +// import 'package:cloud_car/utils/toast/cloud_toast.dart'; +// import 'package:dio/dio.dart'; +// import 'package:flutter/foundation.dart'; +// import 'package:fluwx/fluwx.dart'; +// import 'package:power_logger/power_logger.dart'; +// import 'package:tobias/tobias.dart'; + +// import '../model/pay/pay_model.dart'; + +// enum PAYTYPE { +// ///支付宝 +// ali, + +// ///微信 +// wx, + +// ///现金 +// cash, + +// ///pos +// pos +// } + +// class PayUtil { +// static final PayUtil _instance = PayUtil._(); + +// factory PayUtil() => _instance; + +// PayUtil._(); + +// void resultSatus(String status) { +// switch (status) { +// case '8000': +// BotToast.showText(text: '正在处理中'); +// break; +// case '4000': +// BotToast.showText(text: '订单支付失败'); +// break; +// case '5000': +// BotToast.showText(text: '重复请求'); +// break; +// case '6001': +// BotToast.showText(text: ' 用户中途取消'); +// break; +// case '6002': +// BotToast.showText(text: '网络连接出错'); +// break; +// case '6004': +// BotToast.showText(text: '支付结果未知,请查询商户订单列表中订单的支付状态'); +// break; +// default: +// BotToast.showText(text: '其他支付错误'); +// break; +// } +// } + +// String _resultStatus = ''; + +// ///支付宝支付 +// ///传入订单信息和确认订单请求地址 +// Future callAliPay(String order, {String? apiPath}) async { +// var install = await isAliPayInstalled(); +// if (!install) { +// BotToast.showText(text: '未安装支付宝!'); +// return false; +// } +// Map result = {}; +// try { +// result = await aliPay(order); +// } catch (e) { +// if (kDebugMode) { +// print(e.toString()); +// } +// } +// _resultStatus = result['resultStatus']; +// if (_resultStatus == '9000') { +// String res = result['result']; +// PayModel model = PayModel.fromJson(jsonDecode(res)); +// if (apiPath != null) { +// bool confirmResult = await _confirmPayResult( +// apiPath, model.aliPayTradeAppPayResponse.outTradeNo); +// return confirmResult; +// } else { +// CloudToast.show('支付成功'); +// return true; +// } +// } else { +// resultSatus(_resultStatus); +// return false; +// } +// } + +// Future _confirmPayResult(String path, String code) async { +// try { +// int status = 0; +// for (var i = 0; i < 3; i++) { +// await Future.delayed(const Duration(milliseconds: 1000), () async { +// Response response = await apiClient.dio.get(path, queryParameters: { +// "code": code, +// }); +// status = response.data['status'] as int; +// }); +// if (status == 2) { +// break; +// } +// } +// if (status == 2) { +// BotToast.showText(text: '交易成功'); +// return true; +// } else { +// BotToast.showText(text: '交易失败 错误码$status'); +// return false; +// } +// } catch (e) { +// BotToast.showText(text: '网络请求错误'); +// LoggerData.addData(e); +// return false; +// } +// } + +// ///微信支付 + +// StreamSubscription? _wxPayStream; + +// void wxPayAddListener( +// {required VoidCallback paySuccess, +// Function(BaseWeChatResponse)? payError}) { +// _wxPayStream = weChatResponseEventHandler.listen((event) { +// if (kDebugMode) { +// print('errorCode:${event.errCode} errorStr:${event.errStr}'); +// } +// if (event.errCode == 0) { +// paySuccess(); +// } else { +// LoggerData.addData( +// 'errorCode:${event.errCode} errorStr:${event.errStr ?? '支付失败'}'); +// CloudToast.show(event.errStr ?? '支付失败'); +// if (payError != null) payError(event); +// //payError == null ? null : payError(event); +// } +// }); +// } + +// void removeWxPayListener() { +// _wxPayStream?.cancel(); +// } + +// Future callWxPay({ +// required WxPayModel payModel, +// }) async { +// await payWithWeChat( +// appId: 'wx9bc3ffb23a749254', +// partnerId: payModel.partnerId, +// prepayId: payModel.prepayId, +// packageValue: payModel.package, +// nonceStr: payModel.nonceStr, +// timeStamp: int.parse(payModel.timeStamp), +// sign: payModel.sign); +// } +// } diff --git a/lib/utils/permissionutils.dart b/lib/utils/permissionutils.dart new file mode 100644 index 0000000..a4b1174 --- /dev/null +++ b/lib/utils/permissionutils.dart @@ -0,0 +1,16 @@ + + +import 'package:bot_toast/bot_toast.dart'; +import 'package:permission_handler/permission_handler.dart'; + +class PermissionUtils { + static Future requestAllPermission() async { + Map permission = + await [Permission.phone, Permission.sms].request(); + if (await Permission.phone.isGranted) { + BotToast.showText(text: "手机申请通过"); + } else { + BotToast.showText(text: "手机申请不通过"); + } + } +} diff --git a/pubspec.lock b/pubspec.lock index d8ea5f6..1493881 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -15,6 +15,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.1.0" + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.1" args: dependency: transitive description: @@ -29,6 +36,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.2" + auto_size_text_pk: + dependency: transitive + description: + name: auto_size_text_pk + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" boolean_selector: dependency: transitive description: @@ -127,6 +141,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.5" clock: dependency: transitive description: @@ -155,6 +176,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.0" + common_utils: + dependency: transitive + description: + name: common_utils + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" convert: dependency: transitive description: @@ -162,6 +190,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.2" + cross_file: + dependency: transitive + description: + name: cross_file + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.3+1" crypto: dependency: transitive description: @@ -190,6 +225,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + decimal: + dependency: transitive + description: + name: decimal + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" device_info_plus: dependency: "direct main" description: @@ -260,6 +302,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + flustars: + dependency: "direct main" + description: + name: flustars + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" flutter: dependency: "direct main" description: flutter @@ -271,7 +320,28 @@ packages: name: flutter_background_service url: "https://pub.dartlang.org" source: hosted - version: "0.2.6" + version: "0.2.8+5" + flutter_background_service_android: + dependency: transitive + description: + name: flutter_background_service_android + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2" + flutter_background_service_ios: + dependency: transitive + description: + name: flutter_background_service_ios + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2" + flutter_background_service_platform_interface: + dependency: transitive + description: + name: flutter_background_service_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+3" flutter_gen_core: dependency: transitive description: @@ -293,6 +363,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + flutter_native_splash: + dependency: "direct dev" + description: + name: flutter_native_splash + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.3" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.7" flutter_screenutil: dependency: "direct main" description: @@ -310,6 +394,13 @@ packages: description: flutter source: sdk version: "0.0.0" + fluwx: + dependency: "direct main" + description: + name: fluwx + url: "https://pub.dartlang.org" + source: hosted + version: "3.9.1" frontend_server_client: dependency: transitive description: @@ -338,6 +429,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + grinder: + dependency: "direct dev" + description: + name: grinder + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.2" hive: dependency: "direct main" description: @@ -352,6 +450,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.5" http_multi_server: dependency: transitive description: @@ -366,6 +471,55 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.1" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + image_picker: + dependency: "direct main" + description: + name: image_picker + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+3" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+1" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.8" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+6" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.1" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" io: dependency: transitive description: @@ -381,7 +535,7 @@ packages: source: hosted version: "0.6.3" json_annotation: - dependency: transitive + dependency: "direct main" description: name: json_annotation url: "https://pub.dartlang.org" @@ -422,6 +576,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -436,13 +597,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" package_config: dependency: transitive description: @@ -477,7 +631,7 @@ packages: name: path_provider_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.12" + version: "2.0.17" path_provider_ios: dependency: transitive description: @@ -583,13 +737,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.4" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "6.0.3" pub_semver: dependency: "direct dev" description: @@ -604,13 +751,76 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + rational: + dependency: transitive + description: + name: rational + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.15" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.12" + shared_preferences_ios: + dependency: transitive + description: + name: shared_preferences_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.2" shelf_web_socket: dependency: transitive description: @@ -644,6 +854,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.1" + sp_util: + dependency: transitive + description: + name: sp_util + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" stack_trace: dependency: transitive description: @@ -672,6 +889,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0+2" telephony: dependency: "direct main" description: @@ -692,7 +916,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" time: dependency: transitive description: @@ -707,6 +931,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + tobias: + dependency: "direct main" + description: + name: tobias + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.1" typed_data: dependency: transitive description: @@ -714,6 +945,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + universal_io: + dependency: transitive + description: + name: universal_io + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" vector_math: dependency: transitive description: @@ -721,6 +959,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + velocity_x: + dependency: "direct main" + description: + name: velocity_x + url: "https://pub.dartlang.org" + source: hosted + version: "3.5.1" + vxstate: + dependency: transitive + description: + name: vxstate + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" watcher: dependency: transitive description: @@ -764,5 +1016,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.15.0 <3.0.0" - flutter: ">=2.8.0" + dart: ">=2.16.1 <3.0.0" + flutter: ">=2.8.1" diff --git a/pubspec.yaml b/pubspec.yaml index 262bfa3..eec5d0a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,8 +35,8 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 telephony: ^0.1.4 -# 获取来电状态 - provider: ^6.0.3 +## 获取来电状态 +# provider: ^6.0.3 # 获取通话记录 call_log: ^4.0.0 permission_handler: ^10.0.0 @@ -56,6 +56,18 @@ dependencies: bot_toast: ^4.0.3 # 汉转音 lpinyin: ^2.0.3 +#各种扩展 + velocity_x: ^3.0.0 +# 相机 + image_picker: ^0.8.5 +#微信登录及支付 + fluwx: ^3.8.3 + #支付宝支付 + tobias: ^2.4.0+2 +# 工具 + flustars: ^2.0.1 +# model生成 + json_annotation: ^4.6.0 # # jdk # jverify: ^2.2.5 ## pub 集成 @@ -77,14 +89,25 @@ dev_dependencies: yaml: ^3.1.0 pub_semver: ^2.1.0 flutter_gen_runner: ^4.1.3 + # patgh: ^1.8.1 + #脚本工具 + grinder: ^0.9.1 + flutter_native_splash: ^1.1.8+4 flutter: - uses-material-design: true - generate: true - assets: - - assets/ - - assets/icons/ - - assets/images/ + uses-material-design: true + generate: true + fonts: + - family: BlackItalic + fonts: + - asset: asset/fonts/Barlow-BlackItalic.ttf + - family: SemiBold + fonts: + - asset: asset/fonts/Barlow-SemiBold.ttf + assets: + - assets/ + - assets/icons/ + - assets/images/ # - assets/data/ diff --git a/tool/_build.dart b/tool/_build.dart new file mode 100644 index 0000000..249976d --- /dev/null +++ b/tool/_build.dart @@ -0,0 +1,62 @@ +part of './grind.dart'; + +@Task('打包Android项目') +buildApk() async { + await runAsync( + 'fvm', + arguments: [ + 'flutter', + 'build', + 'apk', + '--target-platform=android-arm64', + '--dart-define', + 'BUILD_TYPE=PRODUCT', + ], + ); + + String date = DateUtil.formatDate(DateTime.now(), format: 'yy_MM_dd_HH_mm'); + String version = await getVersion(); + await runAsync('rm', arguments: ['-rf', Config.apkDir]); + await runAsync('mkdir', arguments: ['-p', Config.apkDir]); + await runAsync('mv', arguments: [ + Config.buildPath, + '${Config.apkDir}/${Config.packageName}_${version}_release_$date.apk' + ]); +} + +@Task('打包Android项目') +buildApkDev() async { + await runAsync( + 'fvm', + arguments: [ + 'flutter', + 'build', + 'apk', + '--target-platform=android-arm64', + '--dart-define', + 'BUILD_TYPE=Dev', + ], + ); + String date = DateUtil.formatDate(DateTime.now(), format: 'yy_MM_dd_HH_mm'); + String version = await getVersion(); + await runAsync('rm', arguments: ['-rf', Config.apkDevDir]); + await runAsync('mkdir', arguments: ['-p', Config.apkDevDir]); + await runAsync('mv', arguments: [ + Config.buildPath, + '${Config.apkDevDir}/${Config.packageName}_${version}_beta_$date.apk' + ]); +} + +@Task('打包iOS项目') +buildIos() async { + await runAsync( + 'fvm', + arguments: [ + 'flutter', + 'build', + 'ios', + '--dart-define', + 'BUILD_TYPE=PRODUCT', + ], + ); +} diff --git a/tool/_project_manage.dart b/tool/_project_manage.dart new file mode 100644 index 0000000..5f58c3a --- /dev/null +++ b/tool/_project_manage.dart @@ -0,0 +1,64 @@ +part of './grind.dart'; + +@Task('import 排序') +void sort() { + Pub.run('import_sorter:main'); +} + +@Task('格式化dart代码') +void format() { + DartFmt.format(libDir); +} + +@Task('自动提交修改') +@Depends(sort, format, gitPush) +void git() { + log(' commit to git'); + run( + 'git', + arguments: [ + 'commit', + '-a', + '-m', + '[auto task] sort & format', + ], + ); +} + +@Task('推送代码') +void gitPush() { + log(' push to git'); + run( + 'git', + arguments: ['push'], + ); +} + +@Task('build runner') +void gen() async { + await runAsync( + 'fvm', + arguments: [ + 'flutter', + 'pub', + 'run', + 'build_runner', + 'build', + ], + ); +} + +@Task('build runner clean') +void genClean() async { + await runAsync( + 'fvm', + arguments: [ + 'flutter', + 'pub', + 'run', + 'build_runner', + 'build', + '--delete-conflicting-outputs' + ], + ); +} diff --git a/tool/grind.dart b/tool/grind.dart new file mode 100644 index 0000000..112ee83 --- /dev/null +++ b/tool/grind.dart @@ -0,0 +1,70 @@ +import 'dart:io'; + +import 'package:flustars/flustars.dart'; +import 'package:grinder/grinder.dart'; +import 'package:path/path.dart'; +import 'package:pub_semver/pub_semver.dart'; +import 'package:yaml/yaml.dart'; + +import 'config.dart'; +import 'version_tool.dart'; + +part '_build.dart'; +part '_project_manage.dart'; + +main(args) => grind(args); + +@Task('add minor version number') +void addVersion() async { + String projectPath = Directory('.').absolute.path; + String yamlPath = join(projectPath, 'pubspec.yaml'); + String yamlContent = await File(yamlPath).readAsString(); + dynamic content = loadYaml(yamlContent); + String version = content['version']; + //rename version + + Version resultVersion = VersionTool.fromText(version).nextMinorTag('dev'); + + String result = yamlContent.replaceFirst(version, resultVersion.toString()); + await File(yamlPath).writeAsString(result); +} + +@Task('add path version number') +void addVersionPatch() async { + String projectPath = Directory('.').absolute.path; + String yamlPath = join(projectPath, 'pubspec.yaml'); + String yamlContent = await File(yamlPath).readAsString(); + dynamic content = loadYaml(yamlContent); + String version = content['version']; + //rename version + + Version resultVersion = VersionTool.fromText(version).nextPatchTag('dev'); + + String result = yamlContent.replaceFirst(version, resultVersion.toString()); + await File(yamlPath).writeAsString(result); +} + +@Task('add major version number') +void addVersionMajor() async { + String projectPath = Directory('.').absolute.path; + String yamlPath = join(projectPath, 'pubspec.yaml'); + String yamlContent = await File(yamlPath).readAsString(); + dynamic content = loadYaml(yamlContent); + String version = content['version']; + //rename version + + Version resultVersion = VersionTool.fromText(version).nextMajorTag('dev'); + + String result = yamlContent.replaceFirst(version, resultVersion.toString()); + await File(yamlPath).writeAsString(result); +} + +@Task() +Future getVersion() async { + String projectPath = Directory('.').absolute.path; + String yamlPath = join(projectPath, 'pubspec.yaml'); + String yamlContent = await File(yamlPath).readAsString(); + dynamic content = loadYaml(yamlContent); + String version = content['version']; + return version; +} diff --git a/tool/version_tool.dart b/tool/version_tool.dart new file mode 100644 index 0000000..e6d629b --- /dev/null +++ b/tool/version_tool.dart @@ -0,0 +1,59 @@ +import 'package:pub_semver/pub_semver.dart'; + +enum VersionNumber { + major, + minor, + patch, +} + +class VersionTool { + Version version; + VersionTool(this.version); + VersionTool.fromText(String text) : version = Version.parse(text); + + Version get nextMajor => _addBuildNumber(VersionNumber.major); + Version get nextMinor => _addBuildNumber(VersionNumber.minor); + Version get nextPatch => _addBuildNumber(VersionNumber.patch); + + Version nextMajorTag(String tag) => _addBuildNumber( + VersionNumber.major, + tag: tag, + ); + Version nextMinorTag(String tag) => _addBuildNumber( + VersionNumber.minor, + tag: tag, + ); + Version nextPatchTag(String tag) => _addBuildNumber( + VersionNumber.patch, + tag: tag, + ); + + Version _addBuildNumber(VersionNumber type, {String? tag}) { + switch (type) { + case VersionNumber.major: + return Version( + version.major, + version.minor, + version.patch + 1, + pre: tag, + build: '${(version.build.first as int) + 1}', + ); + case VersionNumber.minor: + return Version( + version.major, + version.minor + 1, + 0, + pre: tag, + build: '${(version.build.first as int) + 1}', + ); + case VersionNumber.patch: + return Version( + version.major + 1, + 0, + 0, + pre: tag, + build: '${(version.build.first as int) + 1}', + ); + } + } +}