wangyong_wd

播报页面开发

Showing 21 changed files with 536 additions and 4 deletions
... ... @@ -73,6 +73,8 @@ export function registerRouter() {
return WDRouterPage.morningEveningPaperPage
} else if (action.params?.pageID == "IMAGE_TEXT_DETAIL") {
return WDRouterPage.imageTextDetailPage
} else if (action.params?.pageID == "BroadcastPage") {
return WDRouterPage.broadcastPage
}
return undefined
})
... ...
... ... @@ -83,4 +83,7 @@ export class WDRouterPage {
// static loginProtocolPage = new WDRouterPage("wdLogin", "ets/pages/login/LoginProtocolWebview");
//播报页面
static broadcastPage = new WDRouterPage("phone", "ets/pages/broadcast/BroadcastPage");
}
... ...
export interface ChannelInfo {
channelId: string;
channelLevel: string;
channelName: string;
channelSkin: string;
channelStrategy: string;
channelStyle: string;
pageId: string;
pageTopType: string;
pcStyle: string;
webBackgroundImgUrl: string;
}
\ No newline at end of file
... ...
import { Group } from './Group';
import { TopicInfo } from './TopicInfo';
import { ChannelInfo } from './ChannelInfo'
export interface PageInfoBean {
backIconUrl: string;
backgroundColor: string;
... ... @@ -8,7 +8,7 @@ export interface PageInfoBean {
baselineColor: string;
baselineCopywriting: string;
baselineShow: number;
// channelInfo?: any;
channelInfo?: ChannelInfo;
// cornersAdv?: any;
// cornersAdv2: any[];
description: string;
... ...
... ... @@ -55,3 +55,6 @@ export { ZhGridLayoutComponent } from "./src/main/ets/components/view/ZhGridLayo
export { MultiPictureDetailPageComponent } from "./src/main/ets/components/MultiPictureDetailPageComponent"
export { AudioDetailComponent } from "./src/main/ets/components/AudioDetailComponent"
export { BroadcastPageComponent } from "./src/main/ets/components/broadcast/BroadcastPageComponent"
... ...
import router from '@ohos.router';
import { Params } from 'wdBean'
import { RecommendHeader } from './RecommendHeader';
import { RecommendTitle } from './RecommendTitle';
import { RecommendLists } from './RecommendLists'
import { SelectedColumns } from './SelectedColumns'
import { CompList, PageInfoBean, CompInfoBean } from 'wdBean';
import { DateTimeUtils, Logger } from 'wdKit/Index';
import { PaperReaderSimpleDialog } from '../../dialog/PaperReaderDialog';
import { BroadcastViewModel } from '../../viewmodel/BroadcastViewModel';
import { DateFormatUtil, PlayerConstants, WDPlayerController } from 'wdPlayer';
import { AudioDataList } from 'wdBean/src/main/ets/bean/morningevening/AudioDataList';
import { CommonConstants } from 'wdConstant/Index';
const TAG = 'BroadcastPageComponent';
@Entry
@Component
export struct BroadcastPageComponent {
@State params:Params = router.getParams() as Params;
@State pageInfoBean: PageInfoBean = {} as PageInfoBean // 播报页面信息
@State compInfoBean: CompInfoBean = {} as CompInfoBean // 组件信息
@State recommendCompInfoBean: CompInfoBean = {} as CompInfoBean // 推荐播报组件信息
@State columnsCompInfoBean: CompInfoBean = {} as CompInfoBean // 精选栏目组件信息
@State compListItem: CompList = {} as CompList
@State audioPlayUrl: string = ""
@Provide title: string = ''
@Provide subTitle: string = ''
@Provide isAudioPlaying: boolean = false
@Provide status: number = PlayerConstants.STATUS_START;
@Provide currentTime: string = "00:00";
@Provide totalTime: string = "00:00";
@Provide progressVal: number = 0;
private audioDataList: AudioDataList[] = []
private playerController: WDPlayerController = new WDPlayerController();
simpleAudioDialog: CustomDialogController = new CustomDialogController({
builder: PaperReaderSimpleDialog({
cancel: this.onCancel,
confirm: this.onConfirm,
playerController: this.playerController
}),
autoCancel: false,
customStyle: true,
alignment: DialogAlignment.CenterStart,
offset: { dx: 12, dy: -150 },
})
onCancel() {
Logger.info(TAG, "cj2024 onCancel = ")
}
/**
* 回调无用
**/
onConfirm() {
Logger.info(TAG, "cj2024 onConfirm = ")
}
// 续播判断
changeContinue() {
Logger.info(TAG, "cj2024 changeContinue = 1")
this.playerController.continue = () => {
Logger.info(TAG, "cj2024 changeContinue = 2")
this.playerController?.stop();
}
return;
}
async aboutToAppear() {
Logger.debug(TAG, `about1ToAppear`, router.getParams().toString())
const currentTime = new Date().getTime()
try {
// 获取页面信息
Logger.warn('获取页面信息')
let pageInfoBean = await BroadcastViewModel.getBroadcastViewPageInfo('21003')
Logger.warn('pageInfoBean-')
Logger.warn(pageInfoBean.groups[0].blockDesc)
this.pageInfoBean = pageInfoBean;
//TODO 根据页面中组件信息。现在默认认为后端只返回2个。第一个是播报,第二个是精选栏目
const pageId = pageInfoBean.id,
groupId_0 = pageInfoBean.groups[0]?.id,
refreshTime = currentTime + "",
topicId = pageInfoBean?.topicInfo?.topicId || '',
channelId = pageInfoBean?.channelInfo?.channelId || ''
if(pageInfoBean.groups[0]) {
this.recommendCompInfoBean = await BroadcastViewModel.getBroadcastCompInfo(pageId, groupId_0, refreshTime, topicId, channelId)
}
if(pageInfoBean.groups[1]) {
const groupId_1 = pageInfoBean.groups[1]?.id
this.columnsCompInfoBean = await BroadcastViewModel.getBroadcastCompInfo(pageId, groupId_1, refreshTime, topicId, channelId)
}
} catch (exception) {
}
}
onPageShow() {
Logger.debug(TAG, `onPageShow--`, JSON.stringify(router.getParams()))
}
onPageHide() {
this.status = PlayerConstants.STATUS_PAUSE;
this.playerController?.pause();
}
build() {
Column() {
// 顶部标题
RecommendHeader()
List() {
ListItem(){
RecommendTitle()
}
if(this.pageInfoBean.groups && this.pageInfoBean.groups[0] && this.recommendCompInfoBean.compList) {
ListItem(){
RecommendLists({
recommendCompInfoBean: this.recommendCompInfoBean
})
}
}
if(this.pageInfoBean.groups && this.pageInfoBean.groups[1] && this.columnsCompInfoBean.compList) {
ListItem() {
SelectedColumns({
columnsCompTitle: this.pageInfoBean.groups[1].blockDesc,
columnsCompInfoBean: this.columnsCompInfoBean
})
.margin({ top: 12 })
}
}
}
.layoutWeight(1)
// @ts-ignore
.onScrollFrameBegin((offset, state) => {
console.log('ccc',String(offset), state)
})
.onReachStart(() => {
console.log('onReachStart----->',)
})
}
.width(CommonConstants.FULL_WIDTH)
.backgroundImage($r('app.media.broadcast_bg'))
.backgroundImageSize({width: '100%', height: '100%'})
}
}
\ No newline at end of file
... ...
import router from '@ohos.router';
import { CommonConstants } from 'wdConstant/Index';
/**
* 今日推荐顶部标题--fixed标题
*/
@Entry
@Component
export struct RecommendHeader {
build() {
Stack() {
Image($r('app.media.icon_arrow_down_black'))
.height($r('app.float.top_arrow_size'))
.width($r('app.float.top_arrow_size'))
.onClick((event: ClickEvent) => {
router.back()
})
.zIndex(1)
Text('今日推荐')
.margin({ left: 5 })
.fontSize($r('app.float.selected_text_size'))
.fontColor($r('app.color.color_222222'))
.width(CommonConstants.FULL_WIDTH)
.height(CommonConstants.FULL_HEIGHT)
.textAlign(TextAlign.Center)
}
.height($r('app.float.top_bar_height'))
.padding({left: 16, right: 16})
.alignContent(Alignment.Start)
}
}
\ No newline at end of file
... ...
import { CompInfoBean, CompDTO } from 'wdBean'
import { CommonConstants } from 'wdConstant';
import { ProcessUtils } from '../../utils/ProcessUtils';
/**
* 播报--今日推荐列表
*/
@Entry
@Component
export struct RecommendLists {
@Prop recommendCompInfoBean: CompInfoBean = {} as CompInfoBean // 推荐-组件信息
build() {
Column(){
ForEach(this.recommendCompInfoBean.compList.slice(0,3), (item: CompDTO) => {
this.recommendTop3Item(item)
})
// 查看更多
if(this.recommendCompInfoBean.compList.length > 3) {
Row() {
Text("查看全部")
.fontSize($r("app.float.font_size_12"))
.fontColor($r("app.color.color_222222"))
.margin({ right: 1 })
Image($r("app.media.more"))
.width(14)
.height(14)
}
.width(CommonConstants.FULL_WIDTH)
.height(40)
.borderRadius(3)
.justifyContent(FlexAlign.Center)
.margin({top: 5})
.onClick(() => {
// console.log(1)
})
}
}
.margin({left: 16, right: 16})
.padding({left: 16, right: 16})
.backgroundColor($r('app.color.color_fff'))
.borderRadius(5)
}
@Builder
recommendTop3Item(item: CompDTO) {
Row(){
Image($r('app.media.broadcast_pause'))
.width(24)
.height(24)
.margin({right:12})
Text(item.operDataList[0].newsTitle)
.fontSize($r('app.float.font_size_16'))
.fontColor($r('app.color.color_212228'))
.maxLines(1)
.textOverflow({overflow: TextOverflow.Ellipsis})
.layoutWeight(1)
}
.width(CommonConstants.FULL_WIDTH)
.padding({top: 12, bottom: 12})
.onClick(() => {
ProcessUtils.processPage(item.operDataList[0])
})
}
@Builder
recommendListItem() {
}
}
\ No newline at end of file
... ...
import { CommonConstants } from 'wdConstant/Index'
/**
* 播报标题描述
*/
@Entry
@Component
export struct RecommendTitle {
build() {
Row(){
// 左边
Column(){
Text('每日最动听的声音')
.fontSize($r('app.float.font_size_14'))
.fontColor($r('app.color.color_222222'))
.alignSelf(ItemAlign.Start)
Image($r('app.media.broadcast_line'))
.width(147)
.margin({
top: 8, bottom: 8
})
Row(){
Column(){
Text('今推')
.fontSize($r('app.float.font_size_24'))
.fontColor($r('app.color.color_222222'))
.fontWeight(600)
Text('日荐')
.fontSize($r('app.float.font_size_24'))
.fontColor($r('app.color.color_222222'))
.fontWeight(600)
}
.margin({right: 8})
.alignSelf(ItemAlign.Start)
Column() {
Text('正月二十八')
.fontSize($r('app.float.font_size_14'))
.fontColor($r('app.color.color_222222'))
Text('02/28')
.fontSize($r('app.float.font_size_24'))
.fontColor($r('app.color.color_222222'))
}
}
.alignSelf(ItemAlign.Start)
}
Blank()
Image($r('app.media.broadcast_pause'))
.width(90)
.height(90)
.margin({
right: 9
})
}
.width(CommonConstants.FULL_WIDTH)
.padding({left: 16, right: 16})
.margin({bottom: 12})
}
}
\ No newline at end of file
... ...
import { CompInfoBean, CompDTO } from 'wdBean'
import { DateTimeUtils } from 'wdKit/Index'
import { CommonConstants } from 'wdConstant';
import { ProcessUtils } from '../../utils/ProcessUtils';
/**
* 精选栏目
*/
@Entry
@Component
export struct SelectedColumns {
@Prop columnsCompInfoBean: CompInfoBean = {} as CompInfoBean // 精选栏目组件信息
@Prop columnsCompTitle: string = ''
build() {
Column(){
Text(this.columnsCompTitle)
.fontSize($r('app.float.selected_text_size'))
.fontColor($r('app.color.color_222222'))
.fontWeight(500)
.width(CommonConstants.FULL_WIDTH)
ForEach(this.columnsCompInfoBean.compList, (item: CompDTO) => {
this.SelectedColumnsItem(item)
})
}
.padding({left: 16,top: 12, right: 16})
.backgroundColor($r('app.color.white'))
}
@Builder
SelectedColumnsItem(item: CompDTO) {
Row() {
Image(item.operDataList[0].coverUrl)
.height(53)
.width(80)
.objectFit(ImageFit.Cover)
.margin({right: 12})
Column({space: 4}){
Text(item.operDataList[0].newsTitle)
.fontSize($r('app.float.font_size_16'))
.fontColor($r('app.color.color_222222'))
.width(CommonConstants.FULL_WIDTH)
.maxLines(1)
.textOverflow({overflow: TextOverflow.Ellipsis})
Text(item.operDataList[0].newsSummary)
.fontSize($r('app.float.font_size_12'))
.fontColor($r('app.color.color_999999'))
.width(CommonConstants.FULL_WIDTH)
.maxLines(1)
.textOverflow({overflow: TextOverflow.Ellipsis})
Row(){
Image($r('app.media.broadcast_clock'))
.width(12)
.height(12)
.margin({right: 4})
Text(DateTimeUtils.getCommentTime(Number.parseFloat(item.operDataList[0].publishTime)))
.fontSize($r('app.float.font_size_12'))
.fontColor($r('app.color.color_999999'))
.margin({ right :24 })
Image($r('app.media.broadcast_listen'))
.width(12)
.height(12)
.margin({right: 4})
Text('0')
.fontSize($r('app.float.font_size_12'))
.fontColor($r('app.color.color_999999'))
.margin({ right :24})
}
.width(CommonConstants.FULL_WIDTH)
}
.layoutWeight(1)
}
.onClick((event: ClickEvent) => {
// TODO 跳转到音频专题页
})
.width(CommonConstants.FULL_WIDTH)
.height(73)
}
}
\ No newline at end of file
... ...
... ... @@ -213,4 +213,29 @@ export class PageRepository {
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.get<ResponseDTO<CompInfoBean>>(url, headers)
};
}
\ No newline at end of file
/**
* 获取播报pageInfo
* */
static fetchBroadcastPageInfo(pageId: string) {
let url = PageRepository.getMorningEveningPageInfoUrl(pageId)
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.get<ResponseDTO<PageInfoBean>>(url, headers)
};
/**
* 获取播报compInfo
* https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/compInfo
* @param params
* @returns
* */
static fetchBroadcastCompInfo(pageId: number, groupId: number, refreshTime: string, topicId:
string, channelId: string) {
HttpUrlUtils.hostUrl = HttpUrlUtils.HOST_DEV
let url = HttpUrlUtils.getHost() + HttpUrlUtils.MORNING_EVENING_COMP_INFO_PATH;
url = `${url}?topicId=${topicId}&channelStrategy=2&groupId=${groupId}&refreshTime=${refreshTime}&pageSize=50&recommend=0&pageId=${pageId}&loadStrategy=first_load&pageNum=1&channelId=${channelId}`
Logger.info(TAG, "getMorningEveningCompInfoUrl url = " + url)
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.get<ResponseDTO<CompInfoBean>>(url, headers)
};
}
... ...
import { CompInfoBean, PageInfoBean } from 'wdBean/Index';
import { Logger } from 'wdKit/Index';
import { ResponseDTO } from 'wdNetwork/Index';
import { PageRepository } from '../repository/PageRepository';
const TAG = 'BroadcastViewModel'
export class BroadcastViewModel {
static async getBroadcastViewPageInfo(pageId: string): Promise<PageInfoBean> {
return new Promise<PageInfoBean>((success, error) => {
Logger.info(TAG, `getBroadcastViewPageInfo pageInfo start`);
PageRepository.fetchMorningEveningPageInfo(pageId).then((resDTO: ResponseDTO<PageInfoBean>) => {
if (!resDTO || !resDTO.data) {
Logger.error(TAG, 'getBroadcastViewPageInfo then navResDTO is empty');
error('resDTO is empty');
return
}
if (resDTO.code != 0) {
Logger.error(TAG, `getBroadcastViewPageInfo then code:${resDTO.code}, message:${resDTO.message}`);
error('resDTO Response Code is failure');
return
}
// let navResStr = JSON.stringify(navResDTO);
Logger.info(TAG, "getBroadcastViewPageInfo then,navResDTO.timestamp:" + resDTO.timestamp);
success(resDTO.data);
}).catch((err: Error) => {
Logger.error(TAG, `getBroadcastViewPageInfo catch, error.name : ${err.name}, error.message:${err.message}`);
error(err);
})
})
}
// 获取播报组件信息:https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/compInfo?topicId=&
// channelStrategy=2&groupId=30113&refreshTime=1712023953772&pageSize=50&recommend=0&pageId=21003&loadStrategy=first_load&pageNum=1&channelId=2066
static async getBroadcastCompInfo(pageId: number, groupId: number, refreshTime: string, topicId: string, channelId: string): Promise<CompInfoBean> {
return new Promise<CompInfoBean>((success, error) => {
Logger.info(TAG, `getMorningEveningCompInfo pageInfo start`);
PageRepository.fetchBroadcastCompInfo(pageId, groupId, refreshTime, topicId, channelId)
.then((resDTO: ResponseDTO<CompInfoBean>) => {
if (!resDTO || !resDTO.data) {
Logger.error(TAG, 'getMorningEveningCompInfo then navResDTO is empty');
error('resDTO is empty');
return
}
if (resDTO.code != 0) {
Logger.error(TAG, `getMorningEveningCompInfo then code:${resDTO.code}, message:${resDTO.message}`);
error('resDTO Response Code is failure');
return
}
// let navResStr = JSON.stringify(navResDTO);
Logger.info(TAG, "getMorningEveningCompInfo then,navResDTO.timestamp:" + resDTO.timestamp);
success(resDTO.data);
})
.catch((err: Error) => {
Logger.error(TAG, `getMorningEveningCompInfo catch, error.name : ${err.name}, error.message:${err.message}`);
error(err);
})
})
}
}
\ No newline at end of file
... ...
import { BroadcastPageComponent } from 'wdComponent';
import { Logger } from 'wdKit';
const TAG = 'BroadcastPageComponent';
@Entry
@Component
struct BroadcastPage {
build() {
Column() {
BroadcastPageComponent()
}
}
pageTransition() {
// 定义页面进入时的效果,从底侧滑入
PageTransitionEnter({ type: RouteType.None, duration: 300 })
.slide(SlideEffect.Bottom)
// 定义页面退出时的效果,向底侧滑出
PageTransitionExit({ type: RouteType.None, duration: 300 })
.slide(SlideEffect.Bottom)
}
aboutToAppear() {
Logger.info(TAG, 'aboutToAppear');
}
aboutToDisappear() {
Logger.info(TAG, 'aboutToDisappear');
}
onPageShow() {
Logger.info(TAG, 'onPageShow');
}
onPageHide() {
Logger.info(TAG, 'onPageHide');
}
onBackPress() {
Logger.info(TAG, 'onBackPress');
}
}
\ No newline at end of file
... ...
... ... @@ -9,6 +9,7 @@
"pages/detail/MultiPictureDetailPage",
"pages/launchPage/PrivacyPage",
"pages/launchPage/LaunchPage",
"pages/launchPage/LaunchAdvertisingPage"
"pages/launchPage/LaunchAdvertisingPage",
"pages/broadcast/BroadcastPage"
]
}
... ...