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

目录

前言

一、关键技术

二、实验步骤

1.顶栏组件 Header.ets

2.提醒弹窗组件 Dialog.ets

3.结算弹窗组件 JieSuanDialog.ets

4.创建启动页 MainPage.ets

5.创建登录页 LogIn.ets

6.创建注册页 SignUp.ets

 三、遇到的问题

总结


前言

前面提到了数据库的构建流程、各种通用类的创建和一些细节,接下来将继续介绍各种通用组件的构建,其中包括:顶栏组件 Header.ets、提醒弹窗组件 Dialog.ets、结算弹窗组件 JieSuanDialog.ets等。


一、关键技术

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

二、实验步骤

1.顶栏组件 Header.ets

代码如下:

@Component
export  struct Header {
  build() {
    Row(){
      Text('松达的茶')
        .fontColor('white')
        .fontSize(30)
        .padding({left: 15})
    }
    .width('100%')
    .height('220px')
    .backgroundColor('#c49a81');
  }
}

2.提醒弹窗组件 Dialog.ets

作为一个通用的公共组件,其弹窗内容、确定按钮函数以及取消按钮函数都需要在调用时传参。

代码如下:

import systemDateTime from '@ohos.systemDateTime'
import dataCtrl from '../dataModel/DataCtrl'
import { Tea } from '../viewModel/Tea'
import { User } from '../viewModel/User'
@CustomDialog
@Preview
export  struct Dialog {
  controller: CustomDialogController

  message: string
  onYes: () => void
  onNo: () => void

  build() {
    Column({space: 20}){
      Text(this.message)

      Row(){
        Button('确定')
          .onClick(() => {
            this.onYes()
          })
          .type(ButtonType.Normal)
          .borderRadius(15)
          .backgroundColor('#d5be8e')
        Button('取消')
          .onClick(() => {
            this.onNo()
          })
          .type(ButtonType.Normal)
          .borderRadius(15)
          .backgroundColor('#d5be8e')
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
    }
    .width('100%')
    .padding(30)
  }
}

3.结算弹窗组件 JieSuanDialog.ets

代码如下:

import systemDateTime from '@ohos.systemDateTime'
import dataCtrl from '../dataModel/DataCtrl'
import { Tea } from '../viewModel/Tea'
import { User } from '../viewModel/User'
@CustomDialog
export  struct jieSuanDialog {
  controller: CustomDialogController
  // 饮料费、服务费
  @Consume sumF: number
  @Consume sumF_: number
  @Link teas: Tea[]

  // 桌号
  @Prop Btno: number
  // 人数
  @Prop Bsum: number
  // 外带
  @Prop Btype: boolean

  build() {
      Column(){
        Text(`饮料费:¥${this.sumF}`)
          .width('100%')
          .textAlign(TextAlign.Start)
        Text(`服务费:¥${this.sumF_}`)
          .width('100%')
          .textAlign(TextAlign.Start)
        Text(`总价:¥${this.sumF + this.sumF_}`)
          .width('100%')
          .textAlign(TextAlign.Start)
        Text('请扫描以下二维码进行支付:')
          .width('100%')
          .textAlign(TextAlign.Start)
        Image($r('app.media.shouKuan'))
          .margin(20)
        .width('70%')
        Row(){
          Button('完成支付')
            .backgroundColor('#d6b98d')
            .borderRadius(15)
            .onClick(() => {
              // 获取当前时间
              systemDateTime.getDate(async (err,data) => {
                if (err) {
                  console.log('08808', '获取当前时间错误!')
                  return
                }
                const nowYear = data.getFullYear().toString();
                const nowMonth = (data.getMonth() + 1).toString().padStart(2, '0'); // 填充前导零
                const nowDay = data.getDate().toString().padStart(2, '0')
                const nowHour = data.getHours().toString().padStart(2, '0')
                const nowMi = data.getMinutes().toString().padStart(2, '0')
                const nowSec = data.getSeconds().toString().padStart(2, '0')

                // 组装时间
                let Btime: string = `${nowYear}年${nowMonth}月${nowDay}日 ${nowHour}:${nowMi}:${nowSec}`
                // 组装编号:时间+账号
                let Bno: string = `${nowYear}${nowMonth}${nowDay}${nowHour}${nowMi}${nowSec}${User.Uno}`
                // 插入数据
                await dataCtrl.insertBought(Bno,Btime,(this.Btype == true ? '外带' : '堂食'),this.sumF + this.sumF_,User.Uno,this.Btno,this.Bsum)
                console.log('08808','插入订单数据')
                console.log('08808',this.sumF + this.sumF_)

                dataCtrl.deleteBuyCar()
                this.teas = []
                this.sumF = 0
                this.sumF_ = 0
                this.controller.close()
              })
            })
            .type(ButtonType.Normal)
            .fontColor(Color.White)
          Button('取消支付')
            .backgroundColor('#d6b98d')
            .borderRadius(15)
            .onClick(() => {
              this.controller.close()
            })
            .type(ButtonType.Normal)
            .fontColor(Color.White)
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceAround)
      }
    .width('100%')
    .padding(10)
  }
}

4.创建启动页 MainPage.ets

import router from '@ohos.router'
import window from '@ohos.window'
@Entry
@Component
struct MainPage {
  aboutToAppear(){
    setTimeout(
      () => {
        router.pushUrl(
          {
            url: 'pages/LogIn'
          },
          router.RouterMode.Single,
          err => {
            if(err){
              console.log('08808','登录页跳转失败')
            }
          }
        )
      },
      2000
    )
  }

  build() {
    Column(){
      Image($r('app.media.logo_log_in'))
        .sharedTransition(`log_image`, { duration: 800, curve: Curve.Linear, delay: 100 })
        .width(270)
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
    .backgroundColor('#c49a81')
  }
}

5.创建登录页 LogIn.ets

这里的主要细节是登录成功后直接将用户信息(包括用户名、昵称、密码)存入静态变量类StaticValue,方便以后调用。

import router from '@ohos.router'
import promptAction from '@ohos.promptAction'
import dataCtrl from '../dataModel/DataCtrl'
import { Header } from '../view/Header'
import { User } from '../viewModel/User'

@Entry
@Component
struct Index {

  @State Uno: string = ''
  @State Upassword: string = ''

  build() {
    Column(){
      // 顶栏
      Header()

      // logo
      LogoModel()

      // 登录注册
      LogInModel({Uno: $Uno,Upassword: $Upassword})

    }
    .width('100%')
    .height('100%')
    .backgroundColor('#fafafa')
  }
}



// 登录注册模块
@Component
struct LogInModel {

  @Link Uno: string
  @Link Upassword: string

  build() {
    Column({space: 20}){
      TextInput({placeholder: '请输入用户名'})
        .onChange(message => {
          this.Uno = message
        })
        .width('80%')
        .borderRadius(0)
        .backgroundColor('null')
        .border({color: Color.Gray,style: BorderStyle.Solid,width: {
          bottom: 2
        }})
        .backgroundColor('#00000000')

      TextInput({placeholder: '请输入密码'})
        .type(InputType.Password)
        .onChange(message => {
          this.Upassword = message
        })
        .width('80%')
        .borderRadius(0)
        .backgroundColor('null')
        .border({color: Color.Gray,style: BorderStyle.Solid,width: {
          bottom: 2
        }})
        .backgroundColor('#00000000')

      // 登录注册按钮
      Button('登录',{type: ButtonType.Normal})
        .onClick(async () => {
          if(await dataCtrl.selectUser(this.Uno,this.Upassword)) {
            // 密码正确后将用户数据填入
            User.Uno = this.Uno
            User.Upassword = this.Upassword
            User.Uname = await dataCtrl.selectUserName(this.Uno)
            // 跳转
            router.replaceUrl(
              {
                url: 'pages/HomePage',
              },
              router.RouterMode.Single,
              err => {
                if (err) {
                  console.log('testLog', '主页面跳转错误')
                }
              }
            )
          }
          else {
            promptAction.showToast({
              message: '账号或密码错误!',
              duration: 1500
            })
          }
        })
        .margin({top: 20})
        .width('80%')
        .height('15%')
        .backgroundColor('#c49a81')
        .fontColor(Color.White)
        .fontSize(20)
      Button('没有账号?点我注册',{type: ButtonType.Normal})
        .onClick(() => {
          router.pushUrl(
            {
              url: 'pages/SignUp'
            },
            router.RouterMode.Single,
            err => {
              if(err){
                console.log('注册页面跳转失败')
              }
            }
          )
        })
        .height('5%')
        .padding(0)
        .backgroundColor('#00000000')
        .border({color: Color.Gray,width: {
          bottom: 1
        }})
        .fontColor(Color.Gray)
        .fontSize(15)
    }
    .width('100%')
    .height('40%')
  }
}

// logo图片
@Component
struct LogoModel {
  build() {
    Row(){
      Image($r('app.media.logo_log_in'))
        .sharedTransition(`log_image`, { duration: 800, curve: Curve.Linear, delay: 100 })
        .height('100%')
    }
    .width('100%')
    .height('25%')
    .justifyContent(FlexAlign.Center)
    .margin({top: 40,bottom: 40})
  }
}

6.创建注册页 SignUp.ets

用于用户注册,注册成功后跳转到登录页进行登录。

需要注意各种约束,例如输入不能为空、输入不能过长等等,以及数据库查询当前账号是否已被注册。

import router from '@ohos.router'
import promptAction from '@ohos.promptAction'
import { Header } from '../view/Header'
import dataCtrl from '../dataModel/DataCtrl'

@Entry
@Component
struct SignUp {
  @State Uno: string = ''
  @State Uname: string = ''
  @State Upassword: string = ''
  @State reUpassword: string = ''


  build() {
    Column(){
      // 顶栏
      Header()

      // 头像
      TouXiangModel()

      // 输入框及按钮
      InputModel({Uno: $Uno,Uname: $Uname,Upassword: $Upassword,reUpassword: $reUpassword});
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#fafafa')
  }
}


// 头像
@Component
struct TouXiangModel {
  build() {
    Row(){
      Image($r("app.media.tou_xiang"))
        .height('100%')
    }
    .width('100%')
    .height('100')
    .justifyContent(FlexAlign.Center)
    .margin(70)
  }
}

// 输入框及按钮
@Component
struct InputModel {

  @Link Uno: string
  @Link Uname: string
  @Link Upassword: string
  @Link reUpassword: string

  build() {
    Column({space: 20}){
      TextInput({placeholder: '请输入用户名(小于等于15位)'})
        .onChange((message) => {
          this.Uno = message
        })
        .width('90%')
        .height(50)

      TextInput({placeholder: '请输入昵称'})
        .onChange((message) => {
          this.Uname = message
        })
        .width('90%')
        .height(50)

      TextInput({placeholder: '请输入密码(小于等于15位)'})
        .type(InputType.Password)
        .onChange((message) => {
          this.Upassword = message
        })
        .width('90%')
        .height(50)

      TextInput({placeholder: '请再次输入密码'})
        .type(InputType.Password)
        .onChange((message) => {
          this.reUpassword = message
        })
        .width('90%')
        .height(50)

      Row(){
        Button('注册')
          .onClick(async () => {
            if(this.reUpassword != this.Upassword){
              promptAction.showToast({
                message: '密码输入不一致!',
                duration: 1500
              })
            }
            else if(this.Uno == '' || this.Uname == '' || this.Upassword == ''){
              promptAction.showToast({
                message: '信息不可为空!',
                duration: 1500
              })
            }
            else if(!await dataCtrl.selectUser_(this.Uno)){
              promptAction.showToast({
                message: '此账号已存在,请修改!',
                duration: 1500
              })
            }
            else if(this.Uno.length > 15 || this.Upassword.length > 15){
              promptAction.showToast({
                message: '账号或密码不可大于15位,请修改!',
                duration: 1500
              })
            }
            else {
              dataCtrl.insertUser(this.Uno,this.Upassword,this.Uname)
              promptAction.showToast({
                message: '注册成功!',
                duration: 1500
              })
              router.back()
            }
          })
          .width(100)
          .backgroundColor('#c49a81')
        Button('取消')
          .onClick(() => {
            router.back()
          })
          .width(100)
          .backgroundColor('#c49a81')
      }
      .width('100%')
      .margin({top: 20})
      .justifyContent(FlexAlign.SpaceEvenly)
    }
    .width('100%')
    .layoutWeight(1)
  }
}

 三、遇到的问题

问题1:对Button的样式使用@Styles封装时提醒.type非公共样式,故使用@Extend(Button),但是依旧报红。

解决方案:@Extend只能放在全局中使用。

问题2:在模拟器上运行时显示白屏。

解决方案:由于修改了Index.ets的名字,需要在EntryAbility文件里将Index改为修改后的名字。
        ctrl + shift + f 全局搜索windowStage.loadConten,将第一条的pages/...修改即可。


总结

以上就是本章的主要内容,包括了顶栏组件 Header.ets、提醒弹窗组件 Dialog.ets、结算弹窗组件 JieSuanDialog.ets、登录注册等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值