parent
1276d0a98b
commit
7e972a8723
|
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
/**
|
||||
* PageCategoryController.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-09 10:21:27
|
||||
* @modified 2023-02-09 10:21:27
|
||||
*/
|
||||
|
||||
namespace Beike\Admin\Http\Controllers;
|
||||
|
||||
use Beike\Admin\Http\Requests\PageCategoryRequest;
|
||||
use Beike\Admin\Http\Resources\PageCategoryResource;
|
||||
use Beike\Models\PageCategory;
|
||||
use Beike\Repositories\PageCategoryRepo;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PageCategoryController extends Controller
|
||||
{
|
||||
/**
|
||||
* 显示文章分类列表
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$pageCategoryList = PageCategoryRepo::getList();
|
||||
$data = [
|
||||
'page_categories' => $pageCategoryList,
|
||||
'page_categories_format' => PageCategoryResource::collection($pageCategoryList)->jsonSerialize(),
|
||||
];
|
||||
|
||||
return view('admin::pages.page_categories.index', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文章分类
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(): mixed
|
||||
{
|
||||
return view('admin::pages.page_categories.form', ['page_category' => new PageCategory()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存新建
|
||||
*
|
||||
* @param PageCategoryRequest $request
|
||||
* @return RedirectResponse
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function store(PageCategoryRequest $request)
|
||||
{
|
||||
try {
|
||||
$requestData = $request->all();
|
||||
PageCategoryRepo::createOrUpdate($requestData);
|
||||
|
||||
return redirect(admin_route('page_categories.index'));
|
||||
} catch (\Exception $e) {
|
||||
return redirect(admin_route('page_categories.index'))->withErrors(['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param PageCategory $pageCategory
|
||||
* @return mixed
|
||||
*/
|
||||
public function edit(Request $request, PageCategory $pageCategory)
|
||||
{
|
||||
$pageCategory->load(['descriptions', 'parent.description']);
|
||||
$descriptions = $pageCategory->descriptions->keyBy('locale')->toArray();
|
||||
$data = [
|
||||
'page_category' => $pageCategory,
|
||||
'descriptions' => $descriptions,
|
||||
];
|
||||
|
||||
return view('admin::pages.page_categories.form', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新
|
||||
*
|
||||
* @param PageCategoryRequest $request
|
||||
* @param PageCategory $pageCategory
|
||||
* @return RedirectResponse
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function update(PageCategoryRequest $request, PageCategory $pageCategory)
|
||||
{
|
||||
try {
|
||||
$requestData = $request->all();
|
||||
$requestData['id'] = $pageCategory->id;
|
||||
PageCategoryRepo::createOrUpdate($requestData);
|
||||
|
||||
return redirect()->to(admin_route('page_categories.index'));
|
||||
} catch (\Exception $e) {
|
||||
return redirect(admin_route('page_categories.index'))->withErrors(['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单页
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $pageId
|
||||
* @return array
|
||||
*/
|
||||
public function destroy(Request $request, int $pageId): array
|
||||
{
|
||||
PageCategoryRepo::deleteById($pageId);
|
||||
|
||||
return json_success(trans('common.deleted_success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索页面标题自动完成
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function autocomplete(Request $request): array
|
||||
{
|
||||
$products = PageCategoryRepo::autocomplete($request->get('name') ?? '');
|
||||
|
||||
return json_success(trans('common.get_success'), $products);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单页名称
|
||||
* @param PageCategory $pageCategory
|
||||
* @return array
|
||||
*/
|
||||
public function name(PageCategory $pageCategory): array
|
||||
{
|
||||
$name = $pageCategory->description->title ?? '';
|
||||
|
||||
return json_success(trans('common.get_success'), $name);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,10 +15,11 @@ use Beike\Admin\Http\Requests\PageRequest;
|
|||
use Beike\Admin\Repositories\PageRepo;
|
||||
use Beike\Models\Page;
|
||||
use Beike\Shop\Http\Resources\PageDetail;
|
||||
use Beike\Shop\Http\Resources\ProductSimple;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PagesController
|
||||
class PagesController extends Controller
|
||||
{
|
||||
/**
|
||||
* 显示单页列表
|
||||
|
|
@ -66,14 +67,17 @@ class PagesController
|
|||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param int $pageId
|
||||
* @param Page $page
|
||||
* @return mixed
|
||||
*/
|
||||
public function edit(Request $request, int $pageId)
|
||||
public function edit(Request $request, Page $page)
|
||||
{
|
||||
$page->load(['products.description', 'category.description']);
|
||||
|
||||
$data = [
|
||||
'page' => PageRepo::findByPageId($pageId),
|
||||
'descriptions' => PageRepo::getDescriptionsByLocale($pageId),
|
||||
'page' => $page,
|
||||
'products' => ProductSimple::collection($page->products)->jsonSerialize(),
|
||||
'descriptions' => PageRepo::getDescriptionsByLocale($page->id),
|
||||
];
|
||||
|
||||
return view('admin::pages.pages.form', $data);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/**
|
||||
* PageCategoryRequest.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-10 16:04:14
|
||||
* @modified 2023-02-10 16:04:14
|
||||
*/
|
||||
|
||||
namespace Beike\Admin\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class PageCategoryRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'descriptions.*.locale' => 'required|string',
|
||||
'descriptions.*.title' => 'required|string|min:3|max:32',
|
||||
'descriptions.*.summary' => 'string',
|
||||
];
|
||||
}
|
||||
|
||||
public function attributes()
|
||||
{
|
||||
return [
|
||||
'title' => trans('page_category.title'),
|
||||
'summary' => trans('page_category.summary'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ class PageRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'descriptions.*.title' => 'required|string|min:3|max:32',
|
||||
'descriptions.*.title' => 'required|string|min:3|max:128',
|
||||
'descriptions.*.content' => 'required|string',
|
||||
'descriptions.*.locale' => 'required|string',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
/**
|
||||
* PageCategoryResource.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-10 09:20:33
|
||||
* @modified 2023-02-10 09:20:33
|
||||
*/
|
||||
|
||||
namespace Beike\Admin\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PageCategoryResource extends JsonResource
|
||||
{
|
||||
public function toArray($request): array
|
||||
{
|
||||
$description = $this->description;
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'active' => $this->active,
|
||||
'title' => $description->title,
|
||||
'title_format' => sub_string($description->title),
|
||||
'summary' => $description->summary,
|
||||
'summary_format' => sub_string($description->summary, 128),
|
||||
'meta_title' => $description->meta_title,
|
||||
'meta_description' => $description->meta_description,
|
||||
'meta_keywords' => $description->meta_keywords,
|
||||
'created_at' => time_format($this->created_at),
|
||||
'updated_at' => time_format($this->updated_at),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -70,14 +70,31 @@ class PageRepo
|
|||
$page = new Page();
|
||||
}
|
||||
$page->fill([
|
||||
'position' => $data['position'] ?? 0,
|
||||
'active' => $data['active'] ?? true,
|
||||
'page_category_id' => (int) ($data['page_category_id'] ?? 0),
|
||||
'position' => $data['position'] ?? 0,
|
||||
'active' => $data['active'] ?? true,
|
||||
'author' => $data['author'] ?? true,
|
||||
'views' => $data['views'] ?? 0,
|
||||
]);
|
||||
|
||||
$page->saveOrFail();
|
||||
|
||||
$page->descriptions()->delete();
|
||||
$page->descriptions()->createMany($data['descriptions']);
|
||||
$page->load(['descriptions']);
|
||||
|
||||
$products = $data['products'] ?? [];
|
||||
if ($products) {
|
||||
$items = [];
|
||||
foreach ($products as $item) {
|
||||
$items[] = [
|
||||
'product_id' => $item,
|
||||
];
|
||||
}
|
||||
$page->pageProducts()->delete();
|
||||
$page->pageProducts()->createMany($items);
|
||||
}
|
||||
|
||||
$page->load(['descriptions', 'pageProducts']);
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,16 +154,26 @@ Route::prefix($adminName)
|
|||
Route::middleware('can:marketing_buy')->post('marketing/{code}/buy', [Controllers\MarketingController::class, 'buy'])->name('marketing.buy');
|
||||
Route::middleware('can:marketing_download')->post('marketing/{code}/download', [Controllers\MarketingController::class, 'download'])->name('marketing.download');
|
||||
|
||||
// 单页
|
||||
// 文章
|
||||
Route::middleware('can:pages_index')->get('pages', [Controllers\PagesController::class, 'index'])->name('pages.index');
|
||||
Route::middleware('can:pages_index')->get('pages/autocomplete', [Controllers\PagesController::class, 'autocomplete'])->name('pages.autocomplete');
|
||||
Route::middleware('can:pages_create')->get('pages/create', [Controllers\PagesController::class, 'create'])->name('pages.create');
|
||||
Route::middleware('can:pages_show')->get('pages/{code}/edit', [Controllers\PagesController::class, 'edit'])->name('pages.edit');
|
||||
Route::middleware('can:pages_show')->get('pages/{page}/edit', [Controllers\PagesController::class, 'edit'])->name('pages.edit');
|
||||
Route::middleware('can:pages_show')->get('pages/{page}/name', [Controllers\PagesController::class, 'name'])->name('pages.name');
|
||||
Route::middleware('can:pages_create')->post('pages', [Controllers\PagesController::class, 'store'])->name('pages.store');
|
||||
Route::middleware('can:pages_update')->put('pages/{page}', [Controllers\PagesController::class, 'update'])->name('pages.update');
|
||||
Route::middleware('can:pages_delete')->delete('pages/{page}', [Controllers\PagesController::class, 'destroy'])->name('pages.destroy');
|
||||
|
||||
// 文章分类
|
||||
Route::middleware('can:page_categories_index')->get('page_categories', [Controllers\PageCategoryController::class, 'index'])->name('page_categories.index');
|
||||
Route::middleware('can:page_categories_index')->get('page_categories/autocomplete', [Controllers\PageCategoryController::class, 'autocomplete'])->name('page_categories.autocomplete');
|
||||
Route::middleware('can:page_categories_create')->get('page_categories/create', [Controllers\PageCategoryController::class, 'create'])->name('page_categories.create');
|
||||
Route::middleware('can:page_categories_show')->get('page_categories/{page_category}/edit', [Controllers\PageCategoryController::class, 'edit'])->name('page_categories.edit');
|
||||
Route::middleware('can:page_categories_show')->get('page_categories/{page_category}/name', [Controllers\PageCategoryController::class, 'name'])->name('page_categories.name');
|
||||
Route::middleware('can:page_categories_create')->post('page_categories', [Controllers\PageCategoryController::class, 'store'])->name('page_categories.store');
|
||||
Route::middleware('can:page_categories_update')->put('page_categories/{page_category}', [Controllers\PageCategoryController::class, 'update'])->name('page_categories.update');
|
||||
Route::middleware('can:page_categories_delete')->delete('page_categories/{page_category}', [Controllers\PageCategoryController::class, 'destroy'])->name('page_categories.destroy');
|
||||
|
||||
// 商品
|
||||
Route::middleware('can:products_restore')->put('products/restore', [Controllers\ProductController::class, 'restore']);
|
||||
Route::middleware('can:products_trashed')->get('products/trashed', [Controllers\ProductController::class, 'trashed'])->name('products.trashed');
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ class Sidebar extends Component
|
|||
*/
|
||||
private function getPageSubPrefix()
|
||||
{
|
||||
$prefix = ['pages.'];
|
||||
$prefix = ['pages.', 'page_categories.'];
|
||||
|
||||
return hook_filter('admin.sidebar.page.prefix', $prefix);
|
||||
}
|
||||
|
|
@ -230,12 +230,13 @@ class Sidebar extends Component
|
|||
}
|
||||
|
||||
/**
|
||||
* 获取内容管理子页面路由
|
||||
* 获取文章管理子页面路由
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPageSubRoutes()
|
||||
{
|
||||
$routes = [
|
||||
['route' => 'page_categories.index', 'icon' => 'fa fa-tachometer-alt'],
|
||||
['route' => 'pages.index', 'icon' => 'fa fa-tachometer-alt'],
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use Beike\Repositories\BrandRepo;
|
|||
use Beike\Repositories\CategoryRepo;
|
||||
use Beike\Repositories\CurrencyRepo;
|
||||
use Beike\Repositories\LanguageRepo;
|
||||
use Beike\Repositories\PageCategoryRepo;
|
||||
use Beike\Repositories\PageRepo;
|
||||
use Beike\Repositories\ProductRepo;
|
||||
use Beike\Services\CurrencyService;
|
||||
|
|
@ -117,7 +118,7 @@ function shop_route($route, $params = []): string
|
|||
*/
|
||||
function type_route($type, $value): string
|
||||
{
|
||||
$types = ['category', 'product', 'brand', 'page', 'order', 'rma', 'static', 'custom'];
|
||||
$types = ['category', 'product', 'brand', 'page', 'page_category', 'order', 'rma', 'static', 'custom'];
|
||||
if (empty($type) || empty($value) || ! in_array($type, $types)) {
|
||||
return '';
|
||||
}
|
||||
|
|
@ -133,6 +134,8 @@ function type_route($type, $value): string
|
|||
return shop_route('brands.show', [$value]);
|
||||
} elseif ($type == 'page') {
|
||||
return shop_route('pages.show', ['page' => $value]);
|
||||
} elseif ($type == 'page_category') {
|
||||
return shop_route('page_categories.show', ['page_category' => $value]);
|
||||
} elseif ($type == 'order') {
|
||||
return shop_route('account.order.show', ['number' => $value]);
|
||||
} elseif ($type == 'rma') {
|
||||
|
|
@ -160,7 +163,7 @@ function type_route($type, $value): string
|
|||
*/
|
||||
function type_label($type, $value, array $texts = []): string
|
||||
{
|
||||
$types = ['category', 'product', 'brand', 'page', 'static', 'custom'];
|
||||
$types = ['category', 'product', 'brand', 'page', 'page_category', 'static', 'custom'];
|
||||
if (empty($type) || empty($value) || ! in_array($type, $types)) {
|
||||
return '';
|
||||
}
|
||||
|
|
@ -179,7 +182,9 @@ function type_label($type, $value, array $texts = []): string
|
|||
return BrandRepo::getName($value);
|
||||
} elseif ($type == 'page') {
|
||||
return PageRepo::getName($value);
|
||||
} elseif ($type == 'static') {
|
||||
} elseif ($type == 'page_category') {
|
||||
return PageCategoryRepo::getName($value);
|
||||
} elseif ($type == 'static') {
|
||||
return trans('shop/' . $value);
|
||||
} elseif ($type == 'custom') {
|
||||
return $text;
|
||||
|
|
|
|||
|
|
@ -11,13 +11,15 @@
|
|||
|
||||
namespace Beike\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
class Page extends Base
|
||||
{
|
||||
protected $fillable = [
|
||||
'position', 'active',
|
||||
'page_category_id', 'position', 'views', 'author', 'active',
|
||||
];
|
||||
|
||||
public function description(): HasOne
|
||||
|
|
@ -29,4 +31,19 @@ class Page extends Base
|
|||
{
|
||||
return $this->hasMany(PageDescription::class);
|
||||
}
|
||||
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(PageCategory::class, 'page_category_id', 'id');
|
||||
}
|
||||
|
||||
public function pageProducts(): HasMany
|
||||
{
|
||||
return $this->hasMany(PageProduct::class);
|
||||
}
|
||||
|
||||
public function products(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Product::class, PageProduct::class, 'page_id', 'product_id')->withTimestamps();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/**
|
||||
* PageCategory.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-09 10:31:38
|
||||
* @modified 2023-02-09 10:31:38
|
||||
*/
|
||||
|
||||
namespace Beike\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
class PageCategory extends Model
|
||||
{
|
||||
protected $table = 'page_categories';
|
||||
|
||||
protected $fillable = [
|
||||
'parent_id', 'position', 'active',
|
||||
];
|
||||
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(self::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function children(): HasMany
|
||||
{
|
||||
return $this->hasMany(self::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function descriptions(): HasMany
|
||||
{
|
||||
return $this->hasMany(PageCategoryDescription::class);
|
||||
}
|
||||
|
||||
public function description(): HasOne
|
||||
{
|
||||
return $this->hasOne(PageCategoryDescription::class)->where('locale', locale());
|
||||
}
|
||||
|
||||
public function pages(): HasMany
|
||||
{
|
||||
return $this->hasMany(Page::class, 'page_category_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/**
|
||||
* PageCategoryDescription.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-09 10:33:08
|
||||
* @modified 2023-02-09 10:33:08
|
||||
*/
|
||||
|
||||
namespace Beike\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class PageCategoryDescription extends Model
|
||||
{
|
||||
protected $table = 'page_category_descriptions';
|
||||
|
||||
protected $fillable = [
|
||||
'page_category_id', 'locale', 'title', 'summary', 'meta_title', 'meta_description', 'meta_keywords',
|
||||
];
|
||||
}
|
||||
|
|
@ -14,6 +14,6 @@ namespace Beike\Models;
|
|||
class PageDescription extends Base
|
||||
{
|
||||
protected $fillable = [
|
||||
'page_id', 'locale', 'title', 'content', 'meta_title', 'meta_description', 'meta_keywords',
|
||||
'page_id', 'locale', 'title', 'content', 'summary', 'meta_title', 'meta_description', 'meta_keywords',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* PageProduct.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-10 14:49:45
|
||||
* @modified 2023-02-10 14:49:45
|
||||
*/
|
||||
|
||||
namespace Beike\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PageProduct extends Model
|
||||
{
|
||||
protected $table = 'page_products';
|
||||
|
||||
protected $fillable = ['page_id', 'product_id'];
|
||||
|
||||
public function product(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
/**
|
||||
* PageCategoryRepo.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-09 10:26:26
|
||||
* @modified 2023-02-09 10:26:26
|
||||
*/
|
||||
|
||||
namespace Beike\Repositories;
|
||||
|
||||
use Beike\Models\PageCategory;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class PageCategoryRepo
|
||||
{
|
||||
/**
|
||||
* @param array $filters
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public static function getList(array $filters = []): LengthAwarePaginator
|
||||
{
|
||||
$builder = self::getBuilder($filters);
|
||||
|
||||
return $builder->paginate(perPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filters
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public static function getActiveList(array $filters = []): LengthAwarePaginator
|
||||
{
|
||||
$filters['is_active'] = 1;
|
||||
$builder = self::getBuilder($filters);
|
||||
|
||||
return $builder->paginate(perPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filters
|
||||
* @return Builder
|
||||
*/
|
||||
public static function getBuilder(array $filters = []): Builder
|
||||
{
|
||||
$builder = PageCategory::query()->with('description');
|
||||
|
||||
$name = $filters['name'] ?? '';
|
||||
if ($name) {
|
||||
$builder->whereRelation('description', 'title', 'like', "%{$name}%");
|
||||
}
|
||||
|
||||
if (isset($filters['is_active'])) {
|
||||
$builder->where('active', (bool) $filters['is_active']);
|
||||
}
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建或更新文章分类
|
||||
*
|
||||
* @param $data
|
||||
* @return mixed
|
||||
* @throws \Exception|\Throwable
|
||||
*/
|
||||
public static function createOrUpdate($data): mixed
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$pageCategory = self::pushPageCategory($data);
|
||||
DB::commit();
|
||||
|
||||
return $pageCategory;
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private static function pushPageCategory($data)
|
||||
{
|
||||
$id = $data['id'] ?? 0;
|
||||
if (empty($id)) {
|
||||
$pageCategory = new PageCategory($data);
|
||||
} else {
|
||||
$pageCategory = PageCategory::query()->find($id);
|
||||
}
|
||||
|
||||
$pageCategory->fill([
|
||||
'parent_id' => (int) ($data['parent_id'] ?? 0),
|
||||
'position' => (int) ($data['position'] ?? 0),
|
||||
'active' => (bool) ($data['active'] ?? false),
|
||||
]);
|
||||
$pageCategory->saveOrFail();
|
||||
|
||||
$descriptions = $data['descriptions'] ?? [];
|
||||
if ($descriptions) {
|
||||
$pageCategory->descriptions()->delete();
|
||||
$pageCategory->descriptions()->createMany($data['descriptions']);
|
||||
}
|
||||
$pageCategory->load(['descriptions']);
|
||||
|
||||
return $pageCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文章分类
|
||||
*/
|
||||
public static function deleteById($pageCategoryId)
|
||||
{
|
||||
$pageCategory = PageCategory::query()->findOrFail($pageCategoryId);
|
||||
$pageCategory->descriptions()->delete();
|
||||
$pageCategory->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过名字搜索文章分类
|
||||
*
|
||||
* @param $name
|
||||
* @return array
|
||||
*/
|
||||
public static function autocomplete($name)
|
||||
{
|
||||
$pageCategories = self::getBuilder()
|
||||
->whereHas('description', function ($query) use ($name) {
|
||||
$query->where('title', 'like', "%{$name}%");
|
||||
})->limit(10)->get();
|
||||
|
||||
$results = [];
|
||||
foreach ($pageCategories as $item) {
|
||||
$results[] = [
|
||||
'id' => $item->id,
|
||||
'name' => $item->description->title,
|
||||
'status' => $item->active,
|
||||
];
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $page
|
||||
* @return string
|
||||
*/
|
||||
public static function getName($page)
|
||||
{
|
||||
return $page->description->title ?? '';
|
||||
}
|
||||
}
|
||||
|
|
@ -12,15 +12,53 @@
|
|||
namespace Beike\Repositories;
|
||||
|
||||
use Beike\Models\Page;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class PageRepo
|
||||
{
|
||||
private static $allPagesWithName;
|
||||
|
||||
public static function getBuilder(): Builder
|
||||
/**
|
||||
* @param array $filters
|
||||
* @return Builder
|
||||
*/
|
||||
public static function getBuilder(array $filters = []): Builder
|
||||
{
|
||||
return Page::query()->with('description');
|
||||
$builder = Page::query()->with('description');
|
||||
if (isset($filters['is_active'])) {
|
||||
$builder->where('active', (bool) $filters['is_active']);
|
||||
}
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有启用的文章列表
|
||||
*
|
||||
* @param array $filters
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public static function getActivePages(array $filters = []): LengthAwarePaginator
|
||||
{
|
||||
$filters['is_active'] = 1;
|
||||
$filters['category_id'] = 0;
|
||||
$builder = self::getBuilder($filters);
|
||||
|
||||
return $builder->paginate(perPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取启用的非单页
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public static function getCategoryPages(): LengthAwarePaginator
|
||||
{
|
||||
$filters['is_active'] = 1;
|
||||
$builder = self::getBuilder($filters)->whereNot('page_category_id', 0);
|
||||
|
||||
return $builder->paginate(perPage());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PageCategoryController.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-10 11:39:46
|
||||
* @modified 2023-02-10 11:39:46
|
||||
*/
|
||||
|
||||
namespace Beike\Shop\Http\Controllers;
|
||||
|
||||
use Beike\Libraries\Breadcrumb;
|
||||
use Beike\Models\PageCategory;
|
||||
use Beike\Repositories\PageCategoryRepo;
|
||||
use Beike\Repositories\PageRepo;
|
||||
use Beike\Shop\Http\Resources\PageCategoryDetail;
|
||||
|
||||
class PageCategoryController extends Controller
|
||||
{
|
||||
public function home()
|
||||
{
|
||||
$breadCrumb = Breadcrumb::getInstance()
|
||||
->addLink(shop_route('page_categories.home'), trans('page_category.index'));
|
||||
|
||||
$data = [
|
||||
'breadcrumb' => $breadCrumb,
|
||||
'active_page_categories' => PageCategoryRepo::getActiveList(),
|
||||
'active_pages' => PageRepo::getCategoryPages(),
|
||||
];
|
||||
|
||||
return view('page_categories/home', $data);
|
||||
}
|
||||
|
||||
public function show(PageCategory $pageCategory)
|
||||
{
|
||||
$breadCrumb = Breadcrumb::getInstance()
|
||||
->addLink(shop_route('page_categories.home'), trans('page_category.index'));
|
||||
|
||||
$data = [
|
||||
'category' => new PageCategoryDetail($pageCategory),
|
||||
'active_page_categories' => PageCategoryRepo::getActiveList(),
|
||||
'breadcrumb' => $breadCrumb,
|
||||
'category_pages' => $pageCategory->pages()->paginate(perPage()),
|
||||
];
|
||||
|
||||
return view('page_categories/show', $data);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,19 +12,30 @@
|
|||
namespace Beike\Shop\Http\Controllers;
|
||||
|
||||
use Beike\Models\Page;
|
||||
use Beike\Repositories\PageCategoryRepo;
|
||||
use Beike\Shop\Http\Resources\PageDetail;
|
||||
use Beike\Shop\Http\Resources\ProductSimple;
|
||||
|
||||
class PageController extends Controller
|
||||
{
|
||||
public function show(Page $page)
|
||||
{
|
||||
$page->load('description');
|
||||
$page->load(['description', 'category.description', 'products.description']);
|
||||
$page->increment('views');
|
||||
|
||||
$data = [
|
||||
'page' => (new PageDetail($page))->jsonSerialize(),
|
||||
'page' => $page,
|
||||
'active_page_categories' => PageCategoryRepo::getActiveList(),
|
||||
'page_format' => (new PageDetail($page))->jsonSerialize(),
|
||||
'products' => ProductSimple::collection($page->products)->jsonSerialize(),
|
||||
];
|
||||
|
||||
$data = hook_filter('page.show.data', $data);
|
||||
|
||||
return view('pages/detail', $data);
|
||||
if ($page->category) {
|
||||
return view('pages/article', $data);
|
||||
}
|
||||
|
||||
return view('pages/single', $data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
/**
|
||||
* PageCategoryDetail.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-10 11:54:20
|
||||
* @modified 2023-02-10 11:54:20
|
||||
*/
|
||||
|
||||
namespace Beike\Shop\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PageCategoryDetail extends JsonResource
|
||||
{
|
||||
public function toArray($request): array
|
||||
{
|
||||
$description = $this->description;
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'active' => $this->active,
|
||||
'title' => $description->title,
|
||||
'title_format' => sub_string($description->title),
|
||||
'summary' => $description->summary,
|
||||
'summary_format' => sub_string($description->summary, 128),
|
||||
'meta_title' => $description->meta_title,
|
||||
'meta_description' => $description->meta_description,
|
||||
'meta_keywords' => $description->meta_keywords,
|
||||
'created_at' => time_format($this->created_at),
|
||||
'updated_at' => time_format($this->updated_at),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -26,16 +26,21 @@ class PageDetail extends JsonResource
|
|||
$description = $this->description;
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'active' => $this->active,
|
||||
'title' => $description->title,
|
||||
'title_format' => sub_string($description->title),
|
||||
'content' => $description->content,
|
||||
'meta_title' => $description->meta_title,
|
||||
'meta_description' => $description->meta_description,
|
||||
'meta_keywords' => $description->meta_keywords,
|
||||
'created_at' => time_format($this->created_at),
|
||||
'updated_at' => time_format($this->updated_at),
|
||||
'id' => $this->id,
|
||||
'parent_id' => $this->parent_id,
|
||||
'active' => $this->active,
|
||||
'author' => $this->author,
|
||||
'views' => $this->views,
|
||||
'title' => $description->title,
|
||||
'title_format' => sub_string($description->title),
|
||||
'content' => $description->content,
|
||||
'summary' => $description->summary,
|
||||
'summary_format' => sub_string($description->summary, 100),
|
||||
'meta_title' => $description->meta_title,
|
||||
'meta_description' => $description->meta_description,
|
||||
'meta_keywords' => $description->meta_keywords,
|
||||
'created_at' => time_format($this->created_at),
|
||||
'updated_at' => time_format($this->updated_at),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use Beike\Shop\Http\Controllers\CurrencyController;
|
|||
use Beike\Shop\Http\Controllers\FileController;
|
||||
use Beike\Shop\Http\Controllers\HomeController;
|
||||
use Beike\Shop\Http\Controllers\LanguageController;
|
||||
use Beike\Shop\Http\Controllers\PageCategoryController;
|
||||
use Beike\Shop\Http\Controllers\PageController;
|
||||
use Beike\Shop\Http\Controllers\ProductController;
|
||||
use Beike\Shop\Http\Controllers\ZoneController;
|
||||
|
|
@ -54,6 +55,8 @@ Route::prefix('/')
|
|||
Route::post('login', [LoginController::class, 'store'])->name('login.store');
|
||||
Route::get('logout', [LogoutController::class, 'index'])->name('logout');
|
||||
|
||||
Route::get('page_categories', [PageCategoryController::class, 'home'])->name('page_categories.home');
|
||||
Route::get('page_categories/{page_category}', [PageCategoryController::class, 'show'])->name('page_categories.show');
|
||||
Route::get('pages/{page}', [PageController::class, 'show'])->name('pages.show');
|
||||
|
||||
Route::get('products/search', [ProductController::class, 'search'])->name('products.search');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace Beike\Shop\View\Components;
|
||||
|
||||
use Beike\Models\Page;
|
||||
use Beike\Models\PageCategory;
|
||||
use Beike\Models\Product;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
|
|
@ -42,6 +44,10 @@ class Breadcrumb extends Component
|
|||
$breadcrumbs = array_merge($breadcrumbs, $this->handleOrderLinks($value));
|
||||
} elseif ($type == 'rma') {
|
||||
$breadcrumbs = array_merge($breadcrumbs, $this->handleRmaLinks($value));
|
||||
} elseif ($type == 'page') {
|
||||
$breadcrumbs = array_merge($breadcrumbs, $this->handlePageLinks($value));
|
||||
} elseif ($type == 'page_category') {
|
||||
$breadcrumbs = array_merge($breadcrumbs, $this->handlePageCategoryLinks($value));
|
||||
} elseif (Str::startsWith($value, 'account')) {
|
||||
$breadcrumbs = array_merge($breadcrumbs, $this->handleAccountLinks($value));
|
||||
} else {
|
||||
|
|
@ -173,6 +179,70 @@ class Breadcrumb extends Component
|
|||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文章页面包屑
|
||||
*
|
||||
* @param $value
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function handlePageLinks($value): array
|
||||
{
|
||||
$pageId = 0;
|
||||
if (is_array($value)) {
|
||||
$pageId = $value['id'] ?? 0;
|
||||
} elseif (is_int($value)) {
|
||||
$pageId = $value;
|
||||
}
|
||||
|
||||
if (empty($pageId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$links = [];
|
||||
$page = Page::query()->find($pageId);
|
||||
$category = $page->category;
|
||||
if ($category) {
|
||||
$categoryLink = handle_link(['type' => 'page_category', 'value' => $category]);
|
||||
$links[] = ['title' => $categoryLink['text'], 'url' => $categoryLink['link']];
|
||||
}
|
||||
|
||||
$productLink = handle_link(['type' => 'page', 'value' => $value]);
|
||||
$links[] = ['title' => $productLink['text'], 'url' => $productLink['link']];
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文章页面包屑
|
||||
*
|
||||
* @param $value
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function handlePageCategoryLinks($value): array
|
||||
{
|
||||
$id = 0;
|
||||
if (is_array($value)) {
|
||||
$id = $value['id'] ?? 0;
|
||||
} elseif (is_int($value)) {
|
||||
$id = $value;
|
||||
}
|
||||
|
||||
if (empty($id)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$links = [];
|
||||
$category = PageCategory::query()->find($id);
|
||||
if ($category) {
|
||||
$categoryLink = handle_link(['type' => 'page_category', 'value' => $category]);
|
||||
$links[] = ['title' => $categoryLink['text'], 'url' => $categoryLink['link']];
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理个人中心面包屑
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('page_categories', function (Blueprint $table) {
|
||||
$table->comment('文章分类');
|
||||
$table->id()->comment('ID');
|
||||
$table->integer('parent_id')->comment('父级分类')->comment('parent_id');
|
||||
$table->integer('position')->comment('排序');
|
||||
$table->boolean('active')->comment('是否启用');
|
||||
$table->timestamps();
|
||||
});
|
||||
Schema::create('page_category_descriptions', function (Blueprint $table) {
|
||||
$table->comment('文章分类描述');
|
||||
$table->id()->comment('ID');
|
||||
$table->integer('page_category_id')->comment('分类 ID')->index('page_category_id');
|
||||
$table->string('locale')->comment('语言');
|
||||
$table->string('title')->comment('标题');
|
||||
$table->text('summary')->comment('分类简介');
|
||||
$table->string('meta_title')->comment('meta 标题');
|
||||
$table->string('meta_description')->comment('meta 描述');
|
||||
$table->string('meta_keywords')->comment('meta 关键字');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::table('pages', function (Blueprint $table) {
|
||||
$table->integer('page_category_id')->comment('文章分类ID')->after('id')->index('page_category_id');
|
||||
$table->string('author')->comment('作者')->after('position');
|
||||
$table->integer('views')->comment('查看数')->after('position');
|
||||
});
|
||||
|
||||
Schema::table('page_descriptions', function (Blueprint $table) {
|
||||
$table->string('summary')->comment('文章摘要')->after('title');
|
||||
});
|
||||
|
||||
Schema::create('page_products', function (Blueprint $table) {
|
||||
$table->comment('文章产品关联');
|
||||
$table->id()->comment('ID');
|
||||
$table->integer('page_id')->comment('文章 ID')->index('page_id');
|
||||
$table->integer('product_id')->comment('产品 ID')->index('product_id');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
@charset "UTF-8";
|
||||
|
||||
/**
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved.
|
||||
* @link https://beikeshop.com
|
||||
* @Author pu shuo <pushuo@guangda.work>
|
||||
* @Date 2022-08-09 14:12:25
|
||||
* @LastEditTime 2022-09-16 19:05:44
|
||||
*/
|
||||
|
||||
body.page-pages-form {
|
||||
.autocomplete-group-wrapper {
|
||||
.inline-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.item-group-wrapper {
|
||||
padding: 10px;
|
||||
min-height: 280px;
|
||||
overflow: auto;
|
||||
background-color: #f5f5f5;
|
||||
// border: 1px solid #e3e3e3;
|
||||
|
||||
.item {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
padding: 5px 8px;
|
||||
margin-bottom: 4px;
|
||||
background: #fff;
|
||||
border: 1px solid #eee;
|
||||
cursor: move;
|
||||
display: flex;
|
||||
align-items: center; // flex-start | center
|
||||
justify-content: space-between; // flex-end | center | space-between
|
||||
&:hover {
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
line-height: 1;
|
||||
width: calc(100% - 16px);
|
||||
align-items: center; // flex-start | center
|
||||
|
||||
i {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
padding: 2px 0;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
i {
|
||||
// position: absolute;
|
||||
color: #999;
|
||||
font-weight: 400;
|
||||
&.right {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ $primary: #fd560f;
|
|||
@import 'element-ui';
|
||||
@import 'login';
|
||||
@import 'page-product';
|
||||
@import 'page-pages';
|
||||
@import 'marketing';
|
||||
@import 'autocomplete';
|
||||
@import 'page-category';
|
||||
|
|
|
|||
|
|
@ -140,9 +140,9 @@
|
|||
{type: 'product', label: '{{ __('admin/builder.modules_product') }}'},
|
||||
{type: 'category', label: '{{ __('admin/builder.text_category') }}'},
|
||||
{type: 'page', label: '{{ __('admin/builder.text_information') }}'},
|
||||
{type: 'page_category', label: '{{ __('admin/builder.page_category') }}'},
|
||||
{type: 'brand', label: '{{ __('admin/builder.text_manufacturer') }}'},
|
||||
{type: 'static',label: '{{ __('admin/builder.text_static') }}'},
|
||||
// {type: 'blog',label: '博客'},
|
||||
{type: 'custom',label: '{{ __('admin/builder.text_custom') }}'}
|
||||
],
|
||||
static: [
|
||||
|
|
@ -209,6 +209,9 @@
|
|||
case 'page':
|
||||
url = '{{ admin_route('pages.index') }}';
|
||||
break;
|
||||
case 'page_category':
|
||||
url = '{{ admin_route('page_categories.index') }}';
|
||||
break;
|
||||
default:
|
||||
null;
|
||||
}
|
||||
|
|
@ -297,9 +300,12 @@
|
|||
case 'brand':
|
||||
url = 'brands/autocomplete?name=';
|
||||
break;
|
||||
case 'page':
|
||||
case 'page':
|
||||
url = 'pages/autocomplete?name=';
|
||||
break;
|
||||
case 'page_category':
|
||||
url = 'page_categories/autocomplete?name=';
|
||||
break;
|
||||
default:
|
||||
null;
|
||||
}
|
||||
|
|
@ -350,9 +356,12 @@
|
|||
case 'brand':
|
||||
url = `brands/${this.link.value}/name`;
|
||||
break;
|
||||
case 'page':
|
||||
case 'page':
|
||||
url = `pages/${this.link.value}/name`;
|
||||
break;
|
||||
case 'page_category':
|
||||
url = `page_categories/${this.link.value}/name`;
|
||||
break;
|
||||
default:
|
||||
null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
@extends('admin::layouts.master')
|
||||
|
||||
@section('title', __('admin/page_categories.index'))
|
||||
|
||||
@section('page-title-right')
|
||||
<x-admin::form.row title="">
|
||||
<button type="button" class="mt-3 btn btn-primary submit-form">{{ __('common.save') }}</button>
|
||||
</x-admin::form.row>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@if ($errors->has('error'))
|
||||
<x-admin-alert type="danger" msg="{{ $errors->first('error') }}" class="mt-4" />
|
||||
@endif
|
||||
|
||||
<ul class="nav nav-tabs nav-bordered mb-3" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tab-content" type="button" >{{ __('admin/product.basic_information') }}</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-set" type="button">{{ __('common.data') }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="customer-app-form" class="card">
|
||||
<div class="card-body h-min-600">
|
||||
<form novalidate class="needs-validation"
|
||||
action="{{ $page_category->id ? admin_route('page_categories.update', [$page_category->id]) : admin_route('page_categories.store') }}"
|
||||
method="POST">
|
||||
@csrf
|
||||
@method($page_category->id ? 'PUT' : 'POST')
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="tab-content">
|
||||
<ul class="nav nav-tabs mb-3" role="tablist">
|
||||
@foreach (locales() as $language)
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link {{ $loop->first ? 'active' : '' }}" data-bs-toggle="tab" data-bs-target="#tab-{{ $language['code'] }}" type="button" >{{ $language['name'] }}</button>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
@foreach (locales() as $language)
|
||||
<div class="tab-pane fade {{ $loop->first ? 'show active' : '' }}" id="tab-{{ $language['code'] }}">
|
||||
@php
|
||||
$error_title = $errors->first("descriptions.{$language['code']}.title");
|
||||
@endphp
|
||||
<x-admin-form-input
|
||||
error="{{ $error_title }}"
|
||||
name="descriptions[{{ $language['code'] }}][title]"
|
||||
title="{{ __('admin/page.info_title') }}"
|
||||
:required="true"
|
||||
value="{{ old('descriptions.' . $language['code'] . '.title', $descriptions[$language['code']]['title'] ?? '') }}"
|
||||
/>
|
||||
<x-admin::form.row title="{{ __('page_category.text_summary') }}">
|
||||
<div class="input-group w-max-400">
|
||||
<textarea rows="4" type="text" name="descriptions[{{ $language['code'] }}][summary]" class="form-control wp-400" placeholder="分类概述">{{ old('descriptions.' . $language['code'] . '.summary', $descriptions[$language['code']]['summary'] ?? '') }}</textarea>
|
||||
</div>
|
||||
</x-admin::form.row>
|
||||
|
||||
<input type="hidden" name="descriptions[{{ $language['code'] }}][locale]" value="{{ $language['code'] }}">
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_title]" title="{{ __('admin/setting.meta_title') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_title', $descriptions[$language['code']]['meta_title'] ?? '') }}" />
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_description]" title="{{ __('admin/setting.meta_description') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_description', $descriptions[$language['code']]['meta_description'] ?? '') }}" />
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_keywords]" title="{{ __('admin/setting.meta_keywords') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_keywords', $descriptions[$language['code']]['meta_keywords'] ?? '') }}" />
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="tab-set">
|
||||
<x-admin::form.row title="{{ __('admin/category.upper_category') }}">
|
||||
<div class="wp-400">
|
||||
<input type="text" value="{{ $page_category->parent->description->title ?? '' }}" id="categories-autocomplete" class="form-control wp-400 " />
|
||||
<input type="hidden" name="parent_id" value="{{ old('categories_id', $page_category->parent->id ?? '') }}" />
|
||||
</div>
|
||||
</x-admin::form.row>
|
||||
<x-admin-form-input name="position" title="{{ __('common.sort_order') }}" value="{{ old('position', $page_category->position ?? 0) }}" />
|
||||
<x-admin-form-switch name="active" title="{{ __('common.status') }}" value="{{ old('active', $page_category->active ?? 1) }}" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
<script>
|
||||
$(document).ready(function($) {
|
||||
$('.submit-form').click(function () {
|
||||
$('.needs-validation').submit()
|
||||
})
|
||||
|
||||
$('#categories-autocomplete').autocomplete({
|
||||
'source': function(request, response) {
|
||||
$http.get(`page_categories/autocomplete?name=${encodeURIComponent(request)}`, null, {
|
||||
hload: true
|
||||
}).then((res) => {
|
||||
response($.map(res.data, function(item) {
|
||||
return {
|
||||
label: item['name'],
|
||||
value: item['id']
|
||||
}
|
||||
}));
|
||||
})
|
||||
},
|
||||
'select': function(item) {
|
||||
$(this).val(item['label']);
|
||||
$('input[name="parent_id"]').val(item['value']);
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
@extends('admin::layouts.master')
|
||||
|
||||
@section('title', __('admin/page_categories.index'))
|
||||
|
||||
@section('content')
|
||||
@if ($errors->has('error'))
|
||||
<x-admin-alert type="danger" msg="{{ $errors->first('error') }}" class="mt-4" />
|
||||
@endif
|
||||
|
||||
{{-- {{ dd($page_categories_format) }} --}}
|
||||
|
||||
<div class="card" id="app">
|
||||
<div class="card-body h-min-600">
|
||||
<div class="d-flex justify-content-between mb-4">
|
||||
<a href="{{ admin_route('page_categories.create') }}" class="btn btn-primary">{{ __('common.add') }}</a>
|
||||
</div>
|
||||
<div class="table-push">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>{{ __('common.title') }}</th>
|
||||
<th>{{ __('common.status') }}</th>
|
||||
<th>{{ __('common.created_at') }}</th>
|
||||
<th>{{ __('common.updated_at') }}</th>
|
||||
@hook('admin.page.list.column')
|
||||
<th class="text-end">{{ __('common.action') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if (count($page_categories_format))
|
||||
@foreach ($page_categories_format as $item)
|
||||
<tr>
|
||||
<td>{{ $item['id'] }}</td>
|
||||
<td>
|
||||
<div title="{{ $item['title'] ?? '' }}"><a class="text-dark" href="{{ shop_route('pages.show', $item['id']) }}" target="_blank">{{ $item['title_format'] ?? '' }}</a></div>
|
||||
</td>
|
||||
<td class="{{ $item['active'] ? 'text-success' : 'text-secondary' }}">
|
||||
{{ $item['active'] ? __('common.enable') : __('common.disable') }}
|
||||
</td>
|
||||
<td>{{ $item['created_at'] }}</td>
|
||||
<td>{{ $item['updated_at'] }}</td>
|
||||
@hook('admin.page.list.column_value')
|
||||
<td class="text-end">
|
||||
<a href="{{ admin_route('page_categories.edit',$item['id']) }}" class="btn btn-outline-secondary btn-sm" >{{ __('common.edit') }}</a>
|
||||
<button class="btn btn-outline-danger btn-sm delete-btn" type='button' data-id="{{ $item['id'] }}">{{ __('common.delete') }}</button>
|
||||
@hook('admin.page.list.action')
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr><td colspan="5" class="border-0"><x-admin-no-data /></td></tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{ $page_categories->links('admin::vendor/pagination/bootstrap-4') }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@hook('admin.page.list.content.footer')
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
<script>
|
||||
$('.delete-btn').click(function(event) {
|
||||
const id = $(this).data('id');
|
||||
const self = $(this);
|
||||
|
||||
layer.confirm('{{ __('common.confirm_delete') }}', {
|
||||
title: "{{ __('common.text_hint') }}",
|
||||
btn: ['{{ __('common.cancel') }}', '{{ __('common.confirm') }}'],
|
||||
area: ['400px'],
|
||||
btn2: () => {
|
||||
$http.delete(`page_categories/${id}`).then((res) => {
|
||||
layer.msg(res.message);
|
||||
window.location.reload();
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -2,59 +2,142 @@
|
|||
|
||||
@section('title', __('admin/page.index'))
|
||||
|
||||
@section('body-class', 'page-pages-form')
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/vue/Sortable.min.js') }}"></script>
|
||||
<script src="{{ asset('vendor/vue/vuedraggable.js') }}"></script>
|
||||
<script src="{{ asset('vendor/tinymce/5.9.1/tinymce.min.js') }}"></script>
|
||||
@endpush
|
||||
|
||||
@section('page-title-right')
|
||||
<x-admin::form.row title="">
|
||||
<button type="button" class="mt-3 btn btn-primary submit-form">{{ __('common.save') }}</button>
|
||||
</x-admin::form.row>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div id="plugins-app-form" class="card h-min-600">
|
||||
|
||||
<ul class="nav nav-tabs nav-bordered mb-3" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tab-content" type="button" >{{ __('admin/product.basic_information') }}</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-set" type="button">{{ __('common.data') }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="app" class="card h-min-600">
|
||||
<div class="card-body">
|
||||
<form novalidate class="needs-validation" action="{{ $page->id ? admin_route('pages.update', [$page->id]) : admin_route('pages.store') }}" method="POST">
|
||||
@csrf
|
||||
@method($page->id ? 'PUT' : 'POST')
|
||||
<ul class="nav nav-tabs nav-bordered mb-3" role="tablist">
|
||||
@foreach (locales() as $language)
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link {{ $loop->first ? 'active' : '' }}" data-bs-toggle="tab" data-bs-target="#tab-{{ $language['code'] }}" type="button" >{{ $language['name'] }}</button>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
@foreach (locales() as $language)
|
||||
<div class="tab-pane fade {{ $loop->first ? 'show active' : '' }}" id="tab-{{ $language['code'] }}">
|
||||
@php
|
||||
$error_title = $errors->first("descriptions.{$language['code']}.title");
|
||||
@endphp
|
||||
<x-admin-form-input
|
||||
error="{{ $error_title }}"
|
||||
name="descriptions[{{ $language['code'] }}][title]"
|
||||
title="{{ __('admin/page.info_title') }}"
|
||||
:required="true"
|
||||
value="{{ old('descriptions.' . $language['code'] . '.title', $descriptions[$language['code']]['title'] ?? '') }}"
|
||||
/>
|
||||
<div class="tab-pane fade show active" id="tab-content">
|
||||
@csrf
|
||||
@method($page->id ? 'PUT' : 'POST')
|
||||
<ul class="nav nav-tabs mb-3" role="tablist">
|
||||
@foreach (locales() as $language)
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link {{ $loop->first ? 'active' : '' }}" data-bs-toggle="tab" data-bs-target="#tab-{{ $language['code'] }}" type="button" >{{ $language['name'] }}</button>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
@foreach (locales() as $language)
|
||||
<div class="tab-pane fade {{ $loop->first ? 'show active' : '' }}" id="tab-{{ $language['code'] }}">
|
||||
@php
|
||||
$error_title = $errors->first("descriptions.{$language['code']}.title");
|
||||
@endphp
|
||||
<x-admin-form-input
|
||||
error="{{ $error_title }}"
|
||||
name="descriptions[{{ $language['code'] }}][title]"
|
||||
title="{{ __('admin/page.info_title') }}"
|
||||
:required="true"
|
||||
value="{{ old('descriptions.' . $language['code'] . '.title', $descriptions[$language['code']]['title'] ?? '') }}"
|
||||
/>
|
||||
|
||||
<x-admin::form.row title="{{ __('admin/page.info_content') }}">
|
||||
<div class="w-max-1000">
|
||||
<textarea name="descriptions[{{ $language['code'] }}][content]" data-tinymce-height="600" class="form-control tinymce">
|
||||
{{ old('descriptions.' . $language['code'] . '.content', $descriptions[$language['code']]['content'] ?? '') }}
|
||||
</textarea>
|
||||
<x-admin::form.row title="{{ __('page_category.text_summary') }}">
|
||||
<div class="input-group w-max-400">
|
||||
<textarea rows="3" type="text" name="descriptions[{{ $language['code'] }}][summary]" class="form-control wp-400" placeholder="{{ __('page_category.text_summary') }}">{{ old('descriptions.' . $language['code'] . '.summary', $descriptions[$language['code']]['summary'] ?? '') }}</textarea>
|
||||
</div>
|
||||
</x-admin::form.row>
|
||||
|
||||
<x-admin::form.row title="{{ __('admin/page.info_content') }}">
|
||||
<div class="w-max-1000">
|
||||
<textarea name="descriptions[{{ $language['code'] }}][content]" data-tinymce-height="600" class="form-control tinymce">
|
||||
{{ old('descriptions.' . $language['code'] . '.content', $descriptions[$language['code']]['content'] ?? '') }}
|
||||
</textarea>
|
||||
</div>
|
||||
@if ($errors->has("descriptions.{$language['code']}.content"))
|
||||
<span class="invalid-feedback d-block" role="alert">{{ $errors->first("descriptions.{$language['code']}.content") }}</span>
|
||||
@endif
|
||||
</x-admin::form.row>
|
||||
|
||||
<input type="hidden" name="descriptions[{{ $language['code'] }}][locale]" value="{{ $language['code'] }}">
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_title]" title="{{ __('admin/setting.meta_title') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_title', $descriptions[$language['code']]['meta_title'] ?? '') }}" />
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_description]" title="{{ __('admin/setting.meta_description') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_description', $descriptions[$language['code']]['meta_description'] ?? '') }}" />
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_keywords]" title="{{ __('admin/setting.meta_keywords') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_keywords', $descriptions[$language['code']]['meta_keywords'] ?? '') }}" />
|
||||
</div>
|
||||
@if ($errors->has("descriptions.{$language['code']}.content"))
|
||||
<span class="invalid-feedback d-block" role="alert">{{ $errors->first("descriptions.{$language['code']}.content") }}</span>
|
||||
@endif
|
||||
</x-admin::form.row>
|
||||
|
||||
<input type="hidden" name="descriptions[{{ $language['code'] }}][locale]" value="{{ $language['code'] }}">
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_title]" title="{{ __('admin/setting.meta_title') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_title', $descriptions[$language['code']]['meta_title'] ?? '') }}" />
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_description]" title="{{ __('admin/setting.meta_description') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_description', $descriptions[$language['code']]['meta_description'] ?? '') }}" />
|
||||
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_keywords]" title="{{ __('admin/setting.meta_keywords') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_keywords', $descriptions[$language['code']]['meta_keywords'] ?? '') }}" />
|
||||
@endforeach
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="tab-pane fade" id="tab-set">
|
||||
<x-admin-form-input name="author" title="{{ __('page_category.author') }}" value="{{ old('author', $page->author ?? '') }}" />
|
||||
<x-admin::form.row title="{{ __('admin/page_categories.index') }}">
|
||||
<div class="wp-400">
|
||||
<el-autocomplete
|
||||
v-model="page_category_name"
|
||||
value-key="name"
|
||||
size="small"
|
||||
name="category_name"
|
||||
class="w-100"
|
||||
:fetch-suggestions="(keyword, cb) => {relationsQuerySearch(keyword, cb, 'page_categories')}"
|
||||
placeholder="{{ __('common.input') }}"
|
||||
@select="(e) => {handleSelect(e, 'page_categories')}"
|
||||
></el-autocomplete>
|
||||
<input type="hidden" name="page_category_id" :value="page_category_id" />
|
||||
</div>
|
||||
</x-admin::form.row>
|
||||
<x-admin-form-input name="views" title="{{ __('page_category.views') }}" value="{{ old('views', $page->views ?? '') }}" />
|
||||
|
||||
<x-admin-form-switch name="active" title="{{ __('common.status') }}" value="{{ old('active', $page->active) }}" />
|
||||
<x-admin::form.row title="">
|
||||
<button type="submit" class="mt-3 btn btn-primary">{{ __('common.submit') }}</button>
|
||||
</x-admin::form.row>
|
||||
<x-admin::form.row title="{{ __('admin/product.product_relations') }}">
|
||||
<div class="module-edit-group wp-600">
|
||||
<div class="autocomplete-group-wrapper">
|
||||
<el-autocomplete
|
||||
class="inline-input"
|
||||
v-model="relations.keyword"
|
||||
value-key="name"
|
||||
size="small"
|
||||
:fetch-suggestions="(keyword, cb) => {relationsQuerySearch(keyword, cb, 'products')}"
|
||||
placeholder="{{ __('admin/builder.modules_keywords_search') }}"
|
||||
@select="(e) => {handleSelect(e, 'product_relations')}"
|
||||
></el-autocomplete>
|
||||
|
||||
<div class="item-group-wrapper" v-loading="relations.loading">
|
||||
<template v-if="relations.products.length">
|
||||
<draggable
|
||||
ghost-class="dragabble-ghost"
|
||||
:list="relations.products"
|
||||
:options="{animation: 330}"
|
||||
>
|
||||
<div v-for="(item, index) in relations.products" :key="index" class="item">
|
||||
<div>
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
<span>@{{ item.name }}</span>
|
||||
</div>
|
||||
<i class="el-icon-delete right" @click="relationsRemoveProduct(index)"></i>
|
||||
<input type="text" :name="'products['+ index +']'" v-model="item.id" class="form-control d-none">
|
||||
</div>
|
||||
</draggable>
|
||||
</template>
|
||||
<template v-else>{{ __('admin/builder.modules_please_products') }}</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-admin::form.row>
|
||||
|
||||
<x-admin-form-switch name="active" title="{{ __('common.status') }}" value="{{ old('active', $page->active ?? 1) }}" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -63,5 +146,62 @@
|
|||
@hook('admin.page.form.footer')
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
<script>
|
||||
$('.submit-form').click(function () {
|
||||
$('.needs-validation').submit()
|
||||
})
|
||||
|
||||
var app = new Vue({
|
||||
el: '#app',
|
||||
|
||||
data: {
|
||||
relations: {
|
||||
keyword: '',
|
||||
products: [],
|
||||
loading: null,
|
||||
},
|
||||
page_category_name: '{{ old('category_name', $page->category->description->title ?? '') }}',
|
||||
page_category_id: '{{ old('categories_id', $page->category->id ?? '') }}',
|
||||
},
|
||||
|
||||
created() {
|
||||
const products = @json($page['products'] ?? []);
|
||||
|
||||
if (products.length) {
|
||||
this.relations.products = products.map(v => {
|
||||
return {
|
||||
id: v.id,
|
||||
name: v.description.name,
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
relationsQuerySearch(keyword, cb, url) {
|
||||
$http.get(url + '/autocomplete?name=' + encodeURIComponent(keyword), null, {hload:true}).then((res) => {
|
||||
cb(res.data);
|
||||
})
|
||||
},
|
||||
handleSelect(item, key) {
|
||||
if (key == 'product_relations') {
|
||||
if (!this.relations.products.find(v => v == item.id)) {
|
||||
this.relations.products.push(item);
|
||||
}
|
||||
this.relations.keyword = ""
|
||||
} else {
|
||||
this.page_category_name = item.name
|
||||
this.page_category_id = item.id
|
||||
}
|
||||
},
|
||||
relationsRemoveProduct(index) {
|
||||
this.relations.products.splice(index, 1);
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ $primary: #fd560f;
|
|||
@import './header';
|
||||
@import './footer';
|
||||
@import './product-style';
|
||||
@import './news';
|
||||
@import './login';
|
||||
@import './account/account';
|
||||
@import './page-product';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
@charset "UTF-8";
|
||||
|
||||
/**
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved.
|
||||
* @link https://beikeshop.com
|
||||
* @Author pu shuo <pushuo@guangda.work>
|
||||
* @Date 2022-08-02 19:19:52
|
||||
* @LastEditTime 2022-09-16 20:47:45
|
||||
*/
|
||||
|
||||
.page-categories-home, .page-pages {
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
@charset "UTF-8";
|
||||
|
||||
/**
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved.
|
||||
* @link https://beikeshop.com
|
||||
* @Author pu shuo <pushuo@guangda.work>
|
||||
* @Date 2022-08-15 15:43:12
|
||||
* @LastEditTime 2022-09-16 20:56:17
|
||||
*/
|
||||
|
||||
body.page-list {
|
||||
.brand-item {
|
||||
display: flex;
|
||||
align-items: center; // flex-start | center
|
||||
justify-content: center; // flex-end | center | space-between
|
||||
box-shadow: 0 6px 18px rgba(0, 0, 0, .07);
|
||||
margin-bottom: 10px;
|
||||
height: 133px;
|
||||
width: 100%;
|
||||
|
||||
>img {
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
|
||||
a{
|
||||
color: #242424;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.curser {
|
||||
cursor: pointer;
|
||||
|
||||
>li>a {
|
||||
display: block;
|
||||
color: #242424;
|
||||
transition: all .5s;
|
||||
margin: 0 auto;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
background-color: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => 'Seitenbearbeitung',
|
||||
'page_category' => 'Artikelklassifizierung',
|
||||
'modules_instructions' => 'Verfügbare Module, zum Hinzufügen zur Seite klicken',
|
||||
'text_floor_prompt' => 'Einstellungen (Etagenkonfiguration muss gespeichert und aktualisiert werden, um die Seite zu aktualisieren)',
|
||||
'text_new_page' => 'Neue Seite hinzufügen',
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@
|
|||
*/
|
||||
|
||||
return [
|
||||
'index' => 'Informationsseite',
|
||||
'info_title' => 'Informationstitel',
|
||||
'info_content' => 'Inhalt',
|
||||
'index' => 'Artikelverwaltung',
|
||||
'info_title' => 'Informationstitel',
|
||||
'info_content' => 'Inhalt',
|
||||
|
||||
'pages_index' => 'Einzelseitenliste',
|
||||
'pages_create' => 'Eine einzelne Seite erstellen',
|
||||
'pages_show' => 'Einzelseitendetails',
|
||||
'pages_update' => 'Einzelne Seite bearbeiten',
|
||||
'pages_delete' => 'Eine einzelne Seite löschen',
|
||||
'pages_index' => 'Artikelliste',
|
||||
'pages_create' => 'Artikel erstellen',
|
||||
'pages_show' => 'Artikeldetails',
|
||||
'pages_update' => 'Artikelbearbeitung',
|
||||
'pages_delete' => 'Artikel löschen',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => 'Artikelklassifizierung',
|
||||
'info_title' => 'Informationstitel',
|
||||
'info_content' => 'Inhalt',
|
||||
|
||||
'pages_index' => 'Kategorieliste',
|
||||
];
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => 'blog de noticias',
|
||||
'autor' => 'autor',
|
||||
'views' => 'número de vista',
|
||||
'created_at' => 'hora de lanzamiento',
|
||||
'text_summary' => 'Kategorieübersicht',
|
||||
];
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => 'Page editing',
|
||||
'page_category' => 'Article Category',
|
||||
'modules_instructions' => 'Available modules, click Add to page',
|
||||
'text_floor_prompt' => 'Settings',
|
||||
'text_new_page' => 'Add new page',
|
||||
|
|
@ -69,7 +70,7 @@ return [
|
|||
'text_disable' => 'Disable',
|
||||
'text_no_data' => 'Data does not exist or has been deleted',
|
||||
'text_to_add' => 'Go to add',
|
||||
'text_category' => 'Category',
|
||||
'text_category' => 'Porudct Category',
|
||||
'text_information' => 'Information',
|
||||
'text_manufacturer' => 'Brand',
|
||||
'text_static' => 'Fixed connection',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => 'article classification',
|
||||
'info_title' => 'information title',
|
||||
'info_content' => 'content',
|
||||
|
||||
'pages_index' => 'category list',
|
||||
];
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => 'News blog',
|
||||
'author' => 'Author',
|
||||
'views' => 'View number',
|
||||
'created_at' => 'Release time',
|
||||
'text_summary' => 'Summary',
|
||||
];
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => 'edición de página',
|
||||
'page_category' => 'clasificación de artículos',
|
||||
'modules_instructions' => 'Módulos disponibles, haga clic para agregar a la página',
|
||||
'text_floor_prompt' => 'Configuración (la configuración del piso debe guardarse y actualizarse para actualizar la página)',
|
||||
'text_new_page' => 'Agregar una nueva página',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,332 @@
|
|||
<?php
|
||||
/**
|
||||
* order.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'heading_title' => 'imprimir factura',
|
||||
|
||||
'text_success' => 'Éxito: ¡El pedido ha sido modificado! ',
|
||||
'text_list' => 'lista de pedidos',
|
||||
'text_add' => 'añadir pedido',
|
||||
'text_edit' => 'orden de edición',
|
||||
'text_filter' => 'filtro',
|
||||
'text_order_detail' => 'detalles del pedido',
|
||||
'text_customer_detail' => 'detalles del cliente',
|
||||
'text_cart' => 'carrito de compras',
|
||||
'text_payment_detail' => 'información de pago',
|
||||
'text_shipping_detail' => 'información de envío',
|
||||
'text_total_detail' => 'total',
|
||||
'text_option' => 'opción',
|
||||
'text_store' => 'tienda',
|
||||
'text_date_added' => 'Fecha de generación:',
|
||||
'text_payment_method' => 'Método de pago:',
|
||||
'text_shipping_method' => 'Método de envío:',
|
||||
'text_customer' => 'nombre del cliente:',
|
||||
'text_customer_group' => 'grupo de clientes:',
|
||||
'text_email' => 'correo electrónico del cliente:',
|
||||
'text_store_email' => 'Email de contacto:',
|
||||
'text_telephone' => 'Teléfono del cliente:',
|
||||
'text_fax' => 'Fax:',
|
||||
'text_invoice' => 'factura de pedido',
|
||||
'text_reward' => 'puntos de recompensa',
|
||||
'text_afiliado' => 'miembros afiliados',
|
||||
'text_order' => 'pedir (#%s)',
|
||||
'text_payment_address' => 'dirección de pago',
|
||||
'text_shipping_address' => 'dirección de envío:',
|
||||
'text_comment' => 'mensaje del cliente',
|
||||
'text_history' => 'Añadir registro de pedido',
|
||||
'text_history_add' => 'Añadir historial de pedidos',
|
||||
'text_account_custom_field' => 'campo personalizado de cuenta',
|
||||
'text_payment_custom_field' => 'campo personalizado de dirección de pago',
|
||||
'text_shipping_custom_field' => 'Campo personalizado de dirección de envío',
|
||||
'text_browser' => 'navegador',
|
||||
'text_ip' => 'Dirección IP',
|
||||
'text_forwarded_ip' => 'IP reenviada',
|
||||
'text_user_agent' => 'sistema operativo',
|
||||
'text_accept_language' => 'idioma del sistema',
|
||||
'text_order_id' => 'número de pedido:',
|
||||
'text_website' => 'Sitio web:',
|
||||
'text_invoice_no' => 'número de factura:',
|
||||
'text_invoice_date' => 'Fecha de la factura:',
|
||||
'text_sku' => 'SKU:',
|
||||
'text_upc' => 'UPC:',
|
||||
'text_ean' => 'EAN:',
|
||||
'text_jan' => 'ENE:',
|
||||
'text_isbn' => 'ISBN:',
|
||||
'text_mpn' => 'MPN:',
|
||||
'text_date_modified' => 'fecha de modificación:',
|
||||
'text_firstname' => 'primer nombre:',
|
||||
'text_lastname' => 'apellido:',
|
||||
'text_company' => 'Nombre de la empresa:',
|
||||
'text_address_1' => 'Dirección Dirección:',
|
||||
'text_address_2' => 'Dirección 2:',
|
||||
'text_postcode' => 'código postal:',
|
||||
'text_city' => 'Distritos y condados:',
|
||||
'text_zone' => 'Provincia:',
|
||||
'text_zone_code' => 'Código de provincia:',
|
||||
'text_country' => 'nación:',
|
||||
'text_from' => 'lugar de envío',
|
||||
'texto_a' => 'a',
|
||||
'text_missing' => 'pedido perdido',
|
||||
'text_default' => 'predeterminado',
|
||||
'text_product' => 'añadir productos',
|
||||
'text_voucher' => 'Agregar certificado de regalo',
|
||||
'text_order' => 'detalles del pedido',
|
||||
'text_shipping' => 'entrega',
|
||||
'text_contact' => 'contacto',
|
||||
'text_reward_added' => 'Éxito: ¡se agregaron puntos de recompensa! ',
|
||||
'text_reward_removed' => 'Éxito: ¡Se han eliminado los puntos de recompensa! ',
|
||||
'text_commission_added' => 'Éxito: ¡Se ha agregado la comisión! ',
|
||||
'text_commission_removed' => 'Éxito: ¡Se eliminó la comisión! ',
|
||||
'text_restock' => 'Éxito: ¡El producto ha sido almacenado! ',
|
||||
'text_upload' => '¡Su archivo ha sido subido correctamente! ',
|
||||
'text_picklist' => 'Factura',
|
||||
'text_print' => 'imprimir',
|
||||
'text_reward' => 'puntos de recompensa',
|
||||
'text_contacter' => 'Nombre del cliente:',
|
||||
'text_shipping_comment' => '¡Muchas gracias por comprar en este centro comercial, esperamos su visita nuevamente! ',
|
||||
'text_invoice_comment' => '¡Muchas gracias por comprar en este centro comercial, esperamos su visita nuevamente! ',
|
||||
'text_pickup_info' => 'información de recogida',
|
||||
'text_pickup_name' => 'punto de auto-recogida:',
|
||||
'text_pickup_telephone' => 'Número de contacto:',
|
||||
'text_pickup_code' => 'Código de recogida:',
|
||||
'text_pickup_address' => 'dirección de auto-recogida:',
|
||||
'text_pickup_number' => 'Código de recogida:',
|
||||
'text_pickup_open' => 'Horario comercial:',
|
||||
'text_pickup_comment' => 'posdata:',
|
||||
'text_edit_price' => 'modificar el precio',
|
||||
'text_alert' => 'advertencia',
|
||||
'text_product_detail' => 'artículo de pedido',
|
||||
'text_edit_shipping_address' => 'editar dirección de entrega',
|
||||
'text_edit_payment_address' => 'editar dirección de facturación',
|
||||
'text_aftership_info' => 'información logística',
|
||||
'text_edit_products' => 'Añadir artículos de pedido',
|
||||
'text_confirm_delete' => '¿Está seguro de que desea eliminar este producto? ',
|
||||
'text_none' => 'ninguno',
|
||||
'text_bargain' => 'pedido de oferta',
|
||||
'text_group_buying' => 'pedido de grupo',
|
||||
'text_shipping_id_number' => 'Número de identificación',
|
||||
'text_shipping_id_front' => 'Foto del frente del DNI',
|
||||
'text_shipping_id_back' => 'Foto del reverso de la tarjeta de identificación',
|
||||
'text_flash_sale' => 'pedido seckill',
|
||||
'text_normal' => 'orden normal',
|
||||
'text_group_buying_member_add' => 'Agregar miembros del grupo',
|
||||
'text_add_total' => 'añadir tarifa de pedido',
|
||||
'entry_total_select' => 'seleccionar elemento de gasto',
|
||||
'entry_total_price' => 'Por favor ingrese el monto',
|
||||
'button_total_add' => 'añadir tarifas',
|
||||
'text_type_total' => 'tarifa de pedido',
|
||||
'text_type_product' => 'Producto',
|
||||
'text_type_shipping_address' => 'dirección de envío',
|
||||
'text_type_payment_address' => 'dirección de facturación',
|
||||
'text_action_update' => 'actualizar',
|
||||
'text_action_create' => 'crear',
|
||||
'text_action_delete' => 'eliminar',
|
||||
'text_group_buying_master' => '<span class="color-red">Maestro de impresión</span>',
|
||||
'tab_aftership' => 'información logística',
|
||||
'tab_operation' => 'registro de operación',
|
||||
'text_promotion' => 'promoción',
|
||||
'text_suite_count' => 'uno/conjunto',
|
||||
'text_gift' => 'regalo',
|
||||
'text_status_current' => 'estado actual',
|
||||
'text_status_finished' => 'El proceso de pedido ha finalizado, el estado no se puede cambiar',
|
||||
'text_confirm' => '¿Está seguro de modificar el estado del pedido? ',
|
||||
'text_show_return' => 'Ver estado del reembolso',
|
||||
|
||||
'button_refund' => 'reembolso',
|
||||
'text_delete_confirm' => 'OK para borrar',
|
||||
'button_cancel' => 'Cancelar',
|
||||
'text_explode_selected' => 'exportar seleccionado',
|
||||
'text_warning' => 'advertencia',
|
||||
'text_invoice_info' => 'información de la factura',
|
||||
'text_invoice_manage' => 'administración de archivos adjuntos',
|
||||
'text_invoice_attachment' => 'archivo adjunto',
|
||||
'text_invoice_type' => 'Tipo de factura:',
|
||||
'text_invoice_personal' => 'nombre personal:',
|
||||
'text_invoice_content_type' => 'Contenido de la factura:',
|
||||
'text_invoice_company_name' => 'nombre de la unidad:',
|
||||
'text_invoice_vat' => 'número de identificación fiscal:',
|
||||
'text_invoice_company_address' => 'dirección de la unidad:',
|
||||
'text_invoice_company_telephone' => 'teléfono de la unidad:',
|
||||
'text_invoice_bank' => 'cuenta bancaria:',
|
||||
'text_invoice_account' => 'cuenta número de cuenta:',
|
||||
'text_invoice_receiver_phone' => 'número de teléfono del receptor:',
|
||||
'text_invoice_receiver_email' => 'correo electrónico del destinatario:',
|
||||
'text_invoice_delete_confirm' => '¿Está seguro de que desea eliminar el adjunto de la factura?',
|
||||
'text_warning' => 'advertencia',
|
||||
// Colum,
|
||||
'column_product_id' => 'ID del producto',
|
||||
'column_order_id' => 'ID',
|
||||
'column_order_number' => 'número de pedido',
|
||||
'column_customer' => 'nombre del cliente',
|
||||
'column_status' => 'estado',
|
||||
'column_date_added' => 'fecha de generación',
|
||||
'column_date_modified' => 'fecha de modificación',
|
||||
'column_total' => 'total',
|
||||
'column_image' => 'imagen',
|
||||
'column_product' => 'nombre del producto',
|
||||
'column_quantity' => 'cantidad',
|
||||
'column_price' => 'precio',
|
||||
'column_cost_price' => 'precio de coste',
|
||||
'column_comment' => 'Observaciones',
|
||||
'column_notify' => 'notificar a los clientes',
|
||||
'column_ubicación' => 'ubicación',
|
||||
'column_reference' => 'referencia',
|
||||
'column_action' => 'administración',
|
||||
'column_weight' => 'peso de la mercancía',
|
||||
'column_product_total' => 'Total de mercancía:',
|
||||
'column_shipping_fee' => 'Impuesto:',
|
||||
'column_index' => 'número de serie',
|
||||
'column_order_total' => 'cantidad total:',
|
||||
'column_order_total_1' => 'Cantidad total: %s (capital)',
|
||||
'column_shipping_address' => 'dirección de envío',
|
||||
'column_telephone' => 'Número de teléfono del destinatario',
|
||||
'column_products' => 'comprar bienes',
|
||||
'column_shipping_name' => 'Nombre del destinatario',
|
||||
'column_shipping_country' => 'país',
|
||||
'column_shipping_zone' => 'Provincia',
|
||||
'column_shipping_city' => 'ciudad',
|
||||
'column_shipping_county' => 'condado',
|
||||
'column_shipping_address_1' => 'Dirección 1',
|
||||
'column_shipping_address_2' => 'Dirección 2',
|
||||
'column_shipping_postcode' => 'código postal',
|
||||
'column_payment' => 'método de pago',
|
||||
'nombre_columna' => 'nombre',
|
||||
'columna_avatar' => 'Avatar',
|
||||
'column_username' => 'operador',
|
||||
'tipo_columna' => 'tipo',
|
||||
'column_operation_action' => 'modo de operación',
|
||||
'column_before_data' => 'datos antes de la operación',
|
||||
'column_after_data' => 'datos después de la operación',
|
||||
// Entr,
|
||||
'entry_store' => 'tienda',
|
||||
'entry_customer' => 'cliente',
|
||||
'entry_customer_group' => 'grupo de clientes',
|
||||
'entry_firstname' => 'nombre',
|
||||
'entry_lastname' => 'apellido',
|
||||
'entry_email' => 'Correo electrónico',
|
||||
'entry_telephone' => 'teléfono',
|
||||
'entry_address' => 'seleccionar dirección',
|
||||
'entry_company' => 'nombre de la empresa',
|
||||
'entry_address_1' => 'Dirección detallada',
|
||||
'entry_address_2' => 'Línea de dirección 2',
|
||||
'entry_city' => 'ciudad',
|
||||
'entry_postcode' => 'código postal',
|
||||
'entry_country' => 'país',
|
||||
'entry_zone' => 'Provincia',
|
||||
'entry_zone_code' => 'código de provincia',
|
||||
'entry_product' => 'seleccionar producto',
|
||||
'entry_option' => 'Opción de producto',
|
||||
'entry_quantity' => 'cantidad',
|
||||
'entry_to_name' => 'nombre del destinatario',
|
||||
'entry_to_email' => 'Correo electrónico del destinatario',
|
||||
'entry_from_name' => 'nombre del emisor',
|
||||
'entry_from_email' => 'Correo electrónico del emisor',
|
||||
'entry_theme' => 'Tema de cupón de regalo',
|
||||
'entry_message' => 'Información del certificado de regalo',
|
||||
'entry_amount' => 'importe del cupón de regalo',
|
||||
'entry_afiliado' => 'Miembro Afiliado',
|
||||
'entry_order_status' => 'estado',
|
||||
'entry_notify' => 'notificar a los clientes',
|
||||
'entry_override' => 'reescribir',
|
||||
'entry_comment' => 'Observaciones',
|
||||
'entry_currency' => 'moneda',
|
||||
'entry_shipping_method' => 'método de envío',
|
||||
'entry_payment_method' => 'método de pago',
|
||||
'entry_coupon' => 'cupón de descuento',
|
||||
'entry_voucher' => 'vale regalo',
|
||||
'entry_reward' => 'Puntos',
|
||||
'entry_order_id' => 'ID de pedido',
|
||||
'entry_order_number' => 'número de pedido',
|
||||
'entry_total' => 'total',
|
||||
'entry_total_format' => '(formato: 10 o 10-20)',
|
||||
'entry_date_added' => 'Fecha agregada',
|
||||
'entry_date_modified' => 'fecha de modificación',
|
||||
'entry_date_added_start' => 'fecha de generación del pedido (inicio)',
|
||||
'entry_date_added_end' => 'fecha de generación del pedido (fin)',
|
||||
'entry_product_quantity' => 'Editar cantidad de producto',
|
||||
'entry_product_price' => 'Editar precio de mercancía',
|
||||
'entry_remove_product' => '¿Está seguro de que desea eliminar este producto?',
|
||||
'entry_image' => 'imagen',
|
||||
'entry_name' => 'nombre del producto',
|
||||
'entry_model' => 'modelo',
|
||||
'precio_entrada' => 'precio',
|
||||
'entry_action' => 'administración',
|
||||
'entry_location' => 'área',
|
||||
'entry_aftership_code' => 'empresa de logística',
|
||||
'entry_aftership_number' => 'Número de logística',
|
||||
'entry_aftership_comment' => 'Observaciones',
|
||||
'entry_platform' => 'plataforma',
|
||||
'entry_payment' => 'método de pago',
|
||||
'entry_type' => 'categoría de pedido',
|
||||
'entry_group_buying_member_add' => 'añadir miembros',
|
||||
'entry_avatar' => 'Avatar',
|
||||
'tab_group_buying' => 'Únete al grupo',
|
||||
'button_group_buying_member_add' => 'Agregar miembros del grupo',
|
||||
'button_customer' => 'editar información del cliente',
|
||||
'boton_ok' => 'Aceptar',
|
||||
'button_aftership_add' => 'Agregar información logística',
|
||||
'button_confirm' => 'Aceptar',
|
||||
'button_cancel' => 'Cancelar',
|
||||
// Hel,
|
||||
'help_override' => 'La extensión antifraude puede hacer que se anule el estado del pedido, lo que provocará que no se cambie el estado del pedido. ',
|
||||
// Erro,
|
||||
'error_warning' => 'Error: ¡Compruebe si hay errores en el formulario! ',
|
||||
'error_permission' => 'Error: ¡No tienes permiso para modificar el pedido! ',
|
||||
'error_action' => 'Error: ¡No se pudo completar la operación! ',
|
||||
'error_filetype' => '¡Tipo de archivo ilegal! ',
|
||||
'error_customer_params' => 'error de datos del cliente',
|
||||
'error_update_order_quantity' => 'La cantidad de bienes excede el inventario',
|
||||
// Succes,
|
||||
'success_customer' => '¡Información del cliente modificada con éxito! ',
|
||||
'success_delete' => 'Éxito: Eliminado con éxito el artículo del pedido. ',
|
||||
'success_edit_product' => 'Editar correctamente el producto del pedido',
|
||||
'success_shipping_address' => 'Editar correctamente la dirección de envío',
|
||||
'success_payment_address' => 'Editar correctamente la dirección de facturación',
|
||||
'success_edit_order' => 'orden de edición exitosa',
|
||||
'success_remove_total' => '%s eliminado con éxito',
|
||||
'success_add_total' => 'tarifa de pedido agregada con éxito',
|
||||
'error_customer' => '¡Seleccione un cliente! ',
|
||||
'error_firstname' => '¡El nombre debe tener entre 1 y 32 caracteres! ',
|
||||
'error_lastname' => '¡El apellido debe tener entre 1 y 32 caracteres! ',
|
||||
'error_email' => '¡Dirección de correo electrónico no válida! ',
|
||||
'error_telephone' => '¡El teléfono debe tener entre 1 y 32 caracteres! ',
|
||||
'error_custom_field' => '%s es obligatorio! ',
|
||||
'error_required' => '¡Se requiere %s! ',
|
||||
'error_store' => '¡El nombre del producto es incorrecto o ha sido deshabilitado! ',
|
||||
'error_integer' => 'Ingrese un número entero positivo. ',
|
||||
'error_product_exists' => 'El producto no existe. ',
|
||||
'error_out_stock' => 'agotado',
|
||||
'error_edit_type' => 'Operación ilegal',
|
||||
'error_total_type' => 'No existe tal elemento Total',
|
||||
'error_nonnegative_number' => 'Por favor ingrese un número no negativo',
|
||||
'error_address_1' => '¡La dirección detallada debe tener entre 3 y 128 caracteres! ',
|
||||
'error_postcode' => '¡El código postal debe tener de 2 a 10 caracteres! ',
|
||||
'error_zone' => '¡Seleccione una provincia! ',
|
||||
'error_city_id' => '¡Seleccione una ciudad! ',
|
||||
'error_county_id' => '¡Seleccione el condado! ',
|
||||
'error_calling_code' => 'Seleccione un código de área de teléfono',
|
||||
'error_aftership_number' => 'Por favor ingrese el número de orden de logística',
|
||||
'error_order_exist' => 'No existe tal orden',
|
||||
'error_product_exist' => 'No existe tal producto',
|
||||
'error_total_exist' => 'No existe tal elemento de gasto',
|
||||
'error_select_total' => 'Seleccione el artículo de costo',
|
||||
'error_invoice_type' => 'La factura solo admite imágenes (png, jpg, jpeg) y pdf, vuelva a seleccionar cargar',
|
||||
'error_invalid_invoice_attachment' => 'factura adjunta no válida',
|
||||
'error_invalid_order_id' => 'error de número de pedido, compruébelo',
|
||||
'error_invoice_no_need' => 'Este pedido no necesita emitir factura',
|
||||
'error_invoice_file' => 'error en el archivo de la factura, verifíquelo',
|
||||
'error_extension' => 'Habilite la extensión de información de archivo',
|
||||
'error_invoice_mime_type' => 'error de tipo de archivo de factura, verifíquelo',
|
||||
'error_invoice_upload' => 'La carga falló, por favor contacte al administrador',
|
||||
'error_group_buy_completed_or_timeout' => '¡El grupo se ha llenado o ha caducado! ',
|
||||
'error_cart_limit_100' => '¡El carrito de compras supera el límite de 100 líneas de productos! ',
|
||||
|
||||
];
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => 'clasificación de artículos',
|
||||
'info_title' => 'título de la información',
|
||||
'info_content' => 'contenido',
|
||||
|
||||
'pages_index' => 'lista de categorías',
|
||||
];
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => 'Blog de noticias',
|
||||
'autor' => 'Autor',
|
||||
'views' => 'número de vista',
|
||||
'created_at' => 'hora de lanzamiento',
|
||||
'text_summary' => 'aperçu des catégories',
|
||||
];
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => 'édition de pages',
|
||||
'page_category' => 'classification des articles',
|
||||
'modules_instructions' => 'Modules disponibles, cliquez pour ajouter à la page',
|
||||
'text_floor_prompt' => 'Paramètres (la configuration de l\'étage doit être enregistrée et actualisée pour mettre à jour la page)',
|
||||
'text_new_page' => 'Ajouter une nouvelle page',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => 'classification des articles',
|
||||
'info_title' => 'titre des informations',
|
||||
'info_content' => 'contenu',
|
||||
|
||||
'pages_index' => 'liste des catégories',
|
||||
];
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => 'Blog d\'actualités',
|
||||
'author' => 'Auteur',
|
||||
'views' => 'numéro de vue',
|
||||
'created_at' => 'heure de sortie',
|
||||
];
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => 'modifica della pagina',
|
||||
'page_category' => 'classificazione articolo',
|
||||
'modules_instructions' => 'Moduli disponibili, fare clic su Aggiungi alla pagina',
|
||||
'text_floor_prompt' => 'Impostazioni (la configurazione del piano deve essere salvata e aggiornata per aggiornare la pagina)',
|
||||
'text_new_page' => 'Aggiungi nuova pagina',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => 'classificazione articolo',
|
||||
'info_title' => 'titolo informazioni',
|
||||
'info_content' => 'contenuto',
|
||||
|
||||
'pages_index' => 'elenco di categorie',
|
||||
];
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => 'Blog di notizie',
|
||||
'author' => 'Autore',
|
||||
'views' => 'visualizza numero',
|
||||
'created_at' => 'tempo di rilascio',
|
||||
'text_summary' => 'panoramica categoria',
|
||||
'text_summary' => 'aperçu des catégories',
|
||||
];
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => 'ページ編集',
|
||||
'page_category' => '記事分類',
|
||||
'modules_instructions' => '利用可能なモジュール、クリックしてページに追加',
|
||||
'text_floor_prompt' => '設定 (ページを更新するには、フロア構成を保存して更新する必要があります)',
|
||||
'text_new_page' => '新しいページを追加',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => '記事分類',
|
||||
'info_title' => '情報タイトル',
|
||||
'info_content' => 'コンテンツ',
|
||||
|
||||
'pages_index' => 'カテゴリーリスト',
|
||||
];
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => 'ニュースブログ',
|
||||
'author' => '作者',
|
||||
'views' => 'ビュー番号',
|
||||
'created_at' => 'リリース時間',
|
||||
'text_summary' => 'カテゴリ概要',
|
||||
];
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => 'редактирование страницы',
|
||||
'page_category' => 'классификация статей',
|
||||
'modules_instructions' => 'Доступные модули, нажмите Добавить на страницу',
|
||||
'text_floor_prompt' => 'Настройки (конфигурация этажа должна быть сохранена и обновлена для обновления страницы)',
|
||||
'text_new_page' => 'Добавить новую страницу',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => 'Artikelklassifizierung',
|
||||
'info_title' => 'Informationstitel',
|
||||
'info_content' => 'Inhalt',
|
||||
|
||||
'pages_index' => 'Kategorieliste',
|
||||
];
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => 'Блог новостей',
|
||||
'author' => 'Автор',
|
||||
'views' => 'номер просмотра',
|
||||
'created_at' => 'время выпуска',
|
||||
'text_summary' => 'обзор категорий',
|
||||
];
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => '页面编辑',
|
||||
'page_category' => '文章分类',
|
||||
'modules_instructions' => '可用模块,点击添加至页面',
|
||||
'text_floor_prompt' => '设置(楼层配置需要保存刷新页面才会更新)',
|
||||
'text_new_page' => '添加新页面',
|
||||
|
|
@ -69,9 +70,9 @@ return [
|
|||
'text_disable' => '禁用',
|
||||
'text_no_data' => '数据不存在或已被删除',
|
||||
'text_to_add' => '去添加',
|
||||
'text_category' => '分类',
|
||||
'text_information' => '信息页面',
|
||||
'text_manufacturer' => '品牌',
|
||||
'text_category' => '商品分类',
|
||||
'text_information' => '特定页面',
|
||||
'text_manufacturer' => '商品品牌',
|
||||
'text_static' => '固定连接',
|
||||
'text_custom' => '自定义',
|
||||
'text_top_text' => '顶部文字',
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ return [
|
|||
'currencies_index' => '货币管理',
|
||||
'languages_index' => '语言管理',
|
||||
'design_index' => '首页装修',
|
||||
'pages_index' => '信息页面',
|
||||
'pages_index' => '文章管理',
|
||||
'page_categories_index' => '文章分类',
|
||||
'design_footer_index' => '页尾装修',
|
||||
'design_menu_index' => '导航配置',
|
||||
'categories_index' => '商品分类',
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@
|
|||
*/
|
||||
|
||||
return [
|
||||
'index' => '信息页面',
|
||||
'index' => '文章管理',
|
||||
'info_title' => '信息标题',
|
||||
'info_content' => '内容',
|
||||
|
||||
'pages_index' => '单页列表',
|
||||
'pages_create' => '创建单页',
|
||||
'pages_show' => '单页详情',
|
||||
'pages_update' => '单页编辑',
|
||||
'pages_delete' => '删除单页',
|
||||
'pages_index' => '文章列表',
|
||||
'pages_create' => '创建文章',
|
||||
'pages_show' => '文章详情',
|
||||
'pages_update' => '文章编辑',
|
||||
'pages_delete' => '删除文章',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => '文章分类',
|
||||
'info_title' => '信息标题',
|
||||
'info_content' => '内容',
|
||||
|
||||
'pages_index' => '分类列表',
|
||||
];
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => '新闻博客',
|
||||
'author' => '作者',
|
||||
'views' => '查看数',
|
||||
'created_at' => '发布时间',
|
||||
'text_summary' => '摘要',
|
||||
];
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
return [
|
||||
'heading_title' => '頁面編輯',
|
||||
'page_category' => '文章分類',
|
||||
'modules_instructions' => '可用模塊,點擊添加至頁面',
|
||||
'text_floor_prompt' => '設置(樓層配置需要保存刷新頁面才會更新)',
|
||||
'text_new_page' => '添加新頁面',
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@
|
|||
*/
|
||||
|
||||
return [
|
||||
'index' => '信息頁面',
|
||||
'index' => '文章管理',
|
||||
'info_title' => '信息標題',
|
||||
'info_content' => '內容',
|
||||
|
||||
'pages_index' => '單頁列表',
|
||||
'pages_create' => '創建單頁',
|
||||
'pages_show' => '單頁詳情',
|
||||
'pages_update' => '單頁編輯',
|
||||
'pages_delete' => '刪除單頁',
|
||||
'pages_index' => '文章列表',
|
||||
'pages_create' => '創建文章',
|
||||
'pages_show' => '文章詳情',
|
||||
'pages_update' => '文章編輯',
|
||||
'pages_delete' => '刪除文章',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-02 14:22:41
|
||||
* @modified 2022-08-02 14:22:41
|
||||
*/
|
||||
|
||||
return [
|
||||
'index' => '文章分類',
|
||||
'info_title' => '信息標題',
|
||||
'info_content' => '內容',
|
||||
|
||||
'pages_index' => '分類列表',
|
||||
];
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* page.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-07-28 20:59:38
|
||||
* @modified 2022-07-28 20:59:38
|
||||
*/
|
||||
return [
|
||||
'index' => '新聞博客',
|
||||
'author' => '作者',
|
||||
'views' => '查看數',
|
||||
'created_at' => '發佈時間',
|
||||
'text_summary' => '分類概述',
|
||||
];
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-categories-home')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
{{ $breadcrumb->render() }}
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-12">
|
||||
<div class="card mb-4 shadow-sm p-3 h-min-600">
|
||||
<div class="card-body">
|
||||
@foreach ($active_pages as $page)
|
||||
<div>
|
||||
<h5 class="card-title mb-2"><a class="text-black" href="{{ shop_route('pages.show', [$page->id]) }}">{{ $page->description->title }}</a></h5>
|
||||
<p class="fs-6 mb-3 text-secondary">{{ $page->created_at }}</p>
|
||||
@if ($page->description->summary)
|
||||
<p class="card-text mb-3">{{ $page->description->summary ?? '' }}</p>
|
||||
@endif
|
||||
<div class="text-danger"><a href="{{ shop_route('pages.show', [$page->id]) }}">{{ __('shop/account.check_details') }}<i class="bi bi-arrow-right-short"></i></a></div>
|
||||
</div>
|
||||
|
||||
@if (!$loop->last)
|
||||
<hr class="my-4">
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($active_page_categories)
|
||||
<div class="col-lg-3 col-12">
|
||||
<div class="card mb-3 shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('product.category') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach ($active_page_categories as $category)
|
||||
<li class="list-group-item p-0">
|
||||
<a href="{{ shop_route('page_categories.show', [$category->id]) }}"
|
||||
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-categories-home')
|
||||
@section('title', $category->description->meta_title ?: system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 -
|
||||
BeikeShop官网') . ' - ' . $category->description->name)
|
||||
@section('keywords', $category->description->meta_keywords ?: system_setting('base.meta_keyword'))
|
||||
@section('description', $category->description->meta_description ?: system_setting('base.meta_description'))
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<x-shop-breadcrumb type="page_category" :value="$category['id']" />
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-12">
|
||||
<div class="card mb-4 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h3>{{ $category->description->title }}</h3>
|
||||
<div>{{ $category->description->summary }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4 shadow-sm">
|
||||
<div class="card-body">
|
||||
@if ($category_pages->count() > 0)
|
||||
@foreach ($category_pages as $page)
|
||||
<div>
|
||||
<h5 class="card-title mb-2"><a class="text-black"
|
||||
href="{{ shop_route('pages.show', [$page->id]) }}">{{ $page->description->title }}</a></h5>
|
||||
<p class="fs-6 mb-3 text-secondary">{{ $page->created_at }}</p>
|
||||
@if ($page->description->summary)
|
||||
<p class="card-text mb-4">{{ $page->description->summary ?? '' }}</p>
|
||||
@endif
|
||||
<div class="text-danger"><a
|
||||
href="{{ shop_route('pages.show', [$page->id]) }}">{{ __('shop/account.check_details') }}<i
|
||||
class="bi bi-arrow-right-short"></i></a></div>
|
||||
</div>
|
||||
|
||||
@if (!$loop->last)
|
||||
<hr class="my-4">
|
||||
@endif
|
||||
@endforeach
|
||||
@else
|
||||
<x-shop-no-data />
|
||||
@endif
|
||||
|
||||
{{ $category_pages->links('shared/pagination/bootstrap-4') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($active_page_categories)
|
||||
<div class="col-lg-3 col-12">
|
||||
<div class="card mb-3 shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('product.category') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach ($active_page_categories as $category)
|
||||
<li class="list-group-item p-0">
|
||||
<a href="{{ shop_route('page_categories.show', [$category->id]) }}"
|
||||
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
@extends('layout.master')
|
||||
@section('body-class', 'page-pages')
|
||||
@section('title', $page->description->meta_title ?: $page->description->title)
|
||||
@section('keywords', $page->description->meta_keywords)
|
||||
@section('description', $page->description->meta_description)
|
||||
|
||||
@push('header')
|
||||
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<x-shop-breadcrumb type="page" :value="$page['id']" />
|
||||
<div class="row">
|
||||
<div class="{{ $page->category ? "col-lg-9 col-12" : 'col-12' }}">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body h-min-600 p-lg-4">
|
||||
<h2 class="mb-3">{{ $page->description->title }}</h2>
|
||||
<div class="text-secondary opacity-75 mb-4">
|
||||
<span class="me-3"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg> {{ __('page_category.author') }}: {{ $page->author }}</span>
|
||||
<span class="me-3"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clock"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg> {{ __('page_category.created_at') }}: {{ $page->created_at }}</span>
|
||||
<span><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg> {{ __('page_category.views') }}: {{ $page->views }}</span>
|
||||
</div>
|
||||
{!! $page_format['content'] !!}
|
||||
|
||||
|
||||
@if ($products)
|
||||
<div class="relations-wrap mt-5">
|
||||
<div class="container position-relative">
|
||||
<div class="title text-center fs-4 mb-4">{{ __('admin/product.product_relations') }}</div>
|
||||
<div class="product swiper-style-plus">
|
||||
<div class="swiper relations-swiper">
|
||||
<div class="swiper-wrapper">
|
||||
@foreach ($products as $item)
|
||||
<div class="swiper-slide">
|
||||
@include('shared.product', ['product' => $item])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-pagination relations-pagination"></div>
|
||||
<div class="swiper-button-prev relations-swiper-prev"></div>
|
||||
<div class="swiper-button-next relations-swiper-next"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($page->category)
|
||||
<div class="col-lg-3 col-12">
|
||||
<div class="card mb-3 shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">{{ __('product.category') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach ($active_page_categories as $category)
|
||||
<li class="list-group-item p-0">
|
||||
<a href="{{ shop_route('page_categories.show', [$category->id]) }}"
|
||||
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
<script>
|
||||
var relationsSwiper = new Swiper ('.relations-swiper', {
|
||||
watchSlidesProgress: true,
|
||||
breakpoints:{
|
||||
320: {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: 10,
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 30,
|
||||
},
|
||||
},
|
||||
spaceBetween: 30,
|
||||
// 如果需要前进后退按钮
|
||||
navigation: {
|
||||
nextEl: '.relations-swiper-next',
|
||||
prevEl: '.relations-swiper-prev',
|
||||
},
|
||||
|
||||
// 如果需要分页器
|
||||
pagination: {
|
||||
el: '.relations-pagination',
|
||||
clickable: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -7,8 +7,10 @@
|
|||
@section('content')
|
||||
<div class="container">
|
||||
<x-shop-breadcrumb type="page" :value="$page['id']" />
|
||||
<div class="row">
|
||||
{!! $page['content'] !!}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
{!! $page_format['content'] !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Loading…
Reference in New Issue