feat: 登录页 闪屏图

This commit is contained in:
louis 2024-03-19 08:59:08 +08:00
parent 78628e2242
commit 916272bf3b
32 changed files with 466 additions and 552 deletions

25
.vscode/launch.json vendored Normal file
View File

@ -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"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
</layer-list>

BIN
assets/images/edit_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/images/mine_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -1,2 +1,8 @@
flutter_native_splash: flutter_native_splash:
background_image: 'assets/images/launch_image.jpg' background_image: 'assets/images/launch_image.jpg'
android: true
ios: true
landscape:
image: assets/images/launch_image_landscape.jpg
android: true
ios: true

View File

@ -5,10 +5,19 @@ import 'package:sk_base_mobile/constants/global_url.dart';
import 'package:sk_base_mobile/services/dio.service.dart'; import 'package:sk_base_mobile/services/dio.service.dart';
import '../constants/constants.dart'; import '../constants/constants.dart';
Future<Response> login(String? oauthType, String? token) { //
return DioService.dio.post(Urls.login, Future<Response> login(String username, String password) {
data: {'oauthType': oauthType, 'token': token}, return DioService.dio.post(
options: Options(contentType: "application/x-www-form-urlencoded")); Urls.login,
data: {'username': username, 'password': password},
);
}
//
Future<Response> getUserInfo() {
return DioService.dio.get(
Urls.getUserInfo,
);
} }
Future<Response> logout() { Future<Response> logout() {
@ -32,13 +41,6 @@ Future<Response> saveUserInfo(Map<String, dynamic> data) {
return DioService.dio.post(Urls.saveUserInfo, data: data); return DioService.dio.post(Urls.saveUserInfo, data: data);
} }
Future<Response> getUserInfo(String userId) {
Map<String, dynamic> data = {
"userId": userId,
};
return DioService.dio.get(Urls.getUserInfo, queryParameters: data);
}
Future<Response> uploadImg(File file) async { Future<Response> uploadImg(File file) async {
// DateTime dateTime = DateTime.now(); // DateTime dateTime = DateTime.now();
// String fileName = file.path.split('/').last; // String fileName = file.path.split('/').last;

View File

@ -19,7 +19,7 @@ class AppTheme {
static const Color snackbarErrorBackgroudColor = Colors.red; static const Color snackbarErrorBackgroudColor = Colors.red;
static const Color snackbarSuccessBackgroudColor = Colors.green; static const Color snackbarSuccessBackgroudColor = Colors.green;
static const Color snackbarWarningBackgroudColor = Colors.orange; 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'; static const String fontName = 'NotoSans';
} }
@ -33,6 +33,11 @@ final theme = ThemeData(
dividerColor: AppTheme.grey, dividerColor: AppTheme.grey,
cardColor: AppTheme.white, cardColor: AppTheme.white,
scaffoldBackgroundColor: AppTheme.nearlyWhite, 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( tabBarTheme: TabBarTheme(
indicator: BoxDecoration( indicator: BoxDecoration(
border: border:
@ -44,7 +49,7 @@ final theme = ThemeData(
backgroundColor: AppTheme.primaryColor, backgroundColor: AppTheme.primaryColor,
titleTextStyle: TextStyle( titleTextStyle: TextStyle(
color: Colors.black, color: Colors.black,
fontSize: ScreenAdaper.sp(20), fontSize: ScreenAdaper.sp(25),
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
), ),
inputDecorationTheme: InputDecorationTheme( inputDecorationTheme: InputDecorationTheme(

View File

@ -1,6 +1,7 @@
/// Global config /// Global config
class GloablConfig { 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 DOMAIN_NAME = "山矿通";
static const DEBUG = true; static const DEBUG = true;
static const PRIVACY_POLICY = 'http://h5.heeru.xyz/privacyPolicy.html'; static const PRIVACY_POLICY = 'http://h5.heeru.xyz/privacyPolicy.html';

View File

@ -1,27 +1,10 @@
class Urls { class Urls {
static String getAppConfig = 'config/getAppConfig'; static String getAppConfig = 'config/getAppConfig';
static String login = 'security/oauth'; static String login = 'auth/login';
static String isValidToken = 'security/isValidToken'; static String isValidToken = 'security/isValidToken';
static String logout = 'security/logout'; static String logout = 'security/logout';
static String deleteAccount = 'user/deleteAccount'; 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 saveUserInfo = 'user/saveUserInfo';
static String getUserInfo = 'user/getUserInfo'; static String getUserInfo = 'account/profile';
static String getOssPolicy = 'user/oss/policy';
static String updateAvatar = 'user/updateAvatar'; 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';
} }

View File

@ -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/dio.service.dart';
import 'package:sk_base_mobile/services/storage.service.dart'; import 'package:sk_base_mobile/services/storage.service.dart';
import 'store/store.dart'; import 'store/store.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
/// ///
class Global { class Global {

View File

@ -1,9 +1,10 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
class AppBottomNavItem { class AppBottomNavItem {
String? icon; Icon icon;
String? activeIcon; Icon activeIcon;
String? label; String? label;
Widget? page; Widget? page;
AppBottomNavItem({this.icon, this.activeIcon, this.label, this.page}); AppBottomNavItem(
{required this.icon, required this.activeIcon, this.label, this.page});
} }

View File

@ -1,27 +1,15 @@
import 'package:sk_base_mobile/models/user_info.model.dart';
class Auth { class Auth {
bool? isFirstRegister;
String? token; String? token;
UserInfoModel? userInfo;
Auth({this.isFirstRegister, this.token, this.userInfo}); Auth({this.token});
Auth.fromJson(Map<String, dynamic> json) { Auth.fromJson(Map<String, dynamic> json) {
isFirstRegister = json['isFirstRegister'];
token = json['token']; token = json['token'];
userInfo = json['userInfo'] != null
? UserInfoModel.fromJson(json['userInfo'])
: null;
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>(); final Map<String, dynamic> data = Map<String, dynamic>();
data['isFirstRegister'] = isFirstRegister;
data['token'] = token; data['token'] = token;
if (userInfo != null) {
data['userInfo'] = userInfo!.toJson();
}
return data; return data;
} }
} }

View File

@ -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<String, dynamic> json) {
id = json['id'];
createdAt = json['createdAt'];
updatedAt = json['updatedAt'];
name = json['name'];
value = json['value'];
remark = json['remark'];
status = json['status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['createdAt'] = createdAt;
data['updatedAt'] = updatedAt;
data['name'] = name;
data['value'] = value;
data['remark'] = remark;
data['status'] = status;
return data;
}
}

View File

@ -1,230 +1,69 @@
class UserInfoModel { import 'package:sk_base_mobile/models/role.model.dart';
String? userId;
int? userType;
String? nickname;
bool? isInternal;
String? avatar;
String? avatarUrl;
String? avatarThumbUrl;
String? avatarMiddleThumbUrl;
List<String>? mediumList;
List<AvatarRespList>? avatarRespList;
int? gender;
String? birthday;
int? age;
String? country;
String? pkgName;
bool? isAnswer;
int? availableCoins;
int? auditStatus;
bool? isShowReviewSupplementTips;
List<String>? tagsList;
List<TagDetails>? 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;
UserInfoModel({ class UserInfoModel {
this.userId, int? id;
this.userType, String? createdAt;
String? updatedAt;
String? username;
String? nickname;
String? avatar;
String? qq;
String? email;
String? phone;
String? remark;
int? status;
List<RoleModel>? roles;
UserInfoModel(
{this.id,
this.createdAt,
this.updatedAt,
this.username,
this.nickname, this.nickname,
this.isInternal,
this.avatar, this.avatar,
this.avatarUrl, this.qq,
this.avatarThumbUrl, this.email,
this.avatarMiddleThumbUrl, this.phone,
this.mediumList, this.remark,
this.avatarRespList, this.status,
this.gender, this.roles});
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,
});
UserInfoModel.fromJson(Map<String, dynamic> json) { UserInfoModel.fromJson(Map<String, dynamic> json) {
userId = json['userId']; id = json['id'];
userType = json['userType']; createdAt = json['createdAt'];
updatedAt = json['updatedAt'];
username = json['username'];
nickname = json['nickname']; nickname = json['nickname'];
isInternal = json['isInternal'];
avatar = json['avatar']; avatar = json['avatar'];
avatarUrl = json['avatarUrl']; qq = json['qq'];
avatarThumbUrl = json['avatarThumbUrl']; email = json['email'];
avatarMiddleThumbUrl = json['avatarMiddleThumbUrl']; phone = json['phone'];
remark = json['remark'];
if (json['avatarRespList'] != null) { status = json['status'];
avatarRespList = <AvatarRespList>[]; if (json['roles'] != null) {
json['avatarRespList'].forEach((v) { roles = <RoleModel>[];
avatarRespList!.add(AvatarRespList.fromJson(v)); 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 = <String>[];
json['tagsList'].forEach((v) {
tagsList!.add(v);
});
}
if (json['tagDetails'] != null) {
tagDetails = <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<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>(); final Map<String, dynamic> data = <String, dynamic>{};
data['userId'] = userId; data['id'] = id;
data['userType'] = userType; data['createdAt'] = createdAt;
data['updatedAt'] = updatedAt;
data['username'] = username;
data['nickname'] = nickname; data['nickname'] = nickname;
data['isInternal'] = isInternal;
data['avatar'] = avatar; data['avatar'] = avatar;
data['avatarUrl'] = avatarUrl; data['qq'] = qq;
data['avatarThumbUrl'] = avatarThumbUrl; data['email'] = email;
data['avatarMiddleThumbUrl'] = avatarMiddleThumbUrl; data['phone'] = phone;
if (this.avatarRespList != null) { data['remark'] = remark;
data['avatarRespList'] = avatarRespList!.map((v) => v.toJson()).toList(); 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<String, dynamic> json) {
mediaPath = json['mediaPath'];
mediaUrl = json['mediaUrl'];
middleThumbUrl = json['middleThumbUrl'];
thumbUrl = json['thumbUrl'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
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<String, dynamic> json) {
tag = json['tag'];
tagTip = json['tagTip'];
tagColor = json['tagColor'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['tag'] = tag;
data['tagTip'] = tagTip;
data['tagColor'] = tagColor;
return data; return data;
} }
} }

View File

@ -5,6 +5,9 @@ class HomePage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const Placeholder(); return Scaffold(
appBar: AppBar(title: Text('首页')),
body: SizedBox(child: Text('sss')),
);
} }
} }

View File

@ -34,26 +34,16 @@ class _LandingPageState extends State<LandingPage> {
AppInfoService.to.bottomNavItems!; AppInfoService.to.bottomNavItems!;
bottomNavItems = roleWithBottomNavItems bottomNavItems = roleWithBottomNavItems
.map((e) => BottomNavigationBarItem( .map((e) => BottomNavigationBarItem(
icon: Image.asset( icon: e.icon, activeIcon: e.activeIcon, label: e.label))
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))
.toList(); .toList();
pages = roleWithBottomNavItems.map((e) => e.page!).toList(); pages = roleWithBottomNavItems.map((e) => e.page!).toList();
return Scaffold( return Scaffold(
bottomNavigationBar: BottomNavigationBar( bottomNavigationBar: BottomNavigationBar(
iconSize: ScreenAdaper.sp(25), iconSize: ScreenAdaper.sp(40),
type: BottomNavigationBarType.fixed, type: BottomNavigationBarType.fixed,
items: bottomNavItems, items: bottomNavItems,
showSelectedLabels: false, showSelectedLabels: true,
showUnselectedLabels: false, showUnselectedLabels: true,
currentIndex: _selectedLanding, currentIndex: _selectedLanding,
onTap: (landing) { onTap: (landing) {
_onItemTapped(landing); _onItemTapped(landing);

View File

@ -9,10 +9,14 @@ class LoginController extends GetxController {
final isAgreeTerm = RxBool(false); final isAgreeTerm = RxBool(false);
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
final passwordFocusNode = FocusNode(); final passwordFocusNode = FocusNode();
String username = '';
String password = '';
bool loading = false; bool loading = false;
Future<void> doLogin() async { Future<void> doLogin() async {
if (!formKey.currentState!.validate()) { if (!formKey.currentState!.validate()) {
return; return;
} }
// form中的数据
AuthStore.to.login(username: username, password: password);
} }
} }

View File

@ -162,7 +162,9 @@ class LoginScreen extends StatelessWidget {
_controller.passwordFocusNode.requestFocus(); _controller.passwordFocusNode.requestFocus();
}, },
style: TextStyle(fontSize: ScreenAdaper.sp(25)), style: TextStyle(fontSize: ScreenAdaper.sp(25)),
onChanged: (value) {}, onChanged: (value) {
_controller.username = value;
},
); );
} }
@ -181,8 +183,11 @@ class LoginScreen extends StatelessWidget {
onFieldSubmitted: (value) { onFieldSubmitted: (value) {
_controller.doLogin(); _controller.doLogin();
}, },
style: TextStyle(fontSize: ScreenAdaper.sp(25)), style: TextStyle(fontSize: ScreenAdaper.sp(25)),
onChanged: (value) {}, onChanged: (value) {
_controller.password = value;
},
// validator: (String? value) { // validator: (String? value) {
// return (value ?? '').length >= 6 ? null : '密码长度至少6位'; // return (value ?? '').length >= 6 ? null : '密码长度至少6位';
// }, // },

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/mine/mine.controller.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_about.dart';
// import 'package:sk_base_mobile/screens/mine/mine_block.dart'; // import 'package:sk_base_mobile/screens/mine/mine_block.dart';
// import 'package:sk_base_mobile/screens/mine/mine_mytickets.dart'; // import 'package:sk_base_mobile/screens/mine/mine_mytickets.dart';
@ -29,10 +30,6 @@ class _MinePageState extends State<MinePage>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_controller.tabController ??= TabController(
initialIndex: _controller.selectedTabIndex.value,
length: 4,
vsync: this);
} }
@override @override
@ -41,7 +38,7 @@ class _MinePageState extends State<MinePage>
} }
Widget _buildBody() { Widget _buildBody() {
return Column(mainAxisSize: MainAxisSize.max, children: [ return Column(children: [
Container( Container(
height: ScreenAdaper.height(360), height: ScreenAdaper.height(360),
width: ScreenAdaper.screenWidth(), width: ScreenAdaper.screenWidth(),
@ -115,7 +112,7 @@ class _MinePageState extends State<MinePage>
SizedBox( SizedBox(
width: ScreenAdaper.width(210), width: ScreenAdaper.width(210),
child: Text( child: Text(
'ID: ${AuthStore.to.userInfo.value.userId}', 'ID: ${AuthStore.to.userInfo.value.id}',
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 2, maxLines: 2,
style: TextStyle( style: TextStyle(
@ -149,65 +146,20 @@ class _MinePageState extends State<MinePage>
]), ]),
), ),
), ),
Expanded( Expanded(child: MineSettingsPage())
child: DefaultTabController( // Expanded(
length: 4, // child: DefaultTabController(
initialIndex: _controller.selectedTabIndex.value, // length: 4,
child: Scaffold( // initialIndex: _controller.selectedTabIndex.value,
backgroundColor: AppTheme.white, // child: Scaffold(
appBar: AppBar( // backgroundColor: AppTheme.white,
backgroundColor: AppTheme.white, // appBar: AppBar(
elevation: 0, // backgroundColor: AppTheme.white,
automaticallyImplyLeading: false, // elevation: 0,
flexibleSpace: _buildTabBar(), // automaticallyImplyLeading: false,
), // flexibleSpace: _buildTabBar(),
body: _buildTabView()))) // ),
// 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(),
],
);
}
} }

View File

@ -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();
}
}

View File

@ -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<MineController>();
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();
}
}
}

View File

@ -6,22 +6,16 @@ import 'package:sk_base_mobile/apis/api.dart' as Api;
class UserInfoController extends GetxController { class UserInfoController extends GetxController {
final nickNameController = TextEditingController(text: ''); final nickNameController = TextEditingController(text: '');
final countryController = TextEditingController(text: '');
final birthdayController = TextEditingController();
@override @override
void onReady() async { void onReady() async {
nickNameController.text = AuthStore.to.userInfo.value.nickname ?? ''; nickNameController.text = AuthStore.to.userInfo.value.nickname ?? '';
birthdayController.text = AuthStore.to.userInfo.value.birthday ?? '';
countryController.text = AuthStore.to.userInfo.value.country ?? '';
super.onReady(); super.onReady();
} }
Future<void> saveUserInfo() async { Future<void> saveUserInfo() async {
Map<String, dynamic> data = { Map<String, dynamic> data = {
'nickname': nickNameController.text, 'nickname': nickNameController.text,
'birthday': birthdayController.text,
'country': countryController.text,
}; };
await AuthStore.to.saveUserInfo(data); await AuthStore.to.saveUserInfo(data);
} }

View File

@ -74,109 +74,109 @@ class UserInfoPage extends StatelessWidget {
SizedBox( SizedBox(
height: ScreenAdaper.height(15), height: ScreenAdaper.height(15),
), ),
TextFormField( // TextFormField(
controller: _controller.birthdayController, // controller: _controller.birthdayController,
decoration: InputDecoration( // decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB( // contentPadding: EdgeInsets.fromLTRB(
ScreenAdaper.width(12), 0, ScreenAdaper.width(12), 0), // ScreenAdaper.width(12), 0, ScreenAdaper.width(12), 0),
labelText: "Date of birth", // labelText: "Date of birth",
labelStyle: TextStyle( // labelStyle: TextStyle(
color: const Color.fromARGB(255, 136, 136, 136), // color: const Color.fromARGB(255, 136, 136, 136),
fontSize: ScreenAdaper.sp(18)), // fontSize: ScreenAdaper.sp(18)),
enabledBorder: const UnderlineInputBorder( // enabledBorder: const UnderlineInputBorder(
borderSide: BorderSide( // borderSide: BorderSide(
color: Color.fromARGB(153, 191, 190, 190), // color: Color.fromARGB(153, 191, 190, 190),
), // ),
), // ),
focusedBorder: const UnderlineInputBorder( // focusedBorder: const UnderlineInputBorder(
borderSide: BorderSide( // borderSide: BorderSide(
color: Color.fromARGB(153, 191, 190, 190), // color: Color.fromARGB(153, 191, 190, 190),
), // ),
), // ),
), // ),
onTap: () async { // onTap: () async {
await showCupertinoModalPopup( // await showCupertinoModalPopup(
context: Get.context!, // context: Get.context!,
builder: (context) => Container( // builder: (context) => Container(
color: Colors.white, // color: Colors.white,
height: 300, // height: 300,
child: CupertinoDatePicker( // child: CupertinoDatePicker(
initialDateTime: DateTime.parse( // initialDateTime: DateTime.parse(
_controller.birthdayController.text), // _controller.birthdayController.text),
minimumDate: DateTime(1900), // minimumDate: DateTime(1900),
maximumDate: DateTime.now() // maximumDate: DateTime.now()
.subtract(const Duration(days: 18 * 365)), // .subtract(const Duration(days: 18 * 365)),
minimumYear: DateTime(1900).year, // minimumYear: DateTime(1900).year,
maximumYear: DateTime.now() // maximumYear: DateTime.now()
.subtract(const Duration(days: 18 * 365)) // .subtract(const Duration(days: 18 * 365))
.year, // .year,
mode: CupertinoDatePickerMode.date, // mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (pickeddate) { // onDateTimeChanged: (pickeddate) {
_controller.birthdayController.text = // _controller.birthdayController.text =
formatDate(pickeddate, [ // formatDate(pickeddate, [
yyyy, // yyyy,
'-', // '-',
mm, // mm,
'-', // '-',
dd, // dd,
]); // ]);
}), // }),
)); // ));
}, // },
style: // style:
TextStyle(fontSize: ScreenAdaper.sp(18), color: Colors.black), // TextStyle(fontSize: ScreenAdaper.sp(18), color: Colors.black),
cursorColor: const Color.fromARGB(255, 87, 86, 86)), // cursorColor: const Color.fromARGB(255, 87, 86, 86)),
SizedBox( SizedBox(
height: ScreenAdaper.height(15), height: ScreenAdaper.height(15),
), ),
TextFormField( // TextFormField(
controller: _controller.countryController, // controller: _controller.countryController,
decoration: InputDecoration( // decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB( // contentPadding: EdgeInsets.fromLTRB(
ScreenAdaper.width(12), 0, ScreenAdaper.width(12), 0), // ScreenAdaper.width(12), 0, ScreenAdaper.width(12), 0),
labelText: "Country", // labelText: "Country",
labelStyle: TextStyle( // labelStyle: TextStyle(
color: const Color.fromARGB(255, 136, 136, 136), // color: const Color.fromARGB(255, 136, 136, 136),
fontSize: ScreenAdaper.sp(18)), // fontSize: ScreenAdaper.sp(18)),
enabledBorder: const UnderlineInputBorder( // enabledBorder: const UnderlineInputBorder(
borderSide: BorderSide( // borderSide: BorderSide(
color: Color.fromARGB(153, 191, 190, 190), // color: Color.fromARGB(153, 191, 190, 190),
), // ),
), // ),
focusedBorder: const UnderlineInputBorder( // focusedBorder: const UnderlineInputBorder(
borderSide: BorderSide( // borderSide: BorderSide(
color: Color.fromARGB(153, 191, 190, 190), // color: Color.fromARGB(153, 191, 190, 190),
), // ),
), // ),
), // ),
onTap: () async { // onTap: () async {
await showCupertinoModalPopup( // await showCupertinoModalPopup(
context: Get.context!, // context: Get.context!,
builder: (context) => Container( // builder: (context) => Container(
color: Colors.white, // color: Colors.white,
height: 300, // height: 300,
child: CupertinoPicker( // child: CupertinoPicker(
itemExtent: 50, // itemExtent: 50,
onSelectedItemChanged: (index) { // onSelectedItemChanged: (index) {
_controller.countryController.text = // _controller.countryController.text =
Data.countryCodes[index]; // Data.countryCodes[index];
}, // },
children: Data.countryCodes // children: Data.countryCodes
.map((e) => Container( // .map((e) => Container(
height: ScreenAdaper.height(50), // height: ScreenAdaper.height(50),
alignment: Alignment.center, // alignment: Alignment.center,
child: Text( // child: Text(
e, // e,
style: TextStyle( // style: TextStyle(
fontSize: ScreenAdaper.sp(30)), // fontSize: ScreenAdaper.sp(30)),
), // ),
)) // ))
.toList(), // .toList(),
))); // )));
}, // },
style: // style:
TextStyle(fontSize: ScreenAdaper.sp(18), color: Colors.black), // TextStyle(fontSize: ScreenAdaper.sp(18), color: Colors.black),
cursorColor: const Color.fromARGB(255, 87, 86, 86)) // cursorColor: const Color.fromARGB(255, 87, 86, 86))
], ],
); );
} }

View File

@ -1,8 +1,10 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:package_info/package_info.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_bottom_nav_item.dart';
import 'package:sk_base_mobile/models/app_config.dart'; import 'package:sk_base_mobile/models/app_config.dart';
import 'package:sk_base_mobile/screens/home/home.dart'; import 'package:sk_base_mobile/screens/home/home.dart';
@ -25,14 +27,18 @@ class AppInfoService extends GetxService {
final isCameraing = RxBool(false); final isCameraing = RxBool(false);
List<AppBottomNavItem>? bottomNavItems = [ List<AppBottomNavItem>? bottomNavItems = [
AppBottomNavItem( AppBottomNavItem(
icon: 'assets/images/landing_icon_bottom_0.png', icon: const Icon(Icons.home_outlined),
activeIcon: 'assets/images/landing_icon_bottom_active_0.png', activeIcon: const Icon(
label: 'homepage', Icons.home,
),
label: '首页',
page: const HomePage()), page: const HomePage()),
AppBottomNavItem( AppBottomNavItem(
icon: 'assets/images/landing_icon_bottom_3.png', icon: const Icon(Icons.person_outline_outlined),
activeIcon: 'assets/images/landing_icon_bottom_active_3.png', activeIcon: const Icon(
label: 'mine', Icons.person,
),
label: '我的',
page: MinePage()), page: MinePage()),
]; ];
Future<AppInfoService> init() async { Future<AppInfoService> init() async {
@ -40,8 +46,8 @@ class AppInfoService extends GetxService {
.info("[service-appInfo] Register app-related information service"); .info("[service-appInfo] Register app-related information service");
try { try {
await Future.wait( // await Future.wait(
[getDeviceInfo(), getPackageInfo(), getAppConfig(), getossPolicy()]); // [getDeviceInfo(), getPackageInfo(), getAppConfig(), getossPolicy()]);
requestPermission(); requestPermission();
} catch (e) { } catch (e) {
LoggerUtil().error(e); LoggerUtil().error(e);

View File

@ -14,9 +14,9 @@ class DioService extends Get.GetxService {
static DioService get to => Get.Get.find(); static DioService get to => Get.Get.find();
static Dio get dio => _dio; static Dio get dio => _dio;
static late Dio _dio; static late Dio _dio;
List<String> whiteList = [Urls.googleTranslate]; List<String> whiteList = [Urls.login];
BaseOptions dioBaseOptions = BaseOptions( BaseOptions dioBaseOptions = BaseOptions(
connectTimeout: const Duration(minutes: 10), connectTimeout: const Duration(seconds: 5),
baseUrl: '${GloablConfig.BASE_URL}', baseUrl: '${GloablConfig.BASE_URL}',
followRedirects: true); followRedirects: true);
@ -33,7 +33,6 @@ class DioService extends Get.GetxService {
void onError(DioException e, ErrorInterceptorHandler handler) async { void onError(DioException e, ErrorInterceptorHandler handler) async {
if (whiteList.contains(e.requestOptions.path)) { if (whiteList.contains(e.requestOptions.path)) {
await SnackBarUtil().error(e.message);
return handler.next(e); return handler.next(e);
} }
if (GloablConfig.DEBUG) { if (GloablConfig.DEBUG) {
@ -139,31 +138,6 @@ class DioService extends Get.GetxService {
if (response.data is String) { if (response.data is String) {
responseData = jsonDecode(response.data); 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) { } catch (e) {
printError(info: e.toString()); printError(info: e.toString());
} }

View File

@ -15,7 +15,7 @@ class StorageService extends GetxService {
{bool isWithUser = true}) async { {bool isWithUser = true}) async {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return await _prefs.setString(storeKey, value); return await _prefs.setString(storeKey, value);
} }
@ -23,7 +23,7 @@ class StorageService extends GetxService {
Future<bool> setBool(String key, bool value, {bool isWithUser = true}) async { Future<bool> setBool(String key, bool value, {bool isWithUser = true}) async {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return await _prefs.setBool(storeKey, value); return await _prefs.setBool(storeKey, value);
} }
@ -31,7 +31,7 @@ class StorageService extends GetxService {
Future<bool> setInt(String key, int value, {bool isWithUser = true}) async { Future<bool> setInt(String key, int value, {bool isWithUser = true}) async {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return await _prefs.setInt(storeKey, value); return await _prefs.setInt(storeKey, value);
} }
@ -40,7 +40,7 @@ class StorageService extends GetxService {
{bool isWithUser = true}) async { {bool isWithUser = true}) async {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return await _prefs.setStringList(storeKey, value); return await _prefs.setStringList(storeKey, value);
} }
@ -48,7 +48,7 @@ class StorageService extends GetxService {
String? getString(String key, {bool isWithUser = true}) { String? getString(String key, {bool isWithUser = true}) {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return _prefs.getString(storeKey); return _prefs.getString(storeKey);
} }
@ -56,7 +56,7 @@ class StorageService extends GetxService {
int? getInt(String key, {bool isWithUser = true}) { int? getInt(String key, {bool isWithUser = true}) {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return _prefs.getInt(storeKey); return _prefs.getInt(storeKey);
} }
@ -64,7 +64,7 @@ class StorageService extends GetxService {
bool? getBool(String key, {bool isWithUser = true}) { bool? getBool(String key, {bool isWithUser = true}) {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return _prefs.getBool(storeKey) ?? false; return _prefs.getBool(storeKey) ?? false;
} }
@ -72,7 +72,7 @@ class StorageService extends GetxService {
List<String> getList(String key, {bool isWithUser = true}) { List<String> getList(String key, {bool isWithUser = true}) {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return _prefs.getStringList(storeKey) ?? []; return _prefs.getStringList(storeKey) ?? [];
} }
@ -80,7 +80,7 @@ class StorageService extends GetxService {
Future<bool> remove(String key, {bool isWithUser = true}) async { Future<bool> remove(String key, {bool isWithUser = true}) async {
String storeKey = key; String storeKey = key;
if (isWithUser) { if (isWithUser) {
storeKey = '${AuthStore.to.userInfo.value.userId}_$key'; storeKey = '${AuthStore.to.userInfo.value.id}_$key';
} }
return await _prefs.remove(storeKey); return await _prefs.remove(storeKey);
} }

View File

@ -63,59 +63,49 @@ class AuthStore extends GetxController {
} }
Future<void> logout({bool force = false}) async { Future<void> 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.token, isWithUser: false);
await StorageService.to.remove(CacheKeys.userInfo, isWithUser: false); await StorageService.to.remove(CacheKeys.userInfo, isWithUser: false);
try { try {
final response = await Api.logout(); // final response = await Api.logout();
if (response.data != null) { // if (response.data != null) {
LoggerUtil().info('[Store-Auth] Logout succeed.'); LoggerUtil().info('[Store-Auth] Logout succeed.');
if (Get.context != null) Get.offAllNamed(RouteConfig.login); if (Get.context != null) Get.offAllNamed(RouteConfig.login);
} // }
} catch (e) { } catch (e) {
} finally { } finally {
LoadingUtil.dismiss(); LoadingUtil.dismiss();
} }
} }
Future<void> login(LoginEnum type, {String? identityToken}) async { Future<void> login(
{required String username, required String password}) async {
Dio.Response response; Dio.Response response;
if (type == LoginEnum.fastLogin && // if (type == LoginEnum.fastLogin &&
StorageService.to.getString(CacheKeys.deviceUUID, isWithUser: false) == // StorageService.to.getString(CacheKeys.deviceUUID, isWithUser: false) ==
null) { // null) {
SnackBarUtil().error('Need DeviceUUID. Please restart app.'); // SnackBarUtil().error('Need DeviceUUID. Please restart app.');
return; // return;
} // }
LoadingUtil.show(status: 'Login...'); LoadingUtil.show(status: 'Login...');
// Hide keyboard
TapToDismissKeyboard.dismissOf(context: Get.context!); TapToDismissKeyboard.dismissOf(context: Get.context!);
try { try {
response = await Api.login( await Future.delayed(const Duration(seconds: 1));
'4', response = await Api.login(username, password);
type == LoginEnum.fastLogin
? (StorageService.to
.getString(CacheKeys.deviceUUID, isWithUser: false))
: identityToken);
if (response.data != null) { if (response.data != null) {
final auth = Auth.fromJson(response.data['data']); final auth = Auth.fromJson(response.data['data']);
if (auth.token != null) { if (auth.token != null) {
await StorageService.to await StorageService.to
.setString(CacheKeys.token, auth.token!, isWithUser: false); .setString(CacheKeys.token, auth.token!, isWithUser: false);
} }
if (auth.userInfo != null) { await getUserInfo();
userInfo(auth.userInfo!);
await StorageService.to.setString(
CacheKeys.userInfo, jsonEncode(auth.userInfo),
isWithUser: false);
LoggerUtil().info('[Store-Auth] Login succeed.');
}
Get.offNamed(RouteConfig.home); Get.offNamed(RouteConfig.home);
getCommonInfo(); // getCommonInfo();
} }
} catch (e) { } catch (e) {
SnackBarUtil().error('${e}'); await SnackBarUtil().error('账号密码错误');
} finally { } finally {
LoadingUtil.dismiss(); LoadingUtil.dismiss();
} }
@ -130,7 +120,7 @@ class AuthStore extends GetxController {
Future<void> getUserInfo() async { Future<void> getUserInfo() async {
await LoadingUtil.show(status: 'Loading...'); await LoadingUtil.show(status: 'Loading...');
try { try {
final response = await Api.getUserInfo(userInfo.value.userId!); final response = await Api.getUserInfo();
if (response.data != null) { if (response.data != null) {
UserInfoModel userInfo = UserInfoModel.fromJson(response.data['data']); UserInfoModel userInfo = UserInfoModel.fromJson(response.data['data']);
await updateUserInfoState(userInfo); await updateUserInfoState(userInfo);

View File

@ -1,10 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.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 { class LoadingUtil {
LoadingUtil() {} LoadingUtil();
init() {}
static Future<void> show({String? status}) async { static Future<void> show({String? status}) async {
return showLoading(status: status ?? 'Loading...'); return showLoading(status: status ?? 'Loading...');
@ -14,27 +15,35 @@ class LoadingUtil {
return hideLoading(); return hideLoading();
} }
static showLoading({String? status}) { static showLoading({String? status}) async {
Get.dialog( await showDialog(
GestureDetector( context: Get.context!,
barrierColor: AppTheme.barrierColor,
barrierDismissible: false,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: GestureDetector(
child: Container( child: Container(
color: Colors.black54, color: Colors.black54,
child: const Center( child: Center(
child: CircularProgressIndicator( child: LoadingAnimationWidget.fourRotatingDots(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), color: AppTheme.primaryColor,
size: ScreenAdaper.sp(50),
), ),
), ),
), ),
onTap: () { onTap: () {
// 退 // 退
Get.back(); // Navigator.of(context).pop();
}, },
), ),
barrierDismissible: false, );
},
); );
} }
static hideLoading() { static hideLoading() {
Get.back(); Navigator.of(Get.context!).pop();
} }
} }

View File

@ -2,6 +2,7 @@ import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sk_base_mobile/app_theme.dart'; import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
// SnackBar // SnackBar
class SnackBarUtil { class SnackBarUtil {
@ -25,13 +26,18 @@ class SnackBarUtil {
await Get.closeCurrentSnackbar(); await Get.closeCurrentSnackbar();
} }
Get.rawSnackbar( Get.rawSnackbar(
message: title,
snackPosition: SnackPosition.TOP, snackPosition: SnackPosition.TOP,
backgroundColor: AppTheme.snackbarErrorBackgroudColor, backgroundColor: AppTheme.snackbarErrorBackgroudColor,
borderRadius: 15, borderRadius: ScreenAdaper.sp(15),
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0), messageText: Text(
'$title',
style: TextStyle(
fontSize: ScreenAdaper.sp(25), color: AppTheme.nearlyWhite),
),
margin: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(20), vertical: 0),
overlayColor: Colors.white, overlayColor: Colors.white,
duration: Duration(seconds: 3), duration: const Duration(seconds: 3),
forwardAnimationCurve: Curves.fastLinearToSlowEaseIn, forwardAnimationCurve: Curves.fastLinearToSlowEaseIn,
reverseAnimationCurve: Curves.linearToEaseOut); reverseAnimationCurve: Curves.linearToEaseOut);
} }

View File

@ -51,7 +51,7 @@ class MyAvatarWidget extends StatelessWidget {
return _controller.uploadImgFilePath.value.isNotEmpty return _controller.uploadImgFilePath.value.isNotEmpty
? FileImage(File(_controller.uploadImgFilePath.value)) ? FileImage(File(_controller.uploadImgFilePath.value))
: NetworkImage( : NetworkImage(
AuthStore.to.userInfo.value.avatarThumbUrl ?? '', AuthStore.to.userInfo.value.avatar ?? '',
); );
} }
// Widget getShowImg() { // Widget getShowImg() {