Browse Source

订单优惠券使用校验、用户订单操作调整

master
weigang 5 years ago
parent
commit
9f487ee890
  1. 113
      app/Controller/TestController.php
  2. 2
      app/Middleware/Auth/UserMiddleware.php
  3. 3
      app/Model/v3/Goods.php
  4. 3
      app/Model/v3/GoodsActivity.php
  5. 2
      app/Model/v3/Order.php
  6. 24
      app/Service/v3/Implementations/DeliveryMoneyService.php
  7. 4
      app/Service/v3/Implementations/GoodsActivityService.php
  8. 4
      app/Service/v3/Implementations/MiniprogramService.php
  9. 4
      app/Service/v3/Implementations/MqttService.php
  10. 91
      app/Service/v3/Implementations/OrderOnlineService.php
  11. 10
      app/Service/v3/Interfaces/DeliveryMoneyServiceInterface.php

113
app/Controller/TestController.php

@ -7,16 +7,23 @@ namespace App\Controller;
use App\Constants\v3\LogLabel;
use App\Constants\v3\OrderState;
use App\Constants\v3\OrderType;
use App\Constants\v3\SsdbKeys;
use App\Libs\FeiePrintClient;
use App\Model\v3\Order;
use App\Model\v3\OrderGoods;
use App\Model\v3\OrderMain;
use App\Service\v3\Interfaces\CouponRebateServiceInterface;
use App\Service\v3\Interfaces\CouponServiceInterface;
use App\Service\v3\Interfaces\DeviceServiceInterface;
use App\Service\v3\Interfaces\FeiePrintServiceInterface;
use App\Service\v3\Interfaces\FinancialRecordServiceInterface;
use App\Service\v3\Interfaces\GoodsActivityServiceInterface;
use App\Service\v3\Interfaces\MiniprogramServiceInterface;
use App\Service\v3\Interfaces\MqttServiceInterface;
use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
use App\Service\v3\Interfaces\UserServiceInterface;
use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\Utils\Coroutine;
@ -74,6 +81,12 @@ class TestController extends AbstractController
*/
protected $couponRebateService;
/**
* @Inject
* @var CouponServiceInterface
*/
protected $couponService;
/**
* @Inject
* @var OrderOnlineServiceInterface
@ -86,6 +99,18 @@ class TestController extends AbstractController
*/
protected $separateAccountsService;
/**
* @Inject
* @var GoodsActivityServiceInterface
*/
protected $goodsActivityService;
/**
* @Inject
* @var FinancialRecordServiceInterface
*/
protected $financialService;
public function index1(RequestInterface $request)
{
// $container = ApplicationContext::getContainer();
@ -128,13 +153,13 @@ class TestController extends AbstractController
// return $result;
// }
$orderMainId = $this->request->input('order_main_id');
$globalOrderId = $this->request->input('order_main_id');
// 查询订单
$orderMain = OrderMain::query()
->where([
'id' => $orderMainId,
'global_order_id' => $globalOrderId,
'type' => OrderType::ONLINE,
'state' => OrderState::UNPAID
'state' => OrderState::REFUNDING
])
->first();
@ -142,48 +167,82 @@ class TestController extends AbstractController
if (empty($orderMain)) {
$this->log->event(
LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG,
['global_order_id_fail' => $orderMainId]
['global_order_id_fail' => $globalOrderId]
);
return true;
}
// $orderPaid = $this->orderOfflineService->doPaid($orderMainId);
// 线下回调
// $orderPaid = $this->orderOfflineService->doPaid($globalOrderId);
// var_dump('orderOfflineService', $orderPaid);
// $separate = $this->separateAccountsService->orderOfflinePaid($orderMainId);
// $separate = $this->separateAccountsService->orderOfflinePaid($globalOrderId);
// var_dump('separateAccountsService', $separate);
//
// // 喇叭通知,兼容旧音响,MQTT+IOT
// $res = $this->mqttService->speakToStore($orderMainId);
// $res = $this->mqttService->speakToStore($globalOrderId);
// var_dump('mqttService', $res);
// $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMainId);
// $res = $this->deviceService->pubMsgToStoreByOrderMainId($globalOrderId);
// var_dump('deviceService', $res);
//
// // 公众号模板消息
// $res = $this->miniprogramService->sendTemMsgForOfflineOrder($orderMainId);
// $res = $this->miniprogramService->sendTemMsgForOfflineOrder($globalOrderId);
// var_dump('miniprogramService', $res);
// 线上回调
// $res = $this->orderOnlineService->doByPaid($globalOrderId);
// var_dump('orderOnlineService', $res);
// $res = $this->separateAccountsService->orderOnlinePaid($globalOrderId);
// var_dump('separateAccountsService', $res);
//
// // 优惠券返券
// $res = $this->couponRebateService->couponRebateInTask($globalOrderId);
// var_dump('couponRebateService', $res);
//
// // 喇叭通知,兼容旧音响,MQTT+IOT
// $res = $this->mqttService->speakToStore($globalOrderId);
// var_dump('mqttService', $res);
// $res = $this->deviceService->pubMsgToStoreByOrderMainId($globalOrderId);
// var_dump('deviceService', $res);
//
// // 公众号模板消息
// $res = $this->miniprogramService->sendTemMsgForOnlineOrder($globalOrderId);
// var_dump('miniprogramService', $res);
//
// // 打印订单,自动打印
// $res = $this->feiePrintService->feiePrint($globalOrderId);
// var_dump('feiePrintService', $res);
$res = $this->orderOnlineService->doByPaid($orderMainId);
var_dump('orderOnlineService', $res);
$res = $this->separateAccountsService->orderOnlinePaid($orderMainId);
var_dump('separateAccountsService', $res);
// 退款回调
// 添加退款时间
$orderMain->refund_time = time();
$orderMain->state = OrderState::REFUNDED;
$res = $orderMain->save();
var_dump('$orderMain', $res);
// 退款返还优惠券
$res = $this->couponService->orderRefundCoupons($orderMain->global_order_id);
var_dump('couponService', $res);
// 处理特价商品缓存
$orderChildren = Order::query()->where(['order_main_id' => $orderMain->global_order_id])->get()->toArray();
$orderGoods = OrderGoods::query()
->where(['activity_type' => 2])
->whereIn('order_id', array_values(array_column($orderChildren, 'id')))->get();
foreach ($orderGoods as $key => &$item) {
$this->goodsActivityService->clearCacheRecord($item['goods_id'], $item['number'], $orderMain->userId);
}
// 优惠券返券
$res = $this->couponRebateService->couponRebateInTask($orderMainId);
var_dump('couponRebateService', $res);
var_dump('$orderChildren', $orderChildren);
// 喇叭通知,兼容旧音响,MQTT+IOT
$res = $this->mqttService->speakToStore($orderMainId);
var_dump('mqttService', $res);
$res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMainId);
var_dump('deviceService', $res);
// 添加用户的流水
$res = $this->financialService->userByOLOrderRefund($orderMain->user_id, $orderMain->global_order_id, $orderMain->money);
var_dump('financialService', $res);
// 公众号模板消息
$res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMainId);
var_dump('miniprogramService', $res);
// 记录badge
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
$res = $ssdb->exec('hincr', SsdbKeys::USER_ORDER_BADGE.$orderMain->user_id, 'refund', 1);
var_dump('$ssdb', $res);
// 打印订单,自动打印
$res = $this->feiePrintService->feiePrint($orderMainId);
var_dump('feiePrintService', $res);
}
public function index2(RequestInterface $request)

2
app/Middleware/Auth/UserMiddleware.php

@ -2,8 +2,6 @@
namespace App\Middleware\Auth;
use App\Model\v3\User;
use App\TaskWorker\SSDBTask;
use Hashids\Hashids;
use Hyperf\HttpServer\Contract\RequestInterface as HttpRequest;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;

3
app/Model/v3/Goods.php

@ -100,7 +100,8 @@ class Goods extends Model
public function getCartNumAttribute()
{
return (integer)$this->shopCartService->check($this->request->user->id, $this->id);
$userId = $this->request->user->id ?? 0;
return $userId ? (integer)$this->shopCartService->check($userId, $this->id) : 0;
}
public function getIsEffectiveAttribute()

3
app/Model/v3/GoodsActivity.php

@ -67,7 +67,8 @@ class GoodsActivity extends Model
public function getCartNumAttribute()
{
return (integer)$this->shopCartService->check($this->request->user->id, $this->id);
$userId = $this->request->user->id ?? 0;
return $userId ? (integer)$this->shopCartService->check($userId, $this->id) : 0;
}
public function getIsEffectiveAttribute()

2
app/Model/v3/Order.php

@ -46,7 +46,7 @@ class Order extends Model
public function orderMain()
{
return $this->belongsTo(OrderMain::class, 'order_main_id', 'id');
return $this->belongsTo(OrderMain::class, 'order_main_id', 'global_order_id');
}
public function user()

24
app/Service/v3/Implementations/DeliveryMoneyService.php

@ -1,24 +0,0 @@
<?php
namespace App\Service\v3\Implementations;
use App\Service\v3\Interfaces\DeliveryMoneyServiceInterface;
class DeliveryMoneyService implements DeliveryMoneyServiceInterface
{
public function do($lat, $lng)
{
return 5.0;
}
public function check()
{
// TODO: Implement check() method.
}
public function undo()
{
// TODO: Implement undo() method.
}
}

4
app/Service/v3/Implementations/GoodsActivityService.php

@ -38,12 +38,12 @@ class GoodsActivityService implements GoodsActivityServiceInterface
}
// 商品下架或已删除
if($goods->on_sale == Goods::ON_SALE_NO || !is_null($goods->deleted_at)){
if($goods->on_sale == 0 || !is_null($goods->deleted_at)){
return ErrorCode::GOODS_ACTIVITY_ON_SALE_NO;
}
// 商品库存不足
if($goods->is_infinite != Goods::IS_INVENTORY && $goods->inventory < $num){
if($goods->is_infinite != 1 && $goods->inventory < $num){
return ErrorCode::GOODS_ACTIVITY_INVENTORY_ERROR;
}

4
app/Service/v3/Implementations/MiniprogramService.php

@ -44,8 +44,8 @@ class MiniprogramService implements MiniprogramServiceInterface
$goods_temp = [];
foreach ($order_goods as $k => &$goods) {
array_push($goods_temp, $goods['name']."*".$goods['number']."/".($goods['spec']?:$goods['goods_unit']));
array_push($goods_temp_all, $goods['name']."*".$goods['number']."/".($goods['spec']?:$goods['goods_unit']));
array_push($goods_temp, $goods['name']."*".$goods['number']."/".($goods['goods_unit']));
array_push($goods_temp_all, $goods['name']."*".$goods['number']."/".($goods['goods_unit']));
}
// 商户/门店的openid

4
app/Service/v3/Implementations/MqttService.php

@ -24,7 +24,7 @@ class MqttService implements MqttServiceInterface
if ($isMain) {
$orders = $orders->where(['order_main_id' => $globalOrderId])->get();
} else {
$orders = $orders->where(['global_order_id' => $globalOrderId])->get();
$orders = $orders->where(['id' => $globalOrderId])->get();
}
if(empty($orders)) return;
@ -37,6 +37,8 @@ class MqttService implements MqttServiceInterface
// 发布订阅消息
$this->publish($template, config('mqtt.topic'), $to_client_id);
}
return true;
}
/**

91
app/Service/v3/Implementations/OrderOnlineService.php

@ -23,12 +23,11 @@ use App\Model\v3\Store;
use App\Model\v3\UserAddress;
use App\Service\v3\Interfaces\CouponRecServiceInterface;
use App\Service\v3\Interfaces\CouponServiceInterface;
use App\Service\v3\Interfaces\DeliveryMoneyServiceInterface;
use App\Service\v3\Interfaces\DistributionPriceServiceInterface;
use App\Service\v3\Interfaces\GoodsActivityServiceInterface;
use App\Service\v3\Interfaces\GoodsServiceInterface;
use App\Service\v3\Interfaces\PaymentServiceInterface;
use App\Service\v3\Interfaces\ShopCartUpdateServiceInterface;
use App\Service\v3\Interfaces\UserAddressServiceInterface;
use App\TaskWorker\SSDBTask;
use Exception;
use Hyperf\Database\Model\Model;
@ -49,9 +48,9 @@ class OrderOnlineService implements OrderOnlineServiceInterface
/**
* @Inject
* @var DistributionPriceServiceInterface
* @var UserAddressServiceInterface
*/
protected $deliveryService;
protected $userAddressService;
/**
* @Inject
@ -110,11 +109,17 @@ class OrderOnlineService implements OrderOnlineServiceInterface
$currentTime = time();
bcscale(6);
// 用户收货地址
$userAddr = UserAddress::query()->find($userAddrId);
// 获取配送费用
$deliveryAmount = $this->deliveryService->do($userAddr->lat, $userAddr->lng);
// 优惠券数据
$couponRec = CouponRec::query()->lockForUpdate()->whereIn('id', $receiveCouponIds)->get()->toArray();
$userAddrAndDPrice = $this->userAddressService->getAddressAndDistributionPrice($userAddrId, $marketId);
$userAddr = $userAddrAndDPrice['address'];
$deliveryAmount = $userAddrAndDPrice['distribution_price'];
// 优惠券数据,当前订单可用个优惠券
$couponRecs = $this->couponRecService->allForOnlineOrderAvailable($userId, $marketId);
$canRealUseCoupons = $couponRecs['available'];
$canRealUseCouponRecIds = array_values(array_column($canRealUseCoupons, 'id'));
if (!empty(array_diff($receiveCouponIds, $canRealUseCouponRecIds))) {
throw new ErrorCodeException(ErrorCode::GOODS_ACTIVITY_CANNOT_USE_COUPON, '[优惠券不可用]'.$receiveCouponIds.'_'.$canRealUseCouponRecIds);
}
// 处理购物车数据,计算订单金额、子订单数据处理等
$totalAmount = 0; # 实付金额
@ -146,49 +151,27 @@ class OrderOnlineService implements OrderOnlineServiceInterface
$carts = ShoppingCart::query()->whereIn('id', $cartIds)->where(['market_id' => $marketId, 'user_id' => $userId])->get();
foreach ($carts as $k => &$cart) {
// 查个商品
// 查个商品,做商品有效的判断检查
$goods = [];
if ($cart->activity_type == 1) {
$goods = Goods::query()->lockForUpdate()->find($cart->goods_id);
$goods = Goods::query()->lockForUpdate()->with('store')->find($cart->goods_id);
if (empty($goods)) {
throw new ErrorCodeException(ErrorCode::ORDER_GOODS_NOT_AVAILABLE, '[商品失效1]'.$cart->goods_id);
}
$check = $this->goodsService->check($goods, $cart->num);
if (true !== $check) {
throw new ErrorCodeException($check, '[商品失效1]'.$cart->goods_id);
throw new ErrorCodeException($check, '[商品失效2]'.$cart->goods_id);
}
} elseif ($cart->activity_type == 2) {
$goods = GoodsActivity::query()->lockForUpdate()->find($cart->goods_id);
$goods = GoodsActivity::query()->lockForUpdate()->with('store')->find($cart->goods_id);
if (empty($goods)) {
throw new ErrorCodeException(ErrorCode::ORDER_GOODS_NOT_AVAILABLE, '[商品失效3]'.$cart->goods_id);
}
$check = $this->goodsActivityService->check($goods, $cart->num, $userId);
if (true !== $check) {
throw new ErrorCodeException($check, '[商品失效2]'.$cart->goods_id);
}
// 活动商品不可用优惠券
if ($goods->can_use_coupon!=1 && $receiveCouponIds) {
throw new ErrorCodeException(ErrorCode::GOODS_ACTIVITY_CANNOT_USE_COUPON, '[商品失效]'.$cart->goods_id);
throw new ErrorCodeException($check, '[商品失效4]'.$cart->goods_id);
}
// 活动商品可用优惠券,再校验这些优惠券是不是可以在当前活动类型可用
// receiveCouponIds中是不是有当前活动不可用的优惠券
$couponIds = array_values(array_column($couponRec, 'coupon_id'));
$couponsActivityAvailable = Coupon::query()
->select(['id'])
->whereJsonContains('activity_available', [(string)$goods->type])
->whereJsonContains('market_ids', [(string)$goods->market_id])
->whereIn('id', $couponIds)
->get()->toArray();
$couponsActivityAvailableIds = array_values(array_column($couponsActivityAvailable, 'id'));
if (!empty(array_diff($couponIds, $couponsActivityAvailableIds))) {
throw new ErrorCodeException(ErrorCode::GOODS_ACTIVITY_CANNOT_USE_COUPON, '[商品失效]'.json_encode($couponsActivityAvailableIds));
}
}
if (empty($goods)) {
throw new ErrorCodeException(ErrorCode::ORDER_GOODS_NOT_AVAILABLE);
}
// 库存判断
if ($goods->is_infinite !=1 && $goods->inventory < $cart->num) {
throw new ErrorCodeException(ErrorCode::ORDER_GOODS_INVENTORY_LIMIT);
}
// 算金额
@ -228,31 +211,25 @@ class OrderOnlineService implements OrderOnlineServiceInterface
// 优惠券的使用
$couponMoney = 0;
if (!empty($couponRec)) {
$couponsCanUse = $this->couponRecService->allForOrderOlAvailable($totalAmount, $userId, $marketId, 2, $storeTypeIds);
$couponCanUseIds = array_column($couponsCanUse, 'id');
$couponCanUseIds = array_intersect($couponCanUseIds, $receiveCouponIds);
$couponCannotUseIds = array_diff($receiveCouponIds, $couponCanUseIds);
if (empty($couponCanUseIds)||!empty($couponCannotUseIds)) {
throw new ErrorCodeException(ErrorCode::COUPON_NOT_AVAILABLE);
}
if (!empty($receiveCouponIds)) {
// 计算红包折扣金额
foreach ($couponsCanUse as $key => $coupon) {
if (!in_array($coupon->id, $receiveCouponIds)) {
foreach ($canRealUseCoupons as $key => &$coupon) {
if (!in_array($coupon['id'], $receiveCouponIds)) {
unset($coupon);
continue;
}
if ($coupon->discount_type == Coupon::DISCOUNT_TYPE_CASH) {
$couponMoney = bcadd($couponMoney, $coupon->discounts, 2);
} elseif ($coupon->discount_type == Coupon::DISCOUNT_TYPE_RATE) {
$discountRate = bcdiv($coupon->discounts,10);
if ($coupon['coupon']['discount_type'] == Coupon::DISCOUNT_TYPE_CASH) {
$couponMoney = bcadd($couponMoney, $coupon['coupon']['discounts'], 2);
} elseif ($coupon['coupon']['discount_type'] == Coupon::DISCOUNT_TYPE_RATE) {
$discountRate = bcdiv($coupon['coupon']['discounts'],10);
$discountRate = bcsub(1,$discountRate);
$discountMoney = bcmul($orderAmount, $discountRate);
$couponMoney = bcadd($couponMoney, $discountMoney, 2);
}
}
}
// 获取分布式全局ID
@ -324,7 +301,7 @@ class OrderOnlineService implements OrderOnlineServiceInterface
}
// 优惠券红包使用记录
$this->couponService->orderUseCoupons($globalOrderId, $couponRec);
$this->couponService->orderUseCoupons($globalOrderId, $canRealUseCoupons);
Db::commit();

10
app/Service/v3/Interfaces/DeliveryMoneyServiceInterface.php

@ -1,10 +0,0 @@
<?php
namespace App\Service\v3\Interfaces;
interface DeliveryMoneyServiceInterface
{
public function do($lat, $lng);
public function check();
public function undo();
}
Loading…
Cancel
Save