diff --git a/assets/static/rule_explain.png b/assets/static/rule_explain.png new file mode 100644 index 00000000..14a4ee46 Binary files /dev/null and b/assets/static/rule_explain.png differ diff --git a/lib/models/integral/add_integral_config_model.dart b/lib/models/integral/add_integral_config_model.dart new file mode 100644 index 00000000..494fc0fe --- /dev/null +++ b/lib/models/integral/add_integral_config_model.dart @@ -0,0 +1,16 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'add_integral_config_model.g.dart'; + +@JsonSerializable() +class AddIntegralConfigModel { + final int addIntegral; + final bool hasClocked; + factory AddIntegralConfigModel.fromJson(Map json) => + _$AddIntegralConfigModelFromJson(json); + + const AddIntegralConfigModel({ + required this.addIntegral, + required this.hasClocked, + }); +} diff --git a/lib/models/integral/add_integral_config_model.g.dart b/lib/models/integral/add_integral_config_model.g.dart new file mode 100644 index 00000000..5ce9d04d --- /dev/null +++ b/lib/models/integral/add_integral_config_model.g.dart @@ -0,0 +1,14 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'add_integral_config_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AddIntegralConfigModel _$AddIntegralConfigModelFromJson( + Map json) => + AddIntegralConfigModel( + addIntegral: json['addIntegral'] as int, + hasClocked: json['hasClocked'] as bool, + ); diff --git a/lib/models/integral/clocked_record_list_model.dart b/lib/models/integral/clocked_record_list_model.dart new file mode 100644 index 00000000..5c8826d9 --- /dev/null +++ b/lib/models/integral/clocked_record_list_model.dart @@ -0,0 +1,18 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'clocked_record_list_model.g.dart'; + +@JsonSerializable() +class ClockedRecordListModel { + final int day; + final String date; + final int addIntegral; + factory ClockedRecordListModel.fromJson(Map json) => + _$ClockedRecordListModelFromJson(json); + + const ClockedRecordListModel({ + required this.day, + required this.date, + required this.addIntegral, + }); +} diff --git a/lib/models/integral/clocked_record_list_model.g.dart b/lib/models/integral/clocked_record_list_model.g.dart new file mode 100644 index 00000000..5033db87 --- /dev/null +++ b/lib/models/integral/clocked_record_list_model.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'clocked_record_list_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ClockedRecordListModel _$ClockedRecordListModelFromJson( + Map json) => + ClockedRecordListModel( + day: json['day'] as int, + date: json['date'] as String, + addIntegral: json['addIntegral'] as int, + ); diff --git a/lib/pages/personal/clock_in/clock_in_page.dart b/lib/pages/personal/clock_in/clock_in_page.dart new file mode 100644 index 00000000..e06a28e0 --- /dev/null +++ b/lib/pages/personal/clock_in/clock_in_page.dart @@ -0,0 +1,342 @@ +import 'package:aku_new_community/base/base_style.dart'; +import 'package:aku_new_community/constants/api.dart'; +import 'package:aku_new_community/extensions/num_ext.dart'; +import 'package:aku_new_community/extensions/widget_list_ext.dart'; +import 'package:aku_new_community/gen/assets.gen.dart'; +import 'package:aku_new_community/models/integral/add_integral_config_model.dart'; +import 'package:aku_new_community/models/integral/clocked_record_list_model.dart'; +import 'package:aku_new_community/widget/bee_back_button.dart'; +import 'package:aku_new_community/widget/others/user_tool.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:velocity_x/velocity_x.dart'; + +class ClockInPage extends StatefulWidget { + const ClockInPage({Key? key}) : super(key: key); + + @override + _ClockInPageState createState() => _ClockInPageState(); +} + +class _ClockInPageState extends State { + List _configs = [ + AddIntegralConfigModel(addIntegral: 1, hasClocked: true), + AddIntegralConfigModel(addIntegral: 2, hasClocked: false), + AddIntegralConfigModel(addIntegral: 3, hasClocked: false), + AddIntegralConfigModel(addIntegral: 5, hasClocked: false), + AddIntegralConfigModel(addIntegral: 8, hasClocked: false), + AddIntegralConfigModel(addIntegral: 15, hasClocked: false), + AddIntegralConfigModel(addIntegral: 50, hasClocked: false), + ]; + + List _records = [ + ClockedRecordListModel(day: 1, date: '2021-12-29 13:29:24', addIntegral: 1), + ClockedRecordListModel(day: 2, date: '2021-12-28 13:29:24', addIntegral: 2), + ClockedRecordListModel(day: 3, date: '2021-12-27 13:29:24', addIntegral: 3), + ClockedRecordListModel(day: 4, date: '2021-12-26 13:29:24', addIntegral: 5), + ClockedRecordListModel(day: 5, date: '2021-12-25 13:29:24', addIntegral: 8), + ClockedRecordListModel( + day: 6, date: '2021-12-24 13:29:24', addIntegral: 15), + ClockedRecordListModel( + day: 7, date: '2021-12-23 13:29:24', addIntegral: 50), + ClockedRecordListModel(day: 1, date: '2021-12-22 13:29:24', addIntegral: 1), + ]; + + bool _openRemind = false; //演示用,之后删除 + + @override + Widget build(BuildContext context) { + var top = Container( + width: double.infinity, + // height: 441.w, + alignment: Alignment.topCenter, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + 48.hb, + Container( + margin: EdgeInsets.only(left: 32.w), + child: Row( + children: [ + Hero( + tag: 'AVATAR', + child: ClipOval( + child: FadeInImage.assetNetwork( + placeholder: Assets.images.placeholder.path, + image: API.image(UserTool + .userProvider.userInfoModel!.imgUrls.isNotEmpty + ? UserTool + .userProvider.userInfoModel!.imgUrls.first.url + : ''), + height: 106.w, + width: 106.w, + fit: BoxFit.cover, + imageErrorBuilder: (context, error, stackTrace) { + return Image.asset( + Assets.icons.iconMySetting.path, + height: 106.w, + width: 106.w, + ); + }, + ), + ), + ), + Container( + margin: EdgeInsets.only(left: 16.w), + child: UserTool.userProvider.isLogin + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text.rich( + TextSpan(children: [ + '已连续签到 '.textSpan.make(), + '1'.textSpan.size(40.sp).make(), + ' 天'.textSpan.make(), + ]), + style: TextStyle( + fontSize: 32.sp, + color: Colors.black.withOpacity(0.85), + ), + ), + 4.hb, + Text( + '明日签到即可获得2积分', + style: TextStyle( + fontSize: 24.sp, + color: Colors.black.withOpacity(0.45), + ), + ), + ], + ) + : Text( + '登录/注册', + style: TextStyle( + fontSize: 32.sp, + color: Color(0xffad8940), + ), + )), + Spacer(), + MaterialButton( + onPressed: () {}, + elevation: 0, + color: Colors.white.withOpacity(0.2), + minWidth: 155.w, + height: 72.w, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16.w)), + child: Row( + children: [ + Assets.icons.intergral.image(width: 36.w, height: 36.w), + 12.wb, + '123'.text.size(32.sp).white.make(), + ], + ), + ), + 32.w.widthBox, + ], + ), + ), + ], + ), + ); + var clockInCard = Container( + width: 686.w, + height: 428.w, + margin: EdgeInsets.symmetric(horizontal: 32.w), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24.w), + ), + padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 24.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + '连续签到领好礼'.text.size(28.sp).black.make(), + 14.wb, + Icon( + CupertinoIcons.question_circle, + size: 30.w, + color: Colors.black.withOpacity(0.25), + ), + Spacer(), + '开启签到提醒' + .text + .size(24.sp) + .color(Colors.black.withOpacity(0.25)) + .make(), + 24.wb, + SizedBox( + width: 72.w, + height: 40.w, + child: Switch( + value: _openRemind, + onChanged: (value) { + _openRemind = value; + setState(() {}); + }, + )), + ], + ), + Spacer(), + GridView.count( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + crossAxisCount: 7, + childAspectRatio: 70 / 100, + mainAxisSpacing: 24.w, + children: _configs + .mapIndexed((currentValue, index) => gridCard( + index, currentValue.addIntegral, + hasClocked: currentValue.hasClocked)) + .toList(), + ), + Spacer(), + MaterialButton( + onPressed: () {}, + elevation: 0, + color: kPrimaryColor, + minWidth: 560, + height: 93.w, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(59.w)), + child: '签到'.text.size(32.sp).black.bold.make(), + ) + ], + ), + ); + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + title: '每日签到'.text.size(32.sp).white.make(), + leading: BeeBackButton( + color: Colors.white, + ), + ), + extendBody: true, + extendBodyBehindAppBar: true, + body: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration( + image: DecorationImage( + alignment: Alignment.topCenter, + fit: BoxFit.fitHeight, + image: AssetImage(Assets.static.signInBackground.path)), + ), + child: SafeArea( + child: Column( + children: [ + top, + 80.hb, + clockInCard, + 40.hb, + Flexible( + child: Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(30.w), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: + EdgeInsets.only(top: 32.w, left: 32.w, right: 32.w), + child: '签到记录'.text.size(32.sp).black.bold.make(), + ), + 24.hb, + Flexible( + child: ListView( + shrinkWrap: true, + children: [ + ..._records + .mapIndexed((currentValue, index) => + recordListTile( + currentValue.day, + currentValue.date, + currentValue.addIntegral)) + .toList(), + Container( + width: double.infinity, + height: 82.w, + alignment: Alignment.center, + color: Color(0xFFE5E5E5), + child: '没有更多记录了~' + .text + .size(28.sp) + .color(ktextSubColor) + .make(), + ), + ].sepWidget(separate: 32.hb), + ), + ) + ], + ), + ), + ), + ], + ), + ), + ), + ); + } + + Widget recordListTile(int continuityDay, String date, int addIntegral) { + return Padding( + padding: EdgeInsets.only(left: 32.w, right: 32.w), + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + '连续$continuityDay天签到'.text.size(28.sp).black.make(), + date.text.size(24.sp).color(ktextSubColor).make(), + ], + ), + Spacer(), + SizedBox( + width: 100.w, + child: Row( + children: [ + Assets.icons.intergral.image(width: 30.w, height: 30.w), + Spacer(), + '+$addIntegral'.text.size(28.sp).color(kPrimaryColor).make(), + ], + ), + ) + ], + ), + ); + } + + Widget gridCard(int index, int addIntegral, {bool hasClocked = false}) { + return Column( + children: [ + Container( + width: 70.w, + height: 70.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(35.w), + border: (hasClocked + ? Border.fromBorderSide(BorderSide.none) + : Border.all(color: kPrimaryColor)), + color: (hasClocked ? kPrimaryColor : Colors.white)), + alignment: Alignment.center, + child: hasClocked + ? Icon( + CupertinoIcons.check_mark, + size: 40.w, + color: Colors.white, + ) + : '+ $addIntegral'.text.size(22.sp).color(kPrimaryColor).make(), + ), + 14.hb, + '第${index + 1}天'.text.size(22.sp).black.make(), + ], + ); + } +} diff --git a/lib/pages/personal/intergral/integral_center_page.dart b/lib/pages/personal/intergral/integral_center_page.dart index a8db5a04..b3d698a7 100644 --- a/lib/pages/personal/intergral/integral_center_page.dart +++ b/lib/pages/personal/intergral/integral_center_page.dart @@ -83,6 +83,74 @@ class _integralCenterPageState extends State { ), ), ); + var midCard = Positioned( + top: 547.w, + child: Material( + color: Colors.white, + borderRadius: BorderRadius.circular(24.w), + clipBehavior: Clip.antiAlias, + child: Container( + width: 686.w, + height: 343.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24.w), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + Color(0xD9FBB246), + Color(0xE6FF7145), + ])), + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 32.w, top: 32.w, right: 32.w), + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + '活跃度'.text.size(28.sp).white.make(), + 24.w.heightBox, + '2501'.text.size(56.sp).white.make(), + ], + ), + 48.w.widthBox, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + '积分'.text.size(28.sp).white.make(), + 24.w.heightBox, + '123'.text.size(56.sp).white.make(), + ], + ), + Spacer(), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + '积分获取比例'.text.size(28.sp).white.make(), + 24.w.heightBox, + '5%'.text.size(56.sp).white.make(), + ], + ) + ], + ), + ), + Spacer(), + Container( + width: double.infinity, + height: 110.w, + alignment: Alignment.center, + child: ProgressPaint( + activity: 300, + lowLevel: 1, + proportion: _proportion, + ), + ) + ], + ), + ), + )); return Scaffold( extendBodyBehindAppBar: true, extendBody: true, @@ -127,75 +195,7 @@ class _integralCenterPageState extends State { children: [ back, top, - Positioned( - top: 547.w, - child: Material( - color: Colors.white, - borderRadius: BorderRadius.circular(24.w), - clipBehavior: Clip.antiAlias, - child: Container( - width: 686.w, - height: 343.w, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(24.w), - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [ - Color(0xD9FBB246), - Color(0xE6FF7145), - ])), - child: Column( - children: [ - Padding( - padding: EdgeInsets.only( - left: 32.w, top: 32.w, right: 32.w), - child: Row( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - '活跃度'.text.size(28.sp).white.make(), - 24.w.heightBox, - '2501'.text.size(56.sp).white.make(), - ], - ), - 48.w.widthBox, - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - '积分'.text.size(28.sp).white.make(), - 24.w.heightBox, - '123'.text.size(56.sp).white.make(), - ], - ), - Spacer(), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - '积分获取比例'.text.size(28.sp).white.make(), - 24.w.heightBox, - '5%'.text.size(56.sp).white.make(), - ], - ) - ], - ), - ), - Spacer(), - Container( - width: double.infinity, - height: 110.w, - alignment: Alignment.center, - child: ProgressPaint( - activity: 300, - lowLevel: 1, - proportion: _proportion, - ), - ) - ], - ), - ), - )), + midCard, ], ), ), diff --git a/lib/pages/personal/personal_page.dart b/lib/pages/personal/personal_page.dart index 40e79b18..a0431345 100644 --- a/lib/pages/personal/personal_page.dart +++ b/lib/pages/personal/personal_page.dart @@ -1,6 +1,7 @@ import 'package:aku_new_community/const/resource.dart'; import 'package:aku_new_community/constants/api.dart'; import 'package:aku_new_community/gen/assets.gen.dart'; +import 'package:aku_new_community/pages/personal/clock_in/clock_in_page.dart'; import 'package:aku_new_community/pages/personal/user_profile_page.dart'; import 'package:aku_new_community/pages/setting_page/settings_page.dart'; import 'package:aku_new_community/pages/sign/sign_in_page.dart'; @@ -223,114 +224,6 @@ class _PersonalIndexState extends State }, child: Stack( children: [ - // Container( - // - // width: double.infinity, - // height: 441.w, - // alignment: Alignment.topCenter, - // - // decoration: BoxDecoration( - // gradient: LinearGradient( - // begin: Alignment.topCenter, - // end: Alignment.bottomCenter, - // colors: [ - // Color(0xFFF9D57A), - // Color(0xFFF9D57A), - // ], - // ), - // ), - // padding: EdgeInsets.only(top: 130.w), - // child: Column( - // mainAxisAlignment: MainAxisAlignment.start, - // children: [ - // - // MaterialButton( - // padding: EdgeInsets.all(5.w), - // onPressed: () { - // if (!userProvider.isLogin) - // Get.to(() => SignInPage()); - // else - // Get.to(() => UserProfilePage()); - // }, - // child: Container( - // margin: EdgeInsets.only(left: 32.w), - // child: Row( - // children: [ - // Hero( - // tag: 'AVATAR', - // child: ClipOval( - // child: FadeInImage.assetNetwork( - // placeholder: R.ASSETS_IMAGES_PLACEHOLDER_WEBP, - // image: API.image(userProvider - // .userInfoModel!.imgUrls.isNotEmpty - // ? userProvider - // .userInfoModel!.imgUrls.first.url - // : ''), - // height: 106.w, - // width: 106.w, - // fit: BoxFit.cover, - // imageErrorBuilder: (context, error, stackTrace) { - // return Image.asset(R.ASSETS_IMAGES_PLACEHOLDER_WEBP,height: 106.w, - // width: 106.w,); - // }, - // ), - // ), - // ), - // Container( - // margin: EdgeInsets.only(left: 16.w), - // child: userProvider.isLogin - // ? Text( - // userProvider.userInfoModel?.nickName ?? - // '', - // style: TextStyle( - // fontSize: 32.sp, - // color: Color(0xffad8940), - // ), - // ) - // : Text( - // '登录/注册', - // style: TextStyle( - // fontSize: 32.sp, - // color: Color(0xffad8940), - // ), - // )), - // ], - // ), - // ), - // ), - // // Stack( - // // children: [ - // // Positioned( - // // bottom: 0, - // // left: 0, - // // right: 0, - // // child: Container( - // // height: 41.w, - // // width: double.infinity, - // // child: CustomPaint( - // // painter: UserBottomBarPainter(), - // // ), - // // ), - // // ), - // // Container( - // // margin: EdgeInsets.only( - // // top: 38.w, - // // left: 36.w, - // // right: 36.w, - // // bottom: 18.w, - // // ), - // // child: Image.asset( - // // R.ASSETS_IMAGES_MEMBER_BG_PNG, - // // width: 678.w, - // // height: 129.w, - // // ), - // // ), - // // ], - // // ), - // ], - // ), - // ), - Container( width: double.infinity, height: 441.w, @@ -365,7 +258,6 @@ class _PersonalIndexState extends State 24.wb, ], ), - MaterialButton( padding: EdgeInsets.all(5.w), onPressed: () { @@ -437,39 +329,24 @@ class _PersonalIndexState extends State color: Color(0xffad8940), ), )), + Spacer(), + MaterialButton( + onPressed: () { + Get.to(() => ClockInPage()); + }, + elevation: 0, + color: Colors.white, + minWidth: 112.w, + height: 58.w, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50.w)), + child: '签到'.text.size(22.sp).black.make(), + ), + 32.w.widthBox, ], ), ), ), - // Stack( - // children: [ - // Positioned( - // bottom: 0, - // left: 0, - // right: 0, - // child: Container( - // height: 41.w, - // width: double.infinity, - // child: CustomPaint( - // painter: UserBottomBarPainter(), - // ), - // ), - // ), - // Container( - // margin: EdgeInsets.only( - // top: 38.w, - // left: 36.w, - // right: 36.w, - // bottom: 18.w, - // ), - // child: Image.asset( - // R.ASSETS_IMAGES_MEMBER_BG_PNG, - // width: 678.w, - // height: 129.w, - // ), - // ), - // ], - // ), ], ), ), @@ -614,12 +491,6 @@ class _PersonalIndexState extends State canBack: false, ), ''), - - // - // ApplicationView.custom( - // items: userAppObjects, - // needAllApp: false, - // ), ], ), ), diff --git a/lib/provider/user_provider.dart b/lib/provider/user_provider.dart index 03aeaba7..95471e90 100644 --- a/lib/provider/user_provider.dart +++ b/lib/provider/user_provider.dart @@ -13,7 +13,6 @@ import 'package:aku_new_community/utils/websocket/web_socket_util.dart'; import 'package:aku_new_community/widget/others/user_tool.dart'; import 'package:flustars/flustars.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jpush_flutter/jpush_flutter.dart'; import 'package:power_logger/power_logger.dart';