generated from ttipo/project-base
refactor: 신청 화면에서 신청 직전(최종) 유입 표시 제거
운영에 필요한 것은 업체 링크로 들어와 누가 신청·구매했는지이고, 신청 직전 유입은 쓰지 않는다. 기준이 둘(직전·최초)이라 화면만 복잡해져 신청 때 유입은 한 가지만 보여준다. - 신청 유입 집계 기준: 신청 직전 · 신청 때 최초 · 가입 경로 → 신청 때 유입 · 가입 경로 - 신청자 표·상세 패널: 신청 때 유입을 한 줄로 (최초/직전 구분 제거) - 개요의 신청 유입 상위도 신청 때 유입 기준 - 회원 상세의 가입 경로에서 '최종 유입' 줄 제거 백엔드는 그대로 둔다 (최종 유입은 저장만 하고 화면에 쓰지 않는다) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+15
-30
@@ -477,7 +477,7 @@
|
||||
<section class="mgm-card">
|
||||
<div class="mgm-card-head">
|
||||
<h3>신청 유입 상위</h3>
|
||||
<span class="mgm-muted">최근 30일 · 신청 직전 유입 기준</span>
|
||||
<span class="mgm-muted">최근 30일 · 신청 때 유입 기준</span>
|
||||
<span class="mgm-spacer"></span>
|
||||
<button type="button" class="mgm-link" data-goto="applications" data-app-preset="30">신청 내역 →</button>
|
||||
</div>
|
||||
@@ -571,8 +571,7 @@
|
||||
</div>
|
||||
<div class="mgm-row" style="margin-bottom:12px">
|
||||
<div class="mgm-seg" role="group" aria-label="유입 기준">
|
||||
<button type="button" data-app-basis="apply_last" class="is-active" title="신청 직전에 마지막으로 들어온 경로 — 신청을 일으킨 유입">신청 직전</button>
|
||||
<button type="button" data-app-basis="apply_first" title="신청 시점 브라우저에 남아 있던 첫 경로 (2일 보관)">신청 때 최초</button>
|
||||
<button type="button" data-app-basis="apply_first" class="is-active" title="신청 시점에 브라우저에 남아 있던 유입경로 (UTM 스크립트 2일 보관)">신청 때 유입</button>
|
||||
<button type="button" data-app-basis="join" title="신청한 회원이 가입할 때 기록된 경로 (가입 후 채워진 값은 제외)">가입 경로</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -593,7 +592,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>신청일시</th><th>신청자</th><th>연락처</th><th>상품</th><th>업체</th><th title="신청 완료 화면의 오픈카톡 버튼을 누른 수 — 실제 입장 여부는 카카오가 알려주지 않아 알 수 없습니다">카톡 버튼</th>
|
||||
<th title="신청 직전 유입 — 첫 경로와 다르면 아래에 '최초'로 함께 표시">신청 때 유입</th><th>가입 경로</th>
|
||||
<th title="신청 시점에 브라우저에 남아 있던 유입경로 (UTM 스크립트 2일 보관)">신청 때 유입</th><th>가입 경로</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-role="app-rows"></tbody>
|
||||
@@ -900,7 +899,7 @@
|
||||
app: {
|
||||
range: 'all', mode: 'product', group: null, groupLabel: '',
|
||||
cursor: null, loading: false, seq: 0, groupsSeq: 0,
|
||||
basis: 'apply_last', statsGroup: 'source', statsSeq: 0, inflowFilter: null,
|
||||
basis: 'apply_first', statsGroup: 'source', statsSeq: 0, inflowFilter: null,
|
||||
rows: {}
|
||||
},
|
||||
// 업체 링크
|
||||
@@ -1445,7 +1444,6 @@
|
||||
['외부 리퍼러', esc(inf.referrer)],
|
||||
['첫 랜딩', esc(inf.landingPath) + (inf.productId ? ' <span class="mgm-faint">#' + esc(inf.productId) + '</span>' : '')],
|
||||
['최초 유입일', esc(inf.firstTouchDate)],
|
||||
['최종 유입', esc(inf.lastTouch)],
|
||||
['기록일', esc(inf.recordedDate)]
|
||||
]) + '</section>';
|
||||
}
|
||||
@@ -1480,7 +1478,7 @@
|
||||
setKpi('join-week', num(c.atJoin + c.afterJoin + c.none));
|
||||
}).catch(errorNotice);
|
||||
|
||||
api('GET', '/admin/applications/inflow-stats' + toQuery(Object.assign({ basis: 'apply_last', groupBy: 'source' }, periodQuery('30', 'appliedFrom', 'appliedTo')))).then(function (s) {
|
||||
api('GET', '/admin/applications/inflow-stats' + toQuery(Object.assign({ basis: 'apply_first', groupBy: 'source' }, periodQuery('30', 'appliedFrom', 'appliedTo')))).then(function (s) {
|
||||
$('[data-role="ov-app-bars"]').innerHTML = barsHtml(s.items.slice(0, TOP_SIZE), true, null, '건');
|
||||
}).catch(errorNotice);
|
||||
|
||||
@@ -1501,12 +1499,12 @@
|
||||
$('[data-role="ov-recent-rows"]').innerHTML = page.items.length ? page.items.map(function (a) {
|
||||
state.app.rows[a.id] = a;
|
||||
var m = a.member;
|
||||
var last = a.lastInflow && a.lastInflow.source ? a.lastInflow : a.inflow;
|
||||
var inf = a.inflow;
|
||||
return '<tr class="is-clickable" data-app-row="' + esc(a.id) + '">' +
|
||||
'<td>' + whenCell(a.appliedAt) + '</td>' +
|
||||
'<td>' + personCell(m ? m.name : a.memberUid, '') + '</td>' +
|
||||
'<td class="mgm-wrap">' + dash(a.productName) + '</td>' +
|
||||
'<td>' + (a.partner ? '<span class="mgm-badge is-accent">' + esc(a.partner.name) + '</span>' : (last && last.source ? esc(last.source) : '<span class="mgm-faint">-</span>')) + '</td>' +
|
||||
'<td>' + (a.partner ? '<span class="mgm-badge is-accent">' + esc(a.partner.name) + '</span>' : (inf && inf.source ? esc(inf.source) : '<span class="mgm-faint">-</span>')) + '</td>' +
|
||||
'</tr>';
|
||||
}).join('') : '<tr><td colspan="4" class="mgm-empty">아직 신청이 없습니다.</td></tr>';
|
||||
}).catch(errorNotice);
|
||||
@@ -1519,7 +1517,7 @@
|
||||
$('[data-role="ov-app-bars"]').addEventListener('click', function (e) {
|
||||
var bar = closest(e.target, '.mgm-bar');
|
||||
if (!bar || bar.disabled) return;
|
||||
openApplications({ range: '30', inflowFilter: { basis: 'apply_last', field: 'source', value: bar.getAttribute('data-key') } });
|
||||
openApplications({ range: '30', inflowFilter: { basis: 'apply_first', field: 'source', value: bar.getAttribute('data-key') } });
|
||||
});
|
||||
$('[data-role="ov-join-bars"]').addEventListener('click', function (e) {
|
||||
var bar = closest(e.target, '.mgm-bar');
|
||||
@@ -1537,7 +1535,7 @@
|
||||
|
||||
/* ===================== 신청 내역 ===================== */
|
||||
var appForm = $('[data-role="app-filter"]');
|
||||
var APP_BASIS_LABEL = { apply_last: '신청 직전', apply_first: '신청 때 최초', join: '가입 경로' };
|
||||
var APP_BASIS_LABEL = { apply_first: '신청 때 유입', join: '가입 경로' };
|
||||
var APP_GROUP_LABEL = { source: '유입원', medium: '매체', campaign: '캠페인', content: '콘텐츠' };
|
||||
|
||||
// 다른 화면에서 신청 내역 열기 — 기간·유입 필터를 미리 채운다
|
||||
@@ -1631,18 +1629,6 @@
|
||||
$('[data-role="app-chips"]').innerHTML = chips.join('');
|
||||
}
|
||||
|
||||
// 신청 때 유입 칸 — 최종 유입을 보여주고, 첫 경로가 다르면 '최초'로 함께 적는다
|
||||
function applyInflowCell(a) {
|
||||
var first = a.inflow, last = a.lastInflow && a.lastInflow.source ? a.lastInflow : first;
|
||||
var html = inflowText(last);
|
||||
if (first && first.source && last && last.source &&
|
||||
(first.source !== last.source || first.medium !== last.medium || first.campaign !== last.campaign)) {
|
||||
html += '<span class="mgm-cell-sub" title="신청 시점 브라우저에 남아 있던 첫 경로 (2일 보관)">최초: ' +
|
||||
esc(first.source) + (first.medium ? ' / ' + esc(first.medium) : '') + '</span>';
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
function appRowHtml(a) {
|
||||
var m = a.member;
|
||||
state.app.rows[a.id] = a;
|
||||
@@ -1655,7 +1641,7 @@
|
||||
'<td>' + (a.kakaoClickedAt
|
||||
? '<span class="mgm-badge is-ok" title="' + esc(kstDateTime(a.kakaoClickedAt)) + ' 에 버튼을 눌렀습니다 (실제 입장 여부는 알 수 없음)">클릭</span>'
|
||||
: '<span class="mgm-faint">-</span>') + '</td>' +
|
||||
'<td class="mgm-wrap">' + applyInflowCell(a) + '</td>' +
|
||||
'<td class="mgm-wrap">' + inflowText(a.inflow) + '</td>' +
|
||||
'<td class="mgm-wrap">' + joinInflowCell(m) + '</td>' +
|
||||
'</tr>';
|
||||
}
|
||||
@@ -1698,8 +1684,7 @@
|
||||
function openApplicationDrawer(id) {
|
||||
var a = state.app.rows[id];
|
||||
if (!a) return;
|
||||
var first = a.inflow, last = a.lastInflow && a.lastInflow.source ? a.lastInflow : first;
|
||||
var sameTouch = !first || !first.source || (first.source === last.source && first.medium === last.medium && first.campaign === last.campaign);
|
||||
var inf = a.inflow || {};
|
||||
var html = '<section class="mgm-dsec"><h4>신청</h4>' + dlHtml([
|
||||
['상품', dash(a.productName) + ' <span class="mgm-faint">#' + esc(a.productIdx) + '</span>'],
|
||||
['신청일시', esc(kstDateTime(a.appliedAt))],
|
||||
@@ -1707,10 +1692,10 @@
|
||||
['카톡 버튼', a.kakaoClickedAt ? '눌렀음 · ' + esc(kstDateTime(a.kakaoClickedAt)) + ' <span class="mgm-faint">(실제 입장 여부는 알 수 없음)</span>' : '누르지 않음']
|
||||
]) + '</section>' +
|
||||
'<section class="mgm-dsec"><h4>신청 때 유입</h4>' + dlHtml([
|
||||
['신청 직전', last && last.source ? esc(last.source) + (last.medium ? ' / ' + esc(last.medium) : '') : ''],
|
||||
['캠페인', esc(last && last.campaign)],
|
||||
['콘텐츠', esc(last && last.content)],
|
||||
['최초 유입', sameTouch ? '<span class="mgm-faint">신청 직전과 같음</span>' : esc(first.source) + (first.medium ? ' / ' + esc(first.medium) : '') + (first.campaign ? ' · ' + esc(first.campaign) : '')]
|
||||
['유입원', esc(inf.source)],
|
||||
['매체', esc(inf.medium)],
|
||||
['캠페인', esc(inf.campaign)],
|
||||
['콘텐츠', esc(inf.content)]
|
||||
]) + '</section>' + memberSectionsHtml(a.member);
|
||||
openDrawer((a.member ? a.member.name : a.memberUid) + ' 님의 신청', html);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user