wesmiler 3 месяцев назад
Родитель
Сommit
f1f0e2a32f

+ 45 - 0
app/Console/Commands/SwooleTask.php

@@ -2,6 +2,7 @@
 
 namespace App\Console\Commands;
 
+use App\Services\Api\OrderService;
 use App\Services\Common\PayOrdersService;
 use App\Services\RedisService;
 use Illuminate\Console\Command;
@@ -250,6 +251,32 @@ class SwooleTask extends Command
             }
         });
 
+        // 订单自动收货
+        \swoole_timer_tick(10000, function ($timer) use ($serv, &$time) { // 启用定时器,每10秒执行一次
+            $date = date('Y-m-d H:i:s');
+            $orders = OrderService::make()->getCompleteOrders();
+            if($orders){
+                foreach ($orders as $k => $item){
+                    $orderNo = isset($item['order_no'])?$item['order_no'] : '';
+                    if(!RedisService::get('caches:task:lock:order_complete_loaded_'.$orderNo)){
+                        $taskData = [
+                            'taskName' => 'completeOrder',
+                            'name' => "购物订单自动收货处理",
+                            'date' => date('Y-m-d'),
+                            'params'=> $item,
+                        ];
+                        $res = $serv->task($taskData);
+                        RedisService::set('caches:task:lock:order_complete_loaded_'.$k, true, rand(3,5));
+                        echo "[Task completeOrder {$date}] 购物订单【{$orderNo}】自动收货处理结果:{$res}\n";
+                    }else{
+                        echo "[Task completeOrder {$date}] 购物订单【{$orderNo}】自动收货处理间隔时间调用\n";
+                    }
+                }
+            }else{
+                echo "[Task completeOrder {$date}] 暂无可自动收货的购物订单\n";
+            }
+        });
+
     }
 
     //监听连接进入事件
@@ -293,6 +320,24 @@ class SwooleTask extends Command
                         echo "[Task {$taskName} {$date}][{$task_id}] 充值订单状态更新处理结果:{$error}\n";
                     }
                     break;
+                case 'completeOrder': // 自动收货
+                    $orderId = isset($params['id'])? $params['id'] : 0;
+                    $orderNo = isset($params['order_no'])? $params['order_no'] : '';
+                    $userId = isset($params['user_id'])? $params['user_id'] : 0;
+                    if($orderId<=0 || $userId<=0){
+                        echo "[Task {$taskName} {$date}][{$task_id}] 该购物订单参数错误\n";
+                        return false;
+                    }
+                    // 调用处理
+                    if($res = OrderService::make()->complete($userId, $orderId, false)){
+                        $res = is_array($res) && $res? json_encode($res, 256) : 'success';
+                        echo "[Task {$taskName} {$date}][{$task_id}] 购物订单【{$orderNo}】自动收货处理结果:{$res}\n";
+                    }else{
+                        $error = OrderService::make()->getError();
+                        $error = $error? lang($error) : 'failed';
+                        echo "[Task {$taskName} {$date}][{$task_id}] 购物订单【{$orderNo}】自动收货处理结果:{$error}\n";
+                    }
+                    break;
             }
         } catch(\Exception $exception){
             return $exception->getMessage();

+ 1 - 0
app/Models/GoodsModel.php

@@ -77,6 +77,7 @@ class GoodsModel extends BaseModel
     {
         return $this->hasMany(GoodsSkuModel::class, 'goods_id', 'id')
             ->where(['mark' => 1, 'status' => 1])
+            ->where('stock','>', 0)
             ->orderBy('sort', 'desc');
     }
 }

+ 26 - 1
app/Services/Api/AccountService.php

@@ -250,6 +250,11 @@ class AccountService extends BaseService
     {
         $mealId = isset($params['id']) ? $params['id'] : 0; // 套餐ID
         $account = isset($params['account']) ? $params['account'] : ''; // 充值账号/手机号
+        $electricType = isset($params['electric_type']) ? intval($params['electric_type']) : 0; // 电费充值类型
+        $ytype = isset($params['ytype']) ? intval($params['ytype']) : 1; // 电费充值:三要素验证,1-身份证后6位,2-银行卡后六位,3-营业执照后六位
+        $area = isset($params['area']) ? trim($params['area']) : ''; // 电费充值:省份/直辖市
+        $idCardNo = isset($params['id_card_no']) ? trim($params['id_card_no']) : ''; // 电费充值:三要素验证,身份证后6位/银行卡后6位/营业执照后6位
+        $city = isset($params['city']) ? trim($params['city']) : ''; // 电费充值:地级市名
         $cacheKey = "caches:members:pay:{$userId}_{$mealId}";
         if (RedisService::get($cacheKey . '_lock')) {
             $this->error = '请不要频繁提交~';
@@ -269,7 +274,6 @@ class AccountService extends BaseService
         $discount = isset($mealInfo['discount']) ? intval($mealInfo['discount']) : 0;
         $mealType = isset($mealInfo['type']) && $mealInfo['type'] ? intval($mealInfo['type']) : 1;
         $productId= isset($mealInfo['product_id']) ? $mealInfo['product_id'] : 0;
-        $remark= isset($mealInfo['remark']) ? $mealInfo['remark'] : '';
         $price = $discount?moneyFormat($money*$discount/100,2): $money;
         if (empty($mealInfo)) {
             $this->error = '该套餐不存在';
@@ -283,6 +287,27 @@ class AccountService extends BaseService
             return false;
         }
 
+        // 电费验证
+        if($mealType==2){
+            if(empty($area)){
+                $this->error = '请选择省份/直辖市';
+                RedisService::clear($cacheKey . '_lock');
+                return false;
+            }
+
+            if(empty($idCardNo)){
+                $this->error = "请填写".(['验证参数','身份证后6位','银行卡后6位','营业执照后6位'][$ytype]);
+                RedisService::clear($cacheKey . '_lock');
+                return false;
+            }
+
+            if(empty($city)){
+                $this->error = '请选择地级市名';
+                RedisService::clear($cacheKey . '_lock');
+                return false;
+            }
+        }
+
         $info = MemberModel::where(['id' => $userId, 'mark' => 1])
             ->select(['id', 'openid', 'mobile', 'status'])
             ->first();

+ 16 - 4
app/Services/Api/GoodsService.php

@@ -223,29 +223,41 @@ class GoodsService extends BaseService
             ->get();
         $list = $list? $list->toArray() : [];
         if($list){
-            $skus = GoodsSkuModel::whereIn('goods_id', $ids)->select(['id','price','stock'])->get()->keyBy('id');
+            $skus = GoodsSkuModel::whereIn('goods_id', $ids)->select(['id','sku_name','price','stock'])->get()->keyBy('id');
             $skus = $skus?$skus->toArray() :[];
             $result = ['store_id'=>0,'total'=>0,'count'=>0,'goods'=>[]];
-//            var_dump($skus);
-//            var_dump($list);
-//            var_dump($goods);
             foreach ($list as $item){
                 $item['order_no'] = $orderNo;
                 $id = isset($item['goods_id'])?$item['goods_id']:0;
+                $goodsName = isset($item['goods_name'])?$item['goods_name']:'';
                 $params = isset($goods['id_'.$id])? $goods['id_'.$id]:[];
                 $goodsId = isset($params['id'])?$params['id']:0;
                 $storeId = isset($item['store_id'])?$item['store_id']:0;
+                $stock = isset($item['stock'])?$item['stock']:0;
                 $num = isset($params['num'])?$params['num']:0;
                 $skuId = isset($params['sku_id'])?$params['sku_id']:0;
                 $skuType = isset($item['sku_type'])?$item['sku_type']: 1;
                 $skuData = isset($skus[$skuId])? $skus[$skuId]:[];
                 $skuPrice = isset($skuData['price'])?$skuData['price']:0;
+                $skuStock = isset($skuData['stock'])?$skuData['stock']:0;
+                $skuName = isset($skuData['sku_name'])?$skuData['sku_name']:'';
                 $price = $skuType==2 ? $skuPrice : $item['price'];
                 unset($item['skus']);
                 if($result['store_id'] && $storeId != $result['store_id']){
                     $this->error = '一次只能购买同一个商家的商品,请核对后重试~';
                     return false;
                 }
+
+                if($stock<=0 || $num>$stock){
+                    $this->error = "商品[{$goodsName}]库存不足~";
+                    return false;
+                }
+
+                if($skuStock<=0 || $num>$skuStock){
+                    $this->error = "商品[{$goodsName}]规格[{$skuName}]库存不足~";
+                    return false;
+                }
+
                 if($num>0 && $goodsId == $id && $price>0){
                     $result['store_id'] = $storeId;
                     $item['user_id'] = $userId;

+ 89 - 4
app/Services/Api/OrderService.php

@@ -13,6 +13,7 @@ namespace App\Services\Api;
 
 use App\Models\CartModel;
 use App\Models\GoodsModel;
+use App\Models\GoodsSkuModel;
 use App\Models\MemberModel;
 use App\Models\OrderGoodsModel;
 use App\Models\OrderModel;
@@ -333,12 +334,35 @@ class OrderService extends BaseService
             return false;
         }
 
+        // 商品库存扣除
+        if($orderGoods){
+            foreach($orderGoods as $goods){
+                $id = isset($goods['goods_id'])?$goods['goods_id']:0;
+                $num = isset($goods['num'])?$goods['num']:0;
+                $skuId = isset($goods['sku_id'])?$goods['sku_id']:0;
+                if($id && !GoodsModel::where(['id'=>$id])->update(['stock'=>DB::raw("stock - {$num}"),'update_time'=>time()])){
+                    DB::rollBack();
+                    RedisService::clear($cacheLockKey);
+                    $this->error = '商品库存处理失败';
+                    return false;
+                }
+
+                if($skuId && !GoodsSkuModel::where(['id'=>$skuId])->update(['stock'=>DB::raw("stock - {$num}"),'update_time'=>time()])){
+                    DB::rollBack();
+                    RedisService::clear($cacheLockKey);
+                    $this->error = '商品库存处理失败';
+                    return false;
+                }
+            }
+        }
+
         // 清空购物车结算商品
         if($submitType == 'cart'){
             CartModel::whereIn('goods_id',$ids)->whereIn('sku_id',$skuIds)->where(['user_id'=>$userId,'mark'=>1])->update(['mark'=>0,'num'=>0,'update_time'=>time()]);
             RedisService::clear("caches:goods:cartCount:{$userId}");
         }
 
+
         // 用户操作记录
         DB::commit();
         $this->error = '订单创建成功,请前往支付~';
@@ -493,10 +517,35 @@ class OrderService extends BaseService
             RedisService::clear($cacheLockKey);
             return false;
         }
+        $orderGoods = OrderGoodsModel::where(['order_no'=> $orderNo,'mark'])
+            ->select(['goods_id','num','sku_id'])
+            ->get();
+        DB::beginTransaction();
+        if($orderGoods){
+            foreach($orderGoods as $goods){
+                $id = isset($goods['goods_id'])?$goods['goods_id']:0;
+                $num = isset($goods['num'])?$goods['num']:0;
+                $skuId = isset($goods['sku_id'])?$goods['sku_id']:0;
+                if($id && !GoodsModel::where(['id'=>$id])->update(['stock'=>DB::raw("stock + {$num}"),'update_time'=>time()])){
+                    DB::rollBack();
+                    RedisService::clear($cacheLockKey);
+                    $this->error = '商品库存处理失败';
+                    return false;
+                }
+
+                if($skuId && !GoodsSkuModel::where(['id'=>$skuId])->update(['stock'=>DB::raw("stock + {$num}"),'update_time'=>time()])){
+                    DB::rollBack();
+                    RedisService::clear($cacheLockKey);
+                    $this->error = '商品库存处理失败';
+                    return false;
+                }
+            }
+        }
 
         $this->error = '取消订单成功';
         $this->model->where(['user_id' => $userId, 'mark' => 0])->where('update_time', '<=', time() - 300)->delete();
         $this->model->where(['id' => $id])->update(['mark' => 0, 'update_time' => time()]);
+        DB::commit();
         return ['id' => $id];
     }
 
@@ -506,7 +555,7 @@ class OrderService extends BaseService
      * @param $id 订单ID
      * @return array|false
      */
-    public function complete($userId, $id)
+    public function complete($userId, $id, $check= true)
     {
         if ($id <= 0) {
             $this->error = '请选择订单';
@@ -529,7 +578,7 @@ class OrderService extends BaseService
             ->first();
         $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
         $parentId = isset($userInfo['parent_id']) ? $userInfo['parent_id'] : 0;
-        if (empty($userInfo) || $status != 1) {
+        if ($check && (empty($userInfo) || $status != 1)) {
             $this->error = 1045;
             RedisService::clear($cacheLockKey);
             return false;
@@ -542,7 +591,6 @@ class OrderService extends BaseService
         $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
         $deliveryNo = isset($info['delivery_no']) ? $info['delivery_no'] : '';
         $deliverCompany = isset($info['delivery_company']) ? $info['delivery_company'] : '';
-        $deliverCode = isset($info['delivery_code']) ? $info['delivery_code'] : '';
         $storeId = isset($info['store_id']) ? $info['store_id'] : 0;
         $orderTotal = isset($info['pay_total']) ? $info['pay_total'] : 0;
         $bonus = isset($info['bonus']) ? $info['bonus'] : 0;
@@ -563,12 +611,19 @@ class OrderService extends BaseService
 
         if (empty($deliveryNo) || empty($deliverCompany)) {
             $this->error = '订单发货信息错误,请联系客服';
+            $this->model->where(['id'=>$id])->update(['is_complete'=>1,'complete_remark'=>$this->error]);
+            RedisService::clear("caches:orders:completeList");
             RedisService::clear($cacheLockKey);
             return false;
         }
 
         DB::beginTransaction();
-        $this->model->where(['id' => $id])->update(['status' => 4, 'update_time' => time()]);
+        $updateData = ['status' => 4, 'update_time' => time()];
+        if(!$check){
+            $updateData['is_complete'] = 1;
+            $updateData['complete_remark'] = '自动收货';
+        }
+        $this->model->where(['id' => $id])->update($updateData);
 
         // 商家订单数据统计
         $updateData = ['order_count' => DB::raw('order_count+1'), 'order_total' => DB::raw("order_total + {$orderTotal}")];
@@ -610,6 +665,7 @@ class OrderService extends BaseService
         DB::commit();
 
         $this->error = '确认收货成功';
+        RedisService::clear("caches:orders:completeList");
         return ['id' => $id];
     }
 
@@ -893,4 +949,33 @@ class OrderService extends BaseService
         return $data;
 
     }
+
+    /**
+     * 已发货待完成订单
+     * @return array|mixed
+     */
+    public function getCompleteOrders()
+    {
+        $cacheKey = "caches:orders:completeList";
+        $datas = RedisService::get($cacheKey);
+        if($datas){
+            return $datas;
+        }
+
+        $completeDay = ConfigService::make()->getConfigByCode('order_complete_day',7);
+        $limitNum = ConfigService::make()->getConfigByCode('order_complete_batch_num',300);
+        $limitNum = $limitNum>10 && $limitNum<2000? $limitNum : 300;
+        $completeDay = $completeDay>=1 && $completeDay<30? $completeDay : 7;
+        $datas = $this->model->where(['status'=>3,'is_complete'=>2,'mark'=>1])
+            ->select(['id','user_id','order_no','status'])
+            ->where('pay_at','<=', date('Y-m-d H:i:s', time() - $completeDay * 86400))
+            ->limit($limitNum)
+            ->get();
+        $datas = $datas?$datas->toArray() : [];
+        if($datas){
+            RedisService::set($cacheKey, $datas, rand(300, 600));
+        }
+
+        return $datas;
+    }
 }

+ 2 - 2
app/Services/Api/StoreService.php

@@ -157,7 +157,7 @@ class StoreService extends BaseService
      */
     public function getStoreId($userId)
     {
-        $cacheKey = "caches:storeId:id_{$userId}";
+        $cacheKey = "caches:stores:storeId:id_{$userId}";
         $data = RedisService::get($cacheKey);
         if($data){
             return $data;
@@ -198,7 +198,7 @@ class StoreService extends BaseService
         $system = isset($params['system']) ? $params['system'] : [];
         $system = $system && !is_array($system) ? json_decode($system, true) : $system;
         $uuid = isset($system['uuid']) ? $system['uuid'] : '';
-        $uuKey = "caches:storeId:uu_{$uuid}";
+        $uuKey = "caches:stores:storeId:uu_{$uuid}";
         if($parentStoreInfo && $storeId>0){
             RedisService::set($cacheKey, $storeId, 7 * 86400);
             RedisService::set($uuKey, $storeId, 7 * 86400);