diff --git a/database/migrations/2026_05_30_000001_extend_user_table.php b/database/migrations/2026_05_30_000001_extend_user_table.php new file mode 100644 index 0000000..afd6b43 --- /dev/null +++ b/database/migrations/2026_05_30_000001_extend_user_table.php @@ -0,0 +1,56 @@ +string('avatar', 255)->default('')->comment('头像')->after('email'); + $table->string('mobile', 20)->default('')->comment('手机号')->after('avatar'); + $table->tinyInteger('gender')->default(0)->comment('性别:0=未知,1=男,2=女')->after('mobile'); + $table->date('birthday')->nullable()->comment('生日')->after('gender'); + $table->decimal('balance', 10, 2)->default(0)->comment('余额')->after('birthday'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常')->after('balance'); + $table->timestamp('last_login_at')->nullable()->comment('最后登录时间')->after('status'); + $table->string('openid', 64)->default('')->comment('微信OpenID')->after('last_login_at'); + $table->string('unionid', 64)->default('')->comment('微信UnionID')->after('openid'); + $table->index('mobile'); + $table->index('openid'); + }); + + if (! Schema::hasTable('user_addresses')) { + Schema::create('user_addresses', function (Blueprint $table) { + $table->id(); + $table->unsignedInteger('user_id')->comment('用户ID'); + $table->string('name', 30)->comment('收货人'); + $table->string('mobile', 20)->comment('联系电话'); + $table->string('province', 30)->comment('省'); + $table->string('city', 30)->comment('市'); + $table->string('district', 30)->comment('区'); + $table->string('detail', 255)->comment('详细地址'); + $table->tinyInteger('is_default')->default(0)->comment('是否默认:0=否,1=是'); + $table->timestamps(); + $table->index('user_id'); + $table->comment('用户收货地址'); + }); + } + } + + public function down(): void + { + Schema::table('user', function (Blueprint $table) { + $table->dropIndex(['mobile']); + $table->dropIndex(['openid']); + $table->dropColumn([ + 'avatar', 'mobile', 'gender', 'birthday', + 'balance', 'status', 'last_login_at', 'openid', 'unionid', + ]); + }); + + Schema::dropIfExists('user_addresses'); + } +}; diff --git a/database/migrations/2026_05_30_000002_create_forum_tables.php b/database/migrations/2026_05_30_000002_create_forum_tables.php new file mode 100644 index 0000000..1422f63 --- /dev/null +++ b/database/migrations/2026_05_30_000002_create_forum_tables.php @@ -0,0 +1,125 @@ +id(); + $table->unsignedInteger('parent_id')->default(0)->comment('父级ID'); + $table->string('name', 50)->comment('分类名称'); + $table->string('slug', 50)->comment('标识'); + $table->string('description', 255)->default('')->comment('描述'); + $table->string('icon', 255)->default('')->comment('图标'); + $table->integer('sort')->default(0)->comment('排序'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常'); + $table->timestamps(); + $table->index('slug'); + $table->comment('话题分类'); + }); + } + + // 帖子 + if (! Schema::hasTable('forum_posts')) { + Schema::create('forum_posts', function (Blueprint $table) { + $table->id(); + $table->unsignedInteger('user_id')->comment('发布用户ID'); + $table->unsignedBigInteger('category_id')->nullable()->comment('分类ID'); + $table->string('title', 100)->comment('帖子标题'); + $table->text('content')->comment('帖子内容'); + $table->json('images')->nullable()->comment('图片列表'); + $table->integer('view_count')->default(0)->comment('浏览数'); + $table->integer('comment_count')->default(0)->comment('评论数'); + $table->integer('like_count')->default(0)->comment('点赞数'); + $table->integer('favorite_count')->default(0)->comment('收藏数'); + $table->tinyInteger('is_hot')->default(0)->comment('是否热门:0=否,1=是'); + $table->tinyInteger('is_top')->default(0)->comment('是否置顶:0=否,1=是'); + $table->tinyInteger('status')->default(1)->comment('状态:0=草稿,1=发布,2=隐藏'); + $table->timestamps(); + $table->softDeletes(); + $table->index('user_id'); + $table->index('category_id'); + $table->index('status'); + $table->index(['is_hot', 'is_top']); + $table->comment('帖子'); + }); + } + + // 评论 + if (! Schema::hasTable('forum_comments')) { + Schema::create('forum_comments', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('post_id')->comment('帖子ID'); + $table->unsignedInteger('user_id')->comment('评论用户ID'); + $table->unsignedBigInteger('parent_id')->default(0)->comment('父评论ID,0=一级评论'); + $table->unsignedBigInteger('reply_to')->nullable()->comment('回复的用户ID'); + $table->text('content')->comment('评论内容'); + $table->integer('like_count')->default(0)->comment('点赞数'); + $table->tinyInteger('status')->default(1)->comment('状态:0=隐藏,1=正常'); + $table->timestamps(); + $table->index('post_id'); + $table->index('user_id'); + $table->index('parent_id'); + $table->comment('帖子评论'); + }); + } + + // 敏感词 + if (! Schema::hasTable('forum_sensitive_words')) { + Schema::create('forum_sensitive_words', function (Blueprint $table) { + $table->id(); + $table->string('word', 100)->comment('敏感词'); + $table->string('replacement', 100)->default('***')->comment('替换词'); + $table->tinyInteger('type')->default(1)->comment('类型:1=替换,2=禁止发布'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=启用'); + $table->timestamps(); + $table->unique('word'); + $table->comment('敏感词'); + }); + } + + // 帖子点赞 + if (! Schema::hasTable('forum_post_likes')) { + Schema::create('forum_post_likes', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('post_id')->comment('帖子ID'); + $table->unsignedInteger('user_id')->comment('用户ID'); + $table->timestamp('created_at')->nullable()->comment('点赞时间'); + $table->unique(['post_id', 'user_id']); + $table->index('post_id'); + $table->index('user_id'); + $table->comment('帖子点赞'); + }); + } + + // 帖子收藏 + if (! Schema::hasTable('forum_post_favorites')) { + Schema::create('forum_post_favorites', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('post_id')->comment('帖子ID'); + $table->unsignedInteger('user_id')->comment('用户ID'); + $table->timestamp('created_at')->nullable()->comment('收藏时间'); + $table->unique(['post_id', 'user_id']); + $table->index('post_id'); + $table->index('user_id'); + $table->comment('帖子收藏'); + }); + } + } + + public function down(): void + { + Schema::dropIfExists('forum_post_favorites'); + Schema::dropIfExists('forum_post_likes'); + Schema::dropIfExists('forum_comments'); + Schema::dropIfExists('forum_sensitive_words'); + Schema::dropIfExists('forum_posts'); + Schema::dropIfExists('forum_categories'); + } +}; diff --git a/database/migrations/2026_05_30_000003_create_task_tables.php b/database/migrations/2026_05_30_000003_create_task_tables.php new file mode 100644 index 0000000..2f93060 --- /dev/null +++ b/database/migrations/2026_05_30_000003_create_task_tables.php @@ -0,0 +1,81 @@ +id(); + $table->string('name', 50)->comment('分类名称'); + $table->string('slug', 50)->comment('标识'); + $table->string('description', 255)->default('')->comment('描述'); + $table->string('icon', 255)->default('')->comment('图标'); + $table->integer('sort')->default(0)->comment('排序'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常'); + $table->timestamps(); + $table->unique('slug'); + $table->comment('任务分类'); + }); + } + + // 任务订单(跑腿/代取/租借) + 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')->comment('任务描述'); + $table->json('images')->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('status')->default(0)->comment('状态:0=待接单,1=已接单,2=进行中,3=已完成,4=已取消'); + $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->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->timestamps(); + $table->index('task_id'); + $table->index('user_id'); + $table->comment('任务竞价'); + }); + } + } + + public function down(): void + { + Schema::dropIfExists('task_bids'); + Schema::dropIfExists('task_orders'); + Schema::dropIfExists('task_categories'); + } +}; diff --git a/database/migrations/2026_05_30_000004_create_part_time_tables.php b/database/migrations/2026_05_30_000004_create_part_time_tables.php new file mode 100644 index 0000000..5a8af88 --- /dev/null +++ b/database/migrations/2026_05_30_000004_create_part_time_tables.php @@ -0,0 +1,106 @@ +id(); + $table->unsignedInteger('merchant_id')->nullable()->comment('发布商户ID'); + $table->string('title', 100)->comment('岗位标题'); + $table->text('description')->nullable()->comment('岗位描述'); + $table->text('requirements')->nullable()->comment('任职要求'); + $table->decimal('salary', 10, 2)->default(0)->comment('薪资'); + $table->tinyInteger('salary_type')->default(1)->comment('薪资类型:1=时薪,2=日薪,3=月薪'); + $table->string('location', 255)->default('')->comment('工作地点'); + $table->string('contact_name', 30)->default('')->comment('联系人'); + $table->string('contact_mobile', 20)->default('')->comment('联系电话'); + $table->integer('quota')->default(1)->comment('招聘人数'); + $table->integer('applied_count')->default(0)->comment('已申请人数'); + $table->tinyInteger('status')->default(1)->comment('状态:0=草稿,1=发布,2=已关闭'); + $table->date('start_date')->nullable()->comment('开始日期'); + $table->date('end_date')->nullable()->comment('截止日期'); + $table->timestamps(); + $table->index('merchant_id'); + $table->index('status'); + $table->comment('兼职岗位'); + }); + } + + // 兼职申请/报名 + if (! Schema::hasTable('part_time_applications')) { + Schema::create('part_time_applications', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('job_id')->comment('岗位ID'); + $table->unsignedInteger('user_id')->comment('申请用户ID'); + $table->string('real_name', 30)->comment('真实姓名'); + $table->string('mobile', 20)->comment('联系电话'); + $table->string('resume', 500)->default('')->comment('个人简介/简历'); + $table->tinyInteger('status')->default(0)->comment('状态:0=待审核,1=已通过,2=已拒绝'); + $table->string('review_remark', 255)->default('')->comment('审核备注'); + $table->timestamp('reviewed_at')->nullable()->comment('审核时间'); + $table->timestamps(); + $table->index('job_id'); + $table->index('user_id'); + $table->comment('兼职申请'); + }); + } + + // 兼职人员(已认证) + if (! Schema::hasTable('part_time_workers')) { + Schema::create('part_time_workers', function (Blueprint $table) { + $table->id(); + $table->unsignedInteger('user_id')->comment('用户ID'); + $table->string('real_name', 30)->comment('真实姓名'); + $table->string('mobile', 20)->comment('联系电话'); + $table->string('id_card', 18)->comment('身份证号'); + $table->string('id_card_front', 255)->default('')->comment('身份证正面照'); + $table->string('id_card_back', 255)->default('')->comment('身份证背面照'); + $table->decimal('balance', 10, 2)->default(0)->comment('佣金余额'); + $table->decimal('total_income', 10, 2)->default(0)->comment('累计收入'); + $table->tinyInteger('status')->default(0)->comment('状态:0=待认证,1=已认证,2=已拒绝'); + $table->timestamp('verified_at')->nullable()->comment('认证时间'); + $table->timestamps(); + $table->index('user_id'); + $table->index('mobile'); + $table->comment('兼职人员'); + }); + } + + // 兼职提现 + if (! Schema::hasTable('part_time_withdrawals')) { + Schema::create('part_time_withdrawals', function (Blueprint $table) { + $table->id(); + $table->string('withdraw_no', 32)->comment('提现编号'); + $table->unsignedInteger('user_id')->comment('用户ID'); + $table->unsignedBigInteger('worker_id')->comment('兼职人员ID'); + $table->decimal('amount', 10, 2)->comment('提现金额'); + $table->string('channel', 20)->comment('提现渠道:wechat=微信,alipay=支付宝,bank=银行卡'); + $table->json('account_info')->nullable()->comment('收款账户信息'); + $table->tinyInteger('status')->default(0)->comment('状态:0=待审核,1=已通过,2=已完成,3=已拒绝'); + $table->string('remark', 255)->default('')->comment('审核备注'); + $table->timestamp('processed_at')->nullable()->comment('处理时间'); + $table->timestamps(); + $table->unique('withdraw_no'); + $table->index('user_id'); + $table->index('worker_id'); + $table->index('status'); + $table->comment('兼职提现'); + }); + } + } + + public function down(): void + { + Schema::dropIfExists('part_time_withdrawals'); + Schema::dropIfExists('part_time_workers'); + Schema::dropIfExists('part_time_applications'); + Schema::dropIfExists('part_time_jobs'); + } +}; diff --git a/database/migrations/2026_05_30_000005_create_merchant_tables.php b/database/migrations/2026_05_30_000005_create_merchant_tables.php new file mode 100644 index 0000000..785fbde --- /dev/null +++ b/database/migrations/2026_05_30_000005_create_merchant_tables.php @@ -0,0 +1,149 @@ +id(); + $table->string('name', 50)->comment('分类名称'); + $table->string('slug', 50)->comment('标识'); + $table->string('description', 255)->default('')->comment('描述'); + $table->string('icon', 255)->default('')->comment('图标'); + $table->integer('sort')->default(0)->comment('排序'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常'); + $table->timestamps(); + $table->unique('slug'); + $table->comment('商户分类'); + }); + } + + // 商户/店铺 + if (! Schema::hasTable('merchants')) { + Schema::create('merchants', function (Blueprint $table) { + $table->id(); + $table->unsignedInteger('user_id')->comment('所属用户ID'); + $table->unsignedBigInteger('category_id')->nullable()->comment('商户分类ID'); + $table->string('name', 50)->comment('店铺名称'); + $table->string('logo', 255)->default('')->comment('店铺Logo'); + $table->string('banner', 255)->default('')->comment('店铺横幅/封面'); + $table->text('description')->nullable()->comment('店铺简介'); + $table->string('contact_name', 30)->default('')->comment('联系人'); + $table->string('contact_mobile', 20)->default('')->comment('联系电话'); + $table->string('province', 30)->default('')->comment('省'); + $table->string('city', 30)->default('')->comment('市'); + $table->string('district', 30)->default('')->comment('区'); + $table->string('address', 255)->default('')->comment('详细地址'); + $table->string('latitude', 20)->default('')->comment('纬度'); + $table->string('longitude', 20)->default('')->comment('经度'); + $table->string('business_hours', 100)->default('')->comment('营业时间'); + $table->decimal('balance', 10, 2)->default(0)->comment('账户余额'); + $table->decimal('total_income', 10, 2)->default(0)->comment('累计收入'); + $table->decimal('min_price', 10, 2)->default(0)->comment('起送价'); + $table->tinyInteger('status')->default(0)->comment('状态:0=待审核,1=正常,2=停用,3=已关闭'); + $table->string('reject_reason', 255)->default('')->comment('拒绝原因'); + $table->timestamps(); + $table->index('user_id'); + $table->index('category_id'); + $table->index('status'); + $table->comment('商户/店铺'); + }); + } + + // 商品分类 + if (! Schema::hasTable('product_categories')) { + Schema::create('product_categories', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('merchant_id')->comment('商户ID'); + $table->unsignedBigInteger('parent_id')->default(0)->comment('父级ID'); + $table->string('name', 50)->comment('分类名称'); + $table->string('slug', 50)->comment('标识'); + $table->string('description', 255)->default('')->comment('描述'); + $table->string('icon', 255)->default('')->comment('图标'); + $table->integer('sort')->default(0)->comment('排序'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常'); + $table->timestamps(); + $table->index('merchant_id'); + $table->comment('商品分类'); + }); + } + + // 商品 + if (! Schema::hasTable('merchant_products')) { + Schema::create('merchant_products', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('merchant_id')->comment('商户ID'); + $table->unsignedBigInteger('category_id')->nullable()->comment('分类ID'); + $table->string('name', 100)->comment('商品名称'); + $table->text('description')->nullable()->comment('商品描述'); + $table->json('images')->nullable()->comment('商品图片列表'); + $table->decimal('price', 10, 2)->comment('售价'); + $table->decimal('original_price', 10, 2)->nullable()->comment('原价'); + $table->integer('stock')->default(0)->comment('库存'); + $table->string('unit', 20)->default('份')->comment('单位'); + $table->integer('sales')->default(0)->comment('销量'); + $table->tinyInteger('status')->default(1)->comment('状态:0=下架,1=上架'); + $table->tinyInteger('is_recommend')->default(0)->comment('是否推荐:0=否,1=是'); + $table->integer('sort')->default(0)->comment('排序'); + $table->timestamps(); + $table->softDeletes(); + $table->index('merchant_id'); + $table->index('category_id'); + $table->index('status'); + $table->comment('商户商品'); + }); + } + + // 打印机 + if (! Schema::hasTable('printers')) { + Schema::create('printers', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('merchant_id')->comment('商户ID'); + $table->string('name', 50)->comment('打印机名称'); + $table->string('brand', 50)->default('')->comment('品牌'); + $table->string('model', 50)->default('')->comment('型号'); + $table->string('device_no', 100)->default('')->comment('设备编号'); + $table->string('secret_key', 255)->default('')->comment('密钥'); + $table->tinyInteger('status')->default(1)->comment('状态:0=离线,1=在线,2=故障'); + $table->json('config')->nullable()->comment('打印配置'); + $table->timestamps(); + $table->index('merchant_id'); + $table->comment('打印机'); + }); + } + + // 打印任务 + if (! Schema::hasTable('print_tasks')) { + Schema::create('print_tasks', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('printer_id')->comment('打印机ID'); + $table->unsignedBigInteger('order_id')->nullable()->comment('关联订单ID'); + $table->text('content')->comment('打印内容'); + $table->integer('copies')->default(1)->comment('打印份数'); + $table->tinyInteger('status')->default(0)->comment('状态:0=待打印,1=打印中,2=已完成,3=失败'); + $table->string('error_msg', 255)->default('')->comment('错误信息'); + $table->timestamp('printed_at')->nullable()->comment('打印时间'); + $table->timestamps(); + $table->index('printer_id'); + $table->index('order_id'); + $table->comment('打印任务'); + }); + } + } + + public function down(): void + { + Schema::dropIfExists('print_tasks'); + Schema::dropIfExists('printers'); + Schema::dropIfExists('merchant_products'); + Schema::dropIfExists('product_categories'); + Schema::dropIfExists('merchants'); + Schema::dropIfExists('merchant_categories'); + } +}; diff --git a/database/migrations/2026_05_30_000006_create_order_tables.php b/database/migrations/2026_05_30_000006_create_order_tables.php new file mode 100644 index 0000000..618c370 --- /dev/null +++ b/database/migrations/2026_05_30_000006_create_order_tables.php @@ -0,0 +1,110 @@ +id(); + $table->string('order_no', 32)->comment('订单编号'); + $table->unsignedInteger('user_id')->comment('下单用户ID'); + $table->unsignedBigInteger('merchant_id')->comment('商户ID'); + $table->unsignedBigInteger('address_id')->nullable()->comment('收货地址ID'); + $table->decimal('total_amount', 10, 2)->comment('商品总价'); + $table->decimal('discount_amount', 10, 2)->default(0)->comment('优惠金额'); + $table->decimal('delivery_fee', 10, 2)->default(0)->comment('配送费'); + $table->decimal('payment_amount', 10, 2)->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('completed_at')->nullable()->comment('完成时间'); + $table->timestamps(); + $table->unique('order_no'); + $table->index('user_id'); + $table->index('merchant_id'); + $table->index('status'); + $table->index('pay_status'); + $table->comment('订单'); + }); + } + + // 订单明细 + if (! Schema::hasTable('order_items')) { + Schema::create('order_items', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('order_id')->comment('订单ID'); + $table->unsignedBigInteger('product_id')->comment('商品ID'); + $table->string('product_name', 100)->comment('商品名称'); + $table->string('product_image', 255)->default('')->comment('商品图片'); + $table->decimal('price', 10, 2)->comment('单价'); + $table->integer('quantity')->comment('数量'); + $table->decimal('subtotal', 10, 2)->comment('小计'); + $table->timestamps(); + $table->index('order_id'); + $table->index('product_id'); + $table->comment('订单明细'); + }); + } + + // 订单退款 + if (! Schema::hasTable('order_refunds')) { + Schema::create('order_refunds', function (Blueprint $table) { + $table->id(); + $table->string('refund_no', 32)->comment('退款编号'); + $table->unsignedBigInteger('order_id')->comment('订单ID'); + $table->unsignedBigInteger('order_item_id')->nullable()->comment('订单明细ID,空=整单退款'); + $table->unsignedInteger('user_id')->comment('申请用户ID'); + $table->unsignedBigInteger('merchant_id')->comment('商户ID'); + $table->decimal('amount', 10, 2)->comment('退款金额'); + $table->string('reason', 500)->comment('退款原因'); + $table->json('images')->nullable()->comment('凭证图片'); + $table->tinyInteger('status')->default(0)->comment('状态:0=待处理,1=已同意,2=已完成,3=已拒绝'); + $table->string('reply', 500)->default('')->comment('商户回复'); + $table->timestamp('processed_at')->nullable()->comment('处理时间'); + $table->timestamps(); + $table->unique('refund_no'); + $table->index('order_id'); + $table->index('user_id'); + $table->index('merchant_id'); + $table->comment('订单退款'); + }); + } + + // 商户提现 + if (! Schema::hasTable('merchant_withdrawals')) { + Schema::create('merchant_withdrawals', function (Blueprint $table) { + $table->id(); + $table->string('withdraw_no', 32)->comment('提现编号'); + $table->unsignedBigInteger('merchant_id')->comment('商户ID'); + $table->decimal('amount', 10, 2)->comment('提现金额'); + $table->string('channel', 20)->comment('提现渠道:wechat=微信,alipay=支付宝,bank=银行卡'); + $table->json('account_info')->nullable()->comment('收款账户信息'); + $table->tinyInteger('status')->default(0)->comment('状态:0=待审核,1=已通过,2=已完成,3=已拒绝'); + $table->string('remark', 255)->default('')->comment('审核备注'); + $table->timestamp('processed_at')->nullable()->comment('处理时间'); + $table->timestamps(); + $table->unique('withdraw_no'); + $table->index('merchant_id'); + $table->index('status'); + $table->comment('商户提现'); + }); + } + } + + public function down(): void + { + Schema::dropIfExists('merchant_withdrawals'); + Schema::dropIfExists('order_refunds'); + Schema::dropIfExists('order_items'); + Schema::dropIfExists('orders'); + } +}; diff --git a/database/migrations/2026_05_30_000007_create_app_management_tables.php b/database/migrations/2026_05_30_000007_create_app_management_tables.php new file mode 100644 index 0000000..2f44351 --- /dev/null +++ b/database/migrations/2026_05_30_000007_create_app_management_tables.php @@ -0,0 +1,104 @@ +id(); + $table->string('title', 100)->comment('标题'); + $table->text('content')->comment('内容'); + $table->integer('sort')->default(0)->comment('排序'); + $table->tinyInteger('status')->default(1)->comment('状态:0=草稿,1=发布'); + $table->timestamps(); + $table->index('status'); + $table->comment('公告'); + }); + } + + // 链接管理 + if (! Schema::hasTable('links')) { + Schema::create('links', function (Blueprint $table) { + $table->id(); + $table->string('title', 50)->comment('链接标题'); + $table->string('url', 500)->comment('链接地址'); + $table->string('icon', 255)->default('')->comment('图标'); + $table->tinyInteger('type')->default(2)->comment('类型:1=内部链接,2=外部链接'); + $table->integer('sort')->default(0)->comment('排序'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常'); + $table->timestamps(); + $table->index('type'); + $table->index('status'); + $table->comment('链接管理'); + }); + } + + // 广告 + if (! Schema::hasTable('ads')) { + Schema::create('ads', function (Blueprint $table) { + $table->id(); + $table->string('title', 50)->comment('广告标题'); + $table->string('image', 255)->comment('广告图片'); + $table->string('url', 500)->default('')->comment('跳转链接'); + $table->string('position', 30)->comment('位置:home_banner=首页轮播,home_middle=首页中部'); + $table->integer('sort')->default(0)->comment('排序'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常'); + $table->timestamp('start_time')->nullable()->comment('开始时间'); + $table->timestamp('end_time')->nullable()->comment('结束时间'); + $table->timestamps(); + $table->index('position'); + $table->index('status'); + $table->comment('广告'); + }); + } + + // 导航管理 + if (! Schema::hasTable('navigations')) { + Schema::create('navigations', function (Blueprint $table) { + $table->id(); + $table->string('title', 50)->comment('导航标题'); + $table->string('icon', 255)->default('')->comment('图标'); + $table->string('url', 500)->default('')->comment('跳转链接'); + $table->tinyInteger('type')->default(1)->comment('类型:1=内部页面,2=外部链接'); + $table->integer('sort')->default(0)->comment('排序'); + $table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常'); + $table->timestamps(); + $table->index('type'); + $table->comment('导航管理'); + }); + } + + // 意见反馈 + if (! Schema::hasTable('feedbacks')) { + Schema::create('feedbacks', function (Blueprint $table) { + $table->id(); + $table->unsignedInteger('user_id')->comment('用户ID'); + $table->text('content')->comment('反馈内容'); + $table->json('images')->nullable()->comment('图片列表'); + $table->string('contact', 50)->default('')->comment('联系方式'); + $table->tinyInteger('status')->default(0)->comment('状态:0=待处理,1=已处理'); + $table->text('reply')->nullable()->comment('回复内容'); + $table->timestamp('replied_at')->nullable()->comment('回复时间'); + $table->timestamps(); + $table->index('user_id'); + $table->index('status'); + $table->comment('意见反馈'); + }); + } + } + + public function down(): void + { + Schema::dropIfExists('feedbacks'); + Schema::dropIfExists('navigations'); + Schema::dropIfExists('ads'); + Schema::dropIfExists('links'); + Schema::dropIfExists('announcements'); + } +}; diff --git a/database/migrations/2026_05_30_000008_create_wallet_and_message_tables.php b/database/migrations/2026_05_30_000008_create_wallet_and_message_tables.php new file mode 100644 index 0000000..123c0c1 --- /dev/null +++ b/database/migrations/2026_05_30_000008_create_wallet_and_message_tables.php @@ -0,0 +1,71 @@ +id(); + $table->string('owner_type', 30)->comment('所属类型:user=用户,merchant=商户'); + $table->unsignedBigInteger('owner_id')->comment('所属ID'); + $table->decimal('balance', 10, 2)->default(0)->comment('可用余额'); + $table->decimal('frozen_balance', 10, 2)->default(0)->comment('冻结余额'); + $table->timestamps(); + $table->unique(['owner_type', 'owner_id']); + $table->comment('钱包'); + }); + } + + // 资金流水 + if (! Schema::hasTable('transactions')) { + Schema::create('transactions', function (Blueprint $table) { + $table->id(); + $table->string('transaction_no', 32)->comment('流水编号'); + $table->unsignedBigInteger('wallet_id')->comment('钱包ID'); + $table->tinyInteger('type')->comment('类型:1=收入,2=支出'); + $table->decimal('amount', 10, 2)->comment('金额'); + $table->decimal('balance_after', 10, 2)->comment('交易后余额'); + $table->string('description', 255)->comment('描述'); + $table->string('related_type', 30)->nullable()->comment('关联类型:order=订单,task=任务,withdrawal=提现,refund=退款'); + $table->unsignedBigInteger('related_id')->nullable()->comment('关联ID'); + $table->timestamps(); + $table->unique('transaction_no'); + $table->index('wallet_id'); + $table->index(['related_type', 'related_id']); + $table->comment('资金流水'); + }); + } + + // 统一消息 + if (! Schema::hasTable('messages')) { + Schema::create('messages', function (Blueprint $table) { + $table->id(); + $table->unsignedInteger('user_id')->comment('接收用户ID'); + $table->string('title', 100)->comment('消息标题'); + $table->text('content')->nullable()->comment('消息内容'); + $table->string('type', 20)->comment('类型:system=系统,like=点赞,comment=评论,order=订单,task=任务'); + $table->tinyInteger('is_read')->default(0)->comment('是否已读:0=未读,1=已读'); + $table->string('related_type', 30)->nullable()->comment('关联类型'); + $table->unsignedBigInteger('related_id')->nullable()->comment('关联ID'); + $table->timestamps(); + $table->index('user_id'); + $table->index(['user_id', 'is_read']); + $table->index('type'); + $table->comment('消息通知'); + }); + } + } + + public function down(): void + { + Schema::dropIfExists('messages'); + Schema::dropIfExists('transactions'); + Schema::dropIfExists('wallets'); + } +};