初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
+226
View File
@@ -0,0 +1,226 @@
import 'package:flutter/material.dart';
import 'package:hgdj/assets_tool/app_colors.dart';
import 'package:hgdj/hj_model/media_content.dart';
import 'package:hgdj/hj_model/video_model.dart';
/// 短剧作品信息(接口 DramaInfo:一部剧 + 一堆分集)
/// 单集播放数据用 [toVideoModel] 转成 VideoModel 交给短视频播放器
class DramaMediaInfo {
// —— 基础信息 ——
String? id; //短剧id
String? title; //剧名
String? author; //作者/出品方
String? summary; //简介
int? kind; //种类
int? style; //样式
int? status; //0 下架 1 上架
int? number; //序号
VidStatus? mediaStatus; //媒体状态(已购/已收藏/已点赞)
String? lsjId; // 老司机媒体资源ID
// —— 封面 ——
String? horizontalCover; //横版封面
String? verticalCover; //竖版封面
// —— 集数 / 更新 ——
int? totalEpisode; //总集数
int? currentEpisode; //已更新到第几集
int? freeEpisode; //默认免费集数,仅后台初始化用;能不能播一律看分集的 canPlay
int? updateStatus; //1 连载中 2 已完结
String? updateTime; //更新时间
String? createdAt; //创建时间
// —— 价格 / 权限 ——
int? price; //整部价格
int? contentsPrice; //所有分集的价格
int? permission; // 0:会员/短剧卡 1:金币购买 2:免费
bool? permissionIconHide; //售卖类型标识隐藏
// —— 专题 / 模块 ——
String? mId; //模块ID
String? moduleName; //模块名称
String? sId; //专题id
String? sectionName; //专题名称
int? sectionSort; //专题排序
int? sortCode; //排序
// —— 统计 ——
int? countBrowse; //浏览数
int? countCollect; //收藏数
int? countDisLike; //不喜欢数
int? countComment; //评论数
int? countLike; //喜欢数
int? countPurchases; //购买数
int? countView; //展现数
bool? hasFollow; //是否关注
// —— 标签 ——
List<TagsBean>? tagDetails; //标签对象
// —— 其他后端字段 ——
int? direction; //方向(横/竖)
int? freeTime; //免费试看时长
// —— 本地 / UI 字段(非后端返回) ——
List<MediaContent>? episodeList; //分集列表,走 /media_content/list 单独拉,外部赋值
int? episodeCurPage; //当前页码
//每页集数:必须与选集面板的分段大小(DramaEpisodeSheet._segmentSize)一致,
//这样第 i 页正好是第 i 段,点哪段补哪页,不会出现「点进去先 10 个再变 30 个」
int episodePageSize = 30;
int isUpSort = 0; //0-正序 1-倒序
bool haxNextEpisode = true; //是否还有下一页
bool isSelected = false; //是否选中
String? get coverH =>
horizontalCover?.isNotEmpty == true ? horizontalCover : verticalCover;
String? get coverV =>
verticalCover?.isNotEmpty == true ? verticalCover : horizontalCover;
String get unit => '';
//更新状态
String get updateDesc => updateStatus == 1 ? '连载中' : '已完结';
String get tagIds => tagDetails?.map((e) => e.id).toList().join(',') ?? '';
String get tagNames =>
tagDetails?.map((e) => e.name).toList().join(',') ?? '';
Color get updateDescColor =>
updateStatus == 1 ? AppColors.actionRed : const Color(0xff989898);
//集数状态描述
String get episodeNumberStatus {
if (updateStatus == 1 && (currentEpisode ?? 0) > 0) {
return '更新$currentEpisode$unit';
}
//没有集数就别出这行——直接插值会渲染成「共null集」
return (totalEpisode ?? 0) > 0 ? '$totalEpisode$unit' : '';
}
//点赞/评论/分享统一传这个类型
String get commentType => 'drama';
/// 转成播放器用的 [VideoModel][episode] 为当前集;列表卡片场景传 null
VideoModel toVideoModel(MediaContent? episode) {
return VideoModel()
..id = id
..dramaInfo = this
..dramaEpisode = episode
..subid = episode?.id
..episodeNo = episode?.episodeNumber
..totalEpisode = totalEpisode
..updateStatus = updateStatus
..title = title
..tags = tagDetails
..name = episode?.name
..cover = episode?.cover?.isNotEmpty == true ? episode?.cover : coverV
..sourceURL = episode?.videoUrl
..h265Url = episode?.h265Url
..playTime = episode?.playTime
..likeCount = countLike // 短剧点赞走 thumbsUp,操作台右侧显示的就是这个数
..freeTime = freeTime ?? 0
..collectCount = countCollect
..commentCount = countComment
..playCount = countBrowse
..freeArea = episode?.isFree == true
..coins = price
..originCoins = price
..vidStatus = (VidStatus()
..hasPaid = mediaStatus?.hasPaid == true
..hasCollected = mediaStatus?.hasCollected
..hasLiked = mediaStatus?.hasLiked
..hasDisliked = mediaStatus?.hasDisliked);
}
DramaMediaInfo();
DramaMediaInfo.fromJson(dynamic json) {
json ??= {};
id = json['id'];
title = json['title'] ?? json['name'];
author = json['author'];
summary = json['summary'];
kind = json['kind'];
style = json['style'];
status = json['status'];
number = json['number'];
lsjId = json['lsjId'];
horizontalCover = json['horizontalCover'];
verticalCover = json['verticalCover'];
totalEpisode = json['totalEpisode'];
currentEpisode = json['currentEpisode'];
freeEpisode = json['freeEpisode'];
updateStatus = json['updateStatus'];
updateTime = json['updateTime'];
createdAt = json['createdAt'];
price = json['price'];
contentsPrice = json['contentsPrice'];
permission = json['permission'];
permissionIconHide = json['permissionIconHide'];
mId = json['mId'];
moduleName = json['moduleName'];
sId = json['sId'];
sectionName = json['sectionName'];
sectionSort = json['sectionSort'];
sortCode = json['sortCode'];
countBrowse = json['countBrowse'];
countCollect = json['countCollect'];
countDisLike = json['countDisLike'];
countComment = json['countComment'];
countLike = json['countLike'];
countPurchases = json['countPurchases'];
countView = json['countView'];
hasFollow = json['hasFollow'];
direction = json['direction'];
freeTime = json['freeTime'];
mediaStatus = VidStatus.fromMap(json['mediaStatus']);
tagDetails =
(json['tagDetails'] as List?)?.map((e) => TagsBean.fromMap(e)).toList();
}
/// 落本地观看记录用(见 [DramaResume.drama])。只序列化后端字段,
/// episodeList / 分页游标那些是运行期状态,进二级页会重新拉,存了也没意义
Map<String, dynamic> toJson() => {
'id': id,
'title': title,
'author': author,
'summary': summary,
'kind': kind,
'style': style,
'status': status,
'number': number,
'lsjId': lsjId,
'horizontalCover': horizontalCover,
'verticalCover': verticalCover,
'totalEpisode': totalEpisode,
'currentEpisode': currentEpisode,
'freeEpisode': freeEpisode,
'updateStatus': updateStatus,
'updateTime': updateTime,
'createdAt': createdAt,
'price': price,
'contentsPrice': contentsPrice,
'permission': permission,
'permissionIconHide': permissionIconHide,
'mId': mId,
'moduleName': moduleName,
'sId': sId,
'sectionName': sectionName,
'sectionSort': sectionSort,
'sortCode': sortCode,
'countBrowse': countBrowse,
'countCollect': countCollect,
'countDisLike': countDisLike,
'countComment': countComment,
'countLike': countLike,
'countPurchases': countPurchases,
'countView': countView,
'hasFollow': hasFollow,
'direction': direction,
'freeTime': freeTime,
'mediaStatus': mediaStatus?.toJson(),
'tagDetails': tagDetails?.map((e) => e.toJson()).toList(),
};
}