|
|
@ -22,6 +22,8 @@ use App\Service\OrderStatus as Status; |
|
|
*/ |
|
|
*/ |
|
|
class OrderController extends Controller |
|
|
class OrderController extends Controller |
|
|
{ |
|
|
{ |
|
|
|
|
|
private $earnest = 200; //定金和首款默认金额 TODO 定金支付和首款支付暂定为200
|
|
|
|
|
|
|
|
|
//订单列表
|
|
|
//订单列表
|
|
|
public function index(Request $request) |
|
|
public function index(Request $request) |
|
|
{ |
|
|
{ |
|
|
@ -59,7 +61,7 @@ class OrderController extends Controller |
|
|
$timeout_ids[] = $v['id']; |
|
|
$timeout_ids[] = $v['id']; |
|
|
$v['status'] = Status::CANCEL; |
|
|
$v['status'] = Status::CANCEL; |
|
|
$v['status_text'] = '已取消'; |
|
|
$v['status_text'] = '已取消'; |
|
|
//TODO 加回库存,未考虑到几天/几个月后再打开订单列表页的情况
|
|
|
|
|
|
|
|
|
//TODO 加回库存,未考虑到几天/几个月后再打开订单列表页的情况,需要定时任务处理
|
|
|
Product::query()->find($v['product_id'])->update(['stock' => $v['num']]); |
|
|
Product::query()->find($v['product_id'])->update(['stock' => $v['num']]); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -82,7 +84,7 @@ class OrderController extends Controller |
|
|
'id' => ['required', 'regex:/^\d+$/'], |
|
|
'id' => ['required', 'regex:/^\d+$/'], |
|
|
'name' => ['required', 'between:2,20'], |
|
|
'name' => ['required', 'between:2,20'], |
|
|
'mobile' => ['required', 'regex:/^1[3-9]\d{9}$/'], |
|
|
'mobile' => ['required', 'regex:/^1[3-9]\d{9}$/'], |
|
|
'pay_type' => ['required', 'in:0,1,2'], |
|
|
|
|
|
|
|
|
'pay_type' => ['required', 'in:0,1,2,3'], |
|
|
'num' => ['required', 'min:1'], |
|
|
'num' => ['required', 'min:1'], |
|
|
], [ |
|
|
], [ |
|
|
'id.required' => '未指定产品ID', |
|
|
'id.required' => '未指定产品ID', |
|
|
@ -118,7 +120,7 @@ class OrderController extends Controller |
|
|
|
|
|
|
|
|
DB::beginTransaction(); |
|
|
DB::beginTransaction(); |
|
|
try { |
|
|
try { |
|
|
$price = $this->calc($ap, $formData['num']); |
|
|
|
|
|
|
|
|
$price = $this->calc($ap->price, $ap->coupon, $formData['num'], $formData['pay_type']); |
|
|
$title = $ap->product->title; //产品标题
|
|
|
$title = $ap->product->title; //产品标题
|
|
|
//代理商产品表增加销量
|
|
|
//代理商产品表增加销量
|
|
|
// $ap->increment('sale', $formData['num']); TODO 支付成功之后再增加销量
|
|
|
// $ap->increment('sale', $formData['num']); TODO 支付成功之后再增加销量
|
|
|
@ -131,6 +133,7 @@ class OrderController extends Controller |
|
|
// 存入订单表
|
|
|
// 存入订单表
|
|
|
$order = Order::query()->create([ |
|
|
$order = Order::query()->create([ |
|
|
'user_id' => $this->user_id, |
|
|
'user_id' => $this->user_id, |
|
|
|
|
|
'agent_id' => $this->agent_id, |
|
|
'order_no' => $this->getOrderNo(), |
|
|
'order_no' => $this->getOrderNo(), |
|
|
'num' => $formData['num'], |
|
|
'num' => $formData['num'], |
|
|
'price' => $price, |
|
|
'price' => $price, |
|
|
@ -140,28 +143,27 @@ class OrderController extends Controller |
|
|
'picture' => $ap->product->picture, |
|
|
'picture' => $ap->product->picture, |
|
|
'agent_product_id' => $ap->id, |
|
|
'agent_product_id' => $ap->id, |
|
|
'product_id' => $ap->product_id, |
|
|
'product_id' => $ap->product_id, |
|
|
'status' => Status::UNPAID, |
|
|
|
|
|
|
|
|
'status' => $formData['pay_type'] == 3 ? Status::OFFLINE_UNPAID : Status::UNPAID, |
|
|
'pay_type' => $formData['pay_type'], |
|
|
'pay_type' => $formData['pay_type'], |
|
|
'coupon_id' => join(',', $coupon_ids), |
|
|
'coupon_id' => join(',', $coupon_ids), |
|
|
]); |
|
|
]); |
|
|
|
|
|
|
|
|
//资金流水
|
|
|
|
|
|
UserMoneyLog::query()->create([ |
|
|
|
|
|
'user_id' => $this->user_id, |
|
|
|
|
|
'agent_id' => $this->agent_id, |
|
|
|
|
|
'money' => -$price, |
|
|
|
|
|
'order_id' => $order->id, |
|
|
|
|
|
'type' => 1, |
|
|
|
|
|
'desc' => '购买产品:' . $title, |
|
|
|
|
|
'created_at' => time(), //已关闭模型自动写入时间
|
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
|
|
DB::commit(); |
|
|
DB::commit(); |
|
|
} catch (\Exception $e) { |
|
|
} catch (\Exception $e) { |
|
|
DB::rollBack(); |
|
|
DB::rollBack(); |
|
|
return $e->getMessage(); |
|
|
|
|
|
|
|
|
return $this->error($e->getMessage()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ($formData['pay_type'] == 3) { //线下支付
|
|
|
|
|
|
return $this->success('操作成功,请及时联系客服线下支付'); |
|
|
|
|
|
} else { //在线支付或定金支付
|
|
|
|
|
|
$config = $this->payConfig($order->title, $order->order_no, $order->pay_type, $price); |
|
|
|
|
|
if (!empty($config['paySign'])) { |
|
|
|
|
|
return $this->success($config); |
|
|
|
|
|
} else { |
|
|
|
|
|
return $this->error(join(',', $config)); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
return $this->success(); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//申请退款
|
|
|
//申请退款
|
|
|
@ -199,39 +201,74 @@ class OrderController extends Controller |
|
|
return $this->success(); |
|
|
return $this->success(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//获取应付金额
|
|
|
|
|
|
|
|
|
//获取应付金额及相关产品信息
|
|
|
public function getPrice(Request $request) |
|
|
public function getPrice(Request $request) |
|
|
{ |
|
|
{ |
|
|
$id = (int)$request->input('id'); |
|
|
|
|
|
|
|
|
$formData = $request->only(['id', 'num', 'pay_type']); |
|
|
|
|
|
$request->validate([ |
|
|
|
|
|
'id' => 'required|integer', |
|
|
|
|
|
'num' => 'required|integer', |
|
|
|
|
|
'pay_type' => 'required|integer', |
|
|
|
|
|
], [ |
|
|
|
|
|
'*.required' => '参数缺失', |
|
|
|
|
|
'*.integer' => '参数类型错误', |
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
$num = (float)$request->input('num'); |
|
|
|
|
|
if (!$num || $num < 1) { |
|
|
|
|
|
|
|
|
if (!$formData['num'] || $formData['num'] < 1) { |
|
|
return $this->error('未指定产品数量'); |
|
|
return $this->error('未指定产品数量'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
$agent_product = AgentProduct::query() |
|
|
|
|
|
->with('coupon:agent_product_id,type,detail,agent_id,start_at,end_at') |
|
|
|
|
|
->find($id); |
|
|
|
|
|
$final_price = $this->calc($agent_product, $num); |
|
|
|
|
|
return $this->success(['price' => $final_price]); |
|
|
|
|
|
|
|
|
$ap = AgentProduct::query() |
|
|
|
|
|
->with('product:id,title,pictures') |
|
|
|
|
|
->with('coupon:agent_product_id,type,detail,agent_id,tag,start_at,end_at') |
|
|
|
|
|
->find($formData['id'], ['id', 'price', 'original_price', 'product_id']); |
|
|
|
|
|
|
|
|
|
|
|
$ap->final_price = $this->calc($ap->price, $ap->coupon, $formData['num'], $formData['pay_type']); |
|
|
|
|
|
$ap->num = $formData['num']; |
|
|
|
|
|
return $this->success($ap); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//订单支付
|
|
|
|
|
|
public function pay() |
|
|
|
|
|
|
|
|
//订单支付(在订单列表发起)
|
|
|
|
|
|
public function pay(Request $request) |
|
|
{ |
|
|
{ |
|
|
$id = (int)request()->input('id'); |
|
|
$id = (int)request()->input('id'); |
|
|
|
|
|
|
|
|
//订单信息
|
|
|
//订单信息
|
|
|
$order = Order::find($id); |
|
|
|
|
|
|
|
|
$order = Order::query() |
|
|
|
|
|
->with('agentProduct') |
|
|
|
|
|
->where(['user_id' => $this->user_id, 'agent_id' => $this->agent_id]) |
|
|
|
|
|
->whereIn('status', [Status::UNPAID, Status::PAY_EARNEST]) |
|
|
|
|
|
->find($id); |
|
|
if (!$order) { |
|
|
if (!$order) { |
|
|
return $this->error('订单不存在'); |
|
|
|
|
|
|
|
|
return $this->error('订单不存在或已支付'); |
|
|
|
|
|
} |
|
|
|
|
|
$order = $order->toArray(); |
|
|
|
|
|
|
|
|
|
|
|
$coupon = Coupon::whereIn('id', $order['coupon_id'])->get(); |
|
|
|
|
|
|
|
|
|
|
|
//如果已经付定金或首付款,则仅支付尾款
|
|
|
|
|
|
if ($order['status'] == Status::PAY_EARNEST) { |
|
|
|
|
|
$price = $order['price'] - $order['paid_money']; |
|
|
|
|
|
} else { |
|
|
|
|
|
$price = $this->calc($order['price'], $coupon, $order['num'], $order['pay_type']); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$config = $this->payConfig($order['title'], $order['order_no'], $order['pay_type'], $price); |
|
|
|
|
|
if (!empty($config['paySign'])) { |
|
|
|
|
|
return $this->success($config); |
|
|
|
|
|
} else { |
|
|
|
|
|
return $this->error(join(',', $config)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//获取支付配置信息
|
|
|
|
|
|
private function payConfig($title, $order_no, $pay_type, $price) |
|
|
|
|
|
{ |
|
|
//用户openid
|
|
|
//用户openid
|
|
|
$openid = User::query()->find($this->user_id)->value('openid'); |
|
|
|
|
|
|
|
|
$openid = User::query()->where('id', $this->user_id)->value('openid'); //此处要用where,value()用find有BUG
|
|
|
|
|
|
|
|
|
//代理商信息
|
|
|
//代理商信息
|
|
|
$agent = Agent::find($this->agent_id); |
|
|
|
|
|
|
|
|
$agent = Agent::query()->find($this->agent_id); |
|
|
|
|
|
|
|
|
$config = config('wechat.payment.default'); |
|
|
$config = config('wechat.payment.default'); |
|
|
$config = array_merge($config, [ |
|
|
$config = array_merge($config, [ |
|
|
@ -242,18 +279,20 @@ class OrderController extends Controller |
|
|
|
|
|
|
|
|
$app = Factory::payment($config); |
|
|
$app = Factory::payment($config); |
|
|
$result = $app->order->unify([ |
|
|
$result = $app->order->unify([ |
|
|
'body' => $order->title, |
|
|
|
|
|
'out_trade_no' => $order->order_no, |
|
|
|
|
|
'total_fee' => $order->price, //TODO 需要区分定金和全款
|
|
|
|
|
|
'notify_url' => route('wxpay_notify'), // 支付结果通知网址,如果不设置则会使用配置里的默认地址
|
|
|
|
|
|
|
|
|
'body' => $title, |
|
|
|
|
|
'out_trade_no' => $order_no . '-' . $pay_type, //后面加pay_type,主要是为了方便微信支付回调时区分定金(首付款)和尾款支付
|
|
|
|
|
|
'total_fee' => round($price * 100), //支付金额单位为分
|
|
|
|
|
|
'notify_url' => route('wxpay_notify', ['aid' => $this->agent_id]), // 支付结果通知网址,如果不设置则会使用配置里的默认地址
|
|
|
'trade_type' => 'JSAPI', |
|
|
'trade_type' => 'JSAPI', |
|
|
'openid' => $openid, |
|
|
'openid' => $openid, |
|
|
]); |
|
|
]); |
|
|
|
|
|
|
|
|
$jssdk = $app->jssdk; |
|
|
|
|
|
$config = $jssdk->bridgeConfig($result['prepay_id'], false); // 返回数组
|
|
|
|
|
|
|
|
|
if (empty($result['prepay_id'])) { |
|
|
|
|
|
return $result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return $this->success($config); |
|
|
|
|
|
|
|
|
$jssdk = $app->jssdk; |
|
|
|
|
|
return $jssdk->bridgeConfig($result['prepay_id'], false); // 返回数组
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//订单详情
|
|
|
//订单详情
|
|
|
@ -281,19 +320,32 @@ class OrderController extends Controller |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 计算最终价格(扣除优惠券之后的价格) |
|
|
* 计算最终价格(扣除优惠券之后的价格) |
|
|
* @param $agent_product |
|
|
|
|
|
* @param $num |
|
|
|
|
|
|
|
|
* $price:原价;$coupon:优惠券;$num:产品数量;$pay_type:支付方式 |
|
|
|
|
|
* @param float $price |
|
|
|
|
|
* @param Coupon $coupon |
|
|
|
|
|
* @param int $num |
|
|
|
|
|
* @param int $pay_type |
|
|
* @return float |
|
|
* @return float |
|
|
*/ |
|
|
*/ |
|
|
private function calc($agent_product, $num) |
|
|
|
|
|
|
|
|
private function calc($price, $coupon, $num, $pay_type) |
|
|
{ |
|
|
{ |
|
|
$total_price = $agent_product->price * $num; |
|
|
|
|
|
|
|
|
//根据支付方式计算价格
|
|
|
|
|
|
switch ($pay_type) { |
|
|
|
|
|
case 1: |
|
|
|
|
|
case 2: |
|
|
|
|
|
return $this->earnest; |
|
|
|
|
|
case 3: |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
//TODO 还要计算尾款支付金额
|
|
|
|
|
|
|
|
|
|
|
|
$total_price = $price * $num; |
|
|
//没有任何优惠券时直接返回最终价
|
|
|
//没有任何优惠券时直接返回最终价
|
|
|
if ($agent_product->coupon->isEmpty()) { |
|
|
|
|
|
|
|
|
if ($coupon && $coupon->isEmpty()) { |
|
|
return $total_price; |
|
|
return $total_price; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
$coupon = $agent_product->coupon->toArray(); |
|
|
|
|
|
|
|
|
$coupon = $coupon->toArray(); |
|
|
foreach ($coupon as $v) { |
|
|
foreach ($coupon as $v) { |
|
|
// TODO 未判断优惠券有效期
|
|
|
// TODO 未判断优惠券有效期
|
|
|
if ($v['type'] == 1 && !empty($v['detail']['full']) && !empty($v['detail']['reduction'])) { //满减
|
|
|
if ($v['type'] == 1 && !empty($v['detail']['full']) && !empty($v['detail']['reduction'])) { //满减
|
|
|
|