douaojie

Merge remote-tracking branch 'origin/main'

Showing 48 changed files with 846 additions and 182 deletions
@@ -24,4 +24,6 @@ export class SpConstants{ @@ -24,4 +24,6 @@ export class SpConstants{
24 static SETTING_SUSPENSION_SWITCH = "setting_suspension_switch" //悬浮窗 开关 24 static SETTING_SUSPENSION_SWITCH = "setting_suspension_switch" //悬浮窗 开关
25 static SETTING_PUSH_SWITCH = "setting_push_switch" //推送 开关 25 static SETTING_PUSH_SWITCH = "setting_push_switch" //推送 开关
26 26
  27 + //未登录保存兴趣标签
  28 + static PUBLICVISUTORMODE_INTERESTTAGS = 'PublicVisitorMode_InterestTags'
27 } 29 }
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 * ResponseDTO 2 * ResponseDTO
3 */ 3 */
4 export interface ResponseDTO<T = string> { 4 export interface ResponseDTO<T = string> {
5 - success:boolean; 5 + success: boolean;
6 6
7 // 服务请求响应值/微服务响应状态码” 7 // 服务请求响应值/微服务响应状态码”
8 code: number; 8 code: number;
@@ -12,6 +12,7 @@ export interface ResponseDTO<T = string> { @@ -12,6 +12,7 @@ export interface ResponseDTO<T = string> {
12 12
13 // 响应结果 13 // 响应结果
14 data?: T; 14 data?: T;
  15 + totalCount?: number;
15 16
16 // 请求响应时间戳(unix格式) 17 // 请求响应时间戳(unix格式)
17 timestamp?: number; 18 timestamp?: number;
@@ -258,6 +258,10 @@ export class HttpUrlUtils { @@ -258,6 +258,10 @@ export class HttpUrlUtils {
258 * app启动页 兴趣偏好 258 * app启动页 兴趣偏好
259 */ 259 */
260 static readonly INTERESTS_HOTS_DATA_PATH: string = "/api/rmrb-user-center/user/zh/c/tag/queryTags"; 260 static readonly INTERESTS_HOTS_DATA_PATH: string = "/api/rmrb-user-center/user/zh/c/tag/queryTags";
  261 + /**
  262 + * 更新 兴趣偏好
  263 + */
  264 + static readonly INTERESTS_UPDATETAG_PATH: string = "/api/rmrb-user-center/user/zh/c/tag/updateUserTag";
261 265
262 266
263 private static _hostUrl: string = HttpUrlUtils.HOST_PRODUCT; 267 private static _hostUrl: string = HttpUrlUtils.HOST_PRODUCT;
@@ -663,6 +667,11 @@ export class HttpUrlUtils { @@ -663,6 +667,11 @@ export class HttpUrlUtils {
663 667
664 } 668 }
665 669
  670 + static getUpdateInterestsUrl() {
  671 + let url = HttpUrlUtils._hostUrl + HttpUrlUtils.INTERESTS_UPDATETAG_PATH;
  672 + return url;
  673 + }
  674 +
666 static getLiveDetailsUrl() { 675 static getLiveDetailsUrl() {
667 let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_DETAILS_PATH 676 let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_DETAILS_PATH
668 return url 677 return url
@@ -43,6 +43,7 @@ export class WDRouterPage { @@ -43,6 +43,7 @@ export class WDRouterPage {
43 static detailPlayVodPage = new WDRouterPage("wdDetailPlayVod", "ets/pages/DetailPlayVodPage"); 43 static detailPlayVodPage = new WDRouterPage("wdDetailPlayVod", "ets/pages/DetailPlayVodPage");
44 // 直播详情页 44 // 直播详情页
45 static detailPlayLivePage = new WDRouterPage("wdDetailPlayLive", "ets/pages/DetailPlayLivePage"); 45 static detailPlayLivePage = new WDRouterPage("wdDetailPlayLive", "ets/pages/DetailPlayLivePage");
  46 + static detailPlayVLivePage = new WDRouterPage("wdDetailPlayLive", "ets/pages/DetailPlayVLivePage");
46 // 多图(图集)详情页 47 // 多图(图集)详情页
47 static multiPictureDetailPage = new WDRouterPage("phone", "ets/pages/detail/MultiPictureDetailPage"); 48 static multiPictureDetailPage = new WDRouterPage("phone", "ets/pages/detail/MultiPictureDetailPage");
48 // 音乐详情页 49 // 音乐详情页
@@ -167,16 +167,19 @@ export interface LiveDetailsBean { @@ -167,16 +167,19 @@ export interface LiveDetailsBean {
167 } 167 }
168 168
169 export interface LiveInfo { 169 export interface LiveInfo {
170 - //直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停 170 + //直播新闻-直播状态 wait 待开播 running 直播中 end 已结束cancel已取消paused暂停
171 liveState: string 171 liveState: string
172 //2024-04-12 15:00:00 直播开始时间 172 //2024-04-12 15:00:00 直播开始时间
173 planStartTime: string 173 planStartTime: string
  174 + liveStyle: number;
174 vlive: Array<Vlive> 175 vlive: Array<Vlive>
175 - mlive:MLive 176 + mlive: MLive
176 } 177 }
  178 +
177 export interface MLive { 179 export interface MLive {
178 - mliveId:string 180 + mliveId: string
179 } 181 }
  182 +
180 export interface FullColumnImgUrls { 183 export interface FullColumnImgUrls {
181 url: string 184 url: string
182 } 185 }
@@ -63,3 +63,5 @@ export { SpacialTopicPageComponent } from './src/main/ets/components/SpacialTopi @@ -63,3 +63,5 @@ export { SpacialTopicPageComponent } from './src/main/ets/components/SpacialTopi
63 63
64 export { LogoutViewModel } from "./src/main/ets/viewmodel/LogoutViewModel" 64 export { LogoutViewModel } from "./src/main/ets/viewmodel/LogoutViewModel"
65 65
  66 +export { newsSkeleton } from "./src/main/ets/components/skeleton/newsSkeleton"
  67 +
@@ -35,63 +35,63 @@ export struct DynamicDetailComponent { @@ -35,63 +35,63 @@ export struct DynamicDetailComponent {
35 //logo、日期 35 //logo、日期
36 Row() { 36 Row() {
37 Image($r('app.media.ic_article_rmh')) 37 Image($r('app.media.ic_article_rmh'))
38 - .width(80)  
39 - .height(28)  
40 - .margin({ left: 16 }) 38 + .width($r('app.float.margin_80'))
  39 + .height($r('app.float.margin_28'))
  40 + .margin({ left: $r('app.float.margin_16') })
41 Blank() 41 Blank()
42 Text("2023年03月14日 08:16") 42 Text("2023年03月14日 08:16")
43 .fontColor($r('app.color.color_B0B0B0')) 43 .fontColor($r('app.color.color_B0B0B0'))
44 - .fontSize(12)  
45 - .lineHeight(28)  
46 - .margin({ right: 16 }) 44 + .fontSize($r('app.float.font_size_12'))
  45 + .lineHeight($r('app.float.margin_28'))
  46 + .margin({ right: $r('app.float.margin_16') })
47 } 47 }
48 - .height(48) 48 + .height($r('app.float.margin_48'))
49 .width('100%') 49 .width('100%')
50 //分割线 50 //分割线
51 Image($r('app.media.ic_news_detail_division')) 51 Image($r('app.media.ic_news_detail_division'))
52 .width('100%') 52 .width('100%')
53 - .height(7)  
54 - .margin({left: 16, right: 16} ) 53 + .height($r('app.float.margin_7'))
  54 + .margin({left: $r('app.float.margin_16'), right: $r('app.float.margin_16')} )
55 //号主信息 55 //号主信息
56 Row() { 56 Row() {
57 //头像 57 //头像
58 Stack() { 58 Stack() {
59 Image(this.contentDetailData.rmhInfo?.rmhHeadUrl) 59 Image(this.contentDetailData.rmhInfo?.rmhHeadUrl)
60 .alt(this.contentDetailData.rmhInfo?.userType=='1'?$r('app.media.default_head'):$r('app.media.icon_default_head_mater')) 60 .alt(this.contentDetailData.rmhInfo?.userType=='1'?$r('app.media.default_head'):$r('app.media.icon_default_head_mater'))
61 - .width('32')  
62 - .height('32') 61 + .width($r('app.float.margin_32'))
  62 + .height($r('app.float.margin_32'))
63 .objectFit(ImageFit.Cover) 63 .objectFit(ImageFit.Cover)
64 - .borderRadius(16) 64 + .borderRadius($r('app.float.margin_16'))
65 Image($r('app.media.icon_border_test')) 65 Image($r('app.media.icon_border_test'))
66 - .width('48')  
67 - .height('48') 66 + .width($r('app.float.margin_48'))
  67 + .height($r('app.float.margin_48'))
68 .objectFit(ImageFit.Cover) 68 .objectFit(ImageFit.Cover)
69 - .borderRadius(24) 69 + .borderRadius($r('app.float.margin_24'))
70 } 70 }
71 - .width(48)  
72 - .height(48) 71 + .width($r('app.float.margin_48'))
  72 + .height($r('app.float.margin_48'))
73 .alignContent(Alignment.Center) 73 .alignContent(Alignment.Center)
74 Column(){ 74 Column(){
75 //昵称 75 //昵称
76 Text("this.contentDetailData.rmhInfo?.rmhName") 76 Text("this.contentDetailData.rmhInfo?.rmhName")
77 - .fontSize(14) 77 + .fontSize($r('app.float.font_size_14'))
78 .fontColor($r('app.color.color_222222')) 78 .fontColor($r('app.color.color_222222'))
79 .fontWeight(FontWeight.Medium) 79 .fontWeight(FontWeight.Medium)
80 - .margin({ left: 5 }) 80 + .margin({ left: $r('app.float.margin_5') })
81 //简介 81 //简介
82 Text("this.contentDetailData.rmhInfo?.rmhDesc") 82 Text("this.contentDetailData.rmhInfo?.rmhDesc")
83 - .fontSize(14) 83 + .fontSize($r('app.float.font_size_14'))
84 .fontColor($r('app.color.color_B0B0B0')) 84 .fontColor($r('app.color.color_B0B0B0'))
85 .fontWeight(FontWeight.Medium) 85 .fontWeight(FontWeight.Medium)
86 - .margin({ left: 5 }) 86 + .margin({ left: $r('app.float.margin_5') })
87 } 87 }
88 if (!this.followStatus) { 88 if (!this.followStatus) {
89 Text('关注') 89 Text('关注')
90 .width(60) 90 .width(60)
91 - .height(24) 91 + .height($r('app.float.margin_48'))
92 .textAlign(TextAlign.Center) 92 .textAlign(TextAlign.Center)
93 .fontSize($r('app.float.font_size_12')) 93 .fontSize($r('app.float.font_size_12'))
94 - .borderRadius($r('app.float.button_border_radius')) 94 + .borderRadius($r('app.float.vp_3'))
95 .backgroundColor($r('app.color.color_ED2800')) 95 .backgroundColor($r('app.color.color_ED2800'))
96 .fontColor($r('app.color.color_fff')) 96 .fontColor($r('app.color.color_fff'))
97 .onClick(() => { 97 .onClick(() => {
@@ -99,12 +99,12 @@ export struct DynamicDetailComponent { @@ -99,12 +99,12 @@ export struct DynamicDetailComponent {
99 }) 99 })
100 } else { 100 } else {
101 Text('已关注') 101 Text('已关注')
102 - .width(60)  
103 - .height(24) 102 + .width($r('app.float.margin_60'))
  103 + .height($r('app.float.margin_48'))
104 .borderWidth(1) 104 .borderWidth(1)
105 .textAlign(TextAlign.Center) 105 .textAlign(TextAlign.Center)
106 .fontSize($r('app.float.font_size_12')) 106 .fontSize($r('app.float.font_size_12'))
107 - .borderRadius($r('app.float.button_border_radius')) 107 + .borderRadius($r('app.float.vp_3'))
108 .borderColor($r('app.color.color_CCCCCC')) 108 .borderColor($r('app.color.color_CCCCCC'))
109 .fontColor($r('app.color.color_CCCCCC')) 109 .fontColor($r('app.color.color_CCCCCC'))
110 .onClick(() => { 110 .onClick(() => {
@@ -113,6 +113,53 @@ export struct DynamicDetailComponent { @@ -113,6 +113,53 @@ export struct DynamicDetailComponent {
113 } 113 }
114 } 114 }
115 .width('100%') 115 .width('100%')
  116 + //内容
  117 + Text("这里展示标题这里展示标题这里展示标题这里这里展示标题这里展示标题这里展示标题这里这里展示标题这里展示标题这里展示标题这里")
  118 + .fontColor($r('app.color.color_222222'))
  119 + .fontSize($r('app.float.font_size_18'))
  120 + .lineHeight($r('app.float.margin_25'))
  121 + .margin({ top: $r('app.float.margin_6')
  122 + ,left: $r('app.float.margin_16')
  123 + ,right: $r('app.float.margin_16') })
  124 + //特别声明
  125 + Text("特别声明:本文为人民日报新媒体平台“人民号”作者上传并发布,仅代表作者观点。人民日报仅提供信息发布平台。")
  126 + .fontColor($r('app.color.color_CCCCCC'))
  127 + .fontSize($r('app.float.font_size_12'))
  128 + .lineHeight($r('app.float.margin_16'))
  129 + .margin({ top: $r('app.float.margin_16')
  130 + ,left: $r('app.float.margin_16')
  131 + ,right: $r('app.float.margin_16') })
  132 + //微信/朋友圈/微博
  133 + Row(){
  134 + Image($r('app.media.xxhdpi_pic_wechat'))
  135 + .width($r('app.float.margin_116'))
  136 + .height($r('app.float.margin_36'))
  137 + .objectFit(ImageFit.Cover)
  138 + Image($r('app.media.xxhdpi_pic_pyq'))
  139 + .width($r('app.float.margin_116'))
  140 + .height($r('app.float.margin_36'))
  141 + .margin({ left: $r('app.float.margin_4_negative')})
  142 + .objectFit(ImageFit.Cover)
  143 + Image($r('app.media.xxhdpi_pic_wb'))
  144 + .width($r('app.float.margin_116'))
  145 + .height($r('app.float.margin_36'))
  146 + .margin({ left: $r('app.float.margin_4_negative')})
  147 + .objectFit(ImageFit.Cover)
  148 + }
  149 + .margin({ top: $r('app.float.margin_24')})
  150 + //点赞
  151 + Row(){
  152 + Image($r('app.media.icon_like_selected_redheart'))
  153 + .width($r('app.float.margin_24'))
  154 + .height($r('app.float.margin_24'))
  155 + .objectFit(ImageFit.Cover)
  156 + Text("2.6万")
  157 + .fontColor($r('app.color.color_999999'))
  158 + .fontSize($r('app.float.font_size_16'))
  159 + .lineHeight($r('app.float.margin_20'))
  160 + .margin({ left: $r('app.float.margin_2')})
  161 + }
  162 + //评论组件/底部组件
116 } 163 }
117 } 164 }
118 .backgroundColor('#FFFFFFFF') 165 .backgroundColor('#FFFFFFFF')
@@ -2,6 +2,7 @@ import { Action, NewspaperListItemBean, NewspaperPositionItemBean, Params } from @@ -2,6 +2,7 @@ import { Action, NewspaperListItemBean, NewspaperPositionItemBean, Params } from
2 import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO'; 2 import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO';
3 import { StringUtils } from 'wdKit'; 3 import { StringUtils } from 'wdKit';
4 import { WDRouterRule } from 'wdRouter'; 4 import { WDRouterRule } from 'wdRouter';
  5 +import { newsSkeleton } from './skeleton/newsSkeleton';
5 6
6 @Component 7 @Component
7 export struct ENewspaperItemComponent { 8 export struct ENewspaperItemComponent {
@@ -11,13 +12,20 @@ export struct ENewspaperItemComponent { @@ -11,13 +12,20 @@ export struct ENewspaperItemComponent {
11 private startX: number = 0 12 private startX: number = 0
12 private startY: number = 0 13 private startY: number = 0
13 private itemBeanClicked: NewspaperPositionItemBean = {} as NewspaperPositionItemBean 14 private itemBeanClicked: NewspaperPositionItemBean = {} as NewspaperPositionItemBean
  15 + @State isShowSkeleton: boolean = true
14 16
15 build() { 17 build() {
16 Stack() { 18 Stack() {
  19 + newsSkeleton()
  20 + .visibility(this.isShowSkeleton ? Visibility.Visible : Visibility.None)
17 Image(this.newspaperListItemBean.pagePic) 21 Image(this.newspaperListItemBean.pagePic)
18 .width('100%') 22 .width('100%')
19 .aspectRatio(378 / 566) 23 .aspectRatio(378 / 566)
20 .objectFit(ImageFit.Fill) 24 .objectFit(ImageFit.Fill)
  25 + .onComplete(() => {
  26 + this.isShowSkeleton = false
  27 + })
  28 + .visibility(this.isShowSkeleton ? Visibility.None : Visibility.Visible)
21 29
22 Canvas(this.context) 30 Canvas(this.context)
23 .width('100%') 31 .width('100%')
@@ -62,7 +70,7 @@ export struct ENewspaperItemComponent { @@ -62,7 +70,7 @@ export struct ENewspaperItemComponent {
62 pageID: 'IMAGE_TEXT_DETAIL', 70 pageID: 'IMAGE_TEXT_DETAIL',
63 extra: { 71 extra: {
64 relType: this.itemBeanClicked.relType ?? '', 72 relType: this.itemBeanClicked.relType ?? '',
65 - relId: ''+this.itemBeanClicked.relId, 73 + relId: '' + this.itemBeanClicked.relId,
66 sourcePage: '5' 74 sourcePage: '5'
67 } as ExtraDTO 75 } as ExtraDTO
68 } as Params, 76 } as Params,
@@ -110,11 +110,11 @@ export struct ENewspaperPageComponent { @@ -110,11 +110,11 @@ export struct ENewspaperPageComponent {
110 }) 110 })
111 111
112 Row() { 112 Row() {
113 - Text(this.calendarDate) 113 + Text(this.calendarDate?.replace('-', '.')?.replace('-', '.'))
114 .fontSize($r('app.float.font_size_20')) 114 .fontSize($r('app.float.font_size_20'))
115 .fontColor($r('app.color.white')) 115 .fontColor($r('app.color.white'))
116 .fontFamily('BebasNeue_Regular') 116 .fontFamily('BebasNeue_Regular')
117 - .fontWeight(FontWeight.Bold) 117 + .fontWeight(FontWeight.Regular)
118 118
119 Image($r('app.media.icon_triangle')) 119 Image($r('app.media.icon_triangle'))
120 .width($r('app.float.border_radius_6')) 120 .width($r('app.float.border_radius_6'))
@@ -167,6 +167,7 @@ export struct ENewspaperPageComponent { @@ -167,6 +167,7 @@ export struct ENewspaperPageComponent {
167 .autoPlay(false) 167 .autoPlay(false)
168 .cachedCount(3) 168 .cachedCount(3)
169 .indicator(false) 169 .indicator(false)
  170 + .loop(false)
170 .displayCount(1) 171 .displayCount(1)
171 .margin({ top: 35, left: 10, right: 10 }) 172 .margin({ top: 35, left: 10, right: 10 })
172 .id('e_newspaper_content') 173 .id('e_newspaper_content')
@@ -191,12 +192,13 @@ export struct ENewspaperPageComponent { @@ -191,12 +192,13 @@ export struct ENewspaperPageComponent {
191 .id('e_newspaper_shadow') 192 .id('e_newspaper_shadow')
192 193
193 Row() { 194 Row() {
194 - Text('滑动查看下一版') 195 + Text(this.swiperIndex + 1 == this.newspaperListBean?.list?.length ? '已到底部,可以选择其他日期' : '滑动查看下一版')
195 .fontColor(Color.White) 196 .fontColor(Color.White)
196 .fontSize($r('app.float.font_size_14')) 197 .fontSize($r('app.float.font_size_14'))
197 Image($r('app.media.icon_next_page')) 198 Image($r('app.media.icon_next_page'))
198 .width($r('app.float.vp_16')) 199 .width($r('app.float.vp_16'))
199 .height($r('app.float.vp_16')) 200 .height($r('app.float.vp_16'))
  201 + .visibility(this.swiperIndex + 1 == this.newspaperListBean?.list?.length ? Visibility.None : Visibility.Visible)
200 } 202 }
201 .justifyContent(FlexAlign.Center) 203 .justifyContent(FlexAlign.Center)
202 .margin({ top: $r('app.float.margin_16') }) 204 .margin({ top: $r('app.float.margin_16') })
1 import { CompDTO, ContentDTO } from 'wdBean'; 1 import { CompDTO, ContentDTO } from 'wdBean';
2 import { CommonConstants } from 'wdConstant/Index'; 2 import { CommonConstants } from 'wdConstant/Index';
  3 +import { CollectionUtils, DateTimeUtils, Logger, StringUtils, ToastUtils } from 'wdKit/Index';
  4 +import PageViewModel from '../../viewmodel/PageViewModel';
3 5
4 const TAG = 'Zh_Grid_Layout-02'; 6 const TAG = 'Zh_Grid_Layout-02';
5 const FULL_PARENT: string = '100%'; 7 const FULL_PARENT: string = '100%';
@@ -11,46 +13,76 @@ let listSize: number = 2; @@ -11,46 +13,76 @@ let listSize: number = 2;
11 * Zh_Grid_Layout-02 13 * Zh_Grid_Layout-02
12 * 14 *
13 */ 15 */
14 -@Preview  
15 @Component 16 @Component
16 export struct ZhGridLayout02 { 17 export struct ZhGridLayout02 {
17 @State compDTO: CompDTO = {} as CompDTO 18 @State compDTO: CompDTO = {} as CompDTO
  19 + @State operDataList: ContentDTO[] = []
  20 + currentPage = 1
  21 + pageSize = 12
18 22
19 aboutToAppear() { 23 aboutToAppear() {
20 - if (this.compDTO.operDataList) {  
21 - listSize = this.compDTO.operDataList.length > 5 ? 2 : this.compDTO.operDataList.length;  
22 - } 24 + Logger.debug(TAG, 'aboutToAppear ' + this.compDTO.objectTitle)
  25 + this.currentPage = 1
  26 + PageViewModel.getLiveReviewUrl(this.currentPage, this.pageSize).then((liveReviewDTO) => {
  27 + this.operDataList = []
  28 + this.operDataList.push(...liveReviewDTO.list)
  29 + })
23 } 30 }
24 31
25 build() { 32 build() {
26 Column() { 33 Column() {
27 - Row() {  
28 - Image($r("app.media.redLine"))  
29 - .width(3)  
30 - .height(16)  
31 - .margin({ right: 4 })  
32 - Text(this.compDTO.objectTitle)  
33 - .fontSize($r("app.float.font_size_17"))  
34 - .fontColor($r("app.color.color_222222"))  
35 - .fontWeight(600)  
36 - }  
37 - .justifyContent(FlexAlign.Start)  
38 - .margin({ top: 8, bottom: 8 })  
39 - .width(CommonConstants.FULL_WIDTH)  
40 34
41 35
42 - GridRow({  
43 - columns: { sm: listSize, md: 2 },  
44 - breakpoints: { value: ['320vp', '520vp', '840vp'] }  
45 - }) {  
46 - ForEach(this.compDTO.operDataList, (item: ContentDTO, index: number) => {  
47 - GridCol() {  
48 - this.buildItemCard(this.compDTO.operDataList[index]); 36 + Scroll() {
  37 + Column() {
  38 + Row() {
  39 + Image($r("app.media.redLine"))
  40 + .width(3)
  41 + .height(16)
  42 + .margin({ right: 4 })
  43 + Text(this.compDTO.objectTitle)
  44 + .fontSize($r("app.float.font_size_17"))
  45 + .fontColor($r("app.color.color_222222"))
  46 + .fontWeight(600)
  47 + }
  48 + .justifyContent(FlexAlign.Start)
  49 + .margin({ top: 8, bottom: 8 })
  50 + .width(CommonConstants.FULL_WIDTH)
  51 +
  52 + GridRow({
  53 + columns: { sm: listSize, md: 2 },
  54 + breakpoints: { value: ['320vp', '520vp', '840vp'] }
  55 + }) {
  56 + ForEach(this.operDataList, (item: ContentDTO, index: number) => {
  57 + GridCol() {
  58 + this.buildItemCard(item);
  59 + }
  60 + })
49 } 61 }
50 - }) 62 + }
  63 +
51 } 64 }
  65 + .width("100%")
  66 + .height("100%")
  67 + // .layoutWeight(1)
  68 + .edgeEffect(EdgeEffect.None)
  69 + .scrollBar(BarState.Off)
  70 + .onReachStart(() => {
  71 + Logger.debug(TAG, 'onReachStart')
  72 + })
  73 + .onReachEnd(() => {
  74 + Logger.debug(TAG, 'onReachEnd')
  75 + this.addItems()
  76 + })
  77 + .nestedScroll({
  78 + scrollForward: NestedScrollMode.PARENT_FIRST,
  79 + scrollBackward: NestedScrollMode.SELF_FIRST
  80 + })
52 } 81 }
53 .width(CommonConstants.FULL_WIDTH) 82 .width(CommonConstants.FULL_WIDTH)
  83 + // .width("100%")
  84 + .height("100%")
  85 + // .layoutWeight(1)
54 .padding({ 86 .padding({
55 top: 14, 87 top: 14,
56 left: 16, 88 left: 16,
@@ -78,6 +110,15 @@ export struct ZhGridLayout02 { @@ -78,6 +110,15 @@ export struct ZhGridLayout02 {
78 } 110 }
79 .width('100%') 111 .width('100%')
80 } 112 }
  113 +
  114 + addItems() {
  115 + Logger.debug(TAG, 'addItems')
  116 + this.currentPage++
  117 + PageViewModel.getLiveReviewUrl(this.currentPage, this.pageSize).then((liveReviewDTO) => {
  118 + this.operDataList.push(...liveReviewDTO.list)
  119 + Logger.debug(TAG, 'addItems after: ' + this.operDataList.length)
  120 + })
  121 + }
81 } 122 }
82 123
83 124
  1 +import { CompDTO, ContentDTO, Params } from 'wdBean';
  2 +import { WDRouterPage, WDRouterRule } from 'wdRouter/Index';
  3 +import { HttpUrlUtils } from 'wdNetwork/Index';
  4 +import { postInteractAccentionOperateParams } from 'wdBean';
  5 +import { PageRepository } from '../repository/PageRepository';
  6 +import { CommonConstants } from 'wdConstant/Index';
  7 +
  8 +/**
  9 + * 精选评论卡
  10 + * Zh_Single_Row-06
  11 + */
  12 +const TAG = 'Zh_Single_Row-06'
  13 +
  14 +@Entry
  15 +@Component
  16 +export struct ZhSingleRow06 {
  17 + @State compDTO: CompDTO = {} as CompDTO
  18 + @State list: Array<string> = ['社会', '三个字', '是四个字', '时事', '社会', '三个字', '是四个字', '时事']
  19 + @State activeIndexs: Array<number> = []
  20 +
  21 + getItemWidth(index: number) {
  22 + if (index % 4 === 0 || index % 4 === 3) {
  23 + return 80
  24 + } else {
  25 + return 96
  26 + }
  27 + }
  28 +
  29 + build() {
  30 + Column() {
  31 + //顶部
  32 + this.CompHeader(this.compDTO)
  33 + Grid() {
  34 + ForEach(this.list, (item: string, index: number) => {
  35 + GridItem() {
  36 + Text(item)
  37 + .fontSize(14)
  38 + .fontColor(this.activeIndexs.includes(index) ? 0x222222 : 0x666666)
  39 + .fontWeight(this.activeIndexs.includes(index) ? 600 : 400)
  40 + .textAlign(TextAlign.Center)
  41 + }
  42 + .onClick(() => {
  43 + if (this.activeIndexs.includes(index)) {
  44 + const ind = this.activeIndexs.indexOf(index);
  45 + this.activeIndexs.splice(ind, 1)
  46 + } else {
  47 + this.activeIndexs.push(index)
  48 + }
  49 + })
  50 + })
  51 + }
  52 + .height(70)
  53 + .columnsTemplate('1fr 1fr 1fr 1fr')
  54 + .rowsTemplate('1fr 1fr')
  55 + .margin({bottom: 10})
  56 +
  57 +
  58 + Text('选中标签,为您推荐更多您感兴趣的内容')
  59 + .fontSize(12)
  60 + .fontColor(0xB0B0B0)
  61 + .textAlign(TextAlign.Center)
  62 + .margin({bottom: 10})
  63 +
  64 + Row() {
  65 + Text('选好了')
  66 + .fontSize(14)
  67 + .fontColor(0x000000)
  68 + .width('100%')
  69 + .textAlign(TextAlign.Center)
  70 + }
  71 + .height(40)
  72 + .backgroundColor(0xf9f9f9)
  73 + .width('100%')
  74 + .borderRadius(3)
  75 + }
  76 + .padding({
  77 + left: $r('app.float.card_comp_pagePadding_lf'),
  78 + right: $r('app.float.card_comp_pagePadding_lf'),
  79 + top: $r('app.float.card_comp_pagePadding_tb'),
  80 + bottom: $r('app.float.card_comp_pagePadding_tb')
  81 + })
  82 + .backgroundColor($r('app.color.white'))
  83 + .margin({ bottom: 8 })
  84 +
  85 + }
  86 +
  87 + @Builder
  88 + CompHeader(item: CompDTO) {
  89 + Row() {
  90 + Row() {
  91 + Image($r("app.media.icon_interest_ask"))
  92 + .width(24)
  93 + .height(24)
  94 + .margin({ right: 4 })
  95 + Text('以下是否有您感兴趣?')
  96 + .fontSize($r("app.float.font_size_17"))
  97 + .fontColor(0x000000)
  98 + .fontWeight(600)
  99 + }
  100 +
  101 + Row() {
  102 + Image($r("app.media.close_button"))
  103 + .width(14)
  104 + .height(14)
  105 + .onClick(() => {
  106 + })
  107 + }
  108 + .padding({
  109 + right: $r('app.float.card_comp_pagePadding_lf'),
  110 + })
  111 + }
  112 + .justifyContent(FlexAlign.SpaceBetween)
  113 + .margin({ top: 8, bottom: 8 })
  114 + .width('100%')
  115 + }
  116 +}
  117 +
  118 +@Extend(Text)
  119 +function textOverflowStyle(maxLine: number) {
  120 + .maxLines(maxLine)
  121 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  122 +}
  123 +
  124 +@Component
  125 +struct CreatorItem {
  126 + @Prop item: ContentDTO
  127 + @State rmhIsAttention: number = 0
  128 + build() {
  129 + ListItem() {
  130 + Column() {
  131 + Flex({direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween}) {
  132 + Column() {
  133 + Row() {
  134 + Image('')
  135 + .width(20)
  136 + .height(20)
  137 + .margin({right: 4})
  138 + .border({width: 1, color: 0xcccccc, radius: 10})
  139 + Text('立志之间')
  140 + .fontColor(0x212228)
  141 + .fontSize(12)
  142 + }
  143 + }
  144 +
  145 + Column() {
  146 + Row() {
  147 + Image($r('app.media.icon_like_no'))
  148 + .width(16)
  149 + .height(16)
  150 + .margin({right: 4})
  151 + Text('3835')
  152 + .fontSize(14)
  153 + .fontColor(0x999999)
  154 + }
  155 + }
  156 + }
  157 + .margin({top: 10, left: 10, right: 10, bottom: 8})
  158 +
  159 + Text('就业不仅是民生问题,也是发展问题,就业不仅是民生问题,也是发展问题,就业不仅是民生问题,也是发展问题,')
  160 + .maxLines(2)
  161 + .textOverflow({overflow: TextOverflow.Ellipsis})
  162 + .margin({left: 10, right: 10, bottom: 8})
  163 + .fontSize(17)
  164 + .fontColor(0x212228)
  165 + .lineHeight(25)
  166 +
  167 + Row() {
  168 + Image('')
  169 + .width(66)
  170 + .height(44)
  171 + .borderRadius({topLeft: 3, topRight: 0, bottomLeft: 3, bottomRight: 0})
  172 + Text('原文|强化就业优先政策 健全就业促进机制原文|强化就业优先政策 健全就业促进机制原文|强化就业优先政策 健全就业促进机制')
  173 + .margin({left: 8})
  174 + .width(172)
  175 + .maxLines(2)
  176 + .textOverflow({overflow: TextOverflow.Ellipsis})
  177 + }
  178 + .linearGradient({
  179 + direction: GradientDirection.Right,
  180 + colors: [[0xffffff, 0.0],[0xffffff, 0.8], [0xf9f9f9, 1.0]]
  181 + })
  182 + }
  183 + .width(276)
  184 + .height(150)
  185 + .margin({ right: 10 })
  186 + .borderWidth(1)
  187 + .borderColor($r('app.color.color_EDEDED'))
  188 + .borderRadius($r('app.float.image_border_radius'))
  189 + .backgroundColor(0xf9f9f9)
  190 + }
  191 + .onClick(() => {
  192 + console.log('跳转到rmh');
  193 + })
  194 + }
  195 +
  196 + /**
  197 + * 关注号主 TODO 这里后面需要抽离
  198 + */
  199 + handleAccention(item: ContentDTO, status: number) {
  200 + this.rmhIsAttention = this.rmhIsAttention ? 0 : 1
  201 + return
  202 + // 未登录,跳转登录
  203 + if (!HttpUrlUtils.getUserId()) {
  204 + WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
  205 + return
  206 + }
  207 +
  208 + const params: postInteractAccentionOperateParams = {
  209 + attentionUserType: item.rmhInfo?.userType || '', //被关注用户类型(1 普通用户 2 视频号 3 矩阵号)
  210 + attentionUserId: item.rmhInfo?.userId || '', // 被关注用户号主id
  211 + attentionCreatorId: item.rmhInfo?.rmhId || '', // 被关注用户号主id
  212 + // userType: 1,
  213 + // userId: '1', // TODO 用户id需要从本地获取
  214 + status: status,
  215 + }
  216 + PageRepository.postInteractAccentionOperate(params).then(res => {
  217 + console.log(TAG, '关注号主==', JSON.stringify(res.data))
  218 + if (status === 1) {
  219 + this.rmhIsAttention = 0
  220 + } else {
  221 + this.rmhIsAttention = 1
  222 + }
  223 + })
  224 + }
  225 +}
@@ -77,11 +77,13 @@ export struct PageComponent { @@ -77,11 +77,13 @@ export struct PageComponent {
77 refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullUpLoad, this.pageModel.pullUpLoadImage, 77 refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullUpLoad, this.pageModel.pullUpLoadImage,
78 this.pageModel.pullUpLoadText, this.pageModel.pullUpLoadHeight) 78 this.pageModel.pullUpLoadText, this.pageModel.pullUpLoadHeight)
79 }) 79 })
80 - } else { 80 + } else if (!this.pageModel.contentNeedScroll) {
81 NoMoreLayout() 81 NoMoreLayout()
82 } 82 }
83 } 83 }
84 } 84 }
  85 + // comp自己处理分页,这里设置EdgeEffect.None
  86 + .edgeEffect(this.pageModel.contentNeedScroll ? EdgeEffect.None : EdgeEffect.Spring)
85 .scrollBar(BarState.Off) 87 .scrollBar(BarState.Off)
86 .cachedCount(8) 88 .cachedCount(8)
87 .height(CommonConstants.FULL_PARENT) 89 .height(CommonConstants.FULL_PARENT)
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 4
5 @Entry 5 @Entry
6 @Component 6 @Component
7 -export struct detailedSkeleton { 7 +export struct newsSkeleton {
8 @State quantity: Array<number> = [1, 2, 3,] 8 @State quantity: Array<number> = [1, 2, 3,]
9 9
10 build() { 10 build() {
1 -import { CommonConstants } from 'wdConstant'  
2 -import { CompDTO } from 'wdBean' 1 +import { Action, CompDTO, ContentDTO, Params } from 'wdBean'
  2 +import { WDRouterRule } from 'wdRouter/Index'
  3 +import { Logger } from 'wdKit/Index'
  4 +import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO'
3 5
4 @Component 6 @Component
5 export struct HorizontalStrokeCardThreeTwoRadioForOneComponent { 7 export struct HorizontalStrokeCardThreeTwoRadioForOneComponent {
@@ -57,5 +59,23 @@ export struct HorizontalStrokeCardThreeTwoRadioForOneComponent { @@ -57,5 +59,23 @@ export struct HorizontalStrokeCardThreeTwoRadioForOneComponent {
57 }) 59 })
58 .backgroundColor($r("app.color.white")) 60 .backgroundColor($r("app.color.white"))
59 .margin({ bottom: 8 }) 61 .margin({ bottom: 8 })
  62 + .onClick(()=>{
  63 + this.gotoLive(this.compDTO?.operDataList[0])
  64 + })
  65 + }
  66 + gotoLive(content: ContentDTO) {
  67 + let taskAction: Action = {
  68 + type: 'JUMP_DETAIL_PAGE',
  69 + params: {
  70 + detailPageType: 2,
  71 + contentID: content?.objectId,
  72 + extra: {
  73 + relType: content?.relType,
  74 + relId: content?.relId,
  75 + } as ExtraDTO
  76 + } as Params,
  77 + };
  78 + WDRouterRule.jumpWithAction(taskAction)
  79 + Logger.debug(`gotoLive, ${content.objectId}`);
60 } 80 }
61 } 81 }
@@ -4,6 +4,9 @@ import { Action, CompDTO, ContentDTO, Params } from 'wdBean' @@ -4,6 +4,9 @@ import { Action, CompDTO, ContentDTO, Params } from 'wdBean'
4 import { CommonConstants } from 'wdConstant' 4 import { CommonConstants } from 'wdConstant'
5 import { WDRouterRule } from 'wdRouter/Index' 5 import { WDRouterRule } from 'wdRouter/Index'
6 import { CardMediaInfo } from '../cardCommon/CardMediaInfo' 6 import { CardMediaInfo } from '../cardCommon/CardMediaInfo'
  7 +import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO'
  8 +import { Logger } from 'wdKit/Index'
  9 +
7 @Component 10 @Component
8 export struct LiveHorizontalCardComponent { 11 export struct LiveHorizontalCardComponent {
9 @State compDTO: CompDTO = {} as CompDTO 12 @State compDTO: CompDTO = {} as CompDTO
@@ -79,6 +82,7 @@ export struct LiveHorizontalCardComponent { @@ -79,6 +82,7 @@ export struct LiveHorizontalCardComponent {
79 .onClick(() => { 82 .onClick(() => {
80 if (item.objectType != '0') { 83 if (item.objectType != '0') {
81 console.log(item.objectId) 84 console.log(item.objectId)
  85 + this.gotoLive(item)
82 } 86 }
83 }) 87 })
84 }) 88 })
@@ -96,4 +100,19 @@ export struct LiveHorizontalCardComponent { @@ -96,4 +100,19 @@ export struct LiveHorizontalCardComponent {
96 }) 100 })
97 .backgroundColor($r("app.color.white")) 101 .backgroundColor($r("app.color.white"))
98 } 102 }
  103 + gotoLive(content: ContentDTO) {
  104 + let taskAction: Action = {
  105 + type: 'JUMP_DETAIL_PAGE',
  106 + params: {
  107 + detailPageType: 2,
  108 + contentID: content?.objectId,
  109 + extra: {
  110 + relType: content?.relType,
  111 + relId: content?.relId,
  112 + } as ExtraDTO
  113 + } as Params,
  114 + };
  115 + WDRouterRule.jumpWithAction(taskAction)
  116 + Logger.debug(`gotoLive, ${content.objectId}`);
  117 + }
99 } 118 }
1 // 视频直播直播预约 1 // 视频直播直播预约
2 import { LiveHorizontalCardForOneComponent } from './LiveHorizontalCardForOneComponent' 2 import { LiveHorizontalCardForOneComponent } from './LiveHorizontalCardForOneComponent'
3 -import { CompDTO, ContentDTO } from 'wdBean' 3 +import { Action, CompDTO, ContentDTO, Params } from 'wdBean'
4 import { CommonConstants } from 'wdConstant' 4 import { CommonConstants } from 'wdConstant'
5 -import { StringUtils } from 'wdKit/Index' 5 +import { Logger, StringUtils } from 'wdKit/Index'
6 import { CardMediaInfo } from '../cardCommon/CardMediaInfo' 6 import { CardMediaInfo } from '../cardCommon/CardMediaInfo'
  7 +import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO'
  8 +import { WDRouterRule } from 'wdRouter/Index'
  9 +
7 @Component 10 @Component
8 export struct LiveHorizontalReservationComponent { 11 export struct LiveHorizontalReservationComponent {
9 @State compDTO: CompDTO = {} as CompDTO 12 @State compDTO: CompDTO = {} as CompDTO
@@ -70,6 +73,7 @@ export struct LiveHorizontalReservationComponent { @@ -70,6 +73,7 @@ export struct LiveHorizontalReservationComponent {
70 .onClick(() => { 73 .onClick(() => {
71 if (item.objectType != '0') { 74 if (item.objectType != '0') {
72 console.log(item.objectId) 75 console.log(item.objectId)
  76 + this.gotoLive(item)
73 } 77 }
74 }) 78 })
75 }) 79 })
@@ -87,4 +91,20 @@ export struct LiveHorizontalReservationComponent { @@ -87,4 +91,20 @@ export struct LiveHorizontalReservationComponent {
87 }) 91 })
88 .backgroundColor($r("app.color.white")) 92 .backgroundColor($r("app.color.white"))
89 } 93 }
  94 +
  95 + gotoLive(content: ContentDTO) {
  96 + let taskAction: Action = {
  97 + type: 'JUMP_DETAIL_PAGE',
  98 + params: {
  99 + detailPageType: 2,
  100 + contentID: content?.objectId,
  101 + extra: {
  102 + relType: content?.relType,
  103 + relId: content?.relId,
  104 + } as ExtraDTO
  105 + } as Params,
  106 + };
  107 + WDRouterRule.jumpWithAction(taskAction)
  108 + Logger.debug(`gotoLive, ${content.objectId}`);
  109 + }
90 } 110 }
@@ -129,10 +129,13 @@ class EditInfoViewModel { @@ -129,10 +129,13 @@ class EditInfoViewModel {
129 .then((navResDTO: ResponseDTO) => { 129 .then((navResDTO: ResponseDTO) => {
130 if (navResDTO.code == 0) { 130 if (navResDTO.code == 0) {
131 promptAction.showToast({ message: '修改成功' }) 131 promptAction.showToast({ message: '修改成功' })
  132 + }else {
  133 + promptAction.showToast({ message: navResDTO.message })
132 } 134 }
133 }) 135 })
134 .catch((error: Error) => { 136 .catch((error: Error) => {
135 Logger.info(TAG,'updateUserInfo','EditInfoViewModel') 137 Logger.info(TAG,'updateUserInfo','EditInfoViewModel')
  138 + promptAction.showToast({ message: error.message })
136 }) 139 })
137 }) 140 })
138 } 141 }
1 import { PageDTO, CompDTO, PageInfoDTO } from 'wdBean'; 1 import { PageDTO, CompDTO, PageInfoDTO } from 'wdBean';
2 -import { ViewType } from 'wdConstant/Index';  
3 -import { DateTimeUtils, Logger } from 'wdKit'; 2 +import { CompStyle, ViewType } from 'wdConstant/Index';
  3 +import { CollectionUtils, DateTimeUtils, Logger } from 'wdKit';
4 import { closeRefresh } from '../utils/PullDownRefresh'; 4 import { closeRefresh } from '../utils/PullDownRefresh';
5 import PageModel from './PageModel'; 5 import PageModel from './PageModel';
6 import PageViewModel from './PageViewModel'; 6 import PageViewModel from './PageViewModel';
@@ -65,39 +65,33 @@ export class PageHelper { @@ -65,39 +65,33 @@ export class PageHelper {
65 } else { 65 } else {
66 pageModel.hasMore = false; 66 pageModel.hasMore = false;
67 } 67 }
  68 +
  69 + // TODO 暂时去掉互动数据,待优化。(主要是互动数据返回,如何渲染到ui上)
  70 + // TODO updateItems(sizeBefore, data),这里可能有时序问题,导致覆盖别的group数据,需要优化,考虑精准替换
68 // 二次请求,批查互动数据 71 // 二次请求,批查互动数据
69 - PageViewModel.getInteractData(pageDto.compList).then((data: CompDTO[]) => {  
70 - // 刷新,替换所有数据  
71 - // pageModel.compList.replaceAll(...data)  
72 - pageModel.compList.updateItems(sizeBefore, data)  
73 - pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()  
74 - })  
75 - // TODO 待优化,解决content级别的展现加载 72 + // PageViewModel.getInteractData(pageDto.compList).then((data: CompDTO[]) => {
  73 + // // 刷新,替换所有数据
  74 + // // pageModel.compList.replaceAll(...data)
  75 + // pageModel.compList.updateItems(sizeBefore, data)
  76 + // pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
  77 + // })
  78 + // content级别的展现加载丢给comp自己,这里只需要处理屏蔽分页加载,pageModel.pageScroll
76 if (isLastGroup) { 79 if (isLastGroup) {
77 closeRefresh(pageModel, true); 80 closeRefresh(pageModel, true);
78 - // // 最后一个楼层,特殊处理  
79 - // // 检测楼层最后一个组件业务数据是否需要通过访问接口获取  
80 - // let comp: CompDTO = pageDto.compList[pageDto.compList.length - 1]  
81 - // let compSize = CollectionUtils.getListSize(comp.operDataList)  
82 - // // 直播回放,需要二次请求数据  
83 - // if (compSize <= 0 && comp.dataSourceType == 'LIVE_END') {  
84 - // let liveReviewDTO = await PageViewModel.getLiveReviewUrl(pageModel.currentPage, pageModel.pageSize)  
85 - // // content数据回来,塞给comp  
86 - // comp.operDataList.push(...liveReviewDTO.list)  
87 - // } 81 + // 最后一个楼层,特殊处理
  82 + // 检测楼层最后一个组件业务数据是否需要通过访问接口获取
  83 + let comp: CompDTO = pageDto.compList[pageDto.compList.length - 1]
  84 + let compSize = CollectionUtils.getListSize(comp.operDataList)
  85 + // 直播回放,需要二次请求数据
  86 + if (compSize <= 0 && comp.compStyle == CompStyle.Zh_Grid_Layout_02) {
  87 + // 这个comp,数据自己二次请求,自己分页处理,这里加flag,将page层滑动及loadmore ui去掉
  88 + pageModel.contentNeedScroll = true
  89 + }
88 } 90 }
89 } 91 }
90 } 92 }
91 93
92 /** 94 /**
93 - * 获取直播回看数据  
94 - */  
95 - private async getLiveEnd(pageModel: PageModel) {  
96 - let liveReviewDTO = await PageViewModel.getLiveReviewUrl(pageModel.currentPage, pageModel.pageSize)  
97 - Logger.debug(TAG, 'aboutToAppear, getPreviewData ' + liveReviewDTO.hasNext);  
98 - }  
99 -  
100 - /**  
101 * comp加载更多,分页加载 95 * comp加载更多,分页加载
102 */ 96 */
103 private compLoadMore(pageModel: PageModel) { 97 private compLoadMore(pageModel: PageModel) {
@@ -125,14 +119,6 @@ export class PageHelper { @@ -125,14 +119,6 @@ export class PageHelper {
125 promptAction.showToast({ message: err }); 119 promptAction.showToast({ message: err });
126 }) 120 })
127 } 121 }
128 -  
129 - /**  
130 - * 节目数据分页加载  
131 - * TODO 待完善框架  
132 - */  
133 - private contentLoadMore() {  
134 -  
135 - }  
136 } 122 }
137 123
138 124
@@ -20,6 +20,9 @@ export default class PageModel { @@ -20,6 +20,9 @@ export default class PageModel {
20 // 当前请求数据的group 20 // 当前请求数据的group
21 groupData: GroupInfoDTO = {} as GroupInfoDTO; 21 groupData: GroupInfoDTO = {} as GroupInfoDTO;
22 compList: LazyDataSource<CompDTO> = new LazyDataSource(); 22 compList: LazyDataSource<CompDTO> = new LazyDataSource();
  23 + // 是否comp自己处理分页加载;默认是最后一个comp下的content有分页数据,需要节目内容的分页加载
  24 + // (如:首页-视频tab-直播tab,最后一个comp是直播回看列表,视频内容需要分页加载)
  25 + contentNeedScroll: boolean = false;
23 // 页面状态,刷新、加载更多等,1-首次、2-下拉、3上拉 26 // 页面状态,刷新、加载更多等,1-首次、2-下拉、3上拉
24 loadStrategy: number = 1; 27 loadStrategy: number = 1;
25 currentPage: number = 1; 28 currentPage: number = 1;
@@ -37,6 +37,10 @@ @@ -37,6 +37,10 @@
37 "value": "18fp" 37 "value": "18fp"
38 }, 38 },
39 { 39 {
  40 + "name": "font_size_18",
  41 + "value": "18fp"
  42 + },
  43 + {
40 "name": "font_size_24", 44 "name": "font_size_24",
41 "value": "24fp" 45 "value": "24fp"
42 }, 46 },
@@ -49,6 +53,10 @@ @@ -49,6 +53,10 @@
49 "value": "36fp" 53 "value": "36fp"
50 }, 54 },
51 { 55 {
  56 + "name": "margin_4_negative",
  57 + "value": "-4vp"
  58 + },
  59 + {
52 "name": "main_margin", 60 "name": "main_margin",
53 "value": "14vp" 61 "value": "14vp"
54 }, 62 },
@@ -77,6 +85,46 @@ @@ -77,6 +85,46 @@
77 "value": "160vp" 85 "value": "160vp"
78 }, 86 },
79 { 87 {
  88 + "name": "margin_80",
  89 + "value": "80vp"
  90 + },
  91 + {
  92 + "name": "margin_2",
  93 + "value": "2vp"
  94 + },
  95 + {
  96 + "name": "margin_5",
  97 + "value": "5vp"
  98 + },
  99 + {
  100 + "name": "margin_7",
  101 + "value": "7vp"
  102 + },
  103 + {
  104 + "name": "margin_20",
  105 + "value": "20vp"
  106 + },
  107 + {
  108 + "name": "margin_24",
  109 + "value": "24vp"
  110 + },
  111 + {
  112 + "name": "margin_25",
  113 + "value": "25vp"
  114 + },
  115 + {
  116 + "name": "margin_28",
  117 + "value": "28vp"
  118 + },
  119 + {
  120 + "name": "margin_48",
  121 + "value": "48vp"
  122 + },
  123 + {
  124 + "name": "margin_60",
  125 + "value": "60vp"
  126 + },
  127 + {
80 "name": "single_row_03_img_height", 128 "name": "single_row_03_img_height",
81 "value": "88vp" 129 "value": "88vp"
82 }, 130 },
@@ -133,6 +181,10 @@ @@ -133,6 +181,10 @@
133 "value": "24vp" 181 "value": "24vp"
134 }, 182 },
135 { 183 {
  184 + "name": "margin_6",
  185 + "value": "6vp"
  186 + },
  187 + {
136 "name": "margin_16", 188 "name": "margin_16",
137 "value": "16vp" 189 "value": "16vp"
138 }, 190 },
@@ -141,6 +193,14 @@ @@ -141,6 +193,14 @@
141 "value": "20vp" 193 "value": "20vp"
142 }, 194 },
143 { 195 {
  196 + "name": "margin_32",
  197 + "value": "32vp"
  198 + },
  199 + {
  200 + "name": "margin_36",
  201 + "value": "36vp"
  202 + },
  203 + {
144 "name": "vp_3", 204 "name": "vp_3",
145 "value": "3vp" 205 "value": "3vp"
146 }, 206 },
@@ -167,6 +227,10 @@ @@ -167,6 +227,10 @@
167 { 227 {
168 "name": "card_comp_pagePadding_tb", 228 "name": "card_comp_pagePadding_tb",
169 "value": "14fp" 229 "value": "14fp"
  230 + },
  231 + {
  232 + "name": "margin_116",
  233 + "value": "116vp"
170 } 234 }
171 ] 235 ]
172 } 236 }
1 -export { DetailPlayLivePage } from './src/main/ets/pages/DetailPlayLivePage'  
  1 +export { DetailPlayLivePage } from './src/main/ets/pages/DetailPlayLivePage'
  2 +
  3 +export { DetailPlayVLivePage } from './src/main/ets/pages/DetailPlayVLivePage'
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 "wdKit": "file:../../commons/wdKit", 13 "wdKit": "file:../../commons/wdKit",
14 "wdBean": "file:../../features/wdBean", 14 "wdBean": "file:../../features/wdBean",
15 "wdConstant": "file:../../commons/wdConstant", 15 "wdConstant": "file:../../commons/wdConstant",
16 - "wdDetailPlayApi": "file:../../features/wdDetailPlayApi" 16 + "wdDetailPlayApi": "file:../../features/wdDetailPlayApi",
  17 + "wdRouter": "file:../../commons/wdRouter"
17 } 18 }
18 } 19 }
  1 +import { BottomComponent } from '../widgets/details/BottomComponent';
  2 +import { TabComponent } from '../widgets/details/TabComponent';
  3 +import { TopPlayComponent } from '../widgets/details/video/TopPlayComponet';
  4 +
  5 +
  6 +@Component
  7 +export struct DetailPlayHLivePage {
  8 + aboutToAppear(): void {
  9 +
  10 + }
  11 +
  12 + build() {
  13 + Column() {
  14 + TopPlayComponent()
  15 + TabComponent()
  16 + BottomComponent()
  17 + }
  18 + .height('100%')
  19 + .width('100%')
  20 + }
  21 +
  22 + onPageShow(): void {
  23 +
  24 + }
  25 +
  26 + aboutToDisappear(): void {
  27 +
  28 + }
  29 +}
@@ -10,11 +10,12 @@ import router from '@ohos.router'; @@ -10,11 +10,12 @@ import router from '@ohos.router';
10 export struct DetailPlayLivePage { 10 export struct DetailPlayLivePage {
11 TAG: string = 'DetailPlayLivePage'; 11 TAG: string = 'DetailPlayLivePage';
12 liveViewModel: LiveViewModel = new LiveViewModel() 12 liveViewModel: LiveViewModel = new LiveViewModel()
13 - @State relId: string = '500005302448'  
14 - @State contentId: string = '20000016340'  
15 - @State relType: string = '1' 13 + @State relId: string = ''
  14 + @State contentId: string = ''
  15 + @State relType: string = ''
16 @Provide liveDetailsBean: LiveDetailsBean = {} as LiveDetailsBean 16 @Provide liveDetailsBean: LiveDetailsBean = {} as LiveDetailsBean
17 @Provide liveRoomDataBean: LiveRoomDataBean = {} as LiveRoomDataBean 17 @Provide liveRoomDataBean: LiveRoomDataBean = {} as LiveRoomDataBean
  18 + @State tabs: string[] = ['直播间', '大家聊']
18 19
19 aboutToAppear(): void { 20 aboutToAppear(): void {
20 //https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/content/zh/c/content/detail?relId=500005302448&relType=1&contentId=20000016340 21 //https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/content/zh/c/content/detail?relId=500005302448&relType=1&contentId=20000016340
@@ -30,7 +31,7 @@ export struct DetailPlayLivePage { @@ -30,7 +31,7 @@ export struct DetailPlayLivePage {
30 build() { 31 build() {
31 Column() { 32 Column() {
32 TopPlayComponent() 33 TopPlayComponent()
33 - TabComponent() 34 + TabComponent({ tabs: this.tabs })
34 BottomComponent() 35 BottomComponent()
35 } 36 }
36 .height('100%') 37 .height('100%')
@@ -46,6 +47,9 @@ export struct DetailPlayLivePage { @@ -46,6 +47,9 @@ export struct DetailPlayLivePage {
46 .then( 47 .then(
47 (data) => { 48 (data) => {
48 if (data.length > 0) { 49 if (data.length > 0) {
  50 + if (data[0].liveInfo?.liveState == 'wait') {
  51 + this.tabs = ['简介', '直播间', '大家聊']
  52 + }
49 this.liveDetailsBean = data[0] 53 this.liveDetailsBean = data[0]
50 } 54 }
51 }, 55 },
  1 +import { BottomComponent } from '../widgets/details/BottomComponent';
  2 +import { TopPlayComponent } from '../widgets/details/video/TopPlayComponet';
  3 +import { TopPlayVComponent } from '../widgets/details/video/TopPlayVComponet';
  4 +
  5 +
  6 +@Component
  7 +export struct DetailPlayVLivePage {
  8 + aboutToAppear(): void {
  9 +
  10 + }
  11 +
  12 + build() {
  13 + Column() {
  14 + TopPlayVComponent()
  15 + // TabComponent()
  16 + BottomComponent()
  17 + }
  18 + .height('100%')
  19 + .width('100%')
  20 + }
  21 +
  22 + onPageShow(): void {
  23 +
  24 + }
  25 +
  26 + aboutToDisappear(): void {
  27 +
  28 + }
  29 +}
@@ -170,10 +170,10 @@ export class LiveModel { @@ -170,10 +170,10 @@ export class LiveModel {
170 * @param isSubscribe 170 * @param isSubscribe
171 * @returns 171 * @returns
172 */ 172 */
173 - liveAppointment(relationId: string, mLiveId: string, isSubscribe: boolean) { 173 + liveAppointment(relationId: string, liveId: string, isSubscribe: boolean) {
174 let params: Record<string, string> = {}; 174 let params: Record<string, string> = {};
175 params['relationId'] = relationId 175 params['relationId'] = relationId
176 - params['liveId'] = mLiveId 176 + params['liveId'] = liveId
177 params['isSubscribe'] = `${isSubscribe}` 177 params['isSubscribe'] = `${isSubscribe}`
178 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders(); 178 let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
179 return new Promise<ResponseDTO<string>>((success, fail) => { 179 return new Promise<ResponseDTO<string>>((success, fail) => {
@@ -67,9 +67,9 @@ export class LiveViewModel { @@ -67,9 +67,9 @@ export class LiveViewModel {
67 } 67 }
68 68
69 //直播预约/取消预约 69 //直播预约/取消预约
70 - liveAppointment(relationId: string, mLiveId: string, isSubscribe: boolean) { 70 + liveAppointment(relationId: string, liveId: string, isSubscribe: boolean) {
71 return new Promise<ResponseDTO<string>>((success, fail) => { 71 return new Promise<ResponseDTO<string>>((success, fail) => {
72 - this.liveModel.liveAppointment(relationId, mLiveId, isSubscribe).then((data) => { 72 + this.liveModel.liveAppointment(relationId, liveId, isSubscribe).then((data) => {
73 success(data) 73 success(data)
74 }).catch((message: string) => { 74 }).catch((message: string) => {
75 fail(message) 75 fail(message)
@@ -2,10 +2,12 @@ import font from '@ohos.font' @@ -2,10 +2,12 @@ import font from '@ohos.font'
2 import { LiveDetailsBean } from 'wdBean/Index' 2 import { LiveDetailsBean } from 'wdBean/Index'
3 import { DateTimeUtils, StringUtils } from 'wdKit/Index' 3 import { DateTimeUtils, StringUtils } from 'wdKit/Index'
4 import { LiveViewModel } from '../../viewModel/LiveViewModel' 4 import { LiveViewModel } from '../../viewModel/LiveViewModel'
  5 +import { HttpUrlUtils } from 'wdNetwork/Index'
  6 +import { WDRouterPage, WDRouterRule } from 'wdRouter/Index'
5 7
6 @Component 8 @Component
7 export struct LiveCountdownComponent { 9 export struct LiveCountdownComponent {
8 - @Consume @Watch('calculateDataStatus') liveDetailsBean: LiveDetailsBean 10 + @State liveDetailsBean: LiveDetailsBean = {} as LiveDetailsBean
9 textTimerController: TextTimerController = new TextTimerController() 11 textTimerController: TextTimerController = new TextTimerController()
10 @State format: string = 'HH:mm:ss' 12 @State format: string = 'HH:mm:ss'
11 @State month: string = '' 13 @State month: string = ''
@@ -26,7 +28,8 @@ export struct LiveCountdownComponent { @@ -26,7 +28,8 @@ export struct LiveCountdownComponent {
26 }) 28 })
27 setTimeout(() => { 29 setTimeout(() => {
28 this.textTimerController.start() 30 this.textTimerController.start()
29 - }, 2000) 31 + }, 0)
  32 + this.updateData()
30 } 33 }
31 34
32 build() { 35 build() {
@@ -100,7 +103,7 @@ export struct LiveCountdownComponent { @@ -100,7 +103,7 @@ export struct LiveCountdownComponent {
100 103
101 @Builder 104 @Builder
102 showAppointment() { 105 showAppointment() {
103 - Text('我要预约') 106 + Text(this.isAppointmentLive ? '取消预约' : '我要预约')
104 .width('100%') 107 .width('100%')
105 .height(42) 108 .height(42)
106 .textAlign(TextAlign.Center) 109 .textAlign(TextAlign.Center)
@@ -113,13 +116,17 @@ export struct LiveCountdownComponent { @@ -113,13 +116,17 @@ export struct LiveCountdownComponent {
113 .border({ radius: 4 }) 116 .border({ radius: 4 })
114 .backgroundColor(this.isAppointmentLive ? '#CCCCCC' : '#ED2800') 117 .backgroundColor(this.isAppointmentLive ? '#CCCCCC' : '#ED2800')
115 .onClick(() => { 118 .onClick(() => {
  119 + if (!HttpUrlUtils.getUserId()) {
  120 + WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
  121 + return
  122 + }
116 if (this.liveDetailsBean && this.liveDetailsBean.liveInfo) { 123 if (this.liveDetailsBean && this.liveDetailsBean.liveInfo) {
117 this.liveAppointment() 124 this.liveAppointment()
118 } 125 }
119 }) 126 })
120 } 127 }
121 128
122 - calculateDataStatus() { 129 + updateData() {
123 if (!this.liveDetailsBean) { 130 if (!this.liveDetailsBean) {
124 return 131 return
125 } 132 }
1 -import { LiveDetailsBean } from 'wdBean/Index'  
2 import { TabChatComponent } from './TabChatComponent' 1 import { TabChatComponent } from './TabChatComponent'
3 import { TabInfoComponent } from './TabInfoComponent' 2 import { TabInfoComponent } from './TabInfoComponent'
4 import { TabLiveComponent } from './TabLiveComponent' 3 import { TabLiveComponent } from './TabLiveComponent'
@@ -9,7 +8,7 @@ export struct TabComponent { @@ -9,7 +8,7 @@ export struct TabComponent {
9 @State selectedFontColor: string = '#222222' 8 @State selectedFontColor: string = '#222222'
10 @State currentIndex: number = 0 9 @State currentIndex: number = 0
11 private controller: TabsController = new TabsController() 10 private controller: TabsController = new TabsController()
12 - tabs: string[] = ['简介', '直播间', '大家聊'] 11 + @Prop tabs: string[] = []
13 12
14 aboutToAppear(): void { 13 aboutToAppear(): void {
15 14
@@ -19,12 +18,21 @@ export struct TabComponent { @@ -19,12 +18,21 @@ export struct TabComponent {
19 Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) { 18 Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
20 ForEach(this.tabs, (item: string, index: number) => { 19 ForEach(this.tabs, (item: string, index: number) => {
21 TabContent() { 20 TabContent() {
22 - if (0 == index) {  
23 - TabInfoComponent()  
24 - } else if (1 == index) {  
25 - TabLiveComponent()  
26 - } else {  
27 - TabChatComponent() 21 + if (this.tabs.length == 3) {
  22 + if (0 == index) {
  23 + TabInfoComponent()
  24 + } else if (1 == index) {
  25 + TabLiveComponent()
  26 + } else {
  27 + TabChatComponent()
  28 + }
  29 + }
  30 + else {
  31 + if (0 == index) {
  32 + TabLiveComponent()
  33 + } else {
  34 + TabChatComponent()
  35 + }
28 } 36 }
29 }.tabBar(this.tabBuilder(index, item)) 37 }.tabBar(this.tabBuilder(index, item))
30 .backgroundColor('#F5F5F5') 38 .backgroundColor('#F5F5F5')
@@ -12,7 +12,7 @@ export struct TabInfoComponent { @@ -12,7 +12,7 @@ export struct TabInfoComponent {
12 Column() { 12 Column() {
13 this.showLiveTitle() 13 this.showLiveTitle()
14 this.showLiveDetails() 14 this.showLiveDetails()
15 - LiveCountdownComponent() 15 + LiveCountdownComponent({liveDetailsBean:this.liveDetailsBean})
16 }.margin({ 16 }.margin({
17 top: 13, 17 top: 13,
18 left: 16, 18 left: 16,
@@ -8,12 +8,16 @@ import { TabLiveItemComponent } from './TabLiveItemComponent' @@ -8,12 +8,16 @@ import { TabLiveItemComponent } from './TabLiveItemComponent'
8 export struct TabLiveComponent { 8 export struct TabLiveComponent {
9 liveViewModel: LiveViewModel = new LiveViewModel() 9 liveViewModel: LiveViewModel = new LiveViewModel()
10 @State liveList: Array<LiveRoomItemBean> = [] 10 @State liveList: Array<LiveRoomItemBean> = []
11 - @Consume liveDetailsBean: LiveDetailsBean 11 + @Consume @Watch('updateDate') liveDetailsBean: LiveDetailsBean
12 12
13 - aboutToAppear(): void { 13 + updateDate() {
14 this.getLiveList() 14 this.getLiveList()
15 } 15 }
16 16
  17 + aboutToAppear(): void {
  18 +
  19 + }
  20 +
17 build() { 21 build() {
18 Stack() { 22 Stack() {
19 if (this.liveList.length == 0) { 23 if (this.liveList.length == 0) {
@@ -51,14 +51,18 @@ export struct PlayUIComponent { @@ -51,14 +51,18 @@ export struct PlayUIComponent {
51 .margin({ 51 .margin({
52 right: 10 52 right: 10
53 }) 53 })
54 - Text(this.liveDetailsBean.newsTitle)  
55 - .maxLines(1)  
56 - .textOverflow({ overflow: TextOverflow.Ellipsis })  
57 - .fontSize('16fp')  
58 - .fontWeight(500)  
59 - .fontColor(Color.White)  
60 - .textAlign(TextAlign.Start)  
61 - .layoutWeight(1) 54 + if (this.liveDetailsBean.liveInfo?.liveState != 'wait') {
  55 + Text(this.liveDetailsBean.newsTitle)
  56 + .maxLines(1)
  57 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  58 + .fontSize('16fp')
  59 + .fontWeight(500)
  60 + .fontColor(Color.White)
  61 + .textAlign(TextAlign.Start)
  62 + .layoutWeight(1)
  63 + } else {
  64 + Blank()
  65 + }
62 Image($r('app.media.icon_share')) 66 Image($r('app.media.icon_share'))
63 .width(24) 67 .width(24)
64 .aspectRatio(1) 68 .aspectRatio(1)
@@ -86,8 +90,25 @@ export struct PlayUIComponent { @@ -86,8 +90,25 @@ export struct PlayUIComponent {
86 getLiveStatusView() { 90 getLiveStatusView() {
87 // 直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停 91 // 直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停
88 // 预约 92 // 预约
  93 + if (this.liveDetailsBean.liveInfo?.liveState == 'wait') {
  94 + Row() {
  95 + Image($r('app.media.icon_live_status_wait'))
  96 + .width(22)
  97 + .height(18)
  98 + Text('预约')
  99 + .fontSize('11fp')
  100 + .fontWeight(400)
  101 + .fontColor(Color.White)
  102 + }
  103 + .backgroundColor('#4D000000')
  104 + .padding({
  105 + top: 1,
  106 + right: 4,
  107 + bottom: 1
  108 + })
  109 + }
89 // 直播中 110 // 直播中
90 - if (this.liveDetailsBean.liveInfo?.liveState == 'running') { 111 + else if (this.liveDetailsBean.liveInfo?.liveState == 'running') {
91 Row() { 112 Row() {
92 Image($r('app.media.icon_live_status_running')) 113 Image($r('app.media.icon_live_status_running'))
93 .width(22) 114 .width(22)
@@ -6,6 +6,8 @@ import { PlayUIComponent } from './PlayUIComponent'; @@ -6,6 +6,8 @@ import { PlayUIComponent } from './PlayUIComponent';
6 export struct TopPlayComponent { 6 export struct TopPlayComponent {
7 @Consume @Watch('updateData') liveDetailsBean: LiveDetailsBean 7 @Consume @Watch('updateData') liveDetailsBean: LiveDetailsBean
8 playerController: WDPlayerController = new WDPlayerController(); 8 playerController: WDPlayerController = new WDPlayerController();
  9 + @State imgUrl: string = ''
  10 + @State isWait: boolean = false
9 11
10 aboutToAppear(): void { 12 aboutToAppear(): void {
11 this.playerController.onCanplay = () => { 13 this.playerController.onCanplay = () => {
@@ -15,6 +17,10 @@ export struct TopPlayComponent { @@ -15,6 +17,10 @@ export struct TopPlayComponent {
15 17
16 updateData() { 18 updateData() {
17 //直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停 19 //直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停
  20 + if (this.liveDetailsBean.fullColumnImgUrls && this.liveDetailsBean.fullColumnImgUrls.length > 0) {
  21 + this.imgUrl = this.liveDetailsBean.fullColumnImgUrls[0].url
  22 + }
  23 + this.isWait = this.liveDetailsBean?.liveInfo?.liveState == 'wait'
18 if (this.liveDetailsBean.liveInfo && this.liveDetailsBean.liveInfo.vlive.length > 0) { 24 if (this.liveDetailsBean.liveInfo && this.liveDetailsBean.liveInfo.vlive.length > 0) {
19 let playUrl = '' 25 let playUrl = ''
20 if (this.liveDetailsBean.liveInfo.liveState == 'running') { 26 if (this.liveDetailsBean.liveInfo.liveState == 'running') {
@@ -35,6 +41,10 @@ export struct TopPlayComponent { @@ -35,6 +41,10 @@ export struct TopPlayComponent {
35 }) 41 })
36 .height('100%') 42 .height('100%')
37 .width('100%') 43 .width('100%')
  44 + .visibility(this.isWait ? Visibility.None : Visibility.Visible)
  45 + Image(this.imgUrl)
  46 + .objectFit(ImageFit.Contain)
  47 + .visibility(this.isWait ? Visibility.Visible : Visibility.None)
38 PlayUIComponent({ playerController: this.playerController }) 48 PlayUIComponent({ playerController: this.playerController })
39 } 49 }
40 .height(211) 50 .height(211)
@@ -43,5 +53,7 @@ export struct TopPlayComponent { @@ -43,5 +53,7 @@ export struct TopPlayComponent {
43 53
44 aboutToDisappear(): void { 54 aboutToDisappear(): void {
45 this.playerController.pause() 55 this.playerController.pause()
  56 + this.playerController.stop()
  57 + this.playerController.release()
46 } 58 }
47 } 59 }
  1 +import { LiveDetailsBean } from 'wdBean/Index';
  2 +import { WDPlayerController, WDPlayerRenderView } from 'wdPlayer/Index';
  3 +import { PlayUIComponent } from './PlayUIComponent';
  4 +
  5 +@Component
  6 +export struct TopPlayVComponent {
  7 + @Consume @Watch('updateData') liveDetailsBean: LiveDetailsBean
  8 + playerController: WDPlayerController = new WDPlayerController();
  9 +
  10 + aboutToAppear(): void {
  11 + this.playerController.onCanplay = () => {
  12 + this.playerController.play()
  13 + }
  14 + }
  15 +
  16 + updateData() {
  17 + //直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停
  18 + if (this.liveDetailsBean.liveInfo && this.liveDetailsBean.liveInfo.vlive.length > 0) {
  19 + let playUrl = ''
  20 + if (this.liveDetailsBean.liveInfo.liveState == 'running') {
  21 + playUrl = this.liveDetailsBean.liveInfo.vlive[0].liveUrl
  22 + } else if (this.liveDetailsBean.liveInfo.liveState == 'end') {
  23 + playUrl = this.liveDetailsBean.liveInfo.vlive[0].replayUri
  24 + }
  25 + this.playerController.firstPlay(playUrl);
  26 + }
  27 + }
  28 +
  29 + build() {
  30 + Stack() {
  31 + // https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-image-effect-0000001862607345
  32 + Image(this.liveDetailsBean.fullColumnImgUrls[0].url)
  33 + .height('100%')
  34 + .width('100%')
  35 + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
  36 + .blur(100)
  37 +
  38 + WDPlayerRenderView({
  39 + playerController: this.playerController,
  40 + onLoad: async () => {
  41 + }
  42 + })// .height('100%')
  43 + .width('100%')// 扩展至所有非安全区域
  44 + .onClick(() => {
  45 + this.playerController.play()
  46 + })
  47 + // PlayUIComponent({ playerController: this.playerController })
  48 + }
  49 + // .height('100%')
  50 + .width('100%')
  51 + // 扩展至所有非安全区域
  52 + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
  53 + }
  54 +
  55 + aboutToDisappear(): void {
  56 + this.playerController.pause()
  57 + }
  58 +}
1 import mediaquery from '@ohos.mediaquery'; 1 import mediaquery from '@ohos.mediaquery';
2 import { ContentDetailDTO, InteractDataDTO } from 'wdBean'; 2 import { ContentDetailDTO, InteractDataDTO } from 'wdBean';
3 -import { WDPlayerController, WDPlayerRenderView } from 'wdPlayer'; 3 +import { PlayerConstants, WDPlayerController, WDPlayerRenderView } from 'wdPlayer';
4 import { ContentDetailRequest, devicePLSensorManager } from 'wdDetailPlayApi'; 4 import { ContentDetailRequest, devicePLSensorManager } from 'wdDetailPlayApi';
5 import { PlayControlViewContainer } from '../view/PlayControlViewContainer'; 5 import { PlayControlViewContainer } from '../view/PlayControlViewContainer';
6 import { PlayerDetailContainer } from '../view/PlayerDetailContainer'; 6 import { PlayerDetailContainer } from '../view/PlayerDetailContainer';
@@ -32,6 +32,19 @@ export struct DetailPlayShortVideoPage { @@ -32,6 +32,19 @@ export struct DetailPlayShortVideoPage {
32 @Provide videoLandScape?: number = 1; // 视频朝向, 横屏视频:1;竖屏视频:2 32 @Provide videoLandScape?: number = 1; // 视频朝向, 横屏视频:1;竖屏视频:2
33 @Provide newsStatusOfUser: batchLikeAndCollectResult | undefined = undefined // 点赞、收藏状态 33 @Provide newsStatusOfUser: batchLikeAndCollectResult | undefined = undefined // 点赞、收藏状态
34 @Provide followStatus: string = '0' // 关注状态 34 @Provide followStatus: string = '0' // 关注状态
  35 + @Link @Watch('switchVideoStatusChange') switchVideoStatus: boolean
  36 +
  37 + switchVideoStatusChange() {
  38 + if (this.switchVideoStatus) {
  39 + if (this.currentIndex === this.index && this.playerController.getStatus() === PlayerConstants.STATUS_PAUSE) {
  40 + this.playerController.play()
  41 + }
  42 + } else {
  43 + if (this.currentIndex === this.index && this.playerController.getStatus() === PlayerConstants.STATUS_START) {
  44 + this.playerController.pause()
  45 + }
  46 + }
  47 + }
35 48
36 currentIndexChange() { 49 currentIndexChange() {
37 if (this.currentIndex != this.index) { 50 if (this.currentIndex != this.index) {
@@ -166,6 +179,7 @@ export struct DetailPlayShortVideoPage { @@ -166,6 +179,7 @@ export struct DetailPlayShortVideoPage {
166 }) 179 })
167 .height('100%') 180 .height('100%')
168 .width('100%') 181 .width('100%')
  182 + .margin({ top: this.contentDetailData?.videoInfo[0]?.videoLandScape === 1 ? 218 : 0 })
169 .onClick(() => { 183 .onClick(() => {
170 console.error('WDPlayerRenderView=== onClick') 184 console.error('WDPlayerRenderView=== onClick')
171 this.playerController?.switchPlayOrPause(); 185 this.playerController?.switchPlayOrPause();
@@ -24,6 +24,7 @@ export struct DetailVideoListPage { @@ -24,6 +24,7 @@ export struct DetailVideoListPage {
24 @State currentIndex: number = 0 24 @State currentIndex: number = 0
25 @State interactDataList: InteractDataDTO[] = [] 25 @State interactDataList: InteractDataDTO[] = []
26 @State isFullScreen: boolean = false 26 @State isFullScreen: boolean = false
  27 + @State switchVideoStatus: boolean = false
27 28
28 async aboutToAppear(): Promise<void> { 29 async aboutToAppear(): Promise<void> {
29 30
@@ -157,6 +158,7 @@ export struct DetailVideoListPage { @@ -157,6 +158,7 @@ export struct DetailVideoListPage {
157 ForEach(this.data, (item: ContentDetailDTO, index: number) => { 158 ForEach(this.data, (item: ContentDetailDTO, index: number) => {
158 Column() { 159 Column() {
159 DetailPlayShortVideoPage({ 160 DetailPlayShortVideoPage({
  161 + switchVideoStatus: $switchVideoStatus,
160 contentDetailData: item, 162 contentDetailData: item,
161 currentIndex: this.currentIndex, 163 currentIndex: this.currentIndex,
162 index: index, 164 index: index,
@@ -34,14 +34,15 @@ export struct VideoChannelDetail { @@ -34,14 +34,15 @@ export struct VideoChannelDetail {
34 private channelStrategy: string = '1' // 频道策略 1-推荐;2-时间线 34 private channelStrategy: string = '1' // 频道策略 1-推荐;2-时间线
35 // private topicId?: string = '' // 专题id 35 // private topicId?: string = '' // 专题id
36 // private recommend?: string = '' // 0.非推荐,1.推荐; 36 // private recommend?: string = '' // 0.非推荐,1.推荐;
37 - @State @Watch('navIndexChange') bottomNavIndex: number = 0  
38 - @State @Watch('navIndexChange') topNavIndex: number = 0 37 + @Link @Watch('navIndexChange') bottomNavIndex: number
  38 + @Link @Watch('navIndexChange') topNavIndex: number
39 private swiperController: SwiperController = new SwiperController() 39 private swiperController: SwiperController = new SwiperController()
40 @Provide showComment: boolean = false 40 @Provide showComment: boolean = false
41 @State data: ContentDetailDTO[] = [] 41 @State data: ContentDetailDTO[] = []
42 @State currentIndex: number = 0 42 @State currentIndex: number = 0
43 @State interactDataList: InteractDataDTO[] = [] 43 @State interactDataList: InteractDataDTO[] = []
44 @State totalCount: number = 0 44 @State totalCount: number = 0
  45 + @State switchVideoStatus: boolean = false
45 46
46 /** 47 /**
47 * 监听视频频道激活或失活 48 * 监听视频频道激活或失活
@@ -49,30 +50,22 @@ export struct VideoChannelDetail { @@ -49,30 +50,22 @@ export struct VideoChannelDetail {
49 navIndexChange() { 50 navIndexChange() {
50 if (this.bottomNavIndex === 2 && this.topNavIndex === 0) { 51 if (this.bottomNavIndex === 2 && this.topNavIndex === 0) {
51 // 如果视频在暂停则播放视频 52 // 如果视频在暂停则播放视频
  53 + this.switchVideoStatus = true
52 } else { 54 } else {
53 // 如果视频在播放则暂停视频 55 // 如果视频在播放则暂停视频
  56 + this.switchVideoStatus = false
54 } 57 }
  58 +
55 } 59 }
56 60
57 async aboutToAppear(): Promise<void> { 61 async aboutToAppear(): Promise<void> {
58 - const windowStage = WindowModel.shared.getWindowStage() as window.WindowStage  
59 - const windowClass: window.Window = windowStage.getMainWindowSync();  
60 - windowClass.setWindowSystemBarProperties({  
61 - statusBarContentColor: '#ffffff',  
62 - })  
63 - console.error('aboutToAppear groupId', this.groupId)  
64 - console.error('aboutToAppear pageId', this.pageId)  
65 - console.error('aboutToAppear channelId', this.channelId) 62 + WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#ffffff', })
66 // 根据视频频道传参查询视频楼层信息 63 // 根据视频频道传参查询视频楼层信息
67 this.getRecCompInfo() 64 this.getRecCompInfo()
68 } 65 }
69 66
70 aboutToDisappear(): void { 67 aboutToDisappear(): void {
71 - const windowStage = WindowModel.shared.getWindowStage() as window.WindowStage  
72 - const windowClass: window.Window = windowStage.getMainWindowSync();  
73 - windowClass.setWindowSystemBarProperties({  
74 - statusBarContentColor: '#000000',  
75 - }) 68 + WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#000000', })
76 console.error('aboutToDisappear videoChanel') 69 console.error('aboutToDisappear videoChanel')
77 } 70 }
78 71
@@ -105,8 +98,7 @@ export struct VideoChannelDetail { @@ -105,8 +98,7 @@ export struct VideoChannelDetail {
105 } 98 }
106 99
107 await ContentDetailRequest.getRecCompInfo(params).then(res => { 100 await ContentDetailRequest.getRecCompInfo(params).then(res => {
108 - console.log('根据视频频道传参查询视频楼层信息', res.data?.totalCount)  
109 - console.log('根据视频频道传参查询视频楼层信息', JSON.stringify(res.data?.compList)) 101 + console.log('根据视频频道传参查询视频楼层信息totalCount', res.data?.totalCount + '')
110 102
111 this.totalCount = res.data?.totalCount || 0 103 this.totalCount = res.data?.totalCount || 0
112 const list1: batchContentDetailParams = { 104 const list1: batchContentDetailParams = {
@@ -136,8 +128,6 @@ export struct VideoChannelDetail { @@ -136,8 +128,6 @@ export struct VideoChannelDetail {
136 this.batchContentDetail(list1) 128 this.batchContentDetail(list1)
137 this.getContentInteract(list2) 129 this.getContentInteract(list2)
138 130
139 - }).catch((e: BusinessError) => {  
140 - console.error('eeeeeeeeeeeeee', e)  
141 }) 131 })
142 } 132 }
143 133
@@ -147,7 +137,7 @@ export struct VideoChannelDetail { @@ -147,7 +137,7 @@ export struct VideoChannelDetail {
147 async batchContentDetail(list: batchContentDetailParams) { 137 async batchContentDetail(list: batchContentDetailParams) {
148 if (list.contents.length > 0) { 138 if (list.contents.length > 0) {
149 await ContentDetailRequest.batchContentDetail(list).then(res => { 139 await ContentDetailRequest.batchContentDetail(list).then(res => {
150 - console.log('根据视频楼层信息批量查询视频列表', JSON.stringify(res.data)) 140 + console.log('根据视频楼层信息批量查询视频列表', res.data)
151 this.data = this.data.concat(res.data as []) 141 this.data = this.data.concat(res.data as [])
152 }) 142 })
153 } 143 }
@@ -160,7 +150,7 @@ export struct VideoChannelDetail { @@ -160,7 +150,7 @@ export struct VideoChannelDetail {
160 if (list.contentList.length > 0) { 150 if (list.contentList.length > 0) {
161 await ContentDetailRequest.getContentInteract(list).then(res => { 151 await ContentDetailRequest.getContentInteract(list).then(res => {
162 this.interactDataList = res.data || [] 152 this.interactDataList = res.data || []
163 - console.log('根据视频信息批量查询点赞、收藏状态', JSON.stringify(res)) 153 + console.log('根据视频信息批量查询点赞、收藏状态', res.data)
164 }) 154 })
165 } 155 }
166 } 156 }
@@ -171,6 +161,7 @@ export struct VideoChannelDetail { @@ -171,6 +161,7 @@ export struct VideoChannelDetail {
171 ForEach(this.data, (item: ContentDetailDTO, index: number) => { 161 ForEach(this.data, (item: ContentDetailDTO, index: number) => {
172 Column() { 162 Column() {
173 DetailPlayShortVideoPage({ 163 DetailPlayShortVideoPage({
  164 + switchVideoStatus: $switchVideoStatus,
174 contentDetailData: item, 165 contentDetailData: item,
175 currentIndex: this.currentIndex, 166 currentIndex: this.currentIndex,
176 index: index, 167 index: index,
@@ -48,7 +48,9 @@ export struct PlayerTitleComment { @@ -48,7 +48,9 @@ export struct PlayerTitleComment {
48 } 48 }
49 49
50 getName() { 50 getName() {
51 - return this.contentDetailData?.newsSourceName || this.contentDetailData?.editorName || '' 51 + // console.error(this.contentDetailData?.newsSourceName + '===========' + this.contentDetailData?.editorName)
  52 + // this.contentDetailData?.newsSourceName ||
  53 + return this.contentDetailData?.editorName || ''
52 } 54 }
53 55
54 getTitle() { 56 getTitle() {
@@ -8,7 +8,7 @@ import { ErrorToastUtils, SPHelper } from 'wdKit' @@ -8,7 +8,7 @@ import { ErrorToastUtils, SPHelper } from 'wdKit'
8 import { WDRouterPage } from 'wdRouter/src/main/ets/router/WDRouterPage'; 8 import { WDRouterPage } from 'wdRouter/src/main/ets/router/WDRouterPage';
9 import { WDRouterRule } from 'wdRouter/src/main/ets/router/WDRouterRule'; 9 import { WDRouterRule } from 'wdRouter/src/main/ets/router/WDRouterRule';
10 import { Params } from '../../../../../../../commons/wdRouter/oh_modules/wdBean/src/main/ets/bean/content/Params' 10 import { Params } from '../../../../../../../commons/wdRouter/oh_modules/wdBean/src/main/ets/bean/content/Params'
11 - 11 +import {InterestsHobbiesModel} from '../../../../../../../products/phone/src/main/ets/pages/viewModel/InterestsHobbiesModel'
12 @Extend(Row) 12 @Extend(Row)
13 function otherStyle() { 13 function otherStyle() {
14 .backgroundImageSize(ImageSize.Cover) 14 .backgroundImageSize(ImageSize.Cover)
@@ -306,6 +306,10 @@ struct LoginPage { @@ -306,6 +306,10 @@ struct LoginPage {
306 if (this.checkCodePage) { 306 if (this.checkCodePage) {
307 this.loginViewModel.appLogin(this.phoneContent, 2, this.codeContent).then((data) => { 307 this.loginViewModel.appLogin(this.phoneContent, 2, this.codeContent).then((data) => {
308 Logger.debug(TAG, "requestLogin: " + data.jwtToken) 308 Logger.debug(TAG, "requestLogin: " + data.jwtToken)
  309 + ///同步兴趣tag
  310 + let interestsModel = new InterestsHobbiesModel()
  311 + interestsModel.updateInterests()
  312 +
309 router.back({ 313 router.back({
310 params: { userName: data.userName, 314 params: { userName: data.userName,
311 userId:data.id}, 315 userId:data.id},
@@ -319,6 +323,11 @@ struct LoginPage { @@ -319,6 +323,11 @@ struct LoginPage {
319 this.loginViewModel.appLoginByPassword(this.accountContent, 0, this.passwordContent, "").then((data) => { 323 this.loginViewModel.appLoginByPassword(this.accountContent, 0, this.passwordContent, "").then((data) => {
320 Logger.debug(TAG, "requestLogin: " + data.jwtToken) 324 Logger.debug(TAG, "requestLogin: " + data.jwtToken)
321 promptAction.showToast({ message: '登录成功' }) 325 promptAction.showToast({ message: '登录成功' })
  326 +
  327 + ///同步兴趣tag
  328 + let interestsModel = new InterestsHobbiesModel()
  329 + interestsModel.updateInterests()
  330 +
322 router.back({ 331 router.back({
323 params: { userName: data.userName, 332 params: { userName: data.userName,
324 userId:data.id}, 333 userId:data.id},
@@ -41,16 +41,15 @@ class MGPlayRenderViewIns { @@ -41,16 +41,15 @@ class MGPlayRenderViewIns {
41 export struct WDPlayerRenderView { 41 export struct WDPlayerRenderView {
42 private playerController?: WDPlayerController; 42 private playerController?: WDPlayerController;
43 private xComponentController: XComponentController = new XComponentController(); 43 private xComponentController: XComponentController = new XComponentController();
  44 + private insId: string = "WDPlayRenderView" + insIndex;
44 onLoad?: ((event?: object) => void); 45 onLoad?: ((event?: object) => void);
45 - videoWidth: number = 0  
46 - videoHeight: number = 0 46 + @State videoWidth: number = 0
  47 + @State videoHeight: number = 0
47 @State selfSize: Size = new Size('100%', '100%'); 48 @State selfSize: Size = new Size('100%', '100%');
48 - private insId: string = "WDPlayRenderView" + insIndex;  
49 49
50 aboutToAppear() { 50 aboutToAppear() {
51 MGPlayRenderViewIns.add(); 51 MGPlayRenderViewIns.add();
52 52
53 - console.log('playerController', this.playerController)  
54 insIndex++; 53 insIndex++;
55 if (!this.playerController) { 54 if (!this.playerController) {
56 return 55 return
@@ -80,9 +79,7 @@ export struct WDPlayerRenderView { @@ -80,9 +79,7 @@ export struct WDPlayerRenderView {
80 }) 79 })
81 .onLoad(async (event) => { 80 .onLoad(async (event) => {
82 Logger.info(TAG, 'onLoad') 81 Logger.info(TAG, 'onLoad')
83 - let surfaceId = this.xComponentController.getXComponentSurfaceId()  
84 - console.log('surfaceId===', surfaceId)  
85 - console.log('insId===', this.insId) 82 + // const surfaceId = this.xComponentController.getXComponentSurfaceId()
86 this.xComponentController.setXComponentSurfaceSize({ 83 this.xComponentController.setXComponentSurfaceSize({
87 surfaceWidth: 1920, 84 surfaceWidth: 1920,
88 surfaceHeight: 1080 85 surfaceHeight: 1080
@@ -94,27 +91,14 @@ export struct WDPlayerRenderView { @@ -94,27 +91,14 @@ export struct WDPlayerRenderView {
94 }) 91 })
95 .width(this.selfSize.width) 92 .width(this.selfSize.width)
96 .height(this.selfSize.height) 93 .height(this.selfSize.height)
97 - .margin({ top: this.getPlayerMarginTop() })  
98 } 94 }
99 .id(this.insId) 95 .id(this.insId)
100 .onAreaChange(() => { 96 .onAreaChange(() => {
101 // this.updateLayout() 97 // this.updateLayout()
102 }) 98 })
103 .backgroundColor("#000000") 99 .backgroundColor("#000000")
104 - .alignItems(VerticalAlign.Center)  
105 - .justifyContent(FlexAlign.Center)  
106 - .alignItems(this.selfSize.width === '100%' ? VerticalAlign.Top : VerticalAlign.Center)  
107 - .height('100%')  
108 - .width('100%')  
109 } 100 }
110 -  
111 - /**  
112 - * 横屏播放器非居中展示  
113 - */  
114 - getPlayerMarginTop() {  
115 - return this.selfSize.width === '100%' && this.videoWidth > this.videoHeight ? 218 : 0  
116 - }  
117 - 101 +
118 updateLayout() { 102 updateLayout() {
119 let info = componentUtils.getRectangleById(this.insId); 103 let info = componentUtils.getRectangleById(this.insId);
120 if (info.size.width > 0 && info.size.height > 0 && this.videoHeight > 0 && this.videoWidth > 0) { 104 if (info.size.width > 0 && info.size.height > 0 && this.videoHeight > 0 && this.videoWidth > 0) {
1 import {InterestsHobbiesModel, InterestsList} from '../viewModel/InterestsHobbiesModel' 1 import {InterestsHobbiesModel, InterestsList} from '../viewModel/InterestsHobbiesModel'
2 import { WDRouterRule } from 'wdRouter'; 2 import { WDRouterRule } from 'wdRouter';
3 import { WDRouterPage } from 'wdRouter'; 3 import { WDRouterPage } from 'wdRouter';
  4 +import { SPHelper } from 'wdKit/Index';
  5 +import { SpConstants } from 'wdConstant/Index';
4 6
5 @Entry 7 @Entry
6 @Component 8 @Component
@@ -121,6 +123,7 @@ struct LaunchInterestsHobbiesPage { @@ -121,6 +123,7 @@ struct LaunchInterestsHobbiesPage {
121 .width('662lpx') 123 .width('662lpx')
122 .height('84lpx') 124 .height('84lpx')
123 .onClick(()=>{ 125 .onClick(()=>{
  126 + this.saveTagIds()
124 //跳转首页 127 //跳转首页
125 WDRouterRule.jumpWithReplacePage(WDRouterPage.mainPage) 128 WDRouterRule.jumpWithReplacePage(WDRouterPage.mainPage)
126 }) 129 })
@@ -149,4 +152,15 @@ struct LaunchInterestsHobbiesPage { @@ -149,4 +152,15 @@ struct LaunchInterestsHobbiesPage {
149 }) 152 })
150 } 153 }
151 154
  155 + saveTagIds(){
  156 + let tags: string = ''
  157 + if (this.interestsArray.filter(item => item.choose).length > 0) {
  158 + let array = this.interestsArray.filter(item => item.choose)
  159 + for (let index = 0; index < array.length; index++) {
  160 + const element = array[index];
  161 + tags = tags.length === 0 ? element.id.toString() : tags + ',' + element.id.toString()
  162 + }
  163 + }
  164 + SPHelper.default.saveSync(SpConstants.PUBLICVISUTORMODE_INTERESTTAGS,tags)
  165 + }
152 } 166 }
@@ -3,6 +3,7 @@ import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest'; @@ -3,6 +3,7 @@ import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest';
3 import { HttpUrlUtils, ResponseDTO } from 'wdNetwork/Index'; 3 import { HttpUrlUtils, ResponseDTO } from 'wdNetwork/Index';
4 import { Logger, SPHelper } from 'wdKit/Index'; 4 import { Logger, SPHelper } from 'wdKit/Index';
5 import data from '@ohos.telephony.data'; 5 import data from '@ohos.telephony.data';
  6 +import { SpConstants } from 'wdConstant/Index';
6 7
7 8
8 export interface InterestsBean { 9 export interface InterestsBean {
@@ -60,9 +61,23 @@ export class InterestsHobbiesModel { @@ -60,9 +61,23 @@ export class InterestsHobbiesModel {
60 fail(error.message) 61 fail(error.message)
61 }) 62 })
62 }) 63 })
63 -  
64 -  
65 } 64 }
66 65
67 - 66 + updateInterests(){
  67 + let tags = SPHelper.default.getSync(SpConstants.PUBLICVISUTORMODE_INTERESTTAGS,'') as string
  68 + if (tags.length === 0) return
  69 + let bean: Record<string, string> = {};
  70 + bean['tagIds'] = tags
  71 + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
  72 + return new Promise<ResponseDTO>((success, fail) => {
  73 + HttpRequest.post<ResponseDTO>(HttpUrlUtils.getUpdateInterestsUrl(),bean,headers).then((data: ResponseDTO) => {
  74 + if (data.code == 0) {
  75 + Logger.info('InterestsHobbiesModel','updateInterests','更新兴趣成功')
  76 + SPHelper.default.deleteSync(SpConstants.PUBLICVISUTORMODE_INTERESTTAGS)
  77 + }
  78 + }, (error: Error) => {
  79 + fail(error.message)
  80 + })
  81 + })
  82 + }
68 } 83 }