This commit is contained in:
gaofeng
2026-05-13 10:44:29 +08:00
commit 0b165153c6
3674 changed files with 316663 additions and 0 deletions

View File

@@ -0,0 +1,589 @@
{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', 'thailand');
$.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) {
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>