This commit is contained in:
pushuo 2022-07-18 18:38:46 +08:00
parent 9eac191b3a
commit 3f18ce69ca
10 changed files with 354 additions and 29 deletions

View File

@ -19,7 +19,7 @@ class DesignController extends Controller
public function index(Request $request): View
{
$data = [
'editors' => ['editor-slide_show', 'editor-image401'],
'editors' => ['editor-slide_show', 'editor-image401', 'editor-product'],
'languages' => LanguageRepo::all(),
'design_settings' => system_setting('base.design_setting'),
];

View File

@ -0,0 +1,44 @@
<?php
/**
* Render.php
*
* @copyright 2022 opencart.cn - All Rights Reserved
* @link http://www.guangdawangluo.com
* @author Edward Yang <yangjin@opencart.cn>
* @created 2022-07-08 17:09:15
* @modified 2022-07-08 17:09:15
*/
namespace Beike\Admin\View\DesignBuilders;
use Illuminate\View\Component;
use Illuminate\Contracts\View\View;
class Product extends Component
{
/**
* Create a new component instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Get the view / contents that represent the component.
*
* @return View
*/
public function render(): View
{
$data['register'] = [
'code' => 'product',
'sort' => 0,
'name' => '推荐商品',
'icon' => '&#xe634;',
];
return view('admin::pages.design.module.product', $data);
}
}

View File

@ -21,6 +21,9 @@ body.page-design {
height: 100vh;
overflow: hidden;
}
body.page-design [class*=" el-icon-"], body.page-design [class^=el-icon-] {
font-weight: 600;
}
body.page-design .tag {
margin: 8px 0;
color: #777;
@ -51,6 +54,12 @@ body.page-design .design-box .design-head > div {
font-size: 0.8rem;
transition: all 0.2s ease-in-out;
}
body.page-design .design-box .design-head > div.save-btn {
border-right: 1px solid #5692ff;
}
body.page-design .design-box .design-head > div i {
margin-right: 7px;
}
body.page-design .design-box .design-head > div:hover {
background-color: #005bcc;
}

View File

@ -10,6 +10,10 @@ body.page-design {
height: 100vh;
overflow: hidden;
[class*=" el-icon-"], [class^=el-icon-] {
font-weight: 600;
}
.tag {
margin: 8px 0;
color: #777;
@ -42,6 +46,14 @@ body.page-design {
font-size: .8rem;
transition: all .2s ease-in-out;
&.save-btn {
border-right: 1px solid #5692ff;
}
i {
margin-right: 7px;
}
&:hover {
background-color: darken($main_color, 10%);
}

View File

@ -25,8 +25,13 @@
<div class="design-box">
<div class="sidebar-edit-wrap" id="app" v-cloak>
<div class="design-head">
<div @click="saveButtonClicked">保存</div>
<div @click="exitDesign">退出</div>
<template v-if="design.editType == 'add'">
<div @click="saveButtonClicked" class="save-btn"><i class="el-icon-check"></i>保存</div>
<div @click="exitDesign"><i class="el-icon-switch-button"></i>退出</div>
</template>
<template v-else>
<div @click="showAllModuleButtonClicked"><i class="el-icon-back"></i>返回</div>
</template>
</div>
<div class="module-edit" v-if="form.modules.length > 0 && design.editType == 'module'">
<component
@ -62,6 +67,15 @@
var $languages = @json($languages);
var $language_id = '{{ current_language_code() }}';
function languagesFill(text) {
var obj = {};
$languages.map(e => {
obj[e.code] = text
})
return obj;
}
Vue.prototype.thumbnail = function thumbnail(image, width, height) {
return '{{ asset('catalog') }}' + image;
};
@ -78,9 +92,13 @@
previewWindow = document.getElementById("preview-iframe").contentWindow;
app.design.ready = true;
app.design.sidebar = true;
$(previewWindow.document).find('.module-edit .edit').on('click', function(event) {
// console.log($(this).parents('.module-item').prop('id'))
window.parent.postMessage({index: 0}, '*')
$(previewWindow.document).on('click', '.module-edit .edit', function(event) {
// module-b0448efb0989 删除 module-
const module_id = $(this).parents('.module-item').prop('id').replace('module-', '');
const modules = app.form.modules;
const editingModuleIndex = modules.findIndex(e => e.module_id == module_id);
app.editModuleButtonClicked(editingModuleIndex);
});
});
</script>
@ -135,17 +153,24 @@
moduleUpdated(module) {
const data = this.form.modules[this.design.editingModuleIndex]
$http.post('design/builder/preview', data, {hload: true}).then((res) => {
// layer.msg(res.message)
console.log(res)
// $(previewWindow.document).find('.module-edit .edit').on('click', function(event) {
// });
$http.post('design/builder/preview?design=1', data, {hload: true}).then((res) => {
$(previewWindow.document).find('#module-' + data.module_id).replaceWith(res);
})
// console.log(module)
},
addModuleButtonClicked(code) {
console.log(code)
const sourceModule = this.source.modules.find(e => e.code == code)
const _data = {
code: code,
content: sourceModule.make,
module_id: '',
name: sourceModule.name,
}
$http.post('design/builder', _data).then((res) => {
// layer.msg(res.message)
// $(previewWindow.document).find('#module-' + data.module_id + ' .module-info').replaceWith(res);
})
},
// 编辑模块
@ -162,6 +187,11 @@
exitDesign() {
location = '/';
},
showAllModuleButtonClicked() {
this.design.editType = 'add';
this.design.editingModuleIndex = 0;
}
},
created () {
@ -171,12 +201,12 @@
},
})
window.addEventListener('message', (event) => {
event.stopPropagation()
if (typeof(event.data.index) !== 'undefined') {
app.editModuleButtonClicked(event.data.index)
}
}, false)
// window.addEventListener('message', (event) => {
// event.stopPropagation()
// if (typeof(event.data.index) !== 'undefined') {
// app.editModuleButtonClicked(event.data.index)
// }
// }, false)
</script>
</body>
</html>

View File

@ -25,9 +25,6 @@
</template>
<script type="text/javascript">
setTimeout(() => {
app.source.modules.push(@json($register))
}, 100)
Vue.component('module-editor-image-401', {
template: '#module-editor-image-401-template',
@ -59,4 +56,52 @@ Vue.component('module-editor-image-401', {
},
}
});
setTimeout(() => {
const make = {
style: {
background_color: ''
},
floor: languagesFill(''),
images: [
{
image: languagesFill('image/default/image_plus_1.png'),
show: true,
link: {
type: 'product',
value:''
}
},
{
image: languagesFill('image/default/image_plus_2.png'),
show: false,
link: {
type: 'product',
value:''
}
},
{
image: languagesFill('image/default/image_plus_3.png'),
show: false,
link: {
type: 'product',
value:''
}
},
{
image: languagesFill('image/default/image_plus_4.png'),
show: false,
link: {
type: 'product',
value:''
}
}
]
}
let register = @json($register);
register.make = make;
app.source.modules.push(register)
}, 100)
</script>

View File

@ -0,0 +1,130 @@
<template id="module-editor-product-template">
<div class="module-editor-product-template">
<div class="module-editor-title">设置</div>
<div class="module-edit-group">
<div class="module-edit-title">设置标题</div>
<text-i18n v-model="module.title"></text-i18n>
</div>
<div class="module-editor-title">内容</div>
<div class="module-edit-group">
<div class="module-edit-title">设置商品</div>
<div class="autocomplete-group-wrapper">
<el-autocomplete
class="inline-input"
v-model="keyword"
value-key="name"
size="small"
:fetch-suggestions="querySearch"
placeholder="请输入关键字搜索"
:trigger-on-focus="false"
:highlight-first-item="true"
@select="handleSelect"
></el-autocomplete>
<div class="item-group-wrapper" v-loading="loading">
<draggable
ghost-class="dragabble-ghost"
:list="productData"
@change="itemChange"
:options="{animation: 330}"
>
<div v-for="(item, index) in productData" :key="index" class="item">
<span>@{{ item.name }}</span>
<i class="fa fa-minus-circle" @click="removeProduct(index)"></i>
</div>
</draggable>
</div>
</div>
</div>
</div>
</template>
<script type="text/javascript">
Vue.component('module-editor-product', {
template: '#module-editor-product-template',
props: ['module'],
data: function () {
return {
keyword: '',
productData: [],
loading: null,
}
},
watch: {
module: {
handler: function (val) {
this.$emit('on-changed', val);
},
deep: true
}
},
created: function () {
var that = this;
if (!this.module.items.length) return;
this.loading = true;
$.ajax({
url: 'index.php?route=extension/theme/default/page/module/product/productsByIds',
data: {product_ids: this.module.items},
type: 'post',
dataType: 'json',
success: function (json) {
if (json) {
that.loading = false;
that.productData = json;
}
}
});
},
methods: {
querySearch(keyword, cb) {
if (!keyword) {
return;
}
$http.get(`products/${keyword}/name`, null, {hload: true}).then((res) => {
if (res.data) {
cb(res.data);
}
})
},
handleSelect(item) {
if (!this.module.items.find(v => v == item.product_id)) {
this.module.items.push(item.product_id * 1);
this.productData.push(item);
}
this.keyword = ""
},
itemChange(evt) {
this.module.items = this.productData.map(e => e.product_id * 1);
},
removeProduct(index) {
this.productData.splice(index, 1)
this.module.items.splice(index, 1);
}
}
});
setTimeout(() => {
const make = {
style: {
background_color: ''
},
floor: languagesFill(''),
items: [0],
title: languagesFill('商品模块'),
}
let register = @json($register);
register.make = make;
app.source.modules.push(register)
}, 100)
</script>

View File

@ -50,10 +50,6 @@
<script type="text/javascript">
setTimeout(() => {
app.source.modules.push(@json($register))
}, 100)
Vue.component('module-editor-slideshow', {
template: '#module-editor-slideshow-template',
@ -96,4 +92,37 @@ Vue.component('module-editor-slideshow', {
}
}
});
setTimeout(() => {
const make = {
style: {
background_color: ''
},
full: true,
floor: languagesFill(''),
images: [
{
image: languagesFill('/demo/banner.png'),
show: true,
link: {
type: 'product',
value:''
}
},
{
image: languagesFill('/demo/banner.png'),
show: false,
link: {
type: 'product',
value:''
}
}
]
}
let register = @json($register);
register.make = make;
app.source.modules.push(register)
}, 100)
</script>

View File

@ -0,0 +1,27 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@if ($design)
<div class="module-edit">
<div class="edit-wrap">
<div class=""><i class="bi bi-chevron-down"></i></div>
<div class=""><i class="bi bi-chevron-up"></i></div>
<div class="delete"><i class="bi bi-x-lg"></i></div>
<div class="edit"><i class="bi bi-pencil-square"></i></div>
</div>
</div>
@endif
<div class="module-info">
<div class="module-title">推荐品牌模块</div>
<div class="container">
<div class="row">
@for ($i = 0; $i < 8; $i++)
<div class="col-6 col-md-4 col-lg-3">
<div class="brand-item"><img src="{{ asset('image/default/banner-1.png') }}" class="img-fluid"></div>
</div>
@endfor
</div>
</div>
</div>
</section>

View File

@ -28,9 +28,7 @@
<div class="swiper-button-next"></div>
</div>
</div>
</section>
@push('add-scripts')
<script>
new Swiper ('.module-swiper-{{ $module_id }}', {
loop: true, // 循环模式选项
@ -50,6 +48,7 @@
},
})
</script>
@endpush
</section>