初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
+424
View File
@@ -0,0 +1,424 @@
import 'package:hgdj/hj_model/list_base_model.dart';
import 'package:hgdj/hj_model/video_model.dart';
import 'package:hgdj/hj_utils/codec_support.dart';
import 'package:hgdj/tools_base/net/http_manager.dart';
import 'package:hgdj/tools_base/toast.dart';
import '../../config/config.dart';
import '../../hj_model/home/module_detail_model.dart';
import '../../hj_model/home/recommend_list_model.dart';
import '../../hj_model/home/video_library_model.dart';
import '../../hj_model/home/video_list_model.dart';
import '../../hj_model/splash/domain_source_model.dart';
import '../../hj_model/splash/watch_count_model.dart';
class VidService {
/// 根据id获取观看次数
/// [vid] 视频vid 可null
static Future<WatchCount?> fetchWatchCount({String? vid}) async {
final param = <String, dynamic>{'vid': vid};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET('/vid/user/count',
param: param, jsonTransformation: (json) => WatchCount.fromJson(json));
return result.isSuccess ? result.data : null;
}
/// 发送观看视频记录
static Future<bool> sendRecord(
String videoID, {
int? playWay,
int? longer,
int? progress,
int? via,
String? tagID,
}) async {
final param = {
'videoID': videoID,
'playWay': playWay,
'longer': longer,
'progress': progress,
'via': via,
'tagID': tagID,
};
final result =
await httpManager.fetchResponseByPOST('/vid/play', param: param);
return result.isSuccess;
}
/// 用户上传视频发帖接口
/// [actor] 演员名字
/// [bountyPoint] 求车牌悬赏积分
/// [coins] 观看金币
/// [content] 发帖内容
/// [cover] 视频封面
/// [coverThumb] 封面缩略图
/// [filename] 上传的文件名 一般视频用
/// [freeTime] 免费观看时长
/// [isActivity] 是否为参赛作品
/// [md5] 文件摘要上传视频需要
/// [mimeType] 影片类型
/// [newsType] 上传类型 SP:短视频,MOVIE:影视,COVER:图组,POST:帖子,CAR_NO:求车牌
/// [playTime] 视频时长
/// [ratio] 宽高比
/// [relatedSid] 关联番号
/// [resolution] 分辨率
/// [seedLink] 磁力链接
/// [seriesCover] 图集
/// [size] 文件大小
/// [sourceID] 上传视频成功后 返回的ID 为SP时必传
/// [sourceURL] 资源url 为SP,MOVIE时 必传
/// [tags] 视频标签数组
/// [title] 发帖的标题
/// [uid] 用户id
static Future<bool> submit(
{String? actor,
int? bountyPoint,
int? coins,
String? content,
String? cover,
String? coverThumb,
String? filename,
int? freeTime,
bool? isActivity,
String? md5,
String? mimeType,
String? newsType,
int? playTime,
double? ratio,
String? relatedSid,
String? resolution,
List<String>? seriesCover,
int? size,
String? sourceID,
String? sourceURL,
List<String>? tags,
String? title,
int? uid,
String? via,
String? seedLink}) async {
final param = {
'title': title,
'newsType': newsType,
'tags': tags,
'playTime': playTime,
'cover': cover,
'coverThumb': coverThumb,
'seriesCover': seriesCover,
'via': via,
'coins': coins,
'size': size,
'mimeType': mimeType,
'actor': actor,
'sourceURL': sourceURL,
'sourceID': sourceID,
'filename': filename,
'resolution': resolution,
'ratio': ratio,
'md5': md5,
'freeTime': freeTime,
'isActivity': isActivity,
'content': content,
'seedLink': seedLink,
'relatedSid': relatedSid,
'bountyPoint': bountyPoint,
};
param.removeWhere((k, v) => v == null);
final result =
await httpManager.fetchResponseByPOST('/vid/submit', param: param);
if (!result.isSuccess) {
showToast(result.toast);
}
return result.isSuccess;
}
///获取模块详情
/// [moduleSort] 默认视频排序 1、最新,2、最热,3、最多播放量或者推荐,4、十分钟以上视频,5、精华,6、视频 9 最新热评
/// [showType]0 默认为hj
static Future<ModuleDetailModel?> getModuleDetail(String? subModuleID,
{int? moduleSort,
int pageNumber = 1,
int pageSize = 10,
int? showType,
String? tagId}) async {
final param = <String, dynamic>{
'pageSize': pageSize,
'pageNumber': pageNumber,
'moduleSort': moduleSort,
'showType': showType,
'tagId': tagId,
};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET(
'/vid/module/$subModuleID',
param: param,
jsonTransformation: (json) => ModuleDetailModel.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
/// 亚模块热门随机刷新(仅 refreshMode=RANDOM_TOP_N 的排序项)
/// 只回 allVideoInfo,不含专题/精选等结构,调用方别整个替换 dataSource
/// [refreshToken] 每次用户主动下拉换新 UUID;同一 token 重取顺序不变,所以网络层自动重试是安全的
static Future<ModuleDetailModel?> refreshRandomModule(String? subModuleID,
{int? moduleSort,
required String refreshToken,
int pageSize = 30}) async {
final param = <String, dynamic>{
'moduleSort': moduleSort,
'pageSize': pageSize,
'refreshToken': refreshToken,
};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET(
'/vid/module/$subModuleID/refresh',
param: param,
jsonTransformation: (json) => ModuleDetailModel.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
///sortType 1:最新 2:本周热门 4:本月最热 5:年度最热
static Future<VideoListResp?> getNewestModule(
{int? sortType, int pageNumber = 1, int pageSize = 10}) async {
final param = <String, dynamic>{
'pageSize': pageSize,
'pageNumber': pageNumber,
'sortType': sortType,
};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET(
'/vid/home/new/list',
param: param,
jsonTransformation: (json) => VideoListResp.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
static Future<dynamic> getShopAddress() async {
final result =
await httpManager.fetchResponseByGET('/ping/store_url', param: {});
return result.isSuccess ? result.data : null;
}
// 获取视屏详情 番号 番号即是视频id
static Future<VideoModel?> getDetail(
String videoID, {
String? sectionId,
String? postId,
String? seedId,
}) async {
final param = <String, dynamic>{
"videoID": videoID,
"sectionId": sectionId,
"id": postId,
'seedId': seedId,
'supportH265': CodecSupport.useH265, //设备是否用 265,后端据此决定是否下发 h265Url
};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET(
'/vid/info',
param: param,
jsonTransformation: (json) => VideoModel.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
/// 短视频推荐列表:GET /recommend/vid/list
/// 仅传 pageNumber、pageSize(固定20);是否还有下一页以 hasNext 为准,不上传已看视频 ID/offset。
static Future<RecommendListRes?> getRecommendList(
int? pageNumber, {
int pageSize = 20,
}) async {
final param = {'pageNumber': pageNumber, 'pageSize': pageSize};
final result = await httpManager.fetchResponseByGET(
'/recommend/vid/list',
param: param,
jsonTransformation: (json) => RecommendListRes.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
static Future<VideoListResp?> fetchSectionVideos(
String sectionID, {
String? sortType,
int pageNumber = 1,
int pageSize = 10,
}) async {
final param = <String, dynamic>{
"pageNumber": pageNumber,
"pageSize": pageSize,
"sortType": sortType,
};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET(
'/vid/section/$sectionID',
param: param,
jsonTransformation: (json) => VideoListResp.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
static Future<SectionListResp?> fetchSectionAll(
String mid, {
int pageNumber = 1,
int pageSize = 10,
}) async {
final param = <String, dynamic>{
"pageNumber": pageNumber,
"pageSize": pageSize,
"mid": mid,
};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET(
'/vid/section/list',
param: param,
jsonTransformation: (json) => SectionListResp.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
/// 片库搜索视频
static Future<HomeVideoLibraryResult?> searchLibrary(
int pageNumber,
int pageSize, {
Keyword? filterMenu,
}) async {
final param = <String, dynamic>{
'pageNumber': pageNumber,
'pageSize': pageSize,
};
param.addAll({'keyword': filterMenu?.toJson() ?? {}});
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByPOST(
'/vid/library/search',
param: param,
jsonTransformation: (json) => HomeVideoLibraryResult.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
/// 获取福利任务下面的视频
static Future<List<WareDiscountAreaData>?> fetchFreeSource() async {
final result = await httpManager.fetchResponseByGET('/vid/discount/area',
param: {},
jsonTransformation: (json) => (json['List'] as List?)
?.map((e) => WareDiscountAreaData.fromJson(e))
.toList());
return result.isSuccess ? result.data : null;
}
/// 获取免费福利视频数据
/// [sortType] 0 = 福利任务下面 1 最新 2最热
static Future<ListBaseModel<VideoModel>> fetchFreeSourceList(String id,
{int page = 1, int size = 10, required int sortType}) async {
final param = {
'pageNumber': page,
'pageSize': size,
'discountId': id,
'sortType': sortType,
};
final result = await httpManager.fetchResponseByGET('/vid/discount/list',
param: param,
jsonTransformation: (json) => ListBaseModel<VideoModel>.fromJson(json));
//返回类型非空,给不了 null:失败时这里抛,由调用方 try/catch 兜底(改可空要连调用方一起改)
return result.data;
}
/// 获取跑马灯数据
static Future<List<MarqueeModel>?> fetchAnnounce(int type) async {
final param = <String, dynamic>{"type": type};
final result = await httpManager.fetchResponseByGET('/mine/announce/list',
param: param);
final List<MarqueeModel> list = [];
if (result.isSuccess) {
List? values = result.data as List?;
list.addAll(values?.map((e) => MarqueeModel.fromMap(e)).toList() ?? []);
}
Config.marquees = list;
return list;
}
//社区热门推荐
static Future<ModuleDetailModel?> communityRecommend(
int pageNumber, {
int? pageSize = 10,
String? newsType, //PIC:套图站热门推荐 SEED_LINK:黄游热门推荐
int? sortType = 1, //排序:最新:1 最多点赞:2 最多观看:3 最多收藏:7 购买次数:8 最新热评:9
}) async {
final param = <String, dynamic>{
"pageNumber": pageNumber,
"pageSize": pageSize,
"newsType": newsType,
"sortType": sortType,
};
final result = await httpManager.fetchResponseByGET(
'/vid/community/recommend',
param: param,
jsonTransformation: (json) => ModuleDetailModel.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
//0 最多观看 1 最新上架 3 最多收藏
static Future<AllSection?> getGuessLike(
int pageNumber,
int pageSize,
String sectionID,
int? sortType,
) async {
final param = <String, dynamic>{
"pageNumber": pageNumber,
"pageSize": pageSize,
"type": sortType,
};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET(
'/vid/module/all/$sectionID',
param: param,
jsonTransformation: (json) => AllSection.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
/// 获取片库筛选条件
static Future<HomeVideoLibrary> fetchLibrary() async {
final result = await httpManager.fetchResponseByGET('/vid/library',
param: {},
jsonTransformation: (json) => HomeVideoLibrary.fromJson(json));
//返回类型非空,给不了 null:失败时这里抛,由调用方 try/catch 兜底(改可空要连调用方一起改)
return result.data;
}
///视频专题样式-更换一批
static Future<VideoListResp> sectionVideoExchange(String? sectionID) async {
final result = await httpManager
.fetchResponseByGET('/vid/section/changeVideo/$sectionID', param: {});
//失败时 data 是原始结构,别拿它当模型解析;fromJson 内部 json ??= {},传 null 就是空列表
return VideoListResp.fromJson(result.isSuccess ? result.data : null);
}
///发现-pk打榜数据
///[newsType] SP-视频 COVER-帖子 PIC-图集;[type] 1-日榜 2-周榜 3-月榜 4-总榜
static Future<VideoListResp?> vidRanking(
int page,
int size, {
String? newsType,
int? type,
}) async {
final param = {
'pageNumber': page,
'pageSize': size,
'newsType': newsType,
'type': type,
};
param.removeWhere((k, v) => v == null);
final result = await httpManager.fetchResponseByGET(
'/vid/ranking',
param: param,
jsonTransformation: (json) => VideoListResp.fromJson(json),
);
return result.isSuccess ? result.data : null;
}
}