FeeStatisticsService.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <?php
  2. namespace App\Module\Transfer\Services;
  3. use App\Module\Transfer\Models\TransferApp;
  4. use App\Module\Transfer\Models\TransferOrder;
  5. use App\Module\Transfer\Models\TransferFeeDailyStats;
  6. use App\Module\Transfer\Enums\TransferStatus;
  7. use App\Module\Transfer\Enums\TransferType;
  8. use App\Module\Transfer\Logics\FeeStatisticsLogic;
  9. use Illuminate\Support\Facades\Log;
  10. use Carbon\Carbon;
  11. /**
  12. * 手续费统计服务类
  13. *
  14. * 负责处理Transfer模块的手续费统计功能
  15. */
  16. class FeeStatisticsService
  17. {
  18. /**
  19. * 执行每日手续费统计
  20. *
  21. * @param string|null $date 统计日期,默认为昨天
  22. * @return array 统计结果
  23. */
  24. public static function runDailyStatistics(?string $date = null): array
  25. {
  26. try {
  27. $date = $date ?: Carbon::yesterday()->format('Y-m-d');
  28. Log::info("开始执行手续费每日统计", ['date' => $date]);
  29. $result = FeeStatisticsLogic::runDailyStatistics($date);
  30. Log::info("手续费每日统计完成", [
  31. 'date' => $date,
  32. 'processed_apps' => count($result['apps']),
  33. 'total_orders' => $result['summary']['total_orders'],
  34. 'total_fee' => $result['summary']['total_fee']
  35. ]);
  36. return $result;
  37. } catch (\Exception $e) {
  38. Log::error("手续费每日统计失败", [
  39. 'date' => $date ?? 'unknown',
  40. 'error' => $e->getMessage(),
  41. 'trace' => $e->getTraceAsString()
  42. ]);
  43. throw $e;
  44. }
  45. }
  46. /**
  47. * 获取指定日期范围的统计数据
  48. *
  49. * @param string $startDate 开始日期
  50. * @param string $endDate 结束日期
  51. * @param int $appId 应用ID(0表示所有应用)
  52. * @return array
  53. */
  54. public static function getStatsByDateRange(string $startDate, string $endDate, int $appId = 0): array
  55. {
  56. try {
  57. return FeeStatisticsLogic::getStatsByDateRange($startDate, $endDate, $appId);
  58. } catch (\Exception $e) {
  59. Log::error("获取手续费统计数据失败", [
  60. 'start_date' => $startDate,
  61. 'end_date' => $endDate,
  62. 'app_id' => $appId,
  63. 'error' => $e->getMessage()
  64. ]);
  65. return [
  66. 'error' => $e->getMessage(),
  67. 'data' => [],
  68. 'summary' => [
  69. 'total_days' => 0,
  70. 'total_orders' => 0,
  71. 'total_amount' => '0.0000000000',
  72. 'total_fee' => '0.0000000000',
  73. 'avg_fee_rate' => '0.00000'
  74. ]
  75. ];
  76. }
  77. }
  78. /**
  79. * 获取月度统计数据
  80. *
  81. * @param int $year 年份
  82. * @param int $month 月份
  83. * @param int $appId 应用ID(0表示所有应用)
  84. * @return array
  85. */
  86. public static function getMonthlyStats(int $year, int $month, int $appId = 0): array
  87. {
  88. try {
  89. return FeeStatisticsLogic::getMonthlyStats($year, $month, $appId);
  90. } catch (\Exception $e) {
  91. Log::error("获取月度手续费统计失败", [
  92. 'year' => $year,
  93. 'month' => $month,
  94. 'app_id' => $appId,
  95. 'error' => $e->getMessage()
  96. ]);
  97. return [
  98. 'error' => $e->getMessage(),
  99. 'year' => $year,
  100. 'month' => $month,
  101. 'stat_days' => 0,
  102. 'total_orders' => 0,
  103. 'total_amount' => '0.0000000000',
  104. 'total_fee' => '0.0000000000',
  105. 'avg_fee_rate' => '0.00000'
  106. ];
  107. }
  108. }
  109. /**
  110. * 获取应用汇总统计
  111. *
  112. * @param int $appId 应用ID(0表示所有应用)
  113. * @return array
  114. */
  115. public static function getAppSummary(int $appId = 0): array
  116. {
  117. try {
  118. return FeeStatisticsLogic::getAppSummary($appId);
  119. } catch (\Exception $e) {
  120. Log::error("获取应用汇总统计失败", [
  121. 'app_id' => $appId,
  122. 'error' => $e->getMessage()
  123. ]);
  124. return [
  125. 'error' => $e->getMessage(),
  126. 'data' => []
  127. ];
  128. }
  129. }
  130. /**
  131. * 获取最近N天的统计趋势
  132. *
  133. * @param int $days 天数
  134. * @param int $appId 应用ID(0表示所有应用)
  135. * @return array
  136. */
  137. public static function getRecentTrend(int $days = 7, int $appId = 0): array
  138. {
  139. try {
  140. $endDate = Carbon::yesterday()->format('Y-m-d');
  141. $startDate = Carbon::yesterday()->subDays($days - 1)->format('Y-m-d');
  142. return self::getStatsByDateRange($startDate, $endDate, $appId);
  143. } catch (\Exception $e) {
  144. Log::error("获取手续费趋势数据失败", [
  145. 'days' => $days,
  146. 'app_id' => $appId,
  147. 'error' => $e->getMessage()
  148. ]);
  149. return [
  150. 'error' => $e->getMessage(),
  151. 'data' => [],
  152. 'summary' => []
  153. ];
  154. }
  155. }
  156. /**
  157. * 获取手续费收入排行榜
  158. *
  159. * @param string $startDate 开始日期
  160. * @param string $endDate 结束日期
  161. * @param int $limit 限制数量
  162. * @return array
  163. */
  164. public static function getFeeRanking(string $startDate, string $endDate, int $limit = 10): array
  165. {
  166. try {
  167. return FeeStatisticsLogic::getFeeRanking($startDate, $endDate, $limit);
  168. } catch (\Exception $e) {
  169. Log::error("获取手续费排行榜失败", [
  170. 'start_date' => $startDate,
  171. 'end_date' => $endDate,
  172. 'limit' => $limit,
  173. 'error' => $e->getMessage()
  174. ]);
  175. return [
  176. 'error' => $e->getMessage(),
  177. 'data' => []
  178. ];
  179. }
  180. }
  181. /**
  182. * 重新统计指定日期的数据
  183. *
  184. * @param string $date 统计日期
  185. * @param int $appId 应用ID(0表示所有应用)
  186. * @return array
  187. */
  188. public static function restatistics(string $date, int $appId = 0): array
  189. {
  190. try {
  191. Log::info("开始重新统计手续费数据", ['date' => $date, 'app_id' => $appId]);
  192. $result = FeeStatisticsLogic::restatistics($date, $appId);
  193. Log::info("重新统计手续费数据完成", [
  194. 'date' => $date,
  195. 'app_id' => $appId,
  196. 'result' => $result
  197. ]);
  198. return $result;
  199. } catch (\Exception $e) {
  200. Log::error("重新统计手续费数据失败", [
  201. 'date' => $date,
  202. 'app_id' => $appId,
  203. 'error' => $e->getMessage()
  204. ]);
  205. throw $e;
  206. }
  207. }
  208. /**
  209. * 获取统计配置信息
  210. *
  211. * @return array
  212. */
  213. public static function getStatisticsConfig(): array
  214. {
  215. return [
  216. 'schedule_time' => '22:00',
  217. 'timezone' => config('app.timezone', 'Asia/Shanghai'),
  218. 'retention_days' => 365, // 保留365天的统计数据
  219. 'batch_size' => 1000, // 批量处理大小
  220. 'enabled_apps' => TransferApp::where('is_enabled', true)->count(),
  221. 'total_apps' => TransferApp::count(),
  222. ];
  223. }
  224. /**
  225. * 清理过期的统计数据
  226. *
  227. * @param int $retentionDays 保留天数
  228. * @return int 清理的记录数
  229. */
  230. public static function cleanupExpiredStats(int $retentionDays = 365): int
  231. {
  232. try {
  233. $cutoffDate = Carbon::now()->subDays($retentionDays)->format('Y-m-d');
  234. $deletedCount = TransferFeeDailyStats::where('stat_date', '<', $cutoffDate)->delete();
  235. Log::info("清理过期手续费统计数据", [
  236. 'cutoff_date' => $cutoffDate,
  237. 'deleted_count' => $deletedCount
  238. ]);
  239. return $deletedCount;
  240. } catch (\Exception $e) {
  241. Log::error("清理过期手续费统计数据失败", [
  242. 'retention_days' => $retentionDays,
  243. 'error' => $e->getMessage()
  244. ]);
  245. throw $e;
  246. }
  247. }
  248. /**
  249. * 验证统计数据的完整性
  250. *
  251. * @param string $date 检查日期
  252. * @return array
  253. */
  254. public static function validateStatistics(string $date): array
  255. {
  256. try {
  257. return FeeStatisticsLogic::validateStatistics($date);
  258. } catch (\Exception $e) {
  259. Log::error("验证统计数据完整性失败", [
  260. 'date' => $date,
  261. 'error' => $e->getMessage()
  262. ]);
  263. return [
  264. 'valid' => false,
  265. 'error' => $e->getMessage(),
  266. 'details' => []
  267. ];
  268. }
  269. }
  270. }