首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >《仿盒马》app开发技术分享-- 设置安全锁(51)

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

原创
作者头像
用户10696402
发布2025-06-27 20:26:30
发布2025-06-27 20:26:30
1480
举报

## 技术栈

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)

}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档