captain-ui
Version:
有赞vue wap业务组件库
473 lines (430 loc) • 12.4 kB
JavaScript
import "vant/es/toast/style";
import _Toast from "vant/es/toast";
import "vant/es/icon/style";
import _Icon from "vant/es/icon";
import aes from '@youzan/yz-aes';
import ajax from 'zan-ajax';
function drag(e) {
var handlerChange = function handlerChange() {};
var handlerEnd = function handlerEnd() {};
if (e.type === 'touchstart') {
e.preventDefault();
var touchmoveFn = function touchmoveFn(event) {
var touch = event.touches[0];
if (touch) {
handlerChange(touch.pageX, touch.pageY);
}
};
var touchendFn = function touchendFn(event) {
var touch = event.changedTouches[0];
if (touch) {
handlerEnd(touch.pageX, touch.pageY);
}
window.removeEventListener('touchmove', touchmoveFn, true);
window.removeEventListener('touchend', touchendFn, true);
};
window.addEventListener('touchmove', touchmoveFn, true);
window.addEventListener('touchend', touchendFn, true);
window.addEventListener('touchcancel', touchendFn, true);
} else {
var mousemoveFn = function mousemoveFn(event) {
handlerChange(event.pageX, event.pageY);
};
var mouseupFn = function mouseupFn(event) {
handlerEnd(event.pageX, event.pageY);
window.removeEventListener('mousemove', mousemoveFn, false);
window.removeEventListener('mouseup', mouseupFn, false);
};
window.addEventListener('mousemove', mousemoveFn, false);
window.addEventListener('mouseup', mouseupFn, false);
}
return {
change: function change(_handler) {
handlerChange = _handler;
return this;
},
end: function end(_handler) {
handlerEnd = _handler;
}
};
}
export default {
render: function render() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
ref: "contentRef",
staticClass: "content"
}, [['loading', 'exception'].indexOf(_vm.status) !== -1 ? _c('div', {
staticClass: "display",
style: {
height: _vm.bgHeight + 'px' || 'auto'
}
}, [_c('div', {
staticClass: "loading-icon"
}, [_vm.status === 'loading' ? [_c('i', {
staticClass: "icon-l"
}), _c('div', {
staticClass: "tip"
}, [_vm._v("\n 加载中\n ")])] : _vm._e(), _vm.status === 'exception' ? [_c('van-icon', {
staticClass: "icon-e",
attrs: {
"name": "info-o"
}
}), _c('div', {
staticClass: "tip"
}, [_vm._v("\n 加载失败,请重试\n ")])] : _vm._e()], 2)]) : _c('div', {
staticClass: "display",
style: {
height: _vm.bgHeight + 'px' || 'auto'
}
}, [_c('div', {
staticClass: "refresh",
on: {
"click": _vm.refreshCaptcha
}
}), _c('div', {
staticClass: "bg"
}, [_c('img', {
attrs: {
"src": _vm.bigUrl
}
})]), _c('div', {
staticClass: "block",
style: {
left: _vm.left + 'px',
top: _vm.top + 'px'
},
on: {
"touchstart": _vm.handleMouseDown
}
}, [_c('img', {
style: {
width: _vm.smallImageWidth + 'px'
},
attrs: {
"src": _vm.smallUrl
}
})])]), _c('div', {
staticClass: "control"
}, [_c('div', {
class: ['bar', _vm.status]
}, [_c('div', {
staticClass: "placeholder",
on: {
"click": _vm.handleExceptionRefresh
}
}, [_vm.status === 'limit' ? [_c('van-icon', {
staticClass: "icon",
attrs: {
"name": "cross"
}
}), _c('span', [_vm._v("失败过多,点此重试")])] : _vm.status === 'exception' ? [_c('van-icon', {
staticClass: "icon",
attrs: {
"name": "info-0"
}
}), _c('span', [_vm._v("加载失败,请重试")])] : [_vm._v("\n " + _vm._s(_vm.getStatusText) + "\n ")]], 2), _c('div', {
ref: "slideBlockRef",
staticClass: "slide-block",
style: {
left: _vm.left + 'px'
},
on: {
"touchstart": _vm.handleMouseDown
}
}, [_c('van-icon', {
staticClass: "icon",
class: [{
'custom-right': _vm.getSlideBlockIcon === 'arrow'
}],
attrs: {
"name": _vm.getSlideBlockIcon
}
})], 1), _c('div', {
staticClass: "mask",
style: {
width: _vm.left + 'px'
}
})])])]);
},
components: {
'van-icon': _Icon
},
props: {
fingerprint: {
type: String,
default: ''
},
initLeft: {
type: Number,
default: 30
},
bgWhScale: {
type: Number,
default: 290 / 150
},
destroy: {
type: Function,
default: function _default() {}
},
getCaptchaUrl: {
type: String,
default: ''
},
checkCaptchaUrl: {
type: String,
default: ''
}
},
data: function data() {
return {
// 滑块、缺块的X坐标
left: this.initLeft,
// 缺块的Y坐标
top: 0,
bigUrl: '',
smallUrl: '',
token: '',
scale: 1,
smallImageWidth: 1,
status: 'loading',
bgHeight: 0
};
},
computed: {
getStatusText: function getStatusText() {
switch (this.status) {
case 'ready':
return '向右拖动滑块填充拼图';
case 'failed':
return '验证失败';
case 'success':
return '验证成功';
case 'loading':
default:
return '加载中';
}
},
getSlideBlockIcon: function getSlideBlockIcon() {
switch (this.status) {
case 'failed':
return 'cross';
case 'success':
return 'success';
default:
return 'arrow';
}
}
},
created: function created() {
this.$on('success', function () {});
this.$on('fail', function () {});
},
mounted: function mounted() {
var contentElm = this.$refs.contentRef;
var _contentElm$getBoundi = contentElm.getBoundingClientRect(),
width = _contentElm$getBoundi.width;
this.bgHeight = width / this.bgWhScale;
this.refreshCaptcha();
console.log(width, this.bgWhScale);
},
methods: {
handleExceptionRefresh: function handleExceptionRefresh() {
if (['limit', 'exception'].indexOf(this.status) !== -1) {
this.refreshCaptcha();
}
},
refreshCaptcha: function refreshCaptcha() {
var _this = this;
var self = this;
this.status = 'loading';
this.left = this.initLeft;
ajax({
url: this.getCaptchaUrl,
type: 'get',
noXRequestedWithHeader: true,
data: {
fingerPrint: this.token || this.fingerprint
}
}).then(function (_ref) {
var res = _ref.data;
var code = res.code,
data = res.data,
msg = res.msg;
if (code === 0) {
var captchaObtainResult = data.captchaObtainResult;
var bigImage = new Image();
var smallImage = new Image();
Promise.all([new Promise(function (resolve) {
bigImage.onload = function () {
resolve();
};
}), new Promise(function (resolve) {
smallImage.onload = function () {
resolve();
};
})]).then(function () {
var contentElm = self.$refs.contentRef;
var _contentElm$getBoundi2 = contentElm.getBoundingClientRect(),
width = _contentElm$getBoundi2.width;
var scale = width / bigImage.width;
_this.top = Math.ceil(captchaObtainResult.cy * scale);
_this.bigUrl = captchaObtainResult.bigUrl;
_this.smallUrl = captchaObtainResult.smallUrl;
_this.token = captchaObtainResult.token;
_this.scale = scale;
_this.smallImageWidth = smallImage.width * scale;
_this.status = 'ready';
});
bigImage.src = captchaObtainResult.bigUrl;
smallImage.src = captchaObtainResult.smallUrl;
} else if (msg) {
_this.status = 'exception';
msg && _Toast.fail(msg);
}
}).catch(function (res) {
var msg = res.msg;
_this.status = 'exception';
msg && _Toast.fail(msg);
});
},
/**
* 开始滑动
* @param e
*/
handleMouseDown: function handleMouseDown(e) {
var _this2 = this;
var contentElm = this.$refs.contentRef;
var slideBlock = this.$refs.slideBlockRef;
var _contentElm$getBoundi3 = contentElm.getBoundingClientRect(),
x = _contentElm$getBoundi3.left,
y = _contentElm$getBoundi3.top,
width = _contentElm$getBoundi3.width;
var _slideBlock$getBoundi = slideBlock.getBoundingClientRect(),
blockWidth = _slideBlock$getBoundi.width;
var eventData = e;
if (e.type === 'touchstart') {
eventData = event.touches[0];
}
var _eventData = eventData,
beginX = _eventData.pageX,
beginY = _eventData.pageY;
var userDataList = [];
userDataList.push({
x: beginX,
y: beginY,
t: Date.now()
});
drag(e).change(function (pageX, pageY) {
// 最多拿300条
if (userDataList.length < 300) {
userDataList.push({
x: pageX,
y: pageY,
t: Date.now()
});
_this2.left = Math.min(_this2.initLeft + Math.max(0, pageX - beginX), width - blockWidth);
}
}).end(function () {
if (userDataList.length < 5) {
return;
}
_this2.submitUserData( // 相对验证区域(.content)的x,y
userDataList.map(function (_ref2) {
var _x = _ref2.x,
_y = _ref2.y,
t = _ref2.t;
return {
x: _x - x,
y: _y - y,
t: t
};
})).then(function (token) {
_this2.status = 'success';
setTimeout(function () {
_this2.$emit('success', token);
_this2.destroy();
}, 500);
}).catch(function (error) {
if (error && error.needRefresh) {
_this2.status = 'limit';
} else {
_this2.status = 'failed';
setTimeout(function () {
_this2.$emit('fail', _this2.refreshCaptcha.bind(_this2));
if (error && error.msg) {
_Toast.fail(error.msg);
}
_this2.refreshCaptcha();
}, 500);
}
});
});
},
/**
* 提交用户滑动数据
* @param userDataList 滑动过程数据集
*/
submitUserData: function submitUserData(userDataList) {
var _this3 = this;
var dataList = [];
userDataList.reduce(function (pre, current, index) {
if (index === 1) {
dataList.push({
mx: Math.ceil(pre.x),
my: Math.ceil(pre.y),
ts: pre.t
});
}
dataList.push({
// x的增量
mx: Math.ceil(current.x - pre.x),
// y的增量
my: Math.ceil(current.y - pre.y),
// 增量所用的时间
ts: Math.ceil(current.t - pre.t)
});
return current;
});
var _this$$data = this.$data,
cx = _this$$data.left,
cy = _this$$data.top,
scale = _this$$data.scale,
token = _this$$data.token;
return new Promise(function (resolve, reject) {
ajax({
url: _this3.checkCaptchaUrl,
type: 'post',
noXRequestedWithHeader: true,
data: {
token: token,
userBehaviorData: aes.encrypt(JSON.stringify({
cx: Math.ceil(cx),
cy: Math.ceil(cy),
scale: scale,
slidingEvents: dataList
}))
}
}).then(function (_ref3) {
var res = _ref3.data;
var code = res.code,
data = res.data,
message = res.message;
if (code === 0) {
if (data.success) {
resolve(token);
return;
}
reject(data);
} else {
reject({
msg: message
});
}
}).catch(reject);
});
}
}
};