multi-store/app/api/controller/DemoOrderController.php

402 lines
19 KiB
PHP
Raw Normal View History

<?php
namespace app\api\controller;
use app\api\logic\order\CartLogic;
use app\api\logic\order\OrderLogic;
use app\common\enum\PayEnum;
use app\common\enum\YesNoEnum;
use app\common\logic\DemoPayNotifyLogic;
use app\common\logic\PaymentLogic;
use app\common\logic\PayNotifyLogic;
use app\common\model\Config;
use app\common\model\order\Cart;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_category\StoreCategory;
use app\common\model\store_order\StoreOrder;
use app\common\model\store_order_cart_info\StoreOrderCartInfo;
use app\common\model\store_product\StoreProduct;
use app\common\model\store_product_unit\StoreProductUnit;
use app\common\model\system_store\SystemStore;
use app\common\model\user\User;
use app\common\model\user\UserAddress;
use Picqer\Barcode\BarcodeGeneratorPNG;
use support\exception\BusinessException;
use think\facade\Db;
class DemoOrderController extends BaseApiController
{
public $notNeedLogin = ['aa'];
public static $total_price;
public static $pay_price;
public static $cost;
public static $profit;
public static $store_price; //门店零售价
public static $activity_price;
public static $deduction_price;
public static $frozen_money; //返还金额
public static $fresh_price; //生鲜金额
public function aa()
{
$data = Db::name('demo_order')->where('store_id', 22)->group('times')->select();
foreach ($data as $key => $value) {
$res = Db::name('demo_order')->where('times', $value['times'])->select();
foreach ($res as $k => $v) {
$product_id = StoreBranchProduct::where('id', $v['product_id'])->value('product_id');
if (!$product_id) {
return $this->fail('商品不存在');
}
$datas = [
'uid' => $v['uid'],
'type' => 1,
'product_id' => $product_id,
'store_id' => $v['store_id'],
'cart_num' => $v['nums'],
];
CartLogic::add($datas);
}
$this->create($value['uid'],$value['store_id'],$value['times'],$value['pay_type']);
}
}
/**
* 创建订单
*/
public function create($uid,$store_id,$times,$pay_type)
{
$user = User::where('id', $uid)->find();
$cartId = Cart::where([
'uid' => $uid,
'is_pay' => 0
])->column('id');
$params['shipping_type'] = 2;
$params['store_id'] = $store_id;
$params['create_time'] = $times;
$params['pay_type'] = $pay_type;
$order = self::createOrder($cartId, 0, $user, $params);
if ($order != false) {
if ($order['pay_price'] <= 0) {
$pay_type = 3;
}
switch ($pay_type) {
case PayEnum::PURCHASE_FUNDS:
//采购款支付
DemoPayNotifyLogic::handle('purchase_funds', $order['order_id']);
OrderLogic::writeOff(['verify_code'=>$order['verify_code'],'store_id'=>$order['store_id']]);
return $this->success('采购款支付成功');
case PayEnum::BALANCE_PAY:
//余额支付
DemoPayNotifyLogic::handle('balancePay', $order['order_id']);
OrderLogic::writeOff(['verify_code'=>$order['verify_code'],'store_id'=>$order['store_id']]);
return $this->success('余额支付成功');
case PayEnum::CASH_PAY:
//现金支付
DemoPayNotifyLogic::handle('cash_pay', $order['order_id']);
return $this->success('现金支付成功');
case PayEnum::WECHAT_PAY_MINI:
//微信小程序支付
$extra['amount']['payer_total'] = bcmul($order['pay_price'], 100, 2);
$extra['transaction_id'] = time();
DemoPayNotifyLogic::handle('wechat_common', $order['order_id'], $extra);
OrderLogic::writeOff(['verify_code'=>$order['verify_code'],'store_id'=>$order['store_id']]);
return $this->success('微信小程序支付成功');
case PayEnum::WECHAT_PAY_BARCODE:
//微信条码支付
$extra['amount']['payer_total'] = bcmul($order['pay_price'], 100, 2);
$extra['transaction_id'] = time();
DemoPayNotifyLogic::handle('wechat_common', $order['order_id'], $extra);
return $this->success('微信条码支付成功');
case PayEnum::ALIPAY_BARCODE:
//支付宝条码支付
$extra['buyer_pay_amount'] = $order['pay_price'];
DemoPayNotifyLogic::handle('alipay_cashier', $order['order_id'], $extra);
return $this->success('支付宝条码支付成功');
default:
return $this->fail('支付方式错误');
}
// return $this->data(['order_id' => $order->id]);
} else {
return $this->fail(OrderLogic::getError());
}
}
/**
* @notes 获取购物车商品信息
* @param $params
* @return array|bool
*/
static public function cartIdByOrderInfo($cartId, $addressId, $user = null, $params = [], $createOrder = 0)
{
$where = ['is_pay' => 0];
$cart_select = Cart::whereIn('id', $cartId)->where($where)->field('id,product_id,cart_num')->select()->toArray();
if (empty($cart_select)) {
throw new BusinessException('购物车为空', 3000);
}
// try {
self::$total_price = 0;
self::$pay_price = 0;
self::$cost = 0; //成本由采购价替代原成本为门店零售价
self::$profit = 0; //利润
self::$activity_price = 0; //活动减少
self::$store_price = 0; //商户价
self::$deduction_price = 0;
self::$frozen_money = 0; //返还金额
$deduction_price = 0; //抵扣金额
self::$fresh_price = 0; //生鲜金额
/** 计算价格 */
$off_activity = Config::where('name', 'off_activity')->value('value');
$field = 'id branch_product_id,store_name,image,unit,price,vip_price,cost,purchase,product_id,top_cate_id';
foreach ($cart_select as $k => $v) {
$find = StoreBranchProduct::where(['product_id' => $v['product_id'], 'store_id' => $params['store_id']])->field($field)->find();
if (!$find) {
// unset($cart_select[$k]);
// continue;
$field = 'id branch_product_id,store_name,image,unit,price,vip_price,cost,purchase, id product_id,cate_id';
$find = StoreProduct::where(['id' => $v['product_id']])->field($field)->find();
if ($find) {
$cate_id = StoreCategory::where('id', $find['cate_id'])->value('pid');
if ($cate_id > 0) {
$cate_id = StoreCategory::where('id', $cate_id)->value('pid');
if ($cate_id > 0) {
$cate_id = StoreCategory::where('id', $cate_id)->value('pid');
$find['top_cate_id'] = $cate_id;
} else {
$find['top_cate_id'] = $cate_id;
}
}
}
$cart_select[$k]['status'] = 1; //缺货标识
}
unset($cart_select[$k]['id']);
$cart_select[$k]['total_price'] = bcmul($v['cart_num'], $find['price'], 2); //订单总价
if ($off_activity == 1 || ($user != null && in_array($user['user_ship'], [4, 5, 6, 7]))) {
$price = $find['cost'];
} else {
$price = $find['price'];
}
$cart_select[$k]['price'] = $price;
$cart_select[$k]['cost'] = $find['cost'];
$cart_select[$k]['vip'] = 0;
$cart_select[$k]['unit_name'] = StoreProductUnit::where(['id' => $find['unit']])->value('name') ?? ''; //单位名称
//利润
// $cart_select[$k]['profit'] = bcmul($v['cart_num'], $onePrice, 2); //利润
$cart_select[$k]['purchase'] = bcmul($v['cart_num'], $find['purchase'], 2) ?? 0; //成本
$cart_select[$k]['pay_price'] = bcmul($v['cart_num'], $price, 2); //订单支付金额
$cart_select[$k]['store_price'] = bcmul($v['cart_num'], $find['cost'], 2) ?? 0; //商户价
$cart_select[$k]['vip_price'] = bcmul($v['cart_num'], $find['vip_price'], 2) ?? 0; //vip售价
if ($cart_select[$k]['total_price'] > $cart_select[$k]['pay_price']) {
$deduction_price = bcsub($cart_select[$k]['total_price'], $cart_select[$k]['pay_price'], 2);
$cart_select[$k]['deduction_price'] = $deduction_price; //抵扣金额
}
$cart_select[$k]['product_id'] = $find['product_id'];
$cart_select[$k]['old_cart_id'] = $v['id'];
$cart_select[$k]['cart_num'] = $v['cart_num'];
$cart_select[$k]['verify_code'] = $params['verify_code'] ?? '';
$cart_select[$k]['vip_frozen_price'] = 0;
//会员待返回金额
if ($user && $off_activity == 0) {
if ($user['user_ship'] == 4) {
//商户
$cart_select[$k]['vip_frozen_price'] = bcsub($cart_select[$k]['pay_price'], $cart_select[$k]['store_price'], 2);
} else {
//其他会员
$cart_select[$k]['vip_frozen_price'] = bcsub($cart_select[$k]['pay_price'], $cart_select[$k]['vip_price'], 2);
}
}
// d($cart_select[$k]['pay_price'],$cart_select[$k]['store_price'],$cart_select[$k]['vip_price'] );
$cartInfo = $cart_select[$k];
$cartInfo['name'] = $find['store_name'];
$cartInfo['image'] = $find['image'];
$cart_select[$k]['cart_info'] = json_encode($cartInfo);
$cart_select[$k]['branch_product_id'] = $find['branch_product_id'];
//理论上每笔都是拆分了
$cart_select[$k]['name'] = $find['store_name'];
$cart_select[$k]['imgs'] = $find['image'];
$cart_select[$k]['store_id'] = $params['store_id'] ?? 0;
$cart_select[$k]['unit_name'] = StoreProductUnit::where(['id' => $find['unit']])->value('name');
self::$total_price = bcadd(self::$total_price, $cart_select[$k]['total_price'], 2);
self::$pay_price = bcadd(self::$pay_price, $cart_select[$k]['pay_price'], 2);
self::$cost = bcadd(self::$cost, $cart_select[$k]['purchase'], 2);
self::$store_price = bcadd(self::$store_price, $cart_select[$k]['store_price'], 2); //商户价
self::$deduction_price = bcadd(self::$deduction_price, $deduction_price, 2); //抵扣金额
self::$frozen_money = bcadd(self::$frozen_money, $cart_select[$k]['vip_frozen_price'], 2); //返还金额
//计算生鲜
if ($createOrder == 1 && $find['top_cate_id'] == 15201) {
self::$fresh_price = bcadd(self::$fresh_price, $cart_select[$k]['pay_price'], 2);
}
// self::$profit = bcadd(self::$profit, $cart_select[$k]['profit'], 2);
}
//加支付方式限制
// $pay_type = isset($params['pay_type']) ? $params['pay_type'] : 0;
// if ($user && $user['user_ship'] == 1 && $pay_type != 17) {
// $pay_price = self::$pay_price;
// } else {
$pay_price = bcsub(self::$pay_price, self::$activity_price, 2); //减去活动优惠金额
//判断生鲜是否大于200
if ($createOrder == 1 && self::$fresh_price > 0) {
if (self::$pay_price < 200) {
throw new BusinessException('订单包含生鲜产品订单金额必须大于200元才能下单', 3000);
}
}
// }
//成本价 收益
$order = [
'create_time' => time(),
'order_id' => $params['order_id'] ?? getNewOrderId('PF'),
'total_price' => self::$total_price, //总价
'cost' => self::$cost, //成本价1-
'pay_price' => $pay_price, //后期可能有降价抵扣
'vip_price' => 0,
'total_num' => count($cart_select), //总数
'pay_type' => $params['pay_type'] ?? 0,
'reservation_time' => $params['reservation_time'] ?? null,
'cart_id' => implode(',', $cartId),
'store_id' => $params['store_id'] ?? 0,
'shipping_type' => $params['shipping_type'] ?? 2, //配送方式 1=快递 2=门店自提
'activity' => '减免',
'activity_price' => self::$activity_price,
'activities' => self::$activity_price > 0 ? 1 : 0,
'deduction_price' => self::$deduction_price,
'frozen_money' => self::$frozen_money, //返还金额(活动关闭得时候有)
'source' => 0,
'is_storage' => $params['is_storage'] ?? 0,
];
$order['default_delivery'] = 0;
if ($params['store_id']) {
$order['default_delivery'] = SystemStore::where('id', $params['store_id'])->value('is_send');
}
if (isset($params['source']) && $params['source'] > 0) {
$order['source'] = $params['source'];
}
//处理返回最近的店铺
$store_check = 0;
if (empty($user)) {
$store_id = getenv('STORE_ID') ?? 1;
$store['near_store'] = SystemStore::where('id', $store_id)->field('id,name,phone,address,detailed_address,latitude,longitude')->find() ?? [];
} else {
$checkOrderStore = StoreOrder::where('uid', $user['id'])->field('id,store_id')
->order('id', 'desc')->find();
if ($checkOrderStore) {
$store['near_store'] = SystemStore::where('id', $checkOrderStore['store_id'])->field('id,name,phone,address,detailed_address,latitude,longitude')->find() ?? [];
$store_check = 1;
} else {
$store_id = getenv('STORE_ID') ?? 1;
$store['near_store'] = SystemStore::where('id', $store_id)->field('id,name,phone,address,detailed_address,latitude,longitude')->find() ?? [];
}
}
if (empty($store_check)) {
if ((isset($params['lat']) && $params['lat'] != '') && (isset($params['long']) && $params['long'] != '')) {
$storeAll = SystemStore::field('id,name,phone,address,detailed_address,latitude,longitude')->select()->toArray();
$nearestStore = null;
$minDistance = PHP_FLOAT_MAX;
foreach ($storeAll as $value) {
$value['distance'] = haversineDistance($value['latitude'], $value['longitude'], $params['lat'], $params['long']);
if ($value['distance'] < $minDistance) {
$minDistance = $value['distance'];
$nearestStore = $value;
}
}
$store['near_store'] = [];
if ($nearestStore) {
$store['near_store'] = $nearestStore;
}
}
}
// } catch (\Exception $e) {
// d($e);
// throw new BusinessException($e->getMessage(), 3000);
// }
return ['order' => $order, 'cart_list' => $cart_select, 'shopInfo' => $store['near_store']];
}
/**
* 创建新订单
* @return Object|bool|array
*/
static public function createOrder($cartId, $addressId, $user = null, $params = [])
{
$order_id = getNewOrderId('PF');
$code = rand(1, 10) . '-' . substr($order_id, -5);
$verify_code = createCode($code);
$params['order_id'] = $order_id;
$params['verify_code'] = $verify_code;
$orderInfo = self::cartIdByOrderInfo($cartId, $addressId, $user, $params, 1);
if (!$orderInfo) {
return false;
}
$uid = $user['id'] ?? 0;
$_order = $orderInfo['order'];
$_order['uid'] = $uid;
$_order['spread_uid'] = $params['spread_uid'] ?? 0;
$_order['real_name'] = $user['real_name'] ?? '';
$_order['mobile'] = $user['mobile'] ?? '';
$_order['pay_type'] = $orderInfo['order']['pay_type'];
$_order['verify_code'] = $verify_code;
$_order['reservation_time'] = null;
$_order['reservation'] = $params['reservation'] ?? 0; //是否需要预约
if (isset($params['reservation_time']) && $params['reservation_time']) {
$_order['reservation_time'] = $params['reservation_time'];
$_order['reservation'] = YesNoEnum::YES;
}
if ($addressId > 0 && $uid > 0) {
$address = UserAddress::where(['id' => $addressId, 'uid' => $uid])->find();
if ($address) {
$_order['real_name'] = $address['real_name'];
$_order['user_phone'] = $address['phone'];
$_order['user_address'] = $address['detail'];
}
}
if ($params['shipping_type'] == 2) {
$_order['status'] = 1;
}
if ($_order['pay_type'] == PayEnum::BALANCE_PAY && $user != null && $user['now_money'] < $_order['pay_price']) {
throw new \Exception('余额不足');
}
//生成核销码
$generator = new BarcodeGeneratorPNG();
$barcode = $generator->getBarcode($verify_code, $generator::TYPE_CODE_128);
$findPath = '/image/barcode/' . time() . '.png';
$savePath = public_path() . $findPath;
file_put_contents($savePath, $barcode);
$_order['verify_img'] = $findPath;
Db::startTrans();
try {
$times = strtotime($params['create_time']);
$_order['create_time'] = $times;
$_order['update_time'] = $times;
$order = StoreOrder::create($_order);
$goods_list = $orderInfo['cart_list'];
foreach ($goods_list as $k => $v) {
$goods_list[$k]['oid'] = $order->id;
$goods_list[$k]['uid'] = $uid;
$goods_list[$k]['cart_id'] = implode(',', $cartId);
$goods_list[$k]['delivery_id'] = $params['store_id']; //商家id
$goods_list[$k]['create_time'] = $times; //商家id
$goods_list[$k]['update_time'] = $times; //商家id
// $StoreBranchProduct = StoreBranchProduct::where('id', $v['branch_product_id'])->withTrashed()->find();
// if ($StoreBranchProduct['stock'] - $v['cart_num'] <= 0) {
// Db::name('store_product_cate')->where(['cate_id' => $StoreBranchProduct['cate_id'], 'store_id' => $params['store_id']])->update(['count' => 0]);
// }
}
(new StoreOrderCartInfo())->saveAll($goods_list);
Cart::whereIn('id', $cartId)->update(['is_pay' => 1]);
Db::commit();
return $order;
} catch (\Exception $e) {
Db::rollback();
d($e);
throw new BusinessException($e->getMessage(), 3000);
}
}
}