This commit is contained in:
pushuo 2022-07-01 10:36:38 +08:00
parent 297eb25225
commit 2b18477df1
17 changed files with 827 additions and 656 deletions

View File

@ -28,6 +28,7 @@ class CustomerController extends Controller
$data = [
'customers' => CustomerResource::collection($customers),
'customer_groups' => CustomerGroupRepo::list(),
];
return view('admin::pages.customers.index', $data);

View File

@ -13,6 +13,7 @@ namespace Beike\Shop\Services;
use Beike\Repositories\AddressRepo;
use Beike\Repositories\SettingRepo;
use Beike\Repositories\CountryRepo;
class CheckoutService
{
@ -30,6 +31,9 @@ class CheckoutService
$data = [
'addresses' => $addresses,
'shipments' => $shipments,
'country_id' => setting('country_id'),
'customer_id' => $customer->id,
'countries' => CountryRepo::all(),
'payments' => $payments,
'carts' => $carts
];

View File

@ -437,3 +437,7 @@ table.table.table-striped > tbody > tr:nth-of-type(2n) {
.el-tabs__header {
margin-bottom: 25px;
}
.el-tabs__item {
padding: 0 10px;
}

View File

@ -469,7 +469,7 @@ body.page-cart .total-wrap .list-group li .total-price {
font-weight: bold;
}
body.page-checkout h4.title {
body.page-checkout .module-title {
border-bottom: 1px solid #e5e5e5;
padding-bottom: 16px;
margin-bottom: 16px;
@ -551,10 +551,10 @@ body.page-checkout .addresses-wrap {
}
body.page-checkout .addresses-wrap .item {
position: relative;
padding: 20px 20px 30px;
padding: 10px 20px;
margin-bottom: 10px;
border: 1px solid #e8e8e8;
height: 155px;
height: 125px;
cursor: pointer;
}
body.page-checkout .addresses-wrap .item.add-addres {
@ -586,6 +586,7 @@ body.page-checkout .addresses-wrap .item.active:before {
}
body.page-checkout .addresses-wrap .item .name-wrap {
margin-bottom: 0.5rem;
line-height: 1;
}
body.page-checkout .addresses-wrap .item .name-wrap .name {
font-size: 1rem;
@ -596,10 +597,15 @@ body.page-checkout .addresses-wrap .item .name-wrap .phone {
color: #666;
}
body.page-checkout .addresses-wrap .item .zipcode {
margin-bottom: 0.5rem;
margin-bottom: 0.1rem;
}
body.page-checkout .addresses-wrap .item .address-info {
margin-bottom: 0.5rem;
margin-bottom: 0.9rem;
}
body.page-checkout .addresses-wrap .item .address-bottom {
display: flex;
align-items: center;
justify-content: space-between;
}
body.page-checkout .addresses-wrap .item .address-bottom a {
color: #2d68a8;

View File

@ -10,4 +10,8 @@
.el-tabs__header {
margin-bottom: 25px;
}
.el-tabs__item {
padding: 0 10px;
}

View File

@ -3,64 +3,64 @@
@section('title', '分类管理')
@push('header')
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.min.js"></script>
@endpush
@section('content')
<div id="app">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>编辑分类</span>
</div>
<div id="app">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>编辑分类</span>
</div>
<el-form label-width="200px" size="small1">
<el-form label-width="200px" size="small1">
<el-form-item label="分类名称">
<div style="max-width: 400px">
@foreach (locales() as $locale)
<el-input class="mb-1">
<template slot="append">{{ $locale['name'] }}</template>
</el-input>
@endforeach
</div>
</el-form-item>
<el-form-item label="分类名称">
<div style="max-width: 400px">
@foreach (locales() as $locale)
<el-input class="mb-1">
<template slot="append">{{ $locale['name'] }}</template>
</el-input>
@endforeach
</div>
</el-form-item>
<el-form-item label="分类描述">
<div style="max-width: 400px">
@foreach (locales() as $locale)
<el-input v-model="form.descriptions['{{ $locale['code'] }}'].content" class="mb-1">
<template slot="append">{{ $locale['name'] }}</template>
</el-input>
@endforeach
</div>
</el-form-item>
<el-form-item label="分类描述">
<div style="max-width: 400px">
@foreach (locales() as $locale)
<el-input v-model="form.descriptions['{{ $locale['code'] }}'].content" class="mb-1">
<template slot="append">{{ $locale['name'] }}</template>
</el-input>
@endforeach
</div>
</el-form-item>
<el-form-item label="上级分类">
<el-select v-model="form.parent_id" placeholder="请选择上级分类">
@foreach ($categories as $_category)
<el-option label="{{ $_category->name }}" value="{{ $_category->id }}"></el-option>
@endforeach
</el-select>
</el-form-item>
<el-form-item label="上级分类">
<el-select v-model="form.parent_id" placeholder="请选择上级分类">
@foreach ($categories as $_category)
<el-option label="{{ $_category->name }}" value="{{ $_category->id }}"></el-option>
@endforeach
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.active">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.active">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
<el-form-item>
<el-button type="primary" @click="save">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
@endsection
@push('footer')
<script>
<script>
new Vue({
el: '#app',
data() {
@ -92,6 +92,5 @@
}
}
});
</script>
</script>
@endpush

View File

@ -3,52 +3,52 @@
@section('title', '分类管理')
@section('content')
<div id="category-app" class="card">
<div class="card-header">
编辑分类
</div>
<div class="card-body">
<form action="{{ admin_route($category->id ? 'categories.update' : 'categories.store', $category) }}"
method="POST">
@csrf
@method($category->id ? 'PUT' : 'POST')
<input type="hidden" name="_redirect" value="{{ $_redirect }}">
@foreach (locales() as $index => $locale)
{{-- <input type="hidden" name="descriptions[{{ $index }}][locale]" value="{{ $locale['code'] }}"> --}}
@endforeach
<x-admin-form-input-locale name="descriptions.*.name" title="名称" :value="$descriptions" required/>
<x-admin-form-input-locale name="descriptions.*.content" title="内容" :value="$descriptions"/>
<x-admin::form.row title="上级分类">
@php
$_parent_id = old('parent_id', $category->parent_id ?? 0);
@endphp
<select name="parent_id" id="" class="form-control short">
<option value="0">--请选择--</option>
@foreach ($categories as $_category)
<option value="{{ $_category->id }}" {{ $_parent_id == $_category->id ? 'selected' : ''}}>
{{ $_category->name }}
</option>
@endforeach
</select>
</x-admin::form.row>
<x-admin-form-switch title="状态" name="active" :value="old('active', $category->active ?? 1)"/>
<x-admin::form.row>
<button type="submit" class="btn btn-primary">保存</button>
<a href="{{ $_redirect }}" class="btn btn-outline-secondary">返回</a>
</x-admin::form.row>
</form>
</div>
<div id="category-app" class="card">
<div class="card-header">
编辑分类
</div>
<div class="card-body">
<form action="{{ admin_route($category->id ? 'categories.update' : 'categories.store', $category) }}"
method="POST">
@csrf
@method($category->id ? 'PUT' : 'POST')
<input type="hidden" name="_redirect" value="{{ $_redirect }}">
@foreach (locales() as $index => $locale)
{{-- <input type="hidden" name="descriptions[{{ $index }}][locale]" value="{{ $locale['code'] }}"> --}}
@endforeach
<x-admin-form-input-locale name="descriptions.*.name" title="名称" :value="$descriptions" required />
<x-admin-form-input-locale name="descriptions.*.content" title="内容" :value="$descriptions" />
<x-admin::form.row title="上级分类">
@php
$_parent_id = old('parent_id', $category->parent_id ?? 0);
@endphp
<select name="parent_id" id="" class="form-control short">
<option value="0">--请选择--</option>
@foreach ($categories as $_category)
<option value="{{ $_category->id }}" {{ $_parent_id == $_category->id ? 'selected' : '' }}>
{{ $_category->name }}
</option>
@endforeach
</select>
</x-admin::form.row>
<x-admin-form-switch title="状态" name="active" :value="old('active', $category->active ?? 1)" />
<x-admin::form.row>
<button type="submit" class="btn btn-primary">保存</button>
<a href="{{ $_redirect }}" class="btn btn-outline-secondary">返回</a>
</x-admin::form.row>
</form>
</div>
</div>
@endsection
@push('footer')
<script>
<script>
new Vue({
el: '#category-app',
data() {
@ -101,6 +101,5 @@
}
}
});
</script>
</script>
@endpush

View File

@ -3,37 +3,37 @@
@section('title', '分类管理')
@push('header')
<style>
.el-tree-node__content {
height: 32px;
border-bottom: 1px solid #f9f9f9;
}
</style>
<style>
.el-tree-node__content {
height: 32px;
border-bottom: 1px solid #f9f9f9;
}
</style>
@endpush
@section('content')
<div id="category-app" class="card">
<div class="card-body">
<a href="{{ admin_route('categories.create') }}" class="btn btn-primary">创建分类</a>
<div class="mt-4" style="">
<el-tree :data="categories" default-expand-all :expand-on-click-node="false">
<div class="custom-tree-node" slot-scope="{ node, data }" style="flex:1;display:flex">
<span>@{{ data.name }}</span>
<div style="flex:1"></div>
<span class="mr-4">@{{ data.active ? '启用' : '禁用' }}</span>
<div>
<a :href="data.url_edit">编辑</a>
<a>删除</a>
</div>
</div>
</el-tree>
<div id="category-app" class="card">
<div class="card-body">
<a href="{{ admin_route('categories.create') }}" class="btn btn-primary">创建分类</a>
<div class="mt-4" style="">
<el-tree :data="categories" default-expand-all :expand-on-click-node="false">
<div class="custom-tree-node" slot-scope="{ node, data }" style="flex:1;display:flex">
<span>@{{ data.name }}</span>
<div style="flex:1"></div>
<span class="mr-4">@{{ data.active ? '启用' : '禁用' }}</span>
<div>
<a :href="data.url_edit">编辑</a>
<a>删除</a>
</div>
</div>
</div>
</el-tree>
</div>
</div>
</div>
@endsection
@push('footer')
<script>
<script>
new Vue({
el: '#category-app',
data: {
@ -50,6 +50,5 @@
}
}
});
</script>
</script>
@endpush

View File

@ -5,73 +5,76 @@
@section('content')
<div id="currency-app-form" class="card">
<div class="card-body">
<form action="{{ admin_route('currencies.store') }}" method="post">
@csrf
<form action="{{ admin_route('currencies.store') }}" method="post">
@csrf
<div class="form-group">
<label class="form-label" id="name">名称</label>
<input type="input" name="name" value="{{ old('name') }}" class="form-control" placeholder="名称">
@error('name')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="name">名称</label>
<input type="input" name="name" value="{{ old('name') }}" class="form-control" placeholder="名称">
@error('name')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="code">编码</label>
<input type="input" name="code" value="{{ old('code') }}" class="form-control" placeholder="编码">
@error('code')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="code">编码</label>
<input type="input" name="code" value="{{ old('code') }}" class="form-control" placeholder="编码">
@error('code')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="symbol_left">左符号</label>
<input type="input" name="symbol_left" value="{{ old('symbol_left') }}" class="form-control" placeholder="左符号">
@error('symbol_left')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="symbol_left">左符号</label>
<input type="input" name="symbol_left" value="{{ old('symbol_left') }}" class="form-control"
placeholder="左符号">
@error('symbol_left')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="symbol_right">右符号</label>
<input type="input" name="symbol_right" value="{{ old('symbol_right') }}" class="form-control" placeholder="右符号">
@error('symbol_right')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="symbol_right">右符号</label>
<input type="input" name="symbol_right" value="{{ old('symbol_right') }}" class="form-control"
placeholder="右符号">
@error('symbol_right')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="decimal_place">小数位数</label>
<input type="input" name="decimal_place" value="{{ old('decimal_place') }}" class="form-control" placeholder="小数位数">
@error('decimal_place')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="decimal_place">小数位数</label>
<input type="input" name="decimal_place" value="{{ old('decimal_place') }}" class="form-control"
placeholder="小数位数">
@error('decimal_place')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="value">汇率值</label>
<input type="input" name="value" value="{{ old('value') }}" class="form-control" placeholder="汇率值">
@error('value')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="value">汇率值</label>
<input type="input" name="value" value="{{ old('value') }}" class="form-control" placeholder="汇率值">
@error('value')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="status">状态</label>
<input type="input" name="status" class="form-control" placeholder="状态">
@error('status')
<x-admin::form.error :message="$message" />
@enderror
</div>
<div class="form-group">
<label class="form-label" id="status">状态</label>
<input type="input" name="status" class="form-control" placeholder="状态">
@error('status')
<x-admin::form.error :message="$message" />
@enderror
</div>
@if (session('error'))
<div class="alert alert-success">
{{ session('error') }}
</div>
@endif
@if (session('error'))
<div class="alert alert-success">
{{ session('error') }}
</div>
@endif
<button type="submit" class="btn btn-primary mb-4">确定</button>
</form>
<button type="submit" class="btn btn-primary mb-4">确定</button>
</form>
</div>
</div>
@endsection

View File

@ -3,43 +3,44 @@
@section('title', '货币管理')
@section('content')
<div id="customer-app" class="card">
<div class="card-body">
<div class="d-flex justify-content-between my-4">
<a href="{{ admin_route('currencies.create') }}" class="btn btn-primary">创建</a>
</div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>名称</th>
<th>编码</th>
<th>货币左符号</th>
<th>货币右符号</th>
<th>小数位数</th>
<th>汇率值</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach ($currencies as $currency)
<tr>
<td>{{ $currency['id'] }}</td>
<td>{{ $currency['name'] }}</td>
<td>{{ $currency['code'] }}</td>
<td>{{ $currency['symbol_left'] }}</td>
<td>{{ $currency['symbol_right'] }}</td>
<td>{{ $currency['decimal_place'] }}</td>
<td>{{ $currency['value'] }}</td>
<td>{{ $currency['status'] }}</td>
<td>
<a class="btn btn-outline-secondary btn-sm" href="{{ admin_route('currencies.edit', [$currency['id']]) }}">编辑</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div id="customer-app" class="card">
<div class="card-body">
<div class="d-flex justify-content-between my-4">
<a href="{{ admin_route('currencies.create') }}" class="btn btn-primary">创建</a>
</div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>名称</th>
<th>编码</th>
<th>货币左符号</th>
<th>货币右符号</th>
<th>小数位数</th>
<th>汇率值</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach ($currencies as $currency)
<tr>
<td>{{ $currency['id'] }}</td>
<td>{{ $currency['name'] }}</td>
<td>{{ $currency['code'] }}</td>
<td>{{ $currency['symbol_left'] }}</td>
<td>{{ $currency['symbol_right'] }}</td>
<td>{{ $currency['decimal_place'] }}</td>
<td>{{ $currency['value'] }}</td>
<td>{{ $currency['status'] }}</td>
<td>
<a class="btn btn-outline-secondary btn-sm"
href="{{ admin_route('currencies.edit', [$currency['id']]) }}">编辑</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection

View File

@ -54,14 +54,17 @@
<td>222</td>
<td>222</td>
<td>
<button class="btn btn-outline-secondary btn-sm" type="button" @click="editAddress(index)">编辑</button>
<button class="btn btn-outline-danger btn-sm ml-1" type="button" @click="deleteAddress(address.id, index)">删除</button>
<button class="btn btn-outline-secondary btn-sm" type="button"
@click="editAddress(index)">编辑</button>
<button class="btn btn-outline-danger btn-sm ml-1" type="button"
@click="deleteAddress(address.id, index)">删除</button>
</td>
</tbody>
<tbody v-else>
<tr>
<td colspan="6" class="text-center">
<span class="me-2">当前账号无地址</span> <el-link type="primary" @click="editAddress">新增地址</el-link>
<span class="me-2">当前账号无地址</span>
<el-link type="primary" @click="editAddress">新增地址</el-link>
</td>
</tbody>
</table>
@ -70,7 +73,8 @@
</el-form>
</div>
<el-dialog title="编辑地址" :visible.sync="dialogAddress.show" width="600px">
<el-dialog title="编辑地址" :visible.sync="dialogAddress.show" width="600px"
@close="closeAddressDialog('addressForm')">
<el-form ref="addressForm" :rules="addressRules" :model="dialogAddress.form" label-width="100px">
<el-form-item label="姓名" prop="name">
<el-input v-model="dialogAddress.form.name"></el-input>
@ -163,20 +167,44 @@
},
rules: {
name: [{required: true, message: '请输入用户名', trigger: 'blur'}, ],
name: [{
required: true,
message: '请输入用户名',
trigger: 'blur'
}, ],
},
addressRules: {
name: [{required: true, message: '请输入姓名', trigger: 'blur'}, ],
phone: [{required: true, message: '请输入联系电话', trigger: 'blur'}, ],
address_1: [{required: true, message: '请输入详细地址 1', trigger: 'blur'}, ],
zone_id: [{required: true, message: '请选择省份', trigger: 'blur'}, ],
city_id: [{required: true, message: '请填写 city', trigger: 'blur'}, ],
name: [{
required: true,
message: '请输入姓名',
trigger: 'blur'
}, ],
phone: [{
required: true,
message: '请输入联系电话',
trigger: 'blur'
}, ],
address_1: [{
required: true,
message: '请输入详细地址 1',
trigger: 'blur'
}, ],
zone_id: [{
required: true,
message: '请选择省份',
trigger: 'blur'
}, ],
city_id: [{
required: true,
message: '请填写 city',
trigger: 'blur'
}, ],
}
},
// 在挂载开始之前被调用:相关的 render 函数首次被调用
beforeMount () {
beforeMount() {
this.countryChange(this.dialogAddress.form.country_id);
},
@ -190,12 +218,12 @@
return;
}
$.ajax({
url: `/admin/countries/${e}/zones`,
type: 'get',
url: `/admin/customers/{{ $customer['id'] }}`,
type: 'put',
data: self.form,
success: function(res) {
this.$message.success('提交成功');
self.$message.success(res.message);
}
})
});

View File

@ -3,42 +3,144 @@
@section('title', '顾客管理')
@section('content')
<div id="customer-app" class="card">
<div class="card-body">
<div class="d-flex justify-content-between my-4">
<a href="{{ admin_route('customers.create') }}" class="btn btn-primary">创建顾客</a>
</div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>邮箱</th>
<th>名称</th>
<th>注册来源</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach ($customers as $customer)
<tr>
<td>{{ $customer['id'] }}</td>
<td>{{ $customer['email'] }}</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ $customer['avatar'] }}" class="img-fluid rounded-circle me-2" style="width: 40px;">
<div>{{ $customer['name'] }}</div>
</div>
</td>
<td>{{ $customer['from'] }}</td>
<td>{{ $customer['status'] }}</td>
<td>
<a class="btn btn-outline-secondary btn-sm" href="{{ admin_route('customers.edit', [$customer['id']]) }}">编辑</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div id="customer-app" class="card" v-cloak>
<div class="card-body">
<div class="d-flex justify-content-between mb-4">
<button type="button" class="btn btn-primary" @click="checkedCustomersCreate">创建顾客</button>
</div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>邮箱</th>
<th>名称</th>
<th>注册来源</th>
<th>客户组</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="customer, index in customers" :key="index">
<td>@{{ customer.id }}</td>
<td>@{{ customer.email }}</td>
<td>
<div class="d-flex align-items-center">
{{-- <img src="@{{ customer.avatar }}" class="img-fluid rounded-circle me-2" style="width: 40px;"> --}}
<div>@{{ customer.name }}</div>
</div>
</td>
<td>@{{ customer.from }}</td>
<td>@{{ customer.customer_group_name }}</td>
<td>
<el-tag :type="customer.status ? 'success' : 'info'" size="small">@{{ customer.status ? '启用' : '禁用' }}</el-tag>
<td>
<a class="btn btn-outline-secondary btn-sm" :href="customer.href">编辑</a>
<button class="btn btn-outline-danger btn-sm ml-1" type="button" @click="deleteCustomer(customer.id, index)">删除</button>
</td>
</tr>
</tbody>
</table>
</div>
@endsection
<el-dialog title="创建顾客" :visible.sync="dialogCustomers.show" width="600px"
@close="closeCustomersDialog('form')">
<el-form ref="form" :rules="rules" :model="dialogCustomers.form" label-width="100px">
<el-form-item label="用户名" prop="name">
<el-input v-model="dialogCustomers.form.name"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="dialogCustomers.form.email"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="dialogCustomers.form.password"></el-input>
</el-form-item>
<el-form-item label="用户组">
<el-select v-model="dialogCustomers.form.customer_group_id" placeholder="请选择">
<el-option v-for="item in source.customer_group" :key="item.id" :label="item.description.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch v-model="dialogCustomers.form.status" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addCustomersFormSubmit('form')">保存</el-button>
<el-button @click="closeCustomersDialog('form')">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
@endsection
@push('footer')
<script>
new Vue({
el: '#customer-app',
data: {
customers: @json($customers ?? []),
source: {
customer_group: @json($customer_groups ?? []),
},
dialogCustomers: {
show: false,
form: {
id: null,
name: '',
email: '',
password: '',
customer_group_id: 1,
status: 1,
},
},
rules: {
name: [{required: true,message: '请输入用户名',trigger: 'blur'}, ],
}
},
beforeMount() {
},
methods: {
checkedCustomersCreate() {
this.dialogCustomers.show = true
},
addCustomersFormSubmit(form) {
const self = this;
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message.error('请检查表单是否填写正确');
return;
}
$.ajax({
url: `/admin/customers`,
type: 'post',
data: self.dialogCustomers.form,
success: function(res) {
self.$message.success(res.message);
}
})
});
},
deleteCustomer(id, index) {
console.log(id, index)
},
closeCustomersDialog(form) {
this.$refs[form].resetFields();
this.dialogCustomers.show = false
}
}
})
</script>
@endpush

View File

@ -3,13 +3,13 @@
@section('title', '后台管理')
@section('content')
{{-- <a href="{{ route('admin.products.index') }}">Products</a> --}}
@for ($i = 0; $i < 10; $i++)
<div class="card mb-3">
<div class="card-header">订单统计</div>
<div class="card-body">
<div>11</div>
</div>
</div>
@endfor
{{-- <a href="{{ route('admin.products.index') }}">Products</a> --}}
@for ($i = 0; $i < 10; $i++)
<div class="card mb-3">
<div class="card-header">订单统计</div>
<div class="card-body">
<div>11</div>
</div>
</div>
@endfor
@endsection

View File

@ -1,145 +1,141 @@
@extends('admin::layouts.master')
@push('header')
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
@endpush
@section('content')
<div class="card">
<div class="card-body">
<h2>product</h2>
<form action="{{ $product->id ? route('admin.products.update', $product) : route('admin.products.store') }}"
method="POST" id="app">
@csrf
@method($product->id ? 'PUT' : 'POST')
<input type="hidden" name="_redirect" value="{{ $_redirect }}"/>
<div class="card">
<div class="card-body">
<h2>product</h2>
<form action="{{ $product->id ? route('admin.products.update', $product) : route('admin.products.store') }}"
method="POST" id="app">
@csrf
@method($product->id ? 'PUT' : 'POST')
<input type="hidden" name="_redirect" value="{{ $_redirect }}" />
@foreach (locales() as $index => $locale)
{{-- <input type="hidden" name="descriptions[{{ $index }}][locale]" value="{{ $locale['code'] }}"> --}}
@endforeach
@foreach (locales() as $index => $locale)
{{-- <input type="hidden" name="descriptions[{{ $index }}][locale]" value="{{ $locale['code'] }}"> --}}
@endforeach
<x-admin-form-input-locale name="descriptions.*.name" title="名称" :value="$descriptions" required/>
<x-admin-form-input name="image" title="主图" :value="old('image', $product->image ?? '')"/>
<x-admin-form-input name="video" title="视频" :value="old('video', $product->video ?? '')"/>
<x-admin-form-input name="position" title="排序" :value="old('position', $product->position ?? '')"/>
<x-admin-form-switch name="active" title="状态" :value="old('active', $product->active ?? 1)"/>
<x-admin-form-input-locale name="descriptions.*.name" title="名称" :value="$descriptions" required />
<x-admin-form-input name="image" title="主图" :value="old('image', $product->image ?? '')" />
<x-admin-form-input name="video" title="视频" :value="old('video', $product->video ?? '')" />
<x-admin-form-input name="position" title="排序" :value="old('position', $product->position ?? '')" />
<x-admin-form-switch name="active" title="状态" :value="old('active', $product->active ?? 1)" />
<x-admin::form.row title="分类">
@foreach ($source['categories'] as $_category)
<div class="form-check">
<input class="form-check-input" type="checkbox" name="categories[]" value="{{ $_category->id }}" id="category-{{ $_category->id }}" {{ in_array($_category->id, $category_ids) ? 'checked' : '' }}>
<label class="form-check-label" for="category-{{ $_category->id }}">
{{ $_category->name }}
</label>
</div>
@endforeach
</x-admin::form.row>
<x-admin::form.row title="分类">
@foreach ($source['categories'] as $_category)
<div class="form-check">
<input class="form-check-input" type="checkbox" name="categories[]" value="{{ $_category->id }}"
id="category-{{ $_category->id }}" {{ in_array($_category->id, $category_ids) ? 'checked' : '' }}>
<label class="form-check-label" for="category-{{ $_category->id }}">
{{ $_category->name }}
</label>
</div>
@endforeach
</x-admin::form.row>
<div>
<h2>skus</h2>
<input type="radio" v-model="editing.isVariable" :value="false"> 单规格
<input type="radio" v-model="editing.isVariable" :value="true"> 多规格
<div v-if="editing.isVariable">
<div>
<div v-for="(variant, variantIndex) in source.variables">
<div>
<h2>skus</h2>
<input type="radio" v-model="editing.isVariable" :value="false"> 单规格
<input type="radio" v-model="editing.isVariable" :value="true"> 多规格
<div v-if="editing.isVariable">
<div>
<div v-for="(variant, variantIndex) in source.variables">
<div>
<input type="text" v-model="variant.name" placeholder="variant name">
<input type="text" v-model="variant.name" placeholder="variant name">
<div v-for="(value, valueIndex) in variant.values">
<input v-model="variant.values[valueIndex].name" type="text"
placeholder="variant value name">
</div>
<button type="button" @click="addVariantValue(variantIndex)">Add value</button>
</div>
</div>
<button type="button" @click="addVariant">Add variant</button>
</div>
<div v-if="form.skus.length">
<input v-if="form.skus.length" type="hidden" name="variables"
:value="JSON.stringify(form.variables)">
<table>
<thead>
<th v-for="(variant, index) in form.variables" :key="'pv-header-'+index">
@{{ variant.name || 'No name' }}
</th>
<th>image</th>
<th>model</th>
<th>sku</th>
<th>price</th>
<th>orgin price</th>
<th>cost price</th>
<th>quantity</th>
</thead>
<tbody>
<tr v-for="(sku, skuIndex) in form.skus">
<template v-for="(variantValueIndex, j) in sku.variants">
<td v-if="skuIndex % variantValueRepetitions[j] == 0"
:key="'pvv'+skuIndex+'-'+j" :rowspan="variantValueRepetitions[j]">
<span>@{{ form.variables[j].values[variantValueIndex].name || 'No name' }}</span>
</td>
</template>
<td>
<input type="text" v-model="sku.image" :name="'skus[' + skuIndex + '][image]'"
placeholder="image">
<input type="hidden" :name="'skus[' + skuIndex + '][is_default]'"
:value="skuIndex == 0 ? 1 : 0">
<input v-for="(variantValueIndex, j) in sku.variants" type="hidden"
:name="'skus[' + skuIndex + '][variants][' + j + ']'"
:value="variantValueIndex">
</td>
<td><input type="text" v-model="sku.model" :name="'skus[' + skuIndex + '][model]'"
placeholder="model"></td>
<td><input type="text" v-model="sku.sku" :name="'skus[' + skuIndex + '][sku]'"
placeholder="sku"></td>
<td><input type="text" v-model="sku.price" :name="'skus[' + skuIndex + '][price]'"
placeholder="price"></td>
<td><input type="text" v-model="sku.origin_price"
:name="'skus[' + skuIndex + '][origin_price]'"
placeholder="origin_price"></td>
<td><input type="text" v-model="sku.cost_price"
:name="'skus[' + skuIndex + '][cost_price]'" placeholder="cost_price">
</td>
<td><input type="text" v-model="sku.quantity"
:name="'skus[' + skuIndex + '][quantity]'" placeholder="quantity"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-if="!editing.isVariable">
<div>
<input type="text" name="skus[0][image]" placeholder="image"
value="{{ old('skus.0.image', $product->skus[0]->image ?? '') }}">
<input type="text" name="skus[0][model]" placeholder="model"
value="{{ old('skus.0.model', $product->skus[0]->model ?? '') }}">
<input type="text" name="skus[0][sku]" placeholder="sku"
value="{{ old('skus.0.sku', $product->skus[0]->sku ?? '') }}">
<input type="text" name="skus[0][price]" placeholder="price"
value="{{ old('skus.0.price', $product->skus[0]->price ?? '') }}">
<input type="text" name="skus[0][origin_price]" placeholder="origin_price"
value="{{ old('skus.0.origin_price', $product->skus[0]->origin_price ?? '') }}">
<input type="text" name="skus[0][cost_price]" placeholder="cost_price"
value="{{ old('skus.0.cost_price', $product->skus[0]->cost_price ?? '') }}">
<input type="text" name="skus[0][quantity]" placeholder="quantity"
value="{{ old('skus.0.quantity', $product->skus[0]->quantity ?? '') }}">
<input type="hidden" name="skus[0][variants]" placeholder="variants" value="">
<input type="hidden" name="skus[0][position]" placeholder="position" value="0">
<input type="hidden" name="skus[0][is_default]" placeholder="is_default" value="1">
</div>
</div>
<div v-for="(value, valueIndex) in variant.values">
<input v-model="variant.values[valueIndex].name" type="text" placeholder="variant value name">
</div>
<button type="button" @click="addVariantValue(variantIndex)">Add value</button>
</div>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
<button type="button" @click="addVariant">Add variant</button>
</div>
<div v-if="form.skus.length">
<input v-if="form.skus.length" type="hidden" name="variables" :value="JSON.stringify(form.variables)">
<table>
<thead>
<th v-for="(variant, index) in form.variables" :key="'pv-header-' + index">
@{{ variant.name || 'No name' }}
</th>
<th>image</th>
<th>model</th>
<th>sku</th>
<th>price</th>
<th>orgin price</th>
<th>cost price</th>
<th>quantity</th>
</thead>
<tbody>
<tr v-for="(sku, skuIndex) in form.skus">
<template v-for="(variantValueIndex, j) in sku.variants">
<td v-if="skuIndex % variantValueRepetitions[j] == 0" :key="'pvv' + skuIndex + '-' + j"
:rowspan="variantValueRepetitions[j]">
<span>@{{ form.variables[j].values[variantValueIndex].name || 'No name' }}</span>
</td>
</template>
<td>
<input type="text" v-model="sku.image" :name="'skus[' + skuIndex + '][image]'"
placeholder="image">
<input type="hidden" :name="'skus[' + skuIndex + '][is_default]'" :value="skuIndex == 0 ? 1 : 0">
<input v-for="(variantValueIndex, j) in sku.variants" type="hidden"
:name="'skus[' + skuIndex + '][variants][' + j + ']'" :value="variantValueIndex">
</td>
<td><input type="text" v-model="sku.model" :name="'skus[' + skuIndex + '][model]'"
placeholder="model"></td>
<td><input type="text" v-model="sku.sku" :name="'skus[' + skuIndex + '][sku]'" placeholder="sku">
</td>
<td><input type="text" v-model="sku.price" :name="'skus[' + skuIndex + '][price]'"
placeholder="price"></td>
<td><input type="text" v-model="sku.origin_price" :name="'skus[' + skuIndex + '][origin_price]'"
placeholder="origin_price"></td>
<td><input type="text" v-model="sku.cost_price" :name="'skus[' + skuIndex + '][cost_price]'"
placeholder="cost_price">
</td>
<td><input type="text" v-model="sku.quantity" :name="'skus[' + skuIndex + '][quantity]'"
placeholder="quantity"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-if="!editing.isVariable">
<div>
<input type="text" name="skus[0][image]" placeholder="image"
value="{{ old('skus.0.image', $product->skus[0]->image ?? '') }}">
<input type="text" name="skus[0][model]" placeholder="model"
value="{{ old('skus.0.model', $product->skus[0]->model ?? '') }}">
<input type="text" name="skus[0][sku]" placeholder="sku"
value="{{ old('skus.0.sku', $product->skus[0]->sku ?? '') }}">
<input type="text" name="skus[0][price]" placeholder="price"
value="{{ old('skus.0.price', $product->skus[0]->price ?? '') }}">
<input type="text" name="skus[0][origin_price]" placeholder="origin_price"
value="{{ old('skus.0.origin_price', $product->skus[0]->origin_price ?? '') }}">
<input type="text" name="skus[0][cost_price]" placeholder="cost_price"
value="{{ old('skus.0.cost_price', $product->skus[0]->cost_price ?? '') }}">
<input type="text" name="skus[0][quantity]" placeholder="quantity"
value="{{ old('skus.0.quantity', $product->skus[0]->quantity ?? '') }}">
<input type="hidden" name="skus[0][variants]" placeholder="variants" value="">
<input type="hidden" name="skus[0][position]" placeholder="position" value="0">
<input type="hidden" name="skus[0][is_default]" placeholder="is_default" value="1">
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
</div>
</div>
@endsection
@push('footer')
<script>
<script>
var app = new Vue({
el: '#app',
data: {
@ -171,7 +167,7 @@
watch: {
'source.variables': {
deep: true,
handler: function () {
handler: function() {
// 原始规格数据变动,过滤有效规格并同步至 form.variables
let variants = [];
const sourceVariants = JSON.parse(JSON.stringify(this.source.variables));
@ -189,11 +185,17 @@
},
methods: {
addVariant() {
this.source.variables.push({name: '', values: []});
this.source.variables.push({
name: '',
values: []
});
},
addVariantValue(variantIndex) {
this.source.variables[variantIndex].values.push({name: '', image: ''});
this.source.variables[variantIndex].values.push({
name: '',
image: ''
});
},
remakeSkus() {
@ -267,7 +269,5 @@
}
return results;
}
</script>
</script>
@endpush

View File

@ -3,140 +3,134 @@
@section('title', '商品管理')
@push('header')
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/underscore.js/1.13.3/underscore.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/underscore.js/1.13.3/underscore.min.js"></script>
@endpush
@section('content')
<div id="product-app">
<div class="card">
<div class="card-body">
<div id="product-app">
<div class="card">
<div class="card-body">
<div class="bg-light p-4">
<div class="row">
<div class="col-xxl-20 col-xl-3 col-lg-4 col-md-4 d-flex align-items-center mb-3">
<label class="filter-title">商品名称</label>
<input type="text" v-model="filter.keyword" class="form-control" placeholder="keyword">
</div>
<div class="col-xxl-20 col-xl-3 col-lg-4 col-md-4 d-flex align-items-center mb-3">
<label class="filter-title">sku</label>
<input type="text" v-model="filter.sku" class="form-control" placeholder="sku">
</div>
<div class="col-xxl-20 col-xl-3 col-lg-4 col-md-4 d-flex align-items-center mb-3">
<label class="filter-title">分类</label>
<select v-model="filter.category_id" class="form-control">
<option value="0">全部</option>
@foreach ($categories as $_category)
<option :value="{{ $_category->id }}">{{ $_category->name }}</option>
@endforeach
</select>
</div>
<div class="col-xxl-20 col-xl-3 col-lg-4 col-md-4 d-flex align-items-center mb-3">
<label class="filter-title">排序</label>
<select v-model="filter.active" class="form-control">
<option value="">全部</option>
<option value="1">上架</option>
<option value="0">下架</option>
</select>
</div>
</div>
<div class="row">
<label class="filter-title"></label>
<div class="col-auto">
<button type="button" @click="search" class="btn btn-primary">筛选</button>
<button type="button" @click="search" class="btn btn-outline-primary">重置</button>
</div>
</div>
</div>
<div class="d-flex justify-content-between my-4">
<a href="{{ route('admin.products.create') }}">
<button class="btn btn-primary">创建商品</button>
</a>
<div class="right">
<button class="btn btn-outline-secondary">批量删除</button>
<button class="btn btn-outline-secondary">批量上架</button>
<button class="btn btn-outline-secondary">批量下架</button>
<button class="btn btn-outline-secondary">批量改价</button>
</div>
</div>
<template v-if="items.length">
<table class="table" v-loading="loading">
<thead>
<tr>
<th></th>
<th>ID</th>
<th>图片</th>
<th>商品名称</th>
<th>价格</th>
<th>
<div class="d-flex align-items-center">
创建时间
<div class="d-flex flex-column ml-1 order-by-wrap">
<i class="el-icon-caret-top" @click="orderBy = 'created_at:asc'"></i>
<i class="el-icon-caret-bottom" @click="orderBy = 'created_at:desc'"></i>
</div>
</div>
</th>
<th class="d-flex align-items-center">
<div class="d-flex align-items-center">
排序
<div class="d-flex flex-column ml-1 order-by-wrap">
<i class="el-icon-caret-top" @click="orderBy = 'position:asc'"></i>
<i class="el-icon-caret-bottom" @click="orderBy = 'position:desc'"></i>
</div>
</div>
</th>
<th>上架</th>
<th>操作</th>
</tr>
</thead>
<tr v-for="(item, index) in items" :key="item.id">
<td>
<input type="checkbox" :value="item.id" v-model="selected"/>
</td>
<td>@{{ item.id }}</td>
<td><img :src="item.image" style="max-width: 100px;" alt="" srcset=""></td>
<td>@{{ item.name || '无名称' }}</td>
<td>@{{ item.price_formatted }}</td>
<td>@{{ item.created_at }}</td>
<td>@{{ item.position }}</td>
<td>@{{ item.active ? '上架' : '下架' }}</td>
<td>
<a :href="item.url_edit">编辑</a>
<template>
<a v-if="item.deleted_at == ''" href="javascript:void(0)"
@click.prevent="deleteProduct(index)">删除</a>
<a v-else href="javascript:void(0)" @click.prevent="restoreProduct(index)">恢复</a>
</template>
</td>
</tr>
</table>
<el-pagination
layout="prev, pager, next"
background
:page-size="perPage"
:current-page.sync="page"
:total="totals"
></el-pagination>
</template>
<p v-else>无商品</p>
<div class="bg-light p-4">
<div class="row">
<div class="col-xxl-20 col-xl-3 col-lg-4 col-md-4 d-flex align-items-center mb-3">
<label class="filter-title">商品名称</label>
<input type="text" v-model="filter.keyword" class="form-control" placeholder="keyword">
</div>
<div class="col-xxl-20 col-xl-3 col-lg-4 col-md-4 d-flex align-items-center mb-3">
<label class="filter-title">sku</label>
<input type="text" v-model="filter.sku" class="form-control" placeholder="sku">
</div>
<div class="col-xxl-20 col-xl-3 col-lg-4 col-md-4 d-flex align-items-center mb-3">
<label class="filter-title">分类</label>
<select v-model="filter.category_id" class="form-control">
<option value="0">全部</option>
@foreach ($categories as $_category)
<option :value="{{ $_category->id }}">{{ $_category->name }}</option>
@endforeach
</select>
</div>
<div class="col-xxl-20 col-xl-3 col-lg-4 col-md-4 d-flex align-items-center mb-3">
<label class="filter-title">排序</label>
<select v-model="filter.active" class="form-control">
<option value="">全部</option>
<option value="1">上架</option>
<option value="0">下架</option>
</select>
</div>
</div>
<div class="row">
<label class="filter-title"></label>
<div class="col-auto">
<button type="button" @click="search" class="btn btn-primary">筛选</button>
<button type="button" @click="search" class="btn btn-outline-primary">重置</button>
</div>
</div>
</div>
<div class="d-flex justify-content-between my-4">
<a href="{{ route('admin.products.create') }}">
<button class="btn btn-primary">创建商品</button>
</a>
<div class="right">
<button class="btn btn-outline-secondary">批量删除</button>
<button class="btn btn-outline-secondary">批量上架</button>
<button class="btn btn-outline-secondary">批量下架</button>
<button class="btn btn-outline-secondary">批量改价</button>
</div>
</div>
<template v-if="items.length">
<table class="table" v-loading="loading">
<thead>
<tr>
<th></th>
<th>ID</th>
<th>图片</th>
<th>商品名称</th>
<th>价格</th>
<th>
<div class="d-flex align-items-center">
创建时间
<div class="d-flex flex-column ml-1 order-by-wrap">
<i class="el-icon-caret-top" @click="orderBy = 'created_at:asc'"></i>
<i class="el-icon-caret-bottom" @click="orderBy = 'created_at:desc'"></i>
</div>
</div>
</th>
<th class="d-flex align-items-center">
<div class="d-flex align-items-center">
排序
<div class="d-flex flex-column ml-1 order-by-wrap">
<i class="el-icon-caret-top" @click="orderBy = 'position:asc'"></i>
<i class="el-icon-caret-bottom" @click="orderBy = 'position:desc'"></i>
</div>
</div>
</th>
<th>上架</th>
<th>操作</th>
</tr>
</thead>
<tr v-for="(item, index) in items" :key="item.id">
<td>
<input type="checkbox" :value="item.id" v-model="selected" />
</td>
<td>@{{ item.id }}</td>
<td><img :src="item.image" style="max-width: 100px;" alt="" srcset=""></td>
<td>@{{ item.name || '无名称' }}</td>
<td>@{{ item.price_formatted }}</td>
<td>@{{ item.created_at }}</td>
<td>@{{ item.position }}</td>
<td>@{{ item.active ? '上架' : '下架' }}</td>
<td>
<a :href="item.url_edit">编辑</a>
<template>
<a v-if="item.deleted_at == ''" href="javascript:void(0)" @click.prevent="deleteProduct(index)">删除</a>
<a v-else href="javascript:void(0)" @click.prevent="restoreProduct(index)">恢复</a>
</template>
</td>
</tr>
</table>
<el-pagination layout="prev, pager, next" background :page-size="perPage" :current-page.sync="page"
:total="totals"></el-pagination>
</template>
<p v-else>无商品</p>
</div>
</div>
</div>
@endsection
@push('footer')
<script>
<script>
new Vue({
el: '#product-app',
data: {
@ -148,17 +142,17 @@
},
items: [],
selected: [],
page: @json((int)request('page') ?? 1),
page: @json((int) request('page') ?? 1),
totals: 0,
perPage: @json((int)(request('per_page') ?? 10)),
perPage: @json((int) (request('per_page') ?? 10)),
loading: false,
orderBy: @json(request('order_by', 'products.id:desc')),
},
mounted: function () {
mounted: function() {
this.load();
},
computed: {
url: function () {
url: function() {
let filter = {};
filter.per_page = this.perPage;
if (this.orderBy != 'products.id:desc') {
@ -182,15 +176,15 @@
}
},
watch: {
page: function () {
page: function() {
this.load();
},
orderBy: function () {
orderBy: function() {
this.load();
}
},
methods: {
load: function () {
load: function() {
const url = this.url;
window.history.pushState('', '', url);
this.loading = true;
@ -203,12 +197,12 @@
});
},
search: function () {
search: function() {
this.page = 1;
this.load();
},
deleteProduct: function (index) {
deleteProduct: function(index) {
const product = this.items[index];
this.$confirm('确认要删除选中的商品吗?', '删除商品', {
@ -224,7 +218,7 @@
});
},
restoreProduct: function (index) {
restoreProduct: function(index) {
const product = this.items[index];
this.$confirm('确认要恢复选中的商品吗?', '恢复商品', {
@ -241,6 +235,5 @@
}
}
});
</script>
</script>
@endpush

View File

@ -1,7 +1,7 @@
@charset "UTF-8";
body.page-checkout {
h4.title {
.module-title {
border-bottom: 1px solid #e5e5e5;
padding-bottom: 16px;
margin-bottom: 16px;
@ -99,10 +99,10 @@ body.page-checkout {
.item {
position: relative;
padding: 20px 20px 30px;
padding: 10px 20px;
margin-bottom: 10px;
border: 1px solid #e8e8e8;
height: 155px;
height: 125px;
cursor: pointer;
&.add-addres {
@ -140,6 +140,7 @@ body.page-checkout {
.name-wrap {
margin-bottom: .5rem;
line-height: 1;
.name {
font-size: 1rem;
@ -153,14 +154,18 @@ body.page-checkout {
}
.zipcode {
margin-bottom: .5rem;
margin-bottom: .1rem;
}
.address-info {
margin-bottom: .5rem;
margin-bottom: .9rem;
}
.address-bottom {
display: flex;
align-items: center; // flex-start | center
justify-content: space-between; // flex-end | center | space-between
// flex-wrap: wrap;
a {
color: #2d68a8;
}

View File

@ -25,97 +25,7 @@
<div class="col-12 col-md-8">
<form action="">
<div class="checkout-address">
<h4 class="title">地址</h4>
{{-- <div class="row mb-3">
<div class="col-12 col-md-6 mb-3">
<div class="form-floating">
<input type="text" name="email" class="form-control" value="" placeholder="姓名">
<label class="form-label" for="email_1">姓名</label>
</div>
</div>
<div class="col-12 col-md-6 mb-3">
<div class="form-floating">
<input type="text" name="email" class="form-control" value="" placeholder="电话">
<label class="form-label" for="email_1">电话</label>
</div>
</div>
<div class="col-12 col-md-4 mb-3">
<div class="form-floating">
<select class="form-select" aria-label="Default select example" name="county">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<label class="form-label" for="email_1">county</label>
</div>
</div>
<div class="col-12 col-md-4 mb-3">
<div class="form-floating">
<select class="form-select" aria-label="Default select example" name="zone">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<label class="form-label" for="email_1">zone</label>
</div>
</div>
<div class="col-12 col-md-4 mb-3">
<div class="form-floating">
<input type="text" name="email" class="form-control" value="" placeholder="city">
<label class="form-label" for="email_1">city</label>
</div>
</div>
<div class="col-12 mb-3">
<div class="form-floating">
<input type="text" name="email" class="form-control" value="" placeholder="city">
<label class="form-label" for="email_1">邮编</label>
</div>
</div>
<div class="col-12 mb-3">
<div class="form-floating">
<input type="text" name="email" class="form-control" value="" placeholder="city">
<label class="form-label" for="email_1">address 1</label>
</div>
</div>
<div class="col-12 mb-3">
<div class="form-floating">
<input type="text" name="email" class="form-control" value="" placeholder="city">
<label class="form-label" for="email_1">address 2</label>
</div>
</div>
</div> --}}
{{-- <table class="table">
<thead>
<tr>
<th>#</th>
<th>名称</th>
<th>电话</th>
<th>注册来源</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody v-if="source.addresses.length">
<tr v-for="address, index in source.addresses" :key="index">
<td>@{{ index }}</td>
<td>@{{ address.name }}</td>
<td>@{{ address.phone }}</td>
<td>222</td>
<td>222</td>
<td>
<button class="btn btn-outline-secondary btn-sm" type="button" @click="editAddress(index)">编辑</button>
<button class="btn btn-outline-danger btn-sm ml-1" type="button">删除</button>
</td>
</tbody>
<tbody v-else>
<tr>
<td colspan="6" class="text-center">
<span class="me-2">当前账号无地址</span> <el-link type="primary" @click="editAddress">新增地址</el-link>
</td>
</tbody>
</table> --}}
<h4 class="module-title">地址</h4>
<div class="addresses-wrap">
<div class="row">
<div class="col-4" v-for="address, index in source.addresses" :key="index" v-if="source.addresses.length">
@ -127,17 +37,18 @@
<div class="zipcode">@{{ address.zipcode }}</div>
<div class="address-info">@{{ address.country_id }} @{{ address.zone_id }}</div>
<div class="address-bottom">
<a class="">编辑</a>
<span class="badge bg-success">已选择</span>
<a class="" @click="editAddress(index)">编辑</a>
</div>
</div>
</div>
<div class="col-4">
<div class="item add-addres"><i class="bi bi-plus-square-dotted"></i> 添加新地址</div>
<div class="item add-addres" @click="editAddress"><i class="bi bi-plus-square-dotted"></i> 添加新地址</div>
</div>
</div>
</div>
<h4 class="title">支付方式</h4>
<h4 class="module-title">支付方式</h4>
<div class="row mb-3">
<div class="mb-4">
<input type="radio" class="btn-check" name="options-outlined" id="success-outlined" autocomplete="off" checked>
@ -148,7 +59,7 @@
</div>
</div>
<h4 class="title">配送方式</h4>
<h4 class="module-title">配送方式</h4>
<div class="row mb-3">
<div class="mb-4">
<input type="radio" class="btn-check" name="peisong_name" id="peisong-1" autocomplete="off" checked>
@ -166,31 +77,80 @@
<div class="card-header"><h5 class="mb-0">CART TOTALS</h5></div>
<div class="card-body">
<div class="products-wrap">
@for ($i = 0; $i < 4; $i++)
<div class="item">
<div class="item" v-for="cart, index in source.carts.carts" :key="index">
<div class="image">
<img src="http://fpoimg.com/100x100?bg_color=f3f3f3" class="img-fluid">
<img :src="cart.image" class="img-fluid">
<div class="name">
<span>Camera Canon EOS M50 Kit</span>
<span class="quantity">x2</span>
<span v-text="cart.name"></span>
<span class="quantity">x @{{ cart.quantity }}</span>
</div>
</div>
<div class="price">$1156.00</div>
<div class="price" v-text="cart.price_format"></div>
</div>
@endfor
</div>
<ul class="totals">
<li><span>总数</span><span>1120</span></li>
<li><span>运费</span><span>20</span></li>
<li><span>总价</span><span>2220</span></li>
<li><span>总数</span><span v-text="source.carts.quantity"></span></li>
<li><span>运费</span><span v-text="source.carts.quantity"></span></li>
<li><span>总价</span><span v-text="source.carts.amount_format"></span></li>
</ul>
<div class="d-grid gap-2 mt-3">
<button class="btn btn-primary">提交订单</button>
<button class="btn btn-primary" type="button" @click="checkedBtnCheckoutConfirm">提交订单</button>
</div>
</div>
</div>
</div>
</div>
<el-dialog title="编辑地址" :visible.sync="dialogAddress.show" width="600px" @close="closeAddressDialog('addressForm')">
<el-form ref="addressForm" :rules="addressRules" :model="dialogAddress.form" label-width="100px">
<el-form-item label="姓名" prop="name">
<el-input v-model="dialogAddress.form.name"></el-input>
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input maxlength="11" v-model="dialogAddress.form.phone"></el-input>
</el-form-item>
<el-form-item label="地址" required>
<div class="row">
<div class="col-4">
<el-form-item>
<el-select v-model="dialogAddress.form.country_id" filterable placeholder="选择国家" @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">
<el-form-item prop="zone_id">
<el-select v-model="dialogAddress.form.zone_id" filterable placeholder="选择省份">
<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">
<el-form-item prop="city_id">
<el-input v-model="dialogAddress.form.city_id" placeholder="输入 city"></el-input>
</el-form-item>
</div>
</div>
</el-form-item>
<el-form-item label="邮编" prop="zipcode">
<el-input v-model="dialogAddress.form.zipcode"></el-input>
</el-form-item>
<el-form-item label="详细地址 1" prop="address_1">
<el-input v-model="dialogAddress.form.address_1"></el-input>
</el-form-item>
<el-form-item label="详细地址 2">
<el-input v-model="dialogAddress.form.address_2"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addressFormSubmit('addressForm')">保存</el-button>
<el-button @click="closeAddressDialog('addressForm')">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
@endsection
@push('add-scripts')
@ -205,6 +165,9 @@
source: {
addresses: @json($addresses ?? []),
countries: @json($countries ?? []),
carts: @json($carts ?? null),
zones: []
},
dialogAddress: {
@ -221,6 +184,14 @@
address_2: '',
}
},
addressRules: {
name: [{required: true, message: '请输入姓名', trigger: 'blur'}, ],
phone: [{required: true, message: '请输入联系电话', trigger: 'blur'}, ],
address_1: [{required: true, message: '请输入详细地址 1', trigger: 'blur'}, ],
zone_id: [{required: true, message: '请选择省份', trigger: 'blur'}, ],
city_id: [{required: true, message: '请填写 city', trigger: 'blur'}, ],
}
},
beforeMount () {
@ -232,12 +203,64 @@
this.dialogAddress.index = index;
this.$nextTick(() => {
this.dialogAddress.form = JSON.parse(JSON.stringify(this.form.address[index]))
this.dialogAddress.form = JSON.parse(JSON.stringify(this.source.addresses[index]))
})
}
this.dialogAddress.show = true
},
addressFormSubmit(form) {
const self = this;
this.$refs[form].validate((valid) => {
if (!valid) {
this.$message.error('请检查表单是否填写正确');
return;
}
const type = this.dialogAddress.form.id ? 'put' : 'post';
$.ajax({
url: `/admin/customers/{{ $customer_id }}/addresses${type == 'put' ? '/' + this.dialogAddress.form.id : ''}`,
data: self.dialogAddress.form,
type: type,
success: function(res) {
if (type == 'post') {
self.source.addresses.push(res.data)
} else {
self.source.addresses[self.dialogAddress.index] = res.data
}
self.$message.success(res.message);
self.$refs[form].resetFields();
self.dialogAddress.show = false
self.dialogAddress.index = null;
}
})
});
},
closeAddressDialog(form) {
this.$refs[form].resetFields();
this.dialogAddress.show = false
this.dialogAddress.index = null;
},
countryChange(e) {
const self = this;
$.ajax({
url: `/admin/countries/${e}/zones`,
type: 'get',
success: function(res) {
self.source.zones = res.data.zones;
}
})
},
checkedBtnCheckoutConfirm() {
console.log(1)
}
}
})