| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- <?php
- namespace App\Module\Point\Services;
- use App\Module\Point\Dto\PointLogDto;
- use App\Module\Point\Models\PointLogModel;
- use App\Module\Point\Enums\LOG_TYPE;
- /**
- * 积分日志服务类
- *
- * 提供积分日志相关的业务功能
- */
- class LogService
- {
- /**
- * 获取用户积分日志
- *
- * @param int $userId 用户ID
- * @param int|null $pointId 积分类型ID(可选)
- * @param int $limit 限制数量
- * @return array 日志DTO数组
- */
- public static function getUserLogs(int $userId, ?int $pointId = null, int $limit = 50): array
- {
- $logs = PointLogModel::getUserLogs($userId, $pointId, $limit);
- $result = [];
- foreach ($logs as $log) {
- $result[] = new PointLogDto([
- 'id' => $log->id,
- 'user_id' => $log->user_id,
- 'point_id' => $log->point_id,
- 'amount' => $log->amount,
- 'operate_id' => $log->operate_id,
- 'operate_type' => $log->operate_type->value,
- 'operate_type_name' => $log->getOperateTypeName(),
- 'remark' => $log->remark,
- 'create_time' => $log->create_time,
- 'create_ip' => $log->create_ip,
- 'later_balance' => $log->later_balance,
- 'before_balance' => $log->before_balance,
- 'is_income' => $log->isIncome(),
- 'is_expense' => $log->isExpense(),
- ]);
- }
- return $result;
- }
- /**
- * 获取用户指定时间范围的积分日志
- *
- * @param int $userId 用户ID
- * @param int $startTime 开始时间
- * @param int $endTime 结束时间
- * @param int|null $pointId 积分类型ID(可选)
- * @return array 日志DTO数组
- */
- public static function getUserLogsByTimeRange(
- int $userId,
- int $startTime,
- int $endTime,
- ?int $pointId = null
- ): array {
- $logs = PointLogModel::getUserLogsByTimeRange($userId, $startTime, $endTime, $pointId);
- $result = [];
- foreach ($logs as $log) {
- $result[] = new PointLogDto([
- 'id' => $log->id,
- 'user_id' => $log->user_id,
- 'point_id' => $log->point_id,
- 'amount' => $log->amount,
- 'operate_id' => $log->operate_id,
- 'operate_type' => $log->operate_type->value,
- 'operate_type_name' => $log->getOperateTypeName(),
- 'remark' => $log->remark,
- 'create_time' => $log->create_time,
- 'create_ip' => $log->create_ip,
- 'later_balance' => $log->later_balance,
- 'before_balance' => $log->before_balance,
- 'is_income' => $log->isIncome(),
- 'is_expense' => $log->isExpense(),
- ]);
- }
- return $result;
- }
- /**
- * 获取用户积分收支统计
- *
- * @param int $userId 用户ID
- * @param int|null $pointId 积分类型ID(可选)
- * @param int|null $startTime 开始时间(可选)
- * @param int|null $endTime 结束时间(可选)
- * @return array 统计信息
- */
- public static function getUserPointStats(
- int $userId,
- ?int $pointId = null,
- ?int $startTime = null,
- ?int $endTime = null
- ): array {
- $query = PointLogModel::where('user_id', $userId);
- if ($pointId !== null) {
- $query->where('point_id', $pointId);
- }
- if ($startTime !== null && $endTime !== null) {
- $query->whereBetween('create_time', [$startTime, $endTime]);
- }
- $logs = $query->get();
- $stats = [
- 'total_logs' => $logs->count(),
- 'total_income' => 0,
- 'total_expense' => 0,
- 'income_count' => 0,
- 'expense_count' => 0,
- 'by_operate_type' => [],
- ];
- foreach ($logs as $log) {
- if ($log->isIncome()) {
- $stats['total_income'] += $log->amount;
- $stats['income_count']++;
- } else {
- $stats['total_expense'] += abs($log->amount);
- $stats['expense_count']++;
- }
- $operateTypeName = $log->getOperateTypeName();
- if (!isset($stats['by_operate_type'][$operateTypeName])) {
- $stats['by_operate_type'][$operateTypeName] = [
- 'count' => 0,
- 'total_amount' => 0,
- ];
- }
- $stats['by_operate_type'][$operateTypeName]['count']++;
- $stats['by_operate_type'][$operateTypeName]['total_amount'] += $log->amount;
- }
- return $stats;
- }
- /**
- * 验证日志记录的完整性
- *
- * @param int $logId 日志ID
- * @return bool 是否完整
- */
- public static function verifyLogIntegrity(int $logId): bool
- {
- $log = PointLogModel::find($logId);
- return $log ? $log->verifyIntegrity() : false;
- }
- /**
- * 批量验证日志记录的完整性
- *
- * @param array $logIds 日志ID数组
- * @return array 验证结果数组
- */
- public static function batchVerifyLogIntegrity(array $logIds): array
- {
- $results = [];
-
- foreach ($logIds as $logId) {
- $results[$logId] = self::verifyLogIntegrity($logId);
- }
- return $results;
- }
- /**
- * 获取积分日志统计信息(按操作类型)
- *
- * @param int|null $pointId 积分类型ID(可选)
- * @param int|null $startTime 开始时间(可选)
- * @param int|null $endTime 结束时间(可选)
- * @return array 统计信息
- */
- public static function getLogStatsByOperateType(
- ?int $pointId = null,
- ?int $startTime = null,
- ?int $endTime = null
- ): array {
- $query = PointLogModel::query();
- if ($pointId !== null) {
- $query->where('point_id', $pointId);
- }
- if ($startTime !== null && $endTime !== null) {
- $query->whereBetween('create_time', [$startTime, $endTime]);
- }
- $logs = $query->get();
- $stats = [];
- foreach ($logs as $log) {
- $operateType = $log->operate_type->value;
- $operateTypeName = $log->getOperateTypeName();
- if (!isset($stats[$operateType])) {
- $stats[$operateType] = [
- 'operate_type' => $operateType,
- 'operate_type_name' => $operateTypeName,
- 'count' => 0,
- 'total_amount' => 0,
- 'income_count' => 0,
- 'expense_count' => 0,
- 'income_amount' => 0,
- 'expense_amount' => 0,
- ];
- }
- $stats[$operateType]['count']++;
- $stats[$operateType]['total_amount'] += $log->amount;
- if ($log->isIncome()) {
- $stats[$operateType]['income_count']++;
- $stats[$operateType]['income_amount'] += $log->amount;
- } else {
- $stats[$operateType]['expense_count']++;
- $stats[$operateType]['expense_amount'] += abs($log->amount);
- }
- }
- return array_values($stats);
- }
- /**
- * 获取每日积分变化统计
- *
- * @param int $userId 用户ID
- * @param int $pointId 积分类型ID
- * @param int $days 统计天数
- * @return array 每日统计数组
- */
- public static function getDailyPointStats(int $userId, int $pointId, int $days = 30): array
- {
- $endTime = time();
- $startTime = $endTime - ($days * 24 * 60 * 60);
- $logs = PointLogModel::where('user_id', $userId)
- ->where('point_id', $pointId)
- ->whereBetween('create_time', [$startTime, $endTime])
- ->orderBy('create_time')
- ->get();
- $dailyStats = [];
-
- // 初始化每日统计
- for ($i = 0; $i < $days; $i++) {
- $date = date('Y-m-d', $endTime - ($i * 24 * 60 * 60));
- $dailyStats[$date] = [
- 'date' => $date,
- 'income' => 0,
- 'expense' => 0,
- 'net_change' => 0,
- 'log_count' => 0,
- ];
- }
- // 统计每日数据
- foreach ($logs as $log) {
- $date = date('Y-m-d', $log->create_time);
-
- if (isset($dailyStats[$date])) {
- $dailyStats[$date]['log_count']++;
-
- if ($log->isIncome()) {
- $dailyStats[$date]['income'] += $log->amount;
- } else {
- $dailyStats[$date]['expense'] += abs($log->amount);
- }
-
- $dailyStats[$date]['net_change'] = $dailyStats[$date]['income'] - $dailyStats[$date]['expense'];
- }
- }
- return array_values($dailyStats);
- }
- /**
- * 搜索积分日志
- *
- * @param array $filters 搜索条件
- * @param int $limit 限制数量
- * @return array 日志数组
- */
- public static function searchLogs(array $filters, int $limit = 50): array
- {
- $query = PointLogModel::query();
- if (isset($filters['user_id'])) {
- $query->where('user_id', $filters['user_id']);
- }
- if (isset($filters['point_id'])) {
- $query->where('point_id', $filters['point_id']);
- }
- if (isset($filters['operate_type'])) {
- $query->where('operate_type', $filters['operate_type']);
- }
- if (isset($filters['operate_id'])) {
- $query->where('operate_id', 'like', '%' . $filters['operate_id'] . '%');
- }
- if (isset($filters['start_time']) && isset($filters['end_time'])) {
- $query->whereBetween('create_time', [$filters['start_time'], $filters['end_time']]);
- }
- if (isset($filters['min_amount'])) {
- $query->where('amount', '>=', $filters['min_amount']);
- }
- if (isset($filters['max_amount'])) {
- $query->where('amount', '<=', $filters['max_amount']);
- }
- $logs = $query->orderBy('create_time', 'desc')->limit($limit)->get();
- $result = [];
- foreach ($logs as $log) {
- $result[] = [
- 'id' => $log->id,
- 'user_id' => $log->user_id,
- 'point_id' => $log->point_id,
- 'amount' => $log->amount,
- 'operate_id' => $log->operate_id,
- 'operate_type' => $log->operate_type->value,
- 'operate_type_name' => $log->getOperateTypeName(),
- 'remark' => $log->remark,
- 'create_time' => $log->create_time,
- 'create_ip' => $log->create_ip,
- 'later_balance' => $log->later_balance,
- 'before_balance' => $log->before_balance,
- 'is_income' => $log->isIncome(),
- 'is_expense' => $log->isExpense(),
- ];
- }
- return $result;
- }
- }
|