wangliang_wd

Merge branch 'main' of http://192.168.1.42/developOne/harmonyPool into main

* 'main' of http://192.168.1.42/developOne/harmonyPool:
  fix: 18659 人民号动态图文稿件丢失评论入口
  feat: 1)搭建普通信息流模板组件,可支持不用业务接口实现通用组件和稿件展示业务数据; 2)直播列表页面改造成使用通用模板组件
  功能缺陷-【uat】进入视频直播,点击暂停进度条未显示
  ref |> 解决动态详情页首次进入时跳转评论区问题
  ref |> 解决从精选评论、我的评论进入对应文章稿件详情时,自动跳转至稿件详情评论区问题
  功能缺陷-【生产】进入视频直播,点击头像,预期有提示“暂时无法查看该创作者主页”,实际没有
  fix: 18344 【UAT】【组件卡片】横滑卡配置的视频稿件,客户端没有展示标题,且封面图位置展示不正确
  功能缺陷--视频稿件下仅WiFi下自动播放视频功能未实现
  fix: 18738 必修--人民号单图卡-三行标题位置超出分割线
Showing 33 changed files with 913 additions and 504 deletions
@@ -84,4 +84,9 @@ export const enum CompStyle { @@ -84,4 +84,9 @@ export const enum CompStyle {
84 Card_Comp_Adv = 'card_comp_adv', // 信息流广告稿件 84 Card_Comp_Adv = 'card_comp_adv', // 信息流广告稿件
85 85
86 Card_Comp_Zh_Grid_Layout_02 = 'Card_Comp_Zh_Grid_Layout-02', // 一行两列卡业务内容 86 Card_Comp_Zh_Grid_Layout_02 = 'Card_Comp_Zh_Grid_Layout-02', // 一行两列卡业务内容
  87 +
  88 + Card_Comp_Live_Big_Image_01 = 'card_comp_live_sub_big_image_01', // 直播预约大图卡
  89 +
  90 + Card_Comp_Live_Big_Image_02 = 'card_comp_live_sub_big_image_02' // 直播大图卡
  91 +
87 } 92 }
@@ -163,7 +163,8 @@ export class ProcessUtils { @@ -163,7 +163,8 @@ export class ProcessUtils {
163 extra: { 163 extra: {
164 relType: content?.relType, 164 relType: content?.relType,
165 relId: content?.relId, 165 relId: content?.relId,
166 - } as ExtraDTO 166 + } as ExtraDTO,
  167 + targetLayout: content.customParamTargetLayout
167 } as Params, 168 } as Params,
168 }; 169 };
169 WDRouterRule.jumpWithAction(taskAction) 170 WDRouterRule.jumpWithAction(taskAction)
@@ -232,7 +233,8 @@ export class ProcessUtils { @@ -232,7 +233,8 @@ export class ProcessUtils {
232 relId: content?.relId, 233 relId: content?.relId,
233 channelId: content?.channelId, 234 channelId: content?.channelId,
234 pageId: content?.pageId 235 pageId: content?.pageId
235 - } as ExtraDTO 236 + } as ExtraDTO,
  237 + targetLayout: content.customParamTargetLayout
236 } as Params, 238 } as Params,
237 }; 239 };
238 WDRouterRule.jumpWithAction(taskAction) 240 WDRouterRule.jumpWithAction(taskAction)
@@ -300,7 +302,8 @@ export class ProcessUtils { @@ -300,7 +302,8 @@ export class ProcessUtils {
300 channelId: content?.channelId, 302 channelId: content?.channelId,
301 sourcePage: '5', 303 sourcePage: '5',
302 commentId: content?.commentInfo?.commentId 304 commentId: content?.commentInfo?.commentId
303 - } as ExtraDTO 305 + } as ExtraDTO,
  306 + targetLayout: content.customParamTargetLayout
304 } as Params, 307 } as Params,
305 }; 308 };
306 WDRouterRule.jumpWithAction(taskAction) 309 WDRouterRule.jumpWithAction(taskAction)
@@ -316,7 +319,8 @@ export class ProcessUtils { @@ -316,7 +319,8 @@ export class ProcessUtils {
316 extra: { 319 extra: {
317 relType: content?.relType, 320 relType: content?.relType,
318 relId: content?.relId, 321 relId: content?.relId,
319 - } as ExtraDTO 322 + } as ExtraDTO,
  323 + targetLayout: content.customParamTargetLayout
320 } as Params, 324 } as Params,
321 }; 325 };
322 WDRouterRule.jumpWithAction(taskAction) 326 WDRouterRule.jumpWithAction(taskAction)
@@ -352,7 +356,8 @@ export class ProcessUtils { @@ -352,7 +356,8 @@ export class ProcessUtils {
352 extra: { 356 extra: {
353 relType: content?.relType, 357 relType: content?.relType,
354 relId: content?.relId, 358 relId: content?.relId,
355 - } as ExtraDTO 359 + } as ExtraDTO,
  360 + targetLayout: content.customParamTargetLayout
356 } as Params, 361 } as Params,
357 }; 362 };
358 WDRouterRule.jumpWithAction(taskAction) 363 WDRouterRule.jumpWithAction(taskAction)
@@ -394,7 +399,8 @@ export class ProcessUtils { @@ -394,7 +399,8 @@ export class ProcessUtils {
394 extra: { 399 extra: {
395 relType: content?.relType, 400 relType: content?.relType,
396 relId: content?.relId, 401 relId: content?.relId,
397 - } as ExtraDTO 402 + } as ExtraDTO,
  403 + targetLayout: content.customParamTargetLayout
398 } as Params, 404 } as Params,
399 }; 405 };
400 WDRouterRule.jumpWithAction(taskAction) 406 WDRouterRule.jumpWithAction(taskAction)
@@ -116,6 +116,9 @@ export class ContentDTO implements BaseDTO { @@ -116,6 +116,9 @@ export class ContentDTO implements BaseDTO {
116 timeBlurred:number = 0 116 timeBlurred:number = 0
117 top:number = 0 117 top:number = 0
118 118
  119 + // 自定义参数,用于跳转对应页面时 传递targetLayout参数用
  120 + customParamTargetLayout?: string
  121 +
119 static clone(old: ContentDTO): ContentDTO { 122 static clone(old: ContentDTO): ContentDTO {
120 let content = new ContentDTO(); 123 let content = new ContentDTO();
121 content.liveType = old.liveType; 124 content.liveType = old.liveType;
@@ -24,4 +24,6 @@ export interface Params { @@ -24,4 +24,6 @@ export interface Params {
24 videoCoverUrl?: string; 24 videoCoverUrl?: string;
25 pageId?: string; 25 pageId?: string;
26 backVisibility?: boolean; //展示顶部返回栏 26 backVisibility?: boolean; //展示顶部返回栏
  27 +
  28 + targetLayout?: string; // "comment" 表示进入对应页面后,跳转至评论区
27 } 29 }
@@ -18,6 +18,7 @@ import { Card21Component } from './cardview/Card21Component'; @@ -18,6 +18,7 @@ import { Card21Component } from './cardview/Card21Component';
18 import { SearchContentComponent } from './cardview/SearchContentComponent'; 18 import { SearchContentComponent } from './cardview/SearchContentComponent';
19 import { DateTimeUtils } from 'wdKit/Index'; 19 import { DateTimeUtils } from 'wdKit/Index';
20 import { TrackConstants, TrackingPageBrowse } from 'wdTracking/Index'; 20 import { TrackConstants, TrackingPageBrowse } from 'wdTracking/Index';
  21 +import { LiveBigImage02Component } from './cardview/LiveBigImage02Component';
21 22
22 /** 23 /**
23 * card适配器,卡片样式汇总,依据ContentDTO#appStyle 24 * card适配器,卡片样式汇总,依据ContentDTO#appStyle
@@ -89,7 +90,9 @@ export struct CardParser { @@ -89,7 +90,9 @@ export struct CardParser {
89 Card20Component({ contentDTO, compDTO: this.compDTO, pageId: this.pageId, pageName: this.pageName }) 90 Card20Component({ contentDTO, compDTO: this.compDTO, pageId: this.pageId, pageName: this.pageName })
90 } else if (contentDTO.appStyle === CompStyle.Card_21) { 91 } else if (contentDTO.appStyle === CompStyle.Card_21) {
91 Card21Component({ contentDTO, compDTO: this.compDTO, pageId: this.pageId, pageName: this.pageName }) 92 Card21Component({ contentDTO, compDTO: this.compDTO, pageId: this.pageId, pageName: this.pageName })
92 - } else { 93 + } else if (contentDTO.appStyle === CompStyle.Card_Comp_Live_Big_Image_02) {
  94 + LiveBigImage02Component({ contentDTO:contentDTO, compDTO: this.compDTO, pageId: this.pageId, pageName: this.pageName })
  95 + }else {
93 // todo:组件未实现 / Component Not Implemented 96 // todo:组件未实现 / Component Not Implemented
94 // Text(contentDTO.appStyle) 97 // Text(contentDTO.appStyle)
95 // .width(CommonConstants.FULL_PARENT) 98 // .width(CommonConstants.FULL_PARENT)
@@ -60,7 +60,7 @@ export struct CarderInteraction { @@ -60,7 +60,7 @@ export struct CarderInteraction {
60 }) 60 })
61 } 61 }
62 62
63 - if(this.contentDetailData?.openComment == 1){ 63 + if(this.contentDetailData?.openComment == 1 || router.getState().name === 'PeopleShipHomePage'){
64 this.commentLayout() 64 this.commentLayout()
65 } 65 }
66 this.builderLike() 66 this.builderLike()
@@ -79,8 +79,6 @@ export struct CompParser { @@ -79,8 +79,6 @@ export struct CompParser {
79 @Builder 79 @Builder
80 componentBuilder() { 80 componentBuilder() {
81 81
82 - //CardParser({ contentDTO: this.compDTO.operDataList[0], compDTO:this.compDTO })  
83 -  
84 if (this.compDTO.operDataList[0]?.objectType !== '3' && 82 if (this.compDTO.operDataList[0]?.objectType !== '3' &&
85 this.compDTO.operDataList[0]?.objectType !== '13') { //暂时屏蔽活动和音频详情入口 83 this.compDTO.operDataList[0]?.objectType !== '13') { //暂时屏蔽活动和音频详情入口
86 if (this.compDTO.compStyle === CompStyle.Label_03) { 84 if (this.compDTO.compStyle === CompStyle.Label_03) {
@@ -171,7 +169,7 @@ export struct CompParser { @@ -171,7 +169,7 @@ export struct CompParser {
171 AdvCardParser({ pageModel: this.pageModel, compDTO: this.compDTO }) 169 AdvCardParser({ pageModel: this.pageModel, compDTO: this.compDTO })
172 //Text(`compIndex = ${compIndex}`).width('100%').fontSize('12fp').fontColor(Color.Red).padding({ left: 0, right: 0 }) 170 //Text(`compIndex = ${compIndex}`).width('100%').fontSize('12fp').fontColor(Color.Red).padding({ left: 0, right: 0 })
173 Divider().strokeWidth(1).color('#f5f5f5').padding({ left: 16, right: 16 }) 171 Divider().strokeWidth(1).color('#f5f5f5').padding({ left: 16, right: 16 })
174 - } else if (!Number.isNaN(Number(this.compDTO.compStyle))) { 172 + } else if (!Number.isNaN(Number(this.compDTO.compStyle)) || this.compDTO.compType === 'appStyle') {
175 CardParser({ contentDTO: this.compDTO.operDataList[0], compDTO: this.compDTO, pageId: this.pageId, pageName: this.pageName }); 173 CardParser({ contentDTO: this.compDTO.operDataList[0], compDTO: this.compDTO, pageId: this.pageId, pageName: this.pageName });
176 Divider().strokeWidth(1).color('#f5f5f5').padding({ left: 16, right: 16 }) 174 Divider().strokeWidth(1).color('#f5f5f5').padding({ left: 16, right: 16 })
177 } else { 175 } else {
@@ -17,6 +17,7 @@ import { @@ -17,6 +17,7 @@ import {
17 batchLikeAndCollectResult, 17 batchLikeAndCollectResult,
18 RmhInfoDTO, 18 RmhInfoDTO,
19 InteractDataDTO, 19 InteractDataDTO,
  20 + Action,
20 } from 'wdBean'; 21 } from 'wdBean';
21 import media from '@ohos.multimedia.media'; 22 import media from '@ohos.multimedia.media';
22 import { OperRowListView } from './view/OperRowListView'; 23 import { OperRowListView } from './view/OperRowListView';
@@ -56,9 +57,7 @@ const PATTERN_DATE_CN_RN: string = 'yyyy年MM月dd日 HH:mm'; @@ -56,9 +57,7 @@ const PATTERN_DATE_CN_RN: string = 'yyyy年MM月dd日 HH:mm';
56 @Component 57 @Component
57 export struct DynamicDetailComponent { 58 export struct DynamicDetailComponent {
58 //入参 59 //入参
59 - private relId: string = ''  
60 - private contentId: string = ''  
61 - private relType: string = '' 60 + action: Action = {} as Action
62 //出参 61 //出参
63 @Provide contentDetailData: ContentDetailDTO = {} as ContentDetailDTO 62 @Provide contentDetailData: ContentDetailDTO = {} as ContentDetailDTO
64 //UI 63 //UI
@@ -82,6 +81,8 @@ export struct DynamicDetailComponent { @@ -82,6 +81,8 @@ export struct DynamicDetailComponent {
82 @State openLikes: boolean = false // 是否可以点赞 1:可以 0:不可以 81 @State openLikes: boolean = false // 是否可以点赞 1:可以 0:不可以
83 82
84 pageParam: ParamType = {} 83 pageParam: ParamType = {}
  84 + commentListAreaInfo?: Area
  85 + lastTimeoutId?: number
85 86
86 // @Provide bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0 87 // @Provide bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
87 @Provide topSafeHeight: number = AppStorage.get<number>('topSafeHeight') || 0 88 @Provide topSafeHeight: number = AppStorage.get<number>('topSafeHeight') || 0
@@ -553,6 +554,12 @@ export struct DynamicDetailComponent { @@ -553,6 +554,12 @@ export struct DynamicDetailComponent {
553 CommentComponent({ 554 CommentComponent({
554 publishCommentModel: this.publishCommentModel 555 publishCommentModel: this.publishCommentModel
555 }) 556 })
  557 + .id("comment")
  558 + .onAreaChange((oldValue: Area, newValue: Area) => {
  559 + this.commentListAreaInfo = newValue
  560 + this.checkToScrollCommentArea()
  561 + })
  562 +
556 } 563 }
557 Blank().layoutWeight(1) 564 Blank().layoutWeight(1)
558 } 565 }
@@ -587,7 +594,10 @@ export struct DynamicDetailComponent { @@ -587,7 +594,10 @@ export struct DynamicDetailComponent {
587 private async getContentDetailData() { 594 private async getContentDetailData() {
588 this.isNetConnected = NetworkUtil.isNetConnected() 595 this.isNetConnected = NetworkUtil.isNetConnected()
589 try { 596 try {
590 - let data = await MultiPictureDetailViewModel.getDetailData(this.relId, this.contentId, this.relType) 597 + const relId = this.action.params?.extra?.relId || '';
  598 + const relType = this.action.params?.extra?.relType || '';
  599 + const contentId = this.action.params?.contentID || '';
  600 + let data = await MultiPictureDetailViewModel.getDetailData(relId, contentId, relType)
591 this.isPageEnd = true; 601 this.isPageEnd = true;
592 this.contentDetailData = data[0]; 602 this.contentDetailData = data[0];
593 let dateTime = 603 let dateTime =
@@ -804,6 +814,29 @@ export struct DynamicDetailComponent { @@ -804,6 +814,29 @@ export struct DynamicDetailComponent {
804 let context = getContext(this) as common.UIAbilityContext; 814 let context = getContext(this) as common.UIAbilityContext;
805 viewBlogItemInsightIntentShare(context,this.contentDetailData, this.interactDataDTO) 815 viewBlogItemInsightIntentShare(context,this.contentDetailData, this.interactDataDTO)
806 } 816 }
  817 +
  818 + checkToScrollCommentArea() {
  819 + if (!this.commentListAreaInfo) {
  820 + // 需要评论区位置,调用前 请确保它有值
  821 + return
  822 + }
  823 + if (this.action.params?.targetLayout && this.action.params.targetLayout == "comment") {
  824 + if (this.lastTimeoutId) {
  825 + clearTimeout(this.lastTimeoutId)
  826 + }
  827 + this.lastTimeoutId = setTimeout(() => {
  828 + let offSetY = this.commentListAreaInfo?.globalPosition.y as number
  829 + Logger.debug(TAG, "即将滚动至yOffset: " + (offSetY - 100))
  830 + //头部距离48
  831 + this.scroller.scrollTo({
  832 + yOffset: offSetY - 100,
  833 + xOffset: 0,
  834 + animation: { duration: 1000, curve: Curve.Ease }
  835 + })
  836 + this.action.params!.targetLayout = undefined
  837 + }, 600)
  838 + }
  839 + }
807 } 840 }
808 841
809 interface radiusType { 842 interface radiusType {
@@ -66,6 +66,7 @@ export struct ImageAndTextPageComponent { @@ -66,6 +66,7 @@ export struct ImageAndTextPageComponent {
66 @State offsetY: number = 0 66 @State offsetY: number = 0
67 pageShowTime:number = 0; 67 pageShowTime:number = 0;
68 pageHideTime:number = 0; 68 pageHideTime:number = 0;
  69 + lastTimeoutId?: number
69 70
70 onPageShow() { 71 onPageShow() {
71 this.pageShowTime = DateTimeUtils.getTimeStamp() 72 this.pageShowTime = DateTimeUtils.getTimeStamp()
@@ -152,6 +153,8 @@ export struct ImageAndTextPageComponent { @@ -152,6 +153,8 @@ export struct ImageAndTextPageComponent {
152 153
153 .onAreaChange((oldValue: Area, newValue: Area) => { 154 .onAreaChange((oldValue: Area, newValue: Area) => {
154 this.info = newValue 155 this.info = newValue
  156 +
  157 + this.checkToScrollCommentArea()
155 }) 158 })
156 // .onMeasureSize() 159 // .onMeasureSize()
157 160
@@ -413,6 +416,7 @@ export struct ImageAndTextPageComponent { @@ -413,6 +416,7 @@ export struct ImageAndTextPageComponent {
413 if (this.info) { 416 if (this.info) {
414 // let height = DisplayUtils.getDeviceHeight() / 2 417 // let height = DisplayUtils.getDeviceHeight() / 2
415 let offSetY = this.info?.globalPosition.y as number 418 let offSetY = this.info?.globalPosition.y as number
  419 + Logger.debug(TAG, "滚动至yOffset: " + (offSetY - 100))
416 //头部距离48 420 //头部距离48
417 this.scroller.scrollTo({ 421 this.scroller.scrollTo({
418 yOffset: offSetY - 100, 422 yOffset: offSetY - 100,
@@ -427,4 +431,27 @@ export struct ImageAndTextPageComponent { @@ -427,4 +431,27 @@ export struct ImageAndTextPageComponent {
427 431
428 aboutToDisappear() { 432 aboutToDisappear() {
429 } 433 }
  434 +
  435 + checkToScrollCommentArea() {
  436 + if (!this.info) {
  437 + // 需要评论区位置,调用前 请确保它有值
  438 + return
  439 + }
  440 + if (this.action.params?.targetLayout && this.action.params.targetLayout == "comment") {
  441 + if (this.lastTimeoutId) {
  442 + clearTimeout(this.lastTimeoutId)
  443 + }
  444 + this.lastTimeoutId = setTimeout(() => {
  445 + let offSetY = this.info?.globalPosition.y as number
  446 + Logger.debug(TAG, "即将滚动至yOffset: " + (offSetY - 100))
  447 + //头部距离48
  448 + this.scroller.scrollTo({
  449 + yOffset: offSetY - 100,
  450 + xOffset: 0,
  451 + animation: { duration: 1000, curve: Curve.Ease }
  452 + })
  453 + this.action.params!.targetLayout = undefined
  454 + }, 600)
  455 + }
  456 + }
430 } 457 }
@@ -109,7 +109,8 @@ export struct Card6Component { @@ -109,7 +109,8 @@ export struct Card6Component {
109 } 109 }
110 110
111 .alignItems(HorizontalAlign.Start) 111 .alignItems(HorizontalAlign.Start)
112 - .height(this.contentDTO.appStyle === CompStyle.Card_13 ? 78 : 156) 112 + .height(this.contentDTO.appStyle === CompStyle.Card_13 ? '' : 156)
  113 + .constraintSize({minHeight: 78})
113 .justifyContent(FlexAlign.SpaceBetween) 114 .justifyContent(FlexAlign.SpaceBetween)
114 .width('64%') 115 .width('64%')
115 116
  1 +import { CompDTO, ContentDTO } from 'wdBean';
  2 +import { ProcessUtils } from 'wdRouter';
  3 +import { onlyWifiLoadImg } from '../../utils/lazyloadImg';
  4 +import { hasClicked, persistentStorage } from '../../utils/persistentStorage';
  5 +import { SearchShowRed, textItem, titleInitRes } from '../../utils/searchShowRed';
  6 +import { DateTimeUtils } from 'wdKit/Index';
  7 +import { LottieView } from '../lottie/LottieView';
  8 +import { router } from '@kit.ArkUI';
  9 +
  10 +const TAG: string = 'Card6Component-Card13Component';
  11 +
  12 +/**
  13 + * 本地样式卡:直播大图卡
  14 + */
  15 +@Component
  16 +export struct LiveBigImage02Component {
  17 + @ObjectLink compDTO: CompDTO
  18 + @State pageId: string = '';
  19 + @State pageName: string = '';
  20 + @State contentDTO: ContentDTO = new ContentDTO();
  21 + @State loadImg: boolean = false;
  22 + @State clicked: boolean = false;
  23 +
  24 + async aboutToAppear() {
  25 + const curRouter = router.getState().name;
  26 + this.clicked = hasClicked(this.contentDTO.objectId,curRouter)
  27 + this.loadImg = await onlyWifiLoadImg();
  28 + }
  29 +
  30 +
  31 + build() {
  32 + Column() {
  33 + Text(this.contentDTO.newsTitle)
  34 + .fontSize(18)
  35 + .maxLines(2)
  36 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  37 + .margin({ top: 16, bottom: 8 })
  38 + .alignSelf(ItemAlign.Start)
  39 + .fontColor(this.clicked ? 0x848484 : $r('app.color.color_222222'))
  40 +
  41 + Stack() {
  42 + if (this.contentDTO.fullColumnImgUrls && this.contentDTO.fullColumnImgUrls.length > 0) {
  43 + Image(this.contentDTO.fullColumnImgUrls[0].url)//
  44 + .backgroundColor(this.loadImg ? $r('app.color.color_B0B0B0') : 0xf5f5f5)
  45 + .width('100%')
  46 + .aspectRatio(16 / 9)
  47 + .borderRadius(4)
  48 + .borderWidth(0.5)
  49 + .borderColor($r('app.color.color_0D000000'))
  50 + }
  51 + this.LiveImage(this.contentDTO)
  52 + }
  53 + .alignContent(Alignment.BottomEnd)
  54 +
  55 + Row() {
  56 + if (this.contentDTO.rmhInfo && this.contentDTO.rmhInfo.rmhName) {
  57 + Text(this.contentDTO.rmhInfo.rmhName)
  58 + .fontSize(12)
  59 + .fontWeight(400)
  60 + .fontColor($r('app.color.color_B0B0B0'))
  61 + .fontFamily('PingFang SC-Medium')
  62 + .maxLines(1)
  63 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  64 + .align(Alignment.Start)
  65 +
  66 + Image($r('app.media.point_live_icon'))
  67 + .objectFit(ImageFit.Auto)
  68 + .interpolation(ImageInterpolation.High)
  69 + .width(16)
  70 + .height(16)
  71 + .margin(2)
  72 + }
  73 +
  74 + Text(DateTimeUtils.getCommentTime(Number.parseFloat(this.contentDTO.publishTimestamp)))
  75 + .fontSize(12)
  76 + .maxLines(1)
  77 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  78 + .align(Alignment.Start)
  79 + .width('100%')
  80 + .fontColor($r('app.color.color_B0B0B0'))
  81 + }
  82 + .margin({ top: 8, bottom: 8 })
  83 +
  84 + }
  85 + .width('100%')
  86 + .padding({
  87 + left: $r('app.float.card_comp_pagePadding_lf'),
  88 + right: $r('app.float.card_comp_pagePadding_lf'),
  89 + })
  90 + .onClick(() => {
  91 + this.clicked = true;
  92 + persistentStorage(this.contentDTO.objectId);
  93 + ProcessUtils.processPage(this.contentDTO)
  94 + })
  95 + }
  96 +
  97 + @Builder
  98 + LiveImage(item: ContentDTO) {
  99 + Row() {
  100 + LottieView({
  101 + name: 'live_status_wait',
  102 + path: "lottie/live_detail_living.json",
  103 + lottieWidth: 14,
  104 + lottieHeight: 14,
  105 + autoplay: true,
  106 + loop: true,
  107 + title: item.newsTitle
  108 + })
  109 + .margin({
  110 + right: '2vp'
  111 + })
  112 +
  113 + Text('直播中')
  114 + .fontSize('12vp')
  115 + .fontWeight(400)
  116 + .fontColor(Color.White)
  117 + .textShadow({
  118 + radius: 2,
  119 + color: 'rgba(0,0,0,0.3)',
  120 + offsetX: 0,
  121 + offsetY: 2
  122 + })
  123 + .margin({
  124 + right: '5vp'
  125 + })
  126 +
  127 + Image($r('app.media.icon_comp_line_live')).height('11vp').width('1.5vp')
  128 +
  129 + if (this.getLiveRoomNumber(this.compDTO.operDataList[0]).length > 0) {
  130 + Text(this.getLiveRoomNumber(this.compDTO.operDataList[0]))
  131 + .fontSize('12vp')
  132 + .fontWeight(400)
  133 + .textShadow({
  134 + radius: 2,
  135 + color: 'rgba(0,0,0,0.3)',
  136 + offsetX: 0,
  137 + offsetY: 2
  138 + })
  139 + .fontColor(Color.White)
  140 + .margin({
  141 + left: '5vp'
  142 + })
  143 + }
  144 +
  145 + }
  146 + .justifyContent(FlexAlign.End)
  147 + .margin({ right: 8, bottom: 8 })
  148 + }
  149 +
  150 + // 判断是否预约
  151 + getLiveRoomNumber(item: ContentDTO): string {
  152 + const objc = item.liveRoomDataBean
  153 + if (objc && objc.pv && objc.pv > 0) {
  154 + return this.computeShowNum(objc.pv)
  155 + }
  156 + return ''
  157 + }
  158 +
  159 + private computeShowNum(count: number): string {
  160 + if (count >= 10000) {
  161 + let num = (count / 10000).toFixed(1)
  162 + if (Number(num.substring(num.length - 1)) == 0) {
  163 + num = num.substring(0, num.length - 2)
  164 + }
  165 + return num + '万人参加'
  166 + }
  167 + return `${count}人参加`
  168 + }
  169 +}
@@ -498,6 +498,7 @@ struct QualityCommentItem { @@ -498,6 +498,7 @@ struct QualityCommentItem {
498 content.relType = this.item.targetRelType; 498 content.relType = this.item.targetRelType;
499 content.pageId = this.item.pageId; 499 content.pageId = this.item.pageId;
500 content.linkUrl = this.item.h5Url; 500 content.linkUrl = this.item.h5Url;
  501 + content.customParamTargetLayout = "comment"
501 ProcessUtils.processPage(content) 502 ProcessUtils.processPage(content)
502 } 503 }
503 504
@@ -93,6 +93,7 @@ export struct HomePageBottomCommentComponent { @@ -93,6 +93,7 @@ export struct HomePageBottomCommentComponent {
93 .onClick(()=>{ 93 .onClick(()=>{
94 let content = getParams(item) 94 let content = getParams(item)
95 TrackingContent.common(TrackConstants.EventType.Click,TrackConstants.PageName.Main_Personal,TrackConstants.PageName.Main_Personal,TrackParamConvert.program(content)) 95 TrackingContent.common(TrackConstants.EventType.Click,TrackConstants.PageName.Main_Personal,TrackConstants.PageName.Main_Personal,TrackParamConvert.program(content))
  96 + content.customParamTargetLayout = "comment"
96 ProcessUtils.processPage(content) 97 ProcessUtils.processPage(content)
97 }) 98 })
98 .onVisibleAreaChange([0.0, 1.0], (isVisible: boolean, currentRatio: number) => { 99 .onVisibleAreaChange([0.0, 1.0], (isVisible: boolean, currentRatio: number) => {
  1 +import { router } from '@kit.ArkUI'
  2 +
  3 +/**
  4 + * 常见的标题
  5 + */
  6 +@Component
  7 +export default struct CommonPageTitle {
  8 +
  9 + // 标题名称
  10 + @State title:string = ''
  11 +
  12 + build() {
  13 +
  14 + RelativeContainer() {
  15 + //标题栏目
  16 + Image($r('app.media.icon_arrow_left'))
  17 + .width(24)
  18 + .height(24)
  19 + .objectFit(ImageFit.Auto)
  20 + .id("back_icon")
  21 + .alignRules({
  22 + center: { anchor: "__container__", align: VerticalAlign.Center },
  23 + left: { anchor: "__container__", align: HorizontalAlign.Start }
  24 + })
  25 + .onClick(() => {
  26 + router.back()
  27 + })
  28 +
  29 + Text(this.title)
  30 + .maxLines(1)
  31 + .id("title")
  32 + .fontSize('18vp')
  33 + .fontWeight(400)
  34 + .fontColor($r('app.color.color_222222'))
  35 + .lineHeight('22vp')
  36 + .alignRules({
  37 + center: { anchor: "__container__", align: VerticalAlign.Center },
  38 + middle: { anchor: "__container__", align: HorizontalAlign.Center }
  39 + })
  40 + }
  41 + .height(44)
  42 + .padding({
  43 + left: $r('app.float.card_comp_pagePadding_lf'),
  44 + right: $r('app.float.card_comp_pagePadding_lf'),
  45 + })
  46 + .width('100%')
  47 + }
  48 +}
1 -import { ContentDTO, LiveRoomDataBean } from 'wdBean';  
2 -import { ProcessUtils } from 'wdRouter';  
3 -import PageViewModel from '../../viewmodel/PageViewModel';  
4 -import { DateTimeUtils, LazyDataSource, Logger, NetworkUtil } from 'wdKit/Index';  
5 -import { router } from '@kit.ArkUI';  
6 -import { ViewType } from 'wdConstant/src/main/ets/enum/ViewType';  
7 -import { CustomPullToRefresh } from '../reusable/CustomPullToRefresh';  
8 -import { PeopleShipNoMoreData } from '../reusable/PeopleShipNoMoreData';  
9 -import { EmptyComponent, WDViewDefaultType } from '../view/EmptyComponent';  
10 -import { ErrorComponent } from '../view/ErrorComponent';  
11 -import LoadMoreLayout from '../page/LoadMoreLayout';  
12 -import { LottieView } from '../../components/lottie/LottieView';  
13 -import dataPreferences from '@ohos.data.preferences';  
14 -import { BusinessError } from '@ohos.base';  
15 -import { onlyWifiLoadImg } from '../../utils/lazyloadImg';  
16 -import { channelSkeleton } from '../skeleton/channelSkeleton'; 1 +import CommonPageTitle from './CommonPageTitle';
  2 +import TemplatePageComponent from './template/TemplatePageComponent';
  3 +import { TemplatePageConstant } from './template/TemplatePageConstant';
17 4
18 -const TAG: string = 'LiveMorePage';  
19 -  
20 -const PREFERENCES_NAME = 'rmrLiveMorePage.db'  
21 -let preferenceTheme: dataPreferences.Preferences | null = null  
22 5
23 /** 6 /**
24 - * 直播更多:  
25 - * type=1 直播  
26 - * type=2 预约  
27 - * 卡片结构:上下结构  
28 - * 卡片宽度:充满父窗口  
29 - * 卡片高度,仅包含横板图片:图片高度由图片的宽度及宽高比决定,图片宽度占父窗口'100%',宽高比为16:9: 7 + * 直播列表
30 */ 8 */
31 @Entry 9 @Entry
32 @Component 10 @Component
33 struct LiveMorePage { 11 struct LiveMorePage {
34 - @State data: LazyDataSource<ContentDTO> = new LazyDataSource(); 12 +
35 @State topSafeHeight: number = AppStorage.get<number>('topSafeHeight') as number; 13 @State topSafeHeight: number = AppStorage.get<number>('topSafeHeight') as number;
  14 +
36 @State bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0 15 @State bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
37 - type: number = 1;  
38 - pageSize: number = 20;  
39 - operDataList: ContentDTO[] = [];  
40 - title: string = '直播列表'  
41 - @State contentDTO: ContentDTO = new ContentDTO();  
42 - @State private hasMore: boolean = true  
43 - @State private currentPage: number = 1  
44 - @State private isLoading: boolean = false  
45 - private scroller: Scroller = new Scroller()  
46 - @State liveRoomList: LiveRoomDataBean[] = []  
47 - // 点击过的数据  
48 - @State clickDatas: Array<string> = []  
49 - @State loadImg: boolean = false;  
50 - @State viewType: ViewType = ViewType.LOADING  
51 - emptyType: WDViewDefaultType = WDViewDefaultType.WDViewDefaultType_Default  
52 16
53 - async aboutToAppear(): Promise<void> {  
54 - await this.getPreferencesFromStorage()  
55 - this.loadImg = await onlyWifiLoadImg();  
56 - this.getLivMoreClickPreference()  
57 - Logger.debug(TAG, '数据:' + JSON.stringify(this.clickDatas))  
58 - this.currentPage = 1  
59 - this.getData()  
60 - } 17 + title: string = '直播列表'
61 18
62 build() { 19 build() {
63 20
64 Column() { 21 Column() {
65 - this.TabbarNormal()  
66 - if (this.viewType == ViewType.LOADING) {  
67 - this.LoadingLayout()  
68 - } else if (this.viewType == ViewType.EMPTY || this.viewType == ViewType.ERROR) {  
69 - EmptyComponent({  
70 - emptyType: this.emptyType,  
71 - emptyButton: true,  
72 - retry: () => {  
73 - this.getData()  
74 - }  
75 - })  
76 - } else {  
77 - CustomPullToRefresh({  
78 - alldata: this.data,  
79 - scroller: this.scroller,  
80 - hasMore: false,  
81 - customList: () => {  
82 - this.ListLayout()  
83 - },  
84 - onRefresh: (resolve) => {  
85 - this.currentPage = 1  
86 - this.getData(resolve)  
87 - },  
88 - })  
89 - } 22 +
  23 + //常见标题
  24 + CommonPageTitle({ title: this.title })
  25 + // 通用模板组件
  26 + TemplatePageComponent({ pageDataSourceType: TemplatePageConstant.LIVE_HORIZONTAL_CARD })
  27 +
90 } 28 }
91 .height('100%') 29 .height('100%')
  30 + .backgroundColor(Color.White)
92 .padding({ 31 .padding({
93 - left: $r('app.float.card_comp_pagePadding_lf'),  
94 - right: $r('app.float.card_comp_pagePadding_lf'),  
95 top: px2vp(this.topSafeHeight), 32 top: px2vp(this.topSafeHeight),
96 bottom: px2vp(this.bottomSafeHeight) 33 bottom: px2vp(this.bottomSafeHeight)
97 }) 34 })
98 35
99 } 36 }
100 -  
101 - @Builder  
102 - LoadingLayout() {  
103 - channelSkeleton()  
104 - }  
105 -  
106 - @Builder  
107 - ListLayout() {  
108 - List({ scroller: this.scroller }) {  
109 - // 下拉刷新  
110 - LazyForEach(this.data, (contentDTO: ContentDTO) => {  
111 - ListItem() {  
112 - this.buildItem(contentDTO)  
113 - }  
114 - },  
115 - (contentDTO: ContentDTO, contentIndex: number) => contentDTO.pageId + contentIndex.toString()  
116 - )  
117 - // 加载更多  
118 - ListItem() {  
119 - if (this.hasMore && this.data && this.data.totalCount() > 0) {  
120 - LoadMoreLayout({ isVisible: this.hasMore })  
121 - } else if (!this.hasMore && !this.isLoading) {  
122 - PeopleShipNoMoreData()  
123 - }  
124 - }  
125 - }  
126 - .scrollBar(BarState.Off)  
127 - .edgeEffect(EdgeEffect.None)  
128 - .cachedCount(3)  
129 - .height('calc(100% - 44vp)')  
130 - .onReachEnd(() => {  
131 - Logger.debug(TAG, "触底了");  
132 - if (!this.isLoading && this.hasMore) {  
133 - //加载分页数据  
134 - this.currentPage++;  
135 - this.getData()  
136 - }  
137 - })  
138 - }  
139 -  
140 - /**  
141 - * 组件项  
142 - *  
143 - * @param programmeBean item 组件项, 上面icon,下面标题  
144 - */  
145 - @Builder  
146 - buildItem(item: ContentDTO) {  
147 - Column() {  
148 - Text(item.newsTitle)  
149 - .fontSize(18)  
150 - .maxLines(2)  
151 - .textOverflow({ overflow: TextOverflow.Ellipsis })  
152 - .margin({ top: 16, bottom: 8 })  
153 - .alignSelf(ItemAlign.Start)  
154 - .fontColor(this.isClicked(item.objectId) ? $r('app.color.color_848484') : $r('app.color.color_222222'))  
155 -  
156 - Stack() {  
157 - if (item.fullColumnImgUrls && item.fullColumnImgUrls.length > 0) {  
158 - Image(this.loadImg ? item.fullColumnImgUrls[0].url : '')  
159 - .backgroundColor(this.loadImg ? $r('app.color.color_B0B0B0') : 0xf5f5f5)  
160 - .width('100%')  
161 - .aspectRatio(16 / 9)  
162 - .borderRadius(4)  
163 - }  
164 - this.LiveImage(item)  
165 - }  
166 - .alignContent(Alignment.BottomEnd)  
167 -  
168 - Row() {  
169 - if (item.rmhInfo && item.rmhInfo.rmhName) {  
170 - Text(item.rmhInfo.rmhName)  
171 - .fontSize(12)  
172 - .fontWeight(400)  
173 - .fontColor($r('app.color.color_B0B0B0'))  
174 - .fontFamily('PingFang SC-Medium')  
175 - .maxLines(1)  
176 - .textOverflow({ overflow: TextOverflow.Ellipsis })  
177 - .align(Alignment.Start)  
178 -  
179 - Image($r('app.media.point_live_icon'))  
180 - .objectFit(ImageFit.Auto)  
181 - .interpolation(ImageInterpolation.High)  
182 - .width(16)  
183 - .height(16)  
184 - .margin(2)  
185 - }  
186 -  
187 - Text(DateTimeUtils.getCommentTime(Number.parseFloat(item.publishTimestamp)))  
188 - .fontSize(12)  
189 - .maxLines(1)  
190 - .textOverflow({ overflow: TextOverflow.Ellipsis })  
191 - .align(Alignment.Start)  
192 - .width('100%')  
193 - .fontColor($r('app.color.color_B0B0B0'))  
194 - }  
195 - .margin({ top: 8, bottom: 8 })  
196 -  
197 -  
198 - Divider()  
199 - .strokeWidth(1)  
200 - .margin({ top: 6 })  
201 - .width('100%')  
202 - .color('#f5f5f5')  
203 - }  
204 - .width('100%')  
205 - .onClick(() => {  
206 - this.clickRowBuildItem(item)  
207 - ProcessUtils.processPage(item)  
208 - })  
209 - }  
210 -  
211 - /*导航栏*/  
212 - @Builder  
213 - TabbarNormal() {  
214 -  
215 - RelativeContainer() {  
216 - //标题栏目  
217 - Image($r('app.media.icon_arrow_left'))  
218 - .width(24)  
219 - .height(24)  
220 - .objectFit(ImageFit.Auto)  
221 - .id("back_icon")  
222 - .alignRules({  
223 - center: { anchor: "__container__", align: VerticalAlign.Center },  
224 - left: { anchor: "__container__", align: HorizontalAlign.Start }  
225 - })  
226 - .onClick(() => {  
227 - router.back()  
228 - })  
229 -  
230 - Text(this.title)  
231 - .maxLines(1)  
232 - .id("title")  
233 - .fontSize('18vp')  
234 - .fontWeight(400)  
235 - .fontColor($r('app.color.color_222222'))  
236 - .lineHeight('22vp')  
237 - .alignRules({  
238 - center: { anchor: "__container__", align: VerticalAlign.Center },  
239 - middle: { anchor: "__container__", align: HorizontalAlign.Center }  
240 - })  
241 - }  
242 - .height(44)  
243 - .width('100%')  
244 - }  
245 -  
246 - @Builder  
247 - LiveImage(item: ContentDTO) {  
248 - Row() {  
249 - LottieView({  
250 - name: 'live_status_wait',  
251 - path: "lottie/live_detail_living.json",  
252 - lottieWidth: 14,  
253 - lottieHeight: 14,  
254 - autoplay: true,  
255 - loop: true,  
256 - title: item.newsTitle  
257 - })  
258 - .margin({  
259 - right: '2vp'  
260 - })  
261 -  
262 - Text('直播中')  
263 - .fontSize('12vp')  
264 - .fontWeight(400)  
265 - .fontColor(Color.White)  
266 - .textShadow({  
267 - radius: 2,  
268 - color: 'rgba(0,0,0,0.3)',  
269 - offsetX: 0,  
270 - offsetY: 2  
271 - })  
272 - .margin({  
273 - right: '5vp'  
274 - })  
275 -  
276 - Image($r('app.media.icon_comp_line_live')).height('11vp').width('1.5vp')  
277 -  
278 - if (this.getLiveRoomNumber(item).length > 0) {  
279 - Text(this.getLiveRoomNumber(item))  
280 - .fontSize('12vp')  
281 - .fontWeight(400)  
282 - .textShadow({  
283 - radius: 2,  
284 - color: 'rgba(0,0,0,0.3)',  
285 - offsetX: 0,  
286 - offsetY: 2  
287 - })  
288 - .fontColor(Color.White)  
289 - .margin({  
290 - left: '5vp'  
291 - })  
292 - }  
293 - }  
294 - .justifyContent(FlexAlign.End)  
295 - .margin({ right: 8, bottom: 8 })  
296 - }  
297 -  
298 - private async getData(resolve?: (value: string | PromiseLike<string>) => void) {  
299 - if (this.isLoading) {  
300 - if (resolve) {  
301 - resolve('已更新至最新')  
302 - }  
303 - return  
304 - }  
305 -  
306 - // 检测网络  
307 - let netStatus = NetworkUtil.isNetConnected()  
308 - if (!netStatus) {  
309 -  
310 - this.emptyType = WDViewDefaultType.WDViewDefaultType_NoNetwork  
311 - this.viewType = ViewType.ERROR  
312 -  
313 - return  
314 - }  
315 -  
316 -  
317 - this.isLoading = true  
318 - try {  
319 - const liveReviewDTO = await PageViewModel.getLiveMoreUrl(this.type, this.currentPage, this.pageSize)  
320 -  
321 - if (liveReviewDTO && liveReviewDTO.list && liveReviewDTO.list.length > 0) {  
322 - if (liveReviewDTO.list.length === this.pageSize) {  
323 - this.hasMore = true;  
324 - } else {  
325 - this.hasMore = false;  
326 - }  
327 - if (this.currentPage == 1) {  
328 - this.data.clear()  
329 - }  
330 - this.data.push(...liveReviewDTO.list)  
331 - this.getLiveRoomDataInfo(liveReviewDTO.list)  
332 - } else {  
333 - this.hasMore = false;  
334 - }  
335 - this.resolveEnd(true, resolve)  
336 - if (liveReviewDTO.list.length == 0 && this.currentPage == 1) {  
337 - this.viewType = ViewType.EMPTY  
338 - this.emptyType = WDViewDefaultType.WDViewDefaultType_NoListContent  
339 - }  
340 - } catch (exception) {  
341 - this.resolveEnd(false, resolve)  
342 - }  
343 -  
344 - }  
345 -  
346 - private resolveEnd(isTop: boolean, resolve?: (value: string | PromiseLike<string>) => void) {  
347 - if (resolve) {  
348 - if (this.currentPage == 1 && isTop) {  
349 - resolve('已更新至最新')  
350 - } else {  
351 - resolve('')  
352 - }  
353 - }  
354 - if (this.currentPage == 1 && !isTop) {  
355 -  
356 - this.viewType = ViewType.ERROR  
357 - this.emptyType = WDViewDefaultType.WDViewDefaultType_NoListContent  
358 - } else {  
359 - this.viewType = ViewType.LOADED  
360 - }  
361 - this.isLoading = false  
362 - }  
363 -  
364 - private getLiveDetailIds(list: ContentDTO[]): string {  
365 - let idList: string[] = []  
366 - list.forEach(item => {  
367 - idList.push(item.objectId)  
368 - });  
369 - return idList.join(',')  
370 - }  
371 -  
372 - // 获取评论数  
373 - async getLiveRoomDataInfo(list: ContentDTO[]) {  
374 - const reserveIds = this.getLiveDetailIds(list)  
375 - Logger.debug(TAG, '是否预约数据:' + ` ${reserveIds}`)  
376 - PageViewModel.getLiveRoomBatchInfo(reserveIds).then((result) => {  
377 - Logger.debug(TAG, '是否预约数据:' + ` ${JSON.stringify(result)}`)  
378 - if (result && result.length > 0) {  
379 - this.liveRoomList.push(...result)  
380 - this.data.reloadData()  
381 - }  
382 - }).catch(() => {  
383 - // this.data.push(...list)  
384 - })  
385 - }  
386 -  
387 - // 判断是否预约  
388 - getLiveRoomNumber(item: ContentDTO): string {  
389 - const objc = this.liveRoomList.find((element: LiveRoomDataBean) => {  
390 - return element.liveId.toString() == item.objectId  
391 - })  
392 - if (objc && objc.pv && objc.pv > 0) {  
393 - return this.computeShowNum(objc.pv)  
394 - }  
395 - return ''  
396 - }  
397 -  
398 - private computeShowNum(count: number): string {  
399 - if (count >= 10000) {  
400 - let num = (count / 10000).toFixed(1)  
401 - if (Number(num.substring(num.length - 1)) == 0) {  
402 - num = num.substring(0, num.length - 2)  
403 - }  
404 - return num + '万人参加'  
405 - }  
406 - return `${count}人参加`  
407 - }  
408 -  
409 - isClicked(objectId: string) {  
410 - return this.clickDatas.includes(objectId)  
411 - }  
412 -  
413 - clickRowBuildItem(item: ContentDTO) {  
414 - if (item.objectId && !this.clickDatas.includes(item.objectId)) {  
415 - Logger.debug(TAG, '数据:' + JSON.stringify(this.clickDatas))  
416 - this.clickDatas.push(item.objectId.toString())  
417 - this.putLiveMoreClickPreference()  
418 - }  
419 - }  
420 -  
421 - async getPreferencesFromStorage() {  
422 - let context = getContext(this) as Context  
423 - preferenceTheme = await dataPreferences.getPreferences(context, PREFERENCES_NAME)  
424 - }  
425 -  
426 - putLiveMoreClickPreference() {  
427 - Logger.info(TAG, `Put begin` + JSON.stringify(this.clickDatas))  
428 - if (preferenceTheme !== null && this.clickDatas.length > 0) {  
429 - // await  
430 - const arr: Array<string> = []  
431 - arr.push(...this.clickDatas)  
432 - preferenceTheme.put('liveMorePage', arr).then(() => {  
433 - Logger.debug(TAG, "Succeeded in putting value of 'startup'.");  
434 - }).catch((err: BusinessError) => {  
435 - Logger.debug(TAG, "Failed to put value of 'startup'. code =" + err.code + ", message =" + err.message);  
436 - })  
437 - // await preferenceTheme.flush()  
438 - preferenceTheme.flush((err: BusinessError) => {  
439 - if (err) {  
440 - Logger.debug(TAG, "Failed to flush. code =" + err.code + ", message =" + err.message);  
441 - return;  
442 - }  
443 - })  
444 -  
445 - }  
446 - }  
447 -  
448 - getLivMoreClickPreference() {  
449 - Logger.info(TAG, `Get begin`)  
450 - if (preferenceTheme !== null) {  
451 - preferenceTheme.get('liveMorePage', []).then((data: dataPreferences.ValueType) => {  
452 - if (data instanceof Array) {  
453 - this.clickDatas = data as Array<string>  
454 - }  
455 - }).catch((err: BusinessError) => {  
456 - console.error("Failed to get value of 'startup'. code =" + err.code + ", message =" + err.message);  
457 - })  
458 - }  
459 - }  
460 } 37 }
1 -import { BottomNavDTO, CompDTO, TopNavDTO } from 'wdBean'; 1 +import { BottomNavDTO, TopNavDTO } from 'wdBean';
2 import { SpConstants } from 'wdConstant'; 2 import { SpConstants } from 'wdConstant';
3 -import { DisplayUtils, LazyDataSource, Logger, NetworkUtil, SPHelper, ToastUtils } from 'wdKit'; 3 +import { Logger, NetworkUtil, SPHelper, ToastUtils } from 'wdKit';
4 import { ProcessUtils, WDRouterPage, WDRouterRule } from 'wdRouter'; 4 import { ProcessUtils, WDRouterPage, WDRouterRule } from 'wdRouter';
5 import { PageComponent } from './PageComponent'; 5 import { PageComponent } from './PageComponent';
6 import { ChannelSubscriptionLayout } from './ChannelSubscriptionLayout'; 6 import { ChannelSubscriptionLayout } from './ChannelSubscriptionLayout';
@@ -8,9 +8,8 @@ import { FirstTabTopSearchComponent } from '../search/FirstTabTopSearchComponent @@ -8,9 +8,8 @@ import { FirstTabTopSearchComponent } from '../search/FirstTabTopSearchComponent
8 import { AssignChannelParam } from 'wdRouter/src/main/ets/utils/HomeChannelUtils'; 8 import { AssignChannelParam } from 'wdRouter/src/main/ets/utils/HomeChannelUtils';
9 import { PeopleShipMainComponent } from '../peopleShip/PeopleShipMainComponent'; 9 import { PeopleShipMainComponent } from '../peopleShip/PeopleShipMainComponent';
10 import { channelSkeleton } from '../skeleton/channelSkeleton'; 10 import { channelSkeleton } from '../skeleton/channelSkeleton';
11 -import { TrackConstants, TrackingButton } from 'wdTracking/Index';  
12 -import DailyPaperTopicModel from '../../model/DailyPaperTopicModel'  
13 -import { ParamType, Tracking } from 'wdTracking/Index'; 11 +import { ParamType, TrackConstants, Tracking, TrackingButton } from 'wdTracking/Index';
  12 +import DailyPaperTopicModel from '../../model/DailyPaperTopicModel';
14 import { CompUtils } from '../../utils/CompUtils'; 13 import { CompUtils } from '../../utils/CompUtils';
15 14
16 const TAG = 'TopNavigationComponent'; 15 const TAG = 'TopNavigationComponent';
  1 +import { ArrayList } from '@kit.ArkTS'
  2 +import { CompDTO, ContentDTO, LiveRoomDataBean } from 'wdBean/Index'
  3 +import { DateTimeUtils, Logger } from 'wdKit/Index'
  4 +import PageViewModel from '../../../viewmodel/PageViewModel'
  5 +const TAG: string = 'BaseTemplateHelp'
  6 +
  7 +
  8 +export class BasePageHelp {
  9 +
  10 + /**
  11 + * 请求获取直播房间的动态数据
  12 + * @param list
  13 + */
  14 + /**
  15 + * 直播回看的批查数据
  16 + * @param list
  17 + * @param compList
  18 + */
  19 + getLiveRoomDataInfo(compList: CompDTO[]) {
  20 +
  21 + let list: ContentDTO[] = []
  22 + compList.forEach((comp: CompDTO) => {
  23 + list.push(...comp.operDataList)
  24 + })
  25 + let time = DateTimeUtils.getTimeStamp().toString()
  26 +
  27 + let reserveIds = this.getLiveDetailIds(list)
  28 +
  29 + PageViewModel.getLiveRoomBatchInfo(reserveIds).then((result) => {
  30 + if (result && result.length > 0) {
  31 + result.forEach((bean: LiveRoomDataBean) => {
  32 + for (let item of list) {
  33 + if (item.objectId == bean.liveId.toString()) {
  34 + item.liveRoomDataBean = bean
  35 + outer: for (let compBean of compList) {
  36 + for (let contentBean of compBean.operDataList) {
  37 + if (contentBean === item) {
  38 + compBean.timestamp = time
  39 + break outer
  40 + }
  41 + }
  42 + }
  43 + break
  44 + }
  45 + }
  46 + })
  47 + }
  48 + }).catch(() => {
  49 + })
  50 + }
  51 + /**
  52 + * 获取业务内容 objectId 集合穿 如1,2,3
  53 + * @param pageContentList
  54 + * @returns
  55 + */
  56 + private getLiveDetailIds(pageContentList: ContentDTO[]): string {
  57 + let idList: string[] = []
  58 + pageContentList.forEach(item => {
  59 + idList.push(item.objectId)
  60 + });
  61 + return idList.join(',')
  62 + }
  63 +}
  1 +import { CompDTO, ContentDTO } from 'wdBean/Index'
  2 +import { LazyDataSource, Logger } from 'wdKit/Index'
  3 +import { CompParser } from '../../CompParser'
  4 +import { CustomPullToRefresh } from '../../reusable/CustomPullToRefresh'
  5 +import { PeopleShipNoMoreData } from '../../reusable/PeopleShipNoMoreData'
  6 +import { channelSkeleton } from '../../skeleton/channelSkeleton'
  7 +import { EmptyComponent } from '../../view/EmptyComponent'
  8 +import LoadMoreLayout from '../LoadMoreLayout'
  9 +import TemplatePageHelp from './TemplatePageHelp'
  10 +import TemplatePageModel from './TemplatePageModel'
  11 +import { TemplatePageStateType } from './TemplatePageStateType'
  12 +
  13 +
  14 +const TAG: string = 'TemplatePageComponent';
  15 +
  16 +/**
  17 + * @Description: 处理通用信息展示页面,1)业务数据加载;2)异常状况处理;3)展位信息处理
  18 + * @Author:
  19 + * @Email: liyubing@wondertek.com.cn
  20 + * @CreateDate:
  21 + * @UpdateRemark: 更新说明
  22 + * @Version: 1.0
  23 + */
  24 +@Component
  25 +export default struct TemplatePageComponent {
  26 +
  27 + // 模板页面的数据驱动对象
  28 + @State private templatePage: TemplatePageModel = new TemplatePageModel
  29 + // 此内容主要因CustomPullToRefresh需要,目前没任何业务意义要求
  30 + @State pageData: LazyDataSource<ContentDTO> = new LazyDataSource();
  31 + // 滚动
  32 + private templateScroller: Scroller = new Scroller()
  33 + //识别不同页面的业务类型
  34 + pageDataSourceType: string = ''
  35 +
  36 + // 埋点字段
  37 + pageId: string = ''
  38 + pageName: string = ''
  39 +
  40 + async aboutToAppear() {
  41 + Logger.debug(TAG, 'aboutToAppear')
  42 + this.requestPageData()
  43 + }
  44 +
  45 + aboutToDisappear(): void {
  46 +
  47 + }
  48 +
  49 + build() {
  50 + if (this.templatePage.pageCompType === TemplatePageStateType.LOADING) {
  51 + this.LoadingLayout()
  52 + } else if (this.templatePage.pageCompType === TemplatePageStateType.LOADED) {
  53 +
  54 + CustomPullToRefresh({
  55 + alldata: this.pageData,
  56 + scroller: this.templateScroller,
  57 + hasMore: false,
  58 + customList: () => {
  59 + this.ListLayout()
  60 + },
  61 + onRefresh: (resolve) => {
  62 + this.templatePage.currentPage = 1
  63 + this.templatePage.resolve = resolve
  64 + this.requestPageData(resolve)
  65 + },
  66 + })
  67 +
  68 + } else {
  69 + EmptyComponent({
  70 + emptyType: this.templatePage.noNormalState,
  71 + emptyButton: true,
  72 + retry: () => {
  73 + this.requestPageData()
  74 + }
  75 + })
  76 + }
  77 + }
  78 +
  79 + @Builder
  80 + LoadingLayout() {
  81 + channelSkeleton()
  82 + }
  83 +
  84 + @Builder
  85 + ListLayout() {
  86 + List({ scroller: this.templateScroller }) {
  87 + // 下拉刷新
  88 + LazyForEach(this.templatePage.compList, (compDTO: CompDTO, index: number) => {
  89 + ListItem() {
  90 + Column() {
  91 +
  92 + CompParser({
  93 + compDTO: compDTO,
  94 + compIndex: index,
  95 + pageId: this.pageId,
  96 + pageName: this.pageName
  97 + });
  98 + }
  99 + }
  100 + },
  101 + (contentDTO: CompDTO, contentIndex: number) => JSON.stringify(contentDTO))
  102 + // 加载更多
  103 + ListItem() {
  104 + if (this.templatePage.hasMore && this.templatePage.compList && this.templatePage.compList.totalCount() > 0) {
  105 + LoadMoreLayout({ isVisible: this.templatePage.hasMore })
  106 + } else if (!this.templatePage.hasMore && !this.templatePage.isLoading) {
  107 + PeopleShipNoMoreData()
  108 + }
  109 + }
  110 + }
  111 + .scrollBar(BarState.Off)
  112 + .edgeEffect(EdgeEffect.None)
  113 + .cachedCount(3)
  114 + .height('calc(100% - 44vp)')
  115 + .onReachEnd(() => {
  116 + Logger.debug(TAG, "触底了");
  117 + if (!this.templatePage.isLoading && this.templatePage.hasMore) {
  118 + //加载分页数据
  119 + this.templatePage.currentPage++;
  120 + this.requestPageData()
  121 + }
  122 + })
  123 + }
  124 +
  125 + /**
  126 + * 请求业务数据
  127 + */
  128 + async requestPageData(resolve?: (value: string | PromiseLike<string>) => void) {
  129 +
  130 + if (this.templatePage.isLoading) {
  131 + if (resolve) {
  132 + resolve('已更新至最新')
  133 + }
  134 + return
  135 + }
  136 +
  137 + this.templatePage.pageDataSourceType = this.pageDataSourceType
  138 +
  139 + TemplatePageHelp.requestPageData(this.templatePage)
  140 + }
  141 +}
  1 +/**
  2 + * @Description: 模板页面的常量
  3 + * @Author:
  4 + * @Email: liyubing@wondertek.com.cn
  5 + * @CreateDate:
  6 + * @UpdateRemark: 更新说明
  7 + * @Version: 1.0
  8 + */
  9 +export class TemplatePageConstant {
  10 + /**
  11 + * 直播中
  12 + */
  13 + public static LIVE_HORIZONTAL_CARD: string = "LIVE_HORIZONTAL_CARD"
  14 +
  15 +
  16 +}
  1 +import { CompDTO } from 'wdBean/Index';
  2 +import { CompStyle } from 'wdConstant/Index';
  3 +import { NetworkUtil } from 'wdKit/Index';
  4 +import PageViewModel from '../../../viewmodel/PageViewModel';
  5 +import { WDViewDefaultType } from '../../view/EmptyComponent';
  6 +import { BasePageHelp } from './BasePageHelp';
  7 +import { TemplatePageConstant } from './TemplatePageConstant';
  8 +import TemplatePageModel from './TemplatePageModel';
  9 +import { TemplatePageStateType } from './TemplatePageStateType';
  10 +
  11 +const TAG: string = 'TemplatePageHelp';
  12 +
  13 +/**
  14 + * @Description: 完成不同页面业务数据获取并加工
  15 + * @Author:
  16 + * @Email: liyubing@wondertek.com.cn
  17 + * @CreateDate:
  18 + * @UpdateRemark: 更新说明
  19 + * @Version: 1.0
  20 + */
  21 +export class TemplatePageHelp extends BasePageHelp {
  22 + private pageModel: TemplatePageModel = new TemplatePageModel
  23 +
  24 + constructor() {
  25 + super();
  26 + }
  27 +
  28 + /**
  29 + * 请求业务数据
  30 + * @param pageModel
  31 + */
  32 + async requestPageData(pageModel: TemplatePageModel) {
  33 +
  34 + this.pageModel = pageModel
  35 + // 检测网络
  36 + let netStatus = NetworkUtil.isNetConnected()
  37 + if (netStatus) {
  38 + this.treatDiffBusinessDataSource()
  39 + } else if (pageModel.compList.size() > 0) {
  40 + // 加载缓存数据了,不用无网络提示
  41 + } else {
  42 + // 无网情况
  43 + pageModel.pageCompType = TemplatePageStateType.OTHER;
  44 + pageModel.noNormalState = WDViewDefaultType.WDViewDefaultType_NoNetwork
  45 + }
  46 + }
  47 +
  48 +
  49 + /**
  50 + * 区分不同业务数据源
  51 + */
  52 + private treatDiffBusinessDataSource() {
  53 +
  54 + if (this.pageModel.pageDataSourceType === TemplatePageConstant.LIVE_HORIZONTAL_CARD) {
  55 + // 直播列表
  56 + this.requestLiveListData(this.pageModel.resolve)
  57 + }
  58 +
  59 + }
  60 +
  61 +
  62 + /**
  63 + * 请求直播列表数据
  64 + */
  65 + private async requestLiveListData(resolve?: (value: string | PromiseLike<string>) => void) {
  66 +
  67 + this.pageModel.isLoading = true
  68 +
  69 + const liveReviewDTO = await PageViewModel.getLiveMoreUrl(1, this.pageModel.currentPage, this.pageModel.pageSize)
  70 +
  71 + if (liveReviewDTO && liveReviewDTO.list && liveReviewDTO.list.length > 0) {
  72 +
  73 + if (liveReviewDTO.list.length === this.pageModel.pageSize) {
  74 + this.pageModel.hasMore = true
  75 + } else {
  76 + this.pageModel.hasMore = false
  77 + }
  78 +
  79 +
  80 + // 依据业务请求获取的数据,转换成compDTO数据
  81 + let pageContentList: CompDTO[] = [] // 收集页面组件、稿件和本地组件容器
  82 + for (let contentDto of liveReviewDTO.list) {
  83 + let compDTO: CompDTO = new CompDTO()
  84 + compDTO.compType = 'appStyle'
  85 + contentDto.appStyle = CompStyle.Card_Comp_Live_Big_Image_02
  86 + compDTO.operDataList.push(contentDto)
  87 + pageContentList.push(compDTO)
  88 + }
  89 +
  90 + // 推送数据到懒加载机制
  91 + this.pushDataToPage(pageContentList)
  92 + // 完成业务请求加载
  93 + this.pageModel.isLoading = false
  94 + // 批查
  95 + this.allCompBatchRequest(pageContentList)
  96 +
  97 + } else {
  98 +
  99 + this.pageModel.hasMore = false
  100 + if (this.pageModel.currentPage === 1) {
  101 + // 无业务数据
  102 + this.pageNoHaveData()
  103 + }
  104 + }
  105 +
  106 + this.resolveEnd(resolve)
  107 + }
  108 +
  109 +
  110 + /**
  111 + * 处理页面批查业务方法
  112 + * @param list
  113 + */
  114 + private allCompBatchRequest(compList: CompDTO[]) {
  115 +
  116 + // 获取直播房间的动态数据
  117 + this.getLiveRoomDataInfo(compList)
  118 +
  119 + // 测试数据
  120 + // setTimeout(() => {
  121 + // let time = DateTimeUtils.getTimeStamp().toString()
  122 + // let index = 1
  123 + // let compBean = compList[index] as CompDTO
  124 + // let contentBean = compBean.operDataList[0]
  125 + // contentBean.newsTitle = '熬阿斯蒂芬'
  126 + // //comp.operDataList[0].newsTitle = '测试111'
  127 + // let liveRoomBean: LiveRoomDataBean = {} as LiveRoomDataBean;
  128 + // liveRoomBean.pv = 6555
  129 + // contentBean.liveRoomDataBean = liveRoomBean
  130 + // compBean.timestamp = time
  131 + // Logger.debug("ZZZXXXXX",
  132 + // "-----setTimeout--------->" + time)
  133 + // }, 4 * 1000)
  134 + }
  135 +
  136 +
  137 + /**
  138 + * 推数据到页面
  139 + * @param list
  140 + */
  141 + private pushDataToPage(pageContentList: CompDTO[]) {
  142 +
  143 + // 请求第一页数据,需要清理pageData数据
  144 + if (this.pageModel.currentPage == 1) {
  145 + this.pageModel.compList.clear()
  146 + }
  147 + // 懒加载,推送数据
  148 + for (let contentDto of pageContentList) {
  149 + this.pageModel.compList.push(contentDto)
  150 + }
  151 + //完成业务数据请求
  152 + this.pageModel.pageCompType = TemplatePageStateType.LOADED
  153 + }
  154 +
  155 +
  156 + /**
  157 + * 页面没有数据
  158 + */
  159 + private pageNoHaveData() {
  160 + this.pageModel.pageCompType = TemplatePageStateType.OTHER
  161 + this.pageModel.noNormalState = WDViewDefaultType.WDViewDefaultType_NoNetwork
  162 + }
  163 +
  164 + /**
  165 + * 解析结束
  166 + * @param resolve
  167 + */
  168 + private resolveEnd(resolve?: (value: string | PromiseLike<string>) => void) {
  169 + if (resolve) {
  170 + if (this.pageModel.currentPage == 1) {
  171 + resolve('已更新至最新')
  172 + } else {
  173 + resolve('')
  174 + }
  175 + }
  176 +
  177 + }
  178 +}
  179 +
  180 +
  181 +let templatePageHelp = new TemplatePageHelp();
  182 +
  183 +export default templatePageHelp as TemplatePageHelp;
  1 +import { ContentDTO } from 'wdBean/Index';
  2 +import { BaseDTO } from 'wdBean/src/main/ets/bean/component/BaseDTO';
  3 +import { LazyDataSource } from 'wdKit/Index';
  4 +import { WDViewDefaultType } from '../../view/EmptyComponent';
  5 +import { TemplatePageStateType } from './TemplatePageStateType';
  6 +
  7 +/**
  8 + * @Description: 与TemplatePageCompent结合使用,处理业务、异常等数据
  9 + * @Author:
  10 + * @Email: liyubing@wondertek.com.cn
  11 + * @CreateDate:
  12 + * @UpdateRemark: 更新说明
  13 + * @Version: 1.0
  14 + */
  15 +export default class TemplatePageModel {
  16 + /**
  17 + * 不用的页面所展示的业务数据都转换CompDTO对象
  18 + */
  19 + compList: LazyDataSource<BaseDTO> = new LazyDataSource();
  20 + /**
  21 + * 识别不同页面的业务类型
  22 + */
  23 + pageDataSourceType: string = ''
  24 +
  25 + // 页码
  26 + currentPage: number = 1
  27 + // 一页最多信息量
  28 + pageSize: number = 20
  29 + // 是否支持加载更多数据
  30 + hasMore:boolean = false
  31 + // 是否正在请求数据
  32 + isLoading: boolean = false
  33 +
  34 + /**
  35 + * 此字段可驱动组件展示不同业务的组件,
  36 + */
  37 + pageCompType: number = TemplatePageStateType.LOADING
  38 + /**
  39 + * 异常状态 ——> 记录在获取数据中的不同状态,如无数据、无网络等情况
  40 + */
  41 + noNormalState: WDViewDefaultType = WDViewDefaultType.WDViewDefaultType_Default
  42 +
  43 + resolve?: (value: string | PromiseLike<string>) => void
  44 +}
  1 +/**
  2 + *
  3 + * 组件加载数据的不同状态
  4 + *
  5 + */
  6 +export const enum TemplatePageStateType {
  7 + // 已初始化,但尚未发出请求
  8 + INITIAL = 0,
  9 + // 加载中:已发出请求,但请求尚未返回;
  10 + LOADING,
  11 + //
  12 + OTHER,
  13 + // 已加载结束/非失败/非空/可以是仅一页数据,即楼层数据列表PAGE_GROUP_LIST/
  14 + LOADED,
  15 +
  16 +}
@@ -134,7 +134,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent { @@ -134,7 +134,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent {
134 .aspectRatio(1.5) 134 .aspectRatio(1.5)
135 .width(this.compDTO.operDataList.length == 2 ? 210 : 150) 135 .width(this.compDTO.operDataList.length == 2 ? 210 : 150)
136 .borderRadius(4) 136 .borderRadius(4)
137 - .objectFit(ImageFit.Cover) 137 + .objectFit(ImageFit.Contain)
138 CardMediaInfo({ 138 CardMediaInfo({
139 livePeopleNum:false, 139 livePeopleNum:false,
140 contentDTO: item 140 contentDTO: item
@@ -153,7 +153,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent { @@ -153,7 +153,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent {
153 .width(this.compDTO.operDataList.length == 2 ? 210 : 150) 153 .width(this.compDTO.operDataList.length == 2 ? 210 : 150)
154 .lineHeight(21) 154 .lineHeight(21)
155 } 155 }
156 - .height(this.compDTO.operDataList.length == 2 ? 190 : 150) 156 + .height(this.compDTO.operDataList.length == 2 ? 180 : 148)
157 .padding({ right: 16 }) 157 .padding({ right: 16 })
158 // .offset({x:16}) 158 // .offset({x:16})
159 .onClick(() => { 159 .onClick(() => {
@@ -167,7 +167,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent { @@ -167,7 +167,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent {
167 Row() { 167 Row() {
168 Ellipse() 168 Ellipse()
169 .width(2* (this.moreWidth - this.initMoreWidth - 1)) 169 .width(2* (this.moreWidth - this.initMoreWidth - 1))
170 - .height(this.compDTO.operDataList.length == 2 ? 180 : 146) 170 + .height(this.compDTO.operDataList.length == 2 ? 180 : 148)
171 .fill(0xf1f3f4) 171 .fill(0xf1f3f4)
172 .position({ left: -(this.moreWidth - this.initMoreWidth - 3) * 0.8 }) 172 .position({ left: -(this.moreWidth - this.initMoreWidth - 3) * 0.8 })
173 173
@@ -181,7 +181,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent { @@ -181,7 +181,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent {
181 } 181 }
182 .justifyContent(FlexAlign.Center) 182 .justifyContent(FlexAlign.Center)
183 .align(Alignment.Center) 183 .align(Alignment.Center)
184 - .height(this.compDTO.operDataList.length == 2 ? 180 : 146) 184 + .height(this.compDTO.operDataList.length == 2 ? 180 : 148)
185 .width(this.initMoreWidth) 185 .width(this.initMoreWidth)
186 .backgroundColor(0xf1f3f4) 186 .backgroundColor(0xf1f3f4)
187 .borderRadius({ topLeft: 5, bottomLeft: 5 }) 187 .borderRadius({ topLeft: 5, bottomLeft: 5 })
@@ -213,6 +213,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent { @@ -213,6 +213,7 @@ export struct HorizontalStrokeCardThreeTwoRadioForMoreComponent {
213 } 213 }
214 } 214 }
215 }) 215 })
  216 + .height(this.compDTO.operDataList.length == 2 ? 180 : 148)
216 // .width('100%') 217 // .width('100%')
217 218
218 // .backgroundColor($r("app.color.color_FE4B05")) 219 // .backgroundColor($r("app.color.color_FE4B05"))
@@ -170,7 +170,7 @@ export struct LiveHorizontalCardComponent { @@ -170,7 +170,7 @@ export struct LiveHorizontalCardComponent {
170 .width(this.compDTO.operDataList.length == 2 ? 210 : 150) 170 .width(this.compDTO.operDataList.length == 2 ? 210 : 150)
171 .lineHeight(21) 171 .lineHeight(21)
172 } 172 }
173 - .height(this.compDTO.operDataList.length == 2 ? 190 : 150) 173 + .height(this.compDTO.operDataList.length == 2 ? 180 : 148)
174 .padding({ right: 16 }) 174 .padding({ right: 16 })
175 .onClick(() => { 175 .onClick(() => {
176 InfomationCardClick.track(this.compDTO, item, this.pageId, this.pageName) 176 InfomationCardClick.track(this.compDTO, item, this.pageId, this.pageName)
@@ -232,7 +232,7 @@ export struct LiveHorizontalCardComponent { @@ -232,7 +232,7 @@ export struct LiveHorizontalCardComponent {
232 } 232 }
233 }) 233 })
234 .width(CommonConstants.FULL_WIDTH) 234 .width(CommonConstants.FULL_WIDTH)
235 - .height(this.compDTO.operDataList.length == 2 ? 180 : 136) 235 + .height(this.compDTO.operDataList.length == 2 ? 180 : 148)
236 } else if (this.compDTO.operDataList.length) { 236 } else if (this.compDTO.operDataList.length) {
237 // 一个 237 // 一个
238 LiveHorizontalCardForOneComponent({ contentDTO: this.compDTO.operDataList[0] }) 238 LiveHorizontalCardForOneComponent({ contentDTO: this.compDTO.operDataList[0] })
@@ -263,6 +263,13 @@ export class PageViewModel extends BaseViewModel { @@ -263,6 +263,13 @@ export class PageViewModel extends BaseViewModel {
263 }) 263 })
264 } 264 }
265 265
  266 + /**
  267 + *
  268 + * @param type 1:正在直播,2:预告
  269 + * @param pageNum
  270 + * @param pageSize
  271 + * @returns
  272 + */
266 async getLiveMoreUrl(type: number, pageNum: number, pageSize: number): Promise<LiveReviewDTO> { 273 async getLiveMoreUrl(type: number, pageNum: number, pageSize: number): Promise<LiveReviewDTO> {
267 return new Promise<LiveReviewDTO>((success, error) => { 274 return new Promise<LiveReviewDTO>((success, error) => {
268 Logger.info(TAG, `getLiveMoreUrl pageInfo start`); 275 Logger.info(TAG, `getLiveMoreUrl pageInfo start`);
@@ -363,21 +370,22 @@ export class PageViewModel extends BaseViewModel { @@ -363,21 +370,22 @@ export class PageViewModel extends BaseViewModel {
363 async getPageGroupCacheData(pageModel: PageUIReqBean): Promise<PageDTO | null> { 370 async getPageGroupCacheData(pageModel: PageUIReqBean): Promise<PageDTO | null> {
364 Logger.debug(TAG, 'getPageData pageId: ' + pageModel.pageId); 371 Logger.debug(TAG, 'getPageData pageId: ' + pageModel.pageId);
365 return new Promise<PageDTO | null>((success) => { 372 return new Promise<PageDTO | null>((success) => {
366 - CacheData.getLocalCacheData(CacheData.compGroupInfoDataCacheKey + pageModel.pageId + pageModel.groupId).then((data) => {  
367 - // Logger.debug(TAG, 'getPageGroupCacheData 333 ' + JSON.stringify(data));  
368 - if (data) {  
369 - let navBean = JSON.parse(CacheData.getNetworkData(data)) as PageDTO  
370 - success(navBean)  
371 - } else { 373 + CacheData.getLocalCacheData(CacheData.compGroupInfoDataCacheKey + pageModel.pageId + pageModel.groupId)
  374 + .then((data) => {
  375 + // Logger.debug(TAG, 'getPageGroupCacheData 333 ' + JSON.stringify(data));
  376 + if (data) {
  377 + let navBean = JSON.parse(CacheData.getNetworkData(data)) as PageDTO
  378 + success(navBean)
  379 + } else {
  380 + success(null)
  381 + }
  382 + })
  383 + .catch((err: object) => {
  384 + Logger.error(TAG, 'getPageGroupCacheData catch err: ' + JSON.stringify(err));
372 success(null) 385 success(null)
373 - }  
374 - }).catch((err: object) => {  
375 - Logger.error(TAG, 'getPageGroupCacheData catch err: ' + JSON.stringify(err));  
376 - success(null)  
377 - }) 386 + })
378 }); 387 });
379 } 388 }
380 -  
381 } 389 }
382 390
383 391
@@ -17,6 +17,7 @@ import { componentUtils, window } from '@kit.ArkUI'; @@ -17,6 +17,7 @@ import { componentUtils, window } from '@kit.ArkUI';
17 import { PlayerFullScreenView } from '../view/PlayerFullScreenView'; 17 import { PlayerFullScreenView } from '../view/PlayerFullScreenView';
18 import { OperRowListView, publishCommentModel } from 'wdComponent/Index'; 18 import { OperRowListView, publishCommentModel } from 'wdComponent/Index';
19 import { ParamType, TrackConstants } from 'wdTracking/Index'; 19 import { ParamType, TrackConstants } from 'wdTracking/Index';
  20 +import { onlyWifiLoadVideo } from 'wdComponent/src/main/ets/utils/lazyloadImg';
20 21
21 const TAG = 'DetailPlayShortVideoPage'; 22 const TAG = 'DetailPlayShortVideoPage';
22 23
@@ -55,6 +56,8 @@ export struct DetailPlayShortVideoPage { @@ -55,6 +56,8 @@ export struct DetailPlayShortVideoPage {
55 @State playerHeight: number | string = px2vp(this.windowHeight) 56 @State playerHeight: number | string = px2vp(this.windowHeight)
56 pageParam: ParamType = {} 57 pageParam: ParamType = {}
57 PageName: string = '' 58 PageName: string = ''
  59 + @State toastText: ResourceStr = "正在使用非WI-FI网络,播放将产生流量费用"
  60 + @Consume onlyWifiLoadVideo: boolean
58 61
59 /** 62 /**
60 * 页面显示重查用户关注、点赞等信息 63 * 页面显示重查用户关注、点赞等信息
@@ -62,7 +65,7 @@ export struct DetailPlayShortVideoPage { @@ -62,7 +65,7 @@ export struct DetailPlayShortVideoPage {
62 async pageShowChange() { 65 async pageShowChange() {
63 if (this.currentIndex === this.index) { 66 if (this.currentIndex === this.index) {
64 this.queryNewsInfoOfUser() 67 this.queryNewsInfoOfUser()
65 - if (this.switchVideoStatus && this.isPlay) { 68 + if (this.switchVideoStatus && this.isPlay && this.onlyWifiLoadVideo) {
66 await this.playerController.play() 69 await this.playerController.play()
67 this.imageVisible = false 70 this.imageVisible = false
68 } 71 }
@@ -75,7 +78,7 @@ export struct DetailPlayShortVideoPage { @@ -75,7 +78,7 @@ export struct DetailPlayShortVideoPage {
75 */ 78 */
76 async videoStatusChange() { 79 async videoStatusChange() {
77 if (this.currentIndex === this.index) { 80 if (this.currentIndex === this.index) {
78 - if (this.switchVideoStatus && this.isPlay) { 81 + if (this.switchVideoStatus && this.isPlay && this.onlyWifiLoadVideo) {
79 await this.playerController.play() 82 await this.playerController.play()
80 this.imageVisible = false 83 this.imageVisible = false
81 } else { 84 } else {
@@ -99,9 +102,18 @@ export struct DetailPlayShortVideoPage { @@ -99,9 +102,18 @@ export struct DetailPlayShortVideoPage {
99 if (!this.playerController.getPlayer()) { 102 if (!this.playerController.getPlayer()) {
100 this.playerController.firstPlay(this.contentDetailData?.videoInfo[0]?.videoUrl || '', this.PageName, 103 this.playerController.firstPlay(this.contentDetailData?.videoInfo[0]?.videoUrl || '', this.PageName,
101 this.PageName, this.pageParam); 104 this.PageName, this.pageParam);
  105 + this.playerController.onCanplay = async () => {
  106 + this.ratio = this.playerController.videoWidth / this.playerController.videoHeight
  107 + await this.playerController.play()
  108 + this.imageVisible = false
  109 + }
102 } else { 110 } else {
103 - await this.playerController.play()  
104 - this.imageVisible = false 111 + if (!this.onlyWifiLoadVideo) {
  112 + await this.playerController.pause()
  113 + } else {
  114 + await this.playerController.play()
  115 + this.imageVisible = false
  116 + }
105 } 117 }
106 } 118 }
107 } 119 }
@@ -156,15 +168,22 @@ export struct DetailPlayShortVideoPage { @@ -156,15 +168,22 @@ export struct DetailPlayShortVideoPage {
156 168
157 } 169 }
158 170
159 - aboutToAppear() { 171 + async aboutToAppear() {
  172 + if(await onlyWifiLoadVideo()){
  173 + this.onlyWifiLoadVideo = true
  174 + }
160 this.videoLandScape = this.contentDetailData.videoInfo[0]?.videoLandScape 175 this.videoLandScape = this.contentDetailData.videoInfo[0]?.videoLandScape
161 this.ratio = (this.contentDetailData.videoInfo[0]?.resolutionWidth || 16) / 176 this.ratio = (this.contentDetailData.videoInfo[0]?.resolutionWidth || 16) /
162 (this.contentDetailData.videoInfo[0]?.resolutionHeight || 9) 177 (this.contentDetailData.videoInfo[0]?.resolutionHeight || 9)
163 this.playerController.onCanplay = async () => { 178 this.playerController.onCanplay = async () => {
164 this.ratio = this.playerController.videoWidth / this.playerController.videoHeight 179 this.ratio = this.playerController.videoWidth / this.playerController.videoHeight
165 if ((this.index == 0 || this.currentIndex === this.index) && this.switchVideoStatus) { 180 if ((this.index == 0 || this.currentIndex === this.index) && this.switchVideoStatus) {
166 - await this.playerController.play()  
167 - this.imageVisible = false 181 + if (!this.onlyWifiLoadVideo) {
  182 + await this.playerController.pause()
  183 + } else {
  184 + await this.playerController.play()
  185 + this.imageVisible = false
  186 + }
168 } 187 }
169 } 188 }
170 this.playerController.onTimeUpdate = (position, duration) => { 189 this.playerController.onTimeUpdate = (position, duration) => {
@@ -261,12 +280,17 @@ export struct DetailPlayShortVideoPage { @@ -261,12 +280,17 @@ export struct DetailPlayShortVideoPage {
261 playerController: this.playerController 280 playerController: this.playerController
262 }) 281 })
263 282
  283 + if (!this.onlyWifiLoadVideo) {
  284 + this.buildContent()
  285 + }
  286 +
264 } 287 }
265 .width('100%') 288 .width('100%')
266 .layoutWeight(1) 289 .layoutWeight(1)
267 .onClick(() => { 290 .onClick(() => {
268 this.playerController?.switchPlayOrPause(); 291 this.playerController?.switchPlayOrPause();
269 this.playerController.onStatusChange = (status: number) => { 292 this.playerController.onStatusChange = (status: number) => {
  293 + this.status = status
270 if (status === PlayerConstants.STATUS_PAUSE) { 294 if (status === PlayerConstants.STATUS_PAUSE) {
271 this.isPlay = false 295 this.isPlay = false
272 } else if(status === PlayerConstants.STATUS_START) { 296 } else if(status === PlayerConstants.STATUS_START) {
@@ -303,6 +327,51 @@ export struct DetailPlayShortVideoPage { @@ -303,6 +327,51 @@ export struct DetailPlayShortVideoPage {
303 327
304 } 328 }
305 329
  330 + @Builder
  331 + buildContent() {
  332 + Row() {
  333 + Column(){
  334 + Column(){
  335 + Text(this.toastText)
  336 + .fontFamily('PingFang SC-Regular')
  337 + .fontWeight(FontWeight.Regular)
  338 + .fontColor('#FFFFFF')
  339 + .fontSize(14)
  340 + .lineHeight(20)
  341 + .textAlign(TextAlign.Center)
  342 + }
  343 + Column() {
  344 + Text("使用流量播放")
  345 + .fontFamily('PingFang SC-Regular')
  346 + .fontWeight(FontWeight.Regular)
  347 + .fontColor(Color.White)
  348 + .fontSize(12)
  349 + }
  350 + .border({ width: 1, color: '#4DFFFFFF', radius: 4 })
  351 + .height(28)
  352 + .width(88)
  353 + .alignItems(HorizontalAlign.Center)
  354 + .justifyContent(FlexAlign.Center)
  355 + .margin({
  356 + top: 16
  357 + })
  358 + .onClick(() => {
  359 + this.onlyWifiLoadVideo = true
  360 + this.playerController?.play()
  361 + this.imageVisible = false
  362 + })
  363 + }
  364 + .width('100%')
  365 + .height(64)
  366 + }
  367 + .width('100%')
  368 + .height('100%')
  369 + .alignItems(VerticalAlign.Center)
  370 + .justifyContent(FlexAlign.Center)
  371 + .backgroundColor('#222222')
  372 + .opacity(0.7)
  373 + }
  374 +
306 /** 375 /**
307 * 视频首帧图,用于快速显示 376 * 视频首帧图,用于快速显示
308 * 竖屏封面顶部仍然有点偏移,待处理 377 * 竖屏封面顶部仍然有点偏移,待处理
@@ -39,6 +39,7 @@ export struct DetailVideoListPage { @@ -39,6 +39,7 @@ export struct DetailVideoListPage {
39 @State interactDataList: InteractDataDTO[] = [] 39 @State interactDataList: InteractDataDTO[] = []
40 pageShowTime:number = 0; 40 pageShowTime:number = 0;
41 pageHideTime:number = 0; 41 pageHideTime:number = 0;
  42 + @Provide onlyWifiLoadVideo: boolean = false
42 43
43 async aboutToAppear(): Promise<void> { 44 async aboutToAppear(): Promise<void> {
44 // 注册监听网络连接 45 // 注册监听网络连接
@@ -9,12 +9,11 @@ import { @@ -9,12 +9,11 @@ import {
9 contentListParams, 9 contentListParams,
10 getRecCompInfoParams 10 getRecCompInfoParams
11 } from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest'; 11 } from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest';
12 -import { Logger, WindowModel } from 'wdKit/Index'; 12 +import { Logger, WindowModel, DateTimeUtils } from 'wdKit/Index';
13 import { PictureLoading } from './PictureLoading'; 13 import { PictureLoading } from './PictureLoading';
14 import { DisplayDirection } from 'wdConstant/Index'; 14 import { DisplayDirection } from 'wdConstant/Index';
15 import { window } from '@kit.ArkUI'; 15 import { window } from '@kit.ArkUI';
16 import { EmptyComponent, WDViewDefaultType } from 'wdComponent/Index'; 16 import { EmptyComponent, WDViewDefaultType } from 'wdComponent/Index';
17 -import { DateTimeUtils } from 'wdKit/Index';  
18 import { TrackConstants, TrackingPageBrowse } from 'wdTracking/Index'; 17 import { TrackConstants, TrackingPageBrowse } from 'wdTracking/Index';
19 18
20 interface loadMoreData { 19 interface loadMoreData {
@@ -65,6 +64,7 @@ export struct VideoChannelDetail { @@ -65,6 +64,7 @@ export struct VideoChannelDetail {
65 @State isRequesting: boolean = false 64 @State isRequesting: boolean = false
66 pageShowTime: number = 0; 65 pageShowTime: number = 0;
67 pageHideTime: number = 0; 66 pageHideTime: number = 0;
  67 + @Provide onlyWifiLoadVideo: boolean = false
68 68
69 autoRefreshChange() { 69 autoRefreshChange() {
70 if (this.topNavIndex === 0 && !this.isRequesting) { 70 if (this.topNavIndex === 0 && !this.isRequesting) {
@@ -13,6 +13,7 @@ export struct PlayerBottomView { @@ -13,6 +13,7 @@ export struct PlayerBottomView {
13 @Consume isDragging?: boolean 13 @Consume isDragging?: boolean
14 @Consume contentDetailData: ContentDetailDTO 14 @Consume contentDetailData: ContentDetailDTO
15 @Consume displayDirection: DisplayDirection 15 @Consume displayDirection: DisplayDirection
  16 + @Consume onlyWifiLoadVideo: boolean
16 17
17 aboutToAppear(): void { 18 aboutToAppear(): void {
18 19
@@ -14,11 +14,9 @@ export struct PlayerProgressView { @@ -14,11 +14,9 @@ export struct PlayerProgressView {
14 @State loadingTop: number = 10 14 @State loadingTop: number = 10
15 @State loadingWidth: number | string = 1 15 @State loadingWidth: number | string = 1
16 @State showLoading: boolean = false 16 @State showLoading: boolean = false
  17 + @Consume onlyWifiLoadVideo: boolean
17 aboutToAppear() { 18 aboutToAppear() {
18 if (this.playerController) { 19 if (this.playerController) {
19 - this.playerController.onStatusChange = (status: number) => {  
20 - this.status = status  
21 - }  
22 this.playerController.onSeekDone = (status: number) => { 20 this.playerController.onSeekDone = (status: number) => {
23 this.playerController?.play() 21 this.playerController?.play()
24 } 22 }
@@ -26,7 +24,9 @@ export struct PlayerProgressView { @@ -26,7 +24,9 @@ export struct PlayerProgressView {
26 this.playerController.onLoaded = (loaded: number) => { 24 this.playerController.onLoaded = (loaded: number) => {
27 if(loaded == 1) { 25 if(loaded == 1) {
28 this.loadingWidth = '95%' 26 this.loadingWidth = '95%'
29 - this.showLoading = true 27 + if (this.onlyWifiLoadVideo) {
  28 + this.showLoading = true
  29 + }
30 } else { 30 } else {
31 this.loadingWidth = 1 31 this.loadingWidth = 1
32 this.showLoading = false 32 this.showLoading = false
@@ -249,6 +249,8 @@ export struct PlayerRightView { @@ -249,6 +249,8 @@ export struct PlayerRightView {
249 pageID: '' 249 pageID: ''
250 } 250 }
251 WDRouterRule.jumpWithPage(WDRouterPage.peopleShipHomePage, params) 251 WDRouterRule.jumpWithPage(WDRouterPage.peopleShipHomePage, params)
  252 + } else {
  253 + ToastUtils.showToast("暂时无法查看该创作者主页", 2000);
252 } 254 }
253 }) 255 })
254 256
@@ -14,7 +14,7 @@ interface obj { @@ -14,7 +14,7 @@ interface obj {
14 @Observed 14 @Observed
15 export class WDPlayerController { 15 export class WDPlayerController {
16 private initPromise: Promise<void>; 16 private initPromise: Promise<void>;
17 - private avPlayer?: media.AVPlayer; 17 + private avPlayer?: media.AVPlayer | null;
18 private duration: number = 0; 18 private duration: number = 0;
19 private status: number = PlayerConstants.STATUS_IDLE; 19 private status: number = PlayerConstants.STATUS_IDLE;
20 private loop: boolean = true; 20 private loop: boolean = true;
@@ -196,6 +196,7 @@ export class WDPlayerController { @@ -196,6 +196,7 @@ export class WDPlayerController {
196 } 196 }
197 if (this.avPlayer == null) { 197 if (this.avPlayer == null) {
198 console.log("等待") 198 console.log("等待")
  199 + this.initPromise = this.createAVPlayer();
199 await this.initPromise; 200 await this.initPromise;
200 } else { 201 } else {
201 if (this.avPlayer.state != AVPlayerStatus.IDLE) { 202 if (this.avPlayer.state != AVPlayerStatus.IDLE) {
@@ -225,7 +226,7 @@ export class WDPlayerController { @@ -225,7 +226,7 @@ export class WDPlayerController {
225 return 226 return
226 } 227 }
227 this.avPlayer.release() 228 this.avPlayer.release()
228 - this.avPlayer = undefined 229 + this.avPlayer = null
229 230
230 } 231 }
231 232
@@ -9,35 +9,25 @@ const TAG = 'DynamicDetailPage'; @@ -9,35 +9,25 @@ const TAG = 'DynamicDetailPage';
9 @Component 9 @Component
10 struct DynamicDetailPage { 10 struct DynamicDetailPage {
11 pageShowTime:number = 0; 11 pageShowTime:number = 0;
12 - @State relId: string = ''  
13 - @State contentId: string = ''  
14 - @State relType: string = ''  
15 12
16 @Provide pageName: string = TrackConstants.PageName.DynamicDetail 13 @Provide pageName: string = TrackConstants.PageName.DynamicDetail
17 @Provide pageId: string = TrackConstants.PageName.DynamicDetail 14 @Provide pageId: string = TrackConstants.PageName.DynamicDetail
18 15
19 build() { 16 build() {
20 Column() { 17 Column() {
21 - DynamicDetailComponent({  
22 - relId: this.relId,  
23 - contentId: this.contentId,  
24 - relType: this.relType  
25 - }) 18 + DynamicDetailComponent({action: router.getParams() as Action })
26 } 19 }
27 .height('100%') 20 .height('100%')
28 .width('100%') 21 .width('100%')
29 .backgroundColor('#20272E') 22 .backgroundColor('#20272E')
30 } 23 }
31 aboutToAppear() { 24 aboutToAppear() {
32 - let par:Action = router.getParams() as Action;  
33 - let params = par?.params;  
34 - this.relId = params?.extra?.relId || '';  
35 - this.relType = params?.extra?.relType || '';  
36 - this.contentId = params?.contentID || '';  
37 } 25 }
  26 +
38 onPageShow() { 27 onPageShow() {
39 this.pageShowTime = DateTimeUtils.getTimeStamp() 28 this.pageShowTime = DateTimeUtils.getTimeStamp()
40 } 29 }
  30 +
41 onPageHide() { 31 onPageHide() {
42 //页面浏览 32 //页面浏览
43 TrackingPageBrowse.trackCommonPageExposureEnd(TrackConstants.PageName.DynamicDetail,TrackConstants.PageName.DynamicDetail,Math.floor((DateTimeUtils.getTimeStamp() - this.pageShowTime)/1000)) 33 TrackingPageBrowse.trackCommonPageExposureEnd(TrackConstants.PageName.DynamicDetail,TrackConstants.PageName.DynamicDetail,Math.floor((DateTimeUtils.getTimeStamp() - this.pageShowTime)/1000))