feat: 改为移动端用户一键签到
This commit is contained in:
@@ -48,37 +48,8 @@
|
||||
text-decoration: none;
|
||||
}
|
||||
.btn.secondary { color: #1f6feb; background: #eaf2ff; }
|
||||
.btn.checkin { background: #14866d; }
|
||||
.empty, .loading, .error { padding: 28px 16px; color: #667085; text-align: center; font-size: 14px; line-height: 1.7; }
|
||||
.error { color: #b42318; }
|
||||
/* 签到弹窗 */
|
||||
.mask { position: fixed; inset: 0; background: rgba(23,32,51,.45); display: none; z-index: 50; }
|
||||
.mask.show { display: block; }
|
||||
.dialog {
|
||||
position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
||||
width: calc(100vw - 56px); max-width: 380px; background: #fff;
|
||||
border-radius: 10px; padding: 18px 16px; z-index: 51; display: none;
|
||||
box-shadow: 0 18px 48px rgba(23,32,51,.22);
|
||||
}
|
||||
.dialog.show { display: block; }
|
||||
.dialog h3 { margin: 0 0 4px; font-size: 17px; }
|
||||
.dialog .sub { margin: 0 0 14px; font-size: 13px; color: #667085; }
|
||||
.field { margin-bottom: 12px; }
|
||||
.field label { display: block; margin-bottom: 6px; font-size: 14px; color: #344054; }
|
||||
.field input {
|
||||
width: 100%; min-height: 42px; padding: 8px 12px; border: 1px solid #d0d5dd;
|
||||
border-radius: 8px; font-size: 15px; background: #fff; box-sizing: border-box;
|
||||
}
|
||||
.field input:focus { outline: none; border-color: #1f6feb; }
|
||||
.dialog-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 4px; }
|
||||
.btn.ghost { color: #475467; background: #f2f4f7; }
|
||||
.toast {
|
||||
position: fixed; left: 50%; top: 24px; transform: translateX(-50%);
|
||||
padding: 10px 16px; border-radius: 8px; font-size: 14px; color: #fff;
|
||||
background: #14866d; z-index: 60; display: none; max-width: 80vw; text-align: center;
|
||||
}
|
||||
.toast.error { background: #b42318; }
|
||||
.toast.show { display: block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -169,7 +140,6 @@
|
||||
'<p>' + escapeHtml(fair.address) + '</p>' +
|
||||
'</section>' +
|
||||
'<div class="actions">' +
|
||||
'<button type="button" class="btn checkin" id="checkinBtn">签到</button>' +
|
||||
'<a class="btn" href="' + escapeHtml(publicBase() + '/h5/outdoor-fair/detail.html?fairId=' + pageFairId) + '">查看招聘会</a>' +
|
||||
'</div>' +
|
||||
'<section class="section">' +
|
||||
@@ -193,87 +163,7 @@
|
||||
(jobs.length ? '<div class="jobs">' + jobs.map(function (job) {
|
||||
return renderJob(job, educationDict, experienceDict);
|
||||
}).join('') + '</div>' : '<div class="empty">暂无岗位</div>') +
|
||||
'</section>' +
|
||||
'<div class="mask" id="checkinMask"></div>' +
|
||||
'<div class="dialog" id="checkinDialog">' +
|
||||
'<h3>签到</h3>' +
|
||||
'<p class="sub">请填写您的姓名和手机号完成签到</p>' +
|
||||
'<div class="field">' +
|
||||
'<label for="checkinName">姓名</label>' +
|
||||
'<input type="text" id="checkinName" placeholder="请输入姓名" autocomplete="name">' +
|
||||
'</div>' +
|
||||
'<div class="field">' +
|
||||
'<label for="checkinPhone">手机号</label>' +
|
||||
'<input type="tel" id="checkinPhone" placeholder="请输入手机号" autocomplete="tel" maxlength="11">' +
|
||||
'</div>' +
|
||||
'<div class="dialog-actions">' +
|
||||
'<button type="button" class="btn ghost" id="checkinCancel">取消</button>' +
|
||||
'<button type="button" class="btn checkin" id="checkinSubmit">提交签到</button>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="toast" id="checkinToast"></div>';
|
||||
bindCheckIn();
|
||||
}
|
||||
|
||||
function showToast(msg, isError) {
|
||||
var toast = document.getElementById('checkinToast');
|
||||
if (!toast) return;
|
||||
toast.textContent = msg;
|
||||
toast.className = 'toast show' + (isError ? ' error' : '');
|
||||
setTimeout(function () { toast.className = 'toast' + (isError ? ' error' : ''); }, 2400);
|
||||
}
|
||||
|
||||
function openCheckIn() {
|
||||
var mask = document.getElementById('checkinMask');
|
||||
var dialog = document.getElementById('checkinDialog');
|
||||
if (mask && dialog) {
|
||||
mask.className = 'mask show';
|
||||
dialog.className = 'dialog show';
|
||||
}
|
||||
}
|
||||
|
||||
function closeCheckIn() {
|
||||
var mask = document.getElementById('checkinMask');
|
||||
var dialog = document.getElementById('checkinDialog');
|
||||
if (mask) mask.className = 'mask';
|
||||
if (dialog) dialog.className = 'dialog';
|
||||
}
|
||||
|
||||
function bindCheckIn() {
|
||||
var openBtn = document.getElementById('checkinBtn');
|
||||
var cancelBtn = document.getElementById('checkinCancel');
|
||||
var mask = document.getElementById('checkinMask');
|
||||
var submitBtn = document.getElementById('checkinSubmit');
|
||||
if (openBtn) openBtn.onclick = openCheckIn;
|
||||
if (cancelBtn) cancelBtn.onclick = closeCheckIn;
|
||||
if (mask) mask.onclick = closeCheckIn;
|
||||
if (submitBtn) submitBtn.onclick = submitCheckIn;
|
||||
}
|
||||
|
||||
function submitCheckIn() {
|
||||
var name = (document.getElementById('checkinName') || {}).value;
|
||||
var phone = (document.getElementById('checkinPhone') || {}).value;
|
||||
if (!name || !name.trim()) { showToast('请输入姓名', true); return; }
|
||||
if (!phone || !/^\d{11}$/.test(phone.trim())) { showToast('请输入正确的11位手机号', true); return; }
|
||||
if (!pageFairId) { showToast('缺少招聘会信息', true); return; }
|
||||
var submitBtn = document.getElementById('checkinSubmit');
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
fetch(apiBase() + '/app/outdoor-fair/check-in', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ fairId: Number(pageFairId), name: name.trim(), phone: phone.trim() })
|
||||
}).then(function (res) { return res.json(); }).then(function (body) {
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
if (body && body.code === 200) {
|
||||
closeCheckIn();
|
||||
showToast('签到成功');
|
||||
} else {
|
||||
showToast((body && body.msg) || '签到失败', true);
|
||||
}
|
||||
}).catch(function () {
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
showToast('网络异常,请重试', true);
|
||||
});
|
||||
'</section>';
|
||||
}
|
||||
|
||||
function renderJob(job, educationDict, experienceDict) {
|
||||
|
||||
@@ -31,41 +31,11 @@
|
||||
.photo { width: 100%; margin-top: 14px; border-radius: 8px; object-fit: cover; }
|
||||
.loading, .error { padding: 28px 16px; color: #667085; text-align: center; font-size: 14px; line-height: 1.7; }
|
||||
.error { color: #b42318; }
|
||||
.actions { display: grid; grid-template-columns: 1fr; gap: 10px; margin-top: 14px; }
|
||||
.btn {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
min-height: 44px; padding: 10px 14px; color: #fff; background: #1f6feb;
|
||||
border: 0; border-radius: 8px; font-size: 15px; text-decoration: none; width: 100%;
|
||||
}
|
||||
.btn.checkin { background: #14866d; }
|
||||
/* 签到弹窗 */
|
||||
.mask { position: fixed; inset: 0; background: rgba(23,32,51,.45); display: none; z-index: 50; }
|
||||
.mask.show { display: block; }
|
||||
.dialog {
|
||||
position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
||||
width: calc(100vw - 56px); max-width: 380px; background: #fff;
|
||||
border-radius: 10px; padding: 18px 16px; z-index: 51; display: none;
|
||||
box-shadow: 0 18px 48px rgba(23,32,51,.22);
|
||||
}
|
||||
.dialog.show { display: block; }
|
||||
.dialog h3 { margin: 0 0 4px; font-size: 17px; }
|
||||
.dialog .sub { margin: 0 0 14px; font-size: 13px; color: #667085; }
|
||||
.field { margin-bottom: 12px; }
|
||||
.field label { display: block; margin-bottom: 6px; font-size: 14px; color: #344054; }
|
||||
.field input {
|
||||
width: 100%; min-height: 42px; padding: 8px 12px; border: 1px solid #d0d5dd;
|
||||
border-radius: 8px; font-size: 15px; background: #fff; box-sizing: border-box;
|
||||
}
|
||||
.field input:focus { outline: none; border-color: #1f6feb; }
|
||||
.dialog-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 4px; }
|
||||
.btn.ghost { color: #475467; background: #f2f4f7; }
|
||||
.toast {
|
||||
position: fixed; left: 50%; top: 24px; transform: translateX(-50%);
|
||||
padding: 10px 16px; border-radius: 8px; font-size: 14px; color: #fff;
|
||||
background: #14866d; z-index: 60; display: none; max-width: 80vw; text-align: center;
|
||||
}
|
||||
.toast.error { background: #b42318; }
|
||||
.toast.show { display: block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -76,7 +46,6 @@
|
||||
(function () {
|
||||
var app = document.getElementById('app');
|
||||
var fairId = new URLSearchParams(window.location.search).get('fairId');
|
||||
var pageFairId = null;
|
||||
|
||||
function text(value) {
|
||||
return value === null || value === undefined || value === '' ? '暂无' : String(value);
|
||||
@@ -103,7 +72,6 @@
|
||||
|
||||
function render(data) {
|
||||
var fair = data.fair || {};
|
||||
pageFairId = (fair.id !== null && fair.id !== undefined) ? fair.id : fairId;
|
||||
document.title = text(fair.title);
|
||||
app.innerHTML =
|
||||
'<section class="hero">' +
|
||||
@@ -111,9 +79,6 @@
|
||||
'<p>' + escapeHtml(fair.hostUnit) + '</p>' +
|
||||
'<p>' + escapeHtml(fair.address) + '</p>' +
|
||||
'</section>' +
|
||||
'<div class="actions">' +
|
||||
'<button type="button" class="btn checkin" id="checkinBtn">签到</button>' +
|
||||
'</div>' +
|
||||
'<section class="section">' +
|
||||
'<h2>招聘会信息</h2>' +
|
||||
'<div class="meta">' +
|
||||
@@ -125,80 +90,7 @@
|
||||
'<div><span>展位数量</span><span>' + escapeHtml(fair.boothCount) + '</span></div>' +
|
||||
'</div>' +
|
||||
(fair.photoUrl ? '<img class="photo" src="' + escapeHtml(fair.photoUrl) + '" alt="招聘会照片">' : '') +
|
||||
'</section>' +
|
||||
'<div class="mask" id="checkinMask"></div>' +
|
||||
'<div class="dialog" id="checkinDialog">' +
|
||||
'<h3>签到</h3>' +
|
||||
'<p class="sub">请填写您的姓名和手机号完成签到</p>' +
|
||||
'<div class="field">' +
|
||||
'<label for="checkinName">姓名</label>' +
|
||||
'<input type="text" id="checkinName" placeholder="请输入姓名" autocomplete="name">' +
|
||||
'</div>' +
|
||||
'<div class="field">' +
|
||||
'<label for="checkinPhone">手机号</label>' +
|
||||
'<input type="tel" id="checkinPhone" placeholder="请输入手机号" autocomplete="tel" maxlength="11">' +
|
||||
'</div>' +
|
||||
'<div class="dialog-actions">' +
|
||||
'<button type="button" class="btn ghost" id="checkinCancel">取消</button>' +
|
||||
'<button type="button" class="btn checkin" id="checkinSubmit">提交签到</button>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="toast" id="checkinToast"></div>';
|
||||
bindCheckIn();
|
||||
}
|
||||
|
||||
function showToast(msg, isError) {
|
||||
var toast = document.getElementById('checkinToast');
|
||||
if (!toast) return;
|
||||
toast.textContent = msg;
|
||||
toast.className = 'toast show' + (isError ? ' error' : '');
|
||||
setTimeout(function () { toast.className = 'toast' + (isError ? ' error' : ''); }, 2400);
|
||||
}
|
||||
|
||||
function openCheckIn() {
|
||||
var mask = document.getElementById('checkinMask');
|
||||
var dialog = document.getElementById('checkinDialog');
|
||||
if (mask && dialog) { mask.className = 'mask show'; dialog.className = 'dialog show'; }
|
||||
}
|
||||
|
||||
function closeCheckIn() {
|
||||
var mask = document.getElementById('checkinMask');
|
||||
var dialog = document.getElementById('checkinDialog');
|
||||
if (mask) mask.className = 'mask';
|
||||
if (dialog) dialog.className = 'dialog';
|
||||
}
|
||||
|
||||
function bindCheckIn() {
|
||||
var openBtn = document.getElementById('checkinBtn');
|
||||
var cancelBtn = document.getElementById('checkinCancel');
|
||||
var mask = document.getElementById('checkinMask');
|
||||
var submitBtn = document.getElementById('checkinSubmit');
|
||||
if (openBtn) openBtn.onclick = openCheckIn;
|
||||
if (cancelBtn) cancelBtn.onclick = closeCheckIn;
|
||||
if (mask) mask.onclick = closeCheckIn;
|
||||
if (submitBtn) submitBtn.onclick = submitCheckIn;
|
||||
}
|
||||
|
||||
function submitCheckIn() {
|
||||
var name = (document.getElementById('checkinName') || {}).value;
|
||||
var phone = (document.getElementById('checkinPhone') || {}).value;
|
||||
if (!name || !name.trim()) { showToast('请输入姓名', true); return; }
|
||||
if (!phone || !/^\d{11}$/.test(phone.trim())) { showToast('请输入正确的11位手机号', true); return; }
|
||||
if (!pageFairId) { showToast('缺少招聘会信息', true); return; }
|
||||
var submitBtn = document.getElementById('checkinSubmit');
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
fetch(apiBase() + '/app/outdoor-fair/check-in', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ fairId: Number(pageFairId), name: name.trim(), phone: phone.trim() })
|
||||
}).then(function (res) { return res.json(); }).then(function (body) {
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
if (body && body.code === 200) { closeCheckIn(); showToast('签到成功'); }
|
||||
else { showToast((body && body.msg) || '签到失败', true); }
|
||||
}).catch(function () {
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
showToast('网络异常,请重试', true);
|
||||
});
|
||||
'</section>';
|
||||
}
|
||||
|
||||
if (!fairId) {
|
||||
|
||||
Reference in New Issue
Block a user