diff --git a/assets/loading.json b/assets/loading.json new file mode 100644 index 00000000..38bccbed --- /dev/null +++ b/assets/loading.json @@ -0,0 +1 @@ +{"v":"5.7.11","fr":60,"ip":0,"op":81,"w":1920,"h":1080,"nm":"Loading Dots","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Dot4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[25]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":39,"s":[100]},{"t":55,"s":[25]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":25,"s":[1142,540,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":39,"s":[1142,500,0],"to":[0,0,0],"ti":[0,-6.667,0]},{"t":55,"s":[1142,540,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-284,92,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":25,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":39,"s":[75,75,100]},{"t":55,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[120,120],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0039,0.6157,0.5686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-284,92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Dot3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":17,"s":[25]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":31,"s":[100]},{"t":47,"s":[25]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":17,"s":[1022,540,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":31,"s":[1022,500,0],"to":[0,0,0],"ti":[0,-6.667,0]},{"t":47,"s":[1022,540,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-284,92,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":17,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":31,"s":[75,75,100]},{"t":47,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[120,120],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0039,0.6157,0.5686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-284,92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Dot2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9,"s":[25]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":23,"s":[100]},{"t":39,"s":[25]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[902,540,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":23,"s":[902,500,0],"to":[0,0,0],"ti":[0,0,0]},{"t":39,"s":[902,540,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-284,92,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":9,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":23,"s":[75,75,100]},{"t":39,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[120,120],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0039,0.6157,0.5686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-284,92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Dot1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[25]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14,"s":[100]},{"t":30,"s":[25]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[782,540,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[782,500,0],"to":[0,0,0],"ti":[0,-6.667,0]},{"t":30,"s":[782,540,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-284,92,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":14,"s":[75,75,100]},{"t":30,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[120,120],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0039,0.6157,0.5686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-284,92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/assets/trail_loading.json b/assets/trail_loading.json new file mode 100644 index 00000000..9fb39ea6 --- /dev/null +++ b/assets/trail_loading.json @@ -0,0 +1 @@ +{"v":"4.6.8","fr":60,"ip":0,"op":106,"w":500,"h":500,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":20,"s":[0],"e":[360]},{"t":110}]},"p":{"a":0,"k":[251,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[10,10]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":20,"op":620,"st":20,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":15,"s":[0],"e":[360]},{"t":105}]},"p":{"a":0,"k":[251,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":15,"op":615,"st":15,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[0],"e":[360]},{"t":100}]},"p":{"a":0,"k":[251,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[30,30]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":10,"op":610,"st":10,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":5,"s":[0],"e":[360]},{"t":95}]},"p":{"a":0,"k":[251,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[40,40]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":5,"op":605,"st":5,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[360]},{"t":90}]},"p":{"a":0,"k":[250,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":0,"s":[50,50],"e":[40,40]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":84,"s":[40,40],"e":[50,50]},{"t":100}]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":600,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/lib/http/api.dart b/lib/http/api.dart index 42fc03b8..b0fc0556 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -400,12 +400,24 @@ class Api { '${HttpString.passBaseUrl}/x/passport-login/captcha?source=main_web'; // web端短信验证码 - static const String smsCode = + static const String webSmsCode = '${HttpString.passBaseUrl}/x/passport-login/web/sms/send'; // web端验证码登录 + static const String webSmsLogin = + '${HttpString.passBaseUrl}/x/passport-login/web/login/sms'; // web端密码登录 + static const String loginInByWebPwd = + '${HttpString.passBaseUrl}/x/passport-login/web/login'; + + // web端二维码 + static const String qrCodeApi = + '${HttpString.passBaseUrl}/x/passport-login/web/qrcode/generate'; + + // 扫码登录 + static const String loginInByQrcode = + '${HttpString.passBaseUrl}/x/passport-login/web/qrcode/poll'; // app端短信验证码 static const String appSmsCode = diff --git a/lib/http/login.dart b/lib/http/login.dart index ff3fee23..2437b72a 100644 --- a/lib/http/login.dart +++ b/lib/http/login.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:dio/dio.dart'; import 'package:encrypt/encrypt.dart'; +import 'package:pilipala/http/constants.dart'; import 'package:uuid/uuid.dart'; import '../models/login/index.dart'; import '../utils/login.dart'; @@ -21,32 +22,32 @@ class LoginHttp { } } - static Future sendSmsCode({ - int? cid, - required int tel, - required String token, - required String challenge, - required String validate, - required String seccode, - }) async { - var res = await Request().post( - Api.appSmsCode, - data: { - 'cid': cid, - 'tel': tel, - "source": "main_web", - 'token': token, - 'challenge': challenge, - 'validate': validate, - 'seccode': seccode, - }, - options: Options( - contentType: Headers.formUrlEncodedContentType, - // headers: {'user-agent': ApiConstants.userAgent} - ), - ); - print(res); - } + // static Future sendSmsCode({ + // int? cid, + // required int tel, + // required String token, + // required String challenge, + // required String validate, + // required String seccode, + // }) async { + // var res = await Request().post( + // Api.appSmsCode, + // data: { + // 'cid': cid, + // 'tel': tel, + // "source": "main_web", + // 'token': token, + // 'challenge': challenge, + // 'validate': validate, + // 'seccode': seccode, + // }, + // options: Options( + // contentType: Headers.formUrlEncodedContentType, + // // headers: {'user-agent': ApiConstants.userAgent} + // ), + // ); + // print(res); + // } // web端验证码 static Future sendWebSmsCode({ @@ -60,6 +61,7 @@ class LoginHttp { Map data = { 'cid': cid, 'tel': tel, + "source": "main_web", 'token': token, 'challenge': challenge, 'validate': validate, @@ -67,17 +69,56 @@ class LoginHttp { }; FormData formData = FormData.fromMap({...data}); var res = await Request().post( - Api.smsCode, + Api.webSmsCode, data: formData, options: Options( contentType: Headers.formUrlEncodedContentType, ), ); - print(res); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } } // web端验证码登录 - static Future loginInByWebSmsCode() async {} + static Future loginInByWebSmsCode({ + int? cid, + required int tel, + required int code, + required String captchaKey, + }) async { + // webSmsLogin + Map data = { + "cid": cid, + "tel": tel, + "code": code, + "source": "main_mini", + "keep": 0, + "captcha_key": captchaKey, + "go_url": HttpString.baseUrl + }; + FormData formData = FormData.fromMap({...data}); + var res = await Request().post( + Api.webSmsLogin, + data: formData, + options: Options( + contentType: Headers.formUrlEncodedContentType, + ), + ); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } // web端密码登录 static Future liginInByWebPwd() async {} @@ -173,4 +214,69 @@ class LoginHttp { ); print(res); } + + // web端密码登录 + static Future loginInByWebPwd({ + required int username, + required String password, + required String token, + required String challenge, + required String validate, + required String seccode, + }) async { + Map data = { + 'username': username, + 'password': password, + 'keep': 0, + 'token': token, + 'challenge': challenge, + 'validate': validate, + 'seccode': seccode, + 'source': 'main-fe-header', + "go_url": HttpString.baseUrl + }; + FormData formData = FormData.fromMap({...data}); + var res = await Request().post( + Api.loginInByWebPwd, + data: formData, + options: Options( + contentType: Headers.formUrlEncodedContentType, + ), + ); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } + + // web端登录二维码 + static Future getWebQrcode() async { + var res = await Request().get(Api.qrCodeApi); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } + + // web端二维码轮询登录状态 + static Future queryWebQrcodeStatus(String qrcodeKey) async { + var res = await Request() + .get(Api.loginInByQrcode, data: {'qrcode_key': qrcodeKey}); + if (res.data['data']['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } } diff --git a/lib/models/home/rcmd/result.dart b/lib/models/home/rcmd/result.dart index 78747d1a..0098fe95 100644 --- a/lib/models/home/rcmd/result.dart +++ b/lib/models/home/rcmd/result.dart @@ -69,9 +69,10 @@ class RecVideoItemAppModel { : null; // 由于app端api并不会直接返回与owner的关注状态 // 所以借用推荐原因是否为“已关注”、“新关注”等判别关注状态,从而与web端接口等效 + RegExp regex = RegExp(r'已关注|新关注'); isFollowed = rcmdReason != null && rcmdReason!.content != null && - rcmdReason!.content!.contains('关注') + regex.hasMatch(rcmdReason!.content!) ? 1 : 0; // 如果是,就无需再显示推荐原因,交由view统一处理即可 diff --git a/lib/pages/login/controller.dart b/lib/pages/login/controller.dart index c002fdf9..b5ddba16 100644 --- a/lib/pages/login/controller.dart +++ b/lib/pages/login/controller.dart @@ -1,11 +1,14 @@ +import 'dart:async'; import 'dart:io'; +import 'package:encrypt/encrypt.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:pilipala/http/login.dart'; import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart'; import 'package:pilipala/models/login/index.dart'; +import 'package:pilipala/utils/login.dart'; class LoginPageController extends GetxController { final GlobalKey mobFormKey = GlobalKey(); @@ -26,9 +29,23 @@ class LoginPageController extends GetxController { final Gt3FlutterPlugin captcha = Gt3FlutterPlugin(); + // 倒计时60s + RxInt seconds = 60.obs; + late Timer timer; + RxBool smsCodeSendStatus = false.obs; + // 默认密码登录 RxInt loginType = 0.obs; + late String captchaKey; + + late int tel; + late int webSmsCode; + + RxInt validSeconds = 180.obs; + late Timer validTimer; + late String qrcodeKey; + // 监听pageView切换 void onPageChange(int index) { currentIndex.value = index; @@ -43,6 +60,7 @@ class LoginPageController extends GetxController { curve: Curves.easeInOut, ); passwordTextFieldNode.requestFocus(); + (mobFormKey.currentState as FormState).save(); } } @@ -86,18 +104,64 @@ class LoginPageController extends GetxController { } } - // 验证码登录 - void loginInByCode() { - if ((msgCodeFormKey.currentState as FormState).validate()) {} + // web端密码登录 + void loginInByWebPassword() async { + if ((passwordFormKey.currentState as FormState).validate()) { + getCaptcha((data) async { + CaptchaDataModel captchaData = data; + var webKeyRes = await LoginHttp.getWebKey(); + if (webKeyRes['status']) { + String rhash = webKeyRes['data']['hash']; + String key = webKeyRes['data']['key']; + dynamic publicKey = RSAKeyParser().parse(key); + String passwordEncryptyed = Encrypter(RSA(publicKey: publicKey)) + .encrypt(rhash + passwordTextController.text) + .base64; + var res = await LoginHttp.loginInByWebPwd( + username: tel, + password: passwordEncryptyed, + token: captchaData.token!, + challenge: captchaData.geetest!.challenge!, + validate: captchaData.validate!, + seccode: captchaData.seccode!, + ); + if (res['status']) { + await LoginUtils.confirmLogin('', null); + } else { + SmartDialog.showToast(res['msg']); + } + } else { + SmartDialog.showToast(webKeyRes['msg']); + } + }); + } } - // app端验证码 - void getMsgCode() async { + // web端验证码登录 + void loginInByCode() async { + if ((msgCodeFormKey.currentState as FormState).validate()) { + (msgCodeFormKey.currentState as FormState).save(); + var res = await LoginHttp.loginInByWebSmsCode( + cid: 86, + tel: tel, + code: webSmsCode, + captchaKey: captchaKey, + ); + if (res['status']) { + await LoginUtils.confirmLogin('', null); + } else { + SmartDialog.showToast(res['msg']); + } + } + } + + // 获取app端验证码 + void getAppMsgCode() async { getCaptcha((data) async { CaptchaDataModel captchaData = data; var res = await LoginHttp.sendAppSmsCode( cid: 86, - tel: 13734077064, + tel: tel, token: captchaData.token!, challenge: captchaData.geetest!.challenge!, validate: captchaData.validate!, @@ -121,7 +185,7 @@ class LoginPageController extends GetxController { captcha.addEventHandler(onShow: (Map message) async { SmartDialog.dismiss(); }, onClose: (Map message) async { - SmartDialog.showToast('关闭验证'); + SmartDialog.showToast('取消验证'); }, onResult: (Map message) async { debugPrint("Captcha result: $message"); String code = message["code"]; @@ -201,4 +265,72 @@ class LoginPageController extends GetxController { captcha.startCaptcha(registerData); } else {} } + + // 获取web端验证码 + void getWebMsgCode() async { + getCaptcha((data) async { + CaptchaDataModel captchaData = data; + var res = await LoginHttp.sendWebSmsCode( + cid: 86, + tel: tel, + token: captchaData.token!, + challenge: captchaData.geetest!.challenge!, + validate: captchaData.validate!, + seccode: captchaData.seccode!, + ); + if (res['status']) { + captchaKey = res['data']['captcha_key']; + SmartDialog.showToast('验证码已发送'); + // 倒计时60s + smsCodeSendStatus.value = true; + startTimer(); + } else { + SmartDialog.showToast(res['msg']); + } + }); + } + + // 验证码倒计时 + void startTimer() { + timer = Timer.periodic(const Duration(seconds: 1), (timer) { + if (seconds.value > 0) { + seconds.value--; + } else { + seconds.value = 60; + smsCodeSendStatus.value = false; + timer.cancel(); + } + }); + } + + // 获取登录二维码 + Future getWebQrcode() async { + var res = await LoginHttp.getWebQrcode(); + validSeconds.value = 180; + if (res['status']) { + qrcodeKey = res['data']['qrcode_key']; + validTimer = Timer.periodic(const Duration(seconds: 1), (validTimer) { + if (validSeconds.value > 0) { + validSeconds.value--; + queryWebQrcodeStatus(); + } else { + getWebQrcode(); + validTimer.cancel(); + } + }); + return res; + } else { + SmartDialog.showToast(res['msg']); + } + } + + // 轮询二维码登录状态 + Future queryWebQrcodeStatus() async { + var res = await LoginHttp.queryWebQrcodeStatus(qrcodeKey); + if (res['status']) { + await LoginUtils.confirmLogin('', null); + validTimer.cancel(); + Get.back(); + } + } } diff --git a/lib/pages/login/view.dart b/lib/pages/login/view.dart index 6521e9d9..cd91ea26 100644 --- a/lib/pages/login/view.dart +++ b/lib/pages/login/view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:qr_flutter/qr_flutter.dart'; import 'controller.dart'; @@ -37,6 +38,105 @@ class _LoginPageState extends State { icon: const Icon(Icons.arrow_back), ), ), + actions: [ + IconButton( + tooltip: '浏览器打开', + onPressed: () { + Get.offNamed( + '/webview', + parameters: { + 'url': 'https://passport.bilibili.com/h5-app/passport/login', + 'type': 'login', + 'pageTitle': '登录bilibili', + }, + ); + }, + icon: const Icon(Icons.language), + ), + IconButton( + tooltip: '二维码登录', + onPressed: () { + showDialog( + context: context, + builder: (context) { + return StatefulBuilder( + builder: (context, StateSetter setState) { + return AlertDialog( + title: Row( + children: [ + const Text('扫码登录'), + IconButton( + onPressed: () { + setState(() {}); + }, + icon: const Icon(Icons.refresh), + ), + ], + ), + contentPadding: const EdgeInsets.fromLTRB(0, 0, 0, 4), + content: AspectRatio( + aspectRatio: 1, + child: Container( + width: 200, + padding: const EdgeInsets.all(12), + child: FutureBuilder( + future: _loginPageCtr.getWebQrcode(), + builder: (context, snapshot) { + if (snapshot.connectionState == + ConnectionState.done) { + if (snapshot.data == null) { + return const SizedBox(); + } + Map data = snapshot.data as Map; + return QrImageView( + data: data['data']['url'], + backgroundColor: Colors.transparent, + ); + } else { + return const Center( + child: SizedBox( + width: 40, + height: 40, + child: CircularProgressIndicator(), + ), + ); + } + }, + ), + ), + ), + actions: [ + TextButton( + onPressed: () {}, + child: Obx(() { + return Text( + '有效期: ${_loginPageCtr.validSeconds.value}s', + style: Theme.of(context).textTheme.titleMedium, + ); + }), + ), + TextButton( + onPressed: () {}, + child: Text( + '检查登录状态', + style: TextStyle( + fontSize: Theme.of(context) + .textTheme + .titleMedium! + .fontSize, + ), + ), + ) + ], + ); + }); + }, + ); + }, + icon: const Icon(Icons.qr_code), + ), + const SizedBox(width: 22), + ], ), body: PageView( physics: const NeverScrollableScrollPhysics(), @@ -93,35 +193,12 @@ class _LoginPageState extends State { validator: (v) { return v!.trim().isNotEmpty ? null : "手机号码不能为空"; }, - onSaved: (val) { - print(val); - }, + onSaved: (val) => _loginPageCtr.tel = int.parse(val!), onEditingComplete: () { _loginPageCtr.nextStep(); }, ), ), - GestureDetector( - onTap: () { - Get.offNamed( - '/webview', - parameters: { - 'url': - 'https://passport.bilibili.com/h5-app/passport/login', - 'type': 'login', - 'pageTitle': '登录bilibili', - }, - ); - }, - child: Padding( - padding: const EdgeInsets.only(left: 2), - child: Text( - '使用网页端登录', - style: TextStyle( - color: Theme.of(context).colorScheme.primary), - ), - ), - ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -236,7 +313,7 @@ class _LoginPageState extends State { .primary, // 设置按钮背景色 ), onPressed: () => - _loginPageCtr.loginInByAppPassword(), + _loginPageCtr.loginInByWebPassword(), child: const Text('确认登录'), ) ], @@ -308,21 +385,28 @@ class _LoginPageState extends State { ? null : "验证码不能为空"; }, - onSaved: (val) { - print(val); - }, + onSaved: (val) => _loginPageCtr.webSmsCode = + int.parse(val!), ), - Positioned( - right: 8, - top: 4, - child: Center( - child: TextButton( - onPressed: () => - _loginPageCtr.getMsgCode(), - child: const Text('获取验证码'), + Obx(() { + return Positioned( + right: 8, + top: 0, + child: Center( + child: TextButton( + onPressed: _loginPageCtr + .smsCodeSendStatus.value + ? null + : () => + _loginPageCtr.getWebMsgCode(), + child: _loginPageCtr + .smsCodeSendStatus.value + ? Text( + '重新获取(${_loginPageCtr.seconds.value}s)') + : const Text('获取验证码')), ), - ), - ), + ); + }) ], ), ), diff --git a/lib/pages/mine/controller.dart b/lib/pages/mine/controller.dart index a61bb820..153a7162 100644 --- a/lib/pages/mine/controller.dart +++ b/lib/pages/mine/controller.dart @@ -6,7 +6,6 @@ import 'package:pilipala/http/user.dart'; import 'package:pilipala/models/common/theme_type.dart'; import 'package:pilipala/models/user/info.dart'; import 'package:pilipala/models/user/stat.dart'; -import 'package:pilipala/utils/route_push.dart'; import 'package:pilipala/utils/storage.dart'; class MineController extends GetxController { @@ -34,8 +33,8 @@ class MineController extends GetxController { onLogin() async { if (!userLogin.value) { - RoutePush.loginPush(); - // Get.toNamed('/loginPage'); + // RoutePush.loginPush(); + Get.toNamed('/loginPage'); } else { int mid = userInfo.value.mid!; String face = userInfo.value.face!; diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 9103c130..06a026aa 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -5,6 +5,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; +import 'package:lottie/lottie.dart'; import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/pages/video/detail/index.dart'; @@ -97,11 +98,14 @@ class _VideoIntroPanelState extends State ); } } else { - return const SliverToBoxAdapter( + return SliverToBoxAdapter( child: SizedBox( height: 100, child: Center( - child: CircularProgressIndicator(), + child: Lottie.asset( + 'assets/loading.json', + width: 200, + ), ), ), ); @@ -595,8 +599,4 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ); }); } - - // Widget StaffPanel(BuildContext context, videoIntroController) { - // return - // } } diff --git a/lib/pages/webview/controller.dart b/lib/pages/webview/controller.dart index bdacc652..e0ff113c 100644 --- a/lib/pages/webview/controller.dart +++ b/lib/pages/webview/controller.dart @@ -76,7 +76,7 @@ class WebviewController extends GetxController { (url.startsWith( 'https://passport.bilibili.com/web/sso/exchange_cookie') || url.startsWith('https://m.bilibili.com/'))) { - confirmLogin(url); + LoginUtils.confirmLogin(url, controller); } }, onWebResourceError: (WebResourceError error) {}, @@ -97,54 +97,4 @@ class WebviewController extends GetxController { ) ..loadRequest(Uri.parse(url)); } - - confirmLogin(url) async { - var content = ''; - if (url != null) { - content = '${content + url}; \n'; - } - try { - await SetCookie.onSet(); - final result = await UserHttp.userInfo(); - if (result['status'] && result['data'].isLogin) { - SmartDialog.showToast('登录成功'); - try { - Box userInfoCache = GStrorage.userInfo; - if (!userInfoCache.isOpen) { - userInfoCache = await Hive.openBox('userInfo'); - } - await userInfoCache.put('userInfoCache', result['data']); - - final HomeController homeCtr = Get.find(); - homeCtr.updateLoginStatus(true); - homeCtr.userFace.value = result['data'].face; - final MediaController mediaCtr = Get.find(); - mediaCtr.mid = result['data'].mid; - await LoginUtils.refreshLoginStatus(true); - } catch (err) { - SmartDialog.show(builder: (BuildContext context) { - return AlertDialog( - title: const Text('登录遇到问题'), - content: Text(err.toString()), - actions: [ - TextButton( - onPressed: () => controller.reload(), - child: const Text('确认'), - ) - ], - ); - }); - } - Get.back(); - } else { - // 获取用户信息失败 - SmartDialog.showToast(result['msg']); - Clipboard.setData(ClipboardData(text: result['msg'])); - } - } catch (e) { - SmartDialog.showNotify(msg: e.toString(), notifyType: NotifyType.warning); - content = content + e.toString(); - Clipboard.setData(ClipboardData(text: content)); - } - } } diff --git a/lib/pages/webview/view.dart b/lib/pages/webview/view.dart index 8edd2189..cba40ad1 100644 --- a/lib/pages/webview/view.dart +++ b/lib/pages/webview/view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:pilipala/utils/login.dart'; import 'package:url_launcher/url_launcher.dart'; import 'controller.dart'; import 'package:webview_flutter/webview_flutter.dart'; @@ -43,7 +44,8 @@ class _WebviewPageState extends State { Obx( () => _webviewController.type.value == 'login' ? TextButton( - onPressed: () => _webviewController.confirmLogin(null), + onPressed: () => + LoginUtils.confirmLogin(null, _webviewController), child: const Text('刷新登录状态'), ) : const SizedBox(), diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index a695e752..34140be8 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -7,6 +7,7 @@ import 'package:flutter_volume_controller/flutter_volume_controller.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; +import 'package:lottie/lottie.dart'; import 'package:media_kit/media_kit.dart'; import 'package:media_kit_video/media_kit_video.dart'; import 'package:pilipala/models/common/gesture_mode.dart'; @@ -913,9 +914,9 @@ class _PLVideoPlayerState extends State colors: [Colors.black26, Colors.transparent], ), ), - child: Image.asset( - 'assets/images/loading.gif', - height: 25, + child: Lottie.asset( + 'assets/loading.json', + width: 200, ), ), ); diff --git a/lib/utils/login.dart b/lib/utils/login.dart index 59c53027..2687a8c2 100644 --- a/lib/utils/login.dart +++ b/lib/utils/login.dart @@ -2,12 +2,18 @@ import 'dart:convert'; import 'dart:math'; import 'package:crypto/crypto.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; +import 'package:hive/hive.dart'; +import 'package:pilipala/http/user.dart'; import 'package:pilipala/pages/dynamics/index.dart'; import 'package:pilipala/pages/home/index.dart'; import 'package:pilipala/pages/media/index.dart'; import 'package:pilipala/pages/mine/index.dart'; +import 'package:pilipala/utils/cookie.dart'; +import 'package:pilipala/utils/storage.dart'; import 'package:uuid/uuid.dart'; class LoginUtils { @@ -57,4 +63,56 @@ class LoginUtils { String uuid = getUUID() + getUUID(); return 'XY${uuid.substring(0, 35).toUpperCase()}'; } + + static confirmLogin(url, controller) async { + var content = ''; + if (url != null) { + content = '${content + url}; \n'; + } + try { + await SetCookie.onSet(); + final result = await UserHttp.userInfo(); + if (result['status'] && result['data'].isLogin) { + SmartDialog.showToast('登录成功'); + try { + Box userInfoCache = GStrorage.userInfo; + if (!userInfoCache.isOpen) { + userInfoCache = await Hive.openBox('userInfo'); + } + await userInfoCache.put('userInfoCache', result['data']); + + final HomeController homeCtr = Get.find(); + homeCtr.updateLoginStatus(true); + homeCtr.userFace.value = result['data'].face; + final MediaController mediaCtr = Get.find(); + mediaCtr.mid = result['data'].mid; + await LoginUtils.refreshLoginStatus(true); + } catch (err) { + SmartDialog.show(builder: (BuildContext context) { + return AlertDialog( + title: const Text('登录遇到问题'), + content: Text(err.toString()), + actions: [ + TextButton( + onPressed: controller != null + ? () => controller.reload() + : SmartDialog.dismiss, + child: const Text('确认'), + ) + ], + ); + }); + } + Get.back(); + } else { + // 获取用户信息失败 + SmartDialog.showToast(result['msg']); + Clipboard.setData(ClipboardData(text: result['msg'])); + } + } catch (e) { + SmartDialog.showNotify(msg: e.toString(), notifyType: NotifyType.warning); + content = content + e.toString(); + Clipboard.setData(ClipboardData(text: content)); + } + } } diff --git a/pubspec.lock b/pubspec.lock index de434f2e..5c6f2b43 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -674,10 +674,10 @@ packages: dependency: "direct main" description: name: gt3_flutter_plugin - sha256: f12bff2bfbcf27467833f8d564dcc24ee2f1b3254a7c7cf5eb2c4590baf11cc1 + sha256: "08f35692e937770ad6b3e2017eb8ef81839a82b8a63f5acf3abab14b688fc36c" url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.8" + version: "0.1.0" hive: dependency: "direct main" description: @@ -862,6 +862,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" + lottie: + dependency: "direct main" + description: + name: lottie + sha256: "6a24ade5d3d918c306bb1c21a6b9a04aab0489d51a2582522eea820b4093b62b" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.2" mailer: dependency: transitive description: @@ -973,10 +981,10 @@ packages: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.4" + version: "1.0.5" nm: dependency: transitive description: @@ -1046,10 +1054,10 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.1" + version: "2.1.3" path_provider_android: dependency: transitive description: @@ -1062,10 +1070,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.flutter-io.cn" source: hosted - version: "2.3.1" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -1210,6 +1218,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "3.1.0" + qr: + dependency: transitive + description: + name: qr + sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.1" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.1.0" rxdart: dependency: transitive description: @@ -1230,10 +1254,10 @@ packages: dependency: "direct main" description: name: saver_gallery - sha256: "2657953427ebe5a3b2d08157d41587c01923ccce3f1a616d55082be7470f8530" + sha256: "0f740608072053a0da3b19cc5812a87e36f5c3c0b959d2475c4eb3d697f4a782" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.1" + version: "3.0.3" screen_brightness: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index b9390dd9..66187abf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -132,7 +132,7 @@ dependencies: # html渲染 flutter_html: ^3.0.0-beta.2 # 极验 - gt3_flutter_plugin: ^0.0.8 + gt3_flutter_plugin: ^0.1.0 uuid: ^3.0.7 scrollable_positioned_list: ^0.3.8 catcher_2: ^1.2.6 @@ -144,6 +144,9 @@ dependencies: expandable: ^5.0.1 # 投屏 dlna_dart: ^0.0.8 + lottie: ^3.1.2 + # 二维码 + qr_flutter: ^4.1.0 dev_dependencies: flutter_test: @@ -203,6 +206,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: + - assets/ - assets/images/ - assets/images/lv/ - assets/images/logo/