TransferFeeDailyStats.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. namespace App\Module\Transfer\Models;
  3. use UCore\ModelCore;
  4. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  5. /**
  6. * 手续费每日统计模型
  7. *
  8. * field start
  9. * @property int $id 主键ID
  10. * @property \Carbon\Carbon $stat_date 统计日期
  11. * @property int $transfer_app_id 划转应用ID
  12. * @property int $in_order_count 转入订单数量
  13. * @property float $in_total_amount 转入总金额
  14. * @property float $in_fee_amount 转入手续费总额
  15. * @property float $in_avg_fee_rate 转入平均手续费率
  16. * @property int $out_order_count 转出订单数量
  17. * @property float $out_total_amount 转出总金额
  18. * @property float $out_fee_amount 转出手续费总额
  19. * @property float $out_avg_fee_rate 转出平均手续费率
  20. * @property int $total_order_count 总订单数量
  21. * @property float $total_amount 总交易金额
  22. * @property float $total_fee_amount 总手续费金额
  23. * @property float $avg_fee_rate 平均手续费率
  24. * @property \Carbon\Carbon $created_at 创建时间
  25. * @property \Carbon\Carbon $updated_at 更新时间
  26. * field end
  27. *
  28. * relation start
  29. * @property \App\Module\Transfer\Models\TransferApp $transferApp 划转应用
  30. * relation end
  31. */
  32. class TransferFeeDailyStats extends ModelCore
  33. {
  34. /**
  35. * 表名
  36. */
  37. protected $table = 'transfer_fee_daily_stats';
  38. // attrlist start
  39. protected $fillable = [
  40. 'id',
  41. 'stat_date',
  42. 'transfer_app_id',
  43. 'in_order_count',
  44. 'in_total_amount',
  45. 'in_fee_amount',
  46. 'in_avg_fee_rate',
  47. 'out_order_count',
  48. 'out_total_amount',
  49. 'out_fee_amount',
  50. 'out_avg_fee_rate',
  51. 'total_order_count',
  52. 'total_amount',
  53. 'total_fee_amount',
  54. 'avg_fee_rate',
  55. ];
  56. // attrlist end
  57. /**
  58. * 属性类型转换
  59. */
  60. protected $casts = [
  61. 'id' => 'integer',
  62. 'stat_date' => 'date',
  63. 'transfer_app_id' => 'integer',
  64. 'in_order_count' => 'integer',
  65. 'in_total_amount' => 'decimal:10',
  66. 'in_fee_amount' => 'decimal:10',
  67. 'in_avg_fee_rate' => 'decimal:5',
  68. 'out_order_count' => 'integer',
  69. 'out_total_amount' => 'decimal:10',
  70. 'out_fee_amount' => 'decimal:10',
  71. 'out_avg_fee_rate' => 'decimal:5',
  72. 'total_order_count' => 'integer',
  73. 'total_amount' => 'decimal:10',
  74. 'total_fee_amount' => 'decimal:10',
  75. 'avg_fee_rate' => 'decimal:5',
  76. 'created_at' => 'datetime',
  77. 'updated_at' => 'datetime',
  78. ];
  79. /**
  80. * 隐藏字段
  81. */
  82. protected $hidden = [];
  83. /**
  84. * 关联划转应用
  85. */
  86. public function transferApp(): BelongsTo
  87. {
  88. return $this->belongsTo(TransferApp::class, 'transfer_app_id');
  89. }
  90. /**
  91. * 获取指定日期和应用的统计记录
  92. *
  93. * @param string $date 统计日期
  94. * @param int $appId 应用ID
  95. * @return static|null
  96. */
  97. public static function getByDateAndApp(string $date, int $appId): ?static
  98. {
  99. return static::where('stat_date', $date)
  100. ->where('transfer_app_id', $appId)
  101. ->first();
  102. }
  103. /**
  104. * 获取指定日期范围的统计数据
  105. *
  106. * @param string $startDate 开始日期
  107. * @param string $endDate 结束日期
  108. * @param int $appId 应用ID(0表示所有应用)
  109. * @return \Illuminate\Database\Eloquent\Collection
  110. */
  111. public static function getByDateRange(string $startDate, string $endDate, int $appId = 0)
  112. {
  113. $query = static::with('transferApp')
  114. ->whereBetween('stat_date', [$startDate, $endDate]);
  115. if ($appId > 0) {
  116. $query->where('transfer_app_id', $appId);
  117. }
  118. return $query->orderBy('stat_date', 'desc')
  119. ->orderBy('total_fee_amount', 'desc')
  120. ->get();
  121. }
  122. /**
  123. * 获取月度统计汇总
  124. *
  125. * @param int $year 年份
  126. * @param int $month 月份
  127. * @param int $appId 应用ID(0表示所有应用)
  128. * @return array
  129. */
  130. public static function getMonthlyStats(int $year, int $month, int $appId = 0): array
  131. {
  132. $query = static::whereYear('stat_date', $year)
  133. ->whereMonth('stat_date', $month);
  134. if ($appId > 0) {
  135. $query->where('transfer_app_id', $appId);
  136. }
  137. $stats = $query->selectRaw('
  138. COUNT(*) as stat_days,
  139. SUM(total_order_count) as total_orders,
  140. SUM(total_amount) as total_amount,
  141. SUM(total_fee_amount) as total_fee,
  142. AVG(avg_fee_rate) as avg_fee_rate,
  143. SUM(in_order_count) as total_in_orders,
  144. SUM(in_fee_amount) as total_in_fee,
  145. SUM(out_order_count) as total_out_orders,
  146. SUM(out_fee_amount) as total_out_fee
  147. ')->first();
  148. return [
  149. 'year' => $year,
  150. 'month' => $month,
  151. 'stat_days' => $stats->stat_days ?? 0,
  152. 'total_orders' => $stats->total_orders ?? 0,
  153. 'total_amount' => $stats->total_amount ?? '0.0000000000',
  154. 'total_fee' => $stats->total_fee ?? '0.0000000000',
  155. 'avg_fee_rate' => $stats->avg_fee_rate ?? '0.00000',
  156. 'total_in_orders' => $stats->total_in_orders ?? 0,
  157. 'total_in_fee' => $stats->total_in_fee ?? '0.0000000000',
  158. 'total_out_orders' => $stats->total_out_orders ?? 0,
  159. 'total_out_fee' => $stats->total_out_fee ?? '0.0000000000',
  160. ];
  161. }
  162. /**
  163. * 获取应用汇总统计
  164. *
  165. * @param int $appId 应用ID(0表示所有应用)
  166. * @return array
  167. */
  168. public static function getAppSummary(int $appId = 0): array
  169. {
  170. $query = static::with('transferApp');
  171. if ($appId > 0) {
  172. $query->where('transfer_app_id', $appId);
  173. }
  174. $stats = $query->selectRaw('
  175. transfer_app_id,
  176. COUNT(*) as stat_days,
  177. SUM(total_order_count) as total_orders,
  178. SUM(total_amount) as total_amount,
  179. SUM(total_fee_amount) as total_fee,
  180. AVG(avg_fee_rate) as avg_fee_rate,
  181. SUM(in_order_count) as total_in_orders,
  182. SUM(in_fee_amount) as total_in_fee,
  183. SUM(out_order_count) as total_out_orders,
  184. SUM(out_fee_amount) as total_out_fee,
  185. MIN(stat_date) as first_stat_date,
  186. MAX(stat_date) as last_stat_date
  187. ')
  188. ->groupBy('transfer_app_id')
  189. ->orderBy('total_fee', 'desc')
  190. ->get();
  191. return $stats->toArray();
  192. }
  193. /**
  194. * 创建或更新统计记录
  195. *
  196. * @param array $data 统计数据
  197. * @return static
  198. */
  199. public static function createOrUpdate(array $data): static
  200. {
  201. return static::updateOrCreate(
  202. [
  203. 'stat_date' => $data['stat_date'],
  204. 'transfer_app_id' => $data['transfer_app_id'],
  205. ],
  206. $data
  207. );
  208. }
  209. /**
  210. * 格式化手续费金额显示
  211. *
  212. * @return string
  213. */
  214. public function getFormattedTotalFeeAttribute(): string
  215. {
  216. return number_format($this->total_fee_amount, 4);
  217. }
  218. /**
  219. * 格式化手续费率显示
  220. *
  221. * @return string
  222. */
  223. public function getFormattedAvgFeeRateAttribute(): string
  224. {
  225. return number_format($this->avg_fee_rate * 100, 2) . '%';
  226. }
  227. /**
  228. * 获取统计日期的中文格式
  229. *
  230. * @return string
  231. */
  232. public function getFormattedStatDateAttribute(): string
  233. {
  234. return $this->stat_date->format('Y年m月d日');
  235. }
  236. }