feat: 100처방 구성약재 수 표시, 등록 여부 백엔드 판정, 이름매칭 개선

- official_formulas API에 ingredient_count 추가 (LEFT JOIN COUNT)
- 등록 여부를 백엔드에서 판정 (official_formula_id FK 1차 + 이름 포함 매칭 fallback)
- 내 처방 100처방 뱃지 매칭: startsWith → includes 변경
- 100처방 목록에 구성약재 수 뱃지 컬럼 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-18 14:41:40 +00:00
parent 1679f75d33
commit 50883a6a84
3 changed files with 79 additions and 30 deletions

View File

@@ -590,11 +590,18 @@ $(document).ready(function() {
tbody.empty();
response.data.forEach(formula => {
// 100처방 매칭: 정확 매칭 우선, 없으면 내 처방명이 100처방명으로 시작하는지 확인
let officialNum = officialNames.get(formula.formula_name);
// 100처방 매칭: 1차 official_formula_id FK, 2차 이름 매칭 (원방명이 내 처방명에 포함)
let officialNum = null;
if (formula.official_formula_id) {
// FK로 연결된 경우 — official_name은 API에서 JOIN으로 내려옴
officialNum = officialNames.get(formula.official_name);
}
if (officialNum == null) {
officialNum = officialNames.get(formula.formula_name);
}
if (officialNum == null) {
for (const [name, num] of officialNames) {
if (formula.formula_name.startsWith(name)) {
if (formula.formula_name.includes(name)) {
officialNum = num;
break;
}
@@ -697,13 +704,6 @@ $(document).ready(function() {
function loadOfficialFormulas(search) {
const params = search ? `?search=${encodeURIComponent(search)}` : '';
// 내 처방 이름 목록을 API에서 가져와서 비교
$.get('/api/formulas', function(formulasRes) {
const myFormulaNames = new Set();
if (formulasRes.success) {
formulasRes.data.forEach(f => myFormulaNames.add(f.formula_name));
}
$.get(`/api/official-formulas${params}`, function(response) {
if (response.success) {
const tbody = $('#officialFormulasList');
@@ -712,15 +712,24 @@ $(document).ready(function() {
$('#officialFormulaCount').text(response.data.length);
response.data.forEach(formula => {
// 등록 여부: 정확 매칭 또는 내 처방명이 100처방명으로 시작
const isRegistered = myFormulaNames.has(formula.formula_name)
|| [...myFormulaNames].some(name => name.startsWith(formula.formula_name));
const statusBadge = isRegistered
? '<span class="badge bg-success">등록됨</span>'
: '<span class="badge bg-outline-secondary text-muted">미등록</span>';
// 등록 여부: 백엔드에서 판정 (official_formula_id FK + 이름 fallback)
const isRegistered = formula.is_registered;
let statusBadge;
if (isRegistered && formula.registered_names && formula.registered_names.length > 0) {
const names = formula.registered_names.map(n => n.length > 12 ? n.substring(0, 12) + '…' : n).join(', ');
statusBadge = `<span class="badge bg-success" title="${formula.registered_names.join(', ')}">${formula.registered_names.length > 1 ? formula.registered_names.length + '개 등록' : '등록됨'}</span>`;
} else {
statusBadge = '<span class="badge bg-outline-secondary text-muted">미등록</span>';
}
const hasNotes = formula.reference_notes ? '<i class="bi bi-journal-text text-info ms-1" title="참고자료 있음"></i>' : '';
// 구성 약재 수 표시
const ingCount = formula.ingredient_count || 0;
const ingBadge = ingCount > 0
? `<span class="badge bg-success bg-opacity-75">${ingCount}종</span>`
: `<span class="badge bg-light text-muted">미입력</span>`;
tbody.append(`
<tr class="official-formula-row" style="cursor:pointer"
data-id="${formula.official_formula_id}"
@@ -734,17 +743,17 @@ $(document).ready(function() {
<td><strong>${formula.formula_name}</strong>${hasNotes}</td>
<td class="text-muted">${formula.formula_name_hanja || '-'}</td>
<td>${formula.source_text || '-'}</td>
<td class="text-center">${ingBadge}</td>
<td class="text-center">${statusBadge}</td>
</tr>
`);
});
if (response.data.length === 0) {
tbody.html('<tr><td colspan="5" class="text-center text-muted">검색 결과가 없습니다.</td></tr>');
tbody.html('<tr><td colspan="6" class="text-center text-muted">검색 결과가 없습니다.</td></tr>');
}
}
});
}); // /api/formulas 콜백 닫기
}
// 100처방 검색 이벤트