鸿蒙开发-期末项目-饮品点餐系统(1)

目录

前言

一、关键技术

二、实验过程

1.创建数据库

(1)构思数据库

(2)初始化数据库及数据表

(3)定义数据库操作函数

2.构建类

(1)饮品类 Tea

(2)用户类 User

(3)订单类 Bill

(4)静态变量类 StaticValue

三、遇到问题

总结


前言

这是一款模拟饮品点餐系统的软件,基于鸿蒙,使用了数据库,主要功能有:

  1. 用户注册
  2. 用户登录
  3. 搜索饮品
  4. 选择饮品规格后加入购物车
  5. 计算总价
  6. 清空购物车
  7. 删除购物车的某一项
  8. 微信支付进行结算后清空购物车、增加订单项
  9. 查看订单详细信息
  10. 删除订单项
  11. 修改密码
  12. 退出登录

一、关键技术

  1. 数据库操作(包括增、删、改、查)。
  2. @State、@Link、@Prop、@Provide、@Consume、@Observed、@ObjectLink等装饰器的使用。
  3. Tabs 组件的使用。
  4. List 组件的使用。
  5. Panel组件的使用。
  6. 通过systemDateTime库获取系统当前时间。
  7. @Extend修饰器全局通用样式的使用。
  8. @Styles修饰器的使用。

二、效果展示

三、实验过程

1.创建数据库

(1)构思数据库

设计数据库表结构如下(外边框虚线为主键,内边框实线为外键)。

为什么没有饮品表?因为我的思路是前期先将饮品数据固定写死,每次加载应用都将固定数据push进数组teas[],后期如果时间充足可以加网络连接进行网络获取数据,现在不用数据库修改更为方便,若没有时间我觉得也不适合用数据库存储茶品,实际情况中茶品会根据管理员的修改而变动。

(2)初始化数据库及数据表

由于没有数据库的可视化工具并且模拟器的报错并不明显导致很多操作极不方便,特别是最开始创建数据库时,插入购物车表数据时出错,找了一下午,最后发现varchar写成了verchar

代码如下:

initData(context) {
  const config = {
    name: 'MyData.db',
    // 数据库安全级别
    securityLevel: relationalStore.SecurityLevel.S1
  }

  // 若数据表不存在则创建
  const createUserSql = `create table if not exists user(
    Uno varchar(20) primary key,
    Uname varchar(50),
    Upassword varchar(20)
  )`

  const createBuyCarSql = `create table if not exists buy_car(
    Ctime varchar(50),
    Uno varchar(20),
    Tname varchar(50),
    Csum int,
    Ccup int,
    Ctemp int,
    Csweetness int,
    Ctno int,
    primary key(Ctime,Uno),
    FOREIGN KEY (Uno) REFERENCES user(Uno)
  )`

  const createBoughtSql = `create table if not exists bought(
    Bno varchar(70) primary key,
    Btime varchar(50),
    Btype varchar(10),
    Bprice double,
    Uno varchar(20),
    Bdno int,
    Bsum int,
    FOREIGN KEY (Uno) REFERENCES user(Uno)
  )`

  relationalStore.getRdbStore(context,config,(err,rdbStore) => {
    if(err){
      console.log('testLog','获取rdbStore失败')
      return
    }

    // 执行SQL,若数据表存在则不会重复创建
    rdbStore.executeSql(createUserSql)
    rdbStore.executeSql(createBuyCarSql)
    rdbStore.executeSql(createBoughtSql)

    // 保存rdbStore
    this.rdbStore = rdbStore

  })
  console.log('08808','数据库加载成功')
}

(3)定义数据库操作函数

这里需要注意方法的同步和异步,防止发生逻辑错误。


// 用户注册
insertUser(Uno: string,Upassword: string,Uname: string): Promise<number>{
  console.log('08808','用户注册函数运行')
  return this.rdbStore.insert('user',{Uno,Upassword,Uname})
}

// 用户登录查询
async selectUser(Uno: string,Upassword: string): Promise<boolean>{
  let predicates = new relationalStore.RdbPredicates('user')
  // 绑定条件
  predicates.equalTo('Uno',Uno)

  // 定义结果集
  let res = await this.rdbStore.query(predicates)

  // 只要不是最后一行就循环
  while(!res.isAtLastRow){
    res.goToNextRow()
    let password = res.getString(res.getColumnIndex('Upassword'))
    // 密码正确
    if(password == Upassword){
      console.log('08808','密码正确!')
      return true
    }
  }
  // 账号错误或者密码错误
  return false
}

// 用户注册查询
async selectUser_(Uno: string): Promise<boolean>{
  let predicates = new relationalStore.RdbPredicates('user')
  // 绑定条件
  predicates.equalTo('Uno',Uno)

  // 定义结果集
  let res = await this.rdbStore.query(predicates)

  // 此账号唯一
  if(res.isAtLastRow){
    return true
  }
  else{
    // 此账号已存在
    return false
  }

}

// 用户昵称查询
async selectUserName(Uno): Promise<string>{
  let predicates = new relationalStore.RdbPredicates('user')
  // 绑定条件
  predicates.equalTo('Uno',Uno)

  // 定义结果集
  let res = await this.rdbStore.query(predicates)

  if(!res.isAtLastRow){
    res.goToNextRow()
    return res.getString(res.getColumnIndex('Uname'))
  }
}

// 用户密码修改
async updataPassword(Uno,newPassword){
  let data = {'Upassword': newPassword}
  let predicates = new relationalStore.RdbPredicates('user')
  predicates.equalTo('Uno',Uno)

  await this.rdbStore.update(data,predicates)
  console.log('08808','用户数据更新完成')
}

// 购物车表插入数据
async insertBuy_car(Ctime: string,Uno: string,Tname: string,Csum: number,Ccup: number,Ctemp: number,Csweetness: number,Ctno: number): Promise<number>{
  return await this.rdbStore.insert('buy_car',{Ctime,Uno,Tname,Csum,Ccup,Ctemp,Csweetness,Ctno})
}

// 读取购物车表的数据
async readBuy_car(): Promise<Tea[]> {
  let predicates = new relationalStore.RdbPredicates('buy_car')
  // 绑定条件
  predicates.equalTo('Uno',User.Uno)
  let res = await this.rdbStore.query(predicates)
  let teas: Tea[] = []

  while(!res.isAtLastRow){
    res.goToNextRow()
    let Ctno: number = res.getLong(res.getColumnIndex('Ctno'))

    // 构建规格
    let norms: object = {
      cup: res.getLong(res.getColumnIndex('Ccup')),
      temp: res.getLong(res.getColumnIndex('Ctemp')),
      sweetness: res.getLong(res.getColumnIndex('Csweetness'))
    }
    let tea: Tea = new Tea(
      // 饮品名称
      res.getString(res.getColumnIndex('Tname')),
      // 饮品图片地址
      StaticValue.teas[Ctno].image,
      // 饮品简介
      StaticValue.teas[Ctno].about,
      // 饮品总价 数量*单价
      StaticValue.teas[Ctno].price * res.getLong(res.getColumnIndex('Csum')),
      // 饮品类型
      StaticValue.teas[Ctno].type,
      // 饮品数量
      res.getLong(res.getColumnIndex('Csum')),
      // 客户备注 暂且不用
      '',
      // 饮品规格
      norms
    )

    tea.Ctime = res.getString(res.getColumnIndex('Ctime'))
    teas.push(tea)
  }

  return teas
}

// 修改购物车数据
async updateBuyCar(Uno: string,Ctime: string,Csum: number){
  let data = {'Csum': Csum}
  let predicates = new relationalStore.RdbPredicates('buy_car')
  predicates.equalTo('Uno',Uno)
  predicates.equalTo('Ctime',Ctime)

  await this.rdbStore.update(data,predicates)
  console.log('08808','购物车数据更新完成')
}

// 清空购物车
deleteBuyCar(){
  let predicates = new relationalStore.RdbPredicates('buy_car')
  this.rdbStore.delete(predicates)

  // 购物车全部清空
  console.log('08808','购物车清空!')
}

// 删除购物车中的一项
deleteBuyCarTo(Ctime: string,Uno: string){
  let predicates = new relationalStore.RdbPredicates('buy_car')
  predicates.equalTo('Ctime',Ctime)
  predicates.equalTo('Uno',Uno)


  this.rdbStore.delete(predicates)

  // 购物车指定条目删除
  console.log('08808','此项删除')
}

// 插入订单表数据
async insertBought(Bno: string,Btime: string,Btype: string,Bprice: number,Uno: string,Bdno: number,Bsum: number): Promise<number>{
  // console.log('08808',Bprice)
  return await this.rdbStore.insert('bought',{Bno,Btime,Btype,Bprice,Uno,Bdno,Bsum})
}

// 删除一条订单
deleteBill(Bno){
  let predicates = new relationalStore.RdbPredicates('bought')
  predicates.equalTo('Bno',Bno)

  this.rdbStore.delete(predicates)

  // 订单表指定条目删除
  console.log('08808','此项删除')
}

// 读取订单表的数据
async readBought(): Promise<Bill[]> {
  let predicates = new relationalStore.RdbPredicates('bought')
  // 绑定条件
  predicates.equalTo('Uno',User.Uno)
  let res = await this.rdbStore.query(predicates)
  let bills: Bill[] = []

  while(!res.isAtLastRow){
    res.goToNextRow()

    let bill: Bill = new Bill(
      res.getString(res.getColumnIndex('Bno')),
      res.getString(res.getColumnIndex('Btime')),
      res.getString(res.getColumnIndex('Btype')),
      res.getDouble(res.getColumnIndex('Bprice')),
      res.getLong(res.getColumnIndex('Bdno')),
      res.getLong(res.getColumnIndex('Bsum'))
    )
    bills.push(bill)
  }

  return bills
}

2.构建类

根据应用功能的实际需求创建出适合的类。

(1)饮品类 Tea

这里的饮品类属性较多,主要是因为此类算是一个较为通用的类,包括程序加载时读数据用到、读取购物车数据库后封装用到……

import resourceManager from '@ohos.resourceManager'
@Observed
export class Tea {
  // 编号:在数组中的位置
  no: number
  // 首字母
  firstI: string
  name: string
  image: resourceManager.Resource
  // 简介
  about: string
  // 总价格
  price: number
  // 数量
  sum: number
  // 顾客备注
  notes: string
  // 类型,标记属于四类中的哪一类
  type: number
  // 时间
  Ctime: string

  // 规格
  norms: object = {
    cup: 0,
    temp: 0,
    sweetness: 0
  }

  constructor(name: string,image: resourceManager.Resource,about: string,price: number,type: number,sum?: number,notes?: string,norms?: object,firstI?: string,no?: number) {
    this.name = name
    this.image = image
    this.about = about
    this.price = price
    this.type = type

    if(sum){
      this.sum = sum
    }
    if(notes){
      this.notes = notes
    }
    if(norms){
      this.norms = norms
    }
    if(firstI){
      this.firstI = firstI
    }
    if(no){
      this.no = no
    }
  }

}

(2)用户类 User

用于存储当前登陆账户的信息。

export class User{
  public static Uno: string
  public static  Upassword: string
  public static  Uname: string
}

(3)订单类 Bill

export class Bill {
  Bno: string
  Btime: string
  Btype: string
  Bprice: number
  Bdno: number
  Bsum: number

  constructor(Bno,Btime,Btype,Bprice,Bdno,Bsum) {
    this.Bno = Bno
    this.Btime = Btime
    this.Btype = Btype
    this.Bprice = Bprice
    this.Bdno = Bdno
    this.Bsum = Bsum
  }
}

(4)静态变量类 StaticValue

用于存储全局通用的静态变量

import { Tea } from './Tea'
export class StaticValue {
  // 总饮品集合
  public static teas: Tea[]  =[]
  // 服务费
  public static sumF_: number = 0.2

}

四、遇到问题

正如前面所说,由于没有数据库的可视化工具并且模拟器的报错并不明显导致很多操作极不方便,特别是最开始创建数据库时,插入购物车表数据时出错,找了一下午,最后发现varchar写成了verchar。


总结

以上就是本章的主要内容,包括了数据库的构建流程、各种通用类的创建和一些细节。

  • 27
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值