1 line
23 KiB
PHP
1 line
23 KiB
PHP
<?php
|
||
namespace app\api\controller\food;
|
||
|
||
use app\api\controller\food\Controller;
|
||
use app\api\model\food\Order as OrderModel;
|
||
use app\api\model\food\Cart as CartModel;
|
||
use app\api\model\food\Goods as GoodsModel;
|
||
use app\api\model\food\Table as TableModel;
|
||
use app\api\model\food\Shop as ShopModel;
|
||
use app\api\model\food\Setting as SettingModel;
|
||
use app\api\model\food\CouponUser as CouponUserModel;
|
||
use app\api\model\food\Flavor as FlavorModel;
|
||
use app\api\model\food\Device;
|
||
use hema\Helper;
|
||
use hema\wechat\Map;
|
||
use hema\delivery\Driver as Delivery;
|
||
|
||
/**
|
||
* 订单控制器
|
||
*/
|
||
class Order extends Controller
|
||
{
|
||
private $user;
|
||
private $error;
|
||
/**
|
||
* 构造方法
|
||
*/
|
||
public function initialize()
|
||
{
|
||
parent::initialize();
|
||
$this->user = $this->getUserDetail(); // 用户信息
|
||
}
|
||
/**
|
||
* 订单确认-购物车结算
|
||
* $order_mode 点餐模式 10=扫码,20=外卖,30=打包
|
||
* $pay_mode 支付模式 0微信支付,1余额,2后付款 3支付宝支付
|
||
* $people 就餐人数
|
||
* $coupon_user_id 优惠券ID
|
||
* $message=买家留言
|
||
* $arrive_time = 到店时间
|
||
*/
|
||
public function cart($order_mode,$pay_mode=0,$table_id='',$message='',$arrive_time='0,0',$people='',$flavor='',$coupon_user_id=0)
|
||
{
|
||
// 商品结算信息
|
||
$model = new OrderModel;
|
||
$order = $model->getCart($order_mode,$this->shop_id,$this->user_id,$table_id);
|
||
if(sizeof($order['goods_list']) > 0){
|
||
if($order_mode==20){
|
||
//外卖订单处理
|
||
if(!$order = $this->takeout($order)){
|
||
return $this->renderError($this->error);
|
||
}
|
||
}
|
||
//获取优惠券列表
|
||
$coupon_type = 0;
|
||
$order_mode != 20 && $coupon_type = 10;
|
||
$coupon_list = (new CouponUserModel)->getList($this->user_id,$coupon_type,$this->shop_id);
|
||
if(sizeof($coupon_list) > 0){
|
||
$order = $this->checkCoupon($coupon_list,$order);
|
||
if($coupon_user_id > 0){
|
||
$coupon = CouponUserModel::get($coupon_user_id,['coupon']);
|
||
$order = $this->useCoupon($coupon,$order);
|
||
}
|
||
}
|
||
$order = $this->vip($order,$order_mode);//会员处理
|
||
}
|
||
//扫码下单
|
||
$ware_price = 0;//餐具茶水费
|
||
if($order_mode==10 and !empty($table_id)){
|
||
$table = TableModel::get($table_id);
|
||
//如果餐桌状态空闲中才进行验证,否则为加单
|
||
if($table['status']['value'] == 10){
|
||
$order['is_order'] = 1;//点单
|
||
$order['table_name'] = $table['table_name'] . '(点单)';
|
||
}else{
|
||
$order['is_order'] = 0;//加单
|
||
$order['table_name'] = $table['table_name'] . '(加单)';
|
||
}
|
||
$shop = ShopModel::get($this->shop_id);
|
||
//是否计算餐具茶水费
|
||
if($shop['is_people'] == 1 and $shop['ware_price'] > 0){
|
||
$ware_price = $ware_price + (int)$people * $shop['ware_price'];
|
||
}
|
||
|
||
|
||
}
|
||
$order['ware_price'] = Helper::number2($ware_price);//餐位茶水费
|
||
$order['order_pay_price'] = Helper::number2($order['order_pay_price'] + $ware_price);//重新计算支付费用
|
||
if (!$this->request->isPost()) {
|
||
return $this->renderSuccess($order);
|
||
}
|
||
if($order_mode==10 and !empty($table_id)){
|
||
$order['table_id'] = $table_id;//扫码
|
||
$order['people'] = $people;
|
||
}else{
|
||
$order['row_no'] = $model::rowNo($this->shop_id);//生成取餐吗
|
||
}
|
||
//取餐时间计算
|
||
$arrive = explode(',',$arrive_time);
|
||
if($arrive[0] == 0 and $arrive[1] == 0){
|
||
$order['arrive_time'] = time();
|
||
}else{
|
||
$timestamp = strtotime(date('Y-m-d'.'00:00:00',time()));//今天的起始时间戳
|
||
//今天
|
||
if($arrive[0] == 0){
|
||
$order['arrive_time'] = $timestamp + (int)$arrive[1];
|
||
}
|
||
//明天
|
||
if($arrive[0] == 1){
|
||
$order['arrive_time'] = $timestamp + (int)$arrive[1] + 86400;
|
||
}
|
||
//后天
|
||
if($arrive[0] == 2){
|
||
$order['arrive_time'] = $timestamp + (int)$arrive[1] + (86400 * 2);
|
||
}
|
||
}
|
||
$order['message'] = $message;
|
||
$order['flavor'] = $flavor;
|
||
$order['order_mode'] = $order_mode;
|
||
$order['user_id'] = $this->user_id;
|
||
$order['shop_id'] = $this->shop_id;
|
||
$order['applet_id'] = $this->applet_id;
|
||
// 创建订单
|
||
if (!$model->add($order,$coupon_user_id)) {
|
||
$error = $model->getError() ?: '订单创建失败';
|
||
return $this->renderError($error);
|
||
}
|
||
// 清空购物车
|
||
$Card = new CartModel($this->applet_id,$this->shop_id,$this->user_id,$table_id);
|
||
$Card->clearAll();
|
||
$order = OrderModel::detail($model['order_id']);
|
||
if($data = $order->userPay($pay_mode,$this->mp)){
|
||
return $this->renderSuccess($data);
|
||
}
|
||
$error = $order->getError() ?: '支付失败';
|
||
return $this->renderError($error);
|
||
}
|
||
|
||
/**
|
||
* 使用优惠券
|
||
*/
|
||
private function useCoupon($coupon,$order)
|
||
{
|
||
//现金券验证
|
||
if($coupon['type']['value'] == 10){
|
||
//1立减 ={money=金额}
|
||
//2首单减 = {money=金额}
|
||
$price = (float)$coupon['coupon']['values']['money'];
|
||
$order['order_pay_price'] = Helper::number2($order['order_pay_price'] - $price);// 实际支付金额
|
||
$order['activity_price'] = Helper::number2($price); // 优惠金额
|
||
}
|
||
//折扣券
|
||
if($coupon['type']['value'] == 20){
|
||
//6等级折扣 ={ lv=等级 0不限,discount = 折扣 }
|
||
$price = $order['order_total_price'] - $order['order_total_price'] * (float)$coupon['coupon']['values']['discount'] / 100; //计算优惠金额
|
||
$order['order_pay_price'] = Helper::number2($order['order_pay_price'] - $price);// 实际支付金额
|
||
$order['activity_price'] = Helper::number2($price); // 优惠金额
|
||
}
|
||
//满赠券
|
||
if($coupon['type']['value'] == 30){
|
||
//3满赠 = { condition=满足数值条件 {10金额 20数量} num = 数值 type = 赠品类型 {10优惠券 20商品} gift = 礼物{ id=编号 name=名称 image=图片 }
|
||
$order['gift'] = $coupon['coupon']['values']['gift'];
|
||
}
|
||
//减免券
|
||
if($coupon['type']['value'] == 40){
|
||
//4满减 = { condition=满足数值条件 {10金额 20数量} num = 数量值 money = 减/折数值 }
|
||
//5满折 = { condition=满足数值条件 {10金额 20数量} num = 数量值 money = 减/折数值 }
|
||
if($coupon['coupon']['values']['condition'] == 10){
|
||
//按照订单总金额
|
||
if($coupon['coupon']['mode'] == 4){
|
||
//满减
|
||
$price = (float)$coupon['coupon']['values']['money']; //计算优惠金额
|
||
}else{
|
||
//满折
|
||
|
||
$price = $order['order_total_price'] - $order['order_total_price'] * (float)$coupon['coupon']['values']['money'] / 100; //计算优惠金额
|
||
|
||
}
|
||
$order['order_pay_price'] = Helper::number2($order['order_pay_price'] - $price);// 实际支付金额
|
||
$order['activity_price'] = Helper::number2($price); // 优惠金额
|
||
}else{
|
||
for($x=0;$x<sizeof($order['goods_list']);$x++){
|
||
//按照数量
|
||
if($order['goods_list'][$x]['total_num'] >= $coupon['coupon']['values']['num']){
|
||
if($coupon['coupon']['mode'] == 4){
|
||
//满减
|
||
$price = (float)$coupon['coupon']['values']['money']; //计算优惠金额
|
||
$order['goods_list'][$x]['active'] = '满减';
|
||
}else{
|
||
//满折
|
||
$price = $order['goods_list'][$x]['goods_sku']['goods_price'] - $order['goods_list'][$x]['goods_sku']['goods_price'] * (float)$coupon['coupon']['values']['money'] / 100; //计算优惠金额
|
||
$order['goods_list'][$x]['active'] = '满折';
|
||
}
|
||
$order['order_pay_price'] = Helper::number2($order['order_pay_price'] - $price);// 实际支付金额
|
||
$order['activity_price'] = Helper::number2($price); // 优惠金额
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if($order['order_pay_price'] < 0){
|
||
$order['order_pay_price'] = Helper::number2(0);
|
||
}
|
||
return $order;
|
||
|
||
}
|
||
|
||
/**
|
||
* 验证优惠券是否可用
|
||
*/
|
||
private function checkCoupon($list,$order)
|
||
{
|
||
$coupon_list = [];
|
||
for($n=0;$n<sizeof($list);$n++){
|
||
$item = $list[$n]->toArray();
|
||
unset($item['user']);
|
||
//现金券验证
|
||
if($item['type']['value'] == 10){
|
||
//1立减 ={money=金额}
|
||
if($item['coupon']['mode'] == 1){
|
||
array_push($coupon_list,$item);
|
||
}
|
||
//2首单减 = {money=金额}
|
||
if($item['coupon']['mode'] == 2){
|
||
$orderCount = (new OrderModel)->where(['user_id' => $this->user_id])->count();
|
||
if($orderCount == 0){
|
||
array_push($coupon_list,$item);
|
||
}
|
||
}
|
||
}
|
||
//折扣券
|
||
if($item['type']['value'] == 20){
|
||
//6等级折扣 ={ lv=等级 0不限,discount = 折扣 }
|
||
if($item['coupon']['values']['lv'] == 0){
|
||
array_push($coupon_list,$item);
|
||
}else{
|
||
//获取用户详情
|
||
$user = $this->user;
|
||
if($user['v'] == $item['coupon']['values']['lv']){
|
||
array_push($coupon_list,$item);
|
||
}
|
||
}
|
||
}
|
||
//满赠券
|
||
if($item['type']['value'] == 30){
|
||
//3满赠 = { condition=满足数值条件 {10金额 20数量} num = 数值 type = 赠品类型 {10优惠券 20商品} gift = 礼物{ id=编号 name=名称 image=图片 }
|
||
if($item['coupon']['values']['condition'] == 10){
|
||
//按照金额
|
||
if($order['order_total_price'] >= $item['coupon']['values']['num']){
|
||
array_push($coupon_list,$item);
|
||
}
|
||
}else{
|
||
//按照数量
|
||
if($order['order_total_num'] >= $item['coupon']['values']['num']){
|
||
array_push($coupon_list,$item);
|
||
}
|
||
}
|
||
}
|
||
//减免券
|
||
if($item['type']['value'] == 40){
|
||
//4满减 = { condition=满足数值条件 {10金额 20数量} num = 数量值 money = 减/折数值 }
|
||
//5满折 = { condition=满足数值条件 {10金额 20数量} num = 数量值 money = 减/折数值 }
|
||
if($item['coupon']['values']['condition'] == 10){
|
||
//按照订单总金额
|
||
if($order['order_total_price'] >= $item['coupon']['values']['num']){
|
||
array_push($coupon_list,$item);
|
||
}
|
||
}else{
|
||
foreach ($order['goods_list'] as $vo) {
|
||
//按照单品数量
|
||
if($vo['total_num'] >= $item['coupon']['values']['num']){
|
||
array_push($coupon_list,$item);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$order['coupon_list'] = $coupon_list;
|
||
return $order;
|
||
}
|
||
/**
|
||
* 外卖订单处理
|
||
*/
|
||
private function takeout($order)
|
||
{
|
||
$user = $this->user;
|
||
if($user['address_default']){
|
||
$order['address'] = $user['address_default'];
|
||
//如果免费派送范围大于0
|
||
$shop = ShopModel::get($this->shop_id);
|
||
$delivery = SettingModel::getItem('delivery');
|
||
$map = new Map;
|
||
//计算距离
|
||
if($result = $map->getDistance($shop['coordinate'],$user['address_default']['location'])){
|
||
$distance = $result[0]['distance'];//获取距离计算结果
|
||
if($delivery['delivery_range'] < $distance){
|
||
$order['intra_region'] = true;
|
||
}else{
|
||
//如果超出免费区域就计算配送费
|
||
if($delivery['free_range'] < $distance){
|
||
//判断是否开启自动配送
|
||
if($shop['is_delivery']['value'] == 1 AND $shop['delivery'] != 'self'){
|
||
//如第三方配送,同步第三方配送费
|
||
$dv = new Delivery($shop['delivery']);
|
||
if($shop['delivery'] == 'uu'){
|
||
$user_location = explode(',',$user['address_default']['location']);//拆分收货人定位经纬度
|
||
$shop_location = explode(',',$shop['coordinate']);//拆分门店定位经纬度
|
||
$post_data = [
|
||
'origin_id' => order_no(),//第三方对接平台订单id
|
||
'from_address' => $shop['address'],//起始地址
|
||
'to_address' => $user['address_default']['detail'],//目的地址
|
||
'city_name' => $shop['city'],//订单所在城市名 称(如郑州市就填”郑州市“,必须带上“市”)
|
||
'county_name' => $shop['district'],//订单所在县级地名称(如金水区就填“金水区”)(可为空)
|
||
'to_lat' => $user_location[0],//目的地坐标纬度,如果无,传0(坐标系为百度地图坐标系)
|
||
'to_lng' => $user_location[1],//目的地坐标经度,如果无,传0(坐标系为百度地图坐标系)
|
||
'from_lat' => $shop_location[0],//起始地坐标纬度,如果无,传0(坐标系为百度地图坐标系)
|
||
'from_lng' => $shop_location[1] //起始地坐标经度,如果无,传0(坐标系为百度地图坐标系)
|
||
];
|
||
}
|
||
if($shop['delivery'] == 'dada'){
|
||
$user_location = explode(',',$user['address_default']['location']);//拆分收货人定位经纬度
|
||
$shop_location = explode(',',$shop['coordinate']);//拆分门店定位经纬度
|
||
$city_code = $dv->getCiytCode($shop['city']);
|
||
$post_data = [
|
||
'shop_no' => $shop['dada_shop_id'],//是 门店编号
|
||
'origin_id' => order_no(),//是 第三方订单ID
|
||
'city_code' => $city_code,//是 订单所在城市的code
|
||
'cargo_price' => 1,//是 订单金额
|
||
'is_prepay' => 0,//是否需要垫付 1:是 0:否 (垫付订单金额,非运费)
|
||
'receiver_name' => $user['address_default']['name'],//是 收货人姓名
|
||
'receiver_address' => $user['address_default']['detail'],//是 收货人地址
|
||
'callback' => base_url() . 'api/food.delivery/dada',//是 回调URL
|
||
'receiver_lat' => $user_location[0], //否 收货人地址纬度
|
||
'receiver_lng' => $user_location[1],//否 收货人地址经度
|
||
'cargo_weight' => 0.1,//是 订单重量(单位:Kg)
|
||
];
|
||
}
|
||
if($shop['delivery'] == 'make'){
|
||
$post_data = [
|
||
'fromcoord' => $shop['coordinate'],//起点地址坐标
|
||
'tocoord' => $user['address_default']['location'],//终点地址坐标
|
||
'shop_id' => $shop['make_shop_id'] //店铺ID
|
||
];
|
||
}
|
||
if($shop['delivery'] == 'shansong'){
|
||
$user_location = explode(',',$user['address_default']['location']);//拆分收货人定位经纬度
|
||
$shop_location = explode(',',$shop['coordinate']);//拆分门店定位经纬
|
||
$post_data = [
|
||
'cityName' => $shop['city'],//城市名称
|
||
'appointType' => 0,//预约类型Integer 0立即单,1预约单
|
||
'sender' => [//寄件人信息
|
||
'fromAddress' => $shop['district'],//寄件地址
|
||
'fromAddressDetail' => $shop['address'],//寄件详细地址
|
||
'fromSenderName' => $shop['shop_name'], //寄件人姓名
|
||
'fromMobile' => $shop['phone'],//寄件人电话,支持11位手机号;支持座机号(格式:010-12345678)
|
||
'fromLatitude' => $shop_location[0],//寄件纬度,只支持百度坐标系
|
||
'fromLongitude' => $shop_location[1]//寄件经度,只支持百度坐标系
|
||
],
|
||
'receiverList' => [//收件人信息
|
||
'orderNo' => order_no(), //第三方平台流水号
|
||
'toAddress' => $user['address_default']['district'],//收件地址
|
||
'toAddressDetail' => $user['address_default']['detail'],//收件详细地址
|
||
'toLatitude' => $user_location[0],//收件纬度,只支持百度坐标系
|
||
'toLongitude' => $user_location[1],//收件经度,只支持百度坐标系
|
||
'toReceiverName' => $user['address_default']['name'],//收件人姓名
|
||
'toMobile' => $user['address_default']['phone'],//收件联系人,支持11位手机号;支持座机号格式:010-12345678
|
||
'goodType' => 6,// 物品类型,6=餐饮
|
||
'weight' =>1 //物品重量,单位为kg
|
||
]
|
||
];
|
||
}
|
||
if($shop['delivery'] == 'sf'){
|
||
$user_location = explode(',',$user['address_default']['location']);//拆分收货人定位经纬度
|
||
$shop_location = explode(',',$shop['coordinate']);//拆分门店定位经纬度
|
||
$post_data = [
|
||
'shop_id' => $shop['sf_shop_id'],//$this->shop_id,//店铺ID
|
||
//'shop_type' => 1,//店铺ID类型 1:顺丰店铺ID 2:接入方店铺ID
|
||
'user_lng' => $user_location[1],//用户地址经度
|
||
'user_lat' => $user_location[0],//用户地址纬度
|
||
'user_address' => $user['address_default']['district'].','.$user['address_default']['detail'],//用户详细地址
|
||
'city_name' => $user['address_default']['city'],//发单城市
|
||
'weight' => 0,//物品重量(单位:克)
|
||
'product_type' => 1, //物品类型,测试店铺请填写1,否则会造成【没有匹配的计价规则或计价规则已失效】
|
||
'is_appoint' => 0,//是否是预约单0:非预约单;1:预约单
|
||
'expect_time' => time()+1800,//期望送达时间,预约单需必传 秒级时间戳
|
||
//'expect_pickup_time' => time()+600,//期望取货时间
|
||
'lbs_type' => 2,//坐标类型,1:百度坐标,2:高德坐标
|
||
'pay_type' => 1,//用户支付方式:1、已支付 0、货到付款
|
||
'receive_user_money' => 0,//代收金额,单位:分
|
||
'is_insured' => 0,//是否保价,0:非保价;1:保价
|
||
'is_person_direct' => 0,//是否是专人直送订单,0:否;1:是
|
||
'declared_value' => 0,//保价金额,单位:分
|
||
'gratuity_fee' => 0,//订单小费,不传或者传0为不加小费 单位分,加小费最低不能少于100分
|
||
'rider_pick_method' => 1,//物流流向 1:从门店取件送至用户 2:从用户取件送至门店
|
||
'return_flag' => 511,//1:商品总价格,2:配送距离,4:物品重量,8:起送时间,16:期望送达时间,32:支付费用,64:实际支持金额,128:优惠卷总金额,256:结算方式,例如全部返回为填入511
|
||
'push_time' => time(),
|
||
//发货店铺信息;Obj,平台级开发者需要传入
|
||
'shop' => [
|
||
'shop_name' => $shop['shop_name'],//店铺名称
|
||
'shop_phone' => $shop['phone'],//店铺电话
|
||
'shop_address' => $shop['address'],//店铺地址
|
||
'shop_lng' => $shop_location[1],//店铺经度
|
||
'shop_lat' => $shop_location[0]//店铺纬度
|
||
]
|
||
];
|
||
}
|
||
if($result = $dv->preOrder($post_data)){
|
||
$order['delivery_price'] = Helper::number2($result['price']);//第三方配送费
|
||
}else{
|
||
$this->error = $dv->getError();
|
||
return false;
|
||
}
|
||
}else{
|
||
$order['delivery_price'] = Helper::number2($delivery['delivery_price']);
|
||
}
|
||
$order['order_pay_price'] = Helper::number2($order['order_pay_price'] + $order['delivery_price']);
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
return $order;
|
||
}
|
||
/**
|
||
* 会员处理
|
||
*/
|
||
private function vip($order,$order_mode)
|
||
{
|
||
$user = $this->user;
|
||
//如果是会员
|
||
if($user['v']['value'] > 0){
|
||
$vip = SettingModel::getItem('vip');
|
||
//如果开启会员折扣
|
||
if($vip['vip_discount'] == 1){
|
||
//计算会员折扣 - 优惠金额
|
||
$discount = $vip['vip'][$user['v']['value']]['discount'];
|
||
$price = $order['order_pay_price'] * $discount / 100; //折扣后的价格;
|
||
$order['vip_price'] = Helper::number2($order['vip_price']+$order['order_pay_price']-$price);
|
||
$order['order_pay_price'] = Helper::number2($price);
|
||
}
|
||
if($vip['vip'][$user['v']['value']]['free_delivery'] == 1 and $order_mode==20){
|
||
$order['vip_price'] = Helper::number2($order['vip_price']+$order['delivery_price']);
|
||
$order['delivery_price'] = Helper::number2(0);
|
||
$order['free_delivery'] = true;
|
||
}
|
||
}
|
||
return $order;
|
||
}
|
||
/**
|
||
* 呼叫服务员
|
||
*/
|
||
public function spk($order_id,$mode)
|
||
{
|
||
$model = OrderModel::detail($order_id);
|
||
Device::push($this->shop_id,$mode,$model['table']['row_no']);
|
||
return $this->renderMsg('操作成功');
|
||
}
|
||
|
||
/**
|
||
* 获取口味选项
|
||
*/
|
||
public function flavor()
|
||
{
|
||
$model = new FlavorModel;
|
||
$list = $model->getList($this->shop_id);
|
||
return $this->renderSuccess($list);
|
||
}
|
||
}
|
||
|