// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\AccountLogModel; use App\Models\CartsModel; use App\Models\GoodsModel; use App\Models\MemberCouponModel; use App\Models\MemberModel; use App\Models\MerchantModel; use App\Models\OrderGoodsModel; use App\Models\OrderModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; use App\Services\SupplyService; use Illuminate\Support\Facades\DB; /** * 订单管理-服务类 * @author laravel开发员 * @since 2020/11/11 * Class OrderService * @package App\Services\Api */ class OrderService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * OrderService constructor. */ public function __construct() { $this->model = new OrderModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * @param $params * @param int $pageSize * @return array */ public function getDataList($params, $pageSize = 15) { $where = ['a.mark' => 1,'a.is_hide'=>0]; $merchId = isset($params['merch_id']) ? $params['merch_id'] : 0; if ($merchId > 0) { $where['a.merch_id'] = $merchId; } $merchUid = isset($params['merch_uid']) ? $params['merch_uid'] : 0; if ($merchUid > 0) { $where['a.merch_uid'] = $merchUid; } $list = $this->model->from('orders as a')->with(['goods']) ->leftJoin('member as b', 'a.user_id', '=', 'b.id') ->where($where) ->where(function ($query) use ($params) { $keyword = isset($params['kw']) ? $params['kw'] : ''; if ($keyword) { $query->where('a.order_no', 'like', "%{$keyword}%")->orWhere('b.id', '=', "{$keyword}")->orWhere('b.nickname', 'like', "%{$keyword}%")->orWhere('b.mobile', 'like', "%{$keyword}%"); } }) ->where(function ($query) use ($params) { $status = isset($params['status']) ? $params['status'] : 0; $userId = isset($params['user_id']) ? $params['user_id'] : 0; $type = isset($params['type']) ? $params['type'] : 0; if ($userId) { $query->where('a.user_id', '=', $userId); } if ($type > 0) { $query->where('a.type', '=', $type); } if ($status > 0) { $query->where('a.status', '=', $status); }else{ $query->where('a.status', '>', 1); } }) ->select(['a.*', 'b.nickname', 'b.trc_url']) ->orderBy('a.pay_time', 'desc') ->orderBy('a.id', 'desc') ->paginate($pageSize > 0 ? $pageSize : 9999999); $list = $list ? $list->toArray() : []; if ($list) { $refundStatusArr = [1=>'退款中',2=>'已退款',3=>'退款失败']; $statusArr = [1=>'待付款',2=>'待发货',3=>'待收货',4=>'已完成',5=>'已售后']; $supplyList = config('goods.supplyList'); foreach ($list['data'] as &$item) { $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y-m-d H:i:s') : ''; $item['pay_time'] = $item['pay_time'] ? datetime($item['pay_time'], 'Y-m-d H:i:s') : ''; $status = isset($item['status'])? $item['status'] : 0; $item['status_text'] = '待付款'; $item['refund_status_text'] = ''; if($status){ if($item['type'] == 2){ $item['status_text'] = isset($serviceStatusArr[$status])? $serviceStatusArr[$status] : ''; }else{ $item['status_text'] = isset($statusArr[$status])? $statusArr[$status] : ''; } } $refundStatus = isset($item['refund_status'])? $item['refund_status'] : 0; if($refundStatus && $status != 4){ $item['refund_status_text'] = isset($refundStatusArr[$refundStatus])? $refundStatusArr[$refundStatus] : ''; } $goods = isset($item['goods'])? $item['goods'] : []; if($goods){ foreach ($goods as &$v){ $v['supply_name'] = isset($supplyList[$v['supply_type']]) ? $supplyList[$v['supply_type']] : ''; $v['main_img'] = isset($v['main_img']) && $v['main_img']? get_image_url($v['main_img']) : ''; $v['sku_attr'] = isset($v['sku_attr']) && $v['sku_attr']? json_decode($v['sku_attr'], true) : []; } unset($v); } $item['goods'] = $goods? $goods : []; } unset($item); } return [ 'pageSize' => $pageSize, 'total' => isset($list['total']) ? $list['total'] : 0, 'counts' => [], 'list' => isset($list['data']) ? $list['data'] : [] ]; } /** * 购买商品 * @param $userId 用户ID * @param $params * @return array|false */ public function buySubmit($userId, $params) { $payType = isset($params['pay_type'])? intval($params['pay_type']) : 0; $type = isset($params['type']) && $params['type']? intval($params['type']) : 1; $amount = isset($params['total']) && $params['total']? floatval($params['total']) : 0; $couponId = isset($params['coupon_id'])? intval($params['coupon_id']) : 0; $addressId = isset($params['address_id'])? intval($params['address_id']) : 0; $freightAddressId = isset($params['freight_address_id'])? intval($params['freight_address_id']) : 0; $payPassword = isset($params['pay_password'])? trim($params['pay_password']) : ''; $skuList = isset($params['sku_list'])? $params['sku_list'] : []; $ids = isset($params['ids'])? $params['ids'] : []; $cartIds = isset($params['cart_ids'])? trim($params['cart_ids']) : ''; $cartIds = $cartIds? explode('|', $cartIds) : []; if(empty($skuList) || empty($ids) || $addressId<=0 || $freightAddressId<=0 || $payType<=0){ $this->error = 2420; return false; } // 锁 $cacheKey = "caches:orders:buy:{$userId}"; if(RedisService::get($cacheKey)){ $this->error = 1053; return false; } // 订单商品 $goods = GoodsService::make()->getOrderGoods($userId, $ids); if(empty($goods)){ $this->error = 2903; return false; } // 格式化 $skuArr = []; $skuAttr = []; foreach ($skuList as $v){ $skuArr[$v['goods_id']] = [ 'sku_id'=> $v['sku_id'], 'num'=> $v['num'], ]; $skuAttr[$v['goods_id']] = $v['attr']; } $skuList = $skuArr; $goodsNum = 0; $orderTotal = 0; $orderXdTotal = 0; $merchId = 0; $orderNo = get_order_num('XS'); // 价格参数 $usdtPrice = RedisService::get("caches:wallets:usdt_rate"); if($usdtPrice<=0){ $usdtCnyPrice = ConfigService::make()->getConfigByCode('usdt_cny_price', 7.2); $usdtPrice = $usdtCnyPrice>0 && $usdtCnyPrice< 100? $usdtCnyPrice : 0; } $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $xdPrice = $xdPrice > 0 && $xdPrice <= 10000 ? $xdPrice : 100; foreach($goods as &$item){ $goodsId = isset($item['goods_id'])? $item['goods_id'] : 0; $merchId = isset($item['merch_id'])? $item['merch_id'] : 0; $num = isset($skuList[$goodsId]['num'])? intval($skuList[$goodsId]['num']) : 0; $skuId = isset($skuList[$goodsId]['sku_id'])? intval($skuList[$goodsId]['sku_id']) : 0; $goodsSkuList = isset($item['sku_list'])? $item['sku_list'] : []; $skuInfo = isset($goodsSkuList[$skuId])? $goodsSkuList[$skuId] : []; $price = isset($skuInfo['retail_price'])? $skuInfo['retail_price'] : 0; $attr = isset($skuAttr[$goodsId])? $skuAttr[$goodsId] : []; if($num>0 && $skuId >0 && $price>0){ $item['price'] = GoodsService::make()->getRealSalePrice($price); // 浮动后星豆价 $price = GoodsService::make()->getRealSalePrice($price,3); // 浮动后原售价 $total = moneyFormat($price * $num, 2); $xdTotal = moneyFormat($item['price'] * $num, 2); // 订单商品 $item['order_no'] = $orderNo; $item['total'] = $total; $item['xd_total'] = $xdTotal; $item['num'] = $num; $item['sku_attr'] = $attr? json_encode($attr, 256) : ''; $item['create_time'] = time(); $item['update_time'] = time(); $item['status'] = 1; $item['mark'] = 1; // 订单金额 $orderTotal += $total; $orderXdTotal += $xdTotal; $goodsNum += $num; unset($item['sku_list']); }else{ unset($item); } } unset($item); if($orderXdTotal<=0 || $goodsNum<=0){ $this->error = 2904; return false; } // 优惠券 $couponPrice = 0; if($couponId > 0){ } // 验证用户 $userInfo = MemberModel::where(['id'=> $userId,'mark'=> 1,'status'=> 1]) ->select(['id','nickname','pay_password','balance','parent_id','parents']) ->first(); $userInfo = $userInfo? $userInfo->toArray() : []; $userPayPassword = isset($userInfo['pay_password'])? $userInfo['pay_password'] : ''; $userXd = isset($userInfo['balance'])? floatval($userInfo['balance']) : 0.00; if(empty($userInfo)){ $this->error = 2024; return false; } // 余额支付支付密码验证 if($payType == 10 && empty($userPayPassword)){ $this->error =1040; return false; } // 星豆余额支付交易密码 $payPassword = get_password($payPassword); if($payType == 10 && $payPassword != $userPayPassword){ $this->error = 2038; return false; } // 运费 $skus = array_values($skuList); var_dump($skus); var_dump($goods); var_dump($skuList); return false; if(!$freightData = GoodsService::make()->getFreight($userId, $freightAddressId, $skus)){ $this->error = GoodsService::make()->getError()?? 2905; return false; } $freight = isset($freightData['freight'])? floatval($freightData['freight']) : 0; $payTotal = moneyFormat($orderXdTotal+$freight,2); //var_dump($payTotal, $amount); var_dump($payTotal); var_dump($goods); if(intval($amount) != intval($payTotal)){ $this->error = 2906; return false; } return false; // 星豆余额支付验证 if($payType == 10 && $userXd < $payTotal){ $this->error = 2304; return false; } // 收货地址 $addressInfo = MemberAddressService::make()->getBindInfo($userId, $addressId); $addressText = isset($addressInfo['address_text'])? $addressInfo['address_text'] : ''; $city = isset($addressInfo['city'])? $addressInfo['city'] : ''; $realname = isset($addressInfo['realname'])? $addressInfo['realname'] : ''; $mobile = isset($addressInfo['mobile'])? $addressInfo['mobile'] : ''; $address = isset($addressInfo['address'])? $addressInfo['address'] : ''; if(empty($addressText) || empty($addressInfo) || empty($realname) || empty($mobile)){ $this->error = 2902; return false; } $merchUId = 0; // 奖励待返积分 $waitScoreRate = ConfigService::make()->getConfigByCode('shop_award_score_rate',0); $waitScoreRate = $waitScoreRate>=0 && $waitScoreRate<=1000? $waitScoreRate : 0; $awardWaitScore = moneyFormat($orderXdTotal * $waitScoreRate/100, 2); // 算力奖励 $powerRate = ConfigService::make()->getConfigByCode('shop_award_power_rate',0); $powerRate = $powerRate>=0 && $powerRate<=1000? $powerRate : 0; $awardPowerNum = moneyFormat($orderXdTotal * $powerRate/100, 2); // 订单数据 $order = [ 'user_id'=> $userId, 'order_no'=> $orderNo, 'merch_id'=> $merchId, 'merch_uid'=> $merchUId, 'type'=> $type, 'price'=> 0.00, 'xd_price'=> $xdPrice, 'num'=> $goodsNum, 'city'=> $city, 'real_name'=> $realname, 'mobile'=> $mobile, 'address'=> $address && $addressText? $addressText.' '.$address : $addressText, 'total'=> $orderTotal, 'xd_total'=> $orderXdTotal, 'pay_type'=> $payType, 'pay_money'=> $payTotal, 'delivery_type'=> 1, 'coupon_id'=> $couponId, 'coupon_price'=> $couponPrice, 'postage'=> $freight, 'award_wait_score'=> $awardWaitScore, 'award_power_num'=> $awardPowerNum, 'create_time'=> time(), 'update_time'=> time(), 'remark'=> isset($params['remark'])? trim($params['remark']) : '', 'status'=> 1, 'mark'=> 1, ]; // 站外订单提交 RedisService::set($cacheKey, $order, rand(2,3)); $orderParams = [ 'third_order'=> $orderNo, 'address_id'=> $freightAddressId, 'sku_list'=> $skus, 'receiver'=> $realname, 'receiver_phone'=> $mobile, 'address'=> $address, 'other'=> isset($params['remark'])? $params['remark'] : '', ]; $result = SupplyService::make()->getApiData('orderSubmit', $orderParams); $outOrderNo = isset($result['out_order_no'])? $result['out_order_no'] : ''; $expense = isset($result['expense'])? floatval($result['expense']) : 0; $servicePrice = isset($result['service_price'])? floatval($result['service_price']) : 0; if(empty($result)){ RedisService::clear($cacheKey); $this->error = SupplyService::make()->getError(); return false; } // 创建订单 $order['out_order_no'] = $outOrderNo; $order['expense'] = $expense; $order['service_price'] = $servicePrice; if(!$orderId = $this->model->insertGetId($order)){ $this->error = 2907; RedisService::clear($cacheKey); return false; } // 写入订单商品 if($orderId && !OrderGoodsModel::insert($goods)){ $this->error = 2908; RedisService::clear($cacheKey); return false; } DB::beginTransaction(); // 支付处理 $payment = []; $dateTime = date('Y-m-d H:i:s'); switch($payType){ case 10: // 星豆余额支付 // 扣除余额 $updateData = [ 'usdt'=> DB::raw("usdt - {$payTotal}"), // 扣除USDT 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $userId])->update($updateData)){ DB::rollBack(); $this->error = 1042; RedisService::clear($cacheKey); return false; } // 余额明细 $log = [ 'user_id' => $userId, 'source_id' => $orderId, 'source_order_no' => $orderNo, 'type' => 3, 'coin_type' => 2, 'user_type'=> 1, 'money' => $payTotal, 'actual_money' => $payTotal, 'balance' => $userXd, 'create_time' => time(), 'update_time' => time(), 'remark' => "商城购物消费", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } // 更新订单状态 $updateData = ['status'=>2,'pay_status'=> 1,'pay_time'=>date('Y-m-d H:i:s'),'update_time'=>time()]; if(!$this->model->where(['id'=> $orderId,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2909; RedisService::clear($cacheKey); return false; } $payStatus = 1; break; default: $this->error = 1030; return false; } // 更新优惠券状态 if($couponId>0 && !MemberCouponModel::where(['id'=> $couponId,'mark'=>1])->update(['status'=> 2,'update_time'=>time()])){ DB::rollBack(); $this->error = 2908; RedisService::clear($cacheKey); return false; } // 购物车处理 if($cartIds){ CartsModel::where(['user_id'=> $userId,'status'=>1,'mark'=>1]) ->whereIn('id', $cartIds) ->update(['status'=>2,'update_time'=>time()]); RedisService::clear("caches:members:cartList:{$userId}"); RedisService::clear("caches:members:cartCount:{$userId}"); } // 已支付 RedisService::clear($cacheKey); if($payStatus == 1){ // 支付成功订单通知 $message = "您在{$dateTime}(UTC+8)创建的订单【{$orderNo}】,金额{$payTotal}星豆,已支付成功,请耐心等候发货。"; MessageService::make()->pushMessage($userId,"订单支付成功",$message, 2); DB::commit(); $this->error = 2910; return [ 'id'=> $orderId, 'out_order_no'=> $outOrderNo, 'total'=> $payTotal, 'pay_type'=> $payType, ]; }else{ // 下单成功订单通知 $message = "您在{$dateTime}(UTC+8)创建订单【{$orderNo}】成功,请尽快完成支付。"; MessageService::make()->pushMessage($userId,"订单创建成功",$message, 2); DB::commit(); $this->error = 2911; return [ 'id'=> $orderId, 'out_order_no'=> $outOrderNo, 'total'=> $payTotal, 'pay_type'=> $payType, ]; } } /** * 购买商品 * @param $userId 用户ID * @param $params * @return array|false */ public function buySubmit1($userId, $params) { $payType = isset($params['pay_type'])? intval($params['pay_type']) : 0; $type = isset($params['type']) && $params['type']? intval($params['type']) : 1; $amount = isset($params['total']) && $params['total']? floatval($params['total']) : 0; $couponId = isset($params['coupon_id'])? intval($params['coupon_id']) : 0; $addressId = isset($params['address_id'])? intval($params['address_id']) : 0; $freightAddressId = isset($params['freight_address_id'])? intval($params['freight_address_id']) : 0; $payPassword = isset($params['pay_password'])? trim($params['pay_password']) : ''; $skuList = isset($params['sku_list'])? $params['sku_list'] : []; $ids = isset($params['ids'])? $params['ids'] : []; $cartIds = isset($params['cart_ids'])? trim($params['cart_ids']) : ''; $cartIds = $cartIds? explode('|', $cartIds) : []; if(empty($skuList) || empty($ids) || $addressId<=0 || $freightAddressId<=0 || $payType<=0){ $this->error = 2420; return false; } // 锁 $cacheKey = "caches:orders:buy:{$userId}"; if(RedisService::get($cacheKey)){ $this->error = 1053; return false; } // 订单商品 $goods = GoodsService::make()->getOrderGoods($userId, $ids); if(empty($goods)){ $this->error = 2903; return false; } $goodsNum = 0; $orderTotal = 0; $orderXdTotal = 0; $merchId = 0; $goods = []; $orderNo = get_order_num('XS'); // 价格参数 $usdtPrice = RedisService::get("caches:wallets:usdt_rate"); if($usdtPrice<=0){ $usdtCnyPrice = ConfigService::make()->getConfigByCode('usdt_cny_price', 7.2); $usdtPrice = $usdtCnyPrice>0 && $usdtCnyPrice< 100? $usdtCnyPrice : 0; } $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $xdPrice = $xdPrice > 0 && $xdPrice <= 10000 ? $xdPrice : 100; foreach($goods as &$item){ $goodsId = isset($item['goods_id'])? $item['goods_id'] : 0; $merchId = isset($item['merch_id'])? $item['merch_id'] : 0; $retailPrice = isset($item['retail_price'])? $item['retail_price'] : 0; $num = isset($skuList[$goodsId]['num'])? intval($skuList[$goodsId]['num']) : 0; $skuId = isset($skuList[$goodsId]['sku_id'])? intval($skuList[$goodsId]['sku_id']) : 0; if($num>0 && $skuId >0 && $retailPrice>0){ $item['price'] = moneyFormat($retailPrice/$usdtPrice * $xdPrice,2); $total = moneyFormat($retailPrice * $num, 2); $xdTotal = moneyFormat($item['price'] * $num, 2); // 订单商品 $item['order_no'] = $orderNo; $item['total'] = $total; $item['xd_total'] = $xdTotal; $item['num'] = $num; $item['create_time'] = time(); $item['update_time'] = time(); $item['status'] = 1; $item['mark'] = 1; // 订单金额 $orderTotal += $total; $orderXdTotal += $xdTotal; $goodsNum += $num; } } if($orderXdTotal<=0 || $goodsNum<=0){ $this->error ='2904'; return false; } // 优惠券 $couponPrice = 0; if($couponId > 0){ } // 运费 $skus = array_values($skuList); if(!$freightData = GoodsService::make()->getFreight($userId, $freightAddressId, $skus)){ $this->error ='2905'; return false; } $freight = isset($freightData['freight'])? floatval($freightData['freight']) : 0; $payTotal = moneyFormat($orderXdTotal+$freight,2); if($amount != $payTotal){ $this->error ='2906'; return false; } // 验证用户 $userInfo = MemberModel::with(['parent'])->where(['id'=> $userId,'mark'=> 1,'status'=> 1]) ->select(['id','nickname','pay_password','balance','usdt','power_num','wait_score','parent_id','parents']) ->first(); $userInfo = $userInfo? $userInfo->toArray() : []; $parentInfo = isset($userInfo['parent'])? $userInfo['parent'] : []; $userPayPassword = isset($userInfo['pay_password'])? $userInfo['pay_password'] : ''; $userXd = isset($userInfo['balance'])? floatval($userInfo['balance']) : 0.00; $userWaitScore = isset($userInfo['wait_score'])? floatval($userInfo['wait_score']) : 0.00; $userPowerNum = isset($userInfo['power_num'])? floatval($userInfo['power_num']) : 0.00; if(empty($userInfo)){ $this->error = 2024; return false; } // 余额支付支付密码验证 if($payType == 10 && empty($userPayPassword)){ $this->error =1040; return false; } // 星豆余额支付交易密码 $payPassword = get_password($payPassword); if($payType == 10 && $payPassword != $userPayPassword){ $this->error = 2038; return false; } // 星豆余额支付验证 if($payType == 10 && $userXd < $payTotal){ $this->error = 2304; return false; } // 收货地址 $addressInfo = MemberAddressService::make()->getBindInfo($userId, $addressId); $addressText = isset($addressInfo['address_text'])? $addressInfo['address_text'] : ''; $city = isset($addressInfo['city'])? $addressInfo['city'] : ''; $realname = isset($addressInfo['realname'])? $addressInfo['realname'] : ''; $mobile = isset($addressInfo['mobile'])? $addressInfo['mobile'] : ''; $address = isset($addressInfo['address'])? $addressInfo['address'] : ''; if(empty($addressText) || empty($addressInfo) || empty($realname) || empty($mobile)){ $this->error = 2902; return false; } $merchUId = 0; // 奖励待返积分 $waitScoreRate = ConfigService::make()->getConfigByCode('shop_award_score_rate',0); $waitScoreRate = $waitScoreRate>=0 && $waitScoreRate<=1000? $waitScoreRate : 0; $awardWaitScore = moneyFormat($orderXdTotal * $waitScoreRate/100, 2); // 算力奖励 $powerRate = ConfigService::make()->getConfigByCode('shop_award_power_rate',0); $powerRate = $powerRate>=0 && $powerRate<=1000? $powerRate : 0; $awardPowerNum = moneyFormat($orderXdTotal * $powerRate/100, 2); // 订单数据 $order = [ 'user_id'=> $userId, 'order_no'=> $orderNo, 'merch_id'=> $merchId, 'merch_uid'=> $merchUId, 'type'=> $type, 'price'=> 0.00, 'xd_price'=> $xdPrice, 'num'=> $goodsNum, 'city'=> $city, 'real_name'=> $realname, 'mobile'=> $mobile, 'address'=> $address && $addressText? $addressText.' '.$address : $addressText, 'total'=> $orderTotal, 'xd_total'=> $orderXdTotal, 'pay_type'=> $payType, 'pay_money'=> $payTotal, 'delivery_type'=> 1, 'coupon_id'=> $couponId, 'coupon_price'=> $couponPrice, 'postage'=> $freight, 'award_wait_score'=> $awardWaitScore, 'award_power_num'=> $awardPowerNum, 'create_time'=> time(), 'update_time'=> time(), 'remark'=> isset($params['remark'])? trim($params['remark']) : '', 'status'=> 1, 'mark'=> 1, ]; // 创建订单 DB::beginTransaction(); RedisService::set($cacheKey, $order, rand(2,3)); if(!$orderId = $this->model->insertGetId($order)){ DB::rollBack(); $this->error = 2907; RedisService::clear($cacheKey); return false; } // 写入订单商品 if(!OrderGoodsModel::insert($goods)){ DB::rollBack(); $this->error = 2908; RedisService::clear($cacheKey); return false; } // 支付处理 $payment = []; $payStatus = 2; $userAwardWaitScore = 0; $inviteAwardWaitScore = 0; $parentId = isset($parentInfo['id'])? $parentInfo['id'] : 0; $dateTime = date('Y-m-d H:i:s'); switch($payType){ case 10: // 星豆余额支付 // 推荐用户奖励 $parentStatus = isset($parentInfo['status'])? $parentInfo['status'] : 0; if($parentInfo && $parentStatus==1 && $awardWaitScore>0){ // 奖励上级待返积分 $inviteWaitScoreRate = ConfigService::make()->getConfigByCode('cost_award_invite_wait_score',0); $inviteWaitScoreRate = $inviteWaitScoreRate>0 && $inviteWaitScoreRate<100? $inviteWaitScoreRate : 0; $inviteAwardWaitScore = moneyFormat($awardWaitScore * $inviteWaitScoreRate/100, 2); $userAwardWaitScore = moneyFormat($awardWaitScore - $inviteAwardWaitScore, 2); } // 扣除余额 $updateData = [ 'usdt'=> DB::raw("usdt - {$payTotal}"), // 扣除USDT // 'wait_score'=>DB::raw("wait_score + {$userAwardWaitScore}"), // 用户待返积分奖励 // 'power_num'=>DB::raw("power_num + {$awardPowerNum}"), // 算力奖励 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $userId])->update($updateData)){ DB::rollBack(); $this->error = 1042; RedisService::clear($cacheKey); return false; } // 余额明细 $log = [ 'user_id' => $userId, 'source_id' => $orderId, 'source_order_no' => $orderNo, 'type' => 3, 'coin_type' => 2, 'user_type'=> 1, 'money' => $payTotal, 'actual_money' => $payTotal, 'balance' => $userXd, 'create_time' => time(), 'update_time' => time(), 'remark' => "商城购物消费", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } // 更新订单状态 $updateData = ['status'=>2,'pay_status'=> 1,'pay_time'=>date('Y-m-d H:i:s'),'update_time'=>time()]; if(!$this->model->where(['id'=> $orderId,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2909; RedisService::clear($cacheKey); return false; } // 待返积分奖励明细 if($userAwardWaitScore>0){ $log = [ 'user_id' => $userId, 'source_id' => $orderId, 'source_order_no' => $orderNo, 'type' => 9, 'coin_type' => 5, 'user_type'=> 1, 'money' => $userAwardWaitScore, 'actual_money' => $userAwardWaitScore, 'balance' => $userWaitScore, 'create_time' => time(), 'update_time' => time(), 'remark' => "商城消费奖励", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } } // 算力奖励明细 if($awardPowerNum>0){ $log = [ 'user_id' => $userId, 'source_id' => $orderId, 'source_order_no' => $orderNo, 'type' => 9, 'coin_type' => 3, 'user_type'=> 1, 'money' => $awardPowerNum, 'actual_money' => $awardPowerNum, 'balance' => $userPowerNum, 'create_time' => time(), 'update_time' => time(), 'remark' => "商城消费奖励", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } } // 推荐用户待返积分奖励明细 if($inviteAwardWaitScore>0 && $parentId>0){ $updateData = [ 'wait_score'=>DB::raw("wait_score + {$inviteAwardWaitScore}"), // 推荐用户待返积分奖励 'update_time'=>time() ]; if(!MemberModel::where(['id'=> $parentId])->update($updateData)){ DB::rollBack(); $this->error = 2028; RedisService::clear($cacheKey); return false; } $log = [ 'user_id' => $parentId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 9, 'coin_type' => 5, 'user_type'=> 1, 'money' => $userAwardWaitScore, 'actual_money' => $userAwardWaitScore, 'balance' => $userWaitScore, 'create_time' => time(), 'update_time' => time(), 'remark' => "推荐用户商城消费奖励", 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2029; RedisService::clear($cacheKey); return false; } } $payStatus = 1; break; default: $this->error = 1030; return false; } // 更新优惠券状态 if($couponId>0 && !MemberCouponModel::where(['id'=> $couponId,'mark'=>1])->update(['status'=> 2,'update_time'=>time()])){ DB::rollBack(); $this->error = 2908; RedisService::clear($cacheKey); return false; } // 购物车处理 if($cartIds){ CartsModel::where(['user_id'=> $userId,'status'=>1,'mark'=>1]) ->whereIn('id', $cartIds) ->update(['status'=>2,'update_time'=>time()]); } // 已支付 RedisService::clear($cacheKey); if($payStatus == 1){ // 支付成功订单通知 $message = "您在{$dateTime}(UTC+8)创建的订单【{$orderNo}】,金额{$payTotal}星豆,已支付成功。"; MessageService::make()->pushMessage($userId,"订单支付成功",$message, 2); // 奖励消息 // if($userAwardWaitScore>0){ // $message = "您在{$dateTime}(UTC+8)成功支付{$payTotal}星豆完成购物,奖励{$userAwardWaitScore}待返积分已到账。"; // MessageService::make()->pushMessage($userId,"商城消费奖励",$message, 3); // } // // // // 算力奖励消息 // if($awardPowerNum>0){ // $message = "您在{$dateTime}(UTC+8)成功支付{$payTotal}星豆完成购物,奖励{$awardPowerNum}算力已到账。"; // MessageService::make()->pushMessage($userId,"商城消费奖励",$message, 3); // } // // // // 推荐奖励消息 // if($parentId>0 && $inviteAwardWaitScore>0){ // $message = "您推荐的用户【{$userId}】,在{$dateTime}(UTC+8)购物消费{$payTotal}星豆,奖励{$inviteAwardWaitScore}待返积分已到账。"; // MessageService::make()->pushMessage($parentId,"推荐用户商城消费奖励",$message, 3); // } DB::commit(); $this->error = 2910; return [ 'id'=> $orderId, 'total'=> $payTotal, 'pay_type'=> $payType, ]; }else{ // 下单成功订单通知 $message = "您在{$dateTime}(UTC+8)创建订单【{$orderNo}】成功,请尽快完成支付。"; MessageService::make()->pushMessage($userId,"订单创建成功",$message, 2); DB::commit(); $this->error = 2911; return [ 'id'=> $orderId, 'total'=> $payTotal, 'pay_type'=> $payType, ]; } } /** * 详情 * @param $id * @return mixed */ public function getInfo($id, $userId=0) { $where = [ 'a.mark' => 1]; if(intval($id) == $id){ $where['a.id'] = $id; }else{ $where['a.order_no'] = $id; } $info = $this->model->with(['goods']) ->from('orders as a') ->leftJoin('member as b', 'b.id', '=', 'a.user_id') ->where($where) ->select(['a.*', 'b.nickname', 'b.mobile as buy_mobile']) ->first(); if ($info) { $info['create_time_text'] = $info['create_time'] ? datetime($info['create_time'], 'Y-m-d H:i:s') : ''; $info['pay_time'] = $info['pay_time']? datetime($info['pay_time'], 'Y-m-d H:i:s') : ''; $info['mobile'] = isset($info['mobile'])? format_mobile($info['mobile']) : ''; if(isset($info['goods']) && $info['goods']){ foreach ($info['goods'] as &$item){ $item['main_img'] = $item['main_img']? get_image_url($item['main_img']) : ''; $item['sku_attr'] = $item['sku_attr']? json_decode($item['sku_attr'],true) :[]; } unset($item); } $payTypes = [10=>'星豆余额支付']; if(isset($info['pay_type'])){ $info['pay_text'] = isset($payTypes[$info['pay_type']])? $payTypes[$info['pay_type']] : '其他'; } $deliveryTypes = [1=>'快递配送']; if(isset($info['pay_type'])){ $info['delivery_text'] = isset($deliveryTypes[$info['delivery_type']])? $deliveryTypes[$info['delivery_type']] : '其他'; } } return $info; } public function pay($userId, $params) { } /** * 申请退款 * @param $userId * @param $params * @return bool */ public function refund($userId, $params) { $id = isset($params['id']) ? $params['id'] : 0; $goodsId = isset($params['goods_id']) ? $params['goods_id'] : 0; $refundType = isset($params['refund_type']) ? $params['refund_type'] : 0; $refundRemark = isset($params['remark']) ? $params['remark'] : ''; $info = $this->model->with(['goods'])->where(['id' => $id, 'mark' => 1]) ->select(['id','order_no','out_order_no','user_id','merch_id','pay_money','coupon_id','pay_status','status','refund_status','pay_time']) ->first(); $status = isset($info['status']) ? $info['status'] : 0; $orderNo = isset($info['order_no']) ? $info['order_no'] : ''; $outOrderNo = isset($info['out_order_no']) ? $info['out_order_no'] : ''; $orderUserId = isset($info['user_id']) ? $info['user_id'] : 0; $payStatus = isset($info['pay_status']) ? $info['pay_status'] : 0; $refundStatus = isset($info['refund_status']) ? $info['refund_status'] : 0; $goods = isset($info['goods']) ? $info['goods'] : []; if (!$id || empty($info)) { $this->error = 2912; return false; } // 非法操作 if($userId != $orderUserId){ $this->error = 2913; return false; } if(!in_array($status, [2,3])){ $this->error = 2914; return false; } if($refundStatus>0){ $this->error = 2915; return false; } if(!in_array($refundType,[1,2,3,4])){ $this->error = 2922; return false; } // 多商品退款暂不开放 if(count($goods)>1){ $this->error = 2920; return false; } // 订单商品 /*$orderGoodsIds = OrderGoodsModel::where(['order_no'=>$orderNo,'status'=>1,'mark'=>1])->pluck('goods_id'); $orderGoodsIds = $orderGoodsIds? $orderGoodsIds->toArray() : []; if(empty($orderGoodsIds) || ($goodsId && !in_array($goodsId, $orderGoodsIds))){ $this->error = 2904; return false; }*/ // 站外售后验证 $result = SupplyService::make()->getApiData('getAfterCan',['plat_order_no'=> $outOrderNo]); $orderGoods = isset($result['order_goods'])? $result['order_goods'] : []; $orderGoodsInfo = isset($orderGoods[0])? $orderGoods[0] : []; if(empty($orderGoods) || empty($orderGoodsInfo)){ $this->error = 2918; return false; } // 检查 $outRefundStatus = isset($orderGoodsInfo['status'])? $orderGoodsInfo['status'] : 0; if($outRefundStatus == 0){ $this->error = 2921; return false; } // 站外申请售后 $data = [ 'plat_order_no'=> $outOrderNo, 'goods_sku'=> isset($orderGoodsInfo['goods_sku'])? $orderGoodsInfo['goods_sku'] : '', 'after_num'=> isset($orderGoodsInfo['after_num'])? $orderGoodsInfo['after_num'] : 1, 'order_goods_id'=> isset($orderGoodsInfo['order_goods_id'])? $orderGoodsInfo['order_goods_id'] : 0, 'after_type'=> $refundType, 'explain'=> $refundRemark, ]; $result = SupplyService::make()->getApiData('applyAfter', $data); var_dump($result); // if($item['status'] == 0){ // $this->error = 2919; // return false; // } // 处理 // if(!$this->model->where(['id'=> $id,'mark'=>1])->update(['status'=> 5,'refund_status'=>1,'refund_type'=> $refundType,'refund_remark'=> $refundRemark,'refund_result'=>'','update_time'=>time()])){ // $this->error = 2917; // return false; // } $this->error = 2916; return true; } /** * 申请退款取消 * @param $userId * @param $params * @return bool */ public function refundCancel($userId, $params) { $id = isset($params['id']) ? $params['id'] : 0; $merchId = isset($params['merch_id']) ? $params['merch_id'] : 0; // 商家 $mechId = isset($params['mech_id']) ? $params['mech_id'] : 0; //技师 $info = $this->model->where(['id' => $id, 'mark' => 1]) ->select(['id','user_id','merch_id','pay_money','coupon_id','status','refund_status','refund_temp_status','pay_time']) ->first(); $status = isset($info['status']) ? $info['status'] : 0; $orderUserId = isset($info['user_id']) ? $info['user_id'] : 0; $orderMerchId = isset($info['merch_id']) ? $info['merch_id'] : 0; $orderMechId = isset($info['source_id']) ? $info['source_id'] : 0; $refundStatus = isset($info['refund_status']) ? $info['refund_status'] : 0; $tempStatus = isset($info['refund_temp_status']) ? $info['refund_temp_status'] : 0; if (!$id || empty($info)) { $this->error = 2656; return false; } var_dump($info); return false; // 非法操作 if($merchId != $orderMerchId && $userId != $orderUserId && $mechId != $orderMechId){ $this->error = 2667; return false; } if($status != 5){ $this->error = 2668; return false; } if($refundStatus<=0){ $this->error = 2669; return false; } // 处理 $updateData = ['status'=> $info['reception_at']? 3:2,'refund_status'=>0,'refund_remark'=> '','update_time'=>time()]; if(!$this->model->where(['id'=> $id,'mark'=>1])->update($updateData)){ $this->error = 2670; return false; } $this->error = 2671; return true; } /** * 收货/已完成 * @return bool */ public function complete($userId, $params) { $id = isset($params['id']) ? $params['id'] : 0; $merchId = isset($params['merch_id']) ? $params['merch_id'] : 0; $info = $this->model->with(['goods']) ->where(['id' => $id, 'mark' => 1]) ->select(['id','user_id','order_no','merch_id','source_id','city','pay_money','type','postage','reception_at','coupon_id','status','is_service','refund_status','pay_time']) ->first(); $status = isset($info['status']) ? $info['status'] : 0; $orderUserId = isset($info['user_id']) ? $info['user_id'] : 0; $orderMerchId = isset($info['merch_id']) ? $info['merch_id'] : 0; $orderMechId = isset($info['source_id']) ? $info['source_id'] : 0; $orderType = isset($info['type']) ? $info['type'] : 0; $payMoney = isset($info['pay_money']) ? $info['pay_money'] : 0; $goods = isset($info['goods'])? $info['goods'] : []; if (!$id || empty($info)) { $this->error = 2636; return false; } var_dump($info); return false; // 非法操作 if($userId && $merchId != $orderMerchId && $orderUserId != $userId){ $this->error = 2667; return false; } // 订单状态 if (($userId && $status != 3)||(!$userId && !in_array($status,[2,3]))) { $this->error = 2668; return false; } // 限制操作订单类型 if(!in_array($orderType, [1,2,6])){ $this->error = 2681; return false; } // TODO 确认数据处理 DB::beginTransaction(); // 更新订单状态 if (!$this->model->where(['id' => $id])->update(['status' => 4, 'update_time' => time()])) { DB::rollBack(); $this->error = 2678; return false; } // 更新商品/服务销量 if($goods){ foreach($goods as $item){ $num = isset($item['num'])? $item['num'] : 0; if($num>0){ GoodsModel::where(['id'=> $item['goods_id'],'mark'=>1])->update([ 'sales'=> DB::raw("sales + {$num}"),'update_time'=> time() ]); } } } // 服务订单统计处理 if($orderType == 2){ // 更新技师服务订单,接单统计数据 $serviceCount = $this->model->where(['user_id'=> $orderUserId,'source_id'=> $orderMechId,'type'=>2,'status'=>4,'mark'=>1])->count('id'); $updateData = ['order_total'=> DB::raw("order_total + 1"),'update_time'=>time()]; if($serviceCount<=1){ $updateData['service_num'] = DB::raw("service_num + 1"); } if($orderMechId && !MechanicModel::where(['id'=>$orderMechId,'mark'=> 1])->update($updateData)){ DB::rollBack(); $this->error = 2682; return false; } // 更新商家服务订单,统计数据 $updateData = ['service_order_num'=> DB::raw("service_order_num + 1"),'service_order_total'=> DB::raw("service_order_total + {$payMoney}"),'update_time'=>time()]; if($orderMechId && !MerchantModel::where(['id'=>$orderMerchId,'mark'=> 1])->update($updateData)){ DB::rollBack(); $this->error = 2682; return false; } } // 店内订单结算 $balance = MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->value('balance'); if ($orderType == 6){ // 商家入账 $settleRate = ConfigService::make()->getConfigByCode('merch_settle_rate'); $settleRate = $settleRate>0? min(100, $settleRate) : 100; $settleMoney = moneyFormat($payMoney * $settleRate/100, 2); $updateData = ['balance'=> DB::raw("balance + {$settleMoney}"),'update_time'=>time()]; if($settleMoney>0 && !MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2683; return false; } // 流水记录 $log = [ 'user_id'=> 0, 'merch_id'=> $orderMerchId, 'source_uid'=> $orderUserId, 'source_order_no'=> isset($info['order_no'])? $info['order_no'] :'', 'type'=> 3, 'coin_type'=> 2, 'user_type'=> 2, 'money'=> $settleMoney, 'balance'=>$balance? $balance : 0.00, 'create_time'=> time(), 'update_time'=> time(), 'remark'=> '商家店内订单收入', 'status'=>1, 'mark'=>1 ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2641; return false; } // 平台抽成入账,财务统计 $financeMoney = floatval($payMoney - $settleMoney); if($financeMoney>0){ $log = [ 'user_id'=> 0, 'merch_id'=> 0, 'source_uid'=> $orderUserId, 'source_order_no'=> $info['order_no'], 'type'=> 13, 'coin_type'=> 2, 'user_type'=> 5, 'money'=> $financeMoney, 'balance'=> 0, 'create_time'=> time(), 'update_time'=> time(), 'remark'=> '平台店内订单收入', 'status'=>1, 'mark'=>1 ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2641; return false; } FinanceService::make()->saveLog(0,$financeMoney, 1, 1); } } // 服务订单结算 else if(in_array($orderType, [1,2])){ // 计算服务订单分销佣金和代理佣金 if(!$result = FinanceService::make()->settleOrder($info, $userId)){ DB::rollBack(); $this->error = FinanceService::make()->getError(); return false; } // 商家入账 $settleMoney = isset($result['merch_money'])? $result['merch_money'] : 0; $updateData = [ 'balance'=> DB::raw("balance + {$settleMoney}"), 'service_order_num'=>DB::raw("service_order_num + 1"), 'service_order_total'=>DB::raw("service_order_total + {$payMoney}"), 'update_time'=>time() ]; if($settleMoney>0 && !MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2683; return false; } $log = [ 'user_id'=> 0, 'merch_id'=> $orderMerchId, 'source_uid'=> $orderUserId, 'source_order_no'=> isset($info['order_no'])? $info['order_no'] :'', 'type'=> 3, 'coin_type'=> 2, 'user_type'=> 2, 'money'=> $settleMoney, 'balance'=>$balance? $balance : 0.00, 'create_time'=> time(), 'update_time'=> time(), 'remark'=> '商家订单收入', 'status'=>1, 'mark'=>1 ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2641; return false; } // 平台入账,财务统计 $financeMoney = isset($result['platform_money'])? $result['platform_money'] : 0; if($financeMoney>0){ FinanceService::make()->saveLog(0,$financeMoney, 1, 1); } $log = [ 'user_id'=> 0, 'merch_id'=> 0, 'source_uid'=> $orderUserId, 'source_order_no'=> isset($info['order_no'])? $info['order_no'] :'', 'type'=> 13, 'coin_type'=> 2, 'user_type'=> 5, 'money'=> $financeMoney, 'balance'=> 0, 'create_time'=> time(), 'update_time'=> time(), 'remark'=> '平台订单收入', 'status'=>1, 'mark'=>1 ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = 2641; return false; } // 技师累计 if($orderMechId){ $updateData = [ 'order_total'=> DB::raw("order_total + 1"), 'service_num'=>DB::raw("service_num + 1"), 'update_time'=>time() ]; MechanicModel::where(['id'=> $orderMechId,'mark'=>1])->update($updateData); } } // 消息推送 $params = [ 'title' => "订单完成通知", 'body' => "您的订单已完成,请即时查看进度并给予评论", 'type' => 2, // 1-公告通知,2-订单通知,3-交易通知,4-其他 'content' => [ 'order_no' => ['name' => '订单号', 'text' => $info['order_no']], 'time' => ['name' => '下单时间', 'text' => $info['pay_time']], 'picker_time' => ['name' => '确认时间', 'text' => date('Y-m-d H:i:s')], 'mechanic' => [], 'money' => ['name' => '订单金额', 'text' => $info['pay_money']], 'status' => ['name' => '状态', 'text' => '已完成'], ], 'click_type' => 'payload', 'url' => '/pages/order/detail?id=' . $id, ]; $mechanic = isset($info['mechanic'])? $info['mechanic'] : []; $code = isset($mechanic['code'])? $mechanic['code'] : ''; if($code){ $params['content']['mechanic'] = ['name' => '服务技师', 'text' => "{$code}号技师"]; } if(!PushService::make()->pushMessageByUser($info['user_id'], $params, 0)){ DB::rollBack(); $this->error = PushService::make()->getError(); return false; } DB::commit(); $this->error = 1002; return true; } /** * 隐藏删除 * @return false */ public function hide($userId, $params) { $id = isset($params['id']) ? $params['id'] : 0; $info = $this->model->where(['id' => $id, 'mark' => 1]) ->select(['id','user_id','order_no','status','is_hide']) ->first(); if (!$id || empty($info)) { $this->error = 2912; return false; } $isHide = isset($info['is_hide'])? $info['is_hide'] : 0; if($isHide >0){ $this->error = 2914; return false; } if($this->model->where(['id'=> $id])->update(['is_hide'=>2,'update_time'=>time()])) { $this->error = 1002; return true; }else{ $this->error = 1003; return false; } } }