no message

This commit is contained in:
1147192855@qq.com 2024-08-30 15:24:43 +08:00
parent eb4b5ae7a0
commit f38369e224
17 changed files with 720 additions and 80 deletions

View File

@ -29,7 +29,7 @@
type="application/octet-stream" /> type="application/octet-stream" />
</item> --> </item> -->
<item> <item>
<title>Version 1.0.0</title> <title>Version 1.0.1+2</title>
#发行说明-读取html方式(2选1) #发行说明-读取html方式(2选1)
<!-- <sparkle:releaseNotesLink> <!-- <sparkle:releaseNotesLink>
https://your_domain/your_path/release_notes.html https://your_domain/your_path/release_notes.html
@ -38,16 +38,16 @@
<description> <description>
<![CDATA[ <![CDATA[
<ul> <ul>
<li>1、新增XX功能</li> <li>1、优化批阅提示</li>
<li>2、新增XX功能</li> <li>2、优化启动图和展示页面</li>
</ul> </ul>
]]> ]]>
</description> </description>
<pubDate>Sun, 16 Feb 2022 12:00:00 +0800</pubDate> <pubDate>Sun, 16 Feb 2024 12:00:00 +0800</pubDate>
#你更新程序的地址 #你更新程序的地址
<enclosure url="https://dpc-job-oss.23544.com/infra-app/making_school_asignment_app/1.0.0/3/making_school_asignment_app-1.0.0+1-windows-setup.exe" <enclosure url="https://dpc-job-oss.23544.com/infra-app/making_school_asignment_app/1.0.1/3/making_school_asignment_app-1.0.1+2-windows-setup.exe"
sparkle:dsaSignature="MEUCICOob1N5PNhjRDWh2gHHOuJayep41hP+BMyF26BoYjQLAiEA2dG22KMc2HCQTUyWe1pxWmCJqVmdNQU+Mmfvojg0K2M=" sparkle:dsaSignature="MEUCIG2O7ZNPeIs/fi2GF/UCRvooqIZMFjLPyfGsIqTnmfHkAiEAuFusRpYjkf05fqBv3nQqfyy8Y8u6ub5X+QWZU7NJ5qU="
sparkle:version="1.0.0+1" sparkle:version="1.0.1+2"
sparkle:os="windows" sparkle:os="windows"
length="0" length="0"
type="application/octet-stream" /> type="application/octet-stream" />

View File

@ -5,6 +5,7 @@ import 'package:making_school_asignment_app/common/job/marking_models/do_paper_d
import 'package:making_school_asignment_app/common/job/marking_models/favor_param.dart'; import 'package:making_school_asignment_app/common/job/marking_models/favor_param.dart';
import 'package:making_school_asignment_app/common/job/marking_models/original_manuscript_handwriting_params.dart'; import 'package:making_school_asignment_app/common/job/marking_models/original_manuscript_handwriting_params.dart';
import 'package:making_school_asignment_app/common/job/marking_models/review_submission_params.dart'; import 'package:making_school_asignment_app/common/job/marking_models/review_submission_params.dart';
import 'package:making_school_asignment_app/common/job/user_register_params.dart';
import 'package:making_school_asignment_app/page/home_page/children/homework_review/components/job_handwriting.dart'; import 'package:making_school_asignment_app/page/home_page/children/homework_review/components/job_handwriting.dart';
import 'package:retrofit/retrofit.dart'; import 'package:retrofit/retrofit.dart';
import 'package:making_school_asignment_app/common/job/annotated_class.dart'; import 'package:making_school_asignment_app/common/job/annotated_class.dart';
@ -40,6 +41,12 @@ abstract class RetrofitClient {
@POST("/api/rbac/Auth/DcLogin") @POST("/api/rbac/Auth/DcLogin")
Future toLogin(@Field() String account, @Field() String password); Future toLogin(@Field() String account, @Field() String password);
@POST("/api/rbac/Auth/Register")
Future<String> toRegister(@Body() UserRegisterParams params);
@DELETE("/api/rbac/User/Delete")
Future<String> toUserLogout(@Field() int id);
@GET("/api/rbac/User/GetUser") @GET("/api/rbac/User/GetUser")
Future<UserInfoDetail?> getUser(@Query('userId') String userId); Future<UserInfoDetail?> getUser(@Query('userId') String userId);

View File

@ -0,0 +1,21 @@
import 'package:json_annotation/json_annotation.dart';
part 'user_register_params.g.dart';
@JsonSerializable()
class UserRegisterParams extends Object {
@JsonKey(name: 'account')
String account;
@JsonKey(name: 'password')
String password;
UserRegisterParams({
required this.account,
required this.password,
});
factory UserRegisterParams.fromJson(Map<String, dynamic> srcJson) => _$UserRegisterParamsFromJson(srcJson);
Map<String, dynamic> toJson() => _$UserRegisterParamsToJson(this);
}

View File

@ -98,7 +98,7 @@ class AuthInterceptor extends Interceptor {
headers["x-Authorization"] = xToken!; headers["x-Authorization"] = xToken!;
} }
/* if ((userInfo?.isExpired() ?? false) && userInfo?.termYear != '') { /* if ((userInfo?.isExpired() ?? false) && userInfo?.termYear != '') {
headers["term-year"] = userInfo!.termYear; headers["term-year"] = userInfo!.termYear;
}*/ }*/
@ -160,6 +160,16 @@ class TheError extends Interceptor {
int? statusCode = response.statusCode; int? statusCode = response.statusCode;
var errorMap = response.data; var errorMap = response.data;
if (errorMap is String && errorMap.length > 0) {
try {
var errorModel = jsonDecode(errorMap);
var error = errorModel['error'];
if (error != null && error["message"] != null) {
message = error["message"];
}
} catch (e) {}
}
// var runtimeType = errorMap.runtimeType; // var runtimeType = errorMap.runtimeType;
if (errorMap is Map && errorMap['error'] != null) { if (errorMap is Map && errorMap['error'] != null) {
message = errorMap['error']?['message'] ?? '请求错误,请重试'; message = errorMap['error']?['message'] ?? '请求错误,请重试';
@ -198,7 +208,7 @@ class TheError extends Interceptor {
if (message == '用户登录失效,请重新登录' && userInfo.value?.id == null) { if (message == '用户登录失效,请重新登录' && userInfo.value?.id == null) {
return handler.next(error); return handler.next(error);
} }
ToastUtils.showError(message); Future.delayed(const Duration(milliseconds: 600), () => ToastUtils.showError(message));
return handler.next(error); return handler.next(error);
} }
} }

View File

@ -7,7 +7,8 @@ enum AppStorageKey {
userInfo(value: 'USERINFO', label: "登录用户的基本信息 及 token过期时间"), userInfo(value: 'USERINFO', label: "登录用户的基本信息 及 token过期时间"),
userDetailInfo(value: 'USERDETAILINFO', label: "用户的详细信息"), userDetailInfo(value: 'USERDETAILINFO', label: "用户的详细信息"),
account(value: 'ACCOUNT', label: "用户名"), account(value: 'ACCOUNT', label: "用户名"),
pwd(value: 'PWD', label: "密码"); pwd(value: 'PWD', label: "密码"),
privacyAgreement(value: 'PRIVACYAGREEMENT', label: "用户同意隐私协议");
final String label; final String label;
final String value; final String value;

View File

@ -12,7 +12,6 @@ import 'package:making_school_asignment_app/common/utils/storage.dart';
import 'package:making_school_asignment_app/common/utils/utils.dart'; import 'package:making_school_asignment_app/common/utils/utils.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:permission_handler/permission_handler.dart';
import 'common/config/request_config.dart'; import 'common/config/request_config.dart';
import 'common/utils/app_upgrade/upgradeLogic.dart'; import 'common/utils/app_upgrade/upgradeLogic.dart';
@ -47,8 +46,6 @@ void main() async {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); // SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); //
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); // await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); //
runApp(const MyApp()); runApp(const MyApp());
Permission.storage.request();
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {

View File

@ -2,6 +2,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/const_text.dart'; import 'package:making_school_asignment_app/common/const_text.dart';
import 'package:making_school_asignment_app/common/job/user_info_detail.dart';
import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
import 'package:making_school_asignment_app/common/store/user_store.dart';
import 'package:making_school_asignment_app/common/utils/storage.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:making_school_asignment_app/page/global_widget/my_text.dart'; import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
@ -14,7 +18,8 @@ class OhterPage extends StatefulWidget {
State<OhterPage> createState() => _OhterPageState(); State<OhterPage> createState() => _OhterPageState();
} }
class _OhterPageState extends State<OhterPage> { class _OhterPageState extends State<OhterPage> with RequestToolMixin {
late Rx<UserInfoDetail?> userInfo = UserStore.to.userDetailInfo;
RxString localVersion = ''.obs; RxString localVersion = ''.obs;
@override @override
@ -29,16 +34,48 @@ class _OhterPageState extends State<OhterPage> {
localVersion.value = packageInfo.version; localVersion.value = packageInfo.version;
} }
//
_showAlertDialog(context1) async {
await showDialog(
//
barrierDismissible: false,
context: context1,
builder: (context) {
return AlertDialog(title: quickText("提示信息"), content: quickText("账户注销无法恢复,您确定要注销账户吗?"), actions: <Widget>[
TextButton(
child: quickText("取消"),
onPressed: () {
Navigator.pop(context, 'Cancle');
},
),
TextButton(
child: quickText("确定"),
onPressed: () async {
/* ref.read(markingKeyboardProvider.notifier).clean();
ref.read(markingSubtopicSwitchingProvider.notifier).clean();
ref.read(userTokenProvider.notifier).clean();
ref.read(userProvider.notifier).clean();*/
await getClient().toUserLogout(userInfo.value!.id);
try {
UserStore.to.erase();
var msg = await StorageService.to.erase();
print(msg);
Navigator.pop(context, "Ok");
Get.offAllNamed(Routes.login);
} catch (e) {
print(e);
}
})
]);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final personalInfoTitleStly = TextStyle( final personalInfoTitleStly = TextStyle(
color: const Color.fromRGBO(80, 87, 103, 1), color: const Color.fromRGBO(80, 87, 103, 1),
fontSize: 16.sp, fontSize: 16.sp,
); );
final personalInfoValStly = TextStyle(
color: const Color.fromRGBO(148, 163, 182, 1),
fontSize: 16.sp,
);
return Scaffold( return Scaffold(
backgroundColor: const Color.fromRGBO(248, 248, 248, 1), backgroundColor: const Color.fromRGBO(248, 248, 248, 1),
@ -108,6 +145,49 @@ class _OhterPageState extends State<OhterPage> {
), ),
], ],
), ),
Positioned(
bottom: 50.h,
child: InkWell(
child: Container(
height: 46.h,
width: ScreenUtil().screenWidth - 60.w,
padding: EdgeInsets.symmetric(vertical: 14.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(6.w),
),
color: Colors.white,
boxShadow: [
BoxShadow(
color: const Color.fromRGBO(46, 91, 255, 0.2),
offset: Offset(2.w, 2.h), //y轴偏移量
blurRadius: 14, //
spreadRadius: 0.5, //
)
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.exit_to_app_outlined,
size: 13.sp,
color: const Color.fromRGBO(148, 163, 182, 1),
),
Container(
width: 6.w,
),
Text(
'账户注销',
style: TextStyle(color: const Color.fromRGBO(148, 163, 182, 1), fontSize: 13.sp),
),
],
),
),
onTap: () => _showAlertDialog(context),
),
),
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:app_settings/app_settings.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart';
@ -18,6 +19,7 @@ import 'package:making_school_asignment_app/page/home_page/home_view.dart';
import 'package:making_school_asignment_app/page/work_page/work_logic.dart'; import 'package:making_school_asignment_app/page/work_page/work_logic.dart';
import 'package:making_school_asignment_app/page/work_page/work_view.dart'; import 'package:making_school_asignment_app/page/work_page/work_view.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart';
import 'package:permission_handler/permission_handler.dart';
class StartPage extends StatefulWidget { class StartPage extends StatefulWidget {
const StartPage({super.key}); const StartPage({super.key});
@ -28,16 +30,72 @@ class StartPage extends StatefulWidget {
class _StartPageState extends State<StartPage> with RequestToolMixin { class _StartPageState extends State<StartPage> with RequestToolMixin {
Timer? _timer; Timer? _timer;
Timer? _timerPermission;
DateTime? lastPopTime; DateTime? lastPopTime;
final _pageController = Get.find<PageIndexController>(); final _pageController = Get.find<PageIndexController>();
final _upgradeLogic = Get.find<UpgradeLogic>(); final _upgradeLogic = Get.find<UpgradeLogic>();
late final List<Widget> _bodyList; late final List<Widget> _bodyList;
void getStoragePermission() async {
_timerPermission?.cancel();
_timerPermission = null;
var status = await Permission.storage.status;
if (status != PermissionStatus.granted) {
print(status);
if (status == PermissionStatus.denied) {
await showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text("权限拒绝"),
content: Text("权限被永久拒绝,请前往权限设置页面通过权限"),
actions: [
ElevatedButton(
onPressed: () async {
await AppSettings.openAppSettings(asAnotherTask: true);
Navigator.of(context).pop();
_timerPermission = Timer.periodic(const Duration(seconds: 30), (_) => getStoragePermission());
},
child: Text('前往'),
)
],
);
},
);
return;
}
await showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text("内存权限"),
content: Text("为了提供更好的服务,需要获取到存储权限用于保存批阅笔记"),
actions: [
ElevatedButton(
onPressed: () async {
await Permission.storage.request();
Navigator.of(context).pop();
getStoragePermission();
},
child: Text('允许'),
)
],
);
},
);
}
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
Future.delayed(const Duration(seconds: 3), () => FlutterNativeSplash.remove()); Future.delayed(const Duration(seconds: 3), () => FlutterNativeSplash.remove());
Future.delayed(const Duration(seconds: 4), () => getStoragePermission());
Get.put(HomeLogic()); Get.put(HomeLogic());
Get.put(WorkLogic()); Get.put(WorkLogic());
@ -74,6 +132,7 @@ class _StartPageState extends State<StartPage> with RequestToolMixin {
void dispose() { void dispose() {
Get.delete<PageIndexController>(); Get.delete<PageIndexController>();
_timer?.cancel(); _timer?.cancel();
_timerPermission?.cancel();
super.dispose(); super.dispose();
} }
@ -125,7 +184,7 @@ class _StartPageState extends State<StartPage> with RequestToolMixin {
), ),
], ],
// //
type: BottomNavigationBarType.shifting, type: BottomNavigationBarType.fixed,
fixedColor: Theme.of(context).primaryColor, fixedColor: Theme.of(context).primaryColor,
unselectedItemColor: Colors.grey, unselectedItemColor: Colors.grey,
// unselectedItemColor: const Color.fromRGBO(80, 87, 103, 1), // unselectedItemColor: const Color.fromRGBO(80, 87, 103, 1),

View File

@ -35,15 +35,16 @@ class _MyInfoState extends State<MyInfo> with AutomaticKeepAliveClientMixin {
), ),
TextButton( TextButton(
child: quickText("确定"), child: quickText("确定"),
onPressed: () { onPressed: () async {
/* ref.read(markingKeyboardProvider.notifier).clean(); try {
ref.read(markingSubtopicSwitchingProvider.notifier).clean(); UserStore.to.erase();
ref.read(userTokenProvider.notifier).clean(); var msg = await StorageService.to.erase();
ref.read(userProvider.notifier).clean();*/ print(msg);
StorageService.to.remove(AppStorageKey.token.value); Navigator.pop(context, "Ok");
StorageService.to.remove(AppStorageKey.userInfo.value); Get.offAllNamed(Routes.login);
Navigator.pop(context, "Ok"); } catch (e) {
Get.offAllNamed(Routes.login); print(e);
}
}) })
]); ]);
}); });

View File

@ -0,0 +1,281 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/const_text.dart';
import 'package:making_school_asignment_app/common/job/user_register_params.dart';
import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart';
///
class Register extends StatefulWidget {
const Register({super.key});
@override
State<Register> createState() => _RegisterState();
}
class _RegisterState extends State<Register> with RequestToolMixin {
late final FocusNode _theFocus;
late final FocusNode _pwdFocus; //
//
late final TextEditingController _userNameController;
late final TextEditingController _passwordController;
bool readAgreement = false; //
bool _isShowPwd = true;
bool canLogin = true;
@override
void initState() {
super.initState();
_userNameController = TextEditingController();
_passwordController = TextEditingController();
_pwdFocus = FocusNode();
_theFocus = FocusNode();
}
@override
void dispose() {
super.dispose();
_userNameController.dispose();
_passwordController.dispose();
_pwdFocus.dispose();
_theFocus.dispose();
}
void toRegister() async {
if (!canLogin) return;
setState(() => canLogin = false);
void toMsg(msg) {
Future.delayed(Duration.zero, () => ToastUtils.showError(msg));
setState(() => canLogin = true);
}
FocusScope.of(context).requestFocus(_theFocus);
try {
String userName = _userNameController.text.trim();
String userPwd = _passwordController.text.trim();
if (userName == '') return toMsg('请填写用户账号');
if (userPwd == '') return toMsg('请填写密码');
if (userPwd.length < 6) return toMsg('密码长度不得少于6位');
if (!readAgreement) return toMsg('请勾选我已阅读用户协议和隐私协议');
EasyLoading.show(status: 'loading...');
var resultData = await getClient().toRegister(UserRegisterParams(account: userName, password: userPwd));
print(resultData);
// if (resultData.success) return toMsg(resultData.message ?? '注册失败,请重试');
ToastUtils.showSuccess('注册成功,请登录');
//
Future.delayed(Duration.zero, () => Get.back());
} catch (e) {
setState(() => canLogin = true);
} finally {
EasyLoading.dismiss();
}
}
void _showPassword() {
setState(() {
_isShowPwd = !_isShowPwd;
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).requestFocus(_theFocus);
},
child: AnnotatedRegion(
value: const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.light,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.dark,
),
child: Scaffold(
backgroundColor: Colors.transparent,
resizeToAvoidBottomInset: false,
body: Stack(
children: [
Container(
width: double.infinity,
height: double.infinity,
alignment: Alignment.center,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/login_bg.png'),
fit: BoxFit.fill, //
),
),
child: SingleChildScrollView(
child: Column(
children: [
Container(
width: 86.w,
height: 86.w,
alignment: Alignment.center,
child: SizedBox(
height: 86.w,
width: 86.w,
child: Image.asset('assets/images/login_logo.png', fit: BoxFit.cover),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 32.w, vertical: 24.h),
padding: EdgeInsets.only(top: 34.h, bottom: 16.h, left: 22.w, right: 22.w),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1.w, color: Colors.white),
borderRadius: BorderRadius.all(Radius.circular(10.w)),
boxShadow: const [
BoxShadow(
color: Color.fromRGBO(46, 91, 255, 0.1),
offset: Offset.zero, //y轴偏移量
blurRadius: 100, //
spreadRadius: 100, //
)
],
),
child: Column(children: [
TextField(
controller: _userNameController,
maxLines: 1,
maxLength: 20,
textInputAction: TextInputAction.next,
onEditingComplete: () {
FocusScope.of(context).requestFocus(_pwdFocus);
},
style: TextStyle(
color: const Color.fromRGBO(80, 87, 103, 1),
fontSize: 15.sp,
),
decoration: InputDecoration(
hintText: "请输入账号",
hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)),
labelText: "账号",
labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
),
),
TextField(
focusNode: _pwdFocus,
controller: _passwordController,
keyboardType: TextInputType.number,
maxLines: 1,
obscureText: _isShowPwd, //
textInputAction: TextInputAction.go,
onSubmitted: (_) => toRegister(),
style: TextStyle(
color: const Color.fromRGBO(80, 87, 103, 1),
fontSize: 15.sp,
),
decoration: InputDecoration(
hintText: "请输入密码",
suffix: GestureDetector(
onTap: _showPassword,
child: Icon(
Icons.remove_red_eye,
color: !_isShowPwd ? Theme.of(context).primaryColor : Colors.grey,
),
),
hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)),
labelText: "密码",
isDense: true,
labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
),
),
SizedBox(
height: 12.h,
),
InkWell(
onTap: toRegister,
child: Container(
margin: EdgeInsets.symmetric(vertical: 10.h),
decoration: BoxDecoration(
color: canLogin ? Theme.of(context).primaryColor : Colors.grey,
boxShadow: [
BoxShadow(
color: const Color.fromRGBO(76, 199, 147, 0.5),
offset: Offset(4.w, 6.h), //y轴偏移量
blurRadius: 10, //
spreadRadius: 0.5, //
)
],
borderRadius: BorderRadius.all(
Radius.circular(8.w),
),
),
alignment: Alignment.center,
width: double.infinity,
height: 50.h,
child: Text(
'注 册',
style: TextStyle(fontSize: 16.sp, color: Colors.white),
),
),
),
Row(
children: [
Container(
width: 30.w,
padding: EdgeInsets.only(right: 10.w),
child: Checkbox(
activeColor: Colors.deepOrangeAccent,
checkColor: Colors.white,
value: readAgreement,
onChanged: (value) {
FocusScope.of(context).requestFocus(_pwdFocus);
FocusScope.of(context).requestFocus(_theFocus);
setState(() {
readAgreement = value ?? false;
});
},
),
),
InkWell(
onTap: () {
// RouterManager.router.navigateTo(
// context,
// '${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}',
// transition: getTransition(),
// );
},
child: quickText('我已阅读', size: 11.sp),
),
InkWell(
onTap: () {
Get.toNamed(Routes.agreementPage, arguments: {"type": AGREEMENT_KEY.USER_AGREEMENT.name});
},
child: quickText(
'《用户协议》',
size: 12.sp,
color: Colors.deepOrangeAccent,
),
),
],
),
]),
)
],
),
)),
Positioned(
top: MediaQuery.of(context).padding.top + 20.r,
left: 20.r,
child: InkWell(
onTap: () => Navigator.pop(context),
child: Icon(Icons.arrow_back_ios_new_rounded, color: Colors.white, size: 24.sp),
),
),
],
),
),
),
);
}
}

View File

@ -0,0 +1,140 @@
import 'dart:io';
import 'package:get/get.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:making_school_asignment_app/common/const_text.dart';
import 'package:making_school_asignment_app/common/store/app_storage_key.dart';
import 'package:making_school_asignment_app/common/utils/storage.dart';
import 'package:making_school_asignment_app/common/utils/utils.dart';
import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart';
class Protocol extends Dialog {
final BuildContext context;
const Protocol(this.context, {super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: isPad() ? 200.w : 260.w,
height: 400.h,
padding: EdgeInsets.symmetric(vertical: 16.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
),
child: Column(
children: <Widget>[
quickText('用户协议与隐私政策', size: 15.sp, color: const Color.fromRGBO(37, 37, 37, 1), fontWeight: FontWeight.bold),
Expanded(
child: ListView(
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.fromLTRB(16.w, 14.h, 16.w, 10.h),
children: [
Text.rich(TextSpan(children: [
TextSpan(
text: '感谢您选择点智学APP ! 我们非常重视您的个人信息和隐私保护。为了更好地保障您的个人权益,在您使用我们的产品前,请务必审慎阅读',
style: TextStyle(fontSize: 13.sp, color: Color.fromRGBO(51, 51, 51, 1)),
),
TextSpan(
text: '《隐私政策》',
style: TextStyle(fontSize: 13.sp, color: Color.fromRGBO(233, 85, 119, 1)),
recognizer: TapGestureRecognizer()
..onTap = () async {
Get.toNamed(Routes.agreementPage, arguments: {"type": AGREEMENT_KEY.PRIVACY_GREEMENT.name});
// RouterManager.router.navigateTo(
// context,
// '${RouterManager.agreementPath}?type=${AGREEMENT_KEY.PRIVACY_GREEMENT.name}',
// transition: getTransition(),
// );
},
),
TextSpan(
text: '',
style: TextStyle(fontSize: 13.sp, color: Color.fromRGBO(51, 51, 51, 1)),
),
TextSpan(
text: '《用户协议》',
style: TextStyle(fontSize: 13.sp, color: Color.fromRGBO(233, 85, 119, 1)),
recognizer: TapGestureRecognizer()
..onTap = () async {
Get.toNamed(Routes.agreementPage, arguments: {"type": AGREEMENT_KEY.USER_AGREEMENT.name});
// RouterManager.router.navigateTo(
// context,
// '${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}',
// transition: getTransition(),
// );
},
),
TextSpan(
text:
'内的所有条款,尤其是:1.我们对您的个人信息的收集/保存/使用/对外提供/保护等规则条款,以及您的用户权利等条款;2.约定我们的限制责任、免责条款;3.其他以颜色或加粗进行标识的重要条款。如您对以上协议有任何疑问可通过发邮件至yuanxuanjiaoyu@gmail.com与我们联系。您点击"同意并继续”的行为即表示您已阅读完毕并同意以上协议的全部内容。如您同意以上协议内容,请点击"同意并继续”,开始使用我们的产品和服务!',
style: TextStyle(fontSize: 13.sp, color: const Color.fromRGBO(51, 51, 51, 1)),
),
])),
],
),
),
SizedBox(height: 10.h),
Row(
children: [
Expanded(
child: InkWell(
onTap: () {
exit(0);
},
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.only(top: 15.h),
decoration: BoxDecoration(
border: Border(
top: BorderSide(width: 0.5.r, color: const Color.fromRGBO(238, 238, 238, 1)),
right: BorderSide(width: 0.5.r, color: const Color.fromRGBO(238, 238, 238, 1)),
),
),
child: quickText('退出APP', size: 14.sp),
),
),
),
Expanded(
child: InkWell(
onTap: () {
StorageService.to.write(AppStorageKey.privacyAgreement.value, true);
Navigator.of(context).pop(true);
},
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.only(top: 15.h),
decoration: BoxDecoration(
border: Border(
top: BorderSide(width: 0.5.r, color: Color.fromRGBO(238, 238, 238, 1)),
),
),
child: quickText('同意并继续', color: Color.fromRGBO(206, 97, 126, 1), size: 14.sp),
),
),
)
],
),
],
),
),
);
}
}
///
Future<void> sysProtocol(BuildContext context) async {
bool? sysProtocol = StorageService.to.hasData(AppStorageKey.privacyAgreement.value);
if (!sysProtocol) {
return showDialog(
context: context,
barrierDismissible: false,
// useRootNavigator: false,
builder: (ctx) => Protocol(ctx),
);
}
}

View File

@ -1,6 +1,5 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart'; import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
@ -8,8 +7,8 @@ import 'package:making_school_asignment_app/common/store/user_store.dart';
import 'package:making_school_asignment_app/common/utils/storage.dart'; import 'package:making_school_asignment_app/common/utils/storage.dart';
import 'package:making_school_asignment_app/common/utils/toast_utils.dart'; import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
import 'package:making_school_asignment_app/common/utils/utils.dart'; import 'package:making_school_asignment_app/common/utils/utils.dart';
import 'package:making_school_asignment_app/page/login_page/children/sys_protocol.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart'; import 'package:making_school_asignment_app/routes/app_pages.dart';
import 'package:making_school_asignment_app/common/utils/storage.dart';
import 'package:making_school_asignment_app/common/store/app_storage_key.dart'; import 'package:making_school_asignment_app/common/store/app_storage_key.dart';
import 'login_state.dart'; import 'login_state.dart';
@ -41,6 +40,7 @@ class LoginLogic extends GetxController with RequestToolMixin {
state.pwdFocus = FocusNode(); state.pwdFocus = FocusNode();
state.theFocus = FocusNode(); state.theFocus = FocusNode();
getShowUserAdditionalFeatures(); //
} }
void userNameListener() { void userNameListener() {
@ -59,7 +59,7 @@ class LoginLogic extends GetxController with RequestToolMixin {
} }
// //
void toLogin() async { void toLogin(BuildContext context) async {
if (!state.canLogin.value) return; if (!state.canLogin.value) return;
state.canLogin.value = false; state.canLogin.value = false;
@ -77,6 +77,8 @@ class LoginLogic extends GetxController with RequestToolMixin {
if (userPwd == '') return toMsg('请填写密码再试'); if (userPwd == '') return toMsg('请填写密码再试');
if (!state.readAgreement.value) return toMsg('请阅读用户协议'); if (!state.readAgreement.value) return toMsg('请阅读用户协议');
await sysProtocol(context);
EasyLoading.show(status: 'loading...'); EasyLoading.show(status: 'loading...');
try { try {
@ -162,4 +164,9 @@ class LoginLogic extends GetxController with RequestToolMixin {
state.pwdFocus.dispose(); state.pwdFocus.dispose();
state.theFocus.dispose(); state.theFocus.dispose();
} }
///
Future<void> getShowUserAdditionalFeatures() async {
// state.showUserAdditionalFeatures.value = ;
}
} }

View File

@ -15,5 +15,6 @@ class LoginState {
late RxBool isShowPwd = true.obs; late RxBool isShowPwd = true.obs;
late RxBool keepPwd = false.obs; late RxBool keepPwd = false.obs;
late RxBool canLogin = true.obs; late RxBool canLogin = true.obs;
late RxBool readAgreement = true.obs; late RxBool readAgreement = false.obs;
late RxBool showUserAdditionalFeatures = false.obs;
} }

View File

@ -1,7 +1,7 @@
import 'package:get/get.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/const_text.dart'; import 'package:making_school_asignment_app/common/const_text.dart';
import 'package:making_school_asignment_app/common/utils/app_upgrade/upgradeLogic.dart'; import 'package:making_school_asignment_app/common/utils/app_upgrade/upgradeLogic.dart';
import 'package:making_school_asignment_app/common/utils/utils.dart'; import 'package:making_school_asignment_app/common/utils/utils.dart';
@ -11,7 +11,7 @@ import 'package:making_school_asignment_app/routes/app_pages.dart';
import 'login_logic.dart'; import 'login_logic.dart';
class LoginPage extends StatefulWidget { class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key); const LoginPage({super.key});
@override @override
State<LoginPage> createState() => _LoginPageState(); State<LoginPage> createState() => _LoginPageState();
@ -213,53 +213,72 @@ class _LoginPageState extends State<LoginPage> {
), ),
); );
}), }),
SizedBox( SizedBox(height: 10.h),
height: 22.h,
),
Row( Row(
children: [ children: [
Container( Expanded(
width: 25.w, child: Row(
padding: EdgeInsets.only(right: 0.w), children: [
child: Obx(() { Container(
return Transform.scale( width: 25.w,
scale: 1.2, padding: EdgeInsets.only(right: 0.w),
child: Checkbox( child: Obx(() {
activeColor: Theme.of(context).primaryColor, return Transform.scale(
checkColor: Colors.white, scale: 1.2,
value: state.keepPwd.value, child: Checkbox(
onChanged: (value) { // activeColor: Colors.transparent, //
// Get.focusScope?.nextFocus();
activeColor: Theme.of(context).primaryColor,
// checkColor: Colors.white,
value: state.keepPwd.value,
onChanged: (value) {
// Get.focusScope?.nextFocus();
FocusScope.of(context).requestFocus(state.pwdFocus);
FocusScope.of(context).requestFocus(state.theFocus);
state.keepPwd.value = value ?? false;
},
side: WidgetStateBorderSide.resolveWith(
(Set<WidgetState> states) {
if (states.contains(WidgetState.selected)) {
//
return BorderSide(width: 1.5.r, color: Theme.of(context).primaryColor);
}
//绿
return BorderSide(width: 1.5.r, color: Colors.white);
},
)),
);
}),
),
InkWell(
onTap: () {
Utils.hideKeyboard();
Get.focusScope?.nextFocus();
Get.focusScope?.nextFocus();
FocusScope.of(context).requestFocus(state.pwdFocus); FocusScope.of(context).requestFocus(state.pwdFocus);
FocusScope.of(context).requestFocus(state.theFocus); FocusScope.of(context).requestFocus(state.theFocus);
state.keepPwd.value = value ?? false; state.keepPwd.value = !state.keepPwd.value;
}, },
child: Text(
'记住密码',
style: TextStyle(
fontSize: 12.sp,
color: Colors.white,
),
),
), ),
); ],
}),
),
InkWell(
onTap: () {
Utils.hideKeyboard();
Get.focusScope?.nextFocus();
Get.focusScope?.nextFocus();
FocusScope.of(context).requestFocus(state.pwdFocus);
FocusScope.of(context).requestFocus(state.theFocus);
state.keepPwd.value = !state.keepPwd.value;
},
child: Text(
'记住密码',
style: TextStyle(
fontSize: 11.sp,
color: Colors.white,
),
), ),
), ),
InkWell(
onTap: () => Get.toNamed(Routes.register),
child: quickText('账号注册', color: Colors.white),
)
], ],
), ),
InkWell( InkWell(
onTap: () { onTap: () {
logic.toLogin(); logic.toLogin(context);
// Get.toNamed(Routes.home); // Get.toNamed(Routes.home);
}, },
child: Obx(() { child: Obx(() {
@ -282,10 +301,7 @@ class _LoginPageState extends State<LoginPage> {
alignment: Alignment.center, alignment: Alignment.center,
width: double.infinity, width: double.infinity,
height: 50.h, height: 50.h,
child: Text( child: Text('登 录', style: TextStyle(fontSize: 16.sp, color: Colors.white)),
'登 录',
style: TextStyle(fontSize: 16.sp, color: Colors.white),
),
); );
}), }),
), ),
@ -309,6 +325,16 @@ class _LoginPageState extends State<LoginPage> {
state.theFocus);*/ state.theFocus);*/
state.readAgreement.value = value ?? false; state.readAgreement.value = value ?? false;
}, },
side: WidgetStateBorderSide.resolveWith(
(Set<WidgetState> states) {
if (states.contains(WidgetState.selected)) {
//
return BorderSide(width: 1.5.r, color: Theme.of(context).primaryColor);
}
//绿
return BorderSide(width: 1.5.r, color: Colors.white);
},
),
), ),
); );
}), }),

View File

@ -35,6 +35,7 @@ import 'package:making_school_asignment_app/page/home_page/children/student_work
import 'package:making_school_asignment_app/page/home_page/home_binding.dart'; import 'package:making_school_asignment_app/page/home_page/home_binding.dart';
import 'package:making_school_asignment_app/page/home_page/home_view.dart'; import 'package:making_school_asignment_app/page/home_page/home_view.dart';
import 'package:making_school_asignment_app/page/login_page/children/agreement_page.dart'; import 'package:making_school_asignment_app/page/login_page/children/agreement_page.dart';
import 'package:making_school_asignment_app/page/login_page/children/register.dart';
import 'package:making_school_asignment_app/page/login_page/login_binding.dart'; import 'package:making_school_asignment_app/page/login_page/login_binding.dart';
import 'package:making_school_asignment_app/page/login_page/login_view.dart'; import 'package:making_school_asignment_app/page/login_page/login_view.dart';
import 'package:making_school_asignment_app/page/work_page/work_binding.dart'; import 'package:making_school_asignment_app/page/work_page/work_binding.dart';
@ -44,6 +45,7 @@ part 'app_routes.dart';
abstract class AppPages { abstract class AppPages {
static final pages = [ static final pages = [
GetPage(name: Routes.login, page: () => const LoginPage(), binding: LoginBinding(), transition: Transition.noTransition), GetPage(name: Routes.login, page: () => const LoginPage(), binding: LoginBinding(), transition: Transition.noTransition),
GetPage(name: Routes.register, page: () => const Register(), transition: getTransition()),
GetPage(name: Routes.agreementPage, page: () => const AgreementPage(), binding: LoginBinding(), transition: Transition.noTransition), GetPage(name: Routes.agreementPage, page: () => const AgreementPage(), binding: LoginBinding(), transition: Transition.noTransition),
GetPage(name: Routes.home, page: () => const HomePage(), binding: HomeBinding(), transition: Transition.noTransition), GetPage(name: Routes.home, page: () => const HomePage(), binding: HomeBinding(), transition: Transition.noTransition),
GetPage(name: Routes.startPage, page: () => const StartPage(), binding: StartPageIndexBinding(), transition: Transition.noTransition), GetPage(name: Routes.startPage, page: () => const StartPage(), binding: StartPageIndexBinding(), transition: Transition.noTransition),
@ -85,14 +87,20 @@ abstract class AppPages {
page: () => const KnowledgePointsGraspDetailPage(), page: () => const KnowledgePointsGraspDetailPage(),
binding: KnowledgePointsGraspDetailBinding(), binding: KnowledgePointsGraspDetailBinding(),
transition: Transition.noTransition), transition: Transition.noTransition),
GetPage(name: Routes.answerTrajectoryPage, page: () => const AnswerTrajectoryPage(), binding: AnswerTrajectoryBinding(), transition: Transition.noTransition), GetPage(
GetPage(name: Routes.answerTrajectoryDetailPage, page: () => const AnswerTrajectoryDetailPage(), binding: AnswerTrajectoryDetailBinding(), transition: Transition.noTransition), name: Routes.answerTrajectoryPage,
page: () => const AnswerTrajectoryPage(),
binding: AnswerTrajectoryBinding(),
transition: Transition.noTransition),
GetPage(
name: Routes.answerTrajectoryDetailPage,
page: () => const AnswerTrajectoryDetailPage(),
binding: AnswerTrajectoryDetailBinding(),
transition: Transition.noTransition),
// //
GetPage(name: Routes.reviewHomework, page: () => const HomeworkReview(), binding: HomeworkReviewBinding(), transition: getTransition()), GetPage(name: Routes.reviewHomework, page: () => const HomeworkReview(), binding: HomeworkReviewBinding(), transition: getTransition()),
GetPage(name: Routes.reviewExam, page: () => const HomeworkReview(), binding: HomeworkReviewBinding(), transition: getTransition()), GetPage(name: Routes.reviewExam, page: () => const HomeworkReview(), binding: HomeworkReviewBinding(), transition: getTransition()),
GetPage(name: Routes.favStudentPage, page: () => const FavStudentPage(), binding: FavStudentBinding(), transition: Transition.noTransition), GetPage(name: Routes.favStudentPage, page: () => const FavStudentPage(), binding: FavStudentBinding(), transition: Transition.noTransition),
]; ];
} }

View File

@ -2,6 +2,7 @@ part of 'app_pages.dart';
abstract class Routes { abstract class Routes {
static const login = '/login'; static const login = '/login';
static const register = '/register';
static const agreementPage = '/agreementPage'; static const agreementPage = '/agreementPage';
static const home = '/home'; static const home = '/home';
static const startPage = '/startPage'; static const startPage = '/startPage';
@ -24,5 +25,4 @@ abstract class Routes {
static const reviewHomework = '/review/reviewHomework'; // static const reviewHomework = '/review/reviewHomework'; //
static const reviewExam = '/review/reviewExam'; // static const reviewExam = '/review/reviewExam'; //
static const favStudentPage = '/favStudentPage'; // static const favStudentPage = '/favStudentPage'; //
}
}

View File

@ -91,10 +91,11 @@ dependencies:
url_launcher: ^6.1.11 url_launcher: ^6.1.11
app_installer: ^1.1.0 app_installer: ^1.1.0
auto_updater: ^0.2.1 auto_updater: ^0.2.1
permission_handler: ^11.0.1 permission_handler: ^11.3.1
flutter_distributor: ^0.4.5 flutter_distributor: ^0.4.5
flutter_native_splash: ^2.4.1 flutter_native_splash: ^2.4.1
icons_launcher: ^2.1.7 icons_launcher: ^2.1.7
app_settings: ^5.1.1
dev_dependencies: dev_dependencies: