559 lines
17 KiB
PHP
559 lines
17 KiB
PHP
<?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 . ")";
|
||
}
|
||
|
||
// 最终统计
|
||
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);
|
||
var_dump($result);
|
||
return $options['group_by'] ? $result : ($result[0] ?? []);
|
||
} catch (\Exception $e) {
|
||
Log::error("统计送礼数据失败: " . $e->getMessage());
|
||
return [];
|
||
}
|
||
}
|
||
} |