master
lion 1 month ago
commit b0947a4f34

@ -44,9 +44,12 @@ class PushCourses extends Command
public function handle()
{
$today = date('Y-m-d');
$courses = Course::where('sign_end_date', $today)->whereHas('typeDetail', function ($query) {
$courses = Course::whereHas('typeDetail', function ($query) {
$query->where('is_push', 1);
})->get();
})
->where('sign_end_date', $today)
->where('is_push', 1)
->get();
if ($courses->isEmpty()) {
$this->info('没有可推送的课程');
return;
@ -55,13 +58,17 @@ class PushCourses extends Command
foreach ($courses as $course) {
// 所有报名审核成功的用户id
$userIds = $course->courseSigns()->where('status', 1)->pluck('user_id');
$users = User::whereIn('id', $userIds)->whereNotNull('company_id')->get();
$users = User::whereIn('id', $userIds)->whereHas('company', function ($query) {
$query->whereNotNull('credit_code');
})->groupBy('company_id')->get();
foreach ($users as $user) {
$result = $YuanheRepository->pushCourses($course, $user);
$result = $YuanheRepository->pushCourses($course, $user, $out);
if ($result) {
$user->is_push = 1;
$user->save();
$this->info("推送成功:{$course->name}-{$user->name}");
} else {
$this->info("推送失败:{$course->name}-{$user->name}");
$this->info("推送失败:{$course->name}-{$user->name}-{$out}");
}
}
}

@ -0,0 +1,59 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
class TestEmailCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'test:email';
/**
* The console command description.
*
* @var string
*/
protected $description = '测试邮件发送功能是否正常';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
// 写死的收件人地址
$to = 'tanyuan@langye.net';
$subject = '系统测试邮件';
$content = '这是一封测试邮件,用于验证邮件发送功能是否正常工作。';
$this->info("开始测试邮件发送功能...");
$this->info("收件人: {$to}");
$this->info("主题: {$subject}");
try {
// 使用 Laravel 的 Mail 门面发送邮件
Mail::raw($content, function ($message) use ($to, $subject) {
$message->to($to)->subject($subject);
});
$this->info("✅ 邮件发送成功!");
$this->info("邮件已记录到日志文件中,请检查 storage/logs/laravel.log");
return Command::SUCCESS;
} catch (\Exception $e) {
$this->error("❌ 邮件发送失败!");
$this->error("错误信息: " . $e->getMessage());
return Command::FAILURE;
}
}
}

@ -0,0 +1,64 @@
<?php
namespace App\Console\Commands;
use App\Jobs\SendCourseDoor;
use App\Models\Course;
use App\Models\CourseSign;
use App\Models\User;
use App\Notifications\AuditNotify;
use App\Notifications\BirthdayNotify;
use App\Repositories\MeetRepository;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Notification;
class UpdateCourseSignDoor extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'update_course_sign_door';
/**
* 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 mixed
*/
public function handle()
{
$courses = Course::where('status', 1)
->whereIn('id', [97, 99])
->get();
foreach ($courses as $course) {
$courseSigns = CourseSign::where('course_id', $course->id)->where('status', 1)->get();
foreach ($courseSigns as $courseSign) {
dispatch((new SendCourseDoor($courseSign)));
$this->info('更新学员' . $courseSign->user->name . '的门禁权限');
}
}
return $this->info('更新完成');
}
}

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Admin;
use App\Exports\BaseExport;
use App\Exports\CommonExport;
use App\Helpers\ResponseCode;
use App\Models\AppointmentType;
use App\Models\Book;
@ -35,6 +36,9 @@ class CalendarsController extends BaseController
* tags={"日历管理"},
* summary="列表",
* description="",
* @OA\Parameter(name="is_export", in="query", @OA\Schema(type="string"), required=false, description="是否导出0否1是"),
* @OA\Parameter(name="export_fields", in="query", @OA\Schema(type="string"), required=false, description="需要导出的字段数组"),
* @OA\Parameter(name="file_name", in="query", @OA\Schema(type="string"), required=false, description="导出文件名"),
* @OA\Parameter(name="month", in="query", @OA\Schema(type="string"), required=true, description="月份"),
* @OA\Response(
* response="200",
@ -55,6 +59,10 @@ class CalendarsController extends BaseController
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$list = Calendar::with('course', 'courseContent')->where('start_time', 'like', $all['month'] . '%')->orderBy('date')->get();
if (isset($all['is_export']) && $all['is_export'] == 1) {
$list = $list->toArray();
return Excel::download(new CommonExport($list, $all['export_fields'] ?? ''), ($all['file_name'] ?? '') . date('YmdHis') . '.xlsx');
}
return $this->success($list);
}

@ -7,7 +7,6 @@ use App\Helpers\ResponseCode;
use App\Helpers\StarterResponseCode;
use App\Jobs\SendCourseCar;
use App\Jobs\SendCourseDoor;
use App\Models\AppointmentTotalLog;
use App\Models\Course;
use App\Models\CourseAppointmentTotal;
use App\Models\CourseForm;
@ -451,7 +450,7 @@ class CourseSignController extends BaseController
$list[$key]['status'] = 0;
$list[$key]['status_name'] = '待审核';
}
$list[$key] = array_merge($list[$key], ['course_id' => $course_id, 'from' => '跟班学员']);
$list[$key] = array_merge($list[$key], ['course_id' => $course_id]);
}
return $this->success($list);
}
@ -731,7 +730,7 @@ class CourseSignController extends BaseController
if (empty($model)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']);
}
$model = $this->model->witg('course')->find($all['id']);
$model = $this->model->with('course')->find($all['id']);
$course = $model->course;
// 执行预约
// 执行预约操作

@ -303,10 +303,9 @@ class OtherController extends CommonController
public function test()
{
$model = Appointment::find(293);
// 取消预约
dispatch((new CancelAppointMeet($model, 'a0f75f36213a48f59ce860e679a77c5b')));
$model = new DoorRepository();
$result = $model->getAllDoorInfo();
dd(json_encode($result,JSON_UNESCAPED_UNICODE));
}

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Admin;
use App\Exports\BaseExport;
use App\Exports\CommonExport;
use App\Helpers\ResponseCode;
use App\Models\CustomForm;
use App\Models\CustomFormField;
@ -38,6 +39,7 @@ class TeacherController extends BaseController
* @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"),
* @OA\Parameter(name="theme", in="query", @OA\Schema(type="string"), required=false, description="主题"),
* @OA\Parameter(name="direction", in="query", @OA\Schema(type="string"), required=false, description="方向"),
* @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=true, description="搜索关键词"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
@ -108,24 +110,69 @@ class TeacherController extends BaseController
}
}
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc');
// 应用与列表一致的筛选
if (isset($all['theme']) || isset($all['direction'])) {
$list = $list->whereHas('courseContents', function ($query) use ($all) {
if (isset($all['theme'])) {
$query->where('theme', $all['theme']);
}
if (isset($all['direction'])) {
$query->where('direction', $all['direction']);
}
});
}
if (isset($all['keyword'])) {
$list = $list->where(function ($query) use ($all) {
$query->whereHas('courseContents', function ($query) use ($all) {
$query->where('direction', 'like', '%' . $all['keyword'] . '%');
})->orWhere('name', 'like', '%' . $all['keyword'] . '%');
});
}
if (isset($all['is_export']) && !empty($all['is_export'])) {
$list = $list->get()->toArray();
$export_fields = $all['export_fields'] ?? [];
// 导出文件名字
$tableName = $this->model->getTable();
$filename = (new CustomForm())->getTableComment($tableName);
return Excel::download(new BaseExport($export_fields, $list, $tableName), $filename . date('YmdHis') . '.xlsx');
} else {
if (isset($all['theme']) || isset($all['direction'])) {
$list = $list->whereHas('courseContents', function ($query) use ($all) {
if (isset($all['theme'])) {
$query->where('theme', $all['theme']);
}
if (isset($all['direction'])) {
$query->where('direction', $all['direction']);
// 导出
// 取数并展开为“老师 x 课程”的多行
$teachers = $list->limit(5000)->get();
$rows = [];
foreach ($teachers as $teacher) {
$hasCourses = $teacher->courseContents && $teacher->courseContents->count() > 0;
if ($hasCourses) {
foreach ($teacher->courseContents as $content) {
$rows[] = [
'teacher_name' => $teacher->name ?? '',
'introduce' => $teacher->introduce ?? '',
'sex' => $teacher->sex ?? '',
'mobile' => $teacher->mobile ?? '',
'course_name' => optional($content->course)->name ?? '',
'theme' => $content->theme ?? '',
'direction' => $content->direction ?? '',
];
}
});
} else {
// 无课程时也导出一行,课程相关列留空
$rows[] = [
'teacher_name' => $teacher->name ?? '',
'introduce' => $teacher->introduce ?? '',
'sex' => $teacher->sex ?? '',
'mobile' => $teacher->mobile ?? '',
'course_name' => '',
'theme' => '',
'direction' => '',
];
}
}
// 列映射与顺序
$exportFields = [
'teacher_name' => '授课老师',
'introduce' => '老师简介',
'sex' => '性别',
'mobile' => '联系方式',
'course_name' => '课程名称',
'theme' => '课程主题',
'direction' => '课程方向',
];
$fileName = ($all['file_name'] ?? '老师课程_') . date('YmdHis') . '.xlsx';
return Excel::download(new CommonExport($rows, $exportFields), $fileName);
} else {
// 输出
$list = $list->paginate($all['page_size'] ?? 20);
}

@ -804,9 +804,9 @@ class CourseController extends CommonController
$list = $list->orderBy('letter')->paginate(20);
}
// 获取当前用户参与报名
$userCourseSigns = CourseSign::where('user_id',$this->getUserId())->where('status', 1)->get();
$userCourseSigns = CourseSign::where('user_id', $this->getUserId())->where('status', 1)->get();
// 获取当前用户允许的课程体系
$open_course_types = explode(',', $this->getUser()->open_course_types);
$coursesTypeIds = Course::whereIn('id', $userCourseSigns->pluck('course_id'))->pluck('type')->toArray();
foreach ($list as $user) {
$user->open_mobile = false;
@ -819,7 +819,8 @@ class CourseController extends CommonController
continue;
}
// 获取用户的课程体系
$coursesTypeIds = Course::whereIn('id', $userCourseSigns->pluck('course_id'))->pluck('type')->toArray();
// 获取当前用户允许的课程体系,数组
$open_course_types = explode(',', $user->open_course_types);
// 判断当前用户和$user课程体系是否存在交集
if (count(array_intersect($coursesTypeIds, $open_course_types)) > 0) {
$user->open_mobile = true;

@ -16,6 +16,7 @@ use App\Models\CourseSign;
use App\Models\RelatedModel;
use App\Models\ScoreLog;
use App\Models\ThirdAppointmentLog;
use App\Models\Sms;
use App\Models\User;
use App\Repositories\DoorRepository;
use App\Repositories\YuanheRepository;
@ -163,7 +164,7 @@ class UserController extends CommonController
*/
public function updateUser()
{
$all = \request()->all();
$all = \request()->except(['id','mobile','openid']);
$model = User::find($this->getUserId());
if (isset($all['password'])) {
// 判断旧密码是否正确
@ -202,7 +203,8 @@ class UserController extends CommonController
->where('plate', $plate)
->where('plate_status', 1)
->first();
if ($has) continue;
if ($has)
continue;
// 车辆预约
dispatch((new SendAppointCar($appointment, $plate)));
}
@ -226,11 +228,15 @@ class UserController extends CommonController
public function getUserInfo()
{
$user = User::with('appointments')
->withCount(['appointments as pass_appointments' => function ($query) {
$query->whereIn('status', [0, 1]);
}])->with(['courseSigns' => function ($query) {
$query->whereHas('course')->with('course.typeDetail')->where('status', 1)->where('fee_status', 1);
}])->find($this->getUserId());
->withCount([
'appointments as pass_appointments' => function ($query) {
$query->whereIn('status', [0, 1]);
}
])->with([
'courseSigns' => function ($query) {
$query->whereHas('course')->with('course.typeDetail')->where('status', 1)->where('fee_status', 1);
}
])->find($this->getUserId());
$doorRepository = new DoorRepository();
$door_appointments = Appointment::where('user_id', $this->getUserId())
@ -249,7 +255,6 @@ class UserController extends CommonController
})->first();
if ($course_signs) {
$course_signs->qrcode = $doorRepository->getEmpQrCodeByCourse($course_signs, $out);
$course_signs->qrcode = '';
}
// 是否有资格进入校友库
$enter_schoolmate = User::whereHas('courseSigns', function ($query) {
@ -325,6 +330,14 @@ class UserController extends CommonController
public function bindMobile()
{
$all = \request()->all();
$clientIp = request()->ip();
// 检查IP锁定状态
$lockCheck = Sms::checkIpLock($clientIp, 'bind_mobile');
if ($lockCheck['locked']) {
return $this->fail([ResponseCode::ERROR_BUSINESS, $lockCheck['message']]);
}
$messages = [
'mobile.required' => '手机号必填',
'mobile.numeric' => '手机号格式错误',
@ -339,15 +352,29 @@ class UserController extends CommonController
if ($validator->fails()) {
return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$key = 'sms_' . $all['mobile'];
$check = Cache::get($key);
if (empty($check)) return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
if ($check['code'] != $all['code']) return $this->fail([ResponseCode::ERROR_BUSINESS, '验证码错误']);
if (empty($check)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
}
if ($check['code'] != $all['code']) {
$errorResult = Sms::recordError($clientIp, 'bind_mobile');
return $this->fail([ResponseCode::ERROR_BUSINESS, $errorResult['message']]);
}
// 验证码正确,清除错误计数
Sms::clearError($clientIp, 'bind_mobile');
// 删除验证码缓存
Cache::forget($key);
// 判断手机号是否存在
$hasMobile = User::where('mobile', $all['mobile'])->where('id', '!=', $this->getUserId())->first();
if ($hasMobile) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '手机号已存在']);
}
$model = User::find($this->getUserId());
if ($all['is_bind']) {
$model->mobile = $all['mobile'];
@ -374,6 +401,14 @@ class UserController extends CommonController
public function checkMobile()
{
$all = \request()->all();
$clientIp = request()->ip();
// 检查IP锁定状态
$lockCheck = Sms::checkIpLock($clientIp, 'check_mobile');
if ($lockCheck['locked']) {
return $this->fail([ResponseCode::ERROR_BUSINESS, $lockCheck['message']]);
}
$messages = [
'mobile.required' => '手机号必填',
'mobile.numeric' => '手机号格式错误',
@ -386,10 +421,24 @@ class UserController extends CommonController
if ($validator->fails()) {
return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$key = 'sms_' . $all['mobile'];
$check = Cache::get($key);
if (empty($check)) return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
if ($check['code'] != $all['code']) return $this->fail([ResponseCode::ERROR_BUSINESS, '验证码错误']);
if (empty($check)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
}
if ($check['code'] != $all['code']) {
$errorResult = Sms::recordError($clientIp, 'check_mobile');
return $this->fail([ResponseCode::ERROR_BUSINESS, $errorResult['message']]);
}
// 验证码正确,清除错误计数
Sms::clearError($clientIp, 'check_mobile');
// 删除验证码缓存
Cache::forget($key);
// 判断手机号是否存在
$hasMobile = User::where('mobile', $all['mobile'])->first();
if ($hasMobile) {
@ -444,7 +493,7 @@ class UserController extends CommonController
if (isset($check) && time() - $check['time'] <= 60) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请勿频繁发送']);
}
$code = rand(1000, 9999);
$code = rand(100000, 999999);
$smsSign = Config::getValueByKey('sms_sign');
$content = "{$smsSign}您的验证码是:{$code},验证码五分钟内有效,如非本人操作,请忽略。";
$result = ymSms($all['mobile'], $content);
@ -541,6 +590,14 @@ class UserController extends CommonController
public function mobileLogin()
{
$all = \request()->all();
$clientIp = request()->ip();
// 检查IP锁定状态
$lockCheck = Sms::checkIpLock($clientIp, 'mobile_login');
if ($lockCheck['locked']) {
return $this->fail([ResponseCode::ERROR_BUSINESS, $lockCheck['message']]);
}
$messages = [
'code.required' => 'code必填',
'mobile.required' => '手机号必填'
@ -552,10 +609,24 @@ class UserController extends CommonController
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$key = 'sms_login_' . $all['mobile'];
$check = Cache::get($key);
if (empty($check)) return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
if ($check['code'] != $all['code']) return $this->fail([ResponseCode::ERROR_BUSINESS, '验证码错误']);
if (empty($check)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
}
if ($check['code'] != $all['code']) {
$errorResult = Sms::recordError($clientIp, 'mobile_login');
return $this->fail([ResponseCode::ERROR_BUSINESS, $errorResult['message']]);
}
// 验证码正确,清除错误计数
Sms::clearError($clientIp, 'mobile_login');
// 删除验证码缓存
Cache::forget($key);
$user = User::where('mobile', $all['mobile'])->first();
$token = $user->createToken("mobile-token")->plainTextToken;
return $this->success(compact('token'));
@ -621,7 +692,7 @@ class UserController extends CommonController
if (isset($check) && time() - $check['time'] <= 60) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请勿频繁发送']);
}
$code = rand(1000, 9999);
$code = rand(100000, 999999);
$smsSign = Config::getValueByKey('sms_sign');
$content = "{$smsSign}您的验证码是:{$code},验证码五分钟内有效,如非本人操作,请忽略。";
$result = ymSms($all['mobile'], $content);

@ -38,8 +38,11 @@ class SendCourseDoor implements ShouldQueue
*/
public function handle()
{
$door = Config::getValueByKey('course_sign_door');
$doors = Config::getValueByKey('course_sign_door');
$doors = json_decode($doors, true);
$doorRepository = new DoorRepository();
$doorRepository->generateEmpAuthorSet1ByCourse($this->courseSignsModel, $door, $out);
foreach ($doors as $door) {
$doorRepository->generateEmpAuthorSet1ByCourse($this->courseSignsModel, $door, $out);
}
}
}

@ -9,6 +9,19 @@ use Illuminate\Support\Facades\Cache;
class Calendar extends SoftDeletesModel
{
protected $appends = ['is_publish_text','type_text'];
public function getIsPublishTextAttribute()
{
return $this->attributes['is_publish'] == 1 ? '是' : '否';
}
public function getTypeTextAttribute()
{
$array = [1=>'课程', 3=>'自定义事件', 4=>'资讯'];
return $array[$this->attributes['type']] ?? '';
}
public function course()
{
return $this->hasOne(Course::class, 'id', 'course_id');

@ -1,15 +1,76 @@
<?php
namespace App\Models;
use Illuminate\Support\Facades\Cache;
class Sms extends SoftDeletesModel
class Sms
{
protected $table = "sms";
/**
* 检查IP是否被锁定
*
* @param string $ip 客户端IP地址
* @param string $type 方法类型 (bind_mobile/check_mobile)
* @return array ['locked' => bool, 'message' => string]
*/
public static function checkIpLock($ip, $type = 'bind_mobile')
{
$ipLockKey = 'sms_ip_lock_' . $type . '_' . $ip;
if (Cache::has($ipLockKey)) {
$lockTime = Cache::get($ipLockKey);
$remainingTime = $lockTime - time();
if ($remainingTime > 0) {
$minutes = ceil($remainingTime / 60);
return [
'locked' => true,
'message' => "访问过于频繁,请{$minutes}分钟后再试"
];
}
}
public function belongs() {
return $this->morphTo();
return ['locked' => false, 'message' => ''];
}
}
/**
* 记录验证码错误
*
* @param string $ip 客户端IP地址
* @param string $type 方法类型 (bind_mobile/check_mobile)
* @return array ['locked' => bool, 'message' => string]
*/
public static function recordError($ip, $type = 'bind_mobile')
{
$errorKey = 'sms_error_count_' . $type . '_' . $ip;
$ipLockKey = 'sms_ip_lock_' . $type . '_' . $ip;
$errorCount = Cache::get($errorKey, 0) + 1;
Cache::put($errorKey, $errorCount, 3600); // 1小时过期
// 如果错误次数达到10次锁定IP
if ($errorCount >= 10) {
Cache::put($ipLockKey, time() + 3600, 3600); // 锁定1小时
Cache::forget($errorKey); // 清除错误计数
return [
'locked' => true,
'message' => '验证码错误次数过多请1小时后再试'
];
}
return ['locked' => false, 'message' => '验证码错误'];
}
/**
* 清除错误计数
*
* @param string $ip 客户端IP地址
* @param string $type 方法类型 (bind_mobile/check_mobile)
*/
public static function clearError($ip, $type = 'bind_mobile')
{
$errorKey = 'sms_error_count_' . $type . '_' . $ip;
Cache::forget($errorKey);
}
}

@ -286,7 +286,9 @@ class DoorRepository
*/
public function generateEmpAuthorSet1ByCourse($model, $door, &$out)
{
$door = json_decode($door, true);
if (!is_array($door)) {
$door = json_decode($door, true);
}
if (!isset($door['doorName'])) {
$out = '门禁信息不存在';
return false;
@ -310,7 +312,7 @@ class DoorRepository
'timestamp' => time()
];
// 预约开始时间需大于当前时间两分钟
if (date('Y-m-d', strtotime($courseModel->start_date)) == date('Y-m-d')) {
if (date('Y-m-d', strtotime($courseModel->start_date)) <= date('Y-m-d')) {
$params['startTime'] = date('Y-m-d H:i:s', time() + 200);
}
$params['sign'] = $this->sign($params);

@ -83,15 +83,15 @@ class YuanheRepository
/**
* 数据推送
*/
public function pushCourses(Course $course, User $user)
public function pushCourses(Course $course, User $user,&$out)
{
if (empty($user->company)) {
return false;
}
$params = [
'classTeacher' => $course->teacher->name,
'classTeacher' => $course->teacher->name??'',
'courseName' => $course->name,
'description' => $user->company->businessScope,
'description' => $user->company->businessScope??'',
'enterpriseName' => $user->company->company_name,
'creditCode' => $user->company->credit_code,
'groupId' => '1030004',
@ -106,9 +106,11 @@ class YuanheRepository
if ($result['code'] == 200) {
return true;
} else {
$out = $result['msg'];
return false;
}
} catch (\Exception $e) {
$out = $e->getMessage();
return false;
}
}

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('courses', function (Blueprint $table) {
// 是否推送
$table->boolean('is_push')->default(true)->comment('是否推送0否1是');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('courses', function (Blueprint $table) {
//
});
}
};

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('is_push')->default(false)->comment('是否推送过0否1是');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
//
});
}
};

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Loading…
Cancel
Save