id(); $table->string('code', 64)->nullable()->unique()->comment('业务编码,签到等场景'); $table->string('code_prefix', 32)->nullable()->comment('课程前缀,如 AI26,对齐原型'); $table->string('title', 255); $table->foreignId('course_system_dict_item_id') ->nullable() ->constrained('dict_items') ->restrictOnDelete() ->comment('课程体系,字典编码 course_system,存 dict_items.id'); $table->foreignId('course_type_dict_item_id') ->nullable() ->constrained('dict_items') ->restrictOnDelete() ->comment('课程类型,字典编码 course_type,存 dict_items.id'); $table->date('teach_start_date')->nullable(); $table->date('teach_end_date')->nullable(); $table->date('signup_start_date')->nullable(); $table->date('signup_end_date')->nullable(); $table->foreignId('auto_add_teacher_dict_item_id') ->nullable() ->constrained('dict_items') ->restrictOnDelete() ->comment('已审核学员自动入老师库,字典 yes_no,存 dict_items.id'); $table->unsignedInteger('capacity')->default(0)->comment('开课人数'); $table->string('cover_url', 512)->nullable()->comment('课程封面'); $table->string('promo_url', 512)->nullable()->comment('课程宣传页'); $table->string('news_link_url', 512)->nullable()->comment('资讯链接'); $table->longText('intro_html')->nullable()->comment('课程简介(富文本 HTML)'); $table->json('signup_form_schema')->nullable()->comment('报名表单设计器 JSON,对齐 prototype step2'); $table->tinyInteger('progress_status')->default(1)->comment('1未开始 2进行中 3已结束'); $table->tinyInteger('published')->default(0)->comment('1已发布/上架 0未发布'); $table->text('remark')->nullable(); $table->integer('sort')->default(0); $table->timestamps(); $table->softDeletes(); $table->index(['course_system_dict_item_id', 'progress_status', 'published'], 'crs_sys_prog_pub_idx'); $table->index(['course_type_dict_item_id'], 'crs_type_item_idx'); }); Schema::create('course_sessions', function (Blueprint $table) { $table->id(); $table->foreignId('course_id')->constrained('courses')->cascadeOnDelete(); $table->string('title', 255)->nullable(); $table->dateTime('starts_at')->nullable(); $table->dateTime('ends_at')->nullable(); $table->string('venue', 255)->nullable(); $table->unsignedInteger('capacity')->nullable(); $table->integer('sort')->default(0); $table->timestamps(); $table->softDeletes(); $table->index(['course_id', 'sort']); }); Schema::create('course_signups', function (Blueprint $table) { $table->id(); $table->foreignId('course_id')->constrained('courses')->cascadeOnDelete(); $table->foreignId('course_session_id')->nullable()->constrained('course_sessions')->nullOnDelete(); $table->string('name', 64); $table->string('mobile', 32); $table->string('company', 128)->nullable(); $table->dateTime('signed_up_at')->nullable(); $table->dateTime('checked_in_at')->nullable(); $table->tinyInteger('status')->default(1)->comment('1正常 0取消等'); $table->timestamps(); $table->softDeletes(); $table->index(['course_id', 'signed_up_at']); }); Schema::create('activities', function (Blueprint $table) { $table->id(); $table->string('code', 64)->nullable()->unique(); $table->string('title', 255); $table->string('activity_type', 32)->nullable()->comment('沙龙/讲座/论坛'); $table->unsignedInteger('quota')->default(0)->comment('名额'); $table->date('event_start_date')->nullable(); $table->date('event_end_date')->nullable(); $table->date('signup_start_date')->nullable(); $table->date('signup_end_date')->nullable(); $table->string('location', 255)->nullable(); $table->tinyInteger('progress_status')->default(1); $table->tinyInteger('published')->default(0); $table->text('remark')->nullable(); $table->integer('sort')->default(0); $table->timestamps(); $table->softDeletes(); $table->index(['activity_type', 'progress_status', 'published']); }); Schema::create('activity_sessions', function (Blueprint $table) { $table->id(); $table->foreignId('activity_id')->constrained('activities')->cascadeOnDelete(); $table->string('title', 255)->nullable(); $table->dateTime('starts_at')->nullable(); $table->dateTime('ends_at')->nullable(); $table->string('venue', 255)->nullable(); $table->unsignedInteger('capacity')->nullable(); $table->integer('sort')->default(0); $table->timestamps(); $table->softDeletes(); $table->index(['activity_id', 'sort']); }); Schema::create('activity_signups', function (Blueprint $table) { $table->id(); $table->foreignId('activity_id')->constrained('activities')->cascadeOnDelete(); $table->foreignId('activity_session_id')->nullable()->constrained('activity_sessions')->nullOnDelete(); $table->string('name', 64); $table->string('mobile', 32); $table->string('company', 128)->nullable(); $table->dateTime('signed_up_at')->nullable(); $table->dateTime('checked_in_at')->nullable(); $table->tinyInteger('status')->default(1); $table->timestamps(); $table->softDeletes(); $table->index(['activity_id', 'signed_up_at']); }); Schema::create('news', function (Blueprint $table) { $table->id(); $table->string('title', 255); $table->string('category', 64)->nullable(); $table->string('source', 128)->nullable(); $table->string('cover_url', 512)->nullable(); $table->text('summary')->nullable(); $table->longText('content_html')->nullable(); $table->tinyInteger('status')->default(0)->comment('0草稿 1已发布'); $table->dateTime('published_at')->nullable(); $table->timestamps(); $table->softDeletes(); $table->index(['category', 'status', 'published_at']); }); } public function down(): void { Schema::dropIfExists('activity_signups'); Schema::dropIfExists('activity_sessions'); Schema::dropIfExists('activities'); Schema::dropIfExists('course_signups'); Schema::dropIfExists('course_sessions'); Schema::dropIfExists('courses'); Schema::dropIfExists('news'); } };