183 lines
6.0 KiB
PHP
183 lines
6.0 KiB
PHP
<section class="card month">
|
|
<div class="card-header">
|
|
<h3>11월 판매 실적<span class="tail"></span></h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="stat-row month">
|
|
<div class="label-box">
|
|
<span class="label">당월 판매수</span>
|
|
<!-- <span class="change-down">전주대비 <em>114</em></span> -->
|
|
</div>
|
|
<div>
|
|
<span class="big-num" id="month_sales_value">0</span><span class="unit copy">copy</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stat-row">
|
|
<div class="label-box">
|
|
<span class="label">당월 매출액</span>
|
|
<!-- <span class="change">전주대비 <em>0</em></span> -->
|
|
</div>
|
|
<div><span class="big-num" id="month_amount_value">0</span><span class="unit">만원</span></div>
|
|
</div>
|
|
|
|
<div class="stat-row">
|
|
<div class="label-box">
|
|
<span class="label">목표 달성률</span>
|
|
<!-- <span class="change-up">전주대비 <em>3p</em></span> -->
|
|
</div>
|
|
<div><span class="big-num" id="month_rate_value">0</span><span class="unit">%</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="chart-wrap">
|
|
<div class="chart-header">
|
|
<!-- <span class="badge-month">목표 125</span> -->
|
|
<div class="legend">
|
|
<span class="unit">(단위:copy) </span>
|
|
</div>
|
|
</div>
|
|
<div class="chart-body">
|
|
<canvas id="weekly_chart"></canvas>
|
|
<div id="weekly_legend"></div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
(() => {
|
|
let weeklyInstance = null;
|
|
|
|
// ------------------------------
|
|
// 1) 초기값 (0으로 먼저 렌더)
|
|
// ------------------------------
|
|
let cumulative = [0, 0, 0, 0, 0];
|
|
let goal = 0;
|
|
|
|
// ------------------------------
|
|
// 📌 현재 월 텍스트로 변경
|
|
// ------------------------------
|
|
const now = new Date();
|
|
const month = now.getMonth() + 1;
|
|
const monthText = `${month}월 판매 실적`;
|
|
|
|
document.querySelector(".card.month .card-header h3").innerHTML =
|
|
monthText + '<span class="tail"></span>';
|
|
|
|
// ------------------------------
|
|
// 📌 오늘 날짜 기준 몇 주차인지 계산
|
|
// ------------------------------
|
|
function getWeekOfMonth(date = new Date()) {
|
|
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
|
|
|
|
// 월요일 기준 (월=1, 일=7)
|
|
const firstDayOfWeek = firstDay.getDay() === 0 ? 7 : firstDay.getDay();
|
|
const offset = firstDayOfWeek - 1;
|
|
|
|
return Math.floor((date.getDate() + offset) / 7);
|
|
}
|
|
|
|
const CURRENT_WEEK = getWeekOfMonth(); // 1~5
|
|
|
|
// ------------------------------
|
|
// 차트 생성 함수
|
|
// ------------------------------
|
|
function createMonthChart() {
|
|
const ctx = document.getElementById("weekly_chart");
|
|
if (!ctx) return;
|
|
|
|
if (weeklyInstance) weeklyInstance.destroy();
|
|
|
|
const total = cumulative.reduce((a, b) => a + b, 0);
|
|
const remaining = Math.max(0, goal - total);
|
|
|
|
weeklyInstance = new Chart(ctx, {
|
|
type: "doughnut",
|
|
data: {
|
|
labels: ["1주차", "2주차", "3주차", "4주차", "5주차", "남은 목표"],
|
|
datasets: [{
|
|
data: [...cumulative, remaining],
|
|
backgroundColor: [
|
|
"#FFD311", "#FFA808", "#F58C03",
|
|
"#E76C00", "#B65500", "#e1e1e1"
|
|
],
|
|
borderWidth: 2,
|
|
borderColor: "#fff",
|
|
circumference: 180,
|
|
rotation: 270,
|
|
}],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: { display: false },
|
|
tooltip: { enabled: false },
|
|
htmlLegend: {
|
|
containerID: "weekly_legend",
|
|
activeWeek: CURRENT_WEEK,
|
|
},
|
|
},
|
|
cutout: "45%",
|
|
layout: {
|
|
padding: { top: 20, bottom: 40, left: 40, right: 40 }
|
|
}
|
|
},
|
|
plugins: [htmlLegendPlugin, gaugeValuePlugin],
|
|
});
|
|
}
|
|
|
|
// ------------------------------
|
|
// 2) 초기 0 데이터로 차트 1회 렌더
|
|
// ------------------------------
|
|
createMonthChart();
|
|
|
|
// ------------------------------
|
|
// 3) 월간 데이터 로딩 함수 (🔥 핵심)
|
|
// ------------------------------
|
|
function loadMonthDashboardData() {
|
|
return fetch(`/egbim/bbs/sales_dashboard.php?year=${window.APP_YEAR}&_=${Date.now()}`)
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
|
|
// (1) 숫자 UI 반영
|
|
document.getElementById("month_sales_value").textContent =
|
|
data.month_sales ?? 0;
|
|
|
|
document.getElementById("month_amount_value").textContent =
|
|
Math.round(data.month_sales_amount / 10000);
|
|
|
|
document.getElementById("month_rate_value").textContent =
|
|
data.target_rate ?? 0;
|
|
|
|
// (2) 주차별 수량
|
|
const week = data.weekly || {};
|
|
cumulative = [
|
|
week[1] ?? 0,
|
|
week[2] ?? 0,
|
|
week[3] ?? 0,
|
|
week[4] ?? 0,
|
|
week[5] ?? 0,
|
|
];
|
|
|
|
// (3) 목표 수량
|
|
goal = data.target_qty ?? 0;
|
|
|
|
// (4) 차트 재렌더
|
|
createMonthChart();
|
|
});
|
|
console.log('월데이터 성공');
|
|
}
|
|
|
|
// ------------------------------
|
|
// 4) 전역 등록 + 최초 실행
|
|
// ------------------------------
|
|
window.loadMonthDashboardData = loadMonthDashboardData;
|
|
loadMonthDashboardData();
|
|
|
|
})();
|
|
</script>
|
|
|
|
|
|
|
|
|