TransferFeeDailyStats.php 8.1 KB

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