添加活动管理,以及订单参与活动发券发赠品
parent
6b7d6d6ba1
commit
831d49533e
|
|
@ -322,8 +322,8 @@ class OrderController extends AdminController
|
|||
$builder = OrderProduct::withCount('afterSales')->where('order_id', $id);
|
||||
$productGrid = Grid::make($builder, function (Grid $grid) {
|
||||
$grid->column('name')->display(function ($value) {
|
||||
if ($this->gift_for_sku_id) {
|
||||
$value .= '-【赠品】';
|
||||
if ($this->isGift()) {
|
||||
$value = '【赠品】'.$value;
|
||||
}
|
||||
return $value;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class ProductSkuTable extends Grid
|
|||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->expand();
|
||||
$filter->equal('name')->width(3);
|
||||
$filter->like('name')->width(3);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Admin\Services;
|
||||
|
||||
use App\Enums\PayWay;
|
||||
use App\Events\OrderPaid;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderLog;
|
||||
|
|
@ -44,7 +45,8 @@ class OrderService
|
|||
//操作订单状态-需要调整为统一支付方法
|
||||
$orderService = new EndpointOrderService();
|
||||
$orderService->pay($order, PayWay::Offline);
|
||||
|
||||
//注册支付成功事件
|
||||
OrderPaid::dispatch($order);
|
||||
//记录操作日志
|
||||
OrderLog::create([
|
||||
'order_id'=> $order->id,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
namespace App\Listeners;
|
||||
|
||||
use App\Events\OrderPaid;
|
||||
use App\Models\ActivityProductPart;
|
||||
use App\Models\ProductPartSku;
|
||||
use App\Models\UserCoupon;
|
||||
use App\Services\CouponService;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
|
|
@ -34,26 +38,37 @@ class SendCoupons
|
|||
// 处理购买分区商品送券
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$products = $order->products()->with('sku.parts')->get();
|
||||
|
||||
// 整理订单商品的分区
|
||||
$inValidParts = [];
|
||||
|
||||
foreach ($products->pluck('sku.parts') as $parts) {
|
||||
foreach ($parts as $part) {
|
||||
if ($part->is_show) {
|
||||
// 分区去重
|
||||
$inValidParts[$part->id] = $part;
|
||||
$products = $order->products()->where('is_gift', false)->get()->toArray();
|
||||
$_products = array_column($products, 'total_amount', 'sku_id');
|
||||
$partSkus = ProductPartSku::with('part')->whereIn('sku_id', array_keys($_products))->get();
|
||||
foreach ($partSkus as $partSku) {
|
||||
if ($partSku->part?->is_show) {
|
||||
if (isset($inValidParts[$partSku->part_id])) {
|
||||
$inValidParts[$partSku->part_id] += $_products[$partSku->sku_id] ?? 0;
|
||||
} else {
|
||||
$inValidParts[$partSku->part_id] = $_products[$partSku->sku_id] ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
//根据分区整理参与的活动--todo
|
||||
//根据活动规则计算发送券--todo
|
||||
|
||||
// foreach ($inValidParts as $inValidPart) {
|
||||
// $this->couponService->receivePartCoupon($inValidPart, $order->user);
|
||||
// }
|
||||
//根据分区获取活动
|
||||
$partActivities = ActivityProductPart::with(['activity', 'activity.gifts'])->whereHas('activity', function (Builder $query) {
|
||||
return $query->where('is_use', true)->where('started_at', '<', now())->where('ended_at', '>=', now());
|
||||
})->whereIn('part_id', array_keys($inValidParts))->get();
|
||||
//根据活动规则计算发送券
|
||||
foreach ($partActivities as $partActivity) {
|
||||
//获取活动的赠送规则
|
||||
$_giftsRule = $partActivity->activity?->gifts_rule;
|
||||
//判断是否首单:times=0为仅首单赠送, 1为不限
|
||||
if ($_giftsRule['times'] == 0 && UserCoupon::where('activity_id', $partActivity->activity_id)->exists()) {
|
||||
continue;//提前结束本次循环
|
||||
}
|
||||
//判断是否满足门槛
|
||||
if (bcdiv($_giftsRule['value'], 100) > $inValidParts[$partActivity->part_id]) {
|
||||
continue;//提前结束本次循环
|
||||
}
|
||||
//赠券
|
||||
(new CouponService())->receiveActivityCoupons($partActivity->activity, $order->user, $order->id);
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
|
|
|
|||
|
|
@ -39,11 +39,11 @@ class Activity extends Model
|
|||
|
||||
public function coupons()
|
||||
{
|
||||
return $this->belongsToMany(Coupon::class, 'activity_coupons', 'activity_id', 'coupon_id');
|
||||
return $this->belongsToMany(Coupon::class, 'activity_coupons', 'activity_id', 'coupon_id')->withPivot('qty');
|
||||
}
|
||||
|
||||
public function gifts()
|
||||
{
|
||||
return $this->belongsToMany(ProductSku::class, 'activity_gifts', 'activity_id', 'sku_id');
|
||||
return $this->belongsToMany(ProductSku::class, 'activity_gifts', 'activity_id', 'sku_id')->withPivot('qty');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,4 +12,14 @@ class ActivityProductPart extends Model
|
|||
protected $fillable = [
|
||||
'activity_id', 'part_id',
|
||||
];
|
||||
|
||||
public function part()
|
||||
{
|
||||
return $this->belongsTo(Part::class, 'part_id');
|
||||
}
|
||||
|
||||
public function activity()
|
||||
{
|
||||
return $this->belongsTo(Activity::class, 'activity_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class OrderActivityInfo extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public const TYPE_GIFT = 1;
|
||||
public const TYPE_COUPON = 2;
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ class OrderProduct extends Model
|
|||
*/
|
||||
protected $casts = [
|
||||
'specs' => 'json',
|
||||
'is_gift'=>'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -38,6 +39,8 @@ class OrderProduct extends Model
|
|||
'after_sale_state',
|
||||
'after_expire_at',
|
||||
'remain_quantity',
|
||||
'is_gift',
|
||||
'activity_id',
|
||||
];
|
||||
|
||||
public function packageProducts()
|
||||
|
|
@ -97,7 +100,7 @@ class OrderProduct extends Model
|
|||
*/
|
||||
public function isGift()
|
||||
{
|
||||
return $this->gift_for_sku_id !== null;
|
||||
return $this->gift_for_sku_id !== null || $this->is_gift == true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Coupon;
|
||||
use App\Models\ProductPart;
|
||||
use App\Models\ReceivePartCouponLog;
|
||||
|
|
@ -84,6 +85,22 @@ class CouponService
|
|||
ReceivePartCouponLog::create(['user_id'=>$user->id, 'part_id'=>$part->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据活动领取优惠券
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function receiveActivityCoupons(Activity $activity, User $user)
|
||||
{
|
||||
foreach ($activity->coupons as $coupon) {
|
||||
$someCoupons[] = [
|
||||
'coupon'=>$coupon,
|
||||
'num'=>$coupon->pivot->qty,
|
||||
];
|
||||
}
|
||||
$this->receiveSomeCoupons($user, $someCoupons, $activity->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 领取一批券
|
||||
*
|
||||
|
|
@ -91,12 +108,12 @@ class CouponService
|
|||
* @param array $coupons
|
||||
* @return void
|
||||
*/
|
||||
protected function receiveSomeCoupons(User $user, array $coupons)
|
||||
protected function receiveSomeCoupons(User $user, array $coupons, ?int $activityId = null)
|
||||
{
|
||||
$userCoupons = [];
|
||||
foreach ($coupons as $coupon) {
|
||||
for ($i=0; $i<$coupon['num']; $i++) {
|
||||
$userCoupons[] = self::createUserCouponData($user->id, $coupon['coupon']);
|
||||
for ($i = 0; $i < $coupon['num']; $i++) {
|
||||
$userCoupons[] = self::createUserCouponData($user->id, $coupon['coupon'], $activityId ?? null);
|
||||
}
|
||||
//更新对应券发送量,余量;
|
||||
$coupon['coupon']->increment('sent', $coupon['num']);
|
||||
|
|
@ -126,7 +143,7 @@ class CouponService
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function createUserCouponData(int $userId, Coupon $coupon)
|
||||
public static function createUserCouponData(int $userId, Coupon $coupon, ?int $activityId = null)
|
||||
{
|
||||
//如果userId小于等于0,直接退出
|
||||
if ($userId <= 0) {
|
||||
|
|
@ -150,6 +167,7 @@ class CouponService
|
|||
'use_end_at' => $useEndAt,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
'activity_id' => $activityId ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,16 +10,19 @@ use App\Enums\SocialiteType;
|
|||
use App\Enums\WxpayTradeType;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Exceptions\ShippingNotSupportedException;
|
||||
use App\Models\ActivityProductPart;
|
||||
use App\Models\DistributionPreIncomeJob;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderProduct;
|
||||
use App\Models\ProductGift;
|
||||
use App\Models\ProductPartSku;
|
||||
use App\Models\ProductSku;
|
||||
use App\Models\ShippingAddress;
|
||||
use App\Models\SocialiteUser;
|
||||
use App\Models\User;
|
||||
use App\Models\UserCoupon;
|
||||
use App\Services\Payment\WxpayService;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
|
|
@ -240,6 +243,7 @@ class OrderService
|
|||
|
||||
$orderProducts[] = [
|
||||
'gift_for_sku_id' => null,
|
||||
'is_gift'=> false,
|
||||
'user_id' => $order->user_id,
|
||||
'order_id' => $order->id,
|
||||
'spu_id' => $sku->spu_id,
|
||||
|
|
@ -263,35 +267,10 @@ class OrderService
|
|||
|
||||
// 扣除商品库存
|
||||
$this->deductProduct($sku, $qty);
|
||||
//根据订单参加的活动添加赠品 --todo;
|
||||
$gifts = [];
|
||||
foreach ($gifts as $gift) {
|
||||
$giftSku = $gift['sku'];
|
||||
|
||||
$orderProducts[] = [
|
||||
'gift_for_sku_id' => $sku->id,
|
||||
'user_id' => $order->user_id,
|
||||
'order_id' => $order->id,
|
||||
'spu_id' => $giftSku->spu_id,
|
||||
'sku_id' => $giftSku->id,
|
||||
'category_id' => $giftSku->category_id,
|
||||
'name' => $giftSku->name,
|
||||
'specs' => json_encode($giftSku->specs),
|
||||
'cover' => $giftSku->cover,
|
||||
'weight' => $giftSku->weight,
|
||||
'sell_price' => $giftSku->sell_price,
|
||||
'vip_price' => $giftSku->vip_price,
|
||||
'sales_value' => 0, // 赠品不算销售值
|
||||
'quantity' => $gift['num'],
|
||||
'remain_quantity' => $gift['num'], // 剩余发货数量
|
||||
'coupon_discount_amount' => 0,
|
||||
'vip_discount_amount' => 0,
|
||||
'total_amount' => 0,
|
||||
'created_at' => $order->created_at,
|
||||
'updated_at' => $order->updated_at,
|
||||
];
|
||||
}
|
||||
}
|
||||
//根据订单参加的活动添加赠品;
|
||||
$gifts = $this->activityGifts($order, $orderProducts);
|
||||
$orderProducts = array_merge($orderProducts, $gifts);
|
||||
|
||||
OrderProduct::insert($orderProducts);
|
||||
}
|
||||
|
|
@ -384,6 +363,80 @@ class OrderService
|
|||
return $gifts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param Order $order
|
||||
* @param [type] $products
|
||||
* @return array $gifts
|
||||
*/
|
||||
protected function activityGifts(Order $order, $products)
|
||||
{
|
||||
$_products = array_column($products, 'total_amount', 'sku_id');
|
||||
|
||||
$inValidParts = [];
|
||||
// 整理订单商品的分区
|
||||
$partSkus = ProductPartSku::with('part')->whereIn('sku_id', array_keys($_products))->get();
|
||||
foreach ($partSkus as $partSku) {
|
||||
if ($partSku->part?->is_show) {
|
||||
if (isset($inValidParts[$partSku->part_id])) {
|
||||
$inValidParts[$partSku->part_id] += $_products[$partSku->sku_id] ?? 0;
|
||||
} else {
|
||||
$inValidParts[$partSku->part_id] = $_products[$partSku->sku_id] ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
//根据分区获取活动
|
||||
$partActivities = ActivityProductPart::with(['activity', 'activity.gifts'])->whereHas('activity', function (Builder $query) {
|
||||
return $query->where('is_use', true)->where('started_at', '<', now())->where('ended_at', '>=', now());
|
||||
})->whereIn('part_id', array_keys($inValidParts))->get();
|
||||
|
||||
$giveGifts = [];
|
||||
foreach ($partActivities as $partActivity) {
|
||||
//获取活动的赠送规则
|
||||
$_giftsRule = $partActivity->activity?->gifts_rule;
|
||||
//判断是否首单:times=0为仅首单赠送, 1为不限
|
||||
if ($_giftsRule['times'] == 0 && OrderProduct::where('activity_id', $partActivity->activity_id)->exists()) {
|
||||
continue;//提前结束本次循环
|
||||
}
|
||||
//判断是否满足门槛
|
||||
if (bcdiv($_giftsRule['value'], 100) > $inValidParts[$partActivity->part_id]) {
|
||||
continue;//提前结束本次循环
|
||||
}
|
||||
//返回赠品
|
||||
$_gifts = $partActivity->activity->gifts;
|
||||
foreach ($_gifts as $_gift) {
|
||||
$giveGifts[] = [
|
||||
'gift_for_sku_id'=> null,
|
||||
'user_id' => $order->user_id,
|
||||
'order_id' => $order->id,
|
||||
'spu_id' => $_gift->spu_id,
|
||||
'sku_id' => $_gift->id,
|
||||
'category_id' => $_gift->category_id,
|
||||
'name' => $_gift->name,
|
||||
'specs' => json_encode($_gift->specs),
|
||||
'cover' => $_gift->cover,
|
||||
'weight' => $_gift->weight,
|
||||
'sell_price' => $_gift->sell_price,
|
||||
'vip_price' => $_gift->vip_price,
|
||||
'sales_value' => 0, // 赠品不算销售值
|
||||
'quantity' => $_gift->pivot->qty,
|
||||
'remain_quantity' => $_gift->pivot->qty, // 剩余发货数量
|
||||
'coupon_discount_amount' => 0,
|
||||
'vip_discount_amount' => 0,
|
||||
'total_amount' => 0,
|
||||
'created_at' => $order->created_at,
|
||||
'updated_at' => $order->updated_at,
|
||||
'is_gift'=> true,
|
||||
];
|
||||
// 扣除商品库存
|
||||
$this->deductProduct($_gift, $_gift->pivot->qty);
|
||||
}
|
||||
}
|
||||
|
||||
return $giveGifts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认快速下单
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddIsGiftToOrderProductsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('order_products', function (Blueprint $table) {
|
||||
//
|
||||
$table->unsignedTinyInteger('is_gift')->nullable()->default(0)->comment('是否赠品');
|
||||
$table->unsignedBigInteger('activity_id')->nullable()->comment('参与活动ID');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('order_products', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn(['is_gift', 'activity_id']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddActivityIdToUserCouponsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('user_coupons', function (Blueprint $table) {
|
||||
//
|
||||
$table->unsignedBigInteger('activity_id')->nullable()->comment('参与活动ID');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('user_coupons', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn(['activity_id']);
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue