24 changed files with 1982 additions and 6 deletions
-
10app/Controller/NotifyController.php
-
23app/Controller/OrderController.php
-
10app/Controller/PaymentController.php
-
1098app/Libs/MQTTClient.php
-
2app/Middleware/Auth/ApiMiddleware.php
-
3app/Model/Coupon.php
-
10app/Model/CouponUserRec.php
-
10app/Model/CouponUserUse.php
-
12app/Model/Goods.php
-
11app/Model/Order.php
-
8app/Model/OrderGoods.php
-
81app/Model/OrderMain.php
-
17app/Model/SpecCombination.php
-
72app/Request/OrderOnlineRequest.php
-
20app/Service/CoupnoServiceInterface.php
-
85app/Service/CouponService.php
-
423app/Service/OrderService.php
-
29app/Service/OrderServiceInterface.php
-
27app/TaskWorker/MQTTClientTask.php
-
5composer.json
-
4config/autoload/dependencies.php
-
3config/autoload/server.php
-
24config/autoload/snowflake.php
-
1config/routes.php
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Controller; |
||||
|
|
||||
|
|
||||
|
class NotifyController extends BaseController |
||||
|
{ |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Controller; |
||||
|
|
||||
|
use App\Request\OrderOnlineRequest; |
||||
|
use Hyperf\Di\Annotation\Inject; |
||||
|
use App\Service\OrderServiceInterface; |
||||
|
|
||||
|
class OrderController extends BaseController |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var OrderServiceInterface |
||||
|
*/ |
||||
|
protected $orderService; |
||||
|
|
||||
|
public function addOnlineOrder(OrderOnlineRequest $request) |
||||
|
{ |
||||
|
$orderMainId = $this->orderService->addOnlineOrder($request->validated()); |
||||
|
return $this->success(['order_main_id' => $orderMainId]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Controller; |
||||
|
|
||||
|
|
||||
|
class PaymentController extends BaseController |
||||
|
{ |
||||
|
|
||||
|
} |
||||
1098
app/Libs/MQTTClient.php
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Model; |
||||
|
|
||||
|
|
||||
|
class CouponUserRec extends Model |
||||
|
{ |
||||
|
protected $table = 'ims_system_coupon_user_receive'; |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Model; |
||||
|
|
||||
|
|
||||
|
class CouponUserUse extends Model |
||||
|
{ |
||||
|
protected $table = 'ims_system_coupon_user_use'; |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Model; |
||||
|
|
||||
|
|
||||
|
class Goods extends Model |
||||
|
{ |
||||
|
const INVENTORY_NOLIMIT = 1; |
||||
|
|
||||
|
protected $table = 'ims_cjdc_goods'; |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Model; |
||||
|
|
||||
|
|
||||
|
class Order extends Model |
||||
|
{ |
||||
|
protected $table = 'ims_cjdc_order'; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Model; |
||||
|
|
||||
|
class OrderGoods extends Model |
||||
|
{ |
||||
|
protected $table = 'ims_cjdc_order_goods'; |
||||
|
} |
||||
@ -0,0 +1,81 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Model; |
||||
|
|
||||
|
|
||||
|
class OrderMain extends Model |
||||
|
{ |
||||
|
// 线上订单,外卖
|
||||
|
const ORDER_TYPE_ONLINE = 1; |
||||
|
// 线下订单,当面付
|
||||
|
const ORDER_TYPE_OFFLINE = 4; |
||||
|
|
||||
|
// 订单状态
|
||||
|
// 待付款
|
||||
|
const ORDER_STATE_UNPAY = 1; |
||||
|
// 待接单
|
||||
|
const ORDER_STATE_UNTAKE = 2; |
||||
|
// 待送达
|
||||
|
const ORDER_STATE_DELIVERY = 3; |
||||
|
// 已完成
|
||||
|
const ORDER_STATE_COMPLETE = 4; |
||||
|
// 已评价
|
||||
|
const ORDER_STATE_EVALUATED = 5; |
||||
|
// 已取消
|
||||
|
const ORDER_STATE_CANCEL = 6; |
||||
|
// 已拒单
|
||||
|
const ORDER_STATE_REFUSE = 7; |
||||
|
// 退款中
|
||||
|
const ORDER_STATE_REFUNDING = 8; |
||||
|
// 已退款
|
||||
|
const ORDER_STATE_REFUNDED = 9; |
||||
|
// 拒绝退款
|
||||
|
const ORDER_STATE_UNREFUND = 10; |
||||
|
|
||||
|
// 订单支付方式
|
||||
|
// 微信支付
|
||||
|
const ORDER_PAY_WX = 1; |
||||
|
// 余额支付
|
||||
|
const ORDER_PAY_BALANCE = 2; |
||||
|
|
||||
|
protected $table = 'ims_cjdc_order_main'; |
||||
|
|
||||
|
protected $fillable = [ |
||||
|
'order_num', |
||||
|
'delivery_no', |
||||
|
'dada_fee', |
||||
|
'market_id', |
||||
|
'user_id', |
||||
|
'money', |
||||
|
'box_money', |
||||
|
'ps_money', |
||||
|
'mj_money', |
||||
|
'xyh_money', |
||||
|
'yhq_money', |
||||
|
'yhq_money2', |
||||
|
'zk_money', |
||||
|
'tel', |
||||
|
'name', |
||||
|
'address', |
||||
|
'area', |
||||
|
'lat', |
||||
|
'lng', |
||||
|
'note', |
||||
|
'type', |
||||
|
'form_id', |
||||
|
'form_id2', |
||||
|
'delivery_time', |
||||
|
'pay_type', |
||||
|
'order_type', |
||||
|
'code', |
||||
|
'coupon_id', |
||||
|
'coupon_id2', |
||||
|
'uniacid', |
||||
|
'state', |
||||
|
'time', |
||||
|
'time_add', |
||||
|
'global_order_id', |
||||
|
]; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Model; |
||||
|
|
||||
|
|
||||
|
class SpecCombination extends Model |
||||
|
{ |
||||
|
|
||||
|
protected $table = 'ims_cjdc_spec_combination'; |
||||
|
|
||||
|
public function goods() |
||||
|
{ |
||||
|
return $this->belongsTo(Goods::class, 'good_id', 'id'); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,72 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
namespace App\Request; |
||||
|
|
||||
|
use Hyperf\Validation\Request\FormRequest; |
||||
|
|
||||
|
class OrderOnlineRequest extends FormRequest |
||||
|
{ |
||||
|
/** |
||||
|
* Determine if the user is authorized to make this request. |
||||
|
*/ |
||||
|
public function authorize(): bool |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the validation rules that apply to the request. |
||||
|
*/ |
||||
|
public function rules(): array |
||||
|
{ |
||||
|
return [ |
||||
|
'order_num' => 'nonempty', |
||||
|
'delivery_no' => '', |
||||
|
'dada_fee' => 'nonempty', |
||||
|
'market_id' => 'required|nonempty|integer', |
||||
|
'user_id' => 'required|nonempty|integer', |
||||
|
'money' => 'required|nonempty', |
||||
|
'box_money' => '', |
||||
|
'ps_money' => '', |
||||
|
'mj_money' => '', |
||||
|
'xyh_money' => '', |
||||
|
'yhq_money' => '', |
||||
|
'yhq_money2' => '', |
||||
|
'zk_money' => '', |
||||
|
'tel' => 'required|nonempty', |
||||
|
'name' => 'required|nonempty', |
||||
|
'address' => 'required|nonempty', |
||||
|
'area' => '', |
||||
|
'lat' => 'required|nonempty', |
||||
|
'lng' => 'required|nonempty', |
||||
|
'note' => '', |
||||
|
'type' => 'required|nonempty', |
||||
|
'form_id' => '', |
||||
|
'form_id2' => '', |
||||
|
'delivery_time' => '', |
||||
|
'order_type' => 'nonempty', |
||||
|
'pay_type' => 'nonempty', |
||||
|
'coupon_id' => '', |
||||
|
'coupon_id2' => '', |
||||
|
'uniacid' => 'nonempty', |
||||
|
'store_list' => 'nonempty', |
||||
|
'receive_coupon_ids' => '', |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
public function messages(): array |
||||
|
{ |
||||
|
return [ |
||||
|
'*.*' => ':attribute 参数异常' |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
public function attributes(): array |
||||
|
{ |
||||
|
return [ |
||||
|
|
||||
|
]; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Service; |
||||
|
|
||||
|
|
||||
|
interface CoupnoServiceInterface |
||||
|
{ |
||||
|
/** |
||||
|
* 当前订单可用优惠券列表 |
||||
|
* @param $orderAmount 订单金额 |
||||
|
* @param $marketId 市场ID |
||||
|
* @param $userId 用户ID |
||||
|
* @param int $type 优惠券类型,1全平台 2线上 3线下 |
||||
|
* @param int[] $storeTypeIds 商户类型ID数组 |
||||
|
* @param array $fields |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
public function getOrderCanUseCoupons($orderAmount, $marketId, $userId, $fields=[], $type=1, $storeTypeIds=[0]); |
||||
|
} |
||||
@ -0,0 +1,85 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service; |
||||
|
|
||||
|
use Hyperf\DbConnection\Db; |
||||
|
use Hyperf\Redis\Redis; |
||||
|
use Hyperf\Utils\ApplicationContext; |
||||
|
|
||||
|
class CouponService implements CoupnoServiceInterface |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @inheritDoc |
||||
|
*/ |
||||
|
public function getOrderCanUseCoupons($orderAmount, $marketId, $userId, $fields=[], $type = 1, $storeTypeIds = [0]) |
||||
|
{ |
||||
|
|
||||
|
// 用户今日使用过的优惠券
|
||||
|
$redis = ApplicationContext::getContainer()->get(Redis::class); |
||||
|
$couponTodayUsedIds = $redis->sMembers('coupon_'.date('Ymd').'_used_'.$userId); |
||||
|
|
||||
|
$currentTime = time(); |
||||
|
|
||||
|
$builder = Db::table('ims_system_coupon_user_receive as receive') |
||||
|
->join('ims_system_coupon_user as coupon', 'coupon.id', '=', 'receive.system_coupon_user_id', 'inner'); |
||||
|
|
||||
|
if (is_array($fields)&&!empty($fields)) { |
||||
|
$builder->select([ |
||||
|
'receive.id as receive_id', |
||||
|
'receive.user_id', |
||||
|
'receive.number_remain', |
||||
|
'coupon.id', |
||||
|
'coupon.title', |
||||
|
'coupon.full_amount', |
||||
|
'coupon.discounts', |
||||
|
'coupon.usable_start_time', |
||||
|
'coupon.usable_end_time', |
||||
|
'coupon.discount_type' |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
if (is_array($couponTodayUsedIds)&&!empty($couponTodayUsedIds)) { |
||||
|
$builder->whereNotIn('coupon.id', $couponTodayUsedIds); |
||||
|
} |
||||
|
|
||||
|
return $builder->where(['receive.user_id' => $userId]) |
||||
|
->whereIn('receive.status', [0,1]) |
||||
|
->where('receive.number_remain', '>', 0) |
||||
|
->whereIn('coupon.type', [1,$type]) |
||||
|
->where('coupon.full_amount', '<=', $orderAmount) |
||||
|
->where('coupon.usable_start_time', '<=', $currentTime) |
||||
|
->where('coupon.usable_end_time', '>=', $currentTime) |
||||
|
->where('coupon.usable_number', '<=', Db::raw('receive.number_remain')) |
||||
|
->where('coupon.market_id', 'in', [0, $marketId]) |
||||
|
->whereIn('coupon.storetype_id', $storeTypeIds) |
||||
|
->orderByRaw('coupon.discounts DESC, coupon.full_amount DESC') |
||||
|
->get() |
||||
|
->toArray(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 缓存优惠券今日使用情况 |
||||
|
* @param $userId |
||||
|
* @param $couponId |
||||
|
* @param $couponRecId |
||||
|
* @return bool |
||||
|
*/ |
||||
|
function cacheTodayCouponUsed($userId, $couponId, $couponRecId) |
||||
|
{ |
||||
|
|
||||
|
$redis = ApplicationContext::getContainer()->get(Redis::class); |
||||
|
|
||||
|
$setRes = $redis->sAdd( |
||||
|
'coupon_'.date('Ymd').'_used_'.$userId, |
||||
|
$couponId |
||||
|
); |
||||
|
|
||||
|
$expireRes = $redis->expire( |
||||
|
'coupon_'.date('Ymd').'_used_'.$userId, |
||||
|
strtotime(date('Y-m-d').' 23:59:59')-time() |
||||
|
); |
||||
|
|
||||
|
return $setRes&&$expireRes; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,423 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service; |
||||
|
|
||||
|
use App\Model\Coupon; |
||||
|
use App\Model\CouponUserRec; |
||||
|
use App\Model\CouponUserUse; |
||||
|
use App\Model\Goods; |
||||
|
use App\Model\Order; |
||||
|
use App\Model\OrderGoods; |
||||
|
use App\Model\OrderMain; |
||||
|
use App\Model\SpecCombination; |
||||
|
use App\Model\Users; |
||||
|
use Exception; |
||||
|
use Hyperf\DbConnection\Db; |
||||
|
use Hyperf\Snowflake\IdGeneratorInterface; |
||||
|
use Hyperf\Utils\ApplicationContext; |
||||
|
use Hyperf\Di\Annotation\Inject; |
||||
|
|
||||
|
class OrderService implements OrderServiceInterface |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var CoupnoServiceInterface |
||||
|
*/ |
||||
|
protected $couponService; |
||||
|
|
||||
|
/** |
||||
|
* @inheritDoc |
||||
|
*/ |
||||
|
public function addOnlineOrder($data) |
||||
|
{ |
||||
|
|
||||
|
bcscale(6); |
||||
|
|
||||
|
// 订单判重
|
||||
|
$dataMain = $data; |
||||
|
if ($orderMainId = $this->existsByOrderNum($data['order_num'])) { |
||||
|
return $orderMainId; |
||||
|
} |
||||
|
|
||||
|
Db::beginTransaction(); |
||||
|
try { |
||||
|
|
||||
|
// 计算当前订单可用红包优惠金额
|
||||
|
$couponMoney = 0; |
||||
|
if (isset($data['receive_coupon_ids'])&&$data['receive_coupon_ids']) { |
||||
|
$receiveCouponIds = explode(',', str_replace(',',',',$data['receive_coupon_ids'])); |
||||
|
$couponMoney = $this->getCouponAmount($receiveCouponIds, $data['money'], $data['user_id'], $data['market_id']); |
||||
|
} |
||||
|
$dataMain['yhq_money2'] = $couponMoney; |
||||
|
|
||||
|
// 获取分布式全局ID
|
||||
|
$generator = ApplicationContext::getContainer()->get(IdGeneratorInterface::class); |
||||
|
$dataMain['global_order_id'] = $generator->generate(); |
||||
|
|
||||
|
// 店铺IDs
|
||||
|
$dataMain['store_ids'] = ''; |
||||
|
$storeList = json_decode(json_encode($data['store_list']), true); |
||||
|
if (!is_array($storeList)||empty($storeList)) { |
||||
|
Db::rollBack(); |
||||
|
return '订单中商品不存在或已失效'; |
||||
|
} |
||||
|
|
||||
|
// 获取商户IDs
|
||||
|
foreach ($storeList as &$item) { |
||||
|
$dataMain['store_ids'] .= empty($dataMain['store_ids']) ? $item['store_id'] : ','.$item['store_id']; |
||||
|
} |
||||
|
|
||||
|
// 主订单插入数据
|
||||
|
$currentTime = time(); |
||||
|
$dataMain['time'] = date('Y-m-d H:i:s', $currentTime); |
||||
|
$dataMain['time_add'] = $currentTime; |
||||
|
$dataMain['state'] = OrderMain::ORDER_STATE_UNPAY; |
||||
|
$dataMain['code'] = $dataMain['global_order_id']; |
||||
|
|
||||
|
// 主订单模型保存
|
||||
|
$orderMain = OrderMain::create($dataMain); |
||||
|
$orderMainId = $orderMain->id; |
||||
|
|
||||
|
// 统计订单中所有店铺当日订单数,做店铺订单序号
|
||||
|
$countsArr = Order::query()->select('COUNT(*) AS count, id') |
||||
|
->whereIn('store_id', explode(',', $dataMain['store_ids'])) |
||||
|
->where(['type' => OrderMain::ORDER_TYPE_ONLINE]) |
||||
|
->whereBetween('time', [date('Y-m-d 00:00:00'), date('Y-m-d 23:59:59')]) |
||||
|
->get() |
||||
|
->toArray(); |
||||
|
|
||||
|
$storeOrderCounts = []; |
||||
|
foreach ($countsArr as $key => &$row) { |
||||
|
$storeOrderCounts[$row['id']] = $row['count']; |
||||
|
} |
||||
|
|
||||
|
// 循环处理订单总额、子订单总额、商品、商户订单等信息
|
||||
|
$orderAmountTotal = 0; # 总订单金额
|
||||
|
foreach ($storeList as $key => &$item) { |
||||
|
|
||||
|
// 子订单数据处理
|
||||
|
$dataChild = [ |
||||
|
'uniacid' => $data['uniacid'], |
||||
|
'order_num' => 's'.date('YmdHis', time()) . rand(1111, 9999), |
||||
|
'user_id' => $orderMain->user_id, |
||||
|
'store_id' => $item['store_id'], |
||||
|
'order_main_id' => $orderMain, |
||||
|
'state' => OrderMain::ORDER_STATE_UNPAY, |
||||
|
'tel' => $orderMain->tel, |
||||
|
'name' => $orderMain->name, |
||||
|
'address' => $orderMain->address, |
||||
|
'area' => $orderMain->area, |
||||
|
'time' => date("Y-m-d H:i:s"), |
||||
|
'note' => $item['note'], |
||||
|
'delivery_time' => $orderMain->delivery_time, |
||||
|
'type' => $orderMain->type, |
||||
|
'lat' => $orderMain->lat, |
||||
|
'lng' => $orderMain->lng, |
||||
|
'pay_type' => $orderMain->pay_type, |
||||
|
'order_type' => $orderMain->order_type, |
||||
|
'money' => floatval($item['subtotal']), |
||||
|
'box_money' => floatval($item['box_money']), |
||||
|
'mj_money' => floatval($item['mj_money']), |
||||
|
'yhq_money' => floatval($item['yhq_money']), |
||||
|
'yhq_money2' => floatval($item['yhq_money2']), |
||||
|
'zk_money' => floatval($item['zk_money']), |
||||
|
'coupon_id' => $item['coupon_id'], |
||||
|
'coupon_id2' => $item['coupon_id2'], |
||||
|
'xyh_money' => floatval($item['xyh_money']), |
||||
|
'oid' => (isset($storeOrderCounts[$item['store_id']]) ? $item['store_id'] : 0) + 1, |
||||
|
'time_add' => date("Y-m-d H:i:s"), |
||||
|
]; |
||||
|
|
||||
|
$order = Order::create($dataChild); |
||||
|
$orderChildId = $order->id; |
||||
|
|
||||
|
// 子订单内商品处理
|
||||
|
$goodsAmountTotal = 0; |
||||
|
$orderGoods = []; |
||||
|
if (!is_array($item['good_list'])||empty($item['good_list'])) { |
||||
|
Db::rollBack(); |
||||
|
return '订单商品异常'; |
||||
|
} |
||||
|
foreach ($item['good_list'] as &$goods) { |
||||
|
|
||||
|
$goodsAmount = bcadd(floatval($goods['money']), floatval($goods['box_money'])); |
||||
|
$goodsAmount = bcmul($goodsAmount, $goods['num']); |
||||
|
$goodsAmountTotal = bcadd($goodsAmountTotal, $goodsAmount); |
||||
|
|
||||
|
$orderGoods[$goods['id']] = $goods; |
||||
|
$orderGoods[$goods['id']]['uniacid'] = $data['uniacid']; |
||||
|
$orderGoods[$goods['id']]['order_id'] = $orderChildId; |
||||
|
$orderGoods[$goods['id']]['user_id'] = $dataMain['user_id']; |
||||
|
$orderGoods[$goods['id']]['store_id'] = $item['store_id']; |
||||
|
} |
||||
|
|
||||
|
// 子订单优惠总额
|
||||
|
$discountAmountTotal = bcadd($dataChild['mj_money'], $dataChild['yhq_money']); |
||||
|
$discountAmountTotal = bcadd($discountAmountTotal, $dataChild['yhq_money2']); |
||||
|
$discountAmountTotal = bcadd($discountAmountTotal, $dataChild['zk_money']); |
||||
|
$discountAmountTotal = bcadd($discountAmountTotal, $dataChild['xyh_money']); |
||||
|
|
||||
|
$goodsAmountTotal = bcsub($goodsAmountTotal, $discountAmountTotal, 2); |
||||
|
$orderAmountTotal = bcadd($orderAmountTotal, $goodsAmountTotal, 2); |
||||
|
|
||||
|
// 校验子订单金额
|
||||
|
if ($goodsAmountTotal != $dataChild['money']) { |
||||
|
Db::rollBack(); |
||||
|
return '店铺订单总金额错误'; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 校验库存
|
||||
|
foreach ($orderGoods as $Key=>&$goodsItem) { |
||||
|
|
||||
|
$goodsItem['combination_id'] = intval($goodsItem['combination_id']); |
||||
|
|
||||
|
// 存在规格,则去规格处查库存,整个接口还有很多别的问题,目前
|
||||
|
$goods = (object)[]; |
||||
|
if ($goodsItem['combination_id'] > 0) { |
||||
|
|
||||
|
$goods = SpecCombination::query() |
||||
|
->select('id, number AS inventory') |
||||
|
->where(['id' => $goodsItem['combination_id']]) |
||||
|
->first(); |
||||
|
$goods->name = $goods->goods->name; |
||||
|
$goods->is_max = $goods->goods->is_max; |
||||
|
|
||||
|
} else { |
||||
|
|
||||
|
$goods = Goods::query() |
||||
|
->select('id, name, is_max, inventory') |
||||
|
->where(['id' => $goodsItem['good_id']]) |
||||
|
->first(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
if (!$goods) { |
||||
|
Db::rollBack(); |
||||
|
return '缺少商品'; |
||||
|
} |
||||
|
|
||||
|
if($goodsItem['num'] > $goods->inventory && $goods->is_max != Goods::INVENTORY_NOLIMIT){ |
||||
|
Db::rollBack(); |
||||
|
return '商品 '.$goods->name.' 库存不足!'; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 校验总订单金额
|
||||
|
$deliveryAmount = 0; # 配送费用
|
||||
|
if($dataMain['order_type'] == OrderMain::ORDER_TYPE_ONLINE){ |
||||
|
$deliveryAmount = $dataMain['dada_fee']; |
||||
|
} |
||||
|
|
||||
|
$orderAmountTotal = bcadd($orderAmountTotal, $deliveryAmount); |
||||
|
# 总订单优惠总额
|
||||
|
$discountAmountTotal = bcadd($dataMain['mj_money'], $dataMain['yhq_money']); |
||||
|
$discountAmountTotal = bcadd($discountAmountTotal, $dataMain['yhq_money2']); |
||||
|
$discountAmountTotal = bcadd($discountAmountTotal, $dataMain['zk_money']); |
||||
|
$discountAmountTotal = bcadd($discountAmountTotal, $dataMain['xyh_money']); |
||||
|
$orderAmountTotal = bcsub($orderAmountTotal, $discountAmountTotal, 2); |
||||
|
|
||||
|
if ($orderAmountTotal != bcsub(bcadd($dataMain['money'], $deliveryAmount), $discountAmountTotal, 2)) { |
||||
|
Db::rollBack(); |
||||
|
return '订单总金额错误'; |
||||
|
} |
||||
|
|
||||
|
// 添加订单商品
|
||||
|
$tempGoods = $orderGoods; |
||||
|
$orderGoods = []; |
||||
|
foreach ($tempGoods as $key => &$value) { |
||||
|
$goods['good_id'] = $value['good_id']; |
||||
|
$goods['img'] = $value['logo']; |
||||
|
$goods['number'] = $value['num']; |
||||
|
$goods['order_id'] = $value['order_id']; |
||||
|
$goods['name'] = $value['name']; |
||||
|
$goods['money'] = $value['money']; |
||||
|
$goods['dishes_id'] = $value['dishes_id']; |
||||
|
$goods['spec'] = $value['spec']; |
||||
|
$goods['is_qg'] = $value['is_qg']; |
||||
|
$goods['good_unit'] = $value['good_unit']; |
||||
|
$goods['uniacid'] = $value['uniacid']; |
||||
|
$goods['combination_id'] = $value['combination_id']; |
||||
|
$orderGoods[] = $goods; |
||||
|
} |
||||
|
|
||||
|
$addOrderGoods = OrderGoods::query()->insert($orderGoods); |
||||
|
if (!$addOrderGoods) { |
||||
|
Db::rollBack(); |
||||
|
return '订单商品异常'; |
||||
|
} |
||||
|
|
||||
|
// 修改总订单金额,金额是计算来的
|
||||
|
// TODO 这部分其实可以结合处理优化一下,循环前后关联处理太多
|
||||
|
$updateOrderMain = OrderMain::query()->where(['id' => $orderMainId])->update(['money' => $orderAmountTotal, 'total_money' => $dataMain['money']]); |
||||
|
if (!$updateOrderMain) { |
||||
|
Db::rollBack(); |
||||
|
return '订单总金额记录失败'; |
||||
|
} |
||||
|
|
||||
|
// 处理红包的使用
|
||||
|
$canUseConpons = $this->couponService->getOrderCanUseCoupons( |
||||
|
$data['money'], |
||||
|
$data['market_id'], |
||||
|
$data['user_id'], |
||||
|
[ |
||||
|
'receive.id', |
||||
|
'receive.user_id', |
||||
|
'receive.number', |
||||
|
'receive.number_remain', |
||||
|
'receive.system_coupon_user_id', |
||||
|
'coupon.discounts', |
||||
|
'coupon.discount_type', |
||||
|
] |
||||
|
); |
||||
|
|
||||
|
if (is_array($canUseConpons)&&!empty($canUseConpons)) { |
||||
|
# 使用记录、更新当前优惠券
|
||||
|
foreach ($canUseConpons as $key => &$coupon) { |
||||
|
$couponUse = [ |
||||
|
'user_id' => $coupon['user_id'], |
||||
|
'user_receive_id' => $coupon['id'], |
||||
|
'system_coupon_id' => $coupon['system_coupon_user_id'], |
||||
|
'order_main_id' => $orderMainId, |
||||
|
'use_time' => $currentTime, |
||||
|
'return_time' => 0, |
||||
|
'number' => 1, |
||||
|
'status' => 1, |
||||
|
'update_time' => 0, |
||||
|
]; |
||||
|
|
||||
|
$insertRes = CouponUserUse::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 = CouponUserRec::query()->where(['id' => $coupon['id']])->update(['number_remain' => $numberRemain, 'status' => $status]); |
||||
|
|
||||
|
if (!$upRes) { |
||||
|
Db::rollBack(); |
||||
|
return '优惠券使用失败'; |
||||
|
} |
||||
|
|
||||
|
// 缓存使用记录
|
||||
|
$usedRes = $this->couponService->cacheTodayCouponUsed($coupon['user_id'], $coupon['system_coupon_user_id'], $coupon['id']); |
||||
|
if (!$usedRes) { |
||||
|
Db::rollBack(); |
||||
|
return '优惠券使用失败'; |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
Db::rollBack(); |
||||
|
return '优惠券使用失败'; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Db::commit(); |
||||
|
|
||||
|
|
||||
|
} catch (Exception $e) { |
||||
|
|
||||
|
Db::rollBack(); |
||||
|
return $e->getMessage(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 订单成功后处理
|
||||
|
if ($orderMainId) { |
||||
|
|
||||
|
// 处理喇叭播报
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
return $orderMainId; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @inheritDoc |
||||
|
*/ |
||||
|
public function addOfflineOrder() |
||||
|
{ |
||||
|
// TODO: Implement addOfflineOrder() method.
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 计算和校验当前订单可用红包及金额 |
||||
|
* @param $couponIds |
||||
|
* @param $orderAmount |
||||
|
* @param $userId |
||||
|
* @param $marketId |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
protected function getCouponAmount($couponIds, $orderAmount, $userId, $marketId) |
||||
|
{ |
||||
|
|
||||
|
// 用户当前订单可用优惠券
|
||||
|
$couponsCanUse = $this->couponService->getOrderCanUseCoupons( |
||||
|
$orderAmount, |
||||
|
$marketId, |
||||
|
$userId, |
||||
|
[ |
||||
|
'receive.id', |
||||
|
'receive.user_id', |
||||
|
'receive.number', |
||||
|
'receive.number_remain', |
||||
|
'receive.system_coupon_user_id', |
||||
|
'coupon.discounts', |
||||
|
'coupon.discount_type', |
||||
|
] |
||||
|
); |
||||
|
|
||||
|
$couponCanUseIds = array_column($couponsCanUse, 'id'); |
||||
|
$couponCanUseIds = array_intersect($couponCanUseIds, $couponIds); |
||||
|
$couponCannotUseIds = array_diff($couponIds, $couponCanUseIds); |
||||
|
|
||||
|
if (empty($couponCanUseIds)||!empty($couponCannotUseIds)) { |
||||
|
throw new Exception('您的订单中有优惠券已经失效'); |
||||
|
} |
||||
|
|
||||
|
// 计算红包折扣金额
|
||||
|
$couponMoney = 0; |
||||
|
foreach ($couponsCanUse as $key => $coupon) { |
||||
|
|
||||
|
if (!in_array($coupon->id, $couponIds)) { |
||||
|
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); |
||||
|
$discountRate = bcsub(1,$discountRate); |
||||
|
$discountMoney = bcmul($orderAmount, $discountRate); |
||||
|
$couponMoney = bcadd($couponMoney, $discountMoney, 2); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return $couponMoney; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 订单是否存在 |
||||
|
* @param $orderNum |
||||
|
* @return \Hyperf\Utils\HigherOrderTapProxy|mixed|void|null |
||||
|
*/ |
||||
|
public function existsByOrderNum($orderNum) |
||||
|
{ |
||||
|
return OrderMain::query()->where(['order_num' => $orderNum])->value('id'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service; |
||||
|
|
||||
|
interface OrderServiceInterface |
||||
|
{ |
||||
|
/** |
||||
|
* 线上订单下单 |
||||
|
* 外卖 |
||||
|
* @param $data |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
public function addOnlineOrder($data); |
||||
|
|
||||
|
/** |
||||
|
* 线下订单下单 |
||||
|
* 扫码支付 |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
public function addOfflineOrder(); |
||||
|
|
||||
|
/** |
||||
|
* 订单是否已经存在 |
||||
|
* @param $orderNum |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
public function existsByOrderNum($orderNum); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
<?php |
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
namespace App\TaskWorker; |
||||
|
|
||||
|
use App\Libs\MQTTClient; |
||||
|
use Hyperf\Task\Annotation\Task; |
||||
|
|
||||
|
class MQTTClientTask |
||||
|
{ |
||||
|
protected $mqttClient = null; |
||||
|
|
||||
|
/** |
||||
|
* @Task |
||||
|
*/ |
||||
|
public function getClient() |
||||
|
{ |
||||
|
$this->mqttClient = new MQTTClient(env('MQTT_HOST'), env('MQTT_PORT')); |
||||
|
$this->mqttClient->setAuthentication(env('MQTT_NAME'), env('MQTT_PASS')); |
||||
|
|
||||
|
if (env('MQTT_CERT')) { |
||||
|
$this->mqttClient->setEncryption(env('MQTT_CERT')); |
||||
|
} |
||||
|
|
||||
|
return $this->mqttClient; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
/** |
||||
|
* This file is part of Hyperf. |
||||
|
* |
||||
|
* @link https://www.hyperf.io |
||||
|
* @document https://hyperf.wiki |
||||
|
* @contact group@hyperf.io |
||||
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE |
||||
|
*/ |
||||
|
use Hyperf\Snowflake\MetaGenerator\RedisMilliSecondMetaGenerator; |
||||
|
use Hyperf\Snowflake\MetaGenerator\RedisSecondMetaGenerator; |
||||
|
use Hyperf\Snowflake\MetaGeneratorInterface; |
||||
|
|
||||
|
return [ |
||||
|
'begin_second' => MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, |
||||
|
RedisMilliSecondMetaGenerator::class => [ |
||||
|
'pool' => 'default', |
||||
|
], |
||||
|
RedisSecondMetaGenerator::class => [ |
||||
|
'pool' => 'default', |
||||
|
], |
||||
|
]; |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue