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.

191 lines
5.3 KiB

7 months ago
<!-- @format -->
<template>
<div class="silde_box">
<slide-verify
class="silde_box"
ref="block"
:w="width"
:h="height"
:imgs="imgs"
:show="imgShow"
:customVerify="customVerify"
:frontPicture="frontPicture"
:slider-text="text"
:accuracy="accuracy"
:asyncVerify="asyncVerify"
@again="onAgain"
@success="onSuccess"
@fail="onFail"
@refresh="onRefresh"
@verify="verify" />
</div>
</template>
<script lang="ts">
interface frontPictureClass {
width: Number;
height: Number;
src: 'string';
}
import { defineComponent, ref, PropType, nextTick, reactive, toRefs } from 'vue';
// 局部注册组件,需要单独引用组件样式
// 只提供局部引用的方式,不再采用插件形式,方便按需加载,减少主包大小
import SlideVerify, { SlideVerifyInstance } from './components/index';
import { HttpRequestConfig, useApi } from '/nerv-lib/use/use-api';
// import 'vue3-slide-verify/dist/style.css';
import { cloneDeep, get, isArray, isEqual, isFunction, isString, isUndefined } from 'lodash-es';
export default defineComponent({
name: 'NsSildeVerify',
components: { SlideVerify },
props: {
api: {
type: [String, Object, Function] as PropType<string | Function | HttpRequestConfig>,
required: true,
},
params: {
type: Object,
default: () => ({}),
},
imgShow: {
type: Boolean,
default: true,
},
resultField: {
type: String,
default: 'data.data',
},
//数据筛选函数
filterData: {
type: Function,
},
asyncVerify: {
type: Boolean,
default: true,
},
customVerify: {
type: Function,
},
imgWidth: {
type: Number,
default: 300,
},
onSuccess: Function,
},
emits: ['change', 'validateChange'],
setup(props, { attrs, emit }) {
const msg = ref('');
const block = ref<SlideVerifyInstance>();
const imgs = ref<Array<string>>([]);
const frontPicture = ref<frontPictureClass>();
const state = reactive({
width: 290,
height: 177,
verifyData: {},
});
const loadImage = (callback?) => {
const requestConfig: HttpRequestConfig = { method: 'get' };
const { api, params: _params, resultField, filterData } = props;
const params: Recordable = cloneDeep(_params);
const { httpRequest } = useApi();
httpRequest({ api, params, requestConfig })
.then((res: Recordable) => {
imgs.value = [res.data.snapPicture];
let scale: number = props.imgWidth / res.data.expendData.bgImageWidth;
frontPicture.value = {
src: res.data.frontPicture,
width: res.data.expendData.sliderImageWidth * scale,
height: res.data.expendData.sliderImageHeight * scale,
};
state.height = res.data.expendData.bgImageHeight * scale;
state.width = props.imgWidth;
state.verifyData = res.data;
emit('validateChange', { help: undefined });
callback();
})
.catch((error: any) => {
if (error?.response?.status === 403) {
emit('validateChange', { help: '暂无权限', validateStatus: 'error' });
nextTick(() => {
//清空编辑初始值
// modelValue.value = undefined;
});
}
});
};
loadImage();
const onAgain = () => {
msg.value = '检测到非人为操作的哦! try again';
// 刷新
block.value?.refresh();
};
// const onSuccess = (times: number) => {
// msg.value = `login success, 耗时${(times / 1000).toFixed(1)}s`;
// };
const onFail = () => {
msg.value = '验证不通过';
loadImage(() => {
block.value?.resetImg();
});
};
const onRefresh = () => {
block.value.disabled = true;
loadImage(() => {
block.value?.resetImg();
});
};
const handleClick = () => {
// 刷新
block.value?.refresh();
msg.value = '';
};
const verify = (x, timestamp?: number) => {
if (props.customVerify) {
props
.customVerify(x, state.verifyData)
.then((res) => {
let checkValue = {
verifyImgCode: res.resultCode,
verifyImgKey: state.verifyData.k,
verifyNeedStep: 2,
verifyStep: 2,
};
emit('change', checkValue);
block.value?.successFun('success', timestamp);
})
.catch((err) => {
// loadImage();
emit('change', null);
block.value?.successFun('fail');
});
}
};
return {
block,
msg,
text: '向右拖动滑块填充拼图',
accuracy: 1,
imgs,
frontPicture,
...toRefs(state),
onAgain,
onFail,
onRefresh,
handleClick,
verify,
};
},
});
</script>
<style scoped>
.silde_box {
margin: 0 auto;
}
</style>