张善主

fix(聚合页):增加下拉刷新功能

@@ -244,7 +244,6 @@ export class HttpUrlUtils { @@ -244,7 +244,6 @@ export class HttpUrlUtils {
244 * first_load&refreshTime=1710829610144&pageId=28927&channelStrategy=2&groupId=40621& 244 * first_load&refreshTime=1710829610144&pageId=28927&channelStrategy=2&groupId=40621&
245 * pageSize=20&pageNum=1&topicId=10000009445 245 * pageSize=20&pageNum=1&topicId=10000009445
246 * */ 246 * */
247 - static readonly MORNING_EVENING_PAGE_INFO_PATH: string = "/api/rmrb-bff-display-zh/display/zh/c/pageInfo";  
248 /** 247 /**
249 * 直播回顾 248 * 直播回顾
250 * */ 249 * */
  1 +import { CompAdvMatInfoBean } from '../adv/CompAdvInfoBean';
  2 +import { AudioDTO } from '../content/AudioDTO';
  3 +import { ContentDTO } from '../content/ContentDTO';
  4 +
  5 +export interface BaseDTO {
  6 +
  7 +}
1 import { CompAdvMatInfoBean } from '../adv/CompAdvInfoBean'; 1 import { CompAdvMatInfoBean } from '../adv/CompAdvInfoBean';
2 import { AudioDTO } from '../content/AudioDTO'; 2 import { AudioDTO } from '../content/AudioDTO';
3 import { ContentDTO } from '../content/ContentDTO'; 3 import { ContentDTO } from '../content/ContentDTO';
  4 +import { BaseDTO } from './BaseDTO';
4 5
5 -export interface CompDTO { 6 +export interface CompDTO extends BaseDTO{
6 backgroundColor: string; 7 backgroundColor: string;
7 backgroundImgUrl: string; 8 backgroundImgUrl: string;
8 cityCode: string; 9 cityCode: string;
@@ -6,8 +6,9 @@ import { slideShows } from '../morningevening/slideShows'; @@ -6,8 +6,9 @@ import { slideShows } from '../morningevening/slideShows';
6 import { VoiceInfoDTO } from '../detail/VoiceInfoDTO'; 6 import { VoiceInfoDTO } from '../detail/VoiceInfoDTO';
7 import { RmhInfoDTO } from '../detail/RmhInfoDTO'; 7 import { RmhInfoDTO } from '../detail/RmhInfoDTO';
8 import { commentInfo } from './commentInfo'; 8 import { commentInfo } from './commentInfo';
  9 +import { BaseDTO } from '../component/BaseDTO';
9 10
10 -export interface ContentDTO { 11 +export interface ContentDTO extends BaseDTO {
11 appStyle: string; 12 appStyle: string;
12 cityCode: string; 13 cityCode: string;
13 coverSize: string; 14 coverSize: string;
@@ -53,7 +53,7 @@ export struct CardAdvBottom { @@ -53,7 +53,7 @@ export struct CardAdvBottom {
53 let a = this.compDTO; 53 let a = this.compDTO;
54 let currentIndex = -1 54 let currentIndex = -1
55 for (let i = 0; i < this.pageModel.compList.size(); i++) { 55 for (let i = 0; i < this.pageModel.compList.size(); i++) {
56 - let b = this.pageModel.compList.getData(i) 56 + let b = this.pageModel.compList.getData(i) as CompDTO
57 if (a.compStyle === b.compStyle && a.matInfo === b.matInfo) { 57 if (a.compStyle === b.compStyle && a.matInfo === b.matInfo) {
58 currentIndex = i 58 currentIndex = i
59 break; 59 break;
@@ -65,7 +65,7 @@ export struct CardAdvTop { @@ -65,7 +65,7 @@ export struct CardAdvTop {
65 let a = this.compDTO; 65 let a = this.compDTO;
66 let currentIndex = -1 66 let currentIndex = -1
67 for (let i = 0; i < this.pageModel.compList.size(); i++) { 67 for (let i = 0; i < this.pageModel.compList.size(); i++) {
68 - let b = this.pageModel.compList.getData(i) 68 + let b = this.pageModel.compList.getData(i) as CompDTO
69 if (a.compStyle === b.compStyle && a.matInfo === b.matInfo) { 69 if (a.compStyle === b.compStyle && a.matInfo === b.matInfo) {
70 currentIndex = i 70 currentIndex = i
71 break; 71 break;
1 import { ContentDTO , Action,GoldenPositionExtraBean} from 'wdBean'; 1 import { ContentDTO , Action,GoldenPositionExtraBean} from 'wdBean';
2 import { CommonConstants ,ViewType} from 'wdConstant'; 2 import { CommonConstants ,ViewType} from 'wdConstant';
3 import PageViewModel from '../../viewmodel/PageViewModel'; 3 import PageViewModel from '../../viewmodel/PageViewModel';
4 -import RefreshLayout from '../page/RefreshLayout';  
5 -import { RefreshLayoutBean } from '../page/RefreshLayoutBean';  
6 import PageModel from '../../viewmodel/PageModel'; 4 import PageModel from '../../viewmodel/PageModel';
7 import { DateTimeUtils, LazyDataSource } from 'wdKit/Index'; 5 import { DateTimeUtils, LazyDataSource } from 'wdKit/Index';
8 import router from '@ohos.router'; 6 import router from '@ohos.router';
@@ -10,6 +8,12 @@ import { CardParser } from '../CardParser'; @@ -10,6 +8,12 @@ import { CardParser } from '../CardParser';
10 import { channelSkeleton } from '../skeleton/channelSkeleton' 8 import { channelSkeleton } from '../skeleton/channelSkeleton'
11 import { ErrorComponent } from '../view/ErrorComponent'; 9 import { ErrorComponent } from '../view/ErrorComponent';
12 import { EmptyComponent } from '../view/EmptyComponent'; 10 import { EmptyComponent } from '../view/EmptyComponent';
  11 +import { listTouchEvent } from '../../utils/PullDownRefresh';
  12 +import PageAdModel from '../../viewmodel/PageAdvModel';
  13 +import { RefreshLayoutBean } from '../refresh/RefreshLayoutBean';
  14 +import RefreshLayout from '../refresh/RefreshLayout';
  15 +import PageNoMoreLayout from './PageNoMoreLayout';
  16 +import { NoMoreBean } from './NoMoreBean';
13 17
14 const TAG: string = 'ThemeListPage'; 18 const TAG: string = 'ThemeListPage';
15 19
@@ -17,22 +21,26 @@ const TAG: string = 'ThemeListPage'; @@ -17,22 +21,26 @@ const TAG: string = 'ThemeListPage';
17 @Component 21 @Component
18 struct ThemeListPage { 22 struct ThemeListPage {
19 @State private pageModel: PageModel = new PageModel(); 23 @State private pageModel: PageModel = new PageModel();
20 - @State data: LazyDataSource<ContentDTO> = new LazyDataSource();  
21 sort: number = 1; 24 sort: number = 1;
22 currentPage: number = 1; 25 currentPage: number = 1;
23 pageSize: number = 20; 26 pageSize: number = 20;
24 title: string = '金刚位聚合页' 27 title: string = '金刚位聚合页'
25 extra: string = '' 28 extra: string = ''
  29 + @State private pageAdvModel: PageAdModel = new PageAdModel();
26 30
27 aboutToAppear(): void { 31 aboutToAppear(): void {
28 let par:Action = router.getParams() as Action; 32 let par:Action = router.getParams() as Action;
29 let params = par?.params; 33 let params = par?.params;
30 this.extra = params?.extra?.extra || ''; 34 this.extra = params?.extra?.extra || '';
31 this.title = params?.extra?.title || ''; 35 this.title = params?.extra?.title || '';
32 - PageViewModel.postThemeList(this.sort, this.currentPage, this.pageSize,this.extra).then((liveReviewDTO) => { 36 +
  37 + this.pageModel.pageType = 1;
  38 + this.pageModel.extra = this.extra;
  39 +
  40 + PageViewModel.postThemeList(this.currentPage, this.pageSize,this.extra).then((liveReviewDTO) => {
33 console.log(`postThemeList${JSON.stringify(liveReviewDTO)}`) 41 console.log(`postThemeList${JSON.stringify(liveReviewDTO)}`)
34 - this.data.push(...liveReviewDTO.list)  
35 - if(this.data.getDataArray().length > 0){ 42 + this.pageModel.compList.addItems(liveReviewDTO.list)
  43 + if(this.pageModel.compList.getDataArray().length > 0){
36 this.pageModel.viewType = ViewType.LOADED; 44 this.pageModel.viewType = ViewType.LOADED;
37 }else{ 45 }else{
38 this.pageModel.viewType = ViewType.EMPTY 46 this.pageModel.viewType = ViewType.EMPTY
@@ -56,6 +64,13 @@ struct ThemeListPage { @@ -56,6 +64,13 @@ struct ThemeListPage {
56 .padding({ 64 .padding({
57 bottom: $r('app.float.card_comp_pagePadding_tb') 65 bottom: $r('app.float.card_comp_pagePadding_tb')
58 }) 66 })
  67 + .onTouch((event: TouchEvent | undefined) => {
  68 + if (event) {
  69 + if (this.pageModel.viewType === ViewType.LOADED) {
  70 + listTouchEvent(this.pageModel, this.pageAdvModel, event);
  71 + }
  72 + }
  73 + })
59 } 74 }
60 @Builder 75 @Builder
61 LoadingLayout() { 76 LoadingLayout() {
@@ -105,12 +120,12 @@ struct ThemeListPage { @@ -105,12 +120,12 @@ struct ThemeListPage {
105 // 下拉刷新 120 // 下拉刷新
106 ListItem() { 121 ListItem() {
107 RefreshLayout({ 122 RefreshLayout({
108 - refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullDown, this.pageModel.pullDownRefreshImage,  
109 - this.pageModel.pullDownRefreshText, this.pageModel.pullDownRefreshHeight) 123 + refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullDown, this.pageModel.load,
  124 + this.pageModel.offsetY)
110 }) 125 })
111 } 126 }
112 127
113 - LazyForEach(this.data, (contentDTO: ContentDTO, contentIndex: number) => { 128 + LazyForEach(this.pageModel.compList, (contentDTO: ContentDTO, contentIndex: number) => {
114 ListItem() { 129 ListItem() {
115 Column() { 130 Column() {
116 CardParser({ contentDTO }); 131 CardParser({ contentDTO });
@@ -119,6 +134,17 @@ struct ThemeListPage { @@ -119,6 +134,17 @@ struct ThemeListPage {
119 }, 134 },
120 (contentDTO: ContentDTO, contentIndex: number) => contentDTO.pageId + contentIndex.toString() 135 (contentDTO: ContentDTO, contentIndex: number) => contentDTO.pageId + contentIndex.toString()
121 ) 136 )
  137 + // 加载更多
  138 + ListItem() {
  139 + if (this.pageModel.hasMore) {
  140 + // LoadMoreLayout({
  141 + // refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullUpLoad, this.pageModel.pullUpLoadImage,
  142 + // this.pageModel.pullUpLoadText, this.pageModel.pullUpLoadHeight)
  143 + // })
  144 + } else if (!this.pageModel.contentNeedScroll) {
  145 + PageNoMoreLayout({ noMoreBean: new NoMoreBean(this.pageModel.pageInfo.baselineCopywriting) })
  146 + }
  147 + }
122 } 148 }
123 .scrollBar(BarState.Off) 149 .scrollBar(BarState.Off)
124 .cachedCount(8) 150 .cachedCount(8)
@@ -180,7 +180,7 @@ export class PageRepository { @@ -180,7 +180,7 @@ export class PageRepository {
180 * 早晚报pageInfo请求 180 * 早晚报pageInfo请求
181 * */ 181 * */
182 static getMorningEveningPageInfoUrl(pageId: string) { 182 static getMorningEveningPageInfoUrl(pageId: string) {
183 - let url = HttpUrlUtils.getHost() + HttpUrlUtils.MORNING_EVENING_PAGE_INFO_PATH; 183 + let url = HttpUrlUtils.getHost() + HttpUrlUtils.PAGE_INFO_PATH;
184 url = url + "?pageId=" + pageId; 184 url = url + "?pageId=" + pageId;
185 Logger.info(TAG, "getMorningEveningPageInfoUrl url = " + url) 185 Logger.info(TAG, "getMorningEveningPageInfoUrl url = " + url)
186 return url; 186 return url;
@@ -4,7 +4,7 @@ import PageModel from '../viewmodel/PageModel'; @@ -4,7 +4,7 @@ import PageModel from '../viewmodel/PageModel';
4 import PageHelper from '../viewmodel/PageHelper'; 4 import PageHelper from '../viewmodel/PageHelper';
5 import PageAdModel from '../viewmodel/PageAdvModel'; 5 import PageAdModel from '../viewmodel/PageAdvModel';
6 import { LoadStatus } from '../components/refresh/RefreshLayoutBean'; 6 import { LoadStatus } from '../components/refresh/RefreshLayoutBean';
7 - 7 +//下拉刷新上拉加载更多组件
8 export function listTouchEvent(pageModel: PageModel, pageAdvModel: PageAdModel, event: TouchEvent) { 8 export function listTouchEvent(pageModel: PageModel, pageAdvModel: PageAdModel, event: TouchEvent) {
9 switch (event.type) { 9 switch (event.type) {
10 case TouchType.Down: 10 case TouchType.Down:
@@ -51,20 +51,34 @@ export class PageHelper { @@ -51,20 +51,34 @@ export class PageHelper {
51 51
52 getPageInfo(pageModel: PageModel, pageAdvModel: PageAdModel) { 52 getPageInfo(pageModel: PageModel, pageAdvModel: PageAdModel) {
53 pageModel.currentPage = 1; 53 pageModel.currentPage = 1;
54 - PageViewModel.getPageInfo(pageModel.pageId).then(pageInfo => {  
55 - if (pageInfo == null) { 54 + if(pageModel.pageType == 1){
  55 + PageViewModel.postThemeList(pageModel.currentPage, pageModel.pageSize,pageModel.extra).then((liveReviewDTO) => {
  56 + if(liveReviewDTO == null || liveReviewDTO.list == null || liveReviewDTO.list.length == 0){
  57 + pageModel.viewType = ViewType.EMPTY;
  58 + pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_NoContent1;
  59 + return;
  60 + }else{
  61 + //更新数据
  62 + pageModel.compList.addItems(liveReviewDTO.list);
  63 + closeRefresh(pageModel, true);
  64 + }
  65 + })
  66 + }else{
  67 + PageViewModel.getPageInfo(pageModel.pageId).then(pageInfo => {
  68 + if (pageInfo == null) {
  69 + pageModel.viewType = ViewType.EMPTY;
  70 + pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_NoContent1;
  71 + return;
  72 + }
  73 + pageModel.pageInfo = pageInfo;
  74 + //解析广告资源
  75 + pageAdvModel.analysisAdvSource(pageInfo);
  76 + this.parseGroup(pageModel)
  77 + }).catch(() => {
56 pageModel.viewType = ViewType.EMPTY; 78 pageModel.viewType = ViewType.EMPTY;
57 - pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_NoContent1;  
58 - return;  
59 - }  
60 - pageModel.pageInfo = pageInfo;  
61 - //解析广告资源  
62 - pageAdvModel.analysisAdvSource(pageInfo);  
63 - this.parseGroup(pageModel)  
64 - }).catch(() => {  
65 - pageModel.viewType = ViewType.EMPTY;  
66 - pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_ContentFailed;  
67 - }) 79 + pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_ContentFailed;
  80 + })
  81 + }
68 } 82 }
69 83
70 84
@@ -292,31 +306,36 @@ export class PageHelper { @@ -292,31 +306,36 @@ export class PageHelper {
292 * comp加载更多,分页加载 306 * comp加载更多,分页加载
293 */ 307 */
294 private compLoadMore(pageModel: PageModel) { 308 private compLoadMore(pageModel: PageModel) {
295 - PageViewModel.getPageData(pageModel.bizCopy())  
296 - .then((data: PageDTO) => {  
297 - pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()  
298 - if (data == null || data.compList == null || data.compList.length == 0) {  
299 - pageModel.hasMore = false;  
300 - } else {  
301 - // 直接认为有分页,一直加载分页。直到没有数据,再停止  
302 - pageModel.currentPage++;  
303 - pageModel.hasMore = true;  
304 - let sizeBefore: number = pageModel.compList.size();  
305 -  
306 - //移除音频 和 活动  
307 - this.collectPageComp(pageModel, data)  
308 -  
309 - // pageModel.compList.push(...data.compList)  
310 - // TODO 暂时屏蔽,此处代码会造成 广告逻辑错乱,只有第一页有广告数据,随着加载更多,第二页也会出现广告数据  
311 - // PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {  
312 - // // 刷新,替换所有数据  
313 - // pageModel.compList.updateItems(sizeBefore, data)  
314 - // pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()  
315 - // })  
316 - }  
317 - }).catch((err: string | Resource) => {  
318 - promptAction.showToast({ message: err });  
319 - }) 309 + //聚合页
  310 + if(pageModel.pageType == 1){
  311 +
  312 + }else{
  313 + PageViewModel.getPageData(pageModel.bizCopy())
  314 + .then((data: PageDTO) => {
  315 + pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
  316 + if (data == null || data.compList == null || data.compList.length == 0) {
  317 + pageModel.hasMore = false;
  318 + } else {
  319 + // 直接认为有分页,一直加载分页。直到没有数据,再停止
  320 + pageModel.currentPage++;
  321 + pageModel.hasMore = true;
  322 + let sizeBefore: number = pageModel.compList.size();
  323 +
  324 + //移除音频 和 活动
  325 + this.collectPageComp(pageModel, data)
  326 +
  327 + // pageModel.compList.push(...data.compList)
  328 + // TODO 暂时屏蔽,此处代码会造成 广告逻辑错乱,只有第一页有广告数据,随着加载更多,第二页也会出现广告数据
  329 + // PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
  330 + // // 刷新,替换所有数据
  331 + // pageModel.compList.updateItems(sizeBefore, data)
  332 + // pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
  333 + // })
  334 + }
  335 + }).catch((err: string | Resource) => {
  336 + promptAction.showToast({ message: err });
  337 + })
  338 + }
320 } 339 }
321 340
322 341
@@ -7,6 +7,7 @@ import { GroupInfoDTO, PageInfoDTO } from 'wdBean/src/main/ets/bean/navigation/P @@ -7,6 +7,7 @@ import { GroupInfoDTO, PageInfoDTO } from 'wdBean/src/main/ets/bean/navigation/P
7 import { AdvRuleBean, CompAdvBean } from 'wdBean/src/main/ets/bean/adv/AdvsRuleBean'; 7 import { AdvRuleBean, CompAdvBean } from 'wdBean/src/main/ets/bean/adv/AdvsRuleBean';
8 import { WDViewDefaultType } from '../components/view/EmptyComponent'; 8 import { WDViewDefaultType } from '../components/view/EmptyComponent';
9 import { LoadStatus } from '../components/refresh/RefreshLayoutBean'; 9 import { LoadStatus } from '../components/refresh/RefreshLayoutBean';
  10 +import { BaseDTO } from 'wdBean/src/main/ets/bean/component/BaseDTO';
10 11
11 /** 12 /**
12 * 页面下拉刷新、上拉加载数据bean。 13 * 页面下拉刷新、上拉加载数据bean。
@@ -22,7 +23,7 @@ export default class PageModel { @@ -22,7 +23,7 @@ export default class PageModel {
22 groupList: GroupInfoDTO[] = []; 23 groupList: GroupInfoDTO[] = [];
23 // 当前请求数据的group 24 // 当前请求数据的group
24 groupData: GroupInfoDTO = {} as GroupInfoDTO; 25 groupData: GroupInfoDTO = {} as GroupInfoDTO;
25 - compList: LazyDataSource<CompDTO> = new LazyDataSource(); 26 + compList: LazyDataSource<BaseDTO> = new LazyDataSource();
26 // 是否comp自己处理分页加载;默认是最后一个comp下的content有分页数据,需要节目内容的分页加载 27 // 是否comp自己处理分页加载;默认是最后一个comp下的content有分页数据,需要节目内容的分页加载
27 // (如:首页-视频tab-直播tab,最后一个comp是直播回看列表,视频内容需要分页加载) 28 // (如:首页-视频tab-直播tab,最后一个comp是直播回看列表,视频内容需要分页加载)
28 contentNeedScroll: boolean = false; 29 contentNeedScroll: boolean = false;
@@ -58,7 +59,10 @@ export default class PageModel { @@ -58,7 +59,10 @@ export default class PageModel {
58 59
59 // 记录已经展示的稿件和组件数量 60 // 记录已经展示的稿件和组件数量
60 pageTotalCompSize: number = 0; 61 pageTotalCompSize: number = 0;
  62 + //0默认信息流,1聚合页
  63 + pageType: number = 0;
61 64
  65 + extra: string = ''
62 /** 66 /**
63 * 简单复制业务数据 67 * 简单复制业务数据
64 */ 68 */
@@ -380,7 +380,7 @@ export class PageViewModel extends BaseViewModel { @@ -380,7 +380,7 @@ export class PageViewModel extends BaseViewModel {
380 }) 380 })
381 } 381 }
382 382
383 - async postThemeList(sort: number, pageNum: number, pageSize: number,extra: string) : Promise<LiveReviewDTO> { 383 + async postThemeList(pageNum: number, pageSize: number,extra: string) : Promise<LiveReviewDTO> {
384 let bean: GoldenPositionExtraBean = JSON.parse(extra) 384 let bean: GoldenPositionExtraBean = JSON.parse(extra)
385 bean.pageNum = pageNum 385 bean.pageNum = pageNum
386 bean.pageSize = pageSize 386 bean.pageSize = pageSize