From 2f94fd4fc24f03169bbd4181cc95306af5dc6f07 Mon Sep 17 00:00:00 2001 From: wuhui_zzw <1760308791@qq.com> Date: Wed, 27 Mar 2024 16:25:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=9A=E5=88=86=E9=94=80?= =?UTF-8?q?=E5=95=86=E6=B7=BB=E5=8A=A0=E8=B4=AD=E4=B9=B0=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E5=95=86=E5=93=81=E5=8D=87=E7=BA=A7=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common.php | 80 ++++++++++- .../user/UserBrokerageRepository.php | 125 +++++++++++++++++- .../exchangeQuota/OrderPaySuccessEvent.php | 9 ++ app/validate/admin/UserBrokerageValidate.php | 18 +-- crmeb/jobs/UserBrokerageLevelJob.php | 21 ++- route/api.php | 1 + 6 files changed, 228 insertions(+), 26 deletions(-) diff --git a/app/common.php b/app/common.php index 24bedbf..80f2a2d 100644 --- a/app/common.php +++ b/app/common.php @@ -1320,8 +1320,84 @@ if (!function_exists('getFirstCharter')) { return implode($pingYin); } } - - +// 下划线字符串 转 驼峰字符串 +if (!function_exists('camelize')) { + function camelize($string,$separator = '_'){ + $string = $separator. str_replace($separator, " ", strtolower($string)); + return ltrim(str_replace(" ", "", ucwords($string)), $separator ); + } +} +// 根据类型获取对应的时间戳 +if (!function_exists('getTimeStamp')) { + function getTimeStamp($type){ + $startTime = $endTime =0; + #year=本年,month=本月,today=今日,yesterday=昨日,last_week=上周,week=本周,quarter=季度,half_a_year=半年,last_month=上一个月 + switch($type){ + // 本年 + case "year": + $startTime = strtotime(date("Y-1-1"));// 本年1号0点 + $endTime = strtotime(date("Y-1-1"). " +1 year");// 下一年1号0点 + break; + // 本月 + case "month": + $startTime = strtotime(date("Y-m-1"));// 本月1号0点 + $endTime = strtotime(date("Y-m-1"). " +1 month ");// 下一个月1号0点 + break; + // 今日 + case "today": + $startTime = strtotime(date("Y-m-d"));// 今日0点 + $endTime = strtotime(date("Y-m-d"). " +1 day ");// 明日0点 + break; + // 昨日 + case "yesterday": + $startTime = strtotime(date("Y-m-d"). " -1 day ");// 昨日0点 + $endTime = strtotime(date("Y-m-d"));// 今日0点 + break; + // 上周 + case "last_week": + $week = date('w') == 0 ? 7 : date('w'); + $startTime = strtotime('today -' . ($week - 1) . 'day -1 week');// 上周一 0点 + $endTime = strtotime('today +' . (8 - $week) . 'day -1 week');// 本周一 0点 + break; + // 本周 + case "week": + $week = date('w') == 0 ? 7 : date('w'); + $startTime = strtotime('today -' . ($week - 1) . 'day');// 本周一 0点 + $endTime = strtotime('today +' . (8 - $week) . 'day');// 下周一 0点 + break; + // 季度 + case "quarter": + $currentMonth = date('n'); // 获取当前月份 + $currentQuarter = ceil($currentMonth / 3); // 计算当前是第几个季度 + $currentYear = date('Y'); // 获取当前年份 + // 本季度开始时间 + $startTime = strtotime(($currentQuarter - 1) * 3 . ' months', strtotime("$currentYear-01-01")); + // 下一个季度开始时间 + $endTime = strtotime(($currentQuarter * 3) . ' months', strtotime("$currentYear-01-01")); + break; + // 上半年/下半年 + case "half_a_year": + $currentMonth = date('n'); // 获取当前月份 + $currentYear = date('Y'); // 获取当前年份 + if($currentMonth <= 6){ + // 获取上半年时间 + $startTime = strtotime("$currentYear-01-01");// 本年1号 0点 + $endTime = strtotime("$currentYear-07-01");// 本年7月1号 0点 + }else{ + // 获取下半年时间 + $startTime = strtotime("$currentYear-07-01");// 本年7月1号 0点 + $endTime = strtotime("$currentYear-01-01 +1 years");// 明年1号 0点 + } + break; + // 上一个月 + case "last_month": + $startTime = strtotime(date("Y-m-1")." -1 month");// 上一个月1号0点 + $endTime = strtotime(date("Y-m-1"));// 本月1号0点 + break; + } + return [$startTime,$endTime]; + } +} diff --git a/app/common/repositories/user/UserBrokerageRepository.php b/app/common/repositories/user/UserBrokerageRepository.php index 714b2b4..68f2166 100644 --- a/app/common/repositories/user/UserBrokerageRepository.php +++ b/app/common/repositories/user/UserBrokerageRepository.php @@ -6,6 +6,9 @@ namespace app\common\repositories\user; use app\common\dao\user\UserBrokerageDao; +use app\common\model\store\order\StoreOrder; +use app\common\model\store\order\StoreOrderProduct; +use app\common\model\store\product\Spu; use app\common\model\user\User; use app\common\model\user\UserBrokerage; use app\common\repositories\BaseRepository; @@ -13,6 +16,7 @@ use app\common\repositories\system\CacheRepository; use FormBuilder\Factory\Elm; use think\exception\ValidateException; use think\facade\Db; +use think\facade\Log; use think\facade\Route; /** @@ -20,7 +24,7 @@ use think\facade\Route; */ class UserBrokerageRepository extends BaseRepository { - + // 基本升级条件 所有内容走基本升级条件流程统一处理,未添加到该数组中的升级条件为特殊升级条件,全部单独处理 public const BROKERAGE_RULE_TYPE = ['spread_user', 'pay_money', 'pay_num', 'spread_money', 'spread_pay_num']; public function __construct(UserBrokerageDao $dao) @@ -51,6 +55,7 @@ class UserBrokerageRepository extends BaseRepository 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); @@ -72,7 +77,6 @@ class UserBrokerageRepository extends BaseRepository 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]) @@ -96,6 +100,123 @@ class UserBrokerageRepository extends BaseRepository }); 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) { diff --git a/app/listener/exchangeQuota/OrderPaySuccessEvent.php b/app/listener/exchangeQuota/OrderPaySuccessEvent.php index d01aed3..b1d42ae 100644 --- a/app/listener/exchangeQuota/OrderPaySuccessEvent.php +++ b/app/listener/exchangeQuota/OrderPaySuccessEvent.php @@ -12,7 +12,9 @@ use app\common\repositories\marketing\AgentBrokerageRepository; use app\common\repositories\system\merchant\MerchantRepository; use app\common\repositories\user\ExchangePickupPointRepository; use app\common\repositories\user\ExchangeQuotaRepository; +use crmeb\jobs\UserBrokerageLevelJob; use think\facade\Log; +use think\facade\Queue; class OrderPaySuccessEvent{ public $groupOrder; @@ -40,6 +42,13 @@ class OrderPaySuccessEvent{ }else{ // 其他订单 $this->orderPaySuccessHandle($groupOrder); + // 订单支付成功 触发购买商品升级 + Queue::push(UserBrokerageLevelJob::class,[ + 'uid' => $groupOrder->uid, + 'type' => 'many_goods', + 'inc' => 0, + 'group_order_id' => $groupOrder->group_order_id + ]); } }catch(\Exception $e){ diff --git a/app/validate/admin/UserBrokerageValidate.php b/app/validate/admin/UserBrokerageValidate.php index 158bfa0..2dbedaa 100644 --- a/app/validate/admin/UserBrokerageValidate.php +++ b/app/validate/admin/UserBrokerageValidate.php @@ -15,31 +15,31 @@ class UserBrokerageValidate extends Validate protected $rule = [ 'brokerage_level|会员等级' => 'require|integer|>:0', 'brokerage_name|会员名称' => 'require|max:16', - 'brokerage_icon|会员图标' => 'require', - 'brokerage_rule|会员升级规则' => 'requireIf:type,0|array|checkBrokerageRule', + // 'brokerage_icon|会员图标' => 'require', + 'brokerage_rule|会员升级规则' => 'requireIf:type,0|array',// checkBrokerageRule todo: 取消升级条件验证 如果不存在升级条件则不允许升级到该等级 'extension_one|一级佣金比例' => 'requireIf:type,0|float|>=:0|<=:100', 'extension_two|二级佣金比例' => 'requireIf:type,0|float|>=:0|<=:100', 'image|背景图' => 'requireIf:type,1|max:128', 'value|会员成长值' => 'requireIf:type,1|float|>=:0', 'type|类型' => 'require|in:0,1', ]; + // todo 2023-12-25 重构升级条件,这里的验证不在使用 因此未修改验证内容,这里的验证已失效 + public function checkBrokerageRule($value, $rlue, $data){ - public function checkBrokerageRule($value, $rlue, $data) - { if (!$data['type']) { + // 基本升级条件:不在列表中的升级条件,不进行统一升级条件判断 $types = UserBrokerageRepository::BROKERAGE_RULE_TYPE; - if (count($types) != count($value)) { - return '请输入正确的升级任务'; - } + // if (count($types) != count($value)) return '升级任务设置错误'; $flag = 0; foreach ($types as $type) { $val = $value[$type] ?? ''; if (!is_array($val) || !isset($val['name'], $val['num'], $val['info']) || count($val) != 3) return '请输入正确的升级任务'; - if ($val['num'] < 0) - return '请输入正确的任务数量'; + if ($val['num'] < 0) return '请输入正确的任务数量'; if ($val['num'] > 0 && !$val['name']) return '请输入任务名称'; if ($val['num'] > 0) $flag++; } + + if (!$flag) return '请至少设置一个升级任务'; } diff --git a/crmeb/jobs/UserBrokerageLevelJob.php b/crmeb/jobs/UserBrokerageLevelJob.php index 80fa311..b0c9da8 100644 --- a/crmeb/jobs/UserBrokerageLevelJob.php +++ b/crmeb/jobs/UserBrokerageLevelJob.php @@ -18,20 +18,15 @@ class UserBrokerageLevelJob implements JobInterface try { $user = app()->make(UserRepository::class)->get($data['uid']); if ($user) { + // 修改用户信息 $flag = true; - if ($data['type'] == 'spread_money') { - $user->spread_pay_price = bcadd($user->spread_pay_price, $data['inc'], 2); - } else if ($data['type'] == 'spread_pay_num') { - $user->spread_pay_count = bcadd($user->spread_pay_count, $data['inc'], 0); - } else { - $flag = false; - } - if ($flag) { - $user->save(); - } - } - if ($user && $user->is_promoter) { - app()->make(UserBrokerageRepository::class)->inc($user, $data['type'], $data['inc']); + if ($data['type'] == 'spread_money') $user->spread_pay_price = bcadd($user->spread_pay_price, $data['inc'], 2); + else if ($data['type'] == 'spread_pay_num') $user->spread_pay_count = bcadd($user->spread_pay_count, $data['inc'], 0); + else $flag = false; + if ($flag) $user->save(); + // todo: 2023-12-25 分销商升级重构 旧版本弃用,改为使用v2版本升级流程 + // app()->make(UserBrokerageRepository::class)->inc($user, $data); + app()->make(UserBrokerageRepository::class)->incV2($user, $data); } } catch (\Exception $e) { Log::info('分销等级同步失败: ' . var_export($data, 1) . $e->getMessage()); diff --git a/route/api.php b/route/api.php index 5191e55..9be29d0 100644 --- a/route/api.php +++ b/route/api.php @@ -13,6 +13,7 @@ use app\common\middleware\RequestLockMiddleware; use think\facade\Route; Route::group('api/', function () { + Route::any('test', 'api.Test/test'); Route::any('test', 'api.Auth/test'); //强制登录 Route::group(function () {