feat: 搜索结果增加专栏 issues #112
This commit is contained in:
@ -61,6 +61,7 @@ class SearchHttp {
|
|||||||
var res = await Request().get(Api.searchByType, data: reqData);
|
var res = await Request().get(Api.searchByType, data: reqData);
|
||||||
if (res.data['code'] == 0 && res.data['data']['numPages'] > 0) {
|
if (res.data['code'] == 0 && res.data['data']['numPages'] > 0) {
|
||||||
Object data;
|
Object data;
|
||||||
|
try {
|
||||||
switch (searchType) {
|
switch (searchType) {
|
||||||
case SearchType.video:
|
case SearchType.video:
|
||||||
data = SearchVideoModel.fromJson(res.data['data']);
|
data = SearchVideoModel.fromJson(res.data['data']);
|
||||||
@ -74,11 +75,17 @@ class SearchHttp {
|
|||||||
case SearchType.media_bangumi:
|
case SearchType.media_bangumi:
|
||||||
data = SearchMBangumiModel.fromJson(res.data['data']);
|
data = SearchMBangumiModel.fromJson(res.data['data']);
|
||||||
break;
|
break;
|
||||||
|
case SearchType.article:
|
||||||
|
data = SearchArticleModel.fromJson(res.data['data']);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
'status': true,
|
'status': true,
|
||||||
'data': data,
|
'data': data,
|
||||||
};
|
};
|
||||||
|
} catch (err) {
|
||||||
|
print(err);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
'status': false,
|
'status': false,
|
||||||
|
|||||||
@ -12,20 +12,20 @@ enum SearchType {
|
|||||||
live_room,
|
live_room,
|
||||||
// 主播:live_user
|
// 主播:live_user
|
||||||
// live_user,
|
// live_user,
|
||||||
// 专栏:article
|
|
||||||
// article,
|
|
||||||
// 话题:topic
|
// 话题:topic
|
||||||
// topic,
|
// topic,
|
||||||
// 用户:bili_user
|
// 用户:bili_user
|
||||||
bili_user,
|
bili_user,
|
||||||
|
// 专栏:article
|
||||||
|
article,
|
||||||
// 相簿:photo
|
// 相簿:photo
|
||||||
// photo
|
// photo
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchTypeExtension on SearchType {
|
extension SearchTypeExtension on SearchType {
|
||||||
String get type =>
|
String get type =>
|
||||||
['video', 'media_bangumi', 'live_room', 'bili_user'][index];
|
['video', 'media_bangumi', 'live_room', 'bili_user', 'article'][index];
|
||||||
String get label => ['视频', '番剧', '直播间', '用户'][index];
|
String get label => ['视频', '番剧', '直播间', '用户', '专栏'][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 搜索类型为视频、专栏及相簿时
|
// 搜索类型为视频、专栏及相簿时
|
||||||
|
|||||||
@ -376,3 +376,72 @@ class SearchMBangumiItemModel {
|
|||||||
indexShow = json['index_show'];
|
indexShow = json['index_show'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SearchArticleModel {
|
||||||
|
SearchArticleModel({this.list});
|
||||||
|
|
||||||
|
List<SearchArticleItemModel>? list;
|
||||||
|
|
||||||
|
SearchArticleModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
list = json['result'] != null
|
||||||
|
? json['result']
|
||||||
|
.map<SearchArticleItemModel>(
|
||||||
|
(e) => SearchArticleItemModel.fromJson(e))
|
||||||
|
.toList()
|
||||||
|
: [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchArticleItemModel {
|
||||||
|
SearchArticleItemModel({
|
||||||
|
this.pubTime,
|
||||||
|
this.like,
|
||||||
|
this.title,
|
||||||
|
this.rankOffset,
|
||||||
|
this.mid,
|
||||||
|
this.imageUrls,
|
||||||
|
this.id,
|
||||||
|
this.categoryId,
|
||||||
|
this.view,
|
||||||
|
this.reply,
|
||||||
|
this.desc,
|
||||||
|
this.rankScore,
|
||||||
|
this.type,
|
||||||
|
this.templateId,
|
||||||
|
this.categoryName,
|
||||||
|
});
|
||||||
|
|
||||||
|
int? pubTime;
|
||||||
|
int? like;
|
||||||
|
List? title;
|
||||||
|
int? rankOffset;
|
||||||
|
int? mid;
|
||||||
|
List? imageUrls;
|
||||||
|
int? id;
|
||||||
|
int? categoryId;
|
||||||
|
int? view;
|
||||||
|
int? reply;
|
||||||
|
String? desc;
|
||||||
|
int? rankScore;
|
||||||
|
String? type;
|
||||||
|
int? templateId;
|
||||||
|
String? categoryName;
|
||||||
|
|
||||||
|
SearchArticleItemModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
pubTime = json['pub_time'];
|
||||||
|
like = json['like'];
|
||||||
|
title = Em.regTitle(json['title']);
|
||||||
|
rankOffset = json['rank_offset'];
|
||||||
|
mid = json['mid'];
|
||||||
|
imageUrls = json['image_urls'];
|
||||||
|
id = json['id'];
|
||||||
|
categoryId = json['category_id'];
|
||||||
|
view = json['view'];
|
||||||
|
reply = json['reply'];
|
||||||
|
desc = json['desc'];
|
||||||
|
rankScore = json['rank_score'];
|
||||||
|
type = json['type'];
|
||||||
|
templateId = json['templateId'];
|
||||||
|
categoryName = json['category_name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import 'package:pilipala/common/widgets/http_error.dart';
|
|||||||
import 'package:pilipala/models/common/search_type.dart';
|
import 'package:pilipala/models/common/search_type.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
|
import 'widgets/article_panel.dart';
|
||||||
import 'widgets/live_panel.dart';
|
import 'widgets/live_panel.dart';
|
||||||
import 'widgets/media_bangumi_panel.dart';
|
import 'widgets/media_bangumi_panel.dart';
|
||||||
import 'widgets/user_panel.dart';
|
import 'widgets/user_panel.dart';
|
||||||
@ -90,6 +91,8 @@ class _SearchPanelState extends State<SearchPanel>
|
|||||||
return searchUserPanel(context, ctr, list);
|
return searchUserPanel(context, ctr, list);
|
||||||
case SearchType.live_room:
|
case SearchType.live_room:
|
||||||
return searchLivePanel(context, ctr, list);
|
return searchLivePanel(context, ctr, list);
|
||||||
|
case SearchType.article:
|
||||||
|
return searchArticlePanel(context, ctr, list);
|
||||||
default:
|
default:
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
}
|
}
|
||||||
|
|||||||
99
lib/pages/searchPanel/widgets/article_panel.dart
Normal file
99
lib/pages/searchPanel/widgets/article_panel.dart
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pilipala/common/constants.dart';
|
||||||
|
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||||
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
|
||||||
|
Widget searchArticlePanel(BuildContext context, ctr, list) {
|
||||||
|
TextStyle textStyle = TextStyle(
|
||||||
|
fontSize: Theme.of(context).textTheme.labelSmall!.fontSize,
|
||||||
|
color: Theme.of(context).colorScheme.outline);
|
||||||
|
return ListView.builder(
|
||||||
|
controller: ctr!.scrollController,
|
||||||
|
itemCount: list.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(
|
||||||
|
StyleString.safeSpace, 5, StyleString.safeSpace, 5),
|
||||||
|
child: LayoutBuilder(builder: (context, boxConstraints) {
|
||||||
|
double width = (boxConstraints.maxWidth -
|
||||||
|
StyleString.cardSpace *
|
||||||
|
6 /
|
||||||
|
MediaQuery.of(context).textScaleFactor) /
|
||||||
|
2;
|
||||||
|
return Container(
|
||||||
|
constraints: const BoxConstraints(minHeight: 88),
|
||||||
|
height: width / StyleString.aspectRatio,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (list[index].imageUrls != null &&
|
||||||
|
list[index].imageUrls.isNotEmpty)
|
||||||
|
AspectRatio(
|
||||||
|
aspectRatio: StyleString.aspectRatio,
|
||||||
|
child: LayoutBuilder(builder: (context, boxConstraints) {
|
||||||
|
double maxWidth = boxConstraints.maxWidth;
|
||||||
|
double maxHeight = boxConstraints.maxHeight;
|
||||||
|
return NetworkImgLayer(
|
||||||
|
width: maxWidth,
|
||||||
|
height: maxHeight,
|
||||||
|
src: list[index].imageUrls.first,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(10, 2, 6, 0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
RichText(
|
||||||
|
maxLines: 2,
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
for (var i in list[index].title) ...[
|
||||||
|
TextSpan(
|
||||||
|
text: i['text'],
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
letterSpacing: 0.3,
|
||||||
|
color: i['type'] == 'em'
|
||||||
|
? Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.primary
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Text(
|
||||||
|
Utils.dateFormat(list[index].pubTime,
|
||||||
|
formatType: 'detail'),
|
||||||
|
style: textStyle),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text('${list[index].view}浏览', style: textStyle),
|
||||||
|
Text(' • ', style: textStyle),
|
||||||
|
Text('${list[index].reply}评论', style: textStyle),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user