ITPub博客

首页 > 移动开发 > HTML5 > 《仿盒马》app开发技术分享-- 设置安全锁(51)

《仿盒马》app开发技术分享-- 设置安全锁(51)

原创 HTML5 作者:鸿蒙小林 时间:2025-06-27 21:06:54 0 删除 编辑


## 技术栈


Appgallery connect

## 开发准备


上一节我们实现了提现页面以及部分组件的业务逻辑,那么我们在提现这一步为了更多的安全层面的考虑,设置了一个安全锁,用户只要开启了安全锁,那么每次的提现,都需要把本地的密码提交到云端核对安全锁的内容才可以执行后续的提现步骤,如果不能解锁,那么后续的内容都无法实现,这更好的保护了用户的财产安全


## 功能分析

要实现这个功能首先我们需要在个人页面添加一个安全入口,然后在安全锁设置页面开启安全锁的按钮,当没有开启安全锁的时候,点击开启按钮会出现一个安全锁的弹窗,在弹窗里设置对应的密码,设置成功后保存对应的内容提交到云端,进行保存,方便后续的校验,关闭安全锁则在云端删除对应的内容



## 代码实现

首先我们直接在个人页面的列表中添加上对应的数据

```css

  new SectionLine("安全",

        "设置安全锁",

        $r('app.media.anquan'),

        false),

```

然后给这条数据添加对应的点击事件


```css

if (item.title=='安全'){

        if (this.user!=null) {

          router.pushUrl({url:'pages/view/LockPage'})


        }else {

          showToast("请先登录")


        }

      }

```

接下来创建安全锁对应的表


```css

{

  "objectTypeName": "verify_info",

  "fields": [

    {"fieldName": "id", "fieldType": "Integer", "notNull": true, "belongPrimaryKey": true},

    {"fieldName": "open_lock", "fieldType": "Boolean"},

    {"fieldName": "lock_str", "fieldType": "String"},

    {"fieldName": "user_id", "fieldType": "Integer"}


  ],

  "indexes": [

    {"indexName": "field1Index", "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"]}

  ]

}

```

创建对应的安全锁页面,在页面中设置好对应的参数


```css

 @State user: User|null=null

  @State flag:boolean=false

  @State lockInfo:VerifyInfo|null=null

  @State lock_ui_visibility:boolean=false


 Column({space:10}) {

      CommonTopBar({ title: "安全锁", alpha: 0, titleAlignment: TextAlign.Center ,backButton:true})

      Row(){

        Text("安全锁")

          .fontColor(Color.Black)

          .fontSize(16)

        Image(this.lock_ui_visibility?$r('app.media.kai'):$r('app.media.guan'))

          .width(60)

          .height(30)

          .onClick(()=>{

           

          })

      }

      .width('100%')

      .justifyContent(FlexAlign.SpaceBetween)

      .padding({left:10,right:10})

      Divider().width('100%').height(0.8)

        .color("#e6e6e6")

      .width('100%')


    }.width('100%').height('100%').backgroundColor(Color.White)

```


接下来我们创建对应的安全锁设置弹窗并整理好对应的逻辑


```css

import { LengthUnit } from '@kit.ArkUI';


@Preview

@CustomDialog

export struct LockDialog {

  @State passwords: Number[]=[];

  @Link lock_ui_visibility:boolean

  @State message: string = '绘制您的密码图案!';

  public callback:(passwords:string)=>void=():void=>{}

  private patternLockController: PatternLockController = new PatternLockController();

  controller: CustomDialogController;

  build() {

    Column({space:20}) {

      Text(this.message).textAlign(TextAlign.Center).margin(20).fontSize(20)

        .fontColor(Color.Black)

      PatternLock(this.patternLockController)

        .sideLength(300)

        .circleRadius(9)

        .pathStrokeWidth(5)

        .activeColor('#707070')

        .selectedColor('#707070')

        .pathColor('#707070')

        .backgroundColor('#F5F5F5')

        .autoReset(true)

        .activateCircleStyle({

          color: '#707070',

          radius: { value: 16, unit: LengthUnit.VP },

          enableWaveEffect: true

        })

        .onDotConnect((index: number) => {

          console.log("onDotConnect index: " + index);

        })

        .onPatternComplete((input: Array<number>) => {

          if (input.length < 5) {

            this.message = '图案连接数不能小于5';

            return;

          }

          if (this.passwords.length > 0) {

            if (this.passwords.toString() === input.toString()) {

              this.passwords = input;

              this.message = '图案码设置完成';

              this.patternLockController.setChallengeResult(PatternLockChallengeResult.CORRECT);

              const str: string = JSON.stringify(this.passwords);

              this.callback(str)

              this.controller.close()


            } else {

              this.message = '图案码核对失败,请确认后重新绘制.';

              this.patternLockController.setChallengeResult(PatternLockChallengeResult.WRONG);

            }

          } else {

            this.passwords = input;

            this.message = "请再次绘制图案码.";

          }

        })

    }

    .borderRadius({topLeft:20,topRight:20})

    .justifyContent(FlexAlign.Start)

    .backgroundColor(Color.White)

    .height(500)

    .width('100%')

  }

}


```

接下来我们在页面内调用


```css

  private dialogController: CustomDialogController = new CustomDialogController({

    builder: LockDialog({

     lock_ui_visibility:this.lock_ui_visibility,

      callback: async (str:string)=>{

        //在这里提交表单信息,成功插入之后关闭弹窗,修改安全锁按钮的状态,重新查询数据赋值lockInfo

        showToast(str)

        let info=new verify_info()

        info.id=Math.floor(Math.random() * 1000000)

        info.open_lock=true

        info.lock_str=str

        info.user_id=this.user!.user_id

        let num = await databaseZone.upsert(info);

        if (num>0) {

          this.lock_ui_visibility=true

          this.initLockInfo()

        }


      }

    }),

    alignment: DialogAlignment.Bottom,

    customStyle:false

  });

```

因为我们提交数据需要用户信息,进入页面也需要加载对应的状态所以还需要进行数据查询


```css


  async initLockInfo(){

    const value = await StorageUtils.getAll('user');

    if (value != "") {

      this.user = JSON.parse(value)

    }

    let databaseZone = cloudDatabase.zone('default');

    let condition = new cloudDatabase.DatabaseQuery(verify_info);

    condition.equalTo("user_id", this.user?.user_id)

    let listData = await databaseZone.query(condition);

    let json = JSON.stringify(listData)

    let data: VerifyInfo[] = JSON.parse(json)

    if (data.length>0) {

      this.lock_ui_visibility=true

      this.lockInfo=data[0]

    }else {

      this.lock_ui_visibility=false


    }

  }

```


在生命周期方法内调用


```css

  async aboutToAppear(): Promise<void> {



this.initLockInfo()


  }

```

实现开关的业务逻辑


```css

build() {

    Column({space:10}) {

      CommonTopBar({ title: "安全锁", alpha: 0, titleAlignment: TextAlign.Center ,backButton:true})

      Row(){

        Text("安全锁")

          .fontColor(Color.Black)

          .fontSize(16)

        Image(this.lock_ui_visibility?$r('app.media.kai'):$r('app.media.guan'))

          .width(60)

          .height(30)

          .onClick(async ()=>{

            if (this.lock_ui_visibility) {

              let info=new verify_info()

              info.id=this.lockInfo!.id

              let num = await databaseZone.delete(info);

              if (num>0) {

                this.lock_ui_visibility=false

              }

            }else {

              this.dialogController.open()

            }

          })

      }

      .width('100%')

      .justifyContent(FlexAlign.SpaceBetween)

      .padding({left:10,right:10})

      Divider().width('100%').height(0.8)

        .color("#e6e6e6")

      .width('100%')


    }.width('100%').height('100%').backgroundColor(Color.White)

  }


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70046889/viewspace-3089298/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2025-06-26

  • 博文量
    90
  • 访问量
    67478