product_descriptions
This commit is contained in:
parent
274918cb8f
commit
de462ce77f
|
|
@ -1,2 +1,16 @@
|
|||
<?php
|
||||
|
||||
function locales(): array
|
||||
{
|
||||
$locales = [];
|
||||
$locales[] = [
|
||||
'name' => '中文简体',
|
||||
'code' => 'zh_cn',
|
||||
];
|
||||
$locales[] = [
|
||||
'name' => 'English',
|
||||
'code' => 'en',
|
||||
];
|
||||
|
||||
return $locales;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class ProductsController extends Controller
|
|||
public function index()
|
||||
{
|
||||
$products = Product::query()
|
||||
->with('description')
|
||||
->withCount('skus')
|
||||
->paginate();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Shop;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ProductSku;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CartsController extends Controller
|
||||
{
|
||||
public function store(Request $request, ProductSku $sku)
|
||||
{
|
||||
$quantity = $request->quantity ?? 1;
|
||||
dd($sku);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,12 @@ class ProductsController extends Controller
|
|||
{
|
||||
public function show(Request $request, Product $product)
|
||||
{
|
||||
$product->load('skus');
|
||||
dd($product);
|
||||
$product->load('description', 'skus');
|
||||
|
||||
$data = [
|
||||
'product' => $product,
|
||||
];
|
||||
|
||||
return view('product', $data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,16 @@ class Product extends Model
|
|||
|
||||
protected $fillable = ['image', 'video', 'position', 'active', 'variables'];
|
||||
|
||||
public function description()
|
||||
{
|
||||
return $this->hasOne(ProductDescription::class)->where('locale', 'zh_cn');
|
||||
}
|
||||
|
||||
public function descriptions()
|
||||
{
|
||||
return $this->hasMany(ProductDescription::class);
|
||||
}
|
||||
|
||||
public function skus()
|
||||
{
|
||||
return $this->hasMany(ProductSku::class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ProductDescription extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['locale', 'name', 'content', 'meta_title', 'meta_description', 'meta_keyword'];
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Services;
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Models\ProductDescription;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ProductService
|
||||
|
|
@ -28,13 +29,24 @@ class ProductService
|
|||
$product->fill($data);
|
||||
$product->saveOrFail();
|
||||
|
||||
$skus = [];
|
||||
foreach ($data['skus'] as $index => $rawSku) {
|
||||
$skus[] = $rawSku;
|
||||
}
|
||||
|
||||
if ($isUpdating) {
|
||||
$product->skus()->delete();
|
||||
$product->description()->delete();
|
||||
}
|
||||
|
||||
$descriptions = [];
|
||||
foreach ($data['descriptions'] as $locale => $description) {
|
||||
$description['locale'] = $locale;
|
||||
$description['content'] = $description['content'] ?? '';
|
||||
|
||||
$descriptions[] = $description;
|
||||
}
|
||||
$product->descriptions()->createMany($descriptions);
|
||||
|
||||
$skus = [];
|
||||
foreach ($data['skus'] as $index => $sku) {
|
||||
$sku->position = $index;
|
||||
$skus[] = $sku;
|
||||
}
|
||||
$product->skus()->createMany($skus);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,18 @@ class CreateTables extends Migration
|
|||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('product_descriptions', function (Blueprint $table) {
|
||||
$table->id()->startingValue(100_000);
|
||||
$table->unsignedBigInteger('product_id');
|
||||
$table->string('locale');
|
||||
$table->string('name');
|
||||
$table->text('content');
|
||||
$table->string('meta_title')->default('');
|
||||
$table->string('meta_description')->default('');
|
||||
$table->string('meta_keyword')->default('');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('product_skus', function (Blueprint $table) {
|
||||
$table->id()->startingValue(100_000);
|
||||
$table->unsignedBigInteger('product_id');
|
||||
|
|
@ -49,6 +61,7 @@ class CreateTables extends Migration
|
|||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('products');
|
||||
Schema::dropIfExists('product_descriptions');
|
||||
Schema::dropIfExists('product_skus');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,18 @@
|
|||
@csrf
|
||||
@method(($product ?? null) ? 'PUT' : 'POST')
|
||||
|
||||
<input type="text" name="name" placeholder="Name" value="{{ old('name', $product->name ?? '') }}">
|
||||
<input type="text" name="image" placeholder="image" value="{{ old('image', $product->image ?? '') }}">
|
||||
<input type="text" name="video" placeholder="video" value="{{ old('video', $product->video ?? '') }}">
|
||||
<input type="text" name="position" placeholder="position" value="{{ old('position', $product->position ?? 0) }}">
|
||||
<input type="text" name="active" placeholder="active" value="{{ old('active', $product->active ?? 1) }}">
|
||||
<div>
|
||||
@foreach (locales() as $locale)
|
||||
<input type="text" name="descriptions[{{ $locale['code'] }}][name]" placeholder="Name {{ $locale['name'] }}" value="{{ old('name', $product->descriptions->name ?? '') }}">
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="text" name="image" placeholder="image" value="{{ old('image', $product->image ?? '') }}">
|
||||
<input type="text" name="video" placeholder="video" value="{{ old('video', $product->video ?? '') }}">
|
||||
<input type="text" name="position" placeholder="position" value="{{ old('position', $product->position ?? 0) }}">
|
||||
<input type="text" name="active" placeholder="active" value="{{ old('active', $product->active ?? 1) }}">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>skus</h2>
|
||||
|
|
@ -60,7 +67,6 @@
|
|||
</template>
|
||||
<td>
|
||||
<input type="text" v-model="sku.image" :name="'skus[' + skuIndex + '][image]'" placeholder="image">
|
||||
<input type="hidden" :name="'skus[' + skuIndex + '][position]'" :value="skuIndex">
|
||||
<input type="hidden" :name="'skus[' + skuIndex + '][is_default]'" :value="skuIndex == 0 ? 1 : 0">
|
||||
<input v-for="(variantValueIndex, j) in sku.variants" type="hidden" :name="'skus[' + skuIndex + '][variants][' + j + ']'" :value="variantValueIndex">
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
@foreach ($products as $product)
|
||||
<tr>
|
||||
<td>{{ $product->id }}</td>
|
||||
<td>{{ $product->description->name ?? '--' }}</td>
|
||||
<td>{{ $product->variables ? '多规格' : '单规格' }}</td>
|
||||
<td>
|
||||
<a href="{{ route('admin.products.edit', $product) }}">编辑</a>
|
||||
|
|
|
|||
|
|
@ -7,5 +7,7 @@ Route::prefix('/')
|
|||
->group(function () {
|
||||
Route::get('/', [App\Http\Controllers\Shop\HomeController::class, 'index'])->name('home.index');
|
||||
|
||||
Route::get('carts/{sku}', [App\Http\Controllers\Shop\CartsController::class, 'store'])->name('carts.store');
|
||||
|
||||
Route::get('products/{product}', [App\Http\Controllers\Shop\ProductsController::class, 'show'])->name('products.show');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>{{ $product->description->name }}</p>
|
||||
|
||||
<h2>SKUs</h2>
|
||||
@foreach ($product->skus as $sku)
|
||||
<p>
|
||||
<span>model: {{ $sku->model }}</span>
|
||||
<span>price: {{ $sku->price }}</span>
|
||||
<a href="{{ route('shop.carts.store', $sku) }}">Add to cart</a>
|
||||
</p>
|
||||
@endforeach
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue