宝安水环境管控平台(Ionic/Angular 移动端) 问题记录

目录

一. 登录前的验证码校验功能

1. 添加滑动校验 Angular 组件

1.1 verifySlipping.component.html

1.2 verifySlipping.component.css

1.3 verifySlipping.component.ts

1.4 verify.js

1.5 aes-encrypt-decrypt.ts

1.6 verify.service.ts

2. 添加登录时的验证码校验逻辑

2.1 保持 loginService 服务为单例,避免路由守卫出 bug

2.2 获取密钥时,Angular Http 请求发送失败 

2.3 点击登录按钮,初始化验证码

2.4 初始化验证码

2.5 验证码校验成功后 执行真正的登录

2.6 效果展示

二. 修改密码功能

1. 进入页面后,加密登录名,获取新密钥

2. 校验密码,要求包含大小写字母、数字、特殊字符

3. 修改密码,传参格式 FORM['USER_ID'] 的写法


一. 登录前的验证码校验功能

验证码校验功能参考开源项目 AJ-Captcha

将验证码功能,嵌入你的项目里,需要添加以下依赖:

yarn add crypto-js

yarn add jwt-decode

yarn add jquery

1. 添加滑动校验 Angular 组件

AJ-Captcha: 行为验证码(滑动拼图、点选文字),前后端(java)交互,包含vue/h5/Android/IOS/flutter/uni-app/react/php/微信小程序的源码和实现https://gitee.com/anji-plus/captcha

三点说明:

  • 我下载了上面仓库中的 Angular 前端示例,使用 ng serve 运行项目
  • 此示例和我项目中的实际逻辑,区别较大,我几乎只用到了组件
  • 需要参考的前提:项目后端系统已经配备了相应后端接口

下面介绍下验证码组件相关内容

1.1 verifySlipping.component.html

注释掉的部分:验证码提示框的头部,一般情况下用不上,会导致显示混乱

此处需要注意两个ID,这俩 ID 在组件中会被 jquery 操作控制显隐:

  • mpanel1:用于盛放验证码图片、拼图、滑块之类的容器
  • slipping:用于标识这是 滑动校验组件,不是 点选文字校验组件

文件地址:src\app\components\verify\verifySlipping.component.html



1.2 verifySlipping.component.css

验证码弹框组件的基本样式

注意:验证码弹框的宽度是写死的,这会导致屏幕小的手机,显示不全验证码弹框

由于时间紧促,我没研究改哪些宽度百分比,而是直接使用了 scale(0.85) 缩小移动端弹框

文件地址:src\app\components\verify\verifySlipping.component.css

.btn {border: none;outline: none;width: 300px;height: 40px;line-height: 40px;text-align: center;cursor: pointer;background-color: #409eff;color: #fff;font-size: 16px;letter-spacing: 1em;
}.modal-dialog {width: 466px;
}

global.scss 下,补充了全局验证码弹框样式

之前打算使用 important 强行覆盖 jq 动态写入的验证码弹框宽度,后来因为要修改的地方太多,懒得改了,所以采用了 transform: translate(-50%, -50%) scale(0.85);

文件地址:src\global.scss

/*** 安全验证
*/
.verify-code {font-size: 20px;text-align: center;cursor: pointer;margin-bottom: 5px;border: 1px solid #ddd;
}.cerify-code-panel {height: 100%;overflow: hidden;
}.verify-code-area {float: left;
}.verify-input-area {float: left;width: 60%;padding-right: 10px;
}.verify-change-area {line-height: 30px;float: left;
}.varify-input-code {display: inline-block;width: 100%;height: 25px;
}.verify-change-code {color: #337ab7;cursor: pointer;
}.verify-btn {width: 200px;height: 30px;background-color: #337ab7;color: #ffffff;border: none;margin-top: 10px;
}.verifybox {position: relative;box-sizing: border-box;border-radius: 2px;background-color: #fff;left: 50%;top: 50%;transform: translate(-50%, -50%) scale(0.85);
}
.verifybox-top {padding: 0 15px;/* height: 50px; */line-height: 50px;text-align: left;font-size: 16px;color: #45494c;box-sizing: border-box;
}
.verifybox-bottom {padding: 15px;box-sizing: border-box;
}
.verifybox-close {position: absolute;top: 13px;right: 9px;width: 24px;height: 24px;line-height: 24px;text-align: center;cursor: pointer;
}
.mask {position: fixed;top: 0;left: 0;z-index: 1001;width: 100%;height: 100vh;background: rgba(0, 0, 0, 0.3);/* display: none; */transition: all 0.5s;display: none;
}.verify-tips {position: absolute;display: none;left: 0px;bottom: -35px;width: 100%;height: 30px;/* transition: all .5s; */line-height: 30px;color: #fff;/* animation:move 1.5s linear; */
}@keyframes move {0% {bottom: -35px;}50%,80% {bottom: 0px;}100% {bottom: -35px;}
}.suc-bg {background-color: rgba(92, 184, 92, 0.5);filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7f5CB85C, endcolorstr=#7f5CB85C);
}
.err-bg {background-color: rgba(217, 83, 79, 0.5);filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7fD9534F, endcolorstr=#7fD9534F);
}/*滑动验证码*/
.verify-bar-area {position: relative;background: #ffffff;text-align: center;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;border: 1px solid #ddd;-webkit-border-radius: 4px;
}.verify-bar-area .verify-move-block {position: absolute;top: 0px;left: 0;background: #fff;cursor: pointer;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;box-shadow: 0 0 2px #888888;-webkit-border-radius: 1px;
}.verify-bar-area .verify-move-block:hover {background-color: #337ab7;color: #ffffff;
}.verify-bar-area .verify-left-bar {position: absolute;top: -1px;left: -1px;background: #f0fff0;cursor: pointer;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;border: 1px solid #ddd;
}.verify-img-panel {margin: 0;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;border: 1px solid #ddd;border-radius: 3px;position: relative;
}.verify-img-panel .verify-refresh {width: 25px;height: 25px;text-align: center;padding: 5px;cursor: pointer;position: absolute;top: 0;right: 0;z-index: 2;
}.verify-img-panel .icon-refresh {font-size: 20px;color: #fff;
}.verify-img-panel .verify-gap {background-color: #fff;position: relative;z-index: 2;border: 1px solid #fff;
}.verify-bar-area .verify-move-block .verify-sub-block {position: absolute;text-align: center;z-index: 3;/* border: 1px solid #fff; */
}.verify-bar-area .verify-move-block .verify-icon {font-size: 18px;
}.verify-bar-area .verify-msg {z-index: 3;
}/* 字体图标的css */
@font-face {font-family: "iconfont";src: url("./assets/font/iconfont.eot?t=1508229193188"); /* IE9*/src: url("./assets/font/iconfont.eot?t=1508229193188#iefix")format("embedded-opentype"),/* IE6-IE8 */url("data:application/x-font-woff;charset=utf-8;base64,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")format("woff"),url("./assets/font/iconfont.ttf?t=1508229193188") format("truetype"),/* chrome, firefox, opera, Safari, Android, iOS 4.2+*/url("./assets/font/iconfont.svg?t=1508229193188#iconfont") format("svg"); /* iOS 4.1- */
}.iconfont {font-family: "iconfont" !important;font-size: 16px;font-style: normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}.icon-check:before {content: "\e645";
}.icon-close:before {content: "\e646";
}.icon-right:before {content: "\e6a3";
}.icon-refresh:before {content: "\e6a4";
}

1.3 verifySlipping.component.ts

官网示例中,初始化验证码是在组件里进行的

但是,我的项目在 初始化验证码请求图片 时,需要传入额外的参数;因此,我注释了组件内的 初始化验证码 逻辑

文件地址:src\app\components\verify\verifySlipping.component.ts

import { Component } from '@angular/core';
import './verify/verify.js';@Component({selector: 'verify-slipping',templateUrl: './verifySlipping.component.html',styleUrls: ['./verifySlipping.component.css'],
})
export class verifySlippingComponent {/*** 页面初始化*/ngOnInit(): void {// 引入 promiseif (!window.Promise) {document.writeln('
                    

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部