kdrug-inventory-system/templates/index.html
시골약사 2fddc89bca 초기 커밋: 한약 재고관리 시스템
 주요 기능
- 환자 관리: 환자 등록 및 조회 (이름, 전화번호, 주민번호, 성별)
- 입고 관리: Excel 파일 업로드로 대량 입고 처리
- 처방 관리: 약속 처방 템플릿 등록 및 관리
- 조제 관리: 처방 기반 조제 및 약재 가감 기능
- 재고 관리: 실시간 재고 현황 및 로트별 관리

🛠️ 기술 스택
- Backend: Flask (Python 웹 프레임워크)
- Database: SQLite (경량 관계형 데이터베이스)
- Frontend: Bootstrap + jQuery
- Excel 처리: pandas + openpyxl

🔧 핵심 개념
- 1제 = 20첩 = 30파우치 (기본값)
- FIFO 방식 재고 차감
- 로트별 원산지/단가 관리
- 정확한 조제 원가 계산

📁 프로젝트 구조
- app.py: Flask 백엔드 서버
- database/: 데이터베이스 스키마 및 파일
- templates/: HTML 템플릿
- static/: JavaScript 및 CSS
- sample/: 샘플 Excel 파일

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-15 07:57:40 +00:00

556 lines
27 KiB
HTML

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>한약 재고관리 시스템</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans KR', sans-serif;
background-color: #f8f9fa;
}
.navbar-brand {
font-weight: bold;
color: #2c3e50 !important;
}
.sidebar {
min-height: calc(100vh - 56px);
background-color: #fff;
box-shadow: 2px 0 5px rgba(0,0,0,0.05);
}
.sidebar .nav-link {
color: #495057;
padding: 12px 20px;
border-left: 3px solid transparent;
transition: all 0.3s;
}
.sidebar .nav-link:hover {
background-color: #f8f9fa;
border-left-color: #007bff;
}
.sidebar .nav-link.active {
background-color: #e7f1ff;
border-left-color: #007bff;
color: #007bff;
font-weight: 500;
}
.content-area {
padding: 20px;
}
.stat-card {
background: white;
border-radius: 10px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.08);
margin-bottom: 20px;
}
.stat-card h5 {
color: #6c757d;
font-size: 14px;
margin-bottom: 10px;
}
.stat-card .value {
font-size: 24px;
font-weight: bold;
color: #2c3e50;
}
.main-content {
display: none;
}
.main-content.active {
display: block;
}
</style>
</head>
<body>
<!-- Navigation Bar -->
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container-fluid">
<a class="navbar-brand" href="#">
<i class="bi bi-heart-pulse-fill text-primary"></i> 한약 재고관리 시스템
</a>
<div class="navbar-nav ms-auto">
<span class="navbar-text me-3">
<i class="bi bi-person-circle"></i> 관리자
</span>
<button class="btn btn-outline-secondary btn-sm">
<i class="bi bi-box-arrow-right"></i> 로그아웃
</button>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<!-- Sidebar -->
<div class="col-md-2 sidebar p-0">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="#" data-page="dashboard">
<i class="bi bi-speedometer2"></i> 대시보드
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" data-page="patients">
<i class="bi bi-people"></i> 환자 관리
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" data-page="purchase">
<i class="bi bi-file-earmark-arrow-up"></i> 입고 관리
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" data-page="formulas">
<i class="bi bi-journal-medical"></i> 처방 관리
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" data-page="compound">
<i class="bi bi-prescription2"></i> 조제 관리
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" data-page="inventory">
<i class="bi bi-box-seam"></i> 재고 현황
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" data-page="herbs">
<i class="bi bi-flower1"></i> 약재 관리
</a>
</li>
</ul>
</div>
<!-- Main Content Area -->
<div class="col-md-10 content-area">
<!-- Dashboard Page -->
<div id="dashboard" class="main-content active">
<h3 class="mb-4">대시보드</h3>
<div class="row">
<div class="col-md-3">
<div class="stat-card">
<h5><i class="bi bi-people-fill"></i> 총 환자수</h5>
<div class="value" id="totalPatients">0</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<h5><i class="bi bi-box-seam-fill"></i> 재고 품목</h5>
<div class="value" id="totalHerbs">0</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<h5><i class="bi bi-calendar-check"></i> 오늘 조제</h5>
<div class="value" id="todayCompounds">0</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<h5><i class="bi bi-cash-stack"></i> 재고 자산</h5>
<div class="value" id="inventoryValue">0</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h5 class="mb-0">최근 조제 내역</h5>
</div>
<div class="card-body">
<table class="table table-hover">
<thead>
<tr>
<th>조제일</th>
<th>환자명</th>
<th>처방명</th>
<th>제수</th>
<th>파우치</th>
<th>상태</th>
</tr>
</thead>
<tbody id="recentCompounds">
<!-- Dynamic content -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Patients Page -->
<div id="patients" class="main-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3>환자 관리</h3>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#patientModal">
<i class="bi bi-person-plus"></i> 새 환자 등록
</button>
</div>
<div class="card">
<div class="card-body">
<div class="mb-3">
<input type="text" class="form-control" id="patientSearch" placeholder="환자명 또는 전화번호로 검색...">
</div>
<table class="table table-hover">
<thead>
<tr>
<th>환자명</th>
<th>전화번호</th>
<th>성별</th>
<th>생년월일</th>
<th>메모</th>
<th>작업</th>
</tr>
</thead>
<tbody id="patientsList">
<!-- Dynamic content -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Purchase Page -->
<div id="purchase" class="main-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3>입고 관리</h3>
</div>
<div class="card">
<div class="card-body">
<h5>Excel 파일 업로드</h5>
<form id="purchaseUploadForm" enctype="multipart/form-data">
<div class="mb-3">
<label for="purchaseFile" class="form-label">입고 Excel 파일 선택</label>
<input type="file" class="form-control" id="purchaseFile" accept=".xlsx,.xls" required>
<div class="form-text">
양식: 제품코드, 업체명, 약재명, 구입일자, 구입량, 구입액, 원산지
</div>
</div>
<button type="submit" class="btn btn-primary">
<i class="bi bi-upload"></i> 업로드 및 처리
</button>
</form>
<div id="uploadResult" class="mt-3"></div>
</div>
</div>
</div>
<!-- Formulas Page -->
<div id="formulas" class="main-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3>처방 관리</h3>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#formulaModal">
<i class="bi bi-plus-circle"></i> 새 처방 등록
</button>
</div>
<div class="card">
<div class="card-body">
<table class="table table-hover">
<thead>
<tr>
<th>처방코드</th>
<th>처방명</th>
<th>기본 첩수</th>
<th>기본 파우치</th>
<th>구성 약재</th>
<th>작업</th>
</tr>
</thead>
<tbody id="formulasList">
<!-- Dynamic content -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Compound Page -->
<div id="compound" class="main-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3>조제 관리</h3>
<button class="btn btn-primary" id="newCompoundBtn">
<i class="bi bi-plus-circle"></i> 새 조제
</button>
</div>
<div class="card" id="compoundForm" style="display: none;">
<div class="card-body">
<h5>조제 입력</h5>
<form id="compoundEntryForm">
<div class="row">
<div class="col-md-6">
<label class="form-label">환자 선택</label>
<select class="form-control" id="compoundPatient" required>
<option value="">환자를 선택하세요</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">처방 선택</label>
<select class="form-control" id="compoundFormula" required>
<option value="">처방을 선택하세요</option>
</select>
</div>
</div>
<div class="row mt-3">
<div class="col-md-4">
<label class="form-label">제수</label>
<input type="number" class="form-control" id="jeCount" value="1" min="0.5" step="0.5" required>
</div>
<div class="col-md-4">
<label class="form-label">총 첩수</label>
<input type="number" class="form-control" id="cheopTotal" readonly>
</div>
<div class="col-md-4">
<label class="form-label">총 파우치수</label>
<input type="number" class="form-control" id="pouchTotal" required>
</div>
</div>
<div class="mt-3">
<h6>약재 구성 (가감 가능)</h6>
<table class="table table-sm">
<thead>
<tr>
<th>약재명</th>
<th>1첩당 용량(g)</th>
<th>총 용량(g)</th>
<th>재고</th>
<th>작업</th>
</tr>
</thead>
<tbody id="compoundIngredients">
<!-- Dynamic content -->
</tbody>
</table>
<button type="button" class="btn btn-sm btn-outline-primary" id="addIngredientBtn">
<i class="bi bi-plus"></i> 약재 추가
</button>
</div>
<div class="mt-3">
<button type="submit" class="btn btn-success">
<i class="bi bi-check-circle"></i> 조제 실행
</button>
<button type="button" class="btn btn-secondary ms-2" id="cancelCompoundBtn">
취소
</button>
</div>
</form>
</div>
</div>
<div class="card mt-4">
<div class="card-header">
<h5 class="mb-0">조제 내역</h5>
</div>
<div class="card-body">
<table class="table table-hover">
<thead>
<tr>
<th>조제일</th>
<th>환자명</th>
<th>처방명</th>
<th>제수</th>
<th>파우치</th>
<th>원가</th>
<th>상태</th>
</tr>
</thead>
<tbody id="compoundsList">
<!-- Dynamic content -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Inventory Page -->
<div id="inventory" class="main-content">
<h3 class="mb-4">재고 현황</h3>
<div class="card">
<div class="card-body">
<div class="mb-3">
<input type="text" class="form-control" id="inventorySearch" placeholder="약재명으로 검색...">
</div>
<table class="table table-hover">
<thead>
<tr>
<th>보험코드</th>
<th>약재명</th>
<th>현재 재고(g)</th>
<th>로트 수</th>
<th>평균 단가</th>
<th>재고 금액</th>
</tr>
</thead>
<tbody id="inventoryList">
<!-- Dynamic content -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Herbs Page -->
<div id="herbs" class="main-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3>약재 관리</h3>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#herbModal">
<i class="bi bi-plus-circle"></i> 새 약재 등록
</button>
</div>
<div class="card">
<div class="card-body">
<table class="table table-hover">
<thead>
<tr>
<th>보험코드</th>
<th>약재명</th>
<th>규격</th>
<th>현재 재고</th>
<th>작업</th>
</tr>
</thead>
<tbody id="herbsList">
<!-- Dynamic content -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Patient Modal -->
<div class="modal fade" id="patientModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">환자 등록</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="patientForm">
<div class="mb-3">
<label class="form-label">환자명 *</label>
<input type="text" class="form-control" id="patientName" required>
</div>
<div class="mb-3">
<label class="form-label">전화번호 *</label>
<input type="tel" class="form-control" id="patientPhone" required>
</div>
<div class="mb-3">
<label class="form-label">주민번호</label>
<input type="text" class="form-control" id="patientJumin" placeholder="000000-0000000">
</div>
<div class="mb-3">
<label class="form-label">성별</label>
<select class="form-control" id="patientGender">
<option value="">선택</option>
<option value="M">남성</option>
<option value="F">여성</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">생년월일</label>
<input type="date" class="form-control" id="patientBirth">
</div>
<div class="mb-3">
<label class="form-label">주소</label>
<input type="text" class="form-control" id="patientAddress">
</div>
<div class="mb-3">
<label class="form-label">메모</label>
<textarea class="form-control" id="patientNotes" rows="2"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
<button type="button" class="btn btn-primary" id="savePatientBtn">저장</button>
</div>
</div>
</div>
</div>
<!-- Formula Modal -->
<div class="modal fade" id="formulaModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">처방 등록</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="formulaForm">
<div class="row">
<div class="col-md-6">
<label class="form-label">처방코드</label>
<input type="text" class="form-control" id="formulaCode">
</div>
<div class="col-md-6">
<label class="form-label">처방명 *</label>
<input type="text" class="form-control" id="formulaName" required>
</div>
</div>
<div class="row mt-3">
<div class="col-md-4">
<label class="form-label">처방 유형</label>
<select class="form-control" id="formulaType">
<option value="CUSTOM">약속처방</option>
<option value="INSURANCE">보험처방</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">기본 첩수</label>
<input type="number" class="form-control" id="baseCheop" value="20">
</div>
<div class="col-md-4">
<label class="form-label">기본 파우치수</label>
<input type="number" class="form-control" id="basePouches" value="30">
</div>
</div>
<div class="mt-3">
<label class="form-label">설명</label>
<textarea class="form-control" id="formulaDescription" rows="2"></textarea>
</div>
<div class="mt-3">
<h6>구성 약재</h6>
<table class="table table-sm">
<thead>
<tr>
<th>약재명</th>
<th>1첩당 용량(g)</th>
<th>비고</th>
<th>삭제</th>
</tr>
</thead>
<tbody id="formulaIngredients">
<!-- Dynamic content -->
</tbody>
</table>
<button type="button" class="btn btn-sm btn-outline-primary" id="addFormulaIngredientBtn">
<i class="bi bi-plus"></i> 약재 추가
</button>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
<button type="button" class="btn btn-primary" id="saveFormulaBtn">저장</button>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="/static/app.js"></script>
</body>
</html>