client api
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Client;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Api\Client\ClientAuthRequest;
|
||||
use App\Http\Requests\Api\Client\ClientRegisterRequest;
|
||||
use App\Http\Resources\Api\Client\ClientResource;
|
||||
use App\Services\Api\Client\ClientAuthService;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ClientController extends Controller
|
||||
{
|
||||
protected $authService;
|
||||
|
||||
public function __construct(ClientAuthService $authService)
|
||||
{
|
||||
$this->authService = $authService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lấy thông tin khách hàng hiện tại
|
||||
*/
|
||||
public function me()
|
||||
{
|
||||
return new ClientResource(auth('sanctum')->user());
|
||||
}
|
||||
|
||||
/**
|
||||
* Đăng nhập khách hàng
|
||||
*/
|
||||
public function login(ClientAuthRequest $request)
|
||||
{
|
||||
$result = $this->authService->authenticateClient($request->validated());
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'data' => [
|
||||
'client' => new ClientResource($result['client']),
|
||||
'token' => $result['token'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Đăng ký khách hàng mới
|
||||
*/
|
||||
public function register(ClientRegisterRequest $request)
|
||||
{
|
||||
$result = $this->authService->registerClient($request->validated());
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'data' => [
|
||||
'client' => new ClientResource($result['client']),
|
||||
'token' => $result['token'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Đăng xuất khách hàng
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
auth('sanctum')->user()->currentAccessToken()->delete();
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => 'Đã đăng xuất thành công.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Api\Client;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ClientAuthRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Allow request
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation rules
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'email' => [
|
||||
'required',
|
||||
'email',
|
||||
'exists:customers,email'
|
||||
],
|
||||
|
||||
'password' => [
|
||||
'required',
|
||||
'string',
|
||||
'min:6'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom messages (optional)
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'email.required' => 'Email là bắt buộc',
|
||||
'email.email' => 'Email không đúng định dạng',
|
||||
'email.exists' => 'Email không tồn tại',
|
||||
|
||||
'password.required' => 'Mật khẩu là bắt buộc',
|
||||
'password.min' => 'Mật khẩu tối thiểu 6 ký tự',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Api\Client;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ClientRegisterRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Allow request
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation rules
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'fullname' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'phone' => [
|
||||
'required',
|
||||
'digits:10',
|
||||
'unique:customers,phone'
|
||||
],
|
||||
|
||||
'email' => [
|
||||
'required',
|
||||
'email',
|
||||
'max:255',
|
||||
'unique:customers,email'
|
||||
],
|
||||
|
||||
'password' => [
|
||||
'required',
|
||||
'string',
|
||||
'min:6',
|
||||
'confirmed'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom messages
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'fullname.required' => 'Tên là bắt buộc',
|
||||
'phone.required' => 'Số điện thoại là bắt buộc',
|
||||
'phone.digits' => 'Số điện thoại phải có 10 chữ số',
|
||||
'phone.unique' => 'Số điện thoại đã tồn tại',
|
||||
'email.required' => 'Email là bắt buộc',
|
||||
'email.email' => 'Email không đúng định dạng',
|
||||
'email.unique' => 'Email đã tồn tại',
|
||||
|
||||
'password.required' => 'Mật khẩu là bắt buộc',
|
||||
'password.min' => 'Mật khẩu tối thiểu 6 ký tự',
|
||||
'password.confirmed' => 'Xác nhận mật khẩu không khớp',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,11 @@ class UserRegisterRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email|unique:customer',
|
||||
'email' => 'required|email|unique:customers',
|
||||
'firstname' => 'required',
|
||||
'lastname' => 'required',
|
||||
'password' => 'required|min:8',
|
||||
'phone' => 'required|unique:customer'
|
||||
'phone' => 'required|unique:customers'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class UserStoreInformation extends FormRequest
|
||||
return [
|
||||
'firstname' => 'required',
|
||||
'lastname' => 'required',
|
||||
'email' => 'nullable|email|unique:customer,email',
|
||||
'email' => 'nullable|email|unique:customers,email',
|
||||
'address' => 'nullable',
|
||||
'phone' => 'required',
|
||||
'gender' => 'nullable',
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Api\Client;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ClientResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
if (!$this->resource) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'customer' => [
|
||||
'name' => $this->fullname,
|
||||
'email' => $this->email,
|
||||
'phone' => $this->phone,
|
||||
'address' => $this->address,
|
||||
'city' => $this->city,
|
||||
'ward' => $this->ward,
|
||||
'province' => $this->province,
|
||||
'active_phone' => 1,
|
||||
'active_zalo' => 1,
|
||||
'gender' => $this->gender,
|
||||
'date' => $this->created_at ? $this->created_at->format('Y-m-d H:i:s') : null,
|
||||
'company' => $this->company ?? '',
|
||||
'mst' => null,
|
||||
'avatar' => $this->avatar,
|
||||
'cmnd_after' => $this->cmnd_after,
|
||||
'cmnd_before' => $this->cmnd_before,
|
||||
'cmnd_active' => (bool) $this->identity_number,
|
||||
'cmnd' => $this->cmnd,
|
||||
'fb_link' => null,
|
||||
'active_2fa' => 0,
|
||||
'off_mail_marketing' => $this->off_mail_marketing,
|
||||
'is_recharge_zalo' => 0,
|
||||
'is_verify_telegram' => 0,
|
||||
],
|
||||
'credit' => [
|
||||
'credit' => $this->credit,
|
||||
'total' => $this->total,
|
||||
'point' => $this->point,
|
||||
'point_used' => 0,
|
||||
'point_total' => $this->point,
|
||||
],
|
||||
'service' => [
|
||||
'vps' => $this->vps()->count(),
|
||||
'proxy' => 0,
|
||||
'server' => 0,
|
||||
'hosting' => $this->hosting()->count(),
|
||||
'domain' => $this->domain()->count(),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
+63
-7
@@ -2,19 +2,28 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class Customer extends Authenticatable
|
||||
{
|
||||
use HasFactory, HasApiTokens;
|
||||
use HasFactory, HasApiTokens, HasUuids;
|
||||
|
||||
protected $table = 'customer';
|
||||
protected $table = 'customers';
|
||||
|
||||
/**
|
||||
* Chỉ định cột sẽ nhận UUID.
|
||||
* Mặc định HasUuids dùng cột 'id', mình đổi sang 'uuid'.
|
||||
*/
|
||||
public function uniqueIds()
|
||||
{
|
||||
return ['uuid'];
|
||||
}
|
||||
|
||||
protected $fillable = [
|
||||
'firstname',
|
||||
'lastname',
|
||||
'fullname',
|
||||
'avatar',
|
||||
'address',
|
||||
'state',
|
||||
@@ -28,15 +37,26 @@ class Customer extends Authenticatable
|
||||
'email_hash',
|
||||
'email_marketing',
|
||||
'receive_deposit',
|
||||
'cccd',
|
||||
'front_cccd',
|
||||
'back_cccd',
|
||||
'identity_number',
|
||||
'front_identity_number',
|
||||
'back_identity_number',
|
||||
'password',
|
||||
'credit',
|
||||
'total',
|
||||
'remember_token',
|
||||
'status',
|
||||
'gender',
|
||||
'province_code',
|
||||
'ward_code',
|
||||
];
|
||||
|
||||
/**
|
||||
* Appends for API
|
||||
*/
|
||||
protected $appends = [
|
||||
'first_name',
|
||||
'last_name',
|
||||
'point',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -163,4 +183,40 @@ class Customer extends Authenticatable
|
||||
{
|
||||
return (bool) $this->receive_deposit;
|
||||
}
|
||||
|
||||
|
||||
public function getPointAttribute()
|
||||
{
|
||||
return (string) floor($this->total / 100);
|
||||
}
|
||||
|
||||
public function getCmndBeforeAttribute()
|
||||
{
|
||||
return $this->front_identity_number ?? '';
|
||||
}
|
||||
|
||||
public function getCmndAfterAttribute()
|
||||
{
|
||||
return $this->back_identity_number ?? '';
|
||||
}
|
||||
|
||||
public function getCmndAttribute()
|
||||
{
|
||||
return $this->identity_number;
|
||||
}
|
||||
|
||||
public function getOffMailMarketingAttribute()
|
||||
{
|
||||
return $this->email_marketing;
|
||||
}
|
||||
|
||||
public function province()
|
||||
{
|
||||
return $this->belongsTo(Province::class, 'province_code', 'code');
|
||||
}
|
||||
|
||||
public function ward()
|
||||
{
|
||||
return $this->belongsTo(Ward::class, 'ward_code', 'code');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Province extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'provinces';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* The primary key for the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'code';
|
||||
|
||||
/**
|
||||
* The "type" of the primary key ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $keyType = 'string';
|
||||
|
||||
/**
|
||||
* Indicates if the IDs are auto-incrementing.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $incrementing = false;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'name',
|
||||
'name_en',
|
||||
'full_name',
|
||||
'full_name_en',
|
||||
'code_name',
|
||||
'administrative_unit_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the administrative unit that owns the province.
|
||||
*/
|
||||
public function administrativeUnit()
|
||||
{
|
||||
return $this->belongsTo(AdministrativeUnit::class, 'administrative_unit_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the wards for the province.
|
||||
*/
|
||||
public function wards()
|
||||
{
|
||||
return $this->hasMany(Ward::class, 'province_code', 'code');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Ward extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'wards';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* The primary key for the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'code';
|
||||
|
||||
/**
|
||||
* The "type" of the primary key ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $keyType = 'string';
|
||||
|
||||
/**
|
||||
* Indicates if the IDs are auto-incrementing.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $incrementing = false;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'name',
|
||||
'name_en',
|
||||
'full_name',
|
||||
'full_name_en',
|
||||
'code_name',
|
||||
'province_code',
|
||||
'administrative_unit_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the province that owns the ward.
|
||||
*/
|
||||
public function province()
|
||||
{
|
||||
return $this->belongsTo(Province::class, 'province_code', 'code');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the administrative unit that owns the ward.
|
||||
*/
|
||||
public function administrativeUnit()
|
||||
{
|
||||
return $this->belongsTo(AdministrativeUnit::class, 'administrative_unit_id');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,6 +359,12 @@ class RepositoryProvider extends ServiceProvider
|
||||
ProductCategoryRepositoryInterface::class,
|
||||
ProductCategoryRepository::class
|
||||
);
|
||||
|
||||
// Client API
|
||||
$this->app->bind(
|
||||
\App\Repositories\Api\Client\ClientRepositoryInterface::class,
|
||||
\App\Repositories\Api\Client\ClientRepository::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\Api;
|
||||
|
||||
use App\Repositories\BaseRepositoryInterface;
|
||||
|
||||
abstract class BaseApiRepository implements BaseRepositoryInterface
|
||||
{
|
||||
protected $model;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->setModel();
|
||||
}
|
||||
|
||||
abstract public function getModel();
|
||||
|
||||
protected function setModel()
|
||||
{
|
||||
$this->model = app()->make($this->getModel());
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function create(array $data = [])
|
||||
{
|
||||
return $this->model->create($data);
|
||||
}
|
||||
|
||||
public function getAll()
|
||||
{
|
||||
return $this->model->all();
|
||||
}
|
||||
|
||||
public function find($id)
|
||||
{
|
||||
return $this->model->find($id);
|
||||
}
|
||||
|
||||
public function insert(array $data = [])
|
||||
{
|
||||
return $this->model->insert($data);
|
||||
}
|
||||
|
||||
public function update(int $id = 0, array $data = [])
|
||||
{
|
||||
$result = $this->find($id);
|
||||
|
||||
if ($result) {
|
||||
$result->update($data);
|
||||
return $result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$result = $this->find($id);
|
||||
if ($result) {
|
||||
$result->delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getCount()
|
||||
{
|
||||
return $this->model->count('id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\Api\Client;
|
||||
|
||||
use App\Models\Customer;
|
||||
use App\Repositories\Api\BaseApiRepository;
|
||||
|
||||
class ClientRepository extends BaseApiRepository implements ClientRepositoryInterface
|
||||
{
|
||||
public function getModel()
|
||||
{
|
||||
return Customer::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tìm khách hàng theo email
|
||||
*/
|
||||
public function findByEmail(string $email)
|
||||
{
|
||||
return $this->model->where('email', $email)->first();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\Api\Client;
|
||||
|
||||
use App\Repositories\BaseRepositoryInterface;
|
||||
|
||||
interface ClientRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Tìm khách hàng theo email
|
||||
*/
|
||||
public function findByEmail(string $email);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Api\Client;
|
||||
|
||||
use App\Repositories\Api\Client\ClientRepositoryInterface;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ClientAuthService
|
||||
{
|
||||
protected $clientRepository;
|
||||
|
||||
public function __construct(ClientRepositoryInterface $clientRepository)
|
||||
{
|
||||
$this->clientRepository = $clientRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Xác thực khách hàng và tạo token
|
||||
*/
|
||||
public function authenticateClient(array $credentials): array
|
||||
{
|
||||
if (!Auth::guard('client')->attempt($credentials)) {
|
||||
throw ValidationException::withMessages([
|
||||
'email' => ['Thông tin đăng nhập không chính xác.'],
|
||||
]);
|
||||
}
|
||||
|
||||
$client = Auth::guard('client')->user();
|
||||
$token = $client->createToken('client-token')->plainTextToken;
|
||||
|
||||
return [
|
||||
'client' => $client,
|
||||
'token' => $token,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Đăng ký khách hàng mới và tạo token
|
||||
*/
|
||||
public function registerClient(array $data): array
|
||||
{
|
||||
$client = $this->clientRepository->create([
|
||||
'fullname' => $data['fullname'],
|
||||
'phone' => $data['phone'],
|
||||
'email' => $data['email'],
|
||||
'password' => bcrypt($data['password']),
|
||||
]);
|
||||
|
||||
$token = $client->createToken('client-token')->plainTextToken;
|
||||
|
||||
return [
|
||||
'client' => $client,
|
||||
'token' => $token,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace app\Services\Api\Client;
|
||||
|
||||
class ClientService{
|
||||
|
||||
}
|
||||
+5
-1
@@ -51,7 +51,11 @@ return [
|
||||
'users-api' => [
|
||||
'driver' => 'passport',
|
||||
'provider' => 'users',
|
||||
]
|
||||
],
|
||||
'client' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'users',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('administrative_regions', function (Blueprint $table) {
|
||||
$table->integer('id')->primary();
|
||||
$table->string('name');
|
||||
$table->string('name_en');
|
||||
$table->string('code_name')->nullable();
|
||||
$table->string('code_name_en')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('administrative_regions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('administrative_units', function (Blueprint $table) {
|
||||
$table->integer('id')->primary();
|
||||
$table->string('full_name')->nullable();
|
||||
$table->string('full_name_en')->nullable();
|
||||
$table->string('short_name')->nullable();
|
||||
$table->string('short_name_en')->nullable();
|
||||
$table->string('code_name')->nullable();
|
||||
$table->string('code_name_en')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('administrative_units');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('provinces', function (Blueprint $table) {
|
||||
$table->string('code', 20)->primary();
|
||||
$table->string('name');
|
||||
$table->string('name_en')->nullable();
|
||||
$table->string('full_name');
|
||||
$table->string('full_name_en')->nullable();
|
||||
$table->string('code_name')->nullable();
|
||||
$table->integer('administrative_unit_id')->nullable();
|
||||
|
||||
$table->foreign('administrative_unit_id')
|
||||
->references('id')
|
||||
->on('administrative_units')
|
||||
->onDelete('set null');
|
||||
|
||||
$table->index('administrative_unit_id', 'idx_provinces_unit');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('provinces');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('wards', function (Blueprint $table) {
|
||||
$table->string('code', 20)->primary();
|
||||
$table->string('name');
|
||||
$table->string('name_en')->nullable();
|
||||
$table->string('full_name')->nullable();
|
||||
$table->string('full_name_en')->nullable();
|
||||
$table->string('code_name')->nullable();
|
||||
$table->string('province_code', 20)->nullable();
|
||||
$table->integer('administrative_unit_id')->nullable();
|
||||
|
||||
$table->foreign('administrative_unit_id')
|
||||
->references('id')
|
||||
->on('administrative_units')
|
||||
->onDelete('set null');
|
||||
|
||||
$table->foreign('province_code')
|
||||
->references('code')
|
||||
->on('provinces')
|
||||
->onDelete('set null');
|
||||
|
||||
$table->index('province_code', 'idx_wards_province');
|
||||
$table->index('administrative_unit_id', 'idx_wards_unit');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('wards');
|
||||
}
|
||||
};
|
||||
@@ -13,10 +13,10 @@ return new class extends Migration {
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::create('customer', function (Blueprint $table) {
|
||||
Schema::create('customers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('firstname', 100)->nullable();
|
||||
$table->string('lastname', 100)->nullable();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('fullname', 100)->nullable();
|
||||
$table->string('avatar', 100)->nullable();
|
||||
$table->integer('gender')->default(0);
|
||||
$table->string('address', 100)->nullable();
|
||||
@@ -34,12 +34,27 @@ return new class extends Migration {
|
||||
$table->string('password')->nullable();
|
||||
$table->integer('credit')->default(0);
|
||||
$table->integer('total')->default(0);
|
||||
$table->string('cccd')->nullable();
|
||||
$table->string('front_cccd')->nullable();
|
||||
$table->string('back_cccd')->nullable();
|
||||
$table->string('identity_number')->nullable();
|
||||
$table->string('front_identity_number')->nullable();
|
||||
$table->string('back_identity_number')->nullable();
|
||||
$table->string('province_code', 20)->nullable();
|
||||
$table->string('ward_code', 20)->nullable();
|
||||
$table->string('remember_token', 100)->nullable();
|
||||
$table->tinyInteger('status')->default(1);
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('province_code')
|
||||
->references('code')
|
||||
->on('provinces')
|
||||
->onDelete('set null');
|
||||
|
||||
$table->foreign('ward_code')
|
||||
->references('code')
|
||||
->on('wards')
|
||||
->onDelete('set null');
|
||||
|
||||
$table->index('province_code', 'idx_users_province');
|
||||
$table->index('ward_code', 'idx_users_ward');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ return new class extends Migration
|
||||
|
||||
// 3. Add foreign key constraints
|
||||
Schema::table('order', function (Blueprint $table) {
|
||||
$table->foreign('customer_id')->references('id')->on('customer')->onDelete('set null');
|
||||
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('set null');
|
||||
$table->foreign('user_id')->references('id')->on('user')->onDelete('set null');
|
||||
$table->foreign('discount_id')->references('id')->on('discount')->onDelete('set null');
|
||||
$table->foreign('invoice_id')->references('id')->on('invoice')->onDelete('set null');
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@ class DatabaseSeeder extends Seeder
|
||||
User::factory(1)->create();
|
||||
$this->call(TypeSeeder::class);
|
||||
$this->call(DomainTypeSeeder::class);
|
||||
Customer::factory(10)->create();
|
||||
$this->call(GroupSeeder::class);
|
||||
$this->call(Payment::class);
|
||||
$this->call(AddonSeeder::class);
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Api\Client\ClientController;
|
||||
use App\Http\Controllers\rest\ModuleController;
|
||||
use App\Http\Services\Media;
|
||||
use App\Http\Services\vCenter as ServiceVCenter;
|
||||
@@ -187,7 +188,7 @@ Route::prefix('v1')
|
||||
})->name('api.GetVersionOs');
|
||||
Route::post('get-all-image', function (Media $media) {
|
||||
$files = $media->getAllMedia();
|
||||
$data = view('administrator.pages.component.media')->with('media', $files)->render();
|
||||
$data = view('administrator.pages.component.media')->with('media', $files)->render();
|
||||
return response()->json(['data' => $data]);
|
||||
})->name('api.GetAllImage');
|
||||
Route::get('get-list-addon', function () {
|
||||
@@ -197,7 +198,7 @@ Route::prefix('v1')
|
||||
}
|
||||
|
||||
$allAddon = Addon::get();
|
||||
$formAddon = view('administrator.pages.component.addon')->with([
|
||||
$formAddon = view('administrator.pages.component.addon')->with([
|
||||
'addon' => $allAddon
|
||||
])->render();
|
||||
|
||||
|
||||
+16
-7
@@ -1,18 +1,27 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Http\Controllers\Api\Client\ClientController;
|
||||
|
||||
|
||||
|
||||
Route::prefix('v1')->group(function () {
|
||||
Route::get('get-list-product', function () {
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'data' => Product::all()
|
||||
]);
|
||||
})->name('api.user.GetListProduct');
|
||||
// Auth
|
||||
Route::prefix('client')->as('client.')
|
||||
->group(function () {
|
||||
Route::controller(ClientController::class)->group(function () {
|
||||
Route::post('login', 'login')->name('login');
|
||||
Route::post('register', 'register')->name('register');
|
||||
|
||||
Route::group(['middleware' => ['api.auth']], function () {
|
||||
Route::get('me', 'me')->name('me');
|
||||
Route::post('logout', 'logout')->name('logout');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
Route::any('{any}', function () {
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
|
||||
Reference in New Issue
Block a user