208 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			208 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			PHP
		
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace app\traits\order;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use app\exception\RepositoryException;
							 | 
						||
| 
								 | 
							
								use app\model\Account;
							 | 
						||
| 
								 | 
							
								use app\model\Order;
							 | 
						||
| 
								 | 
							
								use app\model\OrderActivity;
							 | 
						||
| 
								 | 
							
								use app\model\OrderGroupList;
							 | 
						||
| 
								 | 
							
								use app\model\Sku;
							 | 
						||
| 
								 | 
							
								use app\model\Spu;
							 | 
						||
| 
								 | 
							
								use app\model\SpuActivity;
							 | 
						||
| 
								 | 
							
								use Exception;
							 | 
						||
| 
								 | 
							
								use think\Collection;
							 | 
						||
| 
								 | 
							
								use think\db\exception\DataNotFoundException;
							 | 
						||
| 
								 | 
							
								use think\db\exception\DbException;
							 | 
						||
| 
								 | 
							
								use think\db\exception\ModelNotFoundException;
							 | 
						||
| 
								 | 
							
								use think\facade\Db;
							 | 
						||
| 
								 | 
							
								use think\Model;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * 活动商品相关
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Trait ShoppingCartTrait
							 | 
						||
| 
								 | 
							
								 * @package app\traits\order
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								trait ActivityTrait
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 创建活动商品订单
							 | 
						||
| 
								 | 
							
								     * 每个活动商品均要创建一个活动订单
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param  int  $accountId
							 | 
						||
| 
								 | 
							
								     * @param  string  $orderCoding  订单编号
							 | 
						||
| 
								 | 
							
								     * @param  array  $skuList  sku列表
							 | 
						||
| 
								 | 
							
								     * @throws Exception
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function createActivityOrder(int $accountId, string $orderCoding, array $skuList)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $activityList    = [];//活动商品订单列表
							 | 
						||
| 
								 | 
							
								        $activitySkuList = [];//活动商品SKU列表
							 | 
						||
| 
								 | 
							
								        $groupList       = [];//拼团列表
							 | 
						||
| 
								 | 
							
								        $groupIds        = [];//拼团ID列表
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $now = date('Y-m-d H:i:s');
							 | 
						||
| 
								 | 
							
								        $this->checkActivity($skuList);
							 | 
						||
| 
								 | 
							
								        foreach ($skuList as $sku) {
							 | 
						||
| 
								 | 
							
								            $spuActivityId = $sku['spu_activity_id'];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($sku['is_activity'] == Spu::COMMON_OFF) {
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!isset($activitySkuList[$spuActivityId])) {
							 | 
						||
| 
								 | 
							
								                $activitySkuList[$spuActivityId] = [];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (!isset($activityList[$spuActivityId])) {
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]                    = [];
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['account_id']      = $accountId;
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['num']             = 0;
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['total_price']     = 0;
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['coding']          = $orderCoding;
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['spu_name']        = $sku['goods_name'];
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['type']            = $sku['activity_type'];
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['created_at']      = $now;
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['updated_at']      = $now;
							 | 
						||
| 
								 | 
							
								                $activityList[$spuActivityId]['spu_activity_id'] = $spuActivityId;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $activityList[$spuActivityId]['num']         += $sku['num'];
							 | 
						||
| 
								 | 
							
								            $activityList[$spuActivityId]['total_price'] += $sku['price'] * $sku['num'];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $activitySkuList[$spuActivityId][] = $sku;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        foreach ($activityList as &$activity) {
							 | 
						||
| 
								 | 
							
								            $activity['sku_info'] = json_encode($activitySkuList[$activity['spu_activity_id']], JSON_UNESCAPED_UNICODE);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 创建虚拟拼团
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param  int  $activityId  商品ID
							 | 
						||
| 
								 | 
							
								     * @param  int  $num  虚拟拼团数量 默认1
							 | 
						||
| 
								 | 
							
								     * @throws DataNotFoundException
							 | 
						||
| 
								 | 
							
								     * @throws DbException
							 | 
						||
| 
								 | 
							
								     * @throws ModelNotFoundException
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function createVirtualGroupList(int $activityId, int $num = 1): bool
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $groupList = [];
							 | 
						||
| 
								 | 
							
								        $activity  = SpuActivity::findById($activityId);
							 | 
						||
| 
								 | 
							
								        if ($activity['activity_type'] != Spu::TYPE_GROUP_MAKE) {
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $sku    = Sku::findOne(['spu_activity_id' => $activityId]);
							 | 
						||
| 
								 | 
							
								        $covers = Account::whereNotNull('headimgurl')->limit($num)->column('headimgurl');
							 | 
						||
| 
								 | 
							
								        $names  = [
							 | 
						||
| 
								 | 
							
								            '13****', '15****', '18****', '17****', '19****'
							 | 
						||
| 
								 | 
							
								        ];
							 | 
						||
| 
								 | 
							
								        for ($i = 0; $i < $num; $i++) {
							 | 
						||
| 
								 | 
							
								            $groupArr = [];
							 | 
						||
| 
								 | 
							
								            // 拼团列表
							 | 
						||
| 
								 | 
							
								            $groupArr['account_id']      = 0;
							 | 
						||
| 
								 | 
							
								            $groupArr['spu_activity_id'] = $activityId;
							 | 
						||
| 
								 | 
							
								            $groupArr['num']             = 0;
							 | 
						||
| 
								 | 
							
								            $groupArr['price']           = 0;
							 | 
						||
| 
								 | 
							
								            $groupArr['total_price']     = 0;
							 | 
						||
| 
								 | 
							
								            $groupArr['group_num']       = $activity['group_num'];
							 | 
						||
| 
								 | 
							
								            $groupArr['surplus']         = $activity['group_num'] - 1;
							 | 
						||
| 
								 | 
							
								            $groupArr['sku_coding']      = $sku['coding'];
							 | 
						||
| 
								 | 
							
								            $groupArr['group_id']        = 0;
							 | 
						||
| 
								 | 
							
								            $groupArr['coding']          = '';
							 | 
						||
| 
								 | 
							
								            $groupTime                   = $activity['group_time'] * 60;//拼团有效期(转为分钟)
							 | 
						||
| 
								 | 
							
								            $groupTime                   = $groupTime ?: rand(11, 23) * 60;//默认11~23小时随机
							 | 
						||
| 
								 | 
							
								            $groupArr['created_at']      = date('Y-m-d H:i:s');
							 | 
						||
| 
								 | 
							
								            $groupArr['expired_at']      = date('Y-m-d H:i:s', strtotime('+'.$groupTime.' minutes'));
							 | 
						||
| 
								 | 
							
								            $groupArr['is_initiator']    = 1;//是否发起人
							 | 
						||
| 
								 | 
							
								            $groupArr['is_virtual']      = 1;//是否虚拟拼团
							 | 
						||
| 
								 | 
							
								            shuffle($names);
							 | 
						||
| 
								 | 
							
								            shuffle($covers);
							 | 
						||
| 
								 | 
							
								            $groupArr['virtual_name']  = $names[0] ?? '13****';//虚拟用户名称
							 | 
						||
| 
								 | 
							
								            $groupArr['virtual_cover'] = $covers[0] ?? '';//虚拟用户头像
							 | 
						||
| 
								 | 
							
								            if (!empty($groupArr)) {
							 | 
						||
| 
								 | 
							
								                $groupList[] = $groupArr;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!empty($groupList)) {
							 | 
						||
| 
								 | 
							
								            OrderGroupList::createGroup($groupList);//创建拼团
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @param  string  $activityCoding
							 | 
						||
| 
								 | 
							
								     * @return bool
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function setPaid(string $activityCoding)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function checkActivity(array $skuList)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        //检测拼团名额是否已满 等
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 获取拼团列表
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param  int  $spuActivityId
							 | 
						||
| 
								 | 
							
								     * @return OrderGroupList[]|array|Collection
							 | 
						||
| 
								 | 
							
								     * @throws DataNotFoundException
							 | 
						||
| 
								 | 
							
								     * @throws DbException
							 | 
						||
| 
								 | 
							
								     * @throws ModelNotFoundException
							 | 
						||
| 
								 | 
							
								     * @throws RepositoryException
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getGroupList(int $spuActivityId)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$activity = SpuActivity::findById($spuActivityId, ['id', 'cover', 'group_num', 'saleable'])) {
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('活动商品不存在或已下架');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($activity['saleable'] == SpuActivity::COMMON_OFF) {
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('活动商品已下架');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $groupList = OrderGroupList::where('spu_activity_id', $spuActivityId)
							 | 
						||
| 
								 | 
							
								            ->where('expired_at', '>', date('Y-m-d H:i:s'))
							 | 
						||
| 
								 | 
							
								            ->where('group_id', '>', 0)
							 | 
						||
| 
								 | 
							
								            ->whereNull('deleted_at')
							 | 
						||
| 
								 | 
							
								            ->group('group_id')
							 | 
						||
| 
								 | 
							
								            ->field('count(`id`) as count, group_id')
							 | 
						||
| 
								 | 
							
								            ->select();
							 | 
						||
| 
								 | 
							
								        $groupIds  = $groupList->where('count', '<=', $activity['group_num'] - 1)->column('group_id');
							 | 
						||
| 
								 | 
							
								        $groupNum  = $groupList->where('count', '<=', $activity['group_num'] - 1)->column('count', 'group_id');
							 | 
						||
| 
								 | 
							
								        $list      = OrderGroupList::with(['accountCover'])
							 | 
						||
| 
								 | 
							
								            ->where('id', 'in', $groupIds)
							 | 
						||
| 
								 | 
							
								            ->whereNull('deleted_at')
							 | 
						||
| 
								 | 
							
								            ->where('expired_at', '>', date('Y-m-d H:i:s'))
							 | 
						||
| 
								 | 
							
								            ->where('is_initiator', OrderGroupList::COMMON_ON)
							 | 
						||
| 
								 | 
							
								            ->order('expired_at', 'asc')
							 | 
						||
| 
								 | 
							
								            ->field('id,is_virtual,spu_activity_id,num,account_id,expired_at as time,group_id,virtual_name,virtual_cover')
							 | 
						||
| 
								 | 
							
								            ->select();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $list->each(function ($item) use ($activity, $groupNum) {
							 | 
						||
| 
								 | 
							
								            // 剩余数量=团购最大数 - 拼团人数
							 | 
						||
| 
								 | 
							
								            $surplus   = $activity['group_num'] - $groupNum[$item->id];
							 | 
						||
| 
								 | 
							
								            $item->num = $surplus;
							 | 
						||
| 
								 | 
							
								            if ($item->is_virtual == 1) {
							 | 
						||
| 
								 | 
							
								                $item->name  = $item->virtual_name;
							 | 
						||
| 
								 | 
							
								                $item->cover = $item->virtual_cover;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            unset($item->account_id);
							 | 
						||
| 
								 | 
							
								            unset($item->spu_activity_id);
							 | 
						||
| 
								 | 
							
								            unset($item->group_id);
							 | 
						||
| 
								 | 
							
								            unset($item->is_virtual);
							 | 
						||
| 
								 | 
							
								            unset($item->virtual_name);
							 | 
						||
| 
								 | 
							
								            unset($item->virtual_cover);
							 | 
						||
| 
								 | 
							
								            if ($surplus <= 0) {
							 | 
						||
| 
								 | 
							
								                unset($item);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |