相关后台商品配置和 前台ui
This commit is contained in:
parent
6e8d7f295f
commit
c1db80eaaa
|
|
@ -173,4 +173,66 @@ body.page-product-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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,11 +37,13 @@
|
|||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-seo" type="button" >SEO</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-relations" type="button">{{ __('admin/product.product_relations') }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="card">
|
||||
{{-- <div class="card-header"><h6 class="card-title">基础信息</h6></div> --}}
|
||||
<div class="card-body">
|
||||
<div class="card-body h-min-600">
|
||||
<form novalidate class="needs-validation" action="{{ $product->id ? admin_route('products.update', $product) : admin_route('products.store') }}"
|
||||
method="POST" id="app">
|
||||
@csrf
|
||||
|
|
@ -317,6 +319,7 @@
|
|||
</div>
|
||||
</x-admin::form.row>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="tab-seo">
|
||||
<h6 class="border-bottom pb-3 mb-4">SEO</h6>
|
||||
<x-admin::form.row title="Meta title">
|
||||
|
|
@ -344,8 +347,45 @@
|
|||
@endforeach
|
||||
</x-admin::form.row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="tab-relations">
|
||||
<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="relationsQuerySearch"
|
||||
placeholder="{{ __('admin/builder.modules_keywords_search') }}"
|
||||
@select="relationsHandleSelect"
|
||||
></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="'relations['+ 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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-admin::form.row title="">
|
||||
<button type="submit" class="btn btn-primary mt-3 btn-lg">{{ __('common.save') }}</button>
|
||||
|
|
@ -422,6 +462,12 @@
|
|||
skus: @json($product->skus ?? []),
|
||||
},
|
||||
|
||||
relations: {
|
||||
keyword: '',
|
||||
products: @json($relations ?? []),
|
||||
loading: null,
|
||||
},
|
||||
|
||||
source: {
|
||||
variables: @json($product->variables ?? []),
|
||||
languages: @json($languages ?? []),
|
||||
|
|
@ -491,6 +537,23 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
relationsQuerySearch(keyword, cb) {
|
||||
$http.get('products/autocomplete?name=' + encodeURIComponent(keyword), null, {hload:true}).then((res) => {
|
||||
cb(res.data);
|
||||
})
|
||||
},
|
||||
|
||||
relationsHandleSelect(item) {
|
||||
if (!this.relations.products.find(v => v == item.id)) {
|
||||
this.relations.products.push(item);
|
||||
}
|
||||
this.relations.keyword = ""
|
||||
},
|
||||
|
||||
relationsRemoveProduct(index) {
|
||||
this.relations.products.splice(index, 1);
|
||||
},
|
||||
|
||||
variantIsImage(e, index) {
|
||||
if (!e) {
|
||||
this.source.variables[index].values.forEach(v => {
|
||||
|
|
|
|||
|
|
@ -22,4 +22,36 @@
|
|||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.swiper-style-plus {
|
||||
position: relative;
|
||||
|
||||
.swiper-button-prev,.swiper-button-next {
|
||||
width: 34px;
|
||||
height: 37px;
|
||||
color: #333;
|
||||
@media (max-width: 768px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:after {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper-button-prev {
|
||||
left: -50px;
|
||||
}
|
||||
|
||||
.swiper-button-next {
|
||||
right: -50px;
|
||||
}
|
||||
|
||||
.swiper-pagination {
|
||||
.swiper-pagination-bullet-active {
|
||||
background: $primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
text-align: center;
|
||||
padding-bottom: .7rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
background-color: #fff;
|
||||
|
||||
.image {
|
||||
margin-bottom: 10px;
|
||||
|
|
@ -41,12 +42,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
||||
@media (min-width: 768px) {
|
||||
&:hover {
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
||||
|
||||
.button-wrap {
|
||||
bottom: 10px;
|
||||
opacity: 1;
|
||||
.button-wrap {
|
||||
bottom: 10px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
|
||||
'basic_information' => 'grundlegende Informationen',
|
||||
'product_details' => 'Produktdetails',
|
||||
'product_relations' => 'bezogene Waren',
|
||||
'stocks' => 'Warenbestand',
|
||||
'model' => 'Modell',
|
||||
'price' => 'Preis',
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ return [
|
|||
|
||||
'basic_information' => 'basic information',
|
||||
'product_details' => 'Product details',
|
||||
'product_relations' => 'Related goods',
|
||||
'stocks' => 'goods inventory',
|
||||
'model' => 'model',
|
||||
'price' => 'price',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
|
||||
'basic_information' => 'información básica',
|
||||
'product_details' => 'Detalles de producto',
|
||||
'product_relations' => 'bienes relacionados',
|
||||
'stocks' => 'Existencias de materias primas',
|
||||
'model' => 'modelo',
|
||||
'price' => 'precio',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
|
||||
'basic_information' => 'informations de base',
|
||||
'product_details' => 'détails du produit',
|
||||
'product_relations' => 'biens liés',
|
||||
'stocks' => 'inventaire des marchandises',
|
||||
'model' => 'maquette',
|
||||
'price' => 'le prix',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
|
||||
'basic_information' => 'informazioni di base',
|
||||
'product_details' => 'Dettagli prodotto',
|
||||
'product_relations' => 'beni correlati',
|
||||
'stocks' => 'inventario merci',
|
||||
'model' => 'modello',
|
||||
'price' => 'prezzo',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
|
||||
'basic_information' => '基本情報',
|
||||
'product_details' => '商品の詳細',
|
||||
'product_relations' => '関連商品',
|
||||
'stocks' => '商品在庫',
|
||||
'model' => 'モデル',
|
||||
'price' => '価格',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
|
||||
'basic_information' => 'основная информация',
|
||||
'product_details' => 'Подробнее о продукте',
|
||||
'product_relations' => 'сопутствующие товары',
|
||||
'stocks' => 'инвентаризация товаров',
|
||||
'model' => 'модель',
|
||||
'price' => 'цена',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
|
||||
'basic_information' => '基础信息',
|
||||
'product_details' => '商品详情',
|
||||
'product_relations' => '相关商品',
|
||||
'stocks' => '商品库存',
|
||||
'model' => '型号',
|
||||
'price' => '价格',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
|
||||
'basic_information' => '基礎信息',
|
||||
'product_details' => '商品詳情',
|
||||
'product_relations' => '相關商品',
|
||||
'stocks' => '商品庫存',
|
||||
'model' => '型號',
|
||||
'price' => '價格',
|
||||
|
|
|
|||
|
|
@ -164,6 +164,27 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($relations)
|
||||
<div class="relations-wrap mt-5">
|
||||
<div class="container position-relative">
|
||||
<div class="title text-center fs-1 mb-4">{{ __('admin/product.product_relations') }}</div>
|
||||
<div class="product swiper-style-plus">
|
||||
<div class="swiper relations-swiper">
|
||||
<div class="swiper-wrapper">
|
||||
@foreach ($relations as $item)
|
||||
<div class="swiper-slide">
|
||||
@include('shared.product', ['product' => $item])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-button-prev relations-swiper-prev"></div>
|
||||
<div class="swiper-button-next relations-swiper-next"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@push('add-scripts')
|
||||
|
|
@ -317,20 +338,34 @@
|
|||
slidesPerView: 6,
|
||||
spaceBetween:3,
|
||||
},
|
||||
|
||||
},
|
||||
pagination: {
|
||||
el: ".swiper-pagination",
|
||||
clickable: true,
|
||||
},
|
||||
navigation: {
|
||||
nextEl: '.swiper-button-next',
|
||||
prevEl: '.swiper-button-prev',
|
||||
nextEl: '.new-feature-slideshow-next',
|
||||
prevEl: '.new-feature-slideshow-prev',
|
||||
},
|
||||
observer: true,
|
||||
observeParents: true
|
||||
});
|
||||
|
||||
var relationsSwiper = new Swiper ('.relations-swiper', {
|
||||
breakpoints:{
|
||||
320: {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: 10,
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 30,
|
||||
},
|
||||
},
|
||||
spaceBetween: 30,
|
||||
// 如果需要前进后退按钮
|
||||
navigation: {
|
||||
nextEl: '.relations-swiper-next',
|
||||
prevEl: '.relations-swiper-prev',
|
||||
},
|
||||
})
|
||||
|
||||
@if (is_mobile())
|
||||
swiperMobile = new Swiper("#swiper-mobile", {
|
||||
slidesPerView: 1,
|
||||
|
|
|
|||
Loading…
Reference in New Issue