管理、商家添加登录图片验证
parent
65cb7787a6
commit
33ec809e73
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#### 在组件上添加v-if来判断组件显隐
|
#### 在组件上添加v-if来判断组件显隐
|
||||||
|
|
||||||
#### verifyType 验证格式[ 'LOGIN' ,'REGISTER' ]等,详情看接口文档
|
#### verifyType 验证格式[ 'LOGIN' ,'REGISTER' ]
|
||||||
|
|
||||||
#### @change方法 获取回调,参数为对象 {status:false,distance:100} status 为回调状态,distance为移动距离
|
#### @change方法 获取回调,参数为对象 {status:false,distance:100} status 为回调状态,distance为移动距离
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,3 @@ export function postVerifyImg (params) {
|
||||||
headers: {uuid: storage.getItem('uuid')}
|
headers: {uuid: storage.getItem('uuid')}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mouseup () {
|
|
||||||
console.log(111);
|
|
||||||
}
|
|
||||||
|
|
|
@ -47,7 +47,8 @@
|
||||||
"vuex": "^3.4.0",
|
"vuex": "^3.4.0",
|
||||||
"wangeditor": "^4.5.3",
|
"wangeditor": "^4.5.3",
|
||||||
"xlsx": "^0.16.2",
|
"xlsx": "^0.16.2",
|
||||||
"xss": "^1.0.7"
|
"xss": "^1.0.7",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^4.4.4",
|
"@vue/cli-plugin-babel": "^4.4.4",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {v4 as uuidv4} from 'uuid';
|
||||||
import {getCategoryTree} from '@/api/goods.js'
|
import {getCategoryTree} from '@/api/goods.js'
|
||||||
export default {
|
export default {
|
||||||
updated() {
|
updated() {
|
||||||
|
@ -15,7 +16,14 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
mounted() {
|
||||||
|
let uuid = this.getStore('uuid');
|
||||||
|
if (!uuid) {
|
||||||
|
uuid = uuidv4();
|
||||||
|
this.setStore('uuid', uuid);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {commonUrl, getRequest} from '@/libs/axios';
|
import {commonUrl, getRequest, getRequestWithNoToken, postRequestWithNoToken} from '@/libs/axios';
|
||||||
|
|
||||||
// 通过id获取子地区
|
// 通过id获取子地区
|
||||||
export const getChildRegion = (id) => {
|
export const getChildRegion = (id) => {
|
||||||
|
@ -6,6 +6,16 @@ export const getChildRegion = (id) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 点地图获取地址信息
|
// 点地图获取地址信息
|
||||||
export const getRegion = (parpams) => {
|
export const getRegion = (params) => {
|
||||||
return getRequest(`${commonUrl}/common/region/region`, parpams);
|
return getRequest(`${commonUrl}/common/region/region`, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取拼图验证
|
||||||
|
export const getVerifyImg = (verificationEnums) => {
|
||||||
|
return getRequestWithNoToken(`${commonUrl}/common/slider/${verificationEnums}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 拼图验证
|
||||||
|
export const postVerifyImg = (params) => {
|
||||||
|
return postRequestWithNoToken(`${commonUrl}/common/slider/${params.verificationEnums}`, params);
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,8 @@ service.interceptors.request.use(
|
||||||
...config.params
|
...config.params
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const uuid = getStore('uuid');
|
||||||
|
config.headers['uuid'] = uuid;
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
|
|
|
@ -5,7 +5,7 @@ export const loginRouter = {
|
||||||
path: "/login",
|
path: "/login",
|
||||||
name: "login",
|
name: "login",
|
||||||
meta: {
|
meta: {
|
||||||
title: "登录 - lili "
|
title: "登录 - lili运营后台"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/login.vue")
|
component: () => import("@/views/login.vue")
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,6 +22,13 @@
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
|
<!-- 拼图验证码 -->
|
||||||
|
<verify
|
||||||
|
ref="verify"
|
||||||
|
class="verify-con"
|
||||||
|
verifyType="LOGIN"
|
||||||
|
@change="verifyChange"
|
||||||
|
></verify>
|
||||||
<div v-if="socialLogining">
|
<div v-if="socialLogining">
|
||||||
<RectLoading />
|
<RectLoading />
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,6 +48,7 @@ import LangSwitch from "@/views/main-components/lang-switch";
|
||||||
import RectLoading from "@/views/my-components/lili/rect-loading";
|
import RectLoading from "@/views/my-components/lili/rect-loading";
|
||||||
import CountDownButton from "@/views/my-components/lili/count-down-button";
|
import CountDownButton from "@/views/my-components/lili/count-down-button";
|
||||||
import util from "@/libs/util.js";
|
import util from "@/libs/util.js";
|
||||||
|
import verify from '@/views/my-components/verify';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -49,6 +57,7 @@ export default {
|
||||||
LangSwitch,
|
LangSwitch,
|
||||||
Header,
|
Header,
|
||||||
Footer,
|
Footer,
|
||||||
|
verify
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -79,7 +88,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
mounted() {},
|
mounted() {},
|
||||||
afterLogin(res) {
|
afterLogin(res) { // 登录成功后处理
|
||||||
let accessToken = res.result.accessToken;
|
let accessToken = res.result.accessToken;
|
||||||
let refreshToken = res.result.refreshToken;
|
let refreshToken = res.result.refreshToken;
|
||||||
this.setStore("accessToken", accessToken);
|
this.setStore("accessToken", accessToken);
|
||||||
|
@ -100,23 +109,28 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
submitLogin() {
|
submitLogin() { // 登录操作
|
||||||
this.$refs.usernameLoginForm.validate((valid) => {
|
this.$refs.usernameLoginForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
this.loading = true;
|
this.$refs.verify.show = true;
|
||||||
login({
|
|
||||||
username: this.form.username,
|
|
||||||
password: this.md5(this.form.password),
|
|
||||||
}).then((res) => {
|
|
||||||
if (res && res.success) {
|
|
||||||
this.afterLogin(res);
|
|
||||||
} else {
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
verifyChange (con) { // 拼图验证码回显
|
||||||
|
if (!con.status) return;
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
login({
|
||||||
|
username: this.form.username,
|
||||||
|
password: this.md5(this.form.password),
|
||||||
|
}).then((res) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
this.afterLogin(res);
|
||||||
|
} else {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}).catch(()=>{this.loading = false});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -140,7 +154,12 @@ export default {
|
||||||
position: relative;
|
position: relative;
|
||||||
zoom: 1;
|
zoom: 1;
|
||||||
}
|
}
|
||||||
|
.verify-con{
|
||||||
|
position: absolute;
|
||||||
|
top: 90px;
|
||||||
|
z-index: 10;
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
.form {
|
.form {
|
||||||
padding-top: 1vh;
|
padding-top: 1vh;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
### 滑动拼图验证
|
||||||
|
|
||||||
|
### 在页面中引入 .vue文件
|
||||||
|
|
||||||
|
#### 参数
|
||||||
|
|
||||||
|
#### 在组件上添加v-if来判断组件显隐
|
||||||
|
|
||||||
|
#### verifyType 验证格式[ 'LOGIN' ,'REGISTER' ]
|
||||||
|
|
||||||
|
#### @change方法 获取回调,参数为对象 {status:false,distance:100} status 为回调状态,distance为移动距离
|
||||||
|
|
||||||
|
|
||||||
|
#### <Verify class="verify-content" verifyType='LOGIN' @change="verifyChange"></Verify>
|
|
@ -0,0 +1,185 @@
|
||||||
|
<template>
|
||||||
|
<div class="verify-content" v-if="show" @mousemove="mouseMove" @mouseup="mouseUp">
|
||||||
|
<div class="imgBox" :style="{width:data.originalWidth+'px',height:data.originalHeight + 'px'}">
|
||||||
|
<img :src="data.backImage" style="width:100%;height:100%" alt="">
|
||||||
|
<img class="slider" :src="data.slidingImage" :style="{left:distance+'px',top:data.randomY+'px'}" :width="data.sliderWidth" :height="data.sliderHeight" alt="">
|
||||||
|
<Icon type="md-refresh" class="refresh" @click="refresh" />
|
||||||
|
</div>
|
||||||
|
<div class="handle" :style="{width:data.originalWidth+'px'}">
|
||||||
|
<span class="bgcolor" :style="{width:distance + 'px',background:bgColor}"></span>
|
||||||
|
<span class="swiper" :style="{left:distance + 'px'}" @mousedown="mouseDown">
|
||||||
|
<Icon type="md-arrow-round-forward" />
|
||||||
|
</span>
|
||||||
|
<span class="text">{{verifyText}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { getVerifyImg, postVerifyImg } from './verify.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
verifyType: {
|
||||||
|
defalut: 'LOGIN',
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
show: false, // 验证码显隐
|
||||||
|
type: 'LOGIN', // 请求类型
|
||||||
|
data: { // 验证码数据
|
||||||
|
backImage: '',
|
||||||
|
slidingImage: '',
|
||||||
|
originalHeight: 150,
|
||||||
|
originalWidth: 300,
|
||||||
|
sliderWidth: 60,
|
||||||
|
sliderHeight: 60
|
||||||
|
},
|
||||||
|
distance: 0, // 拼图移动距离
|
||||||
|
flag: false, // 判断滑块是否按下
|
||||||
|
downX: 0, // 鼠标按下位置
|
||||||
|
bgColor: 'aqua', // 滑动背景颜色
|
||||||
|
verifyText: '拖动滑块解锁' // 文字提示
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
mouseDown (e) {
|
||||||
|
this.downX = e.clientX;
|
||||||
|
this.flag = true;
|
||||||
|
},
|
||||||
|
mouseMove (e) {
|
||||||
|
if (this.flag) {
|
||||||
|
let offset = e.clientX - this.downX;
|
||||||
|
|
||||||
|
if (offset > this.data.originalWidth - 43) {
|
||||||
|
this.distance = this.data.originalWidth - 43;
|
||||||
|
} else if (offset < 0) {
|
||||||
|
this.distance = 0;
|
||||||
|
} else {
|
||||||
|
this.distance = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mouseUp () {
|
||||||
|
if (!this.flag) return false;
|
||||||
|
this.flag = false;
|
||||||
|
let params = {
|
||||||
|
verificationEnums: this.type,
|
||||||
|
xPos: this.distance
|
||||||
|
};
|
||||||
|
postVerifyImg(params).then(res => {
|
||||||
|
if (res.result) {
|
||||||
|
this.bgColor = 'green';
|
||||||
|
this.verifyText = '解锁成功';
|
||||||
|
this.$emit('change', { status: true, distance: this.distance });
|
||||||
|
} else {
|
||||||
|
this.bgColor = 'red';
|
||||||
|
this.verifyText = '解锁失败';
|
||||||
|
let that = this;
|
||||||
|
setTimeout(() => {
|
||||||
|
that.refresh();
|
||||||
|
}, 1000);
|
||||||
|
this.$emit('change', { status: false, distance: this.distance });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
refresh () {
|
||||||
|
this.flag = false;
|
||||||
|
this.downX = 0;
|
||||||
|
this.distance = 0;
|
||||||
|
this.bgColor = 'aqua';
|
||||||
|
this.verifyText = '拖动滑块解锁';
|
||||||
|
this.getImg();
|
||||||
|
},
|
||||||
|
getImg () {
|
||||||
|
getVerifyImg(this.type).then(res => {
|
||||||
|
this.data = res.result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.getImg();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
verifyType: {
|
||||||
|
immediate: true,
|
||||||
|
handler: function (v) {
|
||||||
|
this.type = v;
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
show (v) {
|
||||||
|
if (v) this.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.verify-content{
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 1px 1px 3px #999;
|
||||||
|
}
|
||||||
|
.imgBox {
|
||||||
|
width: 300px;
|
||||||
|
height: 150px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.handle {
|
||||||
|
border: 1px solid rgb(134, 134, 134);
|
||||||
|
margin-top: 5px;
|
||||||
|
height: 42px;
|
||||||
|
background: #ddd;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.bgcolor {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
opacity: 0.5;
|
||||||
|
background: aqua;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper {
|
||||||
|
position: absolute;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background-color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.ivu-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
display: inline-block;
|
||||||
|
width: inherit;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 42px;
|
||||||
|
font-size: 14px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
import {commonUrl, getRequestWithNoToken, postRequestWithNoToken} from '@/libs/axios';
|
||||||
|
|
||||||
|
|
||||||
|
// 获取拼图验证
|
||||||
|
export const getVerifyImg = (verificationEnums) => {
|
||||||
|
return getRequestWithNoToken(`${commonUrl}/common/slider/${verificationEnums}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 拼图验证
|
||||||
|
export const postVerifyImg = (params) => {
|
||||||
|
return postRequestWithNoToken(`${commonUrl}/common/slider/${params.verificationEnums}`, params);
|
||||||
|
};
|
|
@ -44,7 +44,8 @@
|
||||||
"vuex": "^3.4.0",
|
"vuex": "^3.4.0",
|
||||||
"wangeditor": "^4.6.13",
|
"wangeditor": "^4.6.13",
|
||||||
"xlsx": "^0.16.2",
|
"xlsx": "^0.16.2",
|
||||||
"xss": "^1.0.7"
|
"xss": "^1.0.7",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^4.4.4",
|
"@vue/cli-plugin-babel": "^4.4.4",
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {v4 as uuidv4} from 'uuid';
|
||||||
export default {
|
export default {
|
||||||
data() {
|
mounted() {
|
||||||
return {};
|
let uuid = this.getStore('uuid');
|
||||||
|
if (!uuid) {
|
||||||
|
uuid = uuidv4();
|
||||||
|
this.setStore('uuid', uuid);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {},
|
|
||||||
beforeDestroy() {},
|
|
||||||
methods: {}
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ service.interceptors.request.use(
|
||||||
...config.params
|
...config.params
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const uuid = getStore('uuid');
|
||||||
|
config.headers['uuid'] = uuid;
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
|
|
|
@ -5,7 +5,7 @@ export const loginRouter = {
|
||||||
path: "/login",
|
path: "/login",
|
||||||
name: "login",
|
name: "login",
|
||||||
meta: {
|
meta: {
|
||||||
title: "登录 - lili "
|
title: "登录 - lili商家后台 "
|
||||||
},
|
},
|
||||||
component: () => import("@/views/login.vue")
|
component: () => import("@/views/login.vue")
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,6 +55,13 @@
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
<!-- 拼图验证码 -->
|
||||||
|
<verify
|
||||||
|
ref="verify"
|
||||||
|
class="verify-con"
|
||||||
|
verifyType="LOGIN"
|
||||||
|
@change="verifyChange"
|
||||||
|
></verify>
|
||||||
</Col>
|
</Col>
|
||||||
<!-- <LangSwitch /> -->
|
<!-- <LangSwitch /> -->
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -72,11 +79,13 @@ import Header from "@/views/main-components/header";
|
||||||
import Footer from "@/views/main-components/footer";
|
import Footer from "@/views/main-components/footer";
|
||||||
import LangSwitch from "@/views/main-components/lang-switch";
|
import LangSwitch from "@/views/main-components/lang-switch";
|
||||||
import util from "@/libs/util.js";
|
import util from "@/libs/util.js";
|
||||||
|
import verify from '@/views/my-components/verify';
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
LangSwitch,
|
LangSwitch,
|
||||||
Header,
|
Header,
|
||||||
Footer,
|
Footer,
|
||||||
|
verify
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -154,23 +163,27 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
submitLogin() {
|
submitLogin() { // 登录提交
|
||||||
// 正常逻辑
|
|
||||||
this.$refs.usernameLoginForm.validate((valid) => {
|
this.$refs.usernameLoginForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
this.loading = true;
|
this.$refs.verify.show = true;
|
||||||
login({
|
|
||||||
username: this.form.username,
|
|
||||||
password: this.md5(this.form.password),
|
|
||||||
}).then((res) => {
|
|
||||||
this.loading = false;
|
|
||||||
if (res && res.success) {
|
|
||||||
this.afterLogin(res);
|
|
||||||
}
|
|
||||||
}).catch(()=>{this.loading = false})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
verifyChange (con) { // 拼图验证码回显
|
||||||
|
if (!con.status) return;
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
login({
|
||||||
|
username: this.form.username,
|
||||||
|
password: this.md5(this.form.password),
|
||||||
|
}).then((res) => {
|
||||||
|
this.loading = false;
|
||||||
|
if (res && res.success) {
|
||||||
|
this.afterLogin(res);
|
||||||
|
}
|
||||||
|
}).catch(()=>{this.loading = false})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -203,6 +216,12 @@ export default {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column !important;
|
flex-direction: column !important;
|
||||||
}
|
}
|
||||||
|
.verify-con{
|
||||||
|
position: absolute;
|
||||||
|
top: 126px;
|
||||||
|
z-index: 10;
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
.form {
|
.form {
|
||||||
padding-top: 1vh;
|
padding-top: 1vh;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
### 滑动拼图验证
|
||||||
|
|
||||||
|
### 在页面中引入 .vue文件
|
||||||
|
|
||||||
|
#### 参数
|
||||||
|
|
||||||
|
#### 在组件上添加v-if来判断组件显隐
|
||||||
|
|
||||||
|
#### verifyType 验证格式[ 'LOGIN' ,'REGISTER' ]
|
||||||
|
|
||||||
|
#### @change方法 获取回调,参数为对象 {status:false,distance:100} status 为回调状态,distance为移动距离
|
||||||
|
|
||||||
|
|
||||||
|
#### <Verify class="verify-content" verifyType='LOGIN' @change="verifyChange"></Verify>
|
|
@ -0,0 +1,185 @@
|
||||||
|
<template>
|
||||||
|
<div class="verify-content" v-if="show" @mousemove="mouseMove" @mouseup="mouseUp">
|
||||||
|
<div class="imgBox" :style="{width:data.originalWidth+'px',height:data.originalHeight + 'px'}">
|
||||||
|
<img :src="data.backImage" style="width:100%;height:100%" alt="">
|
||||||
|
<img class="slider" :src="data.slidingImage" :style="{left:distance+'px',top:data.randomY+'px'}" :width="data.sliderWidth" :height="data.sliderHeight" alt="">
|
||||||
|
<Icon type="md-refresh" class="refresh" @click="refresh" />
|
||||||
|
</div>
|
||||||
|
<div class="handle" :style="{width:data.originalWidth+'px'}">
|
||||||
|
<span class="bgcolor" :style="{width:distance + 'px',background:bgColor}"></span>
|
||||||
|
<span class="swiper" :style="{left:distance + 'px'}" @mousedown="mouseDown">
|
||||||
|
<Icon type="md-arrow-round-forward" />
|
||||||
|
</span>
|
||||||
|
<span class="text">{{verifyText}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { getVerifyImg, postVerifyImg } from './verify.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
verifyType: {
|
||||||
|
defalut: 'LOGIN',
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
show: false, // 验证码显隐
|
||||||
|
type: 'LOGIN', // 请求类型
|
||||||
|
data: { // 验证码数据
|
||||||
|
backImage: '',
|
||||||
|
slidingImage: '',
|
||||||
|
originalHeight: 150,
|
||||||
|
originalWidth: 300,
|
||||||
|
sliderWidth: 60,
|
||||||
|
sliderHeight: 60
|
||||||
|
},
|
||||||
|
distance: 0, // 拼图移动距离
|
||||||
|
flag: false, // 判断滑块是否按下
|
||||||
|
downX: 0, // 鼠标按下位置
|
||||||
|
bgColor: 'aqua', // 滑动背景颜色
|
||||||
|
verifyText: '拖动滑块解锁' // 文字提示
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
mouseDown (e) {
|
||||||
|
this.downX = e.clientX;
|
||||||
|
this.flag = true;
|
||||||
|
},
|
||||||
|
mouseMove (e) {
|
||||||
|
if (this.flag) {
|
||||||
|
let offset = e.clientX - this.downX;
|
||||||
|
|
||||||
|
if (offset > this.data.originalWidth - 43) {
|
||||||
|
this.distance = this.data.originalWidth - 43;
|
||||||
|
} else if (offset < 0) {
|
||||||
|
this.distance = 0;
|
||||||
|
} else {
|
||||||
|
this.distance = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mouseUp () {
|
||||||
|
if (!this.flag) return false;
|
||||||
|
this.flag = false;
|
||||||
|
let params = {
|
||||||
|
verificationEnums: this.type,
|
||||||
|
xPos: this.distance
|
||||||
|
};
|
||||||
|
postVerifyImg(params).then(res => {
|
||||||
|
if (res.result) {
|
||||||
|
this.bgColor = 'green';
|
||||||
|
this.verifyText = '解锁成功';
|
||||||
|
this.$emit('change', { status: true, distance: this.distance });
|
||||||
|
} else {
|
||||||
|
this.bgColor = 'red';
|
||||||
|
this.verifyText = '解锁失败';
|
||||||
|
let that = this;
|
||||||
|
setTimeout(() => {
|
||||||
|
that.refresh();
|
||||||
|
}, 1000);
|
||||||
|
this.$emit('change', { status: false, distance: this.distance });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
refresh () {
|
||||||
|
this.flag = false;
|
||||||
|
this.downX = 0;
|
||||||
|
this.distance = 0;
|
||||||
|
this.bgColor = 'aqua';
|
||||||
|
this.verifyText = '拖动滑块解锁';
|
||||||
|
this.getImg();
|
||||||
|
},
|
||||||
|
getImg () {
|
||||||
|
getVerifyImg(this.type).then(res => {
|
||||||
|
this.data = res.result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.getImg();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
verifyType: {
|
||||||
|
immediate: true,
|
||||||
|
handler: function (v) {
|
||||||
|
this.type = v;
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
show (v) {
|
||||||
|
if (v) this.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.verify-content{
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 1px 1px 3px #999;
|
||||||
|
}
|
||||||
|
.imgBox {
|
||||||
|
width: 300px;
|
||||||
|
height: 150px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.handle {
|
||||||
|
border: 1px solid rgb(134, 134, 134);
|
||||||
|
margin-top: 5px;
|
||||||
|
height: 42px;
|
||||||
|
background: #ddd;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.bgcolor {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
opacity: 0.5;
|
||||||
|
background: aqua;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper {
|
||||||
|
position: absolute;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background-color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.ivu-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
display: inline-block;
|
||||||
|
width: inherit;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 42px;
|
||||||
|
font-size: 14px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
import {commonUrl, getRequestWithNoToken, postRequestWithNoToken} from '@/libs/axios';
|
||||||
|
|
||||||
|
|
||||||
|
// 获取拼图验证
|
||||||
|
export const getVerifyImg = (verificationEnums) => {
|
||||||
|
return getRequestWithNoToken(`${commonUrl}/common/slider/${verificationEnums}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 拼图验证
|
||||||
|
export const postVerifyImg = (params) => {
|
||||||
|
return postRequestWithNoToken(`${commonUrl}/common/slider/${params.verificationEnums}`, params);
|
||||||
|
};
|
Loading…
Reference in New Issue