From 0d852987fab70d85e16c3265b4a9d7ef838463f4 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Mon, 14 Aug 2023 10:05:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20app=E7=AB=AF=E9=A6=96=E9=A1=B5=E6=8E=A8?= =?UTF-8?q?=E8=8D=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/constants.dart | 7 +++ lib/http/init.dart | 3 ++ lib/http/interceptor.dart | 20 +++++++++ lib/http/user.dart | 18 ++++++++ lib/http/video.dart | 8 ++++ lib/models/home/rcmd/result.dart | 75 +++++++++++++++++++++++++++----- lib/pages/home/controller.dart | 2 + lib/pages/rcmd/controller.dart | 28 +++++++----- lib/utils/storage.dart | 2 + 9 files changed, 140 insertions(+), 23 deletions(-) diff --git a/lib/common/constants.dart b/lib/common/constants.dart index d321b903..08a54805 100644 --- a/lib/common/constants.dart +++ b/lib/common/constants.dart @@ -7,3 +7,10 @@ class StyleString { static const Radius imgRadius = Radius.circular(10); static const double aspectRatio = 16 / 10; } + +class Constants { + static const String appKey = '27eb53fc9058f8c3'; + static const String thirdSign = '04224646d1fea004e79606d3b038c84a'; + static const String thirdApi = + 'https://www.mcbbs.net/template/mcbbs/image/special_photo_bg.png'; +} diff --git a/lib/http/init.dart b/lib/http/init.dart index b36ff57e..6ffacc2f 100644 --- a/lib/http/init.dart +++ b/lib/http/init.dart @@ -58,6 +58,9 @@ class Request { log("setCookie, ${e.toString()}"); } } + var cookieString = + cookie.map((cookie) => '${cookie.name}=${cookie.value}').join('; '); + dio.options.headers['cookie'] = cookieString; } // 移除cookie diff --git a/lib/http/interceptor.dart b/lib/http/interceptor.dart index 87b97810..0ca6e866 100644 --- a/lib/http/interceptor.dart +++ b/lib/http/interceptor.dart @@ -1,6 +1,8 @@ import 'package:dio/dio.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:hive/hive.dart'; +import 'package:pilipala/utils/storage.dart'; // import 'package:get/get.dart' hide Response; class ApiInterceptor extends Interceptor { @@ -13,8 +15,26 @@ class ApiInterceptor extends Interceptor { handler.next(options); } + Box setting = GStrorage.setting; + @override void onResponse(Response response, ResponseInterceptorHandler handler) { + try { + if (response.statusCode == 302) { + List locations = response.headers['location']!; + if (locations.isNotEmpty) { + if (locations.first.startsWith('https://www.mcbbs.net')) { + final uri = Uri.parse(locations.first); + final accessKey = uri.queryParameters['access_key']; + final mid = uri.queryParameters['mid']; + setting.put(UserBoxKey.accessKey, {'mid': mid, 'value': accessKey}); + } + } + } + } catch (err) { + print('ApiInterceptor: $err'); + } + handler.next(response); } diff --git a/lib/http/user.dart b/lib/http/user.dart index 8cefb209..c189d3ce 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -1,4 +1,7 @@ +import 'package:dio/dio.dart'; +import 'package:pilipala/common/constants.dart'; import 'package:pilipala/http/api.dart'; +import 'package:pilipala/http/constants.dart'; import 'package:pilipala/http/init.dart'; import 'package:pilipala/models/model_hot_video_item.dart'; import 'package:pilipala/models/user/fav_detail.dart'; @@ -179,4 +182,19 @@ class UserHttp { return {'status': false, 'msg': res.data['message']}; } } + + // 获取用户凭证 + static Future thirdLogin() async { + var res = await Request().get( + 'https://passport.bilibili.com/login/app/third', + data: { + 'appkey': Constants.appKey, + 'api': Constants.thirdApi, + 'sign': Constants.thirdSign, + }, + ); + if (res.data['code'] == 0 && res.data['data']['has_login'] == 1) { + Request().get(res.data['data']['confirm_uri']); + } + } } diff --git a/lib/http/video.dart b/lib/http/video.dart index 24c0648a..79ffdde2 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -1,5 +1,7 @@ import 'dart:developer'; +import 'package:hive/hive.dart'; +import 'package:pilipala/common/constants.dart'; import 'package:pilipala/http/api.dart'; import 'package:pilipala/http/init.dart'; import 'package:pilipala/models/common/reply_type.dart'; @@ -9,12 +11,15 @@ import 'package:pilipala/models/model_rec_video_item.dart'; import 'package:pilipala/models/user/fav_folder.dart'; import 'package:pilipala/models/video/play/url.dart'; import 'package:pilipala/models/video_detail_res.dart'; +import 'package:pilipala/utils/storage.dart'; /// res.data['code'] == 0 请求正常返回结果 /// res.data['data'] 为结果 /// 返回{'status': bool, 'data': List} /// view层根据 status 判断渲染逻辑 class VideoHttp { + static Box setting = GStrorage.setting; + // 首页推荐视频 static Future rcmdVideoList({required int ps, required int freshIdx}) async { try { @@ -55,6 +60,9 @@ class VideoHttp { 'device_type': 0, 'device_name': 'vivo', 'pull': freshIdx == 0 ? 'true' : 'false', + 'appkey': Constants.appKey, + 'access_key': + setting.get(UserBoxKey.accessKey, defaultValue: {})['value'] ?? '' }, ); if (res.data['code'] == 0) { diff --git a/lib/models/home/rcmd/result.dart b/lib/models/home/rcmd/result.dart index 592d7edb..59515296 100644 --- a/lib/models/home/rcmd/result.dart +++ b/lib/models/home/rcmd/result.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + class RecVideoItemAppModel { RecVideoItemAppModel({ this.id, @@ -11,30 +13,60 @@ class RecVideoItemAppModel { this.isFollowed, this.owner, this.rcmdReason, + this.goto, + this.param, + this.uri, + this.talkBack, + this.bangumiView, + this.bangumiFollow, + this.bangumiBadge, }); int? id; int? aid; - int? bvid; + String? bvid; int? cid; String? pic; Stat? stat; - int? duration; + String? duration; String? title; int? isFollowed; Owner? owner; - String? rcmdReason; + RcmdReason? rcmdReason; + String? goto; + String? param; + String? uri; + String? talkBack; + // 番剧 + String? bangumiView; + String? bangumiFollow; + String? bangumiBadge; RecVideoItemAppModel.fromJson(Map json) { - id = json['player_args']['aid']; - aid = json['player_args']['aid']; - cid = json['player_args']['cid']; + id = json['player_args'] != null + ? json['player_args']['aid'] + : int.parse(json['param'] ?? '-1'); + aid = json['player_args'] != null ? json['player_args']['aid'] : -1; + cid = json['player_args'] != null ? json['player_args']['cid'] : -1; pic = json['cover']; stat = Stat.fromJson(json); - duration = json['player_args']['duration']; + duration = json['cover_right_text']; title = json['title']; isFollowed = 0; owner = Owner.fromJson(json); + rcmdReason = json['rcmd_reason_style'] != null + ? RcmdReason.fromJson(json['rcmd_reason_style']) + : null; + goto = json['goto']; + param = json['param']; + uri = json['uri']; + talkBack = json['talk_back']; + + if (json['goto'] == 'bangumi') { + bangumiView = json['cover_left_text_1']; + bangumiFollow = json['cover_left_text_2']; + bangumiBadge = json['badge']; + } } } @@ -42,15 +74,15 @@ class Stat { Stat({ this.view, this.like, - this.danmaku, + this.danmu, }); String? view; String? like; - String? danmaku; + String? danmu; Stat.fromJson(Map json) { view = json["cover_left_text_1"]; - danmaku = json['cover_left_text_2']; + danmu = json['cover_left_text_2']; } } @@ -58,8 +90,29 @@ class Owner { Owner({this.name}); String? name; + int? mid; Owner.fromJson(Map json) { - name = json['args']['up_name']; + if (json['goto'] == 'bangumi') { + log(json.toString()); + } + name = json['goto'] == 'av' + ? json['args']['up_name'] + : json['desc_button'] != null + ? json['desc_button']['text'] + : ''; + mid = json['args']['up_id'] ?? -1; + } +} + +class RcmdReason { + RcmdReason({ + this.content, + }); + + String? content; + + RcmdReason.fromJson(Map json) { + content = json["title"] ?? ''; } } diff --git a/lib/pages/home/controller.dart b/lib/pages/home/controller.dart index f5ce88ac..c031a2d9 100644 --- a/lib/pages/home/controller.dart +++ b/lib/pages/home/controller.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/http/index.dart'; +import 'package:pilipala/http/user.dart'; import 'package:pilipala/models/common/tab_type.dart'; import 'package:pilipala/utils/storage.dart'; @@ -54,6 +55,7 @@ class HomeController extends GetxController with GetTickerProviderStateMixin { if (res.data['code'] == 0) { defaultSearch.value = res.data['data']['name']; } + UserHttp.thirdLogin(); } // 更新登录状态 diff --git a/lib/pages/rcmd/controller.dart b/lib/pages/rcmd/controller.dart index f8461070..fa3a1147 100644 --- a/lib/pages/rcmd/controller.dart +++ b/lib/pages/rcmd/controller.dart @@ -2,15 +2,16 @@ import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/http/video.dart'; +import 'package:pilipala/models/home/rcmd/result.dart'; import 'package:pilipala/models/model_rec_video_item.dart'; import 'package:pilipala/utils/storage.dart'; class RcmdController extends GetxController { final ScrollController scrollController = ScrollController(); int count = 12; - int _currentPage = 1; + int _currentPage = 0; int crossAxisCount = 2; - RxList videoList = [RecVideoItemModel()].obs; + RxList videoList = [RecVideoItemAppModel()].obs; bool isLoadingMore = false; bool flag = false; OverlayEntry? popupDialog; @@ -19,19 +20,22 @@ class RcmdController extends GetxController { @override void onInit() { super.onInit(); - if (recVideo.get('cacheList') != null && - recVideo.get('cacheList').isNotEmpty) { - List list = []; - for (var i in recVideo.get('cacheList')) { - list.add(i); - } - videoList.value = list; - } + // if (recVideo.get('cacheList') != null && + // recVideo.get('cacheList').isNotEmpty) { + // List list = []; + // for (var i in recVideo.get('cacheList')) { + // list.add(i); + // } + // videoList.value = list; + // } } // 获取推荐 Future queryRcmdFeed(type) async { - var res = await VideoHttp.rcmdVideoList( + if (type == 'onRefresh') { + _currentPage = 0; + } + var res = await VideoHttp.rcmdVideoListApp( ps: count, freshIdx: _currentPage, ); @@ -47,7 +51,7 @@ class RcmdController extends GetxController { } else if (type == 'onLoad') { videoList.addAll(res['data']); } - recVideo.put('cacheList', res['data']); + // recVideo.put('cacheList', res['data']); _currentPage += 1; } isLoadingMore = false; diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index f1a25f49..b9ac3203 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -63,6 +63,8 @@ class UserBoxKey { static const String userMid = 'userMid'; // 登录状态 static const String userLogin = 'userLogin'; + // 凭证 + static const String accessKey = 'accessKey'; } class SettingBoxKey {