id(); $table->string('name', 50)->comment('分类名称'); $table->string('slug', 50)->comment('标识:errand=跑腿,pickup=代取,rental=租借'); $table->string('description', 255)->default('')->comment('描述'); $table->string('icon', 255)->default('')->comment('图标'); $table->json('form_schema')->nullable()->comment('分类特有字段模板,前端据此动态渲染表单'); $table->integer('sort')->default(0)->comment('排序'); $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常'); $table->timestamps(); $table->unique('slug'); $table->comment('任务分类'); }); } // 任务订单(跑腿/代取/租借统一,分类特有字段存 extra) if (! Schema::hasTable('task_orders')) { Schema::create('task_orders', function (Blueprint $table) { $table->id(); $table->string('order_no', 32)->comment('订单编号'); $table->unsignedInteger('user_id')->comment('发布用户ID'); $table->unsignedInteger('runner_id')->nullable()->comment('接单用户ID'); $table->unsignedBigInteger('category_id')->comment('任务分类ID'); $table->string('title', 100)->comment('任务标题'); $table->text('description')->nullable()->comment('任务描述'); $table->json('images')->nullable()->comment('图片列表'); $table->json('extra')->nullable()->comment('分类特有字段:跑腿{取件地址,送达地址},代取{取件地点,取件码},租借{押金,租借天数}'); $table->decimal('price', 10, 2)->default(0)->comment('任务报酬'); $table->string('address', 255)->default('')->comment('任务地址'); $table->string('contact_name', 30)->default('')->comment('联系人'); $table->string('contact_mobile', 20)->default('')->comment('联系电话'); $table->timestamp('deadline')->nullable()->comment('截止时间'); // 支付信息(创建订单时支付) $table->tinyInteger('pay_type')->default(0)->comment('支付方式:0=余额,1=微信支付'); $table->tinyInteger('pay_status')->default(0)->comment('支付状态:0=待支付,1=已支付,2=退款中,3=已退款'); $table->timestamp('paid_at')->nullable()->comment('支付时间'); // 订单状态流转 $table->tinyInteger('status')->default(0)->comment('状态:0=待接单,1=已接单,2=进行中,3=已完成,4=已取消'); $table->string('cancel_reason', 255)->default('')->comment('取消原因'); $table->string('remark', 500)->default('')->comment('订单备注'); $table->timestamp('accepted_at')->nullable()->comment('接单时间'); $table->timestamp('completed_at')->nullable()->comment('完成时间'); $table->timestamp('cancelled_at')->nullable()->comment('取消时间'); $table->timestamps(); $table->softDeletes(); $table->unique('order_no'); $table->index('user_id'); $table->index('runner_id'); $table->index('category_id'); $table->index('status'); $table->index('pay_status'); $table->comment('校园任务订单'); }); } // 接单记录/竞价(用户对任务报价或申请接单) if (! Schema::hasTable('task_bids')) { Schema::create('task_bids', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('task_id')->comment('任务订单ID'); $table->unsignedInteger('user_id')->comment('接单人ID'); $table->decimal('price', 10, 2)->default(0)->comment('报价(等于任务价即为直接接单)'); $table->string('message', 500)->default('')->comment('申请留言/自我介绍'); $table->tinyInteger('status')->default(0)->comment('状态:0=待确认,1=已接受,2=已拒绝'); $table->timestamp('accepted_at')->nullable()->comment('接受时间'); $table->timestamps(); $table->index('task_id'); $table->index('user_id'); $table->unique(['task_id', 'user_id'], 'uk_task_user'); $table->comment('任务接单/竞价记录'); }); } // 任务支付日志(支付成功后写入,关联三方支付流水) if (! Schema::hasTable('task_payments')) { Schema::create('task_payments', function (Blueprint $table) { $table->id(); $table->string('payment_no', 32)->comment('支付日志编号'); $table->unsignedBigInteger('order_id')->comment('任务订单ID'); $table->unsignedInteger('user_id')->comment('支付用户ID'); $table->unsignedBigInteger('payment_transaction_id')->nullable()->comment('三方支付流水ID'); $table->decimal('amount', 10, 2)->comment('支付金额'); $table->tinyInteger('pay_type')->comment('支付方式:0=余额,1=微信支付'); $table->tinyInteger('status')->default(0)->comment('状态:0=待支付,1=已支付,2=已退款'); $table->timestamp('paid_at')->nullable()->comment('支付时间'); $table->timestamp('refund_at')->nullable()->comment('退款时间'); $table->timestamps(); $table->unique('payment_no'); $table->index('order_id'); $table->index('user_id'); $table->index('payment_transaction_id'); $table->index('status'); $table->comment('任务支付日志'); }); } } public function down(): void { Schema::dropIfExists('task_payments'); Schema::dropIfExists('task_bids'); Schema::dropIfExists('task_orders'); Schema::dropIfExists('task_categories'); } };