PromotionQuery.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <?php
  2. declare(strict_types=1);
  3. namespace plugin\saiadmin\app\service\promotion;
  4. use plugin\saiadmin\app\model\water\WaterPromotionCode;
  5. use plugin\saiadmin\app\model\water\WaterPromotionReferral;
  6. use plugin\saiadmin\app\service\WaterBusiness;
  7. use plugin\saiadmin\exception\ApiException;
  8. final class PromotionQuery
  9. {
  10. public const STATUSES = ['bound' => '待首购', 'pending' => '待签收及审核', 'issued' => '已发放', 'rejected' => '不予发放'];
  11. public static function issuedBuckets(int $enterprise): int
  12. {
  13. return (int) WaterPromotionReferral::query()->where('inviter_id', $enterprise)->where('status', 'issued')->sum('quantity');
  14. }
  15. public static function present(WaterPromotionReferral $row, bool $internal = true): array
  16. {
  17. return [
  18. 'id' => (int) $row->id, 'inviter_name' => $row->inviter?->name ?? '已删除企业',
  19. 'enterprise_name' => $row->invited?->name ?? '已删除企业',
  20. 'sku_name' => $row->sku?->name ?? '已删除规格', 'quantity' => (int) $row->quantity,
  21. 'status' => $row->status, 'status_text' => self::STATUSES[$row->status],
  22. 'order_id' => !$internal || $row->order_id === null ? null : (int) $row->order_id,
  23. 'reference' => $internal ? $row->order?->reference : null,
  24. 'amount_cents' => !$internal || $row->purchase_amount_cents === null ? null : (int) $row->purchase_amount_cents,
  25. 'created_at' => $row->created_at, 'qualified_at' => $row->qualified_at,
  26. 'reviewed_at' => $row->reviewed_at, 'review_note' => $internal ? $row->review_note : '',
  27. 'delivery_id' => !$internal || $row->delivery_id === null ? null : (int) $row->delivery_id,
  28. 'revision' => (int) $row->revision,
  29. ];
  30. }
  31. public function dashboard(array $input): array
  32. {
  33. $policy = PromotionPolicy::current();
  34. $page = WaterBusiness::positive($input['page'] ?? 1, '页码');
  35. $limit = min(50, WaterBusiness::positive($input['limit'] ?? 20, '每页条数'));
  36. $status = $input['status'] ?? '';
  37. if (!is_string($status) || ($status !== '' && !isset(self::STATUSES[$status]))) {
  38. throw new ApiException('奖励状态不正确');
  39. }
  40. if (!$policy['initialized']) {
  41. return ['policy' => $policy, 'list' => ['data' => [], 'total' => 0], 'statuses' => self::STATUSES];
  42. }
  43. $query = WaterPromotionReferral::query()->with(['inviter', 'invited', 'sku', 'order']);
  44. if ($status !== '') {
  45. $query->where('status', $status);
  46. }
  47. $total = (clone $query)->count();
  48. $rows = $query->orderByDesc('id')->forPage($page, $limit)->get();
  49. return ['policy' => $policy, 'list' => [
  50. 'data' => $rows->map(fn ($row) => self::present($row))->all(), 'total' => $total,
  51. ], 'statuses' => self::STATUSES];
  52. }
  53. public function enterprise(int $enterprise, array $input = []): array
  54. {
  55. $policy = PromotionPolicy::current();
  56. $page = WaterBusiness::positive($input['page'] ?? 1, '页码');
  57. $base = [
  58. 'enabled' => $policy['enabled'], 'reason' => $policy['rules'], 'reward_type' => 'water',
  59. 'total_cents' => null, 'withdrawable_cents' => null, 'demo' => false,
  60. 'invite_code' => null, 'total_buckets' => 0, 'successful_invites' => 0,
  61. 'first_order_enterprises' => 0, 'bound' => null, 'items' => [], 'total' => 0,
  62. 'policy' => $policy,
  63. ];
  64. if (!$policy['initialized']) {
  65. return $base;
  66. }
  67. $base['invite_code'] = WaterPromotionCode::query()->where('enterprise_id', $enterprise)->value('code');
  68. $invites = WaterPromotionReferral::query()->where('inviter_id', $enterprise);
  69. $base['total_buckets'] = self::issuedBuckets($enterprise);
  70. $base['successful_invites'] = (clone $invites)->count();
  71. $base['first_order_enterprises'] = (clone $invites)->whereNotNull('order_id')->count();
  72. $base['total'] = $base['successful_invites'];
  73. $base['items'] = $invites->with(['inviter', 'invited', 'sku', 'order'])->orderByDesc('id')
  74. ->forPage($page, 20)->get()->map(fn ($row) => self::present($row, false))->all();
  75. $bound = WaterPromotionReferral::query()->with(['inviter', 'invited', 'sku', 'order'])
  76. ->where('invited_id', $enterprise)->first();
  77. $base['bound'] = $bound ? self::present($bound, false) : null;
  78. return $base;
  79. }
  80. }