yangchenggong1_wd

desc:搜索联想和 串联逻辑处理

... ... @@ -180,6 +180,11 @@ export class HttpUrlUtils {
* 搜索主页 热词
*/
static readonly SEARCH_HOTS_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hots";
/**
* 搜索联想词
*/
static readonly RELATED_SEARCH_CONTENT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/suggestions/";
/**
* 早晚报列表
* 根据页面id获取页面楼层列表
... ... @@ -536,6 +541,10 @@ export class HttpUrlUtils {
return url
}
static getRelatedSearchContentDataUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.RELATED_SEARCH_CONTENT_DATA_PATH
return url
}
// static getYcgCommonHeaders(): HashMap<string, string> {
... ...
... ... @@ -39,6 +39,7 @@ export struct FirstTabTopSearchComponent {
Image($r('app.media.icon_search'))
.width(18)
.height(18)
.margin({right:'10lpx'})
if (this.searchTextData != null && this.searchTextData.length > 0) {
Swiper(this.swiperController) {
... ... @@ -58,6 +59,8 @@ export struct FirstTabTopSearchComponent {
.indicator(false)
.vertical(true)
.height(30)
.enabled(false)
.focusable(false)
}
}
.height(30)
... ...
... ... @@ -2,8 +2,10 @@ import router from '@ohos.router'
import { StringUtils, ToastUtils } from 'wdKit'
import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
import { SearchHistoryItem } from '../../viewmodel/SearchHistoryItem'
import { SearchRelatedItem } from '../../viewmodel/SearchRelatedItem'
import { SearchHistoryComponent } from './SearchHistoryComponent'
import { SearchHotsComponent } from './SearchHotsComponent'
import { SearchRelatedComponent } from './SearchRelatedComponent'
const TAG = "SearchComponent"
... ... @@ -12,10 +14,14 @@ export struct SearchComponent {
@State searchTextData: string[] = []
@State hasInputContent: boolean = false
@State hasChooseSearch: boolean = false
@State isClickedHistory: boolean = false
@State isClickedHot: boolean = false
@State isClickedRelated: boolean = false
private swiperController: SwiperController = new SwiperController()
@State searchText: string = ''
controller: TextInputController = new TextInputController()
@State searchHistoryData: SearchHistoryItem[] = []
@State relatedSearchContentsData: SearchRelatedItem[] = []
scroller: Scroller = new Scroller()
aboutToAppear() {
... ... @@ -25,7 +31,41 @@ export struct SearchComponent {
this.getSearchHistoryData()
}
getRelatedSearchContent() {
if(StringUtils.isNotEmpty(this.searchText)){
SearcherAboutDataModel.getRelatedSearchContentData(encodeURI(this.searchText),getContext(this)).then((value) => {
if (value != null) {
this.relatedSearchContentsData = []
value.forEach(item=>{
let tempValue:string = item
let tempArr: string[] = []
if (tempValue.indexOf(this.searchText) === -1) {
tempArr.push(item)
this.relatedSearchContentsData.push(new SearchRelatedItem(item,tempArr))
}else {
while (tempValue.indexOf(this.searchText) != -1){
let index = tempValue.indexOf(this.searchText)
if(index === 0){
tempArr.push(this.searchText)
tempValue = tempValue.substring(this.searchText.length,tempValue.length)
}else {
tempArr.push(tempValue.substring(0,index))
tempArr.push(this.searchText)
tempValue = tempValue.substring(index+this.searchText.length,tempValue.length)
}
}
if(StringUtils.isNotEmpty(tempValue)){
tempArr.push(tempValue)
}
this.relatedSearchContentsData.push(new SearchRelatedItem(item,tempArr))
}
})
}
}).catch((err: Error) => {
console.log(TAG, JSON.stringify(err))
})
}
}
getSearchHint() {
SearcherAboutDataModel.getSearchHintData(getContext(this)).then((value) => {
... ... @@ -48,7 +88,7 @@ export struct SearchComponent {
Scroll(this.scroller) {
Column() {
if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
SearchHistoryComponent({ searchHistoryData: $searchHistoryData, onDelHistory: (): void => this.getSearchHistoryData() })
SearchHistoryComponent({ searchHistoryData: $searchHistoryData, onDelHistory: (): void => this.getSearchHistoryData(),onGetSearchRes: (item,index): void => this.getSearchHistoryResData(item,index) })
}
//分隔符
... ... @@ -58,7 +98,7 @@ export struct SearchComponent {
.color($r('app.color.color_EDEDED'))
.strokeWidth('1lpx')
SearchHotsComponent()
SearchHotsComponent({onGetSearchRes: (item): void => this.getSearchHotResData(item)})
}
}
.scrollable(ScrollDirection.Vertical)
... ... @@ -66,19 +106,68 @@ export struct SearchComponent {
.width('100%')
.height('100%')
.padding({ left: '31lpx', right: '31lpx' })
.margin({ top: '36lpx' })
} else {
if (this.hasChooseSearch) {
//搜索结果
//搜索结果为null(空布局 + 为你推荐)
} else {
//联想搜索
SearchRelatedComponent({relatedSearchContentData:$relatedSearchContentsData,onGetSearchRes: (item): void => this.getSearchRelatedResData(item),searchText:this.searchText})
}
}
}.height('100%')
.width('100%')
}
/**
* 点击搜索记录列表回调
* @param content
*/
getSearchHistoryResData(content:string,index:number){
//删除单挑记录
SearcherAboutDataModel.delSearchSingleHistoryData(index)
this.isClickedHistory = true
this.searchResData(content)
}
searchResData(content:string){
//赋值
this.searchText = content
//保存搜索记录
SearcherAboutDataModel.putSearchHistoryData(this.searchText)
//获取搜索记录
this.getSearchHistoryData()
//清空 联想记录
this.relatedSearchContentsData = []
//查询 操作 TODO
}
/**
* 点击联想搜索列表回调
* @param content
*/
getSearchRelatedResData(content:string){
this.isClickedRelated = true
this.searchResData(content)
}
/**
* 点击热词搜索列表回调
* @param content
*/
getSearchHotResData(content:string){
this.isClickedHot = true
this.searchResData(content)
}
//搜索框
@Builder searchInputComponent() {
Row() {
... ... @@ -119,6 +208,13 @@ export struct SearchComponent {
} else {
this.hasInputContent = false
}
if(this.isClickedHistory || this.isClickedHot || this.isClickedRelated){
this.isClickedHistory = false
this.isClickedHot = false
this.isClickedRelated = false
}else{
this.getRelatedSearchContent()
}
})
.backgroundColor($r('app.color.color_transparent'))
.defaultFocus(true)
... ... @@ -166,6 +262,5 @@ export struct SearchComponent {
.height('85lpx')
.padding({ left: '31lpx' })
.alignItems(VerticalAlign.Center)
.margin({ bottom: '36lpx' })
}
}
\ No newline at end of file
... ...
... ... @@ -9,6 +9,7 @@ import { MyCustomDialog } from '../reusable/MyCustomDialog'
export struct SearchHistoryComponent{
@Link searchHistoryData:SearchHistoryItem[]
onDelHistory?: () => void;
onGetSearchRes?: (item:string,index:number) => void;
dialogController: CustomDialogController = new CustomDialogController({
builder: MyCustomDialog({
cancel: this.onCancel,
... ... @@ -70,16 +71,22 @@ export struct SearchHistoryComponent{
.fontWeight('400lpx')
.lineHeight('46lpx')
.maxLines(1)
.constraintSize({maxWidth:index%2 === 0?'270lpx':'250lpx'})
.constraintSize({maxWidth:index%2 === 0?'270lpx':'230lpx'})
.textOverflow({ overflow: TextOverflow.Ellipsis })
.textAlign(TextAlign.Start)
.margin({left:index%2 === 0?'0lpx':'23lpx'})
.onClick(()=>{
if (this.onGetSearchRes !== undefined) {
this.onGetSearchRes(item.searchContent,index)
}
})
Image($r('app.media.search_item_delete_icon'))
.width('46lpx')
.height('46lpx')
.margin({right:'31lpx',left:'4lpx'})
.interpolation(ImageInterpolation.High)
.objectFit(ImageFit.Cover)
.width('23lpx')
.height('23lpx')
.margin({left:'4lpx'})
.interpolation(ImageInterpolation.Medium)
.objectFit(ImageFit.Auto)
.onClick(()=>{
SearcherAboutDataModel.delSearchSingleHistoryData(index)
if (this.onDelHistory !== undefined) {
... ... @@ -101,9 +108,11 @@ export struct SearchHistoryComponent{
.alignItems(VerticalAlign.Center)
.width('100%')
.margin({left:index%2 === 1?'23lpx':'0lpx'})
}.onClick(()=>{
})
}
.height('46lpx')
.alignSelf(ItemAlign.Center)
})
}
.height(this.getCategoryViewHeight())
... ...
... ... @@ -9,6 +9,7 @@ const TAG = "SearchHotsComponent"
@Component
export struct SearchHotsComponent{
@State searchHotsData:SearchHotContentItem[] = []
onGetSearchRes?: (item:string) => void;
aboutToAppear(){
//获取搜索热词
... ... @@ -101,6 +102,9 @@ export struct SearchHotsComponent{
}
}
.onClick(()=>{
if (this.onGetSearchRes !== undefined) {
this.onGetSearchRes(item.hotEntry)
}
})
.height('117lpx')
})
... ...
import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
import { SearchHotContentItem } from '../../viewmodel/SearchHotContentItem'
import { SearchRelatedItem } from '../../viewmodel/SearchRelatedItem'
const TAG = "SearchRelatedComponent"
/**
* 热门搜索
*/
@Component
export struct SearchRelatedComponent {
@Link relatedSearchContentData: SearchRelatedItem[]
onGetSearchRes?: (item:string) => void;
@Prop searchText: string
build() {
Column() {
List() {
ForEach(this.relatedSearchContentData, (item: SearchRelatedItem, index: number) => {
ListItem() {
Column(){
Row() {
Image($r('app.media.search_related_item_icon'))
.width('31lpx')
.height('31lpx')
.objectFit(ImageFit.Auto)
.margin({ right: '10lpx' })
.interpolation(ImageInterpolation.High)
Text(){
ForEach(item.data_arr,(item:string)=>{
Span(item)
.fontColor(item===this.searchText?$r('app.color.color_ED2800'):$r('app.color.color_000000'))
.fontSize('31lpx')
.fontWeight('400lpx')
.lineHeight('50lpx')
})
}
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.layoutWeight(1)
}.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Start)
.height('95lpx')
if (index != this.relatedSearchContentData.length - 1) {
Divider()
.width('100%')
.height('1lpx')
.color($r('app.color.color_F5F5F5'))
.strokeWidth('1lpx')
}
}
}.width('100%')
.onClick(()=>{
if (this.onGetSearchRes !== undefined) {
this.onGetSearchRes(item.data_string)
}
})
})
}.width('100%')
}.width('100%')
.margin({ top: '8lpx' })
.padding({ left: '31lpx', right: '31lpx' })
}
test(){
let c = "12121212121"
}
}
\ No newline at end of file
... ...
... ... @@ -156,6 +156,46 @@ class SearcherAboutDataModel{
return compRes.data
}
/**
* 搜索 联想词
*/
getRelatedSearchContentData(keyword:string,context: Context): Promise<string[]> {
return new Promise<string[]>((success, error) => {
Logger.info(TAG, `getSearchHintData start`);
this.fetchRelatedSearchContentData(keyword).then((navResDTO: ResponseDTO<string[]>) => {
if (!navResDTO || navResDTO.code != 0) {
success(this.getRelatedSearchContentDataLocal(context))
return
}
Logger.info(TAG, "getSearchHintData then,SearchHintDataResDTO.timeStamp:" + navResDTO.timestamp);
let navigationBean = navResDTO.data as string[]
success(navigationBean);
}).catch((err: Error) => {
Logger.error(TAG, `fetchSearchHintData catch, error.name : ${err.name}, error.message:${err.message}`);
success(this.getRelatedSearchContentDataLocal(context))
})
})
}
fetchRelatedSearchContentData(keyword:string) {
let url = HttpUrlUtils.getRelatedSearchContentDataUrl()+ keyword
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.get<ResponseDTO<string[]>>(url, headers)
};
async getRelatedSearchContentDataLocal(context: Context): Promise<string[]> {
Logger.info(TAG, `getSearchHintDataLocal start`);
let compRes: ResponseDTO<string[]> | null = await ResourcesUtils.getResourcesJson<ResponseDTO<string[]>>(context,'search_related_data_nimen.json' );
if (!compRes || !compRes.data) {
Logger.info(TAG, `getSearchHintDataLocal compRes is empty`);
return []
}
Logger.info(TAG, `getSearchHintDataLocal compRes : ${JSON.stringify(compRes)}`);
return compRes.data
}
}
const searcherAboutDataModel = SearcherAboutDataModel.getInstance()
... ...
export class SearchRelatedItem{
data_arr: string[] = []
data_string: string = ""
constructor(data_string: string,data_arr: string[]) {
this.data_arr = data_arr
this.data_string = data_string
}
}
\ No newline at end of file
... ...
... ... @@ -135,6 +135,10 @@
{
"name": "color_48505A",
"value": "#48505A"
},
{
"name": "color_000000",
"value": "#000000"
}
]
}
\ No newline at end of file
... ...
{
"code": "0",
"data": [
"你们到底喜欢什么颜色的包包?说红色难搭配黑色没特点绿色又觉得",
"你们太帅了!货车起火6辆车紧急停下帮忙",
"你们家的除螨仪真的能除螨吗?听听专业人士怎么说",
"你们辛苦了!85岁 老奶奶亲手缝300双鞋垫送消防员",
"你们都是最棒的!中国队88枚奖牌收官",
"你们平安我们放心!广西玉林地震,中学生操场避险集体大合唱",
"你们也要保护好自己!男孩花掉多年攒的压岁钱,买口罩送民警",
"你们“灰头土脸”的样子,真帅!",
"你们的样子真美!路遇老人身体不适 五名女大学生护送就医",
"你们都在看Mate 30,我却被老干妈洗脑了:这广告比华为还"
],
"message": "Success",
"success": true,
"timestamp": 1712803812695
}
\ No newline at end of file
... ...