fix(Task1): seat展示截断 + 短码改名核销码 + barcode渲染函数化
- WalletService: 移除 getUserTickets() 中重复的 seat_number 字段 - ticket_card.html (PHP模板): - renderTickets(): seat_info → seat_number - 短码标签: 短码 → 核销码 - showTicketBasic/Detail: seat_info → seat_number, 标签改名, canvas条码 - 新增 renderBarcode() 独立函数 - 清理 showTicketDetail/loadQrPayload/refreshQr 中的 inline try-catch JsBarcode - ticket_card.js (静态JS): 同上修复, 同步跟上 PHP 模板的改动 - renderBarcode() 在 refreshQr 中调用feat/phase-b-verification
parent
29f4c61110
commit
4c04b094e2
|
|
@ -96,7 +96,6 @@ class WalletService extends BaseService
|
||||||
'verify_status' => $ticket['verify_status'],
|
'verify_status' => $ticket['verify_status'],
|
||||||
'issued_at' => $ticket['issued_at'],
|
'issued_at' => $ticket['issued_at'],
|
||||||
'short_code' => $shortCode,
|
'short_code' => $shortCode,
|
||||||
'seat_number' => self::parseSeatNumber($ticket['seat_info'] ?? ''),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="vr-ticket-footer">
|
<div class="vr-ticket-footer">
|
||||||
<div class="vr-ticket-short-code">短码: {{short_code}}</div>
|
<div class="vr-ticket-short-code">核销码: {{short_code}}</div>
|
||||||
<a href="javascript:;" class="vr-ticket-view-btn" onclick="VrTicketWallet.viewTicket({{id}})">查看票码 →</a>
|
<a href="javascript:;" class="vr-ticket-view-btn" onclick="VrTicketWallet.viewTicket({{id}})">查看票码 →</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -366,11 +366,11 @@ var VrTicketWallet = (function() {
|
||||||
'<div class="vr-ticket-info">' +
|
'<div class="vr-ticket-info">' +
|
||||||
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">📅</span><span>' + escapeHtml(ticket.session_time) + '</span></div>' +
|
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">📅</span><span>' + escapeHtml(ticket.session_time) + '</span></div>' +
|
||||||
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">📍</span><span>' + escapeHtml(ticket.venue_name) + '</span></div>' +
|
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">📍</span><span>' + escapeHtml(ticket.venue_name) + '</span></div>' +
|
||||||
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">💺</span><span>' + escapeHtml(ticket.seat_info) + '</span></div>' +
|
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">💺</span><span>' + escapeHtml(ticket.seat_number) + '</span></div>' +
|
||||||
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">👤</span><span>' + escapeHtml(ticket.real_name) + ' ' + escapeHtml(ticket.phone) + '</span></div>' +
|
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">👤</span><span>' + escapeHtml(ticket.real_name) + ' ' + escapeHtml(ticket.phone) + '</span></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-footer">' +
|
'<div class="vr-ticket-footer">' +
|
||||||
'<div class="vr-ticket-short-code">短码: ' + escapeHtml(ticket.short_code) + '</div>' +
|
'<div class="vr-ticket-short-code">核销码: ' + escapeHtml(ticket.short_code) + '</div>' +
|
||||||
'<a href="javascript:;" class="vr-ticket-view-btn" onclick="VrTicketWallet.viewTicket(' + ticket.id + ')">查看票码 →</a>' +
|
'<a href="javascript:;" class="vr-ticket-view-btn" onclick="VrTicketWallet.viewTicket(' + ticket.id + ')">查看票码 →</a>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
@ -434,7 +434,7 @@ var VrTicketWallet = (function() {
|
||||||
'<div class="vr-ticket-qr-expire" id="vrQrExpire"></div>' +
|
'<div class="vr-ticket-qr-expire" id="vrQrExpire"></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-short-code-display">' +
|
'<div class="vr-ticket-short-code-display">' +
|
||||||
'<div class="vr-ticket-short-code-label">短码(人工核销)</div>' +
|
'<div class="vr-ticket-short-code-label">核销码</div>' +
|
||||||
'<div class="vr-ticket-short-code-value">' + escapeHtml(ticket.short_code) + '</div>' +
|
'<div class="vr-ticket-short-code-value">' + escapeHtml(ticket.short_code) + '</div>' +
|
||||||
'<canvas id="vrBarcodeCanvas" style="margin-top:8px;max-width:100%;display:block;"></canvas>' +
|
'<canvas id="vrBarcodeCanvas" style="margin-top:8px;max-width:100%;display:block;"></canvas>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
|
|
@ -459,6 +459,7 @@ var VrTicketWallet = (function() {
|
||||||
'<div class="vr-ticket-detail-value">' + escapeHtml(ticket.real_name) + ' ' + escapeHtml(ticket.phone) + '</div>' +
|
'<div class="vr-ticket-detail-value">' + escapeHtml(ticket.real_name) + ' ' + escapeHtml(ticket.phone) + '</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<button class="vr-ticket-refresh-btn" id="vrRefreshBtn" onclick="VrTicketWallet.refreshQr(' + ticket.id + ')">刷新二维码</button>';
|
'<button class="vr-ticket-refresh-btn" id="vrRefreshBtn" onclick="VrTicketWallet.refreshQr(' + ticket.id + ')">刷新二维码</button>';
|
||||||
|
renderBarcode(ticket.short_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -484,7 +485,7 @@ var VrTicketWallet = (function() {
|
||||||
'<div class="vr-ticket-qr-expire" id="vrQrExpire"></div>' +
|
'<div class="vr-ticket-qr-expire" id="vrQrExpire"></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-short-code-display">' +
|
'<div class="vr-ticket-short-code-display">' +
|
||||||
'<div class="vr-ticket-short-code-label">短码(人工核销)</div>' +
|
'<div class="vr-ticket-short-code-label">核销码</div>' +
|
||||||
'<div class="vr-ticket-short-code-value">' + escapeHtml(ticket.short_code) + '</div>' +
|
'<div class="vr-ticket-short-code-value">' + escapeHtml(ticket.short_code) + '</div>' +
|
||||||
'<canvas id="vrBarcodeCanvas" style="margin-top:8px;max-width:100%;display:block;"></canvas>' +
|
'<canvas id="vrBarcodeCanvas" style="margin-top:8px;max-width:100%;display:block;"></canvas>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
|
|
@ -510,7 +511,7 @@ var VrTicketWallet = (function() {
|
||||||
// 渲染 QR 码
|
// 渲染 QR 码
|
||||||
if (ticket.qr_payload) {
|
if (ticket.qr_payload) {
|
||||||
renderQrCode(ticket.qr_payload, ticket.qr_expires_in);
|
renderQrCode(ticket.qr_payload, ticket.qr_expires_in);
|
||||||
try { var bc = document.getElementById('vrBarcodeCanvas'); if (bc && ticket.short_code) { JsBarcode(bc, ticket.short_code, {format:'CODE128', width:2, height:60, displayValue:true, fontSize:14, margin:5}); } } catch(e){}
|
renderBarcode(ticket.short_code);
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('vrQrcodeBox').innerHTML = '<div style="color:#999;">QR加载中...</div>';
|
document.getElementById('vrQrcodeBox').innerHTML = '<div style="color:#999;">QR加载中...</div>';
|
||||||
}
|
}
|
||||||
|
|
@ -558,7 +559,7 @@ var VrTicketWallet = (function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
renderQrCode(ticket.qr_payload, expiresIn);
|
renderQrCode(ticket.qr_payload, expiresIn);
|
||||||
try { var bc = document.getElementById('vrBarcodeCanvas'); if (bc && ticket.short_code) { JsBarcode(bc, ticket.short_code, {format:'CODE128', width:2, height:60, displayValue:true, fontSize:14, margin:5}); } } catch(e){}
|
// barcode 由 showTicketBasic/showTicketDetail 单独调用
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function() {
|
||||||
|
|
@ -597,6 +598,27 @@ var VrTicketWallet = (function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染条形码(CODE128)
|
||||||
|
* @param {string} shortCode - 核销码
|
||||||
|
*/
|
||||||
|
function renderBarcode(shortCode) {
|
||||||
|
try {
|
||||||
|
var canvas = document.getElementById('vrBarcodeCanvas');
|
||||||
|
if (!canvas || !shortCode) return;
|
||||||
|
JsBarcode(canvas, shortCode, {
|
||||||
|
format: 'CODE128',
|
||||||
|
width: 2,
|
||||||
|
height: 60,
|
||||||
|
displayValue: true,
|
||||||
|
fontSize: 14,
|
||||||
|
margin: 5
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Barcode render failed:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新 QR
|
* 刷新 QR
|
||||||
*/
|
*/
|
||||||
|
|
@ -626,7 +648,7 @@ var VrTicketWallet = (function() {
|
||||||
|
|
||||||
// 重新渲染 QR
|
// 重新渲染 QR
|
||||||
renderQrCode(ticket.qr_payload, ticket.qr_expires_in);
|
renderQrCode(ticket.qr_payload, ticket.qr_expires_in);
|
||||||
try { var bc = document.getElementById('vrBarcodeCanvas'); if (bc && ticket.short_code) { JsBarcode(bc, ticket.short_code, {format:'CODE128', width:2, height:60, displayValue:true, fontSize:14, margin:5}); } } catch(e){}
|
renderBarcode(ticket.short_code);
|
||||||
|
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.textContent = '已刷新';
|
btn.textContent = '已刷新';
|
||||||
|
|
|
||||||
|
|
@ -98,11 +98,11 @@ var VrTicketWallet = (function() {
|
||||||
'<div class="vr-ticket-info">' +
|
'<div class="vr-ticket-info">' +
|
||||||
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">📅</span><span>' + escapeHtml(ticket.session_time) + '</span></div>' +
|
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">📅</span><span>' + escapeHtml(ticket.session_time) + '</span></div>' +
|
||||||
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">📍</span><span>' + escapeHtml(ticket.venue_name) + '</span></div>' +
|
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">📍</span><span>' + escapeHtml(ticket.venue_name) + '</span></div>' +
|
||||||
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">💺</span><span>' + escapeHtml(ticket.seat_info) + '</span></div>' +
|
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">💺</span><span>' + escapeHtml(ticket.seat_number) + '</span></div>' +
|
||||||
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">👤</span><span>' + escapeHtml(ticket.real_name) + ' ' + escapeHtml(ticket.phone) + '</span></div>' +
|
'<div class="vr-ticket-info-row"><span class="vr-ticket-info-icon">👤</span><span>' + escapeHtml(ticket.real_name) + ' ' + escapeHtml(ticket.phone) + '</span></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-footer">' +
|
'<div class="vr-ticket-footer">' +
|
||||||
'<div class="vr-ticket-short-code">短码: ' + escapeHtml(ticket.short_code) + '</div>' +
|
'<div class="vr-ticket-short-code">核销码: ' + escapeHtml(ticket.short_code) + '</div>' +
|
||||||
'<a href="javascript:;" class="vr-ticket-view-btn" onclick="VrTicketWallet.viewTicket(' + ticket.id + ')">查看票码 →</a>' +
|
'<a href="javascript:;" class="vr-ticket-view-btn" onclick="VrTicketWallet.viewTicket(' + ticket.id + ')">查看票码 →</a>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
@ -170,8 +170,9 @@ var VrTicketWallet = (function() {
|
||||||
'<div class="vr-ticket-qr-expire" id="vrQrExpire"></div>' +
|
'<div class="vr-ticket-qr-expire" id="vrQrExpire"></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-short-code-display">' +
|
'<div class="vr-ticket-short-code-display">' +
|
||||||
'<div class="vr-ticket-short-code-label">短码(人工核销)</div>' +
|
'<div class="vr-ticket-short-code-label">核销码</div>' +
|
||||||
'<div class="vr-ticket-short-code-value">' + escapeHtml(ticket.short_code) + '</div>' +
|
'<div class="vr-ticket-short-code-value">' + escapeHtml(ticket.short_code) + '</div>' +
|
||||||
|
'<canvas id="vrBarcodeCanvas" style="margin-top:8px;max-width:100%;display:block;"></canvas>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-detail-row">' +
|
'<div class="vr-ticket-detail-row">' +
|
||||||
'<div class="vr-ticket-detail-label">状态</div>' +
|
'<div class="vr-ticket-detail-label">状态</div>' +
|
||||||
|
|
@ -187,13 +188,14 @@ var VrTicketWallet = (function() {
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-detail-row">' +
|
'<div class="vr-ticket-detail-row">' +
|
||||||
'<div class="vr-ticket-detail-label">座位</div>' +
|
'<div class="vr-ticket-detail-label">座位</div>' +
|
||||||
'<div class="vr-ticket-detail-value">' + escapeHtml(ticket.seat_info) + '</div>' +
|
'<div class="vr-ticket-detail-value">' + escapeHtml(ticket.seat_number) + '</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-detail-row">' +
|
'<div class="vr-ticket-detail-row">' +
|
||||||
'<div class="vr-ticket-detail-label">观演人</div>' +
|
'<div class="vr-ticket-detail-label">观演人</div>' +
|
||||||
'<div class="vr-ticket-detail-value">' + escapeHtml(ticket.real_name) + ' ' + escapeHtml(ticket.phone) + '</div>' +
|
'<div class="vr-ticket-detail-value">' + escapeHtml(ticket.real_name) + ' ' + escapeHtml(ticket.phone) + '</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
(ticket.verify_status === 0 ? '<button class="vr-ticket-refresh-btn" id="vrRefreshBtn" onclick="VrTicketWallet.refreshQr(' + ticket.id + ')">刷新二维码</button>' : '');
|
(ticket.verify_status === 0 ? '<button class="vr-ticket-refresh-btn" id="vrRefreshBtn" onclick="VrTicketWallet.refreshQr(' + ticket.id + ')">刷新二维码</button>' : '');
|
||||||
|
renderBarcode(ticket.short_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -219,8 +221,9 @@ var VrTicketWallet = (function() {
|
||||||
'<div class="vr-ticket-qr-expire" id="vrQrExpire"></div>' +
|
'<div class="vr-ticket-qr-expire" id="vrQrExpire"></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-short-code-display">' +
|
'<div class="vr-ticket-short-code-display">' +
|
||||||
'<div class="vr-ticket-short-code-label">短码(人工核销)</div>' +
|
'<div class="vr-ticket-short-code-label">核销码</div>' +
|
||||||
'<div class="vr-ticket-short-code-value">' + escapeHtml(ticket.short_code) + '</div>' +
|
'<div class="vr-ticket-short-code-value">' + escapeHtml(ticket.short_code) + '</div>' +
|
||||||
|
'<canvas id="vrBarcodeCanvas" style="margin-top:8px;max-width:100%;display:block;"></canvas>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
verifiedBadge +
|
verifiedBadge +
|
||||||
'<div class="vr-ticket-detail-row">' +
|
'<div class="vr-ticket-detail-row">' +
|
||||||
|
|
@ -233,7 +236,7 @@ var VrTicketWallet = (function() {
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-detail-row">' +
|
'<div class="vr-ticket-detail-row">' +
|
||||||
'<div class="vr-ticket-detail-label">座位</div>' +
|
'<div class="vr-ticket-detail-label">座位</div>' +
|
||||||
'<div class="vr-ticket-detail-value">' + escapeHtml(ticket.seat_info) + '</div>' +
|
'<div class="vr-ticket-detail-value">' + escapeHtml(ticket.seat_number) + '</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="vr-ticket-detail-row">' +
|
'<div class="vr-ticket-detail-row">' +
|
||||||
'<div class="vr-ticket-detail-label">观演人</div>' +
|
'<div class="vr-ticket-detail-label">观演人</div>' +
|
||||||
|
|
@ -243,6 +246,7 @@ var VrTicketWallet = (function() {
|
||||||
|
|
||||||
if (ticket.qr_payload) {
|
if (ticket.qr_payload) {
|
||||||
renderQrCode(ticket.qr_payload, ticket.qr_expires_in);
|
renderQrCode(ticket.qr_payload, ticket.qr_expires_in);
|
||||||
|
renderBarcode(ticket.short_code);
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('vrQrcodeBox').innerHTML = '<div style="color:#999;">QR加载中...</div>';
|
document.getElementById('vrQrcodeBox').innerHTML = '<div style="color:#999;">QR加载中...</div>';
|
||||||
}
|
}
|
||||||
|
|
@ -323,6 +327,27 @@ var VrTicketWallet = (function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染条形码(CODE128)
|
||||||
|
* @param {string} shortCode - 核销码
|
||||||
|
*/
|
||||||
|
function renderBarcode(shortCode) {
|
||||||
|
try {
|
||||||
|
var canvas = document.getElementById('vrBarcodeCanvas');
|
||||||
|
if (!canvas || !shortCode) return;
|
||||||
|
JsBarcode(canvas, shortCode, {
|
||||||
|
format: 'CODE128',
|
||||||
|
width: 2,
|
||||||
|
height: 60,
|
||||||
|
displayValue: true,
|
||||||
|
fontSize: 14,
|
||||||
|
margin: 5
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Barcode render failed:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新 QR
|
* 刷新 QR
|
||||||
*/
|
*/
|
||||||
|
|
@ -350,6 +375,7 @@ var VrTicketWallet = (function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
renderQrCode(ticket.qr_payload, ticket.qr_expires_in);
|
renderQrCode(ticket.qr_payload, ticket.qr_expires_in);
|
||||||
|
renderBarcode(ticket.short_code);
|
||||||
|
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.textContent = '已刷新';
|
btn.textContent = '已刷新';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue