495 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			495 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
|  | <?php | ||
|  | namespace app\admin\logic\distribution; | ||
|  | 
 | ||
|  | use app\common\basics\Logic; | ||
|  | use app\common\model\distribution\Distribution; | ||
|  | use app\common\model\distribution\DistributionGoods; | ||
|  | use app\common\model\distribution\DistributionLevel; | ||
|  | use app\common\model\distribution\DistributionLevelUpdate; | ||
|  | use app\common\model\distribution\DistributionOrderGoods; | ||
|  | use app\common\model\order\Order; | ||
|  | use app\common\model\order\OrderTrade; | ||
|  | use think\facade\Db; | ||
|  | 
 | ||
|  | class DistributionLevelLogic extends Logic | ||
|  | { | ||
|  |     /** | ||
|  |      * @notes 分销等级列表 | ||
|  |      * @return array | ||
|  |      * @throws \think\db\exception\DataNotFoundException | ||
|  |      * @throws \think\db\exception\DbException | ||
|  |      * @throws \think\db\exception\ModelNotFoundException | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/1 16:19 | ||
|  |      */ | ||
|  |     public static function index() | ||
|  |     { | ||
|  |         $field = [ | ||
|  |             'id', | ||
|  |             'name', | ||
|  |             'weights' => 'weights_desc', | ||
|  |             'first_ratio', | ||
|  |             'second_ratio', | ||
|  |             'is_default', | ||
|  |             'id' => 'members_num' | ||
|  |         ]; | ||
|  |         $lists = DistributionLevel::field($field) | ||
|  |             ->order('weights', 'asc') | ||
|  |             ->select() | ||
|  |             ->toArray(); | ||
|  | 
 | ||
|  |         $count = DistributionLevel::count(); | ||
|  | 
 | ||
|  |         return [ | ||
|  |             'count' => $count, | ||
|  |             'lists' => $lists, | ||
|  |         ]; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 添加分销会员等级 | ||
|  |      * @param $params | ||
|  |      * @return bool | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/1 14:53 | ||
|  |      */ | ||
|  |     public static function add($params) | ||
|  |     { | ||
|  |         Db::startTrans(); | ||
|  |         try{ | ||
|  |             // 写入等级主表
 | ||
|  |             $params['remark'] = $params['remark'] ?? ''; | ||
|  |             $newLevel = DistributionLevel::create($params); | ||
|  | 
 | ||
|  |             // 写入升级条件表
 | ||
|  |             self::addUpdateCondition($params, $newLevel->id); | ||
|  | 
 | ||
|  |             // 处理分销商品比例
 | ||
|  |             self::updateDistributionGoods($newLevel->id); | ||
|  | 
 | ||
|  |             Db::commit(); | ||
|  |             return true; | ||
|  |         }catch(\Exception $e) { | ||
|  |             Db::rollback(); | ||
|  |             self::$error = $e->getMessage(); | ||
|  |             return false; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 添加更新升级条件 | ||
|  |      * @param $params | ||
|  |      * @param $level_id | ||
|  |      * @throws \Exception | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/1 15:08 | ||
|  |      */ | ||
|  |     public static function addUpdateCondition($params, $level_id) | ||
|  |     { | ||
|  |         $updateConditionData = []; | ||
|  |         foreach($params['update_condition'] as $key) { | ||
|  |             // 判断是否在规定的条件字段
 | ||
|  |             if(!in_array($key, DistributionLevel::UPDATE_CONDITION_FIELDS, true)) { | ||
|  |                 continue; | ||
|  |             } | ||
|  |             if ($params[$key] < 0) { | ||
|  |                 throw new \Exception('升级条件不允许小于0'); | ||
|  |             } | ||
|  |             // 获取键对应值的字段名
 | ||
|  |             $valueField = DistributionLevel::getValueFiled($key); | ||
|  |             $updateConditionData[] = [ | ||
|  |                 'level_id' => $level_id, | ||
|  |                 'key' => $key, | ||
|  |                 $valueField => $params[$key] | ||
|  |             ]; | ||
|  |         } | ||
|  |         (new DistributionLevelUpdate())->saveAll($updateConditionData); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 获取分销等级详情 | ||
|  |      * @param $params | ||
|  |      * @return array | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/1 15:36 | ||
|  |      */ | ||
|  |     public static function detail($params) | ||
|  |     { | ||
|  |         $level = DistributionLevel::withoutField('create_time,update_time,delete_time')->findOrEmpty($params['id']); | ||
|  |         if($level->isEmpty()) { | ||
|  |             return []; | ||
|  |         } | ||
|  |         $level = $level->toArray(); | ||
|  |         // 默认等级
 | ||
|  |         if($level['is_default']) { | ||
|  |             unset($level['self_ratio']); | ||
|  |             unset($level['third_ratio']); | ||
|  |             unset($level['update_relation']); | ||
|  |             return $level; | ||
|  |         } | ||
|  |         // 自定义等级
 | ||
|  |         $level['update_condition'] = self::getUpdateCondition($level); | ||
|  |         unset($level['self_ratio']); | ||
|  |         unset($level['third_ratio']); | ||
|  | 
 | ||
|  |         return $level; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 获取升级条件 | ||
|  |      * @param $level | ||
|  |      * @return array | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/1 15:36 | ||
|  |      */ | ||
|  |     public static function getUpdateCondition($level) | ||
|  |     { | ||
|  |         $updateCondition = DistributionLevelUpdate::where('level_id', $level['id'])->column('key,value_int,value_decimal,value_text'); | ||
|  |         $updateConditionData = []; | ||
|  |         foreach($updateCondition as $item) { | ||
|  |             if($item['value_int']) { | ||
|  |                 $updateConditionData[$item['key']] = $item['value_int']; | ||
|  |                 continue; | ||
|  |             } | ||
|  |             if($item['value_decimal']) { | ||
|  |                 $updateConditionData[$item['key']] = $item['value_decimal']; | ||
|  |                 continue; | ||
|  |             } | ||
|  |             if($item['value_text']) { | ||
|  |                 $updateConditionData[$item['key']] = $item['value_text']; | ||
|  |                 continue; | ||
|  |             } | ||
|  |         } | ||
|  |         $data = [ | ||
|  |             'keys' => array_keys($updateConditionData), | ||
|  |             'data' => $updateConditionData | ||
|  |         ]; | ||
|  |         // 补全条件
 | ||
|  |         foreach(DistributionLevel::UPDATE_CONDITION_FIELDS as $field) { | ||
|  |             if(!isset($data['data'][$field])) { | ||
|  |                 $data['data'][$field] =  ''; | ||
|  |             } | ||
|  |         } | ||
|  |         return $data; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 编辑分销等级 | ||
|  |      * @param $params | ||
|  |      * @return bool | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/1 16:20 | ||
|  |      */ | ||
|  |     public static function edit($params) | ||
|  |     { | ||
|  |         Db::startTrans(); | ||
|  |         try{ | ||
|  |             $params['remark'] = $params['remark'] ?? ''; | ||
|  |             $level = DistributionLevel::findOrEmpty($params['id']); | ||
|  |             if($level->isEmpty()) { | ||
|  |                 throw new \Exception('等级不存在'); | ||
|  |             } | ||
|  |             // 默认等级
 | ||
|  |             if($level->is_default) { | ||
|  |                 $level->allowField(['name', 'first_ratio', 'second_ratio','remark'])->save($params); | ||
|  |                 Db::commit(); | ||
|  |                 return true; | ||
|  |             } | ||
|  |             // 自定义等级 - 更新主表信息
 | ||
|  |             if(!$params['weights'] > 1) { | ||
|  |                 throw new \Exception('级别须大于1'); | ||
|  |             } | ||
|  |             if(!isset($params['update_relation'])) { | ||
|  |                 throw new \Exception('请选择升级关系'); | ||
|  |             } | ||
|  |             if(!isset($params['update_condition']) || !count($params['update_condition'])) { | ||
|  |                 throw new \Exception('请选择升级条件'); | ||
|  |             } | ||
|  |             $level->allowField(['name', 'weights', 'first_ratio', 'second_ratio','remark', 'update_relation'])->save($params); | ||
|  | 
 | ||
|  |             // 自定义等级 - 删除旧升级条件
 | ||
|  |             $deleteIds = DistributionLevelUpdate::where('level_id', $level->id)->column('id'); | ||
|  |             DistributionLevelUpdate::destroy($deleteIds); | ||
|  | 
 | ||
|  |             // 自定义等级 - 添加新的升级条件
 | ||
|  |             self::addUpdateCondition($params, $level->id); | ||
|  | 
 | ||
|  |             Db::commit(); | ||
|  |             return true; | ||
|  |         }catch(\Exception $e) { | ||
|  |             Db::rollback(); | ||
|  |             self::$error = $e->getMessage(); | ||
|  |             return false; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 删除分销等级 | ||
|  |      * @param $params | ||
|  |      * @return bool | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/1 16:21 | ||
|  |      */ | ||
|  |     public static function delete($params) | ||
|  |     { | ||
|  |         Db::startTrans(); | ||
|  |         try{ | ||
|  |             $level = DistributionLevel::findOrEmpty($params['id']); | ||
|  |             if($level->isEmpty()) { | ||
|  |                 throw new \Exception('等级不存在'); | ||
|  |             } | ||
|  |             if($level->is_default) { | ||
|  |                 throw new \Exception('系统默认等级不允许删除'); | ||
|  |             } | ||
|  | 
 | ||
|  |             // 重置该等级下的分销会员为系统默认等级
 | ||
|  |             $defaultId = DistributionLevel::where('is_default', 1)->value('id'); | ||
|  |             Distribution::where('level_id', $level->id)->update(['level_id' => $defaultId]); | ||
|  | 
 | ||
|  |             // 删除升级条件
 | ||
|  |             $deleteIds = DistributionLevelUpdate::where('level_id', $level->id)->column('id'); | ||
|  |             DistributionLevelUpdate::destroy($deleteIds); | ||
|  | 
 | ||
|  |             // 删除该等级下的分销商品比例
 | ||
|  |             $deleteIds = DistributionGoods::where('level_id', $level->id)->column('id'); | ||
|  |             DistributionGoods::destroy($deleteIds); | ||
|  | 
 | ||
|  |             // 删除等级
 | ||
|  |             $level->delete(); | ||
|  | 
 | ||
|  |             Db::commit(); | ||
|  |             return true; | ||
|  |         }catch(\Exception $e) { | ||
|  |             Db::rollback(); | ||
|  |             self::$error = $e->getMessage(); | ||
|  |             return false; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 更新分销会员等级 | ||
|  |      * @param $userId | ||
|  |      * @return false | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/2 16:39 | ||
|  |      */ | ||
|  |     public static function updateDistributionLevel($userId) | ||
|  |     { | ||
|  |         // 非默认等级
 | ||
|  |         $levels = DistributionLevel::where('is_default', 0) | ||
|  |             ->order('weights', 'desc') | ||
|  |             ->column('id,name,weights,update_relation', 'id'); | ||
|  | 
 | ||
|  |         $userInfo = Distribution::alias('d') | ||
|  |             ->leftJoin('distribution_level dl', 'dl.id = d.level_id') | ||
|  |             ->field('d.is_distribution,d.level_id,dl.weights') | ||
|  |             ->where('d.user_id', $userId) | ||
|  |             ->findOrEmpty() | ||
|  |             ->toArray(); | ||
|  | 
 | ||
|  |         // 非分销会员直接返回false
 | ||
|  |         if(empty($userInfo) || !$userInfo['is_distribution']) { | ||
|  |             return false; | ||
|  |         } | ||
|  | 
 | ||
|  |         foreach($levels as $level) { | ||
|  |             if(self::isMeetConditions($userId, $level) && $level['weights'] > $userInfo['weights']) { | ||
|  |                 // 满足升级条件且是升更高的等级
 | ||
|  |                 Distribution::where(['user_id' => $userId])->update(['level_id' => $level['id']]); | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 判断是否满足当前等级的升级条件 | ||
|  |      * @param $userId | ||
|  |      * @param $level | ||
|  |      * @return bool | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/2 16:42 | ||
|  |      */ | ||
|  |     public static function isMeetConditions($userId, $level) | ||
|  |     { | ||
|  |         // 任一条件满足升级
 | ||
|  |         if($level['update_relation'] == 1) { | ||
|  |             $flagOr = self::singleConsumptionAmountFlag($userId, $level) || self::cumulativeConsumptionAmountFlag($userId, $level) || self::cumulativeConsumptionTimesFlag($userId, $level) || self::returnedCommissionFlag($userId, $level); | ||
|  |             return $flagOr; | ||
|  |         } | ||
|  | 
 | ||
|  |         // 全部条件满足升级
 | ||
|  |         if($level['update_relation'] == 2) { | ||
|  |             $flagAnd = self::singleConsumptionAmountFlag($userId, $level) && self::cumulativeConsumptionAmountFlag($userId, $level) && self::cumulativeConsumptionTimesFlag($userId, $level) && self::returnedCommissionFlag($userId, $level); | ||
|  |             return $flagAnd; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 判断是否满足单笔消费金额条件 | ||
|  |      * @param $userId | ||
|  |      * @param $level | ||
|  |      * @return bool | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/2 16:44 | ||
|  |      */ | ||
|  |     public static function singleConsumptionAmountFlag($userId, $level) | ||
|  |     { | ||
|  |         $condition = DistributionLevelUpdate::field('value_int,value_decimal,value_text') | ||
|  |             ->where([ | ||
|  |                 'level_id' => $level['id'], | ||
|  |                 'key' => 'singleConsumptionAmount' | ||
|  |             ]) | ||
|  |             ->findOrEmpty(); | ||
|  |         if($condition->isEmpty()) { | ||
|  |             // 没有该条件代表无需判断,直接返回true
 | ||
|  |             return true; | ||
|  |         } | ||
|  |         $recentOrder = Order::where([ | ||
|  |             'user_id' =>  $userId, | ||
|  |             'pay_status' => 1 | ||
|  |         ]) | ||
|  |             ->order('id', 'desc') | ||
|  |             ->findOrEmpty(); | ||
|  |         if($recentOrder->isEmpty()) { | ||
|  |             return false; | ||
|  |         } | ||
|  |         $singleConsumptionAmount = OrderTrade::where('id', $recentOrder['trade_id'])->findOrEmpty()->toArray(); | ||
|  |         if($singleConsumptionAmount['order_amount'] >= $condition['value_decimal']) { | ||
|  |             return true; | ||
|  |         } | ||
|  |         return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 判断是否满足累计消费金额条件 | ||
|  |      * @param $userId | ||
|  |      * @param $level | ||
|  |      * @return bool | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/2 16:50 | ||
|  |      */ | ||
|  |     public static function cumulativeConsumptionAmountFlag($userId, $level) | ||
|  |     { | ||
|  |         $condition = DistributionLevelUpdate::field('value_int,value_decimal,value_text') | ||
|  |             ->where([ | ||
|  |                 'level_id' => $level['id'], | ||
|  |                 'key' => 'cumulativeConsumptionAmount' | ||
|  |             ]) | ||
|  |             ->findOrEmpty(); | ||
|  |         if($condition->isEmpty()) { | ||
|  |             // 没有该条件代表无需判断,直接返回true
 | ||
|  |             return true; | ||
|  |         } | ||
|  |         $cumulativeConsumptionAmount = Order::where([ | ||
|  |             'user_id' =>  $userId, | ||
|  |             'pay_status' => 1 | ||
|  |         ])->sum('order_amount'); | ||
|  |         if($cumulativeConsumptionAmount >= $condition['value_decimal']) { | ||
|  |             return true; | ||
|  |         } | ||
|  |         return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 判断是否满足累计消费次数条件 | ||
|  |      * @param $userId | ||
|  |      * @param $level | ||
|  |      * @return bool | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/2 16:53 | ||
|  |      */ | ||
|  |     public static function cumulativeConsumptionTimesFlag($userId, $level) | ||
|  |     { | ||
|  |         $condition = DistributionLevelUpdate::field('value_int,value_decimal,value_text') | ||
|  |             ->where([ | ||
|  |                 'level_id' => $level['id'], | ||
|  |                 'key' => 'cumulativeConsumptionTimes' | ||
|  |             ]) | ||
|  |             ->findOrEmpty(); | ||
|  |         if($condition->isEmpty()) { | ||
|  |             // 没有该条件代表无需判断,直接返回true
 | ||
|  |             return true; | ||
|  |         } | ||
|  |         $allTradeIds = Order::where([ | ||
|  |             'user_id' =>  $userId, | ||
|  |             'pay_status' => 1 | ||
|  |         ])->column('trade_id'); | ||
|  |         $cumulativeConsumptionTimes = count(array_unique($allTradeIds)); | ||
|  |         if($cumulativeConsumptionTimes >= $condition['value_int']) { | ||
|  |             return true; | ||
|  |         } | ||
|  |         return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 判断是否消费已返佣金条件 | ||
|  |      * @param $userId | ||
|  |      * @param $level | ||
|  |      * @return bool | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/2 17:06 | ||
|  |      */ | ||
|  |     public static function returnedCommissionFlag($userId, $level) | ||
|  |     { | ||
|  |         $condition = DistributionLevelUpdate::field('value_int,value_decimal,value_text') | ||
|  |             ->where([ | ||
|  |                 'level_id' => $level['id'], | ||
|  |                 'key' => 'returnedCommission' | ||
|  |             ]) | ||
|  |             ->findOrEmpty(); | ||
|  |         if($condition->isEmpty()) { | ||
|  |             // 没有该条件代表无需判断,直接返回true
 | ||
|  |             return true; | ||
|  |         } | ||
|  |         $returnedCommission = DistributionOrderGoods::where([ | ||
|  |             'user_id' => $userId, | ||
|  |             'status' => 2 | ||
|  |         ])->sum('money'); | ||
|  |         if($returnedCommission >= $condition['value_decimal']) { | ||
|  |             return true; | ||
|  |         } | ||
|  |         return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 获取所有分销会员等级 | ||
|  |      * @return array | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/2 18:31 | ||
|  |      */ | ||
|  |     public static function getLevels() | ||
|  |     { | ||
|  |         return DistributionLevel::order('weights', 'asc')->column('id, name,weights'); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @notes 更新分销商品比例 | ||
|  |      * @param $levelId | ||
|  |      * @author Tab | ||
|  |      * @date 2021/9/7 17:27 | ||
|  |      */ | ||
|  |     public static function updateDistributionGoods($levelId) | ||
|  |     { | ||
|  |         // 处理单独设置比例的商品,新增分销会等级佣金比例初始化为0
 | ||
|  |         $field = [ | ||
|  |             'shop_id', | ||
|  |             'goods_id', | ||
|  |             'item_id', | ||
|  |         ]; | ||
|  |        $distribution = DistributionGoods::distinct(true)->field($field)->where('rule', 2)->select()->toArray(); | ||
|  |        $addData = []; | ||
|  |        foreach($distribution as $item) { | ||
|  |             $temp = [ | ||
|  |                 'shop_id' => $item['shop_id'], | ||
|  |                 'goods_id' => $item['goods_id'], | ||
|  |                 'item_id' => $item['item_id'], | ||
|  |                 'level_id' => $levelId, | ||
|  |                 'first_ratio' => 0, | ||
|  |                 'second_ratio' => 0, | ||
|  |                 'rule' => 2, | ||
|  |             ]; | ||
|  |             $addData[] = $temp; | ||
|  |        } | ||
|  |         (new  DistributionGoods())->saveAll($addData); | ||
|  |     } | ||
|  | } |