人机验证页面
78
view/molistar/modules/humanMachineVerification/css/index.css
Normal file
@@ -0,0 +1,78 @@
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 0 0.3466666667rem;
|
||||
}
|
||||
.header .txt {
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: 0.32rem;
|
||||
color: #313131;
|
||||
line-height: 0.64rem;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
}
|
||||
.header .name {
|
||||
color: #FF8C03;
|
||||
font-size: 0.5333333333rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 3.2rem);
|
||||
grid-gap: 5px;
|
||||
padding: 0 0.3466666667rem;
|
||||
}
|
||||
.content .image-container {
|
||||
position: relative;
|
||||
}
|
||||
.content .image-container img {
|
||||
width: 2.2933333333rem;
|
||||
height: 2.2933333333rem;
|
||||
border-radius: 0.1066666667rem;
|
||||
transition: filter 0.2s ease;
|
||||
}
|
||||
.content .image-container .checkmark {
|
||||
position: absolute;
|
||||
bottom: 0.24rem;
|
||||
right: 1.0666666667rem;
|
||||
width: 0.4266666667rem;
|
||||
height: 0.4266666667rem;
|
||||
background-image: url("../images/yes.png");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
padding: 0 0.3466666667rem;
|
||||
margin-top: 0.3733333333rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.bottom .left_img img {
|
||||
width: 0.64rem;
|
||||
height: 0.64rem;
|
||||
}
|
||||
.bottom .right_bottom {
|
||||
background: linear-gradient(270deg, #E29030 0%, #FCC074 100%);
|
||||
border-radius: 3.12rem;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: 0.3733333333rem;
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.16rem 0.64rem;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
filter: brightness(0.6);
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
@function px2rem($px) {
|
||||
@return $px / 75+rem;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
// padding: px2rem(26);
|
||||
}
|
||||
|
||||
.header {
|
||||
padding:0 px2rem(26);
|
||||
.txt {
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: px2rem(24);
|
||||
color: #313131;
|
||||
line-height: px2rem(48);
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: #FF8C03;
|
||||
font-size: px2rem(40);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, px2rem(240));
|
||||
grid-gap: 5px;
|
||||
padding: 0 px2rem(26);
|
||||
.image-container {
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: px2rem(172);
|
||||
height: px2rem(172);
|
||||
border-radius: px2rem(8);
|
||||
transition: filter 0.2s ease; // 添加过渡效果
|
||||
}
|
||||
|
||||
.checkmark {
|
||||
position: absolute;
|
||||
bottom: px2rem(18);
|
||||
right: px2rem(80);
|
||||
width: px2rem(32);
|
||||
height: px2rem(32);
|
||||
background-image: url('../images/yes.png'); // 替换为你的选中标记图标路径
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
display: none; // 默认隐藏
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bottom {
|
||||
padding: 0 px2rem(26);
|
||||
margin-top: px2rem(28);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.left_img {
|
||||
img {
|
||||
width: px2rem(48);
|
||||
height: px2rem(48);
|
||||
}
|
||||
}
|
||||
|
||||
.right_bottom {
|
||||
background: linear-gradient(270deg, #E29030 0%, #FCC074 100%);
|
||||
border-radius: px2rem(234);
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: px2rem(28);
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: px2rem(12) px2rem(48);
|
||||
}
|
||||
}
|
||||
|
||||
.shadow {
|
||||
filter: brightness(0.6);
|
||||
}
|
BIN
view/molistar/modules/humanMachineVerification/images/change.png
Normal file
After Width: | Height: | Size: 792 B |
BIN
view/molistar/modules/humanMachineVerification/images/hudie.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
view/molistar/modules/humanMachineVerification/images/jingzi.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
view/molistar/modules/humanMachineVerification/images/shanzi.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
view/molistar/modules/humanMachineVerification/images/shuben.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
view/molistar/modules/humanMachineVerification/images/taozi.png
Normal file
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 38 KiB |
BIN
view/molistar/modules/humanMachineVerification/images/yes.png
Normal file
After Width: | Height: | Size: 564 B |
BIN
view/molistar/modules/humanMachineVerification/images/yizi.png
Normal file
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 35 KiB |
48
view/molistar/modules/humanMachineVerification/index.html
Normal file
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title class="text1"></title>
|
||||
<link rel="stylesheet" href="../../common/css/reset.css" />
|
||||
<link rel="stylesheet" href="../../common/css/animate.css" />
|
||||
<link rel="stylesheet" href="./css/index.css?v=1.1" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="txt" id="text1"> Please select Include </div>
|
||||
<div class="name" ></div>
|
||||
<div class="txt" id="text2"> All pictures of </div>
|
||||
<div class="txt" id="text3"> After there are no new images to click on, click "Verify" </div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<!-- <div class="image-container">
|
||||
<img src="https://image.molistar.xyz/image/2f871546aff0ecd641eaa8509728a8b9.jpeg" alt="" >
|
||||
<div class="checkmark"></div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div class="left_img" id="changeImg">
|
||||
<img src="./images/change.png" alt="">
|
||||
</div>
|
||||
<div class="right_bottom" id="text4">
|
||||
Verify
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<script src="../../common/js/flexible.js"></script>
|
||||
<script src="../../common/js/jquery-3.2.1.min.js"></script>
|
||||
<script src="../../common/js/common2.js"></script>
|
||||
<script src="../../common/js/layer.js"></script>
|
||||
<script src="../../common/js/vconsole.min.js"></script>
|
||||
<script src="../../common/js/route-constant.js"></script>
|
||||
<script src="../../common/js/svga.min.js"></script>
|
||||
<script src="./local/en.js"></script>
|
||||
<script src="./local/zh.js"></script>
|
||||
<script src="./local/ar.js"></script>
|
||||
<script src="./local/tr.js"></script>
|
||||
<script src="../../common/local/langHandler.js"></script>
|
||||
<script src="../../common/js/svga.min.js"></script>
|
||||
<script src="./js/index.js?v=1.0"></script>
|
188
view/molistar/modules/humanMachineVerification/js/index.js
Normal file
@@ -0,0 +1,188 @@
|
||||
let urlPrefix = getUrlPrefix()
|
||||
let browser = checkVersion()
|
||||
let env = EnvCheck();
|
||||
if (env == 'test') {
|
||||
new VConsole();
|
||||
}
|
||||
// 封裝layer消息提醒框
|
||||
let layerIndex
|
||||
var langReplace;
|
||||
var localLang;
|
||||
const showLoading = (content = langReplace(localLang.demoModule.layerIndex1)) => {
|
||||
layer.open({
|
||||
type: 2,
|
||||
shadeClose: false,
|
||||
content,
|
||||
success(e) {
|
||||
layerIndex = $(e).attr('index')
|
||||
}
|
||||
})
|
||||
}
|
||||
const hideLoading = (index) => {
|
||||
layer.close(index)
|
||||
}
|
||||
const toastMsg = (content = langReplace(localLang.demoModule.layerIndex2), time = 2) => {
|
||||
layer.open({
|
||||
content,
|
||||
time,
|
||||
skin: 'msg'
|
||||
})
|
||||
}
|
||||
// 初始化函數
|
||||
$(function () {
|
||||
getInfoFromClient();
|
||||
fuzzyMatchUpdateQueryStringParameterFun(); // 判断语言
|
||||
setTimeout(function () {
|
||||
// 頁面全屏
|
||||
if (browser.app) {
|
||||
if (browser.android) {
|
||||
window.androidJsObj.initShowNav(false)
|
||||
} else {
|
||||
window.webkit.messageHandlers.initShowNav.postMessage(0)
|
||||
}
|
||||
};
|
||||
fuzzyMatchUpdateQueryStringParameterFun(); // 判断语言
|
||||
langReplace = window.lang.replace;
|
||||
localLang = window.lang;
|
||||
renderImgOption();
|
||||
$('#text1').html(langReplace(localLang.demoModule.text1))
|
||||
$('#text2').html(langReplace(localLang.demoModule.text2))
|
||||
$('#text3').html(langReplace(localLang.demoModule.text3))
|
||||
$('#text4').html(langReplace(localLang.demoModule.text4))
|
||||
|
||||
}, 100)
|
||||
|
||||
})
|
||||
let randomImages = []
|
||||
let randomImageSetIndex =''
|
||||
function renderImgOption() {
|
||||
randomImageSetIndex = getRandomImageSet();
|
||||
const targetImage = imgOption[randomImageSetIndex];
|
||||
$('.header .name').html(langReplace(localLang.demoModule[imgOption[randomImageSetIndex].name]))
|
||||
// 随机选择目标图片出现一次或三次
|
||||
const targetCount = Math.random() < 0.5 ? 1 : 3;
|
||||
randomImages = getRandomNineImagesWithTarget(imgOption, targetImage,targetCount);
|
||||
changeImg(randomImages);
|
||||
}
|
||||
function changeImg(obj) {
|
||||
var str = ''
|
||||
obj.forEach((item) => {
|
||||
str += `
|
||||
<div class="image-container">
|
||||
<img src="${item.img}" alt="" >
|
||||
<div class="checkmark"></div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
$('.content').append(str);
|
||||
}
|
||||
$('#changeImg').click(function () {
|
||||
$('.content .image-container').remove();
|
||||
renderImgOption();
|
||||
selectedImages = []
|
||||
})
|
||||
// 定义随机抽取九个数据并确保包含目标图片的函数
|
||||
function getRandomNineImagesWithTarget(imgOption, targetImage,targetCount) {
|
||||
const randomImages = [];
|
||||
const allImages = imgOption.slice(); // 复制 imgOption 数组
|
||||
|
||||
// 从 allImages 中移除所有目标图片
|
||||
const targetImages = allImages.filter(item => item.img === targetImage.img);
|
||||
targetImages.forEach(target => {
|
||||
const index = allImages.indexOf(target);
|
||||
if (index > -1) {
|
||||
allImages.splice(index, 1);
|
||||
}
|
||||
});
|
||||
|
||||
// 确保目标图片在随机抽取的九个图片中
|
||||
for (let i = 0; i < targetCount; i++) {
|
||||
randomImages.push(targetImage);
|
||||
}
|
||||
|
||||
// 随机抽取剩余的八个图片
|
||||
while (randomImages.length < 9) {
|
||||
const randomIndex = Math.floor(Math.random() * allImages.length);
|
||||
const randomImage = allImages[randomIndex];
|
||||
randomImages.push(randomImage);
|
||||
allImages.splice(randomIndex, 1); // 移除已选择的图片,避免重复
|
||||
}
|
||||
|
||||
// 打乱顺序
|
||||
randomImages.sort(() => Math.random() - 0.5);
|
||||
|
||||
return randomImages;
|
||||
}
|
||||
|
||||
// 定义随机选择函数
|
||||
function getRandomImageSet() {
|
||||
const randomIndex = Math.floor(Math.random() * imgOption.length);
|
||||
return randomIndex;
|
||||
}
|
||||
|
||||
|
||||
let selectedImages = [];
|
||||
// 点击图片事件
|
||||
$(document).on('click', '.content .image-container img', function () {
|
||||
const container = $(this).closest('.image-container');
|
||||
const checkmark = container.find('.checkmark');
|
||||
container.find('img').toggleClass('shadow');
|
||||
checkmark.toggle();
|
||||
|
||||
const imgSrc = $(this).attr('src');
|
||||
if (selectedImages.includes(imgSrc)) {
|
||||
selectedImages = selectedImages.filter(src => src !== imgSrc);
|
||||
} else {
|
||||
selectedImages.push(imgSrc);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
let verificationResult = false;
|
||||
// 验证逻辑
|
||||
$('.bottom .right_bottom').click(function () {
|
||||
const targetImageName =imgOption[randomImageSetIndex].name;
|
||||
// 获取所有目标图片的 src
|
||||
const targetImages = imgOption.filter(item => item.name === targetImageName).map(item => item.img);
|
||||
// 计算目标图片的数量
|
||||
const targetImageCount = targetImages.length;
|
||||
// 检查 selectedImages 中是否只包含目标图片
|
||||
const onlyTargetImagesSelected = selectedImages.every(imgSrc => targetImages.includes(imgSrc));
|
||||
// 计算 selectedImages 中目标图片的数量
|
||||
const selectedTargetImageCount = selectedImages.filter(imgSrc => targetImages.includes(imgSrc)).length;
|
||||
|
||||
if (selectedTargetImageCount === targetImageCount && onlyTargetImagesSelected) {
|
||||
toastMsg(langReplace(localLang.demoModule.text6));
|
||||
verificationResult = true
|
||||
} else {
|
||||
toastMsg(langReplace(localLang.demoModule.text5));
|
||||
verificationResult = false;
|
||||
randomImages = []
|
||||
selectedImages = [];
|
||||
randomImageSetIndex = ''
|
||||
setTimeout(()=>{
|
||||
$('.content .image-container').remove();
|
||||
renderImgOption();
|
||||
},500)
|
||||
}
|
||||
// 告知客户端
|
||||
if (browser.app) {
|
||||
if (browser.android) {
|
||||
window.androidJsObj.closeToVerify(verificationResult);
|
||||
} else if (browser.ios) {
|
||||
window.webkit.messageHandlers.closeToVerify.postMessage(verificationResult);
|
||||
}
|
||||
}
|
||||
});
|
||||
var imgOption = [
|
||||
{ img: './images/hudie.png', name: '蝴蝶' },
|
||||
{ img: './images/jingzi.png', name: '镜子' },
|
||||
{ img: './images/shanzi.png', name: '扇子' },
|
||||
{ img: './images/shuben.png', name: '书本' },
|
||||
{ img: './images/taozi.png', name: '桃子' },
|
||||
{ img: './images/tiantianquan.png', name: '甜甜圈' },
|
||||
{ img: './images/xianrenzhang.png', name: '仙人掌' },
|
||||
{ img: './images/xiaofangshuang.png', name: '消防栓' },
|
||||
{ img: './images/yizi.png', name: '椅子' },
|
||||
{ img: './images/zhaoxiangji.png', name: '照相机' },
|
||||
]
|
23
view/molistar/modules/humanMachineVerification/local/ar.js
Normal file
@@ -0,0 +1,23 @@
|
||||
// 阿拉伯
|
||||
langAr = {
|
||||
// 模块
|
||||
demoModule: {
|
||||
text1:'الرجاء تحديد تضمين',
|
||||
text2:'كل صور',
|
||||
text3:'بعد عدم وجود صور جديدة للنقر عليها ، انقر فوق "تحقق"',
|
||||
text4:'يؤكد',
|
||||
text5:'فشل التحقق ، يرجى المحاولة مرة أخرى',
|
||||
镜子:'مرآة',
|
||||
书本:'كتاب',
|
||||
桃子:'خَوخ',
|
||||
椅子:'كرسي',
|
||||
蝴蝶:'فراشة',
|
||||
扇子:'معجب',
|
||||
照相机:'آلة تصوير',
|
||||
甜甜圈:'كعكة محلاة',
|
||||
仙人掌:'صبار',
|
||||
消防栓:'صنبور النار',
|
||||
text6:'تحقق التحقق ، تم إرسال رمز التحقق من البريد الإلكتروني.'
|
||||
}
|
||||
|
||||
}
|
21
view/molistar/modules/humanMachineVerification/local/en.js
Normal file
@@ -0,0 +1,21 @@
|
||||
langEn = {
|
||||
demoModule: {
|
||||
text1:'Please select Include',
|
||||
text2:'All pictures of',
|
||||
text3:'After there are no new images to click on, click "Verify"',
|
||||
text4:'Verify',
|
||||
text5:'Verification failed, please try again.',
|
||||
镜子:'Mirror',
|
||||
书本:'Book',
|
||||
桃子:'Peach',
|
||||
椅子:'Chair',
|
||||
蝴蝶:'Butterfly',
|
||||
扇子:'Fan',
|
||||
照相机:'Camera',
|
||||
甜甜圈:'Donut',
|
||||
仙人掌:'Cactus',
|
||||
消防栓:'Fire Hydrant',
|
||||
text6:'Verification succeed, email verification code has been sent.'
|
||||
|
||||
},
|
||||
}
|
22
view/molistar/modules/humanMachineVerification/local/tr.js
Normal file
@@ -0,0 +1,22 @@
|
||||
langTr = {
|
||||
demoModule: {
|
||||
text1:`Lütfen dahil'yi seçin`,
|
||||
text2:'Tüm resimler',
|
||||
text3:'Tıklamak için yeni bir resim olmadıktan sonra "Doğrula" yı tıklayın',
|
||||
text4:'Doğrulamak',
|
||||
text5:'Doğrulama başarısız oldu, lütfen tekrar deneyin',
|
||||
镜子:'Ayna',
|
||||
书本:'Kitap',
|
||||
桃子:'Şeftali',
|
||||
椅子:'Sandalye',
|
||||
蝴蝶:'Kelebek',
|
||||
扇子:'Fan',
|
||||
照相机:'Kamera',
|
||||
甜甜圈:'Çörek',
|
||||
仙人掌:'Kaktüs',
|
||||
消防栓:'Yangın hidrant',
|
||||
text6:'Doğrulama başarılı, e -posta doğrulama kodu gönderildi.'
|
||||
|
||||
}
|
||||
|
||||
}
|
24
view/molistar/modules/humanMachineVerification/local/zh.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// 中文
|
||||
langZh = {
|
||||
// 模塊
|
||||
demoModule: {
|
||||
text1:'請選擇包含',
|
||||
text2:'的所有圖片',
|
||||
text3:'在沒有新圖片可以點按的圖片後,請點擊“驗證”',
|
||||
text4:'驗證',
|
||||
text5:'驗證失敗,請重試。',
|
||||
镜子:'鏡子',
|
||||
书本:'書本',
|
||||
桃子:'桃子',
|
||||
椅子:'椅子',
|
||||
蝴蝶:'蝴蝶',
|
||||
扇子:'扇子',
|
||||
照相机:'照相機',
|
||||
甜甜圈:'甜甜圈',
|
||||
仙人掌:'仙人掌',
|
||||
消防栓:'消防栓',
|
||||
text6:'驗證成功,已發送驗證碼。'
|
||||
|
||||
}
|
||||
|
||||
}
|