!123 Add video function
* Optimize shopping cart entries * File manager selection type judgment * video function * Support video for file manager * Optimize file manager
This commit is contained in:
parent
523b8a3e7c
commit
e7019a9722
|
|
@ -33,7 +33,7 @@ class UploadRequest extends FormRequest
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'file' => 'required|image|mimes:jpg,png,jpeg,gif,svg|max:10240',
|
'file' => 'required|mimes:jpg,png,jpeg,gif,svg,mp4|max:20480',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,12 +236,19 @@ class FileManagerService
|
||||||
*/
|
*/
|
||||||
private function handleImage($filePath, $baseName): array
|
private function handleImage($filePath, $baseName): array
|
||||||
{
|
{
|
||||||
$path = "catalog{$filePath}";
|
$path = "catalog{$filePath}";
|
||||||
|
$realPath = $this->fileBasePath . $filePath;
|
||||||
|
|
||||||
|
$mime = '';
|
||||||
|
if(file_exists($realPath)) {
|
||||||
|
$mime = mime_content_type($realPath);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'path' => $path,
|
'path' => $path,
|
||||||
'name' => $baseName,
|
'name' => $baseName,
|
||||||
'origin_url' => image_origin($path),
|
'origin_url' => image_origin($path),
|
||||||
|
'mime' => $mime,
|
||||||
'selected' => false,
|
'selected' => false,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ class Order extends Base
|
||||||
public function getStatusFormatAttribute()
|
public function getStatusFormatAttribute()
|
||||||
{
|
{
|
||||||
$statusMap = array_column(StateMachineService::getAllStatuses(), 'name', 'status');
|
$statusMap = array_column(StateMachineService::getAllStatuses(), 'name', 'status');
|
||||||
|
|
||||||
return $statusMap[$this->status];
|
return $statusMap[$this->status];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ class OrderHistory extends Base
|
||||||
public function getStatusFormatAttribute()
|
public function getStatusFormatAttribute()
|
||||||
{
|
{
|
||||||
$statusMap = array_column(StateMachineService::getAllStatuses(), 'name', 'status');
|
$statusMap = array_column(StateMachineService::getAllStatuses(), 'name', 'status');
|
||||||
|
|
||||||
return $statusMap[$this->status];
|
return $statusMap[$this->status];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ class CategoryRepo
|
||||||
$sql .= ' LEFT JOIN categories c2 ON (cp.path_id = c2.id)';
|
$sql .= ' LEFT JOIN categories c2 ON (cp.path_id = c2.id)';
|
||||||
$sql .= ' LEFT JOIN category_descriptions cd1 ON (cp.path_id = cd1.category_id)';
|
$sql .= ' LEFT JOIN category_descriptions cd1 ON (cp.path_id = cd1.category_id)';
|
||||||
$sql .= " WHERE cd1.locale = '" . $locale . "' ";
|
$sql .= " WHERE cd1.locale = '" . $locale . "' ";
|
||||||
if (!$includeInactive) {
|
if (! $includeInactive) {
|
||||||
$sql .= ' AND c1.active = 1 ';
|
$sql .= ' AND c1.active = 1 ';
|
||||||
}
|
}
|
||||||
$sql .= ' GROUP BY cp.category_id ORDER BY c1.position ASC';
|
$sql .= ' GROUP BY cp.category_id ORDER BY c1.position ASC';
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ class OrderController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
$order = Order::query()->where('number', $number)->where('email', $email)->firstOrFail();
|
$order = Order::query()->where('number', $number)->where('email', $email)->firstOrFail();
|
||||||
$data = hook_filter('order.show.data', ['order' => $order, 'html_items' => []]);
|
$data = hook_filter('order.show.data', ['order' => $order, 'html_items' => []]);
|
||||||
|
|
||||||
return view('order_info', $data);
|
return view('order_info', $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class ProductController extends Controller
|
||||||
|
|
||||||
$data = hook_filter('product.show.data', $data);
|
$data = hook_filter('product.show.data', $data);
|
||||||
|
|
||||||
return view('product', $data);
|
return view('product/product', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ class ProductDetail extends JsonResource
|
||||||
'meta_description' => $this->description->meta_description ?? '',
|
'meta_description' => $this->description->meta_description ?? '',
|
||||||
'brand_id' => $this->brand->id ?? 0,
|
'brand_id' => $this->brand->id ?? 0,
|
||||||
'brand_name' => $this->brand->name ?? '',
|
'brand_name' => $this->brand->name ?? '',
|
||||||
|
'video' => $this->video ?? '',
|
||||||
'images' => array_map(function ($image) {
|
'images' => array_map(function ($image) {
|
||||||
return [
|
return [
|
||||||
'preview' => image_resize($image, 500, 500),
|
'preview' => image_resize($image, 500, 500),
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -171,26 +171,21 @@ body.page-filemanager {
|
||||||
|
|
||||||
.content-center {
|
.content-center {
|
||||||
height: calc(100% - 56px);
|
height: calc(100% - 56px);
|
||||||
// display: flex;
|
|
||||||
// align-items: flex-start;
|
|
||||||
// flex-wrap: wrap;
|
|
||||||
// align-items: center; // flex-start | center
|
|
||||||
background: #f7f9fc;
|
background: #f7f9fc;
|
||||||
padding: 16px 6px;
|
padding: 16px 6px;
|
||||||
// justify-content: space-between; // flex-end | center | space-between
|
|
||||||
// flex-wrap: wrap;
|
|
||||||
// margin-right: -20px;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
align-content: flex-start;
|
align-content: flex-start;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
width: 4px;
|
width: 8px;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
border-radius: 2px;
|
border-radius: 4px;
|
||||||
background: $primary;
|
background: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
&::-webkit-scrollbar-track {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
@ -199,27 +194,10 @@ body.page-filemanager {
|
||||||
// display: flex;
|
// display: flex;
|
||||||
// flex-direction: column;
|
// flex-direction: column;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
// align-items: center;
|
|
||||||
// margin-bottom: 20px;
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
margin: 0 8px 16px;
|
margin: 0 8px 16px;
|
||||||
box-shadow: 0 0 2px 1px rgba(0, 0, 0, .07);
|
box-shadow: 0 0 2px 1px rgba(0, 0, 0, .07);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
// width: calc(20% - 20px);
|
|
||||||
|
|
||||||
// @media (min-width: 600px) {
|
|
||||||
// width: calc(25% - 20px);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @media (min-width: 1000px) {
|
|
||||||
// width: calc(20% - 20px);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @media (min-width: 1300px) {
|
|
||||||
// width: calc(16.666% - 20px);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// border: 1px solid transparent;
|
|
||||||
|
|
||||||
.img {
|
.img {
|
||||||
width: 137px;
|
width: 137px;
|
||||||
|
|
@ -232,6 +210,12 @@ body.page-filemanager {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 86px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
|
|
@ -295,22 +279,34 @@ body.page-filemanager {
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-image {
|
.upload-image {
|
||||||
height: 200px;
|
min-height: 200px;
|
||||||
|
max-height: 300px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
margin-right: -4px;
|
||||||
|
padding-right: 6px;
|
||||||
|
|
||||||
|
// 滚动条 透明背景
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
background-color: #f2f2f2;
|
margin-bottom: 12px;
|
||||||
padding: 6px 10px;
|
padding-bottom: 14px;
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
border-bottom: 1px solid #f1f1f1;
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center; // flex-start | center
|
align-items: center; // flex-start | center
|
||||||
justify-content: space-between; // flex-end | center | space-between
|
justify-content: space-between; // flex-end | center | space-between
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
* @link https://beikeshop.com
|
* @link https://beikeshop.com
|
||||||
* @Author pu shuo <pushuo@guangda.work>
|
* @Author pu shuo <pushuo@guangda.work>
|
||||||
* @Date 2022-08-26 18:18:22
|
* @Date 2022-08-26 18:18:22
|
||||||
* @LastEditTime 2023-05-18 15:33:10
|
* @LastEditTime 2023-06-08 19:18:24
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import http from "../../../js/http";
|
import http from "../../../js/http";
|
||||||
|
|
@ -95,21 +95,17 @@ const tinymceInit = () => {
|
||||||
fontsize_formats: "10px 12px 14px 18px 24px 36px 48px 56px 72px 96px",
|
fontsize_formats: "10px 12px 14px 18px 24px 36px 48px 56px 72px 96px",
|
||||||
lineheight_formats: "1 1.1 1.2 1.3 1.4 1.5 1.7 2.4 3 4",
|
lineheight_formats: "1 1.1 1.2 1.3 1.4 1.5 1.7 2.4 3 4",
|
||||||
setup: function(ed) {
|
setup: function(ed) {
|
||||||
const height = ed.getElement().dataset.tinymceHeight;
|
|
||||||
// console.log(ed);
|
|
||||||
// 修改 tinymce 的高度
|
|
||||||
// if (height) {
|
|
||||||
// ed.theme.resizeTo(null, height);
|
|
||||||
// }
|
|
||||||
|
|
||||||
ed.ui.registry.addButton('toolbarImageButton',{
|
ed.ui.registry.addButton('toolbarImageButton',{
|
||||||
// text: '',
|
|
||||||
icon: 'image',
|
icon: 'image',
|
||||||
onAction:function() {
|
onAction:function() {
|
||||||
bk.fileManagerIframe(images => {
|
bk.fileManagerIframe(images => {
|
||||||
if (images.length) {
|
if (images.length) {
|
||||||
images.forEach(e => {
|
images.forEach(e => {
|
||||||
ed.insertContent(`<img src='/${e.path}' class="img-fluid" />`);
|
if (e.mime == 'video/mp4') {
|
||||||
|
ed.insertContent(`<video src='/${e.path}' controls loop muted class="img-fluid" />`);
|
||||||
|
} else {
|
||||||
|
ed.insertContent(`<img src='/${e.path}' class="img-fluid" />`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@
|
||||||
* @link https://beikeshop.com
|
* @link https://beikeshop.com
|
||||||
* @Author pu shuo <pushuo@guangda.work>
|
* @Author pu shuo <pushuo@guangda.work>
|
||||||
* @Date 2022-08-22 18:32:26
|
* @Date 2022-08-22 18:32:26
|
||||||
* @LastEditTime 2023-04-19 15:26:41
|
* @LastEditTime 2023-06-09 08:53:52
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 打开文件管理器
|
// 打开文件管理器
|
||||||
fileManagerIframe(callback) {
|
fileManagerIframe(callback, params) {
|
||||||
const base = document.querySelector('base').href;
|
const base = document.querySelector('base').href;
|
||||||
|
params = params ? `?${Object.keys(params).map(key => `${key}=${params[key]}`).join('&')}` : '';
|
||||||
|
|
||||||
layer.open({
|
layer.open({
|
||||||
type: 2,
|
type: 2,
|
||||||
|
|
@ -19,7 +20,7 @@ export default {
|
||||||
scrollbar: false,
|
scrollbar: false,
|
||||||
shade: 0.4,
|
shade: 0.4,
|
||||||
area: ['1060px', '680px'],
|
area: ['1060px', '680px'],
|
||||||
content: `${base}/file_manager`,
|
content: `${base}/file_manager${params}`,
|
||||||
success: function(layerInstance, index) {
|
success: function(layerInstance, index) {
|
||||||
var iframeWindow = window[layerInstance.find("iframe")[0]["name"]];
|
var iframeWindow = window[layerInstance.find("iframe")[0]["name"]];
|
||||||
iframeWindow.callback = function(images) {
|
iframeWindow.callback = function(images) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="row g-3 mb-3">
|
<div class="row g-3 mb-3">
|
||||||
<label for="" class="wp-200 col-form-label text-end {{ isset($required) && $required ? 'required' : '' }}">{{ $title ?? '' }}</label>
|
<label class="wp-200 col-form-label text-end {{ isset($required) && $required ? 'required' : '' }}">{{ $title ?? '' }}</label>
|
||||||
<div class="col-auto wp-200-">
|
<div class="col-auto wp-200-">
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -107,19 +107,18 @@ Vue.component('rich-text-i18n', {
|
||||||
fontsize_formats: "10px 12px 14px 18px 24px 36px 48px 56px 72px 96px",
|
fontsize_formats: "10px 12px 14px 18px 24px 36px 48px 56px 72px 96px",
|
||||||
lineheight_formats: "1 1.1 1.2 1.3 1.4 1.5 1.7 2.4 3 4",
|
lineheight_formats: "1 1.1 1.2 1.3 1.4 1.5 1.7 2.4 3 4",
|
||||||
relative_urls : true,
|
relative_urls : true,
|
||||||
// init_instance_callback: function (ed) {
|
|
||||||
// let code = ed.getElement().dataset.code
|
|
||||||
// ed.setContent(self.value[code])
|
|
||||||
// },
|
|
||||||
setup: function(ed) {
|
setup: function(ed) {
|
||||||
ed.ui.registry.addButton('toolbarImageButton', {
|
ed.ui.registry.addButton('toolbarImageButton', {
|
||||||
// text: '',
|
|
||||||
icon: 'image',
|
icon: 'image',
|
||||||
onAction:function() {
|
onAction:function() {
|
||||||
bk.fileManagerIframe(images => {
|
bk.fileManagerIframe(images => {
|
||||||
if (images.length) {
|
if (images.length) {
|
||||||
images.forEach(e => {
|
images.forEach(e => {
|
||||||
ed.insertContent(`<img src='/${e.path}' class="img-fluid" />`);
|
if (e.mime == 'video/mp4') {
|
||||||
|
ed.insertContent(`<video src='/${e.path}' controls loop muted class="img-fluid" />`);
|
||||||
|
} else {
|
||||||
|
ed.insertContent(`<img src='/${e.path}' class="img-fluid" />`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,8 @@
|
||||||
<div class="content-head">
|
<div class="content-head">
|
||||||
<div class="left d-lg-flex">
|
<div class="left d-lg-flex">
|
||||||
<el-button class="me-5 mb-1 mb-lg-0" size="small" icon="el-icon-check" type="primary" @click="fileChecked" :disabled="!!!selectImageIndex.length">{{ __('admin/builder.modules_choose') }}</el-button>
|
<el-button class="me-5 mb-1 mb-lg-0" size="small" icon="el-icon-check" type="primary" @click="fileChecked" :disabled="!!!selectImageIndex.length">{{ __('admin/builder.modules_choose') }}</el-button>
|
||||||
<el-link :underline="false" :disabled="!!!selectImageIndex.length" icon="el-icon-download"
|
<el-link :underline="false" :disabled="!!!selectImageIndex.length" icon="el-icon-view"
|
||||||
@click="downloadImages">{{ __('admin/file_manager.download') }}</el-link>
|
@click="viewImages">{{ __('common.view') }}</el-link>
|
||||||
<el-link :underline="false" :disabled="!!!selectImageIndex.length" @click="deleteFile"
|
<el-link :underline="false" :disabled="!!!selectImageIndex.length" @click="deleteFile"
|
||||||
icon="el-icon-delete">{{ __('common.delete') }}</el-link>
|
icon="el-icon-delete">{{ __('common.delete') }}</el-link>
|
||||||
<el-link :underline="false" :disabled="selectImageIndex.length == 1 ? false : true"
|
<el-link :underline="false" :disabled="selectImageIndex.length == 1 ? false : true"
|
||||||
|
|
@ -114,7 +114,10 @@
|
||||||
v-batch-select="{ className: '.image-list', selectImageIndex, setSelectStatus: updateSelectStatus }">
|
v-batch-select="{ className: '.image-list', selectImageIndex, setSelectStatus: updateSelectStatus }">
|
||||||
<div :class="['image-list', file.selected ? 'active' : '']" v-for="file, index in images"
|
<div :class="['image-list', file.selected ? 'active' : '']" v-for="file, index in images"
|
||||||
:key="index" @click="checkedImage(index)">
|
:key="index" @click="checkedImage(index)">
|
||||||
<div class="img"><img :src="file.url"></div>
|
<div class="img">
|
||||||
|
<i class="el-icon-video-play" v-if="file.mime == 'video/mp4'"></i>
|
||||||
|
<img v-else :src="file.url">
|
||||||
|
</div>
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<span :title="file.name">@{{ file.name }}</span>
|
<span :title="file.name">@{{ file.name }}</span>
|
||||||
<i v-if="file.selected" class="el-icon-check"></i>
|
<i v-if="file.selected" class="el-icon-check"></i>
|
||||||
|
|
@ -143,7 +146,6 @@
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<div class="text-center mt-5 w-100 fs-4">{{ __('admin/file_manager.show_pc') }}</div>
|
<div class="text-center mt-5 w-100 fs-4">{{ __('admin/file_manager.show_pc') }}</div>
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<el-dialog title="{{ __('admin/file_manager.upload_files') }}" top="12vh" :visible.sync="uploadFileDialog.show" width="500px"
|
<el-dialog title="{{ __('admin/file_manager.upload_files') }}" top="12vh" :visible.sync="uploadFileDialog.show" width="500px"
|
||||||
|
|
@ -161,11 +163,13 @@
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name">@{{ index + 1 }}. @{{ image.name }}</div>
|
<div class="name">@{{ index + 1 }}. @{{ image.name }}</div>
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<span v-if="image.status == 'complete'">{{ __('admin/file_manager.finish') }}</span>
|
<span v-if="image.status == 'complete'" class="text-success">{{ __('admin/file_manager.finish') }}</span>
|
||||||
|
<span v-else-if="image.status == 'fail'" class="text-danger">{{ __('admin/file_manager.upload_fail') }}</span>
|
||||||
<span v-else>{{ __('admin/file_manager.uploading') }}</span>
|
<span v-else>{{ __('admin/file_manager.uploading') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-progress :percentage="image.progre" :show-text="false" :stroke-width="4"></el-progress>
|
<el-progress :percentage="image.progre" :status="image.status == 'fail' ? 'exception' : 'success'" :show-text="false" :stroke-width="4"></el-progress>
|
||||||
|
<div v-if="image.fail_text" class="mt-1 text-danger" v-text="image.fail_text"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
@ -186,13 +190,10 @@
|
||||||
paneLengthPercent: 26,
|
paneLengthPercent: 26,
|
||||||
triggerLength: 10,
|
triggerLength: 10,
|
||||||
isShift: false,
|
isShift: false,
|
||||||
|
mime: @json(request('mime')),
|
||||||
ssss: [],
|
|
||||||
loading: false,
|
loading: false,
|
||||||
isBatchSelect: false,
|
isBatchSelect: false,
|
||||||
|
|
||||||
selectImageIndex: [],
|
selectImageIndex: [],
|
||||||
|
|
||||||
filter: {
|
filter: {
|
||||||
sort: 'created',
|
sort: 'created',
|
||||||
order: 'desc'
|
order: 'desc'
|
||||||
|
|
@ -330,12 +331,16 @@
|
||||||
|
|
||||||
let index = this.uploadFileDialog.images.length - 1;
|
let index = this.uploadFileDialog.images.length - 1;
|
||||||
|
|
||||||
$http.post('file_manager/upload', formData).then((res) => {
|
$http.post('file_manager/upload', formData, {hmsg: true}).then((res) => {
|
||||||
this.uploadFileDialog.images[index].status = 'complete';
|
this.uploadFileDialog.images[index].status = 'complete';
|
||||||
this.uploadFileDialog.images[index].progre = 100;
|
this.uploadFileDialog.images[index].progre = 100;
|
||||||
|
}).catch((err) => {
|
||||||
|
this.uploadFileDialog.images[index].status = 'fail';
|
||||||
|
this.uploadFileDialog.images[index].progre = 80;
|
||||||
|
this.uploadFileDialog.images[index].fail_text = err.response.data.message;
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
index += 1
|
index += 1
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleUploadChange(e) {
|
handleUploadChange(e) {
|
||||||
|
|
@ -442,6 +447,20 @@
|
||||||
fileChecked() {
|
fileChecked() {
|
||||||
let typedFiles = this.images.filter(e => e.selected)
|
let typedFiles = this.images.filter(e => e.selected)
|
||||||
|
|
||||||
|
if (this.mime) {
|
||||||
|
// 判断 typedFiles 数组内 mime 是否有不是 image 开头的
|
||||||
|
if (this.mime == 'image' && typedFiles.some(e => !e.mime.startsWith('image'))) {
|
||||||
|
layer.msg('{{ __('admin/file_manager.verify_select_image') }}', () => {});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断 typedFiles 数组内 mime 是否有不是 video 开头的
|
||||||
|
if (this.mime == 'video' && typedFiles.some(e => !e.mime.startsWith('video'))) {
|
||||||
|
layer.msg('{{ __('admin/file_manager.verify_select_video') }}', () => {});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (callback !== null) {
|
if (callback !== null) {
|
||||||
callback(typedFiles);
|
callback(typedFiles);
|
||||||
}
|
}
|
||||||
|
|
@ -513,6 +532,13 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
viewImages() {
|
||||||
|
const selectedImages = this.images.filter(e => e.selected);
|
||||||
|
selectedImages.forEach(e => {
|
||||||
|
window.open(e.origin_url);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
openInputBox(type, node, data) {
|
openInputBox(type, node, data) {
|
||||||
let fileSuffix, fileName = '';
|
let fileSuffix, fileName = '';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,19 @@
|
||||||
</draggable>
|
</draggable>
|
||||||
<div class="help-text mb-1 mt-1">{{ __('admin/product.image_help') }}</div>
|
<div class="help-text mb-1 mt-1">{{ __('admin/product.image_help') }}</div>
|
||||||
</x-admin::form.row>
|
</x-admin::form.row>
|
||||||
{{-- <x-admin-form-input name="video" title="视频" :value="old('video', $product->video ?? '')" /> --}}
|
|
||||||
|
<x-admin::form.row title="{{ __('product.video') }}">
|
||||||
|
<div class="d-flex align-items-end">
|
||||||
|
<div class="set-product-img wh-80 rounded-2 me-2" @click="addProductVideo">
|
||||||
|
<i v-if="form.video.path" class="bi bi-play-circle fs-1"></i>
|
||||||
|
<i v-else class="bi bi-plus fs-1 text-muted"></i>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="video" :value="form.video.path">
|
||||||
|
<a v-if="form.video.path" target="_blank" :href="form.video.url">{{ __('common.view') }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="help-text mb-1 mt-1">{{ __('admin/product.video_help') }}</div>
|
||||||
|
</x-admin::form.row>
|
||||||
|
|
||||||
<x-admin-form-input name="position" :title="__('common.sort_order')" :value="old('position', $product->position ?? '0')" />
|
<x-admin-form-input name="position" :title="__('common.sort_order')" :value="old('position', $product->position ?? '0')" />
|
||||||
|
|
||||||
<x-admin::form.row :title="__('admin/product.weight_text')">
|
<x-admin::form.row :title="__('admin/product.weight_text')">
|
||||||
|
|
@ -516,6 +528,10 @@
|
||||||
form: {
|
form: {
|
||||||
attributes: @json(old('pickups', $product_attributes) ?? []),
|
attributes: @json(old('pickups', $product_attributes) ?? []),
|
||||||
images: @json(old('images', $product->images) ?? []),
|
images: @json(old('images', $product->images) ?? []),
|
||||||
|
video: {
|
||||||
|
path: @json(old('video', $product->video ?? '')),
|
||||||
|
url: @json(image_origin(old('video', $product->video ?? ''))),
|
||||||
|
},
|
||||||
model: @json($product->skus[0]['model'] ?? ''),
|
model: @json($product->skus[0]['model'] ?? ''),
|
||||||
price: @json($product->skus[0]['price'] ?? ''),
|
price: @json($product->skus[0]['price'] ?? ''),
|
||||||
quantity: @json($product->skus[0]['quantity'] ?? ''),
|
quantity: @json($product->skus[0]['quantity'] ?? ''),
|
||||||
|
|
@ -678,7 +694,13 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.form.images.push(...images.map(e => e.path))
|
this.form.images.push(...images.map(e => e.path))
|
||||||
})
|
}, {mime: 'image'})
|
||||||
|
},
|
||||||
|
|
||||||
|
addProductVideo() {
|
||||||
|
bk.fileManagerIframe(images => {
|
||||||
|
this.form.video = {path: images[0].path, url: images[0].url}
|
||||||
|
}, {mime: 'video'})
|
||||||
},
|
},
|
||||||
|
|
||||||
removeImages(index) {
|
removeImages(index) {
|
||||||
|
|
|
||||||
|
|
@ -322,4 +322,25 @@ img {
|
||||||
padding-top: .8rem;
|
padding-top: .8rem;
|
||||||
padding-bottom: .8rem;
|
padding-bottom: .8rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 溢出隐藏 显示省略号
|
||||||
|
.text-ellipsis {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
// 加一个 line
|
||||||
|
&.line-2 {
|
||||||
|
white-space: normal;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.line-3 {
|
||||||
|
white-space: normal;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ body.page-product {
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-image {
|
.product-image {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
#swiper {
|
#swiper {
|
||||||
height: 250px;
|
height: 250px;
|
||||||
@media (min-width: 480px) {
|
@media (min-width: 480px) {
|
||||||
|
|
@ -117,6 +119,68 @@ body.page-product {
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#product-video {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open-video {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
z-index: 99;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
transform: translateX(-50%);
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
i {
|
||||||
|
color: #fff;
|
||||||
|
background-color: rgba(0, 0, 0, 0.648);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
line-height: 1;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-weight: 400;
|
||||||
|
display: inline-block;
|
||||||
|
color: rgba(255, 255, 255, 0.948);
|
||||||
|
background-color: rgba(0, 0, 0, 0.348);
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-video {
|
||||||
|
position: absolute;
|
||||||
|
top: 6px;
|
||||||
|
right: 10px;
|
||||||
|
z-index: 9999;
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ return [
|
||||||
'no_file' => 'No File',
|
'no_file' => 'No File',
|
||||||
'picture_space' => 'Picture Space',
|
'picture_space' => 'Picture Space',
|
||||||
'show_pc' => 'Please go to the PC side to operate',
|
'show_pc' => 'Please go to the PC side to operate',
|
||||||
|
'verify_select_image' => 'Please select a picture',
|
||||||
|
'verify_select_video' => 'Please select video',
|
||||||
|
|
||||||
'confirm_delete_file' => 'Do you want to delete the selected file',
|
'confirm_delete_file' => 'Do you want to delete the selected file',
|
||||||
'confirm_delete_folder' => 'The folder deletion operation is in progress, all files in the folder will be deleted, do you want to confirm?',
|
'confirm_delete_folder' => 'The folder deletion operation is in progress, all files in the folder will be deleted, do you want to confirm?',
|
||||||
|
|
@ -40,5 +42,6 @@ return [
|
||||||
'can_empty' => 'Can not be empty',
|
'can_empty' => 'Can not be empty',
|
||||||
'finish' => 'Finish',
|
'finish' => 'Finish',
|
||||||
'uploading' => 'loading...',
|
'uploading' => 'loading...',
|
||||||
|
'upload_fail' => 'Upload failed',
|
||||||
'file_manager' => 'File Manager',
|
'file_manager' => 'File Manager',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ return [
|
||||||
'quantity' => 'Quantity',
|
'quantity' => 'Quantity',
|
||||||
'enable_multi_spec' => 'Enable multi-spec',
|
'enable_multi_spec' => 'Enable multi-spec',
|
||||||
'image_help' => 'The first picture will be used as the main picture of the product, and multiple pictures can be uploaded at the same time, and the position of multiple pictures can be adjusted at will',
|
'image_help' => 'The first picture will be used as the main picture of the product, and multiple pictures can be uploaded at the same time, and the position of multiple pictures can be adjusted at will',
|
||||||
|
'video_help' => 'If the prompt exceeds the system size limit, please modify the php.ini parameter post_max_size',
|
||||||
'add_variable' => 'Add Specs',
|
'add_variable' => 'Add Specs',
|
||||||
'add_variable_value' => 'Add Specification Value',
|
'add_variable_value' => 'Add Specification Value',
|
||||||
'add_variable_image' => 'Add Spec Image',
|
'add_variable_image' => 'Add Spec Image',
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ return [
|
||||||
'g' => 'Gram',
|
'g' => 'Gram',
|
||||||
'oz' => 'Ounce',
|
'oz' => 'Ounce',
|
||||||
'lb' => 'Pound',
|
'lb' => 'Pound',
|
||||||
|
'video' => 'Video',
|
||||||
|
|
||||||
'active' => 'Active',
|
'active' => 'Active',
|
||||||
'inactive' => 'Inactive',
|
'inactive' => 'Inactive',
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ return [
|
||||||
'index' => 'Cart',
|
'index' => 'Cart',
|
||||||
'added_to_cart' => 'Added To Cart',
|
'added_to_cart' => 'Added To Cart',
|
||||||
'select_all' => 'Select All',
|
'select_all' => 'Select All',
|
||||||
'commodity' => 'Commodity',
|
'commodity' => 'Product',
|
||||||
'quantity' => 'Quantity',
|
'quantity' => 'Quantity',
|
||||||
'subtotal' => 'Subtotal',
|
'subtotal' => 'Subtotal',
|
||||||
'product_total' => 'Product Total',
|
'product_total' => 'Product Total',
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,15 @@ return [
|
||||||
'no_file' => '没有文件',
|
'no_file' => '没有文件',
|
||||||
'picture_space' => '图片空间',
|
'picture_space' => '图片空间',
|
||||||
'show_pc' => '请到PC端操作',
|
'show_pc' => '请到PC端操作',
|
||||||
|
'verify_select_image' => '请选择图片',
|
||||||
|
'verify_select_video' => '请选择视频',
|
||||||
|
|
||||||
'confirm_delete_file' => '是否要删除选中文件',
|
'confirm_delete_file' => '是否要删除选中文件',
|
||||||
'confirm_delete_folder' => '正在进行删除文件夹操作,文件夹内所有文件都将被删除,是否确认?',
|
'confirm_delete_folder' => '正在进行删除文件夹操作,文件夹内所有文件都将被删除,是否确认?',
|
||||||
'new_folder' => '新建文件夹',
|
'new_folder' => '新建文件夹',
|
||||||
'can_empty' => '不能为空',
|
'can_empty' => '不能为空',
|
||||||
'finish' => '完成',
|
'finish' => '完成',
|
||||||
'uploading' => '上传中',
|
'uploading' => '上传中',
|
||||||
'file_manager' => '图片管理器',
|
'upload_fail' => '上传失败',
|
||||||
|
'file_manager' => '图片管理器',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ return [
|
||||||
'quantity' => '数量',
|
'quantity' => '数量',
|
||||||
'enable_multi_spec' => '启用多规格',
|
'enable_multi_spec' => '启用多规格',
|
||||||
'image_help' => '第一张图片将作为商品主图,支持同时上传多张图片,多张图片之间可随意调整位置',
|
'image_help' => '第一张图片将作为商品主图,支持同时上传多张图片,多张图片之间可随意调整位置',
|
||||||
|
'video_help' => '如果提示超出系统大小限制,请修改 php.ini 参数 post_max_size',
|
||||||
'add_variable' => '添加规格',
|
'add_variable' => '添加规格',
|
||||||
'add_variable_value' => '添加规格值',
|
'add_variable_value' => '添加规格值',
|
||||||
'add_variable_image' => '添加规格图片',
|
'add_variable_image' => '添加规格图片',
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ return [
|
||||||
'g' => '克',
|
'g' => '克',
|
||||||
'oz' => '盎司',
|
'oz' => '盎司',
|
||||||
'lb' => '磅',
|
'lb' => '磅',
|
||||||
|
'video' => '视频',
|
||||||
|
|
||||||
'active' => '上架',
|
'active' => '上架',
|
||||||
'inactive' => '下架',
|
'inactive' => '下架',
|
||||||
|
|
|
||||||
|
|
@ -14,40 +14,41 @@
|
||||||
<h5 class="card-title">{{ __('shop/account.rma.index') }}</h5>
|
<h5 class="card-title">{{ __('shop/account.rma.index') }}</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table ">
|
<div class="table-responsive">
|
||||||
<thead>
|
<table class="table">
|
||||||
<tr>
|
<thead>
|
||||||
<th>{{ __('shop/account.rma.commodity') }}</th>
|
|
||||||
<th>{{ __('shop/account.rma.quantity') }}</th>
|
|
||||||
<th>{{ __('shop/account.rma.service_type') }}</th>
|
|
||||||
<th>{{ __('shop/account.rma.return_reason') }}</th>
|
|
||||||
<th>{{ __('shop/account.rma.creation_time') }}</th>
|
|
||||||
{{-- <th>状态</th> --}}
|
|
||||||
<th class="text-end">{{ __('common.action') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@if (count($rmas))
|
|
||||||
@foreach ($rmas as $rma)
|
|
||||||
<tr>
|
|
||||||
<td>{{ sub_string($rma['product_name'], 80) }}</td>
|
|
||||||
<td>{{ $rma['quantity'] }}</td>
|
|
||||||
<td>{{ $rma['type'] }}</td>
|
|
||||||
<td>{{ $rma['reason'] }}</td>
|
|
||||||
<td>{{ $rma['created_at'] }}</td>
|
|
||||||
<td class="text-end"><a href="{{ shop_route('account.rma.show', [$rma['id']]) }}"
|
|
||||||
class="btn btn-outline-secondary btn-sm">{{ __('shop/account.rma.check') }}</a> </td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
@else
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="border-0">
|
<th>{{ __('shop/account.rma.commodity') }}</th>
|
||||||
<x-shop-no-data />
|
<th class="text-nowrap">{{ __('shop/account.rma.quantity') }}</th>
|
||||||
</td>
|
<th class="text-nowrap">{{ __('shop/account.rma.service_type') }}</th>
|
||||||
|
<th class="text-nowrap">{{ __('shop/account.rma.creation_time') }}</th>
|
||||||
|
<th class="text-end">{{ __('common.action') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
@endif
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
@if (count($rmas))
|
||||||
|
@foreach ($rmas as $rma)
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="text-ellipsis line-2 w-min-100 w-max-300">{{ sub_string($rma['product_name'], 80) }}</div>
|
||||||
|
</td>
|
||||||
|
<td>{{ $rma['quantity'] }}</td>
|
||||||
|
<td>{{ $rma['type'] }}</td>
|
||||||
|
<td class="text-nowrap">{{ $rma['created_at'] }}</td>
|
||||||
|
<td class="text-end"><a href="{{ shop_route('account.rma.show', [$rma['id']]) }}"
|
||||||
|
class="btn text-nowrap btn-outline-secondary btn-sm">{{ __('shop/account.rma.check') }}</a> </td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
@else
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="border-0">
|
||||||
|
<x-shop-no-data />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{-- {{ $rmas->links('shared/pagination/bootstrap-4') }} --}}
|
{{-- {{ $rmas->links('shared/pagination/bootstrap-4') }} --}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
<div class="row mt-5" v-if="products.length">
|
<div class="row mt-5" v-if="products.length">
|
||||||
<div class="col-12 col-md-9 left-column">
|
<div class="col-12 col-md-9 left-column">
|
||||||
<div class="card shadow-sm">
|
<div class="card shadow-sm h-min-600">
|
||||||
<div class="card-body p-lg-4">
|
<div class="card-body p-lg-4">
|
||||||
<div class="p-lg-0"><h4 class="mb-3">{{ __('shop/carts.commodity') }}</h4></div>
|
<div class="p-lg-0"><h4 class="mb-3">{{ __('shop/carts.commodity') }}</h4></div>
|
||||||
<div class="cart-products-wrap table-responsive">
|
<div class="cart-products-wrap table-responsive">
|
||||||
|
|
@ -36,8 +36,8 @@
|
||||||
{{ __('shop/carts.select_all') }}
|
{{ __('shop/carts.select_all') }}
|
||||||
</label>
|
</label>
|
||||||
</th>
|
</th>
|
||||||
<th width="40%">{{ __('shop/carts.index') }}</th>
|
<th width="40%">{{ __('shop/carts.commodity') }}</th>
|
||||||
<th width="170">{{ __('shop/carts.commodity') }}</th>
|
<th width="170">{{ __('shop/carts.quantity') }}</th>
|
||||||
<th width="170">{{ __('shop/carts.subtotal') }}</th>
|
<th width="170">{{ __('shop/carts.subtotal') }}</th>
|
||||||
<th width="100" class="text-end">{{ __('common.action') }}</th>
|
<th width="100" class="text-end">{{ __('common.action') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
@if ($product['video'])
|
||||||
|
<div class="video-wrap">
|
||||||
|
<video
|
||||||
|
id="product-video"
|
||||||
|
class="video-js vjs-big-play-centered vjs-fluid vjs-16-9"
|
||||||
|
controls loop muted
|
||||||
|
>
|
||||||
|
<source src="{{ image_origin($product['video']) }}" type="video/mp4" />
|
||||||
|
</video>
|
||||||
|
<div class="close-video d-none"><i class="bi bi-x-circle"></i></div>
|
||||||
|
<div class="open-video d-none"><i class="bi bi-play-circle"></i></div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@push('add-scripts')
|
||||||
|
<script>
|
||||||
|
let pVideo = null;
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
if ($('#product-video').length) {
|
||||||
|
pVideo = videojs("product-video");
|
||||||
|
|
||||||
|
pVideo.on('loadedmetadata', function(e) {
|
||||||
|
$('.open-video').removeClass('d-none');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.open-video', function () {
|
||||||
|
pVideo.play();
|
||||||
|
pVideo.currentTime(0);
|
||||||
|
$(this).addClass('d-none');
|
||||||
|
$('#product-video').fadeIn();
|
||||||
|
$('.close-video').removeClass('d-none');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.close-video', function () {
|
||||||
|
closeVideo()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function closeVideo() {
|
||||||
|
if (pVideo) {
|
||||||
|
pVideo.pause();
|
||||||
|
$('#product-video').fadeOut();
|
||||||
|
$('.close-video').addClass('d-none');
|
||||||
|
$('.open-video').removeClass('d-none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
@ -9,6 +9,10 @@
|
||||||
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
||||||
<script src="{{ asset('vendor/zoom/jquery.zoom.min.js') }}"></script>
|
<script src="{{ asset('vendor/zoom/jquery.zoom.min.js') }}"></script>
|
||||||
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
||||||
|
@if ($product['video'])
|
||||||
|
<script src="{{ asset('vendor/video/video.min.js') }}"></script>
|
||||||
|
<link rel="stylesheet" href="{{ asset('vendor/video/video-js.min.css') }}">
|
||||||
|
@endif
|
||||||
@endpush
|
@endpush
|
||||||
|
|
||||||
@php
|
@php
|
||||||
|
|
@ -41,9 +45,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right" id="zoom">
|
<div class="right" id="zoom">
|
||||||
|
@include('product.product-video')
|
||||||
<img :src="images.length ? images[0].preview : '{{ asset('image/placeholder.png') }}'" class="img-fluid">
|
<img :src="images.length ? images[0].preview : '{{ asset('image/placeholder.png') }}'" class="img-fluid">
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
|
@include('product.product-video')
|
||||||
<div class="swiper" id="swiper-mobile">
|
<div class="swiper" id="swiper-mobile">
|
||||||
<div class="swiper-wrapper">
|
<div class="swiper-wrapper">
|
||||||
<div class="swiper-slide" v-for="image, index in images">
|
<div class="swiper-slide" v-for="image, index in images">
|
||||||
|
|
@ -324,6 +330,8 @@
|
||||||
$('#zoom').trigger('zoom.destroy');
|
$('#zoom').trigger('zoom.destroy');
|
||||||
$('#zoom').zoom({url: $('#swiper a').attr('data-zoom-image')});
|
$('#zoom').zoom({url: $('#swiper a').attr('data-zoom-image')});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
closeVideo()
|
||||||
},
|
},
|
||||||
|
|
||||||
addCart(isBuyNow = false) {
|
addCart(isBuyNow = false) {
|
||||||
|
|
@ -385,6 +393,7 @@
|
||||||
$('#zoom').trigger('zoom.destroy');
|
$('#zoom').trigger('zoom.destroy');
|
||||||
$('#zoom img').attr('src', $(this).attr('data-image'));
|
$('#zoom img').attr('src', $(this).attr('data-image'));
|
||||||
$('#zoom').zoom({url: $(this).attr('data-zoom-image')});
|
$('#zoom').zoom({url: $(this).attr('data-zoom-image')});
|
||||||
|
closeVideo()
|
||||||
});
|
});
|
||||||
|
|
||||||
var swiper = new Swiper("#swiper", {
|
var swiper = new Swiper("#swiper", {
|
||||||
Loading…
Reference in New Issue