Browse Source

订单相关操作

master
weigang 5 years ago
parent
commit
f395a4de78
  1. 24
      app/Constants/v3/ErrorCode.php
  2. 10
      app/Constants/v3/LogLabel.php
  3. 4
      app/Constants/v3/OrderState.php
  4. 2
      app/Controller/v3/HomeController.php
  5. 17
      app/Controller/v3/LocationController.php
  6. 2
      app/Controller/v3/OrderOfflineController.php
  7. 90
      app/Controller/v3/OrderOnlineController.php
  8. 48
      app/Controller/v3/PaymentController.php
  9. 87
      app/JsonRpc/OrderOnlineService.php
  10. 8
      app/JsonRpc/OrderOnlineServiceInterface.php
  11. 21
      app/Model/v3/Market.php
  12. 2
      app/Model/v3/OrderMain.php
  13. 2
      app/Model/v3/ServiceReward.php
  14. 2
      app/Model/v3/UserRelationBind.php
  15. 37
      app/Request/v3/OrderOnlineStateRequest.php
  16. 7
      app/Service/v3/Implementations/ActivityService.php
  17. 12
      app/Service/v3/Implementations/BannerService.php
  18. 2
      app/Service/v3/Implementations/CouponRecService.php
  19. 112
      app/Service/v3/Implementations/CouponService.php
  20. 37
      app/Service/v3/Implementations/GoodsActivityService.php
  21. 8
      app/Service/v3/Implementations/OrderOfflineService.php
  22. 167
      app/Service/v3/Implementations/OrderOnlineService.php
  23. 66
      app/Service/v3/Implementations/SeparateAccountsService.php
  24. 15
      app/Service/v3/Interfaces/CouponServiceInterface.php
  25. 2
      app/Service/v3/Interfaces/GoodsActivityServiceInterface.php
  26. 50
      app/Service/v3/Interfaces/OrderOnlineServiceInterface.php
  27. 5
      app/Service/v3/Interfaces/SeparateAccountsServiceInterface.php
  28. 4
      config/autoload/wechat.php
  29. 6
      config/routes.php

24
app/Constants/v3/ErrorCode.php

@ -53,6 +53,30 @@ class ErrorCode extends AbstractConstants
*/
const ORDER_NOT_AVAILABLE = 605;
/**
* 订单取消失败
* @Message("订单取消失败")
*/
const ORDER_CANCEL_FAIL = 606;
/**
* 订单删除失败
* @Message("订单删除失败")
*/
const ORDER_DELETE_FAIL = 607;
/**
* 订单申请退款失败
* @Message("订单申请退款失败")
*/
const ORDER_APPLY_REFUND_FAIL = 608;
/**
* 订单完成失败
* @Message("订单完成失败")
*/
const ORDER_COMPLETE_FAIL = 609;
/************************************/
/* 支付相关 651-700 */
/************************************/

10
app/Constants/v3/LogLabel.php

@ -52,6 +52,11 @@ class LogLabel extends AbstractConstants
*/
const ORDER_PAYMENT_LOG = 'order_payment_log';
/**
* @Message("订单完成")
*/
const ORDER_COMPLETE_LOG = 'order_complete_log';
/**
* @Message("IOT设备绑定")
*/
@ -72,4 +77,9 @@ class LogLabel extends AbstractConstants
*/
const SEPARATE_ACCOUNTS_LOG = 'separate_accounts_log';
/**
* @Message("优惠券退还")
*/
const COUPON_REFUND_LOG = 'coupon_refund_log';
}

4
app/Constants/v3/OrderState.php

@ -68,11 +68,13 @@ class OrderState extends AbstractConstants
/**
* @Message("订单完成")
*/
const FINISH = [self::COMPLETED, self::EVALUATED];
const FINISH = [self::COMPLETED, self::EVALUATED, self::CANCELED];
/**
* @Message("售后/退款")
*/
const REFUND = [self::REFUNDING, self::REFUNDED, self::REFUND_REFUSE];
const CAN_DEL = [self::COMPLETED, self::EVALUATED, self::CANCELED, self::REFUNDED, self::REFUND_REFUSE];
}

2
app/Controller/v3/HomeController.php

@ -94,7 +94,7 @@ class HomeController extends BaseController
public function appletIndex()
{
$marketId = $this->request->input('market_id', 0);
$marketId = $this->request->input('market_id', -1);
$banners = $this->bannerService->all(Banner::TYPE_APPLET_INDEX, $marketId);
$categories = $this->categoryService->allForAppletIndex();
$activity = $this->activityService->allForAppletIndex(env('APPLET_INDEX_ACTIVITY_TYPE'), $marketId);

17
app/Controller/v3/LocationController.php

@ -3,6 +3,7 @@
namespace App\Controller\v3;
use App\Controller\BaseController;
use App\Model\v3\Market;
use App\Service\v3\Interfaces\LocationServiceInterface;
use Hyperf\Di\Annotation\Inject;
@ -27,21 +28,7 @@ class LocationController extends BaseController
*/
public function getNearestMarket()
{
return $this->success([
'market' => [
'id' => 1,
'name' => '海尔青啤',
'province_id' => 1,
'province_name' => '广西',
'city_id' => 2,
'city_name' => '南宁市',
'area_id' => 3,
'area_name' => '良庆区',
'address' => '海尔青啤广场',
'lng' => '108.383566',
'lat' => '22.759946',
]
]);
return $this->success(Market::query()->find(1));
}
public function getMarketListByLocation()

2
app/Controller/v3/OrderOfflineController.php

@ -9,6 +9,7 @@ use App\Service\v3\Interfaces\OrderOfflineServiceInterface;
use App\Service\v3\Interfaces\StoreServiceInterface;
use Hyperf\Validation\ValidationException;
use Hyperf\Di\Annotation\Inject;
use Psr\Http\Message\ResponseInterface;
class OrderOfflineController extends BaseController
{
@ -51,6 +52,7 @@ class OrderOfflineController extends BaseController
* 1、用户id、去商户id下支付、支付的金额
* 2、下单同时支付,下发支付参数
* @param OrderOfflineRequest $request
* @return ResponseInterface
*/
public function add(OrderOfflineRequest $request)
{

90
app/Controller/v3/OrderOnlineController.php

@ -3,12 +3,19 @@
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\OrderMain;
use App\Request\v3\OrderOnlineDetailRequest;
use App\Request\v3\OrderOnlineRequest;
use App\Request\v3\OrderOnlineStateRequest;
use App\Service\v3\Implementations\PaymentService;
use App\Service\v3\Interfaces\CouponRecServiceInterface;
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;
@ -46,6 +53,12 @@ class OrderOnlineController extends BaseController
*/
protected $shopCartService;
/**
* @Inject
* @var SeparateAccountsServiceInterface
*/
protected $separateAccountsService;
/*
* 如果没有绑手机号去绑定页面
* 收货地址接口
@ -110,6 +123,7 @@ class OrderOnlineController extends BaseController
// 下单
$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'],
@ -118,10 +132,84 @@ class OrderOnlineController extends BaseController
$params['total_money'],
$params['delivery_time_note'],
$params['service_money'],
explode(',', $params['coupon_ids']),
$couponIds,
$params['plat']
);
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['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['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['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['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['order_id'], $params['user_id']);
$this->separateAccountsService->orderOnlineCompleted($params['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, $e->getMessage());
}
}
}

48
app/Controller/v3/PaymentController.php

@ -1,48 +0,0 @@
<?php
namespace App\Controller\v3;
use App\Controller\BaseController;
use App\Model\v3\OrderMain;
use App\Service\v3\Interfaces\PaymentServiceInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Validation\ValidationException;
class PaymentController extends BaseController
{
/**
* @Inject
* @var PaymentServiceInterface
*/
protected $paymentService;
/**
* 微信线上订单支付
* 主要用户待付款订单中的付款操作
*/
public function wechatpayOnline()
{
$validator = $this->validationFactory->make(
$this->request->all(),
[
'global_order_id' => 'required|nonempty',
'user_id' => 'required|nonempty',
],
[
'global_order_id.*' => '订单号错误'
]
);
if ($validator->fails()) {
throw new ValidationException($validator);
}
$params = $validator->validated();
$orderMain = OrderMain::query()->select('global_order_id', 'money', 'user_id')
->where(['global_order_id' => $params['global_order_id']])->first();
$parameters = $this->paymentService->do($orderMain->global_order_id, $orderMain->money, $orderMain->user_id);
return $this->success(['parameters' => $parameters]);
}
}

87
app/JsonRpc/OrderOnlineService.php

@ -0,0 +1,87 @@
<?php
namespace App\JsonRpc;
use App\Commons\Log;
use App\Constants\v3\ErrorCode;
use App\Exception\ErrorCodeException;
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
use Hyperf\DbConnection\Db;
use Hyperf\RpcServer\Annotation\RpcService;
use Hyperf\Di\Annotation\Inject;
use App\Constants\v3\LogLabel;
/**
* @RpcService(name="OrderOnlineService", protocol="jsonrpc-http", server="jsonrpc-http", publishTo="")
*/
class OrderOnlineService implements OrderOnlineServiceInterface
{
/**
* @Inject
* @var Log
*/
protected $log;
/**
* @Inject
* @var \App\Service\v3\Interfaces\OrderOnlineServiceInterface
*/
protected $orderOnlineService;
/**
* @Inject
* @var SeparateAccountsServiceInterface
*/
protected $separateAccountsService;
public function onlineComplete($orderMainId, $userId)
{
Db::beginTransaction();
try {
$this->orderOnlineService->doComplete($orderMainId, $userId);
$this->separateAccountsService->orderOnlineCompleted($orderMainId, $userId);
Db::commit();
return [
"status" => 200,
"code" => 0,
"result" => [],
"message" => '调用成功'
];
} catch (\Exception $e) {
Db::rollBack();
$this->log->event(LogLabel::ORDER_COMPLETE_LOG, ['exception' => $e->getMessage()]);
throw new ErrorCodeException(ErrorCode::ORDER_COMPLETE_FAIL, $e->getMessage());
}
}
/**
* 线上订单退款
* 申请退款 state = 8
* 退款成功 state = 9
*/
public function onlineRefund($global_order_id){
$result = [
"status" => 200,
"code" => ErrorCode::ORDER_FAILURE,
"result" => [],
"message" => ''
];
$res = $this->orderOnlineService->onlineRefund($global_order_id);
if($res['code'] > 0){
$result['result'] = $res;
$result['message'] = '退款失败';
}else{
$result['code'] = 0;
$result['result'] = $res;
$result['message'] = '退款成功';
};
return $result;
}
}

8
app/JsonRpc/OrderOnlineServiceInterface.php

@ -0,0 +1,8 @@
<?php
namespace App\JsonRpc;
interface OrderOnlineServiceInterface
{
public function onlineComplete($orderMainId, $userId);
}

21
app/Model/v3/Market.php

@ -8,6 +8,27 @@ class Market extends Model
{
protected $table = 'lanzu_market';
protected $appends = [
'province_name',
'city_name',
'region_name'
];
public function getProvinceNameAttribute()
{
return Area::query()->find($this->attributes['province_id'])->value('name');
}
public function getCityNameAttribute()
{
return Area::query()->find($this->attributes['city_id'])->value('name');
}
public function getRegionNameAttribute()
{
return Area::query()->find($this->attributes['region_id'])->value('name');
}
public function stores()
{
return $this->hasMany(Store::class,'market_id','id');

2
app/Model/v3/OrderMain.php

@ -6,9 +6,11 @@ use App\Constants\v3\OrderState;
use App\Constants\v3\Payment;
use App\Constants\v3\Shipping;
use App\Model\Model;
use Hyperf\Database\Model\SoftDeletes;
class OrderMain extends Model
{
use SoftDeletes;
protected $table = 'lanzu_order_main';
protected $fillable = [

2
app/Model/v3/ServiceReward.php

@ -3,6 +3,8 @@
declare (strict_types=1);
namespace App\Model\v3;
use App\Model\Model;
class ServiceReward extends Model
{
/**

2
app/Model/v3/UserRelationBind.php

@ -3,6 +3,8 @@
declare (strict_types=1);
namespace App\Model\v3;
use App\Model\Model;
/**
*/
class UserRelationBind extends Model

37
app/Request/v3/OrderOnlineStateRequest.php

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace App\Request\v3;
use App\Request\BaseFormRequest;
class OrderOnlineStateRequest extends BaseFormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'order_id' => 'required|nonempty|integer',
'user_id' => 'required|nonempty|integer',
];
}
/**
* @return array
*/
public function messages(): array
{
return [
'*.*' => ':attribute无效',
];
}
public function attributes(): array
{
return parent::attributes();
}
}

7
app/Service/v3/Implementations/ActivityService.php

@ -28,8 +28,11 @@ class ActivityService implements ActivityServiceInterface
{
$builder = GoodsActivity::query()
->with(['store'])
->where(['type' => $type])
->whereIn('market_id', [0,$marketId]);
->where(['type' => $type]);
if ($marketId != -1) {
$builder = $builder->whereJsonContains('market_ids', [(string)$marketId]);
}
return $builder->get()->toArray();
}

12
app/Service/v3/Implementations/BannerService.php

@ -9,9 +9,13 @@ class BannerService implements BannerServiceInterface
{
public function all($type, $marketId)
{
return Banner::query()
->where(['type' => $type])
->whereJsonContains('market_ids', [(string)$marketId])
->get()->toArray();
$builder = Banner::query()
->where(['type' => $type]);
if ($marketId != -1) {
$builder = $builder->whereJsonContains('market_ids', [(string)$marketId]);
}
return $builder->get()->toArray();
}
}

2
app/Service/v3/Implementations/CouponRecService.php

@ -56,7 +56,7 @@ class CouponRecService implements CouponRecServiceInterface
}
if (!empty($storeTypeIds)) {
$builder->whereJsonContains('coupon.storetype_ids', $storeTypeIds);
$builder->whereJsonContains('coupon.category_ids', $storeTypeIds);
}
$builder->where(['receive.user_id' => $userId])

112
app/Service/v3/Implementations/CouponService.php

@ -2,7 +2,14 @@
namespace App\Service\v3\Implementations;
use App\Constants\v3\ErrorCode;
use App\Constants\v3\LogLabel;
use App\Exception\ErrorCodeException;
use App\Model\v3\CouponRec;
use App\Model\v3\CouponUse;
use App\Model\v3\OrderMain;
use App\Service\v3\Interfaces\CouponServiceInterface;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;
@ -55,4 +62,109 @@ class CouponService implements CouponServiceInterface
$expireRes = $redis->expire('coupon_' . date('Ymd') . '_used_' . $userId, strtotime(date('Y-m-d') . ' 23:59:59') - time());
return $setRes && $expireRes;
}
public function orderUseCoupons($orderMainId, $couponRecs)
{
Db::beginTransaction();
try {
if (is_array($couponRecs)&&!empty($couponRecs)) {
# 使用记录、更新当前优惠券
foreach ($couponRecs as $key => &$coupon) {
$couponUse = [
'user_id' => $coupon['user_id'],
'user_receive_id' => $coupon['id'],
'coupon_id' => $coupon['coupon_id'],
'order_main_id' => $orderMainId,
'use_time' => time(),
'return_time' => 0,
'number' => 1,
'status' => 1,
'update_time' => 0,
];
$insertRes = CouponUse::query()->insert($couponUse);
if ($insertRes) {
$status = 0;
$numberRemain = $coupon['number_remain'] - 1;
if ($numberRemain == 0) {
$status = 2;
} elseif ($numberRemain > 0 && $numberRemain < $coupon['number']) {
$status = 1;
} elseif ($numberRemain == $coupon['number']) {
$status = 0;
}
$upRes = CouponRec::query()->where(['id' => $coupon['id']])
->update(['number_remain' => $numberRemain, 'status' => $status]);
if (!$upRes) {
Db::rollBack();
throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE);
}
// 缓存使用记录
$usedRes = $this->cacheTodayCouponUsed($coupon['user_id'], $coupon['coupon_id'], $coupon['id']);
if (!$usedRes) {
Db::rollBack();
throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE);
}
} else {
Db::rollBack();
throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE);
}
}
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE, $e->getMessage());
}
}
/**
* 退还优惠券,订单取消,申请退款成功时
* 先查询是否正常使用优惠券
* 修改状态,退还领取记录库存,删除ssdb缓存
* @param $orderMainId
* @return bool
*/
public function orderRefundCoupons($orderMainId)
{
$currentTime = time();
Db::beginTransaction();
try {
$couponUses = CouponUse::query()
->where('order_main_id', $orderMainId)
->where('status', 1)
->get();
if (!empty($couponUses)) {
foreach ($couponUses as $use) {
$use->status = 1;
$use->return_time = $currentTime;
$use->update_time = $currentTime;
$res = $use->save();
$couponReceive = CouponRec::query()
->where('id', $use->user_receive_id)
->whereRaw('number >= number_remain+' . $use->number)
->update([
'number_remain' => Db::raw('number_remain+' . $use->number),
'status' => Db::raw('IF(number=number_remain, 0,1)'), 'update_time' => $currentTime
]);
if ($res && $couponReceive) {
$redis = ApplicationContext::getContainer()->get(Redis::class);
$clearUseRedis = $redis->sRem('coupon_' . date('Ymd') . '_used_' . $use->user_id, $use->coupon_id);
}
}
}
Db::commit();
return true;
} catch (\Exception $e) {
$this->log->event(LogLabel::COUPON_REFUND_LOG, ['msg' => '订单取消/退款退还优惠券', 'exception' => $e->getMessage()]);
Db::rollBack();
return false;
}
}
}

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

@ -31,7 +31,7 @@ class GoodsActivityService implements GoodsActivityServiceInterface
}
// 商户歇业
if($goods->store->is_rest != Store::IS_OPEN_YES){
if($goods->store->is_rest == 1){
return ErrorCode::GOODS_ACTIVITY_ON_SALE_NO;
}
@ -46,13 +46,13 @@ class GoodsActivityService implements GoodsActivityServiceInterface
}
// 是否超过限购数量
if ($goods->restrict_num > $num) {
if ($goods->restrict_num < $num) {
return ErrorCode::GOODS_ACTIVITY_RESTRICT_LIMIT;
}
// 是否已经购买过(某个时间段内,时间段有商品的限制)
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
$hasBuy = $ssdb->exec('get', SsdbKeys::ACTIVITY_GOODS_BUY_RECORD.$userId.'_'.$goodsId);
$hasBuy = $ssdb->exec('get', SsdbKeys::ACTIVITY_GOODS_BUY_RECORD.$userId.'_'.$goods->type.'_'.$goodsId);
if ($hasBuy && $hasBuy >= $goods->time_limit_num) {
return ErrorCode::GOODS_ACTIVITY_BUY;
}
@ -80,17 +80,19 @@ class GoodsActivityService implements GoodsActivityServiceInterface
public function cacheRecord($goodsId, $num, $userId)
{
$goods = GoodsActivity::query()->select('time_limit_days', 'time_limit_num')
$goods = GoodsActivity::query()
->where('id', $goodsId)
->first();
$ssdbKey = SsdbKeys::ACTIVITY_GOODS_BUY_RECORD.$userId.'_'.$goodsId;
$ssdbKey = SsdbKeys::ACTIVITY_GOODS_BUY_RECORD.$userId.'_'.$goods->type.'_'.$goodsId;
$expireTime = 0;
if ($goods->time_limit_days <= 1) {
if ($goods->time_limit_days >= 1) {
$expireTime += strtotime(date('Y-m-d 23:59:59')) - time();
var_dump('ex1', $expireTime);
}
$expireTime += ($goods->time_limit_days-1) *86400;
$expireTime += ($goods->time_limit_days-1) * 86400;
var_dump('ex2', $expireTime);
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
@ -103,6 +105,27 @@ class GoodsActivityService implements GoodsActivityServiceInterface
}
public function clearCacheRecord($goodsId, $num, $userId)
{
$goods = GoodsActivity::query()
->where('id', $goodsId)
->first();
var_dump('$goods', $goods, $goodsId);
if (empty($goods)) {
return true;
}
$ssdbKey = SsdbKeys::ACTIVITY_GOODS_BUY_RECORD.$userId.'_'.$goods->type.'_'.$goodsId;
var_dump('ssdbkey', $ssdbKey);
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
if (!$ssdb->exec('exists', $ssdbKey)) {
} else {
$res = $ssdb->exec('incr', $ssdbKey, -1*$num);
var_dump('res', $res, -1*$num);
}
}
/**
* 统计订单中活动商品的数量,并校验
* @param $orderGoods

8
app/Service/v3/Implementations/OrderOfflineService.php

@ -57,7 +57,7 @@ class OrderOfflineService implements OrderOfflineServiceInterface
'delivery_time_note' => ''
];
$orderMain = OrderMain::create($dataMain);
$orderMain = OrderMain::query()->create($dataMain);
$orderMainId = $orderMain->id;
// 子订单数据
@ -70,15 +70,15 @@ class OrderOfflineService implements OrderOfflineServiceInterface
'note' => ''
];
$orderChild = Order::create($dataChildren);
$orderChild = Order::query()->create($dataChildren);
$orderChildId = $orderChild->id;
Db::commit();
// 支付
return $this->paymentService->do($globalOrderId, $money, $userId, config('site_host') . '/v3/wechat/notify/offline');
return $this->paymentService->do($globalOrderId, $money, $userId, config('wechat.notify_url.offline'));
} catch (\Exception $e) {
Db::rollBack();
$this->log->event(LogLabel::ORDER_ONLINE_LOG, ['exception_msg' => $e->getMessage()]);
$this->log->event(LogLabel::ORDER_OFFLINE_LOG, ['exception_msg' => $e->getMessage()]);
throw new ErrorCodeException(ErrorCode::ORDER_ONLINE_FAIL);
}
}

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

@ -29,6 +29,8 @@ use App\Service\v3\Interfaces\GoodsActivityServiceInterface;
use App\Service\v3\Interfaces\GoodsServiceInterface;
use App\Service\v3\Interfaces\PaymentServiceInterface;
use App\TaskWorker\SSDBTask;
use Exception;
use Hyperf\Database\Model\Model;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
@ -142,13 +144,13 @@ class OrderOnlineService implements OrderOnlineServiceInterface
$goods = Goods::query()->lockForUpdate()->find($cart->goods_id);
$check = $this->goodsService->check($goods->id, $cart->num);
if (true !== $check) {
// throw new ErrorCodeException($check, '[商品失效1]'.$cart->goods_id);
throw new ErrorCodeException($check, '[商品失效1]'.$cart->goods_id);
}
} elseif ($cart->activity_type == 2) {
$goods = GoodsActivity::query()->lockForUpdate()->find($cart->goods_id);
$check = $this->goodsActivityService->check($goods->id, $cart->num, $userId);
if (true !== $check) {
// throw new ErrorCodeException($check, '[商品失效2]'.$cart->goods_id);
throw new ErrorCodeException($check, '[商品失效2]'.$cart->goods_id);
}
// 活动商品不可用优惠券
@ -314,71 +316,70 @@ class OrderOnlineService implements OrderOnlineServiceInterface
}
// 优惠券红包使用记录
if (is_array($couponRec)&&!empty($couponRec)) {
# 使用记录、更新当前优惠券
foreach ($couponRec as $key => &$coupon) {
$couponUse = [
'user_id' => $coupon['user_id'],
'user_receive_id' => $coupon['id'],
'coupon_id' => $coupon['coupon_id'],
'order_main_id' => $orderMainId,
'use_time' => $currentTime,
'return_time' => 0,
'number' => 1,
'status' => 1,
'update_time' => 0,
];
$insertRes = CouponUse::query()->insert($couponUse);
if ($insertRes) {
$numberRemain = $coupon['number_remain'] - 1;
if ($numberRemain == 0) {
$status = 2;
} elseif ($numberRemain > 0 && $numberRemain < $coupon['number']) {
$status = 1;
} elseif ($numberRemain == $coupon['number']) {
$status = 0;
}
$upRes = CouponRec::query()->where(['id' => $coupon['id']])->update(['number_remain' => $numberRemain, 'status' => $status]);
if (!$upRes) {
Db::rollBack();
throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE);
}
// 缓存使用记录
$usedRes = $this->couponService->cacheTodayCouponUsed($coupon['user_id'], $coupon['coupon_id'], $coupon['id']);
if (!$usedRes) {
Db::rollBack();
throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE);
}
} else {
Db::rollBack();
throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE);
}
}
}
$this->couponService->orderUseCoupons($orderMainId, $couponRec);
Db::commit();
// 支付
return $this->paymentService->do($globalOrderId, $totalAmount, $userId, config('site_host') . '/v3/wechat/notify/online');
} catch (\Exception $e) {
return $this->paymentService->do($globalOrderId, $totalAmount, $userId, config('wechat.notify_url.online'));
} catch (Exception $e) {
Db::rollBack();
$this->log->event(LogLabel::ORDER_ONLINE_LOG, ['exception_msg' => $e->getMessage()]);
throw new ErrorCodeException(ErrorCode::ORDER_ONLINE_FAIL);
throw new ErrorCodeException(ErrorCode::ORDER_ONLINE_FAIL, $e->getMessage());
}
}
public function check()
public function check($orderMainId, $userId, $state): Model
{
// TODO: Implement check() method.
$builder = OrderMain::query()
->where(['id' => $orderMainId, 'user_id' => $userId]);
if (is_array($state)) {
$builder = $builder->whereIn('state', $state);
} else {
$builder = $builder->where(['state' => $state]);
}
$orderMain = $builder->first();
if (empty($orderMain)) {
throw new ErrorCodeException(ErrorCode::ORDER_NOT_AVAILABLE);
}
return $orderMain;
}
public function undo()
/**
* @inheritDoc
*/
public function undo($orderMainId, $userId)
{
// TODO: Implement undo() method.
Db::beginTransaction();
try {
// 订单待支付
$orderMain = $this->check($orderMainId, $userId, OrderState::UNPAID);
$orderMain->state = OrderState::CANCELED;
if (!$orderMain->save()) {
throw new ErrorCodeException(ErrorCode::ORDER_NOT_AVAILABLE);
}
// 退还优惠券
$this->couponService->orderRefundCoupons($orderMainId);
// 撤销活动商品购买记录
$orders = Order::query()->where(['order_main_id' => $orderMainId])->get()->toArray();
$orderGoods = OrderGoods::query()
->where('activity_type', 2)
->whereIn('order_id', array_values(array_column($orders, 'id')))
->get();
foreach ($orderGoods as $key => &$goods) {
$this->goodsActivityService->clearCacheRecord($goods->goods_id, $goods->number, $orderMain->user_id);
}
Db::commit();
return true;
} catch (Exception $e) {
Db::rollBack();
throw new ErrorCodeException(ErrorCode::ORDER_CANCEL_FAIL, $e->getMessage());
}
}
public function detailByUser($orderMainId, $userId)
@ -476,11 +477,67 @@ class OrderOnlineService implements OrderOnlineServiceInterface
Db::commit();
return true;
} catch (\Exception $e) {
} catch (Exception $e) {
$this->log->event(LogLabel::ORDER_ONLINE_PAID_LOG, ['exception' => $e->getMessage()]);
Db::rollBack();
return false;
}
}
/**
* @inheritDoc
*/
public function doPay($orderMainId, $userId)
{
// 订单待支付
$orderMain = $this->check($orderMainId, $userId, OrderState::UNPAID);
return $this->paymentService->do(
$orderMain->global_order_id,
$orderMain->money,
$orderMain->user_id,
config('wechat.notify_url.online')
);
}
/**
* @inheritDoc
* @throws Exception
*/
public function doDel($orderMainId, $userId)
{
// 订单完成
$orderMain = $this->check($orderMainId, $userId, OrderState::CAN_DEL);
if (!$orderMain->delete()) {
throw new ErrorCodeException(ErrorCode::ORDER_DELETE_FAIL);
}
return true;
}
/**
* @inheritDoc
*/
public function doApplyRefund($orderMainId, $userId)
{
// 未接单
$orderMain = $this->check($orderMainId, $userId, OrderState::PAID);
$orderMain->state = OrderState::REFUNDING;
if (!$orderMain->save()) {
throw new ErrorCodeException(ErrorCode::ORDER_APPLY_REFUND_FAIL);
}
return true;
}
/**
* @inheritDoc
*/
public function doComplete($orderMainId, $userId)
{
$orderMain = $this->check($orderMainId, $userId, OrderState::RECEIVING);
$orderMain->state = OrderState::COMPLETED;
if (!$orderMain->save()) {
throw new ErrorCodeException(ErrorCode::ORDER_COMPLETE_FAIL);
}
return true;
}
}

66
app/Service/v3/Implementations/SeparateAccountsService.php

@ -4,6 +4,7 @@ namespace App\Service\v3\Implementations;
use App\Commons\Log;
use App\Constants\v3\LogLabel;
use App\Constants\v3\OrderState;
use App\Model\v3\FinancialRecord;
use App\Model\v3\Order;
use App\Model\v3\OrderMain;
@ -16,6 +17,7 @@ use App\Model\v3\UserRelationBind;
use App\Model\v3\User;
use App\Service\v3\Interfaces\FinancialRecordServiceInterface;
use App\Service\v3\Interfaces\MiniprogramServiceInterface;
use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
use App\Service\v3\Interfaces\UserServiceInterface;
use Hyperf\DbConnection\Db;
@ -47,6 +49,12 @@ class SeparateAccountsService implements SeparateAccountsServiceInterface
*/
protected $miniprogramService;
/**
* @Inject
* @var OrderOnlineServiceInterface
*/
protected $orderOnlineService;
/**
* @inheritDoc
*/
@ -75,18 +83,11 @@ class SeparateAccountsService implements SeparateAccountsServiceInterface
/**
* @inheritDoc
*/
public function orderOnlineCompleted($global_order_id)
public function orderOnlineCompleted($orderMainId, $userId)
{
// 线上订单完成(用户点击确认收货完成/管理后台点击完成/配送员点击完成/自动收货等),进行相关分账
// 订单
$orderMain = OrderMain::query()
->where(['global_order_id' => $global_order_id])
->whereIn('state', [OrderMain::ORDER_STATE_COMPLETE,OrderMain::ORDER_STATE_EVALUATED,OrderMain::ORDER_STATE_UNREFUND])
->first();
if (empty($orderMain)) {
return false;
}
$orderMain = $this->orderOnlineService->check($orderMainId, $userId,OrderState::FINISH);
$currentTime = time();
Db::beginTransaction();
@ -94,35 +95,14 @@ class SeparateAccountsService implements SeparateAccountsServiceInterface
// =======商户订单收入流水 / Start=======
// 查询子订单
$orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time'])
$orders = Order::query()
->where(['order_main_id' => $orderMain->id])
->get()->toArray();
// 新商户流水
foreach ($orders as $key => &$order) {
// 商户
$store = Store::find($order['store_id']);
// 旧商户流水基础数据 TODO 直接移除或后续考虑移除
$storeAccountBase = [
'user_id' => $order['user_id'],
'order_id' => $order['id'],
'store_id' => $order['store_id'],
'type' => 1,
'time' => date('Y-m-d H:i:s', $currentTime),
'add_time' => $currentTime,
];
// 旧商户流水 TODO 直接移除或后续考虑移除
$storeAccount = [
'money' => $order['money'],
'note' => '线上订单',
'category' => 1,
];
StoreAccount::query()->insert(array_merge($storeAccountBase, $storeAccount));
// 新商户流水
$this->financialRecordService->storeByOLOrderComp($store->user_id, $global_order_id ,$order['money']);
$store = Store::query()->find($order['store_id']);
$this->financialRecordService->storeByOLOrderComp($store->user_id, $orderMain->global_order_id ,$order['money']);
}
// =======商户订单收入流水 / End=======
@ -138,25 +118,29 @@ class SeparateAccountsService implements SeparateAccountsServiceInterface
->first();
if ($communityBind) {
// 奖励/分账金额
$award = ServiceReward::query()->where(['type' => ServiceReward::TYPE_COMMUNITY])->first();
if (empty($award)) {
Db::rollBack();
return false;
}
$award = $award->set_reward;
// 平台新用户
if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->id)) {
$this->financialRecordService->communityAwardByPlatNewUser($communityBind->source_id, $global_order_id, $award['new_user_reward']);
$this->financialRecordService->communityAwardByPlatNewUserFirstOLOrder($communityBind->source_id, $global_order_id, $award['first_reward']);
$this->financialRecordService->communityAwardByPlatNewUser(
$communityBind->source_id,
$orderMain->global_order_id,
$award['new_user_reward']
);
$this->financialRecordService->communityAwardByPlatNewUserFirstOLOrder(
$communityBind->source_id,
$orderMain->global_order_id,
$award['first_reward']
);
}
// 账单分成
$money = bcmul($orderMain->money, bcdiv($award['flow_reward'], 100, 6), 2);
$this->financialRecordService->communitySeparateAccountsByOrderComp($communityBind->source_id, $global_order_id, $money);
$this->financialRecordService->communitySeparateAccountsByOrderComp($communityBind->source_id, $orderMain->global_order_id, $money);
}
// =======社区服务点分账 / End=======

15
app/Service/v3/Interfaces/CouponServiceInterface.php

@ -28,4 +28,19 @@ interface CouponServiceInterface
* @return mixed
*/
public function countAvailableByUser($userId);
/**
* 订单使用优惠券
* @param $orderMainId
* @param $couponRecs
* @return mixed
*/
public function orderUseCoupons($orderMainId, $couponRecs);
/**
* 订单退还优惠券
* @param $orderMainId
* @return mixed
*/
public function orderRefundCoupons($orderMainId);
}

2
app/Service/v3/Interfaces/GoodsActivityServiceInterface.php

@ -9,5 +9,7 @@ interface GoodsActivityServiceInterface
public function undo();
public function getBanner($goodsId);
public function detail($goodsId);
public function cacheRecord($goodsId, $num, $userId);
public function clearCacheRecord($goodsId, $num, $userId);
public function checkOrderActivityCount($orderGoods, $limitNum=1);
}

50
app/Service/v3/Interfaces/OrderOnlineServiceInterface.php

@ -2,20 +2,64 @@
namespace App\Service\v3\Interfaces;
use Hyperf\Database\Model\Model;
interface OrderOnlineServiceInterface
{
public function do($marketId, $userId, $userAddrId, $storeList, $totalMoney, $deliveryTimeNote='尽快送达', $serviceMoney, $receiveCouponIds=null, $plat='');
public function check();
/**
* 订单是否存在,有效
* @param $orderMainId
* @param $userId
* @param $state
* @return mixed
*/
public function check($orderMainId, $userId, $state): Model;
public function undo();
/**
* 取消订单
* @param $orderMainId
* @param $userId
* @return mixed
*/
public function undo($orderMainId, $userId);
public function detailByUser($orderMainId, $userId);
/**
* 线上订单支付完成(支付成功)
* 线上订单支付完成(支付成功)后续处理
* @param $orderMainId
* @return mixed
*/
public function doByPaid($orderMainId);
/**
* 线上订单支付
* @param $orderMainId
* @param $userId
*/
public function doPay($orderMainId, $userId);
/**
* 删除订单
* @param $orderMainId
* @param $userId
*/
public function doDel($orderMainId, $userId);
/**
* 申请退款
* @param $orderMainId
* @param $userId
*/
public function doApplyRefund($orderMainId, $userId);
/**
* 确认收货等完成订单
* @param $orderMainId
* @param $userId
* @return mixed
*/
public function doComplete($orderMainId, $userId);
}

5
app/Service/v3/Interfaces/SeparateAccountsServiceInterface.php

@ -14,10 +14,11 @@ interface SeparateAccountsServiceInterface
/**
* (线上)订单确认完成分账
* 用户确认或服务商(服务站确认)
* @param $global_order_id
* @param $orderMainId
* @param $userId
* @return mixed
*/
public function orderOnlineCompleted($global_order_id);
public function orderOnlineCompleted($orderMainId, $userId);
/**
* (线下)订单支付完成分账

4
config/autoload/wechat.php

@ -11,4 +11,8 @@ return [
'app_id' => env('APP_ID',''),
'secret' => env('APP_SECRET',''),
],
'notify_url' => [
'online' => env('SITE_HOST') . '/v3/wechat/notify/online',
'offline' => env('SITE_HOST') . '/v3/wechat/notify/offline',
]
];

6
config/routes.php

@ -120,7 +120,6 @@ Router::addGroup('/v3/', function () {
Router::post('orderOnline/add', 'App\Controller\v3\OrderOnlineController@add');
Router::post('orderOffline/add', 'App\Controller\v3\OrderOfflineController@add');
Router::post('store/storeWithdrawalList', 'App\Controller\v3\BalanceStatementController@getWithdrawalListByStore');
Router::post('payment/wechatpayOnline', 'App\Controller\v3\PaymentController@wechatpayOnline');
Router::post('store/getBusinessHours', 'App\Controller\v3\StoreController@getBusinessHours');
Router::post('store/updateBusinessHours', 'App\Controller\v3\StoreController@updateBusinessHours');
Router::post('userAddress/update', 'App\Controller\v3\UserAddressController@update');
@ -130,6 +129,11 @@ Router::addGroup('/v3/', function () {
Router::post('userAddress/delete', 'App\Controller\v3\UserAddressController@delete');
Router::post('coupon/getListByUser', 'App\Controller\v3\CouponController@getListByUser');
Router::post('shopCart/info', 'App\Controller\v3\ShopCartController@info');
Router::post('orderOnline/pay', 'App\Controller\v3\OrderOnlineController@pay');
Router::post('orderOnline/cancel', 'App\Controller\v3\OrderOnlineController@cancel');
Router::post('orderOnline/del', 'App\Controller\v3\OrderOnlineController@del');
Router::post('orderOnline/applyRefund', 'App\Controller\v3\OrderOnlineController@applyRefund');
Router::post('orderOnline/complete', 'App\Controller\v3\OrderOnlineController@complete');
},['middleware' => [\App\Middleware\Auth\ApiMiddleware::class, \App\Middleware\Auth\UserMiddleware::class]]);
// 微信支付回调

Loading…
Cancel
Save