This commit is contained in:
gaofeng
2026-05-12 18:27:28 +08:00
commit 6d9aee81aa
3664 changed files with 274415 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
// $(window).scroll(function () {
// var wid = $(document).width();
// if (wid > 1200) {
// if ($(document).scrollTop() > 50) {
// if ($(".zh_top").hasClass("white")) {
// } else {
// $(".zh_top").addClass("white");
// $(".zh_head").animate({"height": "50px"});
// $(".zh_nav").animate({"height": "70px"});
// }
// }
// ;
// if ($(document).scrollTop() < 50) {
// if ($(".zh_top").hasClass("white")) {
// $(".zh_top").removeClass("white");
// $(".zh_head").animate({"height": "60px"});
// $(".zh_nav").animate({"height": "100px"});
// }
// }
// }
// })
// $(".zh_nav_btn").click(function () {
// if ($(".nav_con").hasClass("open")) {
// $(".nav_con").removeClass("open").slideUp();
// } else {
// $(".nav_con").addClass("open").slideDown();
// }
// })
$(window).scroll(function() {
if ($(document).scrollTop() > 5) {
$(".zh_top").animate({}, 500).addClass("blackbg");
// $(".nav_con a").attr('style', 'color:#000')
// $(".zh_hr a, .zh_hr span").attr('style', 'color:#000')
// $(".swiper").attr('style', 'color:#000')
} else {
$(".zh_top").animate({}, 500).removeClass("blackbg");
// $(".nav_con a").attr('style', 'color:#fff')
// $(".zh_hr a, .zh_hr span").attr('style', 'color:#fff')
// $(".swiper").attr('style', 'color:#fff')
}
})

2
public/static/js/jquery-1.8.3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

13
public/static/js/jquery-weui.min.js vendored Normal file

File diff suppressed because one or more lines are too long

6
public/static/js/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

399
public/static/js/mala.js Normal file
View File

@@ -0,0 +1,399 @@
var layer = layui.layer, form = layui.form, upload = layui.upload, laydate = layui.laydate
initFormFields()
function initFormFields() {
$('.layui-form-item').each(function() {
const labelText = $(this).find('.layui-form-label').text().replace('*', '').trim();
// 查找所有需要必填提示的表单元素
$(this).find('.layui-input-block input, ' +
'.layui-input-block select, ' +
'.layui-input-block textarea')
.each(function() {
var $field = $(this);
// 如果已有提示则跳过(保留自定义提示)
if (!$field.attr('lay-reqtext')) {
// 设置统一的必填提示
$field.attr('lay-reqtext', labelText + lang.field_required);
$field.attr('lay-verType', 'tips');
}
});
});
// 重新渲染表单
form.render();
}
//遍历日期选择
$(".layui-form-item").find(".layui-time").each(function () {
xvDate({
target: this,
});
});
$(".layui-form-item").find(".layui-qian").each(function () {
xvDate({
target: this,
max: new Date().toISOString().split('T')[0]
});
});
$(".layui-form-item").find(".layui-hou").each(function () {
xvDate({
target: this,
min: new Date().toISOString().split('T')[0]
});
});
$(".layui-form-item").find(".layui-arrive").each(function () {
xvDate({
target: this,
min: new Date().toISOString().split('T')[0],
done: function(value, date, endDate){
const isdate = isWithinThreeDays(value)
if (!isdate){
layer.alert(lang.alert_message, {
icon: 0,
shadeClose: true,
title: lang.notice
});
}
validateDates();
}
});
});
$(".layui-form-item").find(".layui-leave").each(function () {
xvDate({
target: this,
min: new Date().toISOString().split('T')[0],
done: function (value, date, endDate) {
validateDates();
}
});
});
function validateDates() {
var date1 = $('input[name="arrive_date"]').val();
var date2 = $('input[name="leave_date"]').val();
if (date1 && date2) {
var d1 = new Date(date1);
var d2 = new Date(date2);
if (d1 > d2) {
layer.tips(lang.departure_date_error, 'input[name="leave_date"]');
$('input[name="leave_date"]').val('')
return false;
}
return true;
}
}
function isWithinThreeDays(dateString) {
const targetDate = new Date(dateString);
const currentDate = new Date();
const threeDaysInMillis = 2 * 24 * 60 * 60 * 1000;
// 将时间部分设置为0以便只比较日期部分
targetDate.setHours(0, 0, 0, 0);
currentDate.setHours(0, 0, 0, 0);
return targetDate - currentDate <= threeDaysInMillis;
}
//监听
form.on('select(hotel_state_select)', function (data) {
var sub_select = document.getElementById('hotel_city');
sub_select.innerHTML = '';
if (data.value) {
layer.load(0)
$.ajax({
url: "/home/visa/get_sub_city", type: "POST", data: {'id': data.value}, success: function (data) {
if (data.data.length !== 0) {
// 动态添加城市选项
sub_select.innerHTML = '<option value="">'+lang.search_directly+'</option>' + data.data.text;
layer.closeAll()
form.render('select'); // 重新渲染下拉框
} else {
layer.closeAll()
layer.msg(lang.failed, {icon: 5});
form.render('select'); // 重新渲染下拉框
return false;
}
}
});
}
})
$('#shili').on('click', function () {
layer.photos({
photos: {
"data": [ //相册包含的图片,数组格式
{
"src": $('#sample_url').val(),
}]
},
})
});
//是否选择 默认显示或隐藏
$("input[type='radio']").each(function () {
var name = $(this).attr("name");
var alt = $(this).attr("alt");
if ($(this).is(":checked")) {
$(".data-" + alt).show();
} else {
$(".data-" + alt).hide();
}
})
//是否radio 必填判断
form.on("radio", function (data) {
var name = data.elem.name;
var type = data.elem.alt;
$(".data-name-" + name).hide();
$(".data-" + type).show();
$(".data-name-" + name).each(function () {
var that = $(this).find(".layui-required");
var verify = that.attr("lay-verify");
if (verify === undefined || verify === null) {
verify = "";
}
var disAble = that.attr("disabled");
if ($(this).hasClass("data-" + type)) {
if (disAble === "disabled") {
} else if (verify.indexOf("required") >= 0) {
} else {
verify = verify + "|required";
that.attr("lay-verify", verify);
}
} else {
if (disAble === "disabled") {
} else {
if (verify.includes("required")) {
verify = verify.slice(0, verify.length - 9);
}
that.val('')
that.attr("lay-verify", verify);
}
}
})
});
//下一步
form.on('submit', function (data) {
var className = data.elem.className;
if (className.includes("btn-next")) {
$(this).hide()
$(this).parents(".layui-form").next(".layui-form").show();
var h = $(this).parents(".layui-form").next(".layui-form").offset().top - 100;
$("html,body").animate({
scrollTop: h
}, 500);
}
return false;
});
function normalizePassportNo(value) {
return (value || '').toUpperCase().replace(/\s+/g, '');
}
function isChineseNationality(value) {
return (value || '').trim().toUpperCase() === 'CHN';
}
function isValidChinesePassportNo(value) {
value = String(value).trim().toUpperCase();
return /^(?:G\d{8}|E\d{8}|E[A-HJ-NP-Z]\d{7}|[SP]E\d{7})$/.test(value);
}
form.verify({
// 验证至少选中一个 checkbox
checkboxRequired: function (value, item) {
var name = item.getAttribute('name');
var checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
var checkboxes_length = document.querySelectorAll(`input[name="${name}"]`).length;
if (checkboxes.length !== checkboxes_length) {
return lang.check_declaration;
}
}, // 验证必须选中一个 radio
radioRequired: function (value, item) {
var name = item.getAttribute('name');
var radios = document.querySelectorAll(`input[name="${name}"]:checked`);
if (radios.length === 0) {
return lang.choose_package;
}
}, radioChecked: function (value, item) { //value表单的值、item表单的DOM对象
var radio = $(item).parent('div').find('input[type=radio]:checked').length;
if (!radio) {
return lang.select_one_option;
}
}, checkboxChecked: function (value, item) { //value表单的值、item表单的DOM对象
var name = item.getAttribute('name');
var checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
if (checkboxes.length === 0) {
return lang.select_one_option;
}
},
english: [/^[A-Za-z]+$/, lang.english_only]
,daxie: [/^[A-Z]+$/, lang.uppercase_only],
zhongwen: [/^[\u4e00-\u9fa5]+$/, lang.chinese_only],
len40: [/^.{1,100}$/, lang.max_100_chars],
otherReq: function (value, item) {
var $ = layui.$;
var verifyName = $(item).attr('name'), verifyType = $(item).attr('type'),
formElem = $(item).parents('.layui-form')//获取当前所在的form元素如果存在的话
, verifyElem = formElem.find('input[name=' + verifyName + ']')//获取需要校验的元素
, isTrue = verifyElem.is(':checked')//是否命中校验
, focusElem = verifyElem.next().find('i.layui-icon');//焦点元素
if (!isTrue || !value) {
//定位焦点
focusElem.css(verifyType == 'radio' ? {"color": "#FF5722"} : {"border-color": "#FF5722"});
//对非输入框设置焦点
focusElem.first().attr("tabIndex", "1").css("outline", "0").blur(function () {
focusElem.css(verifyType == 'radio' ? {"color": ""} : {"border-color": ""});
}).focus();
return lang.field_required;
}
},
chinaPassport: function (value, item) {
const nationality = $('select[name="nation"]').val();
if (!isChineseNationality(nationality)) {
return;
}
const normalized = normalizePassportNo(value);
if (!isValidChinesePassportNo(normalized)) {
return lang.china_passport_invalid;
}
$(item).val(normalized);
},
englishOnly: function (value, item) {
const v = (value ?? '').replace(/\s+/g, ''); // 去掉所有空白字符
if (!/^[A-Za-z]+$/.test(v)) {
return lang.english_only;
}
}
});
//监听提交
form.on('submit(formSubmit)', function (data) {
var submitVal = "";
for (var i = 1; i < 4; i++) {
submitVal = $.extend(submitVal, form.val('Form' + i));
if (!form.validate('#Form' + i)) {
return false;
}
}
$("#last_name_con").html($('input[name="last_name"]').val() + " " + $('input[name="first_name"]').val())
$("#first_name_con").html($('input[name="first_name"]').val())
$("#birth_date_con").html($('input[name="birth_date"]').val())
$("#passport_number_con").html($('input[name="passport_number"]').val())
$("#passport_expiration_date_con").html($('input[name="passport_expiration_date"]').val())
$("#arrive_date_con").html($('input[name="arrive_date"]').val())
$("#leave_date_con").html($('input[name="leave_date"]').val())
$("#email_con").html($('input[name="email"]').val())
if (window.innerWidth <= 768) {
area = ['90%', 'auto']
} else {
area = ['30%', 'auto']
}
layer.open({
content: $('#confirm'),
type: 1,
title: lang.verify,
btn: [lang.confirms, lang.edit],
btnAlign: 'c',
closeBtn: 0,
area: area,
yes: function () {
var load = layer.load(2, {shade: 0.3})
setTimeout(function () {
$.ajax({
url: "/home/visa/do_apply", type: "POST", data: submitVal, success: function (data) {
if (data.code === 1) {
window.location.href = data.url
} else {
layer.msg(data.msg, {icon: 5});
return false
}
}
});
}, 1500)
},
end: function () {
$('#confirm').hide()
}
});
return false;
});
upload.render({
elem: '#passport_img', // 绑定的按钮 ID
url: '/home/upload/upload_passport', // 后端接口 URL
accept: 'images', // 仅支持图片类型
before: function (obj) {
loadIndex = layer.load(0);
obj.preview(function (index, file, result) {
$('#uploadPassportView').removeClass('layui-hide').find('img').attr('src', result);
});
},
done: function (res) {
// 上传成功后的回调
if (res.path.length !== 0) {
layer.close(loadIndex);
layer.msg(lang.upload_successful, {icon: 1});
$('input[name="passport_img"]').val(res.path);
if (res.data.length !== 0) {
$('input[name="last_name"]').val(res.data.last_name)
$('input[name="first_name"]').val(res.data.first_name)
$('input[name="birth_date"]').val(res.data.birth_date_year + '-' + ('0' + res.data.birth_date_month).slice(-2) + '-' + ('0' + res.data.birth_date_day).slice(-2))
$('input[name="passport_number"]').val(res.data.passport_number)
var gender = res.data.gender == 'male' ? '1' : '2'
$('input[name="gender"][value="' + gender + '"]').prop('checked', true);
$('input[name="passport_expiration_date"]').val(res.data.passport_expiration_date_year + '-' + ('0' + res.data.passport_expiration_date_month).slice(-2) + '-' + ('0' + res.data.passport_expiration_date_day).slice(-2))
form.render('radio');
}
} else {
layer.close(loadIndex);
$('#passport_img_preview').html('')
$('input[name="last_name"]').val('')
$('input[name="first_name"]').val('')
$('input[name="birth_date"]').val('')
$('input[name="passport_number"]').val('')
$('input[name="passport_expiration_date"]').val('')
$('input[name="gender"]').prop('checked', false);
form.render('radio');
layer.msg(lang.upload_failed+'' + res.msg, {icon: 5});
}
}, error: function () {
// 上传失败的回调
layer.close(loadIndex);
$('#passport_img_preview').html('')
$('input[name="passport_img"]').val('')
$('input[name="last_name"]').val('')
$('input[name="first_name"]').val('')
$('input[name="birth_city"]').val('')
$('input[name="issuing_place"]').val('')
$('input[name="birth_date"]').val('')
$('input[name="passport_number"]').val('')
$('input[name="passport_expedition_date"]').val('')
$('input[name="passport_expiration_date"]').val('')
$('input[name="gender"]').prop('checked', false);
form.render('radio');
layer.msg(lang.upload_error, {icon: 5});
}
});
upload.render({
elem: '#person_img',
url: '/home/upload/file_upload', // 后端接口 URL
before: function(obj){
//预读本地文件示例不支持ie8
obj.preview(function(index, file, result){
$('#person_img_view').attr('src', result); //图片链接base64
});
loadIndex = layer.load(0);
},
done: function(res){
layer.close(loadIndex);
// 上传成功后的回调
if (res.path.length !== 0) {
layer.msg(lang.upload_successful, {icon: 1});
$('input[name="person_img"]').val(res.path);
} else {
layer.msg(lang.upload_failed+'' + res.msg, {icon: 5});
}
},
error: function(){
layer.close(loadIndex);
layer.msg(lang.upload_error, {icon: 5});
}
});

167
public/static/js/passport-ocr-sdk.min.js vendored Normal file
View File

@@ -0,0 +1,167 @@
;(function (global) {
"use strict";
function isFileLike(v) {
return (typeof File !== "undefined" && v instanceof File) ||
(typeof Blob !== "undefined" && v instanceof Blob);
}
function fileToDataURL(file) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function () {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
async function normalizeImageInput(input) {
if (typeof input === "string") {
return {
image_base64: input,
filename: "upload_base64",
content_type: null
};
}
if (isFileLike(input)) {
var dataURL = await fileToDataURL(input);
return {
image_base64: dataURL,
filename: input.name || "upload_file",
content_type: input.type || null
};
}
throw new Error("只支持 base64 字符串、File 或 Blob");
}
async function parseJSONResponse(resp) {
var text = await resp.text();
var data = null;
try {
data = text ? JSON.parse(text) : null;
} catch (e) {
data = text;
}
if (!resp.ok) {
var msg = data && data.detail ? data.detail : text || ("HTTP " + resp.status);
throw new Error(msg);
}
return data;
}
function normalizeSign(rawSign, fallbackAppId) {
if (rawSign === undefined || rawSign === null || rawSign === "") {
throw new Error("sign 不能为空,必须由客户后端传入签名字符串或对象");
}
var data = rawSign;
if (typeof rawSign === "string") {
try {
data = JSON.parse(rawSign);
} catch (e) {
throw new Error('sign 字符串必须是 JSON 字符串,例如 {"timestamp":"1718123456","signature":"xxxx"}');
}
}
if (!data || typeof data !== "object") {
throw new Error("sign 必须是对象,或可解析为对象的 JSON 字符串");
}
var appId = data.app_id || data.appId || fallbackAppId;
var timestamp = data.timestamp;
var signature = data.signature;
if (!appId || !timestamp || !signature) {
throw new Error("sign 必须包含 timestamp 和 signatureapp_id 可省略并回退到 config.appId");
}
return {
app_id: String(appId),
timestamp: String(timestamp),
signature: String(signature)
};
}
function PassportOCRClient(config) {
this.apiBase = (config.apiBase || "").replace(/\/+$/, "");
this.appId = config.appId || "";
this.sign = config.sign;
if (!this.apiBase) {
throw new Error("apiBase 不能为空");
}
if (!this.appId) {
throw new Error("appId 不能为空");
}
}
PassportOCRClient.prototype.setSign = function (sign) {
this.sign = sign;
return this;
};
PassportOCRClient.prototype.getSignature = function (signOverride) {
var rawSign = signOverride !== undefined ? signOverride : this.sign;
return normalizeSign(rawSign, this.appId);
};
PassportOCRClient.prototype.callOCR = async function (path, input, options) {
options = options || {};
var imageInfo = await normalizeImageInput(input);
var payload = {
filename: options.filename || imageInfo.filename,
content_type: options.content_type || imageInfo.content_type,
image_base64: imageInfo.image_base64,
text_rec_score_thresh: options.text_rec_score_thresh ?? 0.3,
mrz_text_rec_score_thresh: options.mrz_text_rec_score_thresh ?? 0.0,
mrz_top_ratio: options.mrz_top_ratio ?? 0.68,
return_debug: !!options.return_debug,
auto_rotate: options.auto_rotate ?? true
};
var signed = this.getSignature(options.sign);
var resp = await fetch(this.apiBase + path, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-App-Id": signed.app_id,
"X-Timestamp": signed.timestamp,
"X-Signature": signed.signature
},
body: JSON.stringify(payload)
});
return await parseJSONResponse(resp);
};
PassportOCRClient.prototype.recognizePassport = function (input, options) {
return this.callOCR("/ocr/passport/base64", input, options);
};
PassportOCRClient.prototype.recognizeMRZ = function (input, options) {
return this.callOCR("/ocr/mrz/base64", input, options);
};
PassportOCRClient.prototype.recognizeIdCard = function (input, options) {
return this.callOCR("/ocr/idcard/base64", input, options);
};
PassportOCRClient.prototype.recognizeVisaNumber = function (input, options) {
return this.callOCR("/ocr/visa-number/base64", input, options);
};
global.PassportOCRSDK = {
create: function (config) {
return new PassportOCRClient(config || {});
}
};
})(window);

45
public/static/js/pub.js Normal file
View File

@@ -0,0 +1,45 @@
$(function(){
// nav
var _width=$(window).width();
$('.menu-btn').click(function(event) {
event.stopPropagation()
$('.nav').stop().slideToggle();
});
})

File diff suppressed because one or more lines are too long