This commit is contained in:
liqianjin 2023-05-29 14:08:51 +08:00
parent 5e552c572e
commit 5880fbaa0a
78 changed files with 5107 additions and 0 deletions

2
themes/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
#*
#!default

View File

@ -0,0 +1,101 @@
@extends('layout.master')
@section('body-class', 'page-account')
@section('content')
<div class="container">
<x-shop-breadcrumb type="static" value="account.index" />
<div class="row">
<x-shop-sidebar />
<div class="col-12 col-md-9">
@if (\Session::has('success'))
<div class="alert alert-success">
<ul>
<li>{!! \Session::get('success') !!}</li>
</ul>
</div>
@endif
@if (0)
<div class="card mb-4 account-card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.index') }}</h5>
<a href="{{ shop_route('account.edit.index') }}" class="text-muted">{{ __('shop/account.revise_info') }}</a>
</div>
<div class="card-body">
<div class="d-flex flex-nowrap card-items py-2">
<a href="{{ shop_route('account.wishlist.index') }}" class="d-flex flex-column align-items-center"><i class="iconfont">&#xe77f;</i><span
class="text-muted">{{ __('shop/account.collect') }}</span></a>
<a href="http://" class="d-flex flex-column align-items-center"><i class="iconfont">&#xe6a3;</i><span
class="text-muted">{{ __('shop/account.coupon') }}</span></a>
<a href="http://" class="d-flex flex-column align-items-center"><i class="iconfont">&#xe6a3;</i><span
class="text-muted">{{ __('shop/account.coupon') }}</span></a>
</div>
</div>
</div>
@endif
<div class="card account-card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.my_order') }}</h5>
<a href="{{ shop_route('account.order.index') }}" class="text-muted">{{ __('shop/account.orders') }}</a>
</div>
<div class="card-body">
<div class="d-flex flex-nowrap card-items mb-4 py-3">
<a href="{{ shop_route('account.order.index', ['status' => 'unpaid']) }}" class="d-flex flex-column align-items-center"><i class="iconfont">&#xf12f;</i><span
class="text-muted text-center">{{ __('shop/account.pending_payment') }}</span></a>
<a href="{{ shop_route('account.order.index', ['status' => 'paid']) }}" class="d-flex flex-column align-items-center"><i class="iconfont">&#xf130;</i><span
class="text-muted text-center">{{ __('shop/account.pending_send') }}</span></a>
<a href="{{ shop_route('account.order.index', ['status' => 'shipped']) }}" class="d-flex flex-column align-items-center"><i class="iconfont">&#xf131;</i><span
class="text-muted text-center">{{ __('shop/account.pending_receipt') }}</span></a>
<a href="{{ shop_route('account.rma.index') }}" class="d-flex flex-column align-items-center"><i class="iconfont">&#xf132;</i><span
class="text-muted text-center">{{ __('shop/account.after_sales') }}</span></a>
</div>
<div class="order-wrap">
@if (!count($latest_orders))
<div class="no-order d-flex flex-column align-items-center">
<div class="icon mb-2"><i class="iconfont">&#xe60b;</i></div>
<div class="text mb-3 text-muted">{{ __('shop/account.no_order') }}<a href="">{{ __('shop/account.to_buy') }}</a></div>
</div>
@else
{{-- <p class="text-muted">近期订单</p> --}}
<ul class="list-unstyled orders-list table-responsive">
<table class="table table-hover">
<tbody>
@foreach ($latest_orders as $order)
<tr class="align-middle">
<td style="width: 62px">
<div class="img border wh-60 d-flex justify-content-between align-items-center">
<img src="{{ $order->orderProducts[0]->image ?? '' }}" class="img-fluid">
</div>
</td>
<td>
<div class="mb-2">{{ __('shop/account.order_number') }}<span style="width: 110px;display: inline-block;">{{ $order->number }}</span> <span class="vr lh-1 me-2 bg-secondary"></span> {{ __('shop/account.all') }} {{ count($order->orderProducts) }} {{ __('shop/account.items') }}</div>
<div class="text-muted">{{ __('shop/account.order_time') }}{{ $order->created_at }}</div>
</td>
<td>
<span class="ms-4 d-inline-block">{{ __('shop/account.state') }}{{ $order->status_format }}</span>
</td>
<td>
<span class="ms-3 d-inline-block">{{ __('shop/account.amount') }}{{ currency_format($order->total, $order->currency_code, $order->currency_value) }}</span>
</td>
<td>
<a href="{{ shop_route('account.order.show', ['number' => $order->number]) }}"
class="btn btn-outline-secondary btn-sm">{{ __('shop/account.check_details') }}</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</ul>
@endif
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,127 @@
@extends('layout.master')
@section('body-class', 'page-account-address')
@push('header')
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
@endpush
@section('content')
<div class="container" id="address-app">
<x-shop-breadcrumb type="static" value="account.addresses.index" />
<div class="row">
<x-shop-sidebar />
<div class="col-12 col-md-9">
<div class="card h-min-600">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.addresses.index') }}</h5>
</div>
<div class="card-body h-600">
<button v-if="addresses.length" class="btn btn-dark mb-3" @click="editAddress"><i class="bi bi-plus-square-dotted me-1"></i>
{{ __('shop/account.addresses.add_address') }}</button>
<div class="addresses-wrap" v-cloak>
<div class="row" v-if="addresses.length">
<div class="col-6" v-for="address, index in addresses" :key="index">
<div class="item">
<div class="name-wrap">
<span class="name">@{{ address.name }}</span>
<span class="phone">@{{ address.phone }}</span>
</div>
<div class="zipcode">@{{ address.zipcode }}</div>
<div class="address-info">@{{ address.country }} @{{ address.zone }} @{{ address.city }}
@{{ address.address_1 }}</div>
<div class="address-bottom">
<div><span class="badge bg-success"
v-if="address.default">{{ __('shop/account.addresses.default_address') }}</span></div>
<div>
<a class="me-2" @click.stop="deleteAddress(index)">{{ __('shop/account.addresses.delete') }}</a>
<a href="javascript:void(0)" @click.stop="editAddress(index)">{{ __('shop/account.addresses.edit') }}</a>
</div>
</div>
</div>
</div>
</div>
<div v-else class="text-center">
<x-shop-no-data />
<button class="btn btn-dark mb-3" @click="editAddress"><i class="bi bi-plus-square-dotted me-1"></i>
{{ __('shop/account.addresses.add_address') }}</button>
</div>
</div>
</div>
</div>
</div>
</div>
<address-dialog ref="address-dialog" @change="onAddressDialogChange"></address-dialog>
</div>
@endsection
@push('add-scripts')
@include('shared.address-form')
<script>
new Vue({
el: '#address-app',
data: {
editIndex: null,
addresses: @json($addresses ?? []),
},
// 实例被挂载后调用
mounted() {},
methods: {
editAddress(index) {
let addresses = null
if (typeof index == 'number') {
this.editIndex = index;
addresses = JSON.parse(JSON.stringify(this.addresses[index]))
}
this.$refs['address-dialog'].editAddress(addresses)
},
deleteAddress(index) {
this.$confirm('{{ __('shop/account.addresses.confirm_delete') }}',
'{{ __('shop/account.addresses.hint') }}', {
confirmButtonText: '{{ __('common.confirm') }}',
cancelButtonText: '{{ __('common.cancel') }}',
type: 'warning'
}).then(() => {
$http.delete('/account/addresses/' + this.addresses[index].id).then((res) => {
this.$message.success(res.message);
this.addresses.splice(index, 1)
})
}).catch(() => {})
},
onAddressDialogChange(form) {
const type = form.id ? 'put' : 'post';
const url = `/account/addresses${type == 'put' ? '/' + form.id : ''}`;
$http[type](url, form).then((res) => {
if (res.data.default) {
this.addresses.map(e => e.default = false)
}
if (this.addresses.find(e => e.id == res.data.id)) {
this.addresses[this.editIndex] = res.data
} else {
this.addresses.push(res.data)
}
this.editIndex = null;
this.$forceUpdate()
this.$refs['address-dialog'].closeAddressDialog()
})
},
}
})
</script>
@endpush

View File

@ -0,0 +1,167 @@
@extends('layout.master')
@section('body-class', 'page-account-edit')
@push('header')
<script src="{{ asset('vendor/cropper/cropper.min.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/cropper/cropper.min.css') }}">
@endpush
@section('content')
<div class="container" id="address-app">
<x-shop-breadcrumb type="static" value="account.edit.index" />
<div class="row">
<x-shop-sidebar />
<div class="col-12 col-md-9">
<div class="card h-min-600">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.edit.index') }}</h5>
</div>
<div class="card-body h-600">
<form novalidate class="needs-validation" action="{{ shop_route('account.edit.update') }}" method="POST">
@csrf
{{ method_field('put') }}
@if (session('success'))
<x-shop-alert type="success" msg="{{ session('success') }}" class="mt-4" />
@endif
<div class="bg-light rounded-3 p-4 mb-4" style="background: #f6f9fc;">
<div class="d-flex align-items-center">
<img class="rounded-3" id="avatar" src="{{ image_resize($customer->avatar, 200, 200) }}"
width="90">
<div class="ps-3">
<label class="btn btn-light shadow-sm bg-body mb-2" data-toggle="tooltip" title="Change your avatar">
<i class="bi bi-arrow-repeat"></i> {{ __('shop/account.edit.modify_avatar') }}
<input type="file" class="d-none" id="update-btn" name="" accept="image/*">
<input type="hidden" id="avatar-input" name="avatar" value="{{ $customer->avatar }}">
</label>
<div class="p mb-0 fs-ms text-muted">{{ __('shop/account.edit.suggest') }}</div>
</div>
</div>
</div>
<div class="row gx-4 gy-3">
<div class="col-sm-6">
<label class="form-label">{{ __('shop/account.edit.name') }}</label>
<input class="form-control {{ $errors->has('name') ? 'is-invalid' : '' }}" type="text" name="name"
value="{{ old('name', $customer->name ?? '') }}" required>
<span class="invalid-feedback"
role="alert">{{ $errors->has('name') ? $errors->first('name') : __('common.error_required', ['name' => __('shop/account.edit.name')]) }}</span>
</div>
<div class="col-sm-6">
<label class="form-label">{{ __('shop/account.edit.email') }}</label>
<input class="form-control {{ $errors->has('email') ? 'is-invalid' : '' }}" type="email"
name="email" value="{{ old('email', $customer->email ?? '') }}" required>
<span class="invalid-feedback"
role="alert">{{ $errors->has('email') ? $errors->first('email') : __('common.error_required', ['name' => __('shop/account.edit.email')]) }}</span>
</div>
<div class="col-12 mt-4">
<button class="btn btn-primary mt-sm-0" type="submit">{{ __('common.submit') }}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="modal" tabindex="-1" data-bs-backdrop="static" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">{{ __('shop/account.edit.crop') }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="img-container">
<img id="cropper-image" src="{{ image_resize('/') }}" class="img-fluid">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ __('shop/common.cancel') }}</button>
<button type="button" class="btn btn-primary cropper-crop">{{ __('shop/common.confirm') }}</button>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script>
var avatar = document.getElementById('avatar');
var image = document.getElementById('cropper-image');
var cropper;
var $modal = $('#modal');
$(document).on('change', '#update-btn', function(e) {
var files = e.target.files;
var done = function(url) {
$(this).val('');
image.src = url;
$('#modal').modal('show');
};
var reader;
var file;
var url;
if (files && files.length > 0) {
file = files[0];
$('#update-btn').remove()
$('#avatar-input').before('<input type="file" class="d-none" id="update-btn" name="" accept="image/*">');
if (URL) {
done(URL.createObjectURL(file));
} else if (FileReader) {
reader = new FileReader();
reader.onload = function(e) {
done(reader.result);
};
reader.readAsDataURL(file);
}
}
});
$modal.on('shown.bs.modal', function() {
cropper = new Cropper(image, {
aspectRatio: 1,
viewMode: 3,
});
}).on('hidden.bs.modal', function() {
cropper.destroy();
cropper = null;
});
$('.cropper-crop').click(function(event) {
var initialAvatarURL;
var canvas;
$modal.modal('hide');
if (cropper) {
canvas = cropper.getCroppedCanvas({
width: 200,
height: 200,
});
initialAvatarURL = avatar.src;
// avatar.src = canvas.toDataURL();
canvas.toBlob(function(blob) {
var formData = new FormData();
formData.append('file', blob, 'avatar.png');
formData.append('type', 'avatar');
$http.post('{{ shop_route('file.store') }}', formData).then(res => {
$('#avatar').attr('src', res.data.url);
$('#avatar-input').val(res.data.value)
})
});
}
});
</script>
@endpush

View File

@ -0,0 +1,146 @@
@extends('layout.master')
@section('body-class', 'page-forgotten')
@push('header')
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
@endpush
@section('content')
<div class="container" id="page-forgotten" v-cloak>
<x-shop-breadcrumb type="static" value="forgotten.index" />
<div class="row my-5 justify-content-md-center">
<div class="col-lg-5 col-xxl-4">
<div class="card">
<el-form ref="form" :model="form" :rules="rules">
<div class="card-body p-0">
<h4 class="fw-bold">{{ __('shop/forgotten.follow_prompt') }}</h4>
<p class="text-muted" v-if="!isCode">{{ __('shop/forgotten.email_forCode') }}</p>
<p class="text-muted" v-else>{{ __('shop/forgotten.enter_password') }}</p>
<el-form-item label="{{ __('shop/forgotten.email') }}" prop="email" v-if="!isCode">
<el-input v-model="form.email" placeholder="{{ __('shop/forgotten.email_address') }}"></el-input>
</el-form-item>
<el-form-item label="{{ __('shop/forgotten.verification_code') }}" prop="code" class="mb-3" v-if="isCode">
<el-input v-model="form.code" placeholder="{{ __('shop/forgotten.verification_code') }}"></el-input>
</el-form-item>
<el-form-item label="{{ __('shop/forgotten.password') }}" prop="password" class="mb-3" v-if="isCode">
<el-input type="password" v-model="form.password" placeholder="{{ __('shop/forgotten.password') }}"></el-input>
</el-form-item>
<el-form-item label="{{ __('shop/forgotten.confirm_password') }}" prop="password_confirmation" v-if="isCode">
<el-input type="password" v-model="form.password_confirmation" placeholder="{{ __('shop/forgotten.confirm_password') }}"></el-input>
</el-form-item>
<div class="mt-5 mb-3 d-flex justify-content-between">
<button type="button" @click="submitForm('form')" class="btn w-50 btn-dark">
{{-- @{{ !isCode ? '发送验证码' : '提交' }} --}}
<template v-if="!isCode">{{ __('shop/forgotten.send_code') }}</template>
<template v-else>{{ __('common.submit') }}</template>
</button>
</div>
<a href="javascript:void(0)" v-if="isCode" @click="isCode = false" class="text-muted">{{ __('shop/forgotten.to_back') }}</a>
</div>
</el-form>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script>
var validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('{{ __('shop/forgotten.enter_password') }}'));
} else {
if (value !== '') {
app.$refs.form.validateField('password_confirmation');
}
callback();
}
};
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('{{ __('shop/forgotten.please_confirm') }}'));
} else if (value !== app.form.password) {
callback(new Error('{{ __('shop/forgotten.password_err') }}'));
} else {
callback();
}
};
let app = new Vue({
el: '#page-forgotten',
data: {
form: {
email: bk.getQueryString('email', ''),
code: bk.getQueryString('code', ''),
password: '',
password_confirmation: '',
},
isCode: !!bk.getQueryString('code'),
rules: {
email: [
{required: true, message: '{{ __('shop/forgotten.enter_email') }}', trigger: 'blur'},
{type: 'email', message: '{{ __('shop/forgotten.email_err') }}', trigger: 'blur'},
],
code: [
{required: true, message: '{{ __('shop/forgotten.enter_code') }}', trigger: 'blur'}
],
password: [
{required: true, validator: validatePass, trigger: 'blur'}
],
password_confirmation: [
{required: true, validator: validatePass2, trigger: 'blur'}
]
},
},
mounted () {
},
methods: {
submitForm(form) {
let _data = this.form, url = 'forgotten/password'
if (!this.isCode) {
url = 'forgotten/send_code'
}
this.$refs[form].validate((valid) => {
if (!valid) {
return;
}
$http.post(url, this.form).then((res) => {
if (this.isCode) {
layer.msg(res.message)
} else {
this.$alert(res.message, '{{ __('common.text_hint') }}');
}
this.$refs[form].clearValidate();
if (this.isCode) {
location = "{{ shop_route('login.index') }}"
}
this.isCode = true
})
});
}
}
})
</script>
@endpush

View File

@ -0,0 +1,201 @@
@extends('layout.master')
@section('body-class', 'page-login')
@push('header')
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
@endpush
@section('content')
<div class="{{ request('iframe') ? 'container-fluid form-iframe mt-5' : 'container' }}" id="page-login" v-cloak>
@if (!request('iframe'))
<x-shop-breadcrumb type="static" value="login.index" />
<div class="hero-content pb-5 text-center"><h1 class="hero-heading">{{ __('shop/login.index') }}</h1></div>
@endif
<div class="login-wrap">
<div class="card">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" :inline-message="true">
<div class="login-item-header card-header">
<h6 class="text-uppercase mb-0">{{ __('shop/login.login') }}</h6>
</div>
<div class="card-body px-md-2">
@hookwrapper('account.login.email')
<el-form-item label="{{ __('shop/login.email') }}" prop="email">
<el-input @keyup.enter.native="checkedBtnLogin('loginForm')" v-model="loginForm.email" placeholder="{{ __('shop/login.email_address') }}"></el-input>
</el-form-item>
@endhookwrapper
@hookwrapper('account.login.password')
<el-form-item label="{{ __('shop/login.password') }}" prop="password">
<el-input @keyup.enter.native="checkedBtnLogin('loginForm')" type="password" v-model="loginForm.password" placeholder="{{ __('shop/login.password') }}"></el-input>
</el-form-item>
@endhookwrapper
@hook('account.login.password.after')
@if (!request('iframe'))
<a class="text-muted forgotten-link" href="{{ shop_route('forgotten.index') }}"><i class="bi bi-question-circle"></i> {{ __('shop/login.forget_password') }}</a>
@endif
<div class="mt-4 mb-3">
<button type="button" @click="checkedBtnLogin('loginForm')" class="btn btn-dark btn-lg w-100 fw-bold"><i class="bi bi-box-arrow-in-right"></i> {{ __('shop/login.login') }}</button>
</div>
</div>
</el-form>
@if($social_buttons)
<div class="social-wrap px-2">
<div class="title mb-4"><span>{{ __('shop/login.third_party_logins') }}</span></div>
@foreach($social_buttons as $button)
{!! $button !!}
@endforeach
</div>
@endif
</div>
<div class="d-flex vr-wrap">
<div class="vr bg-secondary"></div>
</div>
<div class="card">
<div class="login-item-header card-header">
<h6 class="text-uppercase mb-0">{{ __('shop/login.new') }}</h6>
</div>
<div class="card-body px-md-2">
<el-form ref="registerForm" :model="registerForm" :rules="registeRules">
@hookwrapper('account.login.new.email')
<el-form-item label="{{ __('shop/login.email') }}" prop="email">
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" v-model="registerForm.email" placeholder="{{ __('shop/login.email_address') }}"></el-input>
</el-form-item>
@endhookwrapper
@hookwrapper('account.login.new.password')
<el-form-item label="{{ __('shop/login.password') }}" prop="password">
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" type="password" v-model="registerForm.password" placeholder="{{ __('shop/login.password') }}"></el-input>
</el-form-item>
@endhookwrapper
@hookwrapper('account.login.new.confirm_password')
<el-form-item label="{{ __('shop/login.confirm_password') }}" prop="password_confirmation">
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" type="password" v-model="registerForm.password_confirmation" placeholder="{{ __('shop/login.confirm_password') }}"></el-input>
</el-form-item>
@endhookwrapper
@hook('account.login.new.confirm_password.bottom')
<div class="mt-5 mb-3">
<button type="button" @click="checkedBtnLogin('registerForm')" class="btn btn-dark btn-lg w-100 fw-bold"><i class="bi bi-person"></i> {{ __('shop/login.register') }}</button>
</div>
</el-form>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script>
var validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('{{ __('shop/login.enter_password') }}'));
} else {
if (value !== '') {
app.$refs.registerForm.validateField('password_confirmation');
}
callback();
}
};
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('{{ __('shop/login.please_confirm') }}'));
} else if (value !== app.registerForm.password) {
callback(new Error('{{ __('shop/login.password_err') }}'));
} else {
callback();
}
};
let app = new Vue({
el: '#page-login',
data: {
loginForm: {
email: '',
password: '',
},
registerForm: {
email: '',
password: '',
password_confirmation: '',
},
loginRules: {
email: [
{required: true, message: '{{ __('shop/login.enter_email') }}', trigger: 'change'},
{type: 'email', message: '{{ __('shop/login.email_err') }}', trigger: 'change'},
],
password: [
{required: true, message: '{{ __('shop/login.enter_password')}}', trigger: 'change'}
]
},
registeRules: {
email: [
{required: true, message: '{{ __('shop/login.enter_email') }}', trigger: 'change'},
{type: 'email', message: '{{ __('shop/login.email_err') }}', trigger: 'change'},
],
password: [
{required: true, trigger: 'change'}
],
password_confirmation: [
{required: true, validator: validatePass2, trigger: 'change'}
]
}
},
beforeMount () {
},
methods: {
checkedBtnLogin(form) {
let _data = this.loginForm, url = '/login'
if (form == 'registerForm') {
_data = this.registerForm, url = '/register'
}
this.$refs['loginForm'].clearValidate();
this.$refs['registerForm'].clearValidate();
this.$refs[form].validate((valid) => {
if (!valid) {
layer.msg('{{ __('shop/login.check_form') }}', () => {})
return;
}
$http.post(url, _data).then((res) => {
layer.msg(res.message)
@if (!request('iframe'))
location = "{{ shop_route('account.index') }}"
@else
var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
setTimeout(() => {
parent.layer.close(index); //再执行关闭
parent.window.location.reload()
}, 400);
@endif
})
});
}
}
})
@hook('account.login.form.js.after')
</script>
@endpush

View File

@ -0,0 +1,79 @@
@extends('layout.master')
@section('body-class', 'page-account-order-list')
@section('content')
<div class="container">
<x-shop-breadcrumb type="static" value="account.order.index" />
<div class="row">
<x-shop-sidebar />
<div class="col-12 col-md-9">
<div class="card mb-4 account-card order-wrap">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.order.index') }}</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table ">
<thead>
<tr>
<th>{{ __('shop/account.order.order_details') }}</th>
<th width="160px">{{ __('shop/account.order.amount') }}</th>
<th width="100px">{{ __('shop/account.order.state') }}</th>
<th width="100px" class="text-end">{{ __('common.action') }}</th>
</tr>
</thead>
@if (count($orders))
@foreach ($orders as $order)
<tbody>
<tr class="sep-row">
<td colspan="4"></td>
</tr>
<tr class="head-tr">
<td colspan="4">
<span class="order-created me-4">{{ $order->created_at }}</span>
<span
class="order-number">{{ __('shop/account.order.order_number') }}{{ $order->number }}</span>
</td>
</tr>
@foreach ($order->orderProducts as $product)
<tr class="{{ $loop->first ? 'first-tr' : '' }}">
<td>
<div class="product-info">
<div class="img border d-flex justify-content-between align-items-center"><img src="{{ $product->image }}" class="img-fluid"></div>
<div class="name">
<a class="text-dark"
href="{{ shop_route('products.show', ['product' => $product->product_id]) }}">{{ $product->name }}</a>
<div class="quantity mt-1 text-secondary">x {{ $product->quantity }}</div>
</div>
</div>
</td>
@if ($loop->first)
<td rowspan="{{ $loop->count }}">
{{ currency_format($order->total, $order->currency_code, $order->currency_value) }}</td>
<td rowspan="{{ $loop->count }}">{{ __("common.order.{$order->status}") }}</td>
<td rowspan="{{ $loop->count }}" class="text-end">
<a href="{{ shop_route('account.order.show', ['number' => $order->number]) }}"
class="btn btn-outline-secondary btn-sm">{{ __('shop/account.order.check') }}</a>
</td>
@endif
</tr>
@endforeach
</tbody>
@endforeach
@else
<tbody>
<tr><td colspan="4" class="border-0"><x-shop-no-data /></td></tr>
</tbody>
@endif
</table>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,241 @@
@extends('layout.master')
@section('body-class', 'page-account-order-info')
@section('content')
<div class="container">
<x-shop-breadcrumb type="order" value="{{ $order->number }}" />
<div class="row">
<x-shop-sidebar />
<div class="col-12 col-md-9">
@if ($errors->any())
@foreach ($errors->all() as $error)
<x-shop-alert type="danger" msg="{{ $error }}" class="mt-4" />
@endforeach
@endif
<div class="card mb-4 order-head">
<div class="card-header d-flex align-items-center justify-content-between">
<h6 class="card-title">{{ __('shop/account.order.order_info.order_details') }}</h6>
<div>
@if ($order->status == 'unpaid')
<a href="{{ shop_route('orders.pay', $order->number) }}" class="btn btn-primary btn-sm nowrap">{{ __('shop/account.order.order_info.to_pay') }}</a>
<button class="btn btn-outline-secondary btn-sm cancel-order" type="button">{{ __('shop/account.order.order_info.cancel') }}</button>
@endif
@if ($order->status == 'shipped')
<button class="btn btn-primary btn-sm shipped-ed" type="button">{{ __('shop/account.order.order_info.confirm_receipt') }}</button>
@endif
</div>
</div>
<div class="card-body">
<div class="bg-light p-2 table-responsive">
<table class="table table-borderless mb-0">
<thead>
<tr>
<th>{{ __('shop/account.order.order_info.order_number') }}</th>
<th class="nowrap">{{ __('shop/account.order.order_info.order_date') }}</th>
<th>{{ __('shop/account.order.order_info.state') }}</th>
<th>{{ __('shop/account.order.order_info.order_amount') }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ $order->number }}</td>
<td>{{ $order->created_at }}</td>
<td>
{{ __("common.order.{$order->status}") }}
</td>
<td>{{ currency_format($order->total, $order->currency_code, $order->currency_value) }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card mb-4">
<div class="card-header"><h6 class="card-title">{{ __('order.address_info') }}</h6></div>
<div class="card-body">
<table class="table ">
<thead class="">
<tr>
<th>{{ __('order.shipping_address') }}</th>
<th>{{ __('order.payment_address') }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>{{ __('address.name') }}{{ $order->shipping_customer_name }} ({{ $order->shipping_telephone }})</div>
<div>
{{ __('address.address') }}
{{ $order->shipping_address_1 }}
{{ $order->shipping_address_2 }}
{{ $order->shipping_city }}
{{ $order->shipping_zone }}
{{ $order->shipping_country }}
</div>
<div>{{ __('address.post_code') }}{{ $order->shipping_zipcode }}</div>
</td>
<td>
<div>{{ __('address.name') }}{{ $order->payment_customer_name }} ({{ $order->payment_telephone }})</div>
<div>
{{ __('address.address') }}
{{ $order->payment_address_1 }}
{{ $order->payment_address_2 }}
{{ $order->payment_city }}
{{ $order->payment_zone }}
{{ $order->payment_country }}
</div>
<div>{{ __('address.post_code') }}{{ $order->payment_zipcode }}</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title">{{ __('shop/account.order.order_info.order_items') }}</h6>
</div>
<div class="card-body">
@foreach ($order->orderProducts as $product)
<div class="product-list">
<div class="d-flex">
<div class="left border d-flex justify-content-between align-items-center"><img src="{{ $product->image }}" class="img-fluid"></div>
<div class="right">
<div class="name">
<a class="text-dark" href="{{ shop_route('products.show', ['product' => $product->product_id]) }}">{{ $product->name }}</a>
</div>
<div class="price">
{{ currency_format($product->price, $order->currency_code, $order->currency_value) }}
x {{ $product->quantity }}
= {{ currency_format($product->price * $product->quantity, $order->currency_code, $order->currency_value) }}
</div>
</div>
</div>
@if ($order->status == 'completed')
<a href="{{ shop_route('account.rma.create', [$product->id]) }}" style="white-space: nowrap;"
class="btn btn-outline-primary btn-sm">{{ __('shop/account.order.order_info.apply_after_sales') }}</a>
@endif
</div>
@endforeach
</div>
</div>
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title">{{ __('shop/account.order.order_info.order_total') }}</h6>
</div>
<div class="card-body">
<table class="table table-bordered border">
<tbody>
@foreach (array_chunk($order->orderTotals->all(), 2) as $totals)
<tr>
@foreach ($totals as $total)
<td class="bg-light wp-200">{{ $total->title }}</td>
<td><strong>{{ currency_format($total->value, $order->currency_code, $order->currency_value) }}</strong></td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@foreach ($html_items as $item)
{!! $item !!}
@endforeach
@if (0)
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title">{{ __('shop/account.order.order_info.logistics_status') }}</h6>
</div>
<div class="card-body">
</div>
</div>
@endif
@if ($order->orderShipments->count())
<div class="card mb-4">
<div class="card-header"><h6 class="card-title">{{ __('order.order_shipments') }}</h6></div>
<div class="card-body">
<div class="table-push">
<table class="table ">
<thead class="">
<tr>
<th>{{ __('order.express_company') }}</th>
<th>{{ __('order.express_number') }}</th>
<th>{{ __('order.history_created_at') }}</th>
</tr>
</thead>
<tbody>
@foreach ($order->orderShipments as $ship)
<tr>
<td>{{ $ship->express_company }}</td>
<td>{{ $ship->express_number }}</td>
<td>{{ $ship->created_at }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
@endif
@if ($order->orderHistories->count())
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title">{{ __('shop/account.order.order_info.order_status') }}</h6>
</div>
<div class="card-body">
<table class="table ">
<thead class="">
<tr>
<th>{{ __('shop/account.order.order_info.state') }}</th>
<th>{{ __('shop/account.order.order_info.remark') }}</th>
<th>{{ __('shop/account.order.order_info.update_time') }}</th>
</tr>
</thead>
<tbody>
@foreach ($order->orderHistories as $orderHistory)
<tr>
<td>{{ $orderHistory->status_format }}</td>
<td><span class="fw-bold">{{ $orderHistory->comment }}</span></td>
<td><span class="fw-bold">{{ $orderHistory->created_at }}</span></td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script>
$('.shipped-ed').click(function(event) {
$http.post('orders/{{ $order->number }}/complete').then((res) => {
layer.msg(res.message)
window.location.reload()
})
});
$('.cancel-order').click(function(event) {
$http.post('orders/{{ $order->number }}/cancel').then((res) => {
layer.msg(res.message)
window.location.reload()
})
});
</script>
@endpush

View File

@ -0,0 +1,57 @@
@extends('layout.master')
@section('body-class', 'page-order-success')
@section('content')
<div class="container">
{{-- <x-shop-breadcrumb type="static" value="account.order.index" /> --}}
<div class="row mt-5 justify-content-center mb-5">
<div class="col-12 col-md-9">@include('shared.steps', ['steps' => 3])</div>
</div>
<div class="card order-wrap border">
<div class="card-body main-body">
<div class="order-top border-bottom">
<div class="left">
<i class="bi bi-check2-circle"></i>
</div>
<div class="right">
<h3 class="order-title">{{ __('shop/account.order.order_success.order_success') }}</h3>
<div class="order-info">
<table class="table table-borderless">
<tbody>
<tr>
<td>{{ __('shop/account.order.order_success.order_number') }}<span class="fw-bold">{{ $order['number'] }}</span></td>
<td>{{ __('shop/account.order.order_success.amounts_payable') }}<span class="fw-bold">{{ currency_format($order['total']) }}</span></td>
</tr>
<tr>
<td>{{ __('shop/account.order.order_success.payment_method') }}<span class="fw-bold">{{ $order['payment_method_name'] }}</span></td>
@if (current_customer())
<td><a href="{{ shop_route('account.order.show', ['number' => $order->number]) }}">{{ __('shop/account.order.order_success.view_order') }}</a></td>
@endif
</tr>
<tr>
<td><a href="{{ shop_route('orders.pay', [$order['number']]) }}" class="btn btn-primary">{{ __('shop/account.order.order_success.pay_now') }}</a></td>
</tr>
</tbody>
</table>
</div>
<div class="text-muted mt-4">{{ __('shop/account.order.order_success.kind_tips') }}</div>
<div class="mt-3">{{ __('shop/account.order.order_success.also') }}<a href="/">{{ __('shop/account.order.order_success.continue_purchase') }}</a></div>
</div>
</div>
<div class="order-bottom">
<div class="text-muted">{{ __('shop/account.order.order_success.contact_customer_service') }}</div>
<div>{{ __('shop/account.order.order_success.emaill') }}: {{ system_setting('base.email', '') }}</div>
<div>{{ __('shop/account.order.order_success.service_hotline') }}: {{ system_setting('base.telephone', '') }}</div>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script></script>
@endpush

View File

@ -0,0 +1,49 @@
@extends('layout.master')
@section('content')
<div class="container">
<h1>Register</h1>
<form action="{{ route('shop.register.store') }}" method="post">
@csrf
@hookwrapper('account.register.email')
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="email">邮箱</span>
</div>
<input type="text" name="register[email]" class="form-control" value="{{ old('register.email') }}"
placeholder="邮箱地址">
</div>
@error('register.email')
<x-admin::form.error :message="$message"/>
@enderror
</div>
@endhookwrapper
@hookwrapper('account.register.password')
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="password">密码</span>
</div>
<input type="password" name="register[password]" class="form-control" placeholder="密码">
</div>
@error('register.password')
<x-admin::form.error :message="$message"/>
@enderror
</div>
@endhookwrapper
@hook('account.register.email.after')
@if (session('error'))
<div class="alert alert-success">
{{ session('error') }}
</div>
@endif
<button type="submit" class="btn btn-primary btn-block mb-4">登录</button>
</form>
</div>
@endsection

View File

@ -0,0 +1,113 @@
@extends('layout.master')
@section('body-class', 'page-account-rmas')
@push('header')
{{-- <script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script> --}}
@endpush
@section('content')
<div class="container" id="address-app">
<x-shop-breadcrumb type="static" value="account.rma.index" />
{{-- <nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">Library</li>
</ol>
</nav> --}}
<div class="row">
<x-shop-sidebar/>
<div class="col-12 col-md-9">
<div class="card h-min-600">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.rma.rma_form.index') }}</h5>
</div>
<div class="card-body h-min-600">
<div class="bg-light rounded-3 p-3 mb-4" style="background: #f6f9fc;">
<div class="d-flex align-items-center">
<div class="left wh-70">
<img src="{{ $orderProduct->image }}" class="img-fluid">
</div>
<div class="right ms-3">
<div class="name mb-2 fw-bold fs-5">{{ $orderProduct->name }}</div>
<div class="price">{{ $orderProduct->price }} x {{ $orderProduct->quantity }}</div>
</div>
</div>
</div>
<form action="{{ shop_route('account.rma.store') }}" method="POST">
@csrf
{{-- {{ method_field('put') }} --}}
@if (session('success'))
<x-shop-alert type="success" msg="{{ session('success') }}" class="mt-4"/>
@endif
<input type="hidden" name="order_product_id" value="{{ $orderProduct->id }}">
<div class="row">
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.service_type') }}</label>
<select class="form-select" name="type">
@foreach ($types as $key => $item)
<option value="{{ $key }}" {{ $key == old('type', '') ? 'selected': '' }}>{{ $item }}</option>
@endforeach
</select>
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.return_quantity') }}</label>
<input class="form-control {{ $errors->has('quantity') ? 'is-invalid' : '' }}" type="text" name="quantity" value="{{ old('quantity', $orderProduct->quantity ?? '1') }}">
@if ($errors->has('quantity'))
<span class="invalid-feedback" role="alert">{{ $errors->first('quantity') }}</span>
@endif
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.unpacked') }}</label>
<select class="form-select" name="opened">
<option selected value="0">{{ __('common.no') }}</option>
<option value="1">{{ __('common.yes') }}</option>
</select>
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.return_reason') }}</label>
<select class="form-select {{ $errors->has('rma_reason_id') ? 'is-invalid' : '' }}" name="rma_reason_id">
@foreach ($reasons as $item)
<option value="{{ $item['id'] }}" {{ $item['id'] == old('opened', '') ? 'selected': '' }}>{{ $item['name'] }}</option>
@endforeach
</select>
@if ($errors->has('rma_reason_id'))
<span class="invalid-feedback" role="alert">{{ $errors->first('rma_reason_id') }}</span>
@endif
</div>
<div class="col-12 "></div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.remark') }}</label>
<textarea rows="4" type="text" name="comment" class="form-control">{{ old('comment', '') }}</textarea>
</div>
<div class="col-12 mt-4">
<button class="btn btn-primary mt-sm-0" type="submit">{{ __('shop/common.submit') }}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
@endpush

View File

@ -0,0 +1,59 @@
@extends('layout.master')
@section('body-class', 'page-account-rmas')
@section('content')
<div class="container">
<x-shop-breadcrumb type="static" value="account.rma.index" />
<div class="row">
<x-shop-sidebar />
<div class="col-12 col-md-9">
<div class="card mb-4 account-card order-wrap h-min-600">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.rma.index') }}</h5>
</div>
<div class="card-body">
<table class="table ">
<thead>
<tr>
<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>
<td colspan="6" class="border-0">
<x-shop-no-data />
</td>
</tr>
@endif
</tbody>
</table>
{{-- {{ $rmas->links('shared/pagination/bootstrap-4') }} --}}
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,96 @@
@extends('layout.master')
@section('body-class', 'page-account-rmas')
@push('header')
{{-- <script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script> --}}
@endpush
@section('content')
<div class="container" id="address-app">
<x-shop-breadcrumb type="rma" value="{{ $rma->id }}" />
<div class="row">
<x-shop-sidebar />
<div class="col-12 col-md-9">
<div class="card h-min-600">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.rma.rma_info.index') }}</h5>
</div>
<div class="card-body h-600">
<div class="bg-light rounded-3 p-3 mb-4" style="background: #f6f9fc;">
<div class="d-flex align-items-center">
<div class="left wh-70">
<img src="{{ $orderProduct->image }}" class="img-fluid">
</div>
<div class="right ms-3">
<div class="name mb-2 fw-bold fs-5">{{ $orderProduct->name }}</div>
<div class="price">{{ $orderProduct->price }} x {{ $orderProduct->quantity }}</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.service_type') }}</label>
@foreach ($types as $key => $item)
@if ($key == $rma->type)
<div>{{ $item}}</div>
@endif
@endforeach
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.return_quantity') }}</label>
<div>{{ $rma->quantity }}</div>
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('common.status') }}</label>
<div>{{ $rma->status }}</div>
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.unpacked') }}</label>
<div>
@if ($rma->opened)
{{ __('common.yes') }}
@else
{{ __('common.no') }}
@endif
</div>
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.creation_time') }}</label>
<div>
{{ $rma->created_at }}
</div>
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.return_reason') }}</label>
<div>
@foreach ($reasons as $item)
@if ($rma->rma_reason_id == $item['id'])
{{$item['name']}}
@endif
@endforeach
</div>
</div>
<div class="col-sm-6 mb-4">
<label class="form-label">{{ __('shop/account.rma.rma_form.remark') }}</label>
<div>{{$rma->comment}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
@endpush

View File

@ -0,0 +1,80 @@
@extends('layout.master')
@section('body-class', 'page-account-wishlist')
@section('content')
<div class="container">
<x-shop-breadcrumb type="static" value="account.wishlist.index" />
<div class="row">
<x-shop-sidebar />
<div class="col-12 col-md-9">
<div class="card mb-4 h-min-600">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('shop/account.wishlist.index') }}</h5>
</div>
<div class="card-body">
<table class="table align-middle">
<thead>
<tr>
<th width="90px"></th>
<th>{{ __('shop/account.wishlist.product') }}</th>
<th>{{ __('shop/account.wishlist.price') }}</th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@if (count($wishlist))
@foreach ($wishlist as $item)
<tr data-id="{{ $item['id'] }}">
<td>
<div class="wh-70 border d-flex justify-content-between align-items-center"><img src="{{ $item['image'] }}" class="img-fluid"></div>
</td>
<td>{{ $item['product_name'] }}</td>
<td>{{ $item['price'] }}</td>
<td class="text-end">
<div class="">
<a class="btn btn-dark btn-sm add-cart"
href="{{ shop_route('products.show', $item['product_id']) }}">{{ __('shop/account.wishlist.check_details') }}</a>
<button class="btn btn-danger btn-sm remove-wishlist"><i class="bi bi-x-lg"></i></button>
</div>
</td>
</tr>
@endforeach
@else
<tr>
<td colspan="4" class="border-0">
<x-shop-no-data />
</td>
</tr>
@endif
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script>
$(document).ready(function() {
$('.remove-wishlist').click(function() {
const product_id = $(this).closest('tr').data('id');
$http.delete('account/wishlist/' + product_id).then((res) => {
if (res.status == 'success') {
$(this).closest('tr').fadeOut(function() {
$(this).remove();
if ($('.remove-wishlist').length == 0) {
location.reload();
}
});
}
})
});
});
</script>
@endpush

View File

@ -0,0 +1,20 @@
@extends('layout.master')
@section('body-class', 'page-categories')
@section('title', $brand->name)
@section('content')
<div class="container">
<x-shop-breadcrumb type="brand" :value="$brand" />
<div class="row">
@foreach ($products_format as $product)
<div class="col-6 col-md-3">@include('shared.product')</div>
@endforeach
</div>
{{ $products->links('shared/pagination/bootstrap-4') }}
</div>
@endsection

View File

@ -0,0 +1,41 @@
@extends('layout.master')
@section('body-class', 'page-brands')
@section('content')
<div class="container">
<x-shop-breadcrumb type="static" value="brands.index" />
<p class="fw-bold fs-3 d-flex justify-content-center mb-4">{{ __('shop/brands.index') }}</p>
<ul class="list-group list-group-horizontal mb-5 curser-list">
@foreach ($brands as $brand)
<li class="list-group-item p-0 flex-grow-1">
<a href="brands#{{ $brand['0']['first'] }}" class="py-2 px-3 text-center fw-bold d-block">{{ $brand['0']['first'] }}</a>
</li>
@endforeach
</ul>
<ul class="brand-list ps-0">
@foreach ($brands as $brand)
<li class="d-flex border-top py-3">
<p class="px-2 fs-5 mt-4 fw-bold py-5" id="{{ $brand['0']['first'] }}">{{ $brand['0']['first'] }}</p>
<div class="container">
<div class="row">
@foreach ($brand as $item)
<div class="text-center col-6 col-md-4 col-lg-2 mt-2">
<a href="{{ type_route('brand', $item['id']) }}">
<div class="brand-item">
<img src="{{ $item['logo'] }}" class="img-fluid" alt="{{ $item['name'] }}">
</div>
<p class="mb-0 mt-1 ">{{ $item['name'] }}</p>
</a>
</div>
@endforeach
</div>
</div>
</li>
@endforeach
</ul>
</div>
@endsection

View File

@ -0,0 +1,202 @@
@extends('layout.master')
@section('body-class', 'page-cart')
@push('header')
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
<script src="{{ asset('vendor/scrolltofixed/jquery-scrolltofixed-min.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
@endpush
@section('content')
<div class="container" id="app-cart" v-cloak>
<x-shop-breadcrumb type="static" value="carts.index" />
<div class="row mt-1 justify-content-center mb-2">
<div class="col-12 col-md-9">@include('shared.steps', ['steps' => 1])</div>
</div>
@if ($errors->has('error'))
<x-shop-alert type="danger" msg="{{ $errors->first('error') }}" class="mt-4" />
@endif
<div class="row mt-5" v-if="products.length">
<div class="col-12 col-md-9 left-column">
<div class="card shadow-sm">
<div class="card-body p-lg-4">
<div class="p-lg-0"><h4 class="mb-3">{{ __('shop/carts.commodity') }}</h4></div>
<div class="cart-products-wrap table-responsive">
<table class="table">
<thead>
<tr>
<th width="130">
<input class="form-check-input" type="checkbox" value="" id="check-all" v-model="allSelected">
<label class="form-check-label ms-1" for="check-all">
{{ __('shop/carts.select_all') }}
</label>
</th>
<th width="40%">{{ __('shop/carts.index') }}</th>
<th width="170">{{ __('shop/carts.commodity') }}</th>
<th width="170">{{ __('shop/carts.subtotal') }}</th>
<th width="100" class="text-end">{{ __('common.action') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="product, index in products" :key="index" :class="product.selected ? 'active' : ''">
<td>
<div class="d-flex align-items-center p-image">
<input class="form-check-input" type="checkbox" @change="checkedCartTr(index)" v-model="product.selected">
<div class="border d-flex align-items-center justify-content-between wh-80 ms-3"><img :src="product.image" class="img-fluid"></div>
</div>
</td>
<td>
<div class="name text-truncate-2 mb-1 fw-bold" v-text="product.name"></div>
<div class="text-size-min text-muted mb-1">@{{ product.variant_labels }}</div>
<div class="price text-muted">@{{ product.price_format }}</div>
</td>
<td>
<div class="quantity-wrap">
<input type="text" class="form-control" @input="quantityChange(product.quantity, product.cart_id, product.sku_id)" onkeyup="this.value=this.value.replace(/\D/g,'')" v-model.number="product.quantity" name="quantity" minimum="1">
<div class="right">
<i class="bi bi-chevron-up"></i>
<i class="bi bi-chevron-down"></i>
</div>
</div>
</td>
<td>@{{ product.subtotal_format }}</td>
<td class="text-end">
<button type="button" class="btn text-danger btn-sm px-0" @click.stop="checkedBtnDelete(product.cart_id)">
<i class="bi bi-x-lg"></i> {{ __('common.delete') }}
</button>
</td>
</tr>
</tbody>
</table>
</div>
@hook('carts.products.after')
</div>
</div>
</div>
<div class="col-12 col-md-3 right-column">
<div class="card shadow-sm x-fixed-top">
<div class="card-body p-lg-4">
<div class="card total-wrap">
<div class="p-lg-0"><h4 class="mb-3">{{ __('shop/carts.product_total') }}</h4></div>
<div class="card-body p-lg-0">
<ul class="list-group list-group-flush">
<li class="list-group-item"><span>{{ __('shop/carts.all') }}</span><span>@{{ allProduct }}</span></li>
<li class="list-group-item"><span>{{ __('shop/carts.selected') }}</span><span>@{{ total_quantity }}</span></li>
<li class="list-group-item border-bottom-0"><span>{{ __('shop/carts.product_total') }}</span><span class="total-price">@{{ amount_format }}</span></li>
<li class="list-group-item d-grid gap-2 mt-3 border-bottom-0">
<button type="button" class="btn btn-primary fs-5 fw-bold" @click="checkedBtnToCheckout">{{ __('shop/carts.to_checkout') }}</button>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-else class="d-flex justify-content-center align-items-center flex-column">
<div class="empty-cart-wrap text-center mt-5">
<div class="empty-cart-icon mb-3">
<i class="bi bi-cart fs-1"></i>
</div>
<div class="empty-cart-text mb-3">
<h5>{{ __('shop/carts.cart_empty') }}</h5>
<p class="text-muted">{{ __('shop/carts.go_buy') }}</p>
</div>
<div class="empty-cart-action">
<a href="{{ shop_route('home.index') }}" class="btn btn-primary">{{ __('shop/carts.go_shopping') }}</a>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script>
var app = new Vue({
el: "#app-cart",
data: {
products: @json($data['carts']),
total_quantity: @json($data['quantity']),
amount: @json($data['amount']),
amount_format: @json($data['amount_format']),
},
// components: {},
// 计算属性
computed: {
allSelected: {
get() {
return !this.products.length ? false : this.products.every(s => s.selected)
},
set(val) {
// return
this.products.map(e => e.selected = val)
this.selectedBtnSelected()
}
},
allProduct() {
return this.products.map(e => e.quantity).reduce((n,m) => n + m);
},
},
// 侦听器
watch: {},
// 组件方法
methods: {
checkedBtnToCheckout() {
if (!this.products.some(e => e.selected)) {
layer.msg('{{ __('shop/carts.empty_selected_products') }}', ()=>{})
return
}
location = '{{ shop_route("checkout.index") }}'
},
quantityChange(quantity, cart_id, sku_id) {
const self = this;
$http.put(`/carts/${cart_id}`, {quantity: quantity, sku_id}, {hload: true}).then((res) => {
this.setUpdateData(res);
})
},
checkedBtnDelete(cart_id) {
const self = this;
$http.delete(`/carts/${cart_id}`).then((res) => {
this.setUpdateData(res);
})
},
checkedCartTr(index) {
// this.products[index].selected = !this.products[index].selected;
this.selectedBtnSelected();
},
selectedBtnSelected() {
const self = this;
const cart_ids = this.products.filter(e => e.selected).map(x => x.cart_id)
$http.post(`/carts/select`, {cart_ids: cart_ids}, {hload: true}).then((res) => {
this.setUpdateData(res);
})
},
setUpdateData(res) {
this.products = res.data.carts
this.amount_format = res.data.amount_format
this.total_quantity = res.data.quantity
bk.getCarts()
}
},
// 实例被挂载后调用
mounted () {
},
})
</script>
@endpush

View File

@ -0,0 +1,70 @@
<div class="offcanvas-header">
<h5 id="offcanvasRightLabel" class="mx-auto mb-0">{{ __('shop/carts.mini') }}</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body pt-0">
@php $check = 0 @endphp
@if ($carts)
<div class="offcanvas-right-products">
@foreach ($carts as $cart)
@if ($cart['selected']) @php $check = $check + 1 @endphp @endif
<div class="product-list d-flex align-items-center">
<div class="select-wrap">
<i class="bi {{ $cart['selected'] ? 'bi-check-circle-fill' : 'bi-circle' }}" data-id="{{ $cart['cart_id'] }}"></i>
</div>
<div class="product-info d-flex align-items-center">
<div class="left"><a href="{{ shop_route('products.show', $cart['product_id']) }}" class="d-flex justify-content-between align-items-center h-100"><img src="{{ $cart['image'] }}" class="img-fluid"></a></div>
<div class="right flex-grow-1">
<a href="{{ shop_route('products.show', $cart['product_id']) }}" class="name fs-sm fw-bold mb-2 text-dark text-truncate-2" title="{{ $cart['name'] }}">{{ $cart['name'] }}</a>
<div class="text-muted mb-1 text-size-min">{{ $cart['variant_labels'] }}</div>
<div class="product-bottom d-flex justify-content-between align-items-center">
<div class="price d-flex align-items-center">
{{ $cart['price_format'] }} x
<input type="text" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
data-id="{{ $cart['cart_id'] }}" data-sku="{{ $cart['sku_id'] }}" class="form-control p-1" value="{{ $cart['quantity'] }}">
</div>
<span class="offcanvas-products-delete" data-id="{{ $cart['cart_id'] }}"><i class="bi bi-x-lg"></i>
{{ __('common.delete') }}</span>
</div>
</div>
</div>
</div>
@endforeach
</div>
@else
<div class="d-flex justify-content-center align-items-center flex-column">
<div class="empty-cart-wrap text-center mt-5">
<div class="empty-cart-icon mb-3">
<i class="bi bi-cart fs-1"></i>
</div>
<div class="empty-cart-text mb-3">
<h5>{{ __('shop/carts.cart_empty') }}</h5>
<p class="text-muted">{{ __('shop/carts.go_buy') }}</p>
</div>
<div class="empty-cart-action">
<a href="{{ shop_route('home.index') }}" class="btn btn-primary">{{ __('shop/carts.go_shopping') }}</a>
</div>
</div>
</div>
@endif
</div>
@if ($carts)
<div class="offcanvas-footer">
<div class="d-flex justify-content-between align-items-center mb-2 p-3 bg-light top-footer">
<div class="select-wrap all-select d-flex align-items-center">
<i class="bi {{ $check == count($carts) ? 'bi-check-circle-fill' : 'bi-circle' }}"></i>
<span class="ms-1 text-secondary">{{ __('common.select_all') }}</span>
</div>
<div>
<span class="text-secondary">{{ __('shop/carts.product_total') }}</span><strong><span class="offcanvas-right-cart-count">{{ $quantity }}</span></strong>
<strong class="ms-auto offcanvas-right-cart-amount">{{ $amount_format }}</strong>
</div>
</div>
<div class="p-4">
<a href="{{ shop_route('checkout.index') }}" class="btn w-100 fw-bold btn-dark to-checkout {{ !$check ? 'disabled' : '' }}">{{ __('shop/carts.to_checkout') }}</a>
<a href="{{ shop_route('carts.index') }}" class="btn w-100 fw-bold btn-outline-dark mt-2">{{ __('shop/carts.check_cart') }}</a>
</div>
</div>
@endif

View File

@ -0,0 +1,152 @@
@extends('layout.master')
@section('body-class', 'page-categories')
@section('title', $category->description->meta_title ?: system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 - BeikeShop官网') .' - '. $category->description->name)
@section('keywords', $category->description->meta_keywords ?: system_setting('base.meta_keyword'))
@section('description', $category->description->meta_description ?: system_setting('base.meta_description'))
@push('header')
<script src="{{ asset('vendor/scrolltofixed/jquery-scrolltofixed-min.js') }}"></script>
@endpush
@section('content')
<div class="container">
<x-shop-breadcrumb type="category" :value="$category" />
<div class="row">
<div class="col-12 col-lg-3 pe-lg-4 left-column d-none d-lg-block">
<div class="x-fixed-top">@include('shared.filter_sidebar_block')</div>
</div>
<div class="col-12 col-lg-9 right-column">
<div class="filter-value-wrap mb-2 d-none">
<ul class="list-group list-group-horizontal">
@foreach ($filter_data['attr'] as $index => $attr)
@foreach ($attr['values'] as $value_index => $value)
@if ($value['selected'])
<li class="list-group-item me-1 mb-1" data-attr="{{ $index }}" data-attrval="{{ $value_index }}">
{{ $attr['name'] }}: {{ $value['name'] }} <i class="bi bi-x-lg ms-1"></i>
</li>
@endif
@endforeach
@endforeach
<li class="list-group-item me-1 mb-1 delete-all">{{ __('common.delete_all') }}</li>
</ul>
</div>
@if (count($products_format))
@include('shared.filter_bar_block')
@if ($children)
<div class="children-wrap me-2 mb-3 mt-n3">
<span class="text-secondary">{{ __('category.children') }}</span>
@foreach ($children as $item)
<a href="{{ $item['url'] }}">{{ $item['name'] }}</a>
@endforeach
</div>
@endif
<div class="row {{ request('style_list') == 'list' ? 'product-list-wrap' : ''}}">
@foreach ($products_format as $product)
<div class="{{ !request('style_list') || request('style_list') == 'grid' ? 'col-6 col-md-4' : 'col-12'}}">
@include('shared.product')
</div>
@endforeach
</div>
@else
<x-shop-no-data />
@endif
{{ $products->links('shared/pagination/bootstrap-4') }}
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script>
let filterAttr = @json($filter_data['attr'] ?? []);
$('.filter-value-wrap li').click(function(event) {
let [attr, val] = [$(this).data('attr'),$(this).data('attrval')];
if ($(this).hasClass('delete-all')) {
return deleteFilterAll();
}
filterAttr[attr].values[val].selected = false;
filterProductData();
});
if ($('.filter-value-wrap li').length > 1) {
$('.filter-value-wrap').removeClass('d-none')
}
$('.child-category').each(function(index, el) {
if ($(this).hasClass('active')) {
$(this).parent('ul').addClass('show').siblings('button').removeClass('collapsed')
$(this).parents('li').addClass('active')
}
});
$('.attr-value-check').change(function(event) {
let [attr, val] = [$(this).data('attr'),$(this).data('attrval')];
filterAttr[attr].values[val].selected = $(this).is(":checked");
filterProductData();
});
$('.form-select, input[name="style_list"]').change(function(event) {
filterProductData();
});
function filterProductData() {
let url = bk.removeURLParameters(window.location.href, 'attr', 'price', 'sort', 'order');
let [psMin, psMax, pMin, pMax] = [$('.price-select-min').val(), $('.price-select-max').val(), $('.price-min').val(), $('.price-max').val()];
let order = $('.order-select').val();
let perpage = $('.perpage-select').val();
let styleList = $('input[name="style_list"]:checked').val();
layer.load(2, {shade: [0.3,'#fff'] })
if (filterAttrChecked(filterAttr)) {
url = bk.updateQueryStringParameter(url, 'attr', filterAttrChecked(filterAttr));
}
if ((psMin != pMin) || (psMax != pMax)) {
url = bk.updateQueryStringParameter(url, 'price', `${psMin}-${psMax}`);
}
if (order) {
let orderKeys = order.split('|');
url = bk.updateQueryStringParameter(url, 'sort', orderKeys[0]);
url = bk.updateQueryStringParameter(url, 'order', orderKeys[1]);
}
if (perpage) {
url = bk.updateQueryStringParameter(url, 'per_page', perpage);
}
if (styleList) {
url = bk.updateQueryStringParameter(url, 'style_list', styleList);
}
location = url;
}
function filterAttrChecked(data) {
let filterAtKey = [];
data.forEach((item) => {
let checkedAtValues = [];
item.values.forEach((val) => val.selected ? checkedAtValues.push(val.id) : '')
if (checkedAtValues.length) {
filterAtKey.push(`${item.id}:${checkedAtValues.join('/')}`)
}
})
return filterAtKey.join('|')
}
function deleteFilterAll() {
let url = bk.removeURLParameters(window.location.href, 'attr', 'price');
location = url;
}
</script>
@endpush

View File

@ -0,0 +1,162 @@
@extends('layout.master')
@section('body-class', 'page-checkout')
@push('header')
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
<script src="{{ asset('vendor/scrolltofixed/jquery-scrolltofixed-min.js') }}"></script>
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
@endpush
@section('content')
<div class="container">
<x-shop-breadcrumb type="static" value="checkout.index" />
<div class="row mt-1 justify-content-center">
<div class="col-12 col-md-9">@include('shared.steps', ['steps' => 2])</div>
</div>
<div class="row mt-5">
<div class="col-12 col-md-8 left-column">
<div class="card shadow-sm">
<div class="card-body p-lg-4">
@include('checkout._address')
<div class="checkout-black">
<h5 class="checkout-title">{{ __('shop/checkout.payment_method') }}</h5>
<div class="radio-line-wrap">
@foreach ($payment_methods as $payment)
<div class="radio-line-item {{ $payment['code'] == $current['payment_method_code'] ? 'active' : '' }}" data-key="payment_method_code" data-value="{{ $payment['code'] }}">
<div class="left">
<span class="radio"></span>
<img src="{{ $payment['icon'] }}" class="img-fluid">
</div>
<div class="right ms-2">
<div class="title">{{ $payment['name'] }}</div>
<div class="sub-title">{!! $payment['description'] !!}</div>
</div>
</div>
@endforeach
</div>
</div>
<div class="checkout-black">
<h5 class="checkout-title">{{ __('shop/checkout.delivery_method') }}</h5>
<div class="radio-line-wrap">
@foreach ($shipping_methods as $methods)
@foreach ($methods['quotes'] as $shipping)
<div class="radio-line-item {{ $shipping['code'] == $current['shipping_method_code'] ? 'active':'' }}" data-key="shipping_method_code" data-value="{{ $shipping['code'] }}">
<div class="left">
<span class="radio"></span>
<img src="{{ $shipping['icon'] }}" class="img-fluid">
</div>
<div class="right ms-2">
<div class="title">{{ $shipping['name'] }}</div>
<div class="sub-title">{!! $shipping['description'] !!}</div>
<div class="mt-2">{!! $shipping['html'] ?? '' !!}</div>
</div>
</div>
@endforeach
@endforeach
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-4 right-column">
<div class="x-fixed-top">
@if (!current_customer())
<div class="card total-wrap mb-4 p-lg-4 shadow-sm">
<div class="card-header">
<h5 class="mb-0">{{ __('shop/login.login_and_sign') }}</h5>
</div>
<div class="card-body">
<button class="btn btn-outline-dark guest-checkout-login"><i class="bi bi-box-arrow-in-right me-2"></i>{{ __('shop/login.login_and_sign') }}</button>
</div>
</div>
@endif
<div class="card total-wrap p-lg-4 shadow-sm">
<div class="card-header d-flex align-items-center justify-content-between">
<h5 class="mb-0">{{ __('shop/checkout.cart_totals') }}</h5>
<span class="rounded-circle bg-primary">{{ $carts['quantity'] }}</span>
</div>
<div class="card-body">
<div class="products-wrap">
@foreach ($carts['carts'] as $cart)
<div class="item">
<div class="image">
<img src="{{ $cart['image'] }}" class="img-fluid">
<div class="name">
<div title="{{ $cart['name'] }}" class="text-truncate-2">{{ $cart['name'] }}</div>
@if ($cart['variant_labels'])
<div class="text-muted mt-1">{{ $cart['variant_labels'] }}</div>
@endif
</div>
</div>
<div class="price text-end">
<div>{{ $cart['price_format'] }}</div>
<div class="quantity">x {{ $cart['quantity'] }}</div>
</div>
</div>
@endforeach
</div>
<ul class="totals">
@foreach ($totals as $total)
<li><span>{{ $total['title'] }}</span><span>{{ $total['amount_format'] }}</span></li>
@endforeach
</ul>
<div class="d-grid gap-2 mt-3">
<button class="btn btn-primary fw-bold fs-5" type="button" id="submit-checkout">{{ __('shop/checkout.submit_order') }}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('add-scripts')
<script>
$(document).ready(function() {
$('.radio-line-item').click(function(event) {
const key = $(this).data('key');
const value = $(this).data('value');
let html = '';
$http.put('/checkout', {[key]: value}).then((res) => {
$(this).addClass('active').siblings().removeClass('active')
res.totals.forEach((item) => {
html += `<li><span>${item.title}</span><span>${item.amount_format}</span></li>`
})
$('ul.totals').html(html);
})
});
$('#submit-checkout').click(function(event) {
if (!config.isLogin && checkoutAddressApp.source.guest_shipping_address === null) {
layer.msg('{{ __('shop/checkout.error_payment_address') }}', ()=>{})
return;
}
if (config.isLogin && !checkoutAddressApp.form.payment_address_id) {
layer.msg('{{ __('shop/checkout.error_payment_address') }}', ()=>{})
return;
}
$http.post('/checkout/confirm').then((res) => {
location = 'orders/' + res.number + '/success?type=create'
})
});
$('.guest-checkout-login').click(function(event) {
bk.openLogin();
});
});
</script>
@endpush

View File

@ -0,0 +1,289 @@
<div id="checkout-address-app" v-cloak>
<div class="checkout-black">
<div class="checkout-title">
<div class="d-flex">
<h5 class="mb-0 me-4">{{ __('shop/checkout.address') }}</h5>
<el-checkbox v-model="same_as_shipping_address" v-if="source.addresses.length || source.guest_shipping_address">{{ __('shop/checkout.same_as_shipping_address') }}
</el-checkbox>
</div>
<button class="btn btn-sm icon" v-if="isAllAddress" @click="isAllAddress = false"><i
class="bi bi-x-lg"></i></button>
</div>
<div class="addresses-wrap">
<div class="row">
<template v-if="source.isLogin">
<div class="col-6" v-for="address, index in source.addresses" :key="index"
v-if="source.addresses.length &&( address.id == form.shipping_address_id || isAllAddress)">
<div :class="['item', address.id == form.shipping_address_id ? 'active' : '']"
@click="updateCheckout(address.id, 'shipping_address_id')">
<div class="name-wrap">
<span class="name">@{{ address.name }}</span>
<span class="phone">@{{ address.phone }}</span>
</div>
<div class="zipcode">@{{ address.zipcode }}</div>
<div class="address-info">@{{ address.country }} @{{ address.zone }} @{{ address.city }}
@{{ address.address_1 }}</div>
<div class="address-bottom">
<div>
<span class="badge bg-success"
v-if="form.shipping_address_id == address.id">{{ __('shop/checkout.chosen') }}</span>
</div>
<a href="javascript:void(0)" class=""
@click.stop="editAddress(index, 'shipping_address_id')">{{ __('shop/checkout.edit') }}</a>
</div>
</div>
</div>
<div class="col-6" v-if="!isAllAddress">
<div class="item address-right">
<button class="btn btn-outline-dark w-100 mb-3" v-if="source.addresses.length > 1"
@click="isAllAddress = true">{{ __('shop/checkout.choose_another_address') }}</button>
<button class="btn btn-outline-dark w-100" @click="editAddress(null, 'shipping_address_id')"><i
class="bi bi-plus-square-dotted"></i> {{ __('shop/checkout.add_new_address') }}</button>
</div>
</div>
</template>
<template v-else>
<div class="col-6" v-if="source.guest_shipping_address">
<div class="item active">
<div class="name-wrap">
<span class="name">@{{ source.guest_shipping_address.name }}</span>
<span class="phone">@{{ source.guest_shipping_address.phone }}</span>
</div>
<div class="zipcode">
<span>@{{ source.guest_shipping_address.zipcode }}</span>
<span class="ms-1">@{{ source.guest_shipping_address.email }}</span>
</div>
<div class="address-info">@{{ source.guest_shipping_address.country }} @{{ source.guest_shipping_address.zone }} @{{ source.guest_shipping_address.city }}
@{{ source.guest_shipping_address.address_1 }}</div>
<div class="address-bottom">
<div>
<span class="badge bg-success">{{ __('shop/checkout.chosen') }}</span>
</div>
<a class="javascript:void(0)"
@click.stop="editAddress(null, 'guest_shipping_address')">{{ __('shop/checkout.edit') }}</a>
</div>
</div>
</div>
<div class="col-6" v-if="!source.guest_shipping_address">
<div class="item address-right">
<button class="btn btn-outline-dark w-100" @click="editAddress(null, 'guest_shipping_address')"><i
class="bi bi-plus-square-dotted"></i> {{ __('shop/checkout.add_new_address') }}</button>
</div>
</div>
</template>
</div>
</div>
</div>
<div class="checkout-black" v-if='!same_as_shipping_address'>
<div class="checkout-title">
<div class="d-flex">
<h5 class="mb-0 me-4">{{ __('shop/checkout.payment_address') }}</h5>
</div>
<button class="btn btn-sm icon" v-if="isAllAddressPayment" @click="isAllAddressPayment = false"><i
class="bi bi-x-lg"></i></button>
</div>
<div class="addresses-wrap">
<div class="row">
<template v-if="source.isLogin">
<div class="col-6" v-for="address, index in source.addresses" :key="index"
v-if="source.addresses.length && (form.payment_address_id == '' || address.id == form.payment_address_id || isAllAddressPayment)">
<div :class="['item', address.id == form.payment_address_id ? 'active' : '']"
@click="updateCheckout(address.id, 'payment_address_id')">
<div class="name-wrap">
<span class="name">@{{ address.name }}</span>
<span class="phone">@{{ address.phone }}</span>
</div>
<div class="zipcode">@{{ address.zipcode }}</div>
<div class="address-info">@{{ address.country }} @{{ address.zone }} @{{ address.city }}
@{{ address.address_1 }}</div>
<div class="address-bottom">
<div>
<span class="badge bg-success"
v-if="form.payment_address_id == address.id">{{ __('shop/checkout.chosen') }}</span>
</div>
<a class="javascript:void(0)"
@click.stop="editAddress(index, 'payment_address_id')">{{ __('shop/checkout.edit') }}</a>
</div>
</div>
</div>
<div class="col-6" v-if="!isAllAddressPayment">
<div class="item address-right">
<button class="btn btn-outline-dark w-100 mb-3" v-if="source.addresses.length > 1"
@click="isAllAddressPayment = true">{{ __('shop/checkout.choose_another_address') }}</button>
<button class="btn btn-outline-dark w-100" @click="editAddress(null, 'payment_address_id')"><i
class="bi bi-plus-square-dotted"></i> {{ __('shop/checkout.add_new_address') }}</button>
</div>
</div>
</template>
<template v-else>
<div class="col-6" v-if="source.guest_payment_address">
<div class="item active">
<div class="name-wrap">
<span class="name">@{{ source.guest_payment_address.name }}</span>
<span class="phone">@{{ source.guest_payment_address.phone }}</span>
</div>
<div class="zipcode">@{{ source.guest_payment_address.zipcode }}</div>
<div class="address-info">@{{ source.guest_payment_address.country }} @{{ source.guest_payment_address.zone }} @{{ source.guest_payment_address.city }}
@{{ source.guest_payment_address.address_1 }}</div>
<div class="address-bottom">
<div>
<span class="badge bg-success">{{ __('shop/checkout.chosen') }}</span>
</div>
<a class="javascript:void(0)"
@click.stop="editAddress(null, 'guest_payment_address')">{{ __('shop/checkout.edit') }}</a>
</div>
</div>
</div>
<div class="col-6" v-if="!source.guest_payment_address">
<div class="item address-right">
<button class="btn btn-outline-dark w-100" @click="editAddress(null, 'guest_payment_address')"><i
class="bi bi-plus-square-dotted"></i> {{ __('shop/checkout.add_new_address') }}</button>
</div>
</div>
</template>
</div>
</div>
</div>
<address-dialog ref="address-dialog" @change="onAddressDialogChange"></address-dialog>
</div>
@push('add-scripts')
@include('shared.address-form')
<script>
var checkoutAddressApp = new Vue({
el: '#checkout-address-app',
data: {
form: {
shipping_address_id: @json($current['shipping_address_id']),
payment_address_id: @json($current['payment_address_id']),
},
isAllAddress: false,
isAllAddressPayment: false,
source: {
addresses: @json($addresses ?? []),
guest_shipping_address: @json($current['guest_shipping_address'] ?? null),
guest_payment_address: @json($current['guest_payment_address'] ?? null),
isLogin: config.isLogin,
},
dialogAddress: {
index: null,
type: 'shipping_address_id',
},
},
computed: {
same_as_shipping_address: {
get() {
if (!this.source.isLogin) {
return JSON.stringify(this.source.guest_shipping_address) === JSON.stringify(this.source.guest_payment_address);
}
return this.form.shipping_address_id === this.form.payment_address_id
},
set(e) {
if (e) {
if (!this.source.isLogin) {
$http.put('/checkout', {guest_payment_address: this.source.guest_shipping_address}).then((res) => {
this.source.guest_payment_address = res.current.guest_payment_address;
})
} else {
this.form.payment_address_id = this.form.shipping_address_id
this.updateCheckout(this.form.payment_address_id, 'same_as_shipping_address')
}
} else {
this.form.payment_address_id = '';
this.source.guest_payment_address = null
}
},
},
},
methods: {
editAddress(index, type) {
let addresses = null
if (typeof index == 'number') {
this.dialogAddress.index = index;
addresses = JSON.parse(JSON.stringify(this.source.addresses[index]))
}
// 游客结账
if ((type == 'guest_shipping_address' || type == 'guest_payment_address') && this.source[type]) {
addresses = JSON.parse(JSON.stringify(this.source[type]))
}
this.dialogAddress.type = type
this.$refs['address-dialog'].editAddress(addresses, this.dialogAddress.type)
},
onAddressDialogChange(form) {
const type = form.id ? 'put' : 'post';
const url = `/account/addresses${type == 'put' ? '/' + form.id : ''}`;
if (!this.source.isLogin) {
let data = {[this.dialogAddress.type]: form}
if (this.source.guest_payment_address === null && this.source.guest_shipping_address === null) {
data = {
guest_shipping_address: form,
guest_payment_address: form
}
}
$http.put('/checkout', data).then((res) => {
if (this.source.guest_payment_address === null && this.source.guest_shipping_address === null) {
this.source.guest_shipping_address = res.current.guest_shipping_address;
this.source.guest_payment_address = res.current.guest_payment_address;
} else {
this.source[this.dialogAddress.type] = res.current[this.dialogAddress.type];
}
this.$message.success('{{ __('common.edit_success') }}');
this.$refs['address-dialog'].closeAddressDialog()
})
} else {
$http[type](url, form).then((res) => {
this.$message.success(res.message);
if (this.source.addresses.find(e => e.id == res.data.id)) {
this.source.addresses[this.dialogAddress.index] = res.data
} else {
this.source.addresses.push(res.data)
this.updateCheckout(res.data.id, this.dialogAddress.type)
this.form[this.dialogAddress.type] = res.data.id
}
this.dialogAddress.index = null;
this.$forceUpdate()
this.$refs['address-dialog'].closeAddressDialog()
})
}
},
updateCheckout(id, key) {
if (this.form[key] === id && key != 'same_as_shipping_address') {
return
}
if (key == 'shipping_address_id' && this.same_as_shipping_address) {
this.form.payment_address_id = id
}
this.form[key] = id
$http.put('/checkout', this.form).then((res) => {
this.form = res.current
this.source.totals = res.totals
this.isAllAddress = false
this.isAllAddressPayment = false
})
},
}
})
</script>
@endpush

View File

@ -0,0 +1,41 @@
@extends('layout.master')
@section('body-class', 'page-payment')
@section('content')
<div class="container">
<div class="row mt-5 mb-5 justify-content-center">
<div class="col-12 col-md-9">@include('shared.steps', ['steps' => 4])</div>
</div>
<div class="col-12">
<div class="card order-wrap border">
<div class="card-body main-body">
<div class="order-top">
<div class="left">
<i class="bi bi-credit-card-2-back"></i>
</div>
<div class="right">
<h3 class="order-title">{{ __('shop/checkout.payment.please_pay') }}</h3>
<div class="order-info mb-4">
<table class="table table-borderless">
<tbody>
<tr>
<td>{{ __('shop/checkout.payment.order_number') }}<span class="fw-bold">{{ $order['number'] }}</span></td>
<td>{{ __('shop/checkout.payment.amounts_payable') }}<span class="fw-bold">{{ $order['total_format'] }}</span></td>
</tr>
<tr>
<td>{{ __('shop/checkout.payment.payment_method') }}<span class="fw-bold">{{ $order['payment_method_name'] }}</span></td>
</tr>
</tbody>
</table>
</div>
{!! $payment !!}
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,35 @@
<div class="col-12 col-md-3">
<div class="account-sides-info">
<div class="head">
<div class="portrait"><img src="{{ image_resize($customer->avatar, 200, 200) }}" class="img-fluid"></div>
<div class="account-name">{{ $customer->name }}</div>
<div class="account-email">{{ $customer->email }}</div>
</div>
<nav class="list-group account-links">
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.index') ? 'active' : '' }}"
href="{{ shop_route('account.index') }}">
<span>{{ __('shop/account.index') }}</span></a>
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.edit.index') ? 'active' : '' }}"
href="{{ shop_route('account.edit.index') }}">
<span>{{ __('shop/account.edit.index') }}</span></a>
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.order.index') || equal_route('shop.account.order.show') ? 'active' : '' }}"
href="{{ shop_route('account.order.index') }}">
<span>{{ __('shop/account.order.index') }}</span></a>
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.addresses.index') ? 'active' : '' }}"
href="{{ shop_route('account.addresses.index') }}">
<span>{{ __('shop/account.addresses.index') }}</span></a>
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.wishlist.index') ? 'active' : '' }}"
href="{{ shop_route('account.wishlist.index') }}">
<span>{{ __('shop/account.wishlist.index') }}</span></a>
<a class="list-group-item d-flex justify-content-between align-items-center {{ equal_route('shop.account.rma.index') || equal_route('shop.account.rma.show') ? 'active' : '' }}"
href="{{ shop_route('account.rma.index') }}">
<span>{{ __('shop/account.rma.index') }}</span></a>
@hook('account.sidebar.before.logout')
<a class="list-group-item d-flex justify-content-between align-items-center" href="{{ shop_route('logout') }}">
<span>{{ __('common.sign_out') }}</span></a>
</nav>
</div>
</div>

View File

@ -0,0 +1,5 @@
<div class="alert alert-{{ $type }} alert-dismissible">
<i class="bi bi-check-circle-fill"></i>
{{ $msg }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>

View File

@ -0,0 +1,15 @@
@unless ($breadcrumbs->isEmpty())
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
@foreach ($breadcrumbs as $breadcrumb)
@if (isset($breadcrumb['url']) && $breadcrumb['url'])
<li class="breadcrumb-item"><a href="{{ $breadcrumb['url'] }}">{{ $breadcrumb['title'] }}</a></li>
@else
<li class="breadcrumb-item active" aria-current="page">{{ $breadcrumb['title'] }}</li>
@endif
@endforeach
</ol>
</nav>
@endunless

View File

@ -0,0 +1,7 @@
<div class="d-flex flex-column align-center align-items-center mb-4">
<img src="{{ asset('image/no-data.svg') }}" class="img-fluid wp-400">
<div class="text-secondary fs-4 mb-3">{{ $text }}</div>
@if ($link)
<a href="{{ $link }}" class="btn btn-primary"><i class="bi bi-box-arrow-left"></i> {{ $btn }}</a>
@endif
</div>

View File

@ -0,0 +1,10 @@
@if ($design)
<div class="module-edit">
<div class="edit-wrap">
<div class="down" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{{ __('admin/builder.move_down') }}"><i class="bi bi-chevron-down"></i></div>
<div class="up" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{{ __('admin/builder.move_up') }}"><i class="bi bi-chevron-up"></i></div>
<div class="delete" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{{ __('common.delete') }}"><i class="bi bi-x-lg"></i></div>
<div class="edit" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{{ __('common.edit') }}"><i class="bi bi-pencil-square"></i></div>
</div>
</div>
@endif

View File

@ -0,0 +1,26 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-info module-brand mb-3 mb-md-5">
<div class="module-title">{{ $content['title'] }}</div>
<div class="container">
<div class="row">
@foreach ($content['brands'] as $brand)
<div class="col-6 col-md-4 col-lg-3">
<a href="{{ $brand['url'] }}" class="text-decoration-none">
<div class="brand-item">
<img src="{{ $brand['logo'] ?? asset('image/default/banner-1.png') }}" class="img-fluid">
</div>
<p class="text-center text-dark mb-4">{{ $brand['name'] }}</p>
</a>
</div>
@endforeach
</div>
</div>
@if ($content['brands'])
<div class="d-flex justify-content-center mt-4">
<a class="btn btn-outline-secondary btn-lg" href="{{ shop_route('brands.index') }}">{{ __('common.show_all') }}</a>
</div>
@endif
</div>
</section>

View File

@ -0,0 +1,28 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-info mb-3 mb-md-5">
@if ($content['title'])
<div class="module-title">{{ $content['title'] }}</div>
@endif
<div class="container">
<div class="row">
@foreach ($content['images'] as $image)
<div class="col-6 col-md-4 col-lg-2">
<a href="{{ $image['link'] ?: 'javascript:void(0)' }}" class="text-decoration-none">
<div class="image-item d-flex justify-content-center mb-3">
<img src="{{ $image['image'] }}" class="img-fluid">
</div>
@if ($image['text'])
<p class="text-center text-dark mb-2 mt-2 fs-5">{{ $image['text'] }}</p>
@endif
@if ($image['sub_text'])
<p class="text-center text-secondary my-2">{{ $image['sub_text'] }}</p>
@endif
</a>
</div>
@endforeach
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,9 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-image-banner module-info {{ !$content['full'] ? 'container' : '' }} mb-3 mb-md-5 d-flex justify-content-center">
<div class="container{{ $content['full'] ? '-fluid' : '' }} d-flex justify-content-center">
<a href="{{ $content['images'][0]['link']['link'] ?: 'javascript:void(0)' }}"><img src="{{ $content['images'][0]['image'] }}" class="img-fluid"></a>
</div>
</div>
</section>

View File

@ -0,0 +1,13 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-image-banner module-info mb-3 mb-md-5">
<div class="container">
<div class="row">
@foreach ($content['images'] as $item)
<div class="col-12 col-md-6 mb-2 mb-xl-0"><a href="{{ $item['link']['link'] ?: 'javascript:void(0)' }}"><img src="{{ $item['image'] }}" class="img-fluid"></a></div>
@endforeach
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,13 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-image-banner module-info mb-3 mb-md-5">
<div class="container">
<div class="row">
@foreach ($content['images'] as $item)
<div class="col-12 col-md-4"><a href="{{ $item['link']['link'] ?: 'javascript:void(0)' }}"><img src="{{ $item['image'] }}" class="img-fluid"></a></div>
@endforeach
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,20 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-image-plus module-info mb-3 mb-md-5">
<div class="container">
<div class="row">
<div class="col-md-6 col-12 mb-3 mb-md-0">
<a href="{{ $content['images'][0]['link']['link'] ?? '' }}"><img src="{{ $content['images'][0]['image'] }}" class="img-fluid"></a>
</div>
<div class="col-md-6 col-12">
<div class="module-image-plus-top">
<a href="{{ $content['images'][1]['link']['link'] ?? '' }}"><img src="{{ $content['images'][1]['image'] }}" class="img-fluid"></a>
<a href="{{ $content['images'][2]['link']['link'] ?? '' }}" class="right"><img src="{{ $content['images'][2]['image'] }}" class="img-fluid"></a>
</div>
<div class="module-image-plus-bottom"><a href="{{ $content['images'][3]['link']['link'] ?? '' }}"><img src="{{ $content['images'][3]['image'] }}" class="img-fluid"></a></div>
</div>
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,68 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-info module-product mb-3 mb-md-5 swiper-style-plus">
<div class="container position-relative">
<div class="module-title">{{ $content['title'] }}</div>
@if ($content['products'])
<div class="swiper module-product-{{ $module_id }} module-slideshow">
<div class="swiper-wrapper">
@foreach ($content['products'] as $product)
<div class="swiper-slide">
@include('shared.product')
</div>
@endforeach
</div>
</div>
<div class="swiper-pagination rectangle module-product-{{ $module_id }}-pagination"></div>
<div class="swiper-button-prev product-prev"></div>
<div class="swiper-button-next product-next"></div>
@elseif (!$content['products'] and $design)
<div class="row">
@for ($s = 0; $s < 4; $s++)
<div class="col-6 col-md-4 col-lg-3">
<div class="product-wrap">
<div class="image"><a href="javascript:void(0)"><img src="{{ asset('catalog/placeholder.png') }}" class="img-fluid"></a></div>
<div class="product-name">请配置商品</div>
<div class="product-price">
<span class="price-new">66.66</span>
<span class="price-lod">99.99</span>
</div>
</div>
</div>
@endfor
</div>
@endif
</div>
</div>
<script>
new Swiper ('.module-product-{{ $module_id }}', {
watchSlidesProgress: true,
breakpoints:{
320: {
slidesPerView: 2,
slidesPerGroup: 2,
spaceBetween: 10,
},
768: {
slidesPerView: 4,
slidesPerGroup: 4,
spaceBetween: 30,
},
},
spaceBetween: 30,
// 如果需要分页器
pagination: {
el: '.module-product-{{ $module_id }}-pagination',
clickable: true,
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.product-next',
prevEl: '.product-prev',
},
})
</script>
</section>

View File

@ -0,0 +1,7 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-info mb-3 mb-md-5">
{!! $content['data'] !!}
</div>
</section>

View File

@ -0,0 +1,47 @@
@push('header')
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
@endpush
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-info mb-3 mb-md-5 {{ !$content['full'] ? 'container' : '' }}">
<div class="swiper module-swiper-{{ $module_id }} module-slideshow">
<div class="swiper-wrapper">
@foreach($content['images'] as $image)
<div class="swiper-slide">
<a href="{{ $image['link']['link'] ?: 'javascript:void(0)' }}" class="d-flex justify-content-center"><img src="{{ $image['image'] }}" class="img-fluid"></a>
</div>
@endforeach
</div>
<div class="swiper-pagination slideshow-pagination-{{ $module_id }}"></div>
<div class="swiper-button-prev slideshow-btnprev-{{ $module_id }}"></div>
<div class="swiper-button-next slideshow-btnnext-{{ $module_id }}"></div>
</div>
</div>
<script>
new Swiper ('.module-swiper-{{ $module_id }}', {
loop: '{{ count($content['images']) > 1 ? true : false }}', // 循环模式选项
autoplay: true,
pauseOnMouseEnter: true,
clickable :true,
// 如果需要分页器
pagination: {
el: '.slideshow-pagination-{{ $module_id }}',
clickable :true
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.slideshow-btnnext-{{ $module_id }}',
prevEl: '.slideshow-btnprev-{{ $module_id }}',
},
})
</script>
</section>

View File

@ -0,0 +1,47 @@
<section class="module-item {{ $design ? 'module-item-design' : ''}}" id="module-{{ $module_id }}">
@include('design._partial._module_tool')
<div class="module-info module-tab-product">
<div class="module-title">{{ $content['title'] }}</div>
<div class="container">
@if ($content['tabs'])
<div class="nav justify-content-center mb-3">
@foreach ($content['tabs'] as $key => $tabs)
<a class="nav-link {{ $loop->first ? 'active' : '' }}" href="#tab-product-{{ $loop->index }}" data-bs-toggle="tab">{{ $tabs['title'] }}</a>
@endforeach
</div>
<div class="tab-content">
@foreach ($content['tabs'] as $products)
<div class="tab-pane fade show {{ $loop->first ? 'active' : '' }}" id="tab-product-{{ $loop->index }}">
<div class="row">
@if ($products['products'])
@foreach ($products['products'] as $product)
<div class="col-6 col-md-4 col-lg-3">
@include('shared.product')
</div>
@endforeach
@elseif (!$products['products'] and $design)
@for ($s = 0; $s < 8; $s++)
<div class="col-6 col-md-4 col-lg-3">
<div class="product-wrap">
<div class="image"><a href="javascript:void(0)"><img src="{{ asset('catalog/placeholder.png') }}" class="img-fluid"></a></div>
<div class="product-name">请配置商品</div>
<div class="product-price">
<span class="price-new">66.66</span>
<span class="price-lod">99.99</span>
</div>
</div>
</div>
@endfor
@endif
</div>
</div>
@endforeach
</div>
@endif
</div>
</div>
</section>

View File

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Unauthorized'))
@section('code', '401')
@section('message', __('Unauthorized'))

View File

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Forbidden'))
@section('code', '403')
@section('message', __($exception->getMessage() ?: 'Forbidden'))

View File

@ -0,0 +1,9 @@
@extends('errors.layout')
@section('title', __('common.error_page'))
@section('content')
<x-shop-no-data
text="{{ __('common.error_page') }}"
link="{{ request()->headers->get('referer') ? 'javascript:history.go(-1)' : '/' }}"
btn="{{ __('common.error_page_btn') }}" />
@endsection

View File

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Page Expired'))
@section('code', '419')
@section('message', __('Page Expired'))

View File

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Too Many Requests'))
@section('code', '429')
@section('message', __('Too Many Requests'))

View File

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Server Error'))
@section('code', '500')
@section('message', __('Server Error'))

View File

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Service Unavailable'))
@section('code', '503')
@section('message', __('Service Unavailable'))

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title')</title>
<link rel="stylesheet" type="text/css" href="{{ asset('/build/beike/shop/default/css/bootstrap.css') }}">
</head>
<body class="page-400">
<div class="flex-center position-ref full-height">
<div class="content">
<div class="title">
@yield('content')
</div>
</div>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,17 @@
@extends('layout.master')
@section('body-class', 'page-home')
@section('content')
<div class="modules-box">
@hook('footer.modules.before')
@foreach($modules as $module)
@include($module['view_path'], $module)
@endforeach
@hook('footer.modules.after')
</div>
@endsection

View File

@ -0,0 +1,102 @@
<footer>
@php
$locale = locale();
@endphp
@hook('footer.services.before')
@if ($footer_content['services']['enable'])
<div class="services-wrap">
<div class="container">
<div class="row">
@foreach ($footer_content['services']['items'] as $item)
<div class="col-lg-3 col-md-6 col-12">
<div class="service-item my-1">
<div class="icon"><img src="{{ image_resize($item['image'], 80, 80) }}" class="img-fluid"></div>
<div class="text">
<p class="title">{{ $item['title'][locale()] ?? '' }}</p>
<p class="sub-title">{{ $item['sub_title'][locale()] ?? '' }}</p>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
@endif
@hook('footer.services.after')
<div class="container">
<div class="footer-content">
<div class="row">
<div class="col-12 col-md-3">
<div class="footer-content-left">
<div class="logo"><a href="http://"><img
src="{{ image_origin($footer_content['content']['intro']['logo']) }}" class="img-fluid"></a></div>
<div class="text tinymce-format-p">{!! $footer_content['content']['intro']['text'][$locale] ?? '' !!}</div>
</div>
</div>
@for ($i = 1; $i <= 3; $i++)
@php
$link = $footer_content['content']['link' . $i];
@endphp
<div class="col-6 col-sm footer-content-link{{ $i }}">
<h6 class="text-uppercase text-dark mb-3">{{ $link['title'][$locale] ?? '' }}</h6>
<ul class="list-unstyled">
@foreach ($link['links'] as $item)
@if ($item['link'])
<li class="lh-lg mb-2">
<a href="{{ $item['link'] }}" @if (isset($item['new_window']) && $item['new_window']) target="_blank" @endif>
{{ $item['text'] }}
</a>
</li>
@endif
@endforeach
</ul>
</div>
@endfor
@hook('footer.contact.before')
@hookwrapper('footer.contact')
<div class="col-12 col-md-3 footer-content-contact">
<h6 class="text-uppercase text-dark mb-3">{{ __('common.contact_us') }}</h6>
<ul class="list-unstyled">
@if ($footer_content['content']['contact']['email'])
<li class="lh-lg mb-2"><i class="bi bi-envelope-fill"></i> {{ $footer_content['content']['contact']['email'] }}</li>
@endif
@if ($footer_content['content']['contact']['telephone'])
<li class="lh-lg mb-2"><i class="bi bi-telephone-fill"></i> {{ $footer_content['content']['contact']['telephone'] }}</li>
@endif
@if ($footer_content['content']['contact']['address'][$locale] ?? '')
<li class="lh-lg mb-2"><i class="bi bi-geo-alt-fill"></i> {{ $footer_content['content']['contact']['address'][$locale] ?? '' }}</li>
@endif
</ul>
</div>
@endhookwrapper
@hook('footer.contact.after')
</div>
</div>
</div>
@hookwrapper('footer.copyright')
<div class="footer-bottom">
<div class="container">
<div class="row align-items-center">
<div class="col">
<div class="d-flex">
Powered By
{!! $footer_content['bottom']['copyright'][$locale] ?? '' !!}
</div>
</div>
@if (isset($footer_content['bottom']['image']) && $footer_content['bottom']['image'])
<div class="col-auto right-img">
<img src="{{ image_origin($footer_content['bottom']['image']) }}" class="img-fluid">
</div>
@endif
</div>
</div>
</div>
@endhookwrapper
</footer>

View File

@ -0,0 +1,171 @@
<header>
<div class="top-wrap">
<div class="container d-flex justify-content-between align-items-center">
<div class="left d-flex align-items-center">
@hookwrapper('header.top.currency')
@if (currencies()->count() > 1)
<div class="dropdown">
<a class="btn dropdown-toggle ps-0" href="javascript:void(0)" role="button" id="currency-dropdown" data-toggle="dropdown"
aria-expanded="false">
@foreach (currencies() as $currency)
@if ($currency->code == current_currency_code())
@if ($currency->symbol_left)
{{ $currency->symbol_left }}
@endif
{{ $currency->name }}
@if ($currency->symbol_right)
{{ $currency->symbol_right }}
@endif
@endif
@endforeach
</a>
<div class="dropdown-menu" aria-labelledby="currency-dropdown">
@foreach (currencies() as $currency)
<a class="dropdown-item"
href="{{ shop_route('currency.switch', [$currency->code]) }}">
@if ($currency->symbol_left)
{{ $currency->symbol_left }}
@endif
{{ $currency->name }}
@if ($currency->symbol_right)
{{ $currency->symbol_right }}
@endif
</a>
@endforeach
</div>
</div>
@endif
@endhookwrapper
@hookwrapper('header.top.language')
@if (count($languages) > 1)
<div class="dropdown">
<a class="btn dropdown-toggle" href="javascript:void(0)" role="button" id="language-dropdown" data-toggle="dropdown"
aria-expanded="false">
{{ current_language()->name }}
</a>
<div class="dropdown-menu" aria-labelledby="language-dropdown">
@foreach ($languages as $language)
<a class="dropdown-item" href="{{ shop_route('lang.switch', [$language->code]) }}">
{{ $language->name }}
</a>
@endforeach
</div>
</div>
@endif
@endhookwrapper
</div>
@if (system_setting('base.telephone', ''))
<div class="right nav">
@hookwrapper('header.top.telephone')
<span class="px-2"><i class="bi bi-telephone-forward me-2"></i> {{ system_setting('base.telephone') }}</span>
@endhookwrapper
</div>
@endif
</div>
</div>
<div class="header-content d-none d-lg-block py-3">
<div class="container navbar-expand-lg">
@hookwrapper('header.menu.logo')
<div class="logo"><a href="{{ shop_route('home.index') }}">
<img src="{{ image_origin(system_setting('base.logo')) }}" class="img-fluid"></a>
</div>
@endhookwrapper
<div class="menu-wrap">
@if (!is_mobile())
@include('shared.menu-pc')
@endif
</div>
<div class="right-btn">
<ul class="navbar-nav flex-row">
@hookwrapper('header.menu.icon')
<li class="nav-item"><a href="#offcanvas-search-top" data-bs-toggle="offcanvas"
aria-controls="offcanvasExample" class="nav-link"><i class="iconfont">&#xe8d6;</i></a></li>
<li class="nav-item"><a href="{{ shop_route('account.wishlist.index') }}" class="nav-link"><i
class="iconfont">&#xe662;</i></a></li>
<li class="nav-item dropdown">
<a href="{{ shop_route('account.index') }}" class="nav-link"><i class="iconfont">&#xe619;</i></a>
<ul class="dropdown-menu dropdown-menu-end">
@auth('web_shop')
<li class="dropdown-item">
<h6 class="mb-0">{{ current_customer()->name }}</h6>
</li>
<li>
<hr class="dropdown-divider opacity-100">
</li>
<li><a href="{{ shop_route('account.index') }}" class="dropdown-item"><i class="bi bi-person me-1"></i>
{{ __('shop/account.index') }}</a></li>
<li><a href="{{ shop_route('account.order.index') }}" class="dropdown-item"><i
class="bi bi-clipboard-check me-1"></i> {{ __('shop/account.order.index') }}</a></li>
<li><a href="{{ shop_route('account.wishlist.index') }}" class="dropdown-item"><i
class="bi bi-heart me-1"></i> {{ __('shop/account.wishlist.index') }}</a></li>
<li>
<hr class="dropdown-divider opacity-100">
</li>
<li><a href="{{ shop_route('logout') }}" class="dropdown-item"><i class="bi bi-box-arrow-left me-1"></i>
{{ __('common.sign_out') }}</a></li>
@else
<li><a href="{{ shop_route('login.index') }}" class="dropdown-item"><i
class="bi bi-box-arrow-right me-1"></i>{{ __('shop/login.login_and_sign') }}</a></li>
@endauth
</ul>
</li>
@endhookwrapper
<li class="nav-item">
<a class="nav-link position-relative" {{ !equal_route('shop.carts.index') ? 'data-bs-toggle=offcanvas' : '' }}
href="{{ !equal_route('shop.carts.index') ? '#offcanvas-right-cart' : 'javascript:void(0);' }}" role="button"
aria-controls="offcanvasExample">
<i class="iconfont">&#xe634;</i>
<span class="cart-badge-quantity"></span>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="header-mobile d-lg-none">
<div class="mobile-content">
<div class="left">
<div class="mobile-open-menu"><i class="bi bi-list"></i></div>
<div class="mobile-open-search" href="#offcanvas-search-top" data-bs-toggle="offcanvas" aria-controls="offcanvasExample">
<i class="iconfont">&#xe8d6;</i>
</div>
</div>
<div class="center"><a href="{{ shop_route('home.index') }}">
<img src="{{ image_origin(system_setting('base.logo')) }}" class="img-fluid"></a>
</div>
<div class="right">
<a href="{{ shop_route('account.index') }}" class="nav-link"><i class="iconfont">&#xe619;</i></a>
<a href="{{ shop_route('carts.index') }}" class="nav-link ms-3"><i class="iconfont">&#xe634;</i></a>
</div>
</div>
</div>
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvas-mobile-menu">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasWithBothOptionsLabel">{{ __('common.menu') }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body mobile-menu-wrap">
@if (is_mobile())
@include('shared.menu-mobile')
@endif
</div>
</div>
@if (!equal_route('shop.carts.index'))
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvas-right-cart" aria-labelledby="offcanvasRightLabel"></div>
@endif
<div class="offcanvas offcanvas-top" tabindex="-1" id="offcanvas-search-top" aria-labelledby="offcanvasTopLabel">
<div class="offcanvas-header">
<input type="text" class="form-control input-group-lg border-0 fs-4" focus
placeholder="{{ __('common.input') }}" aria-label="Type your search here" aria-describedby="button-addon2">
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
</div>
</header>

View File

@ -0,0 +1,44 @@
<div align="center">
<div class="" style="margin-left: 8px; margin-top: 8px; margin-bottom: 8px; margin-right: 8px;">
<div style="word-break: break-all;box-sizing:border-box;text-align:center;min-width:320px; max-width:660px; border:1px solid #f6f6f6; background-color:#f7f8fa; margin:auto; padding:20px 0 30px; font-family:'helvetica neue',PingFangSC-Light,arial,'hiragino sans gb','microsoft yahei ui','microsoft yahei',simsun,sans-serif">
<table style="width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse">
<tbody>
<tr style="font-weight:300">
<td style="width:3%;max-width:30px;"></td>
<td style="max-width:600px;">
<div style="height: 35px;display: block;max-width: 200px;">
<a href="{{ shop_route('home.index') }}" style="display: block;height: 35px;display: block;max-width: 200px;">
<img border="0" src="{{ image_origin(system_setting('base.logo')) }}" style="max-width:100%; max-height: 100%;display">
</a>
</div>
<p style="height:2px;background-color: #fd560f;border: 0;font-size:0;padding:0;width:100%;margin-top:10px;"></p>
<div style="background-color:#fff; padding:23px 0 20px;box-shadow: 0px 1px 1px 0px rgba(122, 55, 55, 0.2);text-align:left;">
<table style="width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse;text-align:left;">
@yield('content')
</table>
</div>
<div style="margin-top: 10px; text-align:center; font-size:12px; line-height:18px; color:#999">
<table style="width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse">
<tbody>
<tr style="font-weight:300">
<td style="width:3.2%;max-width:30px;"></td>
<td style="max-width:540px;">
<p style="max-width: 100%; margin:auto;font-size:12px;color:#999;text-align:center;line-height:22px;">
{{ config('app.name') }} &copy; {{ date('Y') }} All Rights Reserved
</p>
</td>
<td style="width:3.2%;max-width:30px;"></td>
</tr>
</tbody>
</table>
</div>
</td>
<td style="width:3%;max-width:30px;"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,62 @@
<!doctype html>
<html lang="{{ locale() }}">
<head>
<!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=AW-11146062373"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'AW-11146062373'); </script>
<!-- Event snippet for Website sale conversion page --> <script> gtag('event', 'conversion', { 'send_to': 'AW-11146062373/ilbpCKSvzZkYEKXU7cIp', 'transaction_id': '' }); </script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>@yield('title', system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 - BeikeShop官网') )</title><!-- . ' Powered By BeikeShop' -->
<meta name="keywords" content="@yield('keywords', system_setting('base.meta_keywords'))">
<meta name="description" content="@yield('description', system_setting('base.meta_description'))">
<meta name="generator" content="BeikeShop v{{ config('beike.version') }}({{ config('beike.build') }})">
<base href="{{ $shop_base_url }}">
<link rel="stylesheet" type="text/css" href="{{ mix('/build/beike/shop/'.system_setting('base.theme').'/css/bootstrap.css') }}">
<script src="{{ asset('vendor/jquery/jquery-3.6.0.min.js') }}"></script>
<script src="{{ asset('vendor/layer/3.5.1/layer.js') }}"></script>
<link rel="shortcut icon" href="{{ image_origin(system_setting('base.favicon')) }}">
<script src="{{ asset('vendor/bootstrap/5.1.3/js/bootstrap.bundle.min.js') }}"></script>
<script src="{{ mix('/build/beike/shop/'.system_setting('base.theme').'/js/app.js') }}"></script>
<link rel="stylesheet" type="text/css" href="{{ mix('/build/beike/shop/'.system_setting('base.theme').'/css/app.css') }}">
@if (system_setting('base.head_code'))
{!! system_setting('base.head_code') !!}
@endif
@stack('header')
</head>
<body class="@yield('body-class')">
@if (!request('iframe'))
@include('layout.header')
@endif
@yield('content')
@if (!request('iframe'))
@include('layout.footer')
@endif
<script>
const config = {
isLogin: !!{{ current_customer()->id ?? 'null' }},
guestCheckout: !!{{ system_setting('base.guest_checkout', 1) }}
}
// 如果页面使用了ElementUI且当前语言不是中文则加载对应的语言包
@if (locale() != 'zh_cn')
if (typeof ELEMENT !== 'undefined') {
const elLocale = '{{ asset('vendor/element-ui/language/'.locale().'.js') }}';
document.write("<script src='" + elLocale + "'><\/script>")
$(function () {
setTimeout(() => {
ELEMENT.locale(ELEMENT.lang['{{ locale() }}'])
}, 0);
})
}
@endif
</script>
@stack('add-scripts')
</body>
<!-- BeikeShop v{{ config('beike.version') }}({{ config('beike.build') }}) -->
</html>

View File

@ -0,0 +1,8 @@
<div class="product-wrap">
<div class="image"><img src="{{ $product['image'] }}" class="img-fluid"></div>
<div class="product-name">{{ $product['name'] }}</div>
<div class="product-price">
<span class="price-new">$55.00</span>
<span class="price-lod">$125.00</span>
</div>
</div>

View File

@ -0,0 +1,39 @@
@extends('layout.mail')
@section('content')
<tbody>
<tr style="font-weight:300">
<td style="width:3.2%;max-width:30px;"></td>
<td style="max-width:480px;text-align:left;">
<h1 style="font-size: 20px; line-height: 36px; margin: 0px 0px 22px;">
{{ __('mail.retrieve_password_title') }}
</h1>
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('mail.retrieve_password_text') }}
<span style="font-weight: bold;">{{ __('mail.not_oneself') }}</span>
</span>
</p>
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('shop/forgotten.verification_code') }}:
<span style="font-weight: bold;">{{ $code }}</span>
</span>
</p>
<p style="font-size: 14px; color: rgb(51, 51, 51); line-height: 24px; margin: 6px 0px 0px; word-wrap: break-word; word-break: break-all;">
<a href="{{ $is_admin ? admin_route('forgotten.index') : shop_route('forgotten.index') }}?code={{ $code }}&email={{ $email }}" title="" style="font-size: 16px; line-height: 45px; display: block; background-color: #fd560f; color: rgb(255, 255, 255); text-align: center; text-decoration: none; margin-top: 20px; border-radius: 3px;">
{{ __('mail.retrieve_password_btn') }}
</a>
</p>
<dl style="font-size: 14px; color: rgb(51, 51, 51); line-height: 18px;">
<dd style="margin: 0px 0px 6px; padding: 0px; font-size: 12px; line-height: 22px;">
<p style="font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;">
{{ __('mail.sincerely') }}
<br>
<strong>{{ config('app.name') }} {{ __('mail.team') }}</strong>
</p>
</dd>
</dl>
</td>
<td style="width:3.2%;max-width:30px;"></td>
</tr>
</tbody>
@endsection

View File

@ -0,0 +1,88 @@
@extends('layout.mail')
@section('content')
<tbody>
<tr style="font-weight:300">
<td style="width:3.2%;max-width:30px;"></td>
<td style="max-width:480px;text-align:left;">
<h1 style="font-size: 20px; line-height: 36px; margin: 0px 0px 22px;">
{{ __('mail.order_success') }}
</h1>
<p style="font-size:14px;color:#333; line-height:24px; margin:0;">
{{ __('mail.customer_name', ['name' => $order->customer_name]) }}
</p>
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('mail.order_success') }}
<span style="font-weight: bold;">{{ __('mail.not_oneself') }}</span>
</span>
</p>
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('shop/account.order.order_info.order_details') }}</p>
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse; background-color:#f8f9fa">
<thead>
<tr>
<td style="font-size:13px;padding: 7px 6px">{{ __('shop/account.order.order_info.order_number') }}</td>
<td style="font-size:13px;padding: 7px 6px">{{ __('shop/account.order.order_info.order_date') }}</td>
<td style="font-size:13px;padding: 7px 6px">{{ __('shop/account.order.order_info.state') }}</td>
<td style="font-size:13px;padding: 7px 6px">{{ __('shop/account.order.order_info.order_amount') }}</td>
</tr>
</thead>
<tbody>
<tr>
<td style="padding:7px;font-size:13px;">{{ $order->number }}</td>
<td style="padding:7px;font-size:13px;">{{ $order->created_at }}</td>
<td style="padding:7px;font-size:13px;">
{{ __("common.order.{$order->status}") }}
</td>
<td style="padding:7px;font-size:13px;">{{ currency_format($order->total, $order->currency_code, $order->currency_value) }}</td>
</tr>
</tbody>
</table>
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('shop/account.order.order_info.order_items') }}</p>
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse; ">
<thead>
<tr>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px;width: 80px;text-align:center">{{ __('product.image') }}</td>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('product.name') }}</td>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.product_quantity') }}</td>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('product.price') }}</td>
</tr>
</thead>
<tbody>
@foreach ($order->orderProducts as $product)
<tr>
<td style="border: 1px solid #eee;padding:4px;text-align:center"><img style="width: 60px; height: 60px;" src="{{ image_origin($product->image) }}"></td>
<td style="font-size:12px; border: 1px solid #eee; width: 50%;padding:4px;">{{ $product->name }}</td>
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $product->quantity }}</td>
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ currency_format($product->price, $order->currency_code, $order->currency_value) }}</td>
</tr>
@endforeach
</tbody>
</table>
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('shop/account.order.order_info.order_total') }}</p>
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse;border:1px solid #eee;">
<tbody>
@foreach ($order->orderTotals as $total)
<tr>
<td style="border: 1px solid #eee;padding:4px; background-color: #f8f9fa;font-size:13px;padding: 7px;width: 30%">{{ $total->title }}</td>
<td style="border: 1px solid #eee;padding:4px;font-size:13px;padding: 7px"><strong>{{ currency_format($total->value, $order->currency_code, $order->currency_value) }}</strong></td>
</tr>
@endforeach
</tbody>
</table>
<dl style="font-size: 14px; color: rgb(51, 51, 51); line-height: 18px;">
<dd style="margin: 0px 0px 6px; padding: 0px; font-size: 12px; line-height: 22px;">
<p style="font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;">
{{ __('mail.sincerely') }}
<br>
<strong>{{ config('app.name') }} {{ __('mail.team') }}</strong>
</p>
</dd>
</dl>
</td>
<td style="width:3.2%;max-width:30px;"></td>
</tr>
</tbody>
@endsection

View File

@ -0,0 +1,77 @@
@extends('layout.mail')
@section('content')
<tbody>
<tr style="font-weight:300">
<td style="width:3.2%;max-width:30px;"></td>
<td style="max-width:480px;text-align:left;">
<h1 style="font-size: 20px; line-height: 36px; margin: 0px 0px 22px;">
{{ __('mail.order_update') }}
</h1>
<p style="font-size:14px;color:#333; line-height:24px; margin:0;">
{{ __('mail.customer_name', ['name' => $order->customer_name]) }}
</p>
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('mail.order_update_status', ['number' => $order->number]) }}
<span style="font-weight: bold;">{{ __("common.order.{$order->status}") }}</span>
</span>
</p>
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('shop/account.order.order_info.order_items') }}</p>
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse; ">
<thead>
<tr>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px;width: 80px;text-align:center">{{ __('product.image') }}</td>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('product.name') }}</td>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.product_quantity') }}</td>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('product.price') }}</td>
</tr>
</thead>
<tbody>
@foreach ($order->orderProducts as $product)
<tr>
<td style="border: 1px solid #eee;padding:4px;text-align:center"><img style="width: 60px; height: 60px;" src="{{ image_origin($product->image) }}"></td>
<td style="font-size:12px; border: 1px solid #eee; width: 50%;padding:4px;">{{ $product->name }}</td>
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $product->quantity }}</td>
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ currency_format($product->price, $order->currency_code, $order->currency_value) }}</td>
</tr>
@endforeach
</tbody>
</table>
@if ($order->orderShipments->count())
<p style="font-size: 13px;font-weight:bold;margin-bottom:6px;color: #333;">{{ __('order.order_shipments') }}</p>
<table style="width:100%;font-weight:300;margin-top:10px; margin-bottom:10px;border-collapse:collapse; ">
<thead class="">
<tr>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.express_company') }}</td>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.express_number') }}</td>
<td style="font-size:13px;border: 1px solid #eee; background-color: #f8f9fa;padding: 7px 4px">{{ __('order.history_created_at') }}</td>
</tr>
</thead>
<tbody>
@foreach ($order->orderShipments as $ship)
<tr>
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $ship->express_company }}</td>
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $ship->express_number }}</td>
<td style="border: 1px solid #eee;padding:4px;font-size: 13px;">{{ $ship->created_at }}</td>
</tr>
@endforeach
</tbody>
</table>
@endif
<dl style="font-size: 14px; color: rgb(51, 51, 51); line-height: 18px;">
<dd style="margin: 0px 0px 6px; padding: 0px; font-size: 12px; line-height: 22px;">
<p style="font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;">
{{ __('mail.sincerely') }}
<br>
<strong>{{ config('app.name') }} {{ __('mail.team') }}</strong>
</p>
</dd>
</dl>
</td>
<td style="width:3.2%;max-width:30px;"></td>
</tr>
</tbody>
@endsection

View File

@ -0,0 +1,37 @@
@extends('layout.mail')
@section('content')
<tbody>
<tr style="font-weight:300">
<td style="width:3.2%;max-width:30px;"></td>
<td style="max-width:480px;text-align:left;">
<h1 style="font-size: 20px; line-height: 36px; margin: 0px 0px 22px;">
{{ __('mail.welcome_register') }} {{ config('app.name') }}
</h1>
<p style="font-size:14px;color:#333; line-height:24px; margin:0;">
{{ __('mail.customer_name', ['name' => $customer->name]) }}
</p>
<p style="line-height: 24px; margin: 6px 0px 0px; overflow-wrap: break-word; word-break: break-all;">
<span style="color: rgb(51, 51, 51); font-size: 14px;">{{ __('mail.register_end') }}
<span style="font-weight: bold;">{{ __('mail.not_oneself') }}</span>
</span>
</p>
<p style="font-size: 14px; color: rgb(51, 51, 51); line-height: 24px; margin: 6px 0px 0px; word-wrap: break-word; word-break: break-all;">
<a href="{{ config('app.url') }}" title="" style="font-size: 16px; line-height: 45px; display: block; background-color: #fd560f; color: rgb(255, 255, 255); text-align: center; text-decoration: none; margin-top: 20px; border-radius: 3px;">
{{ __('mail.btn_buy_now') }}
</a>
</p>
<dl style="font-size: 14px; color: rgb(51, 51, 51); line-height: 18px;">
<dd style="margin: 0px 0px 6px; padding: 0px; font-size: 12px; line-height: 22px;">
<p style="font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;">
{{ __('mail.sincerely') }}
<br>
<strong>{{ config('app.name') }} {{ __('mail.team') }}</strong>
</p>
</dd>
</dl>
</td>
<td style="width:3.2%;max-width:30px;"></td>
</tr>
</tbody>
@endsection

View File

@ -0,0 +1,50 @@
@extends('layout.master')
@section('body-class', 'page-categories-home')
@section('content')
<div class="container">
{{ $breadcrumb->render() }}
<div class="row">
<div class="col-lg-9 col-12">
<div class="card mb-4 shadow-sm p-3 h-min-600">
<div class="card-body">
@foreach ($active_pages as $page)
<div>
<h5 class="card-title mb-2"><a class="text-black" href="{{ shop_route('pages.show', [$page->id]) }}">{{ $page->description->title }}</a></h5>
<p class="fs-6 mb-3 text-secondary">{{ $page->created_at }}</p>
@if ($page->description->summary)
<p class="card-text mb-3">{{ $page->description->summary ?? '' }}</p>
@endif
<div class="text-danger"><a href="{{ shop_route('pages.show', [$page->id]) }}">{{ __('shop/account.check_details') }}<i class="bi bi-arrow-right-short"></i></a></div>
</div>
@if (!$loop->last)
<hr class="my-4">
@endif
@endforeach
</div>
</div>
</div>
@if ($active_page_categories)
<div class="col-lg-3 col-12">
<div class="card mb-3 shadow-sm">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('product.category') }}</h5>
</div>
<div class="card-body">
<ul class="list-group list-group-flush">
@foreach ($active_page_categories as $category)
<li class="list-group-item p-0">
<a href="{{ shop_route('page_categories.show', [$category->id]) }}"
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
</div>
</div>
@endsection

View File

@ -0,0 +1,70 @@
@extends('layout.master')
@section('body-class', 'page-categories-home')
@section('title', $category->description->meta_title ?: system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 -
BeikeShop官网') . ' - ' . $category->description->name)
@section('keywords', $category->description->meta_keywords ?: system_setting('base.meta_keyword'))
@section('description', $category->description->meta_description ?: system_setting('base.meta_description'))
@section('content')
<div class="container">
<x-shop-breadcrumb type="page_category" :value="$category['id']" />
<div class="row">
<div class="col-lg-9 col-12">
<div class="card mb-4 shadow-sm">
<div class="card-body">
<h3>{{ $category->description->title }}</h3>
<div>{{ $category->description->summary }}</div>
</div>
</div>
<div class="card mb-4 shadow-sm">
<div class="card-body">
@if ($category_pages->count() > 0)
@foreach ($category_pages as $page)
<div>
<h5 class="card-title mb-2"><a class="text-black"
href="{{ type_route('page', $page) }}">{{ $page->description->title }}</a></h5>
<p class="fs-6 mb-3 text-secondary">{{ $page->created_at }}</p>
@if ($page->description->summary)
<p class="card-text mb-4">{{ $page->description->summary ?? '' }}</p>
@endif
<div class="text-danger"><a
href="{{ type_route('page', $page) }}">{{ __('shop/account.check_details') }}<i
class="bi bi-arrow-right-short"></i></a></div>
</div>
@if (!$loop->last)
<hr class="my-4">
@endif
@endforeach
@else
<x-shop-no-data />
@endif
{{ $category_pages->links('shared/pagination/bootstrap-4') }}
</div>
</div>
</div>
@if ($active_page_categories)
<div class="col-lg-3 col-12">
<div class="card mb-3 shadow-sm">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('product.category') }}</h5>
</div>
<div class="card-body">
<ul class="list-group list-group-flush">
@foreach ($active_page_categories as $category)
<li class="list-group-item p-0">
<a href="{{ type_route('page_category', $category) }}"
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
</div>
</div>
@endsection

View File

@ -0,0 +1,104 @@
@extends('layout.master')
@section('body-class', 'page-pages')
@section('title', $page->description->meta_title ?: $page->description->title)
@section('keywords', $page->description->meta_keywords)
@section('description', $page->description->meta_description)
@push('header')
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
@endpush
@section('content')
<div class="container">
<x-shop-breadcrumb type="page" :value="$page['id']" />
<div class="row">
<div class="{{ $page->category ? "col-lg-9 col-12" : 'col-12' }}">
<div class="card shadow-sm">
<div class="card-body h-min-600 p-lg-4">
<h2 class="mb-3">{{ $page->description->title }}</h2>
<div class="text-secondary opacity-75 mb-4">
<span class="me-3"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg> {{ __('page_category.author') }}: {{ $page->author }}</span>
<span class="me-3"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clock"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg> {{ __('page_category.created_at') }}: {{ $page->created_at }}</span>
<span><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg> {{ __('page_category.views') }}: {{ $page->views }}</span>
</div>
{!! $page_format['content'] !!}
@if ($products)
<div class="relations-wrap mt-5">
<div class="container position-relative">
<div class="title text-center fs-4 mb-4">{{ __('admin/product.product_relations') }}</div>
<div class="product swiper-style-plus">
<div class="swiper relations-swiper">
<div class="swiper-wrapper">
@foreach ($products as $item)
<div class="swiper-slide">
@include('shared.product', ['product' => $item])
</div>
@endforeach
</div>
</div>
<div class="swiper-pagination relations-pagination"></div>
<div class="swiper-button-prev relations-swiper-prev"></div>
<div class="swiper-button-next relations-swiper-next"></div>
</div>
</div>
</div>
@endif
</div>
</div>
</div>
@if ($page->category)
<div class="col-lg-3 col-12">
<div class="card mb-3 shadow-sm">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title">{{ __('product.category') }}</h5>
</div>
<div class="card-body">
<ul class="list-group list-group-flush">
@foreach ($active_page_categories as $category)
<li class="list-group-item p-0">
<a href="{{ shop_route('page_categories.show', [$category->id]) }}"
class="p-2 list-group-item-action nav-link">{{ $category->description->title }}</a>
</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
</div>
</div>
@endsection
@push('add-scripts')
<script>
var relationsSwiper = new Swiper ('.relations-swiper', {
watchSlidesProgress: true,
breakpoints:{
320: {
slidesPerView: 2,
spaceBetween: 10,
},
768: {
slidesPerView: 4,
spaceBetween: 30,
},
},
spaceBetween: 30,
// 如果需要前进后退按钮
navigation: {
nextEl: '.relations-swiper-next',
prevEl: '.relations-swiper-prev',
},
// 如果需要分页器
pagination: {
el: '.relations-pagination',
clickable: true,
},
})
</script>
@endpush

View File

@ -0,0 +1,16 @@
@extends('layout.master')
@section('body-class', 'page-pages')
@section('title', $page['meta_title'] ?: $page['title'])
@section('keywords', $page['meta_keywords'])
@section('description', $page['meta_description'])
@section('content')
<div class="container">
<x-shop-breadcrumb type="page" :value="$page['id']" />
<div class="card">
<div class="card-body">
{!! $page_format['content'] !!}
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,417 @@
@extends('layout.master')
@section('body-class', 'page-product')
@section('title', $product['meta_title'] ?: $product['name'])
@section('keywords', $product['meta_keywords'] ?: system_setting('base.meta_keyword'))
@section('description', $product['meta_description'] ?: system_setting('base.meta_description'))
@push('header')
<script src="{{ asset('vendor/vue/2.7/vue' . (!config('app.debug') ? '.min' : '') . '.js') }}"></script>
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
<script src="{{ asset('vendor/zoom/jquery.zoom.min.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
@endpush
@section('content')
<div class="container" id="product-app" v-cloak>
<x-shop-breadcrumb type="product" :value="$product['id']" />
<div class="row mb-5 mt-3 mt-md-0" id="product-top">
<div class="col-12 col-lg-6 mb-3">
<div class="product-image d-flex align-items-start">
@if(!is_mobile())
<div class="left" v-if="images.length">
<div class="swiper" id="swiper">
<div class="swiper-wrapper">
<div class="swiper-slide" :class="!index ? 'active' : ''" v-for="image, index in images">
<a href="javascript:;" :data-image="image.preview" :data-zoom-image="image.popup">
<img :src="image.thumb" class="img-fluid">
</a>
</div>
</div>
<div class="swiper-pager">
<div class="swiper-button-next new-feature-slideshow-next"></div>
<div class="swiper-button-prev new-feature-slideshow-prev"></div>
</div>
</div>
</div>
<div class="right" id="zoom">
<img :src="images.length ? images[0].preview : '{{ asset('image/placeholder.png') }}'" class="img-fluid">
</div>
@else
<div class="swiper" id="swiper-mobile">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="image, index in images">
<img :src="image.preview" class="img-fluid">
</div>
</div>
<div class="swiper-pagination mobile-pagination"></div>
</div>
@endif
</div>
</div>
<div class="col-12 col-lg-6">
<div class="peoduct-info">
@hookwrapper('product.detail.name')
<h1 class="mb-4 product-name">{{ $product['name'] }}</h1>
@endhookwrapper
<div class="price-wrap d-flex align-items-end">
<div class="new-price fs-1 lh-1 fw-bold me-2">@{{ product.price_format }}@{{ price_setting }}</div>
<div class="old-price text-muted text-decoration-line-through" v-if="product.price != product.origin_price && product.origin_price !== 0">
@{{ product.origin_price_format }}
</div>
</div>
<div class="stock-and-sku mb-4">
@hookwrapper('product.detail.quantity')
<div class="d-flex">
<span class="title text-muted">{{ __('product.quantity') }}:</span>
<div :class="product.quantity > 0 ? 'text-success' : 'text-secondary'">
<template v-if="product.quantity > 0">{{ __('shop/products.in_stock') }}</template>
<template v-else>{{ __('shop/products.out_stock') }}</template>
</div>
</div>
@endhookwrapper
@if ($product['brand_id'])
@hookwrapper('product.detail.brand')
<div class="d-flex">
<span class="title text-muted">{{ __('product.brand') }}:</span>
<a href="{{ shop_route('brands.show', $product['brand_id']) }}">{{ $product['brand_name'] }}</a>
</div>
@endhookwrapper
@endif
@hookwrapper('product.detail.sku')
<div class="d-flex"><span class="title text-muted">SKU:</span>@{{ product.sku }}</div>
@endhookwrapper
@hookwrapper('product.detail.model')
<div class="d-flex" v-if="product.model"><span class="title text-muted">{{ __('shop/products.model') }}:</span> @{{ product.model }}</div>
@endhookwrapper
</div>
@if (0)
<div class="rating-wrap d-flex">
<div class="rating">
@for ($i = 0; $i < 5; $i++)
<i class="iconfont">&#xe628;</i>
@endfor
</div>
<span class="text-muted">132 reviews</span>
</div>
@endif
<div class="variables-wrap mb-4" v-if="source.variables.length">
<div class="variable-group mb-2" v-for="variable, variable_index in source.variables" :key="variable_index">
<p class="mb-2">@{{ variable.name }}</p>
<div class="variable-info">
<div
v-for="value, value_index in variable.values"
@click="checkedVariableValue(variable_index, value_index, value)"
:key="value_index"
:class="[value.selected ? 'selected' : '', value.disabled ? 'disabled' : '']">
<span class="image" v-if="value.image"><img :src="value.image" class="img-fluid"></span>
@{{ value.name }}
</div>
</div>
</div>
</div>
@if ($product['active'])
<div class="quantity-btns">
@hook('product.detail.buy.before')
<div class="quantity-wrap">
<input type="text" class="form-control" :disabled="!product.quantity" onkeyup="this.value=this.value.replace(/\D/g,'')" v-model="quantity" name="quantity">
<div class="right">
<i class="bi bi-chevron-up"></i>
<i class="bi bi-chevron-down"></i>
</div>
</div>
<button
class="btn btn-outline-dark ms-md-3 add-cart fw-bold"
:disabled="!product.quantity"
@click="addCart(false, this)"
><i class="bi bi-cart-fill me-1"></i>{{ __('shop/products.add_to_cart') }}
</button>
<button
class="btn btn-dark ms-3 fw-bold"
:disabled="!product.quantity"
@click="addCart(true, this)"
><i class="bi bi-bag-fill me-1"></i>{{ __('shop/products.buy_now') }}
</button>
@hook('product.detail.buy.after')
</div>
<div class="add-wishlist">
<button class="btn btn-link ps-0 text-secondary" data-in-wishlist="{{ $product['in_wishlist'] }}" onclick="bk.addWishlist('{{ $product['id'] }}', this)">
<i class="bi bi-heart{{ $product['in_wishlist'] ? '-fill' : '' }} me-1"></i> {{ __('shop/products.add_to_favorites') }}
</button>
</div>
@else
<div class="text-danger"><i class="bi bi-exclamation-circle-fill"></i> {{ __('product.has_been_inactive') }}</div>
@endif
</div>
</div>
</div>
<div class="product-description">
<div class="nav nav-tabs nav-overflow justify-content-start justify-content-md-center border-bottom mb-3">
<a class="nav-link fw-bold active fs-5" data-bs-toggle="tab" href="#product-description">
{{ __('shop/products.product_details') }}
</a>
@if ($product['attributes'])
<a class="nav-link fw-bold fs-5" data-bs-toggle="tab" href="#product-attributes">
{{ __('admin/attribute.index') }}
</a>
@endif
</div>
<div class="tab-content">
<div class="tab-pane fade show active" id="product-description" role="tabpanel">
{!! $product['description'] !!}
</div>
<div class="tab-pane fade" id="product-attributes" role="tabpanel">
<table class="table table-bordered attribute-table">
@foreach ($product['attributes'] as $group)
<thead class="table-light">
<tr><td colspan="2"><strong>{{ $group['attribute_group_name'] }}</strong></td></tr>
</thead>
<tbody>
@foreach ($group['attributes'] as $item)
<tr>
<td>{{ $item['attribute'] }}</td>
<td>{{ $item['attribute_value'] }}</td>
</tr>
@endforeach
</tbody>
@endforeach
</table>
</div>
</div>
</div>
</div>
@if ($relations)
<div class="relations-wrap mt-5">
<div class="container position-relative">
<div class="title text-center fs-1 mb-4">{{ __('admin/product.product_relations') }}</div>
<div class="product swiper-style-plus">
<div class="swiper relations-swiper">
<div class="swiper-wrapper">
@foreach ($relations as $item)
<div class="swiper-slide">
@include('shared.product', ['product' => $item])
</div>
@endforeach
</div>
</div>
<div class="swiper-pagination relations-pagination"></div>
<div class="swiper-button-prev relations-swiper-prev"></div>
<div class="swiper-button-next relations-swiper-next"></div>
</div>
</div>
</div>
@endif
@endsection
@push('add-scripts')
<script>
let swiperMobile = null;
let app = new Vue({
el: '#product-app',
data: {
selectedVariantsIndex: [], // 选中的变量索引
images: [],
product: {
id: 0,
images: "",
model: "",
origin_price: 0,
origin_price_format: "",
position: 0,
price: 0,
price_format: "",
quantity: 0,
sku: "",
},
quantity: 1,
source: {
skus: @json($product['skus']),
variables: @json($product['variables'] ?? []),
},
},
computed: {
},
beforeMount () {
const skus = JSON.parse(JSON.stringify(this.source.skus));
const skuDefault = skus.find(e => e.is_default)
this.selectedVariantsIndex = skuDefault.variants
// 为 variables 里面每一个 values 的值添加 selected、disabled 字段
if (this.source.variables.length) {
this.source.variables.forEach(variable => {
variable.values.forEach(value => {
this.$set(value, 'selected', false)
this.$set(value, 'disabled', false)
})
})
this.checkedVariants()
this.getSelectedSku();
this.updateSelectedVariantsStatus()
} else {
// 如果没有默认的sku则取第一个sku的第一个变量的第一个值
this.product = skus[0];
this.images = @json($product['images'] ?? []);
}
},
methods: {
checkedVariableValue(variable_idnex, value_index, value) {
$('.product-image .swiper .swiper-slide').eq(0).addClass('active').siblings().removeClass('active');
this.source.variables[variable_idnex].values.forEach((v, i) => {
v.selected = i == value_index
})
this.updateSelectedVariantsIndex();
this.getSelectedSku();
this.updateSelectedVariantsStatus()
},
// 把对应 selectedVariantsIndex 下标选中 variables -> values 的 selected 字段为 true
checkedVariants() {
this.source.variables.forEach((variable, index) => {
variable.values[this.selectedVariantsIndex[index]].selected = true
})
},
getSelectedSku() {
// 通过 selectedVariantsIndex 的值比对 skus 的 variables
const sku = this.source.skus.find(sku => sku.variants.toString() == this.selectedVariantsIndex.toString())
const spuImages = @json($product['images'] ?? []);
this.images = [...sku.images, ...spuImages]
this.product = sku;
if (swiperMobile) {
swiperMobile.slideTo(0, 0, false)
}
this.$nextTick(() => {
$('#zoom img').attr('src', $('#swiper a').attr('data-image'));
$('#zoom').trigger('zoom.destroy');
$('#zoom').zoom({url: $('#swiper a').attr('data-zoom-image')});
})
},
addCart(isBuyNow = false) {
bk.addCart({sku_id: this.product.id, quantity: this.quantity, isBuyNow});
},
updateSelectedVariantsIndex() {
// 获取选中的 variables 内 value的 下标 index 填充到 selectedVariantsIndex 中
this.source.variables.forEach((variable, index) => {
variable.values.forEach((value, value_index) => {
if (value.selected) {
this.selectedVariantsIndex[index] = value_index
}
})
})
},
updateSelectedVariantsStatus() {
// skus 里面 quantity 不为 0 的 sku.variants
const skus = this.source.skus.filter(sku => sku.quantity > 0).map(sku => sku.variants);
this.source.variables.forEach((variable, index) => {
variable.values.forEach((value, value_index) => {
const selectedVariantsIndex = this.selectedVariantsIndex.slice(0);
selectedVariantsIndex[index] = value_index;
const selectedSku = skus.find(sku => sku.toString() == selectedVariantsIndex.toString());
if (selectedSku) {
value.disabled = false;
} else {
value.disabled = true;
}
})
});
},
}
});
$(document).on("mouseover", ".product-image #swiper .swiper-slide a", function() {
$(this).parent().addClass('active').siblings().removeClass('active');
$('#zoom').trigger('zoom.destroy');
$('#zoom img').attr('src', $(this).attr('data-image'));
$('#zoom').zoom({url: $(this).attr('data-zoom-image')});
});
var swiper = new Swiper("#swiper", {
direction: "vertical",
slidesPerView: 1,
spaceBetween:3,
breakpoints:{
375:{
slidesPerView: 3,
spaceBetween:3,
},
480:{
slidesPerView: 4,
spaceBetween:27,
},
768:{
slidesPerView: 6,
spaceBetween:3,
},
},
navigation: {
nextEl: '.new-feature-slideshow-next',
prevEl: '.new-feature-slideshow-prev',
},
observer: true,
observeParents: true
});
var relationsSwiper = new Swiper ('.relations-swiper', {
watchSlidesProgress: true,
breakpoints:{
320: {
slidesPerView: 2,
spaceBetween: 10,
},
768: {
slidesPerView: 4,
spaceBetween: 30,
},
},
spaceBetween: 30,
// 如果需要前进后退按钮
navigation: {
nextEl: '.relations-swiper-next',
prevEl: '.relations-swiper-prev',
},
// 如果需要分页器
pagination: {
el: '.relations-pagination',
clickable: true,
},
})
@if (is_mobile())
swiperMobile = new Swiper("#swiper-mobile", {
slidesPerView: 1,
pagination: {
el: ".mobile-pagination",
},
observer: true,
observeParents: true
});
@endif
$(document).ready(function () {
$('#zoom').trigger('zoom.destroy');
$('#zoom').zoom({url: $('#swiper a').attr('data-zoom-image')});
});
</script>
@endpush

View File

@ -0,0 +1,22 @@
@extends('layout.master')
@section('body-class', 'page-categories')
@section('content')
<div class="container">
<x-shop-breadcrumb type="static" value="products.search" />
<div class="row">
@if (count($items))
@foreach ($items as $product)
<div class="col-6 col-md-3">@include('shared.product')</div>
@endforeach
@else
<x-shop-no-data />
@endif
</div>
{{ $products->links('shared/pagination/bootstrap-4') }}
</div>
@endsection

View File

@ -0,0 +1,197 @@
<template id="address-dialog">
<div>
<el-dialog custom-class="mobileWidth" title="{{ __('address.index') }}" :visible.sync="editShow" @close="closeAddressDialog('addressForm')" :close-on-click-modal="false">
<el-form ref="addressForm" :rules="rules" :model="form" label-width="100px">
<el-form-item label="{{ __('address.name') }}" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
@if (!current_customer())
<el-form-item label="{{ __('common.email') }}" prop="email" v-if="type == 'guest_shipping_address'">
<el-input v-model="form.email"></el-input>
</el-form-item>
@endif
<el-form-item label="{{ __('address.phone') }}" prop="phone">
<el-input maxlength="11" v-model="form.phone" type="number"></el-input>
</el-form-item>
<el-form-item label="{{ __('address.address') }}" required>
<div class="row dialog-address">
<div class="col-4">
<el-form-item>
<el-select v-model="form.country_id" filterable placeholder="{{ __('address.country_id') }}" @change="countryChange">
<el-option v-for="item in source.countries" :key="item.id" :label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</div>
<div class="col-4 mt-2 mt-sm-0">
<el-form-item prop="zone_id">
<el-select v-model="form.zone_id" filterable placeholder="{{ __('address.zone') }}">
<el-option v-for="item in source.zones" :key="item.id" :label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</div>
<div class="col-4 mt-2 mt-sm-0">
<el-form-item prop="city">
<el-input v-model="form.city" placeholder="{{ __('shop/account.addresses.enter_city') }}"></el-input>
</el-form-item>
</div>
</div>
</el-form-item>
<el-form-item label="{{ __('address.post_code') }}" prop="zipcode">
<el-input v-model="form.zipcode"></el-input>
</el-form-item>
<el-form-item label="{{ __('address.address_1') }}" prop="address_1">
<el-input v-model="form.address_1"></el-input>
</el-form-item>
<el-form-item label="{{ __('address.address_2') }}">
<el-input v-model="form.address_2"></el-input>
</el-form-item>
<el-form-item label="{{ __('address.default') }}" v-if="source.isLogin">
<el-switch
v-model="form.default"
>
</el-switch>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addressFormSubmit('addressForm')">{{ __('common.save') }}</el-button>
<el-button @click="closeAddressDialog('addressForm')">{{ __('common.cancel') }}</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
Vue.component('address-dialog', {
template: '#address-dialog',
props: {
value: {
default: null
},
},
data: function () {
return {
editShow: false,
index: null,
type: 'shipping_address_id',
form: {
name: '',
phone: '',
country_id: @json((int) system_setting('base.country_id')),
zipcode: '',
zone_id: @json((int) system_setting('base.zone_id')),
city: '',
address_1: '',
address_2: '',
default: false,
},
rules: {
name: [{
required: true,
message: '{{ __('shop/account.addresses.enter_name') }}',
trigger: 'blur'
}, ],
email: [{
required: true,
type: 'email',
message: '{{ __('shop/login.enter_email') }}',
trigger: 'blur'
}, ],
phone: [{
required: true,
message: '{{ __('shop/account.addresses.enter_phone') }}',
trigger: 'blur'
}, ],
address_1: [{
required: true,
message: ' {{ __('shop/account.addresses.enter_address') }}',
trigger: 'blur'
}, ],
zone_id: [{
required: true,
message: '{{ __('shop/account.addresses.select_province') }}',
trigger: 'blur'
}, ],
city: [{
required: true,
message: '{{ __('shop/account.addresses.enter_city') }}',
trigger: 'blur'
}, ],
},
source: {
countries: @json($countries ?? []),
zones: [],
isLogin: config.isLogin,
},
}
},
computed: {
},
beforeMount() {
this.countryChange(this.form.country_id);
},
methods: {
editAddress(addresses, type) {
this.type = type
if (addresses) {
this.form = addresses
}
this.countryChange(this.form.country_id);
this.editShow = true
},
addressFormSubmit(form) {
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message.error('{{ __('shop/checkout.check_form') }}');
return;
}
this.$emit('change', this.form)
// const type = this.form.id ? 'put' : 'post';
// const url = `/account/addresses${type == 'put' ? '/' + this.form.id : ''}`;
// $http[type](url, this.form).then((res) => {
// this.$message.success(res.message);
// this.$emit('change', res.data)
// this.editShow = false
// })
});
},
closeAddressDialog() {
this.$refs['addressForm'].resetFields();
this.editShow = false
Object.keys(this.form).forEach(key => this.form[key] = '')
this.form.country_id = @json((int) system_setting('base.country_id'));
this.form.default = false;
},
countryChange(e) {
const self = this;
$http.get(`/countries/${e}/zones`, null, {
hload: true
}).then((res) => {
this.source.zones = res.data.zones;
if (!res.data.zones.some(e => e.id == this.form.zone_id)) {
this.form.zone_id = '';
}
})
},
}
});
</script>

View File

@ -0,0 +1,43 @@
<div class="product-tool d-flex justify-content-between align-items-center mb-4">
@if (!is_mobile())
<div class="style-wrap d-flex align-items-center">
<label class="{{ !request('style_list') || request('style_list') == 'grid' ? 'active' : ''}} grid"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ __('common.text_grid') }}"
>
<svg viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg" width="18" height="18"><rect width="5" height="5"></rect><rect x="7" width="5" height="5"></rect><rect x="14" width="5" height="5"></rect><rect y="7" width="5" height="5"></rect><rect x="7" y="7" width="5" height="5"></rect><rect x="14" y="7" width="5" height="5"></rect><rect y="14" width="5" height="5"></rect><rect x="7" y="14" width="5" height="5"></rect><rect x="14" y="14" width="5" height="5"></rect></svg>
<input class="d-none" value="grid" type="radio" name="style_list">
</label>
<label class="ms-1 {{ request('style_list') == 'list' ? 'active' : '' }} list"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ __('common.text_list') }}"
>
<svg viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg" width="18" height="18"><rect width="5" height="5"></rect><rect x="7" height="5" width="12"></rect><rect y="7" width="5" height="5"></rect><rect x="7" y="7" height="5" width="12"></rect><rect y="14" width="5" height="5"></rect><rect x="7" y="14" height="5" width="12"></rect></svg>
<input class="d-none" value="list" type="radio" name="style_list">
</label>
</div>
@endif
<div class="d-flex align-items-center">
<div class="text-nowrap text-secondary">
{{ __('common.showing_page', ['per_page' => request('per_page'), 'total' => $products->total()]) }}
</div>
<select class="form-select perpage-select ms-3">
@foreach ($per_pages as $val)
<option value="{{ $val }}" {{ request('per_page') == $val ? 'selected' : '' }}>{{ $val }}</option>
@endforeach
</select>
<select class="form-select order-select ms-2">
<option value="">{{ __('common.default') }}</option>
<option value="products.sales|asc" {{ request('sort') == 'products.sales' && request('order') == 'asc' ? 'selected' : '' }}>{{ __('common.sales') }} ({{ __('common.low') . '-' . __('common.high')}})</option>
<option value="products.sales|desc" {{ request('sort') == 'products.sales' && request('order') == 'desc' ? 'selected' : '' }}>{{ __('common.sales') }} ({{ __('common.high') . '-' . __('common.low')}})</option>
<option value="pd.name|asc" {{ request('sort') == 'pd.name' && request('order') == 'asc' ? 'selected' : '' }}>{{ __('common.name') }} (A - Z)</option>
<option value="pd.name|desc" {{ request('sort') == 'pd.name' && request('order') == 'desc' ? 'selected' : '' }}>{{ __('common.name') }} (Z - A)</option>
<option value="product_skus.price|asc" {{ request('sort') == 'product_skus.price' && request('order') == 'asc' ? 'selected' : '' }}>{{ __('product.price') }} ({{ __('common.low') . '-' . __('common.high')}})</option>
<option value="product_skus.price|desc" {{ request('sort') == 'product_skus.price' && request('order') == 'desc' ? 'selected' : '' }}>{{ __('product.price') }} ({{ __('common.high') . '-' . __('common.low')}})</option>
</select>
</div>
</div>

View File

@ -0,0 +1,103 @@
<div class="mb-4 module-category-wrap">
<h4 class="mb-3"><span>{{ __('product.category') }}</span></h4>
<ul class="sidebar-widget mb-0" id="category-one">
@foreach ($all_categories as $key_a => $category_all)
<li class="{{ $category_all['id'] == $category->id ? 'active' : ''}}">
<a href="{{ shop_route('categories.show', [$category_all['id']]) }}" title="{{ $category_all['name'] }}" class="category-href">{{ $category_all['name'] }}</a>
@if ($category_all['children'])
<button class="toggle-icon btn {{ $category_all['id'] == $category->id ? '' : 'collapsed'}}" data-bs-toggle="collapse" href="#category-{{ $key_a }}"><i class="bi bi-chevron-up"></i></button>
<ul id="category-{{ $key_a }}" class="accordion-collapse collapse {{ $category_all['id'] == $category->id ? 'show' : ''}}" data-bs-parent="#category-one">
@foreach ($category_all['children'] as $key_b => $child)
<li class="{{ $child['id'] == $category->id ? 'active' : ''}} child-category">
<a href="{{ shop_route('categories.show', [$child['id']]) }}" title="{{ $child['name'] }}">{{ $child['name'] }}</a>
</li>
@endforeach
</ul>
@endif
</li>
@endforeach
</ul>
</div>
<div class="filter-box">
@if ($filter_data['price']['min'] != $filter_data['price']['max'])
@hookwrapper('category.filter.sidebar.price')
@push('header')
<script src="{{ asset('vendor/jquery/jquery-ui/jquery-ui.min.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/jquery/jquery-ui/jquery-ui.min.css') }}">
@endpush
<div class="card">
<div class="card-header p-0">
<h4 class="mb-3">{{ __('product.price') }}</h4>
</div>
<div class="card-body p-0">
<div id="price-slider" class="mb-2"><div class="slider-bg"></div></div>
<div class="text-secondary price-range d-flex justify-content-between">
<div>
{{ __('common.text_form') }}
<span class="min">{{ currency_format($filter_data['price']['select_min'], current_currency_code()) }}</span>
</div>
<div>
{{ __('common.text_to') }}
<span class="max">{{ currency_format($filter_data['price']['select_max'], current_currency_code()) }}</span>
</div>
</div>
<input value="{{ $filter_data['price']['select_min'] }}" class="price-select-min d-none">
<input value="{{ $filter_data['price']['select_max'] }}" class="price-select-max d-none">
<input value="{{ $filter_data['price']['min'] }}" class="price-min d-none">
<input value="{{ $filter_data['price']['max'] }}" class="price-max d-none">
</div>
</div>
@endhookwrapper
@endif
@hookwrapper('category.filter.sidebar.attr')
@foreach ($filter_data['attr'] as $index => $attr)
<div class="card">
<div class="card-header fw-bold p-0">
<h4 class="mb-3">{{ $attr['name'] }}</h4>
</div>
<ul class="list-group list-group-flush attribute-item" data-attribute-id="{{ $attr['id'] }}">
@foreach ($attr['values'] as $value_index => $value)
<li class="list-group-item border-0 px-0">
<label class="form-check-label d-block">
<input class="form-check-input attr-value-check me-2" data-attr="{{ $index }}" data-attrval="{{ $value_index }}" {{ $value['selected'] ? 'checked' : '' }} name="6" type="checkbox" value="{{ $value['id'] }}">{{ $value['name'] }}
</label>
</li>
@endforeach
</ul>
</div>
@endforeach
@endhookwrapper
</div>
@push('add-scripts')
<script>
const currencyRate = {{ current_currency_rate() }};
$(document).ready(function() {
if (!$('#price-slider').length) {
return;
}
$("#price-slider").slider({
range: true,
step: 0.01,
min: {{ $filter_data['price']['min'] ?? 0 }},
max: {{ $filter_data['price']['max'] ?? 0 }},
values: [{{ $filter_data['price']['select_min'] }}, {{ $filter_data['price']['select_max'] }}],
change: function(event, ui) {
$('input.price-select-min').val(ui.values[0])
$('input.price-select-max').val(ui.values[1])
filterProductData();
},
slide: function(event, ui) {
let min = $('.price-range .min').html();
let max = $('.price-range .max').html();
$('.price-range .min').html(min.replace(min.replace(/[^0-9.,]/g, ''), (ui.values[0] * currencyRate).toFixed(2)));
$('.price-range .max').html(max.replace(max.replace(/[^0-9.,]/g, ''), (ui.values[1] * currencyRate).toFixed(2)));
}
});
})
</script>
@endpush

View File

@ -0,0 +1,5 @@
<div class="alert alert-success alert-dismissible">
<i class="bi bi-check-circle-fill"></i>
{{ $msg }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>

View File

@ -0,0 +1,45 @@
<div class="accordion accordion-flush" id="menu-accordion">
@foreach ($menu_content as $key => $menu)
@if ($menu['name'])
<div class="accordion-item">
<div class="nav-item-text">
<a class="nav-link" target="{{ isset($menu['new_window']) && $menu['new_window'] ? '_blank' : '_self' }}" href="{{ $menu['link'] ?? '' }}">
{{ $menu['name'] }}
@if (isset($menu['badge']) && $menu['badge']['name'])
<span class="badge" style="background-color: {{ $menu['badge']['bg_color'] }}; color: {{ $menu['badge']['text_color'] }}; border-color: {{ $menu['badge']['bg_color'] }}">
{{ $menu['badge']['name'] }}
</span>
@endif
</a>
@if (isset($menu['children_group']) && $menu['children_group'])
<span class="collapsed" data-bs-toggle="collapse" data-bs-target="#flush-menu-{{ $key }}"><i class="bi bi-chevron-down"></i></span>
@endif
</div>
@if (isset($menu['children_group']) && $menu['children_group'])
<div class="accordion-collapse collapse" id="flush-menu-{{ $key }}" data-bs-parent="#menu-accordion">
@forelse ($menu['children_group'] as $group)
<div class="children-group mb-3">
@if ($group['name'])
<div class="group-name">{{ $group['name'] }}</div>
@endif
@if ($group['type'] == 'image')
<a target="{{ isset($group['image']['link']['new_window']) && $group['image']['link']['new_window'] ? '_blank' : '_self' }}" href="{{ $group['image']['link'] }}"><img src="{{ $group['image']['image'] }}" class="img-fluid"></a>
@else
<ul class="nav flex-column ul-children">
@foreach ($group['children'] as $children)
@if (!is_array($children['link']['text']) && $children['link']['text'])
<li class="nav-item">
<a target="{{ isset($children['link']['new_window']) && $children['link']['new_window'] ? '_blank' : '_self' }}" class="nav-link px-0" href="{{ $children['link']['link'] }}">{{ $children['link']['text'] }}</a>
</li>
@endif
@endforeach
</ul>
@endif
</div>
@endforeach
</div>
@endif
</div>
@endif
@endforeach
</div>

View File

@ -0,0 +1,61 @@
<ul class="navbar-nav mx-auto">
@hook('header.menu.before')
@foreach ($menu_content as $menu)
@if ($menu['name'])
<li
class="nav-item {{ isset($menu['children_group']) ? 'dropdown' : '' }} {{ isset($menu['isFull']) && $menu['isFull'] ? 'position-static' : '' }}">
<a class="nav-link fw-bold {{ isset($menu['children_group']) ? 'dropdown-toggle' : '' }}"
target="{{ isset($menu['new_window']) && $menu['new_window'] ? '_blank' : '_self' }}"
href="{{ $menu['link'] ?: 'javascript:void(0)' }}">
{{ $menu['name'] }}
@if (isset($menu['badge']) && $menu['badge']['name'])
<span class="badge"
style="background-color: {{ $menu['badge']['bg_color'] }}; color: {{ $menu['badge']['text_color'] }}; border-color: {{ $menu['badge']['bg_color'] }}">
{{ $menu['badge']['name'] }}
</span>
@endif
</a>
@if (isset($menu['children_group']) && $menu['children_group'])
<div class="dropdown-menu {{ $menu['isFull'] ? 'w-100' : '' }}"
style="min-width: {{ count($menu['children_group']) * 240 }}px">
<div class="card card-lg">
<div class="card-body">
<div class="container">
<div class="row">
@forelse ($menu['children_group'] as $group)
<div class="col-6 col-md">
@if ($group['name'])
<div class="mb-3 fw-bold group-name">{{ $group['name'] }}</div>
@endif
@if ($group['type'] == 'image')
<a
target="{{ isset($group['image']['link']['new_window']) && $group['image']['link']['new_window'] ? '_blank' : '_self' }}"
href="{{ $group['image']['link'] ?: 'javascript:void(0)' }}"><img src="{{ $group['image']['image'] }}"
class="img-fluid"></a>
@else
<ul class="nav flex-column ul-children">
@foreach ($group['children'] as $children)
@if (!is_array($children['link']['text']) && $children['link']['text'])
<li class="nav-item">
<a
target="{{ isset($children['link']['new_window']) && $children['link']['new_window'] ? '_blank' : '_self' }}"
class="nav-link px-0"
href="{{ $children['link']['link'] ?: 'javascript:void(0)' }}">{{ $children['link']['text'] }}</a>
</li>
@endif
@endforeach
</ul>
@endif
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
@endif
</li>
@endif
@endforeach
@hook('header.menu.after')
</ul>

View File

@ -0,0 +1,43 @@
@if ($paginator->hasPages())
<nav class="d-flex justify-content-center">
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span class="page-link" aria-hidden="true">&lsaquo;</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span class="page-link" aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@ -0,0 +1,46 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span aria-hidden="true">&lsaquo;</span>
</li>
@else
<li>
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="disabled" aria-disabled="true"><span>{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="active" aria-current="page"><span>{{ $page }}</span></li>
@else
<li><a href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li>
<a href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@ -0,0 +1,36 @@
@if ($paginator->hasPages())
<div class="ui pagination menu" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
@else
<a class="icon item" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<a class="icon item disabled" aria-disabled="true">{{ $element }}</a>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<a class="item active" href="{{ $url }}" aria-current="page">{{ $page }}</a>
@else
<a class="item" href="{{ $url }}">{{ $page }}</a>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a class="icon item" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
@else
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
@endif
</div>
@endif

View File

@ -0,0 +1,27 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.previous')</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
</li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.next')</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@ -0,0 +1,19 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled" aria-disabled="true"><span>@lang('pagination.previous')</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a></li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a></li>
@else
<li class="disabled" aria-disabled="true"><span>@lang('pagination.next')</span></li>
@endif
</ul>
</nav>
@endif

View File

@ -0,0 +1,25 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="Pagination Navigation" class="flex justify-between">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
{!! __('pagination.previous') !!}
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
{!! __('pagination.previous') !!}
</a>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
{!! __('pagination.next') !!}
</a>
@else
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
{!! __('pagination.next') !!}
</span>
@endif
</nav>
@endif

View File

@ -0,0 +1,106 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex items-center justify-between">
<div class="flex justify-between flex-1 sm:hidden">
@if ($paginator->onFirstPage())
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
{!! __('pagination.previous') !!}
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
{!! __('pagination.previous') !!}
</a>
@endif
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
{!! __('pagination.next') !!}
</a>
@else
<span class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
{!! __('pagination.next') !!}
</span>
@endif
</div>
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
<div>
<p class="text-sm text-gray-700 leading-5">
{!! __('Showing') !!}
@if ($paginator->firstItem())
<span class="font-medium">{{ $paginator->firstItem() }}</span>
{!! __('to') !!}
<span class="font-medium">{{ $paginator->lastItem() }}</span>
@else
{{ $paginator->count() }}
@endif
{!! __('of') !!}
<span class="font-medium">{{ $paginator->total() }}</span>
{!! __('results') !!}
</p>
</div>
<div>
<span class="relative z-0 inline-flex shadow-sm rounded-md">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
<span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5" aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</span>
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</a>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<span aria-disabled="true">
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5">{{ $element }}</span>
</span>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<span aria-current="page">
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5">{{ $page }}</span>
</span>
@else
<a href="{{ $url }}" class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
{{ $page }}
</a>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</a>
@else
<span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
<span class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5" aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</span>
</span>
@endif
</span>
</div>
</div>
</nav>
@endif

View File

@ -0,0 +1,63 @@
<div class="product-wrap {{ request('style_list') ?? '' }}">
<div class="image">
<a href="{{ $product['url'] }}">
<div class="image-old">
<img src="{{ $product['images'][0] ?? image_resize('', 400, 400) }}" class="img-fluid">
</div>
</a>
@if (!request('style_list') || request('style_list') == 'grid')
<div class="button-wrap">
<button
class="btn btn-dark text-light mx-1 rounded-3"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ __('shop/products.add_to_favorites') }}"
data-in-wishlist="{{ $product['in_wishlist'] }}"
onclick="bk.addWishlist('{{ $product['id'] }}', this)">
<i class="bi bi-heart{{ $product['in_wishlist'] ? '-fill' : '' }}"></i>
</button>
<button
class="btn btn-dark text-light mx-1 rounded-3"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ __('shop/products.add_to_cart') }}"
onclick="bk.addCart({sku_id: '{{ $product['sku_id'] }}'}, this)">
<i class="bi bi-cart"></i>
</button>
</div>
@endif
</div>
<div class="product-bottom-info">
<div class="product-name">{{ $product['name_format'] }}</div>
<div class="product-price">
<span class="price-new">{{ $product['price_format'] }}</span>
<span>-</span>
@if ($product['price'] != $product['origin_price'] && $product['origin_price'] > 0)
<span class="price-new">{{ $product['origin_price_format'] }}</span>
@endif
<span style="color:#aaa">/pieces</span>
</div>
<!--yt修改-->
<div class="product-price">
<span class="price-new">1 pieces</span>
<span style="color:#aaa;margin-left:4px">(Min Order)</span>
</div>
@if (request('style_list') == 'list')
<div class="button-wrap mt-3">
<button
class="btn btn-dark text-light"
onclick="bk.addCart({sku_id: '{{ $product['sku_id'] }}'}, this)">
<i class="bi bi-cart"></i>
{{ __('shop/products.add_to_cart') }}
</button>
</div>
<div>
<button class="btn btn-link ps-0 text-secondary" data-in-wishlist="{{ $product['in_wishlist'] }}" onclick="bk.addWishlist('{{ $product['id'] }}', this)">
<i class="bi bi-heart{{ $product['in_wishlist'] ? '-fill' : '' }} me-1"></i> {{ __('shop/products.add_to_favorites') }}
</button>
</div>
@endif
</div>
</div>

View File

@ -0,0 +1,7 @@
<div class="quantity-wrap">
<input type="text" class="form-control" onkeyup="this.value=this.value.replace(/\D/g,'')" value="{{ isset($quantity) ? $quantity : 1 }}" name="quantity" minimum="{{ isset($minimum) ? $minimum : 1 }}">
<div class="right">
<i class="bi bi-chevron-up"></i>
<i class="bi bi-chevron-down"></i>
</div>
</div>

View File

@ -0,0 +1,18 @@
<div class="steps-wrap">
<div class="{{ $steps == 1 || $steps == 2 || $steps == 3 || $steps == 4 ? 'active':'' }}">
<div class="number-wrap"><span class="number">1</span></div>
<span class="title">{{ __('shop/steps.cart') }}</span>
</div>
<div class="{{ $steps == 2 || $steps == 3 || $steps == 4 ? 'active':'' }}">
<div class="number-wrap"><span class="number">2</span></div>
<span class="title">{{ __('shop/steps.checkout') }}</span>
</div>
<div class="{{ $steps == 3 || $steps == 4 ? 'active':'' }}">
<div class="number-wrap"><span class="number">3</span></div>
<span class="title">{{ __('shop/steps.submitted_successfully') }}</span>
</div>
<div class="{{ $steps == 4 ? 'active':'' }}">
<div class="number-wrap"><span class="number">4</span></div>
<span class="title">{{ __('shop/steps.payment') }}</span>
</div>
</div>