You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hyp-front/src/components/Verifition/Verify/VerifySlide.vue

434 lines
12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div style="position: relative">
<div
v-if="type === '2'"
class="verify-img-out"
:style="{ height: parseInt(setSize.imgHeight) + vSpace + 'px' }"
>
<div
class="verify-img-panel"
:style="{ width: setSize.imgWidth, height: setSize.imgHeight }"
>
<img
:src="
backImgBase ? 'data:image/png;base64,' + backImgBase : defaultImg
"
alt=""
style="width: 100%; height: 100%; display: block"
/>
<div class="verify-refresh" @click="refresh" v-show="showRefresh">
<i class="iconfont icon-refresh"></i>
</div>
<transition name="tips">
<span
class="verify-tips"
v-if="tipWords"
:class="passFlag ? 'suc-bg' : 'err-bg'"
>{{ tipWords }}</span
>
</transition>
</div>
</div>
<!-- 公共部分 -->
<div
class="verify-bar-area"
:style="{
width: setSize.imgWidth,
height: barSize.height,
'line-height': barSize.height,
}"
>
<span class="verify-msg" v-text="text"></span>
<div
class="verify-left-bar"
:style="{
width: leftBarWidth !== undefined ? leftBarWidth : barSize.height,
height: barSize.height,
'border-color': leftBarBorderColor,
transaction: transitionWidth,
}"
>
<span class="verify-msg" v-text="finishText"></span>
<div
class="verify-move-block"
@touchstart="start"
@mousedown="start"
:style="{
width: barSize.height,
height: barSize.height,
'background-color': moveBlockBackgroundColor,
left: moveBlockLeft,
transition: transitionLeft,
}"
>
<i
:class="['verify-icon iconfont', iconClass]"
:style="{ color: iconColor }"
></i>
<div
v-if="type === '2'"
class="verify-sub-block"
:style="{
width: Math.floor((parseInt(setSize.imgWidth) * 47) / 310) + 'px',
height: setSize.imgHeight,
top: '-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
}"
>
<img
:src="'data:image/png;base64,' + blockBackImgBase"
alt=""
style="width: 100%; height: 100%; display: block"
/>
</div>
</div>
</div>
</div>
</div>
</template>
<script type="text/babel">
/**
* VerifySlide
* @description
* */
import { aesEncrypt } from "./../utils/ase";
import { resetSize } from "./../utils/util";
import { reqGet, reqCheck } from "./../api/index";
// "captchaType":"blockPuzzle",
export default {
name: "VerifySlide",
props: {
captchaType: {
type: String,
},
type: {
type: String,
default: "1",
},
//popfixed
mode: {
type: String,
default: "fixed",
},
vSpace: {
type: Number,
default: 5,
},
explain: {
type: String,
default: "",
},
imgSize: {
type: Object,
default() {
return {
width: "310px",
height: "155px",
};
},
},
blockSize: {
type: Object,
default() {
return {
width: "50px",
height: "50px",
};
},
},
barSize: {
type: Object,
default() {
return {
width: "310px",
height: "40px",
};
},
},
defaultImg: {
type: String,
default: "",
},
},
data() {
return {
secretKey: "", //
passFlag: "", //
backImgBase: "", //
blockBackImgBase: "", //
backToken: "", //token
startMoveTime: "", //
endMovetime: "", //
tipsBackColor: "", //
tipWords: "",
text: "",
finishText: "",
setSize: {
imgHeight: 0,
imgWidth: 0,
barHeight: 0,
barWidth: 0,
},
top: 0,
left: 0,
moveBlockLeft: undefined,
leftBarWidth: undefined,
//
moveBlockBackgroundColor: undefined,
leftBarBorderColor: "#ddd",
iconColor: undefined,
iconClass: "icon-right",
status: false, //
isEnd: false, //
showRefresh: true,
transitionLeft: "",
transitionWidth: "",
};
},
computed: {
barArea() {
return this.$el.querySelector(".verify-bar-area");
},
resetSize() {
return resetSize;
},
},
methods: {
init() {
this.text = this.explain;
this.getPictrue();
this.$nextTick(() => {
let setSize = this.resetSize(this); //重新设置宽度高度
for (let key in setSize) {
this.$set(this.setSize, key, setSize[key]);
}
this.$parent.$emit("ready", this);
});
var _this = this;
window.removeEventListener("touchmove", function (e) {
_this.move(e);
});
window.removeEventListener("mousemove", function (e) {
_this.move(e);
});
//鼠标松开
window.removeEventListener("touchend", function () {
_this.end();
});
window.removeEventListener("mouseup", function () {
_this.end();
});
window.addEventListener("touchmove", function (e) {
_this.move(e);
});
window.addEventListener("mousemove", function (e) {
_this.move(e);
});
//鼠标松开
window.addEventListener("touchend", function () {
_this.end();
});
window.addEventListener("mouseup", function () {
_this.end();
});
},
//鼠标按下
start: function (e) {
e = e || window.event;
if (!e.touches) {
//兼容PC端
var x = e.clientX;
} else {
//兼容移动端
var x = e.touches[0].pageX;
}
this.startLeft = Math.floor(
x - this.barArea.getBoundingClientRect().left
);
this.startMoveTime = +new Date(); //开始滑动的时间
if (this.isEnd == false) {
this.text = "";
this.moveBlockBackgroundColor = "#337ab7";
this.leftBarBorderColor = "#337AB7";
this.iconColor = "#fff";
e.stopPropagation();
this.status = true;
}
},
//鼠标移动
move: function (e) {
e = e || window.event;
if (this.status && this.isEnd == false) {
if (!e.touches) {
//兼容PC端
var x = e.clientX;
} else {
//兼容移动端
var x = e.touches[0].pageX;
}
var bar_area_left = this.barArea.getBoundingClientRect().left;
var move_block_left = x - bar_area_left; //小方块相对于父元素的left值
if (
move_block_left >=
this.barArea.offsetWidth -
parseInt(parseInt(this.blockSize.width) / 2) -
2
) {
move_block_left =
this.barArea.offsetWidth -
parseInt(parseInt(this.blockSize.width) / 2) -
2;
}
if (move_block_left <= 0) {
move_block_left = parseInt(parseInt(this.blockSize.width) / 2);
}
//拖动后小方块的left值
this.moveBlockLeft = move_block_left - this.startLeft + "px";
this.leftBarWidth = move_block_left - this.startLeft + "px";
}
},
//鼠标松开
end: function () {
this.endMovetime = +new Date();
var _this = this;
//判断是否重合
if (this.status && this.isEnd == false) {
var moveLeftDistance = parseInt(
(this.moveBlockLeft || "").replace("px", "")
);
moveLeftDistance =
(moveLeftDistance * 310) / parseInt(this.setSize.imgWidth);
let data = {
captchaType: this.captchaType,
pointJson: this.secretKey
? aesEncrypt(
JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
this.secretKey
)
: JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
token: this.backToken,
};
reqCheck(data).then((res) => {
if (res.repCode == "0000") {
this.moveBlockBackgroundColor = "#5cb85c";
this.leftBarBorderColor = "#5cb85c";
this.iconColor = "#fff";
this.iconClass = "icon-check";
this.showRefresh = false;
this.isEnd = true;
this.passFlag = true;
this.tipWords = `${(
(this.endMovetime - this.startMoveTime) /
1000
).toFixed(2)}s验证成功`;
var captchaVerification = this.secretKey
? aesEncrypt(
this.backToken +
"---" +
JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
this.secretKey
)
: this.backToken +
"---" +
JSON.stringify({ x: moveLeftDistance, y: 5.0 });
setTimeout(() => {
this.tipWords = "";
this.$parent.closeBox();
this.$parent.$emit("success", { captchaVerification });
}, 1000);
} else {
this.moveBlockBackgroundColor = "#d9534f";
this.leftBarBorderColor = "#d9534f";
this.iconColor = "#fff";
this.iconClass = "icon-close";
this.passFlag = false;
setTimeout(function () {
_this.refresh();
}, 1000);
this.$parent.$emit("error", this);
this.tipWords = "验证失败";
setTimeout(() => {
this.tipWords = "";
}, 1000);
}
});
this.status = false;
}
},
refresh: function () {
this.showRefresh = true;
this.finishText = "";
this.transitionLeft = "left .3s";
this.moveBlockLeft = 0;
this.leftBarWidth = undefined;
this.transitionWidth = "width .3s";
this.leftBarBorderColor = "#ddd";
this.moveBlockBackgroundColor = "#fff";
this.iconColor = "#000";
this.iconClass = "icon-right";
this.isEnd = false;
this.getPictrue();
setTimeout(() => {
this.transitionWidth = "";
this.transitionLeft = "";
this.text = this.explain;
}, 300);
},
// 请求背景图片和验证图片
getPictrue() {
let data = {
captchaType: this.captchaType,
clientUid: localStorage.getItem("slider"),
ts: Date.now(), // 现在的时间戳
};
reqGet(data).then((res) => {
if (res.repCode == "0000") {
this.backImgBase = res.repData.originalImageBase64;
this.blockBackImgBase = res.repData.jigsawImageBase64;
this.backToken = res.repData.token;
this.secretKey = res.repData.secretKey;
} else {
this.tipWords = res.repMsg;
}
// 判断接口请求次数是否失效
if (res.repCode == "6201") {
this.backImgBase = null;
this.blockBackImgBase = null;
}
});
},
},
watch: {
// type变化则全面刷新
type: {
immediate: true,
handler() {
this.init();
},
},
},
mounted() {
// 禁止拖拽
this.$el.onselectstart = function () {
return false;
};
},
};
</script>