210 lines
6.5 KiB
PHP
210 lines
6.5 KiB
PHP
<?php
|
|
namespace App\Domains\Virtual\Services;
|
|
|
|
use App\Dicts;
|
|
use App\Core\Service;
|
|
use App\Models\Virtual\Order;
|
|
use Illuminate\Validation\Rule;
|
|
use Illuminate\Support\Facades\DB;
|
|
use App\Exceptions\NotExistException;
|
|
use App\Exceptions\NotAllowedException;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use App\Domains\Virtual\Services\CommonService;
|
|
use App\Domains\Virtual\Repositories\OrderRepository;
|
|
use App\Domains\Virtual\Repositories\ProductRepository;
|
|
|
|
class OrderService extends Service
|
|
{
|
|
protected $orderRepository;
|
|
|
|
/**
|
|
* 构造函数
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct(OrderRepository $orderRepository)
|
|
{
|
|
$this->orderRepository = $orderRepository;
|
|
}
|
|
|
|
/**
|
|
* 订单列表
|
|
*
|
|
* @param array $conditions
|
|
* @return mixed
|
|
*/
|
|
public function paginate(array $conditions = [])
|
|
{
|
|
$limit = $conditions['limit'] ?? 35;
|
|
|
|
$res = $this->orderRepository->with(['company:id,name','package:id,name,carrier_operator'])
|
|
->withConditions($conditions)->applyConditions()->orderBy('order_at', 'desc')->paginate($limit);
|
|
|
|
|
|
$res->map(function ($item) {
|
|
$item->unit_price = sprintf('%.02f', $item->unit_price/100);
|
|
$item->total_price = sprintf('%.02f', $item->total_price/100);
|
|
$item->custom_price = sprintf('%.02f', $item->custom_price/100);
|
|
});
|
|
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 订单计数
|
|
*
|
|
* @param array $conditions
|
|
* @return mixed
|
|
*/
|
|
public function count(array $conditions = [])
|
|
{
|
|
$select = [
|
|
DB::raw('COUNT(*) as total_count'),
|
|
DB::raw('SUM(custom_price) as total_price'),
|
|
DB::raw('SUM(custom_price*transaction_status) as transacted_price'),
|
|
];
|
|
|
|
$res = $this->orderRepository->select($select)->withConditions($conditions)->applyConditions()->first()->toArray();
|
|
|
|
$res['total_price'] = $res['total_price'] ?? 0;
|
|
$res['total_price'] = sprintf('%.02f', $res['total_price']/100);
|
|
$res['transacted_price'] = $res['transacted_price'] ?? 0;
|
|
$res['transacted_price'] = sprintf('%.02f', $res['transacted_price']/100);
|
|
unset($res['company']);
|
|
unset($res['package']);
|
|
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 下单
|
|
*
|
|
* @param array $attributes
|
|
* @return Order
|
|
*/
|
|
public function store(array $attributes = [])
|
|
{
|
|
$attributes['sn'] = $attributes['sn'] ?: $this->generateSn();
|
|
|
|
$rule = [
|
|
'company_id' => ['exists:virtual_companies,id'],
|
|
'product_id' => [],
|
|
'counts' => [],
|
|
'pay_channel' => [Rule::in(array_collapse(app(Dicts::class)->get('pay_channel')))],
|
|
'order_status' => ['in:0,1,2,3,4'],
|
|
'transaction_status' => ['in:0,1,2'],
|
|
'extends' => ['array'],
|
|
];
|
|
|
|
$message = [
|
|
'company_id.required' => '请输入企业ID',
|
|
'company_id.exists' => '企业不存在或已删除',
|
|
'product_id.required' => '请选择套餐',
|
|
'counts.required' => '请输入订购数量',
|
|
'pay_channel.required' => '请选择支付方式',
|
|
'pay_channel.in' => '支付方式不合法',
|
|
'contacts.required' => '请选择收货地址',
|
|
'mobile.required' => '请选择收货地址',
|
|
'address.required' => '请选择收货地址',
|
|
];
|
|
|
|
if (!$attributes['id']) {
|
|
$rule['company_id'][] = 'required';
|
|
$rule['product_id'][] = 'required';
|
|
$rule['counts'][] = 'required';
|
|
$rule['pay_channel'][] = 'required';
|
|
$rule['contacts'][] = 'required';
|
|
$rule['mobile'][] = 'required';
|
|
$rule['address'][] = 'required';
|
|
}
|
|
|
|
Validator::validate($attributes, $rule, $message);
|
|
|
|
if (!$attributes['id']) {
|
|
if (!$product = app(ProductRepository::class)->withConditions(['id' => $attributes['product_id']])->first()) {
|
|
throw new NotExistException('套餐不存在或已删除');
|
|
}
|
|
|
|
if ($product->company_id != $attributes['company_id']) {
|
|
throw new NotAllowedException('非法操作');
|
|
}
|
|
|
|
$attributes['unit_price'] = $product->base_price;
|
|
$attributes['total_price'] = $attributes['unit_price'] * $attributes['counts'];
|
|
$attributes['custom_price'] = $attributes['unit_price'] * $attributes['counts'];
|
|
$attributes['order_at'] = $attributes['order_at'] ?? date('Y-m-d H:i:s');
|
|
$attributes['package_id'] = $attributes['package_id'] ?? $product->package_id;
|
|
|
|
$node = $this->orderRepository->create($attributes);
|
|
}
|
|
|
|
if ($attributes['id']) {
|
|
if (!$node = $this->orderRepository->find($attributes['id'])) {
|
|
throw new NotExistException('订单不存在或已删除');
|
|
}
|
|
|
|
if (!empty($attributes['extends']) && is_array($attributes['extends'])) {
|
|
$attributes['extends'] = array_merge($node->extends ?: [], $attributes['extends']);
|
|
}
|
|
|
|
$this->orderRepository->setModel($node)->update($attributes);
|
|
}
|
|
|
|
return $node;
|
|
}
|
|
|
|
/**
|
|
* 取消订单
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function cancel($id)
|
|
{
|
|
if (!$node = $this->orderRepository->find($id)) {
|
|
throw new NotExistException('订单不存在或已删除');
|
|
}
|
|
|
|
if ($node->order_status !== 0) {
|
|
throw new NotExistException('订单已出库,不能取消');
|
|
}
|
|
|
|
if ($node->transaction_status !== 0) {
|
|
throw new NotExistException('订单已付款,不能取消');
|
|
}
|
|
|
|
$this->orderRepository->setModel($node)->update(['order_status' => 1]);
|
|
|
|
return $node;
|
|
}
|
|
|
|
/**
|
|
* 确认收货
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function received($id)
|
|
{
|
|
if (!$node = $this->orderRepository->find($id)) {
|
|
throw new NotExistException('订单不存在或已删除');
|
|
}
|
|
|
|
if ($node->order_status !== 3) {
|
|
throw new NotExistException('订单未发货,不能修改');
|
|
}
|
|
|
|
$this->orderRepository->setModel($node)->update(['order_status' => 4]);
|
|
|
|
return $node;
|
|
}
|
|
|
|
/**
|
|
* 生成订单编号
|
|
*
|
|
* @return void
|
|
*/
|
|
public function generateSn()
|
|
{
|
|
return date('YmdHis') .sprintf('%04d', explode('.', microtime(true))[1]) . sprintf('%02d', rand(0, 99));
|
|
}
|
|
}
|