parent
7fc1d826f2
commit
a8701ca5b0
|
|
@ -0,0 +1,6 @@
|
||||||
|
Options -Indexes
|
||||||
|
|
||||||
|
<Files "config.php">
|
||||||
|
Order Allow,Deny
|
||||||
|
Deny from all
|
||||||
|
</Files>
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
// =============================================
|
||||||
|
// GOI Dashboard API - 공통 설정
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
define('API_KEY', 'GOI_DASHBOARD_2026_SECRET');
|
||||||
|
|
||||||
|
function validateApiKey() {
|
||||||
|
$key = $_SERVER['HTTP_X_API_KEY'] ?? '';
|
||||||
|
if ($key !== API_KEY) {
|
||||||
|
http_response_code(401);
|
||||||
|
echo json_encode(['success' => false, 'error' => 'Unauthorized']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDB() {
|
||||||
|
// 효진님이 서버 배포 시 아래 정보를 실제 서버 DB 정보로 교체
|
||||||
|
$host = 'mis-mysql'; // 서버 배포 시 교체
|
||||||
|
$dbname = 'goiintra_db'; // 서버 배포 시 교체
|
||||||
|
$user = 'goiintra_root'; // 서버 배포 시 교체
|
||||||
|
$pass = 'L0C2CKN5GHHY'; // 서버 배포 시 교체
|
||||||
|
|
||||||
|
return new PDO(
|
||||||
|
"mysql:host=$host;dbname=$dbname;charset=utf8",
|
||||||
|
$user, $pass,
|
||||||
|
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsonResponse($data) {
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
header('Access-Control-Allow-Origin: *');
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
// =============================================
|
||||||
|
// GOI Dashboard API - Driver List
|
||||||
|
// GET /api/drivers.php
|
||||||
|
//
|
||||||
|
// Header:
|
||||||
|
// X-API-Key: GOI_DASHBOARD_2026_SECRET
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
require_once 'config.php';
|
||||||
|
validateApiKey();
|
||||||
|
|
||||||
|
$pdo = getDB();
|
||||||
|
|
||||||
|
// 활성 드라이버만 (dr_status = 'A')
|
||||||
|
$stmt = $pdo->query("
|
||||||
|
SELECT
|
||||||
|
dr_uid AS uid,
|
||||||
|
dr_firstname AS firstname,
|
||||||
|
dr_lastname AS lastname,
|
||||||
|
dr_initial AS initial,
|
||||||
|
dr_type AS type
|
||||||
|
FROM tbl_driver
|
||||||
|
WHERE dr_status = 'A'
|
||||||
|
ORDER BY dr_initial ASC
|
||||||
|
");
|
||||||
|
$drivers = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
jsonResponse([
|
||||||
|
'success' => true,
|
||||||
|
'count' => count($drivers),
|
||||||
|
'drivers' => $drivers
|
||||||
|
]);
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
<?php
|
||||||
|
// =============================================
|
||||||
|
// GOI Dashboard API - Order List (Full Version)
|
||||||
|
// GET /api/orders.php
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// date_from YYYYMMDD (default: today)
|
||||||
|
// date_to YYYYMMDD (default: today)
|
||||||
|
// driver d_drinitial e.g. M.K (optional)
|
||||||
|
//
|
||||||
|
// Header:
|
||||||
|
// X-API-Key: GOI_DASHBOARD_2026_SECRET
|
||||||
|
//
|
||||||
|
// Returns per driver per day:
|
||||||
|
// - Forecast / Actual / Achievement%
|
||||||
|
// - Total stops / Completed stops
|
||||||
|
// - Departure / Arrival time
|
||||||
|
// - Mileage start / finish
|
||||||
|
// - Opening Balance / Cash In / Cash Out
|
||||||
|
// - Cash Return / Gas / Extra / Total Balance
|
||||||
|
// - Driver comment
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
require_once 'config.php';
|
||||||
|
validateApiKey();
|
||||||
|
|
||||||
|
$pdo = getDB();
|
||||||
|
|
||||||
|
// 날짜 파라미터 (DB 형식: YYYYMMDD varchar)
|
||||||
|
$dateFrom = $_GET['date_from'] ?? date('Ymd');
|
||||||
|
$dateTo = $_GET['date_to'] ?? date('Ymd');
|
||||||
|
$driver = $_GET['driver'] ?? null;
|
||||||
|
|
||||||
|
// 날짜 형식 검증 (8자리 숫자)
|
||||||
|
if (!preg_match('/^\d{8}$/', $dateFrom) || !preg_match('/^\d{8}$/', $dateTo)) {
|
||||||
|
http_response_code(400);
|
||||||
|
jsonResponse(['success' => false, 'error' => 'Invalid date format. Use YYYYMMDD (e.g. 20260521)']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
// 메인 쿼리
|
||||||
|
// tbl_daily → 수거 데이터 (Forecast, Actual, Stops)
|
||||||
|
// tbl_member → 드라이버 조인 조건
|
||||||
|
// tbl_memberhis → 출퇴근/Cash 데이터 (LEFT JOIN: 없어도 수거 데이터는 나옴)
|
||||||
|
// =============================================
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
d.d_orderdate AS order_date,
|
||||||
|
d.d_druid AS driver_uid,
|
||||||
|
d.d_drinitial AS driver,
|
||||||
|
|
||||||
|
-- 수거 데이터
|
||||||
|
COUNT(*) AS total_stops,
|
||||||
|
COUNT(CASE WHEN d.d_status = 'F' THEN 1 END) AS completed_stops,
|
||||||
|
COALESCE(SUM(d.d_estquantity), 0) AS forecast,
|
||||||
|
COALESCE(SUM(d.d_quantity), 0) AS actual,
|
||||||
|
|
||||||
|
-- 출퇴근 시간 (tbl_memberhis)
|
||||||
|
h.h_departuretime AS departure,
|
||||||
|
h.h_arrivaltime AS arrival,
|
||||||
|
|
||||||
|
-- 마일리지 (tbl_memberhis)
|
||||||
|
h.h_mileage_s AS mileage_start,
|
||||||
|
h.h_mileage_f AS mileage_finish,
|
||||||
|
|
||||||
|
-- Cash 데이터 (tbl_memberhis)
|
||||||
|
COALESCE(h.h_balance_o, 0) AS opening_balance,
|
||||||
|
COALESCE(h.h_balance_in, 0) AS cash_in,
|
||||||
|
COALESCE(h.h_balance_out, 0) AS cash_out,
|
||||||
|
COALESCE(h.h_balance_r, 0) AS cash_return,
|
||||||
|
COALESCE(h.h_balance_g, 0) AS gas,
|
||||||
|
COALESCE(h.h_balance_e, 0) AS extra,
|
||||||
|
COALESCE(h.h_balance_t, 0) AS balance_total,
|
||||||
|
|
||||||
|
-- 드라이버 코멘트
|
||||||
|
h.h_comment AS comment
|
||||||
|
|
||||||
|
FROM tbl_daily d
|
||||||
|
INNER JOIN tbl_member m
|
||||||
|
ON (d.d_druid = m.m_currentdriver)
|
||||||
|
LEFT JOIN tbl_memberhis h
|
||||||
|
ON (d.d_druid = h.h_druid AND d.d_orderdate = h.h_date)
|
||||||
|
WHERE d.d_orderdate BETWEEN :date_from AND :date_to
|
||||||
|
";
|
||||||
|
|
||||||
|
if ($driver) {
|
||||||
|
$sql .= " AND d.d_drinitial = :driver ";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= "
|
||||||
|
GROUP BY
|
||||||
|
d.d_orderdate,
|
||||||
|
d.d_drinitial,
|
||||||
|
d.d_druid,
|
||||||
|
h.h_departuretime,
|
||||||
|
h.h_arrivaltime,
|
||||||
|
h.h_mileage_s,
|
||||||
|
h.h_mileage_f,
|
||||||
|
h.h_balance_o,
|
||||||
|
h.h_balance_in,
|
||||||
|
h.h_balance_out,
|
||||||
|
h.h_balance_r,
|
||||||
|
h.h_balance_g,
|
||||||
|
h.h_balance_e,
|
||||||
|
h.h_balance_t,
|
||||||
|
h.h_comment
|
||||||
|
ORDER BY d.d_orderdate DESC, d.d_drinitial ASC
|
||||||
|
";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->bindParam(':date_from', $dateFrom);
|
||||||
|
$stmt->bindParam(':date_to', $dateTo);
|
||||||
|
if ($driver) {
|
||||||
|
$stmt->bindParam(':driver', $driver);
|
||||||
|
}
|
||||||
|
$stmt->execute();
|
||||||
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
// 계산 컬럼 추가
|
||||||
|
// =============================================
|
||||||
|
foreach ($rows as &$row) {
|
||||||
|
|
||||||
|
// 날짜 포맷 변환 YYYYMMDD → YYYY-MM-DD
|
||||||
|
$d = $row['order_date'];
|
||||||
|
if (strlen($d) === 8) {
|
||||||
|
$row['order_date_formatted'] = substr($d,0,4).'-'.substr($d,4,2).'-'.substr($d,6,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 달성률 (%)
|
||||||
|
$fc = floatval($row['forecast']);
|
||||||
|
$ac = floatval($row['actual']);
|
||||||
|
$row['achievement_pct'] = $fc > 0 ? round($ac / $fc * 100, 1) : 0;
|
||||||
|
|
||||||
|
// 잔여 수거량
|
||||||
|
$row['remaining'] = max($fc - $ac, 0);
|
||||||
|
|
||||||
|
// 진행 상태
|
||||||
|
if ($ac <= 0) $row['status'] = 'Pending';
|
||||||
|
elseif ($ac >= $fc) $row['status'] = 'Done';
|
||||||
|
else $row['status'] = 'In Progress';
|
||||||
|
|
||||||
|
// 마일리지 주행거리
|
||||||
|
$ms = intval($row['mileage_start']);
|
||||||
|
$mf = intval($row['mileage_finish']);
|
||||||
|
$row['mileage_driven'] = ($ms > 0 && $mf > 0) ? max($mf - $ms, 0) : null;
|
||||||
|
}
|
||||||
|
unset($row);
|
||||||
|
|
||||||
|
jsonResponse([
|
||||||
|
'success' => true,
|
||||||
|
'date_from' => $dateFrom,
|
||||||
|
'date_to' => $dateTo,
|
||||||
|
'count' => count($rows),
|
||||||
|
'data' => $rows
|
||||||
|
]);
|
||||||
Loading…
Reference in New Issue