| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- <?php
- /**
- * 描述.
- *
- * @author nj
- * @date 2021-07-10 16:47
- */
- namespace Modules\InnerApi\Services;
- use App\Constants\RedisKeysConstant;
- use App\Events\InnerUserOrderIncEvent;
- use App\Models\Mongo\PayLogsModel;
- use App\Models\Mongo\UsersModel;
- use App\Repositories\AgentRepository;
- use App\Repositories\AppDeductionRuleRepository;
- use App\Repositories\ConfigRepoistory;
- use App\Repositories\PayLogRepository;
- use Carbon\Carbon;
- use Illuminate\Support\Facades\Redis;
- use LuckyBox\Card\IdCard;
- use LuckyBox\LuckyBox;
- class PayService
- {
- /**
- * 增量写入或者修改支付订单.
- * @param array $data
- * @return mixed
- */
- public function inc(array $data)
- {
- $eventParams = [];
- foreach ($data as $item) {
- $item['created_at'] = Carbon::parse($item['created_at']);
- $item['updated_at'] = !empty($item['updated_at']) ? Carbon::parse($item['updated_at'])
- : Carbon::now();
- $item['paid_at'] = !empty($item['paid_at']) ? Carbon::parse($item['paid_at']) : null;
- $item['invite_uid'] = !empty($item['invite_uid']) ? $item['invite_uid'] : '';
- $item['order_amount'] = floatval(number_format($item['order_amount'] ?? 0, 2));
- $item['real_amount'] = floatval(number_format($item['real_amount'] ?? 0, 2));
- $item['pay_status'] = isset($item['pay_status']) ? intval($item['pay_status']) : 3;
- $item['order_status'] = isset($item['order_status']) ? intval($item['order_status']) : 3;
- $item['buy_type'] = isset($item['buy_type']) ? intval($item['buy_type']) : 0;
- $item['buy_gold_num'] = isset($item['buy_gold_num']) ? intval($item['buy_gold_num']) : 0;
- $item['user_uid'] = !empty($item['user_uid']) ? $item['user_uid']: '';
- if (!empty($item['invite_uid'])) {
- if ($item['invite_uid'] == $item['user_uid']) {
- // 不能等于自己.
- $item['invite_uid'] = '';
- }
- }
- $oldLogObj = null;
- $isOldLog = false;
- $logObj = PayLogsModel::where(['mom_app_uid' => $item['mom_app_uid']])->where(['order_sn' => $item['order_sn']])->first();
- if (!empty($logObj)) {
- // 存在.
- $isOldLog = true;
- $oldLogObj = clone $logObj; // 克隆老订单.
- $logObj->updated_at = $item['updated_at'];
- $logObj->paid_at = $item['paid_at'];
- $logObj->invite_uid = $item['invite_uid'];
- $logObj->transaction_no = $item['transaction_no'];
- $logObj->pay_status = $item['pay_status'];
- $logObj->order_status = $item['order_status'];
- $logObj->is_deduction = $item['is_deduction'];
- $logObj->save();
- } else {
- // 不存在,新建.
- $logObj = PayLogsModel::create($item);
- }
- if (!empty($logObj->_id)) {
- $eventParams[] = [
- 'log_id' => $logObj->_id,
- 'old_log' => [
- 'pay_status' => $isOldLog ? $oldLogObj->pay_status : 0,
- 'order_status' => $isOldLog ? $oldLogObj->order_status : 0,
- ]
- ];
- }
- }
- // 触发事件.
- event(new InnerUserOrderIncEvent($eventParams));
- return true;
- }
- /**
- * 随机扣量标记.
- * @param array $item
- * @return array
- */
- public function oneRandDeduction(array $item)
- {
- //订单成功才参与扣量
- if ($item['pay_status'] != 1 && $item['order_status'] != 1) {
- return $item;
- }
- $deductionConfig = app(ConfigRepoistory::class)->pickByKeys(['preferential_order', 'user_deduction_switch'], 'sys');
- // 判断总扣规则是否开启
- if ($deductionConfig['user_deduction_switch']['svalue'] == 0) {
- return $item;
- }
- $iTodayPayOrder = PayLogsModel::query()->where([
- 'channel_uid' => $item['channel_uid'],
- 'pay_status' => 1,
- 'order_status' => 1,
- ])->count();
- //每日前多少单不扣
- if ($iTodayPayOrder < $deductionConfig['preferential_order']['svalue']) {
- return $item;
- }
- //代理扣量验证
- $agentInfo = app(AgentRepository::class)->findBy('uid', $item['agent_uid'], ['deduction_switch', 'jdata', 'preferential_order']);
- if ($agentInfo->deduction_switch == 1) {
- if ($iTodayPayOrder >= $agentInfo->preferential_order) {
- $aData = json_decode($agentInfo->jdata, true);
- $item['is_deduction'] = $this->isDeduction($item, $aData);
- }
- } else if ($agentInfo->deduction_switch == 0) {
- // 总扣量规则
- $ruleData = app(AppDeductionRuleRepository::class)->findWhere(['app_uid' => $item['mom_app_uid'], 'deduction_type' => 'cps', 'deduction_rule' => 2])->keyBy('deduction_method');
- $userSuccessOrder = PayLogsModel::query()->where(['user_uid' => $item['user_uid'], 'pay_status' => 1, 'order_status' => 1])->count();
- if ($userSuccessOrder > 0) {
- if (isset($ruleData[2])) {
- $aData = json_decode($ruleData[2]->jdata, true);
- $item['is_deduction'] = $this->isDeduction($item, $aData, 1);
- }
- } else {
- //首充扣量
- if (isset($ruleData[1])) {
- $aData = json_decode($ruleData[1]->jdata, true);
- $item['is_deduction'] = $this->isDeduction($item, $aData, 2);
- }
- }
- } else {
- $item['is_deduction'] = 0;
- }
- return $item;
- }
- /**
- * 判断是否扣量
- *
- * @param array $item
- * @param array $aData
- * @param string $method
- * @return int
- */
- private function isDeduction(array $item,array $aData, $method = '')
- {
- $isDeduction = 0;
- $scope = [];
- $deduction = [];
- $deductionPrice = $aData['deduction_price'];
- $deductionNumber = $aData['deduction_number'];
- foreach ($deductionPrice as $key => $val) {
- if ($item['real_amount'] >= $val['min_price'] && $item['real_amount'] <= $val['max_price']) {
- $scope = $val;
- $deduction = $deductionNumber[$key];
- }
- }
- //如果没有符合的金额规则,就返回
- if (empty($scope) || $deduction['deduction'] == 0) {
- return $isDeduction;
- }
- $hashKey = RedisKeysConstant::DEDUCTION_RULES_HASH . $item['mom_app_uid'] . $item['channel_uid'] . $method;
- //获取扣量标记
- $areaKey = $scope['min_price'] . '-' . $scope['max_price'];
- $deductionMark = Redis::hget($hashKey, $areaKey);
- $mark = [0,0];
- if ($deductionMark) {
- $mark = explode('-', $deductionMark);
- //如果一轮规则达到 且扣量完成 则删除并初始化标记
- if ($mark[0] == $deduction['number'] && $mark[1] == $deduction['deduction']) {
- Redis::hDel($hashKey, $areaKey);
- $mark = [0,0];
- }
- //如果扣量达到,但是一轮还没结束则直接返回
- if ($mark[1] == $deduction['deduction']) {
- // $mark[0] + 1 参与订单总数加1
- Redis::hset($hashKey, $areaKey, $mark[0] + 1 . '-' . $mark[1]);
- return $isDeduction;
- }
- }
- //必扣计算
- if (($deduction['number'] - $mark[0]) <= ($deduction['deduction'] - $mark[1])) {
- $isDeduction = 1;
- } else {
- $boxItems = [
- 1 => ['name' => 0, 'rate' => 80],
- 2 => ['name' => 1, 'rate' => 20]
- ];
- $luckyBox = new LuckyBox();
- foreach ($boxItems as $id => $items) {
- $card = new IdCard();
- $card->setId($id)->setRate($items['rate']);
- $luckyBox->add($card);
- }
- $boxValue = $boxItems[$luckyBox->draw()->getId()];
- $isDeduction = $boxValue['name'];
- }
- if ($isDeduction == 1) {
- $mark[1] += 1;
- }
- $mark[0] += 1;
- Redis::hset($hashKey, $areaKey, $mark[0] . '-' . $mark[1]);
- return $isDeduction;
- }
- }
|