$value) { if (!isset($_GET[$key])) { $_GET[$key] = $value; } } } $act = strtolower(trim($_GET['act'] ?? 'index')); // โ”€โ”€โ”€ ๆ•ฐๆฎ็›ฎๅฝ•้…็ฝฎ โ”€โ”€โ”€ $dataDir = dirname(__FILE__) . '/cache/kitchen/'; if (!is_dir($dataDir)) { if (!@mkdir($dataDir, 0755, true)) { $tmpDir = sys_get_temp_dir() . '/kitchen/'; if (!is_dir($tmpDir)) { @mkdir($tmpDir, 0755, true); } $dataDir = $tmpDir; } } if (!is_writable($dataDir)) { $tmpDir = sys_get_temp_dir() . '/kitchen/'; if (!is_dir($tmpDir)) { @mkdir($tmpDir, 0755, true); } $dataDir = $tmpDir; } $ordersFile = $dataDir . 'orders.json'; $counterFile = $dataDir . 'counter.json'; $updateFlagFile = $dataDir . 'last_update.json'; // โ”€โ”€โ”€ ้ป˜่ฎค่ฟ‡ๆœŸๅคฉๆ•ฐ โ”€โ”€โ”€ $defaultExpireDays = 30; // โ”€โ”€โ”€ ่ทฏ็”ฑๅˆ†ๅ‘ โ”€โ”€โ”€ $result = array(); switch ($act) { case 'create': $result = create_order(); break; case 'get': $result = get_order(); break; case 'update': $result = update_order(); break; case 'list': $result = list_orders(); break; case 'delete': $result = delete_order(); break; case 'cleanup': $result = cleanup_expired(); break; case 'clear_all': $result = clear_all_orders(); break; case 'stats': $result = get_stats(); break; case 'index': default: $result = array( 'code' => 200, 'message' => '๐Ÿฝ๏ธ ็‚น้คๅŠฉๆ‰‹API', 'data' => array( 'version' => '1.0.0', 'description' => '็‚นๅ•CRUDๆ“ไฝœ๏ผŒJSONๆ–‡ไปถๅญ˜ๅ‚จ๏ผŒSSEๅฎžๆ—ถๆŽจ้€', 'endpoints' => array( 'create' => 'POST ?act=create {order JSON}', 'get' => 'GET ?act=get&id=่ฎขๅ•ID', 'update' => 'POST ?act=update {order JSON}', 'list' => 'GET ?act=list&page=1&limit=20&status=0', 'delete' => 'GET ?act=delete&id=่ฎขๅ•ID', 'cleanup' => 'GET ?act=cleanup&days=30', 'clear_all' => 'POST ?act=clear_all&confirm=yes', 'stats' => 'GET ?act=stats', 'sse' => 'GET kitchen_sse.php?order_id=xxx', ), 'storage' => 'JSONๆ–‡ไปถ (' . $ordersFile . ')', 'expire' => $defaultExpireDays . 'ๅคฉ', ) ); break; } $result['_query_time'] = round((microtime(true) - $startTime) * 1000, 2) . 'ms'; echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // ๆ•ฐๆฎ่ฏปๅ†™ๅ‡ฝๆ•ฐ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• /** * ่ฏปๅ–ๆ‰€ๆœ‰่ฎขๅ•ๆ•ฐๆฎ */ function read_orders() { global $ordersFile; if (!file_exists($ordersFile)) { return array(); } $content = file_get_contents($ordersFile); $data = json_decode($content, true); return is_array($data) ? $data : array(); } /** * ๅ†™ๅ…ฅๆ‰€ๆœ‰่ฎขๅ•ๆ•ฐๆฎ๏ผˆๆ–‡ไปถ้”๏ผ‰ */ function write_orders($orders) { global $ordersFile; $fp = fopen($ordersFile, 'c'); if (flock($fp, LOCK_EX)) { ftruncate($fp, 0); rewind($fp); fwrite($fp, json_encode($orders, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); flock($fp, LOCK_UN); } fclose($fp); touch_update_flag(); } /** * ่ฏปๅ–่ฎกๆ•ฐๅ™จ */ function read_counter() { global $counterFile; if (!file_exists($counterFile)) { return array('total' => 0, 'today' => 0, 'today_date' => date('Y-m-d')); } $content = file_get_contents($counterFile); $data = json_decode($content, true); return is_array($data) ? $data : array('total' => 0, 'today' => 0, 'today_date' => date('Y-m-d')); } /** * ๅ†™ๅ…ฅ่ฎกๆ•ฐๅ™จ */ function write_counter($counter) { global $counterFile; file_put_contents($counterFile, json_encode($counter, JSON_UNESCAPED_UNICODE)); } /** * ๆ›ดๆ–ฐSSEๆŽจ้€ๆ ‡่ฎฐ */ function touch_update_flag() { global $updateFlagFile; $data = array( 'timestamp' => microtime(true), 'time' => date('Y-m-d H:i:s'), ); file_put_contents($updateFlagFile, json_encode($data)); } /** * ้€’ๅขž่ฎกๆ•ฐๅ™จ */ function increment_counter() { $counter = read_counter(); $today = date('Y-m-d'); if ($counter['today_date'] !== $today) { $counter['today'] = 0; $counter['today_date'] = $today; } $counter['total']++; $counter['today']++; write_counter($counter); return $counter; } // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // CRUDๅ‡ฝๆ•ฐ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• /** * ๅˆ›ๅปบ็‚นๅ• * POST ?act=create * Body: {order JSON} */ function create_order() { $orderJson = $_GET['order'] ?? $_GET['data'] ?? null; if ($orderJson === null) { $rawBody = file_get_contents('php://input'); $orderData = json_decode($rawBody, true); } else { $orderData = json_decode($orderJson, true); } if (!is_array($orderData)) { return array('code' => 400, 'message' => 'ๆ— ๆ•ˆ็š„่ฎขๅ•ๆ•ฐๆฎ๏ผŒ้œ€่ฆJSONๆ ผๅผ'); } // ่กฅๅ…จๅญ—ๆฎต if (empty($orderData['id'])) { $orderData['id'] = uniqid('ord_', true); } if (empty($orderData['orderNo'])) { $orderData['orderNo'] = generate_order_no(); } if (!isset($orderData['status'])) { $orderData['status'] = 1; // active } if (empty($orderData['createdAt'])) { $orderData['createdAt'] = date('c'); } if (empty($orderData['updatedAt'])) { $orderData['updatedAt'] = date('c'); } if (empty($orderData['createdBy'])) { $orderData['createdBy'] = get_client_ip(); } if (!isset($orderData['recordCount'])) { $counter = increment_counter(); $orderData['recordCount'] = $counter['total']; } if (!isset($orderData['items'])) { $orderData['items'] = array(); } $orders = read_orders(); array_unshift($orders, $orderData); // ้™ๅˆถๆœ€ๅคงๅญ˜ๅ‚จ้‡ if (count($orders) > 500) { $orders = array_slice($orders, 0, 500); } write_orders($orders); return array( 'code' => 200, 'message' => 'ๅˆ›ๅปบๆˆๅŠŸ', 'data' => $orderData, ); } /** * ่Žทๅ–็‚นๅ• * GET ?act=get&id=xxx */ function get_order() { $id = trim($_GET['id'] ?? ''); if (empty($id)) { return array('code' => 400, 'message' => '็ผบๅฐ‘่ฎขๅ•IDๅ‚ๆ•ฐ'); } $orders = read_orders(); foreach ($orders as $order) { if (isset($order['id']) && $order['id'] === $id) { return array( 'code' => 200, 'message' => '่Žทๅ–ๆˆๅŠŸ', 'data' => $order, ); } } return array('code' => 404, 'message' => '่ฎขๅ•ไธๅญ˜ๅœจ'); } /** * ๆ›ดๆ–ฐ็‚นๅ• * POST ?act=update * Body: {order JSON with id} */ function update_order() { $orderJson = $_GET['order'] ?? $_GET['data'] ?? null; if ($orderJson === null) { $rawBody = file_get_contents('php://input'); $orderData = json_decode($rawBody, true); } else { $orderData = json_decode($orderJson, true); } if (!is_array($orderData) || empty($orderData['id'])) { return array('code' => 400, 'message' => 'ๆ— ๆ•ˆ็š„่ฎขๅ•ๆ•ฐๆฎ๏ผŒ็ผบๅฐ‘idๅญ—ๆฎต'); } $orders = read_orders(); $found = false; foreach ($orders as $i => $order) { if (isset($order['id']) && $order['id'] === $orderData['id']) { $orderData['updatedAt'] = date('c'); $orders[$i] = array_merge($order, $orderData); $found = true; break; } } if (!$found) { // ไธๅญ˜ๅœจๅˆ™ๅˆ›ๅปบ array_unshift($orders, $orderData); } write_orders($orders); return array( 'code' => 200, 'message' => $found ? 'ๆ›ดๆ–ฐๆˆๅŠŸ' : '่ฎขๅ•ไธๅญ˜ๅœจ๏ผŒๅทฒๅˆ›ๅปบ', 'data' => $orderData, ); } /** * ็‚นๅ•ๅˆ—่กจ * GET ?act=list&page=1&limit=20&status=0&type=0 */ function list_orders() { $page = max(1, (int)($_GET['page'] ?? 1)); $limit = min(100, max(1, (int)($_GET['limit'] ?? 20))); $status = $_GET['status'] ?? null; $type = $_GET['type'] ?? null; $orders = read_orders(); // ็ญ›้€‰ if ($status !== null) { $statusVal = (int)$status; $orders = array_filter($orders, function($o) use ($statusVal) { return isset($o['status']) && (int)$o['status'] === $statusVal; }); $orders = array_values($orders); } if ($type !== null) { $typeVal = (int)$type; $orders = array_filter($orders, function($o) use ($typeVal) { return isset($o['type']) && (int)$o['type'] === $typeVal; }); $orders = array_values($orders); } $total = count($orders); $offset = ($page - 1) * $limit; $list = array_slice($orders, $offset, $limit); return array( 'code' => 200, 'message' => '่Žทๅ–ๆˆๅŠŸ', 'data' => array( 'list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit, 'pages' => ceil($total / $limit), ), ); } /** * ๅˆ ้™ค็‚นๅ• * GET ?act=delete&id=xxx */ function delete_order() { $id = trim($_GET['id'] ?? ''); if (empty($id)) { return array('code' => 400, 'message' => '็ผบๅฐ‘่ฎขๅ•IDๅ‚ๆ•ฐ'); } $orders = read_orders(); $originalCount = count($orders); $orders = array_filter($orders, function($o) use ($id) { return !isset($o['id']) || $o['id'] !== $id; }); $orders = array_values($orders); if (count($orders) === $originalCount) { return array('code' => 404, 'message' => '่ฎขๅ•ไธๅญ˜ๅœจ'); } write_orders($orders); return array( 'code' => 200, 'message' => 'ๅˆ ้™คๆˆๅŠŸ', 'data' => array('deleted_id' => $id), ); } /** * ๆธ…็†่ฟ‡ๆœŸๆ•ฐๆฎ * GET ?act=cleanup&days=30 */ function cleanup_expired() { global $defaultExpireDays; $days = max(1, (int)($_GET['days'] ?? $defaultExpireDays)); $cutoff = date('c', strtotime("-{$days} days")); $orders = read_orders(); $originalCount = count($orders); $orders = array_filter($orders, function($o) use ($cutoff) { $updatedAt = $o['updatedAt'] ?? $o['createdAt'] ?? ''; return $updatedAt >= $cutoff; }); $orders = array_values($orders); $deletedCount = $originalCount - count($orders); if ($deletedCount > 0) { write_orders($orders); } return array( 'code' => 200, 'message' => "ๆธ…็†ๅฎŒๆˆ๏ผŒๅˆ ้™ค{$deletedCount}ๆก่ฟ‡ๆœŸๆ•ฐๆฎ", 'data' => array( 'deleted_count' => $deletedCount, 'remaining_count' => count($orders), 'cutoff_date' => $cutoff, 'expire_days' => $days, ), ); } /** * ๆธ…็ฉบๅ…จ้ƒจ็‚น้คๅŠฉๆ‰‹ๆ•ฐๆฎ * POST ?act=clear_all&confirm=yes * ไป…ๆธ…็† cache/kitchen/ ็›ฎๅฝ•ไธ‹็š„ๆ–‡ไปถ๏ผŒไธๅฝฑๅ“ๅ…ถไป–ๆ•ฐๆฎ */ function clear_all_orders() { global $dataDir, $ordersFile, $counterFile, $updateFlagFile; $confirm = strtolower(trim($_GET['confirm'] ?? $_POST['confirm'] ?? '')); if ($confirm !== 'yes') { return array( 'code' => 400, 'message' => '้œ€่ฆ็กฎ่ฎคๅ‚ๆ•ฐ confirm=yes ๆ‰่ƒฝๆธ…็ฉบๆ•ฐๆฎ', ); } $deletedFiles = array(); $errors = array(); $kitchenFiles = array( 'orders' => $ordersFile, 'counter' => $counterFile, 'update_flag' => $updateFlagFile, ); foreach ($kitchenFiles as $name => $file) { if (file_exists($file)) { if (@unlink($file)) { $deletedFiles[] = basename($file); } else { $errors[] = 'ๆ— ๆณ•ๅˆ ้™ค: ' . basename($file); } } } $scanDir = $dataDir; if (is_dir($scanDir)) { $extraFiles = @scandir($scanDir); if ($extraFiles !== false) { foreach ($extraFiles as $f) { if ($f === '.' || $f === '..') continue; $fullPath = $scanDir . $f; if (is_file($fullPath) && !in_array($f, $deletedFiles)) { if (@unlink($fullPath)) { $deletedFiles[] = $f; } else { $errors[] = 'ๆ— ๆณ•ๅˆ ้™ค: ' . $f; } } } } } $message = '็‚น้คๅŠฉๆ‰‹ๆ•ฐๆฎๅทฒๆธ…็ฉบ'; if (count($deletedFiles) > 0) { $message .= '๏ผŒๅทฒๅˆ ้™ค: ' . implode(', ', $deletedFiles); } if (count($errors) > 0) { $message .= '๏ผŒ้”™่ฏฏ: ' . implode(', ', $errors); } return array( 'code' => 200, 'message' => $message, 'data' => array( 'deleted_files' => $deletedFiles, 'errors' => $errors, 'data_dir' => basename($dataDir), 'scope' => 'kitchen_only', ), ); } /** * ็ปŸ่ฎกไฟกๆฏ * GET ?act=stats */ function get_stats() { $counter = read_counter(); $orders = read_orders(); $statusCount = array(0 => 0, 1 => 0, 2 => 0, 3 => 0); $typeCount = array(0 => 0, 1 => 0); foreach ($orders as $o) { $s = (int)($o['status'] ?? 0); $t = (int)($o['type'] ?? 0); if (isset($statusCount[$s])) $statusCount[$s]++; if (isset($typeCount[$t])) $typeCount[$t]++; } return array( 'code' => 200, 'message' => '่Žทๅ–ๆˆๅŠŸ', 'data' => array( 'total_orders' => $counter['total'], 'today_orders' => $counter['today'], 'stored_orders' => count($orders), 'by_status' => $statusCount, 'by_type' => $typeCount, 'storage_file' => basename($GLOBALS['ordersFile']), ), ); } // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // ๅทฅๅ…ทๅ‡ฝๆ•ฐ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• /** * ็”Ÿๆˆ่ฎขๅ•ๅท */ function generate_order_no() { $ts = substr(microtime(true) . '', 5); $rand = rand(100, 999); return 'OD' . $ts . $rand; } /** * ่Žทๅ–ๅฎขๆˆท็ซฏIP */ function get_client_ip() { if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); return trim($ips[0]); } if (!empty($_SERVER['HTTP_X_REAL_IP'])) { return $_SERVER['HTTP_X_REAL_IP']; } return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; }