人机验证页面

This commit is contained in:
chenruiye
2025-03-17 17:27:20 +08:00
parent f3fe251bc6
commit cbd42d4da0
22 changed files with 495 additions and 0 deletions

View 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);
}

View File

@@ -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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View 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>

View 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: '照相机' },
]

View File

@@ -0,0 +1,23 @@
// 阿拉伯
langAr = {
// 模块
demoModule: {
text1:'الرجاء تحديد تضمين',
text2:'كل صور',
text3:'بعد عدم وجود صور جديدة للنقر عليها ، انقر فوق "تحقق"',
text4:'يؤكد',
text5:'فشل التحقق ، يرجى المحاولة مرة أخرى',
镜子:'مرآة',
书本:'كتاب',
桃子:'خَوخ',
椅子:'كرسي',
蝴蝶:'فراشة',
扇子:'معجب',
照相机:'آلة تصوير',
甜甜圈:'كعكة محلاة',
仙人掌:'صبار',
消防栓:'صنبور النار',
text6:'تحقق التحقق ، تم إرسال رمز التحقق من البريد الإلكتروني.'
}
}

View 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.'
},
}

View 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.'
}
}

View File

@@ -0,0 +1,24 @@
// 中文
langZh = {
// 模塊
demoModule: {
text1:'請選擇包含',
text2:'的所有圖片',
text3:'在沒有新圖片可以點按的圖片後,請點擊“驗證”',
text4:'驗證',
text5:'驗證失敗,請重試。',
镜子:'鏡子',
书本:'書本',
桃子:'桃子',
椅子:'椅子',
蝴蝶:'蝴蝶',
扇子:'扇子',
照相机:'照相機',
甜甜圈:'甜甜圈',
仙人掌:'仙人掌',
消防栓:'消防栓',
text6:'驗證成功,已發送驗證碼。'
}
}