dao = $dao; } public function getList(array $where, $page, $limit) { $query = $this->dao->search($where)->order('brokerage_level ASC,create_time DESC'); $count = $query->count(); $list = $query->page($page, $limit)->select(); return compact('list', 'count'); } public function getNextLevel($level,$type = 0) { return $this->search(['next_level' => $level,'type' => $type])->order('brokerage_level ASC,create_time DESC')->find(); } public function options(array $where) { return $this->dao->search($where)->field('brokerage_level as value,brokerage_name as label')->order('brokerage_level ASC,create_time DESC')->select(); } public function all(int $type) { return $this->dao->search(['type' => $type])->order('brokerage_level ASC,create_time DESC')->select(); } public function inc(User $user, $type, $inc) { $nextLevel = $this->getNextLevel($user->brokerage_level); if (!$nextLevel) return false; $make = app()->make(UserBillRepository::class); $bill = $make->getWhere(['uid' => $user->uid, 'link_id' => $nextLevel->user_brokerage_id, 'category' => 'sys_brokerage', 'type' => $type]); if ($bill) { $bill->number = bcadd($bill->number, $inc, 2); $bill->save(); } else { $make->incBill($user->uid, 'sys_brokerage', $type, [ 'number' => $inc, 'title' => $type, 'balance' => 0, 'status' => 0, 'link_id' => $nextLevel->user_brokerage_id ]); } return $this->checkLevel($user, $nextLevel); } public function checkLevel(User $user, UserBrokerage $nextLevel) { $info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id]) ->column('number', 'type'); foreach ($nextLevel['brokerage_rule'] as $k => $rule) { if (!isset($info[$k]) && $rule['num'] > 0) return false; if ($rule['num'] > 0 && $rule['num'] > $info[$k]) return false; } $nextLevel->user_num++; Db::transaction(function () use ($nextLevel, $user) { $nextLevel->save(); if ($user->brokerage && $user->brokerage->user_num > 0) { $user->brokerage->user_num--; $user->brokerage->save(); } $user->brokerage_level = $nextLevel->brokerage_level; $user->save(); $key = 'notice_brokerage_level_' . $user->uid; app()->make(CacheRepository::class)->save($key,$nextLevel->brokerage_level); }); return true; } /** * Common: 分销商升级 - 流程开始 * Author: wu-hui * Time: 2023/12/26 14:20 * @param User $user * @param $data * @return bool|void */ public function incV2(User $user, $data){ $type = $data['type'] ?? ''; $inc = $data['inc'] ?? 0; // 判断:不存在下一级 升级失败 $nextLevel = $this->getNextLevel($user->brokerage_level); if (!$nextLevel) return false; // 判断:是否为基本升级条件 是则进行统一账单处理 if(in_array($type,self::BROKERAGE_RULE_TYPE)){ $make = app()->make(UserBillRepository::class); $bill = $make->getWhere(['uid' => $user->uid, 'link_id' => $nextLevel->user_brokerage_id, 'category' => 'sys_brokerage', 'type' => $type]); if ($bill) { $bill->number = bcadd($bill->number, $inc, 2); $bill->save(); } else { $make->incBill($user->uid, 'sys_brokerage', $type, [ 'number' => $inc, 'title' => $type, 'balance' => 0, 'status' => 0, 'link_id' => $nextLevel->user_brokerage_id ]); } } // 升级判断流程开始 return $this->checkLevelV2($user, $nextLevel, $data); } /** * Common: 分销商升级 - 升级判断及修改等级信息 * Author: wu-hui * Time: 2023/12/26 14:20 * @param User $user * @param UserBrokerage $nextLevel * @param $data * @return bool|void */ public function checkLevelV2(User $user, UserBrokerage $nextLevel, $data){ // 分销商升级条件判断 try{ // 循环判断是否达成所有升级条件 全部达成为true-成功升级,未全部达成为false-升级失败;为空则未设置升级条件-不允许升级 $info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id])->column('number', 'type'); $completeResult = [];// 每个条件达成情况:达成=true;未达成=false;未开启=空 foreach ($nextLevel['brokerage_rule'] as $upgradeKey => $rule) { // 是否开启 if($rule['is_open'] != 1) continue; // 根据类型进行对应的处理 if(in_array($upgradeKey,self::BROKERAGE_RULE_TYPE)){ // 基本升级条件 统一处理 if((float)$rule['num'] <= 0) continue;// 条件无效 // 判断:条件是否达标 $num = $info[$upgradeKey] ?? 0; $completeResult[$upgradeKey] = (float)$rule['num'] >= (float)$num; }else{ // 特殊升级条件 全部单独处理 $funName = 'upgradeJudge'.ucfirst(camelize($upgradeKey)); $judgeResult = $this->$funName($rule,$data); if(gettype($judgeResult) == 'boolean') $completeResult[$upgradeKey] = $judgeResult; } } // 判断:是否成功升级 if(array_sum($completeResult) != count($completeResult)) return false;// 结果为空,无有效升级条件;禁止升级 // 升级成功 $nextLevel->user_num++; Db::transaction(function () use ($nextLevel, $user) { $nextLevel->save(); if ($user->brokerage && $user->brokerage->user_num > 0) { $user->brokerage->user_num--; $user->brokerage->save(); } // 不是推广员 开启推广员身份 if((int)$user->is_promoter != 1){ $user->is_promoter = 1; $user->promoter_time = date('Y-m-d H:i:s'); } $user->brokerage_level = $nextLevel->brokerage_level; $user->save(); $key = 'notice_brokerage_level_' . $user->uid; app()->make(CacheRepository::class)->save($key,$nextLevel->brokerage_level); }); return true; }catch(\Exception $e){ Log::info('分销商升级 - 错误: '.var_export([ 'uid' => $user->uid, 'type' => $data['type'], 'msg' => $e->getMessage(), ],1)); } } /** * Common: 分销商升级 - 升级条件判断 - 购买某个商品之一 * Author: wu-hui * Time: 2023/12/26 14:35 * @param $rule * @param $data * @return bool|string */ private function upgradeJudgeManyGoods($rule,$data){ // 判断:条件是否有效 if(count($rule['ids']) <= 0) return '';// 条件无效 未设置商品 // 判断:是否存在订单信息 不存在直接返回false if(!array_key_exists('group_order_id',$data)) return false; // 处理订单信息 $orderIds = StoreOrder::where('group_order_id',$data['group_order_id'])->column('order_id');// 获取订单id $productIds = StoreOrderProduct::whereIn('order_id',$orderIds)->column('product_id');// 获取当前订单中所有商品ID $setNeedProductIds = Spu::whereIn('spu_id',$rule['ids'])->column('product_id');// 设置的需求商品ID $intersectData = array_intersect($productIds,$setNeedProductIds); return count($intersectData) > 0; } public function getLevelRate(User $user, UserBrokerage $nextLevel) { $info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id]) ->column('number', 'type'); $brokerage_rule = $nextLevel['brokerage_rule']; foreach ($nextLevel['brokerage_rule'] as $k => $rule) { if ($rule['num'] <= 0) { unset($brokerage_rule[$k]); continue; } if (!isset($info[$k])) { $rate = 0; } else if ($rule['num'] > $info[$k]) { $rate = bcdiv($info[$k], $rule['num'], 2) * 100; } else { $rate = 100; } $brokerage_rule[$k]['rate'] = $rate; $brokerage_rule[$k]['task'] = (float)(min($info[$k] ?? 0, $rule['num'])); } return $brokerage_rule; } public function form(?int $id = null) { $formData = []; if ($id) { $form = Elm::createForm(Route::buildUrl('systemUserMemberUpdate', ['id' => $id])->build()); $data = $this->dao->get($id); if (!$data) throw new ValidateException('数据不存在'); $formData = $data->toArray(); } else { $form = Elm::createForm(Route::buildUrl('systemUserMemberCreate')->build()); } $rules = [ Elm::number('brokerage_level', '会员等级')->required(), Elm::input('brokerage_name', '会员名称')->required(), Elm::frameImage('brokerage_icon', '会员图标', '/' . config('admin.admin_prefix') . '/setting/uploadPicture?field=brokerage_icon&type=1') ->required() ->value($formData['brokerage_icon'] ?? '') ->modal(['modal' => false]) ->width('1000px') ->height('600px'), Elm::number('value', ' 所需成长值',$formData['brokerage_rule']['value'] ?? 0)->required(), Elm::frameImage('image', '背景图', '/' . config('admin.admin_prefix') . '/setting/uploadPicture?field=image&type=1') ->value($formData['brokerage_rule']['image']??'') ->required() ->modal(['modal' => false]) ->width('1000px') ->height('600px'), ]; $form->setRule($rules); return $form->setTitle(is_null($id) ? '添加会员等级' : '编辑会员等级')->formData($formData); } public function incMemberValue(int $uid, string $type, int $id) { if (!systemConfig('member_status')) return ; $make = app()->make(UserBillRepository::class); $count = $make->getWhereCount(['type' => $type, 'link_id' => $id]); if ($count) return ; $config = [ 'member_pay_num' => '下单获得成长值', 'member_sign_num' => '签到获得成长值', 'member_reply_num' => '评价获得成长值', 'member_share_num' => '邀请获得成长值', 'member_community_num' => '种草图文获得成长值', ]; $inc = systemConfig($type) > 0 ? systemConfig($type) : 0; $user = app()->make(UserRepository::class)->getWhere(['uid' => $uid],'*',['member']); $svip_status = $user->is_svip > 0 && systemConfig('svip_switch_status') == '1'; if ($svip_status) { $svipRate = app()->make(MemberinterestsRepository::class)->getSvipInterestVal(MemberinterestsRepository::HAS_TYPE_MEMBER); if ($svipRate > 0) { $inc = bcmul($svipRate, $inc, 0); } } $this->checkMemberValue($user, $inc); $make->incBill($user->uid, 'sys_members', $type, [ 'number' => $inc, 'title' => $config[$type], 'balance' => $user->member_value, 'status' => 0, 'link_id' => $id, 'mark' => $config[$type].':'.$inc, ]); } /** * TODO 连续升级 * @param $nextLevel * @param $num * @return array * @author Qinii * @day 1/11/22 */ public function upUp($nextLevel, $num) { $newLevel = $this->getNextLevel($nextLevel->brokerage_level, 1); if ($newLevel) { $newNum = $num - $newLevel->brokerage_rule['value']; if ($newNum > 0) { [$nextLevel,$num] = $this->upUp($newLevel, $newNum); } } return [$nextLevel,$num]; } /** * TODO 升级操作 * @param User $user * @param int $inc * @author Qinii * @day 1/11/22 */ public function checkMemberValue(User $user, int $inc) { /** * 下一级所需经验值 * 当前的经验值加上增加经验值是否够升级 */ Db::transaction(function () use ($inc, $user) { $nextLevel = $this->getNextLevel($user->member_level, 1); if (!$nextLevel) return ; if (($user->member_value + $inc) >= $nextLevel->brokerage_rule['value']) { $num = ($user->member_value + $inc) - $nextLevel->brokerage_rule['value']; if ($num > 0) { [$nextLevel,$num] = $this->upUp($nextLevel, $num); } if ($user->member) { $user->member->user_num--; $user->member->save(); } $nextLevel->user_num++; $nextLevel->save(); $user->member_level = $nextLevel->brokerage_level; $key = 'notice_member_level_' . $user->uid; app()->make(CacheRepository::class)->save($key,$nextLevel->brokerage_level); } else { $num = ($user->member_value + $inc); } $user->member_value = $num; $user->save(); }); } }