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; } }