Преглед на файлове

feat: 完成 购物车 页面相关交互和接口

YuJing преди 1 месец
родител
ревизия
2de268faf4

+ 0 - 2
commons/basic/src/main/ets/models/BookModel.ets

@@ -61,6 +61,4 @@ export class BookItem {
   typeName?: string;
   /** 是否加入购物车 0-未加入 1-已加入 */
   @Trace schoolbagFlag?: string;
-
-
 }

+ 19 - 0
features/feature/src/main/ets/apis/ApiUrl.ets

@@ -28,4 +28,23 @@ export class ApiUrl {
    * @method POST
    */
   static searchBooks = '/api/book/information/searchBook';
+
+
+  /**
+   * @description 获取书包里面的书本数据
+   * @method POST
+   */
+  static getBooksInBag = '/api/book/bookSchoolbag/getBookPage';
+
+  /**
+   * @description 添加图书到书包
+   * @method POST
+   */
+  static addBookToBag = '/api/book/bookSchoolbag/addBook';
+
+  /**
+   * @description 移除书包里面的图书
+   * @method POST
+   */
+  static removeBookFromBag = '/api/book/bookSchoolbag/removeBook';
 }

+ 32 - 0
features/feature/src/main/ets/apis/OrderApi.ets

@@ -0,0 +1,32 @@
+import { BookItem, YTRequest } from "basic";
+import { PageResponse } from "../model/PageResponse";
+import { bookPackageQuery } from "../model/Query";
+import { ApiUrl } from "./ApiUrl";
+
+export class OrderApi {
+  /**
+   * @description 获取书包内的书本
+   * @method POSt
+   */
+  static getBagBookList(param: bookPackageQuery): Promise<PageResponse<BookItem>> {
+    return YTRequest.post<PageResponse<BookItem>, bookPackageQuery>(ApiUrl.getBooksInBag, param)
+  }
+
+  /**
+   * @description 添加图书到书包
+   * @method POSt
+   */
+  static addBookToBag(bookId: string): Promise<ESObject> {
+    return YTRequest.post<ESObject>(ApiUrl.addBookToBag, {bookId})
+  }
+
+  /**
+   * @description 移除书包内的图书
+   * @param bookIds
+   * @returns
+   */
+  static removeBookFromBag(bookIds: string[]): Promise<ESObject> {
+    return YTRequest.post<ESObject>(ApiUrl.removeBookFromBag, {bookIds})
+  }
+
+}

+ 8 - 1
features/feature/src/main/ets/components/BookItemComp.ets

@@ -7,6 +7,7 @@ export struct BookItemComp {
   @Param @Require item: BookItem
   // 是否为列表模式, true - 列表模式 false - 封面模式
   @Param showModel: boolean = true
+  @Param schoolbagFlag: string = '0'
 
   @Event addCar: () => void
 
@@ -14,6 +15,12 @@ export struct BookItemComp {
     yTRouter.router2BookItemDetailPage(this.item)
   }
 
+  @Monitor('schoolbagFlag')
+  minor(){
+    console.log(`this.schoolbagFlag = ${JSON.stringify(this.schoolbagFlag)}`)
+  }
+
+
   build() {
     if(this.showModel) {
       this.bookItemComp()
@@ -81,7 +88,7 @@ export struct BookItemComp {
           tagItemComp('情绪价值', '#FF4EB1EF', '#FFEDF7FD')
         }
 
-        Image(this.item.schoolbagFlag == '0' ? $r('[basic].media.icon_deerIncrease') : $r('[basic].media.icon_reduce'))
+        Image(this.schoolbagFlag == '0' ? $r('[basic].media.icon_deerIncrease') : $r('[basic].media.icon_reduce'))
           .width(24)
           .aspectRatio(1)
           .onClick(() => {

+ 8 - 0
features/feature/src/main/ets/model/Query.ets

@@ -56,3 +56,11 @@ export class searchBookQuery extends Query {
     } as ESObject
   }
 }
+
+
+/** 书包里的书本数据 */
+@ObservedV2
+export class bookPackageQuery extends Query{
+  //  0代表全部 1代表可借 2代表已借光
+  flag: number = 0;
+}

+ 37 - 16
features/feature/src/main/ets/pages/BookList/BookSearchPage.ets

@@ -1,9 +1,9 @@
 import { YTAvoid, YTHeader, YTRequest, yTRouter } from 'basic'
 import { DeerSearch } from '../../components/DeerSearch'
 import { CustomTextStyle } from '../../style/CustomTextStyle'
-import { LengthMetrics, PersistenceV2 } from '@kit.ArkUI'
-import { HistoryStorage } from '../../model/Storage'
-import { HotSearchItem } from '../../model/BookModelIndex'
+import { AppStorageV2, LengthMetrics, PersistenceV2 } from '@kit.ArkUI'
+import { BookCategoryStorage, HistoryStorage } from '../../model/Storage'
+import { BookListTypeList, HotSearchItem } from '../../model/BookModelIndex'
 import { bookListApi } from '../../apis/BookListApi'
 
 // 书籍搜索页面
@@ -18,6 +18,9 @@ struct BookSearchPage {
 
   // 搜索历史记录
   searHistory: HistoryStorage = PersistenceV2.connect(HistoryStorage, () => new HistoryStorage())!
+  // 分类列表
+  @Local categoryList: BookListTypeList[] = []
+
 
   // 清空历史记录
   clearHistory() {
@@ -36,6 +39,10 @@ struct BookSearchPage {
   // 获取最热词条
   async getHotSearchKeys() {
     this.hotSearchKeys = await bookListApi.getHotSearchRecords()
+
+    let list = AppStorageV2.connect(BookCategoryStorage, () => new BookCategoryStorage())!
+    this.categoryList = [...list.list]
+    this.categoryList.splice(0, 1)
   }
 
   aboutToAppear(): void {
@@ -109,19 +116,17 @@ struct BookSearchPage {
                         .width('90%')
                         .margin({left: 15, top: 13, bottom: 13})
 
-                      ForEach(this.hotSearchKeys, (item: HotSearchItem, index) => {
-                       Row({space: 5}){
-                         Text(`${index<9?' ':''}${index+1}`)
-                           .attributeModifier(new CustomTextStyle({ size: 14, weight: 400, color: index < 3 ? '#FFFC3636' : '#FF000000'}))
-
-                         Text(item.keyWord)
-                           .attributeModifier(new CustomTextStyle({ size: 14, weight: 400, color: index < 3 ? '#FF000000' : '#80000000'}))
-                       }
-                       .width('100%')
-                       .margin({top: 12})
-                       .justifyContent(FlexAlign.Start)
-                        .onClick(() => { this.onSearch(item.keyWord ?? '') })
-                      })
+                      if(index == 0) {
+                        ForEach(this.hotSearchKeys, (item_: HotSearchItem, index) => {
+                          this.searchKeyItem(item_.keyWord ?? '', index)
+                        })
+                      } else {
+                        ForEach(this.categoryList, (item_: BookListTypeList, index) => {
+                          this.searchKeyItem(item_.typeName ?? '', index)
+                        })
+                      }
+
+
                     }
                     .width(230)
                     .borderRadius(8)
@@ -130,6 +135,7 @@ struct BookSearchPage {
                     .padding({left: 10, right: 10, top: 13, bottom: 13})
                   })
                 }
+                .alignItems(VerticalAlign.Top)
               }
               .scrollBar(BarState.Off)
               .scrollable(ScrollDirection.Horizontal)
@@ -156,6 +162,21 @@ struct BookSearchPage {
     .hideTitleBar(true)
   }
 
+  @Builder
+  searchKeyItem(item: string, index: number){
+    Row({space: 5}){
+      Text(`${index<9?' ':''}${index+1}`)
+        .attributeModifier(new CustomTextStyle({ size: 14, weight: 400, color: index < 3 ? '#FFFC3636' : '#FF000000'}))
+
+      Text(item)
+        .attributeModifier(new CustomTextStyle({ size: 14, weight: 400, color: index < 3 ? '#FF000000' : '#80000000'}))
+    }
+    .width('100%')
+    .margin({top: 12})
+    .justifyContent(FlexAlign.Start)
+    .onClick(() => { this.onSearch(item ?? '') })
+  }
+
 }
 
 @Builder

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

@@ -4,6 +4,7 @@ import { CustomTextStyle } from '../style/CustomTextStyle'
 import { BookListTypeList } from '../model/BookModelIndex'
 import { BookItem } from 'basic'
 import { BookItemComp } from '../components/BookItemComp'
+import { OrderApi } from '../apis/OrderApi'
 
 @ComponentV2
 export struct SecondView {
@@ -128,18 +129,25 @@ export struct SecondView {
               List({space: 12}){
                 // ListItem()
 
+                // todo 找到 repeat 不刷新的原因
                 // Repeat(this.vm.bookList)
                 //   .each((item: RepeatItem<BookItem>) => {
-                //     BookItemComp({item: item.item, showModel: this.vm.showMode == 1,addCar: () => {
-                //       item.item.schoolbagFlag = '1'
-                //       this.vm.bookList.splice(item.index, 1, item.item)
+                //     BookItemComp({
+                //       item: item.item,
+                //       showModel: this.vm.showMode == 1,
+                //       schoolbagFlag: item.item.schoolbagFlag,
+                //       addCar: () => {
+                //         item.item.schoolbagFlag = '1'
+                //         this.vm.bookList.splice(item.index, 1, item.item)
+                //         // OrderApi.addBookToBag(item.id!)
                 //     }})
                 //   })
-                //   .key((item: BookItem) => JSON.stringify(item))
+                //   .key((item: BookItem) => `${item?.id}${item?.schoolbagFlag}${item.bookTitle}`)
                 ForEach(this.vm.bookList, (item: BookItem, index: number) => {
                   BookItemComp({item: item, showModel: this.vm.showMode == 1,addCar: () => {
                       item.schoolbagFlag = '1'
                       this.vm.bookList.splice(index, 1, item)
+                      OrderApi.addBookToBag(item.id!)
                   }})
                 }, (item: BookItem) => JSON.stringify(item))
               }

+ 21 - 15
features/feature/src/main/ets/view/ThirdView.ets

@@ -1,7 +1,7 @@
-import { yTRouter } from "basic";
-import { tagItemComp } from "../components/BuilderIndex";
-import { CustomTextStyle } from "../style/CustomTextStyle";
-import { ThirdViewModel } from "./viewModel/ThirdViewModel";
+import { BookItem } from 'basic';
+import { tagItemComp } from '../components/BuilderIndex';
+import { CustomTextStyle } from '../style/CustomTextStyle';
+import { ThirdViewModel } from './viewModel/ThirdViewModel';
 
 
 @ComponentV2
@@ -24,7 +24,7 @@ export struct ThirdView {
       .borderRadius({bottomLeft: 16, bottomRight: 16})
 
       Column(){
-        if(true) {
+        if(this.vm.bookList.length != 0) {
           this.bookList()
         } else {
           this.emptyView()
@@ -36,7 +36,7 @@ export struct ThirdView {
       // 底部按钮
       Row(){
         Row(){
-          if(true) {
+          if(this.vm.selectList.length != 10 || (this.vm.bookList.length != 0 && this.vm.selectList.length == this.vm.bookList.length)) {
             Row().width(15).aspectRatio(1).borderRadius(15).border({width: 1})
           } else {
             Image($r('[basic].media.icon_select')).width(15).aspectRatio(1)
@@ -48,11 +48,14 @@ export struct ThirdView {
 
           Text(){
             Span('已选:')
-            Span(`1`).fontWeight(700).fontColor('#FFFFC500')
+            Span(`${this.vm.selectList.length}`).fontWeight(700).fontColor('#FFFFC500')
             Span('本书').fontColor('#FF333333')
           }
           .attributeModifier(new CustomTextStyle({size: 14, weight: 400, color: '#80000000'}))
         }
+        .onClick(() => {
+          this.vm.clickSelectAll()
+        })
 
 
         Row(){
@@ -177,26 +180,27 @@ export struct ThirdView {
         this.tip()
       }
 
-      ForEach(new Array(10).fill(1), (item: number, index) => {
+      ForEach(this.vm.bookList, (item: BookItem, index: number) => {
         ListItem(){
           Row({space: 7}){
             Row(){
-              if(index%2 == 1) {
+              if(this.vm.selectList.indexOf(item.id!) == -1) {
                 Row().width(15).aspectRatio(1).borderRadius(15).border({width: 1})
               } else {
                 Image($r('[basic].media.icon_select')).width(15).aspectRatio(1)
               }
             }.height('100%')
-            .onClick(() => { this.vm.changeSelect() })
+            .onClick(() => { this.vm.changeSelect(item, index) })
 
             Row({space: 11}){
-              Image($r('[basic].media.png_defaultBook'))
+              Image(item.coverUrl)
                 .borderRadius(16)
                 .width(86).aspectRatio(1)
                 .backgroundColor('#FECF2F')
+                .alt($r('[basic].media.png_defaultBook'))
 
               Column(){
-                Text('我不愿嫉妒')
+                Text(item.bookTitle)
                   .attributeModifier(new CustomTextStyle({size: 14, weight: 400, color: '#FF111111'}))
 
                 Row(){
@@ -208,7 +212,7 @@ export struct ThirdView {
 
                 Row({space: 8}){
                   tagItemComp('情绪价值', '#FF4EB1EF', '#FFEDF7FD')
-                  tagItemComp('3-8岁', '#FFFC9911', '#FFFFF5E7')
+                  tagItemComp(`${item.minAge}-${item.maxAge}岁`, '#FFFC9911', '#FFFFF5E7')
                 }
               }
               .width("100%")
@@ -227,7 +231,7 @@ export struct ThirdView {
           .alignItems(VerticalAlign.Center)
           .padding({left: 9, top: 8, right: 9, bottom: 8})
         }
-        .swipeAction({ end: () => { this.swipeAction() } })
+        .swipeAction({ end: () => { this.swipeAction(item, index) } })
       })
     }
     .width("100%").height("100%")
@@ -257,7 +261,7 @@ export struct ThirdView {
   }
 
   @Builder
-  swipeAction(){
+  swipeAction(item: BookItem, index: number){
     Row(){
       Text('移除')
         .attributeModifier(new CustomTextStyle({size: 16, weight: 400, color: '#FFFFFFFF'}))
@@ -269,5 +273,7 @@ export struct ThirdView {
     .alignItems(VerticalAlign.Center)
     .justifyContent(FlexAlign.Center)
     .padding({left: 15, right: 15})
+
+    .onClick(() => { this.vm.removeBook(item) })
   }
 }

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

@@ -120,7 +120,7 @@ export class SecondViewModel{
   // 获取书籍列表
   async getBookList() {
     let ans: PageResponse<BookItem> = await bookListApi.searchBooks(this.query.clone())
-    this.bookList = [...ans.list ?? []]
+    this.bookList = [...(ans.list ?? [])]
     console.log(`获取书籍列表 = ${JSON.stringify(this.bookList)}`)
   }
 }

+ 79 - 7
features/feature/src/main/ets/view/viewModel/ThirdViewModel.ets

@@ -1,4 +1,7 @@
-import { YTAvoid, yTRouter } from "basic";
+import { BookItem, YTAvoid, yTRouter } from "basic";
+import { OrderApi } from "../../apis/OrderApi";
+import { PageResponse } from "../../model/PageResponse";
+import { bookPackageQuery } from "../../model/Query";
 
 
 @ObservedV2
@@ -9,29 +12,98 @@ export class ThirdViewModel{
 
   // 当前分类索引
   @Trace categoryIndex: number = 0
-  // 编辑模式
+  // 编辑模式 true - 移除  false - 借阅
   @Trace editMode: boolean = false
 
+  @Trace bookList: BookItem[] = []
+
+  @Trace selectList: string[] = []
+
+  query: bookPackageQuery = new bookPackageQuery()
+
 
   // 分类
-  categoryList = ['全部', '可借', '已借光', '已预订']
+  categoryList = ['全部', '可借', '已借光'] // , '已预订'
 
+  constructor() {
+    this.getBagBookList()
+  }
 
   // 更改 分类
   changeCategory(index: number) {
     this.categoryIndex = index
+
+    this.query.flag = index
+    this.getBagBookList()
   }
 
-  // 切换编辑模式
+  // 切换编辑模式 - 借阅 - 移除
   changeEditMode() {
     this.editMode = !this.editMode
   }
 
   // 更改选中状态
-  changeSelect() {}
+  changeSelect(item: BookItem, index: number) {
+    let i = this.selectList.indexOf(item.id!)
 
-  // 点击按钮
+    if(i == -1 && this.selectList.length < 10) {
+      this.selectList.push(item.id!)
+    }
+
+    if(i != -1) {
+      this.selectList.splice(i, 1)
+    }
+  }
+
+  // 点击按钮 移除书本 || 立刻借阅
   clickButton() {
-    yTRouter.router2OrderDetailPage()
+    if(this.editMode) {
+      this.removeBook()
+    } else {
+      yTRouter.router2OrderDetailPage()
+    }
+  }
+
+  // 全选按钮
+  clickSelectAll() {
+    if(this.bookList.length == 0) return
+
+    let count = this.selectList.length
+    if(count == 10) {
+      this.selectList = []
+    } else {
+      this.bookList.forEach((item) => {
+        if(this.selectList.length == 10) return
+        let i = this.selectList.indexOf(item.id!)
+        if(i == -1) {
+          this.selectList.push(item.id!)
+        }
+      })
+    }
+  }
+
+  // 从书包中移除书本
+  async removeBook(book?: BookItem) {
+    let ids: string[] = []
+    if(book != undefined) {
+      ids.push(book.id || '')
+    } else {
+      ids.push(...this.selectList)
+    }
+
+    await OrderApi.removeBookFromBag(ids)
+
+    if(book == undefined) {
+      this.selectList = []
+    }
+    this.getBagBookList()
+  }
+
+  // 获取书包内的书本
+  async getBagBookList(){
+    let ans: PageResponse<BookItem> = await OrderApi.getBagBookList(this.query)
+
+    this.bookList = [...ans.list ?? []]
+    console.log(`书包内的书本 = ${JSON.stringify(ans)}`)
   }
 }