xugenyuan

ref |> 增加热门评论接口数据展示

Signed-off-by: xugenyuan <xugenyuan@wondertek.com.cn>
@@ -35,6 +35,8 @@ export class commentListModel extends PageModel { @@ -35,6 +35,8 @@ export class commentListModel extends PageModel {
35 totalCommentNum: string = '0' 35 totalCommentNum: string = '0'
36 hasNext: number = 0 36 hasNext: number = 0
37 list: commentItemModel[] = [] 37 list: commentItemModel[] = []
  38 + hotList: commentItemModel[] = [] // 仅第一页存在
  39 + hotIds: string[] = [] // 仅第一页存在
38 // constructor(pageNum:number, pageSize:number, totalCount: number, hasNext: number, list: commentItemModel[]) { 40 // constructor(pageNum:number, pageSize:number, totalCount: number, hasNext: number, list: commentItemModel[]) {
39 // super() 41 // super()
40 // this.pageNum = pageNum 42 // this.pageNum = pageNum
@@ -45,9 +47,16 @@ export class commentListModel extends PageModel { @@ -45,9 +47,16 @@ export class commentListModel extends PageModel {
45 // } 47 // }
46 } 48 }
47 49
  50 +export enum CommentItemCustomType {
  51 + comment = 0,
  52 + newTitle = 1, // 最新评论标题
  53 + hotTitle = 2, // 热门评论标题
  54 + hotComment = 3,
  55 +}
48 56
49 @Observed 57 @Observed
50 export class commentItemModel { 58 export class commentItemModel {
  59 + api_customType: CommentItemCustomType = CommentItemCustomType.comment
51 authorLike: string = '' 60 authorLike: string = ''
52 avatarFrame: string = '' 61 avatarFrame: string = ''
53 checkStatus: string = '' 62 checkStatus: string = ''
1 import { DateTimeUtils, EmitterEventId, EmitterUtils, LazyDataSource, 1 import { DateTimeUtils, EmitterEventId, EmitterUtils, LazyDataSource,
2 PublicDialogManager, 2 PublicDialogManager,
3 StringUtils } from 'wdKit/Index'; 3 StringUtils } from 'wdKit/Index';
4 -import { commentItemModel, WDPublicUserType } from '../model/CommentModel'; 4 +import { CommentItemCustomType, commentItemModel, WDPublicUserType } from '../model/CommentModel';
5 import commentViewModel from '../viewmodel/CommentViewModel'; 5 import commentViewModel from '../viewmodel/CommentViewModel';
6 import { CommentText } from './CommentText'; 6 import { CommentText } from './CommentText';
7 import { CommentCustomDialog } from './CommentCustomDialog'; 7 import { CommentCustomDialog } from './CommentCustomDialog';
@@ -37,6 +37,7 @@ export struct CommentComponent { @@ -37,6 +37,7 @@ export struct CommentComponent {
37 listScroller: ListScroller = new ListScroller(); // scroller控制器 37 listScroller: ListScroller = new ListScroller(); // scroller控制器
38 historyOffset: number = 0; // 上次浏览到列表距离顶端的偏移量offset 38 historyOffset: number = 0; // 上次浏览到列表距离顶端的偏移量offset
39 @State allDatas: LazyDataSource<commentItemModel> = new LazyDataSource(); 39 @State allDatas: LazyDataSource<commentItemModel> = new LazyDataSource();
  40 + firstPageHotIds: string = ''
40 @State dialogController: CustomDialogController | null = null; 41 @State dialogController: CustomDialogController | null = null;
41 // @State private browSingModel: commentListModel = new commentListModel() 42 // @State private browSingModel: commentListModel = new commentListModel()
42 43
@@ -49,6 +50,7 @@ export struct CommentComponent { @@ -49,6 +50,7 @@ export struct CommentComponent {
49 // 是否在弹框中 50 // 是否在弹框中
50 @Provide inDialog: boolean = false 51 @Provide inDialog: boolean = false
51 private dialogBeforeJumpOtherPageAction: () => void = () => {} 52 private dialogBeforeJumpOtherPageAction: () => void = () => {}
  53 + private dialogUpdateTitle: (title: string) => void = () => {}
52 54
53 // 在自定义组件即将析构销毁时将dialogControlle置空 55 // 在自定义组件即将析构销毁时将dialogControlle置空
54 aboutToDisappear() { 56 aboutToDisappear() {
@@ -99,7 +101,16 @@ export struct CommentComponent { @@ -99,7 +101,16 @@ export struct CommentComponent {
99 /*一级评论*/ 101 /*一级评论*/
100 // if (this.publishCommentModel.lastCommentModel) 102 // if (this.publishCommentModel.lastCommentModel)
101 if (this.publishCommentModel.lastCommentModel.parentId == '-1') { 103 if (this.publishCommentModel.lastCommentModel.parentId == '-1') {
102 - this.allDatas.addFirstItem(model) 104 +
  105 + let newCommentHeaderIndex = this.indexOfNewCommentHeaderTitle()
  106 + if (newCommentHeaderIndex === -1) {
  107 + let newCommentTitle = new commentItemModel()
  108 + newCommentTitle.api_customType = CommentItemCustomType.newTitle
  109 + this.allDatas.addItems([newCommentTitle, model])
  110 + } else {
  111 + this.allDatas.addItem(model, newCommentHeaderIndex + 1)
  112 + }
  113 +
103 } else { 114 } else {
104 //二级评论 115 //二级评论
105 this.allDatas.getDataArray().forEach(element => { 116 this.allDatas.getDataArray().forEach(element => {
@@ -116,41 +127,41 @@ export struct CommentComponent { @@ -116,41 +127,41 @@ export struct CommentComponent {
116 127
117 /*标题:全部评论*/ 128 /*标题:全部评论*/
118 @Builder 129 @Builder
119 - titleHeader() { 130 + titleHeader(title: string = "最新评论", showGapLine: boolean = false) {
120 131
121 - Row() {  
122 - Row() {  
123 - Image($r('app.media.redLine'))  
124 - .height(16)  
125 - .width(3)  
126 - Text('全部评论')  
127 - .fontSize(16)// .fontColor('#222222')  
128 - .fontColor($r('app.color.color_222222'))  
129 - .fontWeight(FontWeight.Medium)  
130 - .margin({ left: 5 }) 132 + Column() {
  133 + if (showGapLine) {
  134 + Divider().strokeWidth(6).color('#f5f5f5')
131 } 135 }
132 - .margin({ left: 16 })  
133 136
  137 + Row() {
  138 + Row() {
  139 + Image($r('app.media.redLine'))
  140 + .height(16)
  141 + .width(3)
  142 + Text(title)
  143 + .fontSize(16)// .fontColor('#222222')
  144 + .fontColor($r('app.color.color_222222'))
  145 + .fontWeight(FontWeight.Medium)
  146 + .margin({ left: 5 })
  147 + }
  148 + .margin({ left: 16 })
134 149
135 - Image($r('app.media.comment_close'))  
136 - .height(18)  
137 - .width(18)  
138 - .margin({ right: 16 })  
139 - .visibility(this.showCloseIcon ? Visibility.Visible : Visibility.Hidden)  
140 - .onClick(() => {  
141 - this.onCloseClick()  
142 - })  
143 150
144 - }  
145 - .height(44)  
146 - .width('100%')  
147 - .justifyContent(FlexAlign.SpaceBetween)  
148 - .onClick(() => {  
149 - // this.allDatas.push(new commentItemModel())  
150 - // this.allDatas.addFirstItem(new commentItemModel())  
151 - // this.allDatas.reloadData();  
152 - }) 151 + Image($r('app.media.comment_close'))
  152 + .height(18)
  153 + .width(18)
  154 + .margin({ right: 16 })
  155 + .visibility(this.showCloseIcon ? Visibility.Visible : Visibility.Hidden)
  156 + .onClick(() => {
  157 + this.onCloseClick()
  158 + })
153 159
  160 + }
  161 + .height(44)
  162 + .width('100%')
  163 + .justifyContent(FlexAlign.SpaceBetween)
  164 + }
154 } 165 }
155 166
156 /*1级评论作为titleHeader*/ 167 /*1级评论作为titleHeader*/
@@ -177,16 +188,29 @@ export struct CommentComponent { @@ -177,16 +188,29 @@ export struct CommentComponent {
177 build() { 188 build() {
178 Column() { 189 Column() {
179 List({ scroller: this.listScroller }) { 190 List({ scroller: this.listScroller }) {
180 - if (this.showTitleComponent) {  
181 - ListItemGroup({ header: this.titleHeader() })  
182 - }  
183 -  
184 if (!this.isComments) { 191 if (!this.isComments) {
  192 + if (this.showTitleComponent) {
  193 + ListItemGroup({ header: this.titleHeader() })
  194 + }
185 EmptyComponent({ emptyType: 17 }) 195 EmptyComponent({ emptyType: 17 })
186 .height(300) 196 .height(300)
187 } else { 197 } else {
188 LazyForEach(this.allDatas, (item: commentItemModel, index: number) => { 198 LazyForEach(this.allDatas, (item: commentItemModel, index: number) => {
189 - if (item.hasMore) { 199 + if (item.api_customType === CommentItemCustomType.newTitle) {
  200 + if (this.inDialog && index === 0) {
  201 + ListItemGroup()
  202 + } else {
  203 + ListItemGroup({ header: this.titleHeader("最新评论", index !== 0) })
  204 + }
  205 + }
  206 + else if (item.api_customType === CommentItemCustomType.hotTitle) {
  207 + if (this.inDialog && index === 0) {
  208 + ListItemGroup()
  209 + } else {
  210 + ListItemGroup({ header: this.titleHeader("热门评论") })
  211 + }
  212 + }
  213 + else if (item.hasMore) {
190 ListItemGroup({ 214 ListItemGroup({
191 header: this.CommentHeaderItem(item, index), 215 header: this.CommentHeaderItem(item, index),
192 footer: this.GroupFooterView(item, index) 216 footer: this.GroupFooterView(item, index)
@@ -234,6 +258,9 @@ export struct CommentComponent { @@ -234,6 +258,9 @@ export struct CommentComponent {
234 } 258 }
235 .scrollBar(BarState.Off) 259 .scrollBar(BarState.Off)
236 .margin({ bottom: 10 }) 260 .margin({ bottom: 10 })
  261 + .onScrollIndex((start) => {
  262 + this.updateDialogTitleWithStartIndex(start)
  263 + })
237 .onReachEnd(() => { 264 .onReachEnd(() => {
238 if (!this.fixedHeightMode) { 265 if (!this.fixedHeightMode) {
239 return 266 return
@@ -252,6 +279,30 @@ export struct CommentComponent { @@ -252,6 +279,30 @@ export struct CommentComponent {
252 279
253 } 280 }
254 281
  282 + updateDialogTitleWithStartIndex(start: number) {
  283 + if (!this.inDialog) {
  284 + return
  285 + }
  286 + if (this.allDatas.size() === 0) {
  287 + this.dialogUpdateTitle("评论")
  288 + return
  289 + }
  290 + if (this.allDatas.getFirst().api_customType !== CommentItemCustomType.hotTitle) {
  291 + this.dialogUpdateTitle("最新评论")
  292 + return
  293 + }
  294 + let newCommentHeaderIndex = this.indexOfNewCommentHeaderTitle()
  295 + if (newCommentHeaderIndex == -1) {
  296 + this.dialogUpdateTitle("热门评论")
  297 + return
  298 + }
  299 + if (start < newCommentHeaderIndex + 1) {
  300 + this.dialogUpdateTitle("热门评论")
  301 + } else {
  302 + this.dialogUpdateTitle("最新评论")
  303 + }
  304 + }
  305 +
255 parentOnReachEnd() { 306 parentOnReachEnd() {
256 if (this.fixedHeightMode) { 307 if (this.fixedHeightMode) {
257 return 308 return
@@ -268,11 +319,41 @@ export struct CommentComponent { @@ -268,11 +319,41 @@ export struct CommentComponent {
268 //获取数据 319 //获取数据
269 async getData() { 320 async getData() {
270 let pageIndex = this.currentPage 321 let pageIndex = this.currentPage
271 - commentViewModel.fetchContentCommentList(pageIndex + '', this.publishCommentModel.targetId,  
272 - this.publishCommentModel.targetType) 322 + commentViewModel.fetchContentCommentList(pageIndex + ''
  323 + ,this.publishCommentModel.targetId
  324 + ,this.publishCommentModel.targetType
  325 + ,this.firstPageHotIds)
273 .then(commentListModel => { 326 .then(commentListModel => {
274 console.log('评论:', JSON.stringify(commentListModel.list)) 327 console.log('评论:', JSON.stringify(commentListModel.list))
275 328
  329 + if (pageIndex == 1) {
  330 + // 保存第一页热门评论ids
  331 + if (commentListModel.hotIds.length > 0) {
  332 + this.firstPageHotIds = commentListModel.hotIds.join(",")
  333 + }
  334 + if (commentListModel.list.length > 0) { // 热门评论增加头部
  335 + let newCommentTitle = new commentItemModel()
  336 + newCommentTitle.api_customType = CommentItemCustomType.newTitle
  337 + let newArray = [newCommentTitle]
  338 + commentListModel.list = newArray.concat(commentListModel.list)
  339 + }
  340 + if (commentListModel.hotList.length > 0) { // 最新评论增加头部
  341 + let hotCommentTitle = new commentItemModel()
  342 + hotCommentTitle.api_customType = CommentItemCustomType.hotTitle
  343 + let newArray = [hotCommentTitle]
  344 + commentListModel.hotList = newArray.concat(commentListModel.hotList)
  345 +
  346 + commentListModel.list = commentListModel.hotList.concat(commentListModel.list)
  347 + }
  348 + } else { // 非首页数据
  349 + if (commentListModel.list.length > 0 && !this.hasNewCommentHeaderTitle()) { // 如果之前仅存在热门评论,这里需要补下数据
  350 + let newCommentTitle = new commentItemModel()
  351 + newCommentTitle.api_customType = CommentItemCustomType.newTitle
  352 + let newArray = [newCommentTitle]
  353 + commentListModel.list = newArray.concat(commentListModel.list)
  354 + }
  355 + }
  356 +
276 // 这里需要先赋值,否则下次UI刷新可能重复进入第1页两次 357 // 这里需要先赋值,否则下次UI刷新可能重复进入第1页两次
277 this.currentPage = pageIndex + 1 358 this.currentPage = pageIndex + 1
278 359
@@ -313,6 +394,29 @@ export struct CommentComponent { @@ -313,6 +394,29 @@ export struct CommentComponent {
313 } 394 }
314 }) 395 })
315 } 396 }
  397 +
  398 + hasNewCommentHeaderTitle() {
  399 + let hasNewCommentHeader = false
  400 + this.allDatas.getDataArray().forEach((comment) => {
  401 + if (comment.api_customType === CommentItemCustomType.newTitle) {
  402 + hasNewCommentHeader = true
  403 + }
  404 + })
  405 + return hasNewCommentHeader
  406 + }
  407 +
  408 + indexOfNewCommentHeaderTitle() {
  409 + let resultIndex = -1;
  410 + const array = this.allDatas.getDataArray()
  411 + for (let index = 0; index < array.length; index++) {
  412 + if (array[index].api_customType === CommentItemCustomType.newTitle) {
  413 + resultIndex = index;
  414 + break
  415 + }
  416 + }
  417 + return resultIndex
  418 + }
  419 +
316 } 420 }
317 421
318 422
@@ -74,6 +74,7 @@ struct CommentListDialog { @@ -74,6 +74,7 @@ struct CommentListDialog {
74 /// 内部使用 74 /// 内部使用
75 @Link publishCommentModel: publishCommentModel 75 @Link publishCommentModel: publishCommentModel
76 @State private operationButtonList: string[] = [] 76 @State private operationButtonList: string[] = []
  77 + @State title: string = "评论"
77 78
78 /// 外部初始化 79 /// 外部初始化
79 @Link contentDetailData: ContentDetailDTO // 详情页传 80 @Link contentDetailData: ContentDetailDTO // 详情页传
@@ -122,6 +123,9 @@ struct CommentListDialog { @@ -122,6 +123,9 @@ struct CommentListDialog {
122 if (this.onClose) { 123 if (this.onClose) {
123 this.onClose() 124 this.onClose()
124 } 125 }
  126 + },
  127 + dialogUpdateTitle: (title) => {
  128 + this.title = title
125 } 129 }
126 }).layoutWeight(1) 130 }).layoutWeight(1)
127 131
@@ -153,7 +157,7 @@ struct CommentListDialog { @@ -153,7 +157,7 @@ struct CommentListDialog {
153 Image($r('app.media.redLine')) 157 Image($r('app.media.redLine'))
154 .height(16) 158 .height(16)
155 .width(3) 159 .width(3)
156 - Text('全部评论') 160 + Text(this.title)
157 .fontSize(16)// .fontColor('#222222') 161 .fontSize(16)// .fontColor('#222222')
158 .fontColor($r('app.color.color_222222')) 162 .fontColor($r('app.color.color_222222'))
159 .fontWeight(FontWeight.Medium) 163 .fontWeight(FontWeight.Medium)
@@ -8,6 +8,7 @@ import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest'; @@ -8,6 +8,7 @@ import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest';
8 import { ProcessUtils, WDRouterPage, WDRouterRule } from 'wdRouter/Index'; 8 import { ProcessUtils, WDRouterPage, WDRouterRule } from 'wdRouter/Index';
9 import { TrackConstants, TrackingContent } from 'wdTracking/Index'; 9 import { TrackConstants, TrackingContent } from 'wdTracking/Index';
10 import { 10 import {
  11 + CommentItemCustomType,
11 commentItemModel, 12 commentItemModel,
12 commentListModel, 13 commentListModel,
13 commentStatusListModel, 14 commentStatusListModel,
@@ -33,9 +34,13 @@ class CommentViewModel { @@ -33,9 +34,13 @@ class CommentViewModel {
33 } 34 }
34 35
35 /*获取所有评论*/ 36 /*获取所有评论*/
36 - fetchContentCommentList(pageNum: string, contentId: string, contentType: string): Promise<commentListModel> { 37 + fetchContentCommentList(pageNum: string, contentId: string, contentType: string, firstPageHotIds: string = ''): Promise<commentListModel> {
37 38
38 let url = HttpUrlUtils.getContentCommentListDataUrl() + `?&pageSize=${10}&pageNum=${pageNum}&contentId=${contentId}&contentType=${contentType}&deviceId=${HttpUtils.getDeviceId()}&userId=${HttpUtils.getUserId()}&userType=${HttpUtils.getUserType()}&time=${DateTimeUtils.getCurTime(DateTimeUtils.PATTERN_DATE_TIME_HYPHEN)}` 39 let url = HttpUrlUtils.getContentCommentListDataUrl() + `?&pageSize=${10}&pageNum=${pageNum}&contentId=${contentId}&contentType=${contentType}&deviceId=${HttpUtils.getDeviceId()}&userId=${HttpUtils.getUserId()}&userType=${HttpUtils.getUserType()}&time=${DateTimeUtils.getCurTime(DateTimeUtils.PATTERN_DATE_TIME_HYPHEN)}`
  40 + url = url + "&hotComment=1"
  41 + if (pageNum !== "1" && firstPageHotIds.length > 0) {
  42 + url = url + `&hotIds=` + firstPageHotIds
  43 + }
39 url = url.replace(' ', '%20') 44 url = url.replace(' ', '%20')
40 45
41 return new Promise<commentListModel>((success, fail) => { 46 return new Promise<commentListModel>((success, fail) => {
@@ -49,9 +54,23 @@ class CommentViewModel { @@ -49,9 +54,23 @@ class CommentViewModel {
49 return 54 return
50 } 55 }
51 let listData = data.data as commentListModel 56 let listData = data.data as commentListModel
52 - this.fetchCommentStatusAndConfigAuthIcon(listData).then((commentListModel) => { 57 + this.fetchCommentStatusAndConfigAuthIcon(listData, false).then((commentListModel) => {
53 console.log(TAG, 'fetchCommentStatusAndConfigAuthIcon完成') 58 console.log(TAG, 'fetchCommentStatusAndConfigAuthIcon完成')
54 - success(commentListModel) 59 +
  60 + if (pageNum !== "1") {
  61 + success(commentListModel)
  62 + return
  63 + }
  64 +
  65 + // 热门评论批查
  66 + this.fetchCommentStatusAndConfigAuthIcon(listData, true).then((commentListModel) => {
  67 + console.log(TAG, 'hot comment fetchCommentStatusAndConfigAuthIcon完成')
  68 +
  69 + listData.hotList.forEach((item) => {
  70 + item.api_customType = CommentItemCustomType.hotComment
  71 + })
  72 + success(commentListModel)
  73 + })
55 }) 74 })
56 75
57 }, (error: Error) => { 76 }, (error: Error) => {
@@ -213,7 +232,7 @@ class CommentViewModel { @@ -213,7 +232,7 @@ class CommentViewModel {
213 } 232 }
214 233
215 /*多接口批查*/ 234 /*多接口批查*/
216 - fetchCommentStatusAndConfigAuthIcon(model: commentListModel): Promise<commentListModel> { 235 + fetchCommentStatusAndConfigAuthIcon(model: commentListModel, hot: boolean = false): Promise<commentListModel> {
217 236
218 let commentIDs: string[] = []; 237 let commentIDs: string[] = [];
219 238
@@ -222,7 +241,7 @@ class CommentViewModel { @@ -222,7 +241,7 @@ class CommentViewModel {
222 let creatorIDs: string[] = []; 241 let creatorIDs: string[] = [];
223 242
224 //主评论 243 //主评论
225 - for (const element of model.list) { 244 + for (const element of (hot ? model.hotList : model.list)) {
226 if ((element.id + '').length > 0) { 245 if ((element.id + '').length > 0) {
227 commentIDs.push(element.id + '') 246 commentIDs.push(element.id + '')
228 } 247 }
@@ -277,7 +296,7 @@ class CommentViewModel { @@ -277,7 +296,7 @@ class CommentViewModel {
277 let listData = data.data as commentStatusModel[] 296 let listData = data.data as commentStatusModel[]
278 //点赞 297 //点赞
279 for (const element of listData) { 298 for (const element of listData) {
280 - for (const commentModel of model.list) { 299 + for (const commentModel of (hot ? model.hotList : model.list)) {
281 if (element.commentId == commentModel.id) { 300 if (element.commentId == commentModel.id) {
282 commentModel.api_status = element.status 301 commentModel.api_status = element.status
283 } 302 }
@@ -319,7 +338,7 @@ class CommentViewModel { @@ -319,7 +338,7 @@ class CommentViewModel {
319 let listData = data.data as commentStatusModel[] 338 let listData = data.data as commentStatusModel[]
320 339
321 for (const element of listData) { 340 for (const element of listData) {
322 - for (const commentModel of model.list) { 341 + for (const commentModel of (hot ? model.hotList : model.list)) {
323 if (element.userId == commentModel.fromUserId) { 342 if (element.userId == commentModel.fromUserId) {
324 commentModel.api_levelHead = element.levelHead 343 commentModel.api_levelHead = element.levelHead
325 } 344 }
@@ -364,7 +383,7 @@ class CommentViewModel { @@ -364,7 +383,7 @@ class CommentViewModel {
364 let listData = data.data as commentStatusModel[] 383 let listData = data.data as commentStatusModel[]
365 384
366 for (const element of listData) { 385 for (const element of listData) {
367 - for (const commentModel of model.list) { 386 + for (const commentModel of (hot ? model.hotList : model.list)) {
368 if (element.creatorId == commentModel.fromCreatorId) { 387 if (element.creatorId == commentModel.fromCreatorId) {
369 commentModel.api_authIcon = element.authIcon 388 commentModel.api_authIcon = element.authIcon
370 } 389 }
@@ -400,6 +419,7 @@ class CommentViewModel { @@ -400,6 +419,7 @@ class CommentViewModel {
400 deepCopyCommentItemModel(model: commentItemModel) { 419 deepCopyCommentItemModel(model: commentItemModel) {
401 let newModel = new commentItemModel() 420 let newModel = new commentItemModel()
402 421
  422 + newModel.api_customType = model.api_customType
403 newModel.authorLike = model.authorLike 423 newModel.authorLike = model.authorLike
404 newModel.avatarFrame = model.avatarFrame 424 newModel.avatarFrame = model.avatarFrame
405 newModel.checkStatus = model.checkStatus 425 newModel.checkStatus = model.checkStatus