接单员与财务管理

This commit is contained in:
liu
2026-06-17 10:35:13 +08:00
parent 254823e308
commit 8d52e863b9
110 changed files with 6054 additions and 570 deletions
@@ -8,14 +8,15 @@ return new class extends Migration
{
public function up(): void
{
// 任务分类
// 任务分类(跑腿/代取/租借等,后台可管理)
if (! Schema::hasTable('task_categories')) {
Schema::create('task_categories', function (Blueprint $table) {
$table->id();
$table->string('name', 50)->comment('分类名称');
$table->string('slug', 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();
@@ -24,26 +25,37 @@ return new class extends Migration
});
}
// 任务订单(跑腿/代取/租借)
// 任务订单跑腿/代取/租借统一,分类特有字段存 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->unsignedBigInteger('category_id')->comment('任务分类ID');
$table->string('title', 100)->comment('任务标题');
$table->text('description')->comment('任务描述');
$table->text('description')->nullable()->comment('任务描述');
$table->json('images')->nullable()->comment('图片列表');
$table->decimal('price', 10, 2)->default(0)->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');
@@ -51,29 +63,56 @@ return new class extends Migration
$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->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->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->comment('任务竞价');
$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');
@@ -8,14 +8,14 @@ return new class extends Migration
{
public function up(): void
{
// 兼职申请/报名
if (! Schema::hasTable('part_time_applications')) {
Schema::create('part_time_applications', function (Blueprint $table) {
// 接单员申请
if (! Schema::hasTable('runner_applications')) {
Schema::create('runner_applications', function (Blueprint $table) {
$table->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->string('resume', 500)->default('')->comment('个人简介/申请理由');
$table->string('id_card', 18)->comment('身份证号');
$table->string('id_card_front', 255)->default('')->comment('身份证正面照');
$table->string('id_card_back', 255)->default('')->comment('身份证背面照');
@@ -24,38 +24,41 @@ return new class extends Migration
$table->timestamp('reviewed_at')->nullable()->comment('审核时间');
$table->timestamps();
$table->index('user_id');
$table->comment('兼职申请');
$table->index('mobile');
$table->comment('接单员申请');
});
}
// 兼职人员(已认证)
if (! Schema::hasTable('part_time_workers')) {
Schema::create('part_time_workers', function (Blueprint $table) {
// 接单员列表(审核通过后写入)
if (! Schema::hasTable('runner_workers')) {
Schema::create('runner_workers', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('user_id')->comment('用户ID');
$table->unsignedInteger('user_id')->unique()->comment('用户ID');
$table->string('real_name', 30)->comment('真实姓名');
$table->string('mobile', 20)->comment('联系电话');
$table->string('id_card', 18)->comment('身份证号');
$table->decimal('total_income', 10, 2)->default(0)->comment('累计收入');
$table->integer('total_order')->default(0)->comment('累计订单');
$table->decimal('credit_score', 10, 2)->default(100)->comment('信誉分');
$table->timestamp('verified_at')->nullable()->comment('认证时间');
$table->tinyInteger('status')->default(1)->comment('状态:0=禁止接单,1=正常');
$table->integer('total_order')->default(0)->comment('累计完成订单');
$table->integer('cancel_order')->default(0)->comment('累计取消订单');
$table->decimal('credit_score', 10, 2)->default(100)->comment('信誉分(满分100)');
$table->timestamp('verified_at')->nullable()->comment('认证通过时间');
$table->tinyInteger('status')->default(1)->comment('状态:0=禁止接单,1=正常,2=休息中');
$table->timestamps();
$table->index('user_id');
$table->index('mobile');
$table->comment('兼职人员');
$table->index('credit_score');
$table->comment('接单员');
});
}
// 兼职提现
if (! Schema::hasTable('part_time_withdrawals')) {
Schema::create('part_time_withdrawals', function (Blueprint $table) {
// 接单员提现
if (! Schema::hasTable('runner_withdrawals')) {
Schema::create('runner_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->unsignedBigInteger('worker_id')->comment('接单员ID');
$table->decimal('amount', 10, 2)->comment('提现金额');
$table->decimal('fee', 10, 2)->default(0)->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=已拒绝');
@@ -66,16 +69,127 @@ return new class extends Migration
$table->index('user_id');
$table->index('worker_id');
$table->index('status');
$table->comment('兼职提现');
$table->comment('接单员提现');
});
}
// 信誉分变动记录
if (! Schema::hasTable('runner_credit_logs')) {
Schema::create('runner_credit_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('worker_id')->comment('接单员ID');
$table->decimal('score', 5, 2)->comment('变动分值(正=加分,负=扣分)');
$table->decimal('score_after', 5, 2)->comment('变动后分值');
$table->string('type', 30)->comment('变动类型:order_complete=完成订单,order_cancel=取消订单,order_timeout=超时,complaint=被投诉,appeal_success=申诉成功,manual=管理员调整');
$table->string('description', 255)->comment('变动说明');
$table->string('related_type', 30)->nullable()->comment('关联类型');
$table->unsignedBigInteger('related_id')->nullable()->comment('关联ID');
$table->timestamps();
$table->index('worker_id');
$table->index('type');
$table->index(['related_type', 'related_id']);
$table->comment('接单员信誉分记录');
});
}
// 投诉记录
if (! Schema::hasTable('runner_complaints')) {
Schema::create('runner_complaints', function (Blueprint $table) {
$table->id();
$table->string('complaint_no', 32)->comment('投诉编号');
$table->unsignedInteger('user_id')->comment('投诉用户ID');
$table->unsignedBigInteger('worker_id')->comment('被投诉接单员ID');
$table->unsignedBigInteger('order_id')->nullable()->comment('关联任务订单ID');
$table->string('type', 30)->comment('投诉类型:late=迟到/超时,attitude=服务态度,damage=物品损坏,lost=物品丢失,other=其他');
$table->text('content')->comment('投诉内容');
$table->json('images')->nullable()->comment('凭证图片');
$table->tinyInteger('status')->default(0)->comment('状态:0=待处理,1=已处理,2=已驳回');
$table->string('result', 255)->default('')->comment('处理结果');
$table->string('result_remark', 500)->default('')->comment('处理备注');
$table->timestamp('handled_at')->nullable()->comment('处理时间');
$table->timestamps();
$table->unique('complaint_no');
$table->index('user_id');
$table->index('worker_id');
$table->index('order_id');
$table->index('status');
$table->comment('接单员投诉记录');
});
}
// 投诉申诉记录
if (! Schema::hasTable('runner_complaint_appeals')) {
Schema::create('runner_complaint_appeals', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('complaint_id')->comment('投诉ID');
$table->unsignedBigInteger('worker_id')->comment('申诉接单员ID');
$table->text('content')->comment('申诉内容');
$table->json('images')->nullable()->comment('凭证图片');
$table->tinyInteger('status')->default(0)->comment('状态:0=待审核,1=已通过,2=已驳回');
$table->string('reply', 500)->default('')->comment('审核回复');
$table->timestamp('reviewed_at')->nullable()->comment('审核时间');
$table->timestamps();
$table->index('complaint_id');
$table->index('worker_id');
$table->comment('接单员投诉申诉');
});
}
// 接单员保证金
if (! Schema::hasTable('runner_deposits')) {
Schema::create('runner_deposits', function (Blueprint $table) {
$table->id();
$table->string('deposit_no', 32)->comment('保证金编号');
$table->unsignedBigInteger('worker_id')->comment('接单员ID');
$table->unsignedInteger('user_id')->comment('用户ID');
$table->decimal('amount', 10, 2)->comment('保证金金额');
$table->tinyInteger('status')->default(0)->comment('状态:0=未缴纳,1=已缴纳,2=已退还,3=已扣除');
$table->string('deduct_reason', 255)->default('')->comment('扣除原因');
$table->timestamp('paid_at')->nullable()->comment('缴纳时间');
$table->timestamp('refund_at')->nullable()->comment('退还时间');
$table->timestamp('deducted_at')->nullable()->comment('扣除时间');
$table->timestamps();
$table->unique('deposit_no');
$table->index('worker_id');
$table->index('user_id');
$table->index('status');
$table->comment('接单员保证金');
});
}
// 保证金支付日志(支付成功后写入,关联三方支付流水)
if (! Schema::hasTable('deposit_payments')) {
Schema::create('deposit_payments', function (Blueprint $table) {
$table->id();
$table->string('payment_no', 32)->comment('支付日志编号');
$table->unsignedBigInteger('deposit_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('deposit_id');
$table->index('user_id');
$table->index('payment_transaction_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');
Schema::dropIfExists('deposit_payments');
Schema::dropIfExists('runner_deposits');
Schema::dropIfExists('runner_complaint_appeals');
Schema::dropIfExists('runner_complaints');
Schema::dropIfExists('runner_credit_logs');
Schema::dropIfExists('runner_withdrawals');
Schema::dropIfExists('runner_workers');
Schema::dropIfExists('runner_applications');
}
};
@@ -8,37 +8,28 @@ return new class extends Migration
{
public function up(): void
{
// 钱包
if (! Schema::hasTable('wallets')) {
Schema::create('wallets', function (Blueprint $table) {
// 统一三方支付流水
if (! Schema::hasTable('payment_transactions')) {
Schema::create('payment_transactions', function (Blueprint $table) {
$table->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->string('transaction_no', 64)->comment('第三方交易号(微信支付transaction_id)');
$table->string('out_trade_no', 32)->comment('商户订单号');
$table->string('pay_type', 20)->comment('支付方式:wechat=微信支付,alipay=支付宝');
$table->decimal('amount', 10, 2)->comment('支付金额');
$table->tinyInteger('status')->default(0)->comment('状态:0=待支付,1=成功,2=失败,3=已退款');
$table->string('business_type', 30)->comment('业务类型:task=任务订单,deposit=保证金,order=商城订单');
$table->unsignedBigInteger('business_id')->nullable()->comment('业务ID');
$table->unsignedInteger('user_id')->comment('支付用户ID');
$table->string('openid', 64)->default('')->comment('微信OpenID');
$table->json('raw_data')->nullable()->comment('支付/退款回调原始数据');
$table->timestamp('paid_at')->nullable()->comment('支付时间');
$table->timestamps();
$table->unique('transaction_no');
$table->index('wallet_id');
$table->index(['related_type', 'related_id']);
$table->comment('资金流水');
$table->unique('out_trade_no');
$table->index('user_id');
$table->index(['business_type', 'business_id']);
$table->index('status');
$table->comment('三方支付流水');
});
}
@@ -65,7 +56,6 @@ return new class extends Migration
public function down(): void
{
Schema::dropIfExists('messages');
Schema::dropIfExists('transactions');
Schema::dropIfExists('wallets');
Schema::dropIfExists('payment_transactions');
}
};