31fa8d573b
- SessionMiddleware 추가 (dbx-main/OMS 와 동일 SECRET_KEY/COOKIE_NAME/MAX_AGE).
미설정 시 fail-fast.
- AuthGuardMiddleware: 미인증 시 HTML 요청은 dbx-main /login?next=... 으로 302,
API 요청은 401 JSON. 예외 경로: /static/, /health, OAuth 콜백, /login, /logout.
- /health/db 엔드포인트 추가 (DB ping) — dbx-main 헬스 배지가 폴링.
- /login, /logout 라우트 추가 (자체 OAuth 없음, dbx-main 으로 302 위임).
- APP_ROOT_PATH 환경변수 도입 — Dockerfile 의 uvicorn --root-path 로 전달.
- templates/index.html: 모든 /static/, /js 절대경로를 {{ root_path }} 기반으로,
window.APP_BASE_PATH 변수 주입.
- static/js/app.js: fetch wrapper 1개로 /api/* 호출에 APP_BASE_PATH prepend,
401 응답 시 dbx-main 로그인으로 자동 이동. 32 곳 호출 사이트는 그대로 둠.
- Cafe24 OAuth 콜백의 hard-coded redirect 도 root_path 인지하도록 수정.
- docker-compose.yml: 호스트 포트 바인딩 제거(0.0.0.0:8002 노출 차단),
expose 추가, web_net(npm_default) 외부 네트워크 attach, healthcheck 추가.
- .env.example 에 SSO/네트워크 항목 추가.
1056 lines
77 KiB
HTML
1056 lines
77 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
<title>[No.1 King] CS 통합 관리앱 (미라클주방)</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="{{ root_path }}/static/css/styles.css?v=5">
|
|
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
|
|
<script>
|
|
// 서브경로 호스팅 정보 — JS 가 fetch 시 prefix 로 사용한다.
|
|
window.APP_BASE_PATH = "{{ root_path }}";
|
|
</script>
|
|
<style>
|
|
.hover-row:hover {
|
|
background-color: #a8e0ff !important;
|
|
transition: background-color 0.1s;
|
|
}
|
|
|
|
button,
|
|
input,
|
|
select,
|
|
textarea,
|
|
table,
|
|
th,
|
|
td,
|
|
span,
|
|
div,
|
|
h1,
|
|
h2,
|
|
h3,
|
|
h4,
|
|
h5,
|
|
h6 {
|
|
font-family: inherit;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="app-container">
|
|
<!-- Sidebar Navigation -->
|
|
<nav class="sidebar">
|
|
<div class="logo">
|
|
<h1>No.1 King</h1>
|
|
<p>CS 통합 관리</p>
|
|
<div id="app-version-text" style="color: #a0aec0; font-size: 0.95rem; margin-top: 4px; font-weight: normal;">
|
|
Ver 8.56
|
|
</div>
|
|
<div style="color: #a0aec0; font-size: 0.75rem; margin-top: 4px; font-weight: normal;">
|
|
(2026.05.16)
|
|
</div>
|
|
</div>
|
|
<ul class="nav-links">
|
|
<li class="active" data-tab="order-tab">CS 작업</li>
|
|
<li data-tab="manual-tab">수동발주</li>
|
|
<li data-tab="product-tab">상품 설정</li>
|
|
<li data-tab="auto-order-tab"
|
|
style="pointer-events: none; opacity: 0.5; display: inline-flex; align-items: center; justify-content: center;"
|
|
title="서버 DB 점검으로 인해 잠시 비활성화되었습니다.">
|
|
자동발주
|
|
<span
|
|
style="font-size: 0.6rem; background: #e53e3e; color: #fff; padding: 2px 4px; border-radius: 4px; margin-left: 6px;">준비중</span>
|
|
</li>
|
|
<li data-tab="code-tab">코드표</li>
|
|
<li data-tab="return-tab">반품관리</li>
|
|
<li data-tab="gift-tab">설정</li>
|
|
<li data-tab="version-history-tab">Ver History</li>
|
|
</ul>
|
|
</nav>
|
|
<!-- Main Content Area -->
|
|
<main class="content">
|
|
<!-- =========================
|
|
INTEGRATED TAB (ORDER + SMS)
|
|
========================== -->
|
|
<section id="order-tab" class="tab-content active">
|
|
<div class="main-grid">
|
|
<div class="left-col" id="order-items-container">
|
|
<!-- Dynamic Checkboxes injected here by JS -->
|
|
</div>
|
|
<div class="right-col">
|
|
<!-- Left Panel inside right-col -->
|
|
<div class="right-panel-col1">
|
|
<!-- Customer Info -->
|
|
<div class="glass-card customer-info">
|
|
<h3
|
|
style="border-bottom: 2px solid #3182ce; padding-bottom: 4px; margin-bottom: 12px; width: 100%; color: #2d3748; font-size: 1.1rem; background: transparent; box-shadow: none;">
|
|
📝수동 일반 발주</h3>
|
|
<div class="form-group">
|
|
<label>이름</label>
|
|
<input type="text" id="cust-name" placeholder="고객명">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>연락처</label>
|
|
<input type="text" id="cust-phone" placeholder="010-0000-0000">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>주소</label>
|
|
<textarea id="cust-address" rows="2" placeholder="주소 입력"></textarea>
|
|
</div>
|
|
<div class="radio-group mt-1">
|
|
<label><input type="radio" name="order-type" value="normal" checked> 일반</label>
|
|
<label><input type="radio" name="order-type" value="noolak"> 누락</label>
|
|
<label><input type="radio" name="order-type" value="pason"> 파손</label>
|
|
<label><input type="radio" name="order-type" value="bullyang"> 불량</label>
|
|
<label class="checkbox-label no-lid" style="width: 100%; margin-top: 4px;"><input
|
|
type="checkbox" id="chk-no-lid" disabled> 뚜껑 없이 통만</label>
|
|
</div>
|
|
<div class="action-buttons mt-1">
|
|
<button id="btn-submit-normal" class="btn btn-primary btn-large"
|
|
style="background:#3182ce;">발주 입력</button>
|
|
<button id="btn-submit-ellen" class="btn btn-accent btn-large"
|
|
style="background:#ed8936;">엘렌 입력</button>
|
|
<button id="btn-download-sheet" class="btn btn-secondary btn-large"
|
|
style="grid-column: 1 / -1; background:#1D6F42; color:white; border-color:#175C36;">엑셀
|
|
시트 다운로드</button>
|
|
<div id="download-progress-container"
|
|
style="display: none; grid-column: 1 / -1; margin-top: 4px;">
|
|
<div
|
|
style="font-size: 0.75rem; margin-bottom: 4px; display: flex; justify-content: space-between; font-weight: 600; color: #1D6F42;">
|
|
<span>엑셀 다운로드 및 시트 비우기 진행 중...</span>
|
|
<span id="download-progress-text">0%</span>
|
|
</div>
|
|
<div
|
|
style="width: 100%; height: 6px; background: #e2e8f0; border-radius: 3px; overflow: hidden;">
|
|
<div id="download-progress-bar"
|
|
style="width: 0%; height: 100%; background: #1D6F42; transition: width 0.4s ease;">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="glass-card history-box"
|
|
style="display: flex; flex-direction: column; overflow: hidden; height: 260px; margin-bottom: 10px;">
|
|
<h3
|
|
style="display:flex; justify-content:space-between; width:100%; margin-bottom:4px; font-size: 1.1rem; align-items:flex-end;">
|
|
💬최근 전송 메시지 <span class="action-text" id="btn-sms-clear-all"
|
|
style="color: red; font-size: 0.75rem;">전체 삭제</span></h3>
|
|
<ul id="sms-history-list" style="flex: 1; overflow-y: auto; padding-right: 4px;"></ul>
|
|
</div>
|
|
|
|
<!-- Manual Order History -->
|
|
<div class="glass-card manual-history-box"
|
|
style="display: flex; flex-direction: column; overflow: hidden; height: 260px;">
|
|
<h3
|
|
style="border-bottom: 2px solid #3182ce; padding-bottom: 4px; margin-bottom: 8px; width: 100%; color: #2d3748; font-size: 1.1rem; background: transparent; box-shadow: none;">
|
|
📝오늘 수동발주 내역
|
|
</h3>
|
|
<div
|
|
style="margin-bottom: 8px; display: flex; justify-content: space-between; align-items: flex-end;">
|
|
<div
|
|
style="font-size: 0.95rem; color: #4a5568; border-bottom: 2px solid #ed8936; padding-bottom: 2px; display: inline-block;">
|
|
<span id="manual-total-count" style="color:#ed8936;font-weight:bold;">0</span>건
|
|
/
|
|
<span id="manual-total-amount" style="color:#ed8936;font-weight:bold;">0</span>원
|
|
</div>
|
|
<button class="btn btn-secondary btn-sm" id="btn-copy-manual-total"
|
|
style="font-size: 0.75rem; padding: 2px 6px;">복사</button>
|
|
</div>
|
|
<ul id="manual-history-list" style="flex: 1; overflow-y: auto; padding-right: 4px;">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="right-panel-col2">
|
|
<div class="glass-card preview-box" style="padding: 5px; height: 700px; flex-shrink: 0;">
|
|
<div id="sms-preview"
|
|
style="font-size: 0.75rem; height: 100%; font-family: 'Malgun Gothic', sans-serif; overflow-y: auto; background: #fff; padding: 5px; border: 1px solid #ccc; border-radius: 4px; white-space: pre-wrap;">
|
|
</div>
|
|
</div>
|
|
<!-- SMS Options Group -->
|
|
<div class="glass-card sms-options">
|
|
<h3
|
|
style="border-bottom: 2px solid #3182ce; padding-bottom: 4px; margin-bottom: 12px; width: 100%; color: #2d3748; font-size: 1.1rem; background: transparent; box-shadow: none;">
|
|
📋알림 문자 계산 및 복사</h3>
|
|
<div class="chk-grid"
|
|
style="grid-template-columns: max-content max-content; justify-content: start; gap: 4px 15px; align-items: center;">
|
|
<label><input type="checkbox" id="sms-discount"> 5% 할인</label>
|
|
<label><input type="checkbox" id="sms-june-promo"> 금액별 추가상품</label>
|
|
<label><input type="checkbox" id="sms-ship-extra"> <span id="lbl-ship-extra">추가배송비
|
|
3,000원</span></label>
|
|
<label><input type="checkbox" id="sms-ship-free"> 무료배송</label>
|
|
<label><input type="checkbox" id="sms-coupon"> 6종 할인 쿠폰 적용</label>
|
|
<label style="display:flex; align-items:center;">적립금 <input type="text"
|
|
id="sms-point-deduction"
|
|
style="width: 70px; margin: 0 5px; text-align:right; font-size: 0.85rem;"
|
|
placeholder="0"> 차감</label>
|
|
</div>
|
|
<div class="action-buttons horizontal mt-1"
|
|
style="margin-top: 8px; display: flex; gap: 8px;">
|
|
<button id="btn-sms-calc" class="btn btn-primary block" style="flex: 1;">계산 & 내용
|
|
복사</button>
|
|
<button id="btn-reset" class="btn btn-danger"
|
|
style="flex: 0 0 auto; padding-left: 5px; padding-right: 5px; background:#e53e3e; white-space: nowrap;">초기화</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<!-- =========================
|
|
AUTO ORDER TAB
|
|
========================== -->
|
|
<section id="auto-order-tab" class="tab-content flex-layout"
|
|
style="padding: 20px; overflow-y: hidden; height: 100%; flex-direction: column;">
|
|
<header style="margin-bottom: 1.5rem; text-align: center; flex-shrink: 0;">
|
|
<h1 style="color: #fff; margin-bottom: 5px;">🔥 통합 자동발주 시스템</h1>
|
|
<p style="color: #e2e8f0; font-size: 1rem; margin: 0;">카페24 및 스마트스토어의 주문 내역을 한 곳에서 관리하세요.</p>
|
|
</header>
|
|
|
|
<div
|
|
style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; flex: 1; overflow: hidden;">
|
|
<!-- 좌측: 카페24 패널 -->
|
|
<div
|
|
style="flex: 1; display: flex; flex-direction: column; overflow-y: auto; background: rgba(30, 30, 30, 0.4); padding: 15px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.1);">
|
|
<h2
|
|
style="color: #fff; text-align: center; margin-bottom: 20px; border-bottom: 2px solid #555; padding-bottom: 10px;">
|
|
🛒 카페24 (자사몰)</h2>
|
|
|
|
<div class="glass-card download-section"
|
|
style="margin-bottom: 1rem; padding: 20px; background: rgba(30, 30, 30, 0.8) !important;">
|
|
<!-- 카페24 전용 기능(oauth 로그인 등 필요시 추가 가능) -->
|
|
<div
|
|
style="display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #a0aec0; padding-bottom: 10px; margin-bottom: 15px;">
|
|
<h2 style="font-size: 1.1rem; margin: 0; color: #fff; white-space: nowrap;">1. 신규 주문 내역
|
|
다운로드</h2>
|
|
<button id="cafe24AuthBtn" class="btn btn-secondary"
|
|
style="padding: 2px 6px; font-size: 0.7rem; background-color: #4a5568; color: white; border-radius: 4px; border: none; cursor: pointer; white-space: nowrap; margin-left: 5px;">
|
|
연동 (최초 1회)
|
|
</button>
|
|
</div>
|
|
<p style="margin-bottom: 15px; color: #cbd5e0;">배송준비중(N20) 상태인 자사몰 주문 내역을 다운로드합니다.</p>
|
|
|
|
<!-- 스마트스토어 토글 스위치 영역과 높이를 일치시키기 위한 투명 스페이서 -->
|
|
<div style="margin-bottom: 1rem; height: 26px; display: flex;"></div>
|
|
|
|
<button id="cafe24DownloadBtn" class="btn btn-primary btn-large"
|
|
style="width: 100%; display: flex; justify-content: center; align-items: center; gap: 10px; background-color: #2d3748;">
|
|
<span class="icon">⬇️</span> 카페24 주문 내역 다운로드 (Excel)
|
|
</button>
|
|
|
|
|
|
<div id="cafe24ProgressWrapper" class="hidden" style="margin-top: 15px;">
|
|
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
|
|
<span id="cafe24ProgressText" style="color: #cbd5e0; font-size: 0.9rem;">수집 준비
|
|
중...</span>
|
|
<span id="cafe24ProgressPercent"
|
|
style="color: #fff; font-weight: bold; font-size: 0.9rem;">0%</span>
|
|
</div>
|
|
<div
|
|
style="width: 100%; height: 10px; background-color: #4a5568; border-radius: 5px; overflow: hidden;">
|
|
<div id="cafe24ProgressBar"
|
|
style="width: 0%; height: 100%; background-color: #4299e1; transition: width 0.3s ease;">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="text-align: center; color: #fff; font-size: 2rem; margin: 0.5rem 0;">⬇</div>
|
|
|
|
<div class="glass-card upload-section"
|
|
style="margin-top: 0.5rem; padding: 20px; background: rgba(30, 30, 30, 0.8) !important;">
|
|
<div style="border-bottom: 2px solid #a0aec0; padding-bottom: 10px; margin-bottom: 15px;">
|
|
<h2 style="font-size: 1.2rem; margin: 0; color: #fff;">2. 송장 일괄 등록</h2>
|
|
</div>
|
|
<p style="margin-bottom: 15px; color: #cbd5e0;">송장번호가 입력된 엑셀 파일을 업로드합니다.</p>
|
|
|
|
<form id="cafe24UploadForm">
|
|
<div style="margin-bottom: 15px;">
|
|
<label for="cafe24DeliveryCompany"
|
|
style="display: block; font-weight: bold; margin-bottom: 5px; color: #fff;">택배사
|
|
선택</label>
|
|
<select id="cafe24DeliveryCompany" name="deliveryCompanyCode"
|
|
style="width: 100%; padding: 10px; border-radius: 4px; border: 1px solid #718096; background: #2d3748; color: white;">
|
|
<option value="0004" selected>CJ대한통운</option>
|
|
<option value="0005">한진택배</option>
|
|
<option value="0002">우체국택배</option>
|
|
<option value="0001">롯데택배</option>
|
|
<option value="0010">로젠택배</option>
|
|
<option value="0023">경동택배</option>
|
|
<option value="0003">대신택배</option>
|
|
<option value="0039">우체국EMS</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="file-drop-area" id="cafe24FileDropArea"
|
|
style="background: rgba(255,255,255,0.05); border-color: #718096;">
|
|
<span class="file-msg" id="cafe24FileMsg" style="color:#cbd5e0;">엑셀 파일을 이곳에 드래그하거나
|
|
클릭하여 업로드하세요. (.xls, .xlsx)</span>
|
|
<input type="file" id="cafe24InvoiceFile" name="file" accept=".xls,.xlsx" required
|
|
style="display:none;">
|
|
</div>
|
|
|
|
<button type="submit" id="cafe24UploadBtn" class="btn btn-secondary btn-large"
|
|
style="width: 100%; display: flex; justify-content: center; align-items: center; gap: 10px; background-color: #4a5568; margin-top: 15px; color: white;"
|
|
disabled>
|
|
<span class="icon">🚀</span> 송장 일괄 발송처리
|
|
</button>
|
|
<div id="cafe24UploadSpinner" class="spinner hidden"
|
|
style="border-color: #cbd5e0; border-top-color: transparent;"></div>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="cafe24ResultBox" class="result-box hidden"
|
|
style="margin-top: 15px; padding: 15px; border-radius: 4px;">
|
|
<h3 id="cafe24ResultTitle" style="margin-top: 0; color: #fff;">결과</h3>
|
|
<p id="cafe24ResultText" style="margin-bottom: 0; color: #fff;"></p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 우측: 스마트스토어 패널 -->
|
|
<div
|
|
style="flex: 1; display: flex; flex-direction: column; overflow-y: auto; background: rgba(3, 199, 90, 0.1); padding: 15px; border-radius: 12px; border: 1px solid rgba(3, 199, 90, 0.3);">
|
|
<h2
|
|
style="color: #fff; text-align: center; margin-bottom: 20px; border-bottom: 2px solid #03c75a; padding-bottom: 10px;">
|
|
🟩 스마트스토어</h2>
|
|
|
|
<div class="glass-card download-section" style="margin-bottom: 1rem; padding: 20px;">
|
|
<div
|
|
style="display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #3182ce; padding-bottom: 10px; margin-bottom: 15px;">
|
|
<h2 style="font-size: 1.2rem; margin: 0; color: #000;">1. 신규 주문 내역 다운로드</h2>
|
|
<div
|
|
style="background-color: #e53e3e; color: white; padding: 4px 10px; border-radius: 20px; font-size: 0.8rem; font-weight: bold;">
|
|
발주확인 요망</div>
|
|
</div>
|
|
<p style="margin-bottom: 15px; color: #4a5568;">결제완료 상태인 주문 내역을 다운로드합니다.</p>
|
|
|
|
<div
|
|
style="margin-bottom: 1rem; display: flex; align-items: center; justify-content: flex-end;">
|
|
<label for="confirmToggle"
|
|
style="margin-right: 0.5rem; font-weight: 500; font-size: 0.95rem; color: #555;">다운로드
|
|
시 발주확인(배송준비중) 처리</label>
|
|
<div class="toggle-switch">
|
|
<input type="checkbox" id="confirmToggle">
|
|
<label for="confirmToggle" class="switch-label"></label>
|
|
</div>
|
|
</div>
|
|
|
|
<button id="downloadBtn" class="btn btn-primary btn-large"
|
|
style="width: 100%; display: flex; justify-content: center; align-items: center; gap: 10px; background-color: #03c75a;">
|
|
<span class="icon">⬇️</span> 스마트스토어 주문 내역 다운로드 (Excel)
|
|
</button>
|
|
|
|
<div id="smartstoreProgressWrapper" class="hidden" style="margin-top: 15px;">
|
|
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
|
|
<span id="smartstoreProgressText" style="color: #4a5568; font-size: 0.9rem;">수집 준비
|
|
중...</span>
|
|
<span id="smartstoreProgressPercent"
|
|
style="color: #000; font-weight: bold; font-size: 0.9rem;">0%</span>
|
|
</div>
|
|
<div
|
|
style="width: 100%; height: 10px; background-color: #cbd5e0; border-radius: 5px; overflow: hidden;">
|
|
<div id="smartstoreProgressBar"
|
|
style="width: 0%; height: 100%; background-color: #03c75a; transition: width 0.3s ease;">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="text-align: center; color: #fff; font-size: 2rem; margin: 0.5rem 0;">⬇</div>
|
|
|
|
<div class="glass-card upload-section" style="margin-top: 0.5rem; padding: 20px;">
|
|
<div style="border-bottom: 2px solid #3182ce; padding-bottom: 10px; margin-bottom: 15px;">
|
|
<h2 style="font-size: 1.2rem; margin: 0; color: #000;">2. 송장 일괄 등록</h2>
|
|
</div>
|
|
<p style="margin-bottom: 15px; color: #4a5568;">송장번호가 입력된 엑셀 파일을 업로드합니다.</p>
|
|
|
|
<form id="uploadForm">
|
|
<div style="margin-bottom: 15px;">
|
|
<label for="deliveryCompany"
|
|
style="display: block; font-weight: bold; margin-bottom: 5px; color: #000;">택배사
|
|
선택</label>
|
|
<select id="deliveryCompany" name="deliveryCompanyCode"
|
|
style="width: 100%; padding: 10px; border-radius: 4px; border: 1px solid #cbd5e0;">
|
|
<option value="CJGLS" selected>CJ대한통운</option>
|
|
<option value="HANJIN">한진택배</option>
|
|
<option value="LOTTE">롯데택배</option>
|
|
<option value="EPOST">우체국택배</option>
|
|
<option value="KGB">로젠택배</option>
|
|
<option value="CVSNET">편의점택배</option>
|
|
<option value="KDEX">경동택배</option>
|
|
<option value="DAESIN">대신택배</option>
|
|
<option value="ILYANGLOGIS">일양로지스</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="file-drop-area" id="fileDropArea">
|
|
<span class="file-msg">엑셀 파일을 이곳에 드래그하거나 클릭하여 업로드하세요. (.xls, .xlsx)</span>
|
|
<input type="file" id="invoiceFile" name="file" accept=".xls,.xlsx" required
|
|
style="display:none;">
|
|
</div>
|
|
|
|
<button type="submit" id="uploadBtn" class="btn btn-secondary btn-large"
|
|
style="width: 100%; display: flex; justify-content: center; align-items: center; gap: 10px; background-color: #3182ce; margin-top: 15px; color: white;"
|
|
disabled>
|
|
<span class="icon">🚀</span> 송장 일괄 발송처리
|
|
</button>
|
|
<div id="uploadSpinner" class="spinner hidden"></div>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="resultBox" class="result-box hidden"
|
|
style="margin-top: 15px; padding: 15px; border-radius: 4px;">
|
|
<h3 id="resultTitle" style="margin-top: 0;">결과</h3>
|
|
<p id="resultText" style="margin-bottom: 0;"></p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 3번째 패널 (준비 중) -->
|
|
<div
|
|
style="display: flex; flex-direction: column; justify-content: center; align-items: center; background: rgba(255, 255, 255, 0.02); border-radius: 12px; border: 2px dashed rgba(255, 255, 255, 0.15);">
|
|
<span
|
|
style="font-size: 18rem; color: rgba(255, 255, 255, 0.2); font-weight: bold; user-select: none; cursor: default; line-height: 1;">?</span>
|
|
<span
|
|
style="color: rgba(255, 255, 255, 0.5); font-size: 1.5rem; font-weight: 600; margin-top: 20px;">준비
|
|
중...</span>
|
|
</div>
|
|
|
|
<!-- 4번째 패널 (준비 중) -->
|
|
<div
|
|
style="display: flex; flex-direction: column; justify-content: center; align-items: center; background: rgba(255, 255, 255, 0.02); border-radius: 12px; border: 2px dashed rgba(255, 255, 255, 0.15);">
|
|
<span
|
|
style="font-size: 18rem; color: rgba(255, 255, 255, 0.2); font-weight: bold; user-select: none; cursor: default; line-height: 1;">?</span>
|
|
<span
|
|
style="color: rgba(255, 255, 255, 0.5); font-size: 1.5rem; font-weight: 600; margin-top: 20px;">준비
|
|
중...</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- =========================
|
|
MANUAL ORDER TAB
|
|
========================== -->
|
|
<section id="manual-tab" class="tab-content" style="padding: 0;">
|
|
<div style="padding: 10px 10px 0 10px; display: flex; justify-content: flex-end;">
|
|
<a href="https://docs.google.com/spreadsheets/d/1QxFtjDurPPZd8NmtXBy4XEUIzkf93aXD5Mlx5kB33xw/edit?gid=0#gid=0"
|
|
target="_blank" class="btn btn-secondary"
|
|
style="font-size: 0.8rem; background: #38a169; color: white; text-decoration: none; padding: 6px 12px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.2);">
|
|
새 창에서 구글 시트 직접 열기 (로그인 오류 시 클릭)
|
|
</a>
|
|
</div>
|
|
<div style="flex: 1; padding: 10px; padding-bottom: 0; position: relative;"
|
|
id="manual-iframe-container">
|
|
<div id="sheet-loader" class="sheet-loader-overlay" style="display: none;">
|
|
<div class="spinner"></div>
|
|
<p style="margin-top: 15px; font-weight: 600; color: #2b6cb0; font-size: 1.1rem;">구글 시트 아랫줄에 기록
|
|
중입니다...</p>
|
|
</div>
|
|
<iframe
|
|
src="https://docs.google.com/spreadsheets/d/1QxFtjDurPPZd8NmtXBy4XEUIzkf93aXD5Mlx5kB33xw/edit?gid=0#gid=0"
|
|
width="100%" height="100%"
|
|
style="border: none; border-radius: 8px; box-shadow: var(--card-shadow);"></iframe>
|
|
</div>
|
|
</section>
|
|
<!-- =========================
|
|
GIFT SETTINGS TAB
|
|
========================== -->
|
|
<section id="gift-tab" class="tab-content"
|
|
style="flex-wrap: wrap; flex-direction: row; padding: 15px; gap: 20px; position: relative;">
|
|
<div class="left-settings"
|
|
style="flex: 1; min-width: 400px; display: flex; flex-direction: column; height: 100%;">
|
|
<header>
|
|
<h1 style="color: #fff;">금액별 추가상품 설정</h1>
|
|
</header>
|
|
<div class="gift-settings-container scroll-area" id="gift-rules-container"
|
|
style="flex: 1; margin-top: 10px; gap: 10px;">
|
|
<!-- Rule cards injected via JS -->
|
|
</div>
|
|
</div>
|
|
<div class="right-settings"
|
|
style="display: flex; flex-direction: column; position: relative; height: 100%;">
|
|
<header>
|
|
<h1 style="color: #fff;">문자 메시지 설정</h1>
|
|
</header>
|
|
<div
|
|
style="background: rgba(255,255,255,0.85); border-radius: 8px; padding: 15px; width: 370px; height: 490px; max-width: 370px; max-height: 490px; box-sizing: border-box; flex-shrink: 0; margin-top: 10px; box-shadow: var(--card-shadow); display: flex; flex-direction: column; gap: 10px;">
|
|
<h3 style="color: #000; border-bottom: none; margin-bottom: 0;">머리말</h3>
|
|
<textarea id="sms-header-text"
|
|
style="width: 100%; height: 150px; border: 2px solid #e2e8f0; border-radius: 4px; resize: none; padding: 10px; font-size: 0.8rem;"></textarea>
|
|
<h3 style="color: #000; border-bottom: none; margin-bottom: 0;">꼬리말(입금 금액은 {최종금액} 으로 입력)</h3>
|
|
<textarea id="sms-footer-text"
|
|
style="width: 100%; flex: 1; border: 2px solid #e2e8f0; border-radius: 4px; resize: none; padding: 10px; font-size: 0.8rem;"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="third-settings"
|
|
style="display: flex; flex-direction: column; position: relative; height: 100%;">
|
|
<header>
|
|
<h1 style="color: #fff;">화면 폰트 및 배송비 설정</h1>
|
|
</header>
|
|
<div
|
|
style="background: rgba(255,255,255,0.85); border-radius: 8px; padding: 15px; width: 380px; box-sizing: border-box; flex-shrink: 0; margin-top: 10px; box-shadow: var(--card-shadow); display: flex; flex-direction: column; gap: 10px;">
|
|
<h3 style="color: #000; border-bottom: none; margin-bottom: 0;">폰트 선택</h3>
|
|
<div style="display: flex; gap: 5px;">
|
|
<select id="app-font-select"
|
|
style="width: 300px; max-width: 300px; border: 2px solid #e2e8f0; border-radius: 4px; padding: 6px; font-size: 0.85rem; text-overflow: ellipsis; white-space: nowrap;">
|
|
<option value="">로딩 중...</option>
|
|
</select>
|
|
<button id="btn-font-default" class="btn btn-secondary"
|
|
style="white-space: nowrap; padding: 6px 10px; border-radius: 4px;">기본값</button>
|
|
</div>
|
|
|
|
<h3 style="color: #000; border-bottom: none; margin-top: 15px; margin-bottom: 0;">배송비 설정</h3>
|
|
<div
|
|
style="display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; font-size: 0.95rem;">
|
|
<label
|
|
style="display: flex; justify-content: space-between; align-items: center; width: 230px;">
|
|
기본 배송비:
|
|
<div><input type="text" id="setting-ship-base"
|
|
style="width:100px; text-align:right; font-size: 0.85rem; padding: 4px;"
|
|
placeholder="3,500"> 원</div>
|
|
</label>
|
|
<label
|
|
style="display: flex; justify-content: space-between; align-items: center; width: 230px;">
|
|
추가 배송비:
|
|
<div><input type="text" id="setting-ship-extra"
|
|
style="width:100px; text-align:right; font-size: 0.85rem; padding: 4px;"
|
|
placeholder="3,000"> 원</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="settings-action-container" style="position: absolute; bottom: 20px; right: 20px; display: flex; gap: 10px;">
|
|
<button id="btn-gift-save" class="btn btn-primary"
|
|
style="padding: 10px 20px; font-size: 0.95rem; font-weight: bold; background: #3182ce; transition: background 0.3s ease;">설정
|
|
저장</button>
|
|
</div>
|
|
</section>
|
|
<!-- =========================
|
|
PRODUCT SETTINGS TAB
|
|
========================== -->
|
|
<section id="product-tab" class="tab-content flex-layout"
|
|
style="padding: 15px; height: 100%; position: relative;">
|
|
<header>
|
|
<h1 style="color: #fff;">상품 설정</h1>
|
|
</header>
|
|
<div id="product-groups-container"
|
|
style="flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 15px; margin-top: 10px; padding-bottom: 60px;">
|
|
<!-- Groups injected via JS -->
|
|
</div>
|
|
<div style="position: absolute; bottom: 20px; right: 20px; z-index: 10; display: flex; gap: 10px;">
|
|
<button id="btn-product-save" class="btn btn-primary"
|
|
style="padding: 10px 20px; font-size: 0.95rem; font-weight: bold; background: #3182ce; transition: background 0.3s ease; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">상품
|
|
설정 저장</button>
|
|
</div>
|
|
</section>
|
|
<!-- =========================
|
|
CODE SETTINGS TAB
|
|
========================== -->
|
|
<section id="code-tab" class="tab-content flex-layout"
|
|
style="padding: 15px; height: 100%; position: relative;">
|
|
<header>
|
|
<h1 style="color: #fff;">코드표 관리</h1>
|
|
</header>
|
|
<div class="code-split-container" style="display: flex; gap: 20px; flex: 1; overflow: hidden; margin-top: 10px;">
|
|
<!-- 단품 관리 영역 -->
|
|
<div class="glass-card"
|
|
style="flex: 0 0 560px; width: 560px; max-width: 560px; display: flex; flex-direction: column; overflow: hidden; padding: 15px;">
|
|
<div
|
|
style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
|
<h2 style="font-size: 1.2rem; color: #000000; margin: 0;">단품 코드</h2>
|
|
<button id="btn-add-single" class="btn btn-primary btn-sm"
|
|
style="background:#3182ce; padding: 5px 10px;">+ 새 단품 추가</button>
|
|
</div>
|
|
<div
|
|
style="flex: 1; overflow-y: auto; border: 1px solid #e2e8f0; border-radius: 4px; background: white;">
|
|
<table style="width: 100%; border-collapse: collapse; text-align: left; font-size: 0.9rem;">
|
|
<thead
|
|
style="position: sticky; top: 0; background: #ebf8ff; box-shadow: 0 1px 0 #e2e8f0; z-index: 10;">
|
|
<tr>
|
|
<th class="th-sortable" data-list="single" data-key="item_code"
|
|
style="padding: 10px; font-weight: 600; cursor:pointer; width: 100px; white-space: nowrap;">
|
|
아이템코드 <span class="sort-icon"
|
|
style="color:#3182ce; font-size:0.8rem;">▲</span></th>
|
|
<th class="th-sortable" data-list="single" data-key="sabangnet_code"
|
|
style="padding: 10px; font-weight: 600; cursor:pointer; width: 105px; white-space: nowrap;">
|
|
사방넷 코드 <span class="sort-icon"
|
|
style="color:#e2e8f0; font-size:0.8rem;">↕</span></th>
|
|
<th class="th-sortable" data-list="single" data-key="name"
|
|
style="padding: 10px; font-weight: 600; cursor:pointer; white-space: nowrap;">
|
|
이름 <span class="sort-icon" style="color:#e2e8f0; font-size:0.8rem;">↕</span>
|
|
</th>
|
|
<th style="padding: 10px; text-align: right; width: 60px;">관리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="single-items-tbody">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<!-- 세트 관리 영역 -->
|
|
<div class="glass-card"
|
|
style="flex: 1; display: flex; flex-direction: column; overflow: hidden; padding: 15px;">
|
|
<div
|
|
style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
|
<h2 style="font-size: 1.2rem; color: #000000; margin: 0;">세트 코드</h2>
|
|
<button id="btn-add-set" class="btn btn-accent btn-sm"
|
|
style="background:#ed8936; padding: 5px 10px;">+ 새 세트 추가</button>
|
|
</div>
|
|
<div
|
|
style="flex: 1; overflow-y: auto; border: 1px solid #e2e8f0; border-radius: 4px; background: white;">
|
|
<table style="width: 100%; border-collapse: collapse; text-align: left; font-size: 0.9rem;">
|
|
<thead
|
|
style="position: sticky; top: 0; background: #fffaf0; box-shadow: 0 1px 0 #e2e8f0; z-index: 10;">
|
|
<tr>
|
|
<th class="th-sortable" data-list="set" data-key="item_code"
|
|
style="padding: 10px; font-weight: 600; cursor:pointer; width: 100px; white-space: nowrap;">
|
|
아이템코드 <span class="sort-icon"
|
|
style="color:#3182ce; font-size:0.8rem;">▲</span></th>
|
|
<th class="th-sortable" data-list="set" data-key="name"
|
|
style="padding: 10px; font-weight: 600; cursor:pointer; white-space: nowrap;">
|
|
세트 이름 <span class="sort-icon"
|
|
style="color:#e2e8f0; font-size:0.8rem;">↕</span></th>
|
|
<th style="padding: 10px; font-weight: 600;">
|
|
구성 단품 목록</th>
|
|
<th style="padding: 10px; text-align: right; width: 60px;">관리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="set-items-tbody">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- =========================
|
|
RETURN MANAGEMENT TAB
|
|
========================== -->
|
|
<section id="return-tab" class="tab-content flex-layout"
|
|
style="padding: 15px; height: 100%; position: relative;">
|
|
<header>
|
|
<h1 style="color: #fff;">반품관리 (반품 신청 및 입고 처리)</h1>
|
|
</header>
|
|
<div class="return-split-container" style="display: flex; gap: 20px; flex: 1; overflow: hidden; margin-top: 10px;">
|
|
<!-- 반품 신청 (좌측 50%) -->
|
|
<div class="glass-card"
|
|
style="flex: 1; display: flex; flex-direction: column; overflow: hidden; padding: 15px;">
|
|
<!-- 반품 신청 폼 -->
|
|
<form id="form-return-request"
|
|
style="margin-bottom: 15px; display: flex; flex-direction: column;">
|
|
<div
|
|
style="display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #3182ce; padding-bottom: 5px; margin-bottom: 15px;">
|
|
<h2 style="font-size: 1.2rem; color: #000000; margin: 0; display: flex; align-items: center; gap: 8px;">
|
|
📋 반품 신청
|
|
<button type="button" class="btn-detail-toggle" onclick="this.closest('form').classList.toggle('show-details'); this.textContent = this.closest('form').classList.contains('show-details') ? '접기 ▲' : '상세 ▼';">상세 ▼</button>
|
|
</h2>
|
|
<div style="display: flex; gap: 5px;">
|
|
<button type="button" id="btn-email-req" class="btn btn-secondary"
|
|
style="height: 40px; background: #ed8936; color: white; font-size: 0.8rem; padding: 0 10px; border:none; border-radius:4px; cursor:pointer; display: flex; align-items: center; justify-content: center; gap: 4px;">
|
|
<span style="font-size: 1.4rem;">📧</span> 반품 신청하기
|
|
</button>
|
|
<button type="submit" class="btn btn-primary"
|
|
style="width: 110px; height: 40px; background: #3182ce; font-size: 0.8rem; padding: 0;">반품
|
|
신청 등록</button>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" id="req-id">
|
|
<div style="display: flex; flex-direction: column; gap: 10px;">
|
|
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
|
|
<div class="form-group" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">송장번호 <span
|
|
style="color:#e53e3e">*</span></label>
|
|
<input type="text" id="req-tracking-no" placeholder="입력 후 Enter" required
|
|
style="border: 2px solid #3182ce; width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box;">
|
|
</div>
|
|
<div class="form-group mobile-hide" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">신청날짜</label>
|
|
<input type="date" id="req-date" required
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box;">
|
|
</div>
|
|
<div class="form-group mobile-hide" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">쇼핑몰</label>
|
|
<input type="text" id="req-mall" readonly
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; background-color: #edf2f7; cursor: not-allowed; color: #4a5568;">
|
|
</div>
|
|
<div class="form-group" style="margin-bottom: 0; width: 100px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">신청구분</label>
|
|
<select id="req-type" required
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; border: 1px solid #cbd5e0; border-radius: 4px;">
|
|
<option value="단순변심">단순변심</option>
|
|
<option value="상품불량">상품불량</option>
|
|
<option value="오배송">오배송</option>
|
|
<option value="파손">파손</option>
|
|
<option value="맞교환">맞교환</option>
|
|
<option value="기타">기타</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="mobile-hide" style="display: flex; gap: 10px; flex-wrap: wrap;">
|
|
<div class="form-group" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">수령인명</label>
|
|
<input type="text" id="req-name" required readonly
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; background-color: #edf2f7; cursor: not-allowed; color: #4a5568;">
|
|
</div>
|
|
<div class="form-group" style="margin-bottom: 0; width: 145px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">휴대폰번호</label>
|
|
<input type="text" id="req-phone" readonly
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; background-color: #edf2f7; cursor: not-allowed; color: #4a5568;">
|
|
</div>
|
|
<div class="form-group" style="margin-bottom: 0; flex: 1;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">주소</label>
|
|
<input type="text" id="req-address" readonly
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; background-color: #edf2f7; cursor: not-allowed; color: #4a5568;">
|
|
</div>
|
|
</div>
|
|
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
|
|
<div class="form-group" style="margin-bottom: 0; flex: 1;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">비고</label>
|
|
<input type="text" id="req-remarks" placeholder="참고사항 입력"
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box;">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- 반품 신청 리스트 표기 -->
|
|
<h3
|
|
style="font-size: 0.75rem; margin-bottom: 5px; display: flex; justify-content: space-between; align-items: center;">
|
|
<span>신청 목록</span><label
|
|
style="cursor: pointer; font-weight: normal; margin: 0; display:flex; align-items:center; gap:4px;"><input
|
|
type="checkbox" id="chk-exclude-received"> 입고완료 제외</label>
|
|
</h3>
|
|
<div
|
|
style="flex: 1; overflow: auto; border: 1px solid #e2e8f0; border-radius: 4px; background: white;">
|
|
<table
|
|
style="width: 100%; min-width: 780px; table-layout: fixed; border-collapse: collapse; text-align: left; font-size: 0.75rem;">
|
|
<thead
|
|
style="position: sticky; top: 0; background: #ebf8ff; box-shadow: 0 1px 0 #e2e8f0; z-index: 10;">
|
|
<tr>
|
|
<th style="padding: 8px; width: 30px; text-align: center;"><input
|
|
type="checkbox" id="chk-all-req"></th>
|
|
<th style="padding: 8px; width: 100px; text-align: center; white-space: nowrap;">날짜</th>
|
|
<th style="padding: 8px; width: 90px; text-align: center; white-space: nowrap;">수령인</th>
|
|
<th style="padding: 8px; width: 130px; text-align: center; white-space: nowrap;">휴대폰번호</th>
|
|
<th style="padding: 8px; width: 110px; text-align: center; white-space: nowrap;">송장번호</th>
|
|
<th style="padding: 8px; width: 65px; text-align: center; white-space: nowrap;">상태</th>
|
|
<th style="padding: 8px; width: 215px; text-align: center; white-space: nowrap;">비고</th>
|
|
<th style="padding: 8px; width: 40px; text-align: center; white-space: nowrap;">관리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="tbody-return-requests">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 반품 입고 (우측 50%) -->
|
|
<div class="glass-card"
|
|
style="flex: 1; display: flex; flex-direction: column; overflow: hidden; padding: 15px;">
|
|
<!-- 반품 입고 폼 -->
|
|
<form id="form-return-receive" data-edit="true" style="margin-bottom: 15px;">
|
|
<div
|
|
style="display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #38a169; padding-bottom: 5px; margin-bottom: 15px;">
|
|
<h2 style="font-size: 1.2rem; color: #000000; margin: 0; display: flex; align-items: center; gap: 8px;">
|
|
📦 반품 입고
|
|
<button type="button" class="btn-detail-toggle" onclick="this.closest('form').classList.toggle('show-details'); this.textContent = this.closest('form').classList.contains('show-details') ? '접기 ▲' : '상세 ▼';">상세 ▼</button>
|
|
</h2>
|
|
<div style="display: flex; gap: 5px;">
|
|
<button type="button" id="btn-bulk-receive" class="btn btn-secondary"
|
|
style="width: 110px; height: 40px; background: #4a5568; color: white; font-size: 0.8rem; padding: 0;">송장일괄
|
|
입고</button>
|
|
<button type="submit" class="btn btn-primary"
|
|
style="width: 110px; height: 40px; background: #38a169; font-size: 0.8rem; padding: 0;">반품
|
|
입고 등록</button>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" id="rec-id">
|
|
<div style="display: flex; flex-direction: column; gap: 10px;">
|
|
<!-- Line 1 -->
|
|
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
|
|
<div class="form-group" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">송장번호 <span
|
|
style="color:#e53e3e">*</span></label>
|
|
<input type="text" id="rec-tracking-no" placeholder="입력 후 Enter" required
|
|
style="border: 2px solid #38a169; width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box;">
|
|
</div>
|
|
<div class="form-group mobile-hide" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">입고날짜</label>
|
|
<input type="date" id="rec-date" required
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box;">
|
|
</div>
|
|
<div class="form-group mobile-hide" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">쇼핑몰</label>
|
|
<input type="text" id="rec-mall" readonly
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; background-color: #edf2f7; cursor: not-allowed; color: #4a5568;">
|
|
</div>
|
|
<div class="form-group" style="margin-bottom: 0; width: 120px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">입고상태</label>
|
|
<select id="rec-status" required
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; border: 1px solid #cbd5e0; border-radius: 4px;">
|
|
<option value="대기" selected>대기</option>
|
|
<option value="환불대기">환불대기</option>
|
|
<option value="환불완료">환불완료</option>
|
|
<option value="교환완료">교환완료</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<!-- Line 2 -->
|
|
<div class="mobile-hide" style="display: flex; gap: 10px; flex-wrap: wrap;">
|
|
<div class="form-group" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">이름</label>
|
|
<input type="text" id="rec-name" required readonly
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; background-color: #edf2f7; cursor: not-allowed; color: #4a5568;">
|
|
</div>
|
|
<div class="form-group" style="margin-bottom: 0; width: 135px;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">휴대폰번호</label>
|
|
<input type="text" id="rec-phone" readonly
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; background-color: #edf2f7; cursor: not-allowed; color: #4a5568;">
|
|
</div>
|
|
<div class="form-group" style="margin-bottom: 0; flex: 1;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">주소</label>
|
|
<input type="text" id="rec-address" readonly
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box; border: 1px solid #cbd5e0; border-radius: 4px; background-color: #edf2f7; cursor: not-allowed; color: #4a5568;">
|
|
</div>
|
|
</div>
|
|
<!-- Line 3 -->
|
|
<div style="display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;">
|
|
<div class="form-group" style="margin-bottom: 0; flex: 1;">
|
|
<label style="font-weight: 600; font-size: 0.8rem;">비고</label>
|
|
<input type="text" id="rec-remarks" placeholder="환불 처리 여부 등"
|
|
style="width: 100%; height: 26px; padding: 2px 5px; font-size: 0.85rem; box-sizing: border-box;">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- 송장일괄 입고 모달 -->
|
|
<div id="bulk-receive-modal"
|
|
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center;">
|
|
<div
|
|
style="background: white; padding: 20px; border-radius: 8px; width: 325px; display: flex; flex-direction: column; gap: 15px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
|
|
<h3 style="margin: 0; font-size: 1.2rem; color: #2d3748;">송장일괄 입고</h3>
|
|
<div style="display: flex; align-items: center; justify-content: space-between;">
|
|
<span style="font-size: 0.9rem; font-weight: bold; color: #2d3748; line-height: 1.4;">
|
|
송장 앞 숫자 4자리 <input type="text" id="bulk-prefix-input" style="width: 45px; text-align: center; border: 1px solid #cbd5e0; border-radius: 4px; padding: 2px; font-size: 0.9rem; margin: 0 4px;" maxlength="4">를<br>제외하고 입력 하세요.
|
|
</span>
|
|
<button type="button" id="btn-bulk-prefix-save" class="btn btn-secondary" style="padding: 4px 12px; font-size: 0.9rem; background: #4a5568; color: white; white-space: nowrap; border: none;">설정</button>
|
|
</div>
|
|
<textarea id="bulk-tracking-numbers"
|
|
style="width: 100%; height: 200px; padding: 10px; border: 1px solid #cbd5e0; border-radius: 4px; resize: vertical; font-family: monospace;"
|
|
placeholder="56789012 54321098"></textarea>
|
|
<div style="display: flex; justify-content: flex-end; gap: 10px;">
|
|
<button type="button" id="btn-bulk-cancel" class="btn btn-secondary"
|
|
style="padding: 8px 16px;">취소</button>
|
|
<button type="button" id="btn-bulk-submit" class="btn btn-primary"
|
|
style="padding: 8px 16px; background: #3182ce;">일괄 등록</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 반품 입고 리스트 표기 -->
|
|
<h3
|
|
style="font-size: 0.75rem; margin-bottom: 5px; display: flex; justify-content: space-between; align-items: center;">
|
|
<span>입고 목록</span><label
|
|
style="cursor: pointer; font-weight: normal; margin: 0; display:flex; align-items:center; gap:4px;"><input
|
|
type="checkbox" id="chk-exclude-completed"> 환불/교환완료 제외</label>
|
|
</h3>
|
|
<div
|
|
style="flex: 1; overflow: auto; border: 1px solid #e2e8f0; border-radius: 4px; background: white;">
|
|
<table
|
|
style="width: 100%; min-width: 780px; table-layout: fixed; border-collapse: collapse; text-align: left; font-size: 0.75rem;">
|
|
<thead
|
|
style="position: sticky; top: 0; background: #f0fff4; box-shadow: 0 1px 0 #e2e8f0; z-index: 10;">
|
|
<tr>
|
|
<th
|
|
style="padding: 8px; width: 100px; text-align: center; white-space: nowrap;">
|
|
입고날짜</th>
|
|
<th style="padding: 8px; width: 90px; text-align: center; white-space: nowrap;">
|
|
수령인</th>
|
|
<th
|
|
style="padding: 8px; width: 130px; text-align: center; white-space: nowrap;">
|
|
휴대폰번호</th>
|
|
<th
|
|
style="padding: 8px; width: 110px; text-align: center; white-space: nowrap;">
|
|
송장번호</th>
|
|
<th style="padding: 8px; width: 85px; text-align: center; white-space: nowrap;">
|
|
쇼핑몰</th>
|
|
<th style="padding: 8px; width: 65px; text-align: center; white-space: nowrap;">
|
|
입고상태</th>
|
|
<th style="padding: 8px; width: 160px; text-align: center; white-space: nowrap;">비고</th>
|
|
<th style="padding: 8px; width: 40px; text-align: center; white-space: nowrap;">
|
|
관리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="tbody-return-receivings">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<!-- =========================
|
|
VERSION HISTORY TAB
|
|
========================== -->
|
|
{% include 'version_history.html' %}
|
|
</main>
|
|
</div>
|
|
<script src="{{ root_path }}/static/js/app.js?v=30"></script>
|
|
|
|
<!-- Toast Notification -->
|
|
<div id="toast-notification"
|
|
style="position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.8); color: white; padding: 10px 20px; border-radius: 5px; font-size: 0.9rem; z-index: 1000; opacity: 0; transition: opacity 0.3s; pointer-events: none;">
|
|
클립보드로 주문 내용이 복사되었습니다.
|
|
</div>
|
|
|
|
<!-- Exclusion Modal -->
|
|
<div id="exclude-modal"
|
|
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 2000; align-items: center; justify-content: center;">
|
|
<div class="glass-card"
|
|
style="background: #fff; width: 450px; padding: 25px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.3); max-width: 90%;">
|
|
<h3
|
|
style="margin-top: 0; color: #2b6cb0; border-bottom: 2px solid #3182ce; padding-bottom: 8px; margin-bottom: 15px;">
|
|
🛒 발주 입력 확인</h3>
|
|
<p style="font-size: 0.95rem; color: #4a5568; line-height: 1.4;">아래 상품 중에서 총 금액 계산에서 <br><strong
|
|
style="color:#e53e3e;">제외할 상품을 선택</strong> 하고 [입력] 버튼을 눌러주세요.</p>
|
|
<div id="exclude-items-list"
|
|
style="max-height: 300px; overflow-y: auto; margin: 15px 0; border: 1px solid #e2e8f0; border-radius: 4px; padding: 10px; background: #f7fafc; display: flex; flex-direction: column; gap: 8px;">
|
|
<!-- checkboxes injected here -->
|
|
</div>
|
|
<div
|
|
style="font-size: 1.1rem; font-weight: bold; text-align: right; color: #2d3748; padding-bottom: 15px; border-bottom: 1px dashed #cbd5e0; margin-bottom: 10px;">
|
|
최종 금액: <span id="exclude-modal-totalAmount" style="color: #e53e3e;">0</span>원
|
|
</div>
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-top: 10px;">
|
|
<label
|
|
style="font-weight: bold; color: #3182ce; display: flex; align-items: center; gap: 5px; cursor: pointer; font-size: 0.95rem;">
|
|
<input type="checkbox" id="chk-sample-send" style="transform: scale(1.2); cursor: pointer;"> 샘플 발송
|
|
</label>
|
|
<div style="display: flex; justify-content: flex-end; gap: 10px;">
|
|
<button id="btn-exclude-cancel" class="btn btn-secondary" style="padding: 8px 16px;">취소</button>
|
|
<button id="btn-exclude-submit" class="btn btn-primary"
|
|
style="padding: 8px 16px; background: #3182ce;">입력</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Code Single Item Modal -->
|
|
<div id="single-item-modal"
|
|
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 2000; align-items: center; justify-content: center;">
|
|
<div class="glass-card"
|
|
style="background: #fff; width: 400px; padding: 25px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.3); max-width: 90%;">
|
|
<h3 id="modal-single-title"
|
|
style="margin-top: 0; color: #2b6cb0; border-bottom: 2px solid #3182ce; padding-bottom: 8px; margin-bottom: 15px;">
|
|
📦 단품 추가</h3>
|
|
<div style="display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px;">
|
|
<label style="display: flex; flex-direction: column; font-size: 0.9rem; font-weight: bold;">
|
|
단품 아이템 코드
|
|
<input type="text" id="sin-item-code"
|
|
style="padding: 8px; border: 1px solid #cbd5e0; border-radius: 4px; margin-top: 4px;"
|
|
placeholder="예: ITEM_001">
|
|
<span id="sin-item-warn"
|
|
style="color: #e53e3e; font-size: 0.8rem; margin-top: 4px; display: none;">⚠️ 이미 존재하는 단품
|
|
코드입니다!</span>
|
|
</label>
|
|
<label style="display: flex; flex-direction: column; font-size: 0.9rem; font-weight: bold;">
|
|
사방넷 코드 (형식: XXXXXX-0001)
|
|
<input type="text" id="sin-sabangnet-code"
|
|
style="padding: 8px; border: 1px solid #cbd5e0; border-radius: 4px; margin-top: 4px;"
|
|
placeholder="102845-0001">
|
|
</label>
|
|
<label style="display: flex; flex-direction: column; font-size: 0.9rem; font-weight: bold;">
|
|
단품 이름
|
|
<input type="text" id="sin-name"
|
|
style="padding: 8px; border: 1px solid #cbd5e0; border-radius: 4px; margin-top: 4px;"
|
|
placeholder="상품 이름">
|
|
</label>
|
|
</div>
|
|
<div style="display: flex; justify-content: flex-end; gap: 10px;">
|
|
<button id="btn-sin-cancel" class="btn btn-secondary" style="padding: 8px 16px;">취소</button>
|
|
<button id="btn-sin-save" class="btn btn-primary"
|
|
style="padding: 8px 16px; background: #3182ce;">저장</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Code Set Item Modal -->
|
|
<div id="set-item-modal"
|
|
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 2000; align-items: center; justify-content: center;">
|
|
<div class="glass-card"
|
|
style="background: #fff; width: 550px; padding: 25px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.3); max-width: 90%;">
|
|
<h3 id="modal-set-title"
|
|
style="margin-top: 0; color: #dd6b20; border-bottom: 2px solid #ed8936; padding-bottom: 8px; margin-bottom: 15px;">
|
|
🍱 세트 추가</h3>
|
|
<div style="display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px;">
|
|
<div style="display: flex; gap: 10px;">
|
|
<label
|
|
style="display: flex; flex-direction: column; font-size: 0.9rem; font-weight: bold; flex: 1;">
|
|
세트 아이템 코드
|
|
<input type="text" id="set-item-code"
|
|
style="padding: 8px; border: 1px solid #cbd5e0; border-radius: 4px; margin-top: 4px;"
|
|
placeholder="예: SET_001">
|
|
<span id="set-item-warn"
|
|
style="color: #e53e3e; font-size: 0.8rem; margin-top: 4px; display: none;">⚠️ 이미 존재하는 세트
|
|
코드입니다!</span>
|
|
</label>
|
|
<label
|
|
style="display: flex; flex-direction: column; font-size: 0.9rem; font-weight: bold; flex: 1;">
|
|
세트 이름
|
|
<input type="text" id="set-name"
|
|
style="padding: 8px; border: 1px solid #cbd5e0; border-radius: 4px; margin-top: 4px;"
|
|
placeholder="세트 이름">
|
|
</label>
|
|
</div>
|
|
|
|
<hr style="border: 0; border-top: 1px dashed #cbd5e0;">
|
|
<div style="margin-top: 5px;">
|
|
<h4 style="margin:0 0 10px 0; color:#4a5568; font-size: 0.95rem;">세트 구성품 등록</h4>
|
|
<div id="set-components-wrapper"
|
|
style="display:flex; flex-direction:column; gap:8px; max-height: 200px; overflow-y:auto; padding:5px; border:1px solid #e2e8f0; border-radius:4px; background:#f7fafc;">
|
|
<!-- components rows go here -->
|
|
</div>
|
|
<button id="btn-add-set-component" class="btn btn-secondary btn-sm"
|
|
style="margin-top: 8px; width: 100%; border: 1px dashed #a0aec0; background: transparent; color: #4a5568;">+단품
|
|
추가</button>
|
|
</div>
|
|
|
|
</div>
|
|
<div style="display: flex; justify-content: flex-end; gap: 10px;">
|
|
<button id="btn-set-cancel" class="btn btn-secondary" style="padding: 8px 16px;">취소</button>
|
|
<button id="btn-set-save" class="btn btn-accent"
|
|
style="padding: 8px 16px; background: #ed8936;">저장</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 업데이트 알림 모달 -->
|
|
<div id="update-notice-modal"
|
|
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 9999; align-items: center; justify-content: center;">
|
|
<div
|
|
style="background: white; padding: 30px; border-radius: 12px; width: 450px; display: flex; flex-direction: column; gap: 20px; box-shadow: 0 10px 25px rgba(0,0,0,0.2);">
|
|
<div
|
|
style="display: flex; align-items: center; gap: 10px; border-bottom: 2px solid #3182ce; padding-bottom: 10px;">
|
|
<span style="font-size: 1.8rem;">🎉</span>
|
|
<h3 style="margin: 0; font-size: 1.4rem; color: #2b6cb0;">업데이트 안내</h3>
|
|
</div>
|
|
|
|
<p style="font-size: 1.1rem; margin: 0; color: #2d3748; line-height: 1.6;">
|
|
프로그램이 <strong style="color: #e53e3e; font-size: 1.2rem;" id="update-notice-version"></strong> 버전으로 업데이트
|
|
되었습니다.<br><br>
|
|
<strong>Ver History</strong>에서 내용을 확인 해주세요!!
|
|
</p>
|
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-top: 10px;">
|
|
<label
|
|
style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: #4a5568; font-size: 0.95rem;">
|
|
<input type="checkbox" id="chk-hide-update-notice" style="width: 16px; height: 16px;">
|
|
다시는 메시지 보지 않기
|
|
</label>
|
|
<button type="button" id="btn-close-update-notice" class="btn btn-primary"
|
|
style="padding: 10px 24px; background: #3182ce; font-size: 1rem; border-radius: 6px; cursor: pointer; color: white; border: none;">확인</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
|
|
</html> |