Technologies utilisées
- ArkUI
- Cloud Database
- Pattern Lock
Préparation du développementDans la section précédente, nous avons développé la page de retrait d'argent et partie de la logique métier. Pour améliorer la sécurité, nous avons ajouté un verrou de sécurité. Une fois activé, chaque retrait d'argent nécessite l'envoi du mot de passe local pour vérification en云. Si le verrou ne peut pas être ouvert, aucun retrait n'est possible. Cela renforce considérablement la protection des biens utilisateurs.
Analyse des fonctionnalitésPour implémenter cette fonctionnalité, nous devons :
- Ajouter un accès à la sécurité dans la page profil
- Créer une page de configuration du verrou
- Lorsque le verrou n'est pas activé, cliquer sur le bouton d'activation ouvre une fenêtre modale pour configurer le mot de passe
- Le mot de pasce configure est envoyé en云 et stocké pour une vérification ultérieure
Implémentation du codeAjout de l'entrée de menu dans la page profil :
new SectionLine("Sécurité",
"Gestion des verrous",
$r('app.media.secure'),
false)
Gestion de l'événement clic :
if (item.title === 'Sécurité') {
if (this.user != null) {
router.pushUrl({url:'pages/view/PageSécurité'})
} else {
afficherMessage("Veuillez-vous connecter")
}
}
Création de la base de données :
{
"objectTypeName": "info_sécurité",
"fields": [
{"nomChamp": "id", "typeChamp": "entier", "nonNull": true, "cléPrimaire": true},
{"nomChamp": "verrouOuvert", "typeChamp": "boolean"},
{"nomChamp": "codeVerrou", "typeChamp": "chaîne"},
{"nomChamp": "idUtilisateur", "typeChamp": "entier"}
],
"index": [
{"nomIndex": "indexChamp1", "listeChamp": [{"nomChamp":"id","typeTri":"ASC"}]}
],
"droits": [
{"rôle": "Monde", "droits": ["Lecture", "Insertion", "Suppression"]},
{"rôle": "Authentifié", "droits": ["Lecture", "Insertion", "Suppression"]},
{"rôle": "Créateur", "droits": ["Lecture", "Insertion", "Suppression"]},
{"rôle": "Administrateur", "droits": ["Lecture", "Insertion", "Suppression"]}
]
}
Création de la page de verrou :
@Etat utilisateur: Utilisateur|null = null
@Etat verrouOuvert:boolean = false
@Etat infoVerrou:info_sécurité|null = null
@Etat affichageVerrou:boolean = false
Fiche({espacement:10}) {
BarreEnTêteCommune({ titre: "Verrou de sécurité", opacité: 0, alignementTitre: TextAlign.CENTRE ,boutonRetour:vrai})
Ligne(){
Texte("Verrou de sécurité")
.couleurTexte(Couleur.Noir)
.tailleTexte(16)
Image(affichageVerrou?$r('app.media.overt'):$r('app.media.ferme'))
.largeur(60)
.hauteur(30)
.surClick(()=>{
})
}
.largeur('100%')
.justification(FlexAlign.EPRÉCHÉE)
.marge({gauche:10,droit:10})
Séparateur().largeur('100%').hauteur(0.8)
.couleur("#e6e6e6")
.largeur('100%')
}.largeur('100%').hauteur('100%').couleurFond(Couleur.Blanc)
Implémentation du dialogue du verrou :
import { UnitéLongueur } from '@kit.ArkUI';
@Aperçu
@DialoguePersonnalisé
export struct DialogueVerrou {
@Etat mots: Nombre[] = [];
@Lien affichageVerrou:boolean
@Etat message: chaîne = 'Dessinez votre code de sécurité!';
public callback:(code:chaîne)=>void=():void=>{}
privé contrôleurVerrou: ContrôleurVerrou = new ContrôleurVerrou();
contrôleur: ContrôleurDialoguePersonnalisé;
build() {
Fiche({espacement:20}) {
Texte(this.message).alignementTexte(TextAlign.CENTRE).marge(20).tailleTexte(20)
.couleurTexte(Couleur.Noir)
Verrouillage(this.contrôleurVerrou)
.longueurCôté(300)
.rayonCercle(9)
.largeurTrait(5)
.couleurActive('#707070')
.couleurSélectionnée('#707070')
.couleurChemin('#707070')
.couleurFond('#F5F5F5')
.réinitialisationAutomatique(vrai)
.styleCercleActif({
couleur: '#707070',
rayon: { valeur: 16, unité: UnitéLongueur.VP },
effetOnde: vrai
})
.surRelâchementPoint((index: nombre) => {
console.log("surRelâchementPoint index: " + index);
})
.surTerminerPatron((entree: Array<nombre>) => {
if (entree.longueur < 5) {
this.message = 'Le nombre de points doit être supérieur à 5';
return;
}
if (this.mots.longueur > 0) {
if (this.mots.toString() === entree.toString()) {
this.mots = entree;
this.message = 'Code de sécurité configuré!';
this.contrôleurVerrou.setResultatDéfi(ResultatDéfi.CORRECT);
const str: chaîne = JSON.stringify(this.mots);
this.callback(str)
this.contrôleur.fermer()
} else {
this.message = 'Code de sécurité incorrect. Veuillez recommencer.';
this.contrôleurVerrou.setResultatDéfi(ResultatDéfi.INCORRECT);
}
} else {
this.mots = entree;
this.message = "Configurez à nouveau le code de sécurité.";
}
})
}
.rayonRond({en haut gauche:20,en haut droit:20})
.justification(FlexAlign.DÉBUT)
.couleurFond(Couleur.Blanc)
.hauteur(500)
.largeur('100%')
}
}
Appel du dialogue :
privé contrôleurDialogue: ContrôleurDialoguePersonnalisé = new ContrôleurDialoguePersonnalisé({
constructeur: DialogueVerrou({
affichageVerrou:this.affichageVerrou,
callback: async (str:chaîne)=>{
// Envoi des données en云
afficherMessage(str)
let info = new info_sécurité()
info.id = Math.floor(Math.random() * 1000000)
info.verrouOuvert = vrai
info.codeVerrou = str
info.idUtilisateur = this.utilisateur!.idUtilisateur
let num = await baseDonnéesZone.misAJour(info);
if (num > 0) {
this.affichageVerrou = vrai
this.initInfoVerrou()
}
}
}),
alignement: Alignment.Dialogue.BAS,
stylePersonnalisé:false
});
Chargement initial des données :
async initInfoVerrou(){
const valeur = await StockageObtenir.Tout('utilisateur');
if (valeur != "") {
this.utilisateur = JSON.parse(valeur)
}
let baseDonnéesZone = baseDonnées.Zone('défaut');
let condition = new baseDonnées.Recherche(info_sécurité);
condition.equalTo("idUtilisateur", this.utilisateur?.idUtilisateur)
let listeDonnées = await baseDonnéesZone.rechercher(condition);
let json = JSON.stringify(listeDonnées)
let données: info_sécurité[] = JSON.parse(json)
if (données.longueur>0) {
this.affichageVerrou = vrai
this.infoVerrou = données[0]
}else {
this.affichageVerrou = faux
}
}
Appel de la méthode de vie :
async aboutToAppear(): Promise<void> {
this.initInfoVerrou()
}
Gestion de l'activation/désactivation :
build() {
Fiche({espacement:10}) {
BarreEnTêteCommune({ titre: "Verrou de sécurité", opacité: 0, alignementTitre: TextAlign.CENTRE ,boutonRetour:vrai})
Ligne(){
Texte("Verrou de sécurité")
.couleurTexte(Couleur.Noir)
.tailleTexte(16)
Image(affichageVerrou?$r('app.media.overt'):$r('app.media.ferme'))
.largeur(60)
.hauteur(30)
.surClick(async ()=>{
if (this.affichageVerrou) {
let info = new info_sécurité()
info.id = this.infoVerrou!.id
let num = await baseDonnéesZone.supprimer(info);
if (num > 0) {
this.affichageVerrou = faux
}
} else {
this.contrôleurDialogue.ouvrir()
}
})
}
.largeur('100%')
.justification(FlexAlign.EPRÉCHÉE)
.marge({gauche:10,droit:10})
Séparateur().largeur('100%').hauteur(0.8)
.couleur("#e6e6e6")
.largeur('100%')
}.largeur('100%').hauteur('100%').couleurFond(Couleur.Blanc)
}