!77 Optimize setting background page properties

* Optimize setting background page properties
This commit is contained in:
蒲硕 2023-04-10 06:06:35 +00:00 committed by Edward Yang
parent 237b777c0a
commit d8027054bc
14 changed files with 102 additions and 19 deletions

View File

@ -12,6 +12,7 @@
namespace Beike\Admin\Http\Controllers;
use Beike\Admin\Http\Resources\CustomerGroupDetail;
use Beike\Admin\Repositories\AttributeRepo;
use Beike\Repositories\CountryRepo;
use Beike\Repositories\CurrencyRepo;
use Beike\Repositories\CustomerGroupRepo;

View File

@ -12,6 +12,7 @@
namespace Beike\Admin\Repositories;
use Beike\Models\Attribute;
use Beike\Models\AttributeDescription;
use Beike\Models\AttributeValue;
use Beike\Models\ProductAttribute;
@ -138,4 +139,14 @@ class AttributeRepo
return $builder->limit(10)->get();
}
public static function getByIds($ids)
{
return AttributeDescription::query()
->where('locale', locale())
->whereIn('attribute_id', $ids)
->select(['attribute_id as id', 'name'])
->get()
->toArray();
}
}

View File

@ -3,7 +3,7 @@
* @link https://beikeshop.com
* @Author pu shuo <pushuo@guangda.work>
* @Date 2022-08-17 15:42:46
* @LastEditTime 2023-02-15 11:45:11
* @LastEditTime 2023-04-10 13:56:07
*/
// Example starter JavaScript for disabling form submissions if there are invalid fields
@ -27,15 +27,30 @@ $(function () {
// 如果错误输入框在 tab 页面,则高亮显示对应的选项卡
$('.invalid-feedback').each(function(index, el) {
if ($(el).css('display') == 'block') {
layer.msg(lang.error_form, () => {});
// 兼容使用 element ui input、autocomplete 组件在传统提交报错ui显示
if ($(el).siblings('div[class^="el-"]')) {
$(el).siblings('div[class^="el-"]').find('.el-input__inner').addClass('error-invalid-input')
}
if ($(el).parents('.tab-pane')) {
const id = $(el).parents('.tab-pane').prop('id');
//高亮显示对应的选项卡
$(el).parents('.tab-pane').each(function(index, el) {
const id = $(el).prop('id');
$(`a[href="#${id}"], button[data-bs-target="#${id}"]`).addClass('error-invalid')[0].click();
})
}
$(`a[href="#${id}"], button[data-bs-target="#${id}"]`).addClass('error-invalid');
// 页面滚动到错误输入框位置 只滚动一次
if ($('.main-content > #content').data('scroll') != 1) {
$('.main-content > #content').data('scroll', 1);
setTimeout(() => {
$('.main-content > #content').animate({
scrollTop: $(el).offset().top - 100
}, 500, () => {
$('.main-content > #content').data('scroll', 0);
});
}, 200);
}
}
});

View File

@ -56,6 +56,7 @@
@endif
const lang = {
file_manager: '{{ __('admin/file_manager.file_manager') }}',
error_form: '{{ __('common.error_form') }}',
}
const config = {

View File

@ -53,7 +53,7 @@
<div class="marketing-wrap" v-if="plugins.data.length">
<div class="row">
<div class="col-xxl-2 col-xl-3 col-md-4 col-6" v-for="plugin, index in plugins.data" :key="index">
<div class="col-xxl-20 col-xl-3 col-md-4 col-6" v-for="plugin, index in plugins.data" :key="index">
<div class="card mb-4 marketing-item">
<div class="card-body">
<div class="plugin-img mb-3"><a :href="'{{ system_setting('base.admin_name', 'admin') }}/marketing/' + plugin.code"><img :src="plugin.icon_big"
@ -146,12 +146,12 @@
filter.page = this.page;
}
for (key in this.filter) {
Object.keys(this.filter).forEach(key => {
const value = this.filter[key];
if (value !== '' && value !== null) {
filter[key] = value;
}
}
})
const query = Object.keys(filter).map(key => key + '=' + filter[key]).join('&');

View File

@ -10,12 +10,14 @@
<script src="{{ asset('vendor/tinymce/5.9.1/tinymce.min.js') }}"></script>
@endpush
@section('page-title-right')
<button type="button" class="btn btn-lg btn-primary submit-form">{{ __('common.save') }}</button>
@endsection
@section('content')
@if ($errors->has('error'))
<x-admin-alert type="danger" msg="{{ $errors->first('error') }}" class="mt-4" />
@endif
@if ($errors->any())
<div class="alert alert-danger">
@foreach ($errors->all() as $error)
@ -428,7 +430,7 @@
</div>
<x-admin::form.row title="">
<button type="submit" @click="productsSubmit" class="btn btn-primary btn-submit mt-3 btn-lg">{{ __('common.save') }}</button>
<button type="submit" @click="productsSubmit" class="btn d-none btn-primary btn-submit mt-3 btn-lg">{{ __('common.save') }}</button>
</x-admin::form.row>
<el-dialog
@ -950,6 +952,10 @@
}
$(document).ready(function ($) {
$('.submit-form').click(function () {
$('.needs-validation').find('button[type="submit"]').click()
})
$('#brand-autocomplete').autocomplete({
'source': function(request, response) {
$http.get(`brands/autocomplete?name=${encodeURIComponent(request)}`, null, {hload: true}).then((res) => {

View File

@ -26,6 +26,9 @@
<li class="nav-item" role="presentation">
<a class="nav-link" data-bs-toggle="tab" href="#tab-express-company">{{ __('order.express_company') }}</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" data-bs-toggle="tab" href="#tab-multi-filter">{{ __('admin/setting.multi_filter') }}</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" data-bs-toggle="tab" href="#tab-mail">{{ __('admin/setting.mail_settings') }}</a>
</li>
@ -110,16 +113,15 @@
</x-admin-form-image>
@hook('admin.setting.image.after')
</div>
<div class="tab-pane fade" id="tab-attribute">
<x-admin::form.row title="__('admin/setting.multi_filter')">
<div class="tab-pane fade" id="tab-multi-filter">
<x-admin::form.row :title="__('admin/setting.filter_attribute')">
<div class="module-edit-group wp-600">
<div class="autocomplete-group-wrapper">
<el-autocomplete
class="inline-input"
v-model="attributes.keyword"
v-model="multi_filter.keyword"
value-key="name"
size="small"
:fetch-suggestions="(keyword, cb) => {attributesQuerySearch(keyword, cb, 'products')}"
@ -127,9 +129,9 @@
@select="(e) => {handleSelect(e, 'product_attributes')}"
></el-autocomplete>
<div class="item-group-wrapper" v-loading="attributes.loading">
<template v-if="attributes.multi_filter.attribute.length">
<div v-for="(item, index) in attributes.multi_filter.attribute" :key="index" class="item">
<div class="item-group-wrapper" v-loading="multi_filter.loading">
<template v-if="multi_filter.filters.attribute.length">
<div v-for="(item, index) in multi_filter.filters.attribute" :key="index" class="item">
<div>
<i class="el-icon-s-unfold"></i>
<span>@{{ item.name }}</span>
@ -143,9 +145,9 @@
<input type="text" name="multi_filter" value="" class="form-control d-none">
</template>
</div>
<div class="help-text font-size-12 lh-base">{{ __('admin/setting.multi_filter_helper') }}</div>
</div>
</div>
<div class="help-text font-size-12 lh-base">{{ __('admin/builder.multi_filter_helper') }}</div>
</x-admin::form.row>
</div>
@ -299,6 +301,12 @@
new Vue({
el: '#app',
data: {
multi_filter: {
keyword: '',
filters: @json($multi_filter ?? null),
loading: null,
},
mail_engine: @json(old('mail_engine', system_setting('base.mail_engine', ''))),
express_company: @json(old('express_company', system_setting('base.express_company', []))),
@ -312,6 +320,16 @@
]
},
},
created() {
const multi_filter = @json($multi_filter ?? null);
if (multi_filter) {
this.multi_filter.filters = multi_filter;
} else {
this.multi_filter.filters = {
attribute: [],
}
}
},
methods: {
addCompany() {
if (typeof this.express_company == 'string') {
@ -319,7 +337,29 @@
}
this.express_company.push({name: '', code: ''})
}
},
attributesQuerySearch(keyword, cb, url) {
$http.get('attributes/autocomplete?name=' + encodeURIComponent(keyword), null, {hload:true}).then((res) => {
cb(res.data);
})
},
attributesRemoveProduct(index) {
this.multi_filter.filters.attribute.splice(index, 1);
},
handleSelect(item, key) {
if (key == 'product_attributes') {
if (!this.multi_filter.filters.attribute.find(v => v.id * 1 == item.id * 1)) {
this.multi_filter.filters.attribute.push(item);
} else {
layer.msg('{{ __('common.no_repeat') }}', () => {})
}
this.multi_filter.keyword = ""
}
},
}
});

View File

@ -74,4 +74,5 @@ return [
'multi_filter' => 'Multi Filter',
'please_select' => 'Please select',
'multi_filter_helper' => 'Please select the attributes to be displayed in the Multi Filter module.',
'filter_attribute' => 'Attribute Filter',
];

View File

@ -85,6 +85,7 @@ return [
'sort_order' => 'Sort Order',
'error_page' => 'The data you accessed does not exist or has been deleted~',
'error_page_btn' => 'Return to previous page',
'no_repeat' => 'Do not re-add',
'order' => [
'unpaid' => 'Unpaid',

View File

@ -72,4 +72,5 @@ return [
'multi_filter' => '高级筛选',
'please_select' => '请添加',
'multi_filter_helper' => '请选择需要在筛选模块显示的属性',
'filter_attribute' => '属性筛选',
];

View File

@ -84,6 +84,7 @@ return [
'sort_order' => '排序',
'error_page' => '您访问的数据不存在或已被删除~',
'error_page_btn' => '返回上一页',
'no_repeat' => '请勿重新添加',
'order' => [
'unpaid' => '待支付',

View File

@ -70,4 +70,8 @@ return [
'head_code' => '插入代碼',
'head_code_info' => '會將輸入框中的代碼插入到前端頁面 head 中,可用於統計代碼或者添加特殊插件等',
'rate_api_key' => '匯率 API KEY',
'multi_filter' => '高級篩選',
'please_select' => '請添加',
'multi_filter_helper' => '請選擇需要在篩選模塊顯示的屬性',
'filter_attribute' => '屬性篩選',
];

View File

@ -84,6 +84,7 @@ return [
'sort_order' => '排序',
'error_page' => '您訪問的數據不存在或已被刪除~',
'error_page_btn' => '返回上一頁',
'no_repeat' => '請勿重新添加',
'order' => [
'unpaid' => '待支付',

2
webpack.mix.js vendored
View File

@ -27,7 +27,7 @@ mix.js('resources/beike/shop/fashion/js/app.js', 'public/build/beike/shop/fashio
/* , themeFileName
const themeFileName = 'Fashion2';
const themeCode = themeCode.toLowerCase();
const themeCode = themeFileName.toLowerCase();
// 拷贝模版 blade 文件 到 themes 目录下
mix.copy(`plugins/${themeFileName}/Themes`, 'themes');