feat: referral_code
This commit is contained in:
@@ -210,6 +210,7 @@ public function register(Request $request)
|
||||
'method' => 'string|in:code,link|nullable',
|
||||
'birthday' => 'date|nullable',
|
||||
'gender' => ['integer', 'nullable', Rule::in(User::GENDERS)],
|
||||
'referrer_code' => ['string', 'nullable', 'exists:users,referral_code'],
|
||||
]);
|
||||
|
||||
$method = $data['method'] ?? 'link';
|
||||
@@ -219,6 +220,13 @@ public function register(Request $request)
|
||||
$packageNameValue = $data['package_name'];
|
||||
unset($data['package_name']);
|
||||
|
||||
// Resolve referrer code (کد معرف) to the referring user
|
||||
$referrerCode = $data['referrer_code'] ?? null;
|
||||
unset($data['referrer_code']);
|
||||
if ($referrerCode && $referrer = User::where('referral_code', $referrerCode)->first()) {
|
||||
$data['referred_by'] = $referrer->id;
|
||||
}
|
||||
|
||||
if (isset($data['mobile'])) {
|
||||
$data['mobile'] = MobileNumberHelper::formatMobile($data['mobile']);
|
||||
if (User::where('mobile', $data['mobile'])->exists()) {
|
||||
|
||||
+12
-1
@@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Traits\HasUuid;
|
||||
use App\Traits\HasReferralCode;
|
||||
use DateTimeInterface;
|
||||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@@ -13,7 +14,7 @@
|
||||
use Illuminate\Support\Str;
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable, HasUuid, Filterable;
|
||||
use HasApiTokens, HasFactory, Notifiable, HasUuid, HasReferralCode, Filterable;
|
||||
|
||||
const GENDERS = [
|
||||
'male' => 1,
|
||||
@@ -61,6 +62,16 @@ public function otpTokens()
|
||||
return $this->hasMany(OtpTokens::class);
|
||||
}
|
||||
|
||||
public function referrer()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'referred_by');
|
||||
}
|
||||
|
||||
public function referrals()
|
||||
{
|
||||
return $this->hasMany(User::class, 'referred_by');
|
||||
}
|
||||
|
||||
public function transactions()
|
||||
{
|
||||
return $this->hasMany(Transaction::class);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait HasReferralCode
|
||||
{
|
||||
public static function bootHasReferralCode(): void
|
||||
{
|
||||
static::creating(function ($model) {
|
||||
if (!$model->referral_code) {
|
||||
$model->referral_code = static::generateReferralCode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function generateReferralCode(): string
|
||||
{
|
||||
do {
|
||||
$code = strtoupper(Str::random(8));
|
||||
} while (static::where('referral_code', $code)->exists());
|
||||
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('users', 'referral_code')) {
|
||||
$table->string('referral_code', 12)->nullable()->unique()->after('uuid');
|
||||
}
|
||||
if (!Schema::hasColumn('users', 'referred_by')) {
|
||||
$table->foreignId('referred_by')->nullable()->after('referral_code')
|
||||
->constrained('users')->nullOnDelete();
|
||||
}
|
||||
});
|
||||
|
||||
// Backfill a unique referral code for existing users
|
||||
$existing = DB::table('users')->whereNull('referral_code')->pluck('id');
|
||||
$used = DB::table('users')->whereNotNull('referral_code')->pluck('referral_code')->all();
|
||||
$used = array_flip($used);
|
||||
|
||||
foreach ($existing as $id) {
|
||||
do {
|
||||
$code = strtoupper(Str::random(8));
|
||||
} while (isset($used[$code]));
|
||||
$used[$code] = true;
|
||||
DB::table('users')->where('id', $id)->update(['referral_code' => $code]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('users', 'referred_by')) {
|
||||
$table->dropForeign(['referred_by']);
|
||||
$table->dropColumn('referred_by');
|
||||
}
|
||||
if (Schema::hasColumn('users', 'referral_code')) {
|
||||
$table->dropColumn('referral_code');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user