Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
小滋润 committed Oct 28, 2024
1 parent 1da2302 commit 8f44e43
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 192 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Gin服务端项目传送:https://github.com/ZiRunHua/LeapLedger

1. 检查flutter环境
```bash
docket -v
flutter doctor -v
```

2. 新建./.vscode/launch.json文件并复制一下内容
Expand Down Expand Up @@ -68,7 +68,7 @@ cd service

ApiFox文档:https://zpka7j706w.apifox.cn

如果是通过脚步启动API服务,接口文件在/service/docs,也可以访问:http://localhost:8080/public/swagger/index.html
通过脚步启动API服务,接口文件在/service/docs,也可以访问:http://localhost:8080/public/swagger/index.html
## 构建安装包
如果你已经有flutter环境那么使用指令构建
```bash
Expand All @@ -92,4 +92,4 @@ SERVER_PORT="8080"
```bash
docker-compose up build_apk
```
在docker/build路径查看构建的安装包
在./docker/build查看构建成功的安装包
9 changes: 8 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,14 @@ class MyApp extends StatelessWidget {
iconTheme: IconThemeData.fallback().copyWith(applyTextScaling: true),
useMaterial3: true,
),
home: Navigation(),
home: MultiBlocListener(
listeners: [
BlocListener<AccountBloc, AccountState>(
listener: (context, state) {},
)
],
child: Navigation(),
),
builder: (context, widget) {
Constant.init();
FlutterNativeSplash.remove();
Expand Down
75 changes: 43 additions & 32 deletions lib/view/account/mapping/account_mapping_bottom_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,14 @@ class _AccountMappingBottomSheetState extends State<AccountMappingBottomSheet> {
children: [
Center(
child: Padding(
padding: EdgeInsets.fromLTRB(Constant.margin, Constant.margin, Constant.margin, 0),
padding: EdgeInsets.all(Constant.padding),
child: Text(
'账本关联',
'选择关联账本',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: ConstantFontSize.largeHeadline),
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 2.0,
child: _buildContent(),
),
_buildContent(),
],
),
),
Expand All @@ -68,34 +65,48 @@ class _AccountMappingBottomSheetState extends State<AccountMappingBottomSheet> {

Widget _buildContent() {
return BlocBuilder<AccountMappingCubit, AccountMappingState>(builder: (context, state) {
if (state is AccountListLoad || state is AccountMappingChanged) {
if (_cubit.list.isNotEmpty) {
return ListView.separated(
itemBuilder: (_, int index) {
var account = _cubit.list[index];
return CommonListTile.fromAccountDetailModel(
account,
onSelect: _cubit.isCurrentMappingAccount(account),
ontap: () {
if (_cubit.isCurrentMappingAccount(account)) {
// 确认删除
CommonDialog.showDeleteConfirmationDialog(context, () => _cubit.changeMapping(account));
} else {
_cubit.changeMapping(account);
}
},
);
},
separatorBuilder: (BuildContext context, int index) {
return ConstantWidget.divider.list;
if (state is! AccountListLoad && state is! AccountMappingChanged) {
return const Center(child: ConstantWidget.activityIndicator);
}
if (_cubit.list.isEmpty) {
return Center(child: NoData.accountText(context));
}
if (_cubit.list.length <= 5) {
return Column(
children: List.generate(
_cubit.list.length * 2 - 1,
(index) {
if (index % 2 != 0) {
return ConstantWidget.divider.list;
}
return _buildOne(_cubit.list[index~/2]);
},
itemCount: _cubit.list.length,
);
} else {
return Center(child: NoData.accountText(context));
}
),
);
}
return const Center(child: ConstantWidget.activityIndicator);
return SizedBox(
height: MediaQuery.of(context).size.height / 2.0,
child:ListView.separated(
itemBuilder: (_, int index) => _buildOne(_cubit.list[index]),
separatorBuilder: (BuildContext context, int index) {
return ConstantWidget.divider.list;
},
itemCount: _cubit.list.length,
));
});
}

_buildOne(AccountDetailModel account) {
return CommonListTile.fromAccountDetailModel(
account,
onSelect: _cubit.isCurrentMappingAccount(account),
ontap: () {
if (_cubit.isCurrentMappingAccount(account)) {
CommonDialog.showDeleteConfirmationDialog(context, () => _cubit.changeMapping(account));
} else {
_cubit.changeMapping(account);
}
},
);
}
}
1 change: 1 addition & 0 deletions lib/view/share/home/bloc/share_home_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class ShareHomeBloc extends Bloc<ShareHomeEvent, ShareHomeState> {
}

AccountMappingModel? accountMapping;
List<int> alreadyShownTips = [];
Future<void> _getAccountMapping(emit) async {
if (account == null) {
return;
Expand Down
99 changes: 84 additions & 15 deletions lib/view/share/home/share_home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import 'package:leap_ledger_app/common/global.dart';
import 'package:leap_ledger_app/model/account/model.dart';
import 'package:leap_ledger_app/model/common/model.dart';
import 'package:leap_ledger_app/routes/routes.dart';
import 'package:leap_ledger_app/view/navigation/bloc/navigation_bloc.dart'
show NavigationBloc, TabPage, NavigationState, InSharePage;
import 'package:leap_ledger_app/view/share/home/bloc/share_home_bloc.dart';
import 'package:leap_ledger_app/widget/common/common.dart';

Expand Down Expand Up @@ -40,20 +42,38 @@ class _ShareHomeState extends State<ShareHome> {
Widget build(BuildContext context) {
return BlocProvider.value(
value: _bloc,
child: BlocListener<UserBloc, UserState>(
listenWhen: (context, state) {
return state is CurrentShareAccountChanged || state is CurrentAccountChanged;
},
listener: (context, state) {
if (UserBloc.currentShareAccount.isValid) {
_bloc.add(ChangeAccountEvent(UserBloc.currentShareAccount));
} else if (UserBloc.currentAccount.isValid && UserBloc.currentAccount.type == AccountType.share) {
_bloc.add(ChangeAccountEvent(UserBloc.currentAccount));
} else {
// 否则只能传递无效的共享账本 交给bloc处理
_bloc.add(ChangeAccountEvent(UserBloc.currentShareAccount));
}
},
child: MultiBlocListener(
listeners: [
BlocListener<NavigationBloc, NavigationState>(listenWhen: (context, state) {
return state is InSharePage;
}, listener: (context, state) {
if (state is InSharePage) {
showMappingAccountTip();
}
}),
BlocListener<ShareHomeBloc, ShareHomeState>(listenWhen: (context, state) {
return state is AccountMappingLoad;
}, listener: (context, state) {
if (state is AccountMappingLoad) {
if (BlocProvider.of<NavigationBloc>(context).currentDisplayPage != TabPage.share) {
return;
}
showMappingAccountTip();
}
}),
BlocListener<UserBloc, UserState>(listenWhen: (context, state) {
return state is CurrentShareAccountChanged || state is CurrentAccountChanged;
}, listener: (context, state) {
if (UserBloc.currentShareAccount.isValid) {
_bloc.add(ChangeAccountEvent(UserBloc.currentShareAccount));
} else if (UserBloc.currentAccount.isValid && UserBloc.currentAccount.type == AccountType.share) {
_bloc.add(ChangeAccountEvent(UserBloc.currentAccount));
} else {
// 否则只能传递无效的共享账本 交给bloc处理
_bloc.add(ChangeAccountEvent(UserBloc.currentShareAccount));
}
})
],
child: BlocBuilder<ShareHomeBloc, ShareHomeState>(
builder: (context, state) {
if (state is ShareHomeInitial) {
Expand Down Expand Up @@ -179,7 +199,11 @@ class _ShareHomeState extends State<ShareHome> {
context,
mainAccount: ShareHomeBloc.account!,
mapping: _bloc.accountMapping,
onMappingChange: (mapping) => _bloc.add(SetAccountMappingEvent(mapping)),
onMappingChange: (mapping) {
_bloc.add(SetAccountMappingEvent(mapping));
if (mapping == null) return;
showDialog(context: context, builder: (context) => _buildMappingCategoryTipDialog(mapping));
},
).showModalBottomSheet();
} else {
CommonToast.tipToast("只读,不可关联账本");
Expand Down Expand Up @@ -233,4 +257,49 @@ class _ShareHomeState extends State<ShareHome> {
)),
);
}

showMappingAccountTip() {
if (_bloc.accountMapping != null) return;
if (ShareHomeBloc.account == null || ShareHomeBloc.account!.isReader) return;
if (_bloc.alreadyShownTips.contains(ShareHomeBloc.account!.id)) return;
_bloc.alreadyShownTips.add(ShareHomeBloc.account!.id);
showDialog(context: context, builder: (context) => _buildMappingAccountTipDialog());
}

_buildMappingAccountTipDialog() {
return AlertDialog(
content: Text("设置“关联账本”来开启交易同步"),
actions: <Widget>[
TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text('下次设置')),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
_clickMapping();
},
child: const Text('设置'),
),
],
);
}

_buildMappingCategoryTipDialog(AccountMappingModel accountMapping) {
return AlertDialog(
content: Text("设置两个账本间的“交易类型关联”来定义同步类型"),
actions: <Widget>[
TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text('下次设置')),
ElevatedButton(
onPressed: () {
if (ShareHomeBloc.account == null) return;
Navigator.pop(context);
TransactionCategoryRoutes.accountMappingNavigator(
context,
parentAccount: ShareHomeBloc.account!,
childAccount: accountMapping.relatedAccount,
).push();
},
child: const Text('设置'),
),
],
);
}
}
64 changes: 38 additions & 26 deletions lib/view/transaction/timing/cubit/transaction_timing_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:timezone/timezone.dart';
part 'transaction_timing_state.dart';

class TransactionTimingCubit extends AccountBasedCubit<TransactionTimingState> {
TransactionTimingCubit( {required super.account}) : super(TransactionTimingInitial()) {
TransactionTimingCubit({required super.account}) : super(TransactionTimingInitial()) {
var now = nowTime;
trans = TransactionInfoModel.prototypeData(tradeTime: now.add(const Duration(days: 1)));
config = TransactionTimingModel.prototypeData(
Expand All @@ -22,8 +22,8 @@ class TransactionTimingCubit extends AccountBasedCubit<TransactionTimingState> {
required TransactionInfoModel trans,
required TransactionTimingModel config}) {
this.account = account;
this.trans = trans;
this.config = config;
this.trans = trans.copyWith();
this.config = config.copyWith();
//amend next time
_updateNextTime(trans.tradeTime);
}
Expand Down Expand Up @@ -51,7 +51,7 @@ class TransactionTimingCubit extends AccountBasedCubit<TransactionTimingState> {
bool noMore = false;
Future<List<({TransactionInfoModel trans, TransactionTimingModel config})>> loadMore() async {
emit(TransactionTimingListLoadingMore());
if (noMore == true){
if (noMore == true) {
emit(TransactionTimingListLoaded());
return [];
}
Expand Down Expand Up @@ -83,17 +83,25 @@ class TransactionTimingCubit extends AccountBasedCubit<TransactionTimingState> {
if (config.type == type) {
emit(TransactionTimingTypeChanged(config));
return;
};
}
config.type = type;
switch (config.type) {
case TransactionTimingType.lastDayOfMonth:
changeNextTime(Tz.getLastSecondOfMonth(date: nowTime));
case TransactionTimingType.once:
changeNextTime(nowTime.add(Duration(days: 1)));
break;
case TransactionTimingType.everyDay:
changeNextTime(nowTime.add(Duration(days: 1)));
break;
default:
changeNextTime(nowTime.add(Duration(days: 1)));
case TransactionTimingType.everyWeek:
break;
case TransactionTimingType.everyMonth:
if (config.nextTime.day > 28) {
changeNextTime(nowTime.add(Duration(days: 1)));
}
break;
case TransactionTimingType.lastDayOfMonth:
changeNextTime(Tz.getLastSecondOfMonth(date: nowTime));
break;
}

emit(TransactionTimingTypeChanged(config));
Expand All @@ -106,28 +114,32 @@ class TransactionTimingCubit extends AccountBasedCubit<TransactionTimingState> {
}

_updateNextTime(DateTime date) {
date = Tz.getFirstSecondOfDay(date: getTZDateTime(date));
var now = Tz.getFirstSecondOfDay(date: nowTime);
if (!now.isBefore(date)) {
switch (config.type) {
case TransactionTimingType.once:
date = now.add(Duration(days: 1));
case TransactionTimingType.everyDay:
date = now.add(Duration(days: 1));
case TransactionTimingType.everyWeek:
date = now.add(Duration(days: 7));
case TransactionTimingType.everyMonth:
date = TZDateTime(location,date.year, date.month + 1, date.day);
case TransactionTimingType.lastDayOfMonth:
date = TZDateTime(location,date.year, date.month + 1, 1).add(Duration(hours: -24));
if (!now.isBefore(date)) date = TZDateTime(location,date.year, date.month + 1, 1).add(Duration(hours: -24));
}
}
config.nextTime = date;
trans.tradeTime = date;
config.updateoffsetDaysByNextTime();
}

onOffsetDaysChanged(int offsetDays) {
switch (config.type) {
case TransactionTimingType.everyWeek:
if (nowTime.weekday < offsetDays) {
changeNextTime(nowTime.add(Duration(days: offsetDays - nowTime.weekday)));
} else {
changeNextTime(nowTime.add(Duration(days: offsetDays - nowTime.weekday + DateTime.daysPerWeek)));
}
break;
case TransactionTimingType.everyMonth:
if (nowTime.day < offsetDays) {
changeNextTime(nowTime.add(Duration(days: offsetDays - nowTime.day)));
} else {
final date = nowTime;
changeNextTime(TZDateTime(date.location, date.year, date.month + 1, offsetDays));
}
break;
default:
}
}

save() async {
late final ({TransactionInfoModel trans, TransactionTimingModel config})? responseData;
config = this.config.copyWith(nextTime: Tz.getNewByDate(config.nextTime, account.timeLocation));
Expand Down
Loading

0 comments on commit 8f44e43

Please sign in to comment.