error; } /** * 获取当前表名 * @param int $timestamp 时间戳 * @return string */ protected function getTableName($timestamp = null) { return GiftTableManager::getTableName($timestamp); } /** * 添加送礼记录(直接写入数据库) * @param array $data 数据 * @return int|false */ public function addGiftRecord($data) { try { // 生成雪花ID // $data['id'] = Snowflake::generate(); // 设置时间 if (empty($data['createtime'])) { $data['createtime'] = time(); } $data['updatetime'] = time(); // 确保字段完整 $defaults = [ 'user_id' => 0, 'gift_id' => 0, 'gift_type' => 1, 'number' => 0, 'gift_user' => 0, 'from_id' => 0, 'pit_number' => 0, 'total_price' => 0, 'type' => 1, 'from' => 1, ]; $data = array_merge($defaults, $data); // 获取表名 $tableName = $this->getTableName($data['createtime']); // 确保表存在 $month = date('Ym', $data['createtime']); GiftTableManager::createMonthTable($month); // 插入数据 $result = Db::table($tableName)->insert($data); if ($result) { Log::info("送礼记录写入成功,ID: {$data['id']}, 表: {$tableName}"); return $data['id']; } else { $this->error = '写入数据库失败'; Log::error("送礼记录写入失败: " . json_encode($data)); return false; } } catch (\Exception $e) { $this->error = $e->getMessage(); Log::error("添加送礼记录异常: " . $e->getMessage()); return false; } } /** * 批量添加送礼记录 * @param array $dataList 数据列表 * @return int|false */ public function addGiftRecords($dataList) { try { // 按月份分组 $groupedData = []; foreach ($dataList as $data) { // 生成雪花ID $data['id'] = Snowflake::generate(); // 设置时间 if (empty($data['createtime'])) { $data['createtime'] = time(); } $data['updatetime'] = time(); $month = date('Ym', $data['createtime']); $tableName = 'fa_vs_give_gift_' . $month; // 确保表存在 GiftTableManager::createMonthTable($month); if (!isset($groupedData[$tableName])) { $groupedData[$tableName] = []; } $groupedData[$tableName][] = $data; } // 批量插入 $total = 0; foreach ($groupedData as $tableName => $data) { $result = Db::table($tableName)->insertAll($data); if ($result) { $total += count($data); } } Log::info("批量送礼记录写入成功,总计: {$total} 条"); return $total; } catch (\Exception $e) { $this->error = $e->getMessage(); Log::error("批量添加送礼记录异常: " . $e->getMessage()); return false; } } /** * 查询送礼记录 * @param array $where 查询条件 * @param array $options 查询选项 * @return array */ public function getGiftRecords($where = [], $options = []) { $defaultOptions = [ 'fields' => '*', 'order' => 'createtime desc', 'page' => 1, 'limit' => 20, 'start_time' => null, 'end_time' => null, ]; $options = array_merge($defaultOptions, $options); // 获取需要查询的表 $tables = GiftTableManager::getTablesByTimeRange( $options['start_time'], $options['end_time'] ); if (empty($tables)) { return ['total' => 0, 'data' => [], 'page' => $options['page'], 'limit' => $options['limit']]; } // 构建查询条件 $queryConditions = $this->buildQueryConditions($where); // 多表查询 return $this->unionQuery($tables, $queryConditions, $options); } /** * 构建查询条件 * @param array $where * @return array */ protected function buildQueryConditions($where) { $conditions = []; $fieldMap = [ 'user_id' => 'user_id', 'gift_user' => 'gift_user', 'from_id' => 'from_id', 'gift_id' => 'gift_id', 'type' => 'type', 'from' => 'from', 'gift_type' => 'gift_type', 'createtime' => 'createtime', ]; foreach ($where as $key => $value) { if (isset($fieldMap[$key])) { if (is_array($value) && isset($value[0]) && in_array(strtolower($value[0]), ['>', '<', '>=', '<=', '<>', '!=', 'like', 'not like', 'between'])) { $conditions[$fieldMap[$key]] = $value; } else { $conditions[$fieldMap[$key]] = ['=', $value]; } } } return $conditions; } /** * 多表联合查询 * @param array $tables * @param array $conditions * @param array $options * @return array */ protected function unionQuery($tables, $conditions, $options) { $unionSql = ''; $params = []; // 构建每个表的查询 foreach ($tables as $table) { $sql = "SELECT {$options['fields']} FROM `{$table}` WHERE 1=1"; foreach ($conditions as $field => $condition) { if (is_array($condition)) { if (count($condition) == 2) { $operator = $condition[0]; $value = $condition[1]; $sql .= " AND `{$field}` {$operator} ?"; $params[] = $value; } elseif (count($condition) == 3 && strtolower($condition[0]) == 'between') { $sql .= " AND `{$field}` BETWEEN ? AND ?"; $params[] = $condition[1]; $params[] = $condition[2]; } } } // 时间范围 if ($options['start_time']) { $sql .= " AND createtime >= ?"; $params[] = $options['start_time']; } if ($options['end_time']) { $sql .= " AND createtime <= ?"; $params[] = $options['end_time']; } if ($unionSql) { $unionSql .= " UNION ALL "; } $unionSql .= "(" . $sql . ")"; } // 计算总数 $countSql = "SELECT COUNT(*) as total FROM ({$unionSql}) as tmp"; try { $totalResult = Db::query($countSql, $params); $total = $totalResult[0]['total'] ?? 0; } catch (\Exception $e) { Log::error("查询送礼记录总数失败: " . $e->getMessage()); $total = 0; } // 分页查询 $data = []; if ($total > 0) { $offset = ($options['page'] - 1) * $options['limit']; $dataSql = "{$unionSql} ORDER BY {$options['order']} LIMIT {$offset}, {$options['limit']}"; try { $data = Db::query($dataSql, $params); } catch (\Exception $e) { Log::error("查询送礼记录数据失败: " . $e->getMessage()); $data = []; } } return [ 'total' => $total, 'data' => $data, 'page' => $options['page'], 'limit' => $options['limit'] ]; } /** * 统计送礼数据 * @param array $where 查询条件 * @param array $options 统计选项 * @return array */ public function getGiftStatistics($where = [], $options = []) { $defaultOptions = [ 'group_by' => null, // 分组字段 'start_time' => null, 'end_time' => null, ]; $options = array_merge($defaultOptions, $options); // 获取需要查询的表 $tables = GiftTableManager::getTablesByTimeRange( $options['start_time'], $options['end_time'] ); if (empty($tables)) { return []; } // 构建查询条件 $conditions = $this->buildQueryConditions($where); $unionSql = ''; $params = []; // 构建统计SQL $fields = 'SUM(number) as total_number, SUM(total_price) as total_price, COUNT(*) as total_count'; if ($options['group_by']) { $fields .= ", {$options['group_by']}"; } foreach ($tables as $table) { $sql = "SELECT {$fields} FROM `{$table}` WHERE 1=1"; foreach ($conditions as $field => $condition) { if (is_array($condition) && count($condition) == 2) { $operator = $condition[0]; $value = $condition[1]; $sql .= " AND `{$field}` {$operator} ?"; $params[] = $value; } } // 时间范围 if ($options['start_time']) { $sql .= " AND createtime >= ?"; $params[] = $options['start_time']; } if ($options['end_time']) { $sql .= " AND createtime <= ?"; $params[] = $options['end_time']; } if ($options['group_by']) { $sql .= " GROUP BY {$options['group_by']}"; } if ($unionSql) { $unionSql .= " UNION ALL "; } $unionSql .= "(" . $sql . ")"; } // 最终统计 if ($options['group_by']) { $finalSql = "SELECT {$options['group_by']}, SUM(total_number) as total_number, SUM(total_price) as total_price, SUM(total_count) as total_count FROM ({$unionSql}) as tmp GROUP BY {$options['group_by']}"; } else { $finalSql = "SELECT SUM(total_number) as total_number, SUM(total_price) as total_price, SUM(total_count) as total_count FROM ({$unionSql}) as tmp"; } try { $result = Db::query($finalSql, $params); return $options['group_by'] ? $result : ($result[0] ?? []); } catch (\Exception $e) { Log::error("统计送礼数据失败: " . $e->getMessage()); return []; } } /** * 获取时间范围内的送礼趋势 * @param int $startTime 开始时间 * @param int $endTime 结束时间 * @param string $interval 间隔 day, week, month * @return array */ public function getTrendStatistics($startTime, $endTime, $interval = 'day') { $tables = GiftTableManager::getTablesByTimeRange($startTime, $endTime); if (empty($tables)) { return []; } $dateFormat = ''; switch ($interval) { case 'day': $dateFormat = '%Y-%m-%d'; break; case 'week': $dateFormat = '%Y-%u'; break; case 'month': $dateFormat = '%Y-%m'; break; default: $dateFormat = '%Y-%m-%d'; } $unionSql = ''; $params = []; foreach ($tables as $table) { $sql = "SELECT DATE_FORMAT(FROM_UNIXTIME(createtime), '{$dateFormat}') as date_group, SUM(total_price) as total_price, COUNT(*) as total_count, COUNT(DISTINCT user_id) as user_count, COUNT(DISTINCT gift_user) as receiver_count FROM `{$table}` WHERE createtime >= ? AND createtime <= ? GROUP BY date_group"; if ($unionSql) { $unionSql .= " UNION ALL "; } $unionSql .= "(" . $sql . ")"; $params[] = $startTime; $params[] = $endTime; } $finalSql = "SELECT date_group, SUM(total_price) as total_price, SUM(total_count) as total_count, SUM(user_count) as user_count, SUM(receiver_count) as receiver_count FROM ({$unionSql}) as tmp GROUP BY date_group ORDER BY date_group"; try { $result = Db::query($finalSql, $params); return $result; } catch (\Exception $e) { Log::error("获取送礼趋势失败: " . $e->getMessage()); return []; } } /** * 统计送礼数据排行 * @param array $where 查询条件 * @param array $options 统计选项 * @return array */ public function getGiftStatisticsRanking($where = [], $options = []) { $defaultOptions = [ 'group_by' => null, // 分组字段 'start_time' => null, 'end_time' => null, ]; $options = array_merge($defaultOptions, $options); // 获取需要查询的表 $tables = GiftTableManager::getTablesByTimeRange( $options['start_time'], $options['end_time'] ); if (empty($tables)) { return []; } // 构建查询条件 $conditions = $this->buildQueryConditions($where); $unionSql = ''; $params = []; // 构建统计SQL $fields = 'SUM(total_price) as total_price'; if ($options['group_by']) { $fields .= ", {$options['group_by']}"; } foreach ($tables as $table) { $sql = "SELECT {$fields} FROM `{$table}` WHERE 1=1"; foreach ($conditions as $field => $condition) { if (is_array($condition) && count($condition) == 2) { $operator = $condition[0]; $value = $condition[1]; $sql .= " AND `{$field}` {$operator} ?"; $params[] = $value; } } // 时间范围 if ($options['start_time']) { $sql .= " AND createtime >= ?"; $params[] = $options['start_time']; } if ($options['end_time']) { $sql .= " AND createtime <= ?"; $params[] = $options['end_time']; } if ($options['group_by']) { $sql .= " GROUP BY {$options['group_by']}"; } if ($unionSql) { $unionSql .= " UNION ALL "; } $unionSql .= "(" . $sql . ")"; } // 最终统计 if ($options['group_by']) { $finalSql = "SELECT {$options['group_by']}, SUM(total_price) * 10 as total FROM ({$unionSql}) as tmp GROUP BY {$options['group_by']} ORDER BY total desc"; } else { $finalSql = "SELECT SUM(total_number) as total_number, SUM(total_price) as total, SUM(total_count) as total_count FROM ({$unionSql}) as tmp"; } try { $result = Db::query($finalSql, $params); return $options['group_by'] ? $result : ($result[0] ?? []); } catch (\Exception $e) { Log::error("统计送礼数据失败: " . $e->getMessage()); return []; } } }