优化后台 订单管理、商品管理、客户管理 列表筛选等
This commit is contained in:
parent
db6614e7a3
commit
ee833b9eaa
|
|
@ -3,10 +3,11 @@
|
|||
* @link https://beikeshop.com
|
||||
* @Author pu shuo <pushuo@guangda.work>
|
||||
* @Date 2022-08-22 18:32:26
|
||||
* @LastEditTime 2022-09-16 20:57:51
|
||||
* @LastEditTime 2023-02-03 10:12:59
|
||||
*/
|
||||
|
||||
export default {
|
||||
// 打开文件管理器
|
||||
fileManagerIframe(callback) {
|
||||
const base = document.querySelector('base').href;
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ export default {
|
|||
});
|
||||
},
|
||||
|
||||
// 防抖
|
||||
debounce(fn, delay) {
|
||||
var timeout = null; // 创建一个标记用来存放定时器的返回值
|
||||
|
||||
|
|
@ -41,12 +43,14 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
// 生成随机字符串
|
||||
randomString(length) {
|
||||
let str = '';
|
||||
for (; str.length < length; str += Math.random().toString(36).substr(2));
|
||||
return str.substr(0, length);
|
||||
},
|
||||
|
||||
// 获取url参数
|
||||
getQueryString(name, defaultValue) {
|
||||
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
|
||||
const r = window.location.search.substr(1).match(reg);
|
||||
|
|
@ -57,11 +61,44 @@ export default {
|
|||
return typeof(defaultValue) != 'undefined' ? defaultValue : '';
|
||||
},
|
||||
|
||||
// 控制字符串长度 超出显示...
|
||||
stringLengthInte(text, length = 50) {
|
||||
if (text.length) {
|
||||
return text.slice(0, length) + (text.length > length ? '...' : '');
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
// 给列表页筛选开发插件使用,场景:开发者需要添加筛选条件,不需要到filter添加筛选key
|
||||
addFilterCondition(app) {
|
||||
if (location.search) {
|
||||
const params = location.search.substr(1).split('&');
|
||||
params.forEach(param => {
|
||||
const [key, value] = param.split('=');
|
||||
app.$set(app.filter, key, value);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 将对象内不为空的转换为url参数 并 添加到url后面
|
||||
objectToUrlParams(obj, url) {
|
||||
const params = [];
|
||||
for (const key in obj) {
|
||||
if (obj[key] !== '') {
|
||||
params.push(`${key}=${obj[key]}`);
|
||||
}
|
||||
}
|
||||
|
||||
return `${url}${params.length ? '?' : ''}${params.join('&')}`;
|
||||
},
|
||||
|
||||
// 清空对象内的值
|
||||
clearObjectValue(obj) {
|
||||
for (const key in obj) {
|
||||
obj[key] = '';
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
<div id="content">
|
||||
<div class="page-title-box py-1 d-flex align-items-center justify-content-between">
|
||||
<h5 class="page-title">@yield('title')</h5>
|
||||
@yield('page-title-right')
|
||||
<div>@yield('page-title-right')</div>
|
||||
</div>
|
||||
<div class="container-fluid p-0">
|
||||
@yield('content')
|
||||
|
|
|
|||
|
|
@ -47,55 +47,59 @@
|
|||
<button type="button" class="btn btn-primary" @click="checkedCustomerSclearRestore">{{ __('admin/product.clear_restore') }}</button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="table-push">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('common.id') }}</th>
|
||||
<th>{{ __('customer.email') }}</th>
|
||||
<th>{{ __('customer.name') }}</th>
|
||||
<th>{{ __('customer.from') }}</th>
|
||||
<th>{{ __('customer.customer_group') }}</th>
|
||||
<th>{{ __('common.status') }}</th>
|
||||
<th>{{ __('common.created_at') }}</th>
|
||||
<th>{{ __('common.action') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-if="customers.data.length">
|
||||
<tr v-for="customer, index in customers.data" :key="index">
|
||||
<td>@{{ customer.id }}</td>
|
||||
<td>@{{ customer.email }}</td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
{{-- <img src="@{{ customer.avatar }}" class="img-fluid rounded-circle me-2" style="width: 40px;"> --}}
|
||||
<div>@{{ customer.name }}</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>@{{ customer.from }}</td>
|
||||
<td>@{{ customer.customer_group_name }}</td>
|
||||
<td>
|
||||
<span v-if="customer.status" class="text-success">{{ __('common.enable') }}</span>
|
||||
<span v-else class="text-secondary">{{ __('common.disable') }}</span>
|
||||
</td>
|
||||
<td>@{{ customer.created_at }}</td>
|
||||
<td>
|
||||
@if ($type != 'trashed')
|
||||
<a class="btn btn-outline-secondary btn-sm" :href="customer.edit">{{ __('common.edit') }}</a>
|
||||
<button class="btn btn-outline-danger btn-sm ml-1" type="button" @click="deleteCustomer(customer.delete, index)">{{ __('common.delete') }}</button>
|
||||
@else
|
||||
<a href="javascript:void(0)" class="btn btn-outline-secondary btn-sm"
|
||||
@click.prevent="restore(customer.id, index)">{{ __('common.restore') }}</a>
|
||||
<button class="btn btn-outline-danger btn-sm ml-1" type="button" @click="deleteTrashedCustomer(customer.id, index)">{{ __('common.delete') }}</button>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody v-else><tr><td colspan="9" class="border-0"><x-admin-no-data /></td></tr></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<el-pagination v-if="customers.data.length" layout="total, prev, pager, next" background :page-size="customers.per_page" :current-page.sync="page"
|
||||
:total="customers.total"></el-pagination>
|
||||
@if ($customers->total())
|
||||
<div class="table-push">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('common.id') }}</th>
|
||||
<th>{{ __('customer.email') }}</th>
|
||||
<th>{{ __('customer.name') }}</th>
|
||||
<th>{{ __('customer.from') }}</th>
|
||||
<th>{{ __('customer.customer_group') }}</th>
|
||||
<th>{{ __('common.status') }}</th>
|
||||
<th>{{ __('common.created_at') }}</th>
|
||||
<th>{{ __('common.action') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($customers as $customer)
|
||||
<tr>
|
||||
<td>{{ $customer['id'] }}</td>
|
||||
<td>{{ $customer['email'] }}</td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div>{{ $customer['name'] }}</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ $customer['from'] }}</td>
|
||||
<td>{{ $customer->customerGroup->description->name ?? '' }}</td>
|
||||
<td>
|
||||
<span class="{{ $customer['active'] ? 'text-success' : 'text-secondary' }}">
|
||||
{{ $customer['active'] ? __('common.enable') : __('common.disable') }}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ $customer['created_at'] }}</td>
|
||||
<td>
|
||||
@if ($type != 'trashed')
|
||||
<a class="btn btn-outline-secondary btn-sm" href="{{ admin_route('customers.edit', [$customer->id]) }}">{{ __('common.edit') }}</a>
|
||||
<button class="btn btn-outline-danger btn-sm ml-1" type="button" @click="deleteCustomer({{ $customer['id'] }})">{{ __('common.delete') }}</button>
|
||||
@else
|
||||
<a href="javascript:void(0)" class="btn btn-outline-secondary btn-sm"
|
||||
@click.prevent="restore({{ $customer['id'] }})">{{ __('common.restore') }}</a>
|
||||
<button class="btn btn-outline-danger btn-sm ml-1" type="button" @click="deleteTrashedCustomer({{ $customer['id'] }})">{{ __('common.delete') }}</button>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $customers->withQueryString()->links('admin::vendor/pagination/bootstrap-4') }}
|
||||
@else
|
||||
<x-admin-no-data />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<el-dialog title="{{ __('admin/customer.customers_create') }}" :visible.sync="dialogCustomers.show" width="670px"
|
||||
|
|
@ -135,9 +139,6 @@
|
|||
el: '#customer-app',
|
||||
|
||||
data: {
|
||||
page: 1,
|
||||
customers: @json($customers ?? []),
|
||||
|
||||
source: {
|
||||
customer_group: @json($customer_groups ?? []),
|
||||
},
|
||||
|
|
@ -163,48 +164,24 @@
|
|||
password: [{required: true,message: '{{ __('common.error_required', ['name' => __('shop/login.password')] ) }}',trigger: 'blur'}, ],
|
||||
},
|
||||
|
||||
url: @json(admin_route('customers.index')),
|
||||
url: '{{ $type == 'trashed' ? admin_route('customers.trashed') : admin_route('customers.index') }}',
|
||||
|
||||
filter: {
|
||||
page: bk.getQueryString('page'),
|
||||
email: bk.getQueryString('email'),
|
||||
name: bk.getQueryString('name'),
|
||||
customer_group_id: bk.getQueryString('customer_group_id'),
|
||||
status: bk.getQueryString('status'),
|
||||
},
|
||||
|
||||
customerIds: @json($customers->pluck('id')),
|
||||
},
|
||||
|
||||
mounted () {
|
||||
},
|
||||
|
||||
watch: {
|
||||
page: function() {
|
||||
this.loadData();
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
query() {
|
||||
let query = '';
|
||||
const filter = Object.keys(this.filter)
|
||||
.filter(key => this.filter[key])
|
||||
.map(key => key + '=' + this.filter[key])
|
||||
.join('&');
|
||||
|
||||
if (filter) {
|
||||
query += '?' + filter;
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
created() {
|
||||
bk.addFilterCondition(this);
|
||||
},
|
||||
|
||||
methods: {
|
||||
loadData() {
|
||||
$http.get(`customers?page=${this.page}`).then((res) => {
|
||||
this.customers = res.data.customers;
|
||||
})
|
||||
},
|
||||
|
||||
checkedCustomersCreate() {
|
||||
this.dialogCustomers.show = true
|
||||
},
|
||||
|
|
@ -254,23 +231,22 @@
|
|||
|
||||
$http.post('customers', this.dialogCustomers.form).then((res) => {
|
||||
this.$message.success(res.message);
|
||||
this.loadData();// this.customers.data.push(res.data);
|
||||
window.location.reload();
|
||||
this.dialogCustomers.show = false
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
deleteCustomer(url, index) {
|
||||
deleteCustomer(id) {
|
||||
const self = this;
|
||||
this.$confirm('{{ __('common.confirm_delete') }}', '{{ __('common.text_hint') }}', {
|
||||
confirmButtonText: '{{ __('common.confirm') }}',
|
||||
cancelButtonText: '{{ __('common.cancel') }}',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
$http.delete(url).then((res) => {
|
||||
$http.delete(`customers/${id}`).then((res) => {
|
||||
self.$message.success(res.message);
|
||||
window.location.reload();
|
||||
// self.customers.splice(index, 1)
|
||||
})
|
||||
}).catch(()=>{})
|
||||
},
|
||||
|
|
@ -281,12 +257,12 @@
|
|||
},
|
||||
|
||||
search() {
|
||||
location = this.url + this.query
|
||||
location = bk.objectToUrlParams(this.filter, this.url)
|
||||
},
|
||||
|
||||
resetSearch() {
|
||||
Object.keys(this.filter).forEach(key => this.filter[key] = '')
|
||||
location = this.url + this.query
|
||||
this.filter = bk.clearObjectValue(this.filter)
|
||||
location = bk.objectToUrlParams(this.filter, this.url)
|
||||
},
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,11 +10,10 @@
|
|||
<div id="customer-app" class="card h-min-600">
|
||||
<div class="card-body">
|
||||
<div class="bg-light p-4 mb-3" id="app">
|
||||
<el-form :inline="true" :model="filter" class="demo-form-inline" label-width="100px">
|
||||
<el-form :inline="true" ref="filterForm" :model="filter" class="demo-form-inline" label-width="100px">
|
||||
<div>
|
||||
<el-form-item label="{{ __('order.number') }}">
|
||||
<el-input @keyup.enter.native="search" v-model="filter.number" size="small" placeholder="{{ __('order.number') }}"></el-input>
|
||||
{{-- <input @keyup.enter="search" type="text" v-model="filter.number" class="form-control" placeholder="{{ __('order.number') }}"> --}}
|
||||
</el-form-item>
|
||||
<el-form-item label="{{ __('order.customer_name') }}">
|
||||
<el-input @keyup.enter.native="search" v-model="filter.customer_name" size="small" placeholder="{{ __('order.customer_name') }}">
|
||||
|
|
@ -109,13 +108,13 @@
|
|||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@hook('admin.order.list.content.footer')
|
||||
@hook('admin.order.list.content.footer')
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
<script>
|
||||
new Vue({
|
||||
let app = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
url: @json(admin_route('orders.index')),
|
||||
|
|
@ -130,34 +129,22 @@
|
|||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
query() {
|
||||
let query = '';
|
||||
const filter = Object.keys(this.filter)
|
||||
.filter(key => this.filter[key])
|
||||
.map(key => key + '=' + this.filter[key])
|
||||
.join('&');
|
||||
|
||||
if (filter) {
|
||||
query += '?' + filter;
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
created() {
|
||||
bk.addFilterCondition(this);
|
||||
},
|
||||
|
||||
methods: {
|
||||
search() {
|
||||
location = this.url + this.query
|
||||
location = bk.objectToUrlParams(this.filter, this.url)
|
||||
},
|
||||
|
||||
resetSearch() {
|
||||
Object.keys(this.filter).forEach(key => this.filter[key] = '')
|
||||
location = this.url + this.query
|
||||
this.filter = bk.clearObjectValue(this.filter)
|
||||
location = bk.objectToUrlParams(this.filter, this.url)
|
||||
},
|
||||
|
||||
exportOrder() {
|
||||
location = this.exportUrl + this.query
|
||||
location = bk.objectToUrlParams(this.filter, this.exportUrl)
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -68,18 +68,18 @@
|
|||
<button class="btn btn-primary" @click="clearRestore">{{ __('admin/product.clear_restore') }}</button>
|
||||
@endif
|
||||
|
||||
@if ($type != 'trashed')
|
||||
<div class="right nowrap" v-if="product.data.length">
|
||||
<button class="btn btn-outline-secondary" :disabled="!selected.length" @click="batchDelete">{{ __('admin/product.batch_delete') }}</button>
|
||||
<button class="btn btn-outline-secondary" :disabled="!selected.length"
|
||||
@click="batchActive(true)">{{ __('admin/product.batch_active') }}</button>
|
||||
<button class="btn btn-outline-secondary" :disabled="!selected.length"
|
||||
@click="batchActive(false)">{{ __('admin/product.batch_inactive') }}</button>
|
||||
</div>
|
||||
@if ($type != 'trashed' && $products->total())
|
||||
<div class="right nowrap">
|
||||
<button class="btn btn-outline-secondary" :disabled="!selectedIds.length" @click="batchDelete">{{ __('admin/product.batch_delete') }}</button>
|
||||
<button class="btn btn-outline-secondary" :disabled="!selectedIds.length"
|
||||
@click="batchActive(true)">{{ __('admin/product.batch_active') }}</button>
|
||||
<button class="btn btn-outline-secondary" :disabled="!selectedIds.length"
|
||||
@click="batchActive(false)">{{ __('admin/product.batch_inactive') }}</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<template v-if="product.data.length">
|
||||
@if ($products->total())
|
||||
<div class="table-push">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
|
|
@ -93,8 +93,8 @@
|
|||
<div class="d-flex align-items-center">
|
||||
{{ __('common.created_at') }}
|
||||
<div class="d-flex flex-column ml-1 order-by-wrap">
|
||||
<i class="el-icon-caret-top" @click="orderBy = 'created_at:asc'"></i>
|
||||
<i class="el-icon-caret-bottom" @click="orderBy = 'created_at:desc'"></i>
|
||||
<i class="el-icon-caret-top" @click="checkedOrderBy('created_at:asc')"></i>
|
||||
<i class="el-icon-caret-bottom" @click="checkedOrderBy('created_at:desc')"></i>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
|
|
@ -103,8 +103,8 @@
|
|||
<div class="d-flex align-items-center">
|
||||
{{ __('common.sort_order') }}
|
||||
<div class="d-flex flex-column ml-1 order-by-wrap">
|
||||
<i class="el-icon-caret-top" @click="orderBy = 'position:asc'"></i>
|
||||
<i class="el-icon-caret-bottom" @click="orderBy = 'position:desc'"></i>
|
||||
<i class="el-icon-caret-top" @click="checkedOrderBy('position:asc')"></i>
|
||||
<i class="el-icon-caret-bottom" @click="checkedOrderBy('position:desc')"></i>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
|
|
@ -115,45 +115,44 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in product.data" :key="item.id">
|
||||
<td><input type="checkbox" :value="item.id" v-model="selected" /></td>
|
||||
<td>@{{ item.id }}</td>
|
||||
@foreach ($products as $product)
|
||||
<tr>
|
||||
<td><input type="checkbox" :value="{{ $product['id'] }}" v-model="selectedIds" /></td>
|
||||
<td>{{ $product['id'] }}</td>
|
||||
<td>
|
||||
<div class="wh-60 border d-flex justify-content-between align-items-center"><img :src="item.images[0] || 'image/placeholder.png'" class="img-fluid"></div>
|
||||
<div class="wh-60 border d-flex justify-content-between align-items-center"><img src="{{ $product['images'][0] ?? 'image/placeholder.png' }}" class="img-fluid"></div>
|
||||
</td>
|
||||
<td>
|
||||
<a :href="item.url" target="_blank" :title="item.name" class="text-dark">@{{ stringLengthInte(item.name, 90) }}</a>
|
||||
<a href="{{ $product['url'] }}" target="_blank" title="{{ $product['name'] }}" class="text-dark">{{ $product['name'] }}</a>
|
||||
</td>
|
||||
<td>@{{ item.price_formatted }}</td>
|
||||
<td>@{{ item.created_at }}</td>
|
||||
<td>@{{ item.position }}</td>
|
||||
<td>{{ $product['price_formatted'] }}</td>
|
||||
<td>{{ $product['created_at'] }}</td>
|
||||
<td>{{ $product['position'] }}</td>
|
||||
@if ($type != 'trashed')
|
||||
<td>
|
||||
<span v-if="item.active" class="text-success">{{ __('common.enable') }}</span>
|
||||
<span v-else class="text-secondary">{{ __('common.disable') }}</span>
|
||||
<span class="{{ $product['active'] ? 'text-success' : 'text-secondary' }}">
|
||||
{{ $product['active'] ? __('common.enable') : __('common.disable') }}
|
||||
</span>
|
||||
</td>
|
||||
@endif
|
||||
<td width="140" class="text-end">
|
||||
<template v-if="item.deleted_at == ''">
|
||||
<a :href="item.url_edit" class="btn btn-outline-secondary btn-sm">{{ __('common.edit') }}</a>
|
||||
<a href="javascript:void(0)" class="btn btn-outline-danger btn-sm"
|
||||
@click.prevent="deleteProduct(index)">{{ __('common.delete') }}</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a href="javascript:void(0)" class="btn btn-outline-secondary btn-sm"
|
||||
@click.prevent="restoreProduct(index)">{{ __('common.restore') }}</a>
|
||||
</template>
|
||||
@if ($product['deleted_at'] == '')
|
||||
<a href="{{ admin_route('products.edit', [$product->id]) }}" class="btn btn-outline-secondary btn-sm">{{ __('common.edit') }}</a>
|
||||
<a href="javascript:void(0)" class="btn btn-outline-danger btn-sm" @click.prevent="deleteProduct({{ $loop->index }})">{{ __('common.delete') }}</a>
|
||||
@else
|
||||
<a href="javascript:void(0)" class="btn btn-outline-secondary btn-sm" @click.prevent="restoreProduct({{ $loop->index }})">{{ __('common.restore') }}</a>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<el-pagination layout="total, prev, pager, next" background :page-size="product.per_page" :current-page.sync="page"
|
||||
:total="product.total"></el-pagination>
|
||||
</template>
|
||||
|
||||
<div v-else><x-admin-no-data /></div>
|
||||
{{ $products->withQueryString()->links('admin::vendor/pagination/bootstrap-4') }}
|
||||
@else
|
||||
<x-admin-no-data />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -161,92 +160,46 @@
|
|||
|
||||
@push('footer')
|
||||
<script>
|
||||
new Vue({
|
||||
let app = new Vue({
|
||||
el: '#product-app',
|
||||
data: {
|
||||
product: @json($products),
|
||||
url: '{{ $type == 'trashed' ? admin_route("products.trashed") : admin_route("products.index") }}',
|
||||
filter: {
|
||||
name: bk.getQueryString('name'),
|
||||
page: bk.getQueryString('page'),
|
||||
category_id: bk.getQueryString('category_id'),
|
||||
sku: bk.getQueryString('sku'),
|
||||
model: bk.getQueryString('model'),
|
||||
active: bk.getQueryString('active'),
|
||||
order_by: bk.getQueryString('order_by', ''),
|
||||
},
|
||||
selected: [],
|
||||
page: bk.getQueryString('page', 1) * 1,
|
||||
orderBy: bk.getQueryString('order_by', 'products.id:desc'),
|
||||
selectedIds: [],
|
||||
productIds: @json($products->pluck('id')),
|
||||
},
|
||||
|
||||
computed: {
|
||||
url: function() {
|
||||
let filter = {};
|
||||
if (this.orderBy != 'products.id:desc') {
|
||||
filter.order_by = this.orderBy;
|
||||
}
|
||||
|
||||
if (this.page > 1) {
|
||||
filter.page = this.page;
|
||||
}
|
||||
|
||||
for (key in this.filter) {
|
||||
const value = this.filter[key];
|
||||
if (value !== '' && value !== null) {
|
||||
filter[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
const query = Object.keys(filter).map(key => key + '=' + filter[key]).join('&');
|
||||
// const url = @json(admin_route('products.index'));
|
||||
|
||||
@if ($type == 'products')
|
||||
const url = @json(admin_route('products.index'));
|
||||
@else
|
||||
const url = @json(admin_route('products.trashed'));
|
||||
@endif
|
||||
|
||||
if (query) {
|
||||
return url + '?' + query;
|
||||
}
|
||||
|
||||
return url;
|
||||
},
|
||||
|
||||
allSelected: {
|
||||
get() {
|
||||
return this.selected.length == this.product.data.length;
|
||||
get(e) {
|
||||
return this.selectedIds.length == this.productIds.length;
|
||||
},
|
||||
set(val) {
|
||||
return this.selected = val ? this.product.data.map(e => e.id) : [];
|
||||
return val ? this.selectedIds = this.productIds : this.selectedIds = [];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
page: function() {
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
orderBy: function() {
|
||||
this.loadData();
|
||||
}
|
||||
created() {
|
||||
bk.addFilterCondition(this);
|
||||
},
|
||||
methods: {
|
||||
loadData: function() {
|
||||
window.history.pushState('', '', this.url);
|
||||
$http.get(this.url).then((res) => {
|
||||
this.product = res;
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
batchDelete() {
|
||||
this.$confirm('{{ __('admin/product.confirm_batch_product') }}', '{{ __('common.text_hint') }}', {
|
||||
confirmButtonText: '{{ __('common.confirm') }}',
|
||||
cancelButtonText: '{{ __('common.cancel') }}',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
$http.delete('products/delete', {
|
||||
ids: this.selected
|
||||
}).then((res) => {
|
||||
$http.delete('products/delete', {ids: this.selectedIds}).then((res) => {
|
||||
layer.msg(res.message)
|
||||
location.reload();
|
||||
})
|
||||
|
|
@ -259,50 +212,51 @@
|
|||
cancelButtonText: '{{ __('common.cancel') }}',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
$http.post('products/status', {
|
||||
ids: this.selected,
|
||||
status: type
|
||||
}).then((res) => {
|
||||
$http.post('products/status', {ids: this.selectedIds, status: type}).then((res) => {
|
||||
layer.msg(res.message)
|
||||
location.reload();
|
||||
})
|
||||
}).catch(()=>{});
|
||||
},
|
||||
|
||||
search: function() {
|
||||
this.page = 1;
|
||||
this.loadData();
|
||||
search() {
|
||||
this.filter.page = '';
|
||||
location = bk.objectToUrlParams(this.filter, this.url)
|
||||
},
|
||||
|
||||
checkedOrderBy(orderBy) {
|
||||
this.filter.order_by = orderBy;
|
||||
location = bk.objectToUrlParams(this.filter, this.url)
|
||||
},
|
||||
|
||||
resetSearch() {
|
||||
Object.keys(this.filter).forEach(key => this.filter[key] = '')
|
||||
this.loadData();
|
||||
this.filter = bk.clearObjectValue(this.filter)
|
||||
location = bk.objectToUrlParams(this.filter, this.url)
|
||||
},
|
||||
|
||||
deleteProduct: function(index) {
|
||||
const product = this.product.data[index];
|
||||
deleteProduct(index) {
|
||||
const id = this.productIds[index];
|
||||
|
||||
this.$confirm('{{ __('common.confirm_delete') }}', '{{ __('common.text_hint') }}', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
$http.delete('products/' + product.id).then((res) => {
|
||||
$http.delete('products/' + id).then((res) => {
|
||||
this.$message.success(res.message);
|
||||
location.reload();
|
||||
})
|
||||
});
|
||||
}).catch(()=>{});;
|
||||
},
|
||||
|
||||
restoreProduct: function(index) {
|
||||
const product = this.product.data[index];
|
||||
restoreProduct(index) {
|
||||
const id = this.productIds[index];
|
||||
|
||||
this.$confirm('{{ __('admin/product.confirm_batch_restore') }}', '{{ __('common.text_hint') }}', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
$http.put('products/restore', {
|
||||
id: product.id
|
||||
}).then((res) => {
|
||||
$http.put('products/restore', {id: id}).then((res) => {
|
||||
location.reload();
|
||||
})
|
||||
});
|
||||
}).catch(()=>{});;
|
||||
},
|
||||
|
||||
clearRestore() {
|
||||
|
|
@ -312,7 +266,7 @@
|
|||
$http.post('products/trashed/clear').then((res) => {
|
||||
location.reload();
|
||||
})
|
||||
});
|
||||
}).catch(()=>{});;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ footer {
|
|||
}
|
||||
|
||||
.logo {
|
||||
max-width: 150px;
|
||||
max-width: 240px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ header {
|
|||
|
||||
.header-content {
|
||||
position: relative;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
> .container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -95,8 +96,6 @@ header {
|
|||
> .nav-link {
|
||||
font-size: 15px;
|
||||
padding: 1rem;
|
||||
// padding-right: 1rem;
|
||||
// padding-left: 1rem;
|
||||
position: relative;
|
||||
|
||||
.badge {
|
||||
|
|
@ -136,18 +135,11 @@ header {
|
|||
}
|
||||
}
|
||||
}
|
||||
// .nav-link {
|
||||
// color: #333;
|
||||
// // font-weight: bold;
|
||||
// font-size: .9rem;
|
||||
// padding-left: 1rem;
|
||||
// padding-right: 1rem;
|
||||
// }
|
||||
}
|
||||
|
||||
.logo {
|
||||
img {
|
||||
max-width: 180px;
|
||||
max-width: 200px;
|
||||
max-height: 50px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* @link https://beikeshop.com
|
||||
* @Author pu shuo <pushuo@guangda.work>
|
||||
* @Date 2022-08-29 17:32:51
|
||||
* @LastEditTime 2023-01-16 11:28:28
|
||||
* @LastEditTime 2023-02-02 11:06:01
|
||||
*/
|
||||
|
||||
import http from "../../../../js/http";
|
||||
|
|
|
|||
Loading…
Reference in New Issue