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);
 | 
						|
    }
 | 
						|
} |