// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\AccountLogModel; use App\Models\CouponModel; use App\Models\MemberCouponModel; use App\Models\MemberModel; use App\Models\OrderCommissionModel; use App\Models\OrderModel; use App\Models\PtAccountModel; use App\Models\StoreModel; use App\Services\BaseService; use App\Services\Common\MemberLevelService; use App\Services\ConfigService; use App\Services\RedisService; use Illuminate\Support\Facades\DB; /** * 结算管理-服务类 * @author laravel开发员 * @since 2020/11/11 * @package App\Services\Api */ class SettleService extends BaseService { /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 */ public function __construct() { $this->model = new AccountLogModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * 商家收益结算 * @param $storeId * @param $money 收益 * @param $order 订单数据 * @return array|false|int */ public function storeBonus($storeId, $money, $order) { $orderNo = isset($order['order_no']) ? $order['order_no'] : ''; if ($money <= 0 && $storeId <= 0) { $this->error = '无企业佣金可结算'; return false; } $storeInfo = StoreModel::where(['id' => $storeId, 'mark' => 1])->first(); $balance = isset($storeInfo['bonus_total']) ? $storeInfo['bonus_total'] : 0; $storeUserId = isset($storeInfo['user_id']) ? $storeInfo['user_id'] : 0; if ($storeUserId <= 0) { $this->error = '企业账号错误'; return false; } if (!StoreModel::where(['id' => $storeId])->update(['bonus_total' => DB::raw("bonus_total + {$money}"), 'update_time' => time()])) { $this->error = '收货错误,企业结算错误,请联系客服处理'; return -1; } $log = [ 'user_id' => $storeUserId, 'store_id' => $storeId, 'source_order_no' => isset($order['order_no']) ? $order['order_no'] : '', 'type' => 7, 'money' => $money, 'after_money' => moneyFormat($balance + $money, 2), 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '收益', 'status' => 1 ]; if (!$id = $this->model->insertGetId($log)) { $this->error = '企业收益结算失败,请联系客服处理'; return -1; } $result = ['id' => $id, 'store_id' => $storeId, 'bonus' => $money]; if (env('APP_DEBUG')) { RedisService::set("caches:settle:{$orderNo}:store_{$storeId}", $result, 7200); } return $result; } /** * @param $order * @param int $orderType */ public function commissionCount($order, $orderGoods, $userInfo, $orderType = 1) { $userId = isset($order['user_id']) ? $order['user_id'] : 0; $storeId = isset($order['store_id']) ? $order['store_id'] : 0; $mealType = isset($order['meal_type']) ? $order['meal_type'] : 0; $orderId = isset($order['id']) ? $order['id'] : 0; $orderNo = isset($order['order_no']) ? $order['order_no'] : ''; $orderTotal = isset($order['pay_total']) ? $order['pay_total'] : 0; $profitTotal = isset($order['profit_total']) ? $order['profit_total'] : 0; // 毛利 $costTotal = isset($order['cost_total']) ? $order['cost_total'] : 0; // 总成本 $netProfit = isset($order['net_profit']) ? $order['net_profit'] : 0; // 净利润 $data = [ 'order_id' => $orderId, 'user_id' => $userId, 'order_no' => $orderNo, 'store_id' => $storeId, 'total' => $orderTotal, 'create_time' => time(), 'status' => 2, 'mark' => 1, ]; $errors = []; if ($orderType == 2) { /* TODO 计算直推奖 */ $pointId = isset($userInfo['point_id']) ? $userInfo['point_id'] : 0; $directBonus = ConfigService::make()->getConfigByCode('business_direct_bonus', 0); $directBonus = $directBonus > 0 && $directBonus < $orderTotal ? $directBonus : 0; $pointInfo = MemberModel::where(['id' => $pointId, 'mark' => 1]) ->select(['id', 'nickname', 'buy_type', 'bonus_status', 'status', 'mark']) ->first(); $bonusStatus = isset($pointInfo['bonus_status']) ? $pointInfo['bonus_status'] : 0; $data['direct_uid'] = $pointId; if ($pointInfo && $bonusStatus == 1) { $data['direct_bonus'] = json_encode(['uid' => $pointId, 'bonus' => $directBonus], 256); } else { $data['direct_bonus'] = json_encode(['uid' => $pointId, 'direct_bonus' => $directBonus, 'meal_type' => $mealType, 'error' => '节点推荐人不存在或收益已领完', 'point' => $pointInfo], 256); } /* TODO 计算见单奖和分红奖励 */ $points = isset($userInfo['points']) ? $userInfo['points'] : ''; $points = $points ? explode(',', $points) : []; $points = array_filter($points); $points = array_reverse($points); // 由下到上1-6层 $rewardLayer = ConfigService::make()->getConfigByCode('business_reward_layer', 6); $points = array_splice($points, 0, $rewardLayer); $jdBonus = ConfigService::make()->getConfigByCode("business_jd_bonus_{$mealType}", 0); $jdBonus = $jdBonus > 0 && $jdBonus < $orderTotal ? $jdBonus : 0; // 计算当前平台下各个等级的会员数量 $levelCounts = MemberService::make()->getCountsByLevel(); $levelList = MemberLevelService::make()->getListByLevel(); if ($points) { $pointList = MemberModel::with(['levelData'])->whereIn('id', $points) ->select(['id', 'nickname', 'mobile', 'buy_type', 'member_level', 'bonus_status', 'status', 'mark']) ->orderBy(DB::raw("FIELD(id, " . implode(',', $points) . ")")) ->get(); foreach ($pointList as $k => $point) { // 默认只分6层 $layer = $k + 1; if ($layer > $rewardLayer) { continue; } // 处理见单奖 $pid = isset($point['id']) ? $point['id'] : 0; $pMark = isset($point['mark']) ? $point['mark'] : 0; $bonusStatus = isset($point['bonus_status']) ? $point['bonus_status'] : 0; $pLevel = isset($point['member_level']) ? $point['member_level'] : 0; $levelWeightCountData = isset($levelCounts[$pLevel]) ? $levelCounts[$pLevel] : 0; $levelData = isset($levelList[$pLevel]) ? $levelList[$pLevel] : 0; $levelWeightCount = isset($levelWeightCountData['count']) ? $levelWeightCountData['count'] : 0; $levelBonus = isset($levelData['bonus']) ? $levelData['bonus'] : 0; $levelName = isset($levelData['name']) ? $levelData['name'] : ''; $data["bonus_{$layer}_uid"] = $pid; $bonusData = [ 'id' => $pid, 'nickname' => isset($point['nickname']) ? $point['nickname'] : '', 'mobile' => isset($point['mobile']) ? $point['mobile'] : '', 'jd_bonus' => 0, 'level' => $pLevel, 'meal_type' => $mealType, 'level_name' => $levelName, 'weight' => $levelWeightCount, 'weight_bonus' => $levelBonus, 'level_bonus' => 0, ]; if ($pMark == 1 && $bonusStatus == 1) { $bonusData['jd_bonus'] = $jdBonus; } else { $bonusData["error"] = "上{$layer}级节点推荐人不存在或收益已领完"; } // 处理加权分红 if ($pLevel > 0 && $levelWeightCount > 0 && $levelBonus > 0 && $bonusStatus == 1) { $bonusData['level_bonus'] = moneyFormat($levelBonus * 6 / $levelWeightCount, 2); } // 数据 $data["bonus_{$layer}_data"] = json_encode($bonusData, 256); } } } else { /* TODO 计算商家佣金 */ $storeInfo = StoreModel::where(['id' => $storeId])->first(); $bonusRate = isset($storeInfo['bonus_rate']) ? floatval($storeInfo['bonus_rate']) : 0; $bonusRate = $bonusRate > 0 && $bonusRate < 100 ? $bonusRate : 0; $bonus = $bonusRate? moneyFormat($orderTotal * $bonusRate / 100, 2) : $costTotal; $data['bonus'] = $bonus; $data['bonus_rate'] = $bonusRate; /* TODO 计算绿色积分奖励 */ $lsScoreTotal = 0; $data['ls_score_rates'] = []; $ptLsScoreRate = ConfigService::make()->getConfigByCode('ls_score_rate', 0); $ptLsScoreRate = $ptLsScoreRate > 0 && $ptLsScoreRate <= 50 ? $ptLsScoreRate : 0; if ($orderGoods) { foreach ($orderGoods as $goods) { $lsScoreRate = isset($goods['ls_score_rate']) ? $goods['ls_score_rate'] : 0; $lsScoreRate = $lsScoreRate > 0 && $lsScoreRate <= 50 ? $lsScoreRate : $ptLsScoreRate; //$profitTotal = isset($goods['profit_total']) ? $goods['profit_total'] : 0; $netProfit = isset($goods['net_profit']) ? $goods['net_profit'] : 0; $score = 0; if ($netProfit > 0 && $lsScoreRate > 0) { $score = moneyFormat($netProfit * $lsScoreRate / 100, 2); $lsScoreTotal += floatval($score); } $data['ls_score_rates'][$goods['goods_id']] = [ 'goods_id' => $goods['goods_id'], 'net_profit' => $netProfit, 'score' => $score, 'score_rate' => $lsScoreRate ]; } } $data['ls_score'] = $lsScoreTotal; $data['ls_score_rates'] = json_encode($data['ls_score_rates'], 256); /* TODO 计算数字资产+底池金额 */ $ptPoolRate = ConfigService::make()->getConfigByCode('pt_pool_rate', 0); $ptPoolRate = $ptPoolRate > 0 && $ptPoolRate < 50 ? $ptPoolRate : 0; $rewardPropertyRate = ConfigService::make()->getConfigByCode('reward_property_rate', 0); $rewardPropertyRate = $rewardPropertyRate > 0 && $rewardPropertyRate <= 50 ? $rewardPropertyRate : 0; $propertyTotal = moneyFormat($rewardPropertyRate * $netProfit / 100, 2); $poolTotal = moneyFormat($ptPoolRate * $netProfit / 100, 2); $data['pt_pool_rate'] = $ptPoolRate; $data['pt_pool'] = $poolTotal; $data['property'] = $propertyTotal; $data['property_rate'] = $rewardPropertyRate; } // 佣金数据入库 if (!$cid = OrderCommissionModel::where(['order_no' => $orderNo])->value('id')) { $cid = OrderCommissionModel::insertGetId($data); } else { OrderCommissionModel::where(['id' => $cid])->update($data); } $this->error = '佣金计算成功'; $data['id'] = $cid; return $data; } /** * 订单结算 * @param $orderId * @return array|false */ public function commissionSettle($orderId) { try { $info = OrderModel::with(['commission']) ->where(['id' => $orderId, 'mark' => 1]) ->select(['id', 'order_no', 'type', 'user_id', 'total', 'pay_total', 'bd_score', 'pay_status', 'status', 'refund_status']) ->first(); $info = $info ? $info->toArray() : []; if (empty($info)) { $this->error = '结算订单不存在'; return false; } if ($info['status'] <= 1 || $info['pay_status'] == 10) { $this->error = '订单未支付'; return false; } if (in_array($info['refund_status'], [1, 2, 3])) { $this->error = '订单已退款'; return false; } $orderType = isset($info['type']) ? $info['type'] : 1; $orderNo = isset($info['order_no']) ? $info['order_no'] : ''; $orderUserId = isset($info['user_id']) ? $info['user_id'] : 0; $commission = isset($info['commission']) ? $info['commission'] : []; $commissionId = isset($commission['id']) ? $commission['id'] : 0; if (empty($commission) || $commissionId <= 0) { $this->error = '结算订单收益参数错误'; return false; } if ($commission['status'] == 1) { $this->error = '订单收益已结算'; return false; } $cacheKey = "caches:ordersCommission:{$orderNo}_{$orderUserId}:"; if (RedisService::get("{$cacheKey}lock")) { $this->error = '订单结算中'; return false; } // 创业订单 $logs = []; RedisService::set("{$cacheKey}lock", $info, 300); if ($orderType == 2) { // TODO 结算直推奖 $directData = isset($commission['direct_bonus']) && $commission['direct_bonus'] ? json_decode($commission['direct_bonus'], true) : []; $directUserId = isset($commission['direct_uid']) ? $commission['direct_uid'] : 0; $directBonus = isset($directData['bonus']) ? $directData['bonus'] : 0; if ($directUserId > 0 && $directBonus > 0) { $directUser = isset($commission['direct_user']) ? $commission['direct_user'] : []; $directUserBalance = isset($directUser['balance']) ? $directUser['balance'] : 0; if ($directUser) { $updateData = [ 'balance' => DB::raw("balance + {$directBonus}"), 'bonus_total' => DB::raw("bonus_total + {$directBonus}"), 'update_time' => time() ]; if (!MemberModel::where(['id' => $directUserId])->update($updateData)) { DB::rollBack(); RedisService::clear("{$cacheKey}lock"); $this->error = '直推奖励结算错误'; return false; } $data = [ 'user_id' => $directUserId, 'source_order_no' => $orderNo, 'user_type' => 1, 'account_type' => 1, // 余额 'type' => 8, 'bonus_type' => 1, 'money' => $directBonus, 'after_money' => moneyFormat($directUserBalance + $directBonus, 2), 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '直推奖', 'remark1' => "用户ID:{$orderUserId}购买礼包直推奖励", 'status' => 1, 'mark' => 1 ]; $logs[] = $data; } } // TODO 结算见单奖+分红 $bonusUids = []; for ($i = 1; $i <= 6; $i++) { $uid = isset($commission["bonus_{$i}_uid"]) ? $commission["bonus_{$i}_uid"] : 0; if ($uid) { $bonusUids[] = $uid; } } $bonusUsers = MemberModel::whereIn('id', $bonusUids) ->select(['id', 'openid', 'balance', 'mobile', 'nickname', 'property', 'ls_score', 'status']) ->get() ->keyBy('id'); $bonusUsers = $bonusUsers ? $bonusUsers->toArray() : []; for ($i = 1; $i <= 6; $i++) { $uid = isset($commission["bonus_{$i}_uid"]) ? $commission["bonus_{$i}_uid"] : 0; $bonusData = isset($commission["bonus_{$i}_data"]) ? $commission["bonus_{$i}_data"] : ''; $bonusData = $bonusData ? json_decode($bonusData, true) : []; $jdBonus = isset($bonusData['jd_bonus']) ? $bonusData['jd_bonus'] : 0; $levelName = isset($bonusData['level_name']) ? $bonusData['level_name'] : ''; $levelBonus = isset($bonusData['level_bonus']) ? $bonusData['level_bonus'] : 0; $bonusUser = isset($bonusUsers[$uid]) ? $bonusUsers[$uid] : []; $bonusUserBalance = isset($bonusUser['balance']) ? $bonusUser['balance'] : 0; $bonusTotal = moneyFormat($jdBonus + $levelBonus, 2); if ($uid && $bonusUser && $bonusTotal > 0) { $updateData = [ 'balance' => DB::raw("balance + {$bonusTotal}"), 'bonus_total' => DB::raw("bonus_total + {$bonusTotal}"), 'update_time' => time() ]; if (!MemberModel::where(['id' => $uid])->update($updateData)) { $this->error = '见单和分红奖励结算错误'; RedisService::clear("{$cacheKey}lock"); return false; } if ($jdBonus > 0) { $bonusUserBalance = moneyFormat($bonusUserBalance + $jdBonus, 2); $data = [ 'user_id' => $uid, 'source_order_no' => $orderNo, 'user_type' => 1, 'account_type' => 1, // 余额 'type' => 8, 'bonus_type' => 2, 'money' => $jdBonus, 'after_money' => $bonusUserBalance, 'date' => date('Y-m-d'), 'create_time' => time() + $i, 'remark' => '见单奖', 'remark1' => "下{$i}级用户ID:{$orderUserId}购买礼包见单奖", 'status' => 1, 'mark' => 1 ]; $logs[] = $data; } if ($levelBonus > 0) { $bonusUserBalance = moneyFormat($bonusUserBalance + $levelBonus, 2); $data = [ 'user_id' => $uid, 'source_order_no' => $orderNo, 'user_type' => 1, 'account_type' => 1, // 余额 'type' => 8, 'bonus_type' => 3, 'money' => $levelBonus, 'after_money' => $bonusUserBalance, 'date' => date('Y-m-d'), 'create_time' => time() + $i, 'remark' => '分红收益', 'remark1' => "下{$i}级用户ID:{$orderUserId}购买礼包等级[{$levelName}]分红收益", 'status' => 1, 'mark' => 1 ]; $logs[] = $data; } } } } // 商城订单 else { // TODO 商家结算 $storeInfo = isset($commission['store']) ? $commission['store'] : []; $storeId = isset($commission['store_id']) ? $commission['store_id'] : 0; $storeBonus = isset($commission['bonus']) ? $commission['bonus'] : 0; $storeUserId = isset($storeInfo['user_id']) ? $storeInfo['user_id'] : 0; $storeBalance = isset($storeInfo['balance']) ? $storeInfo['balance'] : 0; if ($storeId > 0 && $storeInfo && $storeBonus > 0) { $updateData = [ 'balance' => DB::raw("balance + {$storeBonus}"), 'income' => DB::raw("income + {$storeBonus}"), 'update_time' => time() ]; if (!StoreModel::where(['id' => $storeId])->update($updateData)) { $this->error = '商家提成结算失败'; RedisService::clear("{$cacheKey}lock"); return false; } $storeBalance = moneyFormat($storeBalance + $storeBonus, 2); $data = [ 'user_id' => $storeUserId, 'store_id' => $storeId, 'source_order_no' => $orderNo, 'user_type' => 2, 'account_type' => 1, // 余额 'type' => 7, 'bonus_type' => 0, 'money' => $storeBonus, 'after_money' => $storeBalance, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '商家提成结算', 'remark1' => "用户ID:{$orderUserId}购买商品提成结算", 'status' => 1, 'mark' => 1 ]; $logs[] = $data; } // TODO 绿色积分结算 $userInfo = isset($commission['user']) ? $commission['user'] : []; $userId = isset($commission['user_id']) ? $commission['user_id'] : 0; $userLsScore = isset($userInfo['ls_score']) ? $userInfo['ls_score'] : 0; $lsScore = isset($commission['ls_score']) ? $commission['ls_score'] : 0; if ($userId > 0 && $userInfo && $lsScore > 0) { $updateData = [ 'ls_score' => DB::raw("ls_score + {$lsScore}"), 'ls_score_total' => DB::raw("ls_score_total + {$lsScore}"), 'update_time' => time() ]; if (!MemberModel::where(['id' => $userId])->update($updateData)) { $this->error = '绿色积分奖励结算错误'; RedisService::clear("{$cacheKey}lock"); return false; } $data = [ 'user_id' => $userId, 'store_id' => 0, 'source_order_no' => $orderNo, 'user_type' => 1, 'account_type' => 4, // 绿色积分 'type' => 8, 'bonus_type' => 4, 'money' => $lsScore, 'after_money' => moneyFormat($userLsScore + $lsScore, 2), 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '绿色积分奖励', 'remark1' => "用户ID:{$orderUserId}购买商品绿色积分奖励", 'status' => 1, 'mark' => 1 ]; $logs[] = $data; } // TODO 数字资产和底池 $property = isset($commission['property']) ? $commission['property'] : 0; $userProperty = isset($userInfo['property']) ? $userInfo['property'] : 0; if ($userId > 0 && $userInfo && $property > 0) { $updateData = [ 'property' => DB::raw("property + {$property}"), 'property_total' => DB::raw("property_total + {$property}"), 'update_time' => time() ]; if (!MemberModel::where(['id' => $userId])->update($updateData)) { $this->error = '数字资产奖励结算错误'; RedisService::clear("{$cacheKey}lock"); return false; } $data = [ 'user_id' => $userId, 'store_id' => 0, 'source_order_no' => $orderNo, 'user_type' => 1, 'account_type' => 2, // 数字资产 'type' => 8, 'bonus_type' => 5, 'money' => $property, 'after_money' => moneyFormat($userProperty + $property, 2), 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '数字资产奖励', 'remark1' => "用户ID:{$orderUserId}购买商品数字资产奖励", 'status' => 1, 'mark' => 1 ]; $logs[] = $data; } // 平台底池结算 $ptAccount = PtAccountModel::where(['mark' => 1])->first(); $accountId = isset($ptAccount['id']) ? $ptAccount['id'] : 0; $poolTotal = isset($ptAccount['pool_total']) ? $ptAccount['pool_total'] : 0; $ptPool = isset($commission['pt_pool']) ? $commission['pt_pool'] : 0; if ($ptAccount && ($ptPool > 0 || $property > 0)) { $updateData = [ 'pool_total' => DB::raw("pool_total + {$ptPool}"), 'today_pool' => DB::raw("today_pool + {$ptPool}"), 'today_property' => DB::raw("today_property + {$property}"), 'update_time' => time() ]; if (!PtAccountModel::where(['id' => $accountId])->update($updateData)) { $this->error = '平台底池和资产结算错误'; RedisService::clear("{$cacheKey}lock"); return false; } // 底池明细 if ($ptPool > 0) { $data = [ 'user_id' => 0, 'store_id' => 0, 'source_order_no' => $orderNo, 'user_type' => 0, 'account_type' => 5, // 平台账户 'type' => 10, 'bonus_type' => 6, 'money' => $ptPool, 'after_money' => moneyFormat($poolTotal + $ptPool, 2), 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '返回底池', 'remark1' => "用户ID:{$orderUserId}购买商品返回底池", 'status' => 1, 'mark' => 1 ]; $logs[] = $data; } } } // TODO 明细入表 RedisService::set("{$cacheKey}logs", $logs, 3600); if ($logs && !AccountLogModel::insert($logs)) { $this->error = '奖励明细结算处理错误'; RedisService::clear("{$cacheKey}lock"); return false; } // 订单结算状态更新 if(!OrderCommissionModel::where(['id'=>$commissionId])->update(['status'=>1,'arrival_at'=>date('Y-m-d H:i:s'),'update_time'=>time()])){ $this->error = '订单结算状态更新失败'; return false; } $this->error = '订单结算完成'; RedisService::clear("{$cacheKey}lock"); RedisService::clear("caches:orders:settleList"); RedisService::set("{$cacheKey}result", $info, 3600); $result = ['id' => $orderId, 'user_id' => $orderUserId, 'logs' => $logs, 'commission' => $commission]; RedisService::set("caches:settles:{$orderId}_{$orderNo}_success", $result, 7200); return $result; } catch (\Exception $exception){ RedisService::set("caches:settles:{$orderId}_error", ['error'=>$exception->getMessage(),'trace'=>$exception->getTrace()], 7200); return false; } } /** * 更新用户等级和下级团队购买礼包人数 * @param $userId * @param $points * @return bool */ public function updateUserData($userId, $points) { // 上级用户复购参数更新 try { $points = $points ? explode(',', $points) : []; $points = array_filter($points); $points = array_reverse($points); $rewardLayer = ConfigService::make()->getConfigByCode('business_reward_layer', 6); $points = array_splice($points, 0, $rewardLayer); if ($points) { // 累计购买人数 MemberModel::where(['bonus_status'=>1,'mark' => 1])->whereIn('id', $points) ->update(['buy_count' => DB::raw("buy_count + 1"), 'update_time' => time()]); // 购买人数满N层暂停收益 $buyCount = pow(2, $rewardLayer + 1) - 2; MemberModel::where('buy_count', '>=', $buyCount) ->where(['bonus_status'=>1]) ->whereIn('id', $points) ->update(['buy_count' => 0, 'buy_type' => DB::raw("buy_type+1"), 'bonus_status' => 2, 'update_time' => time()]); } // 用户升级 $userInfo = MemberModel::with(['parent'])->where(['id' => $userId, 'mark' => 1]) ->select(['id', 'member_level', 'parent_id', 'status']) ->first(); $memberLevel = isset($userInfo['member_level']) ? $userInfo['member_level'] : []; $parent = isset($userInfo['parent']) ? $userInfo['parent'] : []; $parentId = isset($userInfo['parent_id']) ? $userInfo['parent_id'] : 0; $parentLevel = isset($parent['member_level']) ? $parent['member_level'] : 0; $upperLevel = 0; $parentUpperLevel = 0; $levelList = MemberLevelService::make()->getListByLevel(); $orderCount = OrderModel::from('orders as a') ->distinct('user_id') ->leftJoin('member as b', 'b.id', '=', 'a.user_id') ->where('a.status', '>', 1) ->where(['a.main_no' => '', 'a.type' => 2, 'a.user_id' => $userId, 'a.pay_status' => 20]) ->count(); $parentOrderCount = 0; if ($parentId > 0) { $parentOrderCount = OrderModel::from('orders as a') ->distinct('user_id') ->leftJoin('member as b', 'b.id', '=', 'a.user_id') ->where('a.status', '>', 1) ->where(['a.main_no' => '', 'a.type' => 2, 'b.parent_id' => $parentId, 'a.pay_status' => 20]) ->count(); } // 升级检查 if($orderCount||$parentOrderCount){ foreach ($levelList as $item) { $level = isset($item['id']) ? $item['id'] : 0; $upperCount = isset($item['upper_count']) ? $item['upper_count'] : 0; if ($orderCount >= $upperCount && $level > $memberLevel) { $upperLevel = $level; } if ($parentOrderCount >= $upperCount && $level > $parentLevel) { $parentUpperLevel = $level; } } } if ($upperLevel > 0) { MemberModel::where(['id' => $userId])->update(['member_level' => $upperLevel, 'update_time' => time()]); } if ($parentUpperLevel > 0) { MemberModel::where(['id' => $parentId])->update(['member_level' => $parentUpperLevel, 'update_time' => time()]); } $this->error = $upperLevel || $parentUpperLevel? '等级更新成功':'没有等级可更新'; $result = ['user_id' => $userId, 'member_level' => $memberLevel, 'upper_level' => $upperLevel,'order_count'=>$orderCount, 'parent_level' => $parentLevel, 'parent_upper_level' => $parentUpperLevel,'parent_order_count'=>$parentOrderCount, 'parent_id' => $parentId]; RedisService::set("caches:upperLevel:{$userId}_success", $result, 7200); return $result; } catch (\Exception $exception){ RedisService::set("caches:upperLevel:{$userId}_error", ['error'=>$exception->getMessage(),'trace'=>$exception->getTrace()], 7200); return false; } } /** * 新人注册奖励 * @param $userId * @return array|bool */ public function registerReward($userId) { $rewardOpen = ConfigService::make()->getConfigByCode('register_award_coupon', 0); $rewardCouponId = ConfigService::make()->getConfigByCode('register_reward_coupon_id', 0); if ($rewardCouponId <= 0 || $rewardOpen != 1) { $this->error = '未开启或配置注册优惠券奖励'; return true; } $couponInfo = CouponModel::where(['id' => $rewardCouponId, 'mark' => 1]) ->first(); $status = isset($couponInfo['status']) ? $couponInfo['status'] : 0; if (empty($couponInfo) || $status != 1) { $this->error = '配置的注册奖励优惠券不存在或无效'; return true; } $data = [ 'coupon_id' => $rewardCouponId, 'user_id' => $userId, 'store_id' => isset($couponInfo['store_id']) ? $couponInfo['store_id'] : 0, 'name' => isset($couponInfo['name']) ? $couponInfo['name'] : '', 'coupon_type' => isset($couponInfo['coupon_type']) ? $couponInfo['coupon_type'] : 20, 'reduce_price' => isset($couponInfo['reduce_price']) ? $couponInfo['reduce_price'] : 0, 'discount' => isset($couponInfo['discount']) ? $couponInfo['discount'] : 0, 'min_price' => isset($couponInfo['min_price']) ? $couponInfo['min_price'] : 0, 'expire_day' => isset($couponInfo['expire_day']) ? $couponInfo['expire_day'] : 0, 'start_time' => isset($couponInfo['start_time']) ? $couponInfo['start_time'] : 0, 'end_time' => isset($couponInfo['end_time']) ? $couponInfo['end_time'] : 0, 'goods_ids' => isset($couponInfo['goods_ids']) && $couponInfo['goods_ids'] ? $couponInfo['goods_ids'] : '', 'create_time' => time(), 'status' => 1, ]; if (!$id = MemberCouponModel::insertGetId($data)) { $this->error = '奖励注册优惠券失败'; return true; } $data['id'] = $id; $data['discount'] = floatval($data['discount']); $data['reduce_price'] = floatval($data['reduce_price']); unset($data['create_time']); unset($data['status']); unset($data['goods_ids']); $this->error = '奖励注册优惠券成功'; return $data; } }