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