Reward.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. namespace app\api\controller\commission;
  3. use app\common\model\commission\Reward as RewardModel;
  4. use app\common\model\commission\Agent as AgentModel;
  5. use app\common\library\BcMath;
  6. class Reward extends Commission
  7. {
  8. protected $noNeedLogin = [];
  9. protected $noNeedRight = ['*'];
  10. /**
  11. * 分销商佣金列表
  12. */
  13. public function list()
  14. {
  15. $params = $this->request->param();
  16. // 使用验证器验证分页参数:page, page_size, time_filter, start_date, end_date
  17. $validate = new \app\api\validate\Reward();
  18. if (!$validate->scene('list')->check($params)) {
  19. $this->error($validate->getError());
  20. }
  21. $agentId = $this->service->user->id;
  22. // 验证当前用户是否为代理商
  23. $agent = $this->service->agent;
  24. if (!$agent) {
  25. $this->error('您还不是分销商');
  26. }
  27. // 获取验证后的参数
  28. $pageSize = isset($params['page_size']) ? (int)$params['page_size'] : 8;
  29. $timeFilter = isset($params['time_filter']) ? $params['time_filter'] : 'all';
  30. $startDate = isset($params['start_date']) ? $params['start_date'] : '';
  31. $endDate = isset($params['end_date']) ? $params['end_date'] : '';
  32. // 构建查询条件
  33. $query = RewardModel::where('agent_id', $agent->id)
  34. ->where('status', RewardModel::COMMISSION_REWARD_STATUS_ACCOUNTED) // 只查询已结算的佣金
  35. ->with(['commissionOrder']) // 关联佣金订单信息
  36. ->order('commission_time desc'); // 按佣金时间倒序
  37. // 根据时间筛选参数添加时间条件
  38. if ($timeFilter !== 'all') {
  39. $timeConditions = $this->getTimeFilterConditions($timeFilter, $startDate, $endDate);
  40. if ($timeConditions) {
  41. $query->where('commission_time', '>=', $timeConditions['start_time']);
  42. if (isset($timeConditions['end_time'])) {
  43. $query->where('commission_time', '<=', $timeConditions['end_time']);
  44. }
  45. }
  46. }
  47. // 分页查询
  48. $data = $query->paginate($pageSize);
  49. $paginateData = $data->toArray();
  50. // 处理佣金列表数据
  51. $this->processRewardList($paginateData['data']);
  52. // 计算summary统计信息
  53. $summary = $this->calculateSummary($agent, $timeFilter, $startDate, $endDate);
  54. // 重新构造返回数据
  55. $result = [
  56. 'total' => $paginateData['total'],
  57. 'per_page' => $paginateData['per_page'],
  58. 'current_page' => $paginateData['current_page'],
  59. 'last_page' => $paginateData['last_page'],
  60. 'list' => $paginateData['data'],
  61. 'summary' => $summary
  62. ];
  63. $this->success("", $result);
  64. }
  65. /**
  66. * 处理佣金列表数据
  67. * @param array $rewardList 佣金列表数据的引用
  68. * @return void
  69. */
  70. private function processRewardList(&$rewardList)
  71. {
  72. if (empty($rewardList)) {
  73. return;
  74. }
  75. foreach ($rewardList as &$reward) {
  76. // 格式化佣金金额
  77. $reward['commission'] = BcMath::format($reward['commission'] ?? '0.00');
  78. // 格式化佣金时间
  79. $reward['commission_time_text'] = !empty($reward['commission_time'])
  80. ? date('Y-m-d H:i:s', $reward['commission_time'])
  81. : '';
  82. // 添加佣金类型描述
  83. $reward['type_text'] = $this->getRewardTypeText($reward['type'] ?? '');
  84. // 添加订单信息(如果有关联订单)
  85. if (!empty($reward['commission_order'])) {
  86. $order = $reward['commission_order'];
  87. $reward['order_info'] = [
  88. 'order_id' => $order['order_id'] ?? '',
  89. 'amount' => BcMath::format($order['amount'] ?? '0.00'),
  90. 'buyer_nickname' => $order['buyer_nickname'] ?? '',
  91. ];
  92. }
  93. // 清理不需要的关联数据,避免冗余
  94. unset($reward['commission_order']);
  95. }
  96. }
  97. /**
  98. * 获取佣金类型描述
  99. * @param string $type 佣金类型
  100. * @return string
  101. */
  102. private function getRewardTypeText($type)
  103. {
  104. $typeMap = [
  105. 'money' => '现金佣金',
  106. 'score' => '积分佣金',
  107. 'commission' => '佣金收益',
  108. ];
  109. return $typeMap[$type] ?? '未知类型';
  110. }
  111. /**
  112. * 计算summary统计信息
  113. * @param object $agent 当前代理商对象
  114. * @param string $timeFilter 时间筛选类型
  115. * @param string $startDate 开始日期
  116. * @param string $endDate 结束日期
  117. * @return array
  118. */
  119. private function calculateSummary($agent, $timeFilter, $startDate, $endDate)
  120. {
  121. // 根据筛选条件构建统计查询
  122. $query = RewardModel::where('agent_id', $agent->id)
  123. ->where('status', RewardModel::COMMISSION_REWARD_STATUS_ACCOUNTED);
  124. // 应用时间筛选
  125. if ($timeFilter !== 'all') {
  126. $timeConditions = $this->getTimeFilterConditions($timeFilter, $startDate, $endDate);
  127. if ($timeConditions) {
  128. $query->where('commission_time', '>=', $timeConditions['start_time']);
  129. if (isset($timeConditions['end_time'])) {
  130. $query->where('commission_time', '<=', $timeConditions['end_time']);
  131. }
  132. }
  133. }
  134. // 计算筛选条件下的统计数据
  135. $totalCommission = $query->sum('commission') ?: '0.00';
  136. $totalCount = $query->count();
  137. // 按佣金类型统计
  138. $typeStats = $query->field('type, SUM(commission) as total_amount, COUNT(*) as count')
  139. ->group('type')
  140. ->select()
  141. ->toArray();
  142. $typeStatistics = [];
  143. foreach ($typeStats as $stat) {
  144. $typeStatistics[] = [
  145. 'type' => $stat['type'],
  146. 'type_text' => $this->getRewardTypeText($stat['type']),
  147. 'total_amount' => BcMath::format($stat['total_amount'] ?? '0.00'),
  148. 'count' => intval($stat['count'] ?? 0)
  149. ];
  150. }
  151. return [
  152. 'total_commission' => BcMath::format($totalCommission),
  153. 'total_count' => $totalCount,
  154. 'agent_total_income' => BcMath::format($agent->total_income ?? '0.00'),
  155. 'agent_withdrawn_amount' => BcMath::format($agent->withdrawn_amount ?? '0.00'),
  156. 'available_balance' => BcMath::format(BcMath::sub($agent->total_income ?? '0.00', $agent->withdrawn_amount ?? '0.00')),
  157. 'type_statistics' => $typeStatistics
  158. ];
  159. }
  160. /**
  161. * 获取时间筛选条件
  162. * @param string $timeFilter 时间筛选类型
  163. * @param string $startDate 开始日期 (Y-m-d格式,用于自定义时间段)
  164. * @param string $endDate 结束日期 (Y-m-d格式,用于自定义时间段)
  165. * @return array|null 返回包含开始时间和结束时间的数组
  166. */
  167. private function getTimeFilterConditions($timeFilter, $startDate = '', $endDate = '')
  168. {
  169. $currentTime = time();
  170. switch ($timeFilter) {
  171. case 'recent_7_days':
  172. return [
  173. 'start_time' => $currentTime - 7 * 24 * 3600,
  174. ];
  175. case 'recent_30_days':
  176. return [
  177. 'start_time' => $currentTime - 30 * 24 * 3600,
  178. ];
  179. case 'recent_90_days':
  180. return [
  181. 'start_time' => $currentTime - 90 * 24 * 3600,
  182. ];
  183. case 'current_year':
  184. // 当前年份的开始时间
  185. $yearStart = strtotime(date('Y-01-01 00:00:00'));
  186. // 当前年份的结束时间
  187. $yearEnd = strtotime(date('Y-12-31 23:59:59'));
  188. return [
  189. 'start_time' => $yearStart,
  190. 'end_time' => $yearEnd,
  191. ];
  192. case 'custom':
  193. // 自定义时间段
  194. if (empty($startDate) || empty($endDate)) {
  195. return null;
  196. }
  197. $startTime = strtotime($startDate . ' 00:00:00');
  198. $endTime = strtotime($endDate . ' 23:59:59');
  199. if ($startTime === false || $endTime === false || $startTime > $endTime) {
  200. return null;
  201. }
  202. return [
  203. 'start_time' => $startTime,
  204. 'end_time' => $endTime,
  205. ];
  206. default:
  207. return null;
  208. }
  209. }
  210. }