王士厅
Showing 69 changed files with 1709 additions and 47 deletions
import { SearchComponent } from 'wdComponent'
@Entry
@Component
struct SearchPage {
build() {
Column(){
SearchComponent()
}.height('100%')
.width('100%')
}
}
\ No newline at end of file
... ...
... ... @@ -14,6 +14,7 @@
"pages/LaunchPage",
"pages/LaunchAdvertisingPage",
"pages/PrivacyPage",
"pages/OtherNormalUserHomePage"
"pages/OtherNormalUserHomePage",
"pages/SearchPage"
]
}
}
\ No newline at end of file
... ...
{
"code": "0",
"data": [
{
"hotEntry": "习语",
"mark": 1,
"sequence": 1
},
{
"hotEntry": "党史学习教育工作",
"mark": 1,
"sequence": 2
},
{
"hotEntry": "2024年全国两会新闻中心启用",
"mark": 1,
"sequence": 3
},
{
"hotEntry": "第二艘国产大型邮轮后年底交付",
"mark": 0,
"sequence": 4
},
{
"hotEntry": "268名跨境电诈犯罪嫌疑人移交",
"mark": 0,
"sequence": 5
},
{
"hotEntry": "高考倒计时100天",
"mark": 2,
"sequence": 6
},
{
"hotEntry": "日本开始第四轮核污染水排放",
"mark": 0,
"sequence": 7
},
{
"hotEntry": "国台办点名管碧玲",
"mark": 0,
"sequence": 8
},
{
"hotEntry": "美方称不会向乌克兰派兵",
"mark": 2,
"sequence": 9
},
{
"hotEntry": "电动车乱停乱充电",
"mark": 2,
"sequence": 10
}
],
"message": "Success",
"success": true,
"timestamp": 1712631086296
}
\ No newline at end of file
... ...
... ... @@ -44,4 +44,6 @@ export { FollowFirstTabsComponent } from "./components/page/mine/follow/FollowFi
export { MyHomeComponent } from "./components/page/mine/home/MyHomeComponent"
export { OtherUserHomeComponent } from "./components/page/mine/home/OtherUserHomeComponent"
\ No newline at end of file
export { OtherUserHomeComponent } from "./components/page/mine/home/OtherUserHomeComponent"
export { SearchComponent } from "./components/page/search/SearchComponent"
\ No newline at end of file
... ...
import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
import RouteManager from '../../utils/RouteManager'
/**
* 首页顶部搜索导航栏
* 竖向滚动实现方案
... ... @@ -61,6 +62,9 @@ export struct FirstTabTopComponent{
.backgroundImage($r('app.media.top_search_bg'))
.backgroundImageSize(ImageSize.Cover)
.alignItems(VerticalAlign.Center)
.onClick(()=>{
RouteManager.jumpNewPage("pages/SearchPage")
})
Image($r('app.media.top_title_bg'))
.objectFit(ImageFit.Auto)
... ...
import router from '@ohos.router'
import { StringUtils } from 'wdKit/src/main/ets/utils/StringUtils'
import SearcherAboutDataModel from '../../../model/SearcherAboutDataModel'
import { SearchHistoryItem } from '../../../viewmodel/SearchHistoryItem'
import { SearchHistoryComponent } from './SearchHistoryComponent'
import { SearchHotsComponent } from './SearchHotsComponent'
const TAG = "SearchComponent"
@Component
export struct SearchComponent {
@State searchTextData: string[] = []
@State hasInputContent: boolean = false
@State hasChooseSearch: boolean = false
private swiperController: SwiperController = new SwiperController()
@State searchText: string = ''
controller: TextInputController = new TextInputController()
@State searchHistoryData: SearchHistoryItem[] = []
scroller: Scroller = new Scroller()
aboutToAppear() {
//获取提示滚动
this.getSearchHint()
//获取搜索历史
this.getSearchHistoryData()
}
getSearchHint() {
SearcherAboutDataModel.getSearchHintData(getContext(this)).then((value) => {
if (value != null) {
this.searchTextData = value
}
}).catch((err: Error) => {
console.log(TAG, JSON.stringify(err))
})
}
getSearchHistoryData() {
this.searchHistoryData = SearcherAboutDataModel.getSearchHistoryData()
}
build() {
Column() {
this.searchInputComponent()
if (!this.hasInputContent) {
Scroll(this.scroller) {
Column() {
SearchHistoryComponent({ searchHistoryData: $searchHistoryData })
//分隔符
Divider()
.width('100%')
.height('1lpx')
.color($r('app.color.color_EDEDED'))
.strokeWidth('1lpx')
SearchHotsComponent()
}
}
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.Off)
.width('100%')
.height('100%')
.padding({ left: '31lpx', right: '31lpx' })
} else {
if (this.hasChooseSearch) {
//搜索结果
//搜索结果为null(空布局 + 为你推荐)
} else {
//联想搜索
}
}
}.height('100%')
.width('100%')
}
//搜索框
@Builder searchInputComponent() {
Row() {
//左
Stack({ alignContent: Alignment.Start }) {
if (this.searchTextData != null && this.searchTextData.length > 0 && !this.hasInputContent) {
Swiper(this.swiperController) {
ForEach(this.searchTextData, (item: string, index: number) => {
Text(item)
.fontWeight('400lpx')
.fontSize('25lpx')
.fontColor($r('app.color.color_666666'))
.lineHeight('35lpx')
.textAlign(TextAlign.Start)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Clip })
.margin({ left: '40lpx' })
})
}
.loop(true)
.autoPlay(true)
.interval(3000)
.indicator(false)
.vertical(true)
.enabled(false)
.focusable(false)
}
TextInput({ text: this.searchText, placeholder: '', controller: this.controller })
.caretColor(Color.Pink)
.fontSize('27lpx')
.fontColor(Color.Black)
.onChange((value: string) => {
this.searchText = value
if (this.searchText.length > 0) {
this.hasInputContent = false
} else {
this.hasInputContent = true
}
})
.backgroundColor($r('app.color.color_transparent'))
}
.backgroundImage($r('app.media.search_page_input_bg'))
.backgroundImageSize(ImageSize.Cover)
.layoutWeight(1)
.height('69lpx')
//右
Text("取消")
.textAlign(TextAlign.Center)
.fontWeight('400lpx')
.fontSize('31lpx')
.lineHeight('58lpx')
.fontColor($r('app.color.color_222222'))
.width('125lpx')
.height('58lpx')
.onClick(() => {
router.back()
// SearcherAboutDataModel.putSearchHistoryData(this.searchText)
// if(StringUtils.isNotEmpty(this.searchText)){
// if(this.searchHistoryData.length===10){
// this.searchHistoryData.pop()
// }
// this.searchHistoryData.push(new SearchHistoryItem(this.searchText))
// }
})
}
.height('85lpx')
.padding({ left: '31lpx' })
.alignItems(VerticalAlign.Center)
.margin({ bottom: '36lpx' })
}
}
\ No newline at end of file
... ...
import { SearchHistoryItem } from '../../../viewmodel/SearchHistoryItem'
/**
* 搜索历史
*/
@Component
export struct SearchHistoryComponent{
@Link searchHistoryData:SearchHistoryItem[]
build(){
Column(){
Row(){
Text("搜索历史")
.textAlign(TextAlign.Center)
.fontWeight('400lpx')
.fontSize('27lpx')
.lineHeight('38lpx')
.fontColor($r('app.color.color_999999'))
.height('38lpx')
Image($r('app.media.search_delete_icon'))
.height('31lpx')
.width('31lpx')
.objectFit(ImageFit.Auto)
.onClick(()=>{
//清空记录
})
}.justifyContent(FlexAlign.SpaceBetween)
.margin({bottom:'17lpx'})
.width('100%')
Grid(){
ForEach(this.searchHistoryData,(item:SearchHistoryItem,index:number)=>{
GridItem(){
Row(){
Text(`${item.searchContent}`)
.height('23lpx')
.fontColor($r('app.color.color_222222'))
.fontSize('23lpx')
.maxLines(1)
.constraintSize({maxWidth:index%2 === 0?'270lpx':'250lpx'})
.textOverflow({ overflow: TextOverflow.Ellipsis })
.textAlign(TextAlign.Start)
Image($r('app.media.search_item_delete_icon'))
.width('46lpx')
.height('46lpx')
.margin({right:'31lpx',left:'4lpx'})
.interpolation(ImageInterpolation.Medium)
.objectFit(ImageFit.Auto)
Blank()
if(index%2 === 0 && index != this.searchHistoryData.length-1 ){
Divider()
.width('2lpx')
.height('23lpx')
.color($r('app.color.color_CCCCCC'))
.strokeWidth('2lpx')
.vertical(true)
}
}.height('100%')
.alignItems(VerticalAlign.Center)
.width('100%')
.margin({left:index%2 === 1?'23lpx':'0lpx'})
}.onClick(()=>{
})
.height('46lpx')
})
}
.height(this.getCategoryViewHeight())
.rowsTemplate(this.getCategoryRowTmpl())
.columnsTemplate('1fr 1fr')
.rowsGap('23lpx')
}
.margin({bottom:'46lpx'})
}
getCategoryRowCount() {
return Math.ceil(this.searchHistoryData.length / 2);
}
getCategoryRowTmpl() {
const count = this.getCategoryRowCount();
const arr: string[] = new Array(count || 1).fill('1fr');
console.log('tmpl ', arr.join(' '))
return arr.join(' ');
}
getCategoryViewHeight() {
return `${46 * this.getCategoryRowCount()}lpx`;
}
}
\ No newline at end of file
... ...
import SearcherAboutDataModel from '../../../model/SearcherAboutDataModel'
import { SearchHotContentItem } from '../../../viewmodel/SearchHotContentItem'
const TAG = "SearchHotsComponent"
/**
* 热门搜索
*/
@Component
export struct SearchHotsComponent{
@State searchHotsData:SearchHotContentItem[] = []
aboutToAppear(){
//获取搜索热词
this.getSearchHotsData()
}
getSearchHotsData(){
SearcherAboutDataModel.getSearchHotsData(getContext(this)).then((value)=>{
if(value!=null){
this.searchHotsData = value
}
}).catch((err:Error)=>{
console.log(TAG,JSON.stringify(err))
})
}
build(){
Column(){
Row() {
Image($r('app.media.search_hot_icon'))
.width('46lpx')
.height('46lpx')
.objectFit(ImageFit.Auto)
.margin({right:'8lpx'})
.interpolation(ImageInterpolation.Medium)
Text("热门搜索")
.textAlign(TextAlign.Center)
.fontWeight('600lpx')
.fontSize('33lpx')
.lineHeight('46lpx')
.fontColor($r('app.color.color_222222'))
.height('38lpx')
}
.width('100%')
List(){
ForEach(this.searchHotsData,(item:SearchHotContentItem,index:number)=>{
ListItem(){
Column(){
Column(){
Row(){
Row(){
if(item.sequence <=3){
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'))
.width('27lpx')
.height('35lpx')
.objectFit(ImageFit.Auto)
.margin({right:'12lpx'})
}else {
Text(`${item.sequence}`)
.height('31lpx')
.fontColor($r('app.color.color_666666'))
.fontSize('27lpx')
.fontWeight('400lpx')
.lineHeight('31lpx')
.margin({right:'12lpx'})
}
Text(`${item.hotEntry}`)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor($r('app.color.color_222222'))
.fontSize('31lpx')
.maxLines(1)
.fontWeight('400lpx')
.lineHeight('42lpx')
}.layoutWeight(1)
if(item.mark!=0){
Image(item.mark===1?$r('app.media.search_hots_mark1'):$r('app.media.search_hots_mark2'))
.width('42lpx')
.height('31lpx')
.objectFit(ImageFit.Auto)
.interpolation(ImageInterpolation.Medium)
}
}.alignItems(VerticalAlign.Center)
.height('84lpx')
.justifyContent(FlexAlign.SpaceBetween)
if(index != this.searchHotsData.length-1 ){
Divider()
.width('100%')
.height('1lpx')
.color($r('app.color.color_F5F5F5'))
.strokeWidth('1lpx')
}
}.height('108lpx')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Start)
.padding({left:'27lpx'})
}
}
.onClick(()=>{
})
.height('117lpx')
})
}.onScrollFrameBegin((offset, state) => {
return { offsetRemain: 0 }
}).layoutWeight(1)
}.width('100%')
.height('100%')
.margin({top:'46lpx'})
}
}
\ No newline at end of file
... ...
... ... @@ -3,6 +3,8 @@ import { Logger, ResourcesUtils } from 'wdKit';
import { ResponseDTO, WDHttp } from 'wdNetwork';
import HashMap from '@ohos.util.HashMap';
import { HttpUrlUtils } from '../network/HttpUrlUtils';
import { SearchHistoryItem } from '../viewmodel/SearchHistoryItem';
import { SearchHotContentItem } from '../viewmodel/SearchHotContentItem';
const TAG = "SearcherAboutDataModel"
/**
... ... @@ -10,6 +12,7 @@ const TAG = "SearcherAboutDataModel"
*/
class SearcherAboutDataModel{
private static instance: SearcherAboutDataModel;
searchHistoryData:SearchHistoryItem[] = []
private constructor() { }
... ... @@ -25,6 +28,53 @@ class SearcherAboutDataModel{
}
/**
* 静态搜索历史记录
*/
getSearchHistoryData():SearchHistoryItem[]{
if(this.searchHistoryData.length > 0){
return this.searchHistoryData
}
this.searchHistoryData.push(new SearchHistoryItem("评论"))
this.searchHistoryData.push(new SearchHistoryItem("关注关注"))
this.searchHistoryData.push(new SearchHistoryItem("收藏收藏收藏"))
this.searchHistoryData.push(new SearchHistoryItem("历史"))
this.searchHistoryData.push(new SearchHistoryItem("消息消息消息消息消息"))
this.searchHistoryData.push(new SearchHistoryItem("留言板留言板留言板留言板留言板"))
this.searchHistoryData.push(new SearchHistoryItem("预约"))
return this.searchHistoryData
}
// async putSearchHistoryData(content:string){
// let history = await SPHelper.default.get(SearcherAboutDataModel.SEARCH_HISTORY_KEY, '[]') as string;
// this.searchHistoryData = JSON.parse(history)
// this.searchHistoryData.push(new SearchHistoryItem(content))
// await SPHelper.default.save(SearcherAboutDataModel.SEARCH_HISTORY_KEY, JSON.stringify(this.searchHistoryData));
// }
// getSearchHistoryData():Promise<SearchHistoryItem[]>{
// return new Promise<SearchHistoryItem[]>(async (success, error) => {
// if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
// success(this.searchHistoryData)
// return
// }
// try {
// let history = await SPHelper.default.get(SearcherAboutDataModel.SEARCH_HISTORY_KEY, '') as string;
// console.log('ycg',history);
// }catch (error){
// console.log('ycg',"1111");
// }
//
// this.searchHistoryData = JSON.parse(history)
// this.searchHistoryData.push(new SearchHistoryItem("评论"))
// this.searchHistoryData.push(new SearchHistoryItem("关注关注"))
// this.searchHistoryData.push(new SearchHistoryItem("收藏收藏收藏"))
//
// success(this.searchHistoryData)
// })
// }
/**
* 首页 搜索提示滚动内容
*/
getSearchHintData(context: Context): Promise<string[]> {
... ... @@ -62,6 +112,45 @@ class SearcherAboutDataModel{
return compRes.data
}
/**
* 搜索主页 热词
*/
getSearchHotsData(context: Context): Promise<SearchHotContentItem[]> {
return new Promise<SearchHotContentItem[]>((success, error) => {
Logger.info(TAG, `getSearchHintData start`);
this.fetchSearchHotsData().then((navResDTO: ResponseDTO<SearchHotContentItem[]>) => {
if (!navResDTO || navResDTO.code != 0) {
success(this.getSearchHotsDataLocal(context))
return
}
Logger.info(TAG, "getSearchHotsData then,getSearchHotsData.timeStamp:" + navResDTO.timestamp);
let navigationBean = navResDTO.data as SearchHotContentItem[]
success(navigationBean);
}).catch((err: Error) => {
Logger.error(TAG, `getSearchHotsData catch, error.name : ${err.name}, error.message:${err.message}`);
success(this.getSearchHotsDataLocal(context))
})
})
}
fetchSearchHotsData() {
let url = HttpUrlUtils.getSearchHotsDataUrl()
let headers: HashMap<string, string> = HttpUrlUtils.getYcgCommonHeaders();
return WDHttp.get<ResponseDTO<SearchHotContentItem[]>>(url, headers)
};
async getSearchHotsDataLocal(context: Context): Promise<SearchHotContentItem[]> {
Logger.info(TAG, `getSearchHotsDataLocal start`);
let compRes: ResponseDTO<SearchHotContentItem[]> | null = await ResourcesUtils.getResourcesJson<ResponseDTO<SearchHotContentItem[]>>('search_hots_data.json' ,context);
if (!compRes || !compRes.data) {
Logger.info(TAG, `getSearchHotsDataLocal compRes is empty`);
return []
}
Logger.info(TAG, `getSearchHotsDataLocal compRes : ${JSON.stringify(compRes)}`);
return compRes.data
}
}
... ...
... ... @@ -121,6 +121,11 @@ export class HttpUrlUtils {
*/
static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints";
/**
* 搜索主页 热词
*/
static readonly SEARCH_HOTS_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hots";
private static hostUrl: string = HttpUrlUtils.HOST_UAT;
static getCommonHeaders(): HashMap<string, string> {
... ... @@ -308,6 +313,10 @@ export class HttpUrlUtils {
return url
}
static getSearchHotsDataUrl() {
let url = HttpUrlUtils.HOST_SIT + HttpUrlUtils.SEARCH_HOTS_DATA_PATH
return url
}
/**
* 点赞操作
... ...
... ... @@ -40,7 +40,7 @@ export class PageViewModel extends BaseViewModel {
if (mock_switch) {
return this.getBottomNavDataMock(context);
}
return this.getNavData();
return this.getNavData(context);
}
async getBottomNavDataMock(context?: Context): Promise<NavigationBodyDTO> {
... ... @@ -54,12 +54,13 @@ export class PageViewModel extends BaseViewModel {
return compRes.data
}
private getNavData(): Promise<NavigationBodyDTO> {
private getNavData(context?: Context): Promise<NavigationBodyDTO> {
return new Promise<NavigationBodyDTO>((success, error) => {
Logger.info(TAG, `getNavData start`);
PageRepository.fetchNavigationDataApi().then((navResDTO: ResponseDTO<NavigationBodyDTO>) => {
if (this.isRespondsInvalid(navResDTO, 'getNavData')) {
error("page data invalid");
// error("page data invalid");
success(this.getBottomNavDataMock(context))
return
}
Logger.info(TAG, "getNavData then,navResDTO.timeStamp:" + navResDTO.timestamp);
... ...
export class SearchHistoryItem{
searchContent:string = ""
searchUserId:string = ""
searchTime:string = ""
constructor(searchContent: string,searchUserId?:string,searchTime?:string) {
this.searchContent = searchContent
this.searchUserId = searchUserId
this.searchTime = searchTime
}
}
\ No newline at end of file
... ...
export class SearchHotContentItem{
hotEntry:string = ""
mark:number = 0 //1 热 2 新
sequence:number = 0//序号
constructor(hotEntry: string , mark: number , sequence: number ) {
this.hotEntry = hotEntry
this.mark = mark
this.sequence = sequence
}
}
\ No newline at end of file
... ...
... ... @@ -98,9 +98,12 @@ instance.interceptors.response.use(// 响应拦截器response类型就是Axios.r
// console.log(error.request)
// console.log(error.response)
// 这里用来处理http常见错误,进行全局提示
let message = buildErrorMsg(error.response?.status);
// 错误消息可以使用全局弹框展示出来
console.log(`httpStatus:${error.response?.status}-${message},请检查网络或联系管理员!`)
if(error!=null && error.response!=null ){
let message = buildErrorMsg(error.response.status);
// 错误消息可以使用全局弹框展示出来
console.log(`httpStatus:${error.response?.status}-${message},请检查网络或联系管理员!`)
}
return Promise.reject(error);
}
);
... ...
... ... @@ -100,7 +100,7 @@ export class HttpUrlUtils {
*/
static readonly APPOINTMENT_editUserDetail_PATH: string = "/api/rmrb-user-center/user/zh/c/editUserDetail";
/**
* 资料编辑 更新普通用户名
* 资料编辑 更新普通用户名(用户名、身份证号、邮箱、手机号修改url)
*/
static readonly APPOINTMENT_editUserDetail1_PATH: string = "/api/rmrb-user-center/user/zh/c/completeUserInfo";
/**
... ... @@ -177,6 +177,10 @@ export class HttpUrlUtils {
*/
static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints";
/**
* 搜索主页 热词
*/
static readonly SEARCH_HOTS_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hots";
/**
* 早晚报列表
* 根据页面id获取页面楼层列表
* https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/pageInfo?pageId=28927
... ... @@ -527,6 +531,11 @@ export class HttpUrlUtils {
return url
}
static getSearchHotsDataUrl() {
let url = HttpUrlUtils.HOST_SIT + HttpUrlUtils.SEARCH_HOTS_DATA_PATH
return url
}
// static getYcgCommonHeaders(): HashMap<string, string> {
... ...
import ArrayList from '@ohos.util.ArrayList';
import { Action } from 'wdBean'
import { WDRouterPage } from './WDRouterPage'
import { Action } from 'wdBean';
import { WDRouterPage } from './WDRouterPage';
interface HandleObject {
handle: (action: Action) => (WDRouterPage | undefined)
... ... @@ -75,6 +75,8 @@ export function registerRouter() {
return WDRouterPage.imageTextDetailPage
} else if (action.params?.pageID == "BroadcastPage") {
return WDRouterPage.broadcastPage
} else if (action.params?.pageID == "LIVE_DETAILS_PAGER") {
return WDRouterPage.detailPlayLivePage
}
return undefined
})
... ...
... ... @@ -86,4 +86,6 @@ export class WDRouterPage {
//播报页面
static broadcastPage = new WDRouterPage("phone", "ets/pages/broadcast/BroadcastPage");
//搜索主页
static searchPage = new WDRouterPage("wdComponent", "ets/pages/SearchPage");
}
... ...
This file is too large to display.
... ... @@ -60,3 +60,5 @@ export { BroadcastPageComponent } from "./src/main/ets/components/broadcast/Broa
export { FirstTabTopSearchComponent } from "./src/main/ets/components/search/FirstTabTopSearchComponent"
export { ListHasNoMoreDataUI } from "./src/main/ets/components/reusable/ListHasNoMoreDataUI"
... ...
... ... @@ -130,10 +130,9 @@ export struct BroadcastPageComponent {
}
}
.layoutWeight(1)
// @ts-ignore
.onScrollFrameBegin((offset, state) => {
console.log('ccc',String(offset), state)
})
// .onScrollFrameBegin((offset, state) => {
// console.log('ccc',String(offset), state)
// })
.onReachStart(() => {
console.log('onReachStart----->',)
})
... ...
... ... @@ -15,7 +15,6 @@ const LOCAL_CHANNEL: string = '地方频道'
@CustomDialog
struct ChannelDialog {
@State dragItem: number = -1
@State item: number = -1
private dragRefOffsetX: number = 0
private dragRefOffsetY: number = 0
@State offsetX: number = 0
... ... @@ -235,7 +234,7 @@ struct ChannelDialog {
.alignContent(Alignment.Start)
.height(36)
.onClick(() => {
AppStorage.set('indexSettingChannelId',item.channelId)
AppStorage.set('indexSettingChannelId', item.channelId)
})
})
}
... ... @@ -308,6 +307,7 @@ struct ChannelDialog {
})
.zIndex(this.dragItem == item.num ? 1 : 0)
.translate(this.dragItem == item.num ? { x: this.offsetX, y: this.offsetY } : { x: 0, y: 0 })
.gesture(
GestureGroup(GestureMode.Sequence,
PanGesture({ fingers: 1, direction: null, distance: 0 })
... ... @@ -324,12 +324,20 @@ struct ChannelDialog {
.onActionEnd((event: GestureEvent) => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.dragItem = -1
this.offsetX = 0
this.offsetY = 0
this.dragRefOffsetX = 0
this.dragRefOffsetY = 0
})
})
)
.onCancel(() => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.dragItem = -1
this.offsetX = 0
this.offsetY = 0
this.dragRefOffsetX = 0
this.dragRefOffsetY = 0
})
}))
... ...
... ... @@ -103,8 +103,7 @@ struct EditUserInfoPage {
.width('100%')
.onClick(()=>{
if (i === 1){
// TODO 缺失特殊用户判断
let params: editModelParams = {
editContent: this.currentUserInfo.userName
}
... ... @@ -177,7 +176,6 @@ struct EditUserInfoPage {
this.listData.push(...EditInfoViewModel.getEditListInfo(editModel))
});
}
getAreaList(){
EditInfoViewModel.getAreaList(getContext(this)).then((value) =>{
this.dataSource.push(...value)
... ...
... ... @@ -134,6 +134,15 @@ export struct TopNavigationComponent {
};
WDRouterRule.jumpWithAction(taskAction)
}
jumpToLiveDetailsPaper() {
let taskAction: Action = {
type: 'JUMP_INNER_NEW_PAGE',
params: {
pageID: 'LIVE_DETAILS_PAGER'
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
}
build() {
Column() {
... ... @@ -146,7 +155,8 @@ export struct TopNavigationComponent {
.width(72)
.height(29)
.onClick((event: ClickEvent) => {
this.jumpToENewPaper()
this.jumpToLiveDetailsPaper()
// this.jumpToENewPaper()
})
Stack({ alignContent: Alignment.Center }) {
... ...
import { MineAppointmentItem } from '../../viewmodel/MineAppointmentItem'
@CustomDialog
export struct MyCustomDialog {
@State title: string = "标题"
@State titleShow: boolean = true
@State tipValue: string ="提示文字"
@State tipShow: boolean = true
@State leftText: string = "取消"
@State rightText: string = "确认"
... ... @@ -16,16 +16,21 @@ export struct MyCustomDialog {
build() {
Column() {
Text(this.title)
.fontSize("32lpx")
.margin({ top: "40lpx", bottom: "15lpx" })
.fontColor($r('app.color.color_333333'))
.fontSize('35lpx')
.fontWeight('600lpx')
Text(this.tipValue)
.margin({ bottom: "30lpx" })
.fontSize("27lpx")
.fontColor($r('app.color.color_B0B0B0'))
if(this.titleShow){
Text(this.title)
.fontSize("32lpx")
.margin({ top: "40lpx", bottom: "15lpx" })
.fontColor($r('app.color.color_333333'))
.fontSize('35lpx')
.fontWeight('600lpx')
}
if(this.tipShow){
Text(this.tipValue)
.margin({ bottom: "30lpx" })
.fontSize("27lpx")
.fontColor($r('app.color.color_B0B0B0'))
}
Divider()
.width("100%")
... ...
... ... @@ -4,6 +4,7 @@
* 方案一 使用动画 + 定时器
* 方案二 使用容器组件Swiper(当前)
*/
import { WDRouterPage, WDRouterRule } from 'wdRouter'
import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
const TAG = "FirstTabTopSearchComponent"
... ... @@ -56,6 +57,9 @@ export struct FirstTabTopSearchComponent{
.padding({left:15})
.backgroundImage($r('app.media.background_search'))
.backgroundImageSize(ImageSize.Cover)
.onClick(()=>{
WDRouterRule.jumpWithPage(WDRouterPage.searchPage)
})
}
}
\ No newline at end of file
... ...
import router from '@ohos.router'
import { StringUtils, ToastUtils } from 'wdKit'
import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
import { SearchHistoryItem } from '../../viewmodel/SearchHistoryItem'
import { SearchHistoryComponent } from './SearchHistoryComponent'
import { SearchHotsComponent } from './SearchHotsComponent'
const TAG = "SearchComponent"
@Component
export struct SearchComponent {
@State searchTextData: string[] = []
@State hasInputContent: boolean = false
@State hasChooseSearch: boolean = false
private swiperController: SwiperController = new SwiperController()
@State searchText: string = ''
controller: TextInputController = new TextInputController()
@State searchHistoryData: SearchHistoryItem[] = []
scroller: Scroller = new Scroller()
aboutToAppear() {
//获取提示滚动
this.getSearchHint()
//获取搜索历史
this.getSearchHistoryData()
}
getSearchHint() {
SearcherAboutDataModel.getSearchHintData(getContext(this)).then((value) => {
if (value != null) {
this.searchTextData = value
}
}).catch((err: Error) => {
console.log(TAG, JSON.stringify(err))
})
}
getSearchHistoryData() {
this.searchHistoryData = SearcherAboutDataModel.getSearchHistoryData()
}
build() {
Column() {
this.searchInputComponent()
if (!this.hasInputContent) {
Scroll(this.scroller) {
Column() {
if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
SearchHistoryComponent({ searchHistoryData: $searchHistoryData, onDelHistory: (): void => this.getSearchHistoryData() })
}
//分隔符
Divider()
.width('100%')
.height('1lpx')
.color($r('app.color.color_EDEDED'))
.strokeWidth('1lpx')
SearchHotsComponent()
}
}
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.Off)
.width('100%')
.height('100%')
.padding({ left: '31lpx', right: '31lpx' })
} else {
if (this.hasChooseSearch) {
//搜索结果
//搜索结果为null(空布局 + 为你推荐)
} else {
//联想搜索
}
}
}.height('100%')
.width('100%')
}
//搜索框
@Builder searchInputComponent() {
Row() {
//左
Stack({ alignContent: Alignment.Start }) {
if (this.searchTextData != null && this.searchTextData.length > 0 && !this.hasInputContent) {
Swiper(this.swiperController) {
ForEach(this.searchTextData, (item: string, index: number) => {
Text(item)
.fontWeight('400lpx')
.fontSize('25lpx')
.fontColor($r('app.color.color_666666'))
.lineHeight('35lpx')
.textAlign(TextAlign.Start)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Clip })
.margin({ left: '40lpx' })
})
}
.loop(true)
.autoPlay(true)
.interval(3000)
.indicator(false)
.vertical(true)
.enabled(false)
.focusable(false)
}
Row(){
TextInput({ text: this.searchText, placeholder: '', controller: this.controller })
.caretColor(Color.Pink)
.fontSize('27lpx')
.layoutWeight(1)
.fontColor(Color.Black)
.onChange((value: string) => {
this.searchText = value
if (this.searchText.length > 0) {
this.hasInputContent = true
} else {
this.hasInputContent = false
}
})
.backgroundColor($r('app.color.color_transparent'))
.defaultFocus(true)
if(this.hasInputContent){
Image($r('app.media.search_input_del_icon'))
.width('31lpx')
.height('31lpx')
.objectFit(ImageFit.Cover)
.interpolation(ImageInterpolation.High)
.onClick(()=>{
this.searchText = ""
this.hasInputContent = false
})
}
}.padding({right:'30lpx'})
.layoutWeight(1)
}
.backgroundImage($r('app.media.search_page_input_bg'))
.backgroundImageSize(ImageSize.Cover)
.layoutWeight(1)
.height('69lpx')
//TODO 需要修改输入法 换行
//右
Text(this.hasInputContent?"搜索":"取消")
.textAlign(TextAlign.Center)
.fontWeight('400lpx')
.fontSize('31lpx')
.lineHeight('58lpx')
.fontColor($r('app.color.color_222222'))
.width('125lpx')
.height('58lpx')
.onClick(() => {
if(this.hasInputContent){
if(StringUtils.isNotEmpty(this.searchText)){
SearcherAboutDataModel.putSearchHistoryData(this.searchText)
this.getSearchHistoryData()
ToastUtils.shortToast("插入一条搜索记录")
}
}else{
router.back()
}
})
}
.height('85lpx')
.padding({ left: '31lpx' })
.alignItems(VerticalAlign.Center)
.margin({ bottom: '36lpx' })
}
}
\ No newline at end of file
... ...
import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
import { SearchHistoryItem } from '../../viewmodel/SearchHistoryItem'
import { MyCustomDialog } from '../reusable/MyCustomDialog'
/**
* 搜索历史
*/
@Component
export struct SearchHistoryComponent{
@Link searchHistoryData:SearchHistoryItem[]
onDelHistory?: () => void;
dialogController: CustomDialogController = new CustomDialogController({
builder: MyCustomDialog({
cancel: this.onCancel,
confirm: () => {
this.onAccept()
},
title: "确认清空历史记录",
tipShow:false
}),
autoCancel: true,
alignment: DialogAlignment.Center,
offset: { dx: 0, dy: -20 },
gridCount: 4,
customStyle: false
})
onAccept(){
console.info('Callback when the second button is clicked')
//清空记录
this.searchHistoryData = []
SearcherAboutDataModel.delSearchHistoryData()
}
onCancel() {
console.info('Callback when the first button is clicked')
}
build(){
Column(){
Row(){
Text("搜索历史")
.textAlign(TextAlign.Center)
.fontWeight('400lpx')
.fontSize('27lpx')
.lineHeight('38lpx')
.fontColor($r('app.color.color_999999'))
.height('38lpx')
Image($r('app.media.search_delete_icon'))
.height('31lpx')
.width('31lpx')
.interpolation(ImageInterpolation.High)
.objectFit(ImageFit.Cover)
.onClick(()=>{
//弹框提示
this.dialogController.open()
})
}.justifyContent(FlexAlign.SpaceBetween)
.margin({bottom:'17lpx'})
.width('100%')
Grid(){
ForEach(this.searchHistoryData,(item:SearchHistoryItem,index:number)=>{
GridItem(){
Row(){
Text(`${item.searchContent}`)
.fontColor($r('app.color.color_222222'))
.fontSize('31lpx')
.fontWeight('400lpx')
.lineHeight('46lpx')
.maxLines(1)
.constraintSize({maxWidth:index%2 === 0?'270lpx':'250lpx'})
.textOverflow({ overflow: TextOverflow.Ellipsis })
.textAlign(TextAlign.Start)
Image($r('app.media.search_item_delete_icon'))
.width('46lpx')
.height('46lpx')
.margin({right:'31lpx',left:'4lpx'})
.interpolation(ImageInterpolation.High)
.objectFit(ImageFit.Cover)
.onClick(()=>{
SearcherAboutDataModel.delSearchSingleHistoryData(index)
if (this.onDelHistory !== undefined) {
this.onDelHistory()
}
})
Blank()
if(index%2 === 0 && index != this.searchHistoryData.length-1 ){
Divider()
.width('2lpx')
.height('23lpx')
.color($r('app.color.color_CCCCCC'))
.strokeWidth('2lpx')
.vertical(true)
}
}.height('100%')
.alignItems(VerticalAlign.Center)
.width('100%')
.margin({left:index%2 === 1?'23lpx':'0lpx'})
}.onClick(()=>{
})
.height('46lpx')
})
}
.height(this.getCategoryViewHeight())
.rowsTemplate(this.getCategoryRowTmpl())
.columnsTemplate('1fr 1fr')
.rowsGap('23lpx')
}
.margin({bottom:'46lpx'})
}
getCategoryRowCount() {
return Math.ceil(this.searchHistoryData.length / 2);
}
getCategoryRowTmpl() {
const count = this.getCategoryRowCount();
const arr: string[] = new Array(count || 1).fill('1fr');
console.log('tmpl ', arr.join(' '))
return arr.join(' ');
}
getCategoryViewHeight() {
return `${46 * this.getCategoryRowCount()}lpx`;
}
}
\ No newline at end of file
... ...
import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
import { SearchHotContentItem } from '../../viewmodel/SearchHotContentItem'
const TAG = "SearchHotsComponent"
/**
* 热门搜索
*/
@Component
export struct SearchHotsComponent{
@State searchHotsData:SearchHotContentItem[] = []
aboutToAppear(){
//获取搜索热词
this.getSearchHotsData()
}
getSearchHotsData(){
SearcherAboutDataModel.getSearchHotsData(getContext(this)).then((value)=>{
if(value!=null){
this.searchHotsData = value
}
}).catch((err:Error)=>{
console.log(TAG,JSON.stringify(err))
})
}
build(){
Column(){
Row() {
Image($r('app.media.search_hot_icon'))
.width('46lpx')
.height('46lpx')
.objectFit(ImageFit.Auto)
.margin({right:'8lpx'})
.interpolation(ImageInterpolation.Medium)
Text("热门搜索")
.textAlign(TextAlign.Center)
.fontWeight('600lpx')
.fontSize('33lpx')
.lineHeight('46lpx')
.fontColor($r('app.color.color_222222'))
.height('38lpx')
}
.width('100%')
List(){
ForEach(this.searchHotsData,(item:SearchHotContentItem,index:number)=>{
ListItem(){
Column(){
Column(){
Row(){
Row(){
if(item.sequence <=3){
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'))
.width('27lpx')
.height('35lpx')
.objectFit(ImageFit.Auto)
.margin({right:'12lpx'})
.interpolation(ImageInterpolation.High)
}else {
Text(`${item.sequence}`)
.height('31lpx')
.fontColor($r('app.color.color_666666'))
.fontSize('27lpx')
.fontWeight('400lpx')
.lineHeight('31lpx')
.margin({right:'12lpx'})
}
Text(`${item.hotEntry}`)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor($r('app.color.color_222222'))
.fontSize('31lpx')
.maxLines(1)
.fontWeight('400lpx')
.lineHeight('42lpx')
}.layoutWeight(1)
if(item.mark!=0){
Image(item.mark===1?$r('app.media.search_hots_mark1'):$r('app.media.search_hots_mark2'))
.width('42lpx')
.height('31lpx')
.objectFit(ImageFit.Auto)
.interpolation(ImageInterpolation.High)
}
}.alignItems(VerticalAlign.Center)
.height('84lpx')
.justifyContent(FlexAlign.SpaceBetween)
if(index != this.searchHotsData.length-1 ){
Divider()
.width('100%')
.height('1lpx')
.color($r('app.color.color_F5F5F5'))
.strokeWidth('1lpx')
}
}.height('108lpx')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Start)
.padding({left:'27lpx'})
}
}
.onClick(()=>{
})
.height('117lpx')
})
}.onScrollFrameBegin((offset, state) => {
return { offsetRemain: 0 }
}).layoutWeight(1)
}.width('100%')
.height('100%')
.margin({top:'46lpx'})
}
}
\ No newline at end of file
... ...
import { Logger, ResourcesUtils } from 'wdKit';
import { Logger, ResourcesUtils, SPHelper, UserDataLocal } from 'wdKit';
import { HttpUrlUtils, ResponseDTO, WDHttp } from 'wdNetwork';
import HashMap from '@ohos.util.HashMap';
import { SearchHistoryItem } from '../viewmodel/SearchHistoryItem';
import { SearchHotContentItem } from '../viewmodel/SearchHotContentItem';
const TAG = "SearcherAboutDataModel"
/**
... ... @@ -9,6 +12,8 @@ const TAG = "SearcherAboutDataModel"
*/
class SearcherAboutDataModel{
private static instance: SearcherAboutDataModel;
public searchHistoryData:SearchHistoryItem[] = []
public SEARCH_HISTORY_KEY:string = "SEARCH_HISTORY_KEY" + UserDataLocal.userId
private constructor() { }
... ... @@ -24,6 +29,57 @@ class SearcherAboutDataModel{
}
/**
* 插入搜索记录(单个)
*/
public async putSearchHistoryData(content:string){
let history = SPHelper.default.getSync(this.SEARCH_HISTORY_KEY,"[]") as string
this.searchHistoryData = JSON.parse(history)
this.searchHistoryData.splice(0,0,new SearchHistoryItem(content))
await SPHelper.default.saveSync(this.SEARCH_HISTORY_KEY, JSON.stringify(this.searchHistoryData));
}
/**
* 删除搜索记录(所有)
*/
public async delSearchHistoryData(){
SPHelper.default.deleteSync(this.SEARCH_HISTORY_KEY)
this.searchHistoryData = []
}
/**
* 删除搜索记录(单个)
*/
public async delSearchSingleHistoryData(index:number){
if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
this.searchHistoryData.splice(index,1)
}else{
let history = SPHelper.default.getSync(this.SEARCH_HISTORY_KEY,"[]") as string
this.searchHistoryData = JSON.parse(history)
this.searchHistoryData.splice(index,1)
}
SPHelper.default.saveSync(this.SEARCH_HISTORY_KEY, JSON.stringify(this.searchHistoryData))
}
/**
* 查询搜索记录(所有)
*/
public getSearchHistoryData() : SearchHistoryItem[] {
if(this.searchHistoryData!=null && this.searchHistoryData.length>0){
if(this.searchHistoryData.length>10){
this.searchHistoryData.splice(10,this.searchHistoryData.length - 10)
}
return this.searchHistoryData
}
let history = SPHelper.default.getSync(this.SEARCH_HISTORY_KEY,"[]") as string
this.searchHistoryData = JSON.parse(history)
if(this.searchHistoryData.length>10){
this.searchHistoryData.splice(10,this.searchHistoryData.length - 10)
}
return this.searchHistoryData
}
/**
* 首页 搜索提示滚动内容
*/
getSearchHintData(context: Context): Promise<string[]> {
... ... @@ -62,6 +118,43 @@ class SearcherAboutDataModel{
}
/**
* 搜索主页 热词
*/
getSearchHotsData(context: Context): Promise<SearchHotContentItem[]> {
return new Promise<SearchHotContentItem[]>((success, error) => {
Logger.info(TAG, `getSearchHintData start`);
this.fetchSearchHotsData().then((navResDTO: ResponseDTO<SearchHotContentItem[]>) => {
if (!navResDTO || navResDTO.code != 0) {
success(this.getSearchHotsDataLocal(context))
return
}
Logger.info(TAG, "getSearchHotsData then,getSearchHotsData.timeStamp:" + navResDTO.timestamp);
let navigationBean = navResDTO.data as SearchHotContentItem[]
success(navigationBean);
}).catch((err: Error) => {
Logger.error(TAG, `getSearchHotsData catch, error.name : ${err.name}, error.message:${err.message}`);
success(this.getSearchHotsDataLocal(context))
})
})
}
fetchSearchHotsData() {
let url = HttpUrlUtils.getSearchHotsDataUrl()
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return WDHttp.get<ResponseDTO<SearchHotContentItem[]>>(url, headers)
};
async getSearchHotsDataLocal(context: Context): Promise<SearchHotContentItem[]> {
Logger.info(TAG, `getSearchHotsDataLocal start`);
let compRes: ResponseDTO<SearchHotContentItem[]> | null = await ResourcesUtils.getResourcesJson<ResponseDTO<SearchHotContentItem[]>>(context,'search_hots_data.json' ,);
if (!compRes || !compRes.data) {
Logger.info(TAG, `getSearchHotsDataLocal compRes is empty`);
return []
}
Logger.info(TAG, `getSearchHotsDataLocal compRes : ${JSON.stringify(compRes)}`);
return compRes.data
}
}
... ...
import { SearchComponent } from '../components/search/SearchComponent'
@Entry
@Component
struct SearchPage {
build() {
Column(){
SearchComponent()
}.height('100%')
.width('100%')
}
}
\ No newline at end of file
... ...
... ... @@ -123,8 +123,9 @@ class EditInfoViewModel {
} else if (item.editDataType == WDEditDataModelType.WDEditDataModelType_region) {
this.params = {province:item.userExtend.province,city:item.userExtend.city, county: item.userExtend.county ,address:item.userExtend.address}
}
return new Promise((success, error) => {
this.BasePostRequest(HttpUrlUtils.APPOINTMENT_editUserDetail_PATH,this.params)
this.BasePostRequest(item.editDataType == WDEditDataModelType.WDEditDataModelType_nickname?HttpUrlUtils.APPOINTMENT_editUserDetail1_PATH:HttpUrlUtils.APPOINTMENT_editUserDetail_PATH,this.params)
.then((navResDTO: ResponseDTO) => {
if (navResDTO.code == 0) {
promptAction.showToast({ message: '修改成功' })
... ...
export class SearchHistoryItem{
searchContent:string = ""
constructor(searchContent: string) {
this.searchContent = searchContent
}
}
\ No newline at end of file
... ...
export class SearchHotContentItem{
hotEntry:string = ""
mark:number = 0 //1 热 2 新
sequence:number = 0//序号
constructor(hotEntry: string , mark: number , sequence: number ) {
this.hotEntry = hotEntry
this.mark = mark
this.sequence = sequence
}
}
\ No newline at end of file
... ...
... ... @@ -12,6 +12,7 @@
"components/page/EditUserIntroductionPage",
"components/page/BrowsingHistoryPage",
"components/page/MyCollectionListPage",
"pages/OtherNormalUserHomePage"
"pages/OtherNormalUserHomePage",
"pages/SearchPage"
]
}
\ No newline at end of file
... ...
... ... @@ -6,5 +6,7 @@
"description": "Please describe the basic information.",
"main": "Index.ets",
"version": "1.0.0",
"dependencies": {}
"dependencies": {
"wdComponent": "file:../../features/wdComponent"
}
}
... ...
import { BottomComponent } from '../widgets/details/BottomComponent';
import { TabComponent } from '../widgets/details/TabComponent';
import { TopPlayComponent } from '../widgets/details/TopPlayComponet';
@Entry
@Component
export struct DetailPlayLivePage {
@State message: string = 'Detail Play Live Page';
TAG: string = 'DetailPlayLivePage';
aboutToAppear(): void {
}
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
Column() {
TopPlayComponent()
TabComponent()
BottomComponent()
}
.height('100%')
.width('100%')
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
@Component
export struct BottomComponent {
aboutToAppear(): void {
}
build() {
Row() {
}.backgroundColor(Color.Gray)
.height(56)
.width('100%')
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
import font from '@ohos.font'
@Component
export struct LiveCountdownComponent {
textTimerController: TextTimerController = new TextTimerController()
@State format: string = 'HH:mm:ss'
aboutToAppear(): void {
//注册字体
font.registerFont({
familyName: 'BebasNeue_Regular',
familySrc: $rawfile('font/BebasNeue_Regular.otf')
})
setTimeout(() => {
this.textTimerController.start()
}, 2000)
}
build() {
Column() {
this.showTitle()
this.showCountDown()
this.showAppointment()
}.padding({
top: 20,
left: 20,
right: 20,
bottom: 24
})
.backgroundColor(Color.White)
.border({ radius: 6 })
.margin({ top: 16 })
}
aboutToDisappear(): void {
this.textTimerController.pause()
}
@Builder
showTitle() {
Text('距离直播开始还有')
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('14fp')
.fontWeight(400)
.fontColor('#222222')
}
@Builder
showCountDown() {
Row() {
this.showTimeStyle('10', true, 0)
this.showTimeStyle('月', false, 3)
this.showTimeStyle('8', true, 3)
this.showTimeStyle('日', false, 3)
this.showTimeStyle('16', true, 10)
this.showTimeStyle(':', true, 0)
this.showTimeStyle('05', true, 0)
}
.margin({ top: 10 })
.visibility(Visibility.None)
TextTimer({ isCountDown: true, count: 24 * 60 * 60 * 1000 - 1000, controller: this.textTimerController })
.format(this.format)
.fontSize('40fp')
.fontWeight(FontWeight.Bold)
.fontColor('#222222')
.fontFamily('BebasNeue_Regular')
.onTimer((utc: number, elapsedTime: number) => {
console.info('textTimer notCountDown utc is:' + utc + ', elapsedTime: ' + elapsedTime)
})
.margin({ top: 10 })
}
@Builder
showAppointment() {
Text('我要预约')
.width('100%')
.height(42)
.textAlign(TextAlign.Center)
.fontSize('16fp')
.fontWeight(400)
.fontColor(Color.White)
.margin({
top: 16
})
.border({ radius: 4 })
.backgroundColor('#ED2800')
// .backgroundColor('#CCCCCC')
}
@Builder
showTimeStyle(value: string, isBold: boolean, left: number) {
Text(value)
.fontSize(isBold ? '40fp' : '16fp')
.fontFamily(isBold ? 'BebasNeue_Regular' : '')
.fontWeight(isBold ? FontWeight.Bold : 500)
.fontColor('#222222')
.margin({ left: left })
}
}
\ No newline at end of file
... ...
import { ListHasNoMoreDataUI } from 'wdComponent/Index'
import { TabChatItemComponent } from './TabChatItemComponent'
@Component
export struct TabChatComponent {
arr: string[] = []
aboutToAppear(): void {
for (let index = 0; index < 12; index++) {
this.arr.push(index + '')
}
}
build() {
Stack() {
if (this.arr.length == 0) {
ListHasNoMoreDataUI({ style: 2 })
} else {
List() {
ForEach(this.arr, (item: string) => {
ListItem() {
TabChatItemComponent()
}
})
ListItem() {
ListHasNoMoreDataUI()
}
}
}
}
.align(Alignment.Top)
.backgroundColor('#F5F5F5')
.height('100%')
.width('100%')
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
@Component
export struct TabChatItemComponent {
aboutToAppear(): void {
}
build() {
Row() {
Image('https://img0.baidu.com/it/u=4105778329,1297102594&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500')
.borderRadius(90)
.width(24)
.height(24)
Text() {
Span('10999@qq.com: ')
.fontColor('#666666')
Span('少年强则国强:山中有精灵也不过如此了')
.fontColor('#222222')
}
.margin({ left: 8 })
.lineHeight(20)
.layoutWeight(1)
.fontSize('14fp')
.fontWeight(400)
}
.alignItems(VerticalAlign.Top)
.padding({
left: 15,
top: 15,
right: 15
})
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
import { TabChatComponent } from './TabChatComponent'
import { TabInfoComponent } from './TabInfoComponent'
import { TabLiveComponent } from './TabLiveComponent'
@Component
export struct TabComponent {
@State fontColor: string = '#999999'
@State selectedFontColor: string = '#222222'
@State currentIndex: number = 0
private controller: TabsController = new TabsController()
tabs: string[] = ['简介', '直播间', '大家聊']
aboutToAppear(): void {
}
build() {
Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
ForEach(this.tabs, (item: string, index: number) => {
TabContent() {
if (0 == index) {
TabInfoComponent()
} else if (1 == index) {
TabLiveComponent()
} else {
TabChatComponent()
}
}.tabBar(this.tabBuilder(index, item))
.backgroundColor('#F5F5F5')
}, (item: string, index: number) => {
return item + index
})
}
.layoutWeight(1)
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(200)
.barHeight(48)
.animationDuration(100)
.onChange((index: number) => {
this.currentIndex = index
})
.backgroundColor(Color.White)
}
@Builder
tabBuilder(index: number, name: string) {
Column() {
Text(name)
.margin({ top: 6 })
.fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor)
.fontSize('18fp')
.fontWeight(this.currentIndex === index ? 600 : 400)
Divider()
.strokeWidth(2)
.margin({ top: 6 })
.width(15)
.color('#CB0000')
.visibility(this.currentIndex === index ? Visibility.Visible : Visibility.Hidden)
}.width('100%')
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
import { LiveCountdownComponent } from './LiveCountdownComponent'
@Component
export struct TabInfoComponent {
aboutToAppear(): void {
}
build() {
Column() {
this.showLiveTitle()
this.showLiveDetails()
LiveCountdownComponent()
}.margin({
top: 13,
left: 16,
right: 16
})
.height('100%')
}
aboutToDisappear(): void {
}
@Builder
showLiveTitle() {
Text('国新办发布会丨介绍防汛抗旱工国新办发布会丨介绍防汛抗旱工作情况国新办发布会丨介绍防汛抗旱工作情况作情况国新办发布会丨介绍防汛抗旱工作情况')
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('18fp')
.fontWeight(500)
.fontColor('#222222')
}
@Builder
showLiveDetails() {
Text('国务院新闻办公室将于7月25日上午10时举行国务院政策例行吹风会,请应急管理部副部长、水利部副部长王道席和自然资源部、水利部、应急管理部、中国气象局、国家消防救援局有关负责人介绍防汛抗旱工作情况,并答记者问。')
.maxLines(5)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('14fp')
.fontWeight(400)
.fontColor('#666666')
.margin({ top: 8 })
}
}
\ No newline at end of file
... ...
import { ListHasNoMoreDataUI } from 'wdComponent/Index'
import { TabLiveItemComponent } from './TabLiveItemComponent'
@Component
export struct TabLiveComponent {
arr: string[] = []
aboutToAppear(): void {
for (let index = 0; index < 2; index++) {
this.arr.push(index + '')
}
}
build() {
Stack() {
if (this.arr.length == 0) {
ListHasNoMoreDataUI({ style: 2 })
} else {
List() {
ForEach(this.arr, (item: string) => {
ListItem() {
TabLiveItemComponent({ item: item })
}
})
ListItem() {
ListHasNoMoreDataUI()
}
}
}
}
.alignContent(Alignment.Top)
.backgroundColor('#F5F5F5')
.height('100%')
.width('100%')
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
@Component
export struct TabLiveItemComponent {
item: string = ''
aboutToAppear(): void {
}
build() {
Column() {
Row() {
Image('https://img0.baidu.com/it/u=4105778329,1297102594&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500')
.borderRadius(90)
.width(24)
.height(24)
Text('人民日报直播频道')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('14fp')
.fontWeight(400)
.fontColor('#222222')
.margin({ left: 8 })
Text('嘉宾')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('11fp')
.fontWeight(400)
.fontColor('#968562')
.backgroundColor('#F1EFEB')
.padding({
left: 4,
top: 1,
right: 4,
bottom: 1
})
.borderRadius(2)
.margin({ left: 8 })
Text('1小时前')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('12fp')
.fontWeight(400)
.fontColor('#999999')
.margin({ left: 8 })
Blank()
Text('置顶')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('11fp')
.fontWeight(400)
.fontColor('#ED2800')
.backgroundColor('#F1EFEB')
.padding({
left: 4,
top: 1,
right: 4,
bottom: 1
})
.borderRadius(2)
.margin({ left: 8 })
}
.width('100%')
Text('国务院新闻办公室将于7月25日上午10时举行国务院政策例行吹风会,请应急管理部副部长、水利部副部长王道席和自然资源部、水利部、应急管理部、中国气象局、国家消防救援局有关负责人介绍防汛抗旱工作情况,并答记者问。')
.fontSize('14fp')
.fontWeight(400)
.fontColor('#222222')
.margin({
left: 32,
top: 6
})
Image('https://t7.baidu.com/it/u=3690528415,706188365&fm=193&f=GIF')
.height(174)
.width(310)
.aspectRatio(310 / 174)
.objectFit(ImageFit.Auto)
.borderRadius(4)
.margin({
left: 32,
top: 8
})
}.margin({
left:15,
top:15,
right:15
})
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
@Component
export struct TopPlayComponent {
aspectRatioPlayer: number = 375 / 211
aboutToAppear(): void {
}
build() {
Stack()
.height(211)
.aspectRatio(this.aspectRatioPlayer)
.backgroundColor(Color.Black)
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
... ... @@ -159,7 +159,10 @@ export struct DetailPlayShortVideoPage {
onLoad: async () => {
// console.log('onload==', this.index)
// if (this.index === 0) {
this.playerController.firstPlay(this.contentDetailData?.videoInfo[0]?.videoUrl);
if(this.contentDetailData!=null && this.contentDetailData?.videoInfo[0]!=null){
this.playerController.firstPlay(this.contentDetailData.videoInfo[0].videoUrl);
}
// }
}
})
... ...
{
"code": "0",
"data": [
{
"hotEntry": "习语",
"mark": 1,
"sequence": 1
},
{
"hotEntry": "党史学习教育工作",
"mark": 1,
"sequence": 2
},
{
"hotEntry": "2024年全国两会新闻中心启用",
"mark": 1,
"sequence": 3
},
{
"hotEntry": "第二艘国产大型邮轮后年底交付",
"mark": 0,
"sequence": 4
},
{
"hotEntry": "268名跨境电诈犯罪嫌疑人移交",
"mark": 0,
"sequence": 5
},
{
"hotEntry": "高考倒计时100天",
"mark": 2,
"sequence": 6
},
{
"hotEntry": "日本开始第四轮核污染水排放",
"mark": 0,
"sequence": 7
},
{
"hotEntry": "国台办点名管碧玲",
"mark": 0,
"sequence": 8
},
{
"hotEntry": "美方称不会向乌克兰派兵",
"mark": 2,
"sequence": 9
},
{
"hotEntry": "电动车乱停乱充电",
"mark": 2,
"sequence": 10
}
],
"message": "Success",
"success": true,
"timestamp": 1712631086296
}
\ No newline at end of file
... ...