Selaa lähdekoodia

feat: 完成搜索功能和搜索结果页面的UI和请求

YuJing 1 kuukausi sitten
vanhempi
commit
84132c9b5a

+ 5 - 0
commons/basic/src/main/ets/utils/arkts/utils/YTRouter.ets

@@ -161,6 +161,11 @@ class YTRouter extends NavPathStack {
   router2OrderDetailPage(){
     this.pushPathByName('OrderDetailPage', null)
   }
+
+  // 进入搜索结果页
+  router2BookSearchResultPage(key: string){
+    this.pushPathByName('BookSearchResultPage', key)
+  }
 }
 
 export const yTRouter = YTRouter.getInstance()

+ 1 - 1
features/feature/src/main/ets/apis/ApiUrl.ets

@@ -21,7 +21,7 @@ export class ApiUrl {
    * @description 获取所有的主题分类集合
    * @method GET
    */
-  static getAllThemes = '/api/book/bookListType/getAllBookListType';
+  static getAllThemes = 'api/book/bookType/getAllBookType';
 
   /**
    * @description 搜索图书

+ 1 - 1
features/feature/src/main/ets/components/BuilderIndex.ets

@@ -89,7 +89,7 @@ export function bookItemCompCover(item: RepeatItem<BookItem>, onClick: () => voi
 
 
 
-// 书籍Item
+// 书籍Item - 列表模式
 @Builder
 export function bookItemComp(item: RepeatItem<BookItem>, onClick: () => void, onAddCar?: () => void){
   Row({space: 11}){

+ 4 - 5
features/feature/src/main/ets/components/DeerSearch.ets

@@ -8,8 +8,6 @@ export struct DeerSearch {
   @Param showSearchButton: boolean = true
 
   @Event onSearch: (text: string) => void
-  @Event onChange: (text: string) => void
-
 
   @Local searchKey: string = ''
 
@@ -18,7 +16,9 @@ export struct DeerSearch {
   }
 
   onSubmit(){
-    this.onSearch(this.searchKey)
+    if(this.onSearch) {
+      this.onSearch(this.searchKey)
+    }
     this.searchKey = ''
   }
 
@@ -33,13 +33,12 @@ export struct DeerSearch {
         TextInput({text: $$this.searchKey, placeholder: '搜索图书/书单'})
           .padding(0)
           .fontSize(12)
-          // .maxLength(20)
           .fontWeight(400)
           .layoutWeight(1)
           .borderRadius(0)
           .border({ width: 0 })
           .enabled(this.enable)
-          .onSubmit(this.onSubmit)
+          .onSubmit(()=>{ this.onSubmit() })
           .backgroundColor(Color.Transparent)
           .placeholderFont({size: 12, weight: 400})
           .placeholderColor(this.enable ? '#B5B8BC' : Color.Black)

+ 1 - 1
features/feature/src/main/ets/components/ytBuildComp.ets → features/feature/src/main/ets/components/ytComp/ytBuildComp.ets

@@ -1,6 +1,6 @@
 import { EmitterKeyCollection, userInfo, yTRouter } from "basic"
 import { emitter } from "@kit.BasicServicesKit"
-import { CustomTextStyle } from "../style/CustomTextStyle"
+import { CustomTextStyle } from "../../style/CustomTextStyle"
 
 @ComponentV2
 export struct ytBuildComp {

+ 35 - 0
features/feature/src/main/ets/components/ytComp/ytEmptyComp.ets

@@ -0,0 +1,35 @@
+import { CustomTextStyle } from "../../style/CustomTextStyle"
+
+@ComponentV2
+export struct ytEmptyComp {
+  @BuilderParam container: () => void
+
+  @Param @Require dataSource: Array<ESObject>
+  @Param keyStr: string = '书籍'
+
+  build() {
+    Column() {
+      if(this.dataSource.length == 0) {
+        Image($r('[basic].media.png_empty_0'))
+          .width(139)
+          .height(148)
+          .margin({top: 100})
+
+        Text(`未搜索到相关书籍${this.keyStr},${'\n'}` +
+          '换个关键词试试吧!')
+          .margin({top: 10})
+          .textAlign(TextAlign.Center)
+          .attributeModifier(new CustomTextStyle({size: 14, weight: 400, color: '#80000000'}))
+      } else {
+        if(this.container){
+          this.container()
+        }
+      }
+    }
+    .width("100%")
+    .height("100%")
+    .backgroundColor(Color.Transparent)
+    .alignItems(HorizontalAlign.Center)
+    .justifyContent(FlexAlign.Start)
+  }
+}

+ 1 - 1
features/feature/src/main/ets/model/BookModelIndex.ets

@@ -66,7 +66,7 @@ export class BookListTypeList {
   /** 排序 */
   sort?: string;
   /** 分类名称 */
-  bookListTypeName?: string;
+  typeName?: string;
   /** 创建人 */
   createBy?: string;
   /** 创建时间 */

+ 1 - 1
features/feature/src/main/ets/model/Storage.ets

@@ -56,7 +56,7 @@ export class BookCategoryStorage{
 
     ans.sort((a, b) => a.sort! > b.sort! ? 1 : -1)
     this.list = []
-    this.list.push({ bookListTypeName: "全部" }, ...ans)
+    this.list.push({ typeName: "全部" }, ...ans)
     console.log(`书籍分类 = ${JSON.stringify(this.list)}`)
   }
 }

+ 5 - 4
features/feature/src/main/ets/pages/BookList/BookSearchPage.ets

@@ -1,4 +1,4 @@
-import { YTAvoid, YTHeader, YTRequest } from 'basic'
+import { YTAvoid, YTHeader, YTRequest, yTRouter } from 'basic'
 import { DeerSearch } from '../../components/DeerSearch'
 import { CustomTextStyle } from '../../style/CustomTextStyle'
 import { LengthMetrics, PersistenceV2 } from '@kit.ArkUI'
@@ -26,10 +26,11 @@ struct BookSearchPage {
 
   // 开始搜索
   onSearch(text: string) {
-    if(!text) return
-
-    this.searHistory.increaseKey(text.trim())
+    let key = text.trim()
+    if(!key) return
 
+    this.searHistory.increaseKey(key)
+    yTRouter.router2BookSearchResultPage(key)
   }
 
   // 获取最热词条

+ 108 - 0
features/feature/src/main/ets/pages/BookList/BookSearchResultPage.ets

@@ -0,0 +1,108 @@
+import { BookItem, YTHeader } from 'basic'
+import { bookItemComp, bookListItemComp } from '../../components/BuilderIndex';
+import { ytEmptyComp } from '../../components/ytComp/ytEmptyComp';
+import { BookListItem } from '../../model/BookModelIndex';
+import { CustomTextStyle } from '../../style/CustomTextStyle';
+import { BookSearchResultViewModel } from '../viewModel/BookSearchResultViewModel';
+
+@ComponentV2
+struct BookSearchResultPage {
+  @Param @Require vm: BookSearchResultViewModel;
+
+  build() {
+    NavDestination() {
+      Column() {
+        YTHeader({ defaultStyle: {title: '搜索'}, bgc: Color.White })
+
+        Row({space: 130}){
+          ForEach(['图书', '书单'], (item: string, index) => {
+            Column(){
+              Text(item + `(${index == 0 ? this.vm.book.length : this.vm.bookList.length})`)
+                .zIndex(99)
+                .onClick(() => { this.vm.changeCategory(index) })
+                .attributeModifier(new CustomTextStyle({size: 16, weight: 600, color: this.vm.categoryIndex == index ? '#FF111111' : '#FF777777'}))
+
+              if(this.vm.categoryIndex == index){
+                Image($r('[basic].media.icon_SelectBg'))
+                  .width(45)
+                  .height(16)
+                  .margin({top:-10})
+                  .transition(TransitionEffect.translate({ y: -10 })
+                    .animation({ duration: 100, curve: Curve.Friction}))
+              }
+            }
+            .height(30)
+            .width(120)
+            .alignItems(HorizontalAlign.Center)
+          })
+        }
+        .height(80)
+        .width('100%')
+        .backgroundColor(Color.White)
+        .padding({top: 10})
+        .justifyContent(FlexAlign.Center)
+        .borderRadius({bottomLeft: 8, bottomRight: 8})
+
+        Tabs({controller: this.vm.tabControl}){
+          TabContent(){
+            this.BookItemList()
+          }
+
+          TabContent(){
+            this.BookList()
+          }
+        }.width('100%')
+        .layoutWeight(1)
+        .barHeight(0)
+      }
+      .width('100%').height('100%')
+      .backgroundColor('#F7F9FA')
+    }
+    .hideTitleBar(true)
+  }
+
+  // 书籍列表
+  @Builder
+  BookItemList() {
+    ytEmptyComp({ dataSource: this.vm.book, keyStr: '书籍' }){
+      List({space: 16}){
+        ListItem()
+
+        Repeat(this.vm.book)
+          .each((item: RepeatItem<BookItem>) => {
+            ListItem(){
+              bookItemComp(item, () => {}, () => {})
+            }
+          })
+
+        ListItem()
+      }.width('100%').height('100%')
+      .padding({left: 17, right: 17})
+    }
+  }
+
+  // 书单列表
+  @Builder
+  BookList() {
+    ytEmptyComp({ dataSource: this.vm.bookList, keyStr: '书单' }){
+      List({space: 16}){
+        ListItem()
+
+        Repeat(this.vm.bookList)
+          .each((item: RepeatItem<BookListItem>) => {
+            ListItem(){
+              bookListItemComp(item)
+            }
+          })
+
+        ListItem()
+      }.width('100%').height('100%')
+      .padding({left: 17, right: 17})
+    }
+  }
+}
+
+@Builder
+function BookSearchResultBuilder(_: string, key: string) {
+  BookSearchResultPage({ vm: new BookSearchResultViewModel(key) })
+}

+ 63 - 0
features/feature/src/main/ets/pages/viewModel/BookSearchResultViewModel.ets

@@ -0,0 +1,63 @@
+import { BookItem } from "basic";
+import { bookListApi } from "../../apis/BookListApi";
+import { BookListItem } from "../../model/BookModelIndex";
+import { PageResponse } from "../../model/PageResponse";
+import { searchBookListQuery, searchBookQuery } from "../../model/Query";
+
+@ObservedV2
+export class BookSearchResultViewModel{
+  @Trace categoryIndex: number = 0;
+  // 书单
+  @Trace bookList: BookListItem[] = []
+  // 书籍
+  @Trace book: BookItem[] = []
+
+
+  // 书单查询器
+  bookListQuery: searchBookListQuery = new searchBookListQuery()
+  // 书籍查询器
+  booksQuery: searchBookQuery = new searchBookQuery()
+  tabControl: TabsController = new TabsController()
+
+  constructor(key: string) {
+    this.bookListQuery.key = key
+    this.booksQuery.key = key
+
+    this.getBookList()
+    this.getBooks()
+  }
+
+  // 切换选中的显示模式
+  changeCategory(index: number) {
+    if(this.categoryIndex === index) return
+
+    this.categoryIndex = index
+    this.tabControl.changeIndex(index)
+  }
+
+
+  // 获取书单列表
+  async getBookList(isReload: boolean = true) {
+    if(isReload) {
+      this.bookListQuery.reload()
+    } else {
+      this.bookListQuery.reachEnd()
+    }
+
+    try {
+      let ans = await bookListApi.searchBookList(this.bookListQuery)
+
+      this.bookList = [...ans?.list ?? []]
+
+      console.log(`书单列表数据 = ${JSON.stringify(ans)}`)
+    } catch (e) {
+    }
+  }
+
+  // 获取书籍列表
+  async getBooks() {
+    let ans: PageResponse<BookItem> = await bookListApi.searchBooks(this.booksQuery.clone())
+    this.book = ans.list ?? []
+    console.log(`获取书籍列表 = ${JSON.stringify(this.bookList)}`)
+  }
+}

+ 1 - 1
features/feature/src/main/ets/view/MainView.ets

@@ -1,7 +1,7 @@
 import { BasicType, yTRouter } from "basic"
 import { tagItemComp } from "../components/BuilderIndex"
 import { DeerSearch } from "../components/DeerSearch"
-import { ytBuildComp } from "../components/ytBuildComp"
+import { ytBuildComp } from "../components/ytComp/ytBuildComp"
 import { CustomTextStyle } from "../style/CustomTextStyle"
 import { MainViModel } from "./viewModel/MainViewModel"
 

+ 2 - 2
features/feature/src/main/ets/view/SecondView.ets

@@ -50,7 +50,7 @@ export struct SecondView {
                     ForEach(this.vm.categoryList.list, (item: BookListTypeList, index) => {
                       ListItem(){
                         Column(){
-                          Text(item.bookListTypeName)
+                          Text(item.typeName)
                             .zIndex(99)
                             .onClick(() => { this.vm.changeCategory(index) })
                             .attributeModifier(new CustomTextStyle({size: 16, weight: 600, color: this.vm.categoryIndex == index ? '#FF111111' : '#FF777777'}))
@@ -193,7 +193,7 @@ export struct SecondView {
                 Grid(){
                   ForEach(this.vm.categoryList.list, (item: BookListTypeList, index: number) => {
                     GridItem(){
-                      Text(item.bookListTypeName)
+                      Text(item.typeName)
                         .width('100%')
                         .borderRadius(18)
                         .textAlign(TextAlign.Center)

+ 1 - 1
features/feature/src/main/ets/view/viewModel/SecondViewModel.ets

@@ -9,7 +9,7 @@ import { PageResponse } from "../../model/PageResponse"
 export class SecondViewModel{
   @Trace safeTop: number = AppStorage.get(YTAvoid.SAFE_TOP_KEY) as number
 
-  // 书列表
+  // 书列表
   @Trace bookList: BookItem[] = []
   // 分类索引
   @Trace categoryIndex: number = 0

+ 5 - 0
features/feature/src/main/resources/base/profile/router_map.json

@@ -59,6 +59,11 @@
       "name": "ReserveReturnPage",
       "pageSourceFile": "src/main/ets/pages/Order/ReserveReturnPage.ets",
       "buildFunction": "ReserveReturnBuilder"
+    },
+    {
+      "name": "BookSearchResultPage",
+      "pageSourceFile": "src/main/ets/pages/BookList/BookSearchResultPage.ets",
+      "buildFunction": "BookSearchResultBuilder"
     }
   ]
 }