feat: app端首页推荐
This commit is contained in:
@ -7,3 +7,10 @@ class StyleString {
|
|||||||
static const Radius imgRadius = Radius.circular(10);
|
static const Radius imgRadius = Radius.circular(10);
|
||||||
static const double aspectRatio = 16 / 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';
|
||||||
|
}
|
||||||
|
@ -58,6 +58,9 @@ class Request {
|
|||||||
log("setCookie, ${e.toString()}");
|
log("setCookie, ${e.toString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var cookieString =
|
||||||
|
cookie.map((cookie) => '${cookie.name}=${cookie.value}').join('; ');
|
||||||
|
dio.options.headers['cookie'] = cookieString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除cookie
|
// 移除cookie
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.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;
|
// import 'package:get/get.dart' hide Response;
|
||||||
|
|
||||||
class ApiInterceptor extends Interceptor {
|
class ApiInterceptor extends Interceptor {
|
||||||
@ -13,8 +15,26 @@ class ApiInterceptor extends Interceptor {
|
|||||||
handler.next(options);
|
handler.next(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Box setting = GStrorage.setting;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||||
|
try {
|
||||||
|
if (response.statusCode == 302) {
|
||||||
|
List<String> 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);
|
handler.next(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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/api.dart';
|
||||||
|
import 'package:pilipala/http/constants.dart';
|
||||||
import 'package:pilipala/http/init.dart';
|
import 'package:pilipala/http/init.dart';
|
||||||
import 'package:pilipala/models/model_hot_video_item.dart';
|
import 'package:pilipala/models/model_hot_video_item.dart';
|
||||||
import 'package:pilipala/models/user/fav_detail.dart';
|
import 'package:pilipala/models/user/fav_detail.dart';
|
||||||
@ -179,4 +182,19 @@ class UserHttp {
|
|||||||
return {'status': false, 'msg': res.data['message']};
|
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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:pilipala/common/constants.dart';
|
||||||
import 'package:pilipala/http/api.dart';
|
import 'package:pilipala/http/api.dart';
|
||||||
import 'package:pilipala/http/init.dart';
|
import 'package:pilipala/http/init.dart';
|
||||||
import 'package:pilipala/models/common/reply_type.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/user/fav_folder.dart';
|
||||||
import 'package:pilipala/models/video/play/url.dart';
|
import 'package:pilipala/models/video/play/url.dart';
|
||||||
import 'package:pilipala/models/video_detail_res.dart';
|
import 'package:pilipala/models/video_detail_res.dart';
|
||||||
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
/// res.data['code'] == 0 请求正常返回结果
|
/// res.data['code'] == 0 请求正常返回结果
|
||||||
/// res.data['data'] 为结果
|
/// res.data['data'] 为结果
|
||||||
/// 返回{'status': bool, 'data': List}
|
/// 返回{'status': bool, 'data': List}
|
||||||
/// view层根据 status 判断渲染逻辑
|
/// view层根据 status 判断渲染逻辑
|
||||||
class VideoHttp {
|
class VideoHttp {
|
||||||
|
static Box setting = GStrorage.setting;
|
||||||
|
|
||||||
// 首页推荐视频
|
// 首页推荐视频
|
||||||
static Future rcmdVideoList({required int ps, required int freshIdx}) async {
|
static Future rcmdVideoList({required int ps, required int freshIdx}) async {
|
||||||
try {
|
try {
|
||||||
@ -55,6 +60,9 @@ class VideoHttp {
|
|||||||
'device_type': 0,
|
'device_type': 0,
|
||||||
'device_name': 'vivo',
|
'device_name': 'vivo',
|
||||||
'pull': freshIdx == 0 ? 'true' : 'false',
|
'pull': freshIdx == 0 ? 'true' : 'false',
|
||||||
|
'appkey': Constants.appKey,
|
||||||
|
'access_key':
|
||||||
|
setting.get(UserBoxKey.accessKey, defaultValue: {})['value'] ?? ''
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
class RecVideoItemAppModel {
|
class RecVideoItemAppModel {
|
||||||
RecVideoItemAppModel({
|
RecVideoItemAppModel({
|
||||||
this.id,
|
this.id,
|
||||||
@ -11,30 +13,60 @@ class RecVideoItemAppModel {
|
|||||||
this.isFollowed,
|
this.isFollowed,
|
||||||
this.owner,
|
this.owner,
|
||||||
this.rcmdReason,
|
this.rcmdReason,
|
||||||
|
this.goto,
|
||||||
|
this.param,
|
||||||
|
this.uri,
|
||||||
|
this.talkBack,
|
||||||
|
this.bangumiView,
|
||||||
|
this.bangumiFollow,
|
||||||
|
this.bangumiBadge,
|
||||||
});
|
});
|
||||||
|
|
||||||
int? id;
|
int? id;
|
||||||
int? aid;
|
int? aid;
|
||||||
int? bvid;
|
String? bvid;
|
||||||
int? cid;
|
int? cid;
|
||||||
String? pic;
|
String? pic;
|
||||||
Stat? stat;
|
Stat? stat;
|
||||||
int? duration;
|
String? duration;
|
||||||
String? title;
|
String? title;
|
||||||
int? isFollowed;
|
int? isFollowed;
|
||||||
Owner? owner;
|
Owner? owner;
|
||||||
String? rcmdReason;
|
RcmdReason? rcmdReason;
|
||||||
|
String? goto;
|
||||||
|
String? param;
|
||||||
|
String? uri;
|
||||||
|
String? talkBack;
|
||||||
|
// 番剧
|
||||||
|
String? bangumiView;
|
||||||
|
String? bangumiFollow;
|
||||||
|
String? bangumiBadge;
|
||||||
|
|
||||||
RecVideoItemAppModel.fromJson(Map<String, dynamic> json) {
|
RecVideoItemAppModel.fromJson(Map<String, dynamic> json) {
|
||||||
id = json['player_args']['aid'];
|
id = json['player_args'] != null
|
||||||
aid = json['player_args']['aid'];
|
? json['player_args']['aid']
|
||||||
cid = json['player_args']['cid'];
|
: 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'];
|
pic = json['cover'];
|
||||||
stat = Stat.fromJson(json);
|
stat = Stat.fromJson(json);
|
||||||
duration = json['player_args']['duration'];
|
duration = json['cover_right_text'];
|
||||||
title = json['title'];
|
title = json['title'];
|
||||||
isFollowed = 0;
|
isFollowed = 0;
|
||||||
owner = Owner.fromJson(json);
|
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({
|
Stat({
|
||||||
this.view,
|
this.view,
|
||||||
this.like,
|
this.like,
|
||||||
this.danmaku,
|
this.danmu,
|
||||||
});
|
});
|
||||||
String? view;
|
String? view;
|
||||||
String? like;
|
String? like;
|
||||||
String? danmaku;
|
String? danmu;
|
||||||
|
|
||||||
Stat.fromJson(Map<String, dynamic> json) {
|
Stat.fromJson(Map<String, dynamic> json) {
|
||||||
view = json["cover_left_text_1"];
|
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});
|
Owner({this.name});
|
||||||
|
|
||||||
String? name;
|
String? name;
|
||||||
|
int? mid;
|
||||||
|
|
||||||
Owner.fromJson(Map<String, dynamic> json) {
|
Owner.fromJson(Map<String, dynamic> 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<String, dynamic> json) {
|
||||||
|
content = json["title"] ?? '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/http/index.dart';
|
import 'package:pilipala/http/index.dart';
|
||||||
|
import 'package:pilipala/http/user.dart';
|
||||||
import 'package:pilipala/models/common/tab_type.dart';
|
import 'package:pilipala/models/common/tab_type.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
|
|||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
defaultSearch.value = res.data['data']['name'];
|
defaultSearch.value = res.data['data']['name'];
|
||||||
}
|
}
|
||||||
|
UserHttp.thirdLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新登录状态
|
// 更新登录状态
|
||||||
|
@ -2,15 +2,16 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/http/video.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/models/model_rec_video_item.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
class RcmdController extends GetxController {
|
class RcmdController extends GetxController {
|
||||||
final ScrollController scrollController = ScrollController();
|
final ScrollController scrollController = ScrollController();
|
||||||
int count = 12;
|
int count = 12;
|
||||||
int _currentPage = 1;
|
int _currentPage = 0;
|
||||||
int crossAxisCount = 2;
|
int crossAxisCount = 2;
|
||||||
RxList<RecVideoItemModel> videoList = [RecVideoItemModel()].obs;
|
RxList<RecVideoItemAppModel> videoList = [RecVideoItemAppModel()].obs;
|
||||||
bool isLoadingMore = false;
|
bool isLoadingMore = false;
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
OverlayEntry? popupDialog;
|
OverlayEntry? popupDialog;
|
||||||
@ -19,19 +20,22 @@ class RcmdController extends GetxController {
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
if (recVideo.get('cacheList') != null &&
|
// if (recVideo.get('cacheList') != null &&
|
||||||
recVideo.get('cacheList').isNotEmpty) {
|
// recVideo.get('cacheList').isNotEmpty) {
|
||||||
List<RecVideoItemModel> list = [];
|
// List<RecVideoItemModel> list = [];
|
||||||
for (var i in recVideo.get('cacheList')) {
|
// for (var i in recVideo.get('cacheList')) {
|
||||||
list.add(i);
|
// list.add(i);
|
||||||
}
|
// }
|
||||||
videoList.value = list;
|
// videoList.value = list;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取推荐
|
// 获取推荐
|
||||||
Future queryRcmdFeed(type) async {
|
Future queryRcmdFeed(type) async {
|
||||||
var res = await VideoHttp.rcmdVideoList(
|
if (type == 'onRefresh') {
|
||||||
|
_currentPage = 0;
|
||||||
|
}
|
||||||
|
var res = await VideoHttp.rcmdVideoListApp(
|
||||||
ps: count,
|
ps: count,
|
||||||
freshIdx: _currentPage,
|
freshIdx: _currentPage,
|
||||||
);
|
);
|
||||||
@ -47,7 +51,7 @@ class RcmdController extends GetxController {
|
|||||||
} else if (type == 'onLoad') {
|
} else if (type == 'onLoad') {
|
||||||
videoList.addAll(res['data']);
|
videoList.addAll(res['data']);
|
||||||
}
|
}
|
||||||
recVideo.put('cacheList', res['data']);
|
// recVideo.put('cacheList', res['data']);
|
||||||
_currentPage += 1;
|
_currentPage += 1;
|
||||||
}
|
}
|
||||||
isLoadingMore = false;
|
isLoadingMore = false;
|
||||||
|
@ -63,6 +63,8 @@ class UserBoxKey {
|
|||||||
static const String userMid = 'userMid';
|
static const String userMid = 'userMid';
|
||||||
// 登录状态
|
// 登录状态
|
||||||
static const String userLogin = 'userLogin';
|
static const String userLogin = 'userLogin';
|
||||||
|
// 凭证
|
||||||
|
static const String accessKey = 'accessKey';
|
||||||
}
|
}
|
||||||
|
|
||||||
class SettingBoxKey {
|
class SettingBoxKey {
|
||||||
|
Reference in New Issue
Block a user