Showing
23 changed files
with
633 additions
and
14 deletions
| @@ -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> { |
| @@ -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 | } |
| 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 | +} |
sight_harmony/features/wdComponent/src/main/ets/components/search/SearchHistoryComponent.ets
0 → 100644
| 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 | +} |
sight_harmony/features/wdComponent/src/main/ets/components/search/SearchHotsComponent.ets
0 → 100644
| 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 | +} |
| 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 |
239 Bytes
627 Bytes
348 Bytes
379 Bytes
408 Bytes
902 Bytes
863 Bytes
sight_harmony/features/wdComponent/src/main/resources/base/media/search_input_del_icon.png
0 → 100644
793 Bytes
sight_harmony/features/wdComponent/src/main/resources/base/media/search_item_delete_icon.png
0 → 100644
270 Bytes
sight_harmony/features/wdComponent/src/main/resources/base/media/search_page_input_bg.png
0 → 100644
727 Bytes
| @@ -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 | } |
| 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 | +} |
-
Please register or login to post a comment