douaojie

Merge remote-tracking branch 'origin/main'

Showing 58 changed files with 1309 additions and 411 deletions
import { StringUtils } from './StringUtils';
import getLunar from './GetLunar'
import getLunar from './GetLunar';
/**
* 日期/时间工具
*/
... ... @@ -480,6 +481,34 @@ export class DateTimeUtils {
return 0
}
}
/**
* 进度值换算
* @param seconds
* @returns
*/
static secondToTime(seconds: number) {
let time = '00:00'
let hourUnit = 60 * 60;
let hour = Math.floor(seconds / hourUnit);
let minute = Math.floor((seconds - hour * hourUnit) / 60);
let second = seconds - hour * hourUnit - minute * 60;
if (hour > 0) {
return `${DateTimeUtils.padding(hour.toString())}${':'}${DateTimeUtils.padding(minute.toString())}${':'}${DateTimeUtils.padding(second.toString())}`;
}
if (minute > 0) {
return `${DateTimeUtils.padding(minute.toString())}${':'}${DateTimeUtils.padding(second.toString())}`;
} else {
return `${'00'}${':'}${DateTimeUtils.padding(second.toString())}`;
}
}
static padding(num: string) {
let length = 2;
for (let len = (num.toString()).length; len < length; len = num.length) {
num = `${'0'}${num}`;
}
return num;
}
}
// const dateTimeUtils = new DateTimeUtils()
\ No newline at end of file
... ...
... ... @@ -7,7 +7,17 @@ export namespace ErrorToastUtils {
NET_CORE_PAGE_ERROR_NETWORK, //网络出小差了,请检查网络后重试
NET_CORE_LOAD_ERROR_NETWORK, //加载失败,请重试
NET_CORE_ENTER_ERROR_NETWORK, //很抱歉,当前内容无法加载,请点击重试
LIVE_CORE_NO_NETWORK, //网络出小差了,请检查下网络
//直播异常
LIVE_CORE_NO_NETWORK, //直播 无网络 网络出小差了,请检查下网络
LIVE_CORE_WEAK_NETWORK, //直播 弱网 网络出小差了,请检查下网络
LIVE_CORE_IO_NETWORK, //直播 直播流异常 直播加载异常
LIVE_CORE_SERVICE_NETWORK, //直播 服务端接口异常 直播加载异常
LIVE_CORE_SWITCH_FLOW_NETWORK, //直播 网络切换到流量 正在使用流量,请注意流量使用
//审核后异常报错
AUDITING_CORE_CONTENT_DISTRIBUTE, //审核 内容分发下线规则 内容已下线
AUDITING_CORE_ACCOUNT_ERROR, //审核 账号有问题下线规则 内容已下线
}
... ... @@ -32,6 +42,27 @@ export namespace ErrorToastUtils {
case ErrorType.LIVE_CORE_NO_NETWORK:
ToastUtils.shortToast($r('app.string.live_core_no_network'))
break
case ErrorType.LIVE_CORE_WEAK_NETWORK:
ToastUtils.shortToast($r('app.string.live_core_weak_network'))
break
case ErrorType.LIVE_CORE_IO_NETWORK:
ToastUtils.shortToast($r('app.string.live_core_io_network'))
break
case ErrorType.LIVE_CORE_SERVICE_NETWORK:
ToastUtils.shortToast($r('app.string.live_core_service_network'))
break
case ErrorType.LIVE_CORE_SWITCH_FLOW_NETWORK:
ToastUtils.shortToast($r('app.string.live_core_switch_flow_network'))
break
case ErrorType.LIVE_CORE_SWITCH_FLOW_NETWORK:
ToastUtils.shortToast($r('app.string.live_core_switch_flow_network'))
break
case ErrorType.AUDITING_CORE_CONTENT_DISTRIBUTE:
ToastUtils.shortToast($r('app.string.auditing_core_error'))
break
case ErrorType.AUDITING_CORE_ACCOUNT_ERROR:
ToastUtils.shortToast($r('app.string.auditing_core_error'))
break
}
}
... ...
... ... @@ -27,6 +27,26 @@
{
"name": "live_core_no_network",
"value": "网络出小差了,请检查下网络"
},
{
"name": "live_core_weak_network",
"value": "网络出小差了,请检查下网络"
},
{
"name": "live_core_io_network",
"value": "直播加载异常"
},
{
"name": "live_core_service_network",
"value": "直播加载异常"
},
{
"name": "live_core_switch_flow_network",
"value": "正在使用流量,请注意流量使用"
},
{
"name": "auditing_core_error",
"value": "内容已下线"
}
]
}
\ No newline at end of file
... ...
import HashMap from '@ohos.util.HashMap'
import { ConfigConstants, SpConstants } from 'wdConstant'
import { DateTimeUtils, Logger, SPHelper, StringUtils } from 'wdKit'
import HashMap from '@ohos.util.HashMap';
import { SpConstants } from 'wdConstant';
import { SPHelper, StringUtils } from 'wdKit';
/**
* 网络请求业务侧工具类
... ... @@ -213,6 +213,18 @@ export class HttpUrlUtils {
*/
static readonly LIVE_CHAT_LIST_PATH: string = "/api/live-center-message/zh/a/live/message/chat/list";
/**
* 直播详情-直播数据
*/
static readonly LIVE_ROOM_DATA_PATH: string = "/api/live-center-message/zh/a/live/room/number/all";
/**
* 直播详情-预约直播状态
*/
static readonly LIVE_APPOINTMENT_STATUS_PATH: string = "/api/live-center-message/zh/c/live/subscribe/query";
/**
* 直播详情-预约/取消预约直播
*/
static readonly LIVE_APPOINTMENT_PATH: string = "/api/live-center-message/zh/c/live/subscribe";
/**
* 搜索结果 显示tab 数
*/
... ... @@ -653,6 +665,21 @@ export class HttpUrlUtils {
return url
}
static getLiveRoomDataUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_ROOM_DATA_PATH
return url
}
static getLiveAppointmentStatusUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_APPOINTMENT_STATUS_PATH
return url
}
static getLiveAppointmentUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_APPOINTMENT_PATH
return url
}
static getSearchResultCountDataUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.SEARCH_RESULT_COUNT_DATA_PATH
return url
... ...
... ... @@ -120,3 +120,5 @@ export { appStyleImagesDTO } from './src/main/ets/bean/content/appStyleImagesDTO
export { LiveRoomBean,LiveRoomItemBean } from './src/main/ets/bean/live/LiveRoomBean';
export { LiveRoomDataBean } from './src/main/ets/bean/live/LiveRoomDataBean';
... ...
... ... @@ -29,4 +29,9 @@ export interface CompDTO {
subType: string;
imageScale: number; // 封面图比例 1-4:3, 2-16:9, 3-3:2
audioDataList: AudioDTO[];
/**
* 组件内容源类型 (LIVE_HORIZONTAL_CARD\LIVE_RESERVATION\LIVE_LARGE_CARD\LIVE_END\LIVE_MONTHLY_RANKING )
*/
dataSourceType: string;
}
\ No newline at end of file
... ...
... ... @@ -2,6 +2,7 @@ import { CompDTO } from './CompDTO';
/**
* Page数据DTO
* 其实是comp接口(display/zh/c/compInfo)返回
*/
export interface PageDTO {
pageId: string; // 页面id
... ...
... ... @@ -158,9 +158,12 @@ export interface LiveDetailsBean {
*/
liveInfo: LiveInfo
fullColumnImgUrls: Array<FullColumnImgUrls>
vlive: Array<Vlive>
newsTitle: string
newsId: string
newIntroduction: string
//迁移id
oldNewsId: string
reLInfo: ReLInfo
}
export interface LiveInfo {
... ... @@ -168,8 +171,12 @@ export interface LiveInfo {
liveState: string
//2024-04-12 15:00:00 直播开始时间
planStartTime: string
vlive: Array<Vlive>
mlive:MLive
}
export interface MLive {
mliveId:string
}
export interface FullColumnImgUrls {
url: string
}
... ... @@ -179,4 +186,8 @@ export interface Vlive {
liveUrl: string
//直播回看地址,多路直播录制文件URL
replayUri: string
}
export interface ReLInfo {
relId: string
}
\ No newline at end of file
... ...
export interface LiveRoomDataBean {
barrageNum: number,
likeNum: number,
liveId: number,
pv: number,
subscribeNum: number,
}
\ No newline at end of file
... ...
... ... @@ -14,7 +14,12 @@ export struct DynamicDetailComponent {
private contentId: string = ''
private relType: string = ''
//出参
@State contentDetailData: ContentDetailDTO[] = [] as ContentDetailDTO[]
@State contentDetailData: ContentDetailDTO = {} as ContentDetailDTO
//变量
/**
* 默认未关注 点击去关注
*/
private followStatus: boolean = false;
async aboutToAppear() {
... ... @@ -25,17 +30,97 @@ export struct DynamicDetailComponent {
}
build() {
Row() {
Column(){
Text("this is a test!")
Row() {
Column(){
//logo、日期
Row() {
Image($r('app.media.ic_article_rmh'))
.width(80)
.height(28)
.margin({ left: 16 })
Blank()
Text("2023年03月14日 08:16")
.fontColor($r('app.color.color_B0B0B0'))
.fontSize(12)
.lineHeight(28)
.margin({ right: 16 })
}
.height(48)
.width('100%')
//分割线
Image($r('app.media.ic_news_detail_division'))
.width('100%')
.height(7)
.margin({left: 16, right: 16} )
//号主信息
Row() {
//头像
Stack() {
Image(this.contentDetailData.rmhInfo?.rmhHeadUrl)
.alt(this.contentDetailData.rmhInfo?.userType=='1'?$r('app.media.default_head'):$r('app.media.icon_default_head_mater'))
.width('32')
.height('32')
.objectFit(ImageFit.Cover)
.borderRadius(16)
Image($r('app.media.icon_border_test'))
.width('48')
.height('48')
.objectFit(ImageFit.Cover)
.borderRadius(24)
}
.width(48)
.height(48)
.alignContent(Alignment.Center)
Column(){
//昵称
Text("this.contentDetailData.rmhInfo?.rmhName")
.fontSize(14)
.fontColor($r('app.color.color_222222'))
.fontWeight(FontWeight.Medium)
.margin({ left: 5 })
//简介
Text("this.contentDetailData.rmhInfo?.rmhDesc")
.fontSize(14)
.fontColor($r('app.color.color_B0B0B0'))
.fontWeight(FontWeight.Medium)
.margin({ left: 5 })
}
if (!this.followStatus) {
Text('关注')
.width(60)
.height(24)
.textAlign(TextAlign.Center)
.fontSize($r('app.float.font_size_12'))
.borderRadius($r('app.float.button_border_radius'))
.backgroundColor($r('app.color.color_ED2800'))
.fontColor($r('app.color.color_fff'))
.onClick(() => {
// this.handleAccention(this.item, 1)
})
} else {
Text('已关注')
.width(60)
.height(24)
.borderWidth(1)
.textAlign(TextAlign.Center)
.fontSize($r('app.float.font_size_12'))
.borderRadius($r('app.float.button_border_radius'))
.borderColor($r('app.color.color_CCCCCC'))
.fontColor($r('app.color.color_CCCCCC'))
.onClick(() => {
// this.handleAccention(this.item, 0)
})
}
}
.width('100%')
}
}
.backgroundColor('#FFFFFFFF')
}
private async getContentDetailData() {
try {
let data = await MultiPictureDetailViewModel.getDetailData(this.relId, this.contentId, this.relType)
this.contentDetailData = data;
this.contentDetailData = data[0];
console.log('动态详情',JSON.stringify(this.contentDetailData))
} catch (exception) {
console.log('请求失败',JSON.stringify(exception))
... ...
... ... @@ -77,11 +77,6 @@ export struct CardMediaInfo {
.width(14)
.height(14)
.margin({ right: 3 })
.shadow({
radius: 2,
color: 'rgba(0,0,0,0.3)',
offsetY: 2
})
}
}
... ...
... ... @@ -5,51 +5,49 @@ import { DateTimeUtils } from 'wdKit/Index';
@Component
export struct CardSourceInfo {
@State contentDTO: ContentDTO = {} as ContentDTO;
build() {
Flex() {
if(this.contentDTO.corner) {
if (this.contentDTO.corner) {
Text(this.contentDTO.corner)
.fontSize($r("app.float.font_size_12"))
.fontColor($r("app.color.color_ED2800"))
.margin({right: 2})
.margin({ right: 2 })
}
if(this.contentDTO.rmhPlatform === 1) {
if (this.contentDTO.rmhPlatform === 1) {
Text(this.contentDTO.rmhInfo.rmhName)
.fontSize($r("app.float.font_size_12"))
.fontColor($r("app.color.color_B0B0B0"))
.maxLines(1)
.textOverflow({overflow: TextOverflow.Ellipsis})
Image($r("app.media.point"))
.width(16)
.height(16)
} else if(this.contentDTO.source) {
.textOverflow({ overflow: TextOverflow.Ellipsis })
} else if (this.contentDTO.source) {
Text(`${this.contentDTO.source}`)
.fontSize($r("app.float.font_size_12"))
.fontColor($r("app.color.color_B0B0B0"))
.maxLines(1)
.textOverflow({overflow: TextOverflow.Ellipsis})
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
// 新闻tab下的卡片,2天之前的不显示时间。但是如果是搜索情况下展示的卡片,显示时间
if(this.contentDTO.isSearch || !this.contentDTO.isSearch && DateTimeUtils.getCommentTime
if (this.contentDTO.isSearch || !this.contentDTO.isSearch && DateTimeUtils.getCommentTime
(Number
.parseFloat(this
.contentDTO.publishTime))
.contentDTO.publishTime))
.indexOf
('-') === -1) {
('-') === -1) {
Image($r("app.media.point"))
.width(16)
.height(16)
Text(DateTimeUtils.getCommentTime(Number.parseFloat(this.contentDTO.publishTime)))
.fontSize($r("app.float.font_size_12"))
.fontColor($r("app.color.color_B0B0B0"))
.margin({ right: 6 })
.flexShrink(0)
}
if(this.contentDTO?.interactData?.commentNum) {
if (this.contentDTO?.interactData?.commentNum) {
Text(`${this.contentDTO.interactData.commentNum}评`)
.fontSize($r("app.float.font_size_12"))
.fontColor($r("app.color.color_B0B0B0"))
.flexShrink(0)
.margin({ left: 6 })
}
}
.width(CommonConstants.FULL_WIDTH)
... ...
import { ContentDTO, FullColumnImgUrlDTO } from 'wdBean';
import { RmhTitle } from '../cardCommon/RmhTitle'
import { ProcessUtils } from '../../utils/ProcessUtils';
const TAG = 'Card19Component';
/**
... ... @@ -94,6 +94,9 @@ export struct Card19Component {
top: $r('app.float.card_comp_pagePadding_tb'),
bottom: $r('app.float.card_comp_pagePadding_tb')
})
.onClick((event: ClickEvent) => {
ProcessUtils.processPage(this.contentDTO)
})
}
}
... ...
... ... @@ -2,7 +2,7 @@ import { ContentDTO } from 'wdBean';
import { RmhTitle } from '../cardCommon/RmhTitle'
import { CardMediaInfo } from '../cardCommon/CardMediaInfo'
import { CommonConstants } from 'wdConstant/Index';
import { ProcessUtils } from '../../utils/ProcessUtils';
const TAG = 'Card20Component';
/**
... ... @@ -71,6 +71,9 @@ export struct Card20Component {
top: $r('app.float.card_comp_pagePadding_tb'),
bottom: $r('app.float.card_comp_pagePadding_tb')
})
.onClick((event: ClickEvent) => {
ProcessUtils.processPage(this.contentDTO)
})
}
}
... ...
... ... @@ -2,7 +2,7 @@ import { CustomTitleAndEditUI } from '../reusable/CustomTitleAndEditUI'
import MyCollectionViewModel from '../../viewmodel/MyCollectionViewModel';
import PageModel from '../../viewmodel/PageModel';
import { CommonConstants, ViewType } from 'wdConstant'
import { EmptyComponent } from '../view/EmptyComponent'
import { EmptyComponent,WDViewDefaultType } from '../view/EmptyComponent'
import { ErrorComponent } from '../view/ErrorComponent'
import RefreshLayout from './RefreshLayout'
import { RefreshLayoutBean } from './RefreshLayoutBean';
... ... @@ -43,7 +43,7 @@ struct MyCollectionListPage {
}else if(this.browSingModel.viewType == ViewType.ERROR){
ErrorComponent()
}else if(this.browSingModel.viewType == ViewType.EMPTY){
EmptyComponent()
EmptyComponent({emptyType:WDViewDefaultType.WDViewDefaultType_NoCollection})
}else {
this.ListLayout()
}
... ...
import { CollectionUtils, DateTimeUtils, Logger } from 'wdKit';
import { CommonConstants, CompStyle, ViewType } from 'wdConstant';
import { CommonConstants, ViewType } from 'wdConstant';
import { Logger } from 'wdKit';
import PageViewModel from '../../viewmodel/PageViewModel';
import { EmptyComponent } from '../view/EmptyComponent';
import { ErrorComponent } from '../view/ErrorComponent';
... ... @@ -11,9 +11,8 @@ import NoMoreLayout from './NoMoreLayout';
import LoadMoreLayout from './LoadMoreLayout';
import CustomRefreshLoadLayout from './CustomRefreshLoadLayout';
import { CompParser } from '../CompParser';
import { GroupInfoDTO } from 'wdBean/src/main/ets/bean/navigation/PageInfoDTO';
import { CompDTO, LiveReviewDTO, PageDTO, PageInfoBean } from 'wdBean';
import { CompDTO } from 'wdBean';
import PageHelper from '../../viewmodel/PageHelper';
const TAG = 'PageComponent';
... ... @@ -23,22 +22,6 @@ export struct PageComponent {
navIndex: number = 0;
pageId: string = "";
channelId: string = "";
pageNum: number = 1;
isFirstIn: boolean = true
pageDto: PageDTO = {
pageId: '',
id: 0,
name: '',
branchMark: false,
compList: []
}
liveReviewDTO: LiveReviewDTO = {
hasNext: false,
pageNum: 0,
pageSize: 0,
totalCount: 0,
list: []
};
@Link @Watch('onChange') currentTopNavSelectedIndex: number
build() {
... ... @@ -69,7 +52,6 @@ export struct PageComponent {
@Builder
ListLayout() {
List() {
// 下拉刷新
ListItem() {
RefreshLayout({
... ... @@ -99,7 +81,6 @@ export struct PageComponent {
NoMoreLayout()
}
}
}
.scrollBar(BarState.Off)
.cachedCount(8)
... ... @@ -122,171 +103,32 @@ export struct PageComponent {
async aboutToAppear() {
// 选中tab,才请求数据。拦截大量接口请求
if (this.navIndex === 0 && this.navIndex === this.currentTopNavSelectedIndex) {
if (this.navIndex === this.currentTopNavSelectedIndex) {
this.getData();
} else if (this.navIndex === 1) {
this.getPreviewData()
}
}
onChange() {
Logger.info(TAG, `onChangezz id: ${this.pageId} , ${this.channelId} , ${this.navIndex} , ${this.isFirstIn} , navIndex: ${this.currentTopNavSelectedIndex}`);
// if (this.navIndex === this.currentTopNavSelectedIndex && !this.isFirstIn) {
Logger.info(TAG, `onChangezz id: ${this.pageId} , ${this.channelId} , ${this.navIndex} , navIndex: ${this.currentTopNavSelectedIndex}`);
if (this.navIndex === this.currentTopNavSelectedIndex) {
this.getData();
}
}
/**
* 要按顺序处理pageInfo.groups中的每个元素,并确保每个异步操作完成后再继续执行下一个,你应该避免使用forEach。
* 取而代之的是,你可以使用for...of循环,并配合async/await来确保按顺序执行操作。
* */
async getData() {
Logger.info(TAG, `getData id: ${this.pageId} , ${this.channelId} , navIndex: ${this.currentTopNavSelectedIndex}`);
this.pageModel.pageId = this.pageId;
this.pageModel.groupId = this.pageId;
this.pageModel.channelId = this.channelId;
this.pageModel.currentPage = 1;
let pageInfo = await PageViewModel.getPageUrlData(this.pageModel.pageId);
let pageInfo = await PageViewModel.getPageInfo(this.pageModel.pageId);
if (pageInfo == null) {
this.pageModel.viewType = ViewType.EMPTY;
return;
}
if (this.navIndex === 0) {
await this.getVideoListData(pageInfo);
} else {
await this.getLiveListData(pageInfo);
}
}
private async getVideoListData(pageInfo: PageInfoBean) {
let groupInfo: GroupInfoDTO = CollectionUtils.getElement(pageInfo.groups, 0);
if (groupInfo != null) {
this.pageModel.isRecGroup = groupInfo.groupStrategy === 1;
this.pageModel.groupId = groupInfo.id;
}
// pageInfo.groups.forEach(async (group) => { 不能按顺序加载用for...of替代
// for (const group of pageInfo.groups) {
this.pageDto = await PageViewModel.getPageData(this.pageModel, getContext(this));
this.pageModel.timestamp = DateTimeUtils.getTimeStamp().toString();
if (this.pageDto && this.pageDto.compList && this.pageDto.compList.length > 0) {
this.pageDto.compList.forEach((comp) => {
if (comp.compStyle === CompStyle.Zh_Grid_Layout_02 && this.liveReviewDTO && this.liveReviewDTO.list && this.liveReviewDTO.list.length > 0) {
comp.operDataList.push(...this.liveReviewDTO.list);
}
});
this.pageModel.viewType = ViewType.LOADED;
this.pageModel.compList.push(...this.pageDto.compList);
if (this.pageDto.compList.length === this.pageModel.pageSize) {
this.pageModel.currentPage++;
this.pageModel.hasMore = true;
} else {
this.pageModel.hasMore = false;
}
// // 二次请求,批查互动数据
// PageViewModel.getInteractData(pageDto.compList).then((data: CompDTO[]) => {
// // 刷新,替换所有数据
// this.pageModel.compList.replaceAll(...data)
// this.pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
// })
this.isFirstIn = false;
Logger.debug(TAG, 'cj111');
// } else {
// Logger.debug(TAG, 'aboutToAppear, data response page ' + this.pageId + ', comp list is empty.');
// this.pageModel.viewType = ViewType.EMPTY;
// }
}
}
// private async getLiveListData(pageInfo: PageInfoBean) {
// // pageInfo.groups.forEach(async (group) => { 不能按顺序加载用for...of替代
// for (const group of pageInfo.groups) {
// this.pageDto = await PageViewModel.getPageData(this.pageModel, getContext(this));
// this.pageModel.timestamp = DateTimeUtils.getTimeStamp().toString();
// if (this.pageDto && this.pageDto.compList && this.pageDto.compList.length > 0) {
// this.pageDto.compList.forEach((comp) => {
// if (comp.compStyle === CompStyle.Zh_Grid_Layout_02 && this.liveReviewDTO && this.liveReviewDTO.list && this.liveReviewDTO.list.length > 0) {
// comp.operDataList.push(...this.liveReviewDTO.list);
// }
// });
//
// this.pageModel.viewType = ViewType.LOADED;
// this.pageModel.compList.push(...this.pageDto.compList);
// if (this.pageDto.compList.length === this.pageModel.pageSize) {
// this.pageModel.currentPage++;
// this.pageModel.hasMore = true;
// } else {
// this.pageModel.hasMore = false;
// }
// // // 二次请求,批查互动数据
// // PageViewModel.getInteractData(pageDto.compList).then((data: CompDTO[]) => {
// // // 刷新,替换所有数据
// // this.pageModel.compList.replaceAll(...data)
// // this.pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
// // })
// this.isFirstIn = false;
// Logger.debug(TAG, 'cj111');
// // } else {
// // Logger.debug(TAG, 'aboutToAppear, data response page ' + this.pageId + ', comp list is empty.');
// // this.pageModel.viewType = ViewType.EMPTY;
// }
// }
// }
async getLiveListData(pageInfo: PageInfoBean) {
// Logger.info(TAG, `getData id: ${this.pageId} , ${this.channelId} , navIndex: ${this.currentTopNavSelectedIndex}`);
// this.pageModel.pageId = this.pageId;
// this.pageModel.groupId = this.pageId;
// this.pageModel.channelId = this.channelId;
// this.pageModel.currentPage = 1;
// let pageInfo = await PageViewModel.getPageUrlData(this.pageModel.pageId);
// if (pageInfo == null) {
// this.pageModel.viewType = ViewType.EMPTY;
// return;
// }
Logger.debug(TAG, 'getPageUrlData ' + pageInfo.id);
// pageInfo.groups.forEach(async (group) => { 不能按顺序加载用for...of替代
for (const group of pageInfo.groups) {
this.pageDto = await PageViewModel.getLivePageData(this.pageModel.pageId, `${group.id}`, this.pageModel.channelId, group.groupStrategy
, this.pageModel.currentPage, this.pageModel.pageSize, getContext(this))
this.pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
if (this.pageDto && this.pageDto.compList && this.pageDto.compList.length > 0) {
this.pageDto.compList.forEach((comp) => {
if (comp.compStyle === CompStyle.Zh_Grid_Layout_02 && this.liveReviewDTO && this.liveReviewDTO.list && this.liveReviewDTO.list.length > 0) {
comp.operDataList.push(...this.liveReviewDTO.list)
}
})
this.pageModel.viewType = ViewType.LOADED;
this.pageModel.compList.push(...this.pageDto.compList)
if (this.pageDto.compList.length === this.pageModel.pageSize) {
this.pageModel.currentPage++;
this.pageModel.hasMore = true;
} else {
this.pageModel.hasMore = false;
}
// 二次请求,批查互动数据
PageViewModel.getInteractData(this.pageDto.compList).then((data: CompDTO[]) => {
// 刷新,替换所有数据
this.pageModel.compList.replaceAll(...data)
this.pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
})
this.isFirstIn = false
} else {
Logger.debug(TAG, 'aboutToAppear, data response page ' + this.pageId + ', comp list is empty.');
this.pageModel.viewType = ViewType.EMPTY;
}
}
}
async getPreviewData() {
this.liveReviewDTO = await PageViewModel.getLiveReviewUrl(this.pageNum, this.pageModel.pageSize)
Logger.debug(TAG, 'aboutToAppear, getPreviewData ' + this.liveReviewDTO.hasNext);
this.getData();
this.pageModel.pageInfo = pageInfo;
this.pageModel.loadStrategy = 1
PageHelper.parseGroup(this.pageModel)
}
}
... ...
export class PageUIReqBean {
// 页面数据
pageId: string = '';
groupId: string = '';
channelId: string = '';
isRecGroup: boolean = false;
/**
* 首次加载:loadStrategy= 1
* 下拉刷新:loadStrategy= 2
* 上推刷新:loadStrategy= 3
*/
loadStrategy: number = 1;
currentPage: number = 1;
pageSize: number = 0;
/**
* 楼层类型:
* 推荐:1
* 普通:2
*/
groupStrategy: number = 2;
}
\ No newline at end of file
... ...
... ... @@ -4,6 +4,42 @@ import { Logger } from 'wdKit';
const TAG = 'EmptyComponent';
/**
* WDViewDefaultType 缺省页
*/
export const enum WDViewDefaultType {
///默认
WDViewDefaultType_Default,
///无网
WDViewDefaultType_NoNetwork,
///暂无内容(列表页)
WDViewDefaultType_NoListContent,
///内容找不到了(内容详情页)
WDViewDefaultType_NoContent,
///无搜索内容
WDViewDefaultType_NoSearchResult,
///无消息内容
WDViewDefaultType_NoMessage,
///无收藏内容
WDViewDefaultType_NoCollection,
///无历史记录
WDViewDefaultType_NoHistory,
///网络失败
WDViewDefaultType_NetworkFailed,
///内容获取失败
WDViewDefaultType_ContentFailed,
///无预约内容
WDViewDefaultType_NoBooking,
///无评论内容
WDViewDefaultType_NoComment,
///暂无作品
WDViewDefaultType_NoCreation,
///该号主无法访问
WDViewDefaultType_NoVisitAccount,
///暂无关注
WDViewDefaultType_NoFollow
}
/**
* 空数据/无数据
*/
@Component
... ... @@ -11,18 +47,19 @@ export struct EmptyComponent {
// private emptySize: SizeOptions = {};
@State emptyWidth: string | number = CommonConstants.FULL_PARENT;
@State emptyHeight: string | number = CommonConstants.FULL_PARENT;
@State emptyType:number = WDViewDefaultType.WDViewDefaultType_Default
/**
* The empty image width percentage setting.
*/
readonly EMPTY_IMAGE_WIDTH: string = '50%';
readonly EMPTY_IMAGE_WIDTH: string = '15%';
/**
* The empty image height percentage setting.
*/
readonly EMPTY_IMAGE_HEIGHT: string = '30%';
readonly EMPTY_IMAGE_HEIGHT: string = '15%';
/**
* The empty data text component margin top.
*/
readonly EMPTY_TIP_TEXT_MARGIN_TOP: string = '2%';
readonly EMPTY_TIP_TEXT_MARGIN_TOP: string = '10';
/**
* The empty data text opacity.
*/
... ... @@ -38,11 +75,11 @@ export struct EmptyComponent {
@Builder
noProgrammeData() {
Column() {
// Image($r('app.media.icon_no_content'))
// .width(this.EMPTY_IMAGE_WIDTH)
// .height(this.EMPTY_IMAGE_HEIGHT)
// .objectFit(ImageFit.Contain)
// // .border({ width: 1, color: Color.Red, radius: 6 })
Image(this.buildNoDataTipImage())
.width('this.EMPTY_IMAGE_WIDTH')
.height(this.EMPTY_IMAGE_HEIGHT)
.objectFit(ImageFit.Contain)
// .border({ width: 1, color: Color.Red, radius: 6 })
Text(this.buildNoDataTip())
.fontSize($r('app.float.normal_text_size'))
... ... @@ -59,8 +96,22 @@ export struct EmptyComponent {
.height(this.emptyHeight)
}
buildNoDataTip(): Resource | string {
buildNoDataTip(): string {
Logger.info(TAG, "buildNoDataTip");
return $r('app.string.load_net_data_none')
let contentString: string = '暂无内容'
if (this.emptyType === WDViewDefaultType.WDViewDefaultType_NoCollection) {
contentString = '暂无收藏'
}
return contentString
}
buildNoDataTipImage(): Resource | string {
Logger.info(TAG, "buildNoDataTip");
let imageString: Resource | string = $r('app.media.icon_no_content')
if (this.emptyType === WDViewDefaultType.WDViewDefaultType_NoCollection) {
imageString = $r('app.media.icon_no_collection')
}
return imageString
}
}
\ No newline at end of file
... ...
// 视频直播横划卡16:9
import { LiveVideoTypeComponent } from './LiveVideoTypeComponent'
import { LiveHorizontalCardForOneComponent } from './LiveHorizontalCardForOneComponent'
import { Action, CompDTO, ContentDTO, Params } from 'wdBean'
import { CommonConstants } from 'wdConstant'
import { WDRouterRule } from 'wdRouter/Index'
import { CardMediaInfo } from '../cardCommon/CardMediaInfo'
@Component
export struct LiveHorizontalCardComponent {
@State compDTO: CompDTO = {} as CompDTO
... ... @@ -60,19 +59,9 @@ export struct LiveHorizontalCardComponent {
.width(this.compDTO.operDataList.length == 2 ? 210 : 150)
.borderRadius(4)
.objectFit(ImageFit.Cover)
if (item.objectType === '2' && item.liveInfo && item.liveInfo.liveState === 'running') {
LiveVideoTypeComponent({ nType: 0, name: '直播中' })
.padding({
bottom: 4,
right: 4
})
} else if (item.objectType === '1' && item.videoInfo) {
LiveVideoTypeComponent({ nType: 1, name: item.videoInfo.videoDuration + "" })
.padding({
bottom: 4,
right: 4
})
}
CardMediaInfo({
contentDTO: item
})
}
Text(item.newsTitle)
... ...
// 视频直播横划卡16:9/1个
import { CommonConstants } from 'wdConstant'
import { ContentDTO } from 'wdBean'
import { LiveVideoTypeComponent } from './LiveVideoTypeComponent'
import { CardMediaInfo } from '../cardCommon/CardMediaInfo'
@Component
export struct LiveHorizontalCardForOneComponent {
@State contentDTO: ContentDTO = {} as ContentDTO
... ... @@ -15,21 +14,9 @@ export struct LiveHorizontalCardForOneComponent {
.width(CommonConstants.FULL_WIDTH)
.borderRadius(4)
.objectFit(ImageFit.Cover)
if (this.contentDTO.objectType === '2'
&& this.contentDTO.liveInfo
&& this.contentDTO.liveInfo.liveState === 'running') {
LiveVideoTypeComponent({ nType: 0, name: '直播中' })
.padding({
bottom: 2,
right: 2
})
} else if (this.contentDTO.objectType === '1' && this.contentDTO.videoInfo) {
LiveVideoTypeComponent({ nType: 1, name: this.contentDTO.videoInfo.videoDuration + '' ?? '00:00' })
.padding({
bottom: 2,
right: 2
})
}
CardMediaInfo({
contentDTO: this.contentDTO
})
}
Text(this.contentDTO.newsTitle)
... ...
// 视频直播直播预约
import { LiveVideoTypeComponent } from './LiveVideoTypeComponent'
import { LiveHorizontalCardForOneComponent } from './LiveHorizontalCardForOneComponent'
import { CompDTO, ContentDTO } from 'wdBean'
import { CommonConstants } from 'wdConstant'
import { StringUtils } from 'wdKit/Index'
import { CardMediaInfo } from '../cardCommon/CardMediaInfo'
@Component
export struct LiveHorizontalReservationComponent {
@State compDTO: CompDTO = {} as CompDTO
... ... @@ -51,19 +50,9 @@ export struct LiveHorizontalReservationComponent {
.width(this.compDTO.operDataList.length == 2 ? 210 : 150)
.borderRadius(4)
.objectFit(ImageFit.Cover)
if (item.objectType === '2' && item.liveInfo && item.liveInfo.liveState === 'running') {
LiveVideoTypeComponent({ nType: 0, name: '直播中' })
.padding({
bottom: 4,
right: 4
})
} else if (item.objectType === '1' && item.videoInfo) {
LiveVideoTypeComponent({ nType: 1, name: item.videoInfo.videoDuration + "" })
.padding({
bottom: 4,
right: 4
})
}
CardMediaInfo({
contentDTO: item
})
}
Text(item.newsTitle)
... ...
... ... @@ -23,6 +23,7 @@ import {
postInteractAccentionOperateParams,
postRecommendListParams
} from 'wdBean';
import { PageUIReqBean } from '../components/page/bean/PageUIReqBean';
const TAG = 'HttpRequest';
... ... @@ -46,31 +47,70 @@ export class PageRepository {
return url;
}
static getCompInfoUrl(pageId: string, groupId: string, channelId: string, groupStrategy: number, currentPage: number, pageSize: number) {
let url = HttpUrlUtils.getHost();
if (1 == groupStrategy) {
//推荐
url = url + HttpUrlUtils.COMP_REC_PATH;
static getCompInfoUrl(pageBean: PageUIReqBean) {
let url = HttpUrlUtils.getHost() + HttpUrlUtils.COMP_PATH;
// first_load、pull_down、push_up
let loadStrategy = ''
if (pageBean.loadStrategy == 2) {
loadStrategy = 'pull_down'
} else if (pageBean.loadStrategy == 3) {
loadStrategy = 'push_up'
} else {
//非推荐
url = url + HttpUrlUtils.COMP_PATH;
loadStrategy = 'first_load'
}
// TODO 暂定只请求第一页,后续对接分页加载,参数再调整 first_load?
url = url + "?channelStrategy=2&loadStrategy=first_load"
url = url + "?channelStrategy=" + pageBean.groupStrategy
+ "&loadStrategy=" + loadStrategy
+ "&districtCode=" + HttpUrlUtils.getDistrictCode()
+ "&provinceCode=" + HttpUrlUtils.getProvinceCode()
+ "&cityCode=" + HttpUrlUtils.getCityCode()
+ "&refreshTime=" + DateTimeUtils.getTimeStamp()
+ "&pageId=" + pageId
+ "&groupId=" + groupId
+ "&channelId=" + channelId
+ "&pageSize=" + pageSize
+ "&pageNum=" + currentPage;
+ "&pageId=" + pageBean.pageId
+ "&groupId=" + pageBean.groupId
+ "&channelId=" + pageBean.channelId
+ "&pageSize=" + pageBean.pageSize
+ "&pageNum=" + pageBean.currentPage;
// Logger.debug("TAG", 'getCompInfoUrl url: '+url);
Logger.info(TAG, "getCompInfoUrl url = " + url)
return url;
}
static getRecCompInfoUrl(pageBean: PageUIReqBean) {
let url = HttpUrlUtils.getHost() + HttpUrlUtils.COMP_REC_PATH;
/**
* 首次加载:loadStrategy= first_load
* 上推刷新:loadStrategy= push_up
* 下拉刷新:loadStrategy= pull_down
*/
let loadStrategy = ''
if (pageBean.loadStrategy == 2) {
loadStrategy = 'pull_down'
} else if (pageBean.loadStrategy == 3) {
loadStrategy = 'push_up'
} else {
loadStrategy = 'first_load'
}
url = url + "?channelStrategy=" + pageBean.groupStrategy
+ "&loadStrategy=" + loadStrategy
+ "&districtCode=" + HttpUrlUtils.getDistrictCode()
+ "&provinceCode=" + HttpUrlUtils.getProvinceCode()
+ "&cityCode=" + HttpUrlUtils.getCityCode()
+ "&refreshTime=" + DateTimeUtils.getTimeStamp()
+ "&pageId=" + pageBean.pageId
+ "&groupId=" + pageBean.groupId
+ "&channelId=" + pageBean.channelId
+ "&pageSize=" + pageBean.pageSize
+ "&pageNum=" + pageBean.currentPage;
// Logger.debug("TAG", 'getCompInfoUrl url: '+url);
Logger.info(TAG, "getCompInfoUrl url = " + url)
return url;
}
static getLiveReviewUrl(pageNum: number = 1, pageSize: number = 20) {
let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_REVIEW_PATH + "?pageNum=" + pageNum + "&pageSize=" + pageSize;
Logger.info(TAG, "getLiveReviewUrl url = " + url)
return url;
}
static getDetailInfoUrl(relId: string, contentId: string, relType: string) {
let url = HttpUrlUtils.getHost() + HttpUrlUtils.DETAIL_PATH;
url = url + "?relId=" + relId
... ... @@ -155,12 +195,6 @@ export class PageRepository {
return url;
}
static getLiveReviewUrl(pageNum: number = 1, pageSize: number = 20) {
let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_REVIEW_PATH + "?pageNum=" + pageNum + "&pageSize=" + pageSize;
Logger.info(TAG, "getLiveReviewUrl url = " + url)
return url;
}
static fetchNavigationDataApi() {
let url = PageRepository.getBottomNavGroupUrl();
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
... ... @@ -194,14 +228,14 @@ export class PageRepository {
return WDHttp.get<ResponseDTO<PageInfoDTO>>(url, headers)
};
static fetchLivePageData(pageId: string, groupId: string, channelId: string, groupStrategy: number, currentPage: number, pageSize: number) {
let url = PageRepository.getCompInfoUrl(pageId, groupId, channelId, groupStrategy, currentPage, pageSize)
static fetchCompData(pageBean: PageUIReqBean) {
let url = PageRepository.getCompInfoUrl(pageBean)
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.get<ResponseDTO<PageDTO>>(url, headers)
};
static fetchCompData(pageId: string, groupId: string, channelId: string, groupStrategy: number, currentPage: number, pageSize: number) {
let url = PageRepository.getCompInfoUrl(pageId, groupId, channelId, groupStrategy, currentPage, pageSize)
static fetchRecCompData(pageBean: PageUIReqBean) {
let url = PageRepository.getRecCompInfoUrl(pageBean)
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.get<ResponseDTO<PageDTO>>(url, headers)
};
... ...
... ... @@ -5,6 +5,7 @@ import { PageDTO, CompDTO } from 'wdBean';
import PageModel from '../viewmodel/PageModel';
import PageViewModel from '../viewmodel/PageViewModel';
import { DateTimeUtils } from 'wdKit';
import PageHelper from '../viewmodel/PageHelper';
export function listTouchEvent(pageModel: PageModel, event: TouchEvent) {
switch (event.type) {
... ... @@ -71,31 +72,32 @@ export function touchUpPullRefresh(pageModel: PageModel) {
pageModel.currentPage = 1;
setTimeout(() => {
let self: PageModel = pageModel;
PageViewModel.getPageData(self, getContext())
.then((data: PageDTO) => {
self.timestamp = DateTimeUtils.getTimeStamp().toString()
if (data == null || data.compList == null || data.compList.length == 0) {
self.hasMore = false;
} else {
if (data.compList.length == self.pageSize) {
self.currentPage++;
self.hasMore = true;
} else {
self.hasMore = false;
}
// 刷新,替换所有数据
self.compList.replaceAll(...data.compList)
PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
// 刷新,替换所有数据
self.compList.replaceAll(...data)
self.timestamp = DateTimeUtils.getTimeStamp().toString()
})
}
closeRefresh(self, true);
}).catch((err: string | Resource) => {
promptAction.showToast({ message: err });
closeRefresh(self, false);
});
PageHelper.refreshUI(self)
// PageViewModel.getPageData(self.bizCopy(2))
// .then((data: PageDTO) => {
// self.timestamp = DateTimeUtils.getTimeStamp().toString()
// if (data == null || data.compList == null || data.compList.length == 0) {
// self.hasMore = false;
// } else {
// if (data.compList.length == self.pageSize) {
// self.currentPage++;
// self.hasMore = true;
// } else {
// self.hasMore = false;
// }
// // 刷新,替换所有数据
// self.compList.replaceAll(...data.compList)
// PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
// // 刷新,替换所有数据
// self.compList.replaceAll(...data)
// self.timestamp = DateTimeUtils.getTimeStamp().toString()
// })
// }
// closeRefresh(self, true);
// }).catch((err: string | Resource) => {
// promptAction.showToast({ message: err });
// closeRefresh(self, false);
// });
}, Const.DELAY_TIME);
} else {
closeRefresh(pageModel, false);
... ...
... ... @@ -2,8 +2,9 @@ import promptAction from '@ohos.promptAction';
import PageModel from '../viewmodel/PageModel';
import { RefreshConstants as Const } from './RefreshConstants';
import PageViewModel from '../viewmodel/PageViewModel';
import { PageDTO,CompDTO } from 'wdBean';
import { PageDTO, CompDTO } from 'wdBean';
import { DateTimeUtils } from 'wdKit';
import PageHelper from '../viewmodel/PageHelper';
export function touchMoveLoadMore(model: PageModel, event: TouchEvent) {
// list size +1
... ... @@ -28,29 +29,30 @@ export function touchUpLoadMore(model: PageModel) {
self.isLoading = true;
setTimeout(() => {
closeLoadMore(model);
PageViewModel.getPageData(self, getContext())
.then((data: PageDTO) => {
self.timestamp = DateTimeUtils.getTimeStamp().toString()
if (data == null || data.compList == null || data.compList.length == 0) {
self.hasMore = false;
} else {
if (data.compList.length == self.pageSize) {
self.currentPage++;
self.hasMore = true;
} else {
self.hasMore = false;
}
let sizeBefore:number = self.compList.size();
self.compList.push(...data.compList)
PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
// 刷新,替换所有数据
self.compList.updateItems(sizeBefore, data)
self.timestamp = DateTimeUtils.getTimeStamp().toString()
})
}
}).catch((err: string | Resource) => {
promptAction.showToast({ message: err });
})
PageHelper.loadMore(self)
// PageViewModel.getPageData(self.bizCopy())
// .then((data: PageDTO) => {
// self.timestamp = DateTimeUtils.getTimeStamp().toString()
// if (data == null || data.compList == null || data.compList.length == 0) {
// self.hasMore = false;
// } else {
// if (data.compList.length == self.pageSize) {
// self.currentPage++;
// self.hasMore = true;
// } else {
// self.hasMore = false;
// }
// let sizeBefore: number = self.compList.size();
// self.compList.push(...data.compList)
// PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
// // 刷新,替换所有数据
// self.compList.updateItems(sizeBefore, data)
// self.timestamp = DateTimeUtils.getTimeStamp().toString()
// })
// }
// }).catch((err: string | Resource) => {
// promptAction.showToast({ message: err });
// })
}, Const.DELAY_TIME);
} else {
closeLoadMore(self);
... ...
import { PageDTO, CompDTO, PageInfoDTO } from 'wdBean';
import { ViewType } from 'wdConstant/Index';
import { DateTimeUtils, Logger } from 'wdKit';
import { closeRefresh } from '../utils/PullDownRefresh';
import PageModel from './PageModel';
import PageViewModel from './PageViewModel';
import { promptAction } from '@kit.ArkUI';
const TAG = 'PageHelper';
/**
* 处理返回后的数据
* @deprecated
*/
export class PageHelper {
async refreshUI(pageModel: PageModel) {
pageModel.loadStrategy = 2
this.parseGroup(pageModel)
}
async loadMore(pageModel: PageModel) {
pageModel.loadStrategy = 3
// 暂只支持comp分页加载,节目分页加载的得完善框架(如直播回看节目数据分页)
this.compLoadMore(pageModel)
}
async parseGroup(pageModel: PageModel) {
let pageInfo: PageInfoDTO = pageModel.pageInfo
pageModel.groupList = []
pageModel.groupList.push(...pageInfo.groups)
for (const group of pageInfo.groups) {
pageModel.isRecGroup = group.groupStrategy === 1;
pageModel.groupId = group.id;
if (pageModel.isRecGroup) {
pageModel.pageSize = 10
} else {
pageModel.pageSize = 20
}
pageModel.groupData = group
// await,确保groups接口顺序执行
let pageDto = await PageViewModel.getPageData(pageModel.bizCopy())
let index = pageInfo.groups.indexOf(group)
if (index == 0) {
// 清空comp列表
pageModel.compList.clear()
}
this.getGroupData(pageModel, pageDto, index == pageInfo.groups.length - 1)
}
if (pageModel.compList.isEmpty()) {
// 没数据,展示空页面
Logger.debug(TAG, 'aboutToAppear, data response page ' + pageModel.pageId + ', comp list is empty.');
pageModel.viewType = ViewType.EMPTY;
}
}
private async getGroupData(pageModel: PageModel, pageDto: PageDTO, isLastGroup: boolean) {
pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
if (pageDto && pageDto.compList && pageDto.compList.length > 0) {
pageModel.viewType = ViewType.LOADED;
let sizeBefore: number = pageModel.compList.size();
pageModel.compList.push(...pageDto.compList)
if (pageDto.compList.length === pageModel.pageSize) {
pageModel.currentPage++;
pageModel.hasMore = true;
} else {
pageModel.hasMore = false;
}
// 二次请求,批查互动数据
PageViewModel.getInteractData(pageDto.compList).then((data: CompDTO[]) => {
// 刷新,替换所有数据
// pageModel.compList.replaceAll(...data)
pageModel.compList.updateItems(sizeBefore, data)
pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
})
// TODO 待优化,解决content级别的展现加载
if (isLastGroup) {
closeRefresh(pageModel, true);
// // 最后一个楼层,特殊处理
// // 检测楼层最后一个组件业务数据是否需要通过访问接口获取
// let comp: CompDTO = pageDto.compList[pageDto.compList.length - 1]
// let compSize = CollectionUtils.getListSize(comp.operDataList)
// // 直播回放,需要二次请求数据
// if (compSize <= 0 && comp.dataSourceType == 'LIVE_END') {
// let liveReviewDTO = await PageViewModel.getLiveReviewUrl(pageModel.currentPage, pageModel.pageSize)
// // content数据回来,塞给comp
// comp.operDataList.push(...liveReviewDTO.list)
// }
}
}
}
/**
* 获取直播回看数据
*/
private async getLiveEnd(pageModel: PageModel) {
let liveReviewDTO = await PageViewModel.getLiveReviewUrl(pageModel.currentPage, pageModel.pageSize)
Logger.debug(TAG, 'aboutToAppear, getPreviewData ' + liveReviewDTO.hasNext);
}
/**
* comp加载更多,分页加载
*/
private compLoadMore(pageModel: PageModel) {
PageViewModel.getPageData(pageModel.bizCopy())
.then((data: PageDTO) => {
pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
if (data == null || data.compList == null || data.compList.length == 0) {
pageModel.hasMore = false;
} else {
if (data.compList.length == pageModel.pageSize) {
pageModel.currentPage++;
pageModel.hasMore = true;
} else {
pageModel.hasMore = false;
}
let sizeBefore: number = pageModel.compList.size();
pageModel.compList.push(...data.compList)
PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
// 刷新,替换所有数据
pageModel.compList.updateItems(sizeBefore, data)
pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
})
}
}).catch((err: string | Resource) => {
promptAction.showToast({ message: err });
})
}
/**
* 节目数据分页加载
* TODO 待完善框架
*/
private contentLoadMore() {
}
}
let pageHelper = new PageHelper();
export default pageHelper as PageHelper;
\ No newline at end of file
... ...
import { CompDTO } from 'wdBean';
import { CompDTO, GroupDTO } from 'wdBean';
import { LazyDataSource } from 'wdKit';
import { ViewType } from 'wdConstant/src/main/ets/enum/ViewType';
import { RefreshConstants as Const } from '../utils/RefreshConstants';
import { PageUIReqBean } from '../components/page/bean/PageUIReqBean';
import { GroupInfoDTO, PageInfoDTO } from 'wdBean/src/main/ets/bean/navigation/PageInfoDTO';
/**
* 页面下拉刷新、上拉加载数据bean。
* TODO 将业务数据拆出去
*/
export default class PageModel {
// 页面数据
pageId: string = "";
groupId: string = "";
channelId: string = "";
isRecGroup: boolean = false;
pageInfo: PageInfoDTO = {} as PageInfoDTO
groupList: GroupInfoDTO[] = [];
// 当前请求数据的group
groupData: GroupInfoDTO = {} as GroupInfoDTO;
compList: LazyDataSource<CompDTO> = new LazyDataSource();
// 页面状态,刷新、加载更多等
// 页面状态,刷新、加载更多等,1-首次、2-下拉、3上拉
loadStrategy: number = 1;
currentPage: number = 1;
pageSize: number = Const.PAGE_SIZE;
pullDownRefreshText: Resource = $r('app.string.pull_down_refresh_text');
... ... @@ -35,5 +46,20 @@ export default class PageModel {
isCanLoadMore: boolean = false;
// keyGenerator相关字符串,用于刷新list布局
timestamp: String = '1';
groupStrategy: number = 0;
}
\ No newline at end of file
/**
* 简单复制业务数据
*/
bizCopy(): PageUIReqBean {
let page = new PageUIReqBean()
page.pageId = this.pageId
page.groupId = this.groupId
page.channelId = this.channelId
page.isRecGroup = this.isRecGroup
page.currentPage = this.currentPage
page.pageSize = this.pageSize
page.groupStrategy = this.groupData.groupStrategy
page.loadStrategy = this.loadStrategy
return page
}
}
... ...
... ... @@ -7,14 +7,15 @@ import {
MorningEveningPaperDTO,
NavigationBodyDTO,
PageDTO,
PageInfoBean
PageInfoBean,
PageInfoDTO
} from 'wdBean';
import { CollectionUtils, Logger, ResourcesUtils, StringUtils } from 'wdKit';
import { ResponseDTO, } from 'wdNetwork';
import { PageUIReqBean } from '../components/page/bean/PageUIReqBean';
import { PageRepository } from '../repository/PageRepository';
import { BaseViewModel } from './BaseViewModel';
import PageModel from './PageModel';
const TAG = 'PageViewModel';
/**
... ... @@ -141,38 +142,13 @@ export class PageViewModel extends BaseViewModel {
return compRes.data
}
async getPageData(pageModel: PageModel, context?: Context): Promise<PageDTO> {
async getPageData(pageModel: PageUIReqBean): Promise<PageDTO> {
Logger.debug(TAG, 'getPageData pageId: ' + pageModel.pageId);
return this.parseComp(PageRepository.fetchCompData(pageModel.pageId, pageModel.groupId, pageModel.channelId, pageModel.isRecGroup == true ? 1 : 0, pageModel.currentPage, pageModel.pageSize))
}
async getLivePageData(pageId: string, groupId: string, channelId: string, groupStrategy: number, currentPage: number
, pageSize: number, context: Context): Promise<PageDTO> {
Logger.debug(TAG, 'getPageData pageId: ' + pageId);
if (mock_switch) {
return this.getPageData1(currentPage, context);
if (pageModel.isRecGroup) {
return this.parseComp(PageRepository.fetchRecCompData(pageModel))
} else {
return this.parseComp(PageRepository.fetchCompData(pageModel))
}
return new Promise<PageDTO>((success, error) => {
PageRepository.fetchLivePageData(pageId, groupId, channelId, groupStrategy, currentPage, pageSize)
.then((resDTO: ResponseDTO<PageDTO>) => {
if (!resDTO || !resDTO.data) {
Logger.error(TAG, 'getNavData then resDTO is empty');
error('resDTO is empty');
return
}
if (resDTO.code != 0) {
Logger.error(TAG, `getNavData then code:${resDTO.code}, message:${resDTO.message}`);
error('resDTO Response Code is failure');
return
}
Logger.info(TAG, "getNavData then,resDTO.timestamp:" + resDTO.timestamp);
success(resDTO.data);
})
.catch((err: Error) => {
Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`);
error(err);
})
})
}
private parseComp(getData: Promise<ResponseDTO<PageDTO>>): Promise<PageDTO> {
... ... @@ -342,6 +318,19 @@ export class PageViewModel extends BaseViewModel {
return param;
}
async getPageInfo(pageId: string): Promise<PageInfoDTO> {
return new Promise<PageInfoDTO>((success, error) => {
PageRepository.fetchPageData(pageId).then((resDTO: ResponseDTO<PageInfoDTO>) => {
if (this.isRespondsInvalid(resDTO, 'getPageInfo')) {
error("getPageInfo data invalid");
return
}
Logger.info(TAG, "getPageInfo then,resDTO.timeStamp:" + resDTO.timestamp);
success(resDTO.data as PageInfoDTO);
});
});
}
async getLiveReviewUrl(pageNum: number, pageSize: number): Promise<LiveReviewDTO> {
return new Promise<LiveReviewDTO>((success, error) => {
Logger.info(TAG, `getLivePreviewUrl pageInfo start`);
... ...
... ... @@ -12,6 +12,7 @@
"wdNetwork": "file:../../commons/wdNetwork",
"wdKit": "file:../../commons/wdKit",
"wdBean": "file:../../features/wdBean",
"wdConstant": "file:../../commons/wdConstant"
"wdConstant": "file:../../commons/wdConstant",
"wdDetailPlayApi": "file:../../features/wdDetailPlayApi"
}
}
... ...
import { LiveDetailsBean } from 'wdBean/Index';
import { Action, LiveDetailsBean, LiveRoomDataBean } from 'wdBean/Index';
import { LiveViewModel } from '../viewModel/LiveViewModel';
import { BottomComponent } from '../widgets/details/BottomComponent';
import { TabComponent } from '../widgets/details/TabComponent';
import { TopPlayComponent } from '../widgets/details/video/TopPlayComponet';
import router from '@ohos.router';
@Entry
@Component
export struct DetailPlayLivePage {
TAG: string = 'DetailPlayLivePage';
liveViewModel: LiveViewModel = new LiveViewModel()
@State relId: string = '500005302448'
@State contentId: string = '20000016340'
@State relType: string = '1'
@Provide liveDetailsBean: LiveDetailsBean = {} as LiveDetailsBean
@Provide liveRoomDataBean: LiveRoomDataBean = {} as LiveRoomDataBean
aboutToAppear(): void {
//https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/content/zh/c/content/detail?relId=500005302448&relType=1&contentId=20000016340
let par: Action = router.getParams() as Action;
let params = par?.params;
this.relId = params?.extra?.relId || '';
this.relType = params?.extra?.relType || '';
this.contentId = params?.contentID || '';
this.getLiveDetails()
this.getLiveRoomData()
}
build() {
Column() {
TopPlayComponent({playUrl:'http://mlive3.video.weibocdn.com/record/alicdn/5018726527666338/index.m3u8'})
TopPlayComponent()
TabComponent()
BottomComponent()
}
... ... @@ -30,8 +42,7 @@ export struct DetailPlayLivePage {
}
getLiveDetails() {
this.liveViewModel.getLiveDetails('20000016333', '500005300349', '1')//2024-04-12 15:00:00
// this.liveViewModel.getLiveDetails('20000016229', '500005272745', '1')//2024-04-03 05:00:00
this.liveViewModel.getLiveDetails(this.contentId, this.relId, this.relType)
.then(
(data) => {
if (data.length > 0) {
... ... @@ -43,6 +54,17 @@ export struct DetailPlayLivePage {
})
}
getLiveRoomData() {
this.liveViewModel.getLiveRoomData(this.contentId)
.then(
(data) => {
this.liveRoomDataBean = data
},
() => {
})
}
aboutToDisappear(): void {
}
... ...
import HashMap from '@ohos.util.HashMap';
import { HttpUrlUtils, ResponseDTO } from 'wdNetwork';
import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest';
import { Logger } from 'wdKit';
import { LiveDetailsBean, LiveRoomBean } from 'wdBean/Index';
import { Logger, ToastUtils } from 'wdKit';
import { LiveDetailsBean, LiveRoomBean, LiveRoomDataBean } from 'wdBean/Index';
const TAG = 'LiveModel'
... ... @@ -107,5 +107,91 @@ export class LiveModel {
})
})
}
/**
* 获取直播数据
* @param liveId
* @returns
*/
getLiveRoomData(liveId: string) {
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return new Promise<LiveRoomDataBean>((success, fail) => {
HttpRequest.get<ResponseDTO<LiveRoomDataBean>>(
HttpUrlUtils.getLiveRoomDataUrl() + `?liveId=${liveId}`,
headers).then((data: ResponseDTO<LiveRoomDataBean>) => {
if (!data || !data.data) {
fail("数据为空")
return
}
if (data.code != 0) {
fail(data.message)
return
}
success(data.data)
}, (error: Error) => {
fail(error.message)
Logger.debug(TAG + ":error ", error.toString())
})
})
}
/**
* 获取直播预约状态
* @param relationId
* @param liveId
* @returns
*/
getLiveAppointmentStatus(relationId: string, liveId: string) {
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return new Promise<boolean>((success, fail) => {
HttpRequest.get<ResponseDTO<boolean>>(
HttpUrlUtils.getLiveAppointmentStatusUrl() + `?relationId=${relationId}&liveId=${liveId}`,
headers).then((data: ResponseDTO<boolean>) => {
if (!data || !data.data) {
fail("数据为空")
return
}
if (data.code != 0) {
fail(data.message)
return
}
success(data.data)
}, (error: Error) => {
fail(error.message)
Logger.debug(TAG + ":error ", error.toString())
})
})
}
/**
* 直播预约/取消预约
* @param relationId
* @param mLiveId
* @param isSubscribe
* @returns
*/
liveAppointment(relationId: string, mLiveId: string, isSubscribe: boolean) {
let params: Record<string, string> = {};
params['relationId'] = relationId
params['liveId'] = mLiveId
params['isSubscribe'] = `${isSubscribe}`
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return new Promise<ResponseDTO<string>>((success, fail) => {
HttpRequest.post<ResponseDTO<string>>(
HttpUrlUtils.getLiveAppointmentUrl(),
params,
headers).then((data: ResponseDTO<string>) => {
if (data.code != 0) {
fail(data.message)
ToastUtils.shortToast(data.message)
return
}
success(data)
}, (error: Error) => {
fail(error.message)
Logger.debug(TAG + ":error ", error.toString())
})
})
}
}
... ...
import { LiveDetailsBean, LiveRoomBean } from 'wdBean/Index'
import { LiveDetailsBean, LiveRoomBean, LiveRoomDataBean } from 'wdBean/Index'
import { ResponseDTO } from 'wdNetwork/Index'
import { LiveModel } from './LiveModel'
const TAG = "LiveViewModel"
... ... @@ -42,4 +43,37 @@ export class LiveViewModel {
})
})
}
//直播详情直播间数据
getLiveRoomData(liveId: string) {
return new Promise<LiveRoomDataBean>((success, fail) => {
this.liveModel.getLiveRoomData(liveId).then((data) => {
success(data)
}).catch((message: string) => {
fail(message)
})
})
}
//直播预约状态查询
getLiveAppointmentStatus(relationId: string, liveId: string) {
return new Promise<boolean>((success, fail) => {
this.liveModel.getLiveAppointmentStatus(relationId, liveId).then((data) => {
success(data)
}).catch((message: string) => {
fail(message)
})
})
}
//直播预约/取消预约
liveAppointment(relationId: string, mLiveId: string, isSubscribe: boolean) {
return new Promise<ResponseDTO<string>>((success, fail) => {
this.liveModel.liveAppointment(relationId, mLiveId, isSubscribe).then((data) => {
success(data)
}).catch((message: string) => {
fail(message)
})
})
}
}
\ No newline at end of file
... ...
import font from '@ohos.font'
import { LiveDetailsBean } from 'wdBean/Index'
import { DateTimeUtils, StringUtils } from 'wdKit/Index'
import { LiveViewModel } from '../../viewModel/LiveViewModel'
@Component
export struct LiveCountdownComponent {
... ... @@ -13,6 +14,9 @@ export struct LiveCountdownComponent {
@State minute: string = ''
@State differenceTimeStamp: number = 0
@State isCountDownStart: boolean = false
//是否预约过直播
@State isAppointmentLive: boolean = false
liveViewModel: LiveViewModel = new LiveViewModel()
aboutToAppear(): void {
//注册字体
... ... @@ -107,15 +111,23 @@ export struct LiveCountdownComponent {
top: 16
})
.border({ radius: 4 })
.backgroundColor('#ED2800')
// .backgroundColor('#CCCCCC')
.backgroundColor(this.isAppointmentLive ? '#CCCCCC' : '#ED2800')
.onClick(() => {
if (this.liveDetailsBean && this.liveDetailsBean.liveInfo) {
this.liveAppointment()
}
})
}
calculateDataStatus() {
if (!this.liveDetailsBean) {
return
}
this.getLiveAppointmentStatus()
let startTimeStamp: number = DateTimeUtils.getDateTimestamp(this.liveDetailsBean.liveInfo.planStartTime)
let currentTimeStamp: number = DateTimeUtils.getTimeStamp()
let _differenceTimeStampTmp = startTimeStamp - currentTimeStamp
this.isCountDownStart = _differenceTimeStampTmp <= 4 * 60 * 60 * 1000
this.isCountDownStart = _differenceTimeStampTmp <= 0 ? false : _differenceTimeStampTmp <= 4 * 60 * 60 * 1000
if (this.isCountDownStart) {
this.differenceTimeStamp = _differenceTimeStampTmp
return
... ... @@ -129,6 +141,34 @@ export struct LiveCountdownComponent {
this.minute = playStartTimeTmp.substring(14, 16)
}
}
getLiveAppointmentStatus() {
this.liveViewModel.getLiveAppointmentStatus(
this.liveDetailsBean.reLInfo ? this.liveDetailsBean.reLInfo.relId : '',
this.liveDetailsBean.newsId
).then(
(data) => {
this.isAppointmentLive = data
},
() => {
})
}
liveAppointment() {
this.liveViewModel.liveAppointment(
this.liveDetailsBean.reLInfo ? this.liveDetailsBean.reLInfo.relId : '',
this.liveDetailsBean.newsId,
!this.isAppointmentLive).then(
(data) => {
if (data.success) {
this.isAppointmentLive = !this.isAppointmentLive
}
},
() => {
})
}
}
@Extend(Text)
... ...
import { LiveRoomItemBean } from 'wdBean/Index'
import { LiveDetailsBean, LiveRoomItemBean } from 'wdBean/Index'
import { EmptyComponent, ErrorComponent, ListHasNoMoreDataUI } from 'wdComponent/Index'
import CustomRefreshLoadLayout from 'wdComponent/src/main/ets/components/page/CustomRefreshLoadLayout'
import LoadMoreLayout from 'wdComponent/src/main/ets/components/page/LoadMoreLayout'
... ... @@ -14,6 +14,7 @@ export struct TabChatComponent {
@State private pageModel: PageModel = new PageModel()
liveViewModel: LiveViewModel = new LiveViewModel()
@State liveChatList: Array<LiveRoomItemBean> = []
@Consume liveDetailsBean: LiveDetailsBean
aboutToAppear(): void {
this.getLiveChatList()
... ... @@ -77,7 +78,11 @@ export struct TabChatComponent {
getLiveChatList() {
this.pageModel.currentPage = 1
this.liveViewModel.getLiveChatList(1, '20000016257', '20000016229', 20,)
this.liveViewModel.getLiveChatList(
1,
this.liveDetailsBean?.liveInfo?.mlive?.mliveId,
this.liveDetailsBean?.newsId,
20,)
.then(
(data) => {
if (data.barrageResponses && data.barrageResponses.length > 0) {
... ...
... ... @@ -19,6 +19,7 @@ export struct TabInfoComponent {
right: 16
})
.height('100%')
.alignItems(HorizontalAlign.Start)
}
aboutToDisappear(): void {
... ...
import { LiveRoomItemBean } from 'wdBean/Index'
import { LiveDetailsBean, LiveRoomItemBean } from 'wdBean/Index'
import { ListHasNoMoreDataUI } from 'wdComponent/Index'
import { StringUtils } from 'wdKit/Index'
import { LiveViewModel } from '../../viewModel/LiveViewModel'
import { TabLiveItemComponent } from './TabLiveItemComponent'
... ... @@ -7,6 +8,7 @@ import { TabLiveItemComponent } from './TabLiveItemComponent'
export struct TabLiveComponent {
liveViewModel: LiveViewModel = new LiveViewModel()
@State liveList: Array<LiveRoomItemBean> = []
@Consume liveDetailsBean: LiveDetailsBean
aboutToAppear(): void {
this.getLiveList()
... ... @@ -37,9 +39,27 @@ export struct TabLiveComponent {
}
getLiveList() {
this.liveViewModel.getLiveList(1, '20000016257', '20000016229', 20,)
this.liveViewModel.getLiveList(
1,
this.liveDetailsBean?.liveInfo?.mlive?.mliveId,
this.liveDetailsBean?.newsId,
20)
.then(
(data) => {
/**
* 在直播聊天添加一条新内容逻辑:
判断 oldNewsId:迁移id非空 且 直播状态不是预约:"wait"
消息内容:
1.头像固定:APP默认头像
2.名称固定:人民日报主持人
3.内容:详情接口的简介,newIntroduction
*/
if (StringUtils.isNotEmpty(this.liveDetailsBean.oldNewsId) && this.liveDetailsBean && this.liveDetailsBean.liveInfo.liveState != 'wait') {
let liveRoomItemBeanTemp: LiveRoomItemBean = {} as LiveRoomItemBean
liveRoomItemBeanTemp.text = this.liveDetailsBean.newIntroduction
liveRoomItemBeanTemp.senderUserName = '人民日报主持人'
data.barrageResponses.push(liveRoomItemBeanTemp)
}
this.liveList = data.barrageResponses
},
() => {
... ...
import { LiveRoomItemBean } from 'wdBean/Index'
import { DateTimeUtils } from 'wdKit/Index'
import { DateTimeUtils, StringUtils } from 'wdKit/Index'
@Component
export struct TabLiveItemComponent {
... ... @@ -12,7 +12,7 @@ export struct TabLiveItemComponent {
build() {
Column() {
Row() {
Image(this.item.senderUserAvatarUrl)
Image(StringUtils.isEmpty(this.item.senderUserAvatarUrl) ? $r('app.media.default_head') : this.item.senderUserAvatarUrl)
.borderRadius(90)
.width(24)
.height(24)
... ... @@ -46,6 +46,7 @@ export struct TabLiveItemComponent {
.fontWeight(400)
.fontColor('#999999')
.margin({ left: 8 })
.visibility(StringUtils.isNotEmpty(this.item.time) ? Visibility.Visible : Visibility.None)
Blank()
Text('置顶')
.maxLines(1)
... ... @@ -74,6 +75,8 @@ export struct TabLiveItemComponent {
left: 32,
top: 6
})
.width('100%')
.textAlign(TextAlign.Start)
List() {
ForEach(this.item.pictureUrls, (item: string, index: number) => {
ListItem() {
... ...
import { window } from '@kit.ArkUI'
import { NumberFormatterUtils, WindowModel } from 'wdKit/Index'
import { devicePLSensorManager } from 'wdDetailPlayApi/Index'
import { DateFormatUtil, WDPlayerController } from 'wdPlayer/Index'
import { LiveDetailsBean, LiveRoomDataBean } from 'wdBean/Index'
@Entry
@Component
export struct PlayUIComponent {
playerController: WDPlayerController = new WDPlayerController();
//菜单键是否可见
@State isMenuVisible: boolean = true
@State isFullScreen: boolean = false
@Consume liveDetailsBean: LiveDetailsBean
@Consume liveRoomDataBean: LiveRoomDataBean
@State currentTime: string = ''
@State totalTime: string = ''
@State progressVal: number = 0;
//是否处于播放状态中
@State isPlayStatus: boolean = true
aboutToAppear(): void {
//播放进度监听
this.playerController.onTimeUpdate = (position: number, duration: number) => {
this.currentTime = DateFormatUtil.secondToTime(Math.floor(position / 1000));
this.totalTime = DateFormatUtil.secondToTime(Math.floor(duration / 1000));
this.progressVal = Math.floor(position * 100 / duration);
}
}
build() {
Column() {
this.getTopUIComponent()
this.getMiddleUIComponent()
this.getBottomUIComponent()
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
getTopUIComponent() {
Column() {
Row() {
Image($r('app.media.icon_arrow_left_white'))
.width(24)
.aspectRatio(1)
.visibility(Visibility.None)
.margin({
right: 10
})
Text(this.liveDetailsBean.newsTitle)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('16fp')
.fontWeight(500)
.fontColor(Color.White)
.textAlign(TextAlign.Start)
.layoutWeight(1)
Image($r('app.media.icon_share'))
.width(24)
.aspectRatio(1)
.visibility(Visibility.None)
}
.width('100%')
.alignItems(VerticalAlign.Center)
.margin({
bottom: 10
})
this.getLiveStatusView()
}.width('100%')
.padding({
top: 20,
bottom: 6,
left: 10,
right: 10
})
.alignItems(HorizontalAlign.Start)
.visibility(this.isMenuVisible ? Visibility.Visible : Visibility.None)
}
@Builder
getLiveStatusView() {
// 直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停
// 预约
// 直播中
if (this.liveDetailsBean.liveInfo?.liveState == 'running') {
Row() {
Image($r('app.media.icon_live_status_running'))
.width(22)
.height(18)
Text('直播中')
.fontSize('11fp')
.fontWeight(400)
.fontColor(Color.White)
Image($r('app.media.icon_live_player_status_end'))
.width(12)
.height(12)
Text(`${NumberFormatterUtils.formatNumberWithWan(this.liveRoomDataBean.pv)}人参与`)
.fontSize('11fp')
.fontWeight(400)
.fontColor(Color.White)
}
.backgroundColor('#4D000000')
.padding({
top: 1,
right: 4,
bottom: 1
})
}
//回看
else if (this.liveDetailsBean.liveInfo?.liveState == 'end') {
Row() {
Text('回看')
.fontSize('11fp')
.fontWeight(400)
.fontColor(Color.White)
Image($r('app.media.icon_live_player_status_end'))
.width(12)
.height(12)
Text(`${NumberFormatterUtils.formatNumberWithWan(this.liveRoomDataBean.pv)}人参与`)
.fontSize('11fp')
.fontWeight(400)
.fontColor(Color.White)
}
.backgroundColor('#4D000000')
.padding({
left: 4,
top: 1,
right: 4,
bottom: 1
})
}
}
@Builder
getMiddleUIComponent() {
Stack()
.layoutWeight(1)
.width('100%')
.onClick(() => {
this.isMenuVisible = !this.isMenuVisible
})
}
@Builder
getBottomUIComponent() {
Row() {
if (this.liveDetailsBean?.liveInfo?.liveState == 'end') {
this.playOrPauseBtn()
Text(this.currentTime)
.fontColor(Color.White)
.fontWeight(600)
.fontSize('12fp')
.margin({
left: 16
})
this.playProgressView()
Text(this.totalTime)
.fontColor(Color.White)
.fontWeight(600)
.fontSize('12fp')
.margin({
right: 16
})
} else {
Blank()
}
Image($r('app.media.icon_live_player_full_screen'))
.width(24)
.height(24)
.onClick(() => {
this.isFullScreen = !this.isFullScreen
WindowModel.shared.setPreferredOrientation(this.isFullScreen ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT);
devicePLSensorManager.devicePLSensorOn(this.isFullScreen ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT);
})
}
.alignItems(VerticalAlign.Center)
.linearGradient({ angle: 0, colors: [['#99000000', 0], ['#00000000', 1]] })
.width('100%')
.padding({
left: 10,
right: 10,
top: 15,
bottom: 15
})
.visibility(this.isMenuVisible ? Visibility.Visible : Visibility.None)
}
@Builder
playOrPauseBtn() {
//暂停、播放
Image(this.isPlayStatus ? $r('app.media.icon_live_player_pause') : $r('app.media.player_play_ic'))
.width(24)
.height(24)
.onClick(() => {
if (this.isPlayStatus) {
this.isPlayStatus = false
this.playerController.pause()
} else {
this.isPlayStatus = true
this.playerController.play()
}
})
}
@Builder
playProgressView() {
Slider({
value: this.progressVal,
step: 1,
style: SliderStyle.OutSet
})
.blockSize({
width: 18,
height: 12
})// .blockStyle({
// type: SliderBlockType.IMAGE,
// image: $r('app.media.ic_player_block')
// })
.blockColor(Color.White)
.trackColor('#4DFFFFFF')
.selectedColor('#FFED2800')
.height(14)
.trackThickness(1)
.layoutWeight(1)
.margin({
left: 8,
right: 8
})
.onChange((value: number, mode: SliderChangeMode) => {
this.playerController?.setSeekTime(value, mode);
})
}
}
\ No newline at end of file
... ...
import { WDPlayerController, WDPlayerRenderView } from 'wdPlayer/Index';
import { LiveDetailsBean } from 'wdBean/Index';
import { WDPlayerController, WDPlayerRenderLiveView } from 'wdPlayer/Index';
import { PlayUIComponent } from './PlayUIComponent';
@Component
export struct TopPlayComponent {
@Prop playUrl: string=''
aspectRatioPlayer: number = 375 / 211
@State playerController: WDPlayerController = new WDPlayerController();
@Consume @Watch('updateData') liveDetailsBean: LiveDetailsBean
playerController: WDPlayerController = new WDPlayerController();
aboutToAppear(): void {
setTimeout(() => {
this.playerController.switchPlayOrPause()
},2000)
this.playerController.onCanplay = () => {
this.playerController.play()
}
}
updateData() {
//直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停
if (this.liveDetailsBean.liveInfo && this.liveDetailsBean.liveInfo.vlive.length > 0) {
let playUrl = ''
if (this.liveDetailsBean.liveInfo.liveState == 'running') {
playUrl = this.liveDetailsBean.liveInfo.vlive[0].liveUrl
} else if (this.liveDetailsBean.liveInfo.liveState == 'end') {
playUrl = this.liveDetailsBean.liveInfo.vlive[0].replayUri
}
this.playerController.firstPlay(playUrl);
}
}
build() {
Stack() {
WDPlayerRenderView({
WDPlayerRenderLiveView({
playerController: this.playerController,
onLoad: async () => {
this.playerController.firstPlay(this.playUrl);
}
})
.height('100%')
.width('100%')
.onClick(() => {
console.error('WDPlayerRenderView=== onClick')
this.playerController?.switchPlayOrPause();
})
PlayUIComponent({ playerController: this.playerController })
}
.height(211)
.aspectRatio(this.aspectRatioPlayer)
.backgroundColor(Color.Black)
.width('100%')
}
aboutToDisappear(): void {
this.playerController.pause()
}
}
\ No newline at end of file
... ...
... ... @@ -9,6 +9,11 @@
"2in1"
],
"deliveryWithInstall": true,
"pages": "$profile:main_pages"
"pages": "$profile:main_pages",
"requestPermissions": [
{
"name":"ohos.permission.ACCELEROMETER"
}
]
}
}
\ No newline at end of file
... ...
... ... @@ -2,6 +2,8 @@ export { WDPlayerController } from "./src/main/ets/controller/WDPlayerController
export { WDPlayerRenderView } from "./src/main/ets/pages/WDPlayerRenderView"
export { WDPlayerRenderLiveView } from "./src/main/ets/pages/WDPlayerRenderLiveView"
export { PlayerConstants } from "./src/main/ets/constants/PlayerConstants"
export { SpeedBean } from "./src/main/ets/bean/SpeedBean"
... ...
import componentUtils from '@ohos.arkui.componentUtils';
import { WDPlayerController } from '../controller/WDPlayerController'
import { WindowModel } from 'wdKit';
import { Logger } from '../utils/Logger';
class Size {
width: Length = "100%";
height: Length = "100%";
constructor(width: Length, height: Length) {
this.width = width;
this.height = height;
}
}
let insIndex: number = 0;
const TAG = 'WDPlayerRenderLiveView'
class MGPlayRenderViewIns {
static intCount: number = 0;
static add() {
MGPlayRenderViewIns.intCount++;
WindowModel.shared.setWindowKeepScreenOn(true);
console.log("add-- +1")
}
static del() {
console.log("del-- -1")
MGPlayRenderViewIns.intCount--;
if (MGPlayRenderViewIns.intCount <= 0) {
WindowModel.shared.setWindowKeepScreenOn(false);
}
}
}
/**
* 播放窗口组件
*/
@Component
export struct WDPlayerRenderLiveView {
private playerController?: WDPlayerController;
private xComponentController: XComponentController = new XComponentController();
onLoad?: ((event?: object) => void);
videoWidth: number = 0
videoHeight: number = 0
@State selfSize: Size = new Size('100%', '100%');
private insId: string = "WDPlayRenderView" + insIndex;
aboutToAppear() {
MGPlayRenderViewIns.add();
console.log('playerController', this.playerController)
insIndex++;
if (!this.playerController) {
return
}
this.playerController.onVideoSizeChange = (width: number, height: number) => {
// console.log(`WDPlayerRenderView onVideoSizeChange width:${width} videoTop:${height}`)
Logger.info(TAG, ` onVideoSizeChange width:${width} videoTop:${height}`)
this.videoWidth = width;
this.videoHeight = height;
this.updateLayout()
}
}
aboutToDisappear() {
Logger.info(TAG, `aboutToDisappear`)
MGPlayRenderViewIns.del();
}
build() {
Row() {
// 设置为“surface“类型时XComponent组件可以和其他组件一起进行布局和渲染。
XComponent({
id: 'xComponentId',
type: 'surface',
controller: this.xComponentController
})
.onLoad(async (event) => {
Logger.info(TAG, 'onLoad')
let surfaceId = this.xComponentController.getXComponentSurfaceId()
console.log('surfaceId===', surfaceId)
console.log('insId===', this.insId)
this.xComponentController.setXComponentSurfaceSize({
surfaceWidth: 1920,
surfaceHeight: 1080
});
this.playerController?.setXComponentController(this.xComponentController)
if (this.onLoad) {
this.onLoad(event)
}
})
.width(this.selfSize.width)
.height(this.selfSize.height)
}
.id(this.insId)
.onAreaChange(() => {
// this.updateLayout()
})
.backgroundColor("#000000")
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
updateLayout() {
let info = componentUtils.getRectangleById(this.insId);
if (info.size.width > 0 && info.size.height > 0 && this.videoHeight > 0 && this.videoWidth > 0) {
if (info.size.width / info.size.height > this.videoWidth / this.videoHeight) {
let scale = info.size.height / this.videoHeight;
this.selfSize = new Size((this.videoWidth * scale / info.size.width) * 100 + "%", '100%');
} else {
let scale = info.size.width / this.videoWidth;
this.selfSize = new Size('100%', (this.videoHeight * scale / info.size.height) * 100 + "%");
}
}
}
}
\ No newline at end of file
... ...
... ... @@ -17,7 +17,7 @@ export default struct CustomDialogComponent {
Text($r('app.string.dialog_text_title'))
.width("90%")
.fontColor($r('app.color.dialog_text_color'))
.fontSize($r('app.float.dialog_text_privacy_size'))
.fontSize(18)
.textAlign(TextAlign.Center)
.fontWeight('500')
.margin({
... ... @@ -25,10 +25,25 @@ export default struct CustomDialogComponent {
bottom: $r('app.float.dialog_text_privacy_bottom')
})
Text($r('app.string.dialog_text_subTitle'))
.fontSize($r('app.float.dialog_common_text_size'))
.fontSize(14)
.fontColor($r('app.color.dialog_private_text_color'))
.width('90%')
Text($r('app.string.dialog_text_privacy_content'))
.fontSize($r('app.float.dialog_common_text_size'))
Text(){
Span('为了更好地为您提供阅读新闻、发布评论等相关服务,我们会根据您使用服务的具体功能需要,收集必要的用户信息。您可通过阅读')
.fontSize(14).fontColor($r('app.color.dialog_private_text_color'))
Span('《隐私政策》').fontSize(14).fontColor("#ED2800").onClick(()=>{
let bean={contentID:"2",pageID:""} as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean)
})
Span('和').fontSize(14).fontColor($r('app.color.dialog_private_text_color')).fontColor($r('app.color.dialog_private_text_color'))
Span('《用户协议》').fontSize(14).fontColor("#ED2800").onClick(()=>{
let bean={contentID:"1",pageID:""} as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean)
})
Span('了解我们收集、使用、存储和共享个人信息的情况,以及对您个人隐私的保护措施。人民日报客户端深知个人信息对您的重要性,我们将以最高标准遵守法律法规要求,尽全力保护您的个人信息安全。')
.fontSize(14)
.fontColor($r('app.color.dialog_private_text_color'))
}
.width('90%')
Row(){
... ... @@ -115,11 +130,11 @@ export default struct CustomDialogComponent {
.margin({
top:'36lpx',
bottom:'21lpx'
})
}).visibility(Visibility.None)
Text($r('app.string.dialog_text_privacy_statement'))
.width('90%')
.fontColor($r('app.color.dialog_text_color'))
.fontSize($r('app.float.dialog_common_text_size'))
.fontSize(13).margin({top:20})
Row() {
Text($r('app.string.dialog_button_disagree'))
.fancy()
... ... @@ -154,7 +169,7 @@ export default struct CustomDialogComponent {
// Common text styles.
@Extend(Text) function fancy () {
.fontColor($r("app.color.dialog_fancy_text_left_color"))
.fontSize($r("app.float.dialog_fancy_text_size"))
.fontSize(16)
.textAlign(TextAlign.Center)
.fontWeight(FontWeight.Medium)
.layoutWeight('1')
... ... @@ -162,7 +177,7 @@ export default struct CustomDialogComponent {
// Common text styles.
@Extend(Text) function fancyAgree () {
.fontColor($r("app.color.dialog_fancy_text_right_color"))
.fontSize($r("app.float.dialog_fancy_text_size"))
.fontSize(16)
.textAlign(TextAlign.Center)
.fontWeight(FontWeight.Medium)
.layoutWeight('1')
... ...
... ... @@ -51,6 +51,10 @@
{
"name": "dialog_text_statement_color",
"value": "#007DFF"
},
{
"name": "dialog_private_text_color",
"value": "#666666"
}
]
}
... ...