HarmonyOS鸿蒙Next《仿盒马》app开发技术分享之回收金收支查询

HarmonyOS鸿蒙Next《仿盒马》app开发技术分享之回收金收支查询

技术栈

Appgallery connect

开发准备

上一节我们实现了回收金页面的部分布局填充和内容展示,并且实现了当前订单收益总金额的展示,以及金额的隐藏,这一节我们来实现当前用户收支列表的展示,在这之前,我们先要修改一下我们recycleinfo表,我们把规格相关的内容添加上去,方便我们后续的逻辑编写,不然每次都根据weightid查询确实有一点点不方便

功能分析

我们已经通过tab实现了标题的切换,但是我们现在并没有操作列表的内容,所以我们还需要创建一个moneyinfo表,通过绑定userid,我们进行表的操作,然后通过查询出moneyinfo的列表信息,然后根据moneytype字段去筛选出我们想要的数据在列表中展示。同时根据不同的状态我们要展示出当前记录是收入还是支出,要更直观的给用户进行展示。

代码实现

首先我们把修改过的recycleinfo表结构展示一下

{
  "CloudDBZoneName": "default",
  "objectTypeName": "recycle_info",
  "fields": [
    {"fieldName": "id", "fieldType": "Integer", "notNull": true, "belongPrimaryKey": true},
    {"fieldName": "user_id", "fieldType": "Integer", "notNull": true, "defaultValue": 0},
    {"fieldName": "nike_name", "fieldType": "String"},
    {"fieldName": "phone", "fieldType": "String"},
    {"fieldName": "address", "fieldType": "String"},
    {"fieldName": "day", "fieldType": "String"},
    {"fieldName": "start_time", "fieldType": "String"},
    {"fieldName": "end_time", "fieldType": "String"},
    {"fieldName": "msg", "fieldType": "String"},
    {"fieldName": "weight_id", "fieldType": "String"},
    {"fieldName": "weight", "fieldType": "String"},
    {"fieldName": "txt", "fieldType": "String"},
    {"fieldName": "integral", "fieldType": "Double"},
    {"fieldName": "money", "fieldType": "Double"},
    {"fieldName": "create_time", "fieldType": "String"},
    {"fieldName": "express_code", "fieldType": "String"},
    {"fieldName": "express_people", "fieldType": "String"},
    {"fieldName": "express_company", "fieldType": "String"},
    {"fieldName": "order_type", "fieldType": "Integer"},
    {"fieldName": "logistics_id", "fieldType": "Integer"}
  ],
  "indexes": [
    {"indexName": "fieldIndexId", "indexList": [{"fieldName":"id","sortType":"DESC"}]}
  ],
  "permissions": [
    {"role": "World", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Authenticated", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Creator", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Administrator", "rights": ["Read", "Upsert", "Delete"]}
  ]
}

后续的操作我们都用这个结构的表来进行增删改查

然后我们创建对应的moneyinfo表,在内部添加我们需要的字段

{
  "objectTypeName": "money_info",
  "fields": [
    {"fieldName": "id", "fieldType": "Integer", "notNull": true, "belongPrimaryKey": true},
    {"fieldName": "user_id", "fieldType": "Integer", "notNull": true, "defaultValue": 0},
    {"fieldName": "money", "fieldType": "String"},
    {"fieldName": "all_money", "fieldType": "String"},
    {"fieldName": "create_time", "fieldType": "String"},
    {"fieldName": "money_type", "fieldType": "String"},
    {"fieldName": "address", "fieldType": "String"},
    {"fieldName": "year", "fieldType": "String"},
    {"fieldName": "month", "fieldType": "String"},
    {"fieldName": "day", "fieldType": "String"},
    {"fieldName": "time", "fieldType": "String"}
  ],
  "indexes": [
    {"indexName": "field1Id", "indexList": [{"fieldName":"id","sortType":"ASC"}]}
  ],
  "permissions": [
    {"role": "World", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Authenticated", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Creator", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Administrator", "rights": ["Read", "Upsert", "Delete"]}
  ]
}

然后我们生成Server Client 的Model,因为我们的现金奖励以及积分是只有在回收订完完成之后才会添加数据所以我们要在订单完成的点击事件中添加数据的提交,同时把状态改为收入

Text("订单完成")
  .fontColor(Color.Black)
  .fontSize(12)
  .padding(5)
  .borderRadius(10)
  .backgroundColor(Color.Pink)
  .onClick(async () => {
    let data = new recycle_info()
    data.id = item.id
    data.user_id = item.user_id
    data.nike_name = item.nike_name
    data.phone = item.phone
    data.address = item.address
    data.day = item.day
    data.start_time = item.start_time
    data.end_time = item.end_time
    data.msg = item.msg
    data.weight_id = item.weight_id
    data.weight = item.weight
    data.txt = item.txt
    data.money = item.money
    data.integral = item.integral
    data.create_time = item.create_time
    data.express_code = item.express_code
    data.express_people = item.express_people
    data.express_company = item.express_company
    data.order_type = 3
    data.logistics_id = item.logistics_id
    let num = await databaseZone.upsert(data);
    hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${num}`);
    if (num > 0) {
      this.onRefresh()
      showToast("订单已完成")
      let money = new money_info
      money.id = Math.floor(Math.random() * 1000000)
      money.user_id = this.user!.user_id
      money.money = String(item.money)
      money.all_money = ''
      money.money_type = '0'
      money.address = '客户端下单奖励'
      money.year = this.year
      money.month = this.month
      money.day = this.day
      money.time = this.time
      money.create_time = this.year + "-" + this.month + "-" + this.day + " " + this.time
      let nums = await databaseZone.upsert(money);
    }
  })

提交订单后,我们的数据就已经添加到云数据库中,接下来我们回到回收金展示页开始实现数据展示,这里我们拿全部订单展示为例

先创建对应的列表展示组件

import { MoneyInfo } from '../../../entity/money_info'

@Component
export struct RecordList {
  @Prop recodeList: MoneyInfo[] = []

  @Builder
  recordList() {
    List({ space: 10 }) {
      ForEach(this.recodeList, (item: MoneyInfo) => {
        ListItem() {
          this.allItem(item)
        }
      })
    }
    .backgroundColor("#f7f7f7").padding({ top: 10 })
    .sticky(StickyStyle.Header)
  }

  @Builder
  allItem(item: MoneyInfo){
    Row({space:10}) {
      Image(item.money_type == '0' ? $r('app.media.shouru') : $r('app.media.tixian'))
        .height(35)
        .width(35)
        .objectFit(ImageFit.Contain)
        .interpolation(ImageInterpolation.High)
        .borderRadius(25)
      Column({space:10}) {
        Text(item.money_type == '0' ? "收入" : "提现")
          .fontColor("#333333")
          .fontSize(16)
        Text(item.address)
          .fontColor("#999999")
          .fontSize(14)
      }
      .alignItems(HorizontalAlign.Start)
      Blank()
      Column({space:10}) {
        Text(item.money_type == '0' ? "¥" + item.money : "-¥" + item.money)
          .fontColor(item.money_type == '0' ? "#00B644" : "#EC2400")
          .fontSize(16)
          .margin({top:1})
        Text(item.create_time)
          .fontColor("#999999")
          .fontSize(14)
          .margin({top:1})
      }
      .alignItems(HorizontalAlign.End)
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .padding({left:12,right:12})
    .width('100%')
    .alignItems(VerticalAlign.Center)
    .height(71)
    .backgroundColor(Color.White)
  }

  build() {
    Column() {
      this.recordList()
    }
    .height('100%')
    .layoutWeight(1)
    .width('100%')
  }
}

然后在页面的tabs中引用

Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
  ForEach(this.arr, (item: string, index) => {
    TabContent() {
      Column(){
        if (item == '全部') {
          RecordList({recodeList:this.moneyList})
        }
      }
    }
    .tabBar(this.TabBuilder(index, item))
    .borderRadius(10)
    .backgroundColor(Color.White)
  })
}

更多关于HarmonyOS鸿蒙Next《仿盒马》app开发技术分享之回收金收支查询的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

鸿蒙Next开发回收金收支查询功能:

  1. 使用ArkTS构建UI界面,通过Column/Row布局实现收支列表展示
  2. 数据层采用@ohos.data.preferences持久化存储交易记录
  3. 网络请求用@ohos.net.http模块对接后端API获取实时数据
  4. 时间筛选功能调用@ohos.systemDateTime获取系统时间处理
  5. 金额统计使用ArkTS计算属性动态更新总收支

关键代码片段:

@Entry
@Component
struct IncomePage {
  @State incomes: IncomeRecord[] = []
  //...数据加载逻辑
}

更多关于HarmonyOS鸿蒙Next《仿盒马》app开发技术分享之回收金收支查询的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


从技术实现来看,这个回收金收支查询功能的设计比较完整,主要涉及以下几个关键点:

  1. 数据库设计方面:
  • 新增了money_info表来专门存储收支记录
  • 合理设计了字段,包括金额类型区分(money_type)、时间相关字段等
  • 通过user_id关联用户
  1. 业务逻辑实现:
  • 在订单完成时同步创建收支记录
  • 使用随机数生成唯一ID
  • 区分收入(0)和支出(1)类型
  • 记录完整的时间信息
  1. UI展示:
  • 使用Tabs组件实现分类查看
  • 通过RecordList组件展示收支明细
  • 不同状态使用不同颜色区分(收入绿色/支出红色)
  • 显示金额、类型、时间和备注信息
  1. 代码实现亮点:
  • 使用CloudDB进行数据存储
  • 采用声明式UI开发
  • 组件化设计(RecordList)
  • 类型安全(TypeScript)

建议可以进一步完善:

  1. 添加分页加载功能
  2. 实现按时间筛选
  3. 增加收支统计图表
  4. 优化列表项的点击交互

整体实现符合HarmonyOS应用开发规范,代码结构清晰,是一个不错的参考案例。

回到顶部