首页 > 其他分享 >HarmonyOS APP应用开发项目- MCA助手(Day03持续更新中~)

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

时间:2024-07-29 21:53:39浏览次数:8  
标签:10 登录 Day03 APP MCA height width margin 100%

简言:

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


一、邮箱认证服务开通流程

  1. 官方操作文档地址:https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-Guides/agc-auth-harmonyts-login-email-0000001522426989
  2. 判断是否开通邮箱服务:

地址:https://developer.huawei.com/consumer/cn/service/josp/agc/index.html#/myProject/388421841222266117/9249519184595940179?appId=5765880207854757911
image.png

  1. 集成SDK

参考网址:https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-Guides/agc-auth-harmonyts-integration-0000001471227866

//步骤1 添加依赖
entry目录下的oh-package.json5
// 添加:主要前2个依赖
"dependencies": {
    "@hw-agconnect/cloud": "^1.0.0",
    "@hw-agconnect/hmcore": "^1.0.0",
    "@hw-agconnect/auth-component": "^1.0.0",
    "long": "5.2.1"
  }

// 步骤2:初始化SDK文件
// 初始化方法一:
import {initialize} from  "@hw-agconnect/hmcore"
import jsonStr from "../../resources/rawfile/agconnect-services.json"
  onCreate(){
    try {
      initialize(this.context,jsonStr)
    }catch (e){
      console.error(JSON.stringify(e))
    }

  }
// 初始化方法二:
import {initialize} from  "@hw-agconnect/hmcore"
 onCreate(){
    // 初始化
      const context = this.context
      const  value = await context.resourceManager.getRawFileContent("agconnect-services.json")
      let json:string= buffer.from(value).toString("utf8")
      console.log(json)
      initialize(this.context,json)
  }
// 步骤三:开通应用网络权限
 "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
 ]

二、注册登录业务实现

TODO 注册功能实现:
应用通过用户邮箱进行注册,注册时输入密码和向邮箱发送的验证码进行注册,注册成功后直接进入到用户主页,并缓存用户信息
TODO 登录功能实现:
用户用户邮箱地址和密码进行登录,登录成功后进入到应用主页,并缓存用户信息。
TODO 记住用户账号实现:
在用户进行登录或注册操作成功后,进入到应用主页,只要用户不执行个人信息页的退出登录功能,下一次进入应用都将不用再次登录


  1. 实现代码
import InputComponent from '../components/InputComponent';
import TitleComponent from '../components/TitleComponent';
import router from '@ohos.router';
import cloud from '@hw-agconnect/cloud';
import { Auth, VerifyCodeAction } from '@hw-agconnect/cloud';




@Entry
@Component
struct Login {
  aboutToAppear(): void {
    // 页面未加载时调用:
    cloud.auth().getCurrentUser().then(user=>{
      if(user){
        //业务逻辑
        AppStorage.setOrCreate("user",user)
        router.replaceUrl({url:"pages/MainPage/MainPage"})
      }
    });
  }
  @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(result => {
       //创建帐号成功后,默认已登录
       AlertDialog.show({
         title: "提示",
         message: "用户注册成功",
       })
        AppStorage.setOrCreate("user",result.getUser())
        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"))
  }
}
  1. 效果图:
    1. 注册:

image.png
image.png

  1. 登录

image.png
image.png

三、注销功能实现

TODO 注销功能说明
本应用进行了用户持久化处理,只要不进行退出用户操作,下次登录时仍然会保持上次的登录状态。
  1. 实现代码:
// 页面四:个人信息页
import TitleComponent from '../../components/TitleComponent'
import router from '@ohos.router'
import { Router } from '@kit.ArkUI'
import cloud from '@hw-agconnect/cloud'

@Component
export  default struct My {
  build() {
    Column(){
      TitleComponent({title:"个人资料",titleColor:"#ffff"})

      Stack({alignContent:Alignment.Start}){
        Column().width("100%").height(120)
          .backgroundColor("#ffc3f6e1")
          .margin({top:50}).borderRadius(20).shadow({radius:10,color:"#fff"})
        Column(){
          Image($r("app.media.user")).width(66).height(66).borderRadius(22)
            .border({
            width:5,
            color:'#ff09b06d',
              style:BorderStyle.Solid
          }).shadow({radius:10,color:"#fff"})

          Text("追风的少年").offset({x:80,y:-30}).width("100%")
          Text("财富的意义,在于分享与贡献,而非单纯的积累。").fontSize(14).fontColor("#ff969191").margin({top:10})
            .offset({y:-10}).margin({right:10})
        }.width("100%").alignItems(HorizontalAlign.Start).margin({left:10})
        Image($r("app.media.right_i")).height(20).offset({
          y:60,x:270
        })

      }.width("100%").padding({left:30,right:30})


       Row(){
        Image($r("app.media.edit_icon")).height(30).margin({right:20})
        Text("编辑个人信息").layoutWeight(1).fontSize(14)
         Image($r("app.media.right_icon")).height(25)
       }.height(40).padding({left:5,right:10}).backgroundColor("#fff").margin(20)
      .borderRadius(10).shadow({radius:20,color:"#ff70e7d5"}).onClick(()=>{
        router.pushUrl({
          url:"pages/info/InfoEdit"
        })
       })

      Row(){
        Image($r("app.media.qrcode_icon_external")).height(25).margin({left:5,right:30})
        Text("个人二维码").layoutWeight(1).fontSize(14)
        Image($r("app.media.right_icon")).height(25)
      }.height(40).padding({left:5,right:10}).backgroundColor("#fff").margin(20)
      .borderRadius(10).shadow({radius:20,color:"#ff70e7d5"}).onClick(()=>{
        router.pushUrl({
          url :'pages/info/QrCodePage'
        })
      })
    
      Row(){
        Image($r("app.media.loginOut")).height(20).margin({left:10,right:30})
        Text("退出登录").layoutWeight(1).fontSize(14)
        Image($r("app.media.right_icon")).height(25)
      }.height(40).padding({left:5,right:10}).backgroundColor("#fff").margin(20)
      .borderRadius(10).shadow({radius:20,color:"#ff70e7d5"}).onClick(()=>{
        cloud.auth().signOut().then(() => {
          //登出成功
          AlertDialog.show({
            title: "提示",
            message: "用户已成功注销",

          })
          router.replaceUrl({url:'pages/Login'})
        }).catch((error:Promise<Result>) => {

          //登出失败
          AlertDialog.show({
            title: "提示",
            message: "注销用户失败,请重试",

          })
        });
      })

    }.width("100%").height("100%").backgroundImage($r("app.media.myPageBg"))
    .backgroundImageSize({width:"100%",height:"100%"})
  }
}
  1. 效果图:

image.png
image.png


day03 登录注册业务功能基本实现

标签:10,登录,Day03,APP,MCA,height,width,margin,100%
From: https://blog.csdn.net/weixin_45793745/article/details/140782140

相关文章

  • Django-APP及项目入门
    1.APP定义:Django中功能的细分,每个APP有独立的数据库、表结构、HTML模版、CSS。创建APPpythonmanage.pystartappapp01重要文件介绍views.py:常用文件,urls中的函数常常在此处定义。models.py:常用文件,对数据库进行操作。2.项目入门确保app也注册(settings.py)......
  • UniApp 原生插件接入步骤
    app插件主要分2种:原生语言插件原生语言插件有分为2类:(1)moduleAPI接口插件这种插件是API插件,有同步或异步API(2)UIcomponent组件插件这种插件是UI视图组件,使用到插件里的UI组件的页面要用nvueUTS插件uts集成步骤参考https://www.cnblogs.com/wenrisheng/p/183230......
  • window系统使用Tomcat部署若依微服务
    安装JAVA下检查是否安装了JAVAjava-version提示"java:commandnotfound"则表示没有安装,如果安装了会显示JAVA版本信息CentOS安装JAVAsudoyuminstalljava-11-openjdk-devel 安装完成再执行一下:java-version 说明安装成功,没问题设置环境变量设置JAVA_HO......
  • App Inventor 2 低功耗蓝牙 BlueToothLE 拓展中文文档(完整翻译加强版)
    低功耗蓝牙,也称为蓝牙LE或简称BLE,是一种类似于经典蓝牙的新通信协议,不同之处在于它旨在消耗更少的功耗和成本,同时保持同等的功能。因此,低功耗蓝牙是与耗电资源有限的物联网设备进行通信的首选。BluetoothLE扩展需要Android5.0或更高版本。BlueToothLE拓展中文文档入口......
  • 微信小程序,web,uniapp-vue前端图片压缩思路-------uniapp-nvue如何压缩
    uniapp官方提供的压缩接口,只支持jpg的压缩,所以,直接放弃在非nvue的页面中,统一使用canvas获取图片信息,并重新绘制。存在一个问题,canvas必须指定宽高,不能动态给定,所以可能存在一些问题。nvue页面,又无法使用canvas,或者说,性能不是很好。一个隐藏的canvas只做图片处理使用,应该不会影......
  • 棋牌游戏app开发的具体过程是怎样的?
    棋牌游戏开发是一个涉及多个环节和技术的复杂过程,对于初次涉足此领域的创业者来说,了解并遵循正确的开发步骤至关重要。1.选择有市场的棋牌游戏:在选择棋牌游戏类型时,要进行市场调研,了解当前市场上哪些类型的游戏最受欢迎,哪些游戏具有持续的吸引力和盈利能力。考虑目标用户群体......
  • 基于Android平台开发,仿头条新闻app新闻分类分类列表实现(四)
    1.项目涉及到的技术点列表控件RecyclerView的使用调用API获取网络数据Glide加载图片Handler的使用okhttp的使用2.代码实现过程在上集中,已经使用TabLayout+ViewPager2把新闻分类滑动实现了,这集具体实现新闻列表新闻布局fragment_tab_news.xml<?xmlversion="1.0"en......
  • 仿微信im源码开源部署/社交聊天即时通讯im源码[PHP+uniapp]/直播+PC+安卓+IOS
    在数字化时代,即时通讯(InstantMessaging,IM)已成为人们日常生活中不可或缺的一部分,无论是工作协作、社交互动还是日常交流,IM应用都扮演着至关重要的角色。从早期的ICQ、MSN到如今的微信、WhatsApp、Telegram等,IM技术不断演进,为用户提供了更加丰富、便捷、安全的沟通体验。本文旨在......
  • mapper文件 和bean
    <?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="com.hspedu.springboot.my......
  • Memcached跨平台性能解码:操作系统对缓存速度的影响
    Memcached跨平台性能解码:操作系统对缓存速度的影响在分布式缓存系统的设计和部署中,Memcached因其轻量级和高性能而成为首选方案之一。然而,Memcached在不同操作系统上的性能表现可能会有显著差异。本文将深入探讨这些差异的原因,并提供实际的测试方法和代码示例,帮助系统架构......