feat(dispatch): 검색 결과 가독성 — 송장 조회 링크·택배사 배지·줄분리
- api_search: 결과에 courier_tracking_url 주입(송장 클릭 시 조회 페이지) - batches.html: Order/Pkg/송장 한 줄씩, 글자 확대, 송장번호·날짜·쇼핑몰 굵게, 송장 오른쪽 배송사 배지, 송장번호 클릭 → 배송사 조회 새 탭 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -726,7 +726,13 @@ async def api_search(
|
||||
query = (q or "").strip()
|
||||
if len(query) < 2:
|
||||
return JSONResponse({"query": query, "results": []})
|
||||
return JSONResponse({"query": query, "results": st.search_parcels(query=query)})
|
||||
results = st.search_parcels(query=query)
|
||||
# 송장 조회 딥링크는 배송사 맵(store)에서 만든다 — 프런트엔 맵이 없다.
|
||||
for r in results:
|
||||
r["tracking_url"] = store.courier_tracking_url(
|
||||
r.get("tracking_id", ""), r.get("shipping_provider", "")
|
||||
)
|
||||
return JSONResponse({"query": query, "results": results})
|
||||
|
||||
|
||||
@router.get("/health")
|
||||
|
||||
@@ -29,16 +29,25 @@
|
||||
.dsp-q-clear { position:absolute;right:8px;top:50%;transform:translateY(-50%);border:0;background:transparent;color:#94a3b8;font-size:18px;cursor:pointer;line-height:1;padding:0 4px;display:none; }
|
||||
.dsp-search-results { position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:40;background:#fff;border:1px solid #e2e8f0;border-radius:10px;box-shadow:0 8px 24px rgba(15,23,42,.12);max-height:64vh;overflow:auto;display:none;padding:6px; }
|
||||
.dsp-search-results.open { display:block; }
|
||||
.dsp-hit { border-radius:8px;padding:9px 10px;display:flex;justify-content:space-between;gap:12px;align-items:flex-start; }
|
||||
.dsp-hit { border-radius:8px;padding:11px 12px;display:flex;justify-content:space-between;gap:12px;align-items:flex-start; }
|
||||
.dsp-hit + .dsp-hit { border-top:1px solid #f1f5f9; }
|
||||
.dsp-hit:hover { background:#f8fafc; }
|
||||
.dsp-hit-name { font-weight:700;font-size:14px;color:#0f172a; }
|
||||
.dsp-hit-meta { font-size:12.5px;color:#475569;margin-top:2px;line-height:1.5; }
|
||||
.dsp-hit-meta code { background:#f1f5f9;padding:1px 5px;border-radius:4px;font-size:12px; }
|
||||
.dsp-hit-body { min-width:0; }
|
||||
.dsp-hit-name { font-weight:700;font-size:17px;color:#0f172a; }
|
||||
.dsp-hit-meta { font-size:14px;color:#475569;margin-top:3px;line-height:1.5; }
|
||||
/* Order / Pkg / 송장 — 한 줄씩 */
|
||||
.dsp-id { font-size:14.5px;margin-top:4px;display:flex;gap:8px;align-items:baseline;flex-wrap:wrap; }
|
||||
.dsp-id-k { color:#94a3b8;font-size:12px;min-width:42px;flex:0 0 auto; }
|
||||
.dsp-id code { background:#f1f5f9;padding:2px 7px;border-radius:5px;font-size:14px;color:#0f172a; }
|
||||
.dsp-id-track code { font-weight:700; }
|
||||
.dsp-track-lnk { text-decoration:none; }
|
||||
.dsp-track-lnk code { color:#4f46e5;text-decoration:underline;cursor:pointer; }
|
||||
.dsp-track-lnk:hover code { background:#e0e7ff; }
|
||||
.dsp-courier { font-size:12.5px;font-weight:600;color:#475569;background:#eef2ff;border:1px solid #c7d2fe;border-radius:999px;padding:1px 9px; }
|
||||
.dsp-hit mark { background:#fde68a;padding:0 1px;border-radius:2px; }
|
||||
.dsp-hit-batch { font-size:11.5px;color:#64748b;margin-top:3px; }
|
||||
.dsp-hit-batch { font-size:13px;color:#475569;margin-top:5px; }
|
||||
.dsp-hit-go { white-space:nowrap;flex:0 0 auto;align-self:center; }
|
||||
.dsp-hit-empty { color:#94a3b8;font-size:13.5px;padding:10px; }
|
||||
.dsp-hit-empty { color:#94a3b8;font-size:14.5px;padding:11px; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
@@ -294,11 +303,26 @@
|
||||
}
|
||||
function en() { return (window.dspLang && window.dspLang() === 'en'); }
|
||||
|
||||
function idLine(label, value, q) {
|
||||
if (!value) return '';
|
||||
return '<div class="dsp-id"><span class="dsp-id-k">' + label + '</span>'
|
||||
+ '<code>' + hi(value, q) + '</code></div>';
|
||||
}
|
||||
function trackLine(r, q) {
|
||||
if (!r.tracking_id) return '';
|
||||
var num = '<code>' + hi(r.tracking_id, q) + '</code>';
|
||||
// 송장번호 클릭 → 배송사 조회 페이지(딥링크 있으면).
|
||||
var inner = r.tracking_url
|
||||
? '<a href="' + esc(r.tracking_url) + '" target="_blank" rel="noopener" class="dsp-track-lnk">' + num + '</a>'
|
||||
: num;
|
||||
var courier = r.shipping_provider
|
||||
? '<span class="dsp-courier">' + esc(r.shipping_provider) + '</span>'
|
||||
: '';
|
||||
return '<div class="dsp-id dsp-id-track"><span class="dsp-id-k">' + (en() ? 'Track' : '송장') + '</span>'
|
||||
+ inner + courier + '</div>';
|
||||
}
|
||||
|
||||
function row(r, q) {
|
||||
var ids = [];
|
||||
if (r.order_id) ids.push('Order <code>' + hi(r.order_id, q) + '</code>');
|
||||
if (r.package_id) ids.push('Pkg <code>' + hi(r.package_id, q) + '</code>');
|
||||
if (r.tracking_id) ids.push((en() ? 'Track ' : '송장 ') + '<code>' + hi(r.tracking_id, q) + '</code>');
|
||||
var name = r.recipient_name
|
||||
? hi(r.recipient_name, q)
|
||||
: esc(en() ? '(no recipient name)' : '(받는 사람 정보 없음)');
|
||||
@@ -306,14 +330,17 @@
|
||||
if (r.recipient_phone) contact.push(esc(r.recipient_phone));
|
||||
if (r.recipient_address) contact.push(esc(r.recipient_address));
|
||||
var done = r.label_attached && r.handed_to_kagayaku;
|
||||
var batchLine = esc(r.dispatch_date) + ' · ' + esc(r.platform) + ' · ' + esc(r.batch_name || '')
|
||||
+ ' · ' + (en() ? 'Box #' : '박스 #') + esc(r.seq)
|
||||
+ (done ? ' · <span style="color:#16a34a;font-weight:600;">✓</span>' : '');
|
||||
// 날짜·쇼핑몰은 굵게.
|
||||
var batchLine = '<b>' + esc(r.dispatch_date) + '</b> · <b>' + esc(r.platform) + '</b> · '
|
||||
+ esc(r.batch_name || '') + ' · ' + (en() ? 'Box #' : '박스 #') + esc(r.seq)
|
||||
+ (done ? ' · <span style="color:#16a34a;font-weight:700;">✓</span>' : '');
|
||||
return '<div class="dsp-hit">'
|
||||
+ '<div>'
|
||||
+ '<div class="dsp-hit-body">'
|
||||
+ '<div class="dsp-hit-name">' + name + '</div>'
|
||||
+ (contact.length ? '<div class="dsp-hit-meta">' + contact.join(' · ') + '</div>' : '')
|
||||
+ '<div class="dsp-hit-meta">' + ids.join(' ') + '</div>'
|
||||
+ idLine('Order', r.order_id, q)
|
||||
+ idLine('Pkg', r.package_id, q)
|
||||
+ trackLine(r, q)
|
||||
+ '<div class="dsp-hit-batch">' + batchLine + '</div>'
|
||||
+ '</div>'
|
||||
+ '<a class="erp-btn erp-btn-outline dsp-hit-go" href="/dispatch/batches/' + encodeURIComponent(r.batch_id) + '">'
|
||||
|
||||
Reference in New Issue
Block a user