You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aquaculture/app/Admin/Controllers/CouponCodeController.php

193 lines
8.2 KiB

<?php
namespace App\Admin\Controllers;
use App\Enums\UserSexEnum; // 用户性别枚举
use App\Enums\UserSourceEnum; // 用户来源枚举
use App\Models\CouponCode; // 优惠券兑换码模型
use App\Models\CouponTemplate; // 优惠券模板模型
use App\Models\User; // 用户模型
use App\Notifications\CouponCodeNotification; // 优惠券通知
use Carbon\Carbon; // 日期时间处理库
use Encore\Admin\Controllers\AdminController; // 管理员控制器基类
use Encore\Admin\Form; // 表单构建器
use Encore\Admin\Grid; // 网格构建器
use Encore\Admin\Show; // 展示构建器
use Illuminate\Http\Request; // 请求处理
use Illuminate\Notifications\DatabaseNotification; // 数据库通知模型
use Ramsey\Uuid\Uuid; // UUID生成库
class CouponCodeController extends AdminController
{
/**
* 当前资源的标题.
*
* @var string
*/
protected $title = '优惠券兑换码'; // 控制器标题
/**
* 创建网格构建器.
*
* @return Grid 返回网格实例
*/
protected function grid()
{
$grid = new Grid(new CouponCode); // 创建新的网格实例,基于 CouponCode 模型
$grid->model()->latest(); // 按照创建时间降序排列优惠券兑换码
// 定义网格列
$grid->column('id', __('Id')); // 显示ID
$grid->column('code', '兑换码'); // 显示兑换码
$grid->column('user_id', __('User id')); // 显示用户ID
$grid->column('template_id', '优惠券ID'); // 显示优惠券模板ID
// 关联显示用户和优惠券模板的名称
$grid->column('user.name', '会员名'); // 显示会员名称
$grid->column('template.title', '优惠券名'); // 显示优惠券名称
// 显示使用时间和通知时间
$grid->column('used_at', __('Used at')); // 显示使用时间
$grid->column('notification_at', '上一次发送通知时间'); // 显示上一次发送通知的时间
$grid->column('created_at', __('Created at')); // 显示创建时间
// 定义过滤器
$grid->filter(function (Grid\Filter $filter) {
$filter->equal('code', '兑换码'); // 兑换码过滤
$filter->like('user.name', '会员名'); // 会员名模糊查询
$filter->equal('template.title', '优惠券名'); // 优惠券名过滤
$filter->between('used_at')->datetime(); // 使用时间范围过滤
});
// 禁用编辑和查看操作
$grid->actions(function (Grid\Displayers\Actions $actions) {
$actions->disableEdit(); // 禁用编辑按钮
$actions->disableView(); // 禁用查看按钮
});
return $grid; // 返回构建好的网格
}
/**
* 存储新的优惠券兑换码.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
{
$request = request(); // 获取请求实例
/**
* 发放的优惠券不能为空
* @var $template CouponTemplate
*/
// 根据模板ID查找优惠券模板
$template = CouponTemplate::query()->findOrFail($request->input('template_id'));
$today = Carbon::today(); // 获取今天的日期
// 检查优惠券是否过期
if ($today->gt(Carbon::make($template->end_date))) {
admin_error('优惠券已过期'); // 显示错误信息
return back()->withInput(); // 返回上一个页面并保留输入
}
// 如果会员 ID 不为空,则代表是指定会员发放
if ($userIds = $request->input('user_ids')) {
// 使用空格拆分 ID
$ids = array_values(array_filter(explode(' ', $userIds))); // 过滤空值并重建索引
$users = User::query()->findMany($ids); // 查找指定的用户
} else {
// 否则则是条件范围发放
$query = User::query(); // 创建用户查询
// 获取过滤条件
$sex = array_filter($request->input('user_sex')); // 性别
$sources = array_filter($request->input('user_source')); // 会员来源
$loginCount = (int)$request->input('login_count'); // 登录次数
$scoreAll = (int)$request->input('user_score'); // 总积分
// 应用过滤条件
$query->whereIn('sex', $sex)
->whereIn('source', $sources)
->where('login_count', '>=', $loginCount)
->where('score_all', '>=', $scoreAll);
$users = $query->get(); // 获取符合条件的用户
}
// 开始根据用户发放优惠券
$now = Carbon::now()->toDateTimeString(); // 获取当前时间
$notifications = collect(); // 创建通知集合
$codes = $users->map(function (User $user) use ($template, $notifications, $now) {
$code = strtoupper(str_random(16)); // 生成随机兑换码
// 创建通知数据
$notification = [
'id' => Uuid::uuid4()->toString(), // 生成唯一ID
'type' => CouponCodeNotification::class, // 通知类型
'notifiable_id' => $user->id, // 可通知的用户ID
'notifiable_type' => get_class($user), // 用户类型
'data' => json_encode((new CouponCodeNotification($template, $code))->toArray($user), JSON_UNESCAPED_UNICODE), // 通知数据
'created_at' => $now, // 创建时间
'updated_at' => $now, // 更新时间
];
$notifications->push($notification); // 将通知添加到集合
return [
'code' => $code, // 兑换码
'user_id' => $user->id, // 用户ID
'template_id' => $template->id, // 模板ID
'notification_at' => $now, // 通知时间
'created_at' => $now, // 创建时间
'updated_at' => $now, // 更新时间
];
});
$size = 1000; // 每次插入的数量
foreach (array_chunk($codes->all(), $size, true) as $chunk) {
// 批量插入优惠券码
CouponCode::query()->insert($chunk);
}
foreach (array_chunk($notifications->all(), $size, true) as $chunk) {
// 批量插入通知
DatabaseNotification::query()->insert($chunk);
}
admin_toastr("发布成功,总共有{$users->count()}位会员符合发放条件"); // 显示成功提示
return response()->redirectTo(admin_url('/coupon_codes')); // 重定向到优惠券兑换码列表
}
/**
* 创建表单构建器.
*
* @return Form 返回表单实例
*/
protected function form()
{
$form = new Form(new CouponCode); // 创建新的表单实例,基于 CouponCode 模型
$today = Carbon::today()->toDateString(); // 获取今天的日期
$form->divider('指定会员发放'); // 分隔符
$form->text('user_ids', '会员')->help('请输入会员的ID, 多个会员用空格隔开,如果为空则代表是范围发放'); // 会员ID输入框
$form->divider('范围发放'); // 分隔符
// 获取有效的优惠券模板
$templates = CouponTemplate::query()->where('end_date', '>=', $today)->pluck('title', 'id');
$form->checkbox('user_sex', '会员性别')->options([UserSexEnum::MAN => '男', UserSexEnum::WOMAN => '女'])->canCheckAll(); // 性别选择框
$form->checkbox('user_source', '会员来源')->options([
UserSourceEnum::MOON => '前台注册',
UserSourceEnum::GITHUB => 'Github',
UserSourceEnum::QQ => 'QQ',
UserSourceEnum::WEIBO => '微博',
])->canCheckAll(); // 来源选择框
$form->number('login_count', '会员登录次数')->default(0)->help('会员登录次数大于等于给定的次数'); // 登录次数输入框
$form->number('user_score', '会员总积分')->default(0)->help('会员给定的积分大于等于总积分'); // 总积分输入框
$form->divider('优惠券'); // 分隔符
$form->select('template_id', '优惠券')->help('发放的优惠券')->options($templates)->required(); // 优惠券选择框
return $form; // 返回构建好的表单
}
}