product_descriptions

This commit is contained in:
Sam Chen 2022-01-03 18:21:21 +08:00
parent 274918cb8f
commit de462ce77f
12 changed files with 127 additions and 13 deletions

View File

@ -1,2 +1,16 @@
<?php
function locales(): array
{
$locales = [];
$locales[] = [
'name' => '中文简体',
'code' => 'zh_cn',
];
$locales[] = [
'name' => 'English',
'code' => 'en',
];
return $locales;
}

View File

@ -13,6 +13,7 @@ class ProductsController extends Controller
public function index()
{
$products = Product::query()
->with('description')
->withCount('skus')
->paginate();

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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'];
}

View File

@ -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);

View File

@ -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');
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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');
});

View File

@ -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>