添加后台配置发送优惠券任务
parent
c6e4e5a639
commit
6787f9b249
|
|
@ -113,7 +113,7 @@ class AdController extends AdminController
|
|||
])->default(0);
|
||||
$form->text('jump_link');
|
||||
$form->switch('is_show');
|
||||
$form->number('sort')->default(0);
|
||||
$form->number('sort')->min(0)->default(0);
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class ArticleCategoryController extends AdminController
|
|||
$form->text('name')->required();
|
||||
$form->switch('is_show');
|
||||
$form->switch('is_recommend');
|
||||
$form->number('sort')->default(0);
|
||||
$form->number('sort')->min(0)->default(0);
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class ArticleController extends AdminController
|
|||
$form->text('jump_link');
|
||||
$form->switch('is_show');
|
||||
$form->switch('is_recommend');
|
||||
$form->number('sort')->default(0);
|
||||
$form->number('sort')->min(0)->default(0);
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Admin\Controllers;
|
|||
|
||||
use App\Admin\Renderable\CouponRangeTable;
|
||||
use App\Admin\Repositories\Coupon;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\Coupon as CouponModel;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
|
|
@ -103,7 +104,12 @@ class CouponController extends AdminController
|
|||
{
|
||||
return Form::make(new Coupon(), function (Form $form) {
|
||||
$form->display('id');
|
||||
|
||||
$form->text('name')->required();
|
||||
$form->number('limit')->min(0)->default(0)->help('0为不限量');
|
||||
|
||||
if ($form->isEditing()) {
|
||||
if (!$form->model()->hasReceived()) {
|
||||
$form->radio('type')
|
||||
->when(1, function (Form $form) {
|
||||
$form->currency('amount1')->symbol('¥')->help('例:100.00表示优惠100元。')->value($form->model()->amount);
|
||||
|
|
@ -115,19 +121,43 @@ class CouponController extends AdminController
|
|||
1 =>'抵扣券',
|
||||
2 =>'折扣券',
|
||||
])->default(1);
|
||||
|
||||
$form->currency('threshold')->symbol('¥')->default(0);
|
||||
$form->number('limit')->default(0);
|
||||
$form->number('use_day')->default(0)->help('单位:天;指领取后几天内有效。');
|
||||
$form->datetimeRange('use_start_at', 'use_end_at', '使用时间')->help('设置时间后,期限字段失效。');
|
||||
$form->hidden('amount');
|
||||
|
||||
$form->currency('threshold')->symbol('¥')->default(0);
|
||||
$form->number('use_day')->min(0)->default(1)->help('单位:天;指领取后几天内有效。');
|
||||
$form->datetimeRange('use_start_at', 'use_end_at', '使用时间')->help('设置时间后,期限字段失效。');
|
||||
}
|
||||
}
|
||||
|
||||
// $form->editing(function (Form $form) {
|
||||
// if (!$form->model()->hasReceived()) {
|
||||
// $form->radio('type')
|
||||
// ->when(1, function (Form $form) {
|
||||
// $form->currency('amount1')->symbol('¥')->help('例:100.00表示优惠100元。')->value($form->model()->amount);
|
||||
// })
|
||||
// ->when(2, function (Form $form) {
|
||||
// $form->currency('amount2')->symbol('%')->help('例:0.95表示95折。')->value($form->model()->amount);
|
||||
// })
|
||||
// ->options([
|
||||
// 1 =>'抵扣券',
|
||||
// 2 =>'折扣券',
|
||||
// ])->default(1);
|
||||
// $form->hidden('amount');
|
||||
|
||||
// $form->currency('threshold')->symbol('¥')->default(0);
|
||||
// $form->number('use_day')->default(0)->help('单位:天;指领取后几天内有效。');
|
||||
// $form->datetimeRange('use_start_at', 'use_end_at', '使用时间')->help('设置时间后,期限字段失效。');
|
||||
// }
|
||||
// });
|
||||
|
||||
$form->saving(function (Form $form) {
|
||||
if ($form->type) {
|
||||
$amount = 'amount'.$form->type;
|
||||
$form->amount = $form->$amount;
|
||||
|
||||
$form->deleteInput('amount1');
|
||||
$form->deleteInput('amount2');
|
||||
}
|
||||
});
|
||||
|
||||
$form->display('created_at');
|
||||
|
|
@ -135,6 +165,21 @@ class CouponController extends AdminController
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改删除判断
|
||||
*
|
||||
* @param [type] $id
|
||||
* @return void
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$coupon = CouponModel::findOrFail($id);
|
||||
if ($coupon->hasSendTask() || $coupon->hasReceived()) {
|
||||
throw new BizException(__('coupon.options.deny_message'));
|
||||
}
|
||||
return parent::destroy($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取优惠券接口
|
||||
*
|
||||
|
|
|
|||
|
|
@ -65,6 +65,13 @@ class CouponSendTaskController extends AdminController
|
|||
if (Admin::user()->can('dcat.admin.coupon_send_tasks.start')) {
|
||||
$actions->append(new CouponTaskStart());
|
||||
}
|
||||
} else {
|
||||
$actions->disableQuickEdit();
|
||||
if (Admin::user()->can('dcat.admin.coupon_task_logs.index')) {
|
||||
$actions->append('<a href="'.admin_route('coupon_task_logs.index', ['task_id' =>$actions->row->id]).'">
|
||||
<i class="feather icon-list grid-action-icon"></i> '.__('admin.list').
|
||||
'</a>');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -114,7 +121,7 @@ class CouponSendTaskController extends AdminController
|
|||
return [$coupon->id => $coupon->name];
|
||||
}
|
||||
})->ajax(admin_route('api.coupons'));
|
||||
$form->number('num')->default(1);
|
||||
$form->number('num')->min(1)->default(1);
|
||||
$form->radio('type')->options([
|
||||
1=>'指定用户',
|
||||
])->when(1, function (Form $form) {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Repositories\CouponTaskLog;
|
||||
use App\Models\CouponSendTask;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
|
||||
class CouponTaskLogController extends AdminController
|
||||
{
|
||||
|
|
@ -35,12 +37,18 @@ class CouponTaskLogController extends AdminController
|
|||
2=>'success',
|
||||
3=>'danger',
|
||||
]);
|
||||
$grid->column('remarks');
|
||||
$grid->column('created_at');
|
||||
$grid->column('updated_at')->sortable();
|
||||
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel(false);
|
||||
$filter->equal('task_id')->select()->ajax(admin_route('api.coupon_send_tasks'))->width(3);
|
||||
$filter->equal('task_id')->select(function () {
|
||||
$taskId = Request::get('task_id');
|
||||
return CouponSendTask::where('id', $taskId)->pluck('name', 'id');
|
||||
})->ajax(admin_route('api.coupon_send_tasks'))->width(3);
|
||||
$filter->equal('coupon_id')->select()->ajax(admin_route('api.coupons'))->width(3);
|
||||
$filter->like('user.phone')->width(3);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class ProductCategoryController extends AdminController
|
|||
->autoUpload();
|
||||
$form->switch('is_show');
|
||||
$form->switch('is_recommend');
|
||||
$form->number('sort')->default(0);
|
||||
$form->number('sort')->min(0)->default(0);
|
||||
$form->saving(function (Form $form) {
|
||||
//只能添加到三级分类
|
||||
if ($form->parent_id) {
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ class ProductSkuController extends AdminController
|
|||
->autoUpload();
|
||||
$form->editor('description');
|
||||
$form->select('buynote_id')->options(ProductBuynote::all()->pluck('name', 'id'));
|
||||
$form->number('weight');
|
||||
$form->number('stock');
|
||||
$form->number('weight')->min(0)->default(0);
|
||||
$form->number('stock')->min(0)->default(0);
|
||||
$form->divider();
|
||||
$form->currency('sell_price')->symbol('¥')->default(0);
|
||||
$form->currency('market_price')->symbol('¥')->default(0);
|
||||
|
|
|
|||
|
|
@ -142,9 +142,9 @@ class ProductSpuController extends AdminController
|
|||
});
|
||||
$form->editor('description');
|
||||
$form->select('buynote_id')->options(ProductBuynote::all()->pluck('name', 'id'));
|
||||
$form->number('weight');
|
||||
$form->number('weight')->min(0)->default(0);
|
||||
$form->select('shipping_template_id')->options(ShippingTemplate::all()->pluck('name', 'id'))->required();
|
||||
$form->number('stock');
|
||||
$form->number('stock')->min(0)->default(0);
|
||||
$form->divider();
|
||||
$form->currency('sell_price')->symbol('¥')->default(0);
|
||||
$form->currency('market_price')->symbol('¥')->default(0);
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ class ShippingRuleController extends AdminController
|
|||
})
|
||||
->when(2, function (Form $form) {
|
||||
$form->embeds('info2', function ($form) {
|
||||
$form->number('first_weight')->rules('required_if:type,2')->default(2);
|
||||
$form->number('first_weight')->min(1)->rules('required_if:type,2')->default(2);
|
||||
$form->currency('first_w_amount')->rules('required_if:type,2')->symbol('¥');
|
||||
$form->number('continue_weight')->rules('required_if:type,2')->default(1);
|
||||
$form->number('continue_weight')->min(1)->rules('required_if:type,2')->default(1);
|
||||
$form->currency('continue_w_amount')->rules('required_if:type,2')->symbol('¥');
|
||||
})->customFormat(function () {
|
||||
if ($this->model()->type == '2') {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class VipController extends AdminController
|
|||
return Form::make(new Vip(), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->text('name')->required();
|
||||
$form->number('growth_value')->default(0);
|
||||
$form->number('growth_value')->min(0)->default(0);
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ class SkuGift extends Form implements LazyRenderable
|
|||
return [$sku->id => $sku->name];
|
||||
}
|
||||
})->ajax(admin_route('api.product_skus'))->required();
|
||||
$form->number('num')->default(1);
|
||||
$form->number('limit')->default(0);
|
||||
$form->number('num')->min(1)->default(1);
|
||||
$form->number('limit')->min(0)->default(0);
|
||||
})->customFormat(function () use ($sku) {
|
||||
return $sku->gifts;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Coupon;
|
||||
use App\Models\CouponSendTask;
|
||||
use App\Models\CouponTaskLog;
|
||||
use App\Models\UserCoupon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class AdminSendCoupon extends Command
|
||||
{
|
||||
/**
|
||||
* 单次最大条数
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $limit = 100;
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'admin-work:send-coupon';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '后台执行优惠券发放任务';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
//获取需要执行的任务数据包
|
||||
$logs = CouponTaskLog::where('status', '0')->where('num', '>', 0)->orderBy('id')->limit($this->limit)->get();
|
||||
$logs = $logs->groupBy('task_id');
|
||||
foreach ($logs as $taskId => $taskLogs) {
|
||||
$nowTime = now();
|
||||
$task = CouponSendTask::find($taskId);
|
||||
$coupon = Coupon::find($task->coupon_id);
|
||||
//如果优惠券限量,则获取优惠券余量,只发送前面的人;
|
||||
$failedLogs = collect([]);
|
||||
if ($coupon->limit > 0 && $coupon->stock < ($taskLogs->count() * $task->num)) {
|
||||
$failedLogs = $taskLogs->slice($coupon->stock);
|
||||
$taskLogs = $taskLogs->slice(0, $coupon->stock);
|
||||
}
|
||||
if ($coupon->use_start_at && $coupon->use_end_at) {
|
||||
$useStartAt = $coupon->use_start_at;
|
||||
$useEndAt = $coupon->use_end_at;
|
||||
} else {
|
||||
$useStartAt = now();
|
||||
$useEndAt = now()->addDays($coupon->use_day);
|
||||
}
|
||||
|
||||
//批量插入用户优惠券
|
||||
$insertUserCoupons = [];
|
||||
foreach ($taskLogs as $taskLog) {
|
||||
for ($i=0; $i< $taskLog->num; $i++) {
|
||||
$insertUserCoupons[] = [
|
||||
'user_id' => $taskLog->user_id,
|
||||
'coupon_id' => $taskLog->coupon_id,
|
||||
'coupon_name' => $coupon->name,
|
||||
'coupon_type' => $coupon->type,
|
||||
'coupon_amount' => (int) bcmul($coupon->amount, 100),
|
||||
'coupon_threshold'=> (int) bcmul($coupon->threshold, 100),
|
||||
'use_start_at' => $useStartAt,
|
||||
'use_end_at' => $useEndAt,
|
||||
'status' => 0,
|
||||
'created_at' => $nowTime,
|
||||
'updated_at' => $nowTime,
|
||||
];
|
||||
}
|
||||
}
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
count($insertUserCoupons) > 0 && UserCoupon::insert($insertUserCoupons);
|
||||
//更新任务日志状态;
|
||||
CouponTaskLog::whereIn('id', $taskLogs->pluck('id')->toArray())->update(['status'=>2]);
|
||||
$failedLogs->count() == 0 || CouponTaskLog::whereIn('id', $failedLogs->pluck('id')->toArray())->update(['status'=>3, 'remarks'=>'库存余量不足']);
|
||||
//更新任务对应券发送量,余量;
|
||||
$coupon->increment('sent', $taskLogs->count());
|
||||
if ($coupon->limit > 0) {//限量才减少余量
|
||||
$coupon->decrement('stock', $taskLogs->count());
|
||||
}
|
||||
|
||||
//更新如果是任务最后一批,更新任务状态;
|
||||
$taskTotalnum = CouponTaskLog::where('task_id', $taskId)->where('num', '>', 0)->count();
|
||||
$taskDidnum = CouponTaskLog::where('task_id', $taskId)->where('num', '>', 0)->where('status', '>', 0)->count();
|
||||
if ($taskTotalnum == $taskDidnum) {
|
||||
$task->update(['status' => 3]);
|
||||
}
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
}
|
||||
}
|
||||
$this->info('执行成功');
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,4 +26,37 @@ class Coupon extends Model
|
|||
{
|
||||
return $this->hasMany(CouponRange::class, 'coupon_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 优惠券的发放任务
|
||||
*/
|
||||
public function sendTask()
|
||||
{
|
||||
return $this->hasMany(CouponSendTask::class, 'coupon_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 该优惠券下是否有发放任务
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSendTask(): bool
|
||||
{
|
||||
return $this->sendTask()->exists();
|
||||
}
|
||||
|
||||
public function receiveLog()
|
||||
{
|
||||
return $this->hasMany(UserCoupon::class, 'coupon_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否被领取过
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasReceived()
|
||||
{
|
||||
return $this->receiveLog()->exists();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ class CouponSendTask extends Model
|
|||
// 'value'=>JsonArray::class,
|
||||
// ];
|
||||
|
||||
protected $fillable = [
|
||||
'status',
|
||||
];
|
||||
|
||||
public function coupon()
|
||||
{
|
||||
return $this->belongsTo(Coupon::class, 'coupon_id');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ class CouponTaskLog extends Model
|
|||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
protected $fillable = [
|
||||
'status',
|
||||
'remarks',
|
||||
];
|
||||
|
||||
/**
|
||||
* 此记录发放的券
|
||||
*
|
||||
|
|
|
|||
|
|
@ -8,4 +8,18 @@ use Illuminate\Database\Eloquent\Model;
|
|||
class UserCoupon extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'coupon_id',
|
||||
'coupon_name',
|
||||
'coupon_type',
|
||||
'coupon_amount',
|
||||
'coupon_threshold',
|
||||
'use_start_at',
|
||||
'use_end_at',
|
||||
'status',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddRemarksToCouponTaskLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('coupon_task_logs', function (Blueprint $table) {
|
||||
//
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('coupon_task_logs', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn('remarks');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddCouponAmountToUserCouponsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('user_coupons', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn('coupon_value');
|
||||
$table->unsignedInteger('coupon_amount')->default(0)->comment('抵扣金额:分/折扣(100)');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('user_coupons', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ return [
|
|||
'user_id' => '用户',
|
||||
'num' => '张数',
|
||||
'status' => '状态',
|
||||
'remarks'=> '备注',
|
||||
'task'=>[
|
||||
'name' => '任务名称',
|
||||
],
|
||||
|
|
|
|||
|
|
@ -23,5 +23,6 @@ return [
|
|||
'ranges'=>'范围',
|
||||
],
|
||||
'options' => [
|
||||
'deny_message' => '该优惠已被领取或者已配置发送任务',
|
||||
],
|
||||
];
|
||||
|
|
|
|||
Loading…
Reference in New Issue