diff --git a/README.md b/README.md index da49dba..2446e93 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,30 @@ -![GitHub License](https://img.shields.io/github/license/ZiRunHua/LeapLedger-APP) -![Docker Pulls](https://img.shields.io/docker/pulls/xiaozirun/leap-ledger-app) -![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/ZiRunHua/LeapLedger-app/total) -![GitHub stars](https://img.shields.io/github/stars/ZiRunHua/LeapLedger-APP?style=social) +![GitHub License](https://img.shields.io/github/license/ZiRunHua/LeapLedger-App) +![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/ZiRunHua/LeapLedger-App/total) +![GitHub stars](https://img.shields.io/github/stars/ZiRunHua/LeapLedger-App?style=social) +![GitHub Release](https://img.shields.io/github/v/release/ZiRunHua/LeapLedger-App) -# LeapLedger-APP +# LeapLedger-App `LeapLedger`是一个的前后端分离的免费开源的记账软件,基于`flutter`带来丝滑流畅的使用体验,在未来轻松扩展至iOS、Mac和Windows。 -这是更多的介绍内容请浏览:https://github.com/ZiRunHua/LeapLedger + +这是`LeapLedger`的客户端部分,更多的介绍内容请浏览:https://github.com/ZiRunHua/LeapLedger ## 服务端 Gin服务端项目传送:https://github.com/ZiRunHua/LeapLedger -## 运行 -如果你只想使用Docker构建安装包请[跳转](#Docker) +## 开发 +如果你只想使用Docker构建安装包请[跳转](#docker) 1. 检查flutter环境 ```bash flutter doctor -v ``` - -2. 新建./.vscode/launch.json文件并复制一下内容 +2. 克隆项目 +```bash +git clone https://github.com/ZiRunHua/LeapLedger-App.git leap_ledger_app +``` +3. 新建./.vscode/launch.json文件并复制一下内容 +你可以修改`args`来自定义API请求地址 ```json { - // 使用 IntelliSense 了解相关属性。 - // 悬停以查看现有属性的描述。 - // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { @@ -30,17 +32,16 @@ flutter doctor -v "request": "launch", "type": "dart", "args": [ - "--dart-define=config.server.network.host=10.0.2.2", // 或许你需要自定义host + "--dart-define=config.server.network.host=10.0.2.2", "--dart-define=config.server.network.port=8080", ] } ] } ``` +4. 启动API服务 -3. 启动API服务 - -我们提供了启动后端服务器的脚本,它可以寻找当前客户端版本对应的最大修订版本的后端镜像,并执行启动命令 +我们提供了启动后端服务器的脚本,它可以寻找当前客户端版本对应的最新可用的后端镜像,并执行启动命令 API服务依赖[Docker](#https://www.docker.com),请确保你安装了它 ```bash @@ -64,22 +65,23 @@ cd service 传送门:https://github.com/ZiRunHua/LeapLedger -4. API文档 +启动完成后可以通过访问:http://localhost:8080/public/health 来验证API服务 +5. API文档 ApiFox文档:https://zpka7j706w.apifox.cn -通过脚步启动API服务,接口文件在/service/docs,也可以访问:http://localhost:8080/public/swagger/index.html +通过脚步启动API服务,可在`./service/docs`查看API文档,也可以访问:http://localhost:8080/public/swagger/index.html ## 构建安装包 如果你已经有flutter环境那么使用指令构建 ```bash flutter build apk --release ``` -自定义服务器ip、端口和接口签名秘钥 +自定义服务器ip、端口和接口签名秘钥(可选) ```bash flutter build apk --release --dart-define=config.server.network.host= --dart-define=config.server.network.port= --dart-define=config.signKey= ``` ### Docker -在项目根目录下新建.env文件 +使用docker构建请在根目录下新建.env文件 ``` # 服务器地址 SERVER_HOST="10.0.2.2" @@ -88,8 +90,14 @@ SERVER_PORT="8080" # 服务端接口签名对称秘钥 可选 # SERVER_SIGN_KEY="" ``` -然后执行以下命令,构建过程可能需要几分钟 +执行以下命令,构建过程可能需要几分钟,如果你对Android有些了解,你可以挂载本地的gradle路径来加速构建 ```bash docker-compose up build_apk ``` -在./docker/build查看构建成功的安装包 \ No newline at end of file +在./docker/build查看构建成功的安装包 + + +## 我们需要你 + + +[![Stargazers over time](https://starchart.cc/ZiRunHua/LeapLedger-App.svg)](https://starchart.cc/ZiRunHua/LeapLedger-App) \ No newline at end of file diff --git a/lib/view/account/edit/account_edit.dart b/lib/view/account/edit/account_edit.dart index b9786a9..61e1727 100644 --- a/lib/view/account/edit/account_edit.dart +++ b/lib/view/account/edit/account_edit.dart @@ -103,7 +103,7 @@ class AccountEditState extends State { padding: EdgeInsets.symmetric(horizontal: Constant.margin), child: FormSelecter.accountIcon(account.icon, onChanged: _onSelectIcon), ), - _buildRadio(), + if (mode == AccountEditMode.add) _buildTypeSelectRadio(), FormSelectField( options: _options(), label: "地区", @@ -133,50 +133,46 @@ class AccountEditState extends State { return list; } - Widget _buildRadio() { + Widget _buildTypeSelectRadio() { return Padding( - padding: EdgeInsets.symmetric(vertical: Constant.margin, horizontal: Constant.padding), - child: Align( - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.all(Constant.margin), - child: Text("类型", style: TextStyle(letterSpacing: Constant.margin / 2)), - ), - Padding( - padding: EdgeInsets.all(Constant.margin), - child: Row( - children: [ - SizedBox( - width: 100.sp, - child: RadioListTile( - contentPadding: EdgeInsets.zero, - title: const Text("独立"), - value: AccountType.independent, - groupValue: account.type, - onChanged: _onClickRadio, - ), - ), - SizedBox( - width: 100.sp, - child: RadioListTile( - title: const Text("共享"), - contentPadding: EdgeInsets.zero, - value: AccountType.share, - groupValue: account.type, - onChanged: _onClickRadio, + padding: EdgeInsets.symmetric(vertical: Constant.margin, horizontal: Constant.padding), + child: Align( + alignment: Alignment.centerLeft, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.all(Constant.margin), + child: Text("类型", style: TextStyle(letterSpacing: Constant.margin / 2)), + ), + Padding( + padding: EdgeInsets.all(Constant.margin), + child: Row(children: [ + SizedBox( + width: 100.sp, + child: RadioListTile( + contentPadding: EdgeInsets.zero, + title: const Text("独立"), + value: AccountType.independent, + groupValue: account.type, + onChanged: _onClickRadio, + ), ), - ), - ], - )) - ], - ), - ), - ); + SizedBox( + width: 100.sp, + child: RadioListTile( + title: const Text("共享"), + contentPadding: EdgeInsets.zero, + value: AccountType.share, + groupValue: account.type, + onChanged: _onClickRadio, + ), + ) + ])) + ]), + )); } void _onClickRadio(AccountType? value) { diff --git a/lib/view/share/home/bloc/share_home_bloc.dart b/lib/view/share/home/bloc/share_home_bloc.dart index 1777933..3f18086 100644 --- a/lib/view/share/home/bloc/share_home_bloc.dart +++ b/lib/view/share/home/bloc/share_home_bloc.dart @@ -115,6 +115,7 @@ class ShareHomeBloc extends Bloc { AccountMappingModel? accountMapping; List alreadyShownTips = []; + bool notDisturb = false; Future _getAccountMapping(emit) async { if (account == null) { return; diff --git a/lib/view/share/home/share_home.dart b/lib/view/share/home/share_home.dart index bcbbe26..f063404 100644 --- a/lib/view/share/home/share_home.dart +++ b/lib/view/share/home/share_home.dart @@ -80,7 +80,7 @@ class _ShareHomeState extends State { return const Center(child: ConstantWidget.activityIndicator); } if (state is NoShareAccount || ShareHomeBloc.account == null || !ShareHomeBloc.account!.isValid) { - return const NoAccountPage(); + return NoAccountPage(bloc:_bloc); } return Scaffold( appBar: AppBar( @@ -262,12 +262,15 @@ class _ShareHomeState extends State { if (_bloc.accountMapping != null) return; if (ShareHomeBloc.account == null || ShareHomeBloc.account!.isReader) return; if (_bloc.alreadyShownTips.contains(ShareHomeBloc.account!.id)) return; + print(ModalRoute.of(context)?.isCurrent ?? false); + if((ModalRoute.of(context)?.isCurrent ?? false) == false) return; _bloc.alreadyShownTips.add(ShareHomeBloc.account!.id); showDialog(context: context, builder: (context) => _buildMappingAccountTipDialog()); } _buildMappingAccountTipDialog() { return AlertDialog( + contentPadding: EdgeInsets.all( Constant.padding), content: Text("设置“关联账本”来开启交易同步"), actions: [ TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text('下次设置')), @@ -284,6 +287,7 @@ class _ShareHomeState extends State { _buildMappingCategoryTipDialog(AccountMappingModel accountMapping) { return AlertDialog( + contentPadding: EdgeInsets.all( Constant.padding), content: Text("设置两个账本间的“交易类型关联”来定义同步类型"), actions: [ TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text('下次设置')), diff --git a/lib/view/share/home/widget/no_account_page.dart b/lib/view/share/home/widget/no_account_page.dart index 67c993b..28c2a6c 100644 --- a/lib/view/share/home/widget/no_account_page.dart +++ b/lib/view/share/home/widget/no_account_page.dart @@ -1,8 +1,8 @@ part of 'enter.dart'; class NoAccountPage extends StatelessWidget { - const NoAccountPage({super.key}); - + const NoAccountPage({super.key,required this.bloc}); + final ShareHomeBloc bloc; @override Widget build(BuildContext context) { return LayoutBuilder( @@ -19,18 +19,15 @@ class NoAccountPage extends StatelessWidget { _buildButton( ConstantIcon.add, "新建共享账本", - () { - var page = - AccountRoutes.edit(context, account: AccountDetailModel.fromJson({})..type = AccountType.share); - page.push(); - if (page.getReturn() != null) { - BlocProvider.of(context).add(SetCurrentShareAccount(page.getReturn()!)); - } + () async { + await AccountRoutes.edit(context, account: AccountDetailModel.fromJson({})..type = AccountType.share) + .push(); + bloc.add(SetAccountMappingEvent(null)); }, ), _buildButton(Icons.send_outlined, "查看邀请", () { UserRoutes.pushNamed(context, UserRoutes.accountInvitation) - .then((value) => BlocProvider.of(context).add(LoadAccountListEvent())); + .then((value) => bloc.add(LoadAccountListEvent())); }) ], ),