You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
10 KiB
302 lines
10 KiB
<?php
|
|
|
|
namespace App\Controller\v3;
|
|
|
|
use App\Constants\v3\ErrorCode;
|
|
use App\Constants\v3\LogLabel;
|
|
use App\Constants\v3\OrderState;
|
|
use App\Controller\BaseController;
|
|
use App\Exception\ErrorCodeException;
|
|
use App\Model\v3\Market;
|
|
use App\Model\v3\OrderMain;
|
|
use App\Request\v3\OrderOnlineDetailRequest;
|
|
use App\Request\v3\OrderOnlineRequest;
|
|
use App\Request\v3\OrderOnlineStateRequest;
|
|
use App\Request\v3\UserRequest;
|
|
use App\Service\v3\Implementations\PaymentService;
|
|
use App\Service\v3\Interfaces\CouponRecServiceInterface;
|
|
use App\Service\v3\Interfaces\DistributionPriceServiceInterface;
|
|
use App\Service\v3\Interfaces\LocationServiceInterface;
|
|
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
|
|
use App\Service\v3\Interfaces\ShopCartServiceInterface;
|
|
use Hyperf\DbConnection\Db;
|
|
use Hyperf\Di\Annotation\Inject;
|
|
use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
|
|
use App\Service\v3\Interfaces\UserBindTelServiceInterface;
|
|
use App\Service\v3\Interfaces\AppointmentTimeServiceInterface;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use App\Model\v3\UserAddress;
|
|
|
|
class OrderOnlineController extends BaseController
|
|
{
|
|
/**
|
|
* @Inject
|
|
* @var UserBindTelServiceInterface
|
|
*/
|
|
protected $userBindTelService;
|
|
/**
|
|
* @Inject
|
|
* @var CouponRecServiceInterface
|
|
*/
|
|
protected $couponRecService;
|
|
/**
|
|
* @Inject
|
|
* @var AppointmentTimeServiceInterface
|
|
*/
|
|
protected $appointmentTimeService;
|
|
|
|
/**
|
|
* @Inject
|
|
* @var OrderOnlineServiceInterface
|
|
*/
|
|
protected $orderOnlineService;
|
|
|
|
/**
|
|
* @Inject
|
|
* @var ShopCartServiceInterface
|
|
*/
|
|
protected $shopCartService;
|
|
|
|
/**
|
|
* @Inject
|
|
* @var SeparateAccountsServiceInterface
|
|
*/
|
|
protected $separateAccountsService;
|
|
|
|
/**
|
|
* @Inject
|
|
* @var LocationServiceInterface
|
|
*/
|
|
protected $locationService;
|
|
|
|
/**
|
|
* @Inject
|
|
* @var DistributionPriceServiceInterface
|
|
*/
|
|
protected $distributionPriceService;
|
|
|
|
/*
|
|
* 如果没有绑手机号去绑定页面
|
|
* 收货地址接口
|
|
* 返回预约送达时间
|
|
* 商品数据接口
|
|
* 红包独立接口
|
|
* 配送费独立接口 可根据距离动态计算费用
|
|
* 增值服务接口
|
|
* */
|
|
public function review(UserRequest $request)
|
|
{
|
|
$userId = $this->request->input('user_id','');
|
|
$marketId = $this->request->input('market_id','');
|
|
$shopcartIds = $this->request->input('shopcart_ids','');
|
|
|
|
//判断用户有没有绑定手机
|
|
$telExists = $this->userBindTelService->check($userId);
|
|
if(!$telExists){
|
|
throw new ErrorCodeException(ErrorCode::NOT_BIND_TEL_ERROR);
|
|
}
|
|
//获取用户收货地址
|
|
$address = UserAddress::query()
|
|
->where('user_id',$userId)
|
|
//->where('is_default',1)
|
|
->orderByDesc('is_default')
|
|
->orderByDesc('updated_at')
|
|
->first();
|
|
$market = Market::find($marketId);
|
|
$distance = 0;
|
|
if(!empty($address->lng) && !empty($address->lat)){
|
|
$distance = $this->locationService->getDistanceByTencent($market->lng,$market->lat,$address->lng,$address->lat);
|
|
}
|
|
$deliveryDistance = config('distance.delivery_distance');
|
|
if(isset($distance) && $distance < $deliveryDistance){
|
|
if($distance >= 1000){
|
|
$distance_text = '距你收货地址 ' . bcdiv($distance,1000,2) . 'km';
|
|
}else{
|
|
$distance_text = '距你收货地址 ' . $distance . 'm';
|
|
}
|
|
$distributionPrice = $this->distributionPriceService->do($distance);
|
|
$res['location'] = [
|
|
'address' => $address,
|
|
'distribution_price' => $distributionPrice,
|
|
'distance' => $distance,
|
|
'within' => true,
|
|
// 'distribution_text' => '¥ '.$distributionPrice .'(' .$distance_text .')'
|
|
'distribution_text' => $distance_text
|
|
];
|
|
}else{
|
|
$res['location'] = [
|
|
'address' => '',
|
|
'distribution_price' => 3.5,
|
|
'distance' => $distance,
|
|
'within' => false,
|
|
'distribution_text' => '¥ 3.5'
|
|
];
|
|
}
|
|
//返回预约送达时间 数组
|
|
$ret = $retSelfTake = $this->appointmentTimeService->get($shopcartIds);
|
|
array_unshift($ret,['title'=>'尽快送达','value'=>'尽快送达']);
|
|
$res['appointment_time'] = $ret;
|
|
|
|
array_unshift($retSelfTake,['title'=>'尽快取货','value'=>'尽快取货']);
|
|
$res['appointment_time_self_take'] = $retSelfTake;
|
|
|
|
$res['store_list'] = $this->shopCartService->getGoodsByShopcartId($shopcartIds);
|
|
//获取用户优惠券
|
|
$coupons = $this->couponRecService->allForOnlineOrderAvailable($userId, $marketId);
|
|
$res['coupon'] = [
|
|
'available' => [],
|
|
'not_available' => [],
|
|
];
|
|
foreach ($coupons as $key => &$item) {
|
|
foreach ($item as $k => &$rec) {
|
|
for ($i=0; $i<$rec->number_remain; $i++) {
|
|
if ($key == 'available') {
|
|
$res['coupon']['available'][] = $rec;
|
|
} elseif ($key == 'not_available') {
|
|
$res['coupon']['not_available'][] = $rec;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// $res['coupon'] = $coupons;
|
|
//增值服务接口
|
|
$res['value_added_service'] = [
|
|
'text' => '增值服务包含洗菜、切菜、打包等所产生的人工成本费及包装费。',
|
|
'select' => 0,
|
|
'price' => 0,
|
|
'original_price' => 3.5
|
|
];
|
|
$total = 0;
|
|
foreach ($res['store_list'] as $store)
|
|
{
|
|
$total = bcadd($total,$store['subtotal'],2);
|
|
}
|
|
$total = bcadd($total,$res['value_added_service']['price'],2);
|
|
$total = bcadd($total,$res['location']['distribution_price'],2);
|
|
$res['total'] = $total;
|
|
|
|
// 新增返回市场信息
|
|
$res['market'] = $market;
|
|
|
|
return $this->success($res);
|
|
}
|
|
|
|
/**
|
|
* 订单详情
|
|
* 1、主订单信息,用户配送信息(地址、姓名、电话、配送时间、配送类型)、基础信息(订单ID、订单编号、下单时间、订单金额、付款时间、支付方式、红包优惠、服务站电话、增值服务费)
|
|
* 2、子订单以及订单商品,按商户分组,有商户信息(ID、商户名、商户logo),商品信息(id、名字、封面、规格、tag、原价、售价、库存、总销、月销、是否失效、失效原因)
|
|
* @param OrderOnlineDetailRequest $request
|
|
* @return ResponseInterface
|
|
*/
|
|
public function detailByUser(OrderOnlineDetailRequest $request)
|
|
{
|
|
$params = $request->validated();
|
|
return $this->success(['detail' => $this->orderOnlineService->detailByUser($params['global_order_id'], $params['user_id'])]);
|
|
}
|
|
|
|
/**
|
|
* 下单并进行支付,返回支付参数
|
|
* 1、用户传参,用户地址ID,用于获取用户地址经纬度来计算配送费
|
|
* 2、用户传参,购物车IDs,去获取购物车里的商品详情
|
|
* 3、预约送达时间
|
|
* 4、优惠券IDs
|
|
* 5、订单总金额,用于校验比对
|
|
* 6、下单成功,请求支付
|
|
* @param OrderOnlineRequest $request
|
|
* @return ResponseInterface
|
|
*/
|
|
public function add(OrderOnlineRequest $request){
|
|
|
|
// 下单
|
|
$params = $request->validated();
|
|
$couponIds = isset($params['coupon_ids'])&&$params['coupon_ids'] ? explode(',', $params['coupon_ids']) : [];
|
|
$data = $this->orderOnlineService->do(
|
|
$params['market_id'],
|
|
$params['user_id'],
|
|
($params['user_address_id'] ?? 0),
|
|
json_decode($params['store_list']),
|
|
$params['total_money'],
|
|
$params['delivery_time_note'],
|
|
($params['service_money'] ?? 0),
|
|
$couponIds,
|
|
$params['plat'] ?: '',
|
|
($params['self_take'] ?? 0)
|
|
);
|
|
|
|
return $this->success(['data' => $data]);
|
|
}
|
|
|
|
/**
|
|
* 待支付订单重新发起支付
|
|
* 1、用户id、订单id
|
|
* 2、发起支付
|
|
* @param OrderOnlineStateRequest $request
|
|
* @return ResponseInterface
|
|
*/
|
|
public function pay(OrderOnlineStateRequest $request)
|
|
{
|
|
$params = $request->validated();
|
|
$data = $this->orderOnlineService->doPay($params['global_order_id'], $params['user_id']);
|
|
return $this->success(['data' => $data]);
|
|
}
|
|
|
|
/**
|
|
* 取消订单
|
|
* @param OrderOnlineStateRequest $request
|
|
* @return ResponseInterface
|
|
*/
|
|
public function cancel(OrderOnlineStateRequest $request)
|
|
{
|
|
$params = $request->validated();
|
|
$this->orderOnlineService->undo($params['global_order_id'], $params['user_id']);
|
|
return $this->success([]);
|
|
}
|
|
|
|
/**
|
|
* 删除订单
|
|
* @param OrderOnlineStateRequest $request
|
|
* @return ResponseInterface
|
|
*/
|
|
public function del(OrderOnlineStateRequest $request)
|
|
{
|
|
$params = $request->validated();
|
|
$this->orderOnlineService->doDel($params['global_order_id'], $params['user_id']);
|
|
return $this->success([]);
|
|
}
|
|
|
|
/**
|
|
* 申请退款
|
|
* @param OrderOnlineStateRequest $request
|
|
* @return ResponseInterface
|
|
*/
|
|
public function applyRefund(OrderOnlineStateRequest $request)
|
|
{
|
|
$params = $request->validated();
|
|
$this->orderOnlineService->doApplyRefund($params['global_order_id'], $params['user_id']);
|
|
return $this->success([]);
|
|
}
|
|
|
|
/**
|
|
* 完成订单
|
|
* @param OrderOnlineStateRequest $request
|
|
* @return ResponseInterface
|
|
*/
|
|
public function complete(OrderOnlineStateRequest $request)
|
|
{
|
|
Db::beginTransaction();
|
|
try {
|
|
|
|
$params = $request->validated();
|
|
$this->orderOnlineService->doComplete($params['global_order_id'], $params['user_id']);
|
|
$this->separateAccountsService->orderOnlineCompleted($params['global_order_id'], $params['user_id']);
|
|
|
|
Db::commit();
|
|
return $this->success([]);
|
|
} catch (\Exception $e) {
|
|
|
|
Db::rollBack();
|
|
$this->log->event(LogLabel::ORDER_COMPLETE_LOG, ['exception' => $e->getMessage()]);
|
|
throw new ErrorCodeException(ErrorCode::ORDER_COMPLETE_FAIL);
|
|
}
|
|
}
|
|
}
|