orderBy('created_at', 'desc'); // 筛选条件 if ($request->filled('platform')) { $query->where('platform', $request->platform); } if ($request->filled('shop_id')) { $query->where('shop_id', $request->shop_id); } if ($request->filled('order_status')) { $query->where('order_status', $request->order_status); } if ($request->filled('audit_status')) { $query->where('audit_status', $request->audit_status); } if ($request->filled('delivery_status')) { $query->where('delivery_status', $request->delivery_status); } if ($request->filled('keyword')) { $keyword = $request->keyword; $query->where(function ($q) use ($keyword) { $q->where('short_id', 'like', "%{$keyword}%") ->orWhere('platform_order_sn', 'like', "%{$keyword}%") ->orWhere('receiver_name', 'like', "%{$keyword}%") ->orWhere('receiver_phone', 'like', "%{$keyword}%"); }); } if ($request->filled('date_range')) { $dates = explode(',', $request->date_range); if (count($dates) === 2) { $query->whereBetween('order_time', [$dates[0], $dates[1]]); } } $perPage = $request->input('limit', 10); $orders = $query->paginate($perPage); return response()->json([ 'code' => 200, 'data' => [ 'list' => $orders->items(), 'total' => $orders->total(), 'current_page' => $orders->currentPage(), 'last_page' => $orders->lastPage(), ], 'message' => 'success' ]); } /** * 订单详情 */ public function show(string $id) { $order = Order::with(['items', 'warehouse'])->find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } return response()->json([ 'code' => 200, 'data' => $order, 'message' => 'success' ]); } /** * 手动拉取订单 */ public function pullOrders(Request $request) { $request->validate([ 'platform' => 'required|string', 'shop_id' => 'required|integer', 'pull_type' => 'required|in:all,increment,specify', 'order_ids' => 'required_if:pull_type,specify|string', 'start_time' => 'nullable|date', 'end_time' => 'nullable|date', ]); // TODO: 这里应该调用平台API拉取订单 // 暂时返回模拟数据 $mockOrders = [ [ 'platform_order_sn' => 'TEST' . Str::random(10), 'order_time' => now()->toDateTimeString(), 'buyer_nick' => '测试买家', 'receiver_name' => '张三', 'receiver_phone' => '13800138000', 'receiver_address' => '测试地址', 'goods_amount' => 199.00, 'discount_amount' => 0, 'freight' => 10.00, 'total_amount' => 209.00, 'platform_status' => 'WAIT_SELLER_SEND_GOODS', 'items' => [ [ 'goods_name' => '测试商品', 'platform_sku' => 'SKU001', 'quantity' => 1, 'price' => 199.00, 'total_amount' => 199.00, ] ] ] ]; $createdCount = 0; try { DB::beginTransaction(); foreach ($mockOrders as $orderData) { // 生成短ID $shortId = 'O' . date('Ymd') . strtoupper(Str::random(6)); $order = Order::create([ 'short_id' => $shortId, 'platform_order_sn' => $orderData['platform_order_sn'], 'platform' => $request->platform, 'shop_id' => $request->shop_id, 'shop_name' => '测试店铺', 'order_time' => $orderData['order_time'], 'buyer_nick' => $orderData['buyer_nick'], 'receiver_name' => $orderData['receiver_name'], 'receiver_phone' => $orderData['receiver_phone'], 'receiver_address' => $orderData['receiver_address'], 'goods_amount' => $orderData['goods_amount'], 'discount_amount' => $orderData['discount_amount'], 'freight' => $orderData['freight'], 'total_amount' => $orderData['total_amount'], 'order_status' => 'pending', 'platform_status' => $orderData['platform_status'], 'audit_status' => 'pending', 'delivery_status' => 'pending', ]); // 创建订单项 foreach ($orderData['items'] as $itemData) { OrderItem::create([ 'order_id' => $order->id, 'goods_name' => $itemData['goods_name'], 'platform_sku' => $itemData['platform_sku'], 'quantity' => $itemData['quantity'], 'price' => $itemData['price'], 'total_amount' => $itemData['total_amount'], ]); } $createdCount++; } DB::commit(); return response()->json([ 'code' => 200, 'data' => ['count' => $createdCount], 'message' => "成功拉取 {$createdCount} 个订单" ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'code' => 500, 'message' => '拉取失败: ' . $e->getMessage() ], 500); } } /** * 批量审核订单 */ public function batchAudit(Request $request) { $request->validate([ 'order_ids' => 'required|array|min:1', 'order_ids.*' => 'integer|exists:orders,id', 'action' => 'required|in:approve,reject', 'comment' => 'required_if:action,reject|string|max:500', ]); $successCount = 0; $failedOrders = []; try { DB::beginTransaction(); foreach ($request->order_ids as $orderId) { $order = Order::find($orderId); if (!$order) { $failedOrders[] = ['id' => $orderId, 'reason' => '订单不存在']; continue; } // 只有待审核状态的订单可以审核 if ($order->audit_status !== 'pending') { $failedOrders[] = ['id' => $orderId, 'reason' => '订单状态不可审核']; continue; } // 驳回时解锁库存 if ($request->action === 'reject') { $stockService = app(\App\Services\StockService::class); foreach ($order->items as $item) { $stockService->unlockStock( $item->sku_code ?? $item->erp_sku_id, $order->warehouse_id, $item->quantity, $order->id ); } } $order->update([ 'audit_status' => $request->action === 'approve' ? 'approved' : 'rejected', 'audit_comment' => $request->comment, 'order_status' => $request->action === 'approve' ? 'auditing' : 'pending', ]); $successCount++; } DB::commit(); return response()->json([ 'code' => 200, 'data' => [ 'success_count' => $successCount, 'failed_orders' => $failedOrders, ], 'message' => "成功审核 {$successCount} 个订单" ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'code' => 500, 'message' => '审核失败: ' . $e->getMessage() ], 500); } } /** * 单个订单审核 */ public function auditOrder(Request $request, string $id) { $request->validate([ 'action' => 'required|in:approve,reject', 'comment' => 'required_if:action,reject|string|max:500', ]); $order = Order::find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } // 只有待审核状态的订单可以审核 if ($order->audit_status !== 'pending') { return response()->json([ 'code' => 400, 'message' => '订单状态不可审核' ], 400); } // 驳回时解锁库存 if ($request->action === 'reject') { $stockService = app(\App\Services\StockService::class); foreach ($order->items as $item) { $stockService->unlockStock( $item->sku_code ?? $item->erp_sku_id, $order->warehouse_id, $item->quantity, $order->id ); } } $order->update([ 'audit_status' => $request->action === 'approve' ? 'approved' : 'rejected', 'audit_comment' => $request->comment, 'order_status' => $request->action === 'approve' ? 'auditing' : 'pending', ]); return response()->json([ 'code' => 200, 'message' => $request->action === 'approve' ? '订单审核通过' : '订单已驳回' ]); } /** * 设置仓库和快递 */ public function setWarehouseExpress(Request $request, string $id) { $request->validate([ 'warehouse_id' => 'nullable|integer|exists:warehouses,id', 'express_company' => 'nullable|string|max:50', 'express_name' => 'nullable|string|max:50', 'express_template_id' => 'nullable|integer|exists:templates,id', ]); $order = Order::find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } // 只有已审核的订单可以设置仓库和快递 if ($order->audit_status !== 'approved') { return response()->json([ 'code' => 400, 'message' => '只有已审核的订单可以设置仓库和快递' ], 400); } $order->update([ 'warehouse_id' => $request->warehouse_id ?? $order->warehouse_id, 'express_company' => $request->express_company ?? $order->express_company, 'express_name' => $request->express_name ?? $order->express_name, ]); return response()->json([ 'code' => 200, 'message' => '设置成功' ]); } /** * 发货 */ public function shipOrder(Request $request, string $id) { $request->validate([ 'express_company' => 'required|string|max:50', 'express_no' => 'required|string|max:50', 'is_print' => 'nullable|boolean', ]); $order = Order::with('items')->find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } // 检查订单状态 if ($order->order_status !== 'auditing') { return response()->json([ 'code' => 400, 'message' => '只有待发货的订单可以发货' ], 400); } // 检查是否设置了仓库 if (!$order->warehouse_id) { return response()->json([ 'code' => 400, 'message' => '请先设置发货仓库' ], 400); } try { DB::beginTransaction(); // 更新订单状态 $order->update([ 'express_company' => $request->express_company, 'express_no' => $request->express_no, 'delivery_status' => 'delivered', 'delivery_time' => now(), 'order_status' => 'shipped', ]); // 扣减库存 foreach ($order->items as $item) { if ($item->erp_sku) { $this->deductStock( $order->warehouse_id, $item->erp_sku, $item->quantity, $order->short_id ); } } DB::commit(); return response()->json([ 'code' => 200, 'message' => '发货成功' ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'code' => 500, 'message' => '发货失败: ' . $e->getMessage() ], 500); } } /** * 扣减库存 */ private function deductStock($warehouseId, $skuCode, $quantity, $relatedNo) { $stock = Stock::where('warehouse_id', $warehouseId) ->where('sku_code', $skuCode) ->first(); if (!$stock) { throw new \Exception("商品 {$skuCode} 在仓库中不存在"); } if ($stock->available_quantity < $quantity) { throw new \Exception("商品 {$skuCode} 库存不足,可用库存: {$stock->available_quantity}"); } $stock->decrement('quantity', $quantity); // 记录库存流水 StockLog::create([ 'sku_code' => $skuCode, 'warehouse_id' => $warehouseId, 'change_quantity' => -$quantity, 'type' => 'order_ship', 'related_no' => $relatedNo, 'remark' => '订单发货出库', ]); } /** * 订单统计 */ public function statistics(Request $request) { $query = Order::query(); // 时间范围筛选 if ($request->filled('start_date')) { $query->where('order_time', '>=', $request->start_date); } if ($request->filled('end_date')) { $query->where('order_time', '<=', $request->end_date); } // 平台筛选 if ($request->filled('platform')) { $query->where('platform', $request->platform); } // 店铺筛选 if ($request->filled('shop_id')) { $query->where('shop_id', $request->shop_id); } // 订单状态统计 $statusStats = [ 'pending' => (clone $query)->where('order_status', 'pending')->count(), 'auditing' => (clone $query)->where('order_status', 'auditing')->count(), 'shipped' => (clone $query)->where('order_status', 'shipped')->count(), 'completed' => (clone $query)->where('order_status', 'completed')->count(), 'cancelled' => (clone $query)->where('order_status', 'cancelled')->count(), ]; // 审核状态统计 $auditStats = [ 'pending' => (clone $query)->where('audit_status', 'pending')->count(), 'approved' => (clone $query)->where('audit_status', 'approved')->count(), 'rejected' => (clone $query)->where('audit_status', 'rejected')->count(), ]; // 发货状态统计 $deliveryStats = [ 'pending' => (clone $query)->where('delivery_status', 'pending')->count(), 'delivered' => (clone $query)->where('delivery_status', 'delivered')->count(), ]; // 金额统计 $amountStats = [ 'total_goods_amount' => (clone $query)->sum('goods_amount'), 'total_discount_amount' => (clone $query)->sum('discount_amount'), 'total_freight' => (clone $query)->sum('freight'), 'total_amount' => (clone $query)->sum('total_amount'), 'avg_order_amount' => (clone $query)->avg('total_amount') ?? 0, ]; // 平台分布统计 $platformStats = Order::select('platform', DB::raw('count(*) as count'), DB::raw('sum(total_amount) as amount')) ->when($request->filled('start_date'), function ($q) use ($request) { $q->where('order_time', '>=', $request->start_date); }) ->when($request->filled('end_date'), function ($q) use ($request) { $q->where('order_time', '<=', $request->end_date); }) ->groupBy('platform') ->get() ->map(function ($item) { return [ 'platform' => $item->platform, 'count' => $item->count, 'amount' => (float) $item->amount, ]; }); // 时间趋势统计(按天) $dateFormat = $request->input('date_format', 'day'); // day, week, month $format = $dateFormat === 'day' ? '%Y-%m-%d' : ($dateFormat === 'week' ? '%Y-%U' : '%Y-%m'); $trendStats = Order::select( DB::raw("DATE_FORMAT(order_time, '{$format}') as date_group"), DB::raw('count(*) as order_count'), DB::raw('sum(total_amount) as total_amount') ) ->when($request->filled('start_date'), function ($q) use ($request) { $q->where('order_time', '>=', $request->start_date); }) ->when($request->filled('end_date'), function ($q) use ($request) { $q->where('order_time', '<=', $request->end_date); }) ->groupBy('date_group') ->orderBy('date_group') ->get(); return response()->json([ 'code' => 200, 'data' => [ 'status_stats' => $statusStats, 'audit_stats' => $auditStats, 'delivery_stats' => $deliveryStats, 'amount_stats' => $amountStats, 'platform_stats' => $platformStats, 'trend_stats' => $trendStats, 'total_orders' => array_sum($statusStats), 'date_range' => [ 'start_date' => $request->start_date, 'end_date' => $request->end_date, ], ], 'message' => 'success' ]); } /** * 订单导出 */ public function export(Request $request) { $request->validate([ 'export_type' => 'required|in:excel,csv', 'order_ids' => 'nullable|array', 'order_ids.*' => 'integer|exists:orders,id', 'start_date' => 'nullable|date', 'end_date' => 'nullable|date', 'platform' => 'nullable|string', 'order_status' => 'nullable|string', 'audit_status' => 'nullable|string', 'delivery_status' => 'nullable|string', ]); $query = Order::with(['items', 'warehouse']); // 筛选条件 if ($request->filled('order_ids')) { $query->whereIn('id', $request->order_ids); } if ($request->filled('start_date')) { $query->where('order_time', '>=', $request->start_date); } if ($request->filled('end_date')) { $query->where('order_time', '<=', $request->end_date); } if ($request->filled('platform')) { $query->where('platform', $request->platform); } if ($request->filled('order_status')) { $query->where('order_status', $request->order_status); } if ($request->filled('audit_status')) { $query->where('audit_status', $request->audit_status); } if ($request->filled('delivery_status')) { $query->where('delivery_status', $request->delivery_status); } $orders = $query->orderBy('order_time', 'desc')->get(); // 准备导出数据 $exportData = $orders->map(function ($order) { return [ '订单短ID' => $order->short_id, '平台订单号' => $order->platform_order_sn, '平台' => $order->platform, '店铺名称' => $order->shop_name, '下单时间' => $order->order_time, '买家昵称' => $order->buyer_nick, '收货人' => $order->receiver_name, '收货电话' => $order->receiver_phone, '收货地址' => $order->receiver_address, '商品金额' => $order->goods_amount, '优惠金额' => $order->discount_amount, '运费' => $order->freight, '总金额' => $order->total_amount, '订单状态' => $this->getStatusText($order->order_status), '平台状态' => $order->platform_status, '审核状态' => $this->getAuditStatusText($order->audit_status), '发货状态' => $this->getDeliveryStatusText($order->delivery_status), '发货时间' => $order->delivery_time, '快递公司' => $order->express_company, '快递单号' => $order->express_no, '仓库名称' => $order->warehouse_name, '备注' => $order->remark, '创建时间' => $order->created_at, '更新时间' => $order->updated_at, ]; }); // 生成文件名 $filename = 'orders_export_' . date('Ymd_His') . '.' . $request->export_type; // 在实际项目中,这里会生成Excel或CSV文件 // 暂时返回数据供前端处理 return response()->json([ 'code' => 200, 'data' => [ 'filename' => $filename, 'count' => $orders->count(), 'data' => $exportData, 'headers' => array_keys($exportData->first() ?? []), ], 'message' => '导出数据准备完成' ]); } /** * 获取状态文本 */ private function getStatusText($status): string { $statusMap = [ 'pending' => '待处理', 'auditing' => '审核中', 'shipped' => '已发货', 'completed' => '已完成', 'cancelled' => '已取消', ]; return $statusMap[$status] ?? $status; } /** * 获取审核状态文本 */ private function getAuditStatusText($status): string { $statusMap = [ 'pending' => '待审核', 'approved' => '已通过', 'rejected' => '已驳回', ]; return $statusMap[$status] ?? $status; } /** * 获取发货状态文本 */ private function getDeliveryStatusText($status): string { $statusMap = [ 'pending' => '待发货', 'delivered' => '已发货', ]; return $statusMap[$status] ?? $status; } /** * 订单操作日志 */ public function getOrderLogs(string $id) { $order = Order::find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } // 在实际项目中,这里应该查询操作日志表 // 暂时返回模拟数据 $logs = $this->generateOrderLogs($order); return response()->json([ 'code' => 200, 'data' => $logs, 'message' => 'success' ]); } /** * 生成订单操作日志 */ private function generateOrderLogs(Order $order): array { $logs = []; // 订单创建日志 $logs[] = [ 'id' => 1, 'operator' => '系统', 'operator_id' => 0, 'action' => 'create', 'action_text' => '创建订单', 'content' => "订单创建成功,订单号:{$order->short_id}", 'ip' => '127.0.0.1', 'user_agent' => '系统自动创建', 'created_at' => $order->created_at, ]; // 如果订单已审核,添加审核日志 if ($order->audit_status === 'approved') { $logs[] = [ 'id' => 2, 'operator' => '管理员', 'operator_id' => 1, 'action' => 'audit_approve', 'action_text' => '审核通过', 'content' => '订单审核通过,进入待发货状态', 'ip' => '192.168.1.100', 'user_agent' => 'Chrome/120.0.0.0', 'created_at' => $order->updated_at, ]; } elseif ($order->audit_status === 'rejected') { $logs[] = [ 'id' => 2, 'operator' => '管理员', 'operator_id' => 1, 'action' => 'audit_reject', 'action_text' => '审核驳回', 'content' => "订单审核驳回,原因:{$order->audit_comment}", 'ip' => '192.168.1.100', 'user_agent' => 'Chrome/120.0.0.0', 'created_at' => $order->updated_at, ]; } // 如果设置了仓库,添加仓库设置日志 if ($order->warehouse_id) { $logs[] = [ 'id' => 3, 'operator' => '操作员', 'operator_id' => 2, 'action' => 'set_warehouse', 'action_text' => '设置仓库', 'content' => "设置发货仓库:{$order->warehouse_name}", 'ip' => '192.168.1.101', 'user_agent' => 'Firefox/121.0.0.0', 'created_at' => $order->updated_at, ]; } // 如果已发货,添加发货日志 if ($order->delivery_status === 'delivered') { $logs[] = [ 'id' => 4, 'operator' => '发货员', 'operator_id' => 3, 'action' => 'ship', 'action_text' => '订单发货', 'content' => "订单已发货,快递公司:{$order->express_company},快递单号:{$order->express_no}", 'ip' => '192.168.1.102', 'user_agent' => 'Safari/17.0.0.0', 'created_at' => $order->delivery_time, ]; } // 如果订单已完成,添加完成日志 if ($order->order_status === 'completed') { $logs[] = [ 'id' => 5, 'operator' => '系统', 'operator_id' => 0, 'action' => 'complete', 'action_text' => '订单完成', 'content' => '订单已完成交易', 'ip' => '127.0.0.1', 'user_agent' => '系统自动完成', 'created_at' => $order->end_time, ]; } // 如果订单已取消,添加取消日志 if ($order->order_status === 'cancelled') { $logs[] = [ 'id' => 6, 'operator' => '管理员', 'operator_id' => 1, 'action' => 'cancel', 'action_text' => '订单取消', 'content' => "订单已取消,原因:{$order->audit_comment}", 'ip' => '192.168.1.100', 'user_agent' => 'Chrome/120.0.0.0', 'created_at' => $order->updated_at, ]; } // 按时间倒序排序 usort($logs, function ($a, $b) { return strtotime($b['created_at']) - strtotime($a['created_at']); }); return $logs; } /** * 记录订单操作日志 */ private function logOrderOperation(Order $order, string $action, string $content, array $data = []): void { // 在实际项目中,这里应该将日志保存到数据库 // 暂时只记录到文件或控制台 $logData = [ 'order_id' => $order->id, 'short_id' => $order->short_id, 'action' => $action, 'content' => $content, 'operator' => auth()->user() ? auth()->user()->name : '系统', 'operator_id' => auth()->id() ?? 0, 'data' => $data, 'created_at' => now()->toDateTimeString(), ]; // 记录到日志文件 $logPath = storage_path('logs/order_operations.log'); file_put_contents($logPath, json_encode($logData, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND); } /** * 批量操作订单 */ public function batchOperation(Request $request) { $request->validate([ 'order_ids' => 'required|array|min:1', 'order_ids.*' => 'integer|exists:orders,id', 'operation' => 'required|in:audit_approve,audit_reject,set_warehouse,ship,cancel,delete', 'data' => 'nullable|array', ]); $successCount = 0; $failedOrders = []; try { DB::beginTransaction(); foreach ($request->order_ids as $orderId) { $order = Order::find($orderId); if (!$order) { $failedOrders[] = ['id' => $orderId, 'reason' => '订单不存在']; continue; } $result = $this->processBatchOperation($order, $request->operation, $request->data ?? []); if ($result['success']) { $successCount++; // 记录操作日志 $this->logOrderOperation( $order, $request->operation, $result['log_content'] ?? '批量操作', $request->data ?? [] ); } else { $failedOrders[] = ['id' => $orderId, 'reason' => $result['reason']]; } } DB::commit(); return response()->json([ 'code' => 200, 'data' => [ 'success_count' => $successCount, 'failed_orders' => $failedOrders, ], 'message' => "成功处理 {$successCount} 个订单" ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'code' => 500, 'message' => '批量操作失败: ' . $e->getMessage() ], 500); } } /** * 处理批量操作 */ private function processBatchOperation(Order $order, string $operation, array $data): array { $logContent = ''; switch ($operation) { case 'audit_approve': if ($order->audit_status !== 'pending') { return ['success' => false, 'reason' => '订单状态不可审核']; } $order->update([ 'audit_status' => 'approved', 'order_status' => 'auditing', ]); $logContent = '批量审核通过'; break; case 'audit_reject': if ($order->audit_status !== 'pending') { return ['success' => false, 'reason' => '订单状态不可审核']; } $order->update([ 'audit_status' => 'rejected', 'audit_comment' => $data['comment'] ?? '', ]); $logContent = '批量审核驳回,原因:' . ($data['comment'] ?? '无'); break; case 'set_warehouse': if ($order->audit_status !== 'approved') { return ['success' => false, 'reason' => '只有已审核的订单可以设置仓库']; } $order->update([ 'warehouse_id' => $data['warehouse_id'] ?? $order->warehouse_id, 'warehouse_name' => $data['warehouse_name'] ?? $order->warehouse_name, ]); $logContent = '批量设置仓库:' . ($data['warehouse_name'] ?? '未知仓库'); break; case 'ship': if ($order->order_status !== 'auditing') { return ['success' => false, 'reason' => '只有待发货的订单可以发货']; } if (!$order->warehouse_id) { return ['success' => false, 'reason' => '请先设置发货仓库']; } $order->update([ 'express_company' => $data['express_company'] ?? '', 'express_no' => $data['express_no'] ?? '', 'delivery_status' => 'delivered', 'delivery_time' => now(), 'order_status' => 'shipped', ]); $logContent = '批量发货,快递:' . ($data['express_company'] ?? '未知') . ',单号:' . ($data['express_no'] ?? '无'); break; case 'cancel': if (!in_array($order->order_status, ['pending', 'auditing'])) { return ['success' => false, 'reason' => '订单状态不可取消']; } $order->update([ 'order_status' => 'cancelled', 'audit_status' => 'rejected', 'audit_comment' => '订单已取消', ]); $logContent = '批量取消订单'; break; case 'delete': if (!in_array($order->order_status, ['cancelled', 'completed'])) { return ['success' => false, 'reason' => '只有已取消或已完成的订单可以删除']; } $order->delete(); $logContent = '批量删除订单'; break; default: return ['success' => false, 'reason' => '不支持的操作类型']; } return ['success' => true, 'log_content' => $logContent]; } /** * 获取订单状态选项 */ public function getStatusOptions() { $options = [ ['value' => 'pending', 'label' => '待处理'], ['value' => 'auditing', 'label' => '审核中'], ['value' => 'shipped', 'label' => '已发货'], ['value' => 'completed', 'label' => '已完成'], ['value' => 'cancelled', 'label' => '已取消'], ]; return response()->json([ 'code' => 200, 'data' => $options, 'message' => 'success' ]); } /** * 获取审核状态选项 */ public function getAuditStatusOptions() { $options = [ ['value' => 'pending', 'label' => '待审核'], ['value' => 'approved', 'label' => '已通过'], ['value' => 'rejected', 'label' => '已驳回'], ]; return response()->json([ 'code' => 200, 'data' => $options, 'message' => 'success' ]); } /** * 获取发货状态选项 */ public function getDeliveryStatusOptions() { $options = [ ['value' => 'pending', 'label' => '待发货'], ['value' => 'delivered', 'label' => '已发货'], ]; return response()->json([ 'code' => 200, 'data' => $options, 'message' => 'success' ]); } /** * 获取平台选项 */ public function getPlatformOptions() { $platforms = Order::select('platform') ->distinct() ->orderBy('platform') ->get() ->map(function ($item) { return [ 'value' => $item->platform, 'label' => $item->platform, ]; }); return response()->json([ 'code' => 200, 'data' => $platforms, 'message' => 'success' ]); } /** * 获取店铺选项 */ public function getShopOptions() { $shops = Order::select('shop_id', 'shop_name') ->distinct() ->orderBy('shop_name') ->get() ->map(function ($item) { return [ 'value' => $item->shop_id, 'label' => $item->shop_name, ]; }); return response()->json([ 'code' => 200, 'data' => $shops, 'message' => 'success' ]); } /** * 更新订单备注 */ public function updateRemark(Request $request, string $id) { $request->validate([ 'remark' => 'required|string|max:1000', ]); $order = Order::find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } $oldRemark = $order->remark; $order->update(['remark' => $request->remark]); // 记录操作日志 $this->logOrderOperation( $order, 'update_remark', "更新订单备注,原备注:{$oldRemark},新备注:{$request->remark}" ); return response()->json([ 'code' => 200, 'message' => '备注更新成功' ]); } /** * 完成订单 */ public function completeOrder(string $id) { $order = Order::find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } // 只有已发货的订单可以完成 if ($order->order_status !== 'shipped') { return response()->json([ 'code' => 400, 'message' => '只有已发货的订单可以完成' ], 400); } $order->update([ 'order_status' => 'completed', 'end_time' => now(), ]); // 记录操作日志 $this->logOrderOperation( $order, 'complete', '订单已完成交易' ); return response()->json([ 'code' => 200, 'message' => '订单已完成' ]); } /** * 同步订单到平台 */ public function syncToPlatform(string $id) { $order = Order::find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } // TODO: 实现同步到平台API // 这里应该调用对应平台的API更新订单状态 // 记录操作日志 $this->logOrderOperation( $order, 'sync_to_platform', "同步订单到平台:{$order->platform},平台订单号:{$order->platform_order_sn}" ); return response()->json([ 'code' => 200, 'message' => '订单已同步到平台(模拟)', 'data' => [ 'order_id' => $id, 'platform' => $order->platform, 'platform_order_sn' => $order->platform_order_sn, ] ]); } /** * 获取订单操作历史 */ public function getOperationHistory(string $id) { $order = Order::find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } // 在实际项目中,这里应该查询操作日志表 // 暂时返回模拟数据 $history = $this->generateOrderLogs($order); return response()->json([ 'code' => 200, 'data' => $history, 'message' => 'success' ]); } /** * 获取订单数量统计(用于仪表板) */ public function getDashboardStats() { $today = now()->startOfDay(); $yesterday = now()->subDay()->startOfDay(); $thisMonth = now()->startOfMonth(); $stats = [ 'today' => [ 'total' => Order::where('order_time', '>=', $today)->count(), 'pending' => Order::where('order_time', '>=', $today)->where('order_status', 'pending')->count(), 'auditing' => Order::where('order_time', '>=', $today)->where('order_status', 'auditing')->count(), 'shipped' => Order::where('order_time', '>=', $today)->where('order_status', 'shipped')->count(), 'amount' => Order::where('order_time', '>=', $today)->sum('total_amount'), ], 'yesterday' => [ 'total' => Order::whereBetween('order_time', [$yesterday, $today])->count(), 'amount' => Order::whereBetween('order_time', [$yesterday, $today])->sum('total_amount'), ], 'this_month' => [ 'total' => Order::where('order_time', '>=', $thisMonth)->count(), 'amount' => Order::where('order_time', '>=', $thisMonth)->sum('total_amount'), ], 'all' => [ 'total' => Order::count(), 'pending' => Order::where('order_status', 'pending')->count(), 'auditing' => Order::where('order_status', 'auditing')->count(), 'shipped' => Order::where('order_status', 'shipped')->count(), 'completed' => Order::where('order_status', 'completed')->count(), 'cancelled' => Order::where('order_status', 'cancelled')->count(), 'amount' => Order::sum('total_amount'), ], ]; return response()->json([ 'code' => 200, 'data' => $stats, 'message' => 'success' ]); } /** * 获取订单操作类型选项 */ public function getOperationTypeOptions() { $options = [ ['value' => 'create', 'label' => '创建'], ['value' => 'audit_approve', 'label' => '审核通过'], ['value' => 'audit_reject', 'label' => '审核驳回'], ['value' => 'set_warehouse', 'label' => '设置仓库'], ['value' => 'ship', 'label' => '发货'], ['value' => 'complete', 'label' => '完成'], ['value' => 'cancel', 'label' => '取消'], ['value' => 'update_remark', 'label' => '更新备注'], ['value' => 'sync_to_platform', 'label' => '同步到平台'], ['value' => 'delete', 'label' => '删除'], ]; return response()->json([ 'code' => 200, 'data' => $options, 'message' => 'success' ]); } /** * 导出订单操作日志 */ public function exportOperationLogs(Request $request, string $id) { $order = Order::find($id); if (!$order) { return response()->json([ 'code' => 404, 'message' => '订单不存在' ], 404); } $request->validate([ 'export_type' => 'required|in:excel,csv', ]); // 获取操作日志 $logs = $this->generateOrderLogs($order); // 准备导出数据 $exportData = array_map(function ($log) { return [ '操作时间' => $log['created_at'], '操作人' => $log['operator'], '操作类型' => $log['action_text'], '操作内容' => $log['content'], 'IP地址' => $log['ip'], '用户代理' => $log['user_agent'], ]; }, $logs); // 生成文件名 $filename = "order_{$order->short_id}_logs_" . date('Ymd_His') . '.' . $request->export_type; return response()->json([ 'code' => 200, 'data' => [ 'filename' => $filename, 'count' => count($logs), 'data' => $exportData, 'headers' => array_keys($exportData[0] ?? []), 'order_info' => [ 'short_id' => $order->short_id, 'platform_order_sn' => $order->platform_order_sn, 'platform' => $order->platform, 'shop_name' => $order->shop_name, ], ], 'message' => '操作日志导出数据准备完成' ]); } }