HarmonyOS APP应用开发项目- MCA助手(Day04持续更新中~)

本文涉及的产品
多模态交互后付费免费试用,全链路、全Agent
简介: 本项目为基于HarmonyOS的端云一体化记账App,集成华为AGC云数据库与认证服务,实现用户注册登录及数据云端存储。通过DevEco Studio开发,解决CloudProgram模块显示问题,完成云数据库初始化与用户信息关联功能。

简言:

gitee地址:https://gitee.com/whltaoin_admin/money-controller-app.git

端云一体化开发在线文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5

注:此App参照此教程进行二次修改:https://www.bilibili.com/video/BV1q5411v7o7

一、解决问题-DevEco不显示CloudProgram解决方法

1. 重现问题

2. 解决问题

// 打开目录:Application/.idea/modules.xml
// 添加
   <module fileurl="file://$PROJECT_DIR$/../CloudProgram/.idea/CloudProgram.iml" filepath="$PROJECT_DIR$/../CloudProgram/.idea/CloudProgram.iml" />
// 重启项目

3. 正常效果

二、建立云数据库

1. 创建存储区

进入到我的项目后,点击左侧的云数据库,选择存储区后点击新增
输入存储区名称后(mca),点击确认

2. 创建数据类型

选择上方导航中的对象类型后,点击新增,
输入对象类型名称、所需字段、索引、用户权限后点击确定

3. 创建云函数

TODO:该步骤可省略,暂无无调用

cloudFunctions目录中创建一个名为mca-user的云函数后
创建resources目录
AGC网页下载认证凭据文件放入resources目录中
下载位置:

4. 集成云数据库SDK

TODO:该步骤可省略,暂无无调用

地址:https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-Guides/agc-clouddb-sdk-integration-server-nodejs-0000001775071093
步骤一:
找到定制Demo包后并直接下载demo
地址:https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-Guides/query-clouddb-modify-demo-0000001549461562

三、初始化云数据库及注册业务修改

TODO:注册业务:将在用户注册时将用户数据存储到云数据库中,从而关联个人信息页信息。

1. 初始化

步骤一:建立数据库对象模型

步骤二:导出schema

2. 注册业务实现

import InputComponent from '../components/InputComponent';
import TitleComponent from '../components/TitleComponent';
import router from '@ohos.router';
import cloud, { Database } from '@hw-agconnect/cloud';
import { Auth, VerifyCodeAction } from '@hw-agconnect/cloud';
import { addMcaUser } from '../service/mcaUserService';
import { JSON } from '@kit.ArkTS';
import { mca_user } from '../model/mca_user';
import  mcaInfo  from '../../resources/rawfile/mca_1_cn.json';
import { Logger } from '@hw-agconnect/hmcore/src/main/ets/base/log/Logger';
import { TAG } from '@ohos/hypium/src/main/Constant';
@Entry
@Component
struct Login {
  // 页面未加载时调用:
  aboutToAppear(): void {
    // 登录页加载时初始化云数据库:
    this.database= cloud.database({
      zoneName:'mca',
      objectTypeInfo:mcaInfo
    })
    // 通过获取认证对象判断用户是否已经登录
    cloud.auth().getCurrentUser().then(user=>{
      if(user){
        //业务逻辑
        AppStorage.setOrCreate("user",user)
        router.replaceUrl({url:"pages/MainPage/MainPage"})
      }
    });
  }
   database:Database |null= null
  // 接收数据集
  @State mcaUser :mca_user|null = null
  @State message: string = 'Login';
  @State eMail:string = ''
  @State EMailPassword :string = '' // 邮箱密码
  @State vCode:string = "" // 验证码
  // 倒计时
  @State countDown :number = 60
  timer :number=0
  @State isRegister:boolean= false
  // 发送验证码
   sendCode(){
    // 倒计时
    this.startCountDown()
    // 生成验证码
     cloud.auth().requestVerifyCode({
       action: VerifyCodeAction.REGISTER_LOGIN,
       lang: 'zh_CN',
       sendInterval: 60,
       verifyCodeType: {
         email: this.eMail,
         kind: "email",
       }
     }).then(verifyCodeResult => {
       //验证码申请成功
       console.log(JSON.stringify(verifyCodeResult))
       // this.data = JSON.stringify(verifyCodeResult)
       AlertDialog.show({
         title: "提示",
         message: "获取验证码成功",
       })
     }).catch((error: Promise<Result>) => {
       AlertDialog.show({
         title: "提示",
         message: "获取验证码失败",
       })
       //验证码申请失败
     });
  }
  //邮箱用户登录
  loginEMail(){
    cloud.auth().signIn({
      autoCreateUser: true,
      credentialInfo: {
        kind: 'email',
        password: this.EMailPassword,
        email: this.eMail
      }
    }).then(user => {
      //登录成功
      AppStorage.setOrCreate("user",user)
      router.replaceUrl({url:"pages/MainPage/MainPage"})
    }).catch((error:Promise<Result>) => {
      //登录失败
      AlertDialog.show({
        title: "提示",
        message: "用户登录失败,请重试",
      })
    });
  }
  // 注册用户
   registerUser(){
      try{
      cloud.auth().createUser({
          "kind": "email",
          "email": this.eMail,
          "password": this.EMailPassword,
          "verifyCode": this.vCode
        }).then(async result => {
       //创建帐号成功后,默认已登录
       AlertDialog.show({
         title: "提示",
         message: "用户注册成功",
       })
        const user = result.getUser()
        // 存数据库
        const mcaUser :mca_user = new mca_user();
       mcaUser.setUuid(user.getUid())
        mcaUser.setEmail(user.getEmail())
        mcaUser.setPassword(this.EMailPassword)
        mcaUser.setAge(18)
        mcaUser.setSex(1)
        Logger.info(TAG, "upsert mca_userInfo  = " + JSON.stringify(mcaUser));
        try {
          const record = await this.database?.collection(mca_user).upsert(mcaUser);
          Logger.info(TAG, "upsert mca_user success, record  = " + record);
        } catch (err) {
          Logger.error(TAG, "upsert mca_user err------------" + JSON.stringify(err));
        }
        // 页面跳转
        AppStorage.setOrCreate("user",user)
        router.replaceUrl({url:"pages/MainPage/MainPage"})
        })
      }catch(e){
        AlertDialog.show({
          title: "提示",
          message: "用户注册失败,请重试",
        })
      }
  }
  // 开始倒计时
  startCountDown(){
  this.timer =   setInterval(()=>{
      this.countDown--
      if(this.countDown===0){
        this.countDown=60
        clearInterval(this.timer)
      }
    },1000)
  }
  build() {
      Column(){
        // title
        TitleComponent({title:"登录"})
        // login_content
        Stack({alignContent:Alignment.Top}){
          Image($r("app.media.Login_icon")).width(88).height(88).offset({y:-44}).zIndex(999)
       Column({space:10}){
            // email
          InputComponent({title:"电子邮箱",inputIcon:$r("app.media.mail_icon"),placeholder:"请输入邮箱信息",
            change:(value:string)=>{
                this.eMail=value
          }})
            // pwd
          InputComponent({title:"密码",inputIcon:$r("app.media.pwd_icon"),placeholder:"请输入密码",inputType:InputType.Password,
          change:(value:string) =>{
            this.EMailPassword = value
          }
          })
            // VCode
          if(this.isRegister){
            Column(){
              Text("验证码").width("100%").textAlign(TextAlign.Start).fontWeight(500)
                .fontSize(16).fontColor(Color.Black).margin({bottom:14})
              Row(){
                TextInput({placeholder:"请输入验证码"})
                  .layoutWeight(1)
                  .backgroundColor(Color.Transparent)
                  .border({
                    width:1,
                    color:"#ff9b9b9b"
                  }).borderRadius(10)
                  .onChange((value)=>{
                    this.vCode = value
                  })
                Button(this.countDown==60?"点击获取验证码":`${this.countDown}s`).fontSize("10").margin({left:10}).width(100).padding(0).onClick((event: ClickEvent) => {
                  if(this.countDown===60){
                    this.sendCode()
                  }else{
                    AlertDialog.show({
                      message:"正在获取验证码,请等待..."
                    })
                  }
                })
              }.width("100%").height(50)
            }
          }
            // login_btn
            Button(this.isRegister?"注册":"登录").width(228).backgroundColor("#ff09b19d").margin({top:50})
              .onClick(()=>{
                // 登录方法
                if(this.isRegister){
                  // 注册用户
                  this.registerUser()
                }else{
                  // 登录用户
                   this.loginEMail()
                }
              })
         
            // re_btn
         Row(){
           Text(this.isRegister?"去登录":"去注册").fontSize(12).onClick(()=>{
             this.isRegister= !this.isRegister
           })
           Text("|").padding({left:10,right:10})
           Text("忘记密码").fontSize(12)
         }.width("100%").layoutWeight(1).justifyContent(FlexAlign.Center)
       }.width("100%").height("100%").padding({left:14,right:14}).margin({top:44})
        }.width("90%").backgroundColor(Color.White).margin({top:44}).layoutWeight(1)
        .borderRadius(20)
      }.width("100%").height("100%").backgroundColor($r("app.color.page_Color"))
  }
}

目录
相关文章
|
4月前
|
容器
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
仓颉语言实战分享,教你如何用仓颉开发外卖App界面。内容包括页面布局、导航栏自定义、搜索框实现、列表模块构建等,附完整代码示例。轻松掌握Scroll、List等组件使用技巧,提升HarmonyOS应用开发能力。
|
11天前
|
JSON 自然语言处理 数据格式
使用Tabs选项卡组件快速搭建鸿蒙APP框架
ArkUI提供了很多布局组件,其中Tabs选项卡组件可以用于快速搭建鸿蒙APP框架,本文通过案例研究Tabs构建鸿蒙原生应用框架的方法和步骤。
114 5
使用Tabs选项卡组件快速搭建鸿蒙APP框架
|
3月前
|
移动开发 前端开发 JavaScript
鸿蒙NEXT时代你所不知道的全平台跨端框架:CMP、Kuikly、Lynx、uni-app x等
本篇基于当前各大活跃的跨端框架的现状,对比当前它们的情况和未来的可能,帮助你在选择框架时更好理解它们的特点和差异。
317 0
HarmonyOS NEXT仓颉开发语言实战案例:电影App
周末好!本文分享使用仓颉语言重构ArkTS实现的电影App案例,对比两者在UI布局、组件写法及语法差异。内容包括页面结构、列表分组、分类切换与电影展示等。通过代码演示仓颉在HarmonyOS开发中的应用。##仓颉##ArkTS##HarmonyOS开发
|
4月前
|
容器
HarmonyOS NEXT仓颉开发语言实战案例:健身App
本期分享一个健身App首页的布局实现,顶部采用Stack容器实现重叠背景与偏移效果,列表部分使用List结合Scroll实现可滚动内容。代码结构清晰,适合学习HarmonyOS布局技巧。
HarmonyOS NEXT仓颉开发语言实战案例:小而美的旅行App
本文分享了一个旅行App首页的设计与实现,使用List容器搭配Row、Column布局完成个人信息、功能列表及推荐模块的排版,详细展示了HarmonyOS下的界面构建技巧。
|
4月前
|
容器
HarmonyOS NEXT仓颉开发语言实战案例:银行App
仓颉语言银行App项目分享,页面布局采用List容器,实现沉浸式体验与模块化设计。顶部资产模块结合Stack与Row布局,背景图与内容分离,代码清晰易懂;功能按钮部分通过负边距实现上移效果,圆角仅保留顶部;热门推荐使用header组件,结构更规范。整体代码风格与ArkTS相似,但细节更灵活,适合金融类应用开发。
|
20天前
|
安全 开发工具 开发者
HarmonyOS APP应用开发项目- MCA助手
moneyControllerApp(MCA)是一款基于鸿蒙HarmonyOS Next开发的个人财务管理应用,采用端云一体化架构,支持多设备协同与数据实时同步。应用通过DevEco Studio集成Cloud Foundation Kit,实现高效云端联动,具备登录注册、主页导航、钱包管理、个人信息维护及支付功能,界面简洁,操作流畅,助力用户智能化管理财务。项目开源,支持二次开发。
45 0
|
20天前
|
存储 开发者 容器
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
本文介绍了ArkTS语言中的Class类、泛型、接口、模块化、自定义组件及状态管理等核心概念,并结合代码示例讲解了对象属性、构造方法、继承、静态成员、访问修饰符等内容,同时涵盖了路由管理、生命周期和Stage模型等应用开发关键知识点。
156 0
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
|
20天前
鸿蒙 HarmonyOS NEXT星河版APP应用开发-阶段三
本文介绍了UI开发中的样式复用与组件构建技术,涵盖@Extend、@Styles和@Builder的使用方法,并通过Swiper轮播、Scroll滚动、Tabs导航等常用组件实现典型界面效果,结合生肖抽卡、小米轮播、回顶按钮等案例,展示实际应用技巧。
79 0