This commit is contained in:
Paidax
2024-07-25 18:22:29 +08:00
parent ed80df416c
commit 3270efcdc6
6 changed files with 153 additions and 39 deletions
@@ -51,8 +51,8 @@ public class ValidateService {
throw new SmsException("请1分钟之后再试"); throw new SmsException("请1分钟之后再试");
} }
if (redisService.exists(RedisConstant.REDIS_SMSCODE_KEY + mobile)){ if (redisService.exists(RedisConstant.REDIS_SMSCODE_KEY + mobile)) {
return NutMap.NEW().addv("key", RedisConstant.REDIS_SMSCODE_KEY + mobile); return NutMap.NEW().addv("key", RedisConstant.REDIS_SMSCODE_KEY + mobile).addv("msg", "验证码仍在有效期内");
} }
Orm_Msg ormMsgJsr = new Orm_Msg(); Orm_Msg ormMsgJsr = new Orm_Msg();
@@ -65,7 +65,7 @@ public class ValidateService {
log.debug("sms code:::" + text); log.debug("sms code:::" + text);
redisService.setex(RedisConstant.REDIS_SMSCODE_KEY + mobile, 300, text); redisService.setex(RedisConstant.REDIS_SMSCODE_KEY + mobile, 300, text);
redisService.setex(RedisConstant.REDIS_SMSCODE_KEY + mobile + ":LOCK", 60, text); redisService.setex(RedisConstant.REDIS_SMSCODE_KEY + mobile + ":LOCK", 60, text);
return NutMap.NEW().addv("key", RedisConstant.REDIS_SMSCODE_KEY + mobile); return NutMap.NEW().addv("key", RedisConstant.REDIS_SMSCODE_KEY + mobile).addv("msg", "发送成功");
} }
throw new SmsException("发送验证码失败,请联系管理员或稍后重试"); throw new SmsException("发送验证码失败,请联系管理员或稍后重试");
} }
@@ -57,10 +57,14 @@ public class mobileLoginController {
@At("/doLogin") @At("/doLogin")
@Ok("json") @Ok("json")
@Filters(@By(type = PlatformAuthenticationFilter.class)) @Filters(@By(type = PlatformAuthenticationFilter.class))
public Object doLogin(@Attr("platformLoginToken") AuthenticationToken token, HttpServletRequest request, HttpSession session) { public Object doLogin(@Attr("platformLoginToken") AuthenticationToken token, String loginType, HttpServletRequest request, HttpSession session) {
int errCount = NumberUtils.toInt(Strings.sNull(SecurityUtils.getSubject().getSession(true).getAttribute("platformErrCount"))); int errCount = NumberUtils.toInt(Strings.sNull(SecurityUtils.getSubject().getSession(true).getAttribute("platformErrCount")));
try { try {
loginUtil.doLogin(token, request, session, LoginUtil.LoginOrigin.WEB_H5); if ("SMS_CODE".equals(loginType)){
loginUtil.doLogin(token, request, session, LoginUtil.LoginOrigin.SMS_CODE);
} else {
loginUtil.doLogin(token, request, session, LoginUtil.LoginOrigin.WEB_H5);
}
return Result.success("login.success"); return Result.success("login.success");
} catch (CaptchaIncorrectException e) { } catch (CaptchaIncorrectException e) {
return Result.error(1, "login.error.captcha"); return Result.error(1, "login.error.captcha");
Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 KiB

After

Width:  |  Height:  |  Size: 214 KiB

@@ -172,8 +172,7 @@
width="450" width="450"
popper-class="appCenterPopover" popper-class="appCenterPopover"
placement="top-start" placement="top-start"
v-model="menuPopover" trigger="click">
trigger="visible">
<el-card shadow="never" class="appCenterCard"> <el-card shadow="never" class="appCenterCard">
<template #header> <template #header>
<el-row type="flex" justify="space-between"> <el-row type="flex" justify="space-between">
@@ -205,9 +204,9 @@
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<el-row type="flex" justify="end"> <!--<el-row type="flex" justify="end">
<el-button type="primary" size="mini" @click="menuPopover=!menuPopover">关闭</el-button> <el-button type="primary" size="mini" @click="menuPopover=!menuPopover">关闭</el-button>
</el-row> </el-row>-->
</el-card> </el-card>
<a href="javascript:" slot="reference" @click="toggleMenuPopover"> <a href="javascript:" slot="reference" @click="toggleMenuPopover">
<i class="fa fa-th-large" aria-hidden="true"></i> <i class="fa fa-th-large" aria-hidden="true"></i>
+140 -30
View File
@@ -67,7 +67,7 @@ layout("/mobile/platform.html"){
.bottom_v { .bottom_v {
position: absolute; position: absolute;
bottom: 0; bottom: 30px;
left: 0; left: 0;
width: 100%; width: 100%;
} }
@@ -98,10 +98,12 @@ layout("/mobile/platform.html"){
</svg> </svg>
</van-col> </van-col>
<van-col span="22"> <van-col span="22">
<van-field v-model="formData.username" placeholder="输入工号" clearable></van-field> <van-field v-model="formData.mobile" type="tel" maxlength="11"
:rules="[{ pattern , message: '请输入正确的手机号' }]"
placeholder="请输入手机号" clearable></van-field>
</van-col> </van-col>
</van-row> </van-row>
<van-row style="border-bottom: 1px rgb(230, 230, 230) solid !important;"> <!--<van-row style="border-bottom: 1px rgb(230, 230, 230) solid !important;">
<van-col span="2" style="line-height:50px;text-align: left;margin-top: 30px;"> <van-col span="2" style="line-height:50px;text-align: left;margin-top: 30px;">
<svg t="1592742837149" class="icon" viewBox="0 0 1024 1024" version="1.1" <svg t="1592742837149" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="3554" width="16" height="16"> xmlns="http://www.w3.org/2000/svg" p-id="3554" width="16" height="16">
@@ -113,7 +115,7 @@ layout("/mobile/platform.html"){
<van-field v-model="formData.password" type="password" placeholder="输入密码" <van-field v-model="formData.password" type="password" placeholder="输入密码"
style="margin-top: 30px" clearable></van-field> style="margin-top: 30px" clearable></van-field>
</van-col> </van-col>
</van-row> </van-row>-->
<van-row style="border-bottom: 1px rgb(230,230,230) solid !important;"> <van-row style="border-bottom: 1px rgb(230,230,230) solid !important;">
<van-col span="2" style="line-height:50px;text-align: left;margin-top: 30px;"> <van-col span="2" style="line-height:50px;text-align: left;margin-top: 30px;">
<svg t="1592742837149" class="icon" viewBox="0 0 1024 1024" version="1.1" <svg t="1592742837149" class="icon" viewBox="0 0 1024 1024" version="1.1"
@@ -123,24 +125,32 @@ layout("/mobile/platform.html"){
</svg> </svg>
</van-col> </van-col>
<van-col span="22"> <van-col span="22">
<van-field v-model="formData.platformCaptcha" placeholder="输入验证码" <van-field v-model="formData.platformCaptcha" placeholder="请输入手机动态码"
style="margin-top: 30px" clearable> style="margin-top: 30px" maxlength="6" clearable>
<template #button> <template #button>
<div class="login-code"> <div class="login-code" style="margin-top: -20px">
<img :src="codeUrl" @click="getCode" alt=""> <van-button type="info" @click="sendCode()">{{ codeMsg }}</van-button>
</div> </div>
</template> </template>
</van-field> </van-field>
</van-col> </van-col>
</van-row> </van-row>
</div> </div>
<div class="bottom_v"> <div class="bottom_v">
<van-button :loading="loading" size="large" color="linear-gradient(to right,#2b97d7,#8bc4ff)" <van-button :loading="loading" size="large" color="linear-gradient(to right,#2b97d7,#8bc4ff)"
@click="doLogin">登 录 @click="handleLogin">登 录
</van-button> </van-button>
</div> </div>
<van-dialog
title="请拖动滑块完成拼图"
v-model="isShowSliderVerify"
@close="refresh"
append-to-body>
<slider-verify ref="sliderVerify" @success="onSuccess" @fail="onFail" @again="onAgain"></slider-verify>
</van-dialog>
</div> </div>
</div> </div>
<script> <script>
@@ -149,55 +159,155 @@ layout("/mobile/platform.html"){
el: "#app", el: "#app",
data() { data() {
return { return {
// 是否禁用按钮
codeDisabled: false,
// 倒计时秒数
countdown: 60,
// 按钮上的文字
codeMsg: '获取动态码',
// 定时器
timer: null,
isShowSliderVerify: false,
loading: false, loading: false,
formData: { formData: {
username: '', mobile: '',
password: '', password: '',
platformKey: '', platformKey: '',
platformCaptcha: "", platformCaptcha: '',
// 随机字符串
nonceStr: '',
// 验证值
value: '',
}, },
isNull(val) { isNull(val) {
return !val; return !val;
}, },
codeUrl: "${base!}/platform/login/captcha", pattern: /^1[3-9]\d{9}$/
} }
}, },
components: {
'slider-verify': httpVueLoader('/components/captcha/sliderVerify.vue'),
},
methods: { methods: {
doLogin() { async sendCode() {
let self = this if (this.codeDisabled) {
if (this.isNull(this.formData.username)) {
vue.$notify({type: 'warning', message: '请填写工号'});
return return
} }
if (this.isNull(this.formData.password)) { if (this.isNull(this.formData.mobile)) {
vue.$notify({type: 'warning', message: '请填写密码'}); vue.$notify({type: 'warning', message: '请填写手机号'});
return
}
const resp = await this.validMobile();
if (resp.code !== 0) {
vue.$notify({type: 'warning', message: resp.msg});
return
}
/*发送验证码功能*/
//若发送验证码成功,则调用倒计时函数
const {code, data} = await $.post('/platform/login/mobileCaptcha', {mobile: this.formData.mobile})
if(code === 0) {
this.formData.platformKey = data.key
vue.$notify({type: 'success', message: data.msg});
await this.getCode();
} else {
vue.$notify({type: 'warning', message: '动态码发送失败,请联系管理员'});
}
},
//验证手机号是否存在
async validMobile() {
return await $.post('${base!}/platform/login/validMobile', {mobile: this.formData.mobile})
},
// 获取验证码
async getCode() {
// 验证码60秒倒计时
if (!this.timer) {
this.timer = setInterval(() => {
if (this.countdown > 0 && this.countdown <= 60) {
this.countdown--;
if (this.countdown !== 0) {
this.codeDisabled = true;
this.codeMsg = "重新发送(" + this.countdown + ")";
} else {
clearInterval(this.timer);
this.codeMsg = "获取动态码";
this.countdown = 60;
this.timer = null;
this.codeDisabled = false;
}
}
}, 1000)
}
},
//验证图片滑动
async validVerify() {
return await $.post('${base!}/platform/login/validVerify', {
nonceStr: this.formData.nonceStr,
value: this.formData.value,
})
},
/* 滑动验证成功*/
async onSuccess(captcha) {
Object.assign(this.formData, captcha);
const resp = await this.validVerify()
if(resp.code === 0) {
await this.doLogin();
} else {
this.$refs.sliderVerify.verifyFailEvent(resp.msg);
}
},
/* 滑动验证失败*/
onFail(msg) {
vue.$notify({type: 'warning', message: msg || '验证失败,请控制拼图对齐缺口'});
},
/* 滑动验证异常*/
onAgain() {
vue.$notify({type: 'warning', message: '滑动操作异常,请重试'});
this.$refs.sliderVerify.refresh();
},
/* 刷新验证码*/
refresh() {
this.$refs.sliderVerify.refresh();
},
handleLogin() {
if (this.isNull(this.formData.mobile)) {
vue.$notify({type: 'warning', message: '请填写手机号'});
return return
} }
if (this.isNull(this.formData.platformCaptcha)) { if (this.isNull(this.formData.platformCaptcha)) {
vue.$notify({type: 'warning', message: '请填写验证码'}); vue.$notify({type: 'warning', message: '请填写手机动态码'});
return
}
this.isShowSliderVerify = true;
},
doLogin() {
let self = this
if (this.isNull(this.formData.mobile)) {
vue.$notify({type: 'warning', message: '请填写手机号'});
return
}
if (this.isNull(this.formData.platformCaptcha)) {
vue.$notify({type: 'warning', message: '请填写手机动态码'});
return return
} }
this.loading = true this.loading = true
this.formData.loginType = 'SMS_CODE'
$.post("/mobile/login/doLogin", this.formData, function (d) { $.post("/mobile/login/doLogin", this.formData, function (d) {
self.loading = false self.loading = false
if (d.code === 0) { if (d.code === 0) {
location.href = '/mobile/index' vue.$notify({type: 'success', message: d.msg})
setTimeout(() => {
location.href = '/mobile/index'
},500)
} else { } else {
vue.$notify({type: 'danger', message: d.msg}) vue.$notify({type: 'danger', message: d.msg})
self.getCode() self.isShowSliderVerify = false
} }
}, "json"); }, "json");
}, },
async getCode() {
const {data} = await $.get('/platform/login/captcha')
this.codeUrl = data.codeUrl
this.formData.platformKey = data.key
}
}, },
created() {
this.getCode()
}
}) })
</script> </script>
<!--# <!--#
@@ -308,6 +308,7 @@
const {code, data} = await $.post('/platform/login/mobileCaptcha', {mobile: this.loginForm.mobile}) const {code, data} = await $.post('/platform/login/mobileCaptcha', {mobile: this.loginForm.mobile})
if(code === 0) { if(code === 0) {
this.loginForm.platformKey = data.key this.loginForm.platformKey = data.key
this.$message.success(data.msg)
this.getCode(); this.getCode();
} else { } else {
this.$message({showClose: true, type: 'warning', message: '动态码发送失败,请联系管理员'}); this.$message({showClose: true, type: 'warning', message: '动态码发送失败,请联系管理员'});