Files
yusheng-php/application/common/model/GiveGiftBase.php
2026-01-09 17:53:33 +08:00

559 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// application/common/model/GiveGiftBases.php
namespace app\common\model;
use think\Model;
use think\Db;
use think\Log;
use app\common\library\GiftTableManager;
use app\common\library\Snowflake;
class GiveGiftBase extends Model
{
// 关闭自动时间戳
protected $autoWriteTimestamp = false;
// 错误信息
protected $error = '';
/**
* 获取错误信息
* @return string
*/
public function getError()
{
return $this->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 . ")";
}
var_dump(1231);
var_dump($unionSql);exit;
// 最终统计
if ($options['group_by']) {
$finalSql = "SELECT {$options['group_by']},
SUM(total_price) as total_price,
FROM ({$unionSql}) as tmp
GROUP BY {$options['group_by']}
ORDER BY total_price";
} 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 [];
}
}
}