yumaochao
Showing 30 changed files with 1187 additions and 124 deletions
@@ -207,6 +207,14 @@ export class HttpUrlUtils { @@ -207,6 +207,14 @@ export class HttpUrlUtils {
207 */ 207 */
208 static readonly LIVE_ROOM_DATA_PATH: string = "/api/live-center-message/zh/a/live/room/number/all"; 208 static readonly LIVE_ROOM_DATA_PATH: string = "/api/live-center-message/zh/a/live/room/number/all";
209 /** 209 /**
  210 + * 直播详情-C端点赞接口
  211 + */
  212 + static readonly LIVE_ROOM_NUMBER_LIKE: string = "/api/live-center-message/zh/c/live/room/number/like";
  213 + /**
  214 + * 直播详情-查询是否点赞接口
  215 + */
  216 + static readonly LIVE_LIKE: string = "/api/live-center-message/zh/a/live/like";
  217 + /**
210 * 直播详情-预约直播状态 218 * 直播详情-预约直播状态
211 */ 219 */
212 static readonly LIVE_APPOINTMENT_STATUS_PATH: string = "/api/live-center-message/zh/c/live/subscribe/query"; 220 static readonly LIVE_APPOINTMENT_STATUS_PATH: string = "/api/live-center-message/zh/c/live/subscribe/query";
@@ -633,11 +641,21 @@ export class HttpUrlUtils { @@ -633,11 +641,21 @@ export class HttpUrlUtils {
633 let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_CHAT_LIST_PATH 641 let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_CHAT_LIST_PATH
634 return url 642 return url
635 } 643 }
636 - 644 + // 直播详情-直播数据
637 static getLiveRoomDataUrl() { 645 static getLiveRoomDataUrl() {
638 let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_ROOM_DATA_PATH 646 let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_ROOM_DATA_PATH
639 return url 647 return url
640 } 648 }
  649 + // 直播详情-C端点赞接口
  650 + static getLiveRoomNumberLikeUrl() {
  651 + let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_ROOM_NUMBER_LIKE
  652 + return url
  653 + }
  654 + // 直播详情-查询是否点赞接口
  655 + static getLiveLikeUrl() {
  656 + let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_LIKE
  657 + return url
  658 + }
641 659
642 static getLiveAppointmentStatusUrl() { 660 static getLiveAppointmentStatusUrl() {
643 let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_APPOINTMENT_STATUS_PATH 661 let url = HttpUrlUtils.getHost() + HttpUrlUtils.LIVE_APPOINTMENT_STATUS_PATH
@@ -122,7 +122,7 @@ export { appStyleImagesDTO } from './src/main/ets/bean/content/appStyleImagesDTO @@ -122,7 +122,7 @@ export { appStyleImagesDTO } from './src/main/ets/bean/content/appStyleImagesDTO
122 122
123 export { LiveRoomBean, LiveRoomItemBean } from './src/main/ets/bean/live/LiveRoomBean'; 123 export { LiveRoomBean, LiveRoomItemBean } from './src/main/ets/bean/live/LiveRoomBean';
124 124
125 -export { LiveRoomDataBean } from './src/main/ets/bean/live/LiveRoomDataBean'; 125 +export { LiveRoomDataBean, ValueType } from './src/main/ets/bean/live/LiveRoomDataBean';
126 126
127 export { ReserveBean } from './src/main/ets/bean/live/ReserveBean'; 127 export { ReserveBean } from './src/main/ets/bean/live/ReserveBean';
128 128
@@ -11,7 +11,7 @@ import { UserInfoDTO } from './UserInfoDTO' @@ -11,7 +11,7 @@ import { UserInfoDTO } from './UserInfoDTO'
11 * 接口定义: 11 * 接口定义:
12 * http://192.168.1.3:3300/project/3802/interface/api/200915 12 * http://192.168.1.3:3300/project/3802/interface/api/200915
13 */ 13 */
14 -export interface ContentDetailDTO { 14 +export class ContentDetailDTO {
15 newsId: number; 15 newsId: number;
16 newsTitle: string; 16 newsTitle: string;
17 newsShortTitle: string; 17 newsShortTitle: string;
@@ -72,4 +72,8 @@ export interface ContentDetailDTO { @@ -72,4 +72,8 @@ export interface ContentDetailDTO {
72 isNewspaper: boolean; 72 isNewspaper: boolean;
73 oldNewsId: string; 73 oldNewsId: string;
74 serials: any; 74 serials: any;
  75 +
  76 +
  77 + // 本地字段
  78 + showTime:boolean = false;
75 } 79 }
@@ -5,3 +5,5 @@ export interface LiveRoomDataBean { @@ -5,3 +5,5 @@ export interface LiveRoomDataBean {
5 pv: number, 5 pv: number,
6 subscribeNum: number, 6 subscribeNum: number,
7 } 7 }
  8 +
  9 +export type ValueType = number | string | boolean | Array<number> | Array<string> | Array<boolean> | Uint8Array | object | bigint;
@@ -90,6 +90,8 @@ export { MultiPictureDetailItemComponent } from './src/main/ets/components/Multi @@ -90,6 +90,8 @@ export { MultiPictureDetailItemComponent } from './src/main/ets/components/Multi
90 90
91 export { OperRowListView } from './src/main/ets/components/view/OperRowListView'; 91 export { OperRowListView } from './src/main/ets/components/view/OperRowListView';
92 92
  93 +export { LiveOperRowListView } from './src/main/ets/components/view/LiveOperRowListView';
  94 +
93 export { ImageDownloadComponent } from './src/main/ets/components/ImageDownloadComponent'; 95 export { ImageDownloadComponent } from './src/main/ets/components/ImageDownloadComponent';
94 96
95 export { PageRepository } from './src/main/ets/repository/PageRepository'; 97 export { PageRepository } from './src/main/ets/repository/PageRepository';
@@ -32,12 +32,6 @@ export struct CardParser { @@ -32,12 +32,6 @@ export struct CardParser {
32 pageShowTime:number = 0; 32 pageShowTime:number = 0;
33 pageHideTime:number = 0; 33 pageHideTime:number = 0;
34 34
35 - aboutToAppear(): void {  
36 -  
37 - console.log('CardParser-contentDTO', JSON.stringify(this.contentDTO))  
38 - console.log('CardParser-compDTO', JSON.stringify(this.compDTO))  
39 - }  
40 -  
41 onPageShow() { 35 onPageShow() {
42 this.pageShowTime = DateTimeUtils.getTimeStamp() 36 this.pageShowTime = DateTimeUtils.getTimeStamp()
43 } 37 }
@@ -42,6 +42,9 @@ export struct CompParser { @@ -42,6 +42,9 @@ export struct CompParser {
42 @State noneAudioItems: ContentDTO[] = []; 42 @State noneAudioItems: ContentDTO[] = [];
43 43
44 aboutToAppear(): void { 44 aboutToAppear(): void {
  45 +
  46 +
  47 + console.log('CompParser-compDTO', JSON.stringify(this.compDTO))
45 // 轮播图屏蔽音频类型稿件 48 // 轮播图屏蔽音频类型稿件
46 if (this.compDTO.compStyle === CompStyle.Zh_Carousel_Layout_01) { 49 if (this.compDTO.compStyle === CompStyle.Zh_Carousel_Layout_01) {
47 this.audioItems = this.compDTO.operDataList.filter(item => { 50 this.audioItems = this.compDTO.operDataList.filter(item => {
@@ -5,7 +5,7 @@ import { @@ -5,7 +5,7 @@ import {
5 ContentDetailRequest, 5 ContentDetailRequest,
6 postInteractAccentionOperateParams 6 postInteractAccentionOperateParams
7 } from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest'; 7 } from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest';
8 -import { RmhInfoDTO } from 'wdBean' 8 +import { RmhInfoDTO, CompDTO, ContentDTO } from 'wdBean'
9 import { CommonConstants } from 'wdConstant/Index'; 9 import { CommonConstants } from 'wdConstant/Index';
10 import { DateTimeUtils, SPHelper, Logger, ToastUtils } from 'wdKit'; 10 import { DateTimeUtils, SPHelper, Logger, ToastUtils } from 'wdKit';
11 import { SpConstants } from 'wdConstant/Index' 11 import { SpConstants } from 'wdConstant/Index'
@@ -14,9 +14,14 @@ import router from '@ohos.router' @@ -14,9 +14,14 @@ import router from '@ohos.router'
14 import { postBatchAttentionStatusParams } from 'wdBean/Index'; 14 import { postBatchAttentionStatusParams } from 'wdBean/Index';
15 import { MultiPictureDetailViewModel } from '../../viewmodel/MultiPictureDetailViewModel' 15 import { MultiPictureDetailViewModel } from '../../viewmodel/MultiPictureDetailViewModel'
16 import { onlyWifiLoadImg } from '../../utils/lazyloadImg'; 16 import { onlyWifiLoadImg } from '../../utils/lazyloadImg';
  17 +import { InfomationCardClick } from '../../utils/infomationCardClick'
17 18
18 @Component 19 @Component
19 export struct RmhTitle { 20 export struct RmhTitle {
  21 + @State compDTO: CompDTO = new CompDTO()
  22 + @State contentDTO: ContentDTO = new ContentDTO();
  23 + @State pageId: string = '';
  24 + @State pageName: string = '';
20 @Prop rmhInfo: RmhInfoDTO 25 @Prop rmhInfo: RmhInfoDTO
21 @Prop publishTime: string | undefined 26 @Prop publishTime: string | undefined
22 @State loadImg: boolean = false; 27 @State loadImg: boolean = false;
@@ -48,6 +53,16 @@ export struct RmhTitle { @@ -48,6 +53,16 @@ export struct RmhTitle {
48 } 53 }
49 ContentDetailRequest.postInteractAccentionOperate(params2).then(res => { 54 ContentDetailRequest.postInteractAccentionOperate(params2).then(res => {
50 console.log('rmhTitle-data', JSON.stringify(res.data)) 55 console.log('rmhTitle-data', JSON.stringify(res.data))
  56 +
  57 + InfomationCardClick.track(
  58 + this.compDTO,
  59 + this.contentDTO,
  60 + this.pageId,
  61 + this.pageName,
  62 + 'follow', // like, commentClick, follow
  63 + this.followStatus == '0' ? true : false,
  64 + )
  65 +
51 if (this.followStatus == '1') { 66 if (this.followStatus == '1') {
52 this.followStatus = '0' 67 this.followStatus = '0'
53 } else { 68 } else {
@@ -38,7 +38,16 @@ export struct Card12Component { @@ -38,7 +38,16 @@ export struct Card12Component {
38 Column() { 38 Column() {
39 // rmh信息 39 // rmh信息
40 if (this.contentDTO.rmhInfo) { 40 if (this.contentDTO.rmhInfo) {
41 - RmhTitle({ rmhInfo: this.contentDTO.rmhInfo, publishTime: this.contentDTO.publishTime }) 41 + RmhTitle(
  42 + {
  43 + rmhInfo: this.contentDTO.rmhInfo,
  44 + publishTime: this.contentDTO.publishTime,
  45 + contentDTO: this.contentDTO,
  46 + compDTO: this.compDTO,
  47 + pageId: this.pageId,
  48 + pageName: this.pageName
  49 + }
  50 + )
42 } 51 }
43 // 标题 52 // 标题
44 if (this.contentDTO.newsTitle) { 53 if (this.contentDTO.newsTitle) {
@@ -41,7 +41,16 @@ export struct Card14Component { @@ -41,7 +41,16 @@ export struct Card14Component {
41 Column() { 41 Column() {
42 // rmh信息 42 // rmh信息
43 if (this.contentDTO.rmhInfo) { 43 if (this.contentDTO.rmhInfo) {
44 - RmhTitle({ rmhInfo: this.contentDTO.rmhInfo, publishTime: this.contentDTO.publishTime }) 44 + RmhTitle(
  45 + {
  46 + rmhInfo: this.contentDTO.rmhInfo,
  47 + publishTime: this.contentDTO.publishTime,
  48 + contentDTO: this.contentDTO,
  49 + compDTO: this.compDTO,
  50 + pageId: this.pageId,
  51 + pageName: this.pageName
  52 + }
  53 + )
45 } 54 }
46 // 左标题,右图 55 // 左标题,右图
47 Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) { 56 Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
@@ -44,8 +44,16 @@ export struct Card15Component { @@ -44,8 +44,16 @@ export struct Card15Component {
44 build() { 44 build() {
45 Column() { 45 Column() {
46 // rmh信息 46 // rmh信息
47 - RmhTitle({ rmhInfo: this.contentDTO.rmhInfo, publishTime: this.contentDTO.publishTime })  
48 - //新闻标题 47 + RmhTitle(
  48 + {
  49 + rmhInfo: this.contentDTO.rmhInfo,
  50 + publishTime: this.contentDTO.publishTime,
  51 + contentDTO: this.contentDTO,
  52 + compDTO: this.compDTO,
  53 + pageId: this.pageId,
  54 + pageName: this.pageName
  55 + }
  56 + ) //新闻标题
49 if (this.contentDTO.newsTitle) { 57 if (this.contentDTO.newsTitle) {
50 Text() { 58 Text() {
51 if (this.titleMarked) { 59 if (this.titleMarked) {
@@ -46,7 +46,16 @@ export struct Card16Component { @@ -46,7 +46,16 @@ export struct Card16Component {
46 Column() { 46 Column() {
47 // rmh信息 47 // rmh信息
48 if (this.contentDTO.rmhInfo) { 48 if (this.contentDTO.rmhInfo) {
49 - RmhTitle({ rmhInfo: this.contentDTO.rmhInfo, publishTime: this.contentDTO.publishTime }) 49 + RmhTitle(
  50 + {
  51 + rmhInfo: this.contentDTO.rmhInfo,
  52 + publishTime: this.contentDTO.publishTime,
  53 + contentDTO: this.contentDTO,
  54 + compDTO: this.compDTO,
  55 + pageId: this.pageId,
  56 + pageName: this.pageName
  57 + }
  58 + )
50 } 59 }
51 // 标题 60 // 标题
52 if (this.contentDTO.newsTitle) { 61 if (this.contentDTO.newsTitle) {
@@ -38,8 +38,16 @@ export struct Card19Component { @@ -38,8 +38,16 @@ export struct Card19Component {
38 build() { 38 build() {
39 Column() { 39 Column() {
40 // rmh信息 40 // rmh信息
41 - RmhTitle({ rmhInfo: this.contentDTO.rmhInfo, publishTime: this.contentDTO.publishTime })  
42 - // 标题 41 + RmhTitle(
  42 + {
  43 + rmhInfo: this.contentDTO.rmhInfo,
  44 + publishTime: this.contentDTO.publishTime,
  45 + contentDTO: this.contentDTO,
  46 + compDTO: this.compDTO,
  47 + pageId: this.pageId,
  48 + pageName: this.pageName
  49 + }
  50 + ) // 标题
43 if (this.contentDTO.newsTitle) { 51 if (this.contentDTO.newsTitle) {
44 Text() { 52 Text() {
45 if (this.titleMarked) { 53 if (this.titleMarked) {
@@ -38,8 +38,16 @@ export struct Card20Component { @@ -38,8 +38,16 @@ export struct Card20Component {
38 build() { 38 build() {
39 Column() { 39 Column() {
40 // rmh信息 40 // rmh信息
41 - RmhTitle({ rmhInfo: this.contentDTO.rmhInfo, publishTime: this.contentDTO.publishTime })  
42 - // 标题 41 + RmhTitle(
  42 + {
  43 + rmhInfo: this.contentDTO.rmhInfo,
  44 + publishTime: this.contentDTO.publishTime,
  45 + contentDTO: this.contentDTO,
  46 + compDTO: this.compDTO,
  47 + pageId: this.pageId,
  48 + pageName: this.pageName
  49 + }
  50 + ) // 标题
43 if (this.contentDTO.newsTitle) { 51 if (this.contentDTO.newsTitle) {
44 Text() { 52 Text() {
45 53
@@ -40,8 +40,16 @@ export struct Card21Component { @@ -40,8 +40,16 @@ export struct Card21Component {
40 build() { 40 build() {
41 Column() { 41 Column() {
42 // 顶部 rmh信息 42 // 顶部 rmh信息
43 - RmhTitle({ rmhInfo: this.contentDTO.rmhInfo, publishTime: this.contentDTO.publishTime })  
44 - // 中间内容 43 + RmhTitle(
  44 + {
  45 + rmhInfo: this.contentDTO.rmhInfo,
  46 + publishTime: this.contentDTO.publishTime,
  47 + contentDTO: this.contentDTO,
  48 + compDTO: this.compDTO,
  49 + pageId: this.pageId,
  50 + pageName: this.pageName
  51 + }
  52 + ) // 中间内容
45 Grid() { 53 Grid() {
46 GridItem() { 54 GridItem() {
47 Text() { 55 Text() {
@@ -5,6 +5,7 @@ import EditInfoViewModel from '../../viewmodel/EditInfoViewModel'; @@ -5,6 +5,7 @@ import EditInfoViewModel from '../../viewmodel/EditInfoViewModel';
5 import { WDRouterPage, WDRouterRule } from 'wdRouter'; 5 import { WDRouterPage, WDRouterRule } from 'wdRouter';
6 import {AreaPickerDialog} from '../view/areaPickerDialog/AreaPickerDialog' 6 import {AreaPickerDialog} from '../view/areaPickerDialog/AreaPickerDialog'
7 import {EditUserInfoCustomDialog} from '../view/areaPickerDialog/EditUserInfoCustomDialog' 7 import {EditUserInfoCustomDialog} from '../view/areaPickerDialog/EditUserInfoCustomDialog'
  8 +import {EditUserSexCustomDialog} from '../view/areaPickerDialog/EditUserSexCustomDialog'
8 import { AreaListModel } from '../../model/AreaListModel'; 9 import { AreaListModel } from '../../model/AreaListModel';
9 import router from '@ohos.router'; 10 import router from '@ohos.router';
10 import TrackingPageBrowseUtils from '../../utils/TrackingPageBrowseUtils' 11 import TrackingPageBrowseUtils from '../../utils/TrackingPageBrowseUtils'
@@ -58,6 +59,22 @@ struct EditUserInfoPage { @@ -58,6 +59,22 @@ struct EditUserInfoPage {
58 }, 59 },
59 }) 60 })
60 61
  62 + sexDialogController: CustomDialogController = new CustomDialogController({
  63 + builder: EditUserSexCustomDialog({
  64 + confirmCallback:(index)=>{
  65 + this.currentUserInfo.userExtend.sex = index;
  66 + this.currentUserInfo.editDataType = WDEditDataModelType.WDEditDataModelType_sex
  67 + this.updateEditModel()
  68 + }
  69 + }),
  70 + alignment: DialogAlignment.Bottom,
  71 + customStyle: true,
  72 + offset: {
  73 + dx: 0,
  74 + dy: -this.bottomSafeHeight
  75 + },
  76 + })
  77 +
61 async aboutToAppear() { 78 async aboutToAppear() {
62 let windowHight: window.Window = await window.getLastWindow(getContext(this)); 79 let windowHight: window.Window = await window.getLastWindow(getContext(this));
63 this.bottomSafeHeight = px2vp(windowHight.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).bottomRect.height) 80 this.bottomSafeHeight = px2vp(windowHight.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).bottomRect.height)
@@ -174,32 +191,8 @@ struct EditUserInfoPage { @@ -174,32 +191,8 @@ struct EditUserInfoPage {
174 this.dialogController.open() 191 this.dialogController.open()
175 } else if (i === 4) { 192 } else if (i === 4) {
176 this.dateDialogController.open() 193 this.dateDialogController.open()
177 -  
178 - // DatePickerDialog.show({  
179 - // start:new Date('1900-1-1'),  
180 - // end:new Date(),  
181 - // selected:new Date,  
182 - // lunar:false,  
183 - // onAccept:(value:DatePickerResult) => {  
184 - // let mon = value.month as number + 1  
185 - // let monStr = mon < 10? '0'+mon.toString():mon.toString();  
186 - // let dayStr = value.day as number < 10? '0'+value.day:value.day;  
187 - // this.currentUserInfo.userExtend.birthday = value.year+'-'+monStr+'-'+dayStr;  
188 - // this.currentUserInfo.editDataType = WDEditDataModelType.WDEditDataModelType_birthday  
189 - // this.updateEditModel()  
190 - // }  
191 - // })  
192 }else if(i === 5){ 194 }else if(i === 5){
193 - TextPickerDialog.show({  
194 - range:['男','女'],  
195 - canLoop:false,  
196 - selected:this.currentUserInfo.userExtend.sex === 0?1:0,  
197 - onAccept:(value:TextPickerResult) => {  
198 - this.currentUserInfo.userExtend.sex = value.index == 0?1:0;  
199 - this.currentUserInfo.editDataType = WDEditDataModelType.WDEditDataModelType_sex  
200 - this.updateEditModel()  
201 - }  
202 - }) 195 + this.sexDialogController.open()
203 } 196 }
204 }) 197 })
205 } 198 }
  1 +import { DisplayUtils, NumberFormatterUtils } from 'wdKit/Index'
  2 +import { SPHelper } from 'wdKit';
  3 +import { WDRouterPage, WDRouterRule } from 'wdRouter/Index';
  4 +import { SpConstants } from 'wdConstant/Index';
  5 +import measure from '@ohos.measure'
  6 +import {
  7 + ContentDetailRequest,
  8 + postExecuteLikeParams,
  9 +} from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest';
  10 +import { ParamType, TrackConstants, TrackingContent } from 'wdTracking/Index';
  11 +import {
  12 + ContentDetailDTO,
  13 + contentListParams,
  14 +} from 'wdBean';
  15 +import { PageRepository } from '../../repository/PageRepository';
  16 +import { LiveModel } from '../../viewmodel/LiveModel';
  17 +import { HttpUtils } from 'wdNetwork/Index';
  18 +
  19 +const TAG = 'LiveLikeComponent';
  20 +
  21 +interface ILikeStyleResp {
  22 + url: Resource;
  23 + name: string;
  24 +}
  25 +
  26 +@Component
  27 +export struct LiveLikeComponent {
  28 + private LiveModel: LiveModel = new LiveModel()
  29 + @Consume contentDetailData: ContentDetailDTO
  30 + @Prop pageComponentType: number
  31 + @State likesStyle: string = "love" // 点赞样式 love爱心型 thumb点赞手势 mourning 蜡烛(默哀) pray 祈福
  32 + @State likeStatus: boolean = false
  33 + @State openLikes: boolean = false // 是否可以点赞 1:可以 0:不可以
  34 + @Prop @Watch('onDataUpdated') data: Record<string, string>
  35 + enableBtn = true
  36 + styleType: number = 1 //1: 白色背景(图文底部栏) 2: 黑色背景(图集底部栏) 3 透明背景
  37 + @State likeCount: number = 0 //点赞数
  38 + pageParam: ParamType = {}
  39 + PageName: string = ''
  40 +
  41 + //上层传值 样例
  42 + // this.data['contentId'] = '30035444649' //必须
  43 + // this.data['userName'] = '人民日报网友2kD2xW'
  44 + // this.data['contentType'] = '8' //必须
  45 + // this.data['title'] = '开创两校交流先河!克罗地亚教育代表团访问同济大学'
  46 + // this.data['userHeaderUrl'] = ""
  47 + // this.data['channelId'] = "2059" //必须
  48 + // this.data['status'] = "1"
  49 + // 内容用 是否开启点赞 1是 0否;
  50 + // this.contentDetailData.openLikes == 1
  51 + async aboutToAppear() {
  52 + // 2:竖屏直播页 4:横屏直播页
  53 + // 点赞样式 love爱心型 thumb点赞手势 mourning 蜡烛(默哀) pray 祈福
  54 + this.likesStyle = this.contentDetailData?.liveInfo?.likesStyle
  55 + this.openLikes = this.contentDetailData?.liveInfo?.likeEnable == 1 ? true : false
  56 + console.log(TAG, 'this.contentDetailData', JSON.stringify(this.contentDetailData))
  57 + console.log(TAG, 'this.likesStyle', this.likesStyle)
  58 + console.log(TAG, 'this.openLikes', this.openLikes)
  59 + this.onDataUpdated()
  60 + this.contentTrackingDict()
  61 + }
  62 +
  63 + onDataUpdated() {
  64 + console.log(TAG, '点赞点击')
  65 + if (this.data) {
  66 + if (this.data['contentType'] !== 'undefined') {
  67 + //获取点赞状态
  68 + this.getLikeStatus()
  69 + //获取点赞数
  70 + this.getLikeCount()
  71 + }
  72 + }
  73 + }
  74 +
  75 + contentTrackingDict(){
  76 + this.pageParam = {
  77 + 'contentType': `${this.contentDetailData.newsType}`,
  78 + 'contentId': `${this.contentDetailData.newsId}`,
  79 + 'contentName': `${this.contentDetailData.newsTitle || ''}`,
  80 + }
  81 + if(this.contentDetailData.newsType == 2) {
  82 + this.PageName = TrackConstants.PageName.Live_Detail // 直播
  83 + }
  84 + }
  85 +
  86 + build() {
  87 + // 直播,点赞按钮底测有灰色圆角背景+右上点赞数量
  88 + this.likeCompStyle()
  89 + }
  90 +
  91 + /**
  92 + * 将点赞样式转换为icon
  93 + */
  94 + transLikeStyle(): ILikeStyleResp {
  95 + if (this.likesStyle === 'love' || this.likesStyle === 'thumb') {
  96 + return {
  97 + url: this.likeStatus ? $r(`app.media.ic_like_check`) :
  98 + this.styleType == 1 ? $r('app.media.icon_like_default') : $r(`app.media.ic_like_uncheck`),
  99 + name: '赞'
  100 + }
  101 + } else if (this.likesStyle === 'pray') {
  102 + return {
  103 + url: this.likeStatus ? $r(`app.media.ic_thub_check`) : $r(`app.media.ic_thub_uncheck`),
  104 + name: '祈祷'
  105 + }
  106 + } else if (this.likesStyle === 'mourning') {
  107 + return {
  108 + url: this.likeStatus ? $r(`app.media.ic_candle_check`) :
  109 + $r(`app.media.ic_candle_uncheck`),
  110 + name: '默哀'
  111 + }
  112 + }
  113 + return {
  114 + url: this.likeStatus ? $r(`app.media.ic_like_check`) :
  115 + this.styleType == 1 ? $r('app.media.icon_like_default') : $r(`app.media.ic_like_uncheck`),
  116 + name: '点赞'
  117 + }
  118 + }
  119 +
  120 + @Builder
  121 + likeCompStyle() {
  122 + Stack({ alignContent: Alignment.Bottom }) {
  123 + Column() {
  124 + Image(this.transLikeStyle().url)
  125 + .width(24)
  126 + .height(24)
  127 + .onClick(() => {
  128 + this.clickButtonEvent()
  129 + })
  130 + }
  131 + .justifyContent(FlexAlign.Center)
  132 + .width(36)
  133 + .height(36)
  134 + .borderRadius(18)
  135 + .backgroundColor((this.pageComponentType === 4 || this.pageComponentType === 2) ? '#4D000000' : this.pageComponentType === 8 ? Color.Transparent : '#FFF5F5F5')
  136 + Row() {
  137 + Text(NumberFormatterUtils.formatNumberWithWan(this.likeCount || ''))
  138 + .fontSize(8)
  139 + .fontColor(Color.White)
  140 + .padding({ left: 8, right: 2 })
  141 + }
  142 + .height(12)
  143 + .alignItems(VerticalAlign.Center)
  144 + .position({ x: '100%', y: 10 })
  145 + .markAnchor({ x: '100%' })
  146 + .backgroundImage($r('app.media.ic_like_back'))
  147 + .backgroundImageSize({height: 13})
  148 + .width(this.getMeasureText(NumberFormatterUtils.formatNumberWithWan(this.likeCount || '')) +
  149 + 12)
  150 + .visibility(this.likeCount > 0 ? Visibility.Visible : Visibility.Hidden)
  151 + }
  152 + .width(36)
  153 + .height(42)
  154 + .visibility(this.likesStyle == 'empty' || !this.openLikes ? Visibility.None : Visibility.Visible)
  155 +
  156 + }
  157 +
  158 + async clickButtonEvent() {
  159 + console.log(TAG, '点赞点击')
  160 + // 未登录,跳转登录
  161 + const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
  162 + if (!user_id) {
  163 + console.log(TAG, '点赞点击,未登录')
  164 + WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
  165 + return
  166 + }
  167 +
  168 + // if (!this.enableBtn) {
  169 + // return
  170 + // }
  171 + this.executeLike(this.likeStatus ? '0' : '1')
  172 +
  173 + }
  174 +
  175 + executeLike(status: string) {
  176 + console.log(TAG, '点赞接口调用', status)
  177 +
  178 + const params: postExecuteLikeParams = {
  179 + status: Number(status),
  180 + contentId: this.data['contentId'],
  181 + contentType: this.data['contentType']
  182 + }
  183 + if(this.data['relType']) {
  184 + params.relType = this.data['relType']
  185 + }
  186 + if(this.data['contentRelId']) {
  187 + params.contentRelId = this.data['contentRelId']
  188 + }
  189 + if(this.data['channelId']) {
  190 + params.channelId = this.data['channelId']
  191 + }
  192 +
  193 + console.log(TAG, "点赞 params", JSON.stringify(params))
  194 + ContentDetailRequest.postExecuteLike(params).then((data) => {
  195 +
  196 + console.log(TAG, '点赞接口调用成功', JSON.stringify(data))
  197 +
  198 + // 直播点赞一直增加
  199 + if (this.contentDetailData.liveInfo) {
  200 + this.likeStatus = true
  201 + this.likeCount++
  202 + TrackingContent.like(true,this.PageName,this.PageName,this.pageParam)
  203 + }
  204 +
  205 + if (this.likeCount <= 0) {
  206 + this.likeCount = 0
  207 + }
  208 +
  209 + this.enableBtn = true
  210 + }).catch(() => {
  211 + this.enableBtn = true
  212 + })
  213 + }
  214 +
  215 + async getLikeStatus() {
  216 + const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
  217 + if (!user_id) {
  218 + console.log(TAG, '查询点赞状态,未登录')
  219 + return
  220 + }
  221 + this.LiveModel.getLiveLike(this.data['contentId'], user_id, HttpUtils.getDeviceId()).then(data => {
  222 + console.log(TAG, '查询点赞、收藏状态==', JSON.stringify(data))
  223 + this.likeStatus = data
  224 + }).catch(() => {
  225 + this.likeStatus = false
  226 + })
  227 + }
  228 +
  229 + /**
  230 + * 获取点赞数
  231 + */
  232 + getLikeCount() {
  233 + // console.error(TAG, 'contentDetailData2222', JSON.stringify(this.contentDetailData))
  234 + const params: contentListParams = {
  235 + contentList: [{
  236 + contentId: this.contentDetailData?.newsId + '',
  237 + contentType: this.contentDetailData?.newsType,
  238 + }]
  239 + }
  240 + console.log(TAG, '查询点赞、收藏数量', JSON.stringify(params))
  241 + PageRepository.getContentInteract(params).then(res => {
  242 + console.log(TAG, '查询点赞、收藏数量 res', JSON.stringify(res))
  243 + if (res.data) {
  244 + this.likeCount = Number(res.data[0]?.likeNum)
  245 + } else {
  246 + this.likeCount = 0
  247 + }
  248 + }).catch(() => {
  249 + this.likeCount = 0
  250 + })
  251 + }
  252 + private getMeasureText(text: string) {
  253 + let width = measure.measureText({
  254 + textContent: text,
  255 + fontSize: 8,
  256 + lineHeight: 12,
  257 + constraintWidth: DisplayUtils.getDeviceWidth(),
  258 + })
  259 + width = px2vp(width)
  260 + return width
  261 + }
  262 +}
  1 +import { NumberFormatterUtils, SPHelper } from 'wdKit';
  2 +import promptAction from '@ohos.promptAction';
  3 +import {
  4 + batchLikeAndCollectResult,
  5 + batchLikeAndCollectParams,
  6 + ContentDetailDTO,
  7 + contentListParams,
  8 + InteractDataDTO,
  9 + postExecuteCollectRecordParams
  10 +} from 'wdBean';
  11 +import router from '@ohos.router';
  12 +import { MultiPictureDetailViewModel } from '../../viewmodel/MultiPictureDetailViewModel';
  13 +import { LiveLikeComponent } from './LiveLikeComponent';
  14 +import { CommentTabComponent, CommentIconComponent, } from '../comment/view/CommentTabComponent';
  15 +import { publishCommentModel } from '../comment/model/PublishCommentModel'
  16 +import { WDRouterPage, WDRouterRule } from 'wdRouter/Index';
  17 +import { PageRepository } from '../../repository/PageRepository';
  18 +import { SpConstants } from 'wdConstant/Index';
  19 +import { WDShare } from 'wdShare/Index';
  20 +import { EmitterEventId, EmitterUtils } from 'wdKit/Index'
  21 +import { ParamType, TrackConstants, TrackingContent } from 'wdTracking/Index';
  22 +
  23 +const TAG = 'LiveOperRowListView';
  24 +
  25 +/**
  26 + * 直播详情页底部通栏组件:包含返回、评论、点赞、收藏、分享
  27 + * 上层传值:
  28 + * 1、(必传) contentDetailData---直播详情
  29 + * 2、(非必传) operationButtonList---组件展示条件,
  30 + * ['comment', 'like', 'collect', 'share'],需要展示什么传什么
  31 + * comment--评论;like--点赞;collect--收藏;share--分享;
  32 + * 注意:外层需注册 @Provide contentDetailData:contentDetailData = {} as contentDetailData
  33 + * 传值示例:
  34 + LiveOperRowListView({
  35 +
  36 + contentDetailData: this.contentDetailData[0],
  37 + operationButtonList: ['comment', 'like', 'collect', 'share']
  38 + })
  39 + */
  40 +
  41 +@Preview
  42 +@Component
  43 +export struct LiveOperRowListView {
  44 + private onBack: () => void = () => {
  45 + }
  46 + private onCommentFocus: () => void = () => {
  47 + }
  48 + private onCommentIconClick: () => void = () => {
  49 + }
  50 +
  51 + @Provide inDialog: boolean = false
  52 +
  53 + @Prop @Watch('onDetailUpdated') contentDetailData: ContentDetailDTO // 稿件详情
  54 + /**
  55 + * 用于区分页面类型,在哪个页面嵌套就传相应的值
  56 + * 2:竖屏直播页 4:横屏直播页
  57 + * 8: 评论弹框内
  58 + */
  59 + @Prop pageComponentType?: number = -1
  60 + @Prop showBackIcon?: boolean = true
  61 + @Prop operationButtonList?: string[] = ['comment', 'collect', 'share'] // 组件展示条件
  62 + @State needLike: boolean = true
  63 + @ObjectLink publishCommentModel: publishCommentModel
  64 + @State styleType: number = -1
  65 + @State showCommentIcon: boolean = true // 评论图标
  66 + @State bgColor: ResourceColor = Color.White
  67 + @State interactData: InteractDataDTO = {} as InteractDataDTO
  68 + @State newsStatusOfUser: batchLikeAndCollectResult | undefined = undefined // 点赞、收藏状态
  69 + @State likeBean: Record<string, string> = {}
  70 + @State bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
  71 + @State dialogController: CustomDialogController | null = null;
  72 + pageParam: ParamType = {}
  73 + PageName: string = ''
  74 + @State likesStyle: number | string = "love" // 点赞样式 love爱心型 thumb点赞手势 mourning 蜡烛(默哀) pray 祈福
  75 + @State openLikes: boolean = false // 是否可以点赞 1:可以 0:不可以
  76 +
  77 + async aboutToAppear() {
  78 + console.info(TAG, 'this.needLike', this.needLike)
  79 + this.handleStyle()
  80 + this.onDetailUpdated()
  81 + //注册通知,来自别的组件的评论成功通知
  82 + EmitterUtils.receiveEvent(EmitterEventId.COMMENT_PUBLISH, (targetId?: string) => {
  83 + if (targetId) {
  84 + if (targetId == this.publishCommentModel.targetId) {
  85 + //新增评论
  86 + this.queryContentInteractCount()
  87 + }
  88 + }
  89 + })
  90 + this.contentTrackingDict()
  91 + }
  92 +
  93 + contentTrackingDict(){
  94 + this.pageParam = {
  95 + 'contentType': `${this.contentDetailData.newsType}`,
  96 + 'contentId': `${this.contentDetailData.newsId}`,
  97 + 'contentName': `${this.contentDetailData.newsTitle || ''}`,
  98 + }
  99 + if(this.contentDetailData.newsType == 2) {
  100 + this.PageName = TrackConstants.PageName.Live_Detail // 直播
  101 + }
  102 + }
  103 +
  104 + async onDetailUpdated() {
  105 + console.info(TAG, 'this.styleType', this.styleType)
  106 + this.handleStyle()
  107 + if (!this.contentDetailData) {
  108 + return
  109 + }
  110 + const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
  111 + if (user_id) {
  112 + this.getInteractDataStatus()
  113 + }
  114 + await this.queryContentInteractCount()
  115 + // 点赞需要数据
  116 + this.likeBean['contentId'] = this.contentDetailData.newsId + ''
  117 + if(this.contentDetailData.userInfo?.userName) {
  118 + this.likeBean['userName'] = this.contentDetailData.userInfo?.userName + ''
  119 + }
  120 + this.likeBean['contentType'] = this.contentDetailData.newsType + ''
  121 + if(this.contentDetailData.newsTitle) {
  122 + this.likeBean['title'] = this.contentDetailData.newsTitle + ''
  123 + }
  124 + if(this.contentDetailData.userInfo?.headPhotoUrl) {
  125 + this.likeBean['userHeaderUrl'] = this.contentDetailData.userInfo?.headPhotoUrl + ''
  126 + }
  127 + if(this.contentDetailData.reLInfo?.channelId) {
  128 + this.likeBean['channelId'] = this.contentDetailData.reLInfo?.channelId + ''
  129 + }
  130 + if(this.contentDetailData?.reLInfo?.relType) {
  131 + this.likeBean['relType'] = this.contentDetailData?.reLInfo?.relType + ''
  132 + }
  133 + if(this.contentDetailData?.reLInfo?.relId) {
  134 + this.likeBean['contentRelId'] = this.contentDetailData?.reLInfo?.relId + ''
  135 + }
  136 + console.info(TAG, 'contentDetailData----', JSON.stringify(this.contentDetailData))
  137 + console.info(TAG, 'likeBean----', JSON.stringify(this.likeBean))
  138 + console.info(TAG, 'this.operationButtonList', JSON.stringify(this.operationButtonList))
  139 + // 评论需要数据
  140 + /* this.publishCommentModel.targetId = this.contentDetailData.newsId + ''
  141 + this.publishCommentModel.targetRelId = this.contentDetailData.reLInfo?.relId + ''
  142 + this.publishCommentModel.targetTitle = this.contentDetailData.newsTitle + ''
  143 + this.publishCommentModel.targetRelType = this.contentDetailData.reLInfo?.relType + ''
  144 + this.publishCommentModel.targetRelObjectId = this.contentDetailData.reLInfo?.relObjectId + ''
  145 + this.publishCommentModel.keyArticle = this.contentDetailData.keyArticle + ''
  146 + this.publishCommentModel.targetType = this.contentDetailData.newsType + ''*/
  147 + // 2:竖屏直播页 3:图集 4:横屏直播页
  148 + // 点赞样式 love爱心型 thumb点赞手势 mourning 蜡烛(默哀) pray 祈福
  149 + this.likesStyle = this.contentDetailData?.liveInfo?.likesStyle
  150 + this.openLikes = this.contentDetailData?.liveInfo?.likeEnable == 1 ? true : false
  151 + }
  152 +
  153 + build() {
  154 + // 直播详情页
  155 +
  156 + Column() {
  157 + if(this.styleType != 3) {
  158 + Divider().strokeWidth(1).color(this.styleType == 1 ? '#F5F5F5' : this.styleType == 2 ? '#262626' : 'rgba(0,0,0,0)')
  159 + }
  160 +
  161 + Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
  162 + Row() {
  163 + Column() {
  164 + Image(this.styleType == 1 ? $r('app.media.icon_arrow_left') :
  165 + $r('app.media.icon_arrow_left_white'))
  166 + .width(24)
  167 + .height(24)
  168 + .aspectRatio(1)
  169 + .interpolation(ImageInterpolation.High)
  170 + }
  171 + .width(48)
  172 + .hoverEffect(HoverEffect.Scale)
  173 + .visibility(this.showBackIcon ? Visibility.Visible : Visibility.None)
  174 + .onClick(() => {
  175 + if (this.onBack) {
  176 + this.onBack()
  177 + }
  178 + router.back();
  179 + })
  180 +
  181 +
  182 + if (this.contentDetailData?.newsId) {
  183 + ForEach(this.operationButtonList, (item: string, index: number) => {
  184 + if (item == 'comment') {
  185 + this.builderComment()
  186 + } else if (item == 'like' && this.needLike) {
  187 + this.builderLike()
  188 + } else if (item == 'collect') {
  189 + this.builderCollect()
  190 + } else if (item == 'share') {
  191 + this.builderShare()
  192 + } else {
  193 + }
  194 + })
  195 + }
  196 + }
  197 + .width('100%')
  198 + .justifyContent(FlexAlign.Start)
  199 + }
  200 + .width('100%')
  201 + .backgroundColor(this.bgColor)
  202 + .padding({
  203 + top: 10,
  204 + // bottom: 10
  205 + bottom: `${this.bottomSafeHeight}px`
  206 + // bottom: 50
  207 + })
  208 + }
  209 +
  210 + }
  211 +
  212 + /**
  213 + * 评论组件
  214 + */
  215 + @Builder
  216 + builderComment() {
  217 + Column() {
  218 + if (this.contentDetailData.openComment == 1
  219 + && this.contentDetailData.commentDisplay == 1
  220 + && this.publishCommentModel?.targetId) {
  221 + CommentTabComponent({
  222 + publishCommentModel: this.publishCommentModel,
  223 + contentDetail: this.contentDetailData,
  224 + onCommentFocus: this.onCommentFocus,
  225 + pageComponentType: this.pageComponentType,
  226 + onLoad: (dialogController: CustomDialogController | null) => {
  227 + this.dialogController = dialogController
  228 + }
  229 + })
  230 + } else {
  231 + Blank()
  232 + }
  233 + }
  234 + .layoutWeight(1)
  235 + .margin({
  236 + right: this.pageComponentType === 1 ? 20 : 0,
  237 + left: 16
  238 + })
  239 +
  240 + if (this.showCommentIcon // 页面控制开关,直播传false
  241 + && this.contentDetailData.openComment == 1 // 内容开关
  242 + && this.publishCommentModel?.targetId) {
  243 + Column() {
  244 + CommentIconComponent({
  245 + publishCommentModel: this.publishCommentModel,
  246 + styleType: this.styleType,
  247 + contentDetail: this.contentDetailData
  248 + })
  249 + .onClick(() => {
  250 + this.onCommentIconClick()
  251 +
  252 + console.log(JSON.stringify(this.dialogController?.open))
  253 +
  254 + // 评论弹框内部嵌入
  255 + !this.showBackIcon && this.dialogController?.open()
  256 + })
  257 + }
  258 + .width(48)
  259 + }
  260 +
  261 + }
  262 +
  263 + /**
  264 + * 点赞组件
  265 + */
  266 + @Builder
  267 + builderLike() {
  268 + Column() {
  269 + LiveLikeComponent({
  270 + data: this.likeBean,
  271 + styleType: this.styleType,
  272 + pageComponentType: this.pageComponentType
  273 + })
  274 + }
  275 + .width(48)
  276 + .visibility(this.likesStyle == 4 || this.likesStyle == 'empty' || !this.openLikes ? Visibility.None : Visibility.Visible)
  277 + }
  278 +
  279 + /**
  280 + * 收藏组件
  281 + */
  282 + @Builder
  283 + builderCollect() {
  284 +
  285 + Stack() {
  286 + Image(this.newsStatusOfUser?.collectStatus == 1 ? $r('app.media.ic_collect_check1') :
  287 + this.styleType == 1 ? $r('app.media.iv_live_comment_collect_un') :
  288 + $r('app.media.iv_live_comment_collect_un_white'))
  289 + .width(24)
  290 + .height(24)
  291 + .interpolation(ImageInterpolation.High)
  292 + /*Text(`${this.interactData?.collectNum}`)
  293 + .fontSize(8)
  294 + .fontColor(Color.White)
  295 + .height(12)
  296 + .margin({ left: 6 })
  297 + .backgroundImage($r('app.media.comment_icon_number'))
  298 + .offset({
  299 + x: 12
  300 + })*/
  301 + }
  302 + .height(36)
  303 + .width(48)
  304 + .borderRadius(18)
  305 + .backgroundColor(this.pageComponentType === 2 ? '#4D000000' : Color.Transparent)
  306 + .onClick(() => {
  307 + this.toggleCollectStatus()
  308 + })
  309 +
  310 + }
  311 +
  312 + /**
  313 + * 分享组件
  314 + */
  315 + @Builder
  316 + builderShare() {
  317 + Column() {
  318 + Image(this.styleType == 1 ? $r('app.media.iv_live_comment_share') :
  319 + $r('app.media.iv_live_comment_share_white'))
  320 + .width(24)
  321 + .height(24)
  322 + .aspectRatio(1)
  323 + .interpolation(ImageInterpolation.High)
  324 + .onClick((event: ClickEvent) => {
  325 + // ToastUtils.showToast('分享为公共方法,待开发', 1000);
  326 + this.share()
  327 + })
  328 + }
  329 + .justifyContent(FlexAlign.Center)
  330 + .height(36)
  331 + .width(48)
  332 + .borderRadius(18)
  333 + .backgroundColor(this.pageComponentType === 2 ? '#4D000000' : Color.Transparent)
  334 + }
  335 +
  336 + handleStyle() {
  337 + if (this.styleType == 1) {
  338 + this.bgColor = Color.White
  339 + } else if (this.styleType == 2) {
  340 + this.bgColor = Color.Black
  341 + } else if (this.styleType == 3) {
  342 + this.bgColor = Color.Transparent
  343 + }
  344 + }
  345 +
  346 + share() {
  347 + WDShare.shareContent(this.contentDetailData)
  348 + }
  349 +
  350 + // 已登录->查询用户对作品收藏状态
  351 + private async getInteractDataStatus() {
  352 + try {
  353 + const params: batchLikeAndCollectParams = {
  354 + contentList: [
  355 + {
  356 + contentId: this.contentDetailData?.newsId + '',
  357 + contentType: this.contentDetailData?.newsType + '',
  358 + contentRelId: this.contentDetailData?.reLInfo?.relId || '' + '',
  359 + }
  360 + ]
  361 + }
  362 + console.info(TAG, '查询用户对作品收藏1', JSON.stringify(params))
  363 + // console.info(TAG, '查询用户对作品收藏11', JSON.stringify(params))
  364 + let data = await MultiPictureDetailViewModel.getInteractDataStatus(params)
  365 + console.info(TAG, '查询用户对作品收藏22', JSON.stringify(data))
  366 + this.newsStatusOfUser = data[0];
  367 + } catch (exception) {
  368 + // console.error(TAG, JSON.stringify(exception))
  369 + }
  370 + }
  371 +
  372 + /**
  373 + * 收藏、取消收藏
  374 + */
  375 + async toggleCollectStatus() {
  376 + // 未登录,跳转登录
  377 + const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
  378 + console.log(TAG, '收藏点击,登录', user_id)
  379 + if (!user_id) {
  380 + console.log(TAG, '收藏点击,用户未登录')
  381 + WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
  382 + return
  383 + }
  384 + const params: postExecuteCollectRecordParams = {
  385 + status: this.newsStatusOfUser?.collectStatus === 1 ? '0' : '1',
  386 + contentList: [{
  387 + contentId: this.contentDetailData?.newsId + '',
  388 + contentType: this.contentDetailData?.newsType + '',
  389 + relType: this.contentDetailData?.reLInfo?.relType || '' + '',
  390 + contentRelId: this.contentDetailData?.reLInfo?.relId || '' + '',
  391 + }],
  392 +
  393 + }
  394 + console.log(TAG, '收藏点击', JSON.stringify(params))
  395 + PageRepository.postExecuteCollectRecord(params).then(res => {
  396 + if (this.newsStatusOfUser) {
  397 + this.newsStatusOfUser.collectStatus = this.newsStatusOfUser?.collectStatus === 1 ? 0 : 1
  398 + if (this.newsStatusOfUser.collectStatus === 1) {
  399 + promptAction.showToast({ message: '收藏成功' })
  400 + TrackingContent.collect(true,this.PageName,this.PageName,this.pageParam)
  401 + } else {
  402 + TrackingContent.collect(false,this.PageName,this.PageName,this.pageParam)
  403 + }
  404 + this.queryContentInteractCount()
  405 + }
  406 + console.log(TAG, '收藏点击 this.newsStatusOfUser', JSON.stringify(this.newsStatusOfUser))
  407 + })
  408 +
  409 + }
  410 +
  411 + /**
  412 + * 查询点赞、收藏数量
  413 + */
  414 + queryContentInteractCount() {
  415 + // console.error(TAG, 'contentDetailData2222', JSON.stringify(this.contentDetailData))
  416 + const params: contentListParams = {
  417 + contentList: [{
  418 + contentId: this.contentDetailData?.newsId + '',
  419 + contentType: this.contentDetailData?.newsType,
  420 + }]
  421 + }
  422 + console.log(TAG, '查询点赞、收藏数量', JSON.stringify(params))
  423 + PageRepository.getContentInteract(params).then(res => {
  424 + console.log(TAG, '查询点赞、收藏数量 res', JSON.stringify(res))
  425 + if (res.data) {
  426 + this.interactData.likeNum = NumberFormatterUtils.formatNumberWithWan(res.data[0]?.likeNum)
  427 + this.interactData.collectNum = NumberFormatterUtils.formatNumberWithWan(res.data[0]?.collectNum)
  428 + this.interactData.commentNum = NumberFormatterUtils.formatNumberWithWan(res.data[0]?.commentNum)
  429 + // 评论组件需要数据
  430 + if (Number.parseInt(this.interactData.commentNum) >
  431 + Number.parseInt(this.publishCommentModel.totalCommentNumer)) {
  432 + this.publishCommentModel.totalCommentNumer = this.interactData.commentNum + '' || '0'
  433 + }
  434 + }
  435 + // console.log(TAG, '获取互动点赞等数据===', JSON.stringify(res))
  436 + console.log(TAG, 'this.interactData44', JSON.stringify(this.interactData))
  437 + console.log(TAG, 'this.publishCommentModel', JSON.stringify(this.publishCommentModel))
  438 + })
  439 + }
  440 +}
@@ -14,14 +14,6 @@ export struct DateCustomComponent { @@ -14,14 +14,6 @@ export struct DateCustomComponent {
14 .onDateChange((value) => { 14 .onDateChange((value) => {
15 this.selectDate = value as Date 15 this.selectDate = value as Date
16 }) 16 })
17 - // .onDateChange:(value:DatePickerResult) => {  
18 - // let mon = value.month as number + 1  
19 - // let monStr = mon < 10? '0'+mon.toString():mon.toString();  
20 - // let dayStr = value.day as number < 10? '0'+value.day:value.day;  
21 - // this.currentUserInfo.userExtend.birthday = value.year+'-'+monStr+'-'+dayStr;  
22 - // this.currentUserInfo.editDataType = WDEditDataModelType.WDEditDataModelType_birthday  
23 - // this.updateEditModel()  
24 - // }  
25 }.justifyContent(FlexAlign.Center) 17 }.justifyContent(FlexAlign.Center)
26 }.height('100%') 18 }.height('100%')
27 } 19 }
  1 +@CustomDialog
  2 +
  3 +export struct EditUserSexCustomDialog {
  4 + controller: CustomDialogController
  5 + confirmCallback: (selectIndex:number) => void = () => {
  6 + }
  7 + build() {
  8 + Column(){
  9 + Button('男',{type:ButtonType.Normal}).height(45).width('100%').fontSize(14).fontColor('#222222').backgroundColor(0xffffff)
  10 + .onClick(()=>{
  11 + this.confirmCallback(1)
  12 + this.controller.close()
  13 + })
  14 + Divider()
  15 + .color('#f5f5f5')
  16 + .width('100%')
  17 + .strokeWidth(1)
  18 + Button('女',{type:ButtonType.Normal}).height(45).width('100%').fontSize(14).fontColor('#222222').backgroundColor(0xffffff)
  19 + .onClick(()=>{
  20 + this.confirmCallback(0)
  21 + this.controller.close()
  22 + })
  23 + Divider()
  24 + .color('#f5f5f5')
  25 + .width('100%')
  26 + .strokeWidth(5)
  27 + Button('取消',{type:ButtonType.Normal}).height(80).width('100%').fontSize(14).fontColor('#222222').backgroundColor(0xffffff)
  28 + .onClick(()=>{
  29 + this.controller.close()
  30 + })
  31 + }.height(176).width('100%').backgroundColor(Color.White)
  32 + }
  33 +}
@@ -43,10 +43,19 @@ export class InfomationCardClick { @@ -43,10 +43,19 @@ export class InfomationCardClick {
43 return summaryType; 43 return summaryType;
44 } 44 }
45 45
46 - public static track(compDTO: CompDTO, contentDTO: ContentDTO, pageId: string, pageName: string): void { 46 + public static track(
  47 + compDTO: CompDTO,
  48 + contentDTO: ContentDTO,
  49 + pageId: string,
  50 + pageName: string,
  51 + action = 'detailPageShow', // like, commentClick, follow
  52 + bl = false,
  53 + followUserId = '',
  54 + followUserName = ''
  55 + ): void {
47 try { 56 try {
48 const extParams: ParamType = { 57 const extParams: ParamType = {
49 - 'action': 'detailPageShow', 58 + 'action': action,
50 'shareChannel': '', 59 'shareChannel': '',
51 'duration': 0, 60 'duration': 0,
52 'contentName': contentDTO.newsTitle, 61 'contentName': contentDTO.newsTitle,
@@ -87,7 +96,15 @@ export class InfomationCardClick { @@ -87,7 +96,15 @@ export class InfomationCardClick {
87 extParams['saAuthorName'] = contentDTO.source; 96 extParams['saAuthorName'] = contentDTO.source;
88 } 97 }
89 console.log('InfomationCardClick-params:', JSON.stringify(extParams)) 98 console.log('InfomationCardClick-params:', JSON.stringify(extParams))
90 - TrackingContent.common(TrackConstants.EventType.Click, pageId, pageName, extParams) 99 + if (action === 'detailPageShow') {
  100 + TrackingContent.common(TrackConstants.EventType.Click, pageId, pageName, extParams);
  101 + } else if (action === 'like') {
  102 + TrackingContent.like(bl, pageId, pageName, extParams);
  103 + } else if (action === 'commentClick') {
  104 + TrackingContent.commentClick(pageId, pageName, extParams);
  105 + } else if (action === 'follow') {
  106 + TrackingContent.follow(bl, followUserId, followUserName, pageId, pageName, extParams)
  107 + }
91 } catch (err) { 108 } catch (err) {
92 console.log('InfomationCardClick-err', JSON.stringify(err)) 109 console.log('InfomationCardClick-err', JSON.stringify(err))
93 } 110 }
1 import { HttpUrlUtils, ResponseDTO } from 'wdNetwork'; 1 import { HttpUrlUtils, ResponseDTO } from 'wdNetwork';
2 import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest'; 2 import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest';
3 import { Logger, ToastUtils, EmitterEventId, EmitterUtils } from 'wdKit'; 3 import { Logger, ToastUtils, EmitterEventId, EmitterUtils } from 'wdKit';
4 -import { LiveDetailsBean, ReserveBean, ReserveItemBean, joinPeopleNum } from 'wdBean/Index'; 4 +import { LiveDetailsBean, ReserveBean, ReserveItemBean, joinPeopleNum, LiveRoomDataBean, ValueType } from 'wdBean/Index';
5 5
6 const TAG = 'LiveModel' 6 const TAG = 'LiveModel'
7 7
@@ -73,6 +73,88 @@ export class LiveModel { @@ -73,6 +73,88 @@ export class LiveModel {
73 } 73 }
74 74
75 /** 75 /**
  76 + * 获取直播数据
  77 + * @param liveId
  78 + * @returns
  79 + */
  80 + getLiveRoomData(liveId: string) {
  81 + return new Promise<LiveRoomDataBean>((success, fail) => {
  82 + HttpRequest.get<ResponseDTO<LiveRoomDataBean>>(
  83 + HttpUrlUtils.getLiveRoomDataUrl() + `?liveId=${liveId}`,
  84 + ).then((data: ResponseDTO<LiveRoomDataBean>) => {
  85 + if (!data || !data.data) {
  86 + fail("数据为空")
  87 + return
  88 + }
  89 + if (data.code != 0) {
  90 + fail(data.message)
  91 + return
  92 + }
  93 + success(data.data)
  94 + }, (error: Error) => {
  95 + fail(error.message)
  96 + Logger.debug(TAG + ":error ", error.toString())
  97 + })
  98 + })
  99 + }
  100 +
  101 + /**
  102 + * 直播详情-C端点赞接口
  103 + * @param liveId
  104 + * @param number
  105 + * @param deviceId
  106 + * @returns
  107 + */
  108 + getLiveRoomNumberLike(liveId: string, number: number, deviceId: string | number) {
  109 + return new Promise<number>((success, fail) => {
  110 + HttpRequest.get<ResponseDTO<number>>(
  111 + HttpUrlUtils.getLiveRoomNumberLikeUrl() + `?liveId=${liveId}&number=${number}&deviceId=${deviceId}`,
  112 + ).then((data: ResponseDTO<number>) => {
  113 + if (!data || !data.data) {
  114 + fail("数据为空")
  115 + return
  116 + }
  117 + if (data.code != 0) {
  118 + fail(data.message)
  119 + return
  120 + }
  121 + success(data.data)
  122 + }, (error: Error) => {
  123 + fail(error.message)
  124 + Logger.debug(TAG + ":error ", error.toString())
  125 + })
  126 + })
  127 + }
  128 +
  129 + /**
  130 + * 直播详情-查询是否点赞接口
  131 + * @param liveId
  132 + * @param userId
  133 + * @param deviceId
  134 + * @returns
  135 + */
  136 + getLiveLike(liveId: string, userId: ValueType, deviceId: string | number) {
  137 + return new Promise<boolean>((success, fail) => {
  138 + HttpRequest.get<ResponseDTO<boolean>>(
  139 + HttpUrlUtils.getLiveLikeUrl() + `?liveId=${liveId}&userId=${userId}&deviceId=${deviceId}`,
  140 + ).then((data: ResponseDTO<boolean>) => {
  141 + if (!data || !data.data) {
  142 + fail("数据为空")
  143 + return
  144 + }
  145 + if (data.code != 0) {
  146 + fail(data.message)
  147 + return
  148 + }
  149 + success(data.data)
  150 + }, (error: Error) => {
  151 + fail(error.message)
  152 + Logger.debug(TAG + ":error ", error.toString())
  153 + })
  154 + })
  155 + }
  156 +
  157 + /**
76 * 查询预约状态 158 * 查询预约状态
77 * 159 *
78 [{"relationId":"500002824823","liveId":"20000120522"},{"relationId":"500002845517","liveId":"20000120782"}] 160 [{"relationId":"500002824823","liveId":"20000120522"},{"relationId":"500002845517","liveId":"20000120782"}]
@@ -112,6 +112,23 @@ export struct DetailPlayLiveCommon { @@ -112,6 +112,23 @@ export struct DetailPlayLiveCommon {
112 }) 112 })
113 } 113 }
114 114
  115 + // /**
  116 + // *
  117 + // * @returns true : 沉浸式;false : 非沉浸式
  118 + // */
  119 + // isImmersionLive(): boolean {
  120 + //
  121 + // let flag = false
  122 + //
  123 + // if (this.liveState === 'wait' || this.liveLandscape === 'news') {
  124 + // flag = false
  125 + // } else if (this.liveLandscape === 'general') {
  126 + // flag = true
  127 + // }
  128 + //
  129 + // return flag
  130 + // }
  131 +
115 onPageShow() { 132 onPageShow() {
116 this.pageShow = Math.random() 133 this.pageShow = Math.random()
117 Logger.info(TAG, 'onPageShow') 134 Logger.info(TAG, 'onPageShow')
1 -import { ContentDetailDTO, LiveRoomDataBean } from 'wdBean/Index'; 1 +import { ContentDetailDTO, LiveDetailsBean, LiveRoomDataBean } from 'wdBean/Index';
2 import { LiveViewModel } from '../viewModel/LiveViewModel'; 2 import { LiveViewModel } from '../viewModel/LiveViewModel';
3 import { TabComponent } from '../widgets/details/TabComponent'; 3 import { TabComponent } from '../widgets/details/TabComponent';
4 import { TopPlayComponent } from '../widgets/details/video/TopPlayComponet'; 4 import { TopPlayComponent } from '../widgets/details/video/TopPlayComponet';
@@ -6,9 +6,12 @@ import { DisplayDirection } from 'wdConstant/Index'; @@ -6,9 +6,12 @@ import { DisplayDirection } from 'wdConstant/Index';
6 import mediaquery from '@ohos.mediaquery'; 6 import mediaquery from '@ohos.mediaquery';
7 import { Logger, WindowModel } from 'wdKit/Index'; 7 import { Logger, WindowModel } from 'wdKit/Index';
8 import { router, window } from '@kit.ArkUI'; 8 import { router, window } from '@kit.ArkUI';
9 -import { WDAliPlayerController } from 'wdPlayer/Index'; 9 +import { devicePLSensorManager } from 'wdDetailPlayApi/Index';
  10 +import { LiveCommentComponent } from 'wdComponent/Index';
  11 +import { WDAliPlayerController, WDPlayerController } from 'wdPlayer/Index';
10 import { OperRowListView } from 'wdComponent/src/main/ets/components/view/OperRowListView'; 12 import { OperRowListView } from 'wdComponent/src/main/ets/components/view/OperRowListView';
11 import { publishCommentModel } from 'wdComponent/src/main/ets/components/comment/model/PublishCommentModel'; 13 import { publishCommentModel } from 'wdComponent/src/main/ets/components/comment/model/PublishCommentModel';
  14 +import { ResponseDTO } from 'wdNetwork/Index';
12 15
13 let TAG: string = 'DetailPlayLivePage'; 16 let TAG: string = 'DetailPlayLivePage';
14 17
@@ -34,6 +37,7 @@ export struct DetailPlayLivePage { @@ -34,6 +37,7 @@ export struct DetailPlayLivePage {
34 @Consume @Watch('onBackPressCus') pageBackPress: number 37 @Consume @Watch('onBackPressCus') pageBackPress: number
35 @Consume contentDetailData: ContentDetailDTO 38 @Consume contentDetailData: ContentDetailDTO
36 @Consume publishCommentModel: publishCommentModel 39 @Consume publishCommentModel: publishCommentModel
  40 + @Consume liveDetailsBean: LiveDetailsBean
37 41
38 aboutToAppear(): void { 42 aboutToAppear(): void {
39 Logger.info(TAG, `wyj-aboutToAppear`) 43 Logger.info(TAG, `wyj-aboutToAppear`)
@@ -61,14 +65,11 @@ export struct DetailPlayLivePage { @@ -61,14 +65,11 @@ export struct DetailPlayLivePage {
61 65
62 build() { 66 build() {
63 Column() { 67 Column() {
64 -  
65 TopPlayComponent({ playerController: this.playerController }) 68 TopPlayComponent({ playerController: this.playerController })
66 - .height(this.displayDirection == DisplayDirection.VERTICAL ? 211 : '100%')  
67 - 69 + .height(this.displayDirection == DisplayDirection.VERTICAL ?211:'100%')
68 TabComponent({ tabs: this.tabs, changeToTab: this.changeToTab }) 70 TabComponent({ tabs: this.tabs, changeToTab: this.changeToTab })
69 .layoutWeight(1) 71 .layoutWeight(1)
70 .visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None) 72 .visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None)
71 -  
72 OperRowListView({ 73 OperRowListView({
73 componentType: 4, 74 componentType: 4,
74 operationButtonList: ['comment', 'collect', 'share', 'like'], 75 operationButtonList: ['comment', 'collect', 'share', 'like'],
@@ -80,7 +81,8 @@ export struct DetailPlayLivePage { @@ -80,7 +81,8 @@ export struct DetailPlayLivePage {
80 // 切换到大家聊 81 // 切换到大家聊
81 this.changeToTab = Math.random() 82 this.changeToTab = Math.random()
82 } 83 }
83 - }).visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None) 84 + })
  85 + .visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None)
84 86
85 // LiveCommentComponent({ heartNum: this.liveRoomDataBean.likeNum }) 87 // LiveCommentComponent({ heartNum: this.liveRoomDataBean.likeNum })
86 // .visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None) 88 // .visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None)
@@ -118,9 +120,7 @@ export struct DetailPlayLivePage { @@ -118,9 +120,7 @@ export struct DetailPlayLivePage {
118 } 120 }
119 121
120 getLiveDetails() { 122 getLiveDetails() {
121 - const data = this.contentDetailData  
122 - console.error("XXXXZZZZ", 'contentDetailData ----liveState==>' + data.liveInfo?.liveState)  
123 - console.error("XXXXZZZZ", 'contentDetailData ----liveStyle==>' + data.liveInfo?.liveStyle) 123 + const data = this.liveDetailsBean
124 if (data.liveInfo?.liveState == 'wait') { 124 if (data.liveInfo?.liveState == 'wait') {
125 //直播样式 0-正常模式 , 1-隐藏直播间,2-隐藏大家聊 【人民号发布是竖屏的,为空】 125 //直播样式 0-正常模式 , 1-隐藏直播间,2-隐藏大家聊 【人民号发布是竖屏的,为空】
126 if (data.liveInfo?.liveStyle == 1) { 126 if (data.liveInfo?.liveStyle == 1) {
@@ -131,14 +131,8 @@ export struct DetailPlayLivePage { @@ -131,14 +131,8 @@ export struct DetailPlayLivePage {
131 this.tabs = ['简介', '直播间', '大家聊'] 131 this.tabs = ['简介', '直播间', '大家聊']
132 } 132 }
133 } else { 133 } else {
134 - if (data.liveInfo?.liveStyle == 1) {  
135 - this.tabs = ['大家聊']  
136 - } else if (data.liveInfo?.liveStyle == 2) {  
137 - this.tabs = ['直播间',]  
138 - } else {  
139 this.tabs = ['直播间', '大家聊'] 134 this.tabs = ['直播间', '大家聊']
140 } 135 }
141 - }  
142 136
143 } 137 }
144 138
1 import { HttpUrlUtils, ResponseDTO } from 'wdNetwork'; 1 import { HttpUrlUtils, ResponseDTO } from 'wdNetwork';
2 import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest'; 2 import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest';
3 import { Logger, ToastUtils, EmitterEventId, EmitterUtils } from 'wdKit'; 3 import { Logger, ToastUtils, EmitterEventId, EmitterUtils } from 'wdKit';
4 -import { ContentDetailDTO, LiveDetailsBean, LiveRoomBean, LiveRoomDataBean, ReserveItemBean } from 'wdBean/Index'; 4 +import { ContentDetailDTO, LiveDetailsBean, LiveRoomBean, LiveRoomDataBean, ReserveItemBean, ValueType } from 'wdBean/Index';
5 import { ContentDetailRequest } from 'wdDetailPlayApi/Index'; 5 import { ContentDetailRequest } from 'wdDetailPlayApi/Index';
6 6
7 const TAG = 'LiveModel' 7 const TAG = 'LiveModel'
@@ -151,6 +151,62 @@ export class LiveModel { @@ -151,6 +151,62 @@ export class LiveModel {
151 } 151 }
152 152
153 /** 153 /**
  154 + * 直播详情-C端点赞接口
  155 + * @param liveId
  156 + * @param number
  157 + * @param deviceId
  158 + * @returns
  159 + */
  160 + getLiveRoomNumberLike(liveId: string, number: number, deviceId: string | number) {
  161 + return new Promise<number>((success, fail) => {
  162 + HttpRequest.get<ResponseDTO<number>>(
  163 + HttpUrlUtils.getLiveRoomNumberLikeUrl() + `?liveId=${liveId}&number=${number}&deviceId=${deviceId}`,
  164 + ).then((data: ResponseDTO<number>) => {
  165 + if (!data || !data.data) {
  166 + fail("数据为空")
  167 + return
  168 + }
  169 + if (data.code != 0) {
  170 + fail(data.message)
  171 + return
  172 + }
  173 + success(data.data)
  174 + }, (error: Error) => {
  175 + fail(error.message)
  176 + Logger.debug(TAG + ":error ", error.toString())
  177 + })
  178 + })
  179 + }
  180 +
  181 + /**
  182 + * 直播详情-查询是否点赞接口
  183 + * @param liveId
  184 + * @param userId
  185 + * @param deviceId
  186 + * @returns
  187 + */
  188 + getLiveLike(liveId: string, userId: ValueType, deviceId: string | number) {
  189 + return new Promise<boolean>((success, fail) => {
  190 + HttpRequest.get<ResponseDTO<boolean>>(
  191 + HttpUrlUtils.getLiveLikeUrl() + `?liveId=${liveId}&userId=${userId}&deviceId=${deviceId}`,
  192 + ).then((data: ResponseDTO<boolean>) => {
  193 + if (!data || !data.data) {
  194 + fail("数据为空")
  195 + return
  196 + }
  197 + if (data.code != 0) {
  198 + fail(data.message)
  199 + return
  200 + }
  201 + success(data.data)
  202 + }, (error: Error) => {
  203 + fail(error.message)
  204 + Logger.debug(TAG + ":error ", error.toString())
  205 + })
  206 + })
  207 + }
  208 +
  209 + /**
154 * 获取直播预约状态 210 * 获取直播预约状态
155 * @param relationId 211 * @param relationId
156 * @param liveId 212 * @param liveId
1 -import { ContentDetailDTO, LiveDetailsBean, LiveRoomBean, LiveRoomDataBean } from 'wdBean/Index' 1 +import { ContentDetailDTO, LiveDetailsBean, LiveRoomBean, LiveRoomDataBean, ValueType } from 'wdBean/Index'
2 2
3 import { ResponseDTO } from 'wdNetwork/Index' 3 import { ResponseDTO } from 'wdNetwork/Index'
4 import { LiveModel } from './LiveModel' 4 import { LiveModel } from './LiveModel'
@@ -68,6 +68,26 @@ export class LiveViewModel { @@ -68,6 +68,26 @@ export class LiveViewModel {
68 }) 68 })
69 }) 69 })
70 } 70 }
  71 + // 直播详情-C端点赞接口
  72 + getLiveRoomNumberLike(liveId: string, number: number, deviceId: string | number) {
  73 + return new Promise<number>((success, fail) => {
  74 + this.liveModel.getLiveRoomNumberLike(liveId, number, deviceId).then((data) => {
  75 + success(data)
  76 + }).catch((message: string) => {
  77 + fail(message)
  78 + })
  79 + })
  80 + }
  81 + // 直播详情-查询是否点赞接口
  82 + getLiveLike(liveId: string, userId: ValueType, deviceId: string | number) {
  83 + return new Promise<boolean>((success, fail) => {
  84 + this.liveModel.getLiveLike(liveId, userId, deviceId).then((data) => {
  85 + success(data)
  86 + }).catch((message: string) => {
  87 + fail(message)
  88 + })
  89 + })
  90 + }
71 91
72 //直播预约状态查询 92 //直播预约状态查询
73 getLiveAppointmentStatus(relationId: string, liveId: string) { 93 getLiveAppointmentStatus(relationId: string, liveId: string) {
1 -import { window } from '@kit.ArkUI' 1 +import { window } from '@kit.ArkUI';
2 import lottie from '@ohos/lottie'; 2 import lottie from '@ohos/lottie';
3 3
4 -import { NumberFormatterUtils, StringUtils, WindowModel } from 'wdKit/Index'  
5 -import { DateFormatUtil, WDAliPlayerController, WDPlayerController } from 'wdPlayer/Index'  
6 -import { ContentDetailDTO, LiveDetailsBean, LiveRoomDataBean } from 'wdBean/Index'  
7 -import { DisplayDirection } from 'wdConstant/Index'  
8 -import { LiveFollowComponent, LottieView } from 'wdComponent/Index' 4 +import { NumberFormatterUtils, StringUtils, WindowModel } from 'wdKit/Index';
  5 +import { DateFormatUtil, PlayerConstants, WDAliPlayerController } from 'wdPlayer/Index';
  6 +import { ContentDetailDTO, LiveRoomDataBean } from 'wdBean/Index';
  7 +import { DisplayDirection } from 'wdConstant/Index';
  8 +import { LiveFollowComponent, LottieView } from 'wdComponent/Index';
9 9
10 @Component 10 @Component
11 export struct PlayUIComponent { 11 export struct PlayUIComponent {
12 playerController?: WDAliPlayerController; 12 playerController?: WDAliPlayerController;
13 //菜单键是否可见 13 //菜单键是否可见
14 @State @Watch('onChangeMenuVisible') isMenuVisible: boolean = true 14 @State @Watch('onChangeMenuVisible') isMenuVisible: boolean = true
15 -// @Consume liveDetailsBean: LiveDetailsBean  
16 @Consume contentDetailData: ContentDetailDTO 15 @Consume contentDetailData: ContentDetailDTO
17 @Consume liveRoomDataBean: LiveRoomDataBean 16 @Consume liveRoomDataBean: LiveRoomDataBean
18 @State currentTime: string = '' 17 @State currentTime: string = ''
@@ -21,8 +20,11 @@ export struct PlayUIComponent { @@ -21,8 +20,11 @@ export struct PlayUIComponent {
21 //是否处于播放状态中 20 //是否处于播放状态中
22 @State isPlayStatus: boolean = true 21 @State isPlayStatus: boolean = true
23 @Consume displayDirection: DisplayDirection 22 @Consume displayDirection: DisplayDirection
24 -  
25 @Prop isShowBottom: boolean 23 @Prop isShowBottom: boolean
  24 + // 播放地址 (视频或者 直播地址)
  25 + @Prop liveUrl: string
  26 + // 当前播放资源的状态
  27 + @Consume playSourceState: number
26 28
27 onChangeMenuVisible() { 29 onChangeMenuVisible() {
28 if (!this.contentDetailData || !this.contentDetailData.liveInfo || 30 if (!this.contentDetailData || !this.contentDetailData.liveInfo ||
@@ -41,6 +43,21 @@ export struct PlayUIComponent { @@ -41,6 +43,21 @@ export struct PlayUIComponent {
41 43
42 aboutToAppear(): void { 44 aboutToAppear(): void {
43 this.onChangeMenuVisible() 45 this.onChangeMenuVisible()
  46 +
  47 + this.initPlayerSet()
  48 + }
  49 +
  50 + aboutToDisappear(): void {
  51 + if (this.contentDetailData.liveInfo?.liveState == 'running') {
  52 + lottie.destroy('live_status_wait')
  53 + }
  54 + }
  55 +
  56 + /*
  57 + 初始话播放器设置
  58 + */
  59 + initPlayerSet(){
  60 +
44 //播放进度监听 61 //播放进度监听
45 if (this.playerController) { 62 if (this.playerController) {
46 this.playerController.onTimeUpdate = (position: number, duration: number) => { 63 this.playerController.onTimeUpdate = (position: number, duration: number) => {
@@ -49,12 +66,7 @@ export struct PlayUIComponent { @@ -49,12 +66,7 @@ export struct PlayUIComponent {
49 this.progressVal = Math.floor(position * 100 / duration); 66 this.progressVal = Math.floor(position * 100 / duration);
50 } 67 }
51 } 68 }
52 - }  
53 69
54 - aboutToDisappear(): void {  
55 - if (this.contentDetailData.liveInfo?.liveState == 'running') {  
56 - lottie.destroy('live_status_wait')  
57 - }  
58 } 70 }
59 71
60 build() { 72 build() {
@@ -62,7 +74,7 @@ export struct PlayUIComponent { @@ -62,7 +74,7 @@ export struct PlayUIComponent {
62 if (this.contentDetailData && this.contentDetailData.liveInfo) { 74 if (this.contentDetailData && this.contentDetailData.liveInfo) {
63 this.getTopUIComponent() 75 this.getTopUIComponent()
64 this.getMiddleUIComponent() 76 this.getMiddleUIComponent()
65 - if(this.isShowBottom){ 77 + if (this.isShowBottom) {
66 this.getBottomUIComponent() 78 this.getBottomUIComponent()
67 } 79 }
68 80
@@ -251,16 +263,13 @@ export struct PlayUIComponent { @@ -251,16 +263,13 @@ export struct PlayUIComponent {
251 @Builder 263 @Builder
252 getBottomUIComponent() { 264 getBottomUIComponent() {
253 Row() { 265 Row() {
254 - if (this.contentDetailData?.liveInfo?.liveState == 'wait') {  
255 - Blank()  
256 - } else if (this.contentDetailData?.liveInfo?.liveState == 'running') {  
257 - this.playOrPauseBtn()  
258 - Blank()  
259 - } else if (this.contentDetailData?.liveInfo?.liveState == 'end') {  
260 - if (StringUtils.isEmpty(this.contentDetailData?.liveInfo?.vlive[0]?.replayUri)) {  
261 - Blank()  
262 - } else { 266 +
  267 + // 视频资源
  268 + if (!StringUtils.isEmpty(this.liveUrl)) {
  269 + // 暂定和播放按钮
263 this.playOrPauseBtn() 270 this.playOrPauseBtn()
  271 + // 开始时间
  272 + if (this.contentDetailData?.liveInfo?.liveState != 'running' || this.contentDetailData.showTime) {
264 Text(this.currentTime) 273 Text(this.currentTime)
265 .fontColor(Color.White) 274 .fontColor(Color.White)
266 .fontWeight(600) 275 .fontWeight(600)
@@ -268,7 +277,12 @@ export struct PlayUIComponent { @@ -268,7 +277,12 @@ export struct PlayUIComponent {
268 .margin({ 277 .margin({
269 left: 16 278 left: 16
270 }) 279 })
  280 + }
  281 +
  282 + // 进度条
271 this.playProgressView() 283 this.playProgressView()
  284 + // 总的播放时间
  285 + if (this.contentDetailData?.liveInfo?.liveState != 'running' || this.contentDetailData.showTime) {
272 Text(this.totalTime) 286 Text(this.totalTime)
273 .fontColor(Color.White) 287 .fontColor(Color.White)
274 .fontWeight(600) 288 .fontWeight(600)
@@ -277,11 +291,13 @@ export struct PlayUIComponent { @@ -277,11 +291,13 @@ export struct PlayUIComponent {
277 right: 16 291 right: 16
278 }) 292 })
279 } 293 }
  294 +
  295 + } else {
  296 + Blank()
280 } 297 }
281 - if (this.contentDetailData?.liveInfo?.liveState == 'running'  
282 - || (this.contentDetailData?.liveInfo?.liveState == 'end' &&  
283 - StringUtils.isNotEmpty(this.contentDetailData?.liveInfo?.vlive[0]?.replayUri))  
284 - ) { 298 +
  299 + // 全屏按钮
  300 + if (!StringUtils.isEmpty(this.liveUrl)) {
285 Image($r('app.media.icon_live_player_full_screen')) 301 Image($r('app.media.icon_live_player_full_screen'))
286 .width(24) 302 .width(24)
287 .height(24) 303 .height(24)
@@ -298,6 +314,7 @@ export struct PlayUIComponent { @@ -298,6 +314,7 @@ export struct PlayUIComponent {
298 }) 314 })
299 .visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None) 315 .visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None)
300 } 316 }
  317 +
301 } 318 }
302 .alignItems(VerticalAlign.Center) 319 .alignItems(VerticalAlign.Center)
303 .linearGradient({ angle: 0, colors: [['#99000000', 0], ['#00000000', 1]] }) 320 .linearGradient({ angle: 0, colors: [['#99000000', 0], ['#00000000', 1]] })
@@ -313,6 +330,19 @@ export struct PlayUIComponent { @@ -313,6 +330,19 @@ export struct PlayUIComponent {
313 330
314 @Builder 331 @Builder
315 playOrPauseBtn() { 332 playOrPauseBtn() {
  333 +
  334 + if (this.playSourceState === PlayerConstants.STATUS_COMPLETION) {
  335 + //资源播放完成
  336 + Image($r('app.media.player_play_ic'))
  337 + .width(24)
  338 + .height(24)
  339 + .onClick(() => {
  340 + this.isPlayStatus = true
  341 + this.initPlayerSet()
  342 + this.playerController?.firstPlay(this.liveUrl)
  343 + this.playerController?.play()
  344 + })
  345 + } else {
316 //暂停、播放 346 //暂停、播放
317 Image(this.isPlayStatus ? $r('app.media.icon_live_player_pause') : $r('app.media.player_play_ic')) 347 Image(this.isPlayStatus ? $r('app.media.icon_live_player_pause') : $r('app.media.player_play_ic'))
318 .width(24) 348 .width(24)
@@ -328,6 +358,8 @@ export struct PlayUIComponent { @@ -328,6 +358,8 @@ export struct PlayUIComponent {
328 }) 358 })
329 } 359 }
330 360
  361 + }
  362 +
331 @Builder 363 @Builder
332 playProgressView() { 364 playProgressView() {
333 Slider({ 365 Slider({
@@ -13,7 +13,9 @@ const TAG: string = 'TopPlayComponent' @@ -13,7 +13,9 @@ const TAG: string = 'TopPlayComponent'
13 export struct TopPlayComponent { 13 export struct TopPlayComponent {
14 @Consume @Watch('updateData') contentDetailData: ContentDetailDTO 14 @Consume @Watch('updateData') contentDetailData: ContentDetailDTO
15 playerController?: WDAliPlayerController 15 playerController?: WDAliPlayerController
16 - @State imgUrl: string = '' 16 + // 预告片图片/视频url
  17 + @State previewUrl: string = ''
  18 + @State isVideoSource: boolean = false
17 //未开始 19 //未开始
18 @State isWait: boolean = false 20 @State isWait: boolean = false
19 //已结束直播 21 //已结束直播
@@ -24,14 +26,15 @@ export struct TopPlayComponent { @@ -24,14 +26,15 @@ export struct TopPlayComponent {
24 @State isLoading: boolean = false 26 @State isLoading: boolean = false
25 // 获取播放资源能播放了 27 // 获取播放资源能播放了
26 @State isCanPlay: boolean = false 28 @State isCanPlay: boolean = false
27 - 29 + // 当前播放资源的状态
  30 + @Provide playSourceState: number = 0
28 private playUrl: string = "" 31 private playUrl: string = ""
29 private xComponentIsLoaded: boolean = false 32 private xComponentIsLoaded: boolean = false
30 33
31 aboutToAppear(): void { 34 aboutToAppear(): void {
32 if (this.playerController) { 35 if (this.playerController) {
33 this.playerController.onCanplay = () => { 36 this.playerController.onCanplay = () => {
34 - 37 + Logger.debug(TAG, 'onCanplay==>')
35 this.isCanPlay = true 38 this.isCanPlay = true
36 this.isLoading = true 39 this.isLoading = true
37 this.playerController?.play() 40 this.playerController?.play()
@@ -40,35 +43,56 @@ export struct TopPlayComponent { @@ -40,35 +43,56 @@ export struct TopPlayComponent {
40 43
41 this.playerController.onStatusChange = (status: number) => { 44 this.playerController.onStatusChange = (status: number) => {
42 45
  46 + this.playSourceState = status
  47 + Logger.debug(TAG, 'status==>' + status)
43 if (status === PlayerConstants.STATUS_ERROR) { 48 if (status === PlayerConstants.STATUS_ERROR) {
44 this.isError = true 49 this.isError = true
45 this.isLoading = true 50 this.isLoading = true
46 -  
47 this.isCanPlay = false 51 this.isCanPlay = false
  52 + } else if (status === PlayerConstants.STATUS_COMPLETION) {
  53 + // 播放完成
  54 +
  55 +
48 } else { 56 } else {
49 this.isError = false 57 this.isError = false
50 } 58 }
51 59
52 -  
53 } 60 }
54 } 61 }
55 this.updateData() 62 this.updateData()
56 } 63 }
57 64
58 updateData() { 65 updateData() {
  66 +
  67 + // 检测等待中的直播预告是否视频资源
  68 + if (this.contentDetailData.liveInfo && this.contentDetailData.liveInfo.previewType === 1
  69 + && this.contentDetailData.liveInfo.previewUrl &&
  70 + this.contentDetailData.liveInfo.previewUrl.length > 0) {
  71 + // 预告资源是视频
  72 + this.isVideoSource = true
  73 + this.contentDetailData.showTime = true
  74 + }
59 //直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停 75 //直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停
60 if (this.contentDetailData.liveInfo && this.contentDetailData.liveInfo.previewUrl && 76 if (this.contentDetailData.liveInfo && this.contentDetailData.liveInfo.previewUrl &&
61 this.contentDetailData.liveInfo.previewUrl.length > 0) { 77 this.contentDetailData.liveInfo.previewUrl.length > 0) {
62 - this.imgUrl = this.contentDetailData.liveInfo.previewUrl  
63 - Logger.debug(TAG, 'ok+' + `${this.imgUrl}`) 78 + this.previewUrl = this.contentDetailData.liveInfo.previewUrl
  79 +
64 } else if (this.contentDetailData.fullColumnImgUrls && this.contentDetailData.fullColumnImgUrls.length > 0) { 80 } else if (this.contentDetailData.fullColumnImgUrls && this.contentDetailData.fullColumnImgUrls.length > 0) {
65 - this.imgUrl = this.contentDetailData.fullColumnImgUrls[0].url  
66 - Logger.debug(TAG, 'ok-' + `${this.imgUrl}`) 81 + this.previewUrl = this.contentDetailData.fullColumnImgUrls[0].url
67 } 82 }
  83 +
  84 + Logger.debug(TAG, 'ok+' + `${this.previewUrl}`)
  85 +
  86 + if (this.isVideoSource) {
  87 + this.isWait = false
  88 + this.isLoading = false
  89 + } else {
68 this.isWait = this.contentDetailData?.liveInfo?.liveState == 'wait' 90 this.isWait = this.contentDetailData?.liveInfo?.liveState == 'wait'
69 - if(this.isWait ){ 91 + if (this.isWait) {
70 this.isLoading = true 92 this.isLoading = true
71 } 93 }
  94 + }
  95 +
72 this.isEnd = this.contentDetailData?.liveInfo?.liveState === 'end' && 96 this.isEnd = this.contentDetailData?.liveInfo?.liveState === 'end' &&
73 StringUtils.isEmpty(this.contentDetailData?.liveInfo?.vlive[0]?.replayUri) 97 StringUtils.isEmpty(this.contentDetailData?.liveInfo?.vlive[0]?.replayUri)
74 if (!this.isWait && this.contentDetailData.liveInfo && this.contentDetailData.liveInfo.vlive.length > 0) { 98 if (!this.isWait && this.contentDetailData.liveInfo && this.contentDetailData.liveInfo.vlive.length > 0) {
@@ -78,13 +102,19 @@ export struct TopPlayComponent { @@ -78,13 +102,19 @@ export struct TopPlayComponent {
78 } else if (this.contentDetailData.liveInfo.liveState == 'end') { 102 } else if (this.contentDetailData.liveInfo.liveState == 'end') {
79 playUrl = this.contentDetailData.liveInfo.vlive[0].replayUri 103 playUrl = this.contentDetailData.liveInfo.vlive[0].replayUri
80 } 104 }
81 - // this.playerController?.firstPlay('https://rmrbcmsonline.peopleapp.com/upload/rmh/video/mp4/202404/1713752415708fb81d0b8f137b.mp4'); 105 +
  106 + if (this.isVideoSource) {
  107 + this.playUrl = this.previewUrl
  108 + this.tryToPlay()
  109 + } else {
82 if (StringUtils.isNotEmpty(playUrl)) { 110 if (StringUtils.isNotEmpty(playUrl)) {
83 Logger.debug(TAG, `${playUrl}`) 111 Logger.debug(TAG, `${playUrl}`)
84 this.playUrl = playUrl 112 this.playUrl = playUrl
85 this.tryToPlay() 113 this.tryToPlay()
86 } 114 }
87 } 115 }
  116 +
  117 + }
88 } 118 }
89 119
90 tryToPlay() { 120 tryToPlay() {
@@ -115,18 +145,22 @@ export struct TopPlayComponent { @@ -115,18 +145,22 @@ export struct TopPlayComponent {
115 .width('100%') 145 .width('100%')
116 .visibility(this.isWait ? Visibility.None : Visibility.Visible) 146 .visibility(this.isWait ? Visibility.None : Visibility.Visible)
117 147
  148 + if (this.isVideoSource) {
  149 +
  150 + } else {
118 // 直播房间图 151 // 直播房间图
119 - Image(this.imgUrl) 152 + Image(this.previewUrl)
120 .objectFit(ImageFit.Cover) 153 .objectFit(ImageFit.Cover)
121 .visibility(this.isWait || this.isEnd ? Visibility.Visible : Visibility.None) 154 .visibility(this.isWait || this.isEnd ? Visibility.Visible : Visibility.None)
122 .contrast(this.isEnd ? 0.2 : 1) 155 .contrast(this.isEnd ? 0.2 : 1)
123 .width('100%') 156 .width('100%')
  157 + }
124 158
125 // loading 159 // loading
126 PictureLoading().visibility(this.isLoading ? Visibility.None : Visibility.Visible) 160 PictureLoading().visibility(this.isLoading ? Visibility.None : Visibility.Visible)
127 161
128 // 视频播放器上的控制面板和信息 162 // 视频播放器上的控制面板和信息
129 - PlayUIComponent({ playerController: this.playerController, isShowBottom: this.isCanPlay }) 163 + PlayUIComponent({ playerController: this.playerController, isShowBottom: this.isCanPlay, liveUrl: this.playUrl })
130 164
131 // 直播结束 165 // 直播结束
132 Text('直播已结束') 166 Text('直播已结束')
1 import { Action, ContentDetailDTO, LiveDetailsBean, LiveRoomDataBean, LiveRoomItemBean } from 'wdBean/Index' 1 import { Action, ContentDetailDTO, LiveDetailsBean, LiveRoomDataBean, LiveRoomItemBean } from 'wdBean/Index'
2 import { LiveCommentComponent } from 'wdComponent/Index' 2 import { LiveCommentComponent } from 'wdComponent/Index'
3 import { publishCommentModel } from 'wdComponent/src/main/ets/components/comment/model/PublishCommentModel' 3 import { publishCommentModel } from 'wdComponent/src/main/ets/components/comment/model/PublishCommentModel'
4 -import { OperRowListView } from 'wdComponent/src/main/ets/components/view/OperRowListView' 4 +import { LiveOperRowListView } from 'wdComponent'
5 import PageModel from 'wdComponent/src/main/ets/viewmodel/PageModel' 5 import PageModel from 'wdComponent/src/main/ets/viewmodel/PageModel'
6 import { DisplayDirection, SpConstants, ViewType } from 'wdConstant/Index' 6 import { DisplayDirection, SpConstants, ViewType } from 'wdConstant/Index'
7 import { ContentDetailRequest } from 'wdDetailPlayApi/Index' 7 import { ContentDetailRequest } from 'wdDetailPlayApi/Index'
@@ -112,9 +112,8 @@ export struct PlayerCommentComponent { @@ -112,9 +112,8 @@ export struct PlayerCommentComponent {
112 .margin({ bottom: 20 }) 112 .margin({ bottom: 20 })
113 113
114 // 收藏、分享、点赞是否需要根据字段显隐 114 // 收藏、分享、点赞是否需要根据字段显隐
115 - OperRowListView({ 115 + LiveOperRowListView({
116 styleType: 3, 116 styleType: 3,
117 - componentType: 4,  
118 pageComponentType: 2, // 竖屏直播页 117 pageComponentType: 2, // 竖屏直播页
119 operationButtonList: ['comment', 'collect', 'share', 'like'], 118 operationButtonList: ['comment', 'collect', 'share', 'like'],
120 contentDetailData: this.contentDetailData, 119 contentDetailData: this.contentDetailData,
@@ -50,8 +50,6 @@ export struct WDPlayerRenderLiveView { @@ -50,8 +50,6 @@ export struct WDPlayerRenderLiveView {
50 50
51 aboutToAppear() { 51 aboutToAppear() {
52 MGPlayRenderViewIns.add(); 52 MGPlayRenderViewIns.add();
53 -  
54 - console.log('playerController', this.playerController)  
55 insIndex++; 53 insIndex++;
56 if (!this.playerController) { 54 if (!this.playerController) {
57 return 55 return
@@ -59,7 +57,6 @@ export struct WDPlayerRenderLiveView { @@ -59,7 +57,6 @@ export struct WDPlayerRenderLiveView {
59 57
60 this.playerController.onVideoSizeChange = (width: number, height: number) => { 58 this.playerController.onVideoSizeChange = (width: number, height: number) => {
61 // console.log(`WDPlayerRenderView onVideoSizeChange width:${width} videoTop:${height}`) 59 // console.log(`WDPlayerRenderView onVideoSizeChange width:${width} videoTop:${height}`)
62 - Logger.info(TAG, ` onVideoSizeChange width:${width} videoTop:${height}`)  
63 this.videoWidth = width; 60 this.videoWidth = width;
64 this.videoHeight = height; 61 this.videoHeight = height;
65 this.updateLayout() 62 this.updateLayout()
@@ -83,8 +80,6 @@ export struct WDPlayerRenderLiveView { @@ -83,8 +80,6 @@ export struct WDPlayerRenderLiveView {
83 .onLoad(async (event) => { 80 .onLoad(async (event) => {
84 Logger.info(TAG, 'onLoad') 81 Logger.info(TAG, 'onLoad')
85 let surfaceId = this.xComponentController.getXComponentSurfaceId() 82 let surfaceId = this.xComponentController.getXComponentSurfaceId()
86 - console.log('surfaceId===', surfaceId)  
87 - console.log('insId===', this.insId)  
88 this.xComponentController.setXComponentSurfaceSize({ 83 this.xComponentController.setXComponentSurfaceSize({
89 surfaceWidth: 1920, 84 surfaceWidth: 1920,
90 surfaceHeight: 720 85 surfaceHeight: 720