diff --git a/CHANGELOG.md b/CHANGELOG.md index 535f28b..2e48bee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.0.3 + +* 解决2.10.12及以下版本无法登录的问题 +* 适配最新版qinglong 相关接口字段 + ## 1.0.2 * 支持修改用户名密码(仅限使用用户名密码登录用户) diff --git a/lib/base/http/api.dart b/lib/base/http/api.dart index 508a26e..577da93 100644 --- a/lib/base/http/api.dart +++ b/lib/base/http/api.dart @@ -24,7 +24,18 @@ class Api { }, ); } - + static Future> loginOld( + String userName, + String passWord, + ) async { + return await Http.post( + Url.loginOld, + { + "username": userName, + "password": passWord, + }, + ); + } static Future> loginTwo( String userName, String passWord, @@ -103,6 +114,7 @@ class Api { if (id != null) { data["_id"] = id; + data["id"] = id; return await Http.put( Url.addTask, data, @@ -207,6 +219,7 @@ class Api { if (id != null) { data["_id"] = id; + data["id"] = id; return await Http.put( Url.addEnv, data, diff --git a/lib/base/http/http.dart b/lib/base/http/http.dart index f6d0133..0832509 100644 --- a/lib/base/http/http.dart +++ b/lib/base/http/http.dart @@ -5,6 +5,7 @@ import 'package:dio/dio.dart'; import 'package:dio_log/dio_log.dart'; import 'package:flutter/foundation.dart'; import 'package:qinglong_app/base/http/token_interceptor.dart'; +import 'package:qinglong_app/base/http/url.dart'; import 'package:qinglong_app/base/userinfo_viewmodel.dart'; import 'package:qinglong_app/utils/extension.dart'; @@ -54,7 +55,7 @@ class Http { return decodeResponse(response, serializationName, compute); } on DioError catch (e) { - return exceptionHandler(e); + return exceptionHandler(e, uri); } } @@ -74,7 +75,7 @@ class Http { compute, ); } on DioError catch (e) { - return exceptionHandler(e); + return exceptionHandler(e, uri); } } @@ -94,7 +95,7 @@ class Http { compute, ); } on DioError catch (e) { - return exceptionHandler(e); + return exceptionHandler(e, uri); } } @@ -113,7 +114,7 @@ class Http { compute, ); } on DioError catch (e) { - return exceptionHandler(e); + return exceptionHandler(e, uri); } } @@ -125,8 +126,8 @@ class Http { } } - static HttpResponse exceptionHandler(DioError e) { - if (e.response?.statusCode == 401) { + static HttpResponse exceptionHandler(DioError e, String path) { + if (e.response?.statusCode == 401 && !Url.inWhiteList(path)) { if (!getIt().useSecretLogined) { exitLogin(); } diff --git a/lib/base/http/token_interceptor.dart b/lib/base/http/token_interceptor.dart index 294e872..e174885 100644 --- a/lib/base/http/token_interceptor.dart +++ b/lib/base/http/token_interceptor.dart @@ -7,18 +7,18 @@ import '../userinfo_viewmodel.dart'; class TokenInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { - if (getIt().token != null && - getIt().token!.isNotEmpty) { - options.headers["Authorization"] = - "Bearer " + getIt().token!; + if (getIt().token != null && getIt().token!.isNotEmpty) { + options.headers["Authorization"] = "Bearer " + getIt().token!; } - options.headers["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"; + options.headers["User-Agent"] = + "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"; options.headers["Content-Type"] = "application/json;charset=UTF-8"; - if (options.path != Url.loginByClientId && options.path!= Url.loginTwo) { - options.queryParameters["t"] = - (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(); + + + if (!Url.inWhiteList(options.path)) { + options.queryParameters["t"] = (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(); } return handler.next(options); } diff --git a/lib/base/http/url.dart b/lib/base/http/url.dart index 7bd8cb4..4b6345d 100644 --- a/lib/base/http/url.dart +++ b/lib/base/http/url.dart @@ -3,6 +3,9 @@ import '../userinfo_viewmodel.dart'; class Url { static get login => "/api/user/login"; + + static get loginOld => "/api/login"; + static get loginTwo => "/api/user/two-factor/login"; static const loginByClientId = "/open/auth/token"; static const user = "/api/user"; @@ -50,6 +53,7 @@ class Url { static get taskLogDetail => getIt().useSecretLogined ? "/open/logs/" : "/api/logs/"; static get scripts => getIt().useSecretLogined ? "/open/scripts/files" : "/api/scripts/files"; + static get scriptUpdate => getIt().useSecretLogined ? "/open/scripts" : "/api/scripts"; static get scriptDetail => getIt().useSecretLogined ? "/open/scripts/" : "/api/scripts/"; @@ -58,9 +62,6 @@ class Url { static get dependencyReinstall => getIt().useSecretLogined ? "/open/dependencies/reinstall" : "/api/dependencies/reinstall"; - - - static intimeLog(String cronId) { return getIt().useSecretLogined ? "/open/crons/$cronId/log" : "/api/crons/$cronId/log"; } @@ -68,4 +69,11 @@ class Url { static envMove(String envId) { return getIt().useSecretLogined ? "/open/envs/$envId/move" : "/api/envs/$envId/move"; } + + static bool inWhiteList(String path) { + if (path == login || path == loginByClientId || path == loginTwo || path == loginOld) { + return true; + } + return false; + } } diff --git a/lib/module/env/env_bean.dart b/lib/module/env/env_bean.dart index 1cf32f9..d54c3d5 100644 --- a/lib/module/env/env_bean.dart +++ b/lib/module/env/env_bean.dart @@ -10,18 +10,11 @@ class EnvBean { String? name; String? remarks; - EnvBean( - {this.value, - this.sId, - this.created, - this.status, - this.timestamp, - this.name, - this.remarks}); + EnvBean({this.value, this.sId, this.created, this.status, this.timestamp, this.name, this.remarks}); EnvBean.fromJson(Map json) { value = json['value']; - sId = json['_id']; + sId = json.containsKey('_id') ? json['_id'].toString() : (json.containsKey('id') ? json['id'].toString() : ""); created = json['created']; status = json['status']; timestamp = json['timestamp']; diff --git a/lib/module/login/login_page.dart b/lib/module/login/login_page.dart index dc941b8..90a07d1 100644 --- a/lib/module/login/login_page.dart +++ b/lib/module/login/login_page.dart @@ -94,42 +94,24 @@ class _LoginPageState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( - height: MediaQuery.of(context).size.height / 10, + height: MediaQuery.of(context).size.height / 8, ), - SizedBox( - height: 50, - width: MediaQuery.of(context).size.width, - child: Stack( - children: [ - Positioned( - top: 0, - left: 0, + Row( + children: [ + Expanded( + child: Align( + alignment: Alignment.centerLeft, child: Image.asset( "assets/images/login_tip.png", height: 45, ), ), - const Positioned( - top: 10, - left: 0, - child: Text( - "登录", - style: TextStyle( - fontSize: 30, - fontWeight: FontWeight.bold, - ), - ), - ), - Positioned( - top: 5, - right: 0, - child: Image.asset( - "assets/images/ql.png", - height: 45, - ), - ), - ], - ), + ), + Image.asset( + "assets/images/ql.png", + height: 45, + ), + ], ), SizedBox( height: MediaQuery.of(context).size.height / 15, @@ -276,7 +258,9 @@ class _LoginPageState extends ConsumerState { ), ), Padding( - padding: const EdgeInsets.symmetric(horizontal: 25,), + padding: const EdgeInsets.symmetric( + horizontal: 25, + ), child: Row( children: [ Checkbox( @@ -307,7 +291,9 @@ class _LoginPageState extends ConsumerState { ), ), ), - SizedBox(width: 10,), + SizedBox( + width: 10, + ), ], ), ), @@ -316,7 +302,9 @@ class _LoginPageState extends ConsumerState { ), Container( alignment: Alignment.center, - padding: const EdgeInsets.symmetric(horizontal: 40,), + padding: const EdgeInsets.symmetric( + horizontal: 40, + ), child: SizedBox( width: MediaQuery.of(context).size.width - 80, child: IgnorePointer( @@ -377,72 +365,26 @@ class _LoginPageState extends ConsumerState { } if (response.success) { loginSuccess(response, userName, password); + } else if (loginByUserName() && response.code == 401) { + //可能用户使用的是老版本qinglong + HttpResponse oldResponse = await Api.loginOld(userName, password); + if (oldResponse.success) { + loginSuccess(oldResponse, userName, password); + } else { + (oldResponse.message ?? "请检查网络情况").toast(); + if (oldResponse.code == 420) { + twoFact(userName, password); + } else { + isLoading = false; + setState(() {}); + } + } } else { print(response.code); (response.message ?? "请检查网络情况").toast(); //420代表需要2步验证 if (response.code == 420) { - String twoFact = ""; - showCupertinoDialog( - context: context, - builder: (_) => CupertinoAlertDialog( - title: const Text("两步验证"), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Material( - color: Colors.transparent, - child: TextField( - onChanged: (value) { - twoFact = value; - }, - maxLines: 1, - keyboardType: TextInputType.number, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入code", - ), - autofocus: true, - ), - ), - ], - ), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: primaryColor, - ), - ), - onPressed: () async { - Navigator.of(context).pop(true); - HttpResponse response = await Api.loginTwo(userName, password, twoFact); - if (response.success) { - loginSuccess(response, userName, password); - } else { - loginFailed(response); - } - }, - ), - ], - )).then((value) { - if (value == null) { - isLoading = false; - setState(() {}); - } - }); + twoFact(userName, password); } else { isLoading = false; setState(() {}); @@ -475,4 +417,68 @@ class _LoginPageState extends ConsumerState { return _userNameController.text.isNotEmpty && _passwordController.text.isNotEmpty; } } + + void twoFact(String userName, String password) { + String twoFact = ""; + showCupertinoDialog( + context: context, + builder: (_) => CupertinoAlertDialog( + title: const Text("两步验证"), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Material( + color: Colors.transparent, + child: TextField( + onChanged: (value) { + twoFact = value; + }, + maxLines: 1, + keyboardType: TextInputType.number, + decoration: const InputDecoration( + contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), + hintText: "请输入code", + ), + autofocus: true, + ), + ), + ], + ), + actions: [ + CupertinoDialogAction( + child: const Text( + "取消", + style: TextStyle( + color: Color(0xff999999), + ), + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + CupertinoDialogAction( + child: Text( + "确定", + style: TextStyle( + color: primaryColor, + ), + ), + onPressed: () async { + Navigator.of(context).pop(true); + HttpResponse response = await Api.loginTwo(userName, password, twoFact); + if (response.success) { + loginSuccess(response, userName, password); + } else { + loginFailed(response); + } + }, + ), + ], + )).then((value) { + if (value == null) { + isLoading = false; + setState(() {}); + } + }); + } } diff --git a/lib/module/others/about_page.dart b/lib/module/others/about_page.dart index 4c4e825..6a21fcd 100644 --- a/lib/module/others/about_page.dart +++ b/lib/module/others/about_page.dart @@ -66,6 +66,21 @@ class _AboutPageState extends ConsumerState { fontSize: 16, ), ), + const SizedBox( + height: 15, + ), + GestureDetector( + onTap: () { + _launchURL("https://t.me/qinglongapp"); + }, + child: Text( + "Telegram频道", + style: TextStyle( + color: primaryColor, + fontSize: 16, + ), + ), + ), const Spacer(), Row( children: [ diff --git a/lib/module/others/other_page.dart b/lib/module/others/other_page.dart index 68d0921..339bf68 100644 --- a/lib/module/others/other_page.dart +++ b/lib/module/others/other_page.dart @@ -367,6 +367,9 @@ class _OtherPageState extends ConsumerState { }), ), ), + const SizedBox( + height: 30, + ), ], ), ); diff --git a/lib/module/task/task_bean.dart b/lib/module/task/task_bean.dart index d320e50..7d8ddf6 100644 --- a/lib/module/task/task_bean.dart +++ b/lib/module/task/task_bean.dart @@ -43,7 +43,7 @@ class TaskBean { command = json['command'].toString(); schedule = json['schedule'].toString(); saved = json['saved']; - sId = json['_id'].toString(); + sId = json.containsKey('_id') ? json['_id'].toString() : (json.containsKey('id') ? json['id'].toString() : ""); created = json['created']; status = json['status']; timestamp = json['timestamp'].toString(); diff --git a/pubspec.lock b/pubspec.lock index 25589ca..32253ba 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -884,4 +884,4 @@ packages: version: "3.1.0" sdks: dart: ">=2.15.1 <3.0.0" - flutter: ">=2.5.0" + flutter: ">=2.8.1" diff --git a/pubspec.yaml b/pubspec.yaml index bc82328..3df434f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,11 @@ name: qinglong_app description: A new Flutter project. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 1.0.2+3 +version: 1.0.3+4 environment: sdk: ">=2.15.1 <3.0.0" + flutter: ">=2.8.1" dependencies: