diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a9cbb89 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "sk_base_mobile", + "request": "launch", + "type": "dart" + }, + { + "name": "sk_base_mobile (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "sk_base_mobile (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/android/app/src/main/res/drawable-land/background.png b/android/app/src/main/res/drawable-land/background.png new file mode 100644 index 0000000..d3fbf10 Binary files /dev/null and b/android/app/src/main/res/drawable-land/background.png differ diff --git a/android/app/src/main/res/drawable-land/launch_background.xml b/android/app/src/main/res/drawable-land/launch_background.xml new file mode 100644 index 0000000..f88598c --- /dev/null +++ b/android/app/src/main/res/drawable-land/launch_background.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/edit_icon.png b/assets/images/edit_icon.png new file mode 100644 index 0000000..3132186 Binary files /dev/null and b/assets/images/edit_icon.png differ diff --git a/assets/images/mine_bg.png b/assets/images/mine_bg.png new file mode 100644 index 0000000..26d2615 Binary files /dev/null and b/assets/images/mine_bg.png differ diff --git a/assets/images/photo_icon.png b/assets/images/photo_icon.png new file mode 100644 index 0000000..2c82a1c Binary files /dev/null and b/assets/images/photo_icon.png differ diff --git a/flutter_native_splash.yaml b/flutter_native_splash.yaml index 8adc6ed..1a5fe72 100644 --- a/flutter_native_splash.yaml +++ b/flutter_native_splash.yaml @@ -1,2 +1,8 @@ flutter_native_splash: background_image: 'assets/images/launch_image.jpg' + android: true + ios: true + landscape: + image: assets/images/launch_image_landscape.jpg + android: true + ios: true diff --git a/lib/apis/api.dart b/lib/apis/api.dart index 5b17a1b..7ed29ed 100644 --- a/lib/apis/api.dart +++ b/lib/apis/api.dart @@ -5,10 +5,19 @@ import 'package:sk_base_mobile/constants/global_url.dart'; import 'package:sk_base_mobile/services/dio.service.dart'; import '../constants/constants.dart'; -Future login(String? oauthType, String? token) { - return DioService.dio.post(Urls.login, - data: {'oauthType': oauthType, 'token': token}, - options: Options(contentType: "application/x-www-form-urlencoded")); +// 登录 +Future login(String username, String password) { + return DioService.dio.post( + Urls.login, + data: {'username': username, 'password': password}, + ); +} + +// 获取个人信息 +Future getUserInfo() { + return DioService.dio.get( + Urls.getUserInfo, + ); } Future logout() { @@ -32,13 +41,6 @@ Future saveUserInfo(Map data) { return DioService.dio.post(Urls.saveUserInfo, data: data); } -Future getUserInfo(String userId) { - Map data = { - "userId": userId, - }; - return DioService.dio.get(Urls.getUserInfo, queryParameters: data); -} - Future uploadImg(File file) async { // DateTime dateTime = DateTime.now(); // String fileName = file.path.split('/').last; diff --git a/lib/app_theme.dart b/lib/app_theme.dart index 697b0be..88dbcc9 100644 --- a/lib/app_theme.dart +++ b/lib/app_theme.dart @@ -19,7 +19,7 @@ class AppTheme { static const Color snackbarErrorBackgroudColor = Colors.red; static const Color snackbarSuccessBackgroudColor = Colors.green; static const Color snackbarWarningBackgroudColor = Colors.orange; - static const Color dismissibleBackground = Color(0xFF364A54); + static Color barrierColor = Colors.black.withOpacity(0.5); static const String fontName = 'NotoSans'; } @@ -33,6 +33,11 @@ final theme = ThemeData( dividerColor: AppTheme.grey, cardColor: AppTheme.white, scaffoldBackgroundColor: AppTheme.nearlyWhite, + bottomNavigationBarTheme: BottomNavigationBarThemeData( + backgroundColor: AppTheme.nearlyWhite, + unselectedLabelStyle: TextStyle(fontSize: ScreenAdaper.sp(20)), + selectedLabelStyle: TextStyle(fontSize: ScreenAdaper.sp(20)), + selectedItemColor: AppTheme.primaryColor), tabBarTheme: TabBarTheme( indicator: BoxDecoration( border: @@ -44,7 +49,7 @@ final theme = ThemeData( backgroundColor: AppTheme.primaryColor, titleTextStyle: TextStyle( color: Colors.black, - fontSize: ScreenAdaper.sp(20), + fontSize: ScreenAdaper.sp(25), fontWeight: FontWeight.bold), ), inputDecorationTheme: InputDecorationTheme( diff --git a/lib/config.dart b/lib/config.dart index dd66a9b..ae92f66 100644 --- a/lib/config.dart +++ b/lib/config.dart @@ -1,6 +1,7 @@ /// Global config class GloablConfig { - static const BASE_URL = "http://172.21.128.1:3000/"; + // static const BASE_URL = "http://172.21.128.1:3000/api"; + static const BASE_URL = "http://10.0.2.2:7001/api/"; static const DOMAIN_NAME = "山矿通"; static const DEBUG = true; static const PRIVACY_POLICY = 'http://h5.heeru.xyz/privacyPolicy.html'; diff --git a/lib/constants/global_url.dart b/lib/constants/global_url.dart index 8d9d512..46ded4a 100644 --- a/lib/constants/global_url.dart +++ b/lib/constants/global_url.dart @@ -1,27 +1,10 @@ class Urls { static String getAppConfig = 'config/getAppConfig'; - static String login = 'security/oauth'; + static String login = 'auth/login'; static String isValidToken = 'security/isValidToken'; static String logout = 'security/logout'; static String deleteAccount = 'user/deleteAccount'; - static String rankList = 'broadcaster/wall/search'; - static String addFriend = 'user/addFriend'; - static String removeFriend = 'user/unfriend'; - static String goodsList = 'coin/goods/search'; static String saveUserInfo = 'user/saveUserInfo'; - static String getUserInfo = 'user/getUserInfo'; - static String getOssPolicy = 'user/oss/policy'; + static String getUserInfo = 'account/profile'; static String updateAvatar = 'user/updateAvatar'; - static String getFollowedList = 'user/getFriendsListPage'; - static String reportComplain = 'report/complain/insertRecord'; - static String blockList = 'report/complain/blockList'; - static String unblock = 'report/complain/removeBlock'; - static String googleTranslate = - 'https://translation.googleapis.com/language/translate/v2'; - static String getIMStrategy = 'config/getStrategy'; - static String getIMToken = 'user/rongcloud/token'; - static String trackingLog = 'log/live-chat'; - static String createOrder = 'coin/recharge/create'; - static String validateOrder = 'coin/recharge/payment/ipa'; - static String reviewModeConsume = 'coin/reviewModeConsume'; } diff --git a/lib/global.dart b/lib/global.dart index 21b0f5a..55fc531 100644 --- a/lib/global.dart +++ b/lib/global.dart @@ -7,6 +7,7 @@ import 'package:sk_base_mobile/services/app_info.service.dart'; import 'package:sk_base_mobile/services/dio.service.dart'; import 'package:sk_base_mobile/services/storage.service.dart'; import 'store/store.dart'; +import 'package:flutter_native_splash/flutter_native_splash.dart'; /// 全局注册 class Global { diff --git a/lib/models/app_bottom_nav_item.dart b/lib/models/app_bottom_nav_item.dart index b8747d4..85b6511 100644 --- a/lib/models/app_bottom_nav_item.dart +++ b/lib/models/app_bottom_nav_item.dart @@ -1,9 +1,10 @@ import 'package:flutter/cupertino.dart'; class AppBottomNavItem { - String? icon; - String? activeIcon; + Icon icon; + Icon activeIcon; String? label; Widget? page; - AppBottomNavItem({this.icon, this.activeIcon, this.label, this.page}); + AppBottomNavItem( + {required this.icon, required this.activeIcon, this.label, this.page}); } diff --git a/lib/models/auth.dart b/lib/models/auth.dart index b122d08..0347d4b 100644 --- a/lib/models/auth.dart +++ b/lib/models/auth.dart @@ -1,27 +1,15 @@ -import 'package:sk_base_mobile/models/user_info.model.dart'; - class Auth { - bool? isFirstRegister; String? token; - UserInfoModel? userInfo; - Auth({this.isFirstRegister, this.token, this.userInfo}); + Auth({this.token}); Auth.fromJson(Map json) { - isFirstRegister = json['isFirstRegister']; token = json['token']; - userInfo = json['userInfo'] != null - ? UserInfoModel.fromJson(json['userInfo']) - : null; } Map toJson() { final Map data = Map(); - data['isFirstRegister'] = isFirstRegister; data['token'] = token; - if (userInfo != null) { - data['userInfo'] = userInfo!.toJson(); - } return data; } } diff --git a/lib/models/role.model.dart b/lib/models/role.model.dart new file mode 100644 index 0000000..432fb28 --- /dev/null +++ b/lib/models/role.model.dart @@ -0,0 +1,40 @@ +class RoleModel { + int? id; + String? createdAt; + String? updatedAt; + String? name; + String? value; + String? remark; + int? status; + + RoleModel( + {this.id, + this.createdAt, + this.updatedAt, + this.name, + this.value, + this.remark, + this.status}); + + RoleModel.fromJson(Map json) { + id = json['id']; + createdAt = json['createdAt']; + updatedAt = json['updatedAt']; + name = json['name']; + value = json['value']; + remark = json['remark']; + status = json['status']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['createdAt'] = createdAt; + data['updatedAt'] = updatedAt; + data['name'] = name; + data['value'] = value; + data['remark'] = remark; + data['status'] = status; + return data; + } +} diff --git a/lib/models/user_info.model.dart b/lib/models/user_info.model.dart index 45a9eec..87e9f9a 100644 --- a/lib/models/user_info.model.dart +++ b/lib/models/user_info.model.dart @@ -1,230 +1,69 @@ -class UserInfoModel { - String? userId; - int? userType; - String? nickname; - bool? isInternal; - String? avatar; - String? avatarUrl; - String? avatarThumbUrl; - String? avatarMiddleThumbUrl; - List? mediumList; - List? avatarRespList; - int? gender; - String? birthday; - int? age; - String? country; - String? pkgName; - bool? isAnswer; - int? availableCoins; - int? auditStatus; - bool? isShowReviewSupplementTips; - List? tagsList; - List? tagDetails; - String? rongcloudToken; - bool? isRecharge; - bool? isVip; - int? level; - int? followNum; - int? praiseNum; - bool? isBlock; - bool? isSwitchNotDisturbIm; - bool? isSwitchNotDisturbCall; - bool? isHavePassword; - bool? isReview; - bool? isMultiple; - String? registerPkgName; - String? registerCountry; - String? loginPkgName; - int? giftWallAction; +import 'package:sk_base_mobile/models/role.model.dart'; - UserInfoModel({ - this.userId, - this.userType, - this.nickname, - this.isInternal, - this.avatar, - this.avatarUrl, - this.avatarThumbUrl, - this.avatarMiddleThumbUrl, - this.mediumList, - this.avatarRespList, - this.gender, - this.birthday, - this.age, - this.country, - this.pkgName, - this.isAnswer, - this.availableCoins, - this.auditStatus, - this.isShowReviewSupplementTips, - this.tagsList, - this.tagDetails, - this.rongcloudToken, - this.isRecharge, - this.isVip, - this.level, - this.followNum, - this.praiseNum, - this.isBlock, - this.isSwitchNotDisturbIm, - this.isSwitchNotDisturbCall, - this.isHavePassword, - this.isReview, - this.isMultiple, - this.registerPkgName, - this.registerCountry, - this.loginPkgName, - this.giftWallAction, - }); +class UserInfoModel { + int? id; + String? createdAt; + String? updatedAt; + String? username; + String? nickname; + String? avatar; + String? qq; + String? email; + String? phone; + String? remark; + int? status; + List? roles; + + UserInfoModel( + {this.id, + this.createdAt, + this.updatedAt, + this.username, + this.nickname, + this.avatar, + this.qq, + this.email, + this.phone, + this.remark, + this.status, + this.roles}); UserInfoModel.fromJson(Map json) { - userId = json['userId']; - userType = json['userType']; + id = json['id']; + createdAt = json['createdAt']; + updatedAt = json['updatedAt']; + username = json['username']; nickname = json['nickname']; - isInternal = json['isInternal']; avatar = json['avatar']; - avatarUrl = json['avatarUrl']; - avatarThumbUrl = json['avatarThumbUrl']; - avatarMiddleThumbUrl = json['avatarMiddleThumbUrl']; - - if (json['avatarRespList'] != null) { - avatarRespList = []; - json['avatarRespList'].forEach((v) { - avatarRespList!.add(AvatarRespList.fromJson(v)); + qq = json['qq']; + email = json['email']; + phone = json['phone']; + remark = json['remark']; + status = json['status']; + if (json['roles'] != null) { + roles = []; + json['roles'].forEach((v) { + roles!.add(RoleModel.fromJson(v)); }); } - gender = json['gender']; - birthday = json['birthday']; - age = json['age']; - country = json['country']; - pkgName = json['pkgName']; - - isAnswer = json['isAnswer']; - availableCoins = json['availableCoins']; - auditStatus = json['auditStatus']; - isShowReviewSupplementTips = json['isShowReviewSupplementTips']; - if (json['tagsList'] != null) { - tagsList = []; - json['tagsList'].forEach((v) { - tagsList!.add(v); - }); - } - if (json['tagDetails'] != null) { - tagDetails = []; - json['tagDetails'].forEach((v) { - tagDetails!.add(TagDetails.fromJson(v)); - }); - } - rongcloudToken = json['rongcloudToken']; - isRecharge = json['isRecharge']; - isVip = json['isVip']; - level = json['level']; - followNum = json['followNum']; - praiseNum = json['praiseNum']; - isBlock = json['isBlock']; - isSwitchNotDisturbIm = json['isSwitchNotDisturbIm']; - isSwitchNotDisturbCall = json['isSwitchNotDisturbCall']; - isHavePassword = json['isHavePassword']; - isReview = json['isReview']; - isMultiple = json['isMultiple']; - registerPkgName = json['registerPkgName']; - registerCountry = json['registerCountry']; - loginPkgName = json['loginPkgName']; - giftWallAction = json['giftWallAction']; } Map toJson() { - final Map data = Map(); - data['userId'] = userId; - data['userType'] = userType; + final Map data = {}; + data['id'] = id; + data['createdAt'] = createdAt; + data['updatedAt'] = updatedAt; + data['username'] = username; data['nickname'] = nickname; - data['isInternal'] = isInternal; data['avatar'] = avatar; - data['avatarUrl'] = avatarUrl; - data['avatarThumbUrl'] = avatarThumbUrl; - data['avatarMiddleThumbUrl'] = avatarMiddleThumbUrl; - if (this.avatarRespList != null) { - data['avatarRespList'] = avatarRespList!.map((v) => v.toJson()).toList(); + data['qq'] = qq; + data['email'] = email; + data['phone'] = phone; + data['remark'] = remark; + data['status'] = status; + if (roles != null) { + data['roles'] = roles!.map((v) => v.toJson()).toList(); } - data['gender'] = gender; - data['birthday'] = birthday; - data['age'] = age; - data['country'] = country; - data['pkgName'] = pkgName; - - data['isAnswer'] = isAnswer; - data['availableCoins'] = availableCoins; - data['auditStatus'] = auditStatus; - data['isShowReviewSupplementTips'] = isShowReviewSupplementTips; - if (this.tagsList != null) { - data['tagsList'] = tagsList!.map((v) => v).toList(); - } - if (this.tagDetails != null) { - data['tagDetails'] = tagDetails!.map((v) => v.toJson()).toList(); - } - data['rongcloudToken'] = rongcloudToken; - data['isRecharge'] = isRecharge; - data['isVip'] = isVip; - data['level'] = level; - data['followNum'] = followNum; - data['praiseNum'] = praiseNum; - data['isBlock'] = isBlock; - data['isSwitchNotDisturbIm'] = isSwitchNotDisturbIm; - data['isSwitchNotDisturbCall'] = isSwitchNotDisturbCall; - data['isHavePassword'] = isHavePassword; - data['isReview'] = isReview; - data['isMultiple'] = isMultiple; - data['registerPkgName'] = registerPkgName; - data['registerCountry'] = registerCountry; - data['loginPkgName'] = loginPkgName; - data['giftWallAction'] = giftWallAction; - return data; - } -} - -class AvatarRespList { - String? mediaPath; - String? mediaUrl; - String? middleThumbUrl; - String? thumbUrl; - - AvatarRespList({this.mediaPath, mediaUrl, middleThumbUrl, thumbUrl}); - - AvatarRespList.fromJson(Map json) { - mediaPath = json['mediaPath']; - mediaUrl = json['mediaUrl']; - middleThumbUrl = json['middleThumbUrl']; - thumbUrl = json['thumbUrl']; - } - - Map toJson() { - final Map data = Map(); - data['mediaPath'] = mediaPath; - data['mediaUrl'] = mediaUrl; - data['middleThumbUrl'] = middleThumbUrl; - data['thumbUrl'] = thumbUrl; - return data; - } -} - -class TagDetails { - String? tag; - String? tagTip; - String? tagColor; - - TagDetails({this.tag, tagTip, tagColor}); - - TagDetails.fromJson(Map json) { - tag = json['tag']; - tagTip = json['tagTip']; - tagColor = json['tagColor']; - } - - Map toJson() { - final Map data = Map(); - data['tag'] = tag; - data['tagTip'] = tagTip; - data['tagColor'] = tagColor; return data; } } diff --git a/lib/screens/home/home.dart b/lib/screens/home/home.dart index 0ff65ec..7adc960 100644 --- a/lib/screens/home/home.dart +++ b/lib/screens/home/home.dart @@ -5,6 +5,9 @@ class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { - return const Placeholder(); + return Scaffold( + appBar: AppBar(title: Text('首页')), + body: SizedBox(child: Text('sss')), + ); } } diff --git a/lib/screens/landing/zt_landing.dart b/lib/screens/landing/zt_landing.dart index 67d1f38..827f476 100644 --- a/lib/screens/landing/zt_landing.dart +++ b/lib/screens/landing/zt_landing.dart @@ -34,26 +34,16 @@ class _LandingPageState extends State { AppInfoService.to.bottomNavItems!; bottomNavItems = roleWithBottomNavItems .map((e) => BottomNavigationBarItem( - icon: Image.asset( - e.icon!, - height: ScreenAdaper.width(30), - width: ScreenAdaper.width(30), - ), - activeIcon: Image.asset( - e.activeIcon!, - height: ScreenAdaper.width(30), - width: ScreenAdaper.width(30), - ), - label: e.label)) + icon: e.icon, activeIcon: e.activeIcon, label: e.label)) .toList(); pages = roleWithBottomNavItems.map((e) => e.page!).toList(); return Scaffold( bottomNavigationBar: BottomNavigationBar( - iconSize: ScreenAdaper.sp(25), + iconSize: ScreenAdaper.sp(40), type: BottomNavigationBarType.fixed, items: bottomNavItems, - showSelectedLabels: false, - showUnselectedLabels: false, + showSelectedLabels: true, + showUnselectedLabels: true, currentIndex: _selectedLanding, onTap: (landing) { _onItemTapped(landing); diff --git a/lib/screens/login/login.controller.dart b/lib/screens/login/login.controller.dart index 8fd0a65..dafcab7 100644 --- a/lib/screens/login/login.controller.dart +++ b/lib/screens/login/login.controller.dart @@ -9,10 +9,14 @@ class LoginController extends GetxController { final isAgreeTerm = RxBool(false); final formKey = GlobalKey(); final passwordFocusNode = FocusNode(); + String username = ''; + String password = ''; bool loading = false; Future doLogin() async { if (!formKey.currentState!.validate()) { return; } + // 拿出form中的数据 + AuthStore.to.login(username: username, password: password); } } diff --git a/lib/screens/login/login.dart b/lib/screens/login/login.dart index ddbf4af..a239cec 100644 --- a/lib/screens/login/login.dart +++ b/lib/screens/login/login.dart @@ -162,7 +162,9 @@ class LoginScreen extends StatelessWidget { _controller.passwordFocusNode.requestFocus(); }, style: TextStyle(fontSize: ScreenAdaper.sp(25)), - onChanged: (value) {}, + onChanged: (value) { + _controller.username = value; + }, ); } @@ -181,8 +183,11 @@ class LoginScreen extends StatelessWidget { onFieldSubmitted: (value) { _controller.doLogin(); }, + style: TextStyle(fontSize: ScreenAdaper.sp(25)), - onChanged: (value) {}, + onChanged: (value) { + _controller.password = value; + }, // validator: (String? value) { // return (value ?? '').length >= 6 ? null : '密码长度至少6位'; // }, diff --git a/lib/screens/mine/mine.dart b/lib/screens/mine/mine.dart index 88f87dc..27d37ae 100644 --- a/lib/screens/mine/mine.dart +++ b/lib/screens/mine/mine.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:sk_base_mobile/screens/mine/mine.controller.dart'; +import 'package:sk_base_mobile/screens/mine/settings/mine_settings.dart'; // import 'package:sk_base_mobile/screens/mine/mine_about.dart'; // import 'package:sk_base_mobile/screens/mine/mine_block.dart'; // import 'package:sk_base_mobile/screens/mine/mine_mytickets.dart'; @@ -29,10 +30,6 @@ class _MinePageState extends State @override void initState() { super.initState(); - _controller.tabController ??= TabController( - initialIndex: _controller.selectedTabIndex.value, - length: 4, - vsync: this); } @override @@ -41,7 +38,7 @@ class _MinePageState extends State } Widget _buildBody() { - return Column(mainAxisSize: MainAxisSize.max, children: [ + return Column(children: [ Container( height: ScreenAdaper.height(360), width: ScreenAdaper.screenWidth(), @@ -115,7 +112,7 @@ class _MinePageState extends State SizedBox( width: ScreenAdaper.width(210), child: Text( - 'ID: ${AuthStore.to.userInfo.value.userId}', + 'ID: ${AuthStore.to.userInfo.value.id}', overflow: TextOverflow.ellipsis, maxLines: 2, style: TextStyle( @@ -149,65 +146,20 @@ class _MinePageState extends State ]), ), ), - Expanded( - child: DefaultTabController( - length: 4, - initialIndex: _controller.selectedTabIndex.value, - child: Scaffold( - backgroundColor: AppTheme.white, - appBar: AppBar( - backgroundColor: AppTheme.white, - elevation: 0, - automaticallyImplyLeading: false, - flexibleSpace: _buildTabBar(), - ), - body: _buildTabView()))) + Expanded(child: MineSettingsPage()) + // Expanded( + // child: DefaultTabController( + // length: 4, + // initialIndex: _controller.selectedTabIndex.value, + // child: Scaffold( + // backgroundColor: AppTheme.white, + // appBar: AppBar( + // backgroundColor: AppTheme.white, + // elevation: 0, + // automaticallyImplyLeading: false, + // flexibleSpace: _buildTabBar(), + // ), + // body: _buildTabView()))) ]); } - - Widget _buildTabBar() { - final tabs = _controller.mineTabs - .asMap() - .map((index, item) { - return MapEntry( - index, - Obx( - () => Tab( - child: Image( - image: AssetImage( - 'assets/images/$item${_controller.selectedTabIndex.value == index ? '_active' : ''}.png'))), - )); - }) - .values - .toList(); - - return Container( - margin: EdgeInsets.only(top: ScreenAdaper.height(20)), - padding: EdgeInsets.symmetric(vertical: ScreenAdaper.height(10)), - decoration: const BoxDecoration( - border: Border.symmetric( - horizontal: BorderSide(color: Color(0xFFCCCCCC)))), - child: TabBar( - controller: _controller.tabController, - tabs: tabs, - indicator: const BoxDecoration(), - onTap: (index) { - _controller.selectedTabIndex.value = index; - }, /* */ - ), - ); - } - - Widget _buildTabView() { - return TabBarView( - controller: _controller.tabController, - physics: const NeverScrollableScrollPhysics(), - children: [ - SizedBox(), - SizedBox(), - SizedBox(), - SizedBox(), - ], - ); - } } diff --git a/lib/screens/mine/settings/mine.controller.dart b/lib/screens/mine/settings/mine.controller.dart new file mode 100644 index 0000000..763a7e2 --- /dev/null +++ b/lib/screens/mine/settings/mine.controller.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/models/mine_about.model.dart'; + +class MineController extends GetxController { + final selectedTabIndex = 0.obs; + TabController? tabController; + + @override + void onInit() { + super.onInit(); + } +} diff --git a/lib/screens/mine/settings/mine_settings.dart b/lib/screens/mine/settings/mine_settings.dart new file mode 100644 index 0000000..7f722d7 --- /dev/null +++ b/lib/screens/mine/settings/mine_settings.dart @@ -0,0 +1,71 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/app_theme.dart'; +import 'package:sk_base_mobile/screens/mine/mine.controller.dart'; +import 'package:sk_base_mobile/store/auth.store.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; + +class MineSettingsPage extends StatelessWidget { + final _controller = Get.find(); + MineSettingsPage({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(horizontal: ScreenAdaper.width(15)), + child: ListView.separated( + separatorBuilder: (_, index) => const Divider( + color: Color(0xFFCCCCCC), + ), + itemBuilder: ((_, index) => _buildSettingsItem( + index, + )), + itemCount: 4), + ); + } + + Widget _buildSettingsItem(int index) { + switch (index) { + // auto translate + case 0: + return Container( + padding: EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)), + child: Row( + children: [], + )); + case 1: + return InkWell( + onTap: () async { + await AuthStore.to.deleteAccount(); + }, + child: Container( + padding: EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)), + child: Row( + children: [ + Text( + 'Delete acount', + style: TextStyle(fontSize: ScreenAdaper.sp(18)), + ), + ], + ))); + case 2: + return InkWell( + onTap: () async { + await AuthStore.to.logout(force: true); + }, + child: Container( + padding: EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)), + child: Row( + children: [ + Text( + 'Logout', + style: TextStyle(fontSize: ScreenAdaper.sp(18)), + ), + ], + ))); + default: + return SizedBox(); + } + } +} diff --git a/lib/screens/mine/useinfo/userinfo.controller.dart b/lib/screens/mine/useinfo/userinfo.controller.dart index fa24420..ecbf77f 100644 --- a/lib/screens/mine/useinfo/userinfo.controller.dart +++ b/lib/screens/mine/useinfo/userinfo.controller.dart @@ -6,22 +6,16 @@ import 'package:sk_base_mobile/apis/api.dart' as Api; class UserInfoController extends GetxController { final nickNameController = TextEditingController(text: ''); - final countryController = TextEditingController(text: ''); - final birthdayController = TextEditingController(); @override void onReady() async { nickNameController.text = AuthStore.to.userInfo.value.nickname ?? ''; - birthdayController.text = AuthStore.to.userInfo.value.birthday ?? ''; - countryController.text = AuthStore.to.userInfo.value.country ?? ''; super.onReady(); } Future saveUserInfo() async { Map data = { 'nickname': nickNameController.text, - 'birthday': birthdayController.text, - 'country': countryController.text, }; await AuthStore.to.saveUserInfo(data); } diff --git a/lib/screens/mine/useinfo/userinfo.dart b/lib/screens/mine/useinfo/userinfo.dart index 97b1212..356b7ff 100644 --- a/lib/screens/mine/useinfo/userinfo.dart +++ b/lib/screens/mine/useinfo/userinfo.dart @@ -74,109 +74,109 @@ class UserInfoPage extends StatelessWidget { SizedBox( height: ScreenAdaper.height(15), ), - TextFormField( - controller: _controller.birthdayController, - decoration: InputDecoration( - contentPadding: EdgeInsets.fromLTRB( - ScreenAdaper.width(12), 0, ScreenAdaper.width(12), 0), - labelText: "Date of birth", - labelStyle: TextStyle( - color: const Color.fromARGB(255, 136, 136, 136), - fontSize: ScreenAdaper.sp(18)), - enabledBorder: const UnderlineInputBorder( - borderSide: BorderSide( - color: Color.fromARGB(153, 191, 190, 190), - ), - ), - focusedBorder: const UnderlineInputBorder( - borderSide: BorderSide( - color: Color.fromARGB(153, 191, 190, 190), - ), - ), - ), - onTap: () async { - await showCupertinoModalPopup( - context: Get.context!, - builder: (context) => Container( - color: Colors.white, - height: 300, - child: CupertinoDatePicker( - initialDateTime: DateTime.parse( - _controller.birthdayController.text), - minimumDate: DateTime(1900), - maximumDate: DateTime.now() - .subtract(const Duration(days: 18 * 365)), - minimumYear: DateTime(1900).year, - maximumYear: DateTime.now() - .subtract(const Duration(days: 18 * 365)) - .year, - mode: CupertinoDatePickerMode.date, - onDateTimeChanged: (pickeddate) { - _controller.birthdayController.text = - formatDate(pickeddate, [ - yyyy, - '-', - mm, - '-', - dd, - ]); - }), - )); - }, - style: - TextStyle(fontSize: ScreenAdaper.sp(18), color: Colors.black), - cursorColor: const Color.fromARGB(255, 87, 86, 86)), + // TextFormField( + // controller: _controller.birthdayController, + // decoration: InputDecoration( + // contentPadding: EdgeInsets.fromLTRB( + // ScreenAdaper.width(12), 0, ScreenAdaper.width(12), 0), + // labelText: "Date of birth", + // labelStyle: TextStyle( + // color: const Color.fromARGB(255, 136, 136, 136), + // fontSize: ScreenAdaper.sp(18)), + // enabledBorder: const UnderlineInputBorder( + // borderSide: BorderSide( + // color: Color.fromARGB(153, 191, 190, 190), + // ), + // ), + // focusedBorder: const UnderlineInputBorder( + // borderSide: BorderSide( + // color: Color.fromARGB(153, 191, 190, 190), + // ), + // ), + // ), + // onTap: () async { + // await showCupertinoModalPopup( + // context: Get.context!, + // builder: (context) => Container( + // color: Colors.white, + // height: 300, + // child: CupertinoDatePicker( + // initialDateTime: DateTime.parse( + // _controller.birthdayController.text), + // minimumDate: DateTime(1900), + // maximumDate: DateTime.now() + // .subtract(const Duration(days: 18 * 365)), + // minimumYear: DateTime(1900).year, + // maximumYear: DateTime.now() + // .subtract(const Duration(days: 18 * 365)) + // .year, + // mode: CupertinoDatePickerMode.date, + // onDateTimeChanged: (pickeddate) { + // _controller.birthdayController.text = + // formatDate(pickeddate, [ + // yyyy, + // '-', + // mm, + // '-', + // dd, + // ]); + // }), + // )); + // }, + // style: + // TextStyle(fontSize: ScreenAdaper.sp(18), color: Colors.black), + // cursorColor: const Color.fromARGB(255, 87, 86, 86)), SizedBox( height: ScreenAdaper.height(15), ), - TextFormField( - controller: _controller.countryController, - decoration: InputDecoration( - contentPadding: EdgeInsets.fromLTRB( - ScreenAdaper.width(12), 0, ScreenAdaper.width(12), 0), - labelText: "Country", - labelStyle: TextStyle( - color: const Color.fromARGB(255, 136, 136, 136), - fontSize: ScreenAdaper.sp(18)), - enabledBorder: const UnderlineInputBorder( - borderSide: BorderSide( - color: Color.fromARGB(153, 191, 190, 190), - ), - ), - focusedBorder: const UnderlineInputBorder( - borderSide: BorderSide( - color: Color.fromARGB(153, 191, 190, 190), - ), - ), - ), - onTap: () async { - await showCupertinoModalPopup( - context: Get.context!, - builder: (context) => Container( - color: Colors.white, - height: 300, - child: CupertinoPicker( - itemExtent: 50, - onSelectedItemChanged: (index) { - _controller.countryController.text = - Data.countryCodes[index]; - }, - children: Data.countryCodes - .map((e) => Container( - height: ScreenAdaper.height(50), - alignment: Alignment.center, - child: Text( - e, - style: TextStyle( - fontSize: ScreenAdaper.sp(30)), - ), - )) - .toList(), - ))); - }, - style: - TextStyle(fontSize: ScreenAdaper.sp(18), color: Colors.black), - cursorColor: const Color.fromARGB(255, 87, 86, 86)) + // TextFormField( + // controller: _controller.countryController, + // decoration: InputDecoration( + // contentPadding: EdgeInsets.fromLTRB( + // ScreenAdaper.width(12), 0, ScreenAdaper.width(12), 0), + // labelText: "Country", + // labelStyle: TextStyle( + // color: const Color.fromARGB(255, 136, 136, 136), + // fontSize: ScreenAdaper.sp(18)), + // enabledBorder: const UnderlineInputBorder( + // borderSide: BorderSide( + // color: Color.fromARGB(153, 191, 190, 190), + // ), + // ), + // focusedBorder: const UnderlineInputBorder( + // borderSide: BorderSide( + // color: Color.fromARGB(153, 191, 190, 190), + // ), + // ), + // ), + // onTap: () async { + // await showCupertinoModalPopup( + // context: Get.context!, + // builder: (context) => Container( + // color: Colors.white, + // height: 300, + // child: CupertinoPicker( + // itemExtent: 50, + // onSelectedItemChanged: (index) { + // _controller.countryController.text = + // Data.countryCodes[index]; + // }, + // children: Data.countryCodes + // .map((e) => Container( + // height: ScreenAdaper.height(50), + // alignment: Alignment.center, + // child: Text( + // e, + // style: TextStyle( + // fontSize: ScreenAdaper.sp(30)), + // ), + // )) + // .toList(), + // ))); + // }, + // style: + // TextStyle(fontSize: ScreenAdaper.sp(18), color: Colors.black), + // cursorColor: const Color.fromARGB(255, 87, 86, 86)) ], ); } diff --git a/lib/services/app_info.service.dart b/lib/services/app_info.service.dart index d9958e5..8d2c040 100644 --- a/lib/services/app_info.service.dart +++ b/lib/services/app_info.service.dart @@ -1,8 +1,10 @@ import 'dart:convert'; import 'dart:io'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:package_info/package_info.dart'; +import 'package:sk_base_mobile/app_theme.dart'; import 'package:sk_base_mobile/models/app_bottom_nav_item.dart'; import 'package:sk_base_mobile/models/app_config.dart'; import 'package:sk_base_mobile/screens/home/home.dart'; @@ -25,14 +27,18 @@ class AppInfoService extends GetxService { final isCameraing = RxBool(false); List? bottomNavItems = [ AppBottomNavItem( - icon: 'assets/images/landing_icon_bottom_0.png', - activeIcon: 'assets/images/landing_icon_bottom_active_0.png', - label: 'homepage', + icon: const Icon(Icons.home_outlined), + activeIcon: const Icon( + Icons.home, + ), + label: '首页', page: const HomePage()), AppBottomNavItem( - icon: 'assets/images/landing_icon_bottom_3.png', - activeIcon: 'assets/images/landing_icon_bottom_active_3.png', - label: 'mine', + icon: const Icon(Icons.person_outline_outlined), + activeIcon: const Icon( + Icons.person, + ), + label: '我的', page: MinePage()), ]; Future init() async { @@ -40,8 +46,8 @@ class AppInfoService extends GetxService { .info("[service-appInfo] Register app-related information service"); try { - await Future.wait( - [getDeviceInfo(), getPackageInfo(), getAppConfig(), getossPolicy()]); + // await Future.wait( + // [getDeviceInfo(), getPackageInfo(), getAppConfig(), getossPolicy()]); requestPermission(); } catch (e) { LoggerUtil().error(e); diff --git a/lib/services/dio.service.dart b/lib/services/dio.service.dart index 60fe18c..7b648c0 100644 --- a/lib/services/dio.service.dart +++ b/lib/services/dio.service.dart @@ -14,9 +14,9 @@ class DioService extends Get.GetxService { static DioService get to => Get.Get.find(); static Dio get dio => _dio; static late Dio _dio; - List whiteList = [Urls.googleTranslate]; + List whiteList = [Urls.login]; BaseOptions dioBaseOptions = BaseOptions( - connectTimeout: const Duration(minutes: 10), + connectTimeout: const Duration(seconds: 5), baseUrl: '${GloablConfig.BASE_URL}', followRedirects: true); @@ -33,7 +33,6 @@ class DioService extends Get.GetxService { void onError(DioException e, ErrorInterceptorHandler handler) async { if (whiteList.contains(e.requestOptions.path)) { - await SnackBarUtil().error(e.message); return handler.next(e); } if (GloablConfig.DEBUG) { @@ -139,31 +138,6 @@ class DioService extends Get.GetxService { if (response.data is String) { responseData = jsonDecode(response.data); } - switch (responseData['code']) { - case 0: - handler.next(response); - return; - // 其他设备登录 - case 10010304: - await AuthStore().logout(force: true); - await SnackBarUtil() - .error('Other devices have logged in, please log in again.'); - break; - case 100103: - case 10010303: - await AuthStore().logout(force: true); - await SnackBarUtil() - .error('Login has timed out, please log in again.'); - break; - case 10010301: - await AuthStore().logout(force: true); - await SnackBarUtil().error('Token can not empty'); - break; - default: - await SnackBarUtil() - .error('${responseData['key']}: ${responseData['msg']}'); - break; - } } catch (e) { printError(info: e.toString()); } diff --git a/lib/services/storage.service.dart b/lib/services/storage.service.dart index 8f61198..df072f4 100644 --- a/lib/services/storage.service.dart +++ b/lib/services/storage.service.dart @@ -15,7 +15,7 @@ class StorageService extends GetxService { {bool isWithUser = true}) async { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return await _prefs.setString(storeKey, value); } @@ -23,7 +23,7 @@ class StorageService extends GetxService { Future setBool(String key, bool value, {bool isWithUser = true}) async { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return await _prefs.setBool(storeKey, value); } @@ -31,7 +31,7 @@ class StorageService extends GetxService { Future setInt(String key, int value, {bool isWithUser = true}) async { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return await _prefs.setInt(storeKey, value); } @@ -40,7 +40,7 @@ class StorageService extends GetxService { {bool isWithUser = true}) async { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return await _prefs.setStringList(storeKey, value); } @@ -48,7 +48,7 @@ class StorageService extends GetxService { String? getString(String key, {bool isWithUser = true}) { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return _prefs.getString(storeKey); } @@ -56,7 +56,7 @@ class StorageService extends GetxService { int? getInt(String key, {bool isWithUser = true}) { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return _prefs.getInt(storeKey); } @@ -64,7 +64,7 @@ class StorageService extends GetxService { bool? getBool(String key, {bool isWithUser = true}) { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return _prefs.getBool(storeKey) ?? false; } @@ -72,7 +72,7 @@ class StorageService extends GetxService { List getList(String key, {bool isWithUser = true}) { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return _prefs.getStringList(storeKey) ?? []; } @@ -80,7 +80,7 @@ class StorageService extends GetxService { Future remove(String key, {bool isWithUser = true}) async { String storeKey = key; if (isWithUser) { - storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; + storeKey = '${AuthStore.to.userInfo.value.id}_$key'; } return await _prefs.remove(storeKey); } diff --git a/lib/store/auth.store.dart b/lib/store/auth.store.dart index 23fd73b..dcb0bd7 100644 --- a/lib/store/auth.store.dart +++ b/lib/store/auth.store.dart @@ -63,59 +63,49 @@ class AuthStore extends GetxController { } Future logout({bool force = false}) async { - await LoadingUtil.show(status: 'Logout...'); + LoadingUtil.show(status: 'Logout...'); await StorageService.to.remove(CacheKeys.token, isWithUser: false); await StorageService.to.remove(CacheKeys.userInfo, isWithUser: false); try { - final response = await Api.logout(); - if (response.data != null) { - LoggerUtil().info('[Store-Auth] Logout succeed.'); - if (Get.context != null) Get.offAllNamed(RouteConfig.login); - } + // final response = await Api.logout(); + // if (response.data != null) { + LoggerUtil().info('[Store-Auth] Logout succeed.'); + if (Get.context != null) Get.offAllNamed(RouteConfig.login); + // } } catch (e) { } finally { LoadingUtil.dismiss(); } } - Future login(LoginEnum type, {String? identityToken}) async { + Future login( + {required String username, required String password}) async { Dio.Response response; - if (type == LoginEnum.fastLogin && - StorageService.to.getString(CacheKeys.deviceUUID, isWithUser: false) == - null) { - SnackBarUtil().error('Need DeviceUUID. Please restart app.'); - return; - } + // if (type == LoginEnum.fastLogin && + // StorageService.to.getString(CacheKeys.deviceUUID, isWithUser: false) == + // null) { + // SnackBarUtil().error('Need DeviceUUID. Please restart app.'); + // return; + // } LoadingUtil.show(status: 'Login...'); - // Hide keyboard TapToDismissKeyboard.dismissOf(context: Get.context!); try { - response = await Api.login( - '4', - type == LoginEnum.fastLogin - ? (StorageService.to - .getString(CacheKeys.deviceUUID, isWithUser: false)) - : identityToken); - + await Future.delayed(const Duration(seconds: 1)); + response = await Api.login(username, password); if (response.data != null) { final auth = Auth.fromJson(response.data['data']); + if (auth.token != null) { await StorageService.to .setString(CacheKeys.token, auth.token!, isWithUser: false); } - if (auth.userInfo != null) { - userInfo(auth.userInfo!); - await StorageService.to.setString( - CacheKeys.userInfo, jsonEncode(auth.userInfo), - isWithUser: false); - LoggerUtil().info('[Store-Auth] Login succeed.'); - } + await getUserInfo(); Get.offNamed(RouteConfig.home); - getCommonInfo(); + // getCommonInfo(); } } catch (e) { - SnackBarUtil().error('${e}'); + await SnackBarUtil().error('账号密码错误'); } finally { LoadingUtil.dismiss(); } @@ -130,7 +120,7 @@ class AuthStore extends GetxController { Future getUserInfo() async { await LoadingUtil.show(status: 'Loading...'); try { - final response = await Api.getUserInfo(userInfo.value.userId!); + final response = await Api.getUserInfo(); if (response.data != null) { UserInfoModel userInfo = UserInfoModel.fromJson(response.data['data']); await updateUserInfoState(userInfo); diff --git a/lib/util/loading_util.dart b/lib/util/loading_util.dart index eb1f792..13b4595 100644 --- a/lib/util/loading_util.dart +++ b/lib/util/loading_util.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:loading_animation_widget/loading_animation_widget.dart'; +import 'package:sk_base_mobile/app_theme.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; -/// Loading工具 class LoadingUtil { - LoadingUtil() {} - init() {} + LoadingUtil(); static Future show({String? status}) async { return showLoading(status: status ?? 'Loading...'); @@ -14,27 +15,35 @@ class LoadingUtil { return hideLoading(); } - static showLoading({String? status}) { - Get.dialog( - GestureDetector( - child: Container( - color: Colors.black54, - child: const Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - ), - ), - onTap: () { - // 点击是否退出模态框 - Get.back(); - }, - ), + static showLoading({String? status}) async { + await showDialog( + context: Get.context!, + barrierColor: AppTheme.barrierColor, barrierDismissible: false, + builder: (BuildContext context) { + return WillPopScope( + onWillPop: () async => false, + child: GestureDetector( + child: Container( + color: Colors.black54, + child: Center( + child: LoadingAnimationWidget.fourRotatingDots( + color: AppTheme.primaryColor, + size: ScreenAdaper.sp(50), + ), + ), + ), + onTap: () { + // 点击是否退出模态框 + // Navigator.of(context).pop(); + }, + ), + ); + }, ); } static hideLoading() { - Get.back(); + Navigator.of(Get.context!).pop(); } } diff --git a/lib/util/snack_bar.util.dart b/lib/util/snack_bar.util.dart index 649188d..be2a37e 100644 --- a/lib/util/snack_bar.util.dart +++ b/lib/util/snack_bar.util.dart @@ -2,6 +2,7 @@ import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:sk_base_mobile/app_theme.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; // SnackBar 工具 class SnackBarUtil { @@ -25,13 +26,18 @@ class SnackBarUtil { await Get.closeCurrentSnackbar(); } Get.rawSnackbar( - message: title, snackPosition: SnackPosition.TOP, backgroundColor: AppTheme.snackbarErrorBackgroudColor, - borderRadius: 15, - margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0), + borderRadius: ScreenAdaper.sp(15), + messageText: Text( + '$title', + style: TextStyle( + fontSize: ScreenAdaper.sp(25), color: AppTheme.nearlyWhite), + ), + margin: EdgeInsets.symmetric( + horizontal: ScreenAdaper.width(20), vertical: 0), overlayColor: Colors.white, - duration: Duration(seconds: 3), + duration: const Duration(seconds: 3), forwardAnimationCurve: Curves.fastLinearToSlowEaseIn, reverseAnimationCurve: Curves.linearToEaseOut); } diff --git a/lib/widgets/my_avatar.dart b/lib/widgets/my_avatar.dart index 96ac159..9e7107a 100644 --- a/lib/widgets/my_avatar.dart +++ b/lib/widgets/my_avatar.dart @@ -51,7 +51,7 @@ class MyAvatarWidget extends StatelessWidget { return _controller.uploadImgFilePath.value.isNotEmpty ? FileImage(File(_controller.uploadImgFilePath.value)) : NetworkImage( - AuthStore.to.userInfo.value.avatarThumbUrl ?? '', + AuthStore.to.userInfo.value.avatar ?? '', ); } // Widget getShowImg() {