| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- <?php
- /**
- * 支付统计仓库.
- *
- * @author nj
- * @date 2021-07-23 10:34
- */
- namespace App\Repositories\Statistics;
- use App\Models\Mysql\AgentAttrsDayModel;
- use App\Models\Mysql\AgentAttrsModel;
- use App\Models\Mysql\AgentModel;
- use App\Repositories\AgentRepository;
- use App\Repositories\CommissionLogRepository;
- use Carbon\Carbon;
- use App\Models\Mongo\PayLogsModel;
- use Jenssegers\Mongodb\Eloquent\Model;
- use DB;
- class StatisticsPayRepository
- {
- /**
- * @var null|AgentRepository
- */
- protected $agentRepo = null;
- /**
- * @var null|CommissionLogRepository
- */
- protected $commissionLogRepo = null;
- /**
- * 计算某一个天的值
- * @param string $computeType 计算类型,count=总计数量;money=总计金额
- * @param mixed $date 日期.
- * @param array $conditions 查询条件.
- * @return int|mixed
- */
- public function computeOneDay($computeType, $date, array $conditions = [])
- {
- $computeType = strtolower($computeType);
- $channelUid = isset($conditions['channel_uid']) ? $conditions['channel_uid'] : null;
- $momAppUid = isset($conditions['mom_app_uid']) ? $conditions['mom_app_uid'] : null;
- $agentUid = isset($conditions['agent_uid']) ? $conditions['agent_uid'] : null;
- $deviceType = data_get($conditions, 'device_type', '');
- $payChannel = data_get($conditions, 'pay_channel', null);
- $transactionNo = data_get($conditions, 'transaction_no', null);
- $payStatus = data_get($conditions, 'pay_status', null);
- $isDeduction = data_get($conditions, 'is_deduction', null);
- $dayStartObj = Carbon::parse($date)->startOfDay();
- $dayEndObj = Carbon::parse($date)->endOfDay();
- $model = new PayLogsModel();
- if (!is_null($channelUid)) {
- $model = $model->where(['channel_uid' => $channelUid]);
- }
- if (!is_null($momAppUid)) {
- $model = $model->where(['mom_app_uid' => $momAppUid]);
- }
- if (!is_null($agentUid)) {
- $model = $model->where(['agent_uid' => $agentUid]);
- }
- if (!empty($deviceType)) {
- $model = $model->where(['device_type' => $deviceType]);
- }
- if (!is_null($isDeduction)) {
- $model = $model->where(['is_deduction' => $isDeduction]);
- }
- if (!is_null($payChannel)) {
- $model = $model->where(['pay_channel' => $payChannel]);
- }
- if (!is_null($transactionNo)) {
- $model = $model->where(['transaction_no' => $transactionNo]);
- }
- if (!is_null($payStatus)) {
- $model = $model->where(['pay_status' => $payStatus]);
- }
- // 日期查询放最后.
- $t1 = $dayStartObj;
- $t2 = $dayEndObj;
- $model = $model->whereBetween('created_at', [$t1, $t2]);
- $result = 0;
- if ($computeType == 'money') {
- $result = $model->sum('real_amount');
- } else {
- $result = $model->count();
- }
- return $result;
- }
- /**
- * 计算时间段内的值
- * @param string $computeType 计算类型,count=总计数量;money=总计金额
- * @param mixed $startDate 日期.
- * @param mixed $endDate 日期.
- * @param array $conditions 查询条件.
- * @return int|mixed
- */
- public function computeSomeDays($computeType, $startDate, $endDate = null, array $conditions = [])
- {
- $computeType = strtolower($computeType);
- $channelUid = isset($conditions['channel_uid']) ? $conditions['channel_uid'] : null;
- $momAppUid = isset($conditions['mom_app_uid']) ? $conditions['mom_app_uid'] : null;
- $agentUid = isset($conditions['agent_uid']) ? $conditions['agent_uid'] : null;
- $deviceType = data_get($conditions, 'device_type', '');
- $payChannel = data_get($conditions, 'pay_channel', null);
- $transactionNo = data_get($conditions, 'transaction_no', null);
- $payStatus = data_get($conditions, 'pay_status', null);
- $isDeduction = data_get($conditions, 'is_deduction', null);
- $startDateObj = Carbon::parse($startDate);
- $startYmd = $startDateObj->toDateString();
- $startDayObj = (clone $startDateObj)->startOfDay();
- $endDateObj = null;
- $endDayObj = null;
- $endYmd = '';
- if (!empty($endDate)) {
- $endDateObj = Carbon::parse($endDate);
- $endYmd = $endDateObj->toDateString();
- $endDayObj = (clone $endDateObj)->endOfDay();
- if ($startDateObj > $endDateObj) {
- // 时间溢出.
- return 0;
- }
- }
- $model = new PayLogsModel();
- if (!is_null($channelUid)) {
- $model = $model->where(['channel_uid' => $channelUid]);
- }
- if (!is_null($momAppUid)) {
- $model = $model->where(['mom_app_uid' => $momAppUid]);
- }
- if (!is_null($agentUid)) {
- $model = $model->where(['agent_uid' => $agentUid]);
- }
- if (!empty($deviceType)) {
- $model = $model->where(['device_type' => $deviceType]);
- }
- if (!is_null($isDeduction)) {
- $model = $model->where(['is_deduction' => $isDeduction]);
- }
- if (!is_null($payChannel)) {
- $model = $model->where(['pay_channel' => $payChannel]);
- }
- if (!is_null($transactionNo)) {
- $model = $model->where(['transaction_no' => $transactionNo]);
- }
- if (!is_null($payStatus)) {
- $model = $model->where(['pay_status' => $payStatus]);
- }
- // 日期查询放最后.
- if (!empty($endDate)) {
- if ($endYmd != $startYmd) {
- $model = $model->whereNested(function (Model $query) use ($startDayObj, $endDayObj) {
- $t1 = $startDayObj;
- $t2 = $endDayObj;
- $query->whereBetween('created_at', [$t1, $t2]);
- });
- } else {
- $tmpEndDayObj = (clone $startDayObj)->endOfDay();
- $t1 = $startDayObj;
- $t2 = $tmpEndDayObj;
- $model = $model->whereBetween('created_at', [$t1, $t2]);
- }
- } else {
- $t = $startDayObj;
- $model = $model->where('created_at', '>=', $t);
- }
- $result = 0;
- if ($computeType == 'money') {
- $result = $model->sum('real_amount');
- } else {
- $result = $model->count();
- }
- return $result;
- }
- /**
- * 记录每层代理提成日志.
- * @param string $logId mongo支付日志_id
- * @return bool
- * @throws \KZ2\Laravel\Repositories\Exceptions\RepositoryException
- */
- public function recordCommissionOneDayByRoot($logId)
- {
- $logObj = PayLogsModel::where(['_id' => $logId, 'is_deduction' => 0])->first();
- if (empty($logObj->_id)) {
- return false;
- }
- if ($logObj->order_status != 1 || $logObj->pay_status != 1) {
- // 没有成功的订单不处理.
- return false;
- }
- $createdAt = $logObj->created_at;
- $date = Carbon::parse($createdAt)->toDateString();
- $orderAmount = $logObj->order_amount;
- $agentUid = $logObj->agent_uid;
- /**
- * @var $agentRepo AgentRepository;
- */
- $agentRepo = app(AgentRepository::class);
- $rootAgent = $agentRepo->makeModel()->query()->where(['uid' => $agentUid])->first();
- if (empty($rootAgent)) {
- return false;
- }
- self::loopParentCommission($logObj, $rootAgent->uid, $rootAgent->commission_ratio);
- return true;
- }
- /**
- * 递归循环上级记录.
- * @param $logObj
- * @param string $agentParentUid
- * @param int $diffRatio
- * @return false
- * @throws \KZ2\Laravel\Repositories\Exceptions\RepositoryException
- */
- private function loopParentCommission($logObj, $agentParentUid = '', $diffRatio = 0)
- {
- if ($logObj->is_deduction != 0) {
- // 如果是标记为扣量的订单,不给代理分,算官方的.
- return false;
- }
- if (empty($agentParentUid)) {
- return false;
- }
- $createdAt = $logObj->created_at;
- $date = Carbon::parse($createdAt)->toDateString();
- $parentAgent = $this->getAgentRepo()
- ->makeModel()
- ->query()
- ->where(['uid' => $agentParentUid])
- ->first(['id', 'uid', 'commission_ratio', 'commission_diff_ratio', 'parent_uid']);
- if (!empty($parentAgent)) {
- $commissionMoney = floatval(number_format($logObj->order_amount * ($diffRatio / 100), 2)); // 当前渠道的当前用户用commission_ratio计算
- $setarr = [
- 'date' => $date,
- 'channel_uid' => $logObj->channel_uid,
- 'root_agent_uid' => $logObj->agent_uid,
- 'agent_uid' => $agentParentUid,
- 'mom_app_uid' => $logObj->mom_app_uid,
- 'order_sn' => $logObj->order_sn,
- 'order_amount' => $logObj->order_amount,
- 'commission_money' => $commissionMoney,
- 'commission_curr_ratio' => $diffRatio,
- ];
- $parentLogObj = $this->getCommissionLogRepo()->create($setarr);
- return self::loopParentCommission($logObj, $parentAgent->parent_uid, $parentAgent->commission_diff_ratio);
- } else {
- return false;
- }
- }
- /**
- * 根据根用户订单增量更新代理属性一次性(不把下级的累加进来)
- * @param $logId
- * @param array $oldLog
- * @return false
- */
- public function updateAgentAttrsOnceByRootOrder($logId, $oldLog = [])
- {
- $logObj = PayLogsModel::where(['_id' => $logId])->first();
- if (empty($logObj->_id)) {
- return false;
- }
- $agentUid = $logObj->agent_uid;
- if (empty($agentUid)) {
- // 没有渠道,不叠加属性.
- return false;
- }
- $result = false;
- $originAgent = AgentModel::query()->where(['uid' => $agentUid])->first();
- DB::beginTransaction();
- try {
- // 加悲观锁,因为2个仓库可能同时更新表, 临时取消悲观锁.
- $agent = AgentAttrsModel::where(['agent_uid' => $agentUid])->firstOrFail();
- // 表没有commission_ratio,commission_diff_ratio,重新赋值.
- $todayDate = Carbon::now()->toDateString();
- $logDateYmd = Carbon::parse($logObj->created_at)->toDateString();
- $isNewToday = false;
- if ((empty($agent->td_date) || $agent->td_date != $todayDate) && $todayDate == $logDateYmd) {
- $isNewToday = true;
- $agent->td_date = $todayDate;
- }
- $agent = self::updateCommonAttrsFields($originAgent, $agent, $logObj, $oldLog, false);
- if ($agent->td_date == $todayDate && $todayDate == $logDateYmd) {
- // 更新td字段开头的.
- $agent = self::updateCommonAttrsFields($originAgent, $agent, $logObj, $oldLog, true, $isNewToday);
- }
- $result = $agent->save();
- if ($result) {
- // 对day表进行处理.
- $dayAttrsObj = AgentAttrsDayModel::whereDate('td_date', $logDateYmd)->where(['agent_uid' => $agentUid])->first();
- if (empty($dayAttrsObj)) {
- $setarr = [
- 'agent_uid' => $agentUid,
- 'td_date' => $logDateYmd,
- 'is_used' => 0,
- ];
- $dayAttrsObj = AgentAttrsDayModel::create($setarr);
- }
- $dayAttrsObj = self::updateCommonAttrsFields($originAgent, $dayAttrsObj, $logObj, $oldLog, true, false);
- // $fields = $agent->getCommonOrderSubffixFields();
- // foreach ($fields as $field) {
- // $tdFieldName = 'td_'. $field;
- // $dayAttrsObj->{$tdFieldName} = $agent->{$tdFieldName}; // 重新给day表赋值
- // }
- $dayAttrsObj->save();
- }
- DB::commit();
- } catch (\Exception $e) {
- DB::rollBack();
- logger('[error][StatisticsPayRepository][updateAgentAttrsOnceByRootOrder]', ['msg' => $e->getMessage(), 'log_id' => $logId, 'agent_uid' => $agentUid, 'detail' => $e->getTrace()]);
- }
- return $result;
- }
- /**
- * 更新订单公共字段.
- * @param mixed $originAgent 代理原始主表数据.
- * @param AgentAttrsModel $agent
- * @param PayLogsModel $logObj
- * @param array $oldLog
- * @param false $isForToday
- * @param false $isNewToday
- * @return mixed
- */
- private function updateCommonAttrsFields($originAgent, $agent, $logObj, $oldLog = [], $isForToday = false, $isNewToday = false)
- {
- $fields = $agent->getCommonOrderSubffixFields();
- foreach ($fields as $field) {
- ${$field} = $isForToday ? 'td_' . $field : $field;
- if ($isNewToday) {
- // 重制今日字段数据属性.
- $agent->{${$field}} = 0;
- }
- }
- if (empty($oldLog['pay_status'])) {
- // 新订单
- $agent->{$order_total} = $agent->{$order_total} + 1;
- $agent->{$order_money} += $logObj->real_amount;
- if ($logObj->device_type == 'A') {
- $agent->{$android_total} = $agent->{$android_total} + 1;
- $agent->{$android_money} += $logObj->real_amount;
- } elseif ($logObj->device_type == 'I') {
- $agent->{$ios_total} = $agent->{$ios_total} + 1;
- $agent->{$ios_money} += $logObj->real_amount;
- } elseif ($logObj->device_type == 'H') {
- $agent->{$h5_total} = $agent->{$h5_total} + 1;
- $agent->{$h5_money} += $logObj->real_amount;
- }
- if ($logObj->pay_status == 1) {
- $agent->{$order_success} = $agent->{$order_success} + 1;
- $agent->{$order_success_money} += $logObj->real_amount;
- if ($logObj->device_type == 'A') {
- $agent->{$android_success} = $agent->{$android_success} + 1;
- $agent->{$android_success_money} += $logObj->real_amount;
- } elseif ($logObj->device_type == 'I') {
- $agent->{$ios_success} = $agent->{$ios_success} + 1;
- $agent->{$ios_success_money} += $logObj->real_amount;
- } elseif ($logObj->device_type == 'H') {
- $agent->{$h5_success} = $agent->{$h5_success} + 1;
- $agent->{$h5_success_money} += $logObj->real_amount;
- }
- } elseif ($logObj->pay_status == 2) {
- $agent->{$order_failed} = $agent->{$order_failed} + 1;
- if ($logObj->device_type == 'A') {
- $agent->{$android_failed} = $agent->{$android_failed} + 1;
- } elseif ($logObj->device_type == 'I') {
- $agent->{$ios_failed} = $agent->{$ios_failed} + 1;
- } elseif ($logObj->device_type == 'H') {
- $agent->{$h5_failed} = $agent->{$h5_failed} + 1;
- }
- }
- if ($logObj->is_deduction == 1) {
- // 此订单没被扣量,就记录.
- $agent->{$deduction_total} = $agent->{$deduction_total} + 1;
- $agent->{$deduction_money} += $logObj->real_amount;
- if ($logObj->pay_status == 1) {
- $agent->{$deduction_success} = $agent->{$deduction_success} + 1;
- $agent->{$deduction_success_money} += $logObj->real_amount;
- } elseif ($logObj->pay_status == 2) {
- $agent->{$deduction_failed} = $agent->{$deduction_failed} + 1;
- }
- } else {
- if ($logObj->pay_status == 1) {
- $countCommissionMoney = floatval(number_format($logObj->real_amount * ($originAgent->commission_ratio / 100), 2)); // 当前渠道的当前用户用commission_ratio计算
- $agent->{$commission_money} += $countCommissionMoney;
- }
- }
- } else {
- // 更新老订单
- if ($oldLog['pay_status'] != $logObj->pay_status) {
- // 支付状态前后变化, 才执行更新.
- if ($logObj->pay_status == 1) {
- // 成功订单
- $agent->{$order_success} = $agent->{$order_success} + 1;
- $agent->{$order_success_money} += $logObj->real_amount;
- if ($logObj->device_type == 'A') {
- $agent->{$android_success} = $agent->{$android_success} + 1;
- $agent->{$android_success_money} += $logObj->real_amount;
- } elseif ($logObj->device_type == 'I') {
- $agent->{$ios_success} = $agent->{$ios_success} + 1;
- $agent->{$ios_success_money} += $logObj->real_amount;
- } elseif ($logObj->device_type == 'H') {
- $agent->{$h5_success} = $agent->{$h5_success} + 1;
- $agent->{$h5_success_money} += $logObj->real_amount;
- }
- } elseif ($logObj->pay_status == 2) {
- // 失败订单
- $agent->{$order_failed} = $agent->{$order_failed} + 1;
- if ($logObj->device_type == 'A') {
- $agent->{$android_failed} = $agent->{$android_failed} + 1;
- } elseif ($logObj->device_type == 'I') {
- $agent->{$ios_failed} = $agent->{$ios_failed} + 1;
- } elseif ($logObj->device_type == 'H') {
- $agent->{$h5_failed} = $agent->{$h5_failed} + 1;
- }
- }
- if ($logObj->is_deduction == 1) {
- // 订单被扣量,就记录.
- if ($logObj->pay_status == 1) {
- $agent->{$deduction_success} = $agent->{$deduction_success} + 1;
- $agent->{$deduction_success_money} += $logObj->real_amount;
- } elseif ($logObj->pay_status == 2) {
- $agent->{$deduction_failed} = $agent->{$deduction_failed} + 1;
- }
- } else {
- if ($logObj->pay_status == 1) {
- $countCommissionMoney = floatval(number_format($logObj->real_amount * ($originAgent->commission_ratio / 100), 2)); // 当前渠道的当前用户用commission_ratio计算
- $agent->{$commission_money} += $countCommissionMoney;
- }
- }
- }
- }
- return $agent;
- }
- /**
- * @return AgentRepository|\Illuminate\Contracts\Foundation\Application|mixed|null
- */
- private function getAgentRepo()
- {
- if (!$this->agentRepo instanceof AgentRepository) {
- $this->agentRepo = app(AgentRepository::class);
- }
- return $this->agentRepo;
- }
- /**
- * @return CommissionLogRepository|\Illuminate\Contracts\Foundation\Application|mixed|null
- */
- private function getCommissionLogRepo()
- {
- if (!$this->commissionLogRepo instanceof CommissionLogRepository) {
- $this->commissionLogRepo = app(CommissionLogRepository::class);
- }
- return $this->commissionLogRepo;
- }
- }
|