瀏覽代碼

feat: 为列表加载添加触底加载更多逻辑

YuJing 1 月之前
父節點
當前提交
7ab316bc68

+ 3 - 2
features/feature/src/main/ets/apis/BookListApi.ets

@@ -41,13 +41,14 @@ class BookListApi {
    * @description 搜索图书
    * @method POST
    */
-  async searchBooks(params: searchBookQuery): Promise<Array<BookItem>>{
+  async searchBooks(params: searchBookQuery): Promise<PageResponse<BookItem>>{
     let ans = await YTRequest.post<PageResponse<BookItem>, searchBookQuery>(ApiUrl.searchBooks, params)
     let list: Array<BookItem> = []
     ans.list?.forEach(item => {
       list.push(new BookItem(item))
     })
-    return list
+    ans.list = list
+    return ans
   }
 
   /**

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

@@ -15,7 +15,7 @@ export function tagItemComp(text: string, fontColor: ResourceColor, bgColor: Res
 }
 
 
-// todo 跳转事件在 Builder 内部实现, 添加购物车事件交给 vm
+
 // 书单Item
 @Builder
 export function bookListItemComp(item: RepeatItem<BookListItem>){

+ 0 - 16
features/feature/src/main/ets/model/Address.ets

@@ -49,20 +49,4 @@ export interface Address {
    */
   updateTime?: string;
 
-
-  // // todo
-  // constructor(data?: Address) {
-  //   if (data) {
-  //     this.id = data.id;
-  //     this.userId = data.userId;
-  //     this.userName = data.userName;
-  //     this.phone = data.phone;
-  //     this.region = data.region;
-  //     this.address = data.address;
-  //     this.createBy = data.createBy;
-  //     this.createTime = data.createTime;
-  //     this.updateBy = data.updateBy;
-  //     this.updateTime = data.updateTime;
-  //   }
-  // }
 }

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

@@ -16,7 +16,7 @@ abstract class Query{
 
   // 触底加载更多
   reachEnd(sourceLength: number): boolean {
-    if(sourceLength < this.pageSize) {
+    if(sourceLength < this.total) {
       this.pageNum++
       return true
     }

+ 1 - 1
features/feature/src/main/ets/pages/Address/IncreaseAddressPage.ets

@@ -168,7 +168,7 @@ struct IncreaseAddressPage {
           .borderRadius(8)
           .backgroundColor(Color.White)
 
-          // todo 是否保留
+          // todo 默认地址是否保留
           if(true) {
             Row(){
               Text('设为默认地址')

+ 9 - 2
features/feature/src/main/ets/pages/BookList/BookListDetailPage.ets

@@ -11,7 +11,14 @@ import { BookListDetailViewModel } from '../viewModel/BookListDetailViewModel';
 @ComponentV2
 @RouterPage
 struct BookListDetailPage {
-  @Param @Require vm: BookListDetailViewModel;
+  @Param @Require item: BookListItem
+
+  vm: BookListDetailViewModel = {} as ESObject;
+
+  aboutToAppear(): void {
+    this.vm = new BookListDetailViewModel(this.item);
+  }
+
 
   build() {
     NavDestination() {
@@ -137,5 +144,5 @@ struct BookListDetailPage {
 
 @Builder
 function BookListDetailBuilder(_: string, item: BookListItem) {
-  BookListDetailPage({ vm: new BookListDetailViewModel(item) })
+  BookListDetailPage({ item })
 }

+ 3 - 0
features/feature/src/main/ets/pages/BookList/BookListPage.ets

@@ -85,6 +85,9 @@ struct BookListPage {
           .width("100%")
           .height("100%")
           .scrollBar(BarState.Off)
+          .onReachEnd(() => {
+            if(this.vm.bookList.length > 0) this.vm.getBookList(false)
+          })
         }
         .width("100%")
         .layoutWeight(1)

+ 11 - 3
features/feature/src/main/ets/pages/BookList/BookSearchResultPage.ets

@@ -11,7 +11,12 @@ import { BookSearchResultViewModel } from '../viewModel/BookSearchResultViewMode
  */
 @ComponentV2
 struct BookSearchResultPage {
-  @Param @Require vm: BookSearchResultViewModel;
+  @Param @Require keyWord: string;
+  vm: BookSearchResultViewModel = {} as ESObject;
+
+  aboutToAppear(): void {
+    this.vm = new BookSearchResultViewModel(this.keyWord)
+  }
 
   build() {
     NavDestination() {
@@ -87,6 +92,9 @@ struct BookSearchResultPage {
         ListItem()
       }.width('100%').height('100%')
       .padding({left: 17, right: 17})
+      .onReachEnd(() => {
+        if(this.vm.book.length > 0) this.vm.getBookList(false)
+      })
     }
   }
 
@@ -112,6 +120,6 @@ struct BookSearchResultPage {
 }
 
 @Builder
-function BookSearchResultBuilder(_: string, key: string) {
-  BookSearchResultPage({ vm: new BookSearchResultViewModel(key) })
+function BookSearchResultBuilder(_: string, keyWord: string) {
+  BookSearchResultPage({ keyWord })
 }

+ 3 - 1
features/feature/src/main/ets/pages/Order/InitiatePayPage.ets

@@ -8,7 +8,9 @@ import { GetUnifiedPayInfoRequestData, OrderPayResultData } from '../../model/Or
 import { OrderApi } from '../../apis/OrderApi'
 import { PageState } from '../../model/EnumState'
 
-
+/**
+ * 支付页面
+ */
 @Component
 struct InitiatePayPage {
   @Require orderId: string

+ 1 - 1
features/feature/src/main/ets/pages/Order/OrderConfirmPage.ets

@@ -97,7 +97,7 @@ struct OrderConfirmPage {
   @Builder
   AddressBuilder() {
     ListItem(){
-      // todo 订单地址校验
+      // 订单地址校验
       if(this.vm.address?.phone) {
         AddressItemComp({type: 0, address: this.vm.address, click: () => { this.openAddressDialog() }})
       } else {

+ 4 - 4
features/feature/src/main/ets/pages/Order/OrderDetailPage.ets

@@ -76,9 +76,9 @@ struct OrderDetailPage {
 
         // todo 不同订单下的按钮显示不同的
         Row(){
-          buttonComp('联系客服', '100%', 10, new CustomTextStyle({size: 18}), () => {
-            this.vm.gotoCustomerService()
-          })
+          // buttonComp('联系客服', '100%', 10, new CustomTextStyle({size: 18}), () => {
+          //   this.vm.gotoCustomerService()
+          // })
         }
         .width('100%')
         .backgroundColor(Color.White)
@@ -99,7 +99,7 @@ struct OrderDetailPage {
   @Builder
   AddressBuilder() {
     ListItem(){
-      // todo 订单地址校验
+      // 订单地址
       if(this.vm.address?.phone) {
         AddressItemComp({type: 0, address: this.vm.address})
       }

+ 10 - 8
features/feature/src/main/ets/pages/viewModel/BookListViewModel.ets

@@ -58,24 +58,26 @@ export class BookListViewModel{
   }
 
   // 获取书单列表
-  // todo 列表加载待完善
   async getBookList(isReload: boolean = true) {
     if(isReload) {
       this.query.reload()
     } else {
-      // if()
-
-      // this.query.reachEnd()
+      if (!this.query.reachEnd(this.bookList.length)) return
     }
 
     try {
       let ans = await bookListApi.searchBookList(this.query)
 
-      this.bookList = [...ans?.list ?? []]
-
-      console.log(`书单列表数据 = ${JSON.stringify(ans)}`)
+      this.query.setTotal(ans.total)
+      if (isReload) {
+        this.bookList = [...ans?.list ?? []]
+      } else {
+        this.bookList = [...this.bookList, ...ans?.list ?? []]
+      }
     } catch (e) {
-
+      if (isReload) {
+        this.query.backPage()
+      }
     }
   }
 }

+ 56 - 10
features/feature/src/main/ets/pages/viewModel/BookSearchResultViewModel.ets

@@ -36,28 +36,74 @@ export class BookSearchResultViewModel{
 
 
   // 获取书单列表
-  // todo 列表加载待完善
   async getBookList(isReload: boolean = true) {
     if(isReload) {
       this.bookListQuery.reload()
     } else {
-      // this.bookListQuery.reachEnd()
+      if(!this.bookListQuery.reachEnd(this.bookList.length)) return
     }
 
     try {
       let ans = await bookListApi.searchBookList(this.bookListQuery)
 
-      this.bookList = [...ans?.list ?? []]
-
-      console.log(`书单列表数据 = ${JSON.stringify(ans)}`)
+      this.bookListQuery.setTotal(ans?.total)
+      if(isReload) {
+        this.bookList = [...ans?.list ?? []]
+      } else {
+        this.bookList = [...this.bookList, ...ans?.list ?? []]
+      }
     } catch (e) {
+      if(!isReload){
+        this.bookListQuery.backPage()
+      }
     }
   }
 
   // 获取书籍列表
-  async getBooks() {
-    this.book = await bookListApi.searchBooks(this.booksQuery.clone())
-    // this.book = ans.list ?? []
-    console.log(`获取书籍列表 = ${JSON.stringify(this.bookList)}`)
+  async getBooks(isReload: boolean = true) {
+
+    if (isReload) {
+      this.booksQuery.reload()
+    } else {
+      if (!this.booksQuery.reachEnd(this.book.length)) return
+    }
+
+
+    try {
+      let ans = await bookListApi.searchBooks(this.booksQuery.clone())
+      this.booksQuery.setTotal(ans.total)
+      if (isReload) {
+        this.book = [...ans?.list ?? []]
+      } else {
+        this.book = [...this.book, ...ans?.list ?? []]
+      }
+    } catch (err) {
+      if (!isReload) {
+        this.booksQuery.backPage()
+      }
+    }
   }
-}
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 1 - 0
features/feature/src/main/ets/pages/viewModel/OrderManagementViewModel.ets

@@ -38,6 +38,7 @@ export class OrderManagementViewModel{
       this.query.statusCode = this.orderStatus[index-1]
     }
 
+    this.isLoading = false
     this.onRefreshing(index)
   }
 

+ 4 - 1
features/feature/src/main/ets/view/SecondView.ets

@@ -136,13 +136,16 @@ export struct SecondView {
                       addCar: () => {}
                     })
                   })
-                  .key((item: BookItem) => `${item?.id}${item?.schoolbagFlag}${item.bookTitle}`)
+                  .key((item: BookItem) => JSON.stringify(item))
 
                 ListItem()
               }
               .width("100%")
               .height("100%")
               .scrollBar(BarState.Off)
+              .onReachEnd(() => {
+                if(this.vm.bookList.length > 0) { this.vm.getBookList(true) }
+              })
             }
             .id('list')
             .width("100%")

+ 5 - 0
features/feature/src/main/ets/view/ThirdView.ets

@@ -240,6 +240,11 @@ export struct ThirdView {
     }
     .width("100%").height("100%")
     .scrollBar(BarState.Off)
+    .onReachEnd(() => {
+      if(this.vm.bookList.length > 0) {
+        this.vm.getBagBookList(false)
+      }
+    })
   }
 
   @Builder

+ 3 - 2
features/feature/src/main/ets/view/viewModel/MainViewModel.ets

@@ -39,8 +39,9 @@ export class MainViModel{
 
   async getNewBookList(){
     let query: searchBookQuery = new searchBookQuery()
-
-    this.newBookList = (await bookListApi.searchBooks(query.clone())).slice(0, 4)
+    // todo
+    let ans = await bookListApi.searchBooks(query.clone())
+    this.newBookList = ans.list?.slice(0, 4) ?? []
   }
 
 }

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

@@ -33,6 +33,7 @@ export class SecondViewModel{
 
   ageList: string[] = ['年龄选择', '0-2岁', '3-6岁', '7-10岁', '10岁+']
 
+  isLoading: boolean = false
 
   constructor() {
     this.changeCategory(0)
@@ -117,9 +118,34 @@ export class SecondViewModel{
   }
 
   // 获取书籍列表
-  async getBookList() {
-    this.bookList = await bookListApi.searchBooks(this.query.clone())
+  async getBookList(isReachEnd: boolean = false) {
+    if(this.isLoading) return
+    this.isLoading = true
 
-    console.log(`获取书籍列表 = ${JSON.stringify(this.bookList)}`)
+    if(isReachEnd) {
+      if(!this.query.reachEnd(this.bookList.length)) return
+    } else {
+      this.query.reload()
+    }
+
+    try {
+      let ans = await bookListApi.searchBooks(this.query.clone())
+
+      this.query.setTotal(ans.total)
+
+      if(isReachEnd) {
+        this.bookList.push(...ans.list ?? [])
+      } else {
+        this.bookList = [...ans.list ?? []]
+      }
+
+      console.log(`获取书籍列表 = ${JSON.stringify(this.bookList)}`)
+    } catch (err) {
+      if(isReachEnd) {
+        this.query.backPage()
+      }
+    } finally {
+      this.isLoading = false
+    }
   }
 }

+ 22 - 4
features/feature/src/main/ets/view/viewModel/ThirdViewModel.ets

@@ -137,10 +137,28 @@ export class ThirdViewModel{
   }
 
   // 获取书包内的书本
-  async getBagBookList(){
-    let ans: PageResponse<BookItem> = await OrderApi.getBagBookList(this.query)
+  async getBagBookList(isReload: boolean = true){
+    if (isReload) {
+      this.query.reload()
+    } else {
+      if(!this.query.reachEnd(this.bookList.length)) return
+    }
+
+    try {
+      let ans: PageResponse<BookItem> = await OrderApi.getBagBookList(this.query)
+
+      this.query.setTotal(ans.total)
+
+      if (isReload) {
+        this.bookList = [...ans.list ?? []]
+      } else {
+        this.bookList.push(...ans.list ?? [])
+      }
+    } catch (err) {
+      if (isReload) {
+       this.query.backPage()
+      }
+    }
 
-    this.bookList = [...ans.list ?? []]
-    console.log(`书包内的书本 = ${JSON.stringify(ans)}`)
   }
 }

+ 13 - 8
features/feature/src/main/resources/rawfile/index.html

@@ -1,9 +1,14 @@
-<!DOCTYPE html> <html><body>
+<!DOCTYPE html>
+<html>
+<body style="font-size:16px;color:rgba(0,0,0,0.6);flex-shrink:0;font-style:normal;font-weight:normal;background-color:rgb(255, 255, 255);">
 
-<form name="punchout_form" method="post" action="https://openapi.alipay.com/gateway.do?alipay_sdk=OpenAPI-Generator%2F3.1.0.ALL%2Fjava&charset=UTF-8&method=alipay.trade.wap.pay&format=json&sign=OugRSBEB8tyZLmtlMDVYVw0j0NbCYAQlvBkTGBTh%2BlAcch3nCbGl2C220CgqisE%2BpLQNbtqgMsUHtnwVE4znPPNQ7zyU0WTc02uD9YMwK7SobTBpgbwBaZxXvs04tSuGN4oXbObov2vWdsgofQqTmACfE5ukRVJp7v82gq7uqFUI55NGj8OzrTohHDda3GwnIY%2BtnPItxBaOmyknZRvCkmnDNY%2BpxD8qCk7fGR0wrGBjI5E%2B%2BmwNIoN4cfnx4b%2BvWLMxYm2q12VEeURyz731OtpCR66CNBEqnIxEWSEMOpqvLCQBDRE2E12fOiq0obfP98wcwgFf1QkR3qMAiV%2FIHA%3D%3D&app_id=2021004172698934&version=1.0&sign_type=RSA2&timestamp=2025-11-13+14%3A42%3A43">
-    <input type="hidden" name="biz_content" value="{&quot;time_expire&quot;:&quot;2025-11-13 14:57:43&quot;,&quot;out_trade_no&quot;:&quot;16&quot;,&quot;quit_url&quot;:&quot;https://hm-test.ytpm.net/prod-book/api/book/order/zfb/quit&quot;,&quot;total_amount&quot;:&quot;17.99&quot;,&quot;subject&quot;:&quot;直租下单&quot;,&quot;product_code&quot;:&quot;QUICK_WAP_WAY&quot;,&quot;passback_params&quot;:&quot;&quot;}">
-    <input type="hidden" name="notify_url" value="https://hm-test.ytpm.net/prod-book/api/book/order/zfb/notify">
-    <input type="submit" value="立即支付" style="display:none" >
-</form>
-<script>document.forms[0].submit();</script>
-</body></html>
+<div id="content"></div>
+<script>
+    function writeHtml(str) {
+      const el = document.querySelector('#content');
+      el.innerHTML = str;
+    }
+</script>
+
+</body>
+</html>