| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- <?php
- namespace App\Services;
- use App\Models\Backflow;
- use Carbon\Carbon;
- use Exception;
- class BackflowService extends BaseService
- {
- public static string $MODEL = Backflow::class;
- public static function findOne(array $search): ?Backflow
- {
- return self::$MODEL::where(static::getWhere($search))->first();
- }
- /**
- * 进行回水操作
- * @param $id
- * @return bool
- * @throws Exception
- */
- public static function grant($id): bool
- {
- return RewardGrantService::grant('backflow', (int) $id, (string) (request()->user->username ?? 'system'));
- }
- /**
- * 只记录当月充值/提现,回水金额由 rewards:sync-bases 按分类亏损和规则计算。
- * @param $memberId string 会员ID
- * @param $changeAmount float 充值或提现金额
- * @return Backflow
- */
- public static function updateOrCreate(string $memberId, float $changeAmount): Backflow
- {
- $date = Carbon::now('Asia/Shanghai')->format('Y-m');
- $field = $changeAmount > 0 ? 'recharge_amount' : 'withdrawal_amount';
- $backflow = static::$MODEL::firstOrCreate(['date' => $date, 'member_id' => $memberId]);
- if (in_array((int) $backflow->status, Backflow::OPEN_STATUSES, true)) $backflow->increment($field, $changeAmount);
- return $backflow->refresh();
- }
- /** 已发放 / 待发放 / 是否可发放(回水可在当月多次发放差额) */
- public static function grantFields(array $row): array
- {
- $amount = bcadd((string) ($row['amount'] ?? 0), '0', 2);
- $granted = bcadd((string) ($row['granted_amount'] ?? 0), '0', 2);
- $open = in_array((int) ($row['status'] ?? 0), Backflow::OPEN_STATUSES, true);
- $pending = $open && bccomp($amount, $granted, 2) > 0 ? bcsub($amount, $granted, 2) : '0.00';
- $month = Carbon::now('Asia/Shanghai')->format('Y-m');
- return [
- 'amount' => $amount,
- 'granted_amount' => $granted,
- 'pending_amount' => $pending,
- // 当月需有差额才能发;往月未结清的记录即使差额为 0 也可点发放以结清
- 'can_grant' => $open && (bccomp($pending, '0', 2) > 0 || (string) ($row['date'] ?? '') < $month),
- 'status_text' => [Backflow::STATUS_PENDING => '未发放', Backflow::STATUS_GRANTED => '已发放', Backflow::STATUS_PARTIAL => '部分发放'][(int) ($row['status'] ?? 0)] ?? '',
- ];
- }
- public static function getWhere(array $search = []): array
- {
- $where = [];
- if (isset($search['id']) && !empty($search['id'])) {
- $where[] = ['backflow.id', '=', $search['id']];
- }
- if (isset($search['member_id']) && !empty($search['member_id'])) {
- $where[] = ['backflow.member_id', '=', $search['member_id']];
- }
- if (isset($search['date']) && !empty($search['date'])) {
- $where[] = ['backflow.date', '=', $search['date']];
- }
- if (isset($search['status']) && $search['status'] != '') {
- $where[] = ['backflow.status', '=', $search['status']];
- }
-
- if (!empty($search['account'])) {
- $where[] = ['users.account', 'like', '%' . trim((string)$search['account']) . '%'];
- }
- if (!empty($search['first_name'])) {
- $where[] = ['users.first_name','like', '%'.$search['first_name'].'%'];
- }
- return $where;
- }
- public static function paginate(array $search = []): array
- {
- // 当月(上海时间)的记录也展示实时统计;后台可手动提前发放,自动发放仍等到下个月,见 RewardGrantService::grant
- $month = Carbon::now('Asia/Shanghai')->format('Y-m');
- $query = static::$MODEL::join('users', 'users.member_id', '=', 'backflow.member_id')
- ->where(static::getWhere($search))
- ->where('backflow.date', '<=', $month);
- $paginator = $query->select("backflow.*", "users.first_name", "users.account", "users.admin_note as user_admin_note")->orderByDesc('date')->orderBy('status')
- ->paginate($search['limit']);
- foreach ($paginator->items() as $item) {
- foreach (self::grantFields($item->toArray()) as $field => $value) $item[$field] = $value;
- }
- // $count = $query->count();
- // $query->with(['user'])->orderByDesc('date')->orderBy('status');
- // $list = $query->forPage($search['page'], $search['limit'])->get()->toArray();
- // return ['total' => $count, 'data' => $list];
- return ['total' => $paginator->total(), 'data' => $paginator->items()];
- }
- }
|