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,441 @@
{include file="public/head" /}
<link rel="stylesheet" href="/static/css/visa.css?v={:time()}">
<style>
body { background-color: #f5f5f5; }
/* ===== 页面容器:居中卡片风格 ===== */
.contact-card{
background: #fff;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,.06);
padding: 28px 30px 22px;
border: 1px solid rgba(0,0,0,.06);
}
.contact-title h2{
font-size: 34px;
font-weight: 800;
color: #111;
margin: 0 0 10px;
}
.contact-desc{
color: #666;
font-size: 14px;
margin: 0 0 18px;
}
.contact-hr{
height: 1px;
background: #eee;
margin: 16px 0 22px;
}
/* ===== 表单:标签在上(截图同款) ===== */
.layui-form-item{ margin-bottom: 18px; }
.layui-form-label{
float: none;
width: 100%;
text-align: left;
padding: 0 0 8px 0;
font-weight: 700;
color: #222;
}
.layui-input-block{
margin-left: 0;
min-height: auto;
}
.layui-form-label span{
color: #e53935;
margin-left: 4px;
font-weight: 800;
}
/* 输入框更接近截图(高度、边框、圆角) */
.layui-input, .layui-textarea, .layui-select{
border-radius: 4px;
border-color: #e6e6e6;
}
.layui-input{ height: 44px; line-height: 44px; }
.layui-textarea{ min-height: 150px; padding: 10px 12px; }
/* ===== 输入组:做成 flex验证码在右侧不挤压 ===== */
.layui-input-group{
display: flex;
align-items: center;
gap: 12px;
width: 100%;
}
.layui-input-group > .layui-input,
.layui-input-group > input.layui-input{
flex: 1 1 auto;
min-width: 0;
}
.layui-input-group .layui-input-group-prepend{
flex: 0 0 auto;
width: auto;
}
.captcha-img-container{
display: flex;
align-items: center;
gap: 10px;
white-space: nowrap;
}
.captcha-img-container img{
height: 44px;
border-radius: 4px;
}
.captcha-img-container a{
color: #1e88e5;
font-size: 13px;
}
/* radio 更靠近截图:一行内更紧凑 */
.layui-form-radio{ margin: 0 18px 0 0; }
/* 提交按钮居中、接近你导航蓝色 */
.contact-actions{ margin-top: 8px; }
.contact-actions .layui-btn{
height: 44px;
line-height: 44px;
padding: 0 34px;
border-radius: 4px;
background: #1e73b8;
font-weight: 700;
}
@media (max-width: 740px) {
.contact-card{ padding: 22px 16px 18px; }
.contact-title h2{ font-size: 28px; }
}
/* 只影响验证码这一行 */
.captcha-item .layui-input-group{
justify-content: flex-start; /* 不把验证码推到最右 */
}
/* 固定验证码输入框宽度(你可以改成 180/200/220 */
.captcha-item .layui-input-group > input.layui-input{
flex: 0 0 220px;
max-width: 220px;
}
/* 小屏幕下恢复全宽并换行更舒服 */
@media (max-width: 740px){
.captcha-item .layui-input-group{
flex-wrap: wrap;
gap: 10px;
}
.captcha-item .layui-input-group > input.layui-input{
flex: 1 1 100%;
max-width: 100%;
}
}
</style>
<body>
<div class="zh_content">
{include file="public/newnav" /}
</div>
<div class="layui-container contact-page">
<div class="contact-card">
<div class="contact-title">
<h2>{:lang('contact.menu_contact')}</h2>
</div>
<p class="contact-desc">
{:lang('contact.info')}
</p>
<div class="contact-hr"></div>
<form class="layui-form" id="Form1" lay-filter="Form1" autocomplete="off" style="display:block;">
<div class="layui-row layui-col-space20">
<div class="layui-col-xs12 layui-col-md12">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('contact.full_name')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<input type="text" name="name" value=""
placeholder="{:lang('contact.full_name')}"
lay-verify="required" class="layui-input">
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('contact.email')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<input type="text" name="email" value=""
placeholder="{:lang('contact.email')}"
lay-verify="required|email" class="layui-input">
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('contact.repeat_email')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<input type="text" name="re_email" value=""
placeholder="{:lang('contact.repeat_email')}"
lay-verify="required|email|sameEmail" class="layui-input">
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('contact.passport_number')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<input type="text" name="passport_number" value=""
placeholder="{:lang('contact.passport_number')}"
lay-verify="required" class="layui-input">
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('contact.is_apply')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group" style="gap:22px;">
<input type="radio" name="is_apply" value="1" title="{:lang('contact.yes')}" alt="is_apply_1" lay-verify="otherReq"/>
<input type="radio" name="is_apply" value="0" title="{:lang('contact.no')}" alt="is_apply_0" lay-verify="otherReq"/>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-row data-name-is_apply data-is_apply_1">
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('contact.contact_reason')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<select name="reason_contact" class="layui-required">
<option value="">{:lang('contact.contact_reason')}</option>
{foreach $reason as $key=>$value}
<option value="{$value}">{$value}</option>
{/foreach}
</select>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('contact.order_sn')}<span style="color:#999;font-weight:600;">{:lang('contact.optional')}</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<input type="text" name="order_sn" value=""
placeholder="{:lang('contact.order_sn')}"
class="layui-input">
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md12">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('contact.comment')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<textarea name="comments" class="layui-textarea" placeholder="{:lang('contact.comment')}" lay-verify="required"></textarea>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md12">
<div class="layui-form-item captcha-item">
<label class="layui-form-label">{:lang('contact.yzm')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<input type="text" name="yzm" value=""
placeholder="{:lang('contact.yzm')}"
lay-verify="required" class="layui-input">
<div class="layui-input-group-prepend">
<div class="captcha-img-container">
<img src="{:captcha_src()}" id="captcha-img"
onclick="refreshCaptcha()"
style="cursor:pointer; border:1px solid #ddd;">
<a href="javascript:void(0);" onclick="refreshCaptcha()">
{:lang('contact.change')}
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 text-center contact-actions">
<div class="layui-form-item">
<button class="layui-btn" lay-submit lay-filter="formSubmit" id="submit">
{:lang('contact.submit_now')}
</button>
</div>
</div>
</div>
</form>
</div>
</div>
{include file="public/newfooter" /}
<script>
var layer = layui.layer, form = layui.form, laydate = layui.laydate, util = layui.util;
function refreshCaptcha() {
$('#captcha-img').attr('src', '{:captcha_src()}?t=' + Date.now());
}
form.on('submit(formSubmit)', function (data) {
var submitVal = "";
for (var i = 1; i < 2; i++) {
submitVal = $.extend(submitVal, form.val('Form' + i));
if (!form.validate('#Form' + i)) {
return false;
}
}
var load = layer.load(2, {shade: 0.3})
$.ajax({
url: "/home/contact/do_apply",
type: "POST",
data: submitVal,
success: function (data) {
layer.close(load);
refreshCaptcha()
if (data.code === 1) {
layer.msg(data.msg, {icon: 1}, function () {
window.location.reload()
});
} else {
layer.msg(data.msg, {icon: 5});
return false
}
}
});
return false;
});
form.verify({
/* 确认邮箱一致 */
sameEmail: function(value){
var email = $('input[name="email"]').val() || '';
if ((email.trim() !== (value || '').trim())) {
return '{:lang("contact.repeat_email")} 不一致';
}
},
otherReq: function (value, item) {
var $ = layui.$;
var verifyName = $(item).attr('name'),
verifyType = $(item).attr('type'),
formElem = $(item).parents('.layui-form'),
verifyElem = formElem.find('input[name=' + verifyName + ']'),
isTrue = verifyElem.is(':checked'),
focusElem = verifyElem.next().find('i.layui-icon'),
reqText = $(item).attr('lay-reqtext') || '{:lang("contact.default_reqtext")}';
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 reqText;
}
}
});
$("input[type='radio']").each(function () {
var alt = $(this).attr("alt");
if ($(this).is(":checked")) {
$(".data-" + alt).show();
} else {
$(".data-" + alt).hide();
}
})
form.on("radio", function (data) {
var name = data.elem.name;
var alt = data.elem.alt;
var $sections = $(".data-name-" + name);
$sections.each(function () {
var $section = $(this);
var isMatch = $section.hasClass("data-" + alt);
if (isMatch) {
$section.show();
} else {
$section.hide();
// 隐藏时移除 required 相关验证(你原逻辑保留)
$section.find("input, textarea, select").each(function () {
var $el = $(this);
var old = $el.attr("lay-verify") || "";
var newVerify = old
.split("|")
.filter(v => !["required", "otherReq", "checkboxChecked"].includes(v))
.join("|");
$el.attr("lay-verify", newVerify);
});
$section.find(".xm-select-default").each(function () {
var $el = $(this);
var old = $el.attr("lay-verify") || "";
var newVerify = old
.split("|")
.filter(v => !["required", "otherReq", "checkboxChecked"].includes(v))
.join("|");
$el.attr("lay-verify", newVerify);
});
}
});
// 只给当前显示块补 required
var $target = $(".data-" + alt);
$target.children().find(".layui-required").each(function () {
const $el = $(this);
const isVisible = $el.closest(".layui-form-item, .layui-col-xs12, .layui-col-md6").is(":visible");
if (!isVisible) return;
let verifyList = ($el.attr("lay-verify") || "").split("|").filter(Boolean);
if ($el.is(":radio")) {
if (!verifyList.includes("otherReq")) verifyList.push("otherReq");
} else if ($el.is(":checkbox")) {
if (!verifyList.includes("checkboxChecked")) verifyList.push("checkboxChecked");
} else {
if (!verifyList.includes("required")) verifyList.push("required");
}
$el.attr("lay-verify", verifyList.join("|"));
});
$target.find(".xm-select-default:visible").each(function () {
var $el = $(this);
var verifyList = ($el.attr("lay-verify") || "").split("|").filter(Boolean);
if (!verifyList.includes("required")) verifyList.push("required");
$el.attr("lay-verify", verifyList.join("|"));
});
form.render("radio");
form.render("checkbox");
});
</script>
</body>

View File

@@ -0,0 +1,279 @@
{include file="public/head" /}
<link rel="stylesheet" href="/static/css/index.css">
<style>
body {
background: #fff !important;
}
</style>
<body>
{include file="public/newnav" /}
<!-- ===== Hero ===== -->
<section class="hero">
<div class="container">
<div class="hero-card">
<h1>{$country|default=''}{:lang('index.visa_service')}</h1>
<p>
{:str_replace('%country%', $country ?? '', lang('index.welcome_message'))} </p>
<a class="btn btn-primary btn-primary-brand w-100" href="/home/visa/index.html">{:lang('index.online_application')}</a>
</div>
</div>
</section>
<!-- ===== Notice ===== -->
<section class="notice">
<div class="container">
<p>
<span class="tip-title">{:lang('index.notice')}</span>
{:lang('index.notice_text')}
</p>
</div>
</section>
<!-- ===== Flow ===== -->
<section class="section">
<div class="container">
<div class="section-title">{:lang('index.process_title')}</div>
<div class="row g-3 align-items-stretch">
<div class="col-lg-7">
<div class="flow2">
<div class="step">
<div class="badge-num">1</div>
<div>
<h6>{:lang('index.step1_title')}</h6>
<p>{:lang('index.step1_desc')}</p>
</div>
</div>
<div class="step">
<div class="badge-num">2</div>
<div>
<h6>{:lang('index.step2_title')}</h6>
<p>{:lang('index.step2_desc')}</p>
</div>
</div>
<div class="step">
<div class="badge-num">3</div>
<div>
<h6>{:lang('index.step3_title')}</h6>
<p>{:lang('index.step3_desc')}</p>
</div>
</div>
</div>
</div>
<div class="col-lg-5">
<div class="flow2-side">
<div class="k"><i class="bi bi-lightning-charge me-1"></i>{:lang('index.tip')}</div>
<div class="i">
• {:lang('index.tip_1')}<br>
• {:lang('index.tip_2')}<br>
• {:lang('index.tip_3')}<br>
• {:lang('index.tip_4')}
</div>
<div class="d-grid mt-3">
<a class="btn btn-primary btn-primary-brand" href="/home/visa/index.html">{:lang('index.online_application')}</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ===== Intro + Map ===== -->
<section class="section pt-0">
<div class="container">
<div class="intro2" id="apply">
<div class="row g-0">
<div class="col-lg-5">
<div class="left"></div>
</div>
<div class="col-lg-7">
<div class="right">
<h2>{$country|default=''}{:lang('index.entry_card_application')}</h2>
<p style="color: rgba(15,23,42,.72); line-height:1.9; margin:0;">
{:str_replace('%country%', $country ?? '', lang('index.application_description1'))}
</p>
<div class="bul">
<div><i class="bi bi-check2-circle"></i> {:str_replace('%country%', $country ?? '', lang('index.application_notice'))}</div>
</div>
<a class="btn btn-outline-brand w-100" href="/home/visa/index.html">
{$country|default=''}{:lang('index.apply_now')}
</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ===== 为什么选择我们 ===== -->
<section class="section pt-0">
<div class="container">
<div class="why-title"> {:lang('index.why_choose_us_title')}</div>
<div class="why-sub"> {:lang('index.why_choose_us_subtitle')}</div>
<div class="row g-3">
<div class="col-lg-6">
<div class="why2-item">
<div class="why2-ico"><i class="bi bi-lightning-charge"></i></div>
<div>
<h6>{:lang('index.convenient')}</h6>
<p>{:lang('index.convenient_desc')}</p>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="why2-item">
<div class="why2-ico"><i class="bi bi-shield-check"></i></div>
<div>
<h6>{:lang('index.secure')}</h6>
<p>{:lang('index.secure_desc')}</p>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="why2-item">
<div class="why2-ico"><i class="bi bi-award"></i></div>
<div>
<h6>{:lang('index.approval')}</h6>
<p>{:lang('index.approval_desc')}</p>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="why2-item">
<div class="why2-ico"><i class="bi bi-headset"></i></div>
<div>
<h6>{:lang('index.support')}</h6>
<p>{:lang('index.support_desc')}</p>
</div>
</div>
</div>
</div>
<div class="text-center mt-4">
<a class="btn btn-primary btn-primary-brand px-5" href="/home/visa/index.html">
{$country|default=''}{:lang('index.apply_now')}
</a>
</div>
</div>
</section>
<section class="section pt-0" id="plans">
<div class="container">
<div class="section-title">{:lang('index.setmeal')}</div>
<div class="row g-3">
<div class="col-lg-4">
<div class="plan">
<span class="tag">{:lang('index.setmeal_st')}</span>
<h5>{:lang('index.suitable_for_advance_preparation')}</h5>
<div class="meta">{:lang('index.processing_time_limit')}</div>
<ul>
<li>{:lang('index.chinese_guided_filling')}</li>
<li>{:lang('index.key_field_consistency_check')}</li>
<li>{:lang('index.basic_error_reminder')}</li>
</ul>
<div class="d-grid mt-3">
<a class="btn btn-outline-brand" href="/home/visa/index.html">{:lang('index.select_standard_plan')}</a>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="plan" style="border-color: rgba(240,90,40,.35);">
<span class="tag" style="border-color: rgba(240,90,40,.22); background: rgba(240,90,40,.10);">{:lang('index.setmeal_ex')}</span>
<h5>{:lang('index.suitable_for_departure_soon')}</h5>
<div class="meta">{:lang('index.urgent_availability')}</div>
<ul>
<li>{:lang('index.priority_processing_queue')}</li>
<li>{:lang('index.stricter_reminder_for_key_fields')}</li>
<li>{:lang('index.faster_feedback_and_supplementary_suggestions')}</li>
</ul>
<div class="d-grid mt-3">
<a class="btn btn-accent" href="/home/visa/index.html">{:lang('index.select_urgent_plan')}</a>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="plan">
<span class="tag">{:lang('index.setmeal_team')}</span>
<h5>{:lang('index.group_travel_batch_reg')}</h5>
<div class="meta">{:lang('index.group_meta_info')}</div>
<ul>
<li>{:lang('index.batch_data_collect')}</li>
<li>{:lang('index.unified_verify_submit')}</li>
<li>{:lang('index.progress_track_reconcile')}</li>
</ul>
<div class="d-grid mt-3">
<a class="btn btn-primary btn-primary-brand" href="/home/contact">{:lang('index.contact_team_plan')}</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ===== 新增模块 2FAQ提升转化不改整体风格 ===== -->
<section class="section pt-0" id="faq">
<div class="container">
<div class="section-title">{:lang('index.common_questions')}</div>
<div class="accordion" id="accFaq">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#f1">
{:lang('index.faq_is_official_website')}
</button>
</h2>
<div id="f1" class="accordion-collapse collapse" data-bs-parent="#accFaq">
<div class="accordion-body" style="color: rgba(15,23,42,.72); line-height: 1.9; font-size: 13px;">
{:lang('index.faq_is_official_website_answer')}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#f2">
{:lang('index.faq_guarantee_approval')}
</button>
</h2>
<div id="f2" class="accordion-collapse collapse" data-bs-parent="#accFaq">
<div class="accordion-body" style="color: rgba(15,23,42,.72); line-height: 1.9; font-size: 13px;">
{:lang('index.faq_guarantee_approval_answer')}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#f3">
{:lang('index.faq_query_download_after_payment')}
</button>
</h2>
<div id="f3" class="accordion-collapse collapse" data-bs-parent="#accFaq">
<div class="accordion-body" style="color: rgba(15,23,42,.72); line-height: 1.9; font-size: 13px;">
{:lang('index.faq_query_download_after_payment_answer')}
</div>
</div>
</div>
</div>
</div>
</section>
{include file="public/newfooter" /}
</body>
</html>

View File

@@ -0,0 +1,187 @@
{include file="public/head"}
<link rel="stylesheet" href="/static/css/index.css?v={:time()}">
<style>
body {
background: #fff !important;
}
</style>
<body>
<div class="zh_content">
{include file="public/nav"}
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="swiper-slide-img">
</div>
</div>
</div>
<div class="evus-main">
<div class="djcon">
<div class="dj-box">
<div class="dj-txt" style="font-size: 24px; line-height: 40px; color: #14286d;">{$country|default=''}{:lang('index.visa_service')}</div>
<div class="dj-txt2">{:str_replace('%country%', $country ?? '', lang('index.welcome_message'))}</div>
<a href="/home/visa/index.html" class="dj-btn">{:lang('index.online_application')}</a>
</div>
</div>
</div>
</div>
<div class="container-apply notice" style="margin-top: 16px">
<p style="font-size: 16px;line-height: 30px;">
<span style="color: red;font-weight: bold;">{:lang('index.notice')}</span>
<span>{:lang('index.notice_text')}</span>
</p>
</div>
<div class="process">
<div class="ps-tit">{:lang('index.process_title')}</div>
<div class="pro-con">
<div class="ps-item item-border">
<img src="/static/image/icon-infor.png" alt="">
<div class="ps-text">{:lang('index.step1_title')}</div>
<div class="ps-text">{:lang('index.step1_desc')}</div>
</div>
<div class="ps-item ps-item2">
<img class="pc-ps-item" src="/static/image/icon-arrow.png" alt="">
<img style="display: none" class="m-ps-item" src="/static/image/micon-arrow.png" alt=""/>
</div>
<div class="ps-item item-border">
<img src="/static/image/icon-up2.png" alt="">
<div class="ps-text">{:lang('index.step2_title')}</div>
<div class="ps-text">{:lang('index.step2_desc')}</div>
</div>
<div class="ps-item ps-item2">
<img class="pc-ps-item" src="/static/image/icon-arrow.png" alt="">
<img style="display: none" class="m-ps-item" src="/static/image/micon-arrow.png" alt=""/>
</div>
<div class="ps-item item-border">
<img src="/static/image/icon-down.png" alt="">
<div class="ps-text">{:lang('index.step3_title')}</div>
<div class="ps-text">{:lang('index.step3_desc')}</div>
</div>
</div>
</div>
<div class="container-apply">
<div class="apply-item">
<img src="/static/image/malaixiya.jpg" >
</div>
<div class="apply-item" style="margin-top:35px;">
<div class="bt" style="text-align: center">{$country|default=''}{:lang('index.entry_card_application')}</div>
<div style="font-size:16px; line-height:30px;">
{:str_replace('%country%', $country ?? '', lang('index.application_description1'))}
<br>
<p style="padding-top:15px;line-height:30px;">
{:str_replace('%country%', $country ?? '', lang('index.application_notice'))}
</p>
<div style="text-align: center;">
<a href="{:url('visa/index')}">
<button class="dj-btn">{$country|default=''}{:lang('index.apply_now')}</button>
</a>
</div>
</div>
</div>
</div>
{include file="public/middle"}
<div style="text-align: center;margin-bottom: 20px;">
<a href="{:url('visa/index')}">
<button class="dj-btn">{$country|default=''}{:lang('index.apply_now')}</button>
</a>
</div>
<div class="advantages-section">
<div class="content1">
<h3 class="title">{$country|default=''}{:lang('index.electronic_arrival_card')}</h3>
<div style="color:#fff; font-size:16px; line-height:35px;">
{:str_replace('%country%', $country ?? '', lang('index.environmental_initiative'))}<br>
{:lang('index.digital_process_benefits')}<br><br>
{:str_replace('%country%', $country ?? '', lang('index.submission_requirement'))}<br>
{:str_replace('%country%', $country ?? '', lang('index.card_validity'))}
</div>
<div style="text-align: center;margin-bottom: 20px;">
<a href="{:url('visa/index')}">
<button class="dj-btn" style="background: linear-gradient(180deg, #a83723 0, #a83723 100%);">{$country|default=''}{:lang('index.apply_now')}</button>
</a>
</div>
</div>
</div>
{include file="public/footer"}
</body>
<script>
// 监听复选框点击
$('.termsCheckbox').click(function (e) {
e.preventDefault();
if (window.innerWidth <= 768) {
area = ['90%', '90%']
} else {
area = ['50%', '60%']
}
// 弹出条款内容的弹窗
layer.open({
type: 1, // 弹窗类型:页面层
title: '{:lang(\'js.terms_conditions\')}', content: `
<div style="padding: 20px;">
<h3>{:lang(\'js.terms_conditions\')}</h3>
<p></p><p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.terms_intro\'))}</span></p>
<p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.our_services\'))}</span></p>
<p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.application_process\'))}</span></p>
<p><span style="font-size: 12px;">{:lang(\'js.read_confirmation\')}</span></p>
<p><br></p><p></p>
</div>
`, area: area, // 弹窗大小
btn: ['关闭'], // 按钮
yes: function (index) {
layer.close(index); // 关闭弹窗
}
});
});
$('.privacy_policy').click(function (e) {
e.preventDefault();
if (window.innerWidth <= 768) {
area = ['90%', '90%']
} else {
area = ['50%', '60%']
}
// 弹出条款内容的弹窗
layer.open({
type: 1, // 弹窗类型:页面层
title: '{:lang(\'js.privacy_policy\')}', content: `
<div style="padding: 20px;">
<h3>{:lang(\'js.privacy_policy\')}</h3>
<p></p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.privacy_intro\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">1. {:lang(\'js.scope\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.scope_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">2. {:lang(\'js.information_use\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_use_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">3. {:lang(\'js.information_disclosure\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_disclosure_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">4. {:lang(\'js.information_storage\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_storage_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">5. {:lang(\'js.cookie_use\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.cookie_use_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">6. {:lang(\'js.information_security\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_security_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">7. {:lang(\'js.policy_changes\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.policy_changes_content\')}</p>
<p><br></p><p></p>
</div>
`, area: area, // 弹窗大小
btn: ['关闭'], // 按钮
yes: function (index) {
layer.close(index); // 关闭弹窗
}
});
});
</script>
</html>

View File

@@ -0,0 +1,182 @@
{include file="public/head" /}
<link rel="stylesheet" href="/static/css/user.css?v={:time()}">
<link rel="stylesheet" href="/static/css/invoice.css?v={:time()}">
</head>
<body class="user-page">
{include file="public/newnav" /}
<main class="user-main">
<div class="layui-container">
<div class="account-layout">
<aside class="account-nav">
<div class="account-nav__title">个人中心</div>
<a href="{:url('user/index')}" class="account-nav__link">
<i class="bi bi-receipt"></i><span>我的订单</span>
</a>
<a href="{:url('user/invoice')}" class="account-nav__link is-active">
<i class="bi bi-file-earmark-text"></i><span>自助开票</span>
</a>
<a href="{:url('user/multiple')}" class="account-nav__link">
<i class="bi bi-files"></i><span>合并开票</span>
</a>
</aside>
<section class="account-panel">
<div class="account-panel__title">发票申请</div>
<div class="account-panel__body">
<div class="invoice-summary">
<div>
<strong>开票金额</strong>
<span>{$data.total_price}</span>
</div>
<p>提交后,商家将在 1-3 个工作日内完成开票。</p>
</div>
<p class="invoice-tip">
个人开票时,税号请填写身份证号码;企业开票请填写统一社会信用代码。
</p>
<form class="layui-form invoice-form" action="">
<div class="invoice-section-title">必填信息</div>
<div class="layui-row layui-col-space24">
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">手机号<span>*</span></label>
<div class="layui-input-block">
<input type="tel" autocomplete="off" class="layui-input" lay-verify="required|phone" name="phone" placeholder="用于接收发票通知">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">客户名称<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="title" lay-verify="required" placeholder="限55个字符" maxlength="55" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">税号<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="tax_number" lay-verify="required" placeholder="请输入税号或身份证号码" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">联系人<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="link_person" lay-verify="required" placeholder="请输入联系人姓名" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12">
<div class="layui-form-item">
<label class="layui-form-label">邮箱<span>*</span></label>
<div class="layui-input-block">
<input type="email" name="link_email" lay-verify="required|email" placeholder="用于接收电子发票" autocomplete="off" class="layui-input">
</div>
</div>
</div>
</div>
<div class="invoice-section-title invoice-section-title--sub">补充信息</div>
<div class="layui-row layui-col-space24">
<div class="layui-col-xs12">
<div class="layui-form-item">
<label class="layui-form-label">地址</label>
<div class="layui-input-block">
<input type="text" name="address" placeholder="请输入注册地址" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">电话</label>
<div class="layui-input-block">
<input type="text" name="mobile" placeholder="请输入联系电话" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">开户行</label>
<div class="layui-input-block">
<input type="text" name="bank" placeholder="请输入开户银行" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12">
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-block">
<input type="text" name="account" placeholder="请输入银行账号" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12">
<input type="hidden" name="order_id" value="{$data.id}">
<input type="hidden" name="order_sn" value="{$data.order_sn}">
<button type="submit" id="button" class="layui-btn layui-btn-fluid" lay-submit lay-filter="demo1">
<span>提交申请</span>
</button>
</div>
</div>
</form>
</div>
</section>
</div>
</div>
</main>
{include file="public/newfooter" /}
<!--//倒计时-->
<script>
layui.use(function(){
var $ = layui.$;
var form = layui.form;
var layer = layui.layer;
// 提交事件
form.on('submit(demo1)', function(data){
var field = data.field; // 获取表单字段值
field.tax_number = $.trim(field.tax_number || '');
var tax_len = field.tax_number.length;
var arr = [15, 17, 18, 20];
if (arr.indexOf(tax_len) == -1) {
layer.msg('仅支持购方税号长度为15、17、18、20请重新输入');
return false;
}
var $button = $('#button');
var buttonText = $button.find('span').text();
$button.prop('disabled', true).find('span').text('提交中...');
$.ajax({
url: "/home/invoice/add_invoice",
type: 'POST',
data: field,
success: function (res) {
if (res.status == 1) {
layer.alert('已提交开票申请,商家会在 1-3个工作日内完成开票,<br>请扫描下方二维码进行添加客服收取发票<br><div class="in-img"><img src="{$fapiao_kefu}" width: 150px;></div>', {
icon: 1,
title:'发票申请',
closeBtn: 0
}, function(index){
layer.close(index);
window.location.href = res.url;
});
} else {
$button.prop('disabled', false).find('span').text(buttonText);
layer.msg(res.msg || '提交失败,请稍后重试');
}
},
error: function () {
$button.prop('disabled', false).find('span').text(buttonText);
layer.msg('网络异常,请稍后重试');
}
})
return false; // 阻止默认 form 跳转
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,591 @@
{include file="public/head"}
<style>
/* ---- Card ---- */
.lookup-card{
background:#fff;
border:1px solid rgba(0,0,0,.06);
box-shadow: 0 2px 10px rgba(0,0,0,.06);
border-radius: 6px;
margin: 18px 0 26px;
overflow:hidden;
max-width: 100%;
}
.lookup-bar{
background: var(--main-color);
color:#fff;
font-size: 24px;
font-weight: 900;
padding: 8px 16px;
line-height: 1.2;
}
.lookup-body{
padding: 18px 22px 8px;
}
/* ---- Form labels above ---- */
.label-above .layui-form-label{
display:block;
float:none;
width:auto !important;
text-align:left;
padding: 0 0 6px 0;
font-weight: 800;
font-size: 18px; /* PC 默认就用 18避免过大 */
color:#3a3a3a;
}
.label-above .layui-form-label span{
color:#e53935;
margin-left:4px;
font-weight:900;
}
.layui-input-block{
margin-left:0;
min-height: auto;
box-sizing: border-box;
}
/* ---- Inputs ---- */
.layui-form input.layui-input{
height: 50px; /* 统一高度 */
border: 1px solid #d6d6d6;
border-radius: 2px;
padding: 10px 12px;
font-size: 14px; /* PC 默认 14 */
color:#333;
background:#fff;
box-sizing: border-box;
}
/* Layui date input background keep */
.layui-input-wrap .layui-input-prefix + .layui-input,
.layui-input-wrap .layui-input-prefix ~ * .layui-input{
background:#fff;
}
/* ---- Date prefix icon vertical align ---- */
.layui-input-wrap{
display: flex;
align-items: center; /* 关键prefix 与 input 垂直居中 */
}
.layui-input-wrap .layui-input-prefix{
display: flex;
align-items: center;
justify-content: center;
height: 50px;
line-height: 50px;
}
/* ---- Help tip ---- */
.help-tip{
margin-top: 8px;
display:flex;
align-items:flex-start;
gap: 6px;
color:#666;
font-size: 13px;
line-height: 1.6;
}
.help-tip i{
font-size: 14px;
color:#333;
margin-top: 2px;
}
/* ---- Button ---- */
.btn-row{ margin-top: 8px; }
.layui-btn{
background:#153854;
border:1px solid #153854;
box-shadow: 0 2px 4px rgba(0,0,0,.35);
border-radius: 6px;
font-size: 20px;
font-weight: 900;
height: 50px;
line-height: 50px;
padding: 0 28px;
letter-spacing: .5px;
box-sizing: border-box;
}
.btn-fixed{
width: 520px;
max-width: 100%;
}
/* ---- Result area ---- */
#result{ padding: 0 22px 22px; }
.container-tit{
font-size: 18px;
font-weight: 900;
color:#153854;
margin: 12px 0 8px;
}
.container-con{
font-size: 14px;
color:#555;
margin-bottom: 12px;
}
.layui-table thead{
color:#fff;
background:#153854;
}
.layui-laydate .layui-this,
.layui-laydate .layui-this > div{
background-color:#153854 !important;
color:#fff !important;
}
/* ---- Prevent overflow caused by row negative margin / fixed width elements ---- */
.layui-row{
max-width: 100%;
box-sizing: border-box;
}
img, table, .layui-table-view{
max-width: 100% !important;
}
/* ===============================
Mobile adjustments
=============================== */
@media (max-width: 768px){
/* 容器左右留白,防止撑破 */
.layui-container{
padding-left: 12px !important;
padding-right: 12px !important;
}
/* row 可能有负 margin清掉 */
.layui-row{
margin-left: 0 !important;
margin-right: 0 !important;
}
/* 卡片内部 padding 更紧凑 */
.lookup-bar{
font-size: 22px;
padding: 12px 14px;
}
.lookup-body{
padding: 14px 14px 6px;
}
.label-above .layui-form-label{
font-size: 18px;
}
.layui-form input.layui-input{
height: 50px;
font-size: 15px;
}
.layui-input-wrap .layui-input-prefix{
height: 50px;
line-height: 50px;
}
.layui-btn{
font-size: 22px;
height: 62px;
line-height: 62px;
width: 100%;
}
.layui-table-header{ display:none; }
}
/* ===============================
Desktop fine-tune (optional)
=============================== */
@media (min-width: 992px){
/* 大屏让卡片更像截图:稍微增加左右 padding */
.lookup-body{ padding: 18px 22px 8px; }
}
</style>
<body>
<div class="zh_content">
{include file="public/newnav" }
</div>
<div class="layui-container">
<div class="lookup-card">
<div class="lookup-bar">{:lang('lookup.status_query_title')}</div>
<div class="lookup-body">
<form class="layui-form label-above" lay-filter="Form1" id="Form1" autocomplete="off">
<div class="layui-row layui-col-space30" style="margin-top: 10px;">
<!-- 护照号 -->
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="passport_number">
{:lang('lookup.passport_number')}<span>*</span>
</label>
<div class="layui-input-block passport-wrap">
<input type="text" name="passport_number" lay-verify="required"
placeholder="{:lang('lookup.passport_number_placeholder')}"
class="layui-input" value="">
<!-- 关键:给 file 一个 id并隐藏 -->
<input id="passport_file" class="passport-file" type="file" accept="image/*"
onchange="uploadPassport(this,'passport')">
<!-- 关键label 的 for 指向 file 的 id -->
<label class="passport-upload" for="passport_file" title="拍照/上传有效护照照片">
<i class="layui-icon layui-icon-camera"></i>
</label>
</div>
</div>
</div>
<!-- 出生日期 -->
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="birth_date">
{:lang('lookup.birth_date')}<span>*</span>
</label>
<div class="layui-input-block">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-date"></i>
</div>
<input type="text" name="birth_date" id="birth_date" lay-verify="required"
placeholder="{:lang('lookup.birth_date_placeholder')}"
class="layui-input layui-time" value="">
</div>
</div>
</div>
</div>
<!---->
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('lookup.last_name')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="last_name" lay-verify="required|english"
placeholder="{:lang('lookup.last_name_placeholder')}"
class="layui-input" value="">
<div class="help-tip">
<i class="layui-icon layui-icon-tips-fill"></i>
<span>{:lang('lookup.last_name_tooltip')}</span>
</div>
</div>
</div>
</div>
<!---->
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('lookup.first_name')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="first_name" lay-verify="required|english"
placeholder="{:lang('lookup.first_name_placeholder')}"
class="layui-input" value="">
<div class="help-tip">
<i class="layui-icon layui-icon-tips-fill"></i>
<span>{:lang('lookup.first_name_tooltip')}</span>
</div>
</div>
</div>
</div>
<!-- 按钮:半宽且不铺满 -->
<div class="layui-col-xs12 layui-col-md6 btn-row">
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn btn-fixed" lay-submit lay-filter="formSubmit" id="submit">
{:lang('lookup.query_status_button')}
</button>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="layui-row container" style="display:none" id="result">
<div class="layui-col-xs12 layui-col-md12" style="display:none" id="result1">
<div class="container-tit">{:lang('lookup.registered_status')}</div>
<div class="container-con">{:lang('lookup.approval_message')}</div>
</div>
<div class="layui-col-xs12 layui-col-md12">
<table class="layui-hide" id="demo"></table>
</div>
</div>
</div>
</div>
{include file="public/newfooter" }
<script>
var layer = layui.layer, form = layui.form, laydate = layui.laydate, table = layui.table;
var ocrConfigRaw = '{$ocr_config|default = ''}'.replace(/&quot;/g, '"');
var ocrConfig = {};
var sdk = null;
try {
ocrConfig = ocrConfigRaw ? JSON.parse(ocrConfigRaw) : {};
} catch (e) {
console.error('Failed to parse OCR config', e);
}
if (window.PassportOCRSDK && ocrConfig.base_url && ocrConfig.app_id && ocrConfig.signature && ocrConfig.timestamp) {
try {
sdk = PassportOCRSDK.create({
apiBase: ocrConfig.base_url,
appId: ocrConfig.app_id,
sign: ocrConfig
});
} catch (e) {
console.error('Failed to init OCR sdk', e);
}
}
// 更稳的手机判断
function isMobile() {
return window.matchMedia && window.matchMedia('(max-width: 767.98px)').matches;
}
// 日期控件(建议固定格式)
$(".layui-form-item").find(".layui-time").each(function () {
laydate.render({
elem: this,
trigger: 'click',
format: 'yyyy-MM-dd'
});
});
// ✅兼容你 onchange 传了第二个参数
function uploadPassport(_this, type) {
var file = _this.files && _this.files[0];
var loadingIndex = null;
var closeLoading = function () {
if (loadingIndex !== null) {
layer.close(loadingIndex);
loadingIndex = null;
}
};
var resetFileInput = function () {
$(_this).val('');
};
if (!file) {
layer.msg('{:lang("controller.upload_missing")}', {icon: 5});
return false;
}
if (!/image\/\w+/.test(file.type || '')) {
layer.msg("{:lang('js.upload_image_only')}", {icon: 5});
return false;
}
if (!FileReader) {
layer.msg("{:lang('js.browser_not_supported')}", {icon: 5});
return false;
}
var url = "/home/upload/upload_passport";
loadingIndex = layer.load(2, {shade: 0.3});
compressImage(file, 0.2, async function (compressedFile) {
try {
if (!compressedFile) {
closeLoading();
resetFileInput();
layer.msg('{:lang("js.upload_retry")}', {icon: 5});
return false;
}
var ocrWarningMsg = '';
if (sdk) {
try {
var ocrData = await sdk.recognizePassport(compressedFile, {
auto_rotate: true,
return_debug: false
});
if (ocrData && ocrData.code === 1 && ocrData.data) {
var ocr = ocrData.data || {};
var pad2 = function (n) {
return String(n || '').padStart(2, '0');
};
var buildDate = function (y, m, d) {
if (!y || !m || !d) return '';
return y + '-' + pad2(m) + '-' + pad2(d);
};
$('input[name="last_name"]').val(ocr.last_name || '');
$('input[name="first_name"]').val(ocr.first_name || '');
$('input[name="passport_number"]').val(ocr.passport_number || '');
var birthDate = buildDate(ocr.birth_date_year, ocr.birth_date_month, ocr.birth_date_day);
if (birthDate) {
$('input[name="birth_date"]').val(birthDate);
}
} else {
ocrWarningMsg = '{:lang("js.manual_entry_required")}';
}
} catch (ocrErr) {
ocrWarningMsg = '{:lang("js.manual_entry_required")}';
}
} else {
ocrWarningMsg = '{:lang("js.manual_entry_required")}';
}
var formData = new FormData();
formData.append('file', compressedFile);
formData.append('path', 'mala');
$.ajax({
url: url,
type: "post",
data: formData,
dataType: "json",
contentType: false,
processData: false,
mimeType: "multipart/form-data",
success: function (res) {
closeLoading();
resetFileInput();
if (res.code != 1) {
//layer.msg('{:lang("js.manual_entry_required")}', {icon: 5});
//return;
}
},
error: function () {
closeLoading();
resetFileInput();
//layer.msg('{:lang("js.manual_entry_required")}', {icon: 5});
}
});
if (ocrWarningMsg) {
layer.msg(ocrWarningMsg, {icon: 5});
}
} catch (e) {
closeLoading();
resetFileInput();
layer.msg('{:lang("js.manual_entry_required")}', {icon: 5});
}
});
}
function compressImage(file, quality, callback) {
console.log("开始压缩"+Date.now())
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (event) {
const img = new Image();
img.src = event.target.result;
img.onload = function () {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let maxWidth = 1200;
let width = img.width;
let height = img.height;
if (width > maxWidth) {
height *= maxWidth / width;
width = maxWidth;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob(function (blob) {
const newFile = new File([blob], file.name, { type: file.type });
callback(newFile);
}, file.type, quality);
};
};
}
// 监听提交
form.on('submit(formSubmit)', function (data) {
$('#result').hide();
$('#result1').hide();
$.ajax({
type: "POST",
url: "/home/lookup/enrollment",
data: data.field,
beforeSend: function () {
window.index1 = layer.load(1, {shade: [0.3, '#fff']});
},
success: function (_data) {
layer.close(window.index1);
if (_data.code == 0) {
layer.msg(_data.msg, {icon: 5});
return;
}
$('#result').show();
var row = _data.data || {};
var hasFile = !!(row.file_url && row.file_url !== '');
if (isMobile()) {
// 手机:字段-值
var mobileData = [
{field: '{:lang("lookup.passport_number")}', value: row.passport_number || ''},
{field: '{:lang("lookup.birth_date")}', value: row.birth_date || ''},
{field: '{:lang("lookup.last_name")}', value: row.last_name || ''},
{field: '{:lang("lookup.first_name")}', value: row.first_name || ''},
{field: hasFile ? '{:lang("lookup.document")}' : '{:lang("lookup.status")}', value: row.file_url || ''}
];
if (hasFile) $('#result1').show();
table.render({
elem: '#demo',
data: mobileData,
cols: [[
{field:'field', title:'{:lang("lookup.field")}', width:110},
{
field:'value',
title:'{:lang("lookup.value")}',
templet: function(d){
if (d.field === '{:lang("lookup.document")}') {
return '<a href="'+ row.file_url +'?'+ Math.random() +'" target="_blank"><img src="/static/image/pdf.png" alt="{:lang("lookup.click_download")}"></a>';
}
if (d.field === '{:lang("lookup.status")}') {
return '{:lang("lookup.in_progress")}';
}
return d.value;
}
}
]]
});
} else {
if (hasFile) $('#result1').show();
table.render({
elem: '#demo',
data: [row],
cols: [[
{field:'last_name', title:'{:lang("lookup.last_name")}', width:200},
{field:'first_name', title:'{:lang("lookup.first_name")}', width:200},
{field:'birth_date', title:'{:lang("lookup.birth_date")}', width:200},
{field:'passport_number', title:'{:lang("lookup.passport_number")}'},
{
field:'file_url',
title: hasFile ? '{:lang("lookup.document")}' : '{:lang("lookup.status")}',
templet: function(){
if (hasFile) {
return '<a href="'+ row.file_url +'?'+ Math.random() +'" target="_blank"><img src="/static/image/pdf.png" alt="{:lang("lookup.click_download")}"></a>';
}
return '{:lang("lookup.in_progress")}';
}
}
]]
});
}
}
});
return false;
});
form.verify({
english: [/^[A-Za-z]+$/, '{:lang("lookup.english_only")}']
});
</script>
</body>
</html>

View File

@@ -0,0 +1,141 @@
{include file="public/head"}
</head>
<style>
@media (max-width: 1110px) {
.nav a {
width: 35%;
}
}
</style>
<style>
.news_cc {
width: 100%;
}
a:link, a:visited {
text-decoration: none;
}
.news_item {
width: 100%;
height: auto;
overflow: hidden;
margin-top: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
cursor: pointer;
display: block;
}
.news_intro p,.news_intro span{
width: 100%;
line-height: 24px !important;
font-size: 13px !important;
color: #888 !important;
margin: 0 !important;
}
a {
cursor: pointer;
color: #333;
}
.news_text {
float: left;
width: 100%;
}
span{
font-style:unset !important;
}
.news_ct {
width: 100%;
line-height: 18px;
font-size: 15px;
margin-bottom: 8px;
}
.news_intro {
width: 100%;
line-height: 24px;
font-size: 13px;
color: #888;
overflow: hidden;
}
.news_time {
text-align: right;
color: #888;
line-height: 28px;
font-size: 12px;
}
@media (max-width: 720px){
.content {
width: 100%;
padding: 30px 0px 0px;
background: none;
}
}
.layui-laypage .layui-laypage-curr .layui-laypage-em {
background-color: var(--main-color);
}
</style>
<body style="background: #F8F8F8;display: flex; flex-direction: column; min-height: 100vh;">
<div class="zh_content">
{include file="public/newnav" }
</div>
<div class="layui-container" style="flex: 1;margin-top: 36px;">
<div class="modular-row callout bg-grey">
<div class="container">
<div class="news_cc">
{volist name="news_list" id="vo"}
<a class="news_item" href="{:url('news/detail', ['id' => $vo.id])}">
<div class="news_text">
<div class="news_ct animate_tit">{:cookie('think_var') == 'en-us' ? $vo['en_title'] : $vo['title']}</div>
<div class="news_intro">
<?= mb_strlen($plain = strip_tags(html_entity_decode(cookie('think_var') == 'en-us' ? $vo['en_contents'] : $vo['contents']))) > 100 ? htmlspecialchars(mb_substr($plain, 0, 100, 'UTF-8')).'...' : htmlspecialchars($plain) ?>
</div>
<div class="news_time">{$vo.create_time|date='Y-m-d H:i:s'}</div>
</div>
</a>
{/volist}
</div>
<div style="width: 100%; text-align: center;" id="case_page"></div>
</div>
</div>
</div>
{include file="public/newfooter" }
<script>
layui.use(function(){
var laypage = layui.laypage;
// 自定义每页条数的选择项
laypage.render({
elem: 'case_page',
count: '{$count}',
curr: '{$page}',
limit: '{$size}',
prev: '<em>←</em>',
next: '<em>→</em>',
jump: function(obj, first){
if(!first){
window.location.href = '{:Url("news/index")}?page='+obj.curr;
}
}
});
});
$('a[href*="articles"]').parents(".search-row").addClass("hidden");
$(document).ready(function () {
if (window.location.href.indexOf("query") > -1) {
$(".results").css("visibility", "inherit")
} else {
}
if ($(window).width() > 768) {
$("a:not(a.cookieAccept)").each(function () {
// $(this).attr('target', '_blank');
});
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,69 @@
{include file="public/head"}
<style>
.evus_tit {
width: 100%;
font-size: 24px;
text-align: center;
line-height: 40px;
}
.evus_infor {
color: #666;
font-size: 14px;
text-align: center;
padding: 20px 0;
border-bottom: 1px dashed #ddd;
margin-bottom: 20px;
}
.evus_con {
padding-bottom: 10px;
border-bottom: 1px dashed #ddd;
font-size: 14px;
}
.evus_con img {
margin: 0 auto;
width: 80%;
margin: 10px 0;
}
.evus_con p,
.evus_con span {
font-size: 14px;
}
.evus_other {
margin-top: 10px;
line-height: 30px;
}
@media (max-width: 720px) {
.content {
width: 100%;
padding: 30px 0px 0px;
background: none;
}
}
</style>
<body style="background: #F8F8F8;display: flex; flex-direction: column; min-height: 100vh;">
<div class="zh_content">
{include file="public/newnav" }
</div>
<div class="container" style="flex: 1;">
<div class="modular-row callout bg-grey">
<div class="container">
<h1 class="evus_tit">{:cookie('think_var') == 'en-us' ? $info['en_title'] : $info['title']}</h1>
<div class="evus_infor">
{:lang('index.news_author')}admin {:lang('index.news_time')}{$info.create_time}
</div>
<div class="evus_con">
<?= html_entity_decode(cookie('think_var') == 'en-us' ? $info['en_contents'] : $info['contents']) ?>
</div>
</div>
</div>
</div>
{include file="public/newfooter" }
</body>
</html>

View File

@@ -0,0 +1,47 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>{:lang('pay.wechat_pay_title')}</title>
<script type="text/javascript" src="/static/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="/static/js/jquery-weui.min.js"></script>
<link rel="stylesheet" href="/static/css/weui.min.css">
<link rel="stylesheet" href="/static/css/jquery-weui.min.css">
<script type="text/javascript">
$(document).on("click", "#confirm", function () {
//进行查询订单
$.ajax({
type: "POST",
url: "{:url('pay/h5result',['order_sn'=>$order_sn])}",//+tab,
dataType: "json",
success: function (data) {
$.alert(data.msg);
setTimeout(function () {
location.href = data.url; // 跳转
}, 1000);
}
});
})
$(document).on("click", "#repay", function () {
//进行重新支付
window.location.href="{:url('pay/pay',['order_sn'=>$order_sn])}";
})
</script>
</head>
<body>
<div class="weui-mask weui-mask--visible"></div>
<div class="weui-dialog weui-dialog--visible">
<div class="weui-dialog__hd">
<strong class="weui-dialog__title">{:lang('pay.dialog_title')}</strong>
</div>
<div class="weui-dialog__bd">{:lang('pay.payment_confirmation')}</div>
<div class="weui-dialog__ft">
<a href="javascript:;" class="weui-dialog__btn default" id="repay">{:lang('pay.repay_button')}</a>
<a href="javascript:;" class="weui-dialog__btn primary" id="confirm">{:lang('pay.confirm_button')}</a>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,207 @@
{include file="public/head"}
<link rel="stylesheet" href="/static/css/pcpay.css?v=2">
<style>
.payment-pending {
max-width: 760px;
margin: 0 auto;
text-align: left;
}
.payment-pending-title {
font-size: 24px;
font-weight: 700;
margin-bottom: 16px;
color: #1f2937;
}
.payment-pending-text {
font-size: 16px;
line-height: 1.8;
color: #4b5563;
margin-bottom: 12px;
}
.payment-pending-status {
font-size: 15px;
color: #b45309;
margin-bottom: 24px;
}
.payment-spinner {
display: inline-block;
width: 24px;
height: 24px;
border: 3px solid #e5e7eb;
border-top-color: #2563eb;
border-radius: 50%;
animation: sqpay-spin 0.8s linear infinite;
vertical-align: middle;
margin-right: 10px;
}
@keyframes sqpay-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
</head>
<body style="display: flex; flex-direction: column; min-height: 100vh;">
<div class="zh_content">
{include file="public/newnav" }
</div>
<div
class="container"
id="payment-success-page"
data-payment-confirmed="{$payment_confirmed}"
data-poll-status-url="{$poll_status_url}"
>
<div class="modular-row callout bg-grey" style="margin-top: 50px; flex: 1;">
<div class="container">
<div class="row">
<div class="col-md-12 text-left">
<div id="payment-pending-block" class="payment-pending" style="display: none;">
<p class="payment-pending-title">
<span class="payment-spinner"></span>{:lang('sqpay.notice_title')}
</p>
<p class="payment-pending-text">{:lang('sqpay.notice_text')}</p>
<p class="payment-pending-text">
{:str_replace('%order_sn%', $order_sn ?? '', lang('pay.order_submitted'))}
</p>
<p class="payment-pending-status" id="payment-pending-status">{:lang('sqpay.notice_text')}</p>
<div class="register">
<a href="{$repay_url}">
<button class="dj-btn">{:lang('pay.repay_button')}</button>
</a>
</div>
</div>
<div id="payment-success-block">
<p style="font-size: 20px">{:lang('pay.thank_you_message')}</p>
<p style="font-size: 18px;color: #880000">
{:str_replace('%order_sn%', $order_sn ?? '', lang('pay.order_submitted'))}
</p>
<p style="font-size: 15px">
{:str_replace('%country%', $country ?? '', lang('pay.processing_time_info'))}
</p>
{if $arrive_date_info}
<p style="font-size: 15px">
{$arrive_date_info}
</p>
{/if}
<p style="font-size: 20px;font-weight: bolder;color: red">
{:lang('pay.contact')}
</p>
</div>
</div>
<div class="register" id="payment-success-action">
<a href="{:url('visa/index')}">
<button class="dj-btn">{:lang('pay.visa_application_button')}</button>
</a>
</div>
</div>
</div>
</div>
</div>
{include file="public/newfooter" }
<script>
(function () {
var pageEl = document.getElementById('payment-success-page');
if (!pageEl) {
return;
}
var isConfirmed = pageEl.getAttribute('data-payment-confirmed') === '1';
var pollUrl = pageEl.getAttribute('data-poll-status-url');
var pendingBlock = document.getElementById('payment-pending-block');
var successBlock = document.getElementById('payment-success-block');
var successAction = document.getElementById('payment-success-action');
var pendingStatus = document.getElementById('payment-pending-status');
var pendingText = "{:lang('sqpay.notice_text')}";
var successText = "{:lang('controller.payment_success')}";
var pollTimer = null;
var maxAttempts = 30;
var attempt = 0;
function showPending() {
if (pendingBlock) {
pendingBlock.style.display = 'block';
}
if (successBlock) {
successBlock.style.display = 'none';
}
if (successAction) {
successAction.style.display = 'none';
}
}
function showSuccess() {
if (pendingBlock) {
pendingBlock.style.display = 'none';
}
if (successBlock) {
successBlock.style.display = 'block';
}
if (successAction) {
successAction.style.display = 'block';
}
}
if (isConfirmed || !pollUrl) {
showSuccess();
return;
}
showPending();
async function pollStatus() {
attempt++;
try {
var response = await fetch(pollUrl, {
method: 'GET',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
var data = await response.json();
if (data.status === 1) {
if (pendingStatus) {
pendingStatus.textContent = successText;
}
window.clearInterval(pollTimer);
showSuccess();
return;
}
if (data.status === -1 && data.url) {
window.clearInterval(pollTimer);
window.location.href = data.url;
return;
}
if (pendingStatus) {
pendingStatus.textContent = data.msg || pendingText;
}
} catch (e) {
if (pendingStatus) {
pendingStatus.textContent = pendingText;
}
}
if (attempt >= maxAttempts) {
window.clearInterval(pollTimer);
if (pendingStatus) {
pendingStatus.textContent = pendingText;
}
}
}
pollStatus();
pollTimer = window.setInterval(pollStatus, 2000);
})();
</script>
</body>
</html>

View File

@@ -0,0 +1,34 @@
{include file="public/head" /}
<style>
body {
background-color: #f5f5f5;
}
.footer {
position: fixed;
bottom: 0;
}
</style>
<body>
<div class="wrap">
<div class="zh_content">
{include file="public/newnav" /}
</div>
<div class="layui-container">
<div class="container">
<section class="m-form-application-category-container active" style="margin-top: 20px;">
<div class="m-form-application-title">
<h2>{:lang('foot.cookie_policy')}</h2>
</div>
<div class="modular-row callout bg-grey">
<div class="row">
<div class="col-md-12 text-left" style="font-size: 18px">
{:lang('foot.cookie_policy_info')}
</div>
</div>
</div>
</section>
</div>
</div>
</div>
{include file="public/newfooter" /}
</body>

View File

@@ -0,0 +1,38 @@
{include file="public/head" /}
<style>
body {
background: #F8F8F8;
}
.footer {
position: fixed;
bottom: 0;
}
</style>
<body>
<div class="wrap">
<div class="zh_content">
{include file="public/newnav" /}
</div>
<div class="layui-container">
<div class="u-bg-greylight">
<div class="container">
<section class="m-form-application-category-container active" style="margin-top: 20px;">
<div class="m-form-application-title">
<h2>{:lang('foot.disclaimer')}</h2>
</div>
<div class="modular-row callout bg-grey">
<div class="row">
<div class="col-md-12 text-left" style="font-size: 18px">
{:lang('foot.disclaimer_info')}
</div>
</div>
</div>
</section>
</div>
</div>
</div>
</div>
{include file="public/newfooter" /}
</body>

View File

@@ -0,0 +1,37 @@
{include file="public/head" /}
<style>
.text-left h4 {
margin-top: 20px;
}
body {
background-color: #f5f5f5;
}
.footer {
position: fixed;
bottom: 0;
}
</style>
<body>
<div class="wrap">
<div class="zh_content">
{include file="public/newnav" /}
</div>
<div class="layui-container">
<div class="container">
<section class="m-form-application-category-container active" style="margin-top: 20px;">
<div class="m-form-application-title">
<h2>{:lang('foot.refund_policy')}</h2>
</div>
<div class="modular-row callout bg-grey">
<div class="row">
<div class="col-md-12 text-left" style="font-size: 18px">
{:lang('foot.refund_policy_info')}
</div>
</div>
</div>
</section>
</div>
</div>
</div>
{include file="public/newfooter" /}
</body>

View File

@@ -0,0 +1,35 @@
{include file="public/head" /}
<style>
body {
background: #F8F8F8;
}
.section {
padding: 0;
}
</style>
<body>
<div class="wrap">
<div class="zh_content">
{include file="public/newnav" /}
</div>
<div class="layui-container">
<div class="u-bg-greylight">
<div class="container">
<section class="m-form-application-category-container active" style="margin-top: 20px;">
<div class="m-form-application-title">
<h2>{:lang('foot.privacy_policy')}</h2>
</div>
<div class="modular-row callout bg-grey">
<div class="row">
<div class="col-md-12 text-left" style="font-size: 18px">
{:lang('foot.privacy_policy_info')}
</div>
</div>
</div>
</section>
</div>
</div>
</div>
</div>
{include file="public/newfooter" /}
</body>

View File

@@ -0,0 +1,71 @@
{include file="public/head" /}
<style>
.text-left h4 {
margin-top: 20px;
}
body {
background-color: #f5f5f5;
}
.card {
background: #ffffff;
padding: 40px 32px;
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06);
}
h1 {
margin: 0 0 16px;
font-size: 32px;
line-height: 1.3;
color: #111827;
}
.intro {
margin: 0 0 28px;
color: #6b7280;
font-size: 16px;
}
section {
margin-top: 28px;
padding-top: 22px;
border-top: 1px solid #e5e7eb;
}
h2 {
margin: 0 0 12px;
font-size: 22px;
}
p {
margin: 0 0 12px;
}
.sub-list {
margin-top: 8px;
}
.contact a {
color: #0f766e;
text-decoration: none;
}
.contact a:hover {
text-decoration: underline;
}
</style>
<body>
<div class="wrap">
<div class="zh_content">
{include file="public/newnav" /}
</div>
<div class="layui-container">
<div class="container">
<section class="m-form-application-category-container active" style="margin-top: 20px;">
<div class="m-form-application-title">
<h2>{:lang('foot.refund_policy')}</h2>
</div>
<div class="modular-row callout bg-grey">
<div class="row">
<div class="col-md-12 text-left" style="font-size: 18px">
{:lang('foot.refund_policy_info')}
</div>
</div>
</div>
</section>
</div>
</div>
</div>
{include file="public/newfooter" /}
</body>

View File

@@ -0,0 +1,35 @@
{include file="public/head" /}
<style>
.text-left h4 {
margin-bottom: 20px;
}
body {
background: #F8F8F8;
}
</style>
<body>
<div class="wrap">
<div class="zh_content">
{include file="public/newnav" /}
</div>
<div class="layui-container">
<div class="u-bg-greylight">
<div class="container">
<section class="m-form-application-category-container active" style="margin-top: 20px;">
<div class="m-form-application-title">
<h2>{:lang('foot.user_agreement')}</h2>
</div>
<div class="modular-row callout bg-grey">
<div class="row">
<div class="col-md-12 text-left" style="font-size: 18px">
{:lang('foot.user_agreement_info')}
</div>
</div>
</div>
</section>
</div>
</div>
</div>
</div>
{include file="public/newfooter" /}
</body>

View File

@@ -0,0 +1,10 @@
<div class="footer">
<?= html_entity_decode($footer) ?>
<p><a href="#" class="termsCheckbox">{:lang('js.terms_conditions')}</a>&nbsp;|&nbsp;<a href="#" class="privacy_policy">{:lang('js.privacy_policy')}</a></p>
</div>
<style>
.footer a{
color: #ffffff;
}
</style>

View File

@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html lang="" style="height:100%;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{:lang('head.title')}</title>
<meta name="keywords" content="{:lang('head.keywords')}"/>
<meta name="description" content="{:lang('head.description')}"/>
<meta property="og:title" content="{:lang('head.og_title')}"/>
<meta property="og:description" content="{:lang('head.og_description')}"/>
<meta property="og:url" content="{$_SERVER['HTTP_HOST']}"/>
<meta property="og:type" content="website"/>
<link rel="icon" type="image/png" href="/static/image/icon.png">
<link rel="stylesheet" href="/static/layui/css/layui.css">
<script src="/static/layui/layui.js"></script>
<script src="/static/js/jquery.js"></script>
<script>
(function () {
function detectBasePath() {
var pathname = window.location.pathname || '';
var match = pathname.match(/^\/[^\/]+(?=\/home\/|\/static\/|\/json\/|\/$)/);
return match ? match[0] : '';
}
function normalizeBasePath(base) {
base = (base || '').trim();
// 模板变量未渲染时,退回到 URL 推断
if (!base || base === '/' || base.charAt(0) === '{') {
base = detectBasePath();
}
return base.replace(/\/+$/, '');
}
window.__BASE_PATH__ = normalizeBasePath('{$base_path}');
window.withBase = function (url) {
if (!url) {
return url;
}
if (/^(?:[a-z][a-z0-9+\-.]*:)?\/\//i.test(url) || /^[a-z][a-z0-9+\-.]*:/i.test(url)) {
return url;
}
if (url.charAt(0) !== '/') {
return url;
}
var base = window.__BASE_PATH__ || '';
if (!base) {
return url;
}
if (url === base || url.indexOf(base + '/') === 0) {
return url;
}
return base + url;
};
function attachAjaxPrefilter(jq) {
if (!jq || !jq.ajaxPrefilter || jq.__with_base_prefilter_attached__) {
return;
}
jq.__with_base_prefilter_attached__ = true;
jq.ajaxPrefilter(function (options) {
if (options && options.url) {
options.url = window.withBase(options.url);
}
});
}
attachAjaxPrefilter(window.jQuery);
attachAjaxPrefilter(window.$);
// 兼容 layui 可能持有独立 jQuery 实例
if (window.layui && window.layui.$) {
attachAjaxPrefilter(window.layui.$);
}
})();
</script>
<script src="/static/js/pub.js"></script>
<link rel="stylesheet" href="/static/css/tur_main.css?v={:time()}">
<link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link href="/static/bootstrap/css/bootstrap-icons.min.css" rel="stylesheet">
<link href="/static/css/newin.css?v={:time()}" rel="stylesheet">
<script type="text/javascript" async="" src="/static/js/footer.js"></script>
<script type="text/javascript" async="" src="/static/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="/static/js/passport-ocr-sdk.min.js?v=1"></script>
<script>
$(function(){
var footHight=$(".footer").height();
var docHeight=document.documentElement.clientHeight;
var bodyHeight=$("body").height();
var subHeight=docHeight-bodyHeight-footHight;
if(subHeight>30){
$(".footer").css({"position":"fixed","bottom":"0","z-index":"1000"});
$("body").css({"padding-bottom":"142px"});
} else {
$(".footer").css({"position": "static"});
$("body").css({"padding-bottom": "0"});
}
$(".footer").show();
})
</script>
</head>

View File

@@ -0,0 +1,46 @@
{include file="public/head"}
<link rel="stylesheet" href="/static/css/jump.css?v=1">
<body class="jump-page">
<div class="zh_content">
{include file="public/newnav" }
</div>
<main class="jump-shell">
<section class="jump-panel jump-panel--{$type|default='success'}">
<div class="jump-icon" aria-hidden="true"></div>
<div class="jump-content">
<h1 class="jump-message">{$msg}</h1>
<p class="jump-countdown">
<span id="countdown">{$wait|default=3}</span> {:lang('jump.auto_redirect')}...
</p>
</div>
<div class="jump-actions">
<a href="{$url ?: 'javascript:history.back();'}" class="jump-button">{:lang('jump.redirect_now')}</a>
</div>
</section>
</main>
{include file="public/newfooter" }
<script>
// 倒计时显示
let time = {$wait|default=3};
const countdownEl = document.getElementById('countdown');
const targetUrl = "{$url|default=''}";
const timer = setInterval(() => {
time--;
countdownEl.textContent = time;
if (time <= 0) {
clearInterval(timer);
if (targetUrl) {
location.href = targetUrl;
} else {
history.back();
}
}
}, 1000);
</script>
</body>
</html>

View File

@@ -0,0 +1,136 @@
<div class="process" style="background: none;margin-top: 0">
<div class="ps-tit" style="color: #151423; font-weight: 600; font-size: 32px; letter-spacing: .2px;">
{:lang('index.why_choose_us_title')}
<p style="font-size: 15px; padding: 10px;">
{:lang('index.why_choose_us_subtitle')}
</p>
</div>
</div>
<section class="middle-box2">
<!-- <div class="">-->
<!-- <div class="image-box">-->
<!-- <img class="" src="__TMPL__/public/static/image/why-choose-us.webp">-->
<!-- </div>-->
<!-- <h2 class="">为什么选择我们?</h2>-->
<!-- <p class="">了解为什么我们在旅行证件行业处于领先地位,使旅客能够轻松飞行。</p>-->
<!-- <div class="mt30">-->
<!-- <a href="{:url('visa/index')}" tabindex="-1">-->
<!-- <button-->
<!-- class="">-->
<!-- 立即申请-->
<!-- <svg class="wh16" fill="currentColor"-->
<!-- xmlns="http://www.w3.org/2000/svg"-->
<!-- viewBox="0 0 448 512">-->
<!-- <path-->
<!-- d="M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z">-->
<!-- </path>-->
<!-- </svg>-->
<!-- </button>-->
<!-- </a>-->
<!-- </div>-->
<!-- </div>-->
<div class="right-box">
<div
class="item">
<svg class=""
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<mask id="a" width="20" height="20" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha">
<path fill="#D9D9D9" d="M0 0h20v20H0z"></path>
</mask>
<g>
<path fill="currentColor"
d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16Zm-.75 3.75V10c0 .25.125.484.334.625l3 2a.748.748 0 0 0 1.041-.21.748.748 0 0 0-.21-1.04L10.75 9.6V5.75A.748.748 0 0 0 10 5a.748.748 0 0 0-.75.75Z">
</path>
</g>
</svg>
<div class="">
<h6 class="">{:lang('index.convenient')}</h6>
<p class="">{:lang('index.convenient_desc')}</p>
</div>
</div>
<div
class="item">
<svg class=""
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
<path
d="M7 10a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-1.428 1.5A5.57 5.57 0 0 0 0 17.072c0 .512.416.928.928.928h12.144c.056 0 .11-.006.166-.016-2.385-1.722-3.12-4.406-3.222-6.256A5.533 5.533 0 0 0 8.43 11.5h-2.86Zm9.65-2.447-3.75 1.5a.754.754 0 0 0-.472.697c0 1.978.81 5.275 4.213 6.694a.742.742 0 0 0 .578 0C19.19 16.525 20 13.228 20 11.25a.754.754 0 0 0-.472-.697l-3.75-1.5a.744.744 0 0 0-.556 0Zm3.26 2.697c-.123 1.584-.85 3.647-2.982 4.678v-5.872l2.981 1.194Z">
</path>
</svg>
<div class="">
<h6 class="">{:lang('index.secure')}</h6>
<p class="">{:lang('index.secure_desc')}</p>
</div>
</div>
<div
class="item">
<svg class=""
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
<path
d="M1.2 4.8c0-1.324 1.076-2.4 2.4-2.4h6v4.8c0 .664.536 1.2 1.2 1.2h4.8v1.448a6.602 6.602 0 0 0-4.8 6.352 6.6 6.6 0 0 0 2.764 5.374c-.12.018-.24.026-.364.026H3.6a2.402 2.402 0 0 1-2.4-2.4V4.8Zm14.4 2.4h-4.8V2.4l4.8 4.8Zm-3.6 9a5.4 5.4 0 1 1 10.8 0 5.4 5.4 0 0 1-10.8 0Zm7.924-1.624a.602.602 0 0 0-.848 0L16.8 16.852l-1.076-1.076a.602.602 0 0 0-.848 0 .602.602 0 0 0 0 .848l1.5 1.5a.602.602 0 0 0 .848 0l2.7-2.7a.602.602 0 0 0 0-.848Z">
</path>
</svg>
<div class="">
<h6 class="">{:lang('index.approval')}</h6>
<p class="">{:lang('index.approval_desc')}</p>
</div>
</div>
<div
class="item">
<svg class="" width="20"
height="20" viewBox="0 0 20 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path id="Vector"
d="M10 18C12.1217 18 14.1566 17.1571 15.6569 15.6569C17.1571 14.1566 18 12.1217 18 10C18 7.87827 17.1571 5.84344 15.6569 4.34315C14.1566 2.84285 12.1217 2 10 2C7.87827 2 5.84344 2.84285 4.34315 4.34315C2.84285 5.84344 2 7.87827 2 10C2 12.1217 2.84285 14.1566 4.34315 15.6569C5.84344 17.1571 7.87827 18 10 18ZM7.30625 7.16563C7.55312 6.46875 8.21563 6 8.95625 6H10.7781C11.8687 6 12.75 6.88438 12.75 7.97188C12.75 8.67813 12.3719 9.33125 11.7594 9.68437L10.75 10.2625C10.7437 10.6687 10.4094 11 10 11C9.58437 11 9.25 10.6656 9.25 10.25V9.82812C9.25 9.55937 9.39375 9.3125 9.62813 9.17812L11.0125 8.38438C11.1594 8.3 11.25 8.14375 11.25 7.975C11.25 7.7125 11.0375 7.50313 10.7781 7.50313H8.95625C8.85 7.50313 8.75625 7.56875 8.72188 7.66875L8.70937 7.70625C8.57188 8.09688 8.14062 8.3 7.75313 8.1625C7.36563 8.025 7.15938 7.59375 7.29688 7.20625L7.30937 7.16875L7.30625 7.16563ZM9 13C9 12.7348 9.10536 12.4804 9.29289 12.2929C9.48043 12.1054 9.73478 12 10 12C10.2652 12 10.5196 12.1054 10.7071 12.2929C10.8946 12.4804 11 12.7348 11 13C11 13.2652 10.8946 13.5196 10.7071 13.7071C10.5196 13.8946 10.2652 14 10 14C9.73478 14 9.48043 13.8946 9.29289 13.7071C9.10536 13.5196 9 13.2652 9 13Z">
</path>
</svg>
<div class="">
<h6 class="">{:lang('index.support')}</h6>
<p class="">{:lang('index.support_desc')}</p>
</div>
</div>
<div
class="item">
<svg xmlns="http://www.w3.org/2000/svg" class="" viewBox="0 0 512 512" fill="currentColor">
<path d="M258.9 48C141.92 46.42 46.42 141.92 48 258.9c1.56 112.19 92.91 203.54 205.1 205.1 117 1.6 212.48-93.9 210.88-210.88C462.44 140.91 371.09 49.56 258.9 48zm-3.68 152.11c.21-1.2.44-2.4.71-3.59a66.46 66.46 0 0116.29-31.21c12.89-13.73 31.16-21.31 51.45-21.31a74.05 74.05 0 0125.06 4.26 66.69 66.69 0 0126.27 17.2 68.15 68.15 0 0118 42.14 78.46 78.46 0 010 11.4 86.19 86.19 0 01-8.2 31q-.76 1.59-1.59 3.15c-1.11 2.07-2.3 4.1-3.58 6.06a79.47 79.47 0 01-8.63 11c-13.12 14-29.92 21.73-47.31 21.73a59.61 59.61 0 01-19.17-3.18 63.47 63.47 0 01-6.1-2.43 70.76 70.76 0 01-22.07-16.12 83.76 83.76 0 01-22-51.32q-.27-3.88-.18-7.68a75.62 75.62 0 011.05-11.08zm-149.73 24.34a59.87 59.87 0 015.2-20.64 56.76 56.76 0 012.78-5.3 54.49 54.49 0 017.19-9.56 55.62 55.62 0 0114-10.82 56.84 56.84 0 018.11-3.64 63.85 63.85 0 0133.35-2.39 57 57 0 0130.78 17 57.86 57.86 0 0115.41 38.62c.05 2.11 0 4.23-.15 6.38a71.58 71.58 0 01-6 23.84 69.49 69.49 0 01-5.73 10.42 65.39 65.39 0 01-15.76 16.57c-1.5 1.07-3.06 2.07-4.67 3.07a54.21 54.21 0 01-10 4.65 49.31 49.31 0 01-16.2 2.76c-.93 0-1.86 0-2.78-.08a47.6 47.6 0 01-5.48-.62 51.19 51.19 0 01-5.35-1.23 53.54 53.54 0 01-7.72-2.89c-.84-.39-1.66-.8-2.48-1.23-18-9.49-31.57-29.16-34.23-52.12-.12-1.05-.22-2.1-.29-3.16a66.59 66.59 0 01.02-9.63zm53.92 178.6a177.27 177.27 0 01-61.94-70.65 4 4 0 011.62-5.26C117.67 316.69 141.4 311 163.82 311c17 0 30.7 2 42.69 5.88a8 8 0 012.59 13.77c-23.35 19-38.4 42.54-45.47 70.75a2.77 2.77 0 01-4.22 1.65zM256 432a175.12 175.12 0 01-65.7-12.72 4 4 0 01-2.4-4.46c.4-2.05.84-3.92 1.23-5.48 7.12-28.43 24.76-52 51-68.18 23.29-14.35 53-22.25 83.52-22.25 31.16 0 60 7.58 83.48 21.91a2.72 2.72 0 01.91 3.67A176.1 176.1 0 01256 432z"/>
<path d="M161 295.28a47.6 47.6 0 01-5.48-.62 47.6 47.6 0 005.48.62zM134.64 178.13a55.62 55.62 0 00-14 10.82 54.49 54.49 0 00-7.19 9.56 54.49 54.49 0 017.19-9.56 55.62 55.62 0 0114-10.82zM216.17 257.89a71.58 71.58 0 006-23.84c.15-2.15.2-4.27.15-6.38q.08 3.15-.15 6.38a71.58 71.58 0 01-6 23.84zM134.64 178.13a56.84 56.84 0 018.11-3.64 56.84 56.84 0 00-8.11 3.64zM150.21 293.43a53.54 53.54 0 01-7.72-2.89 53.54 53.54 0 007.72 2.89zM105.78 237.19c2.66 23 16.26 42.63 34.23 52.12-18.01-9.49-31.57-29.16-34.23-52.12zM254.34 219a83.76 83.76 0 0022 51.32 70.76 70.76 0 0022.07 16.12 70.76 70.76 0 01-22.07-16.12 83.76 83.76 0 01-22-51.32q-.27-3.88-.18-7.68-.09 3.75.18 7.68zM304.5 288.82a63.47 63.47 0 01-6.1-2.43 63.47 63.47 0 006.1 2.43zM255.93 196.54a66.46 66.46 0 0116.29-31.21 66.46 66.46 0 00-16.29 31.21zM375 165.46a68.15 68.15 0 0118 42.14 68.15 68.15 0 00-18-42.14 66.69 66.69 0 00-26.27-17.2 66.69 66.69 0 0126.27 17.2zM393 219a86.19 86.19 0 01-8.2 31 86.19 86.19 0 008.2-31zM254.16 211.27a75.62 75.62 0 011.06-11.14 75.62 75.62 0 00-1.06 11.14zM383.19 253.16zM206.88 189.05a57.86 57.86 0 0115.41 38.62 57.86 57.86 0 00-15.41-38.62 57 57 0 00-30.78-17 57 57 0 0130.78 17zM190 288a54.21 54.21 0 01-10 4.65 54.21 54.21 0 0010-4.65zM105.49 224.45a59.87 59.87 0 015.2-20.64 59.87 59.87 0 00-5.2 20.64zM194.68 284.88C193.17 286 191.61 287 190 288c1.61-1 3.17-2 4.68-3.12zM216.17 257.89a69.49 69.49 0 01-5.73 10.42 69.49 69.49 0 005.73-10.42zM110.69 203.81a56.76 56.76 0 012.78-5.3 56.76 56.76 0 00-2.78 5.3zM194.68 284.88a65.39 65.39 0 0015.76-16.57 65.39 65.39 0 01-15.76 16.57z"/>
</svg>
<div class="">
<h6 class="">{:lang('index.clients')}</h6>
<p class="">{:lang('index.clients_desc')}</p>
</div>
</div>
<div
class="item">
<svg xmlns="http://www.w3.org/2000/svg" class="" viewBox="0 0 512 512" fill="currentColor">
<path d="M479.07 111.36a16 16 0 00-13.15-14.74c-86.5-15.52-122.61-26.74-203.33-63.2a16 16 0 00-13.18 0C168.69 69.88 132.58 81.1 46.08 96.62a16 16 0 00-13.15 14.74c-3.85 61.11 4.36 118.05 24.43 169.24A349.47 349.47 0 00129 393.11c53.47 56.73 110.24 81.37 121.07 85.73a16 16 0 0012 0c10.83-4.36 67.6-29 121.07-85.73a349.47 349.47 0 0071.5-112.51c20.07-51.19 28.28-108.13 24.43-169.24zm-131 75.11l-110.8 128a16 16 0 01-11.41 5.53h-.66a16 16 0 01-11.2-4.57l-49.2-48.2a16 16 0 1122.4-22.86l37 36.29 99.7-115.13a16 16 0 0124.2 20.94z"/>
</svg>
<div class="">
<h6 class="">{:lang('index.service')}</h6>
<p class="">{:lang('index.service_desc')}</p>
</div>
</div>
<div
class="item">
<svg xmlns="http://www.w3.org/2000/svg" class="" viewBox="0 0 512 512" fill="currentColor">
<path d="M432.8 211.44c-15.52-8.82-34.91-2.28-43.31 13.68l-41.38 84.41a7 7 0 01-8.93 3.43 7 7 0 01-4.41-6.52V72c0-13.91-12.85-24-26.77-24s-26 10.09-26 24v156.64A11.24 11.24 0 01271.21 240 11 11 0 01260 229V24c0-13.91-10.94-24-24.86-24S210 10.09 210 24v204.64A11.24 11.24 0 01199.21 240 11 11 0 01188 229V56c0-13.91-12.08-24-26-24s-26 11.09-26 25v187.64A11.24 11.24 0 01125.21 256 11 11 0 01114 245V120c0-13.91-11.08-24-25-24s-25.12 10.22-25 24v216c0 117.41 72 176 160 176h16c88 0 115.71-39.6 136-88l68.71-169c6.62-18 3.6-34.75-11.91-43.56z"/>
</svg>
<div class="">
<h6 class="">{:lang('index.experience')}</h6>
<p class="">{:lang('index.experience_desc')}</p>
</div>
</div>
<div
class="item">
<svg xmlns="http://www.w3.org/2000/svg" class="" viewBox="0 0 512 512" fill="currentColor">
<path d="M256 448a32 32 0 01-18-5.57c-78.59-53.35-112.62-89.93-131.39-112.8-40-48.75-59.15-98.8-58.61-153C48.63 114.52 98.46 64 159.08 64c44.08 0 74.61 24.83 92.39 45.51a6 6 0 009.06 0C278.31 88.81 308.84 64 352.92 64c60.62 0 110.45 50.52 111.08 112.64.54 54.21-18.63 104.26-58.61 153-18.77 22.87-52.8 59.45-131.39 112.8a32 32 0 01-18 5.56z"/>
</svg>
<div class="">
<h6 class="">{:lang('index.approval_rate')}</h6>
<p class="">{:lang('index.approval_rate_desc')}</p>
</div>
</div>
</div>
</section>

View File

@@ -0,0 +1,284 @@
<style>
.zh_top {
display: flex;
padding-top: 5px;
padding-bottom: 10px;
}
.zh_head {
width: 40%;
justify-content: right;
}
.zh_hcon {
margin: unset;
width: unset;
}
.zh_nav {
width: 50%;
height: 70px;
position: relative;
}
@media (max-width: 1620px) and (min-width: 1201px){
.zh_nav {
width: 68%;
height: 70px;
position: relative;
}
}
@media (max-width: 1200px) {
.language-switcher {
top: 20%;
}
.zh_nav_btn {
display: block;
width: 30px;
height: 30px;
position: absolute;
right: 10px;
top: 20px;
cursor: pointer;
z-index: 1001;
}
.zh_nav {
width: 100%;
position: absolute;
left: 0;
background-color: var(--main-color);
display: none;
z-index: 1001;
}
/* 点击展开时显示 */
.zh_nav.active {
display: block;
}
.nav_con {
display: flex;
flex-direction: column;
width: 100%;
padding: 0;
margin: 0;
}
.nav_con li {
width: 100%;
border-bottom: 1px solid #eee;
list-style: none;
}
.nav_con li a {
display: block;
width: 100%;
text-align: center;
color: #fff;
text-decoration: none;
font-size: 15px;
background-color: var(--main-color);
}
.nav_con li a:hover {
background-color: #f8f8f8;
}
/* 语言切换按钮放在导航底部 */
.nav-language-switcher {
position: unset !important;
width: 100%;
padding: 10px 15px;
background-color: var(--main-color);
display: flex;
justify-content: flex-start;
}
.language-btn {
font-size: 13px;
padding: 5px 10px;
height: auto;
}
.language-dropdown {
position: relative;
width: auto;
border: none;
box-shadow: none;
}
.language-dropdown a {
padding: 8px 10px;
font-size: 13px;
}
}
/* 语言切换按钮容器 */
.language-switcher {
position: absolute;
display: inline-block;
right: 20%;
}
/* 语言切换按钮样式 */
.language-btn {
background-color: #f8f8f8;
border: 1px solid #ddd;
border-radius: 4px;
padding: 5px 10px;
font-size: 14px;
cursor: pointer;
display: flex;
align-items: center;
height: 40px;
}
.language-btn:hover {
background-color: #e8e8e8;
}
/* 下拉菜单样式 */
.language-dropdown {
display: none;
position: absolute;
/*right: 0;*/
top: 100%;
background-color: white;
border: 1px solid #ddd;
border-radius: 4px;
/*width: 100%;*/
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
z-index: 1000;
}
.language-dropdown a {
padding: 5px;
width: 100%;
display: block;
text-decoration: none;
color: #333;
font-size: 14px;
float: unset;
line-height: 40px;
}
.language-dropdown a:hover {
background-color: #f5f5f5;
display: block;
text-decoration: none;
color: #333;
font-size: 14px;
width: 100%;
float: unset;
line-height: 40px;
}
/* 显示下拉菜单 */
.show-dropdown {
display: block;
}
ol, ul, dl {
margin-bottom: 0;
}
.nav_con {
padding: 0;
}
/* ===== 手机端语言切换显示控制 ===== */
@media (max-width: 1200px) {
/* 手机端显示 languageBtn1顶部 */
#language-switcher1 {
display: inline-flex !important;
}
/* 隐藏导航栏中的 languageBtn */
#languageBtn {
display: none !important;
}
}
/* ===== PC端反向控制 ===== */
@media (min-width: 1201px) {
/* PC端隐藏顶部语言切换显示导航栏内的 */
#language-switcher1 {
display: none !important;
}
#languageBtn {
display: inline-flex !important;
}
}
</style>
<div class="zh_top">
<div class="zh_head">
<div class="zh_hcon">
<div class="zh_logo"><a href="/"><img src="/static/image/logo.png" alt=""></a></div>
</div>
</div>
<div class="language-switcher clearfix-language-switcher" id="language-switcher1" style="display:none;">
<button class="language-btn" id="languageBtn1">
<span>{if $think_lang == 'en-us'}English{else/}中文 {/if}</span>
<span style="margin-left: 5px;"></span>
</button>
<div class="language-dropdown" id="languageDropdown1">
<a class="language" href="#" data-id="zh-cn">中文</a>
<a class="language" href="#" data-id="en-us">English</a>
</div>
</div>
<img class="zh_nav_btn" src="/static/image/menu.png" alt="">
<div class="zh_nav">
<ul class="nav_con">
<li class=""><a href="/">{:lang('index.home')}</a></li>
<li class=""><a href="{:url('visa/index')}">{:lang('index.online_application')}</a></li>
<li class=""><a href="{:url('lookup/index')}">{:lang('index.entry_card_query')}</a></li>
<li class=""><a href="{:url('contact/index')}">{:lang('contact.menu_contact')}</a></li>
<li class=""><a href="{:url('news/index')}">{:lang('index.usage_help')}</a></li>
<div class="language-switcher nav-language-switcher">
<button class="language-btn" id="languageBtn">
<span>{if $think_lang == 'en-us'}English{else/}中文 {/if}</span>
<span style="margin-left: 5px;"></span>
</button>
<div class="language-dropdown" id="languageDropdown">
<a class="language" href="#" data-id="zh-cn">中文</a>
<a class="language" href="#" data-id="en-us">English</a>
</div>
</div>
</ul>
</div>
</div>
<script>
$('.zh_nav_btn').click(function () {
$('.zh_nav').toggleClass('active');
});
</script>
<div class="swiper" style="height: 100px;background: var(--main-color)">
</div>
<script>
const languageBtn = document.getElementById('languageBtn');
const languageDropdown = document.getElementById('languageDropdown');
// 切换下拉菜单显示/隐藏
languageBtn.addEventListener('click', function() {
languageDropdown.classList.toggle('show-dropdown');
});
// 点击页面其他地方关闭下拉菜单
document.addEventListener('click', function(e) {
if (!languageBtn.contains(e.target) && !languageDropdown.contains(e.target)) {
languageDropdown.classList.remove('show-dropdown');
}
});
const languageBtn1 = document.getElementById('languageBtn1');
const languageDropdown1 = document.getElementById('languageDropdown1');
// 切换下拉菜单显示/隐藏
languageBtn1.addEventListener('click', function() {
languageDropdown1.classList.toggle('show-dropdown');
});
// 点击页面其他地方关闭下拉菜单
document.addEventListener('click', function(e) {
if (!languageBtn1.contains(e.target) && !languageDropdown1.contains(e.target)) {
languageDropdown1.classList.remove('show-dropdown');
}
});
$('.language').click(function () {
const lang = $(this).attr('data-id');
$.ajax({
url: '/home/index/langset',
type: 'post',
data: {
lang: lang
},
success: function (res) {
if (res.code === 1) {
window.location.reload();
}
}
})
})
</script>

View File

@@ -0,0 +1,103 @@
<footer>
<div class="container">
<div class="text-center">
<?= html_entity_decode($footer) ?>
<div>{if $company_address}{:lang('foot.company_address')}{$company_address}{/if}</div>
</div>
<div class="footer-divider"></div>
<div class="d-flex flex-column flex-md-row justify-content-between align-items-center gap-2">
<div></div>
<!-- <div class="d-flex gap-3">-->
<!-- <a href="/home/policy/user"><span>{:lang('foot.user_agreement')}</span></a>-->
<!-- <a href="/home/policy/privacy"><span>{:lang('foot.privacy_policy')}</span></a>-->
<!-- <a href="/home/policy/disclaimer"><span>{:lang('foot.disclaimer')}</span></a>-->
<!-- <a href="/home/policy/refund"><span>{:lang('foot.refund_policy')}</span></a>-->
<!-- <a href="/home/policy/cookie"><span>{:lang('foot.cookie_policy')}</span></a>-->
<!-- </div>-->
</div>
</div>
</footer>
<!-- ===== 新增:悬浮客服/返回顶部(小模块很实用) ===== -->
<div class="float-help">
<a class="float-btn" href="/home/contact" title="{:lang('contact.menu_contact')}"><i class="bi bi-chat-dots"></i></a>
<a class="float-btn" href="#" title="{:lang('contact.back_to_top')}" onclick="window.scrollTo({top:0,behavior:'smooth'});return false;">
<i class="bi bi-arrow-up"></i>
</a>
</div>
<script>
// 监听复选框点击
$('.termsCheckbox').click(function (e) {
e.preventDefault();
if (window.innerWidth <= 768) {
area = ['90%', '90%']
} else {
area = ['50%', '60%']
}
// 弹出条款内容的弹窗
layer.open({
type: 1, // 弹窗类型:页面层
title: '{:lang(\'js.terms_conditions\')}', content: `
<div style="padding: 20px;">
<h3>{:lang(\'js.terms_conditions\')}</h3>
<p></p><p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.terms_intro\'))}</span></p>
<p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.our_services\'))}</span></p>
<p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.application_process\'))}</span></p>
<p><span style="font-size: 12px;">{:lang(\'js.read_confirmation\')}</span></p>
<p><br></p><p></p>
</div>
`, area: area, // 弹窗大小
btn: ['关闭'], // 按钮
yes: function (index) {
layer.close(index); // 关闭弹窗
}
});
});
$('.privacy_policy').click(function (e) {
e.preventDefault();
if (window.innerWidth <= 768) {
area = ['90%', '90%']
} else {
area = ['50%', '60%']
}
// 弹出条款内容的弹窗
layer.open({
type: 1, // 弹窗类型:页面层
title: '{:lang(\'js.privacy_policy\')}', content: `
<div style="padding: 20px;">
<h3>{:lang(\'js.privacy_policy\')}</h3>
<p></p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.privacy_intro\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">1. {:lang(\'js.scope\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.scope_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">2. {:lang(\'js.information_use\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_use_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">3. {:lang(\'js.information_disclosure\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_disclosure_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">4. {:lang(\'js.information_storage\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_storage_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">5. {:lang(\'js.cookie_use\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.cookie_use_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">6. {:lang(\'js.information_security\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_security_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">7. {:lang(\'js.policy_changes\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.policy_changes_content\')}</p>
<p><br></p><p></p>
</div>
`, area: area, // 弹窗大小
btn: ['关闭'], // 按钮
yes: function (index) {
layer.close(index); // 关闭弹窗
}
});
});
</script>

View File

@@ -0,0 +1,73 @@
<!-- ===== Topbar / Navbar ===== -->
<header class="topbar">
<nav class="navbar navbar-expand-xl">
<div class="container py-2 topbar-inner">
<!-- 顶栏:永远一行 -->
<div class="topbar-head">
<a class="brand-wrap" href="#">
<span class="brand-badge brand-badge-logo"></span>
<span>
<div class="brand-title">{$country}TDAC</div>
<div class="brand-sub">Online Application Service</div>
</span>
</a>
<div class="topbar-right">
<!-- 手机端语言:始终显示,不进折叠菜单 -->
<div class="dropdown lang-mobile d-lg-none">
<button class="btn btn-sm lang-btn dropdown-toggle" data-bs-toggle="dropdown">{if $think_lang == 'en-us'}English{else/}中文 {/if}</button>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item language" data-id="zh-cn" href="#">中文</a></li>
<li><a class="dropdown-item language" data-id="en-us" href="#">English</a></li>
</ul>
</div>
<button class="navbar-toggler d-xl-none text-white border-0" type="button"
data-bs-toggle="collapse" data-bs-target="#nav">
<span class="navbar-toggler-icon" style="filter: invert(1)"></span>
</button>
</div>
</div>
<!-- 折叠菜单:永远在下一行展开 -->
<div class="collapse navbar-collapse" id="nav">
<ul class="navbar-nav ms-auto align-items-lg-center gap-lg-2 mt-2 mt-lg-0">
<li class="nav-item"><a class="nav-link" href="{$base_path}/">{:lang('index.home')}</a></li>
<li class="nav-item"><a class="nav-link" href="{:url('visa/index')}">{:lang('index.online_application')}</a></li>
<li class="nav-item"><a class="nav-link" href="{:url('lookup/index')}">{:lang('index.entry_card_query')}</a></li>
<li class="nav-item"><a class="nav-link" href="{:url('contact/index')}">{:lang('contact.menu_contact')}</a></li>
<li class="nav-item"><a class="nav-link" href="{:url('news/index')}">{:lang('index.usage_help')}</a></li>
<!-- PC 端语言:仍放在菜单里(手机端隐藏避免重复) -->
<li class="nav-item dropdown ms-lg-2 d-none d-lg-block">
<button class="btn btn-sm lang-btn dropdown-toggle" data-bs-toggle="dropdown">{if $think_lang == 'en-us'}English{else/}中文 {/if}</button>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item language" data-id="zh-cn" href="#">中文</a></li>
<li><a class="dropdown-item language" data-id="en-us" href="#">English</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</header>
<script>
$('.language').click(function () {
const lang = $(this).attr('data-id');
$.ajax({
url: '/home/index/langset',
type: 'post',
data: {
lang: lang
},
success: function (res) {
if (res.code === 1) {
window.location.reload();
}
}
})
})
</script>

View File

@@ -0,0 +1,134 @@
{include file="public/head"}
<link rel="stylesheet" href="/static/css/page-sqpay.css?v=1">
<script type="text/javascript" src="https://web.squarecdn.com/v1/square.js"></script>
<script type="text/javascript">
window.applicationId = "{$applicationId}";
window.locationId = "{$locationId}";
window.currency = "{$currency}";
window.country = "{$pay_country}";
window.idempotencyKey = "{$uid}";
</script>
</head>
<body class="sqpay-page">
<div class="sqpay-layout">
{include file="public/newnav"}
<main class="sqpay-main">
<div class="sqpay-shell">
<section class="sqpay-card">
<div class="sqpay-heading">
<h1 class="sqpay-title">{:lang('sqpay.payment_title')}</h1>
<p class="sqpay-order">
{:str_replace('%order_sn%', $order_sn ?? '', lang('pay.order_submitted'))}
</p>
</div>
<div class="sqpay-amount">
<p class="sqpay-amount-label">{:lang('sqpay.total_amount_label')}</p>
<p class="sqpay-amount-value">{$total_fee} {$currency}</p>
</div>
<div class="sqpay-grid">
<section class="sqpay-method">
<header class="sqpay-method-head">
<h2 class="sqpay-method-title">{:lang('sqpay.card_pay_title')}</h2>
<div class="sqpay-brand-list">
<img alt="Visa" src="/static/image/pay/visa.png">
<img alt="Mastercard" src="/static/image/pay/logo_mastercard.png">
<img alt="JCB" src="/static/image/pay/logo_jcb.png">
<img alt="Discover" src="/static/image/pay/logo_discover.png">
<img alt="Diners Club" src="/static/image/pay/logo_diners.png">
<img alt="CB" src="/static/image/pay/logo_cb.png">
<img alt="Amex" src="/static/image/pay/logo_amex.png">
</div>
</header>
<div class="sqpay-method-body">
<form class="payment-form" id="fast-checkout" autocomplete="off">
<div id="card-container"></div>
<button id="card-button" class="sqpay-pay-button" type="button">{:lang('sqpay.pay_now')}</button>
</form>
</div>
</section>
<aside class="sqpay-notice">
<h3 class="sqpay-notice-head">{:lang('sqpay.notice_title')}</h3>
<p class="sqpay-notice-body">{:lang('sqpay.notice_text')}</p>
</aside>
</div>
</section>
</div>
</main>
{include file="public/newfooter"}
</div>
<script>
const order_sn = "{$order_sn}";
const total_price = "{$total_price}";
const paySuccessText = "{:lang('sqpay.pay_success')}";
const payFailedText = "{:lang('sqpay.pay_failed')}";
async function CardPay(fieldEl, buttonEl) {
// Create a card payment object and attach to page
const card = await window.payments.card();
await card.attach(fieldEl);
async function eventHandler(event) {
try {
const result = await card.tokenize();
if (result.status === 'OK') {
window.createPayment(result.token);
}
} catch (e) {
console.log( e.message)
layer.msg(payFailedText, {icon: 2, time: 2000})
layer.closeAll();
}
}
buttonEl.addEventListener('click', eventHandler);
layer.closeAll();
}
async function SquarePaymentFlow() {
var load = layer.load(2, {shade: 0.3})
CardPay(document.getElementById('card-container'), document.getElementById('card-button'));
}
window.payments = Square.payments(window.applicationId, window.locationId);
window.createPayment = async function (token) {
var load = layer.load(2, {shade: 0.3})
const dataJsonString = JSON.stringify({
token,
idempotencyKey: window.idempotencyKey,
order_sn: order_sn,
amount: total_price,
});
try {
const response = await fetch(`{:url('sqpay/paySquare')}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: dataJsonString
});
const data = await response.json();
if (data['code'] == 1) {
// 跳转成功页面
layer.msg(paySuccessText, {icon: 1, time: 2000}, function () {
window.location.href = data.url;
layer.closeAll();
})
} else {
layer.msg(payFailedText, {icon: 2, time: 2000})
layer.closeAll();
}
} catch (error) {
layer.msg(payFailedText, {icon: 2, time: 2000})
layer.closeAll();
}
}
SquarePaymentFlow();
</script>
</body>
</html>

View File

@@ -0,0 +1,242 @@
{include file="public/head" /}
<style>
body.user-page {
min-height: 100vh;
display: flex;
flex-direction: column;
background: #f5f7fb;
}
.user-main {
flex: 1;
padding: 32px 0 52px;
}
.account-layout {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: 18px;
align-items: start;
}
.account-nav,
.account-panel {
background: #fff;
border: 1px solid rgba(15, 23, 42, .08);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(15, 23, 42, .06);
overflow: hidden;
}
.account-nav__title,
.account-panel__title {
background: var(--main-color);
color: #fff;
font-size: 17px;
font-weight: 800;
line-height: 50px;
padding: 0 20px;
}
.account-nav__link {
display: flex;
align-items: center;
gap: 9px;
height: 50px;
padding: 0 18px;
color: #263241;
border-bottom: 1px solid #eef1f5;
text-decoration: none;
font-size: 15px;
}
.account-nav__link:hover,
.account-nav__link.is-active {
color: var(--main-color);
background: rgba(21, 56, 84, .06);
text-decoration: none;
}
.account-panel__body {
padding: 18px;
}
.order-list {
display: grid;
gap: 14px;
}
.order-card {
border: 1px solid #dfe5ee;
border-radius: 8px;
overflow: hidden;
background: #fff;
}
.order-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.order-item {
display: grid;
grid-template-columns: 96px minmax(0, 1fr);
gap: 8px;
padding: 12px 14px;
border-bottom: 1px solid #edf1f5;
color: #334155;
line-height: 1.55;
min-width: 0;
}
.order-item:nth-child(odd) {
border-right: 1px solid #edf1f5;
}
.order-item strong {
color: #0f172a;
font-weight: 700;
white-space: nowrap;
}
.order-item span {
word-break: break-word;
}
.order-actions {
display: flex;
justify-content: flex-end;
gap: 10px;
padding: 12px 14px;
background: #f8fafc;
}
.account-btn {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 92px;
height: 36px;
padding: 0 16px;
border-radius: 4px;
background: var(--main-color);
color: #fff;
text-decoration: none;
font-weight: 700;
}
.account-btn:hover {
color: #fff;
background: #0f2b42;
text-decoration: none;
}
.empty-state {
padding: 52px 20px;
text-align: center;
color: #64748b;
}
.empty-state .account-btn {
margin-top: 16px;
}
@media (max-width: 768px) {
.user-main {
padding: 20px 12px 36px;
}
.account-layout {
grid-template-columns: 1fr;
gap: 12px;
}
.account-nav {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.account-nav__title {
display: none;
}
.account-nav__link {
justify-content: center;
padding: 0 8px;
font-size: 14px;
border-right: 1px solid #eef1f5;
}
.order-grid {
grid-template-columns: 1fr;
}
.order-item {
grid-template-columns: 88px minmax(0, 1fr);
}
.order-item:nth-child(odd) {
border-right: 0;
}
}
</style>
<body class="user-page">
{include file="public/newnav" /}
<main class="user-main">
<div class="layui-container">
<div class="account-layout">
<aside class="account-nav">
<div class="account-nav__title">个人中心</div>
<a href="{:url('user/index')}" class="account-nav__link is-active">
<i class="bi bi-receipt"></i><span>我的订单</span>
</a>
<a href="{:url('user/invoice')}" class="account-nav__link">
<i class="bi bi-file-earmark-text"></i><span>自助开票</span>
</a>
<a href="{:url('visa/index')}" class="account-nav__link">
<i class="bi bi-send"></i><span>签证申请</span>
</a>
</aside>
<section class="account-panel">
<div class="account-panel__title">我的订单</div>
<div class="account-panel__body">
<div class="order-list">
{volist name="order_list" id="vo"}
<article class="order-card">
<div class="order-grid">
<div class="order-item"><strong>订单号</strong><span>{$vo.order_sn}</span></div>
<div class="order-item"><strong>姓名</strong><span>{$vo.last_name} {$vo.first_name}</span></div>
<div class="order-item"><strong>出生日期</strong><span>{$vo.birth_date}</span></div>
<div class="order-item"><strong>护照号</strong><span>{$vo.passport_number}</span></div>
<div class="order-item"><strong>手机号</strong><span>{$vo.phone}</span></div>
<div class="order-item"><strong>下单时间</strong><span>{$vo.reg_time}</span></div>
<div class="order-item"><strong>状态</strong><span>{$vo.order_text}</span></div>
</div>
<div class="order-actions">
{eq name="$vo.pay_status" value="1"}
{eq name="$vo.invoice" value="0"}
<a class="account-btn" href="{:url('invoice/index',array('order_sn'=>$vo['order_sn']))}">开发票</a>
{/eq}
{/eq}
</div>
</article>
{/volist}
</div>
{empty name="order_list"}
<div class="empty-state">
<div>暂无订单记录</div>
<a class="account-btn" href="{:url('visa/index')}">去登记</a>
</div>
{/empty}
</div>
</section>
</div>
</div>
</main>
{include file="public/newfooter" /}
</body>
</html>

View File

@@ -0,0 +1,273 @@
{include file="public/head" /}
<style>
body.user-page {
min-height: 100vh;
display: flex;
flex-direction: column;
background: #f5f7fb;
}
.user-main {
flex: 1;
padding: 32px 0 52px;
}
.account-layout {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: 18px;
align-items: start;
}
.account-nav,
.account-panel {
background: #fff;
border: 1px solid rgba(15, 23, 42, .08);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(15, 23, 42, .06);
overflow: hidden;
}
.account-nav__title,
.account-panel__title {
background: var(--main-color);
color: #fff;
font-size: 17px;
font-weight: 800;
line-height: 50px;
padding: 0 20px;
}
.account-nav__link {
display: flex;
align-items: center;
gap: 9px;
height: 50px;
padding: 0 18px;
color: #263241;
border-bottom: 1px solid #eef1f5;
text-decoration: none;
font-size: 15px;
}
.account-nav__link:hover,
.account-nav__link.is-active {
color: var(--main-color);
background: rgba(21, 56, 84, .06);
text-decoration: none;
}
.account-panel__body {
padding: 22px;
}
.invoice-tip {
margin: 0 0 20px;
padding: 12px 14px;
border: 1px solid rgba(149, 30, 20, .16);
border-radius: 6px;
color: #951e14;
background: rgba(149, 30, 20, .05);
line-height: 1.7;
text-align: center;
}
.invoice-tip a {
color: var(--main-color);
font-weight: 800;
text-decoration: none;
}
.invoice-form .layui-form-label {
display: block;
float: none;
width: auto;
padding: 0 0 7px;
color: #1f2937;
text-align: left;
font-weight: 800;
}
.invoice-form .layui-form-label span {
color: #e53935;
margin-left: 3px;
}
.invoice-form .layui-input-block {
margin-left: 0;
min-height: auto;
}
.invoice-form .layui-input {
height: 50px;
border: 1px solid #d8dee8;
border-radius: 4px;
font-size: 15px;
}
.invoice-form .layui-input:focus {
border-color: var(--main-color) !important;
box-shadow: 0 0 0 3px rgba(21, 56, 84, .08);
}
.invoice-form .layui-btn {
height: 50px;
line-height: 50px;
border-radius: 6px;
background: var(--main-color);
font-size: 17px;
font-weight: 800;
}
@media (max-width: 768px) {
.user-main {
padding: 20px 12px 36px;
}
.account-layout {
grid-template-columns: 1fr;
gap: 12px;
}
.account-nav {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.account-nav__title {
display: none;
}
.account-nav__link {
justify-content: center;
padding: 0 8px;
font-size: 14px;
border-right: 1px solid #eef1f5;
}
.account-panel__body {
padding: 18px;
}
}
</style>
<body class="user-page">
{include file="public/newnav" /}
<main class="user-main">
<div class="layui-container">
<div class="account-layout">
<aside class="account-nav">
<div class="account-nav__title">个人中心</div>
<a href="{:url('user/index')}" class="account-nav__link">
<i class="bi bi-receipt"></i><span>我的订单</span>
</a>
<a href="{:url('user/invoice')}" class="account-nav__link is-active">
<i class="bi bi-file-earmark-text"></i><span>自助开票</span>
</a>
<a href="{:url('user/multiple')}" class="account-nav__link">
<i class="bi bi-files"></i><span>合并开票</span>
</a>
</aside>
<section class="account-panel">
<div class="account-panel__title">自助开票</div>
<div class="account-panel__body">
<p class="invoice-tip">
适用于单个订单开票。多个订单请使用
<a href="{:url('user/multiple')}">合并开票</a>
</p>
<form class="layui-form invoice-form" id="lookupform" name="form1" autocomplete="off">
<div class="layui-row layui-col-space24">
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="passport_number">护照号码<span>*</span></label>
<div class="layui-input-block">
<input type="text" id="passport_number" name="passport_number"
maxlength="9" minlength="9" lay-verify="required"
placeholder="输入护照号码" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="order_sn">订单号<span>*</span></label>
<div class="layui-input-block">
<input type="text" id="order_sn" name="order_sn" lay-verify="required"
placeholder="输入订单号" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="last_name">姓氏<span>*</span></label>
<div class="layui-input-block">
<input type="text" id="last_name" name="last_name" maxlength="45"
lay-verify="required|englishName" placeholder="填写姓氏拼音"
class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="first_name">名字<span>*</span></label>
<div class="layui-input-block">
<input type="text" id="first_name" name="first_name" maxlength="40"
lay-verify="required|englishName" placeholder="填写名字拼音"
class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12">
<button class="layui-btn layui-btn-fluid" lay-submit lay-filter="invoiceSubmit">提交</button>
</div>
</div>
</form>
</div>
</section>
</div>
</div>
</main>
{include file="public/newfooter" /}
<script>
layui.use(function () {
var $ = layui.$;
var form = layui.form;
var layer = layui.layer;
form.verify({
englishName: [/^[A-Za-z]+$/, '请填写英文拼音']
});
form.on('submit(invoiceSubmit)', function () {
var index1;
$.ajax({
type: 'POST',
url: "{:url('user/checkInvoice')}",
data: $('#lookupform').serialize(),
beforeSend: function () {
index1 = layer.load(1, {shade: [0.3, '#fff']});
},
success: function (data) {
layer.close(index1);
if (data.status == 1) {
layer.msg('查询成功');
window.location.href = data.url;
} else {
layer.msg(data.msg);
}
},
error: function () {
layer.close(index1);
layer.msg('请求失败,请稍后重试');
}
});
return false;
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,368 @@
{include file="public/head" /}
<style>
body.login-page {
min-height: 100vh;
display: flex;
flex-direction: column;
background: #f5f7fb;
}
.login-main {
flex: 1;
padding: 42px 0 56px;
}
.login-card {
max-width: 520px;
margin: 0 auto;
background: #fff;
border: 1px solid rgba(15, 23, 42, .08);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(15, 23, 42, .08);
overflow: hidden;
}
.login-card__hd {
background: var(--main-color);
color: #fff;
padding: 18px 24px;
}
.login-card__hd h1 {
margin: 0;
font-size: 22px;
font-weight: 800;
line-height: 1.35;
letter-spacing: 0;
}
.login-card__hd p {
margin: 6px 0 0;
color: rgba(255, 255, 255, .76);
font-size: 13px;
line-height: 1.6;
}
.login-form {
padding: 28px 24px 26px;
}
.login-form .layui-form-item {
margin-bottom: 18px;
}
.login-form .layui-input-wrap {
width: 100%;
}
.login-form .layui-input {
height: 50px;
border: 1px solid #d8dee8;
border-radius: 4px;
font-size: 15px;
}
.login-form .layui-input:focus {
border-color: var(--main-color) !important;
box-shadow: 0 0 0 3px rgba(21, 56, 84, .08);
}
.login-code-row {
display: grid;
grid-template-columns: minmax(0, 1fr) 148px;
gap: 12px;
}
.login-get {
width: 100%;
height: 50px;
line-height: 50px;
padding: 0 12px;
border-radius: 4px;
border-color: var(--main-color);
color: var(--main-color);
background: #fff;
font-weight: 700;
}
.login-get:hover,
.login-get:focus {
border-color: var(--main-color);
color: var(--main-color);
background: rgba(21, 56, 84, .06);
}
.login-get[disabled] {
border-color: #d8dee8 !important;
color: #9aa3af !important;
background: #f6f7f9 !important;
cursor: not-allowed;
}
.login-submit {
height: 50px;
line-height: 50px;
border-radius: 6px;
background: var(--main-color);
border-color: var(--main-color);
font-size: 17px;
font-weight: 800;
}
.login-submit:hover,
.login-submit:focus {
background: #0f2b42;
border-color: #0f2b42;
}
.login-agreement {
margin-top: 2px;
color: #475569;
font-size: 13px;
line-height: 1.7;
}
.login-agreement a {
color: var(--main-color);
font-weight: 700;
text-decoration: none;
}
.login-agreement a:hover {
text-decoration: underline;
}
.layui-form-checked[lay-skin=primary] > i {
border-color: var(--main-color) !important;
background-color: var(--main-color);
color: #fff;
}
.login-terms {
padding: 20px;
max-height: 70vh;
overflow-y: auto;
color: #333;
line-height: 1.8;
}
.login-terms h3 {
margin: 10px 0 8px;
color: var(--main-color);
font-size: 18px;
font-weight: 700;
}
.login-terms p {
margin: 0 0 10px;
font-size: 13px;
}
@media (max-width: 768px) {
.login-main {
padding: 24px 12px 36px;
}
.login-card__hd,
.login-form {
padding-left: 18px;
padding-right: 18px;
}
.login-code-row {
grid-template-columns: 1fr;
gap: 10px;
}
}
</style>
<body class="login-page">
{include file="public/newnav" /}
<main class="login-main">
<div class="layui-container">
<section class="login-card">
<div class="login-card__hd">
<h1>用户登录</h1>
<p>使用手机号验证码登录后,可查看订单进度和已提交的申请信息。</p>
</div>
<form class="layui-form login-form" autocomplete="off">
<div class="layui-form-item">
<div class="login-code-row">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-cellphone"></i>
</div>
<input type="text" name="phone" value="" lay-verify="required|phone"
placeholder="{:lang('visa.phone_placeholder')}"
lay-reqtext="{:lang('visa.phone_placeholder')}" autocomplete="off"
class="layui-input" id="reg-cellphone">
</div>
<input class="login-get layui-btn layui-btn-primary" type="button"
id="getcode" value="获取验证码" lay-on="reg-get-vercode">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-vercode"></i>
</div>
<input type="text" name="vercode" value="" lay-verify="required"
placeholder="{:lang('contact.yzm')}" lay-reqtext="请填写验证码"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item login-agreement">
<input type="checkbox" lay-filter="termsCheckbox" name="agreement" lay-skin="primary"
title="{:lang('visa.terms_acceptance')}" checked
lay-verify="required|checkboxRequired">
</div>
<div class="layui-form-item" style="margin-bottom: 0;">
<button class="layui-btn layui-btn-fluid login-submit" lay-submit lay-filter="demo-reg">登录</button>
</div>
</form>
</section>
</div>
</main>
{include file="public/newfooter" /}
<script>
layui.use(function () {
var $ = layui.$;
var form = layui.form;
var layer = layui.layer;
var util = layui.util;
var wait = 60;
var timer = null;
form.verify({
checkboxRequired: function () {
if (!$('input[name="agreement"]').prop('checked')) {
return '请先阅读并接受《条款与条件》及《隐私政策》';
}
}
});
function getLayerArea() {
return window.innerWidth <= 768 ? ['90%', '90%'] : ['50%', '60%'];
}
function openTermsDialog() {
layer.open({
type: 1,
title: '{:lang(\'js.terms_privacy_title\')}',
area: getLayerArea(),
btn: ['关闭'],
content: `
<div class="login-terms">
<h3>{:lang('js.terms_conditions')}</h3>
<p>{:str_replace('%country%', $country ?? '', lang('js.terms_intro'))}</p>
<p>{:str_replace('%country%', $country ?? '', lang('js.our_services'))}</p>
<p>{:str_replace('%country%', $country ?? '', lang('js.application_process'))}</p>
<p>{:lang('js.read_confirmation')}</p>
<h3>{:lang('js.privacy_policy')}</h3>
<p>{:lang('js.privacy_intro')}</p>
<h3>1. {:lang('js.scope')}</h3>
<p>{:lang('js.scope_content')}</p>
<h3>2. {:lang('js.information_use')}</h3>
<p>{:lang('js.information_use_content')}</p>
<h3>3. {:lang('js.information_disclosure')}</h3>
<p>{:lang('js.information_disclosure_content')}</p>
<h3>4. {:lang('js.information_storage')}</h3>
<p>{:lang('js.information_storage_content')}</p>
<h3>5. {:lang('js.cookie_use')}</h3>
<p>{:lang('js.cookie_use_content')}</p>
<h3>6. {:lang('js.information_security')}</h3>
<p>{:lang('js.information_security_content')}</p>
<h3>7. {:lang('js.policy_changes')}</h3>
<p>{:lang('js.policy_changes_content')}</p>
</div>
`
});
}
form.on('checkbox(termsCheckbox)', function (data) {
if (data.elem.checked) {
openTermsDialog();
}
});
form.on('submit(demo-reg)', function (data) {
if (!data.field.agreement) {
layer.msg('请先阅读并接受《条款与条件》及《隐私政策》', {icon: 2});
return false;
}
$.ajax({
url: '/home/login/login',
type: 'post',
data: data.field,
success: function (res) {
if (res.code == 1) {
layer.msg('登录成功', {icon: 1}, function () {
window.location.href = res.url;
});
} else {
layer.msg(res.msg, {icon: 2});
}
},
error: function () {
layer.msg('请求失败,请稍后重试', {icon: 2});
}
});
return false;
});
function settime() {
var $code = $('#getcode');
if (wait <= 0) {
$code.removeAttr('disabled').val('获取验证码');
wait = 60;
timer = null;
return;
}
$code.prop('disabled', true).val('重新发送 ' + wait + 's');
wait--;
timer = setTimeout(settime, 1000);
}
util.on('lay-on', {
'reg-get-vercode': function () {
var isvalid = form.validate('#reg-cellphone');
if (isvalid) {
$.ajax({
url: '/home/login/login_code',
type: 'POST',
data: {mobile: $('#reg-cellphone').val()},
dataType: 'json',
success: function (data) {
if (data.code == 1) {
if (timer) {
clearTimeout(timer);
}
wait = 60;
settime();
} else {
layer.msg(data.msg, {icon: 2});
}
},
error: function () {
layer.msg('验证码发送失败,请稍后重试', {icon: 2});
}
});
}
}
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,387 @@
{include file="public/head" /}
<style>
body.user-page {
min-height: 100vh;
display: flex;
flex-direction: column;
background: #f5f7fb;
}
.user-main {
flex: 1;
padding: 32px 0 52px;
}
.account-layout {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: 18px;
align-items: start;
}
.account-nav,
.account-panel {
background: #fff;
border: 1px solid rgba(15, 23, 42, .08);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(15, 23, 42, .06);
overflow: hidden;
}
.account-nav__title,
.account-panel__title {
background: var(--main-color);
color: #fff;
font-size: 17px;
font-weight: 800;
line-height: 50px;
padding: 0 20px;
}
.account-nav__link {
display: flex;
align-items: center;
gap: 9px;
height: 50px;
padding: 0 18px;
color: #263241;
border-bottom: 1px solid #eef1f5;
text-decoration: none;
font-size: 15px;
}
.account-nav__link:hover,
.account-nav__link.is-active {
color: var(--main-color);
background: rgba(21, 56, 84, .06);
text-decoration: none;
}
.account-panel__body {
padding: 22px;
}
.invoice-tip {
margin: 0 0 20px;
padding: 12px 14px;
border: 1px solid rgba(149, 30, 20, .16);
border-radius: 6px;
color: #951e14;
background: rgba(149, 30, 20, .05);
line-height: 1.7;
text-align: center;
}
.invoice-tip a {
color: var(--main-color);
font-weight: 800;
text-decoration: none;
}
.invoice-row {
position: relative;
margin-bottom: 16px;
padding: 18px;
border: 1px solid #dfe5ee;
border-radius: 8px;
background: #fff;
}
.invoice-row__actions {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 4px;
}
.invoice-action {
display: inline-flex;
align-items: center;
gap: 5px;
color: var(--main-color);
cursor: pointer;
font-weight: 800;
user-select: none;
}
.invoice-action.is-danger {
color: #951e14;
}
.invoice-form .layui-form-label {
display: block;
float: none;
width: auto;
padding: 0 0 7px;
color: #1f2937;
text-align: left;
font-weight: 800;
}
.invoice-form .layui-form-label span {
color: #e53935;
margin-left: 3px;
}
.invoice-form .layui-input-block {
margin-left: 0;
min-height: auto;
}
.invoice-form .layui-input {
height: 50px;
border: 1px solid #d8dee8;
border-radius: 4px;
font-size: 15px;
}
.invoice-form .layui-input:focus {
border-color: var(--main-color) !important;
box-shadow: 0 0 0 3px rgba(21, 56, 84, .08);
}
.invoice-submit {
height: 50px;
line-height: 50px;
border-radius: 6px;
background: var(--main-color);
font-size: 17px;
font-weight: 800;
}
@media (max-width: 768px) {
.user-main {
padding: 20px 12px 36px;
}
.account-layout {
grid-template-columns: 1fr;
gap: 12px;
}
.account-nav {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.account-nav__title {
display: none;
}
.account-nav__link {
justify-content: center;
padding: 0 8px;
font-size: 14px;
border-right: 1px solid #eef1f5;
}
.account-panel__body {
padding: 18px;
}
}
</style>
<body class="user-page">
{include file="public/newnav" /}
<main class="user-main">
<div class="layui-container">
<div class="account-layout">
<aside class="account-nav">
<div class="account-nav__title">个人中心</div>
<a href="{:url('user/index')}" class="account-nav__link">
<i class="bi bi-receipt"></i><span>我的订单</span>
</a>
<a href="{:url('user/invoice')}" class="account-nav__link">
<i class="bi bi-file-earmark-text"></i><span>自助开票</span>
</a>
<a href="{:url('user/multiple')}" class="account-nav__link is-active">
<i class="bi bi-files"></i><span>合并开票</span>
</a>
</aside>
<section class="account-panel">
<div class="account-panel__title">合并开票</div>
<div class="account-panel__body">
<p class="invoice-tip">
适用于多个订单合并开票。单个订单请使用
<a href="{:url('user/invoice')}">自助开票</a>
</p>
<form class="layui-form invoice-form" id="lookupform" name="form1" autocomplete="off">
<div id="invoiceRows">
<div class="invoice-row">
<div class="layui-row layui-col-space24">
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">护照号码<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="passport_number" maxlength="9" minlength="9"
lay-verify="required" placeholder="输入护照号码" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">订单号<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="order_sn" lay-verify="required"
placeholder="输入订单号" class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">姓氏<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="last_name" maxlength="45"
lay-verify="required|englishName" placeholder="填写姓氏拼音"
class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">名字<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="first_name" maxlength="40"
lay-verify="required|englishName" placeholder="填写名字拼音"
class="layui-input">
</div>
</div>
</div>
</div>
<div class="invoice-row__actions">
<span class="invoice-action js-add-row"><i class="layui-icon layui-icon-add-circle"></i>添加</span>
<span class="invoice-action is-danger js-remove-row"><i class="layui-icon layui-icon-reduce-circle"></i>删除</span>
</div>
</div>
</div>
<button class="layui-btn layui-btn-fluid invoice-submit" lay-submit lay-filter="multipleSubmit">提交</button>
</form>
</div>
</section>
</div>
</div>
</main>
{include file="public/newfooter" /}
<script>
layui.use(function () {
var $ = layui.$;
var form = layui.form;
var layer = layui.layer;
form.verify({
englishName: [/^[A-Za-z]+$/, '请填写英文拼音']
});
function refreshRemoveButtons() {
var $rows = $('#invoiceRows .invoice-row');
$rows.find('.js-remove-row').toggle($rows.length > 1);
}
function getRowData($row) {
return {
passport_number: $.trim($row.find("input[name='passport_number']").val()),
order_sn: $.trim($row.find("input[name='order_sn']").val()),
last_name: $.trim($row.find("input[name='last_name']").val()),
first_name: $.trim($row.find("input[name='first_name']").val())
};
}
function validateRow($row) {
var data = getRowData($row);
if (!data.passport_number) {
layer.msg('请输入护照号');
return false;
}
if (!data.order_sn) {
layer.msg('请输入订单号');
return false;
}
if (!data.last_name) {
layer.msg('请输入姓氏');
return false;
}
if (!data.first_name) {
layer.msg('请输入名字');
return false;
}
if (!/^[A-Za-z]+$/.test(data.last_name) || !/^[A-Za-z]+$/.test(data.first_name)) {
layer.msg('请填写英文拼音');
return false;
}
return true;
}
$(document).on('click', '.js-add-row', function () {
var $row = $(this).closest('.invoice-row');
if (!validateRow($row)) {
return false;
}
var $newRow = $row.clone(false, false);
$newRow.find('input').val('');
$('#invoiceRows').append($newRow);
refreshRemoveButtons();
});
$(document).on('click', '.js-remove-row', function () {
$(this).closest('.invoice-row').remove();
refreshRemoveButtons();
});
form.on('submit(multipleSubmit)', function () {
var datas = [];
var isValid = true;
var index1;
$('#invoiceRows .invoice-row').each(function () {
var $row = $(this);
if (!validateRow($row)) {
isValid = false;
return false;
}
datas.push(getRowData($row));
});
if (!isValid) {
return false;
}
$.ajax({
type: 'POST',
url: "{:url('user/checkMultiple')}",
data: {datas: JSON.stringify(datas)},
beforeSend: function () {
index1 = layer.load(1, {shade: [0.3, '#fff']});
},
success: function (data) {
layer.close(index1);
if (data.status == 1) {
layer.msg('查询成功');
window.location.href = data.url;
} else {
layer.msg(data.msg);
}
},
error: function () {
layer.close(index1);
layer.msg('请求失败,请稍后重试');
}
});
return false;
});
refreshRemoveButtons();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,738 @@
{include file="public/head"}
<link rel="stylesheet" href="/static/css/visa.css?v={:time()}">
<link rel="stylesheet" href="https://files.jzvisa.com/visa/calendar/calendar.min.css"/>
<script src="https://files.jzvisa.com/visa/calendar/calendar.min.js"></script>
<script type="text/javascript" async="" src="/static/js/xm-select.js"></script>
<style>
.confirm-table td {
padding: 8px 12px !important;
vertical-align: middle;
word-break: break-word;
font-size: 16px;
}
.confirm-table tr:nth-child(even) {
background-color: #fafafa;
}
.confirm-table td:first-child {
font-weight: 600;
color: #333;
background-color: #f8f8f8;
width: 40%;
}
.confirm-note {
color: #e53e3e;
font-size: 14px;
margin-top: 12px;
text-align: center;
}
.layui-form-checkbox[lay-skin=primary]>div {
white-space: normal;
word-break: break-word;
word-wrap: break-word;
}
</style>
<body>
<div class="zh_content">
{include file="public/newnav"/}
</div>
<div class="layui-container contact-page">
<ol class="m-steps__classic m-steps__classic--progress">
<li class="current">
<div class="m-steps-textcontainer">1. {:lang('visa.step1_title')}</div>
<span></span>
</li>
<li>
<div class="m-steps-textcontainer">2. {:lang('visa.step2_title')}</div>
<span></span>
</li>
<li>
<div class="m-steps-textcontainer">3. {:lang('visa.step3_title')}</div>
<span></span>
</li>
</ol>
<div class="u-bg-greylight" style="background: #ffffff">
<!-- 第一步 -->
<form class="layui-form" lay-filter="Form1" id="Form1" autocomplete="off">
<div class="m-form-application-title">
<h2>{:lang('visa.personal_details_title')}</h2>
</div>
<div class="layui-row">
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.passport_number')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="passport_number" lay-verify="required|chinaPassport"
placeholder="{:lang('visa.passport_number_placeholder')}"
class="layui-input">
<input type="hidden" name="passport_img" value="">
<!-- 关键:给 file 一个 id并隐藏 -->
<input id="passport_file" class="passport-file" type="file" accept="image/*"
onchange="upload(this,'passport')">
<!-- 关键label 的 for 指向 file 的 id -->
<label class="passport-upload" for="passport_file" title="拍照/上传有效护照照片">
<i class="layui-icon layui-icon-camera"></i>
</label>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.nationality')}<span>*</span></label>
<div class="layui-input-block">
<select lay-search="" name="nation" lay-verify="required">
<option value="">{:lang('visa.nationality_placeholder')}</option>
{volist name="nation" id="vo"}
<option value="{$vo['iso3']}" {$vo['iso3']=='CHN' ?'selected' : ''}>{:cookie('think_var')=='zh-cn' ? $vo['name_zh']: $vo['name_en'] }</option>
{/volist}
</select>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.last_name_en')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="last_name" lay-verify="required|englishOnly"
placeholder="{:lang('visa.last_name_placeholder')}"
class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.first_name_en')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="first_name" lay-verify="required|englishOnly"
placeholder="{:lang('visa.first_name_placeholder')}"
class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="birth_date">{:lang('visa.birth_date')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-date"></i>
</div>
<input type="text" name="birth_date" id="birth_date" lay-verify="required"
placeholder="{:lang('visa.birth_date_placeholder')}"
class="layui-input layui-qian " readonly>
<div class="layui-input-suffix">
<i class="layui-icon layui-icon-down"></i>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label"
for="passport_expiration_date">{:lang('visa.passport_expiry')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-date"></i>
</div>
<input type="text" name="passport_expiration_date" id="passport_expiration_date"
lay-verify="required"
placeholder="{:lang('visa.passport_expiry_placeholder')}"
class="layui-input layui-hou" readonly>
<div class="layui-input-suffix">
<i class="layui-icon layui-icon-down"></i>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="email">{:lang('visa.email_address')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="email"
placeholder="{:lang('visa.email_placeholder')}"
class="layui-input" lay-verify="required|email">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="phone">{:lang('visa.phone_number')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-group">
<!-- 前缀 select -->
<div class="layui-input-group-prepend">
<select name="phone_prefix" lay-search lay-verify="required">
{volist name="phone_prefix" id="vo"}
<option value="{$vo['0']}">{$vo['1']}</option>
{/volist}
</select>
</div>
<input type="text" name="phone"
placeholder="{:lang('visa.phone_placeholder')}"
class="layui-input" lay-verify="required|number">
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label" for="gender">{:lang('visa.gender')}<span>*</span></label>
<div class="layui-input-block">
<input type="radio" name="gender" value="1" title="{:lang('visa.gender_male')}" lay-verify="otherReq"/>
<input type="radio" name="gender" value="2" title="{:lang('visa.gender_female')}" lay-verify="otherReq"/>
</div>
</div>
</div>
</div>
<div class="layui-row text-center">
<div class="layui-col-xs12">
<div class="layui-form-item">
<button class="layui-btn btn-next" lay-submit>{:lang('visa.next_step')}</button>
</div>
</div>
</div>
</form>
<!-- 第二步 -->
<form class="layui-form" lay-filter="Form2" id="Form2" autocomplete="off">
<div class="m-form-application-title">
<h2>{:lang('visa.travel_information_title')}</h2>
</div>
<div class="layui-row">
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.arrive_date')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-date"></i>
</div>
<input type="text" name="arrive_date" lay-verify="required"
placeholder="{:lang('visa.arrive_date_placeholder')}"
class="layui-input layui-arrive" readonly>
<div class="layui-input-suffix">
<i class="layui-icon layui-icon-down"></i>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.leave_date')}<span>*</span></label>
<div class="layui-input-block">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-date"></i>
</div>
<input type="text" name="leave_date" lay-verify="required"
placeholder="{:lang('visa.leave_date_placeholder')}"
class="layui-input layui-leave" readonly>
<div class="layui-input-suffix">
<i class="layui-icon layui-icon-down"></i>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.travel_way')}<span>*</span></label>
<div class="layui-input-block">
<select name="travel_way" lay-verify="required">
<option value="">{:lang('visa.travel_way_placeholder')}</option>
<option value="1">{:lang('visa.by_air')}</option>
<option value="2">{:lang('visa.by_sea')}</option>
<option value="3">{:lang('visa.by_land')}</option>
</select>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.travel_country')}<span>*</span></label>
<div class="layui-input-block">
<select name="travel_country" lay-search lay-verify="required">
<option value="">{:lang('visa.travel_country_placeholder')}</option>
{volist name="travel_country" id="vo"}
<option value="{$vo['value']}">{$vo['text']}</option>
{/volist}
</select>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.travel_number')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="travel_number" lay-verify="required"
placeholder="{:lang('visa.travel_number_placeholder')}"
class="layui-input">
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.hotel_type')}<span>*</span></label>
<div class="layui-input-block">
<select name="hotel_type" lay-verify="required">
<option value="">{:lang('visa.hotel_type_placeholder')}</option>
<option value="01">{:lang('visa.guesthouse')}</option>
<option value="02">{:lang('visa.friend')}</option>
<option value="99">{:lang('visa.other')}</option>
</select>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.hotel_state')}<span>*</span></label>
<div class="layui-input-block">
<select name="hotel_state" lay-search lay-filter="hotel_state_select"
lay-verify="required">
<option value="">{:lang('visa.hotel_state_placeholder')}</option>
<option value="01">JOHOR 柔佛</option>
<option value="02">KEDAH 吉打</option>
<option value="03">KELANTAN 吉兰丹</option>
<option value="04">MELAKA 马六甲</option>
<option value="05">NEGERI SEMBILAN 森美兰</option>
<option value="06">PAHANG 彭亨</option>
<option value="07">PULAU PINANG 槟城</option>
<option value="08">PERAK 霹雳</option>
<option value="09">PERLIS 玻璃市</option>
<option value="10">SELANGOR 雪兰莪</option>
<option value="11">TERENGGANU 登嘉楼</option>
<option value="12">SABAH 沙巴</option>
<option value="13">SARAWAK 砂拉越</option>
<option value="14">WP KUALA LUMPUR 联邦直辖区吉隆坡</option>
<option value="15">WP LABUAN 联邦直辖区纳闽</option>
<option value="16">WP PUTRAJAYA 联邦直辖区布城</option>
</select>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.hotel_city')}<span>*</span></label>
<div class="layui-input-block">
<select name="hotel_city" id="hotel_city" lay-verify="required">
<option value="">{:lang('visa.hotel_city_placeholder')}</option>
</select>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.hotel_address')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="hotel_address" lay-verify="required"
placeholder="{:lang('visa.hotel_address_placeholder')}"
class="layui-input">
<span class="layui-form-mid layui-word-aux">{:lang('visa.copy_hotel')}</span>
</div>
</div>
</div>
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<label class="layui-form-label">{:lang('visa.hotel_zip')}<span>*</span></label>
<div class="layui-input-block">
<input type="text" name="hotel_zip" lay-verify="required"
placeholder="{:lang('visa.hotel_zip_placeholder')}"
class="layui-input">
</div>
</div>
</div>
</div>
<div class="layui-row text-center">
<div class="layui-col-xs12">
<div class="layui-form-item">
<button class="layui-btn btn-next" lay-submit>{:lang('visa.next_step')}</button>
</div>
</div>
</div>
</form>
<!-- <form class="layui-form" lay-filter="Form5" id="Form5" action="" autocomplete="off">-->
<!-- <div class="m-form-application-title">-->
<!-- <h2>附件信息</h2>-->
<!-- </div>-->
<!-- <div class="layui-row">-->
<!-- <div class="layui-col-xs12 layui-col-md12">-->
<!-- <div class="layui-form-item">-->
<!-- <label class="layui-form-label">证件照片<span>*</span></label>-->
<!-- <div class="layui-input-block">-->
<!-- <div class="layui-upload">-->
<!-- <button type="button" class="layui-btn" id="person_img">上传图片</button>-->
<!-- <div class="layui-upload-list">-->
<!-- <img class="layui-upload-img" id="person_img_view">-->
<!-- </div>-->
<!-- </div>-->
<!-- <input type="hidden" name="person_img" lay-verify="required">-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="layui-row text-center">-->
<!-- <div class="layui-col-xs12">-->
<!-- <div class="layui-form-item">-->
<!-- <button class="layui-btn btn-next" lay-submit>下一步</button>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </form>-->
<!-- 提交表单 -->
<form class="layui-form" lay-filter="Form3" id="Form3" action="" autocomplete="off">
<div class="m-form-application-title">
<h2>{:lang('visa.applicant_declaration_title')}</h2>
</div>
<div class="layui-row">
<div class="layui-col-xs12 layui-col-md6">
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="check1" checked lay-verify="required|checkboxRequired"
title="{:lang('visa.declaration_statement')}" value="1">
<input type="checkbox" lay-filter="termsCheckbox" name="check2"
title="{:lang('visa.terms_acceptance')}" value="1" checked
lay-verify="required|checkboxRequired">
</div>
</div>
</div>
</div>
<div class="m-form-application-title" style="background: none;color: #000;">
<h2 style="font-size: 16px">{:lang('visa.select_package_title')}</h2>
</div>
<div class="layui-row">
<div class="layui-col-xs12 layui-col-md12">
<div class="layui-form-item">
{volist name="goods" id="vo" key="k"}
<div class="layui-input-block">
<input type="radio" name="total_price" value="{$vo.value}" title="{$vo.desc}"
{if condition="$vo.is_checked eq 1" }
checked="checked"
{/if}
/>
</div>
{/volist}
</div>
</div>
</div>
<!-- <div class="m-form-application-title" style="background: none;color: #000;">-->
<!-- <h2 style="font-size: 16px">{:lang('visa.select_payment_method')}</h2>-->
<!-- </div>-->
<!-- <div class="layui-row">-->
<!-- <div class="layui-col-xs12 layui-col-md12">-->
<!-- <div class="layui-form-item">-->
<!-- <div class="layui-input-block">-->
<!-- <input type="radio" name="pay_type" value="1"-->
<!-- title="{:lang('visa.wechat_pay')}" checked>-->
<!-- <input type="radio" name="pay_type" value="3" title="{:lang('visa.card')}">-->
<!--&lt;!&ndash; <input type="radio" name="pay_type" value="2" title="{:lang('visa.alipay')}">&ndash;&gt;-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div class="layui-row text-center">
<div class="layui-col-xs12">
<div class="layui-form-item">
<button class="layui-btn" lay-submit lay-filter="formSubmit" id="submit">{:lang('visa.submit_application_button')}
</button>
</div>
</div>
</div>
</form>
</div>
</div>
<div id="confirm" style="display: none">
<table class="layui-table confirm-table">
<colgroup>
<col width="40%">
<col width="60%">
</colgroup>
<tbody>
<tr>
<td>{:lang('visa.confirm_name')}:</td>
<td id="last_name_con"></td>
</tr>
<tr>
<td>{:lang('visa.birth_date')}:</td>
<td id="birth_date_con"></td>
</tr>
<tr>
<td>{:lang('visa.passport_number')}:</td>
<td id="passport_number_con"></td>
</tr>
<tr>
<td>{:lang('visa.passport_expiry')}:</td>
<td id="passport_expiration_date_con"></td>
</tr>
<tr>
<td>{:lang('visa.arrive_date')}:</td>
<td id="arrive_date_con"></td>
</tr>
<tr>
<td>{:lang('visa.leave_date')}:</td>
<td id="leave_date_con"></td>
</tr>
<tr>
<td>{:lang('visa.email_address')}:</td>
<td id="email_con"></td>
</tr>
</tbody>
</table>
<div class="confirm-note">{:lang('visa.verify')}</div>
</div>
{include file="public/newfooter"}
<script>
var lang = {
field_required: "{:lang('js.field_required')}",
alert_message:"{:lang('js.alert_message')}",
notice:"{:lang('js.notice')}",
departure_date_error:"{:lang('js.departure_date_error')}",
failed:"{:lang('js.failed')}",
search_directly:"{:lang('js.search_directly')}",
check_declaration:"{:lang('js.check_declaration')}",
select_one_option:"{:lang('js.select_one_option')}",
choose_package:"{:lang('js.choose_package')}",
english_only:"{:lang('js.english_only')}",
uppercase_only:"{:lang('js.uppercase_only')}",
chinese_only:"{:lang('js.chinese_only')}",
max_100_chars:"{:lang('js.max_100_chars')}",
upload_successful:"{:lang('js.upload_successful')}",
upload_failed:"{:lang('js.upload_failed')}",
upload_error:"{:lang('js.upload_error')}",
verify:"{:lang('js.verify')}",
confirms:"{:lang('js.confirm')}",
edit:"{:lang('js.edit')}",
china_passport_invalid:"{:lang('controller.china_passport_invalid')}",
};
var ocrConfigRaw = '{$ocr_config|default = ''}'.replace(/&quot;/g, '"');
var ocrConfig = {};
var sdk = null;
try {
ocrConfig = ocrConfigRaw ? JSON.parse(ocrConfigRaw) : {};
} catch (e) {
console.error('Failed to parse OCR config', e);
}
if (window.PassportOCRSDK && ocrConfig.base_url && ocrConfig.app_id && ocrConfig.signature && ocrConfig.timestamp) {
try {
sdk = PassportOCRSDK.create({
apiBase: ocrConfig.base_url,
appId: ocrConfig.app_id,
sign: ocrConfig
});
} catch (e) {
console.error('Failed to init OCR sdk', e);
}
}
</script>
<script src="/static/js/mala.js"></script>
<script>
var ismobile = `{$ismobile}`
// 监听复选框点击
form.on('checkbox(termsCheckbox)', function (data) {
var area = [];
if (ismobile == 1) {
area = ['90%', '90%']
} else {
area = ['50%', '60%']
}
if (data.elem.checked) {
// 弹出条款内容的弹窗
layer.open({
type: 1, // 弹窗类型:页面层
title: '{:lang(\'js.terms_privacy_title\')}', content: `
<div style="padding: 20px;">
<h3>{:lang(\'js.terms_conditions\')}</h3>
<p></p><p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.terms_intro\'))}</span></p>
<p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.our_services\'))}</span></p>
<p><span style="font-size: 12px;">{:str_replace(\'%country%\', $country ?? \'\', lang(\'js.application_process\'))}</span></p>
<p><span style="font-size: 12px;">{:lang(\'js.read_confirmation\')}</span></p>
<p><br></p><p></p>
<h3>{:lang(\'js.privacy_policy\')}</h3>
<p></p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.privacy_intro\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">1. {:lang(\'js.scope\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.scope_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">2. {:lang(\'js.information_use\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_use_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">3. {:lang(\'js.information_disclosure\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_disclosure_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">4. {:lang(\'js.information_storage\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_storage_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">5. {:lang(\'js.cookie_use\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.cookie_use_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">6. {:lang(\'js.information_security\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.information_security_content\')}</p>
<h3 style="box-sizing: border-box; margin: 2px 0px; padding: 10px 0px 0px; border: 0px; font-weight: 400; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 18px; line-height: 1.1; color: rgb(0, 48, 73); white-space: normal; background-color: rgb(255, 255, 255);">7. {:lang(\'js.policy_changes\')}</h3>
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; font-size: 12px; color: rgb(51, 51, 51); white-space: normal; background-color: rgb(255, 255, 255);">{:lang(\'js.policy_changes_content\')}</p>
<p><br></p><p></p>
</div>
`, area: area, // 弹窗大小
btn: ['关闭'], // 按钮
yes: function (index) {
layer.close(index); // 关闭弹窗
}
});
}
});
function upload(_this) {
var file = _this.files && _this.files[0];
var loadingIndex = null;
var resetFileInput = function () {
$(_this).val('');
};
var closeLoading = function () {
if (loadingIndex !== null) {
layer.close(loadingIndex);
loadingIndex = null;
}
};
var showError = function (msg) {
closeLoading();
layer.msg(msg || '{:lang("js.manual_entry_required")}', {icon: 5});
};
if (!file) {
layer.msg('{:lang("controller.upload_missing")}', {icon: 5});
return false;
}
if (!/image\/\w+/.test(file.type || '')) {
layer.msg("{:lang('js.upload_image_only')}", {icon: 5});
return false;
}
if (!FileReader) {
layer.msg("{:lang('js.browser_not_supported')}", {icon: 5});
return false;
}
var url = "/home/upload/upload_passport";
loadingIndex = layer.load(3, {shade: [0.1]});
compressImage(file, 0.2, async function (compressedFile) {
try {
if (!compressedFile) {
resetFileInput();
showError('{:lang("js.upload_retry")}');
return false;
}
var ocrWarningMsg = '';
if (sdk) {
try {
var ocr_data = await sdk.recognizePassport(compressedFile, {
auto_rotate: true,
return_debug: false
});
if (ocr_data && ocr_data.code === 1 && ocr_data.data) {
var ocr = ocr_data.data || {};
var pad2 = function (n) {
return String(n || '').padStart(2, '0');
};
var buildDate = function (y, m, d) {
if (!y || !m || !d) return '';
return y + '-' + pad2(m) + '-' + pad2(d);
};
$('input[name="last_name"]').val(ocr.last_name || '');
$('input[name="first_name"]').val(ocr.first_name || '');
$('input[name="passport_number"]').val(ocr.passport_number || '');
$('select[name="nation"]').val(ocr.nationality || '');
if (ocr.gender === 'male' || ocr.gender === 'female') {
var gender = ocr.gender === 'male' ? '1' : '2';
$('input[name="gender"][value="' + gender + '"]').prop('checked', true);
}
var expeditionDate = buildDate(ocr.passport_expedition_date_year, ocr.passport_expedition_date_month, ocr.passport_expedition_date_day);
var expirationDate = buildDate(ocr.passport_expiration_date_year, ocr.passport_expiration_date_month, ocr.passport_expiration_date_day);
var birthDate = buildDate(ocr.birth_date_year, ocr.birth_date_month, ocr.birth_date_day);
if (expeditionDate) $('input[name="passport_expedition_date"]').val(expeditionDate);
if (expirationDate) $('input[name="passport_expiration_date"]').val(expirationDate);
if (birthDate) $('input[name="birth_date"]').val(birthDate);
layui.form.render('radio');
layui.form.render('select');
} else {
ocrWarningMsg = '{:lang("js.manual_entry_required")}';
}
} catch (ocrErr) {
ocrWarningMsg = '{:lang("js.manual_entry_required")}';
}
} else {
ocrWarningMsg = '{:lang("js.manual_entry_required")}';
}
closeLoading();
var formData = new FormData();
formData.append('file', compressedFile);
formData.append('path', 'mala');
$.ajax({
url: url,
type: "post",
data: formData,
dataType: "json",
contentType: false,
processData: false,
mimeType: "multipart/form-data",
success: function (res) {
resetFileInput();
if (res.code == 1) {
$('input[name="passport_img"]').val(res.path);
} else {
//ocrWarningMsg = '{:lang("js.upload_retry")}';
}
},
error: function () {
resetFileInput();
//ocrWarningMsg = '{:lang("js.upload_retry")}';
}
});
if (ocrWarningMsg) {
showError(ocrWarningMsg);
}
} catch (e) {
resetFileInput();
showError('{:lang("js.manual_entry_required")}');
}
});
}
function compressImage(file, quality, callback) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (event) {
const img = new Image();
img.src = event.target.result;
img.onload = function () {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let maxWidth = 1200;
let width = img.width;
let height = img.height;
if (width > maxWidth) {
height *= maxWidth / width;
width = maxWidth;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob(function (blob) {
const newFile = new File([blob], file.name, { type: file.type });
callback(newFile);
}, file.type, quality);
};
};
}
</script>
</body>
</html>

View File

@@ -0,0 +1,79 @@
{include file="public/head"}
<link rel="stylesheet" href="/static/css/wepay.css?v=1">
<body class="wepay-page">
<div class="zh_content">
{include file="public/newnav"}
</div>
<main class="layui-container wepay-shell">
<section class="wepay-card">
<div class="wepay-card__head">
<div>
<p class="wepay-eyebrow">{:lang('wepay.payment_title')}</p>
<h1>{:lang('wepay.order_success_notice')}</h1>
</div>
<img src="/static/image/zf3.png" alt="{:lang('wepay.payment_title')}">
</div>
<div class="wepay-summary">
<div>
<span>{:lang('wepay.order_number')}</span>
<strong>{$order_sn}</strong>
</div>
<div>
<span>{:lang('wepay.amount_due')}</span>
<strong class="wepay-amount">¥{$total_fee}</strong>
</div>
</div>
<div class="wepay-methods">
<div class="wepay-method">
<div class="wepay-method__title">
<img src="/static/image/wx.png" alt="{:lang('wepay.wechat_pay')}">
<span>{:lang('wepay.wechat_pay')}</span>
</div>
<div class="wepay-qr">
<img src="{$url}" alt="{:lang('wepay.wechat_pay')}">
</div>
</div>
<div class="wepay-method">
<div class="wepay-method__title">
<img src="/static/image/zfb.jpg" alt="{:lang('wepay.alipay')}">
<span>{:lang('wepay.alipay')}</span>
</div>
<div class="wepay-qr">
<img src="{$aliurl}" alt="{:lang('wepay.alipay')}">
</div>
</div>
<aside class="wepay-guide">
<img src="/static/image/saoyisao.png" alt="{:lang('wepay.scan_to_pay')}">
<h2>{:lang('wepay.scan_to_pay')}</h2>
<p>{:lang('wepay.scan_notice')}</p>
<div class="wepay-waiting">{:lang('wepay.processing')}</div>
</aside>
</div>
</section>
</main>
{include file="public/newfooter" }
<script>
var interval = setInterval(function () {
layui.$.ajax({
type: "POST",
url: "{:url('wepay/pcresult', ['order_sn' => $order_sn])}",
dataType: "json",
success: function (data) {
if (data.status == 1) {
clearInterval(interval);
location.href = data.url;
}
}
});
}, 1000);
</script>
</body>
</html>

View File

@@ -0,0 +1,154 @@
{include file="public/head"}
<link rel="stylesheet" href="/static/css/wepay.css?v=2">
</head>
<body class="wepay-page">
<div class="zh_content">
{include file="public/newnav" }
</div>
<main
class="container wepay-shell"
id="payment-success-page"
data-payment-confirmed="{$payment_confirmed}"
data-poll-status-url="{$poll_status_url}"
>
<section class="wepay-result-card">
<div id="payment-pending-block" class="payment-pending" style="display: none;">
<div class="wepay-result-icon wepay-result-icon--pending">
<span class="payment-spinner"></span>
</div>
<p class="wepay-eyebrow">{:lang('wepay.payment_title')}</p>
<h1 class="payment-pending-title">{:lang('sqpay.notice_title')}</h1>
<p class="payment-pending-text">{:lang('sqpay.notice_text')}</p>
<p class="payment-pending-order">
{:str_replace('%order_sn%', $order_sn ?? '', lang('pay.order_submitted'))}
</p>
<p class="payment-pending-status" id="payment-pending-status">{:lang('sqpay.notice_text')}</p>
<div class="wepay-actions">
<a class="wepay-button wepay-button--ghost" href="{$repay_url}">{:lang('pay.repay_button')}</a>
</div>
</div>
<div id="payment-success-block" class="wepay-success-detail">
<div class="wepay-result-icon wepay-result-icon--success">&check;</div>
<p class="wepay-eyebrow">{:lang('wepay.payment_success')}</p>
<h1>{:lang('pay.thank_you_message')}</h1>
<p class="wepay-success-order">
{:str_replace('%order_sn%', $order_sn ?? '', lang('pay.order_submitted'))}
</p>
<p class="wepay-success-text">
{:str_replace('%country%', $country ?? '', lang('pay.processing_time_info'))}
</p>
{if $arrive_date_info}
<p class="wepay-success-text">
{$arrive_date_info}
</p>
{/if}
<p class="wepay-contact-text">
{:lang('pay.contact')}
</p>
</div>
<div class="wepay-actions" id="payment-success-action">
<a class="wepay-button" href="{:url('visa/index')}">{:lang('pay.visa_application_button')}</a>
</div>
</section>
</main>
{include file="public/newfooter" }
<script>
(function () {
var pageEl = document.getElementById('payment-success-page');
if (!pageEl) {
return;
}
var isConfirmed = pageEl.getAttribute('data-payment-confirmed') === '1';
var pollUrl = pageEl.getAttribute('data-poll-status-url');
var pendingBlock = document.getElementById('payment-pending-block');
var successBlock = document.getElementById('payment-success-block');
var successAction = document.getElementById('payment-success-action');
var pendingStatus = document.getElementById('payment-pending-status');
var pendingText = "{:lang('sqpay.notice_text')}";
var successText = "{:lang('controller.payment_success')}";
var pollTimer = null;
var maxAttempts = 30;
var attempt = 0;
function showPending() {
if (pendingBlock) {
pendingBlock.style.display = 'block';
}
if (successBlock) {
successBlock.style.display = 'none';
}
if (successAction) {
successAction.style.display = 'none';
}
}
function showSuccess() {
if (pendingBlock) {
pendingBlock.style.display = 'none';
}
if (successBlock) {
successBlock.style.display = 'block';
}
if (successAction) {
successAction.style.display = 'block';
}
}
if (isConfirmed || !pollUrl) {
showSuccess();
return;
}
showPending();
async function pollStatus() {
attempt++;
try {
var response = await fetch(pollUrl, {
method: 'GET',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
var data = await response.json();
if (data.status === 1) {
if (pendingStatus) {
pendingStatus.textContent = successText;
}
window.clearInterval(pollTimer);
showSuccess();
return;
}
if (data.status === -1 && data.url) {
window.clearInterval(pollTimer);
window.location.href = data.url;
return;
}
if (pendingStatus) {
pendingStatus.textContent = data.msg || pendingText;
}
} catch (e) {
if (pendingStatus) {
pendingStatus.textContent = pendingText;
}
}
if (attempt >= maxAttempts) {
window.clearInterval(pollTimer);
if (pendingStatus) {
pendingStatus.textContent = pendingText;
}
}
}
pollStatus();
pollTimer = window.setInterval(pollStatus, 2000);
})();
</script>
</body>
</html>