wangliang_wd

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

* 'main' of http://192.168.1.42/developOne/harmonyPool:
  desc:完善 搜索历史
  feat:1)添加直播详情页基本组件(直播间和大家聊页面)
  拖拽复位
  feat:1)添加直播详情页基本组件(直播间和大家聊页面)
  拖拽复位
  desc:同步 搜索主页(4.0)
  desc:3.0 搜索主页(竖滚动,热门搜索,搜索历史)
  feat:1)添加直播详情页基本组件(直播预约信息tab页面)
  新增变量
  图片新增
  人民号入住卡样式新增
  人民号主题卡样式新增
  首页请求互动数据,优化为异步加载
  首页请求互动数据,优化为异步加载
  样式卡及组件配置更新
  多图(图集)详情页 底部titles代码手机端适配
Showing 94 changed files with 2850 additions and 366 deletions
  1 +import { SearchComponent } from 'wdComponent'
  2 +
  3 +@Entry
  4 +@Component
  5 +struct SearchPage {
  6 +
  7 + build() {
  8 + Column(){
  9 + SearchComponent()
  10 + }.height('100%')
  11 + .width('100%')
  12 + }
  13 +}
@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 "pages/LaunchPage", 14 "pages/LaunchPage",
15 "pages/LaunchAdvertisingPage", 15 "pages/LaunchAdvertisingPage",
16 "pages/PrivacyPage", 16 "pages/PrivacyPage",
17 - "pages/OtherNormalUserHomePage" 17 + "pages/OtherNormalUserHomePage",
  18 + "pages/SearchPage"
18 ] 19 ]
19 -} 20 +}
  1 +{
  2 + "code": "0",
  3 + "data": [
  4 + {
  5 + "hotEntry": "习语",
  6 + "mark": 1,
  7 + "sequence": 1
  8 + },
  9 + {
  10 + "hotEntry": "党史学习教育工作",
  11 + "mark": 1,
  12 + "sequence": 2
  13 + },
  14 + {
  15 + "hotEntry": "2024年全国两会新闻中心启用",
  16 + "mark": 1,
  17 + "sequence": 3
  18 + },
  19 + {
  20 + "hotEntry": "第二艘国产大型邮轮后年底交付",
  21 + "mark": 0,
  22 + "sequence": 4
  23 + },
  24 + {
  25 + "hotEntry": "268名跨境电诈犯罪嫌疑人移交",
  26 + "mark": 0,
  27 + "sequence": 5
  28 + },
  29 + {
  30 + "hotEntry": "高考倒计时100天",
  31 + "mark": 2,
  32 + "sequence": 6
  33 + },
  34 + {
  35 + "hotEntry": "日本开始第四轮核污染水排放",
  36 + "mark": 0,
  37 + "sequence": 7
  38 + },
  39 + {
  40 + "hotEntry": "国台办点名管碧玲",
  41 + "mark": 0,
  42 + "sequence": 8
  43 + },
  44 + {
  45 + "hotEntry": "美方称不会向乌克兰派兵",
  46 + "mark": 2,
  47 + "sequence": 9
  48 + },
  49 + {
  50 + "hotEntry": "电动车乱停乱充电",
  51 + "mark": 2,
  52 + "sequence": 10
  53 + }
  54 + ],
  55 + "message": "Success",
  56 + "success": true,
  57 + "timestamp": 1712631086296
  58 +}
@@ -44,4 +44,6 @@ export { FollowFirstTabsComponent } from "./components/page/mine/follow/FollowFi @@ -44,4 +44,6 @@ export { FollowFirstTabsComponent } from "./components/page/mine/follow/FollowFi
44 44
45 export { MyHomeComponent } from "./components/page/mine/home/MyHomeComponent" 45 export { MyHomeComponent } from "./components/page/mine/home/MyHomeComponent"
46 46
47 -export { OtherUserHomeComponent } from "./components/page/mine/home/OtherUserHomeComponent"  
  47 +export { OtherUserHomeComponent } from "./components/page/mine/home/OtherUserHomeComponent"
  48 +
  49 +export { SearchComponent } from "./components/page/search/SearchComponent"
1 import SearcherAboutDataModel from '../../model/SearcherAboutDataModel' 1 import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
  2 +import RouteManager from '../../utils/RouteManager'
2 /** 3 /**
3 * 首页顶部搜索导航栏 4 * 首页顶部搜索导航栏
4 * 竖向滚动实现方案 5 * 竖向滚动实现方案
@@ -61,6 +62,9 @@ export struct FirstTabTopComponent{ @@ -61,6 +62,9 @@ export struct FirstTabTopComponent{
61 .backgroundImage($r('app.media.top_search_bg')) 62 .backgroundImage($r('app.media.top_search_bg'))
62 .backgroundImageSize(ImageSize.Cover) 63 .backgroundImageSize(ImageSize.Cover)
63 .alignItems(VerticalAlign.Center) 64 .alignItems(VerticalAlign.Center)
  65 + .onClick(()=>{
  66 + RouteManager.jumpNewPage("pages/SearchPage")
  67 + })
64 68
65 Image($r('app.media.top_title_bg')) 69 Image($r('app.media.top_title_bg'))
66 .objectFit(ImageFit.Auto) 70 .objectFit(ImageFit.Auto)
1 import { CommonConstants, ViewType } from 'wdConstant'; 1 import { CommonConstants, ViewType } from 'wdConstant';
2 -import { CollectionUtils, Logger } from 'wdKit'; 2 +import { CollectionUtils, DateTimeUtils, Logger } from 'wdKit';
3 import { CompDTO } from '../../repository/bean/CompDTO'; 3 import { CompDTO } from '../../repository/bean/CompDTO';
4 import PageViewModel from '../../viewmodel/PageViewModel'; 4 import PageViewModel from '../../viewmodel/PageViewModel';
5 import { EmptyComponent } from '../view/EmptyComponent'; 5 import { EmptyComponent } from '../view/EmptyComponent';
@@ -65,7 +65,9 @@ export struct PageComponent { @@ -65,7 +65,9 @@ export struct PageComponent {
65 CompParser({ compDTO: compDTO, compIndex: compIndex }); 65 CompParser({ compDTO: compDTO, compIndex: compIndex });
66 } 66 }
67 } 67 }
68 - }) 68 + },
  69 + (compDTO: CompDTO, compIndex: number) => compDTO.id + compIndex.toString() + this.pageModel.timestamp
  70 + )
69 71
70 // 加载更多 72 // 加载更多
71 ListItem() { 73 ListItem() {
@@ -136,6 +138,11 @@ export struct PageComponent { @@ -136,6 +138,11 @@ export struct PageComponent {
136 } else { 138 } else {
137 this.pageModel.hasMore = false; 139 this.pageModel.hasMore = false;
138 } 140 }
  141 + PageViewModel.getInteractData(pageDto.compList).then((data: CompDTO[]) => {
  142 + // 刷新,替换所有数据
  143 + this.pageModel.compList.replaceAll(...data)
  144 + this.pageModel.timestamp = DateTimeUtils.getCurrentTimeMillis().toString()
  145 + })
139 } else { 146 } else {
140 Logger.debug(TAG, 'aboutToAppear, data response page ' + this.pageId + ', comp list is empty.'); 147 Logger.debug(TAG, 'aboutToAppear, data response page ' + this.pageId + ', comp list is empty.');
141 this.pageModel.viewType = ViewType.EMPTY; 148 this.pageModel.viewType = ViewType.EMPTY;
  1 +import router from '@ohos.router'
  2 +import { StringUtils } from 'wdKit/src/main/ets/utils/StringUtils'
  3 +import SearcherAboutDataModel from '../../../model/SearcherAboutDataModel'
  4 +import { SearchHistoryItem } from '../../../viewmodel/SearchHistoryItem'
  5 +import { SearchHistoryComponent } from './SearchHistoryComponent'
  6 +import { SearchHotsComponent } from './SearchHotsComponent'
  7 +
  8 +const TAG = "SearchComponent"
  9 +
  10 +@Component
  11 +export struct SearchComponent {
  12 + @State searchTextData: string[] = []
  13 + @State hasInputContent: boolean = false
  14 + @State hasChooseSearch: boolean = false
  15 + private swiperController: SwiperController = new SwiperController()
  16 + @State searchText: string = ''
  17 + controller: TextInputController = new TextInputController()
  18 + @State searchHistoryData: SearchHistoryItem[] = []
  19 + scroller: Scroller = new Scroller()
  20 +
  21 + aboutToAppear() {
  22 + //获取提示滚动
  23 + this.getSearchHint()
  24 + //获取搜索历史
  25 + this.getSearchHistoryData()
  26 + }
  27 +
  28 + getSearchHint() {
  29 + SearcherAboutDataModel.getSearchHintData(getContext(this)).then((value) => {
  30 + if (value != null) {
  31 + this.searchTextData = value
  32 + }
  33 + }).catch((err: Error) => {
  34 + console.log(TAG, JSON.stringify(err))
  35 + })
  36 + }
  37 +
  38 + getSearchHistoryData() {
  39 + this.searchHistoryData = SearcherAboutDataModel.getSearchHistoryData()
  40 + }
  41 +
  42 + build() {
  43 + Column() {
  44 + this.searchInputComponent()
  45 + if (!this.hasInputContent) {
  46 + Scroll(this.scroller) {
  47 + Column() {
  48 + SearchHistoryComponent({ searchHistoryData: $searchHistoryData })
  49 +
  50 + //分隔符
  51 + Divider()
  52 + .width('100%')
  53 + .height('1lpx')
  54 + .color($r('app.color.color_EDEDED'))
  55 + .strokeWidth('1lpx')
  56 +
  57 + SearchHotsComponent()
  58 + }
  59 + }
  60 + .scrollable(ScrollDirection.Vertical)
  61 + .scrollBar(BarState.Off)
  62 + .width('100%')
  63 + .height('100%')
  64 + .padding({ left: '31lpx', right: '31lpx' })
  65 + } else {
  66 + if (this.hasChooseSearch) {
  67 + //搜索结果
  68 +
  69 + //搜索结果为null(空布局 + 为你推荐)
  70 + } else {
  71 + //联想搜索
  72 + }
  73 + }
  74 + }.height('100%')
  75 + .width('100%')
  76 + }
  77 +
  78 + //搜索框
  79 + @Builder searchInputComponent() {
  80 + Row() {
  81 + //左
  82 + Stack({ alignContent: Alignment.Start }) {
  83 + if (this.searchTextData != null && this.searchTextData.length > 0 && !this.hasInputContent) {
  84 + Swiper(this.swiperController) {
  85 + ForEach(this.searchTextData, (item: string, index: number) => {
  86 + Text(item)
  87 + .fontWeight('400lpx')
  88 + .fontSize('25lpx')
  89 + .fontColor($r('app.color.color_666666'))
  90 + .lineHeight('35lpx')
  91 + .textAlign(TextAlign.Start)
  92 + .maxLines(1)
  93 + .textOverflow({ overflow: TextOverflow.Clip })
  94 + .margin({ left: '40lpx' })
  95 + })
  96 + }
  97 + .loop(true)
  98 + .autoPlay(true)
  99 + .interval(3000)
  100 + .indicator(false)
  101 + .vertical(true)
  102 + .enabled(false)
  103 + .focusable(false)
  104 + }
  105 + TextInput({ text: this.searchText, placeholder: '', controller: this.controller })
  106 + .caretColor(Color.Pink)
  107 + .fontSize('27lpx')
  108 + .fontColor(Color.Black)
  109 + .onChange((value: string) => {
  110 + this.searchText = value
  111 + if (this.searchText.length > 0) {
  112 + this.hasInputContent = false
  113 + } else {
  114 + this.hasInputContent = true
  115 + }
  116 + })
  117 + .backgroundColor($r('app.color.color_transparent'))
  118 + }
  119 + .backgroundImage($r('app.media.search_page_input_bg'))
  120 + .backgroundImageSize(ImageSize.Cover)
  121 + .layoutWeight(1)
  122 + .height('69lpx')
  123 +
  124 + //右
  125 + Text("取消")
  126 + .textAlign(TextAlign.Center)
  127 + .fontWeight('400lpx')
  128 + .fontSize('31lpx')
  129 + .lineHeight('58lpx')
  130 + .fontColor($r('app.color.color_222222'))
  131 + .width('125lpx')
  132 + .height('58lpx')
  133 + .onClick(() => {
  134 + router.back()
  135 + // SearcherAboutDataModel.putSearchHistoryData(this.searchText)
  136 + // if(StringUtils.isNotEmpty(this.searchText)){
  137 + // if(this.searchHistoryData.length===10){
  138 + // this.searchHistoryData.pop()
  139 + // }
  140 + // this.searchHistoryData.push(new SearchHistoryItem(this.searchText))
  141 + // }
  142 + })
  143 + }
  144 + .height('85lpx')
  145 + .padding({ left: '31lpx' })
  146 + .alignItems(VerticalAlign.Center)
  147 + .margin({ bottom: '36lpx' })
  148 + }
  149 +}
  1 +import { SearchHistoryItem } from '../../../viewmodel/SearchHistoryItem'
  2 +
  3 +
  4 +/**
  5 + * 搜索历史
  6 + */
  7 +@Component
  8 +export struct SearchHistoryComponent{
  9 + @Link searchHistoryData:SearchHistoryItem[]
  10 +
  11 + build(){
  12 + Column(){
  13 + Row(){
  14 + Text("搜索历史")
  15 + .textAlign(TextAlign.Center)
  16 + .fontWeight('400lpx')
  17 + .fontSize('27lpx')
  18 + .lineHeight('38lpx')
  19 + .fontColor($r('app.color.color_999999'))
  20 + .height('38lpx')
  21 +
  22 + Image($r('app.media.search_delete_icon'))
  23 + .height('31lpx')
  24 + .width('31lpx')
  25 + .objectFit(ImageFit.Auto)
  26 + .onClick(()=>{
  27 + //清空记录
  28 + })
  29 + }.justifyContent(FlexAlign.SpaceBetween)
  30 + .margin({bottom:'17lpx'})
  31 + .width('100%')
  32 +
  33 + Grid(){
  34 + ForEach(this.searchHistoryData,(item:SearchHistoryItem,index:number)=>{
  35 + GridItem(){
  36 + Row(){
  37 + Text(`${item.searchContent}`)
  38 + .height('23lpx')
  39 + .fontColor($r('app.color.color_222222'))
  40 + .fontSize('23lpx')
  41 + .maxLines(1)
  42 + .constraintSize({maxWidth:index%2 === 0?'270lpx':'250lpx'})
  43 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  44 + .textAlign(TextAlign.Start)
  45 +
  46 + Image($r('app.media.search_item_delete_icon'))
  47 + .width('46lpx')
  48 + .height('46lpx')
  49 + .margin({right:'31lpx',left:'4lpx'})
  50 + .interpolation(ImageInterpolation.Medium)
  51 + .objectFit(ImageFit.Auto)
  52 +
  53 + Blank()
  54 +
  55 + if(index%2 === 0 && index != this.searchHistoryData.length-1 ){
  56 + Divider()
  57 + .width('2lpx')
  58 + .height('23lpx')
  59 + .color($r('app.color.color_CCCCCC'))
  60 + .strokeWidth('2lpx')
  61 + .vertical(true)
  62 + }
  63 + }.height('100%')
  64 + .alignItems(VerticalAlign.Center)
  65 + .width('100%')
  66 + .margin({left:index%2 === 1?'23lpx':'0lpx'})
  67 + }.onClick(()=>{
  68 + })
  69 + .height('46lpx')
  70 + })
  71 + }
  72 + .height(this.getCategoryViewHeight())
  73 + .rowsTemplate(this.getCategoryRowTmpl())
  74 + .columnsTemplate('1fr 1fr')
  75 + .rowsGap('23lpx')
  76 + }
  77 + .margin({bottom:'46lpx'})
  78 + }
  79 +
  80 + getCategoryRowCount() {
  81 + return Math.ceil(this.searchHistoryData.length / 2);
  82 + }
  83 +
  84 + getCategoryRowTmpl() {
  85 + const count = this.getCategoryRowCount();
  86 + const arr: string[] = new Array(count || 1).fill('1fr');
  87 + console.log('tmpl ', arr.join(' '))
  88 + return arr.join(' ');
  89 + }
  90 +
  91 + getCategoryViewHeight() {
  92 + return `${46 * this.getCategoryRowCount()}lpx`;
  93 + }
  94 +}
  1 +import SearcherAboutDataModel from '../../../model/SearcherAboutDataModel'
  2 +import { SearchHotContentItem } from '../../../viewmodel/SearchHotContentItem'
  3 +
  4 +const TAG = "SearchHotsComponent"
  5 +
  6 +/**
  7 + * 热门搜索
  8 + */
  9 +@Component
  10 +export struct SearchHotsComponent{
  11 + @State searchHotsData:SearchHotContentItem[] = []
  12 +
  13 + aboutToAppear(){
  14 + //获取搜索热词
  15 + this.getSearchHotsData()
  16 + }
  17 +
  18 + getSearchHotsData(){
  19 + SearcherAboutDataModel.getSearchHotsData(getContext(this)).then((value)=>{
  20 + if(value!=null){
  21 + this.searchHotsData = value
  22 + }
  23 + }).catch((err:Error)=>{
  24 + console.log(TAG,JSON.stringify(err))
  25 + })
  26 + }
  27 +
  28 + build(){
  29 + Column(){
  30 + Row() {
  31 + Image($r('app.media.search_hot_icon'))
  32 + .width('46lpx')
  33 + .height('46lpx')
  34 + .objectFit(ImageFit.Auto)
  35 + .margin({right:'8lpx'})
  36 + .interpolation(ImageInterpolation.Medium)
  37 +
  38 + Text("热门搜索")
  39 + .textAlign(TextAlign.Center)
  40 + .fontWeight('600lpx')
  41 + .fontSize('33lpx')
  42 + .lineHeight('46lpx')
  43 + .fontColor($r('app.color.color_222222'))
  44 + .height('38lpx')
  45 + }
  46 + .width('100%')
  47 +
  48 + List(){
  49 + ForEach(this.searchHotsData,(item:SearchHotContentItem,index:number)=>{
  50 + ListItem(){
  51 + Column(){
  52 + Column(){
  53 + Row(){
  54 + Row(){
  55 + if(item.sequence <=3){
  56 + Image(item.sequence===1?$r('app.media.search_hot_num1'):item.sequence===2?$r('app.media.search_hot_num2'):$r('app.media.search_hot_num3'))
  57 + .width('27lpx')
  58 + .height('35lpx')
  59 + .objectFit(ImageFit.Auto)
  60 + .margin({right:'12lpx'})
  61 + }else {
  62 + Text(`${item.sequence}`)
  63 + .height('31lpx')
  64 + .fontColor($r('app.color.color_666666'))
  65 + .fontSize('27lpx')
  66 + .fontWeight('400lpx')
  67 + .lineHeight('31lpx')
  68 + .margin({right:'12lpx'})
  69 + }
  70 + Text(`${item.hotEntry}`)
  71 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  72 + .fontColor($r('app.color.color_222222'))
  73 + .fontSize('31lpx')
  74 + .maxLines(1)
  75 + .fontWeight('400lpx')
  76 + .lineHeight('42lpx')
  77 + }.layoutWeight(1)
  78 + if(item.mark!=0){
  79 + Image(item.mark===1?$r('app.media.search_hots_mark1'):$r('app.media.search_hots_mark2'))
  80 + .width('42lpx')
  81 + .height('31lpx')
  82 + .objectFit(ImageFit.Auto)
  83 + .interpolation(ImageInterpolation.Medium)
  84 + }
  85 + }.alignItems(VerticalAlign.Center)
  86 + .height('84lpx')
  87 + .justifyContent(FlexAlign.SpaceBetween)
  88 +
  89 + if(index != this.searchHotsData.length-1 ){
  90 + Divider()
  91 + .width('100%')
  92 + .height('1lpx')
  93 + .color($r('app.color.color_F5F5F5'))
  94 + .strokeWidth('1lpx')
  95 + }
  96 + }.height('108lpx')
  97 + .justifyContent(FlexAlign.Center)
  98 + .alignItems(HorizontalAlign.Start)
  99 + .padding({left:'27lpx'})
  100 + }
  101 + }
  102 + .onClick(()=>{
  103 + })
  104 + .height('117lpx')
  105 + })
  106 + }.onScrollFrameBegin((offset, state) => {
  107 + return { offsetRemain: 0 }
  108 + }).layoutWeight(1)
  109 + }.width('100%')
  110 + .height('100%')
  111 + .margin({top:'46lpx'})
  112 + }
  113 +}
@@ -35,6 +35,8 @@ export struct BigPicCardComponent { @@ -35,6 +35,8 @@ export struct BigPicCardComponent {
35 Column() { 35 Column() {
36 36
37 Column() { 37 Column() {
  38 + // TODO 测试代码
  39 + Text("likeNum " + this.contentDTO?.interactData?.likeNum)
38 //新闻标题 40 //新闻标题
39 Text(this.compDTO.operDataList[0].newsTitle) 41 Text(this.compDTO.operDataList[0].newsTitle)
40 .fontSize(17) 42 .fontSize(17)
@@ -3,6 +3,8 @@ import { Logger, ResourcesUtils } from 'wdKit'; @@ -3,6 +3,8 @@ import { Logger, ResourcesUtils } from 'wdKit';
3 import { ResponseDTO, WDHttp } from 'wdNetwork'; 3 import { ResponseDTO, WDHttp } from 'wdNetwork';
4 import HashMap from '@ohos.util.HashMap'; 4 import HashMap from '@ohos.util.HashMap';
5 import { HttpUrlUtils } from '../network/HttpUrlUtils'; 5 import { HttpUrlUtils } from '../network/HttpUrlUtils';
  6 +import { SearchHistoryItem } from '../viewmodel/SearchHistoryItem';
  7 +import { SearchHotContentItem } from '../viewmodel/SearchHotContentItem';
6 const TAG = "SearcherAboutDataModel" 8 const TAG = "SearcherAboutDataModel"
7 9
8 /** 10 /**
@@ -10,6 +12,7 @@ const TAG = "SearcherAboutDataModel" @@ -10,6 +12,7 @@ const TAG = "SearcherAboutDataModel"
10 */ 12 */
11 class SearcherAboutDataModel{ 13 class SearcherAboutDataModel{
12 private static instance: SearcherAboutDataModel; 14 private static instance: SearcherAboutDataModel;
  15 + searchHistoryData:SearchHistoryItem[] = []
13 16
14 private constructor() { } 17 private constructor() { }
15 18
@@ -25,6 +28,53 @@ class SearcherAboutDataModel{ @@ -25,6 +28,53 @@ class SearcherAboutDataModel{
25 } 28 }
26 29
27 /** 30 /**
  31 + * 静态搜索历史记录
  32 + */
  33 + getSearchHistoryData():SearchHistoryItem[]{
  34 + if(this.searchHistoryData.length > 0){
  35 + return this.searchHistoryData
  36 + }
  37 + this.searchHistoryData.push(new SearchHistoryItem("评论"))
  38 + this.searchHistoryData.push(new SearchHistoryItem("关注关注"))
  39 + this.searchHistoryData.push(new SearchHistoryItem("收藏收藏收藏"))
  40 + this.searchHistoryData.push(new SearchHistoryItem("历史"))
  41 + this.searchHistoryData.push(new SearchHistoryItem("消息消息消息消息消息"))
  42 + this.searchHistoryData.push(new SearchHistoryItem("留言板留言板留言板留言板留言板"))
  43 + this.searchHistoryData.push(new SearchHistoryItem("预约"))
  44 + return this.searchHistoryData
  45 + }
  46 +
  47 + // async putSearchHistoryData(content:string){
  48 + // let history = await SPHelper.default.get(SearcherAboutDataModel.SEARCH_HISTORY_KEY, '[]') as string;
  49 + // this.searchHistoryData = JSON.parse(history)
  50 + // this.searchHistoryData.push(new SearchHistoryItem(content))
  51 + // await SPHelper.default.save(SearcherAboutDataModel.SEARCH_HISTORY_KEY, JSON.stringify(this.searchHistoryData));
  52 + // }
  53 +
  54 + // getSearchHistoryData():Promise<SearchHistoryItem[]>{
  55 + // return new Promise<SearchHistoryItem[]>(async (success, error) => {
  56 + // if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
  57 + // success(this.searchHistoryData)
  58 + // return
  59 + // }
  60 + // try {
  61 + // let history = await SPHelper.default.get(SearcherAboutDataModel.SEARCH_HISTORY_KEY, '') as string;
  62 + // console.log('ycg',history);
  63 + // }catch (error){
  64 + // console.log('ycg',"1111");
  65 + // }
  66 + //
  67 + // this.searchHistoryData = JSON.parse(history)
  68 + // this.searchHistoryData.push(new SearchHistoryItem("评论"))
  69 + // this.searchHistoryData.push(new SearchHistoryItem("关注关注"))
  70 + // this.searchHistoryData.push(new SearchHistoryItem("收藏收藏收藏"))
  71 + //
  72 + // success(this.searchHistoryData)
  73 + // })
  74 + // }
  75 +
  76 +
  77 + /**
28 * 首页 搜索提示滚动内容 78 * 首页 搜索提示滚动内容
29 */ 79 */
30 getSearchHintData(context: Context): Promise<string[]> { 80 getSearchHintData(context: Context): Promise<string[]> {
@@ -62,6 +112,45 @@ class SearcherAboutDataModel{ @@ -62,6 +112,45 @@ class SearcherAboutDataModel{
62 return compRes.data 112 return compRes.data
63 } 113 }
64 114
  115 + /**
  116 + * 搜索主页 热词
  117 + */
  118 + getSearchHotsData(context: Context): Promise<SearchHotContentItem[]> {
  119 + return new Promise<SearchHotContentItem[]>((success, error) => {
  120 + Logger.info(TAG, `getSearchHintData start`);
  121 + this.fetchSearchHotsData().then((navResDTO: ResponseDTO<SearchHotContentItem[]>) => {
  122 + if (!navResDTO || navResDTO.code != 0) {
  123 + success(this.getSearchHotsDataLocal(context))
  124 + return
  125 + }
  126 + Logger.info(TAG, "getSearchHotsData then,getSearchHotsData.timeStamp:" + navResDTO.timestamp);
  127 + let navigationBean = navResDTO.data as SearchHotContentItem[]
  128 + success(navigationBean);
  129 + }).catch((err: Error) => {
  130 + Logger.error(TAG, `getSearchHotsData catch, error.name : ${err.name}, error.message:${err.message}`);
  131 + success(this.getSearchHotsDataLocal(context))
  132 + })
  133 + })
  134 + }
  135 +
  136 + fetchSearchHotsData() {
  137 + let url = HttpUrlUtils.getSearchHotsDataUrl()
  138 + let headers: HashMap<string, string> = HttpUrlUtils.getYcgCommonHeaders();
  139 + return WDHttp.get<ResponseDTO<SearchHotContentItem[]>>(url, headers)
  140 + };
  141 +
  142 + async getSearchHotsDataLocal(context: Context): Promise<SearchHotContentItem[]> {
  143 + Logger.info(TAG, `getSearchHotsDataLocal start`);
  144 + let compRes: ResponseDTO<SearchHotContentItem[]> | null = await ResourcesUtils.getResourcesJson<ResponseDTO<SearchHotContentItem[]>>('search_hots_data.json' ,context);
  145 + if (!compRes || !compRes.data) {
  146 + Logger.info(TAG, `getSearchHotsDataLocal compRes is empty`);
  147 + return []
  148 + }
  149 + Logger.info(TAG, `getSearchHotsDataLocal compRes : ${JSON.stringify(compRes)}`);
  150 + return compRes.data
  151 + }
  152 +
  153 +
65 154
66 155
67 } 156 }
@@ -121,6 +121,11 @@ export class HttpUrlUtils { @@ -121,6 +121,11 @@ export class HttpUrlUtils {
121 */ 121 */
122 static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints"; 122 static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints";
123 123
  124 + /**
  125 + * 搜索主页 热词
  126 + */
  127 + static readonly SEARCH_HOTS_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hots";
  128 +
124 private static hostUrl: string = HttpUrlUtils.HOST_UAT; 129 private static hostUrl: string = HttpUrlUtils.HOST_UAT;
125 130
126 static getCommonHeaders(): HashMap<string, string> { 131 static getCommonHeaders(): HashMap<string, string> {
@@ -308,6 +313,10 @@ export class HttpUrlUtils { @@ -308,6 +313,10 @@ export class HttpUrlUtils {
308 return url 313 return url
309 } 314 }
310 315
  316 + static getSearchHotsDataUrl() {
  317 + let url = HttpUrlUtils.HOST_SIT + HttpUrlUtils.SEARCH_HOTS_DATA_PATH
  318 + return url
  319 + }
311 320
312 /** 321 /**
313 * 点赞操作 322 * 点赞操作
1 /** 1 /**
2 * 批查接口查询互动相关数据,返回数据bean 2 * 批查接口查询互动相关数据,返回数据bean
3 */ 3 */
4 -export interface InteractDataDTO { 4 +export class InteractDataDTO {
5 collectNum: number; 5 collectNum: number;
6 commentNum: number; 6 commentNum: number;
7 contentId: string; 7 contentId: string;
@@ -4,6 +4,8 @@ import { RefreshConstants as Const, RefreshState } from './RefreshConstants'; @@ -4,6 +4,8 @@ import { RefreshConstants as Const, RefreshState } from './RefreshConstants';
4 import PageViewModel from '../viewmodel/PageViewModel'; 4 import PageViewModel from '../viewmodel/PageViewModel';
5 import { PageDTO } from '../repository/bean/PageDTO'; 5 import { PageDTO } from '../repository/bean/PageDTO';
6 import { touchMoveLoadMore, touchUpLoadMore } from './PullUpLoadMore'; 6 import { touchMoveLoadMore, touchUpLoadMore } from './PullUpLoadMore';
  7 +import { CompDTO } from '../repository/bean/CompDTO';
  8 +import { DateTimeUtils } from 'wdKit/src/main/ets/utils/DateTimeUtils';
7 9
8 export function listTouchEvent(pageModel: PageModel, event: TouchEvent) { 10 export function listTouchEvent(pageModel: PageModel, event: TouchEvent) {
9 switch (event.type) { 11 switch (event.type) {
@@ -73,6 +75,7 @@ export function touchUpPullRefresh(pageModel: PageModel) { @@ -73,6 +75,7 @@ export function touchUpPullRefresh(pageModel: PageModel) {
73 75
74 PageViewModel.getPageData(self) 76 PageViewModel.getPageData(self)
75 .then((data: PageDTO) => { 77 .then((data: PageDTO) => {
  78 + self.timestamp = DateTimeUtils.getCurrentTimeMillis().toString()
76 if (data == null || data.compList == null || data.compList.length == 0) { 79 if (data == null || data.compList == null || data.compList.length == 0) {
77 self.hasMore = false; 80 self.hasMore = false;
78 } else { 81 } else {
@@ -84,6 +87,11 @@ export function touchUpPullRefresh(pageModel: PageModel) { @@ -84,6 +87,11 @@ export function touchUpPullRefresh(pageModel: PageModel) {
84 } 87 }
85 // 刷新,替换所有数据 88 // 刷新,替换所有数据
86 self.compList.replaceAll(...data.compList) 89 self.compList.replaceAll(...data.compList)
  90 + PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
  91 + // 刷新,替换所有数据
  92 + self.compList.replaceAll(...data)
  93 + self.timestamp = DateTimeUtils.getCurrentTimeMillis().toString()
  94 + })
87 } 95 }
88 closeRefresh(self, true); 96 closeRefresh(self, true);
89 }).catch((err: string | Resource) => { 97 }).catch((err: string | Resource) => {
@@ -3,6 +3,8 @@ import PageModel from '../viewmodel/PageModel'; @@ -3,6 +3,8 @@ import PageModel from '../viewmodel/PageModel';
3 import { RefreshConstants as Const } from './RefreshConstants'; 3 import { RefreshConstants as Const } from './RefreshConstants';
4 import PageViewModel from '../viewmodel/PageViewModel'; 4 import PageViewModel from '../viewmodel/PageViewModel';
5 import { PageDTO } from '../repository/bean/PageDTO'; 5 import { PageDTO } from '../repository/bean/PageDTO';
  6 +import { CompDTO } from '../repository/bean/CompDTO';
  7 +import { DateTimeUtils } from 'wdKit';
6 8
7 export function touchMoveLoadMore(model: PageModel, event: TouchEvent) { 9 export function touchMoveLoadMore(model: PageModel, event: TouchEvent) {
8 // list size +1 10 // list size +1
@@ -38,7 +40,13 @@ export function touchUpLoadMore(model: PageModel) { @@ -38,7 +40,13 @@ export function touchUpLoadMore(model: PageModel) {
38 } else { 40 } else {
39 self.hasMore = false; 41 self.hasMore = false;
40 } 42 }
  43 + let sizeBefore = self.compList.size();
41 self.compList.push(...data.compList) 44 self.compList.push(...data.compList)
  45 + PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
  46 + // 刷新,替换所有数据
  47 + self.compList.updateItems(sizeBefore, data)
  48 + self.timestamp = DateTimeUtils.getCurrentTimeMillis().toString()
  49 + })
42 } 50 }
43 }).catch((err: string | Resource) => { 51 }).catch((err: string | Resource) => {
44 promptAction.showToast({ message: err }); 52 promptAction.showToast({ message: err });
@@ -34,4 +34,6 @@ export default class PageModel { @@ -34,4 +34,6 @@ export default class PageModel {
34 isPullRefreshOperation = false; 34 isPullRefreshOperation = false;
35 isLoading: boolean = false; 35 isLoading: boolean = false;
36 isCanLoadMore: boolean = false; 36 isCanLoadMore: boolean = false;
  37 + // keyGenerator相关字符串,用于刷新list布局
  38 + timestamp: String = '1';
37 } 39 }
@@ -40,7 +40,7 @@ export class PageViewModel extends BaseViewModel { @@ -40,7 +40,7 @@ export class PageViewModel extends BaseViewModel {
40 if (mock_switch) { 40 if (mock_switch) {
41 return this.getBottomNavDataMock(context); 41 return this.getBottomNavDataMock(context);
42 } 42 }
43 - return this.getNavData(); 43 + return this.getNavData(context);
44 } 44 }
45 45
46 async getBottomNavDataMock(context?: Context): Promise<NavigationBodyDTO> { 46 async getBottomNavDataMock(context?: Context): Promise<NavigationBodyDTO> {
@@ -54,12 +54,13 @@ export class PageViewModel extends BaseViewModel { @@ -54,12 +54,13 @@ export class PageViewModel extends BaseViewModel {
54 return compRes.data 54 return compRes.data
55 } 55 }
56 56
57 - private getNavData(): Promise<NavigationBodyDTO> { 57 + private getNavData(context?: Context): Promise<NavigationBodyDTO> {
58 return new Promise<NavigationBodyDTO>((success, error) => { 58 return new Promise<NavigationBodyDTO>((success, error) => {
59 Logger.info(TAG, `getNavData start`); 59 Logger.info(TAG, `getNavData start`);
60 PageRepository.fetchNavigationDataApi().then((navResDTO: ResponseDTO<NavigationBodyDTO>) => { 60 PageRepository.fetchNavigationDataApi().then((navResDTO: ResponseDTO<NavigationBodyDTO>) => {
61 if (this.isRespondsInvalid(navResDTO, 'getNavData')) { 61 if (this.isRespondsInvalid(navResDTO, 'getNavData')) {
62 - error("page data invalid"); 62 + // error("page data invalid");
  63 + success(this.getBottomNavDataMock(context))
63 return 64 return
64 } 65 }
65 Logger.info(TAG, "getNavData then,navResDTO.timeStamp:" + navResDTO.timestamp); 66 Logger.info(TAG, "getNavData then,navResDTO.timeStamp:" + navResDTO.timestamp);
@@ -147,14 +148,6 @@ export class PageViewModel extends BaseViewModel { @@ -147,14 +148,6 @@ export class PageViewModel extends BaseViewModel {
147 return; 148 return;
148 } 149 }
149 success(resDTO.data); 150 success(resDTO.data);
150 - // TODO 打开同步请求互动数据,待优化为异步加载  
151 - if (CollectionUtils.isEmpty(resDTO.data.compList)) {  
152 - success(resDTO.data);  
153 - } else {  
154 - this.getInteractData(resDTO.data.compList).then(() => {  
155 - success(resDTO.data);  
156 - })  
157 - }  
158 }) 151 })
159 .catch((err: Error) => { 152 .catch((err: Error) => {
160 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`); 153 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`);
@@ -249,7 +242,8 @@ export class PageViewModel extends BaseViewModel { @@ -249,7 +242,8 @@ export class PageViewModel extends BaseViewModel {
249 } 242 }
250 if (id == content.objectId) { 243 if (id == content.objectId) {
251 content.interactData = interactData; 244 content.interactData = interactData;
252 - content.interactData.likeNum = 109; 245 + // TODO 测试代码,待删除
  246 + // content.interactData.likeNum = Math.floor(Math.random() * Math.floor(999));;
253 break outer; 247 break outer;
254 } 248 }
255 } 249 }
  1 +export class SearchHistoryItem{
  2 + searchContent:string = ""
  3 + searchUserId:string = ""
  4 + searchTime:string = ""
  5 +
  6 + constructor(searchContent: string,searchUserId?:string,searchTime?:string) {
  7 + this.searchContent = searchContent
  8 + this.searchUserId = searchUserId
  9 + this.searchTime = searchTime
  10 + }
  11 +}
  1 +export class SearchHotContentItem{
  2 + hotEntry:string = ""
  3 + mark:number = 0 //1 热 2 新
  4 + sequence:number = 0//序号
  5 +
  6 + constructor(hotEntry: string , mark: number , sequence: number ) {
  7 + this.hotEntry = hotEntry
  8 + this.mark = mark
  9 + this.sequence = sequence
  10 + }
  11 +}
@@ -254,4 +254,10 @@ export class LazyDataSource<T> extends BasicDataSource<T> { @@ -254,4 +254,10 @@ export class LazyDataSource<T> extends BasicDataSource<T> {
254 sort(comparator: (firstValue: T, secondValue: T) => number): void { 254 sort(comparator: (firstValue: T, secondValue: T) => number): void {
255 this.dataArray.sort(comparator) 255 this.dataArray.sort(comparator)
256 } 256 }
  257 +
  258 + public updateItems(start: number, data: T[]): void {
  259 + // 从数组中的start位置开始删除dataArray.length个元素,并在同一位置插入((1个或多个))新元素。
  260 + this.dataArray.splice(start, this.dataArray.length, ...data);
  261 + this.notifyDataReload()
  262 + }
257 } 263 }
1 /** 1 /**
2 * 组件Style/展示样式 2 * 组件Style/展示样式
3 */ 3 */
  4 +
4 export const enum CompStyle { 5 export const enum CompStyle {
5 Label_03 = 'Label-03', // 标题卡:icon+文字 6 Label_03 = 'Label-03', // 标题卡:icon+文字
6 - Carousel_Layout_01 = 'Zh_Carousel_Layout-01', // 通用轮播卡:视频、直播、活动、专题、榜单、外链  
7 Carousel_Layout_02 = 'Carousel_Layout-02', // 直播轮播卡:直播 7 Carousel_Layout_02 = 'Carousel_Layout-02', // 直播轮播卡:直播
8 - Single_Row_01 = 'Zh_Single_Row-01', // 三格方形小卡(排名):专题、活动  
9 - Zh_Single_Row_01 = 'Zh_Single_Row-01', // 横划卡 imageScale-封面图比例 1-4:3, 2-16:9, 3-3:2  
10 Single_Row_02 = 'Zh_Single_Row-02', // 通用横划卡:视频、直播、专题 8 Single_Row_02 = 'Zh_Single_Row-02', // 通用横划卡:视频、直播、专题
11 Single_Row_03 = 'Single_Row-03', // 直播横划卡:直播 9 Single_Row_03 = 'Single_Row-03', // 直播横划卡:直播
12 Single_Row_04 = 'Single_Row-04', // 三格方形小卡:专题、活动 10 Single_Row_04 = 'Single_Row-04', // 三格方形小卡:专题、活动
@@ -17,17 +15,52 @@ export const enum CompStyle { @@ -17,17 +15,52 @@ export const enum CompStyle {
17 Single_Column_04 = 'Single_Column-04', // 大卡横屏(带背景):视频、直播 15 Single_Column_04 = 'Single_Column-04', // 大卡横屏(带背景):视频、直播
18 Single_Column_05 = 'Single_Column-05', // 海报图卡:/ 16 Single_Column_05 = 'Single_Column-05', // 海报图卡:/
19 Single_Column_06 = 'Single_Column-06', // 留言板卡:/ 17 Single_Column_06 = 'Single_Column-06', // 留言板卡:/
20 - Zh_Single_Column_02 = 'Zh_Single_Column-02', // 头图卡  
21 Grid_Layout_01 = 'Grid_Layout-01', // 横屏宫格卡:视频、直播 18 Grid_Layout_01 = 'Grid_Layout-01', // 横屏宫格卡:视频、直播
22 Grid_Layout_02 = 'Grid_Layout-02', // 竖屏宫格卡:视频、直播、榜单 19 Grid_Layout_02 = 'Grid_Layout-02', // 竖屏宫格卡:视频、直播、榜单
23 Masonry_Layout_01 = 'Masonry_Layout-01', // 双列瀑布流/瀑布流卡:视频、直播、专题、活动 20 Masonry_Layout_01 = 'Masonry_Layout-01', // 双列瀑布流/瀑布流卡:视频、直播、专题、活动
24 - Title_Abbr_01 = '11', // 标题缩略  
25 - Title_All_01 = '3', // 全标题  
26 - Single_ImageCard_03 = '13',//单图卡:3行标题  
27 - Single_ImageCard_01 = '6',//单图卡,竖图  
28 - ZhGrid_Layout_03 = 'Zh_Grid_Layout-03', //金刚位卡  
29 - Album_Card_01 = '17', //图卡集  
30 - Zh_Single_Row_04 = 'Zh_Single_Row-04', // 地方精选卡  
31 - CompStyle_09 = '9', // 时间链卡  
32 - CompStyle_10 = '10', // 大专题卡 21 +
  22 +
  23 + Zh_Carousel_Layout_01 = 'Zh_Carousel_Layout-01', //1 轮播图卡---1
  24 + Zh_Single_Row_01 = 'Zh_Single_Row-01', //2 横划卡 imageScale-封面图比例 1-4:3, 2-16:9, 3-3:2---1
  25 + Zh_Single_Row_02 = 'Zh_Single_Row-02', //3 小视频横划卡---1
  26 + Zh_Single_Row_03 = 'Zh_Single_Row-03', //6 直播预约卡
  27 + Zh_Single_Row_04 = 'Zh_Single_Row-04', // 地方精选卡---2
  28 + Zh_Single_Row_05 = 'Zh_Single_Row-05', //15 人民号横划卡---1
  29 + Zh_Single_Row_06 = 'Zh_Single_Row-06', //20 热门评论卡--精选评论卡-1
  30 + Zh_Single_Column_01 = 'Zh_Single_Column-01', //5 专题时间链卡
  31 + Zh_Single_Column_02 = 'Zh_Single_Column-02', //10 头图卡---2
  32 + Zh_Single_Column_03 = 'Zh_Single_Column-03', //9 直播大图卡
  33 + Zh_Single_Column_04 = 'Zh_Single_Column-04', //17 人民号主题卡---1
  34 + Zh_Single_Column_05 = 'Zh_Single_Column-05', //16 人民号入驻卡---1
  35 + Zh_Single_Column_06 = 'Zh_Single_Column-06', //12 本地问政卡
  36 + Zh_Single_Column_07 = 'Zh_Single_Column-07', //14 热门留言卡
  37 + Zh_Single_Column_08 = 'Zh_Single_Column-08', //12 问政提问卡
  38 + Zh_Single_Column_10 = 'Zh_Single_Column-10', //18 服务组合卡
  39 + Zh_Single_Column_11 = 'Zh_Single_Column-11', //19 问政组合卡
  40 + Zh_Grid_Layout_01 = 'Zh_Grid_Layout-01', //4 信息流组合卡
  41 + Zh_Grid_Layout_02 = 'Zh_Grid_Layout-02', //7 双列流小视频,一行两图卡---1
  42 + Zh_Grid_Layout_03 = 'Zh_Grid_Layout-03', //11 金刚位卡---2
  43 + Card_01 = '1', // 小图卡
  44 + Card_02 = '2', // 大图卡---2
  45 + Card_03 = '3', // 无图卡(全标题)---2
  46 + Card_04 = '4', // 三图卡---2
  47 + Card_05 = '5', // 头图卡---2
  48 + Card_06 = '6', // 小视频卡---2
  49 + Card_07 = '7', // 作者卡
  50 + Card_08 = '8', // 财经快讯卡
  51 + Card_09 = '9', // 时间轴卡---2
  52 + Card_10 = '10', // 大专题卡---2
  53 + Card_11 = '11', // 无图卡(标题省略)---2
  54 + Card_12 = '12', // 无图卡人民号---1
  55 + Card_13 = '13', // 单图卡---2--同6
  56 + Card_14 = '14', // 单图卡人民号---1
  57 + Card_15 = '15', // 大图卡人民号---1
  58 + Card_16 = '16', // 三图卡人民号---1
  59 + Card_17 = '17', // 图卡集---2
  60 + Card_18 = '18', // 图卡集人民号
  61 + Card_19 = '19', // 动态图文卡人民号---1
  62 + Card_20 = '20', // 动态视频卡人民号---1
  63 + Card_21 = '21', // 小视频卡人民号---1
  64 + Card_22 = '22', // 时间链
  65 + Card_23 = '23', // 问政卡
33 } 66 }
@@ -39,6 +39,10 @@ export class LazyDataSource<T> extends BasicDataSource<T> { @@ -39,6 +39,10 @@ export class LazyDataSource<T> extends BasicDataSource<T> {
39 return this.getData(this.totalCount() - 1); 39 return this.getData(this.totalCount() - 1);
40 } 40 }
41 41
  42 + public size(): number {
  43 + return this.dataArray.length
  44 + }
  45 +
42 // 获取所有数据 46 // 获取所有数据
43 public getDataArray(): T[] { 47 public getDataArray(): T[] {
44 return this.dataArray; 48 return this.dataArray;
@@ -276,4 +280,10 @@ export class LazyDataSource<T> extends BasicDataSource<T> { @@ -276,4 +280,10 @@ export class LazyDataSource<T> extends BasicDataSource<T> {
276 public sort(comparator: (firstValue: T, secondValue: T) => number): void { 280 public sort(comparator: (firstValue: T, secondValue: T) => number): void {
277 this.dataArray.sort(comparator) 281 this.dataArray.sort(comparator)
278 } 282 }
  283 +
  284 + public updateItems(start: number, data: T[]): void {
  285 + // 从数组中的start位置开始删除dataArray.length个元素,并在同一位置插入((1个或多个))新元素。
  286 + this.dataArray.splice(start, this.dataArray.length, ...data);
  287 + this.notifyDataReload()
  288 + }
279 } 289 }
@@ -177,6 +177,10 @@ export class HttpUrlUtils { @@ -177,6 +177,10 @@ export class HttpUrlUtils {
177 */ 177 */
178 static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints"; 178 static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints";
179 /** 179 /**
  180 + * 搜索主页 热词
  181 + */
  182 + static readonly SEARCH_HOTS_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hots";
  183 + /**
180 * 早晚报列表 184 * 早晚报列表
181 * 根据页面id获取页面楼层列表 185 * 根据页面id获取页面楼层列表
182 * https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/pageInfo?pageId=28927 186 * https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/pageInfo?pageId=28927
@@ -527,6 +531,11 @@ export class HttpUrlUtils { @@ -527,6 +531,11 @@ export class HttpUrlUtils {
527 return url 531 return url
528 } 532 }
529 533
  534 + static getSearchHotsDataUrl() {
  535 + let url = HttpUrlUtils.HOST_SIT + HttpUrlUtils.SEARCH_HOTS_DATA_PATH
  536 + return url
  537 + }
  538 +
530 539
531 540
532 // static getYcgCommonHeaders(): HashMap<string, string> { 541 // static getYcgCommonHeaders(): HashMap<string, string> {
1 import ArrayList from '@ohos.util.ArrayList'; 1 import ArrayList from '@ohos.util.ArrayList';
2 -import { Action } from 'wdBean'  
3 -import { WDRouterPage } from './WDRouterPage' 2 +import { Action } from 'wdBean';
  3 +import { WDRouterPage } from './WDRouterPage';
4 4
5 interface HandleObject { 5 interface HandleObject {
6 handle: (action: Action) => (WDRouterPage | undefined) 6 handle: (action: Action) => (WDRouterPage | undefined)
@@ -75,6 +75,8 @@ export function registerRouter() { @@ -75,6 +75,8 @@ export function registerRouter() {
75 return WDRouterPage.imageTextDetailPage 75 return WDRouterPage.imageTextDetailPage
76 } else if (action.params?.pageID == "BroadcastPage") { 76 } else if (action.params?.pageID == "BroadcastPage") {
77 return WDRouterPage.broadcastPage 77 return WDRouterPage.broadcastPage
  78 + } else if (action.params?.pageID == "LIVE_DETAILS_PAGER") {
  79 + return WDRouterPage.detailPlayLivePage
78 } 80 }
79 return undefined 81 return undefined
80 }) 82 })
@@ -86,4 +86,6 @@ export class WDRouterPage { @@ -86,4 +86,6 @@ export class WDRouterPage {
86 86
87 //播报页面 87 //播报页面
88 static broadcastPage = new WDRouterPage("phone", "ets/pages/broadcast/BroadcastPage"); 88 static broadcastPage = new WDRouterPage("phone", "ets/pages/broadcast/BroadcastPage");
  89 + //搜索主页
  90 + static searchPage = new WDRouterPage("wdComponent", "ets/pages/SearchPage");
89 } 91 }
@@ -59,10 +59,11 @@ export interface ContentDTO { @@ -59,10 +59,11 @@ export interface ContentDTO {
59 59
60 newsSummary: string; //appstyle:2 ,新闻详情 60 newsSummary: string; //appstyle:2 ,新闻详情
61 61
62 - // 二次请求接口,返回的数据,这里组装到content里;TODO 后续优化 62 + // 二次请求接口,返回的数据,这里组装到content里;
63 interactData:InteractDataDTO; 63 interactData:InteractDataDTO;
64 64
65 hasMore: number, 65 hasMore: number,
66 slideShows: slideShows[], 66 slideShows: slideShows[],
67 - voiceInfo: VoiceInfoDTO 67 + voiceInfo: VoiceInfoDTO,
  68 + tagWord: number,
68 } 69 }
@@ -60,3 +60,5 @@ export { BroadcastPageComponent } from "./src/main/ets/components/broadcast/Broa @@ -60,3 +60,5 @@ export { BroadcastPageComponent } from "./src/main/ets/components/broadcast/Broa
60 60
61 export { FirstTabTopSearchComponent } from "./src/main/ets/components/search/FirstTabTopSearchComponent" 61 export { FirstTabTopSearchComponent } from "./src/main/ets/components/search/FirstTabTopSearchComponent"
62 62
  63 +export { ListHasNoMoreDataUI } from "./src/main/ets/components/reusable/ListHasNoMoreDataUI"
  64 +
1 -import { CommonConstants } from 'wdConstant';  
2 -import { Card3Component } from './cardview/Card3Component'; 1 +import { CommonConstants, CompStyle } from 'wdConstant';
  2 +import { ContentDTO } from 'wdBean';
3 import { Card2Component } from './cardview/Card2Component'; 3 import { Card2Component } from './cardview/Card2Component';
  4 +import { Card3Component } from './cardview/Card3Component';
4 import { Card4Component } from './cardview/Card4Component'; 5 import { Card4Component } from './cardview/Card4Component';
5 -import { ContentDTO } from 'wdBean';  
6 import { Card5Component } from './cardview/Card5Component'; 6 import { Card5Component } from './cardview/Card5Component';
7 import { Card6Component } from './cardview/Card6Component'; 7 import { Card6Component } from './cardview/Card6Component';
  8 +import { Card9Component } from './cardview/Card9Component';
  9 +import { Card10Component } from './cardview/Card10Component';
  10 +import { Card11Component } from './cardview/Card11Component';
  11 +import { Card17Component } from './cardview/Card17Component';
8 12
9 /** 13 /**
10 * card适配器,卡片样式汇总,依据ContentDTO#appStyle 14 * card适配器,卡片样式汇总,依据ContentDTO#appStyle
@@ -20,16 +24,25 @@ export struct CardParser { @@ -20,16 +24,25 @@ export struct CardParser {
20 24
21 @Builder 25 @Builder
22 contentBuilder(contentDTO: ContentDTO) { 26 contentBuilder(contentDTO: ContentDTO) {
23 - if (contentDTO.appStyle === '2') { 27 + if (contentDTO.appStyle === CompStyle.Card_02) {
24 Card2Component({ contentDTO }) 28 Card2Component({ contentDTO })
25 - } else if (contentDTO.appStyle === '3') { 29 + } else if (contentDTO.appStyle === CompStyle.Card_03) {
26 Card3Component({ contentDTO }) 30 Card3Component({ contentDTO })
27 - } else if (contentDTO.appStyle === "4") { 31 + } else if (contentDTO.appStyle === CompStyle.Card_04) {
28 Card4Component({ contentDTO }) 32 Card4Component({ contentDTO })
29 - } else if (contentDTO.appStyle === "5") { 33 + } else if (contentDTO.appStyle === CompStyle.Card_05) {
30 Card5Component({ contentDTO }) 34 Card5Component({ contentDTO })
31 - } else if (contentDTO.appStyle === "6") { 35 + } else if (contentDTO.appStyle === CompStyle.Card_06 || contentDTO.appStyle === CompStyle
  36 + .Card_13) {
32 Card6Component({ contentDTO }) 37 Card6Component({ contentDTO })
  38 + } else if (contentDTO.appStyle === CompStyle.Card_09) {
  39 + Card9Component({ contentDTO })
  40 + } else if (contentDTO.appStyle === CompStyle.Card_10) {
  41 + Card10Component({ contentDTO })
  42 + } else if (contentDTO.appStyle === CompStyle.Card_11) {
  43 + Card11Component({ contentDTO })
  44 + } else if (contentDTO.appStyle === CompStyle.Card_17) {
  45 + Card17Component({ contentDTO })
33 } 46 }
34 else { 47 else {
35 // todo:组件未实现 / Component Not Implemented 48 // todo:组件未实现 / Component Not Implemented
1 -import { CompDTO, ContentDTO , slideShows} from 'wdBean'; 1 +import { CompDTO} from 'wdBean';
2 import { CommonConstants, CompStyle } from 'wdConstant'; 2 import { CommonConstants, CompStyle } from 'wdConstant';
3 import { BannerComponent } from './view/BannerComponent'; 3 import { BannerComponent } from './view/BannerComponent';
4 import { LabelComponent } from './view/LabelComponent'; 4 import { LabelComponent } from './view/LabelComponent';
5 -import { TitleAbbrComponent } from './view/TitleAbbrComponent';  
6 -import { TitleAllComponent } from './view/TitleAllComponent';  
7 -import { SingleImageCardComponent } from './view/SingleImageCardComponent';  
8 -import { BigPicCardComponent } from './view/BigPicCardComponent';  
9 -import { TriPicCardComponent } from './view/TriPicCardComponent';  
10 import { LiveHorizontalCardComponent } from './view/LiveHorizontalCardComponent'; 5 import { LiveHorizontalCardComponent } from './view/LiveHorizontalCardComponent';
11 -import { HeadPictureCardComponent } from './view/HeadPictureCardComponent';  
12 -import { ZhGridLayoutComponent } from './view/ZhGridLayoutComponent';  
13 import { 6 import {
14 HorizontalStrokeCardThreeTwoRadioForMoreComponent 7 HorizontalStrokeCardThreeTwoRadioForMoreComponent
15 } from './view/HorizontalStrokeCardThreeTwoRadioForMoreComponent'; 8 } from './view/HorizontalStrokeCardThreeTwoRadioForMoreComponent';
16 import { 9 import {
17 HorizontalStrokeCardThreeTwoRadioForOneComponent 10 HorizontalStrokeCardThreeTwoRadioForOneComponent
18 } from './view/HorizontalStrokeCardThreeTwoRadioForOneComponent'; 11 } from './view/HorizontalStrokeCardThreeTwoRadioForOneComponent';
19 -import { AlbumCardComponent } from './view/AlbumCardComponent';  
20 -import { ZhSingleRow04 } from './view/ZhSingleRow04'  
21 -import { CompStyle_09 } from './view/CompStyle_09'  
22 -import { CompStyle_10 } from './view/CompStyle_10'  
23 - 12 +import { ZhSingleRow04 } from './compview/ZhSingleRow04'
  13 +import { ZhSingleColumn04 } from './compview/ZhSingleColumn04'
  14 +import { ZhSingleColumn05 } from './compview/ZhSingleColumn05'
  15 +import { ZhGridLayout03 } from './compview/ZhGridLayout03'
  16 +import { CardParser } from './CardParser';
24 /** 17 /**
25 * comp适配器. 18 * comp适配器.
26 * 首页楼层comp解析器. 19 * 首页楼层comp解析器.
@@ -28,67 +21,7 @@ import { CompStyle_10 } from './view/CompStyle_10' @@ -28,67 +21,7 @@ import { CompStyle_10 } from './view/CompStyle_10'
28 @Preview 21 @Preview
29 @Component 22 @Component
30 export struct CompParser { 23 export struct CompParser {
31 - @State compDTO: CompDTO = {  
32 - compStyle: '17',  
33 - imageScale: 3,  
34 - operDataList: [  
35 - {  
36 - title: 'title0',  
37 - description: "description0",  
38 - coverUrl: 'https://uatjdcdnphoto.aikan.pdnews' +  
39 - '.cn/sjbj-20231208/image/display/d4496925a1264a749975ae9b01a4ef46.png?x-oss-process=image/resize,w_550/quality,q_90/format,jpg',  
40 - fullColumnImgUrls: [{  
41 - url: "https://uatjdcdnphoto.aikan.pdnews.cn/sjbj-20240104/image/display/c4a9b526e0994d1bbd3ac8450f5cfc6c.jpg?x-oss-process=image/resize,w_550/quality,q_90/format,jpg",  
42 - },{  
43 - url:'https://uatjdcdnphoto.aikan.pdnews' +  
44 - '.cn/sjbj-20231208/image/display/d4496925a1264a749975ae9b01a4ef46.png?x-oss-process=image/resize,w_550/quality,q_90/format,jpg',  
45 - },{  
46 - url: 'https://uatjdcdnphoto.aikan.pdnews' +  
47 - '.cn/sjbj-20231208/image/display/d4496925a1264a749975ae9b01a4ef46.png?x-oss-process=image/resize,w_550/quality,q_90/format,jpg',  
48 - }]  
49 - } as ContentDTO,  
50 - {  
51 - title: 'title1 title1 title1 title1 title1 title1 title1 title1 title1',  
52 - description: "description1",  
53 - coverUrl: "https://uatjdcdnphoto.aikan.pdnews.cn/sjbj-20240104/image/display/c4a9b526e0994d1bbd3ac8450f5cfc6c.jpg?x-oss-process=image/resize,w_550/quality,q_90/format,jpg",  
54 - } as ContentDTO,  
55 - {  
56 - title: 'title2',  
57 - description: "description2",  
58 - coverUrl: "https://cdnjdphoto.aikan.pdnews.cn/sjbj-20231206/image/live/bbe6d821e92b48919d90c7dadfd1f05a.jpg?x-oss-process=image/resize,l_850/auto-orient,1/quality,q_95/format,jpg",  
59 - } as ContentDTO,  
60 - {  
61 - title: 'title3',  
62 - description: "description3",  
63 - coverUrl: 'https://cdnjdphoto.aikan.pdnews.cn/sjbj-20231109/image/live/102e6eb9356b4ef19405b04c1f6ff875.png?x-oss-process=image/resize,l_850/auto-orient,1/quality,q_95/format,jpg'  
64 - } as ContentDTO,  
65 - {  
66 - title: 'title4',  
67 - description: "description4",  
68 - coverUrl: "https://uatjdcdnphoto.aikan.pdnews.cn/sjbj-20231218/image/display/62bdbbb35dbd45689e00790c81f04c4b.png?x-oss-process=image/resize,w_550/quality,q_90/format,jpg",  
69 - } as ContentDTO,  
70 - {  
71 - title: 'title5',  
72 - description: "description5",  
73 - coverUrl: "https://uatjdcdnphoto.aikan.pdnews.cn/sjbj-20231218/image/display/f79bbaa5a33b4bd88176071c4f797ff6.png?x-oss-process=image/resize,w_550/quality,q_90/format,jpg",  
74 - } as ContentDTO,  
75 - {  
76 - title: 'title6',  
77 - description: "description6",  
78 - coverUrl: "https://uatjdcdnphoto.aikan.pdnews.cn/sjbj-20231218/image/display/2c1d917009584ce2bb4a35cbb3a860a0.png?x-oss-process=image/resize,w_550/quality,q_90/format,jpg",  
79 - } as ContentDTO,  
80 - {  
81 - title: 'title7',  
82 - description: "description7",  
83 - coverUrl: "https://uatjdcdnphoto.aikan.pdnews.cn/sjbj-20231222/image/display/117dc516ca5c42d5843c0d32050c9fc6.jpeg?x-oss-process=image/resize,w_240/quality,q_90/format,jpg",  
84 - } as ContentDTO,  
85 - {  
86 - title: 'title8',  
87 - description: "description8",  
88 - coverUrl: "https://uatjdcdnphoto.aikan.pdnews.cn/sjbj-20231228/image/display/90a2db4077d44a1f887f068fc659d977.jpeg?x-oss-process=image/resize,w_550/quality,q_90/format,jpg",  
89 - } as ContentDTO  
90 - ]  
91 - } as CompDTO 24 + @State compDTO: CompDTO = {} as CompDTO
92 compIndex: number = 0; 25 compIndex: number = 0;
93 26
94 build() { 27 build() {
@@ -99,19 +32,8 @@ export struct CompParser { @@ -99,19 +32,8 @@ export struct CompParser {
99 componentBuilder(compDTO: CompDTO, compIndex: number) { 32 componentBuilder(compDTO: CompDTO, compIndex: number) {
100 if (compDTO.compStyle === CompStyle.Label_03) { 33 if (compDTO.compStyle === CompStyle.Label_03) {
101 LabelComponent({ compDTO: compDTO }) 34 LabelComponent({ compDTO: compDTO })
102 - } else if (compDTO.compStyle === CompStyle.Title_Abbr_01) {  
103 - TitleAbbrComponent({ compDTO: compDTO })  
104 - } else if (compDTO.compStyle === CompStyle.Title_All_01) {  
105 - TitleAllComponent({ compDTO: compDTO })  
106 - } else if (compDTO.compStyle === CompStyle.Carousel_Layout_01) { 35 + } else if (compDTO.compStyle === CompStyle.Zh_Carousel_Layout_01) {
107 BannerComponent({ compDTO: compDTO }) 36 BannerComponent({ compDTO: compDTO })
108 - } else if (compDTO.compStyle === CompStyle.Single_ImageCard_03  
109 - || compDTO.compStyle === CompStyle.Single_ImageCard_01) {  
110 - SingleImageCardComponent({ compDTO: compDTO })  
111 - } else if (compDTO.compStyle === "2") {  
112 - BigPicCardComponent({ compDTO: compDTO })  
113 - } else if (compDTO.compStyle === "4") {  
114 - TriPicCardComponent({ compDTO: compDTO })  
115 } else if (compDTO.compStyle === CompStyle.Zh_Single_Row_01 && compDTO.imageScale === 2) { 37 } else if (compDTO.compStyle === CompStyle.Zh_Single_Row_01 && compDTO.imageScale === 2) {
116 LiveHorizontalCardComponent({ compDTO: compDTO }) 38 LiveHorizontalCardComponent({ compDTO: compDTO })
117 } else if (compDTO.compStyle === CompStyle.Zh_Single_Row_01 && compDTO.imageScale === 3) { 39 } else if (compDTO.compStyle === CompStyle.Zh_Single_Row_01 && compDTO.imageScale === 3) {
@@ -120,19 +42,16 @@ export struct CompParser { @@ -120,19 +42,16 @@ export struct CompParser {
120 } else { 42 } else {
121 HorizontalStrokeCardThreeTwoRadioForOneComponent({ compDTO: compDTO }) 43 HorizontalStrokeCardThreeTwoRadioForOneComponent({ compDTO: compDTO })
122 } 44 }
123 - } else if (compDTO.compStyle === CompStyle.Zh_Single_Column_02  
124 - || compDTO.compStyle === '5') {  
125 - HeadPictureCardComponent({ compDTO: compDTO })  
126 - } else if (compDTO.compStyle === CompStyle.ZhGrid_Layout_03) {  
127 - ZhGridLayoutComponent({ compDTO: compDTO })  
128 - } else if (compDTO.compStyle === CompStyle.Album_Card_01) {  
129 - AlbumCardComponent({ compDTO: compDTO }) 45 + } else if (compDTO.compStyle === CompStyle.Zh_Grid_Layout_03) {
  46 + ZhGridLayout03({ compDTO: compDTO })
130 } else if (compDTO.compStyle === CompStyle.Zh_Single_Row_04) { 47 } else if (compDTO.compStyle === CompStyle.Zh_Single_Row_04) {
131 ZhSingleRow04({ compDTO: compDTO}) 48 ZhSingleRow04({ compDTO: compDTO})
132 - } else if (compDTO.compStyle === CompStyle.CompStyle_09) {  
133 - CompStyle_09({ compDTO: compDTO})  
134 - } else if (compDTO.compStyle === CompStyle.CompStyle_10) {  
135 - CompStyle_10({ compDTO: compDTO}) 49 + } else if (compDTO.compStyle === CompStyle.Zh_Single_Column_04) {
  50 + ZhSingleColumn04({ compDTO: compDTO})
  51 + } else if (compDTO.compStyle === CompStyle.Zh_Single_Column_05) {
  52 + ZhSingleColumn05({ compDTO: compDTO})
  53 + } else if (!Number.isNaN(Number(compDTO.compStyle))) {
  54 + CardParser({ contentDTO: compDTO.operDataList[0]});
136 } 55 }
137 else { 56 else {
138 // todo:组件未实现 / Component Not Implemented 57 // todo:组件未实现 / Component Not Implemented
@@ -27,11 +27,13 @@ export struct MultiPictureDetailPageComponent { @@ -27,11 +27,13 @@ export struct MultiPictureDetailPageComponent {
27 private screenWidth: number = 0 27 private screenWidth: number = 0
28 private picWidth: number = 0 28 private picWidth: number = 0
29 @State picHeight: number = 0 29 @State picHeight: number = 0
  30 + @State titleHeight: number = 0
30 @State contentDetailData: ContentDetailDTO = {} as ContentDetailDTO 31 @State contentDetailData: ContentDetailDTO = {} as ContentDetailDTO
31 @Provide @Watch('onCurrentPageNumUpdated') currentPageNum: string = '01' 32 @Provide @Watch('onCurrentPageNumUpdated') currentPageNum: string = '01'
32 private swiperController: SwiperController = new SwiperController() 33 private swiperController: SwiperController = new SwiperController()
33 @State swiperIndex: number = 0; 34 @State swiperIndex: number = 0;
34 @Provide followStatus: string = '0' // 关注状态 35 @Provide followStatus: string = '0' // 关注状态
  36 + private scroller: Scroller = new Scroller()
35 37
36 //watch监听页码回调 38 //watch监听页码回调
37 onCurrentPageNumUpdated(): void { 39 onCurrentPageNumUpdated(): void {
@@ -47,7 +49,8 @@ export struct MultiPictureDetailPageComponent { @@ -47,7 +49,8 @@ export struct MultiPictureDetailPageComponent {
47 this.screenWidth = this.displayTool.width 49 this.screenWidth = this.displayTool.width
48 // this.picWidth = this.screenWidth - vp2px(52) 50 // this.picWidth = this.screenWidth - vp2px(52)
49 this.picWidth = this.screenWidth 51 this.picWidth = this.screenWidth
50 - this.picHeight = this.picWidth * 566 / 378 52 + this.picHeight = this.picWidth * 578 / 375
  53 + this.titleHeight = this.screenWidth * 178 / 375
51 //注册字体 54 //注册字体
52 font.registerFont({ 55 font.registerFont({
53 familyName: 'BebasNeue_Regular', 56 familyName: 'BebasNeue_Regular',
@@ -74,7 +77,7 @@ export struct MultiPictureDetailPageComponent { @@ -74,7 +77,7 @@ export struct MultiPictureDetailPageComponent {
74 } 77 }
75 .index(this.swiperIndex) 78 .index(this.swiperIndex)
76 .width('100%') 79 .width('100%')
77 - .height(px2vp(this.picHeight)) 80 + .height(px2vp(this.picHeight) + 32)
78 .vertical(false) 81 .vertical(false)
79 .autoPlay(false) 82 .autoPlay(false)
80 .cachedCount(3) 83 .cachedCount(3)
@@ -82,7 +85,7 @@ export struct MultiPictureDetailPageComponent { @@ -82,7 +85,7 @@ export struct MultiPictureDetailPageComponent {
82 .displayCount(1) 85 .displayCount(1)
83 .id('e_swiper_content') 86 .id('e_swiper_content')
84 .alignRules({ 87 .alignRules({
85 - top: { anchor: "__container__", align: VerticalAlign.Top }, 88 + center: { anchor: "__container__", align: VerticalAlign.Center },
86 middle: { anchor: "__container__", align: HorizontalAlign.Center } 89 middle: { anchor: "__container__", align: HorizontalAlign.Center }
87 }) 90 })
88 .onChange((index: number) => { 91 .onChange((index: number) => {
@@ -166,50 +169,56 @@ export struct MultiPictureDetailPageComponent { @@ -166,50 +169,56 @@ export struct MultiPictureDetailPageComponent {
166 }) 169 })
167 .id('e_attention') 170 .id('e_attention')
168 } 171 }
  172 + Row(){
  173 + Scroll(this.scroller) {
  174 + Row() {
  175 + Flex({
  176 + direction: FlexDirection.Column,
  177 + justifyContent: FlexAlign.Start
  178 + }) {
  179 + Text() {
  180 + Span(`${this.swiperIndex + 1}`).fontSize(24).fontFamily('PingFang SC-Medium').fontWeight(500).lineHeight(28)
  181 + Span(`/${this.contentDetailData.photoList.length}`).fontSize(14).fontFamily('PingFang SC-Medium').fontWeight(500).lineHeight(19)
  182 + }.fontColor(Color.White).margin(4)
169 183
170 - Row() {  
171 - Flex({  
172 - direction: FlexDirection.Column,  
173 - justifyContent: FlexAlign.Start  
174 - }) {  
175 - Text() {  
176 - Span(`${this.swiperIndex + 1}`).fontSize(24).fontFamily('PingFang SC-Medium').fontWeight(500).lineHeight(28)  
177 - Span(`/${this.contentDetailData.photoList.length}`).fontSize(14).fontFamily('PingFang SC-Medium').fontWeight(500).lineHeight(19)  
178 - }.fontColor(Color.White).margin(4)  
179 -  
180 - Text(`${this.contentDetailData.newsTitle}`).fontColor(Color.White).fontSize(16).fontFamily('PingFang SC-Semibold')  
181 - .fontWeight(600).lineHeight(24)  
182 - .margin ({  
183 - top: 4,  
184 - left: 0,  
185 - bottom: 4,  
186 - right: 0  
187 - })  
188 - Text(`${this.contentDetailData.photoList?.[this.swiperIndex].picDesc}`).fontColor(Color.White)  
189 - .fontSize(14).fontFamily('PingFang SC-Regular').fontWeight(400).lineHeight(22)  
190 - .textOverflow({ overflow: TextOverflow.Ellipsis })  
191 - .margin ({  
192 - top: 4,  
193 - left: 0,  
194 - bottom: 4,  
195 - right: 18  
196 - })  
197 - .maxLines(3) 184 + Text(`${this.contentDetailData.newsTitle}`).fontColor(Color.White).fontSize(16).fontFamily('PingFang SC-Semibold')
  185 + .fontWeight(600).lineHeight(24)
  186 + .margin ({
  187 + top: 4,
  188 + left: 0,
  189 + bottom: 4,
  190 + right: 0
  191 + })
  192 + Text(`${this.contentDetailData.photoList?.[this.swiperIndex].picDesc}`).fontColor(Color.White)
  193 + .fontSize(14).fontFamily('PingFang SC-Regular').fontWeight(400).lineHeight(22)
  194 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  195 + .margin ({
  196 + top: 4,
  197 + left: 0,
  198 + bottom: 4,
  199 + right: 18
  200 + })
  201 + .maxLines(16)
  202 + }
  203 + }
  204 + .width('100%')
  205 + .margin ({
  206 + top: 8,
  207 + left: 18,
  208 + bottom: 24,
  209 + right: 18
  210 + })
198 } 211 }
  212 + .scrollable(ScrollDirection.Vertical)
  213 + .scrollBarWidth(0)
  214 + .height(px2vp(this.titleHeight))
199 } 215 }
200 - .width('100%')  
201 - .height(178)  
202 - .margin ({  
203 - top: 8,  
204 - left: 18,  
205 - bottom: 8,  
206 - right: 18  
207 - })  
208 .id('e_swiper_titles') 216 .id('e_swiper_titles')
209 .alignRules({ 217 .alignRules({
210 - bottom: { anchor: "e_swiper_content", align: VerticalAlign.Bottom },  
211 - middle: { anchor: "e_swiper_content", align: HorizontalAlign.Center } 218 + bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
  219 + middle: { anchor: "__container__", align: HorizontalAlign.Center }
212 }) 220 })
  221 + .height(px2vp(this.titleHeight) + 64)
213 222
214 OperRowListView({ 223 OperRowListView({
215 contentDetailData: this.contentDetailData, 224 contentDetailData: this.contentDetailData,
@@ -218,7 +227,12 @@ export struct MultiPictureDetailPageComponent { @@ -218,7 +227,12 @@ export struct MultiPictureDetailPageComponent {
218 bottom: { anchor: "__container__", align: VerticalAlign.Bottom }, 227 bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
219 middle: { anchor: "__container__", align: HorizontalAlign.Center } 228 middle: { anchor: "__container__", align: HorizontalAlign.Center }
220 }) 229 })
221 - .width('100%').height(56).margin(16) 230 + .width('100%').height(56).margin({
  231 + top: 16,
  232 + left: 16,
  233 + right:16,
  234 + bottom: 0
  235 + })
222 .border({ width: {top: 0.5}, color: '#FFFFFF' }) 236 .border({ width: {top: 0.5}, color: '#FFFFFF' })
223 .id('e_oper_row') 237 .id('e_oper_row')
224 } 238 }
  1 +import { ContentDTO, slideShows } from 'wdBean';
  2 +import { CommonConstants } from 'wdConstant'
  3 +import { DateTimeUtils } from 'wdKit';
  4 +import { ProcessUtils } from '../../utils/ProcessUtils';
  5 +
  6 +
  7 +/**
  8 + * 大专题卡--CompStyle: 10
  9 + */
  10 +const TAG: string = 'Card10Component';
  11 +
  12 +@Component
  13 +export struct Card10Component {
  14 + @State contentDTO: ContentDTO = {} as ContentDTO;
  15 +
  16 + build() {
  17 + Column() {
  18 + // 顶部标题,最多两行
  19 + if (this.contentDTO.newsTitle) {
  20 + Text(this.contentDTO.newsTitle)
  21 + .width(CommonConstants.FULL_WIDTH)
  22 + .fontSize($r('app.float.font_size_17'))
  23 + .fontWeight(600)
  24 + .maxLines(2)
  25 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  26 + .margin({ bottom: 19 })
  27 + }
  28 + // 大图
  29 + Stack() {
  30 + Image(this.contentDTO && this.contentDTO.coverUrl)
  31 + .width('100%')
  32 + .borderRadius({
  33 + topLeft: $r('app.float.image_border_radius'),
  34 + topRight: $r('app.float.image_border_radius')
  35 + })
  36 + .onClick((event: ClickEvent) => {
  37 + ProcessUtils.processPage(this.contentDTO)
  38 + })
  39 + Text('专题')
  40 + .fontSize($r('app.float.font_size_12'))
  41 + .padding({ left: 8, right: 8, top: 3, bottom: 3 })
  42 + .backgroundColor(Color.Red)
  43 + .fontColor(Color.White)
  44 + .borderRadius($r('app.float.button_border_radius'))
  45 + .margin({ left: 5, bottom: 5 })
  46 + }.alignContent(Alignment.BottomStart)
  47 +
  48 + // 专题列表--后端返回三个,
  49 + Column() {
  50 + ForEach(this.contentDTO.slideShows, (item: slideShows, index: number) => {
  51 + this.timelineItem(item, index)
  52 + })
  53 + }
  54 +
  55 + // 底部-查看更多。根据接口返回的isMore判断是否显示查看更多
  56 + if (this.contentDTO.hasMore == 1) {
  57 + Row() {
  58 + Text("查看更多")
  59 + .fontSize($r("app.float.font_size_14"))
  60 + .fontColor($r("app.color.color_222222"))
  61 + .margin({ right: 1 })
  62 + Image($r("app.media.more"))
  63 + .width(14)
  64 + .height(14)
  65 + }
  66 + .backgroundColor($r('app.color.color_F5F5F5'))
  67 + .width(CommonConstants.FULL_WIDTH)
  68 + .height(40)
  69 + .borderRadius($r('app.float.button_border_radius'))
  70 + .justifyContent(FlexAlign.Center)
  71 + .margin({ top: 5 })
  72 + .onClick((event: ClickEvent) => {
  73 + ProcessUtils.processPage(this.contentDTO)
  74 + })
  75 + }
  76 + }
  77 + .width(CommonConstants.FULL_WIDTH)
  78 + .padding({
  79 + top: 14,
  80 + left: 16,
  81 + right: 16,
  82 + bottom: 14
  83 + })
  84 + .backgroundColor($r("app.color.white"))
  85 + .margin({ bottom: 8 })
  86 + }
  87 +
  88 + @Builder
  89 + timelineItem(item: slideShows, index: number) {
  90 + Row() {
  91 + Column() {
  92 + Text(item.newsTitle)
  93 + .fontSize($r('app.float.font_size_17'))
  94 + .fontWeight(400)
  95 + .fontColor($r('app.color.color_222222'))
  96 + .maxLines(2)
  97 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  98 + Row() {
  99 + // 展示发稿人
  100 + if (item.source) {
  101 + Text(item.source)
  102 + .fontSize($r('app.float.font_size_12'))
  103 + .fontColor($r('app.color.color_B0B0B0'))
  104 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  105 + .maxLines(1)
  106 + .width(item.source.length > 10 ? '60%' : '')
  107 +
  108 + Image($r('app.media.point'))
  109 + .width(16)
  110 + .height(16)
  111 + }
  112 + Text(DateTimeUtils.getCommentTime(Number.parseFloat(String(item.publishTime))))
  113 + .fontSize($r("app.float.font_size_12"))
  114 + .fontColor($r("app.color.color_B0B0B0"))
  115 + }
  116 + .margin({ top: 12 })
  117 + }
  118 + .layoutWeight(1)
  119 + .alignItems(HorizontalAlign.Start)
  120 +
  121 + // 右侧图片
  122 + if (item.fullColumnImgUrls[0] && item.fullColumnImgUrls[0].url) {
  123 + Image(item.fullColumnImgUrls[0].url)
  124 + .width(117)
  125 + .height(78)
  126 + .objectFit(ImageFit.Cover)
  127 + .borderRadius($r('app.float.image_border_radius'))
  128 + .margin({ left: 12 })
  129 + }
  130 + }
  131 + .padding({ top: 10, bottom: 10 })
  132 + .onClick((event: ClickEvent) => {
  133 + const str: string = JSON.stringify(this.contentDTO);
  134 + const data: ContentDTO = JSON.parse(str)
  135 + data.objectId = item.newsId
  136 + data.relId = item.relId
  137 + data.objectType = String(item.objectType)
  138 + ProcessUtils.processPage(data)
  139 + })
  140 + }
  141 +}
  1 +//缩略标题
  2 +import { CommonConstants } from 'wdConstant'
  3 +import { ContentDTO } from 'wdBean'
  4 +import { DateTimeUtils } from 'wdKit'
  5 +
  6 +const TAG = 'Card11Component';
  7 +
  8 +/**
  9 + * 无图卡(标题省略)
  10 + */
  11 +@Component
  12 +export struct Card11Component {
  13 + @State contentDTO: ContentDTO = {} as ContentDTO;
  14 +
  15 + build() {
  16 + Column() {
  17 + Text(this.contentDTO.newsTitle)
  18 + .fontSize($r("app.float.font_size_16"))
  19 + .fontColor($r("app.color.color_222222"))
  20 + .maxLines(3)
  21 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  22 + .width(CommonConstants.FULL_WIDTH)
  23 + Row() {
  24 + Text("锐评")
  25 + .fontSize($r("app.float.font_size_12"))
  26 + .fontColor($r("app.color.color_ED2800"))
  27 + Text(this.contentDTO.source)
  28 + .fontSize($r("app.float.font_size_12"))
  29 + .fontColor($r("app.color.color_B0B0B0"))
  30 + .margin({ left: 6 })
  31 + Image($r("app.media.point"))
  32 + .width(16)
  33 + .height(16)
  34 +
  35 + Text(DateTimeUtils.formatDate(Number.parseFloat(this.contentDTO.publishTime)))
  36 + .fontSize($r("app.float.font_size_12"))
  37 + .fontColor($r("app.color.color_B0B0B0"))
  38 +
  39 + }.width(CommonConstants.FULL_WIDTH)
  40 + .justifyContent(FlexAlign.Start)
  41 + .margin({ top: 8 })
  42 +
  43 + }.width(CommonConstants.FULL_WIDTH)
  44 + .padding({
  45 + top: 14,
  46 + left: 16,
  47 + right: 16,
  48 + bottom: 14
  49 + })
  50 + .backgroundColor($r("app.color.white"))
  51 + .margin({ bottom: 8 })
  52 + }
  53 +}
  1 +import { Action, CompDTO, ContentDTO, Params } from 'wdBean';
  2 +import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO';
  3 +import { CommonConstants } from 'wdConstant/Index';
  4 +import { DateTimeUtils } from 'wdKit';
  5 +import { WDRouterRule } from 'wdRouter';
  6 +
  7 +const TAG = 'Card17Component';
  8 +/**
  9 +* 图卡集---2
  10 +*/
  11 +
  12 +@Component
  13 +export struct Card17Component {
  14 + @State compDTO: CompDTO = {} as CompDTO
  15 + @State contentDTO: ContentDTO = {} as ContentDTO;
  16 +
  17 + build() {
  18 + Column({ space: 8 }) {
  19 + Text(this.contentDTO.newsTitle)
  20 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  21 + .fontSize(17)
  22 + .fontColor(0x222222)
  23 + .lineHeight(25)
  24 + .maxLines(3)
  25 + .width(CommonConstants.FULL_WIDTH)
  26 +
  27 + RelativeContainer() {
  28 + Image(this.contentDTO.fullColumnImgUrls[0].url)
  29 + .width('66.6%')
  30 + .aspectRatio(16 / 9)
  31 + .alignRules({
  32 + top: { anchor: "__container__", align: VerticalAlign.Top },
  33 + left: { anchor: "__container__", align: HorizontalAlign.Start }
  34 + })
  35 + .id('mainImage')
  36 +
  37 + Image(this.contentDTO.fullColumnImgUrls[1].url)
  38 + .width('33%')
  39 + .aspectRatio(16 / 9)
  40 + .alignRules({
  41 + top: { anchor: "__container__", align: VerticalAlign.Top },
  42 + right: { anchor: "__container__", align: HorizontalAlign.End }
  43 + })
  44 + .id('subTopImage')
  45 +
  46 + Image(this.contentDTO.fullColumnImgUrls[2].url)
  47 + .width('33%')
  48 + .aspectRatio(16 / 9)
  49 + .alignRules({
  50 + right: { anchor: "__container__", align: HorizontalAlign.End },
  51 + bottom: { anchor: "__container__", align: VerticalAlign.Bottom }
  52 + })
  53 + .id('subBottomImage')
  54 + // 下面是渲染右下角图标
  55 + Shape() {
  56 + Rect().width(33).height(18)
  57 + }
  58 + .fill(0x000000)
  59 + .fillOpacity(0.3)
  60 + .strokeLineCap(LineCapStyle.Round)
  61 + .strokeLineJoin(LineJoinStyle.Round)
  62 + .antiAlias(true)
  63 + .id('shape')
  64 + .alignRules({
  65 + right: { anchor: "__container__", align: HorizontalAlign.End },
  66 + bottom: { anchor: "__container__", align: VerticalAlign.Bottom }
  67 + })
  68 + .margin({
  69 + right: 4,
  70 + bottom: 4
  71 + })
  72 +
  73 + Image($r('app.media.album_card_shape'))
  74 + .width(22)
  75 + .height(18)
  76 + .alignRules({
  77 + left: { anchor: "shape", align: HorizontalAlign.Start },
  78 + top: { anchor: "shape", align: VerticalAlign.Top }
  79 + })
  80 + .id('shapeSubImage')
  81 +
  82 + Text(this.contentDTO.fullColumnImgUrls.length + '')
  83 + .fontSize(13)
  84 + .fontColor(0xFFFFFF)
  85 + .id('pageIndex')
  86 + .alignRules({
  87 + right: { anchor: "shape", align: HorizontalAlign.End },
  88 + top: { anchor: "shape", align: VerticalAlign.Top }
  89 + })
  90 + .margin({ right: 2 })
  91 + .textAlign(TextAlign.Center)
  92 + .width(17)
  93 + .height(17)
  94 + }
  95 + .width(CommonConstants.FULL_WIDTH)
  96 + .aspectRatio(24 / 9)
  97 + .onClick((event: ClickEvent) => {
  98 + let taskAction: Action = {
  99 + type: 'JUMP_DETAIL_PAGE',
  100 + params: {
  101 + detailPageType: 17,
  102 + contentID: this.contentDTO.objectId,
  103 + extra: {
  104 + relType: this.contentDTO.relType,
  105 + relId: `${this.contentDTO.relId}`,
  106 + } as ExtraDTO
  107 + } as Params,
  108 + };
  109 + WDRouterRule.jumpWithAction(taskAction)
  110 + })
  111 +
  112 + Row() {
  113 + if (this.contentDTO.source) {
  114 + Text(this.contentDTO.source)
  115 + .fontSize(13)
  116 + .fontColor(0xB0B0B0)
  117 + Image($r('app.media.point'))
  118 + .width(16)
  119 + .height(16)
  120 + }
  121 + if (this.contentDTO.publishTime && this.contentDTO.publishTime.length === 13) {
  122 + Text(DateTimeUtils.getCommentTime(Number.parseFloat(this.contentDTO.publishTime)))
  123 + .fontSize(13)
  124 + .fontColor(0xB0B0B0)
  125 + }
  126 + Text('328评')
  127 + .fontSize(13)
  128 + .fontColor(0xB0B0B0)
  129 + .margin({
  130 + left: 6
  131 + })
  132 + }
  133 + .width(CommonConstants.FULL_WIDTH)
  134 + .height(16)
  135 + .id('label')
  136 + }
  137 + .width(CommonConstants.FULL_WIDTH)
  138 + .padding({
  139 + top: 14,
  140 + left: 16,
  141 + right: 16,
  142 + bottom: 14
  143 + })
  144 + }
  145 +}
@@ -62,8 +62,8 @@ export struct Card6Component { @@ -62,8 +62,8 @@ export struct Card6Component {
62 Stack() { 62 Stack() {
63 Image(this.contentDTO.coverUrl) 63 Image(this.contentDTO.coverUrl)
64 .borderRadius(5) 64 .borderRadius(5)
65 - .aspectRatio(this.contentDTO.appStyle === CompStyle.Single_ImageCard_03 ? 3 / 2 : 3 / 4)  
66 - .height(this.contentDTO.appStyle === CompStyle.Single_ImageCard_03 ? 90 : 180) 65 + .aspectRatio(this.contentDTO.appStyle === CompStyle.Card_13 ? 3 / 2 : 3 / 4)
  66 + .height(this.contentDTO.appStyle === CompStyle.Card_13 ? 90 : 180)
67 if (this.contentDTO.videoInfo) { 67 if (this.contentDTO.videoInfo) {
68 Row() { 68 Row() {
69 Image($r('app.media.iv_card_play_yellow_flag')) 69 Image($r('app.media.iv_card_play_yellow_flag'))
@@ -111,7 +111,7 @@ export struct Card6Component { @@ -111,7 +111,7 @@ export struct Card6Component {
111 .padding( 111 .padding(
112 { top: 16, bottom: 16, left: 14, right: 14 }) 112 { top: 16, bottom: 16, left: 14, right: 14 })
113 .width(FULL_PARENT) 113 .width(FULL_PARENT)
114 - .height(this.contentDTO.appStyle === CompStyle.Single_ImageCard_03 ? 127 : 217) 114 + .height(this.contentDTO.appStyle === CompStyle.Card_13 ? 127 : 217)
115 .justifyContent(FlexAlign.SpaceBetween) 115 .justifyContent(FlexAlign.SpaceBetween)
116 116
117 } 117 }
  1 +import { ContentDTO, slideShows } from 'wdBean';
  2 +import { CommonConstants } from 'wdConstant'
  3 +import { DateTimeUtils } from 'wdKit';
  4 +import { ProcessUtils } from '../../utils/ProcessUtils';
  5 +
  6 +/**
  7 + * 时间链卡--CompStyle: 09
  8 + */
  9 +const TAG: string = 'Card9Component';
  10 +
  11 +@Component
  12 +export struct Card9Component {
  13 + @State contentDTO: ContentDTO = {} as ContentDTO;
  14 +
  15 + build() {
  16 + Column() {
  17 + // 顶部标题,最多两行
  18 + if (this.contentDTO.newsTitle) {
  19 + Text(this.contentDTO.newsTitle)
  20 + .width(CommonConstants.FULL_WIDTH)
  21 + .fontSize($r('app.float.font_size_17'))
  22 + .fontWeight(600)
  23 + .maxLines(2)
  24 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  25 + .margin({ bottom: 19 })
  26 + }
  27 + // 大图
  28 + Stack() {
  29 + Image(this.contentDTO.coverUrl)
  30 + .width('100%')
  31 + .borderRadius({
  32 + topLeft: $r('app.float.image_border_radius'),
  33 + topRight: $r('app.float.image_border_radius')
  34 + })
  35 + Text('专题')
  36 + .fontSize($r('app.float.font_size_12'))
  37 + .padding({ left: 8, right: 8, top: 3, bottom: 3 })
  38 + .backgroundColor(Color.Red)
  39 + .fontColor(Color.White)
  40 + .borderRadius($r('app.float.button_border_radius'))
  41 + .margin({ left: 5, bottom: 5 })
  42 + }.alignContent(Alignment.BottomStart)
  43 +
  44 + // 时间线--后端返回三个,
  45 + Column() {
  46 + ForEach(this.contentDTO.slideShows, (item: slideShows, index: number) => {
  47 + this.timelineItem(item, index)
  48 + })
  49 + }
  50 +
  51 + // 底部-查看更多。根据接口返回的isMore判断是否显示查看更多
  52 + if (this.contentDTO.hasMore == 1) {
  53 + Row() {
  54 + Text("查看更多")
  55 + .fontSize($r("app.float.font_size_14"))
  56 + .fontColor($r("app.color.color_222222"))
  57 + .margin({ right: 1 })
  58 + Image($r("app.media.more"))
  59 + .width(14)
  60 + .height(14)
  61 + }
  62 + .backgroundColor($r('app.color.color_F5F5F5'))
  63 + .width(CommonConstants.FULL_WIDTH)
  64 + .height(40)
  65 + .borderRadius($r('app.float.button_border_radius'))
  66 + .justifyContent(FlexAlign.Center)
  67 + .margin({ top: 5 })
  68 + }
  69 + }
  70 + .width(CommonConstants.FULL_WIDTH)
  71 + .padding({
  72 + top: 14,
  73 + left: 16,
  74 + right: 16,
  75 + bottom: 14
  76 + })
  77 + .backgroundColor($r("app.color.white"))
  78 + .margin({ bottom: 8 })
  79 + .onClick((event: ClickEvent) => {
  80 + ProcessUtils.processPage(this.contentDTO)
  81 + })
  82 + }
  83 +
  84 + @Builder
  85 + timelineItem(item: slideShows, index: number) {
  86 + Column() {
  87 + Stack() {
  88 + if (index < this.contentDTO.slideShows.length - 1) {
  89 + Divider()
  90 + .vertical(true)
  91 + .color($r('app.color.color_EDEDED'))
  92 + .strokeWidth(1)
  93 + .margin({ top: index > 0 ? 0 : 16, left: 4 })
  94 + }
  95 + if (index > 0 && index == this.contentDTO.slideShows.length - 1) {
  96 + Divider()
  97 + .vertical(true)
  98 + .color($r('app.color.color_EDEDED'))
  99 + .strokeWidth(1)
  100 + .height(16)
  101 + .margin({ left: 4 })
  102 + }
  103 +
  104 + Column() {
  105 + Row() {
  106 + // 标题
  107 + Image($r("app.media.point_icon"))
  108 + .width(9)
  109 + .height(9)
  110 + .margin({ right: 5 })
  111 + Text(DateTimeUtils.formatDate(item.publishTime, "MM月dd日 HH:mm"))
  112 + .fontSize($r('app.float.font_size_12'))
  113 + .fontColor($r('app.color.color_222222'))
  114 + .fontWeight(600)
  115 + }
  116 + .width(CommonConstants.FULL_WIDTH)
  117 + .height(32)
  118 + .alignItems(VerticalAlign.Center)
  119 +
  120 + Row() {
  121 + Text(item.newsTitle)
  122 + .fontSize($r('app.float.font_size_17'))
  123 + .fontWeight(400)
  124 + .fontColor($r('app.color.color_222222'))
  125 + .layoutWeight(1)
  126 + .maxLines(2)
  127 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  128 + .alignSelf(ItemAlign.Center)
  129 + .margin({ left: 12 })
  130 + if (item.fullColumnImgUrls[0] && item.fullColumnImgUrls[0].url) {
  131 + Image(item.fullColumnImgUrls[0].url)
  132 + .width(90)
  133 + .height(60)
  134 + .borderRadius($r('app.float.image_border_radius'))
  135 + }
  136 + }
  137 + }
  138 + }
  139 + .alignContent(Alignment.TopStart)
  140 + }
  141 + .height(item.fullColumnImgUrls[0] && item.fullColumnImgUrls[0].url ? 100 : 78)
  142 + .alignItems(HorizontalAlign.Start)
  143 + }
  144 +}
  1 +import { Action, CompDTO, ContentDTO, Params } from 'wdBean';
  2 +import { CompStyle } from 'wdConstant';
  3 +import { Logger } from 'wdKit';
  4 +import { WDRouterRule } from 'wdRouter';
  5 +import { ProcessUtils } from '../../utils/ProcessUtils';
  6 +
  7 +const TAG = 'Zh_Grid_Layout-03';
  8 +const FULL_PARENT: string = '100%';
  9 +let listSize: number = 4;
  10 +
  11 +/**
  12 + * 金刚卡位
  13 + * 枚举值Zh_Grid_Layout-03
  14 + * Zh_Grid_Layout-03
  15 + *
  16 + */
  17 +@Preview
  18 +@Component
  19 +export struct ZhGridLayout03 {
  20 + @State compDTO: CompDTO = {} as CompDTO
  21 +
  22 + aboutToAppear() {
  23 + if (this.compDTO.operDataList) {
  24 + listSize = this.compDTO.operDataList.length > 5 ? 4 : this.compDTO.operDataList.length;
  25 + }
  26 + }
  27 +
  28 + build() {
  29 + GridRow({
  30 + columns: { sm: listSize, md: 8 },
  31 + breakpoints: { value: ['320vp', '520vp', '840vp'] }
  32 + }) {
  33 + ForEach(this.compDTO.operDataList, (item: ContentDTO, index: number) => {
  34 + GridCol() {
  35 + this.buildItemCard(this.compDTO.operDataList[index]);
  36 + }
  37 + })
  38 + }
  39 + }
  40 +
  41 + /**
  42 + * 组件项
  43 + *
  44 + * @param programmeBean item 组件项, 上面icon,下面标题
  45 + */
  46 + @Builder
  47 + buildItemCard(item: ContentDTO) {
  48 + Column() {
  49 + Image(item.coverUrl)
  50 + .width(44)
  51 + .aspectRatio(1 / 1)
  52 + .margin(16)
  53 + Text(item.newsTitle)
  54 + .fontSize(13)
  55 + .maxLines(1)
  56 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  57 + }
  58 + .width('100%')
  59 + }
  60 +}
  61 +
  62 +
  1 +import { CompDTO, ContentDTO } from 'wdBean';
  2 +import { CommonConstants } from 'wdConstant';
  3 +import { ProcessUtils } from '../../utils/ProcessUtils';
  4 +
  5 +const TAG = 'Zh_Single_Column-04';
  6 +
  7 +/**
  8 + * 人民号主题卡
  9 + * 枚举值 Zh_Single_Column-04
  10 + */
  11 +@Entry
  12 +@Component
  13 +export struct ZhSingleColumn04 {
  14 + @State compDTO: CompDTO = {} as CompDTO
  15 + operDataList: ContentDTO[] = [
  16 + // {newsTitle: "民检普法课堂:正当防卫是什么正当防卫是什么正当防卫是什么正当防卫是什么?", tagWord: 1} as ContentDTO,
  17 + // {newsTitle: "审批站”进菜市场 学才艺有云课堂", tagWord: 2} as ContentDTO,
  18 + ]
  19 +
  20 + aboutToAppear() {
  21 + this.operDataList = this.compDTO.operDataList;
  22 + }
  23 +
  24 + build() {
  25 + Column() {
  26 + Row() {
  27 + Image($r("app.media.redLine"))
  28 + .width(3)
  29 + .height(16)
  30 + .margin({ right: 4 })
  31 + Text(this.compDTO.objectTitle)
  32 + .fontSize($r("app.float.font_size_17"))
  33 + .fontColor($r("app.color.color_222222"))
  34 + .fontWeight(600)
  35 + }
  36 + .width(CommonConstants.FULL_WIDTH)
  37 + .margin({ bottom: 10 })
  38 +
  39 + Column() {
  40 + ForEach(this.operDataList, (item: ContentDTO) => {
  41 + this.rmhThemeItem(item)
  42 + })
  43 + }
  44 + }
  45 + .width(CommonConstants.FULL_WIDTH)
  46 + .padding({
  47 + left: $r('app.float.card_comp_pagePadding_lf'),
  48 + right: $r('app.float.card_comp_pagePadding_lf'),
  49 + top: $r('app.float.card_comp_pagePadding_tb'),
  50 + bottom: $r('app.float.card_comp_pagePadding_tb')
  51 + })
  52 + }
  53 +
  54 + @Builder
  55 + rmhThemeItem(item: ContentDTO) {
  56 + Row() {
  57 + Image($r('app.media.rmh_theme_book_icon'))
  58 + .width(12)
  59 + .margin({ left: 12, right: 8 })
  60 + Text(item.newsTitle)
  61 + .fontSizeColorWeight($r('app.float.font_size_12'), $r('app.color.color_222222'), 400)
  62 + .maxLines(1)
  63 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  64 + .layoutWeight(1)
  65 + if (item.tagWord === 1) {
  66 + Text('热')
  67 + .padding(3)
  68 + .borderRadius(4)
  69 + .fontSizeColorWeight($r('app.float.vp_12'), '#F07E46', 500)
  70 + .backgroundColor('rgba(240, 126, 70, 0.2)')
  71 + .margin({ right: 18 })
  72 + } else if (item.tagWord === 2) {
  73 + Text('新')
  74 + .padding(3)
  75 + .borderRadius(4)
  76 + .fontSizeColorWeight($r('app.float.vp_12'), '#468DF0', 500)
  77 + .backgroundColor('rgba(70, 141, 240, 0.2)')
  78 + .margin({ right: 18 })
  79 + }
  80 + }
  81 + .width(CommonConstants.FULL_WIDTH)
  82 + .height(32)
  83 + .margin({ bottom: 4 })
  84 + .backgroundImage($r('app.media.rmh_theme_bg'))
  85 + .backgroundImageSize({ width: CommonConstants.FULL_WIDTH, height: CommonConstants.FULL_WIDTH })
  86 + .onClick(() => {
  87 + ProcessUtils.processPage(item)
  88 + })
  89 + }
  90 +}
  91 +
  92 +@Extend(Text)
  93 +function fontSizeColorWeight(fontSize: Resource, fontColor: Resource | string,
  94 + fontWeight:
  95 + number) {
  96 + .fontSize(fontSize)
  97 + .fontColor(fontColor)
  98 + .fontWeight(fontWeight)
  99 +}
  100 +
  1 +import { CommonConstants } from 'wdConstant';
  2 +import { Action, CompDTO, Params } from 'wdBean';
  3 +import { WDRouterRule } from 'wdRouter';
  4 +
  5 +const TAG = 'Zh_Single_Column-05';
  6 +
  7 +/**
  8 + * 人民号入住卡
  9 + * 枚举值 Zh_Single_Column-05
  10 + */
  11 +@Entry
  12 +@Component
  13 +export struct ZhSingleColumn05 {
  14 + @State compDTO: CompDTO = {} as CompDTO
  15 +
  16 + build() {
  17 + Row() {
  18 + Image($r('app.media.rmh_join_log'))
  19 + .height(18)
  20 + .margin({ right: 10 })
  21 + Text('快速入住通道')
  22 + Image($r('app.media.arrow_icon_right'))
  23 + .width(16)
  24 + .height(16)
  25 + }
  26 + .width(CommonConstants.FULL_WIDTH)
  27 + .padding({
  28 + left: $r('app.float.card_comp_pagePadding_lf'),
  29 + right: $r('app.float.card_comp_pagePadding_lf'),
  30 + top: $r('app.float.card_comp_pagePadding_tb'),
  31 + bottom: $r('app.float.card_comp_pagePadding_tb')
  32 + })
  33 + .backgroundColor($r('app.color.color_fff'))
  34 + .justifyContent(FlexAlign.Center)
  35 + .onClick(() => {
  36 + let taskAction: Action = {
  37 + type: 'JUMP_H5_BY_WEB_VIEW',
  38 + params: {
  39 + url: this.compDTO.linkUrl
  40 + } as Params,
  41 + };
  42 + WDRouterRule.jumpWithAction(taskAction)
  43 + })
  44 + }
  45 +}
  46 +
  47 +
  1 +import { CompDTO, ContentDTO } from 'wdBean';
  2 +import { CommonConstants } from 'wdConstant';
  3 +import { DateTimeUtils } from 'wdKit';
  4 +import { ProcessUtils } from '../../utils/ProcessUtils';
  5 +
  6 +/**
  7 + * 本地精选卡
  8 + * ZhSingleRow04
  9 + */
  10 +
  11 +@Component
  12 +export struct ZhSingleRow04 {
  13 + @State compDTO: CompDTO = {} as CompDTO
  14 +
  15 + aboutToAppear() {}
  16 +
  17 + build() {
  18 + Column(){
  19 + //顶部
  20 + Row(){
  21 + Row() {
  22 + Image($r("app.media.local_selection"))
  23 + .width(24)
  24 + .height(24)
  25 + .margin({ right: 4 })
  26 + Text(this.compDTO.objectTitle)
  27 + .fontSize($r("app.float.font_size_17"))
  28 + .fontColor($r("app.color.color_222222"))
  29 + .fontWeight(600)
  30 + }
  31 + Row() {
  32 + Text("更多")
  33 + .fontSize($r("app.float.font_size_14"))
  34 + .fontColor($r("app.color.color_999999"))
  35 + .margin({ right: 1 })
  36 + Image($r("app.media.more"))
  37 + .width(14)
  38 + .height(14)
  39 + }
  40 + }
  41 + .justifyContent(FlexAlign.SpaceBetween)
  42 + .margin({ top: 8, bottom: 8 })
  43 + .width('100%')
  44 + // 列表内容
  45 + List({ space: 12 }) {
  46 + ForEach(this.compDTO.operDataList, (item: ContentDTO) => {
  47 + ListItem() {
  48 + Row(){
  49 + if(item.coverUrl) {
  50 + Image(item.coverUrl)
  51 + .width(84)
  52 + .height(56)
  53 + .borderRadius(3)
  54 + .objectFit(ImageFit.Cover)
  55 + .padding({right: 6})
  56 + }
  57 + Column(){
  58 + Text(item.newsTitle)
  59 + .fontSize($r("app.float.font_size_16"))
  60 + .fontColor($r("app.color.color_212228"))
  61 + .fontWeight(400)
  62 + .maxLines(2)
  63 + .textOverflow({ overflow: TextOverflow.Ellipsis })// 超出的部分显示省略号。
  64 + .margin({ top: 8 })
  65 +
  66 + Row(){
  67 + Text(item.source)
  68 + .fontSize($r('app.float.font_size_12'))
  69 + .fontColor($r('app.color.color_B0B0B0'))
  70 + .textOverflow({overflow: TextOverflow.Ellipsis})
  71 + .maxLines(1)
  72 + .width(item.source.length > 10 ? '60%' : '')
  73 + Image($r("app.media.point"))
  74 + .width(16)
  75 + .height(16)
  76 + Text(DateTimeUtils.getCommentTime(Number.parseFloat(this.compDTO.operDataList[0].publishTime)))
  77 + .fontSize($r("app.float.font_size_12"))
  78 + .fontColor($r("app.color.color_B0B0B0"))
  79 + }
  80 + .width('100%')
  81 + }
  82 + .width(200)
  83 + }
  84 + // .margin({right: 18})
  85 + .onClick(() =>{
  86 + ProcessUtils.processPage(item)
  87 + })
  88 + }
  89 + })
  90 + }
  91 + .listDirection(Axis.Horizontal)
  92 + .width('100%')
  93 + }
  94 + .width(CommonConstants.FULL_WIDTH)
  95 + .padding({
  96 + top: 14,
  97 + left: 16,
  98 + right: 16,
  99 + bottom: 14
  100 + })
  101 + .backgroundColor($r("app.color.white"))
  102 + .margin({ bottom: 8 })
  103 + }
  104 +}
@@ -15,7 +15,6 @@ const LOCAL_CHANNEL: string = '地方频道' @@ -15,7 +15,6 @@ const LOCAL_CHANNEL: string = '地方频道'
15 @CustomDialog 15 @CustomDialog
16 struct ChannelDialog { 16 struct ChannelDialog {
17 @State dragItem: number = -1 17 @State dragItem: number = -1
18 - @State item: number = -1  
19 private dragRefOffsetX: number = 0 18 private dragRefOffsetX: number = 0
20 private dragRefOffsetY: number = 0 19 private dragRefOffsetY: number = 0
21 @State offsetX: number = 0 20 @State offsetX: number = 0
@@ -235,7 +234,7 @@ struct ChannelDialog { @@ -235,7 +234,7 @@ struct ChannelDialog {
235 .alignContent(Alignment.Start) 234 .alignContent(Alignment.Start)
236 .height(36) 235 .height(36)
237 .onClick(() => { 236 .onClick(() => {
238 - AppStorage.set('indexSettingChannelId',item.channelId) 237 + AppStorage.set('indexSettingChannelId', item.channelId)
239 }) 238 })
240 }) 239 })
241 } 240 }
@@ -308,6 +307,7 @@ struct ChannelDialog { @@ -308,6 +307,7 @@ struct ChannelDialog {
308 }) 307 })
309 .zIndex(this.dragItem == item.num ? 1 : 0) 308 .zIndex(this.dragItem == item.num ? 1 : 0)
310 .translate(this.dragItem == item.num ? { x: this.offsetX, y: this.offsetY } : { x: 0, y: 0 }) 309 .translate(this.dragItem == item.num ? { x: this.offsetX, y: this.offsetY } : { x: 0, y: 0 })
  310 +
311 .gesture( 311 .gesture(
312 GestureGroup(GestureMode.Sequence, 312 GestureGroup(GestureMode.Sequence,
313 PanGesture({ fingers: 1, direction: null, distance: 0 }) 313 PanGesture({ fingers: 1, direction: null, distance: 0 })
@@ -324,12 +324,20 @@ struct ChannelDialog { @@ -324,12 +324,20 @@ struct ChannelDialog {
324 .onActionEnd((event: GestureEvent) => { 324 .onActionEnd((event: GestureEvent) => {
325 animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => { 325 animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
326 this.dragItem = -1 326 this.dragItem = -1
  327 + this.offsetX = 0
  328 + this.offsetY = 0
  329 + this.dragRefOffsetX = 0
  330 + this.dragRefOffsetY = 0
327 }) 331 })
328 }) 332 })
329 ) 333 )
330 .onCancel(() => { 334 .onCancel(() => {
331 animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => { 335 animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
332 this.dragItem = -1 336 this.dragItem = -1
  337 + this.offsetX = 0
  338 + this.offsetY = 0
  339 + this.dragRefOffsetX = 0
  340 + this.dragRefOffsetY = 0
333 }) 341 })
334 })) 342 }))
335 343
1 import { CommonConstants, ViewType } from 'wdConstant'; 1 import { CommonConstants, ViewType } from 'wdConstant';
2 -import { Logger } from 'wdKit'; 2 +import { Logger, DateTimeUtils } from 'wdKit';
3 import PageViewModel from '../../viewmodel/PageViewModel'; 3 import PageViewModel from '../../viewmodel/PageViewModel';
4 import { EmptyComponent } from '../view/EmptyComponent'; 4 import { EmptyComponent } from '../view/EmptyComponent';
5 import { ErrorComponent } from '../view/ErrorComponent'; 5 import { ErrorComponent } from '../view/ErrorComponent';
@@ -48,7 +48,8 @@ export struct PageComponent { @@ -48,7 +48,8 @@ export struct PageComponent {
48 48
49 } 49 }
50 50
51 - @Builder ListLayout() { 51 + @Builder
  52 + ListLayout() {
52 List() { 53 List() {
53 // 下拉刷新 54 // 下拉刷新
54 ListItem() { 55 ListItem() {
@@ -64,7 +65,9 @@ export struct PageComponent { @@ -64,7 +65,9 @@ export struct PageComponent {
64 CompParser({ compDTO: compDTO, compIndex: compIndex }); 65 CompParser({ compDTO: compDTO, compIndex: compIndex });
65 } 66 }
66 } 67 }
67 - }) 68 + },
  69 + (compDTO: CompDTO, compIndex: number) => compDTO.id + compIndex.toString() + this.pageModel.timestamp
  70 + )
68 71
69 // 加载更多 72 // 加载更多
70 ListItem() { 73 ListItem() {
@@ -79,7 +82,7 @@ export struct PageComponent { @@ -79,7 +82,7 @@ export struct PageComponent {
79 } 82 }
80 } 83 }
81 .scrollBar(BarState.Off) 84 .scrollBar(BarState.Off)
82 - .cachedCount(5) 85 + .cachedCount(8)
83 .height(CommonConstants.FULL_PARENT) 86 .height(CommonConstants.FULL_PARENT)
84 .onScrollIndex((start: number, end: number) => { 87 .onScrollIndex((start: number, end: number) => {
85 // Listen to the first index of the current list. 88 // Listen to the first index of the current list.
@@ -89,7 +92,8 @@ export struct PageComponent { @@ -89,7 +92,8 @@ export struct PageComponent {
89 }) 92 })
90 } 93 }
91 94
92 - @Builder LoadingLayout() { 95 + @Builder
  96 + LoadingLayout() {
93 CustomRefreshLoadLayout({ refreshBean: new RefreshLayoutBean(true, 97 CustomRefreshLoadLayout({ refreshBean: new RefreshLayoutBean(true,
94 $r('app.media.ic_pull_up_load'), $r('app.string.pull_up_load_text'), this.pageModel.pullDownRefreshHeight) }) 98 $r('app.media.ic_pull_up_load'), $r('app.string.pull_up_load_text'), this.pageModel.pullDownRefreshHeight) })
95 } 99 }
@@ -116,6 +120,7 @@ export struct PageComponent { @@ -116,6 +120,7 @@ export struct PageComponent {
116 this.pageModel.currentPage = 1; 120 this.pageModel.currentPage = 1;
117 let pageDto = await PageViewModel.getPageData(this.pageModel.pageId, this.pageModel.pageId, this.pageModel.channelId 121 let pageDto = await PageViewModel.getPageData(this.pageModel.pageId, this.pageModel.pageId, this.pageModel.channelId
118 , this.pageModel.currentPage, this.pageModel.pageSize, getContext(this)) 122 , this.pageModel.currentPage, this.pageModel.pageSize, getContext(this))
  123 + this.pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
119 if (pageDto && pageDto.compList && pageDto.compList.length > 0) { 124 if (pageDto && pageDto.compList && pageDto.compList.length > 0) {
120 this.pageModel.viewType = ViewType.LOADED; 125 this.pageModel.viewType = ViewType.LOADED;
121 this.pageModel.compList.push(...pageDto.compList) 126 this.pageModel.compList.push(...pageDto.compList)
@@ -125,6 +130,12 @@ export struct PageComponent { @@ -125,6 +130,12 @@ export struct PageComponent {
125 } else { 130 } else {
126 this.pageModel.hasMore = false; 131 this.pageModel.hasMore = false;
127 } 132 }
  133 + // 二次请求,批查互动数据
  134 + PageViewModel.getInteractData(pageDto.compList).then((data: CompDTO[]) => {
  135 + // 刷新,替换所有数据
  136 + this.pageModel.compList.replaceAll(...data)
  137 + this.pageModel.timestamp = DateTimeUtils.getTimeStamp().toString()
  138 + })
128 } else { 139 } else {
129 Logger.debug(TAG, 'aboutToAppear, data response page ' + this.pageId + ', comp list is empty.'); 140 Logger.debug(TAG, 'aboutToAppear, data response page ' + this.pageId + ', comp list is empty.');
130 this.pageModel.viewType = ViewType.EMPTY; 141 this.pageModel.viewType = ViewType.EMPTY;
@@ -134,6 +134,15 @@ export struct TopNavigationComponent { @@ -134,6 +134,15 @@ export struct TopNavigationComponent {
134 }; 134 };
135 WDRouterRule.jumpWithAction(taskAction) 135 WDRouterRule.jumpWithAction(taskAction)
136 } 136 }
  137 + jumpToLiveDetailsPaper() {
  138 + let taskAction: Action = {
  139 + type: 'JUMP_INNER_NEW_PAGE',
  140 + params: {
  141 + pageID: 'LIVE_DETAILS_PAGER'
  142 + } as Params,
  143 + };
  144 + WDRouterRule.jumpWithAction(taskAction)
  145 + }
137 146
138 build() { 147 build() {
139 Column() { 148 Column() {
@@ -146,7 +155,8 @@ export struct TopNavigationComponent { @@ -146,7 +155,8 @@ export struct TopNavigationComponent {
146 .width(72) 155 .width(72)
147 .height(29) 156 .height(29)
148 .onClick((event: ClickEvent) => { 157 .onClick((event: ClickEvent) => {
149 - this.jumpToENewPaper() 158 + this.jumpToLiveDetailsPaper()
  159 + // this.jumpToENewPaper()
150 }) 160 })
151 161
152 Stack({ alignContent: Alignment.Center }) { 162 Stack({ alignContent: Alignment.Center }) {
1 -import { MineAppointmentItem } from '../../viewmodel/MineAppointmentItem'  
2 -  
3 @CustomDialog 1 @CustomDialog
4 export struct MyCustomDialog { 2 export struct MyCustomDialog {
5 @State title: string = "标题" 3 @State title: string = "标题"
  4 + @State titleShow: boolean = true
6 @State tipValue: string ="提示文字" 5 @State tipValue: string ="提示文字"
  6 + @State tipShow: boolean = true
7 7
8 @State leftText: string = "取消" 8 @State leftText: string = "取消"
9 @State rightText: string = "确认" 9 @State rightText: string = "确认"
@@ -16,16 +16,21 @@ export struct MyCustomDialog { @@ -16,16 +16,21 @@ export struct MyCustomDialog {
16 16
17 build() { 17 build() {
18 Column() { 18 Column() {
19 - Text(this.title)  
20 - .fontSize("32lpx")  
21 - .margin({ top: "40lpx", bottom: "15lpx" })  
22 - .fontColor($r('app.color.color_333333'))  
23 - .fontSize('35lpx')  
24 - .fontWeight('600lpx')  
25 - Text(this.tipValue)  
26 - .margin({ bottom: "30lpx" })  
27 - .fontSize("27lpx")  
28 - .fontColor($r('app.color.color_B0B0B0')) 19 + if(this.titleShow){
  20 + Text(this.title)
  21 + .fontSize("32lpx")
  22 + .margin({ top: "40lpx", bottom: "15lpx" })
  23 + .fontColor($r('app.color.color_333333'))
  24 + .fontSize('35lpx')
  25 + .fontWeight('600lpx')
  26 + }
  27 +
  28 + if(this.tipShow){
  29 + Text(this.tipValue)
  30 + .margin({ bottom: "30lpx" })
  31 + .fontSize("27lpx")
  32 + .fontColor($r('app.color.color_B0B0B0'))
  33 + }
29 34
30 Divider() 35 Divider()
31 .width("100%") 36 .width("100%")
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 * 方案一 使用动画 + 定时器 4 * 方案一 使用动画 + 定时器
5 * 方案二 使用容器组件Swiper(当前) 5 * 方案二 使用容器组件Swiper(当前)
6 */ 6 */
  7 +import { WDRouterPage, WDRouterRule } from 'wdRouter'
7 import SearcherAboutDataModel from '../../model/SearcherAboutDataModel' 8 import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
8 9
9 const TAG = "FirstTabTopSearchComponent" 10 const TAG = "FirstTabTopSearchComponent"
@@ -56,6 +57,9 @@ export struct FirstTabTopSearchComponent{ @@ -56,6 +57,9 @@ export struct FirstTabTopSearchComponent{
56 .padding({left:15}) 57 .padding({left:15})
57 .backgroundImage($r('app.media.background_search')) 58 .backgroundImage($r('app.media.background_search'))
58 .backgroundImageSize(ImageSize.Cover) 59 .backgroundImageSize(ImageSize.Cover)
  60 + .onClick(()=>{
  61 + WDRouterRule.jumpWithPage(WDRouterPage.searchPage)
  62 + })
59 } 63 }
60 64
61 } 65 }
  1 +import router from '@ohos.router'
  2 +import { StringUtils, ToastUtils } from 'wdKit'
  3 +import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
  4 +import { SearchHistoryItem } from '../../viewmodel/SearchHistoryItem'
  5 +import { SearchHistoryComponent } from './SearchHistoryComponent'
  6 +import { SearchHotsComponent } from './SearchHotsComponent'
  7 +
  8 +const TAG = "SearchComponent"
  9 +
  10 +@Component
  11 +export struct SearchComponent {
  12 + @State searchTextData: string[] = []
  13 + @State hasInputContent: boolean = false
  14 + @State hasChooseSearch: boolean = false
  15 + private swiperController: SwiperController = new SwiperController()
  16 + @State searchText: string = ''
  17 + controller: TextInputController = new TextInputController()
  18 + @State searchHistoryData: SearchHistoryItem[] = []
  19 + scroller: Scroller = new Scroller()
  20 +
  21 + aboutToAppear() {
  22 + //获取提示滚动
  23 + this.getSearchHint()
  24 + //获取搜索历史
  25 + this.getSearchHistoryData()
  26 + }
  27 +
  28 +
  29 +
  30 + getSearchHint() {
  31 + SearcherAboutDataModel.getSearchHintData(getContext(this)).then((value) => {
  32 + if (value != null) {
  33 + this.searchTextData = value
  34 + }
  35 + }).catch((err: Error) => {
  36 + console.log(TAG, JSON.stringify(err))
  37 + })
  38 + }
  39 +
  40 + getSearchHistoryData() {
  41 + this.searchHistoryData = SearcherAboutDataModel.getSearchHistoryData()
  42 + }
  43 +
  44 + build() {
  45 + Column() {
  46 + this.searchInputComponent()
  47 + if (!this.hasInputContent) {
  48 + Scroll(this.scroller) {
  49 + Column() {
  50 + if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
  51 + SearchHistoryComponent({ searchHistoryData: $searchHistoryData, onDelHistory: (): void => this.getSearchHistoryData() })
  52 + }
  53 +
  54 + //分隔符
  55 + Divider()
  56 + .width('100%')
  57 + .height('1lpx')
  58 + .color($r('app.color.color_EDEDED'))
  59 + .strokeWidth('1lpx')
  60 +
  61 + SearchHotsComponent()
  62 + }
  63 + }
  64 + .scrollable(ScrollDirection.Vertical)
  65 + .scrollBar(BarState.Off)
  66 + .width('100%')
  67 + .height('100%')
  68 + .padding({ left: '31lpx', right: '31lpx' })
  69 + } else {
  70 + if (this.hasChooseSearch) {
  71 + //搜索结果
  72 +
  73 + //搜索结果为null(空布局 + 为你推荐)
  74 + } else {
  75 + //联想搜索
  76 + }
  77 + }
  78 + }.height('100%')
  79 + .width('100%')
  80 + }
  81 +
  82 + //搜索框
  83 + @Builder searchInputComponent() {
  84 + Row() {
  85 + //左
  86 + Stack({ alignContent: Alignment.Start }) {
  87 + if (this.searchTextData != null && this.searchTextData.length > 0 && !this.hasInputContent) {
  88 + Swiper(this.swiperController) {
  89 + ForEach(this.searchTextData, (item: string, index: number) => {
  90 + Text(item)
  91 + .fontWeight('400lpx')
  92 + .fontSize('25lpx')
  93 + .fontColor($r('app.color.color_666666'))
  94 + .lineHeight('35lpx')
  95 + .textAlign(TextAlign.Start)
  96 + .maxLines(1)
  97 + .textOverflow({ overflow: TextOverflow.Clip })
  98 + .margin({ left: '40lpx' })
  99 + })
  100 + }
  101 + .loop(true)
  102 + .autoPlay(true)
  103 + .interval(3000)
  104 + .indicator(false)
  105 + .vertical(true)
  106 + .enabled(false)
  107 + .focusable(false)
  108 + }
  109 + Row(){
  110 + TextInput({ text: this.searchText, placeholder: '', controller: this.controller })
  111 + .caretColor(Color.Pink)
  112 + .fontSize('27lpx')
  113 + .layoutWeight(1)
  114 + .fontColor(Color.Black)
  115 + .onChange((value: string) => {
  116 + this.searchText = value
  117 + if (this.searchText.length > 0) {
  118 + this.hasInputContent = true
  119 + } else {
  120 + this.hasInputContent = false
  121 + }
  122 + })
  123 + .backgroundColor($r('app.color.color_transparent'))
  124 + .defaultFocus(true)
  125 + if(this.hasInputContent){
  126 + Image($r('app.media.search_input_del_icon'))
  127 + .width('31lpx')
  128 + .height('31lpx')
  129 + .objectFit(ImageFit.Cover)
  130 + .interpolation(ImageInterpolation.High)
  131 + .onClick(()=>{
  132 + this.searchText = ""
  133 + this.hasInputContent = false
  134 + })
  135 + }
  136 + }.padding({right:'30lpx'})
  137 + .layoutWeight(1)
  138 + }
  139 + .backgroundImage($r('app.media.search_page_input_bg'))
  140 + .backgroundImageSize(ImageSize.Cover)
  141 + .layoutWeight(1)
  142 + .height('69lpx')
  143 +
  144 + //TODO 需要修改输入法 换行
  145 + //右
  146 + Text(this.hasInputContent?"搜索":"取消")
  147 + .textAlign(TextAlign.Center)
  148 + .fontWeight('400lpx')
  149 + .fontSize('31lpx')
  150 + .lineHeight('58lpx')
  151 + .fontColor($r('app.color.color_222222'))
  152 + .width('125lpx')
  153 + .height('58lpx')
  154 + .onClick(() => {
  155 + if(this.hasInputContent){
  156 + if(StringUtils.isNotEmpty(this.searchText)){
  157 + SearcherAboutDataModel.putSearchHistoryData(this.searchText)
  158 + this.getSearchHistoryData()
  159 + ToastUtils.shortToast("插入一条搜索记录")
  160 + }
  161 + }else{
  162 + router.back()
  163 + }
  164 + })
  165 + }
  166 + .height('85lpx')
  167 + .padding({ left: '31lpx' })
  168 + .alignItems(VerticalAlign.Center)
  169 + .margin({ bottom: '36lpx' })
  170 + }
  171 +}
  1 +import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
  2 +import { SearchHistoryItem } from '../../viewmodel/SearchHistoryItem'
  3 +import { MyCustomDialog } from '../reusable/MyCustomDialog'
  4 +
  5 +/**
  6 + * 搜索历史
  7 + */
  8 +@Component
  9 +export struct SearchHistoryComponent{
  10 + @Link searchHistoryData:SearchHistoryItem[]
  11 + onDelHistory?: () => void;
  12 + dialogController: CustomDialogController = new CustomDialogController({
  13 + builder: MyCustomDialog({
  14 + cancel: this.onCancel,
  15 + confirm: () => {
  16 + this.onAccept()
  17 + },
  18 + title: "确认清空历史记录",
  19 + tipShow:false
  20 + }),
  21 + autoCancel: true,
  22 + alignment: DialogAlignment.Center,
  23 + offset: { dx: 0, dy: -20 },
  24 + gridCount: 4,
  25 + customStyle: false
  26 + })
  27 +
  28 + onAccept(){
  29 + console.info('Callback when the second button is clicked')
  30 + //清空记录
  31 + this.searchHistoryData = []
  32 + SearcherAboutDataModel.delSearchHistoryData()
  33 + }
  34 +
  35 + onCancel() {
  36 + console.info('Callback when the first button is clicked')
  37 + }
  38 +
  39 + build(){
  40 + Column(){
  41 + Row(){
  42 + Text("搜索历史")
  43 + .textAlign(TextAlign.Center)
  44 + .fontWeight('400lpx')
  45 + .fontSize('27lpx')
  46 + .lineHeight('38lpx')
  47 + .fontColor($r('app.color.color_999999'))
  48 + .height('38lpx')
  49 +
  50 + Image($r('app.media.search_delete_icon'))
  51 + .height('31lpx')
  52 + .width('31lpx')
  53 + .interpolation(ImageInterpolation.High)
  54 + .objectFit(ImageFit.Cover)
  55 + .onClick(()=>{
  56 + //弹框提示
  57 + this.dialogController.open()
  58 + })
  59 + }.justifyContent(FlexAlign.SpaceBetween)
  60 + .margin({bottom:'17lpx'})
  61 + .width('100%')
  62 +
  63 + Grid(){
  64 + ForEach(this.searchHistoryData,(item:SearchHistoryItem,index:number)=>{
  65 + GridItem(){
  66 + Row(){
  67 + Text(`${item.searchContent}`)
  68 + .fontColor($r('app.color.color_222222'))
  69 + .fontSize('31lpx')
  70 + .fontWeight('400lpx')
  71 + .lineHeight('46lpx')
  72 + .maxLines(1)
  73 + .constraintSize({maxWidth:index%2 === 0?'270lpx':'250lpx'})
  74 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  75 + .textAlign(TextAlign.Start)
  76 +
  77 + Image($r('app.media.search_item_delete_icon'))
  78 + .width('46lpx')
  79 + .height('46lpx')
  80 + .margin({right:'31lpx',left:'4lpx'})
  81 + .interpolation(ImageInterpolation.High)
  82 + .objectFit(ImageFit.Cover)
  83 + .onClick(()=>{
  84 + SearcherAboutDataModel.delSearchSingleHistoryData(index)
  85 + if (this.onDelHistory !== undefined) {
  86 + this.onDelHistory()
  87 + }
  88 + })
  89 +
  90 + Blank()
  91 +
  92 + if(index%2 === 0 && index != this.searchHistoryData.length-1 ){
  93 + Divider()
  94 + .width('2lpx')
  95 + .height('23lpx')
  96 + .color($r('app.color.color_CCCCCC'))
  97 + .strokeWidth('2lpx')
  98 + .vertical(true)
  99 + }
  100 + }.height('100%')
  101 + .alignItems(VerticalAlign.Center)
  102 + .width('100%')
  103 + .margin({left:index%2 === 1?'23lpx':'0lpx'})
  104 + }.onClick(()=>{
  105 + })
  106 + .height('46lpx')
  107 + })
  108 + }
  109 + .height(this.getCategoryViewHeight())
  110 + .rowsTemplate(this.getCategoryRowTmpl())
  111 + .columnsTemplate('1fr 1fr')
  112 + .rowsGap('23lpx')
  113 + }
  114 + .margin({bottom:'46lpx'})
  115 + }
  116 +
  117 + getCategoryRowCount() {
  118 + return Math.ceil(this.searchHistoryData.length / 2);
  119 + }
  120 +
  121 + getCategoryRowTmpl() {
  122 + const count = this.getCategoryRowCount();
  123 + const arr: string[] = new Array(count || 1).fill('1fr');
  124 + console.log('tmpl ', arr.join(' '))
  125 + return arr.join(' ');
  126 + }
  127 +
  128 + getCategoryViewHeight() {
  129 + return `${46 * this.getCategoryRowCount()}lpx`;
  130 + }
  131 +}
  1 +import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
  2 +import { SearchHotContentItem } from '../../viewmodel/SearchHotContentItem'
  3 +
  4 +const TAG = "SearchHotsComponent"
  5 +
  6 +/**
  7 + * 热门搜索
  8 + */
  9 +@Component
  10 +export struct SearchHotsComponent{
  11 + @State searchHotsData:SearchHotContentItem[] = []
  12 +
  13 + aboutToAppear(){
  14 + //获取搜索热词
  15 + this.getSearchHotsData()
  16 + }
  17 +
  18 + getSearchHotsData(){
  19 + SearcherAboutDataModel.getSearchHotsData(getContext(this)).then((value)=>{
  20 + if(value!=null){
  21 + this.searchHotsData = value
  22 + }
  23 + }).catch((err:Error)=>{
  24 + console.log(TAG,JSON.stringify(err))
  25 + })
  26 + }
  27 +
  28 + build(){
  29 + Column(){
  30 + Row() {
  31 + Image($r('app.media.search_hot_icon'))
  32 + .width('46lpx')
  33 + .height('46lpx')
  34 + .objectFit(ImageFit.Auto)
  35 + .margin({right:'8lpx'})
  36 + .interpolation(ImageInterpolation.Medium)
  37 +
  38 + Text("热门搜索")
  39 + .textAlign(TextAlign.Center)
  40 + .fontWeight('600lpx')
  41 + .fontSize('33lpx')
  42 + .lineHeight('46lpx')
  43 + .fontColor($r('app.color.color_222222'))
  44 + .height('38lpx')
  45 + }
  46 + .width('100%')
  47 +
  48 + List(){
  49 + ForEach(this.searchHotsData,(item:SearchHotContentItem,index:number)=>{
  50 + ListItem(){
  51 + Column(){
  52 + Column(){
  53 + Row(){
  54 + Row(){
  55 + if(item.sequence <=3){
  56 + Image(item.sequence===1?$r('app.media.search_hot_num1'):item.sequence===2?$r('app.media.search_hot_num2'):$r('app.media.search_hot_num3'))
  57 + .width('27lpx')
  58 + .height('35lpx')
  59 + .objectFit(ImageFit.Auto)
  60 + .margin({right:'12lpx'})
  61 + .interpolation(ImageInterpolation.High)
  62 + }else {
  63 + Text(`${item.sequence}`)
  64 + .height('31lpx')
  65 + .fontColor($r('app.color.color_666666'))
  66 + .fontSize('27lpx')
  67 + .fontWeight('400lpx')
  68 + .lineHeight('31lpx')
  69 + .margin({right:'12lpx'})
  70 + }
  71 + Text(`${item.hotEntry}`)
  72 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  73 + .fontColor($r('app.color.color_222222'))
  74 + .fontSize('31lpx')
  75 + .maxLines(1)
  76 + .fontWeight('400lpx')
  77 + .lineHeight('42lpx')
  78 + }.layoutWeight(1)
  79 + if(item.mark!=0){
  80 + Image(item.mark===1?$r('app.media.search_hots_mark1'):$r('app.media.search_hots_mark2'))
  81 + .width('42lpx')
  82 + .height('31lpx')
  83 + .objectFit(ImageFit.Auto)
  84 + .interpolation(ImageInterpolation.High)
  85 + }
  86 + }.alignItems(VerticalAlign.Center)
  87 + .height('84lpx')
  88 + .justifyContent(FlexAlign.SpaceBetween)
  89 +
  90 + if(index != this.searchHotsData.length-1 ){
  91 + Divider()
  92 + .width('100%')
  93 + .height('1lpx')
  94 + .color($r('app.color.color_F5F5F5'))
  95 + .strokeWidth('1lpx')
  96 + }
  97 + }.height('108lpx')
  98 + .justifyContent(FlexAlign.Center)
  99 + .alignItems(HorizontalAlign.Start)
  100 + .padding({left:'27lpx'})
  101 + }
  102 + }
  103 + .onClick(()=>{
  104 + })
  105 + .height('117lpx')
  106 + })
  107 + }.onScrollFrameBegin((offset, state) => {
  108 + return { offsetRemain: 0 }
  109 + }).layoutWeight(1)
  110 + }.width('100%')
  111 + .height('100%')
  112 + .margin({top:'46lpx'})
  113 + }
  114 +}
@@ -32,7 +32,8 @@ export struct BigPicCardComponent { @@ -32,7 +32,8 @@ export struct BigPicCardComponent {
32 @Builder 32 @Builder
33 originalBuild() { 33 originalBuild() {
34 Column() { 34 Column() {
35 - 35 + // TODO 测试代码
  36 + // Text("likeNum " + this.contentDTO?.interactData?.likeNum)
36 Column() { 37 Column() {
37 //新闻标题 38 //新闻标题
38 Text(this.compDTO.operDataList[0].newsTitle) 39 Text(this.compDTO.operDataList[0].newsTitle)
@@ -73,8 +73,8 @@ export struct SingleImageCardComponent { @@ -73,8 +73,8 @@ export struct SingleImageCardComponent {
73 Stack() { 73 Stack() {
74 Image(this.compDTO.operDataList[0].coverUrl) 74 Image(this.compDTO.operDataList[0].coverUrl)
75 .borderRadius(5) 75 .borderRadius(5)
76 - .aspectRatio(this.compDTO.compStyle === CompStyle.Single_ImageCard_03 ? 3 / 2 : 3 / 4)  
77 - .height(this.compDTO.compStyle === CompStyle.Single_ImageCard_03 ? 90 : 180) 76 + .aspectRatio(this.compDTO.compStyle === CompStyle.Card_13 ? 3 / 2 : 3 / 4)
  77 + .height(this.compDTO.compStyle === CompStyle.Card_13 ? 90 : 180)
78 if (this.compDTO.operDataList[0].videoInfo) { 78 if (this.compDTO.operDataList[0].videoInfo) {
79 Row() { 79 Row() {
80 Image($r('app.media.iv_card_play_yellow_flag')) 80 Image($r('app.media.iv_card_play_yellow_flag'))
@@ -122,7 +122,7 @@ export struct SingleImageCardComponent { @@ -122,7 +122,7 @@ export struct SingleImageCardComponent {
122 .padding( 122 .padding(
123 { top: 16, bottom: 16, left: 14, right: 14 }) 123 { top: 16, bottom: 16, left: 14, right: 14 })
124 .width(FULL_PARENT) 124 .width(FULL_PARENT)
125 - .height(this.compDTO.compStyle === CompStyle.Single_ImageCard_03 ? 127 : 217) 125 + .height(this.compDTO.compStyle === CompStyle.Card_13 ? 127 : 217)
126 .justifyContent(FlexAlign.SpaceBetween) 126 .justifyContent(FlexAlign.SpaceBetween)
127 } 127 }
128 } 128 }
1 1
2 -import { Logger, ResourcesUtils } from 'wdKit'; 2 +import { Logger, ResourcesUtils, SPHelper, UserDataLocal } from 'wdKit';
3 import { HttpUrlUtils, ResponseDTO, WDHttp } from 'wdNetwork'; 3 import { HttpUrlUtils, ResponseDTO, WDHttp } from 'wdNetwork';
4 import HashMap from '@ohos.util.HashMap'; 4 import HashMap from '@ohos.util.HashMap';
  5 +import { SearchHistoryItem } from '../viewmodel/SearchHistoryItem';
  6 +import { SearchHotContentItem } from '../viewmodel/SearchHotContentItem';
  7 +
5 const TAG = "SearcherAboutDataModel" 8 const TAG = "SearcherAboutDataModel"
6 9
7 /** 10 /**
@@ -9,6 +12,8 @@ const TAG = "SearcherAboutDataModel" @@ -9,6 +12,8 @@ const TAG = "SearcherAboutDataModel"
9 */ 12 */
10 class SearcherAboutDataModel{ 13 class SearcherAboutDataModel{
11 private static instance: SearcherAboutDataModel; 14 private static instance: SearcherAboutDataModel;
  15 + public searchHistoryData:SearchHistoryItem[] = []
  16 + public SEARCH_HISTORY_KEY:string = "SEARCH_HISTORY_KEY" + UserDataLocal.userId
12 17
13 private constructor() { } 18 private constructor() { }
14 19
@@ -24,6 +29,57 @@ class SearcherAboutDataModel{ @@ -24,6 +29,57 @@ class SearcherAboutDataModel{
24 } 29 }
25 30
26 /** 31 /**
  32 + * 插入搜索记录(单个)
  33 + */
  34 + public async putSearchHistoryData(content:string){
  35 + let history = SPHelper.default.getSync(this.SEARCH_HISTORY_KEY,"[]") as string
  36 + this.searchHistoryData = JSON.parse(history)
  37 + this.searchHistoryData.splice(0,0,new SearchHistoryItem(content))
  38 + await SPHelper.default.saveSync(this.SEARCH_HISTORY_KEY, JSON.stringify(this.searchHistoryData));
  39 + }
  40 +
  41 + /**
  42 + * 删除搜索记录(所有)
  43 + */
  44 + public async delSearchHistoryData(){
  45 + SPHelper.default.deleteSync(this.SEARCH_HISTORY_KEY)
  46 + this.searchHistoryData = []
  47 + }
  48 + /**
  49 + * 删除搜索记录(单个)
  50 + */
  51 + public async delSearchSingleHistoryData(index:number){
  52 + if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
  53 + this.searchHistoryData.splice(index,1)
  54 + }else{
  55 + let history = SPHelper.default.getSync(this.SEARCH_HISTORY_KEY,"[]") as string
  56 + this.searchHistoryData = JSON.parse(history)
  57 + this.searchHistoryData.splice(index,1)
  58 + }
  59 + SPHelper.default.saveSync(this.SEARCH_HISTORY_KEY, JSON.stringify(this.searchHistoryData))
  60 + }
  61 +
  62 + /**
  63 + * 查询搜索记录(所有)
  64 + */
  65 + public getSearchHistoryData() : SearchHistoryItem[] {
  66 + if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
  67 + if(this.searchHistoryData.length>10){
  68 + this.searchHistoryData.splice(10,this.searchHistoryData.length - 10)
  69 + }
  70 + return this.searchHistoryData
  71 + }
  72 + let history = SPHelper.default.getSync(this.SEARCH_HISTORY_KEY,"[]") as string
  73 +
  74 + this.searchHistoryData = JSON.parse(history)
  75 + if(this.searchHistoryData.length>10){
  76 + this.searchHistoryData.splice(10,this.searchHistoryData.length - 10)
  77 + }
  78 +
  79 + return this.searchHistoryData
  80 + }
  81 +
  82 + /**
27 * 首页 搜索提示滚动内容 83 * 首页 搜索提示滚动内容
28 */ 84 */
29 getSearchHintData(context: Context): Promise<string[]> { 85 getSearchHintData(context: Context): Promise<string[]> {
@@ -62,6 +118,43 @@ class SearcherAboutDataModel{ @@ -62,6 +118,43 @@ class SearcherAboutDataModel{
62 } 118 }
63 119
64 120
  121 + /**
  122 + * 搜索主页 热词
  123 + */
  124 + getSearchHotsData(context: Context): Promise<SearchHotContentItem[]> {
  125 + return new Promise<SearchHotContentItem[]>((success, error) => {
  126 + Logger.info(TAG, `getSearchHintData start`);
  127 + this.fetchSearchHotsData().then((navResDTO: ResponseDTO<SearchHotContentItem[]>) => {
  128 + if (!navResDTO || navResDTO.code != 0) {
  129 + success(this.getSearchHotsDataLocal(context))
  130 + return
  131 + }
  132 + Logger.info(TAG, "getSearchHotsData then,getSearchHotsData.timeStamp:" + navResDTO.timestamp);
  133 + let navigationBean = navResDTO.data as SearchHotContentItem[]
  134 + success(navigationBean);
  135 + }).catch((err: Error) => {
  136 + Logger.error(TAG, `getSearchHotsData catch, error.name : ${err.name}, error.message:${err.message}`);
  137 + success(this.getSearchHotsDataLocal(context))
  138 + })
  139 + })
  140 + }
  141 +
  142 + fetchSearchHotsData() {
  143 + let url = HttpUrlUtils.getSearchHotsDataUrl()
  144 + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
  145 + return WDHttp.get<ResponseDTO<SearchHotContentItem[]>>(url, headers)
  146 + };
  147 +
  148 + async getSearchHotsDataLocal(context: Context): Promise<SearchHotContentItem[]> {
  149 + Logger.info(TAG, `getSearchHotsDataLocal start`);
  150 + let compRes: ResponseDTO<SearchHotContentItem[]> | null = await ResourcesUtils.getResourcesJson<ResponseDTO<SearchHotContentItem[]>>(context,'search_hots_data.json' ,);
  151 + if (!compRes || !compRes.data) {
  152 + Logger.info(TAG, `getSearchHotsDataLocal compRes is empty`);
  153 + return []
  154 + }
  155 + Logger.info(TAG, `getSearchHotsDataLocal compRes : ${JSON.stringify(compRes)}`);
  156 + return compRes.data
  157 + }
65 158
66 } 159 }
67 160
  1 +import { SearchComponent } from '../components/search/SearchComponent'
  2 +
  3 +@Entry
  4 +@Component
  5 +struct SearchPage {
  6 + build() {
  7 + Column(){
  8 + SearchComponent()
  9 + }.height('100%')
  10 + .width('100%')
  11 + }
  12 +}
1 import promptAction from '@ohos.promptAction'; 1 import promptAction from '@ohos.promptAction';
2 import { RefreshConstants as Const, RefreshState } from './RefreshConstants'; 2 import { RefreshConstants as Const, RefreshState } from './RefreshConstants';
3 import { touchMoveLoadMore, touchUpLoadMore } from './PullUpLoadMore'; 3 import { touchMoveLoadMore, touchUpLoadMore } from './PullUpLoadMore';
4 -import { PageDTO } from 'wdBean'; 4 +import { PageDTO, CompDTO } from 'wdBean';
5 import PageModel from '../viewmodel/PageModel'; 5 import PageModel from '../viewmodel/PageModel';
6 import PageViewModel from '../viewmodel/PageViewModel'; 6 import PageViewModel from '../viewmodel/PageViewModel';
  7 +import { DateTimeUtils } from 'wdKit';
7 8
8 export function listTouchEvent(pageModel: PageModel, event: TouchEvent) { 9 export function listTouchEvent(pageModel: PageModel, event: TouchEvent) {
9 switch (event.type) { 10 switch (event.type) {
@@ -73,6 +74,7 @@ export function touchUpPullRefresh(pageModel: PageModel) { @@ -73,6 +74,7 @@ export function touchUpPullRefresh(pageModel: PageModel) {
73 74
74 PageViewModel.getPageData(self.pageId, self.groupId, self.channelId, self.currentPage, self.pageSize, getContext()) 75 PageViewModel.getPageData(self.pageId, self.groupId, self.channelId, self.currentPage, self.pageSize, getContext())
75 .then((data: PageDTO) => { 76 .then((data: PageDTO) => {
  77 + self.timestamp = DateTimeUtils.getTimeStamp().toString()
76 if (data == null || data.compList == null || data.compList.length == 0) { 78 if (data == null || data.compList == null || data.compList.length == 0) {
77 self.hasMore = false; 79 self.hasMore = false;
78 } else { 80 } else {
@@ -84,6 +86,11 @@ export function touchUpPullRefresh(pageModel: PageModel) { @@ -84,6 +86,11 @@ export function touchUpPullRefresh(pageModel: PageModel) {
84 } 86 }
85 // 刷新,替换所有数据 87 // 刷新,替换所有数据
86 self.compList.replaceAll(...data.compList) 88 self.compList.replaceAll(...data.compList)
  89 + PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
  90 + // 刷新,替换所有数据
  91 + self.compList.replaceAll(...data)
  92 + self.timestamp = DateTimeUtils.getTimeStamp().toString()
  93 + })
87 } 94 }
88 closeRefresh(self, true); 95 closeRefresh(self, true);
89 }).catch((err: string | Resource) => { 96 }).catch((err: string | Resource) => {
@@ -2,7 +2,8 @@ import promptAction from '@ohos.promptAction'; @@ -2,7 +2,8 @@ import promptAction from '@ohos.promptAction';
2 import PageModel from '../viewmodel/PageModel'; 2 import PageModel from '../viewmodel/PageModel';
3 import { RefreshConstants as Const } from './RefreshConstants'; 3 import { RefreshConstants as Const } from './RefreshConstants';
4 import PageViewModel from '../viewmodel/PageViewModel'; 4 import PageViewModel from '../viewmodel/PageViewModel';
5 -import { PageDTO } from 'wdBean'; 5 +import { PageDTO,CompDTO } from 'wdBean';
  6 +import { DateTimeUtils } from 'wdKit';
6 7
7 export function touchMoveLoadMore(model: PageModel, event: TouchEvent) { 8 export function touchMoveLoadMore(model: PageModel, event: TouchEvent) {
8 // list size +1 9 // list size +1
@@ -29,6 +30,7 @@ export function touchUpLoadMore(model: PageModel) { @@ -29,6 +30,7 @@ export function touchUpLoadMore(model: PageModel) {
29 closeLoadMore(model); 30 closeLoadMore(model);
30 PageViewModel.getPageData(self.pageId, self.groupId, self.channelId, self.currentPage, self.pageSize, getContext()) 31 PageViewModel.getPageData(self.pageId, self.groupId, self.channelId, self.currentPage, self.pageSize, getContext())
31 .then((data: PageDTO) => { 32 .then((data: PageDTO) => {
  33 + self.timestamp = DateTimeUtils.getTimeStamp().toString()
32 if (data == null || data.compList == null || data.compList.length == 0) { 34 if (data == null || data.compList == null || data.compList.length == 0) {
33 self.hasMore = false; 35 self.hasMore = false;
34 } else { 36 } else {
@@ -38,7 +40,13 @@ export function touchUpLoadMore(model: PageModel) { @@ -38,7 +40,13 @@ export function touchUpLoadMore(model: PageModel) {
38 } else { 40 } else {
39 self.hasMore = false; 41 self.hasMore = false;
40 } 42 }
  43 + let sizeBefore:number = self.compList.size();
41 self.compList.push(...data.compList) 44 self.compList.push(...data.compList)
  45 + PageViewModel.getInteractData(data.compList).then((data: CompDTO[]) => {
  46 + // 刷新,替换所有数据
  47 + self.compList.updateItems(sizeBefore, data)
  48 + self.timestamp = DateTimeUtils.getTimeStamp().toString()
  49 + })
42 } 50 }
43 }).catch((err: string | Resource) => { 51 }).catch((err: string | Resource) => {
44 promptAction.showToast({ message: err }); 52 promptAction.showToast({ message: err });
@@ -32,4 +32,6 @@ export default class PageModel { @@ -32,4 +32,6 @@ export default class PageModel {
32 isPullRefreshOperation = false; 32 isPullRefreshOperation = false;
33 isLoading: boolean = false; 33 isLoading: boolean = false;
34 isCanLoadMore: boolean = false; 34 isCanLoadMore: boolean = false;
  35 + // keyGenerator相关字符串,用于刷新list布局
  36 + timestamp: String = '1';
35 } 37 }
@@ -11,11 +11,7 @@ const TAG = 'PageViewModel'; @@ -11,11 +11,7 @@ const TAG = 'PageViewModel';
11 * mock数据是本地json数据,可自行修改内容(‘entry\src\main\resources\rawfile\’目录) 11 * mock数据是本地json数据,可自行修改内容(‘entry\src\main\resources\rawfile\’目录)
12 */ 12 */
13 const mock_switch = false; 13 const mock_switch = false;
14 -/**  
15 - * 互动数据获取开关开关,默认开。  
16 - * TODO 后续需要优化掉,变为二次请求异步刷新  
17 - */  
18 -const interact_sync_switch = false; 14 +
19 /** 15 /**
20 * 处理返回后的数据 16 * 处理返回后的数据
21 */ 17 */
@@ -114,18 +110,7 @@ export class PageViewModel extends BaseViewModel { @@ -114,18 +110,7 @@ export class PageViewModel extends BaseViewModel {
114 return 110 return
115 } 111 }
116 Logger.info(TAG, "getNavData then,resDTO.timestamp:" + resDTO.timestamp); 112 Logger.info(TAG, "getNavData then,resDTO.timestamp:" + resDTO.timestamp);
117 - if (!interact_sync_switch) {  
118 - success(resDTO.data);  
119 - return;  
120 - }  
121 - // TODO 打开同步请求互动数据,待优化为异步加载  
122 - // if (CollectionUtils.isEmpty(resDTO.data.compList)) {  
123 - // success(resDTO.data);  
124 - // } else {  
125 - // this.getInteractData(resDTO.data.compList).then(() => {  
126 - // success(resDTO.data);  
127 - // })  
128 - // } 113 + success(resDTO.data);
129 }) 114 })
130 .catch((err: Error) => { 115 .catch((err: Error) => {
131 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`); 116 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`);
@@ -165,18 +150,7 @@ export class PageViewModel extends BaseViewModel { @@ -165,18 +150,7 @@ export class PageViewModel extends BaseViewModel {
165 return 150 return
166 } 151 }
167 Logger.info(TAG, "getNavData then,resDTO.timestamp:" + resDTO.timestamp); 152 Logger.info(TAG, "getNavData then,resDTO.timestamp:" + resDTO.timestamp);
168 - if (!interact_sync_switch) {  
169 - success(resDTO.data);  
170 - return;  
171 - }  
172 - // TODO 打开同步请求互动数据,待优化为异步加载  
173 - // if (CollectionUtils.isEmpty(resDTO.data.compList)) {  
174 - // success(resDTO.data);  
175 - // } else {  
176 - // this.getInteractData(resDTO.data.compList).then(() => {  
177 - // success(resDTO.data);  
178 - // })  
179 - // } 153 + success(resDTO.data);
180 }) 154 })
181 .catch((err: Error) => { 155 .catch((err: Error) => {
182 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`); 156 Logger.error(TAG, `getPageData catch, error.name : ${err.name}, error.message:${err.message}`);
@@ -185,120 +159,123 @@ export class PageViewModel extends BaseViewModel { @@ -185,120 +159,123 @@ export class PageViewModel extends BaseViewModel {
185 }) 159 })
186 } 160 }
187 161
188 - // async getInteractData(compList: CompDTO[]) {  
189 - // let param: InteractParam = this.getInteractParams(compList);  
190 - // const SIZE = 20;  
191 - // // 批查接口,参数size限制20,这里截断分批查询,0,20;20,40...  
192 - // let count = Math.ceil(param.contentList.length / SIZE);  
193 - // if (count == 1) {  
194 - // let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(param);  
195 - // promises.push(promise);  
196 - // } else {  
197 - // for (let i = 1;i <= count; i++) {  
198 - // // 将查询参数截断(参数限制20个),分批请求接口  
199 - // let subList = new Array<ContentBean>();  
200 - // let start = 0;  
201 - // let end = 0;  
202 - // if (i == count) {  
203 - // start = (i - 1) * SIZE;  
204 - // end = param.contentList.length;  
205 - // subList = CollectionUtils.getSubElements(param.contentList, start, end)  
206 - // } else {  
207 - // start = (i - 1) * SIZE;  
208 - // end = start + SIZE;  
209 - // subList = CollectionUtils.getSubElements(param.contentList, start, end)  
210 - // }  
211 - // let subParam: InteractParam = {} as InteractParam;  
212 - // subParam.contentList = subList;  
213 - // let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(subParam);  
214 - // promises.push(promise);  
215 - // }  
216 - // }  
217 - //  
218 - // return new Promise<CompDTO[]>((success, error) => {  
219 - // Promise.all(promises).then((result) => {  
220 - // if (!CollectionUtils.isArray(result)) {  
221 - // success(compList);  
222 - // return;  
223 - // }  
224 - //  
225 - // let allInteractDataList = new Array();  
226 - // result.forEach((value: InteractDataDTO[]) => {  
227 - // if (value != null && value.length > 0) {  
228 - // allInteractDataList.push(...value);  
229 - // }  
230 - // })  
231 - // // 批查全部完成,统一设置到comp里  
232 - // this.resetInteract(allInteractDataList, compList);  
233 - // success(compList);  
234 - // })  
235 - // })  
236 - // }  
237 - //  
238 - // private createInteractDataPromise(param: InteractParam) {  
239 - // return new Promise<InteractDataDTO[]>((success, error) => {  
240 - // PageRepository.fetchInteractData(param).then((resDTO: ResponseDTO<InteractDataDTO[]>) => {  
241 - // if (this.isRespondsInvalid(resDTO, 'getInteractData')) {  
242 - // Logger.info(TAG, "getInteractData then,resDTO.timeStamp:" + resDTO.timestamp);  
243 - // success(null);  
244 - // return;  
245 - // }  
246 - // success(resDTO.data);  
247 - // }).catch((err: Error) => {  
248 - // Logger.error(TAG, `getInteractData catch, error.name : ${err.name}, error.message:${err.message}`);  
249 - // // 无论是否成功(暂不做重试),都回调结果,通知刷新数据  
250 - // success(null);  
251 - // })  
252 - // });  
253 - // }  
254 - //  
255 - // private resetInteract(interact: InteractDataDTO[], compList: CompDTO[]) {  
256 - // if (interact == null || interact.length == 0) {  
257 - // return  
258 - // }  
259 - // interact.forEach((interactData) => {  
260 - // let id = interactData.contentId;  
261 - // outer: for (let i = 0;i < compList.length; i++) {  
262 - // let comp = compList[i];  
263 - // if (comp == null || comp.operDataList == null || comp.operDataList.length == 0) {  
264 - // continue;  
265 - // }  
266 - // for (let j = 0;j < comp.operDataList.length; j++) {  
267 - // let content = comp.operDataList[j];  
268 - // if (content == null) {  
269 - // continue;  
270 - // }  
271 - // if (id == content.objectId) {  
272 - // content.interactData = interactData;  
273 - // break outer;  
274 - // }  
275 - // }  
276 - // }  
277 - // })  
278 - // }  
279 - //  
280 - // private getInteractParams(compList: CompDTO[]): InteractParam {  
281 - // if (compList == null || compList.length == 0) {  
282 - // return null;  
283 - // }  
284 - //  
285 - // let param: InteractParam = {} as InteractParam;  
286 - // param.contentList = new Array<ContentBean>();  
287 - // compList.forEach((value) => {  
288 - // let contentList = value.operDataList;  
289 - // if (contentList != null && contentList.length > 0) {  
290 - // contentList.forEach((v) => {  
291 - // if (StringUtils.isNotEmpty(v.objectId)) {  
292 - // let bean = {} as ContentBean;  
293 - // bean.contentId = v.objectId;  
294 - // bean.contentType = v.objectType;  
295 - // param.contentList.push(bean);  
296 - // }  
297 - // })  
298 - // }  
299 - // })  
300 - // return param;  
301 - // } 162 + async getInteractData(compList: CompDTO[]) {
  163 + let param: InteractParam = this.getInteractParams(compList);
  164 + const SIZE = 20;
  165 + // 批查接口,参数size限制20,这里截断分批查询,0,20;20,40...
  166 + let count = Math.ceil(param.contentList.length / SIZE);
  167 + let promises: Array<Promise<InteractDataDTO[]>> = new Array;
  168 + if (count == 1) {
  169 + let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(param);
  170 + promises.push(promise);
  171 + } else {
  172 + for (let i = 1; i <= count; i++) {
  173 + // 将查询参数截断(参数限制20个),分批请求接口
  174 + let subList = new Array<ContentBean>();
  175 + let start = 0;
  176 + let end = 0;
  177 + if (i == count) {
  178 + start = (i - 1) * SIZE;
  179 + end = param.contentList.length;
  180 + subList = CollectionUtils.getSubElements(param.contentList, start, end)
  181 + } else {
  182 + start = (i - 1) * SIZE;
  183 + end = start + SIZE;
  184 + subList = CollectionUtils.getSubElements(param.contentList, start, end)
  185 + }
  186 + let subParam: InteractParam = {} as InteractParam;
  187 + subParam.contentList = subList;
  188 + let promise: Promise<InteractDataDTO[]> = this.createInteractDataPromise(subParam);
  189 + promises.push(promise);
  190 + }
  191 + }
  192 +
  193 + return new Promise<CompDTO[]>((success, error) => {
  194 + Promise.all(promises).then((result) => {
  195 + if (!CollectionUtils.isArray(result)) {
  196 + success(compList);
  197 + return;
  198 + }
  199 +
  200 + let allInteractDataList: Array<InteractDataDTO> = new Array();
  201 + result.forEach((value: InteractDataDTO[]) => {
  202 + if (value != null && value.length > 0) {
  203 + allInteractDataList.push(...value);
  204 + }
  205 + })
  206 + // 批查全部完成,统一设置到comp里
  207 + this.resetInteract(allInteractDataList, compList);
  208 + success(compList);
  209 + })
  210 + })
  211 + }
  212 +
  213 + private createInteractDataPromise(param: InteractParam) {
  214 + return new Promise<InteractDataDTO[]>((success, error) => {
  215 + PageRepository.fetchInteractData(param).then((resDTO: ResponseDTO<InteractDataDTO[]>) => {
  216 + if (!resDTO || !resDTO.data) {
  217 + Logger.info(TAG, "getInteractData then,resDTO.timeStamp:" + resDTO.timestamp);
  218 + success([]);
  219 + return;
  220 + }
  221 + success(resDTO.data);
  222 + }).catch((err: Error) => {
  223 + Logger.error(TAG, `getInteractData catch, error.name : ${err.name}, error.message:${err.message}`);
  224 + // 无论是否成功(暂不做重试),都回调结果,通知刷新数据
  225 + success([]);
  226 + })
  227 + });
  228 + }
  229 +
  230 + private resetInteract(interact: InteractDataDTO[], compList: CompDTO[]) {
  231 + if (interact == null || interact.length == 0) {
  232 + return
  233 + }
  234 + interact.forEach((interactData) => {
  235 + let id = interactData.contentId;
  236 + outer: for (let i = 0; i < compList.length; i++) {
  237 + let comp = compList[i];
  238 + if (comp == null || comp.operDataList == null || comp.operDataList.length == 0) {
  239 + continue;
  240 + }
  241 + for (let j = 0; j < comp.operDataList.length; j++) {
  242 + let content = comp.operDataList[j];
  243 + if (content == null) {
  244 + continue;
  245 + }
  246 + if (id == content.objectId) {
  247 + content.interactData = interactData;
  248 + // TODO 测试代码,待删除
  249 + // content.interactData.likeNum = Math.floor(Math.random() * Math.floor(999));;
  250 + break outer;
  251 + }
  252 + }
  253 + }
  254 + })
  255 + }
  256 +
  257 + private getInteractParams(compList: CompDTO[]): InteractParam {
  258 + if (compList == null || compList.length == 0) {
  259 + return {} as InteractParam;
  260 + }
  261 +
  262 + let param: InteractParam = {} as InteractParam;
  263 + param.contentList = new Array<ContentBean>();
  264 + compList.forEach((value) => {
  265 + let contentList = value.operDataList;
  266 + if (contentList != null && contentList.length > 0) {
  267 + contentList.forEach((v) => {
  268 + if (StringUtils.isNotEmpty(v.objectId)) {
  269 + let bean = {} as ContentBean;
  270 + bean.contentId = v.objectId;
  271 + bean.contentType = v.objectType;
  272 + param.contentList.push(bean);
  273 + }
  274 + })
  275 + }
  276 + })
  277 + return param;
  278 + }
302 } 279 }
303 280
304 281
  1 +export class SearchHistoryItem{
  2 + searchContent:string = ""
  3 +
  4 +
  5 + constructor(searchContent: string) {
  6 + this.searchContent = searchContent
  7 + }
  8 +}
  1 +export class SearchHotContentItem{
  2 + hotEntry:string = ""
  3 + mark:number = 0 //1 热 2 新
  4 + sequence:number = 0//序号
  5 +
  6 + constructor(hotEntry: string , mark: number , sequence: number ) {
  7 + this.hotEntry = hotEntry
  8 + this.mark = mark
  9 + this.sequence = sequence
  10 + }
  11 +}
@@ -159,6 +159,14 @@ @@ -159,6 +159,14 @@
159 { 159 {
160 "name": "vp_16", 160 "name": "vp_16",
161 "value": "16vp" 161 "value": "16vp"
  162 + },
  163 + {
  164 + "name": "card_comp_pagePadding_lf",
  165 + "value": "16fp"
  166 + },
  167 + {
  168 + "name": "card_comp_pagePadding_tb",
  169 + "value": "14fp"
162 } 170 }
163 ] 171 ]
164 -}  
  172 +}
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
12 "components/page/EditUserIntroductionPage", 12 "components/page/EditUserIntroductionPage",
13 "components/page/BrowsingHistoryPage", 13 "components/page/BrowsingHistoryPage",
14 "components/page/MyCollectionListPage", 14 "components/page/MyCollectionListPage",
15 - "pages/OtherNormalUserHomePage" 15 + "pages/OtherNormalUserHomePage",
  16 + "pages/SearchPage"
16 ] 17 ]
17 } 18 }
@@ -6,5 +6,7 @@ @@ -6,5 +6,7 @@
6 "description": "Please describe the basic information.", 6 "description": "Please describe the basic information.",
7 "main": "Index.ets", 7 "main": "Index.ets",
8 "version": "1.0.0", 8 "version": "1.0.0",
9 - "dependencies": {} 9 + "dependencies": {
  10 + "wdComponent": "file:../../features/wdComponent"
  11 + }
10 } 12 }
  1 +import { BottomComponent } from '../widgets/details/BottomComponent';
  2 +import { TabComponent } from '../widgets/details/TabComponent';
  3 +import { TopPlayComponent } from '../widgets/details/TopPlayComponet';
  4 +
1 @Entry 5 @Entry
2 @Component 6 @Component
3 export struct DetailPlayLivePage { 7 export struct DetailPlayLivePage {
4 - @State message: string = 'Detail Play Live Page'; 8 + TAG: string = 'DetailPlayLivePage';
  9 +
  10 + aboutToAppear(): void {
  11 +
  12 + }
5 13
6 build() { 14 build() {
7 - Row() {  
8 - Column() {  
9 - Text(this.message)  
10 - .fontSize(50)  
11 - .fontWeight(FontWeight.Bold)  
12 - }  
13 - .width('100%') 15 + Column() {
  16 + TopPlayComponent()
  17 + TabComponent()
  18 + BottomComponent()
14 } 19 }
15 .height('100%') 20 .height('100%')
  21 + .width('100%')
  22 + }
  23 +
  24 + aboutToDisappear(): void {
16 } 25 }
17 } 26 }
  1 +@Component
  2 +export struct BottomComponent {
  3 + aboutToAppear(): void {
  4 + }
  5 +
  6 + build() {
  7 + Row() {
  8 +
  9 + }.backgroundColor(Color.Gray)
  10 + .height(56)
  11 + .width('100%')
  12 + }
  13 +
  14 + aboutToDisappear(): void {
  15 + }
  16 +}
  1 +import font from '@ohos.font'
  2 +
  3 +@Component
  4 +export struct LiveCountdownComponent {
  5 + textTimerController: TextTimerController = new TextTimerController()
  6 + @State format: string = 'HH:mm:ss'
  7 +
  8 + aboutToAppear(): void {
  9 + //注册字体
  10 + font.registerFont({
  11 + familyName: 'BebasNeue_Regular',
  12 + familySrc: $rawfile('font/BebasNeue_Regular.otf')
  13 + })
  14 + setTimeout(() => {
  15 + this.textTimerController.start()
  16 + }, 2000)
  17 + }
  18 +
  19 + build() {
  20 + Column() {
  21 + this.showTitle()
  22 + this.showCountDown()
  23 + this.showAppointment()
  24 + }.padding({
  25 + top: 20,
  26 + left: 20,
  27 + right: 20,
  28 + bottom: 24
  29 + })
  30 + .backgroundColor(Color.White)
  31 + .border({ radius: 6 })
  32 + .margin({ top: 16 })
  33 + }
  34 +
  35 + aboutToDisappear(): void {
  36 + this.textTimerController.pause()
  37 + }
  38 +
  39 + @Builder
  40 + showTitle() {
  41 + Text('距离直播开始还有')
  42 + .maxLines(2)
  43 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  44 + .fontSize('14fp')
  45 + .fontWeight(400)
  46 + .fontColor('#222222')
  47 + }
  48 +
  49 + @Builder
  50 + showCountDown() {
  51 + Row() {
  52 + this.showTimeStyle('10', true, 0)
  53 + this.showTimeStyle('月', false, 3)
  54 + this.showTimeStyle('8', true, 3)
  55 + this.showTimeStyle('日', false, 3)
  56 + this.showTimeStyle('16', true, 10)
  57 + this.showTimeStyle(':', true, 0)
  58 + this.showTimeStyle('05', true, 0)
  59 + }
  60 + .margin({ top: 10 })
  61 + .visibility(Visibility.None)
  62 +
  63 + TextTimer({ isCountDown: true, count: 24 * 60 * 60 * 1000 - 1000, controller: this.textTimerController })
  64 + .format(this.format)
  65 + .fontSize('40fp')
  66 + .fontWeight(FontWeight.Bold)
  67 + .fontColor('#222222')
  68 + .fontFamily('BebasNeue_Regular')
  69 + .onTimer((utc: number, elapsedTime: number) => {
  70 + console.info('textTimer notCountDown utc is:' + utc + ', elapsedTime: ' + elapsedTime)
  71 + })
  72 + .margin({ top: 10 })
  73 + }
  74 +
  75 + @Builder
  76 + showAppointment() {
  77 + Text('我要预约')
  78 + .width('100%')
  79 + .height(42)
  80 + .textAlign(TextAlign.Center)
  81 + .fontSize('16fp')
  82 + .fontWeight(400)
  83 + .fontColor(Color.White)
  84 + .margin({
  85 + top: 16
  86 + })
  87 + .border({ radius: 4 })
  88 + .backgroundColor('#ED2800')
  89 + // .backgroundColor('#CCCCCC')
  90 + }
  91 +
  92 + @Builder
  93 + showTimeStyle(value: string, isBold: boolean, left: number) {
  94 + Text(value)
  95 + .fontSize(isBold ? '40fp' : '16fp')
  96 + .fontFamily(isBold ? 'BebasNeue_Regular' : '')
  97 + .fontWeight(isBold ? FontWeight.Bold : 500)
  98 + .fontColor('#222222')
  99 + .margin({ left: left })
  100 + }
  101 +}
  1 +import { ListHasNoMoreDataUI } from 'wdComponent/Index'
  2 +import { TabChatItemComponent } from './TabChatItemComponent'
  3 +
  4 +@Component
  5 +export struct TabChatComponent {
  6 + arr: string[] = []
  7 +
  8 + aboutToAppear(): void {
  9 + for (let index = 0; index < 12; index++) {
  10 + this.arr.push(index + '')
  11 + }
  12 + }
  13 +
  14 + build() {
  15 + Stack() {
  16 + if (this.arr.length == 0) {
  17 + ListHasNoMoreDataUI({ style: 2 })
  18 + } else {
  19 + List() {
  20 + ForEach(this.arr, (item: string) => {
  21 + ListItem() {
  22 + TabChatItemComponent()
  23 + }
  24 + })
  25 + ListItem() {
  26 + ListHasNoMoreDataUI()
  27 + }
  28 + }
  29 + }
  30 + }
  31 + .align(Alignment.Top)
  32 + .backgroundColor('#F5F5F5')
  33 + .height('100%')
  34 + .width('100%')
  35 + }
  36 +
  37 + aboutToDisappear(): void {
  38 + }
  39 +}
  1 +@Component
  2 +export struct TabChatItemComponent {
  3 + aboutToAppear(): void {
  4 + }
  5 +
  6 + build() {
  7 + Row() {
  8 + Image('https://img0.baidu.com/it/u=4105778329,1297102594&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500')
  9 + .borderRadius(90)
  10 + .width(24)
  11 + .height(24)
  12 + Text() {
  13 + Span('10999@qq.com: ')
  14 + .fontColor('#666666')
  15 + Span('少年强则国强:山中有精灵也不过如此了')
  16 + .fontColor('#222222')
  17 + }
  18 + .margin({ left: 8 })
  19 + .lineHeight(20)
  20 + .layoutWeight(1)
  21 + .fontSize('14fp')
  22 + .fontWeight(400)
  23 + }
  24 + .alignItems(VerticalAlign.Top)
  25 + .padding({
  26 + left: 15,
  27 + top: 15,
  28 + right: 15
  29 + })
  30 + }
  31 +
  32 + aboutToDisappear(): void {
  33 +
  34 + }
  35 +}
  1 +import { TabChatComponent } from './TabChatComponent'
  2 +import { TabInfoComponent } from './TabInfoComponent'
  3 +import { TabLiveComponent } from './TabLiveComponent'
  4 +
  5 +@Component
  6 +export struct TabComponent {
  7 + @State fontColor: string = '#999999'
  8 + @State selectedFontColor: string = '#222222'
  9 + @State currentIndex: number = 0
  10 + private controller: TabsController = new TabsController()
  11 + tabs: string[] = ['简介', '直播间', '大家聊']
  12 +
  13 + aboutToAppear(): void {
  14 +
  15 + }
  16 +
  17 + build() {
  18 + Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
  19 + ForEach(this.tabs, (item: string, index: number) => {
  20 + TabContent() {
  21 + if (0 == index) {
  22 + TabInfoComponent()
  23 + } else if (1 == index) {
  24 + TabLiveComponent()
  25 + } else {
  26 + TabChatComponent()
  27 + }
  28 + }.tabBar(this.tabBuilder(index, item))
  29 + .backgroundColor('#F5F5F5')
  30 + }, (item: string, index: number) => {
  31 + return item + index
  32 + })
  33 + }
  34 + .layoutWeight(1)
  35 + .vertical(false)
  36 + .barMode(BarMode.Fixed)
  37 + .barWidth(200)
  38 + .barHeight(48)
  39 + .animationDuration(100)
  40 + .onChange((index: number) => {
  41 + this.currentIndex = index
  42 + })
  43 + .backgroundColor(Color.White)
  44 + }
  45 +
  46 + @Builder
  47 + tabBuilder(index: number, name: string) {
  48 + Column() {
  49 + Text(name)
  50 + .margin({ top: 6 })
  51 + .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor)
  52 + .fontSize('18fp')
  53 + .fontWeight(this.currentIndex === index ? 600 : 400)
  54 + Divider()
  55 + .strokeWidth(2)
  56 + .margin({ top: 6 })
  57 + .width(15)
  58 + .color('#CB0000')
  59 + .visibility(this.currentIndex === index ? Visibility.Visible : Visibility.Hidden)
  60 + }.width('100%')
  61 + }
  62 +
  63 + aboutToDisappear(): void {
  64 + }
  65 +}
  1 +import { LiveCountdownComponent } from './LiveCountdownComponent'
  2 +
  3 +@Component
  4 +export struct TabInfoComponent {
  5 + aboutToAppear(): void {
  6 + }
  7 +
  8 + build() {
  9 + Column() {
  10 + this.showLiveTitle()
  11 + this.showLiveDetails()
  12 + LiveCountdownComponent()
  13 + }.margin({
  14 + top: 13,
  15 + left: 16,
  16 + right: 16
  17 + })
  18 + .height('100%')
  19 + }
  20 +
  21 + aboutToDisappear(): void {
  22 + }
  23 +
  24 + @Builder
  25 + showLiveTitle() {
  26 + Text('国新办发布会丨介绍防汛抗旱工国新办发布会丨介绍防汛抗旱工作情况国新办发布会丨介绍防汛抗旱工作情况作情况国新办发布会丨介绍防汛抗旱工作情况')
  27 + .maxLines(2)
  28 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  29 + .fontSize('18fp')
  30 + .fontWeight(500)
  31 + .fontColor('#222222')
  32 + }
  33 +
  34 + @Builder
  35 + showLiveDetails() {
  36 + Text('国务院新闻办公室将于7月25日上午10时举行国务院政策例行吹风会,请应急管理部副部长、水利部副部长王道席和自然资源部、水利部、应急管理部、中国气象局、国家消防救援局有关负责人介绍防汛抗旱工作情况,并答记者问。')
  37 + .maxLines(5)
  38 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  39 + .fontSize('14fp')
  40 + .fontWeight(400)
  41 + .fontColor('#666666')
  42 + .margin({ top: 8 })
  43 + }
  44 +}
  1 +import { ListHasNoMoreDataUI } from 'wdComponent/Index'
  2 +import { TabLiveItemComponent } from './TabLiveItemComponent'
  3 +
  4 +@Component
  5 +export struct TabLiveComponent {
  6 + arr: string[] = []
  7 +
  8 + aboutToAppear(): void {
  9 + for (let index = 0; index < 2; index++) {
  10 + this.arr.push(index + '')
  11 + }
  12 + }
  13 +
  14 + build() {
  15 + Stack() {
  16 + if (this.arr.length == 0) {
  17 + ListHasNoMoreDataUI({ style: 2 })
  18 + } else {
  19 + List() {
  20 + ForEach(this.arr, (item: string) => {
  21 + ListItem() {
  22 + TabLiveItemComponent({ item: item })
  23 + }
  24 + })
  25 + ListItem() {
  26 + ListHasNoMoreDataUI()
  27 + }
  28 + }
  29 + }
  30 + }
  31 + .alignContent(Alignment.Top)
  32 + .backgroundColor('#F5F5F5')
  33 + .height('100%')
  34 + .width('100%')
  35 +
  36 + }
  37 +
  38 + aboutToDisappear(): void {
  39 + }
  40 +}
  1 +@Component
  2 +export struct TabLiveItemComponent {
  3 + item: string = ''
  4 +
  5 + aboutToAppear(): void {
  6 +
  7 + }
  8 +
  9 + build() {
  10 + Column() {
  11 + Row() {
  12 + Image('https://img0.baidu.com/it/u=4105778329,1297102594&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500')
  13 + .borderRadius(90)
  14 + .width(24)
  15 + .height(24)
  16 + Text('人民日报直播频道')
  17 + .maxLines(1)
  18 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  19 + .fontSize('14fp')
  20 + .fontWeight(400)
  21 + .fontColor('#222222')
  22 + .margin({ left: 8 })
  23 + Text('嘉宾')
  24 + .maxLines(1)
  25 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  26 + .fontSize('11fp')
  27 + .fontWeight(400)
  28 + .fontColor('#968562')
  29 + .backgroundColor('#F1EFEB')
  30 + .padding({
  31 + left: 4,
  32 + top: 1,
  33 + right: 4,
  34 + bottom: 1
  35 + })
  36 + .borderRadius(2)
  37 + .margin({ left: 8 })
  38 + Text('1小时前')
  39 + .maxLines(1)
  40 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  41 + .fontSize('12fp')
  42 + .fontWeight(400)
  43 + .fontColor('#999999')
  44 + .margin({ left: 8 })
  45 + Blank()
  46 + Text('置顶')
  47 + .maxLines(1)
  48 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  49 + .fontSize('11fp')
  50 + .fontWeight(400)
  51 + .fontColor('#ED2800')
  52 + .backgroundColor('#F1EFEB')
  53 + .padding({
  54 + left: 4,
  55 + top: 1,
  56 + right: 4,
  57 + bottom: 1
  58 + })
  59 + .borderRadius(2)
  60 + .margin({ left: 8 })
  61 + }
  62 + .width('100%')
  63 +
  64 + Text('国务院新闻办公室将于7月25日上午10时举行国务院政策例行吹风会,请应急管理部副部长、水利部副部长王道席和自然资源部、水利部、应急管理部、中国气象局、国家消防救援局有关负责人介绍防汛抗旱工作情况,并答记者问。')
  65 + .fontSize('14fp')
  66 + .fontWeight(400)
  67 + .fontColor('#222222')
  68 + .margin({
  69 + left: 32,
  70 + top: 6
  71 + })
  72 +
  73 + Image('https://t7.baidu.com/it/u=3690528415,706188365&fm=193&f=GIF')
  74 + .height(174)
  75 + .width(310)
  76 + .aspectRatio(310 / 174)
  77 + .objectFit(ImageFit.Auto)
  78 + .borderRadius(4)
  79 + .margin({
  80 + left: 32,
  81 + top: 8
  82 + })
  83 + }.margin({
  84 + left:15,
  85 + top:15,
  86 + right:15
  87 + })
  88 + }
  89 +
  90 + aboutToDisappear(): void {
  91 +
  92 + }
  93 +}
  1 +@Component
  2 +export struct TopPlayComponent {
  3 + aspectRatioPlayer: number = 375 / 211
  4 +
  5 + aboutToAppear(): void {
  6 +
  7 + }
  8 +
  9 + build() {
  10 + Stack()
  11 + .height(211)
  12 + .aspectRatio(this.aspectRatioPlayer)
  13 + .backgroundColor(Color.Black)
  14 + }
  15 +
  16 + aboutToDisappear(): void {
  17 + }
  18 +}
  1 +{
  2 + "code": "0",
  3 + "data": [
  4 + {
  5 + "hotEntry": "习语",
  6 + "mark": 1,
  7 + "sequence": 1
  8 + },
  9 + {
  10 + "hotEntry": "党史学习教育工作",
  11 + "mark": 1,
  12 + "sequence": 2
  13 + },
  14 + {
  15 + "hotEntry": "2024年全国两会新闻中心启用",
  16 + "mark": 1,
  17 + "sequence": 3
  18 + },
  19 + {
  20 + "hotEntry": "第二艘国产大型邮轮后年底交付",
  21 + "mark": 0,
  22 + "sequence": 4
  23 + },
  24 + {
  25 + "hotEntry": "268名跨境电诈犯罪嫌疑人移交",
  26 + "mark": 0,
  27 + "sequence": 5
  28 + },
  29 + {
  30 + "hotEntry": "高考倒计时100天",
  31 + "mark": 2,
  32 + "sequence": 6
  33 + },
  34 + {
  35 + "hotEntry": "日本开始第四轮核污染水排放",
  36 + "mark": 0,
  37 + "sequence": 7
  38 + },
  39 + {
  40 + "hotEntry": "国台办点名管碧玲",
  41 + "mark": 0,
  42 + "sequence": 8
  43 + },
  44 + {
  45 + "hotEntry": "美方称不会向乌克兰派兵",
  46 + "mark": 2,
  47 + "sequence": 9
  48 + },
  49 + {
  50 + "hotEntry": "电动车乱停乱充电",
  51 + "mark": 2,
  52 + "sequence": 10
  53 + }
  54 + ],
  55 + "message": "Success",
  56 + "success": true,
  57 + "timestamp": 1712631086296
  58 +}