版本合并、和客户修改后的版本合并
修改:商品编辑页面取消sku;起订量从规格中移除,统一设置起订量 修改:客服端显示最小起订量
This commit is contained in:
parent
39cd329a47
commit
b679d66adb
BIN
43.153.17.83.rar
BIN
43.153.17.83.rar
Binary file not shown.
|
|
@ -40,7 +40,7 @@ class LogisticsController extends Controller
|
|||
'logistics' => $logistics,
|
||||
'type' => 'logistics',
|
||||
'default_countries' => $countries,
|
||||
'default_countries_name' => is_array($countries) ? array_values($countries)[0]['name'] : ''
|
||||
'default_countries_name' => is_array($countries) && count($countries) > 0 ? array_values($countries)[0]['name'] : ''
|
||||
];
|
||||
|
||||
$data = hook_filter('admin.logistics.index.data', $data);
|
||||
|
|
|
|||
|
|
@ -32,14 +32,20 @@ class ProductRequest extends FormRequest
|
|||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
$rules = [
|
||||
'descriptions.*.name' => 'required|string|min:3|max:128',
|
||||
'brand_id' => 'int',
|
||||
'skus.*.sku' => 'required|string',
|
||||
// 'skus.*.sku' => 'required|string',
|
||||
'skus.*.price' => 'required|numeric',
|
||||
'skus.*.origin_price' => 'required|numeric',
|
||||
'skus.*.cost_price' => 'numeric',
|
||||
// 'skus.*.cost_price' => 'numeric',
|
||||
];
|
||||
// 判断:最小起订量是否必填 直接下单产品 - 必填
|
||||
if($this->active == 1){
|
||||
$rules['minimum_order'] = 'required|numeric|gt:0';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function attributes()
|
||||
|
|
@ -47,10 +53,11 @@ class ProductRequest extends FormRequest
|
|||
return [
|
||||
'descriptions.*.name' => trans('product.name'),
|
||||
'brand_id' => trans('product.brand'),
|
||||
'skus.*.sku' => trans('product.sku'),
|
||||
// 'skus.*.sku' => trans('product.sku'),
|
||||
'skus.*.price' => trans('product.price'),
|
||||
'skus.*.origin_price' => trans('product.origin_price'),
|
||||
'skus.*.cost_price' => trans('product.cost_price'),
|
||||
// 'skus.*.cost_price' => trans('product.cost_price'),
|
||||
'minimum_order' => trans('product.minimum_order'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ class ProductResource extends JsonResource
|
|||
return image_resize($image);
|
||||
}, $this->images ?? []),
|
||||
'name' => $this->description->name ?? '',
|
||||
'model' => $masterSku->model,
|
||||
'quantity' => $masterSku->quantity,
|
||||
'price_formatted' => currency_format($masterSku->price),
|
||||
'model' => $masterSku->model ?? '',
|
||||
'quantity' => $masterSku->quantity ?? 0,
|
||||
'price_formatted' => currency_format($masterSku->price ?? 0),
|
||||
'active' => $this->active,
|
||||
'position' => $this->position,
|
||||
'url' => $this->url,
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class ProductService
|
|||
foreach ($data['skus'] as $index => $sku) {
|
||||
$sku['position'] = $index;
|
||||
$sku['origin_price'] = (float) $sku['origin_price'];
|
||||
$sku['cost_price'] = (float) $sku['cost_price'];
|
||||
$sku['cost_price'] = (float) ($sku['cost_price'] ?? 0);
|
||||
$sku['quantity'] = (int) $sku['quantity'];
|
||||
$skus[] = $sku;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class Product extends Base
|
|||
use HasFactory;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['images', 'video', 'position', 'brand_id', 'tax_class_id', 'weight', 'weight_class', 'active', 'variables', 'price_setting', 'length', 'width', 'height'];
|
||||
protected $fillable = ['images', 'video', 'position', 'brand_id', 'tax_class_id', 'weight', 'weight_class', 'active', 'variables', 'price_setting', 'length', 'width', 'height', 'minimum_order'];
|
||||
|
||||
protected $casts = [
|
||||
'active' => 'boolean',
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class InquiryDetail extends JsonResource{
|
|||
];
|
||||
}
|
||||
$product = $productsku->product;
|
||||
$description = $product->description;
|
||||
$description = $product->description ?? '';
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'product_sku_id' => $this->product_sku_id,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class ProductSimple extends JsonResource
|
|||
'in_wishlist' => $this->inCurrentWishlist->id ?? 0,
|
||||
'price_setting' => $this->price_setting ?? '',
|
||||
'numprices' => NumPricesDetail::collection($this->numprices)->jsonSerialize() ?? '',
|
||||
|
||||
'minimum_order' => $this->minimum_order,
|
||||
'images' => array_map(function ($item) {
|
||||
return image_resize($item, 400, 400);
|
||||
}, $images),
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -1 +0,0 @@
|
|||
open_basedir=/www/wwwroot/wyyl.dev.zoomtk.com/:/tmp/
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 8.1 KiB |
|
|
@ -136,7 +136,23 @@
|
|||
</div>
|
||||
</x-admin::form.row>
|
||||
|
||||
<x-admin-form-switch-status name="active" :title="__('common.status')" :value="old('active', $product->active ?? 1)" />
|
||||
{{--<x-admin-form-switch-status name="active" :title="__('common.status')" :value="old('active', $product->active ?? 1)" v-model="editing.isVariable" />--}}
|
||||
<x-admin::form.row title="{{ __('common.status') }}">
|
||||
<div class="mb-1 mt-2">
|
||||
<div class="form-check form-check-inline">
|
||||
<input v-model="form.active" class="form-check-input" id="active-1" type="radio" name="active" value="1">
|
||||
<label class="form-check-label" for="active-1">{{ __('common.enable_status') }}</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input v-model="form.active" class="form-check-input" id="active-0" type="radio" name="active" value="0">
|
||||
<label class="form-check-label" for="active-0">{{ __('common.disable_status') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</x-admin::form.row>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@hook('admin.product.edit.extra')
|
||||
|
||||
|
|
@ -161,7 +177,7 @@
|
|||
<div class="price_setting_by_num">
|
||||
<div class="left">
|
||||
<div class="head">
|
||||
<div class="num" >最小起订量</div>
|
||||
<div class="num" >{{__('admin/product.minimum_order')}}</div>
|
||||
<div class="price">产品价格</div>
|
||||
<div class="delete">删除</div>
|
||||
</div>
|
||||
|
|
@ -301,10 +317,10 @@
|
|||
<i class="bi bi-plus fs-3 text-muted" v-else></i>
|
||||
</div>
|
||||
<input type="text" class="form-control me-2 bg-white" v-model="variablesBatch.model" placeholder="{{ __('admin/product.model') }}">
|
||||
<input type="text" class="form-control me-2 bg-white" v-model="variablesBatch.sku" placeholder="sku">
|
||||
{{--<input type="text" class="form-control me-2 bg-white" v-model="variablesBatch.sku" placeholder="sku">--}}
|
||||
<input type="number" v-if="form.price_setting === 'sku'" class="form-control me-2 bg-white" v-model="variablesBatch.price" placeholder="{{ __('admin/product.price') }}">
|
||||
<input type="number" v-if="form.price_setting === 'sku'" class="form-control me-2 bg-white" v-model="variablesBatch.origin_price" placeholder="{{ __('admin/product.origin_price') }}">
|
||||
<input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.cost_price" placeholder="{{ __('admin/product.cost_price') }}">
|
||||
{{-- <input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.cost_price" placeholder="{{ __('admin/product.cost_price') }}">--}}
|
||||
<input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.quantity" placeholder="{{ __('admin/product.quantity') }}">
|
||||
<button type="button" class="btn btn-primary text-nowrap" @click="batchSettingVariant">{{ __('common.batch_setting') }}</button>
|
||||
</div>
|
||||
|
|
@ -316,10 +332,10 @@
|
|||
</th>
|
||||
<th width="106px">{{ __('common.image') }}</th>
|
||||
<th class="w-min-100">{{ __('admin/product.model') }}</th>
|
||||
<th class="w-min-100">sku</th>
|
||||
{{--<th class="w-min-100">sku</th>--}}
|
||||
<th v-if="form.price_setting === 'sku'" class="w-min-100">{{ __('admin/product.price') }}</th>
|
||||
<th v-if="form.price_setting === 'sku'" class="w-min-100">{{ __('admin/product.origin_price') }}</th>
|
||||
<th class="w-min-100">{{ __('admin/product.cost_price') }}</th>
|
||||
{{--<th class="w-min-100">{{ __('admin/product.cost_price') }}</th>--}}
|
||||
<th class="w-min-100">{{ __('admin/product.quantity') }}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -348,11 +364,11 @@
|
|||
</td>
|
||||
<td><input type="text" class="form-control" v-model="sku.model" :name="'skus[' + skuIndex + '][model]'"
|
||||
placeholder="{{ __('admin/product.model') }}"></td>
|
||||
<td>
|
||||
{{-- <td>
|
||||
<input type="text" class="form-control" v-model="sku.sku" :name="'skus[' + skuIndex + '][sku]'" placeholder="sku" :style="sku.is_default ? 'margin-top: 19px;' : ''" required>
|
||||
<span role="alert" class="invalid-feedback">{{ __('common.error_required', ['name' => 'sku']) }}</span>
|
||||
<span v-if="sku.is_default" class="text-success">{{ __('admin/product.default_main_product') }}</span>
|
||||
</td>
|
||||
</td>--}}
|
||||
<td v-if="form.price_setting === 'sku'">
|
||||
<input type="number" class="form-control" v-model="sku.price" :name="'skus[' + skuIndex + '][price]'" step="any"
|
||||
placeholder="{{ __('admin/product.price') }}" required>
|
||||
|
|
@ -365,10 +381,9 @@
|
|||
</td>
|
||||
<input type="hidden" :name="'skus[' + skuIndex + '][price]'" v-if="form.price_setting === 'num'" placeholder="variants" :value="form.numPrices.length !== 0 ? form.numPrices[0].price : ''">
|
||||
<input type="hidden" :name="'skus[' + skuIndex + '][origin_price]'" v-if="form.price_setting === 'num'" placeholder="position" :value="form.numPrices.length !== 0 ? form.numPrices[form.numPrices.length - 1].price : ''">
|
||||
|
||||
<td><input type="number" class="form-control" v-model="sku.cost_price" :name="'skus[' + skuIndex + '][cost_price]'"
|
||||
placeholder="{{ __('admin/product.cost_price') }}">
|
||||
</td>
|
||||
{{--<td>
|
||||
<input type="number" class="form-control" v-model="sku.cost_price" :name="'skus[' + skuIndex + '][cost_price]'" placeholder="{{ __('admin/product.cost_price') }}">
|
||||
</td>--}}
|
||||
<td><input type="number" class="form-control" v-model="sku.quantity" :name="'skus[' + skuIndex + '][quantity]'"
|
||||
placeholder="{{ __('admin/product.quantity') }}"></td>
|
||||
</tr>
|
||||
|
|
@ -380,22 +395,42 @@
|
|||
<div class="invalid-feedback" style="font-size: 16px"><i class="bi bi-exclamation-circle-fill"></i> {{ __('admin/product.add_variable') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{--最小起订量--}}
|
||||
{{-- 未开启根据数量设置价格、直接下单产品 --}}
|
||||
<template v-if="form.price_setting === 'sku' && form.active == 1">
|
||||
<x-admin::form.row :title="__('admin/product.minimum_order')" required>
|
||||
<input type="number" name="minimum_order" v-model="form.minimum_order" class="form-control wp-400"/>
|
||||
</x-admin::form.row>
|
||||
</template>
|
||||
{{-- 未开启根据数量设置价格、非直接下单商品 --}}
|
||||
<template v-else-if="form.price_setting === 'sku' && form.active != 1">
|
||||
<x-admin::form.row :title="__('admin/product.minimum_order')">
|
||||
<input type="number" name="minimum_order" v-model="form.minimum_order" class="form-control wp-400" />
|
||||
</x-admin::form.row>
|
||||
</template>
|
||||
{{--开启根据数量设置价格 - 数量固定为最小起订量--}}
|
||||
<template v-else>
|
||||
<x-admin::form.row :title="__('admin/product.minimum_order')" required>
|
||||
<input type="number" name="minimum_order" :value="form.numPrices.length !== 0 ? form.numPrices[0].num : 0" class="form-control wp-400" readonly/>
|
||||
</x-admin::form.row>
|
||||
</template>
|
||||
|
||||
|
||||
@hookwrapper('admin.product.edit.variable')
|
||||
<div v-if="!editing.isVariable">
|
||||
<input type="hidden" value="{{ old('skus.0.image', $product->skus[0]->image ?? '') }}" name="skus[0][image]">
|
||||
<x-admin-form-input name="skus[0][model]" :title="__('admin/product.model')" :value="old('skus.0.model', $product->skus[0]->model ?? '')" />
|
||||
<x-admin-form-input name="skus[0][sku]" title="sku" :value="old('skus.0.sku', $product->skus[0]->sku ?? '')" required />
|
||||
{{--<x-admin-form-input name="skus[0][sku]" title="sku" :value="old('skus.0.sku', $product->skus[0]->sku ?? '')" required />--}}
|
||||
<span v-if="form.price_setting === 'sku'">
|
||||
<x-admin-form-input name="skus[0][price]" type="number" :title="__('admin/product.price')" :value="old('skus.0.price', $product->skus[0]->price ?? '')" step="any" required />
|
||||
<x-admin-form-input name="skus[0][origin_price]" type="number" :title="__('admin/product.origin_price')" :value="old('skus.0.origin_price', $product->skus[0]->origin_price ?? '')" step="any" required />
|
||||
</span>
|
||||
<x-admin-form-input name="skus[0][cost_price]" type="number" :title="__('admin/product.cost_price')" :value="old('skus.0.cost_price', $product->skus[0]->cost_price ?? '')" />
|
||||
<x-admin-form-input name="skus[0][quantity]" type="number" :title="__('admin/product.quantity')" :value="old('skus.0.quantity', $product->skus[0]->quantity ?? '')" />
|
||||
<input type="hidden" name="skus[0][price]" v-if="form.price_setting === 'num'" placeholder="variants" :value="form.numPrices.length !== 0 ? form.numPrices[0].price : ''">
|
||||
<input type="hidden" name="skus[0][origin_price]" v-if="form.price_setting === 'num'" placeholder="position" :value="form.numPrices.length !== 0 ? form.numPrices[form.numPrices.length - 1].price : ''">
|
||||
<input type="hidden" name="skus[0][variants]" placeholder="variants" value="">
|
||||
<input type="hidden" name="skus[0][position]" placeholder="position" value="0">
|
||||
{{--<x-admin-form-input name="skus[0][cost_price]" type="number" :title="__('admin/product.cost_price')" :value="old('skus.0.cost_price', $product->skus[0]->cost_price ?? '')" required />--}}
|
||||
<input type="hidden" name="skus[0][is_default]" placeholder="is_default" value="1">
|
||||
</div>
|
||||
@endhookwrapper
|
||||
|
|
@ -636,8 +671,10 @@
|
|||
status: @json($product->skus[0]['status'] ?? false),
|
||||
variables: @json($product->variables ?? []),
|
||||
skus: @json(old('skus', $product->skus) ?? []),
|
||||
active: {{(int)$product->active}},
|
||||
price_setting: @json(old('price_setting', $product->price_setting) ?? 'sku'),
|
||||
numPrices: @json(old('numPrices', $product->numprices) ?? []),
|
||||
minimum_order: {{$product->minimum_order ?? 0}},
|
||||
},
|
||||
|
||||
variablesBatch: {
|
||||
|
|
|
|||
|
|
@ -56,4 +56,5 @@ return [
|
|||
'confirm_batch_restore' => 'Confirm to restore the selected product? ',
|
||||
'confirm_delete_restore' => 'Are you sure you want to empty the recycle bin? ',
|
||||
'num_select' => 'Num select ',
|
||||
'minimum_order' => 'Min Order'
|
||||
];
|
||||
|
|
|
|||
|
|
@ -28,4 +28,5 @@ return [
|
|||
'active' => 'Active',
|
||||
'inactive' => 'Inactive',
|
||||
'has_been_inactive' => 'The product has been inactive',
|
||||
'minimum_order' => 'Min Order'
|
||||
];
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ return [
|
|||
'product_relations' => '相关物流',
|
||||
'stocks' => '物流库存',
|
||||
'model' => '型号',
|
||||
'price' => '价格',
|
||||
'origin_price' => '原价',
|
||||
'cost_price' => '成本价',
|
||||
'price' => '区间低价',
|
||||
'origin_price' => '区间高价',
|
||||
'cost_price' => '起订量',
|
||||
'quantity' => '数量',
|
||||
'enable_multi_spec' => '启用多规格',
|
||||
'image_help' => '第一张图片将作为物流主图,支持同时上传多张图片,多张图片之间可随意调整位置',
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ return [
|
|||
'product_relations' => '相关商品',
|
||||
'stocks' => '商品库存',
|
||||
'model' => '型号',
|
||||
'price' => '价格',
|
||||
'origin_price' => '原价',
|
||||
'cost_price' => '成本价',
|
||||
'price' => '区间低价',
|
||||
'origin_price' => '区间高价',
|
||||
'cost_price' => '起订量',
|
||||
'quantity' => '数量',
|
||||
'enable_multi_spec' => '启用多规格',
|
||||
'image_help' => '第一张图片将作为商品主图,支持同时上传多张图片,多张图片之间可随意调整位置',
|
||||
|
|
@ -61,4 +61,5 @@ return [
|
|||
'num' => '根据数量设置价格',
|
||||
],
|
||||
'num_select' => '数量选择',
|
||||
'minimum_order' => '起订量'
|
||||
];
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
return [
|
||||
'name' => '名称',
|
||||
'sku' => 'SKU',
|
||||
'price' => '价格',
|
||||
'origin_price' => '原价',
|
||||
'cost_price' => '成本价',
|
||||
'price' => '区间低价',
|
||||
'origin_price' => '区间高价',
|
||||
'cost_price' => '起订量',
|
||||
'brand' => '品牌',
|
||||
'category' => '分类',
|
||||
'model' => '型号',
|
||||
|
|
@ -29,4 +29,5 @@ return [
|
|||
'active' => '上架',
|
||||
'inactive' => '下架',
|
||||
'has_been_inactive' => '该商品已下架',
|
||||
'minimum_order' => '起订量'
|
||||
];
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@
|
|||
@endhookwrapper
|
||||
<div class="price-wrap d-flex align-items-end" v-if="price_setting === 'sku'">
|
||||
<div class="new-price fs-1 lh-1 fw-bold me-2">@{{ product.price_format }}</div>
|
||||
<div class="old-price text-muted text-decoration-line-through" v-if="product.price != product.origin_price && product.origin_price !== 0">
|
||||
<div class="new-price fs-1 lh-1 fw-bold me-2">-</div>
|
||||
<div class="old-price fs-1 lh-1 fw-bold me-2" v-if="product.price != product.origin_price && product.origin_price !== 0">
|
||||
@{{ product.origin_price_format }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -169,7 +169,8 @@
|
|||
@hookwrapper('product.detail.price')
|
||||
<div class="price-wrap d-flex align-items-end" v-if="price_setting === 'sku'">
|
||||
<div class="new-price fs-1 lh-1 fw-bold me-2">@{{ product.price_format }}</div>
|
||||
<div class="old-price text-muted text-decoration-line-through" v-if="product.price != product.origin_price && product.origin_price !== 0">
|
||||
<div class="new-price fs-1 lh-1 fw-bold me-2">-</div>
|
||||
<div class="old-price fs-1 lh-1 fw-bold me-2" v-if="product.price != product.origin_price && product.origin_price !== 0">
|
||||
@{{ product.origin_price_format }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -73,9 +73,9 @@
|
|||
@if ($product['price_setting'] === 'num')
|
||||
<span class="price-new">{{$product['numprices'] != [] ? $product['numprices'][0]['num'] : 1}} pieces</span>
|
||||
@else
|
||||
<span class="price-new">1 pieces</span>
|
||||
<span class="price-new">{{$product['minimum_order'] ?? 0}} pieces</span>
|
||||
@endif
|
||||
<span style="color:#aaa;margin-left:4px">(Min Order)</span>
|
||||
<span style="color:#aaa;margin-left:4px">({{__('admin/product.minimum_order')}})</span>
|
||||
</div>
|
||||
|
||||
@if (request('style_list') == 'list')
|
||||
|
|
|
|||
Loading…
Reference in New Issue