feat: 搜索计数
This commit is contained in:
@ -520,4 +520,7 @@ class Api {
|
|||||||
|
|
||||||
/// 删除收藏夹
|
/// 删除收藏夹
|
||||||
static const String delFavFolder = '/x/v3/fav/folder/del';
|
static const String delFavFolder = '/x/v3/fav/folder/del';
|
||||||
|
|
||||||
|
/// 搜索结果计数
|
||||||
|
static const String searchCount = '/x/web-interface/wbi/search/all/v2';
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:pilipala/models/search/all.dart';
|
||||||
|
import 'package:pilipala/utils/wbi_sign.dart';
|
||||||
import '../models/bangumi/info.dart';
|
import '../models/bangumi/info.dart';
|
||||||
import '../models/common/search_type.dart';
|
import '../models/common/search_type.dart';
|
||||||
import '../models/search/hot.dart';
|
import '../models/search/hot.dart';
|
||||||
@ -179,4 +181,26 @@ class SearchHttp {
|
|||||||
'pic': res.data['data'].first['first_frame'],
|
'pic': res.data['data'].first['first_frame'],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<Map<String, dynamic>> searchCount(
|
||||||
|
{required String keyword}) async {
|
||||||
|
Map<String, dynamic> data = {
|
||||||
|
'keyword': keyword,
|
||||||
|
'web_location': 333.999,
|
||||||
|
};
|
||||||
|
Map params = await WbiSign().makSign(data);
|
||||||
|
final dynamic res = await Request().get(Api.searchCount, data: params);
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
return {
|
||||||
|
'status': true,
|
||||||
|
'data': SearchAllModel.fromJson(res.data['data']),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
'status': false,
|
||||||
|
'data': [],
|
||||||
|
'msg': '请求错误 🙅',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
9
lib/models/search/all.dart
Normal file
9
lib/models/search/all.dart
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
class SearchAllModel {
|
||||||
|
SearchAllModel({this.topTList});
|
||||||
|
|
||||||
|
Map? topTList;
|
||||||
|
|
||||||
|
SearchAllModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
topTList = json['top_tlist'];
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/http/search.dart';
|
||||||
|
import 'package:pilipala/models/common/search_type.dart';
|
||||||
|
|
||||||
class SearchResultController extends GetxController {
|
class SearchResultController extends GetxController {
|
||||||
String? keyword;
|
String? keyword;
|
||||||
int tabIndex = 0;
|
int tabIndex = 0;
|
||||||
|
RxList searchTabs = [].obs;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
@ -10,5 +13,21 @@ class SearchResultController extends GetxController {
|
|||||||
if (Get.parameters.keys.isNotEmpty) {
|
if (Get.parameters.keys.isNotEmpty) {
|
||||||
keyword = Get.parameters['keyword'];
|
keyword = Get.parameters['keyword'];
|
||||||
}
|
}
|
||||||
|
searchTabs.value = SearchType.values
|
||||||
|
.map((type) => {'label': type.label, 'id': type.type})
|
||||||
|
.toList();
|
||||||
|
querySearchCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future querySearchCount() async {
|
||||||
|
var result = await SearchHttp.searchCount(keyword: keyword!);
|
||||||
|
if (result['status']) {
|
||||||
|
for (var i in searchTabs) {
|
||||||
|
final count = result['data'].topTList[i['id']];
|
||||||
|
i['count'] = count > 99 ? '99+' : count.toString();
|
||||||
|
}
|
||||||
|
searchTabs.refresh();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ class SearchResultPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _SearchResultPageState extends State<SearchResultPage>
|
class _SearchResultPageState extends State<SearchResultPage>
|
||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
late SearchResultController? _searchResultController;
|
late SearchResultController _searchResultController;
|
||||||
late TabController? _tabController;
|
late TabController? _tabController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -25,7 +25,7 @@ class _SearchResultPageState extends State<SearchResultPage>
|
|||||||
_tabController = TabController(
|
_tabController = TabController(
|
||||||
vsync: this,
|
vsync: this,
|
||||||
length: SearchType.values.length,
|
length: SearchType.values.length,
|
||||||
initialIndex: _searchResultController!.tabIndex,
|
initialIndex: _searchResultController.tabIndex,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class _SearchResultPageState extends State<SearchResultPage>
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Text(
|
child: Text(
|
||||||
'${_searchResultController!.keyword}',
|
'${_searchResultController.keyword}',
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -64,10 +64,12 @@ class _SearchResultPageState extends State<SearchResultPage>
|
|||||||
splashColor: Colors.transparent, // 点击时的水波纹颜色设置为透明
|
splashColor: Colors.transparent, // 点击时的水波纹颜色设置为透明
|
||||||
highlightColor: Colors.transparent, // 点击时的背景高亮颜色设置为透明
|
highlightColor: Colors.transparent, // 点击时的背景高亮颜色设置为透明
|
||||||
),
|
),
|
||||||
child: TabBar(
|
child: Obx(
|
||||||
|
() => (TabBar(
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
tabs: [
|
tabs: [
|
||||||
for (var i in SearchType.values) Tab(text: i.label),
|
for (var i in _searchResultController.searchTabs)
|
||||||
|
Tab(text: "${i['label']} ${i['count'] ?? ''}")
|
||||||
],
|
],
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
indicatorWeight: 0,
|
indicatorWeight: 0,
|
||||||
@ -78,21 +80,23 @@ class _SearchResultPageState extends State<SearchResultPage>
|
|||||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||||
),
|
),
|
||||||
indicatorSize: TabBarIndicatorSize.tab,
|
indicatorSize: TabBarIndicatorSize.tab,
|
||||||
labelColor: Theme.of(context).colorScheme.onSecondaryContainer,
|
labelColor:
|
||||||
|
Theme.of(context).colorScheme.onSecondaryContainer,
|
||||||
labelStyle: const TextStyle(fontSize: 13),
|
labelStyle: const TextStyle(fontSize: 13),
|
||||||
dividerColor: Colors.transparent,
|
dividerColor: Colors.transparent,
|
||||||
unselectedLabelColor: Theme.of(context).colorScheme.outline,
|
unselectedLabelColor: Theme.of(context).colorScheme.outline,
|
||||||
tabAlignment: TabAlignment.start,
|
tabAlignment: TabAlignment.start,
|
||||||
onTap: (index) {
|
onTap: (index) {
|
||||||
if (index == _searchResultController!.tabIndex) {
|
if (index == _searchResultController.tabIndex) {
|
||||||
Get.find<SearchPanelController>(
|
Get.find<SearchPanelController>(
|
||||||
tag: SearchType.values[index].type +
|
tag: SearchType.values[index].type +
|
||||||
_searchResultController!.keyword!)
|
_searchResultController.keyword!)
|
||||||
.animateToTop();
|
.animateToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
_searchResultController!.tabIndex = index;
|
_searchResultController.tabIndex = index;
|
||||||
},
|
},
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -102,7 +106,7 @@ class _SearchResultPageState extends State<SearchResultPage>
|
|||||||
children: [
|
children: [
|
||||||
for (var i in SearchType.values) ...{
|
for (var i in SearchType.values) ...{
|
||||||
SearchPanel(
|
SearchPanel(
|
||||||
keyword: _searchResultController!.keyword,
|
keyword: _searchResultController.keyword,
|
||||||
searchType: i,
|
searchType: i,
|
||||||
tag: DateTime.now().millisecondsSinceEpoch.toString(),
|
tag: DateTime.now().millisecondsSinceEpoch.toString(),
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user