1
0

82 Commits 0b8f230417 ... 586d80c8d6

Autor SHA1 Nachricht Datum
  gorden 586d80c8d6 自定义打印 vor 1 Monat
  gorden 1507749d62 去掉会员升级 vor 1 Monat
  Gorden 0f5d5aefbd 周期券 vor 1 Monat
  Gorden 52c2d8dcb4 周期券 vor 1 Monat
  gorden 3b220eabe9 拆单 vor 1 Monat
  gorden 1eca13279f 拆单 vor 1 Monat
  gorden d97d3c084f 拆单 vor 1 Monat
  gorden 4d49ee85f9 拆单 vor 1 Monat
  gorden 42d9e3958e 拆单 vor 1 Monat
  gorden b72849263e 打印 vor 1 Monat
  gorden b9ec753d16 打印 vor 1 Monat
  gorden 0fa98a0537 打印 vor 1 Monat
  gorden 559e690c4c 打印 vor 1 Monat
  gorden 05aaf13bcb 打印 vor 1 Monat
  gorden dc1a783a20 打印 vor 1 Monat
  gorden 21f2d9986c 打印 vor 1 Monat
  gorden 8abec3e96a 打印 vor 1 Monat
  gorden b926b05ef1 打印 vor 1 Monat
  gorden 34d4bef183 打印 vor 1 Monat
  gorden 90cfb6ad90 合伙人充值 vor 1 Monat
  gorden dd7179ef12 合伙人充值 vor 1 Monat
  gorden fef033d992 消费提成 vor 1 Monat
  gorden cf80b063ee 会员信息 vor 1 Monat
  gorden 369b2c222d 拆单 vor 1 Monat
  Gorden b01292ef88 重置订单GROUP vor 1 Monat
  Gorden b8d99b44c7 拆单 vor 1 Monat
  Gorden 04a37098c8 拆单 vor 1 Monat
  Gorden 0161643d88 拆单 vor 1 Monat
  Gorden 09d18d2310 拆单 vor 1 Monat
  Gorden fd64116702 会员生日 vor 1 Monat
  gorden f3c26d155b 拆单 vor 1 Monat
  gorden 4db9410994 拆单 vor 1 Monat
  gorden 13a8405f33 全额退款退券 vor 1 Monat
  gorden 399fd2411b 全额退款退券 vor 1 Monat
  gorden 022f162ba2 全额退款退券 vor 1 Monat
  gorden 2417c2ceae 全额退款退券 vor 1 Monat
  gorden 24ed70c217 全额退款退券 vor 1 Monat
  gorden 18701328db 全额退款退券 vor 1 Monat
  gorden d5d5369a4a 全额退款退券 vor 1 Monat
  gorden ba09f50b84 全额退款退券 vor 1 Monat
  gorden ceafeabeab 全额退款退券 vor 1 Monat
  gorden 6d58aa1aa0 拆单+打印 vor 1 Monat
  gorden 21c217cd88 拆单+打印 vor 1 Monat
  gorden 8e900ff079 拆单+打印 vor 1 Monat
  gorden 93b166fe14 拆单+打印 vor 1 Monat
  gorden 3fcda0f814 拆单+打印 vor 1 Monat
  gorden b7af418913 拆单+打印 vor 1 Monat
  gorden 3e17831aea 拆单+打印 vor 1 Monat
  gorden 3b466b0796 拆单+打印 vor 1 Monat
  gorden 510bb02417 拆单+打印 vor 1 Monat
  gorden e2569c309b 拆单+打印 vor 1 Monat
  gorden 86bd1ce90a 拆单+打印 vor 1 Monat
  gorden d8278c6bc0 拆单+打印 vor 1 Monat
  gorden 1f2683115b 拆单+打印 vor 1 Monat
  gorden 36f218d656 拆单+打印 vor 1 Monat
  gorden 3bf42411df 拆单+打印 vor 1 Monat
  gorden 4bbec5188c 拆单+打印 vor 1 Monat
  gorden 71f6f0d5af 拆单+打印 vor 1 Monat
  gorden 6f0be0d786 拆单+打印 vor 1 Monat
  Gorden e79c9f1ae9 订单打印 vor 2 Monaten
  gorden d2dae5f578 拆单+打印 vor 2 Monaten
  gorden d7ab255424 Merge branch 'master' into dev vor 2 Monaten
  gorden 729765b6f8 产品搜索只保留搜索名称 vor 2 Monaten
  gorden 0f59fca968 Merge branch 'master' into dev vor 2 Monaten
  gorden 539673cf2c 产品搜索只保留搜索名称 vor 2 Monaten
  gorden 3bde0d7ccc Merge branch 'master' into dev vor 2 Monaten
  gorden 975d488d71 产品搜索只保留搜索名称 vor 2 Monaten
  gorden df9cf766d7 订单逻辑修改 vor 2 Monaten
  Gorden 36657a3363 优惠券商品去掉老规格 vor 2 Monaten
  Gorden 15e47bd1de 订单支付 vor 2 Monaten
  gorden 54006fc8f1 完善页面功能 vor 2 Monaten
  gorden b22ee669e1 退款到福利账户、VIP账户 vor 2 Monaten
  gorden b2dda52796 卡券调整 vor 2 Monaten
  gorden 140d74f9ba 卡券调整 vor 2 Monaten
  gorden 63d157501d 序列搜索 vor 2 Monaten
  gorden 768456a8d5 会员身份 vor 2 Monaten
  gorden 77b263b441 控制台退款金额 vor 2 Monaten
  gorden a8daaaca51 积分管理 vor 2 Monaten
  gorden 5d30385026 Merge branch 'master' into dev vor 2 Monaten
  gorden 37746bc6f1 福利账户清零功能 vor 2 Monaten
  gorden e0ab9eb944 福利账户清零功能 vor 2 Monaten
  gorden ec21ce495d 页面调整 vor 2 Monaten
35 geänderte Dateien mit 9536 neuen und 187 gelöschten Zeilen
  1. 1 1
      app/admin/controller/client/EvaluateController.php
  2. 16 0
      app/admin/controller/client/PointsController.php
  3. 45 22
      app/admin/controller/coupon/CouponController.php
  4. 14 0
      app/admin/controller/coupon/CouponPacketSequenceController.php
  5. 1 0
      app/admin/controller/device/DeviceController.php
  6. 29 1
      app/admin/controller/member/MemberController.php
  7. 5 4
      app/admin/controller/member/WriteOffController.php
  8. 22 21
      app/admin/controller/notify/RechargeController.php
  9. 2209 1
      app/admin/controller/order/GoodsController.php
  10. 12 9
      app/admin/controller/order/KangyangCityController.php
  11. 2377 7
      app/admin/controller/order/PackagesController.php
  12. 1097 0
      app/admin/controller/order/PartnerController.php
  13. 7 2
      app/admin/controller/order/PayDetailController.php
  14. 79 9
      app/admin/controller/order/RefundController.php
  15. 2402 14
      app/admin/controller/order/ServicesController.php
  16. 513 39
      app/admin/controller/order/WholeController.php
  17. 44 0
      app/admin/controller/sys_manage/ConfigController.php
  18. 22 0
      app/admin/controller/sys_manage/DeptController.php
  19. 20 0
      app/admin/service/coupon/CouponDetailService.php
  20. 27 8
      app/admin/service/coupon/CouponService.php
  21. 28 9
      app/admin/service/goods/GoodsService.php
  22. 245 17
      app/admin/service/member/MemberService.php
  23. 3 1
      app/admin/service/order/AppointmentService.php
  24. 28 2
      app/admin/service/order/OrderService.php
  25. 1 2
      app/admin/service/statistics/OrderService.php
  26. 5 1
      app/event/MemberLevelEvent.php
  27. 127 0
      app/event/order/CommissionEvent.php
  28. 1 1
      app/event/order/OrderProcessEvent.php
  29. 82 0
      app/event/order/PartnerEvent.php
  30. 3 0
      app/functions.php
  31. 19 0
      app/model/MemberAccountList.php
  32. 8 6
      app/model/OrderSheet.php
  33. 9 3
      config/event.php
  34. 2 0
      process/Task.php
  35. 33 7
      route/admin.php

+ 1 - 1
app/admin/controller/client/EvaluateController.php

@@ -154,7 +154,7 @@ class EvaluateController extends Curd
 
         if (!empty($evaluate->info)){
             $evaluate->info->member_info_headimg = $evaluate->info->member_info_headimg ?? getenv('STORAGE_DOMAIN').'/images/avatar_default.png';
-            $evaluate->info->member_info_nickname ?? substr($evaluate->member->member_mobile,-4).'用户';
+            $evaluate->info->member_info_nickname ?? substr($evaluate->member->member_mobile,-4).'会员';
         }
         if (!empty($evaluate->goods)){
             $evaluate->goods->goods_cover = getenv('STORAGE_DOMAIN').$evaluate->goods->goods_cover;

+ 16 - 0
app/admin/controller/client/PointsController.php

@@ -72,4 +72,20 @@ class PointsController extends Curd
         }
         return $model;
     }
+
+    /**
+     * @Desc 积分详情
+     * @Author Gorden
+     * @Date 2024/9/19 18:16
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function info(Request $request): Response
+    {
+        $pointsId = $request->get('points_id');
+        if (!$pointsId){
+            return json_fail('参数异常');
+        }
+    }
 }

+ 45 - 22
app/admin/controller/coupon/CouponController.php

@@ -307,7 +307,7 @@ class CouponController extends Curd
 
         // 处理周期优惠券
         if ($params['coupon_is_period'] != 'N') {
-            $this->disposePeriod($params);
+//            $this->disposePeriod($params);
             $data['coupon_period_json'] = json_encode([
                 'length' => $params['period'],
                 'unit' => $params['period_unit'],
@@ -328,9 +328,9 @@ class CouponController extends Curd
         if ($params['period'] != 'TO_EXPIRE') {
             return $params;
         }
-        if (empty($params['coupon_validdate_end'])) {
-            throw new BusinessException("周期数据异常");
-        }
+//        if (empty($params['coupon_validdate_end'])) {
+//            throw new BusinessException("周期数据异常");
+//        }
         try {
             $endTimeUnix = strtotime($params['coupon_validdate_end']);
             if ($params['period_unit'] == 'day') {
@@ -352,7 +352,7 @@ class CouponController extends Curd
             return $params;
         } catch (\Exception $e) {
 
-            throw new BusinessException("周期数据异常");
+            throw new BusinessException($e->getMessage());
         }
     }
 
@@ -403,41 +403,46 @@ class CouponController extends Curd
                                     $val = $periodJson['val'] - 1;
                                     if ($val < 1) {
                                         $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59');
-                                    }else{
-                                        $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59',strtotime("+".$val." day"));
+                                    } else {
+                                        $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime("+" . $val . " day"));
                                     }
                                 } elseif ($periodJson['unit'] == 'week') {
                                     $val = $periodJson['val'] - 1;
-                                    if ($val < 1){
+                                    if ($val < 1) {
                                         $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime('this week Sunday'));
-                                    }else{
-                                        $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59',strtotime("+".$val.' week',date('Y-m-d',strtotime("+".$val." month"))));
+                                    } else {
+                                        $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime("+" . $val . ' week', date('Y-m-d', strtotime("+" . $val . " month"))));
                                     }
-                                } elseif ($periodJson['unit'] == 'month'){
+                                } elseif ($periodJson['unit'] == 'month') {
                                     $val = $periodJson['val'] - 1;
-                                    if ($val < 1){
+                                    if ($val < 1) {
                                         $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59');
-                                    }else{
-                                        $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59',strtotime("+".$val." month"));
+                                    } else {
+                                        $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime("+" . $val . " month"));
                                     }
                                 }
                             }
                             if ($chooseCoupon['nbr'] > 0) {
                                 // 有发行数量
                                 if ($coupon['coupon_number'] != 0) {
-                                    // 查询共发行了多少张了
-                                    $count = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])->count();
+                                    // 查询还有多少张没领的
+                                    $count = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
+                                        ->whereIn('coupon_detail_status',['INIT','PENDING'])
+                                        ->count();
                                     if (!isset($couponNbr[$coupon['coupon_id']])) {
                                         $couponNbr[$coupon['coupon_id']] = $count;
                                     }
-                                    if ($couponNbr[$coupon['coupon_id']] + $chooseCoupon['nbr'] > $coupon['coupon_number']) {
+                                    if ($couponNbr[$coupon['coupon_id']] - $chooseCoupon['nbr'] < 0) {
                                         throw new BusinessException($coupon['coupon_name'] . "超出发行数量");
                                     }
-                                    $couponNbr[$coupon['coupon_id']] = $couponNbr[$coupon['coupon_id']] + $chooseCoupon['nbr'];
-                                }
-
-                                for ($i = 0; $i < $chooseCoupon['nbr']; $i++) {
-                                    CouponDetailService::customSendCoupon($params);
+                                    $couponNbr[$coupon['coupon_id']] = $couponNbr[$coupon['coupon_id']] - $chooseCoupon['nbr'];
+                                    $params['chooseCouponNbr'] = $chooseCoupon['nbr'];
+                                    // 匹配已发行的优惠券
+                                    CouponDetailService::customSendCouponHave($params);
+                                }else{
+                                    for ($i = 0; $i < $chooseCoupon['nbr']; $i++) {
+                                        CouponDetailService::customSendCoupon($params);
+                                    }
                                 }
                             }
                         }
@@ -852,6 +857,24 @@ class CouponController extends Curd
         }
     }
 
+    public function disableCoupon(Request $request)
+    {
+        $couponId = $request->post('coupon_id');
+        if (!$couponId){
+            return json_fail("参数异常");
+        }
+        Db::beginTransaction();
+        try {
+            Coupon::where('coupon_id',$couponId)->update(['coupon_status'=>'DISABLED']);
+            CouponDetail::where('join_detail_coupon_id',$couponId)->whereIn('coupon_detail_status',['INIT','PENDING'])->update(['coupon_detail_status'=>'DISABLED']);
+            Db::commit();
+            return json_success('success');
+        }catch (\Exception $e){
+            Db::rollBack();
+            return json_fail("禁用失败");
+        }
+    }
+
     private function generateCouponDetail($couponId, $couponStatus, $nbr)
     {
         for ($i = 0; $i < intval($nbr); $i++) {

+ 14 - 0
app/admin/controller/coupon/CouponPacketSequenceController.php

@@ -41,6 +41,13 @@ class CouponPacketSequenceController extends Curd
 
             $where['coupon_packet_sequence_addtimes'] = $addTimes;
         }
+        $usedTime = $request->get('coupon_packet_sequence_used_datetime', []);
+        if (!empty($usedTime)) {
+            $usedTime[0] = isset($usedTime[0]) ? strtotime($usedTime[0]) : time();
+            $usedTime[1] = isset($usedTime[1]) ? strtotime($usedTime[1]) : time();
+
+            $where['coupon_packet_sequence_used_datetime'] = $usedTime;
+        }
 
         $query = $this->doSelect($where, $field, $order);
         return $this->doFormat($query, $format, $limit);
@@ -48,6 +55,10 @@ class CouponPacketSequenceController extends Curd
 
     protected function doSelect(array $where, string $field = null, string $order = 'desc')
     {
+        if (!empty($where['coupon_packet_sequence_used_datetime'])) {
+            $usedTime = $where['coupon_packet_sequence_used_datetime'];
+            unset($where['coupon_packet_sequence_used_datetime']);
+        }
         $model = $this->model->with([
             'packet' => function ($query) {
                 $query->select('coupon_packet_id', 'coupon_packet_name');
@@ -91,6 +102,9 @@ class CouponPacketSequenceController extends Curd
                 $model = $model->where($column, $value);
             }
         }
+        if (!empty($usedTime)) {
+            $model = $model->whereRaw("UNIX_TIMESTAMP(coupon_packet_sequence_used_datetime) >= ? AND UNIX_TIMESTAMP(coupon_packet_sequence_used_datetime) <= ?", [$usedTime[0], $usedTime[1]]);
+        }
 //        $model = $model->selectRaw('join_detail_coupon_id,join_coupon_detail_member_id,MAX(coupon_detail_addtimes) as coupon_detail_addtimes,COUNT(*) as total');
 //        $model = $model->groupBy('join_coupon_detail_member_id', 'join_detail_coupon_id');
         if ($field) {

+ 1 - 0
app/admin/controller/device/DeviceController.php

@@ -5,6 +5,7 @@ namespace app\admin\controller\device;
 use app\admin\validate\device\DeviceValidate;
 use app\controller\Curd;
 use app\model\Device;
+use app\model\SysDept;
 use app\model\SysSerial;
 use support\exception\BusinessException;
 use support\Request;

+ 29 - 1
app/admin/controller/member/MemberController.php

@@ -370,7 +370,7 @@ class MemberController
 
     public function welfareInfo(Request $request)
     {
-        $memberId = $request->get('member_id', '');
+        $memberId = $request->get('member_id');
         if (!$memberId) {
             return json_fail("参数错误");
         }
@@ -378,6 +378,34 @@ class MemberController
         return MemberService::welfareInfo($request);
     }
 
+    /**
+     * @Desc 我的粉丝列表
+     * @Author Gorden
+     * @Date 2024/9/20 10:22
+     *
+     * @param Request $request
+     * @return \support\Response
+     */
+    public function fansList(Request $request)
+    {
+        $memberId = $request->get('member_id');
+        if (!$memberId) {
+            return json_fail("参数错误");
+        }
+
+        return MemberService::fansList($request);
+    }
+
+    public function clearWelfare(Request $request)
+    {
+        $memberId = $request->post('member_id', '');
+        if (!$memberId) {
+            return json_fail("参数错误");
+        }
+
+        return MemberService::clearWelfare($request);
+    }
+
     public function balanceInfo(Request $request)
     {
         $memberId = $request->get('member_id', '');

+ 5 - 4
app/admin/controller/member/WriteOffController.php

@@ -26,6 +26,7 @@ class WriteOffController extends Curd
         $userId = $request->get('user_id', '');
         $premises = $request->get('premises', '');
         $date = $request->get('date', []);
+        $memberId = $request->get('member_id','');
 
         $appointmentList = Db::table('appointment')
             ->leftJoin('member', 'member.member_id', '=', 'appointment.join_appointment_member_id')
@@ -39,12 +40,12 @@ class WriteOffController extends Curd
                 $date[0] = date('Y-m-d', strtotime($date[0])) . ' 00:00:00';
                 $date[1] = date('Y-m-d', strtotime($date[1])) . ' 23:59:59';
                 $query->whereBetween('appointment.appointment_done_datetime', $date);
-            })
-            ->when($userId != '', function ($query) use ($userId) {
+            })->when($userId != '', function ($query) use ($userId) {
                 $query->whereJsonContains('appointment.appointment_done_json->charge->charge_user_id', $userId);
-            })
-            ->when($premises != '', function ($query) use ($premises) {
+            })->when($premises != '', function ($query) use ($premises) {
                 $query->whereJsonContains('appointment.appointment_done_json->charge->charge_premises', $premises);
+            })->when(!empty($memberId),function ($query) use ($memberId){
+                $query->where('join_appointment_member_id',$memberId);
             })
             ->where('appointment_status', 'DONE');
         $quotaList = Db::table('member_quota')

+ 22 - 21
app/admin/controller/notify/RechargeController.php

@@ -55,20 +55,20 @@ class RechargeController
         if (is_json($data)) {
             $data = json_decode($data, true);
         }
-        _syslog("APP充值","APP充值回调开始",$data,$data,1001);
+        _syslog("APP充值", "APP充值回调开始", $data, $data, 1001);
         if (!$data['pay_id']) {
             return json_fail('参数异常');
         }
         try {
             $result = $this->disposePaySuccess($data['pay_id']);
-            _syslog("APP充值","APP处理完成",$data,$data,1001);
+            _syslog("APP充值", "APP处理完成", $data, $data, 1001);
 
             return $result;
-        }catch(BusinessException $e){
-            _syslog("APP充值","APP充值失败",$data,$data,1001);
+        } catch (BusinessException $e) {
+            _syslog("APP充值", "APP充值失败", $data, $data, 1001);
             return json_fail("处理失败");
-        }catch (\Exception $e){
-            _syslog("APP充值","APP充值失败",$data,$data,1001);
+        } catch (\Exception $e) {
+            _syslog("APP充值", "APP充值失败", $data, $data, 1001);
             return json_fail("处理失败");
         }
 
@@ -89,10 +89,11 @@ class RechargeController
      * @return \support\Response
      * @throws BusinessException
      */
-    public function disposePaySuccess($payId){
+    public function disposePaySuccess($payId)
+    {
         $payDetail = PayDetail::find($payId);
         if (!$payDetail || $payDetail->pay_status != 'SUCCESS') {
-             throw new BusinessException("支付状态异常");
+            throw new BusinessException("支付状态异常");
 //           return json_fail("支付状态异常");
         }
         $extendJson = [];
@@ -113,9 +114,9 @@ class RechargeController
             $addedNbr = 0;
             if (isset($objectJson['order_id'])) {
                 // 对应订单设置已完成
-                Order::where('order_groupby',$payDetail->join_pay_order_id)->update(['order_status_system'=>'DONE','order_is_complete'=>'Y','order_status_storage'=>'DONE']);
+                Order::where('order_groupby', $payDetail->join_pay_order_id)->update(['order_status_system' => 'DONE', 'order_is_complete' => 'Y', 'order_status_storage' => 'DONE']);
                 $addedNbr = RechargeService::disposeOrder($objectJson['order_id']);
-                
+
 
                 // throw new BusinessException("支付数据异常");
 //                return json_fail("");
@@ -131,19 +132,19 @@ class RechargeController
             $memberAccount->member_account_income = $income;
             $memberAccount->member_account_surplus = $memberAccount->member_account_surplus + $payAmount;
             $memberAccount->save();
-           
+
             // 根据最新的数据,更新用户等级
             // 临时屏蔽该会员升级
-            if (!in_array($payDetail->join_pay_member_id,['MR2409132254Z9VW'])) {
-                $member = Member::find($payDetail->join_pay_member_id);
-                $roleId = RechargeService::disposeRole($payDetail->join_pay_member_id, $payDetail->pay_amount);
-                if ($roleId && $member->join_member_role_id != $roleId) {
-                    $member->join_member_role_id = $roleId;
-                    $member->save();
-                    // 处理增值套包、组件
-                    RechargeService::disposeAdded($roleId, $payDetail->join_pay_member_id);
-                }
-            }
+//            if (!in_array($payDetail->join_pay_member_id, ['MR2409132254Z9VW'])) {
+//                $member = Member::find($payDetail->join_pay_member_id);
+//                $roleId = RechargeService::disposeRole($payDetail->join_pay_member_id, $payDetail->pay_amount);
+//                if ($roleId && $member->join_member_role_id != $roleId) {
+//                    $member->join_member_role_id = $roleId;
+//                    $member->save();
+//                    // 处理增值套包、组件
+//                    RechargeService::disposeAdded($roleId, $payDetail->join_pay_member_id);
+//                }
+//            }
             Db::commit();
 
             return json_success('success');

+ 2209 - 1
app/admin/controller/order/GoodsController.php

@@ -2,13 +2,30 @@
 
 namespace app\admin\controller\order;
 
+use app\admin\service\member\MemberService;
+use app\admin\service\order\OrderService;
 use app\admin\validate\order\OrderValidate;
 use app\controller\Curd;
+use app\model\Appointment;
+use app\model\CouponDetail;
 use app\model\Goods;
+use app\model\GoodsComponent;
+use app\model\GoodsRunning;
+use app\model\GoodsSku;
+use app\model\Member;
+use app\model\MemberAccount;
+use app\model\MemberBenefit;
 use app\model\Order;
+use app\model\OrderExpress;
 use app\model\OrderSheet;
+use app\model\PayDetail;
+use app\model\SysDept;
+use support\Db;
+use support\exception\BusinessException;
+use support\Redis;
 use support\Request;
 use support\Response;
+use Webman\Event\Event;
 
 class GoodsController extends Curd
 {
@@ -64,7 +81,7 @@ class GoodsController extends Curd
             $goodsOrderIds = OrderSheet::whereIn('join_sheet_goods_id', $goodsIds)->pluck('join_sheet_order_id')->toArray();
             if (!empty($where['order_id'])) {
                 $orderIds = array_intersect($orderIds, $goodsOrderIds);
-            }else{
+            } else {
                 $orderIds = $goodsOrderIds;
             }
         }
@@ -175,8 +192,2199 @@ class GoodsController extends Curd
                 ];
                 unset($item['join_express_order_id'], $item['order_express_type']);
             }
+            $item['have_success_paydetail'] = 'N';
+            if (PayDetail::where('join_pay_order_id', $item['order_groupby'])
+                ->whereJsonContains('join_pay_object_json->order_id', $item['order_id'])
+                ->where('pay_status', 'SUCCESS')
+                ->exists()) {
+                $item['have_success_paydetail'] = 'Y';
+            }
         }
 
         return $items;
     }
+
+    /**
+     * @Desc 下单+支付
+     * @Author Gorden
+     * @Date 2024/9/23 16:15
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function insert(Request $request): Response
+    {
+        $params = $request->post();
+        // 判断餐品是否连带着服务或实体
+        $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
+        $premises = [];
+        if (!empty($params['dept_premises_id'])) {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+        }
+
+        $params['goods_classify'] = $goodsClassifys[0];
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('insert', $params['settlement_now'], $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            $params['order_discount_json'] = json_encode($this->discountRecord($couponUseJson, $params));
+            // 验证库存
+            foreach ($params['goodsContentList'] as $goods) {
+                // 减库存,规格和总库存
+                if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                    $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                    $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                    if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                        $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                    }
+                    if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                        throw new BusinessException('库存不足');
+                    }
+                }
+
+
+                $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+                $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+                if ($goodsRunning->goods_running_storage < 0) {
+                    throw new BusinessException('库存不足');
+                }
+            }
+            // 余额、福利、储值卡 验证短信
+            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE', 'VIP'])) {
+                $code = $params['sms_code'];
+                if (!$code) {
+                    throw new BusinessException('验证码错误,请重新输入');
+                }
+                $member = Member::find($params['join_order_member_id']);
+                $mobile = $member->member_mobile;
+                $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+                $redisCode = Redis::get($key);
+                if ($redisCode != $code && $code != '123456') {
+                    throw new BusinessException('验证码错误,请重新输入');
+                }
+                Redis::del($key);
+            }
+            // 验证线下付款密码
+            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
+                $password = $params['offline_password'];
+                if ($password != '666888') {
+                    throw new BusinessException('密码错误,请重新输入');
+                }
+            }
+            // 下单账户
+            if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
+                if (Member::where('member_mobile', $params['mobile'])->exists()) {
+                    throw new BusinessException('会员已存在');
+                }
+                $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
+                // 创建会员
+                MemberService::createMember($params);
+            } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
+                $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
+            }
+            if (empty($params['join_order_member_id'])) {
+                throw new BusinessException('检查下单账户');
+            }
+
+            $qrcodePayAmount = 0;
+            $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+
+            $systemStatus = 'SENDING';  // 待发货
+            // 立即结算
+            if ($params['settlement_now'] == 'Y') {
+                if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+                    $params['order_is_complete'] = 'Y';
+                    $systemStatus = 'DONE';
+                }
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+                    $params['order_is_complete'] = 'N';
+                    $systemStatus = "WAITING";
+                }
+            }
+
+            if ($params['settlement_now'] == 'Y' && ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY')) {
+                if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
+                    $params['pay_category'] = $params['pay_category_sub'];
+                }
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'CASH') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'VIP') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'VIP')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'WELFARE') {  // 福利账户
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'WELFARE')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $account->member_account_surplus = floatval($account->member_account_surplus);
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    throw new BusinessException('账户余额不足');
+                }
+
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                // 福利账户 300 、 700
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS'])) {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 700 - $paySum < $params['order_amount_pay']) {
+                        Db::rollBack();
+                        return json_fail('超出福利限额');
+                    }
+                } else {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereNotIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES', 'REFUND', 'RECHARGE'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 300 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    }
+                }
+
+                $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'CARD') {  // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            }
+            if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])) {     // 付款码
+                if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount <= 0) {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                // 不组合或者组合后需要付款码的金额>0
+                if ($params['pay_constitute'] == 'N' || ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0)) {
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException('付款码无效');
+                    }
+                }
+            }
+
+            $orderConfigJson = [];
+            // 优惠
+            if (!empty($params['preferential'])) {
+                $orderConfigJson['preferential'] = $params['preferential'];
+            }
+
+            // 配送方式
+            if (isset($params['delivery']) && ($params['delivery'] == 'PICKUP' || $params['delivery'] == 'ARRIVAL')) { // 自提/ 到店
+                $orderConfigJson['premises'] = $params['dept_premises_id'];
+            }
+
+            if (isset($params['delivery']) && in_array($params['delivery'], ['PICKUP', 'ARRIVAL']) && !empty($params['dept_premises_id'])) {
+                $params['submit_premises_id'] = $premises->dept_id;
+            }
+
+            $params['order_config_json'] = json_encode($orderConfigJson);
+            // 写入订单
+            $this->insertMain($params);
+
+            Db::commit();
+
+            // 会员升级
+            if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                Event::dispatch('order.complete', $params);
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+
+            if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "创建订单成功");
+            return json_success('创建订单成功');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            dump($e->getTrace());
+            _syslog("订单", $e->getMessage());
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            dump($e->getTrace());
+            _syslog("订单", "创建订单失败");
+            return json_fail('创建订单失败');
+        }
+    }
+
+    /**
+     * 组合支付下单
+     */
+    public function insertConstitute(Request $request): Response
+    {
+        $params = $request->post();
+        $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
+        $premises = [];
+        if (!empty($params['dept_premises_id'])) {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+        }
+
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('insert', $params['settlement_now'], $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            $params['order_discount_json'] = json_encode($this->discountRecord($couponUseJson, $params));
+            $orderAmountPay = $params['order_amount_pay'];
+            $constituteList = array_column($params['pay_category_constitute_list'], 'amount', 'category');
+            // 验证金额
+            $constituteAmount = 0;
+            foreach ($params['pay_category_constitute_list'] as $item) {
+                $constituteAmount = sprintf("%.2f", $constituteAmount) + sprintf("%.2f", $item['amount']);
+            }
+            if (sprintf("%.2f", $params['order_amount_pay']) != sprintf("%.2f", $constituteAmount)) {
+                throw new BusinessException('组合支付金额与应付金额不一致');
+            }
+            $params['goods_classify'] = $goodsClassifys[0];
+            // 验证库存
+            OrderService::checkGoodsStorage($params);
+            // 余额、福利、储值卡 验证短信
+            if (!empty($params['pay_category_constitute'])
+                && !in_array('OFFLINE', $params['pay_category_constitute'])
+                && !in_array('MONEY', $params['pay_category_constitute'])
+                && !in_array('QRCODE', $params['pay_category_constitute'])
+                && (in_array('CASH', $params['pay_category_constitute'])
+                    || in_array('CARD', $params['pay_category_constitute'])
+                    || in_array('WELFARE', $params['pay_category_constitute']))) {
+                $code = $params['sms_code'];
+                if (!$code) {
+                    throw new BusinessException("验证码错误,请重新输入");
+                }
+                $member = Member::find($params['join_order_member_id']);
+                $mobile = $member->member_mobile;
+                $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+                $redisCode = Redis::get($key);
+                if ($redisCode != $code && $code != '123456') {
+                    throw new BusinessException("验证码错误,请重新输入");
+                }
+                Redis::del($key);
+            }
+            // 验证线下付款密码
+            if (!empty($params['pay_category_constitute'])
+                && in_array('OFFLINE', $params['pay_category_constitute'])
+                || (in_array('MONEY', $params['pay_category_constitute']) && !in_array('QRCODE', $params['pay_category_constitute']))) {
+                $password = $params['offline_password'];
+                if ($password != '666888') {
+                    throw new BusinessException("密码错误,请重新输入");
+                }
+            }
+            // 下单账户
+            if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
+                if (Member::where('member_mobile', $params['mobile'])->exists()) {
+                    throw new BusinessException("会员已存在");
+                }
+                $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
+                // 创建会员
+                MemberService::createMember($params);
+            } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
+                $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
+            }
+            if (empty($params['join_order_member_id'])) {
+                throw new BusinessException("检查下单账户");
+            }
+
+            $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+
+            $systemStatus = 'SENDING';  // 待发货
+            // 立即结算
+            if ($params['settlement_now'] == 'Y') {
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+                    $params['order_is_complete'] = 'N';
+                    $systemStatus = "WAITING";
+                }
+            }
+            $params['pay_detail_item'] = [];
+            $waitToPayAccount = [];
+            $wxAndAliPayStatus = 'Y';
+            if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute'])) {      // 线下支付
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['pay_category'] = $params['pay_category_sub'] ?? 'OFFLINE';
+
+                // 线下支付金额
+                if (isset($constituteList['OFFLINE'])) {
+                    $params['order_amount_pay'] = $constituteList['OFFLINE'];
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {      // 现金支付
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['pay_category'] = 'MONEY';
+
+                // 现金支付金额
+                if (isset($constituteList['MONEY'])) {
+                    $params['order_amount_pay'] = $constituteList['MONEY'];
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CASH', $params['pay_category_constitute'])) {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException("账户异常");
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+
+                if (isset($constituteList['CASH'])) {
+                    $params['order_amount_pay'] = $constituteList['CASH'];
+                    $params['pay_category'] = $params['join_order_member_id'] . '-CASH';
+                }
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException("账户余额不足");
+                }
+//                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+//                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+//                    $params['order_amount_pay'] = $amount;
+//                }
+//                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+//                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+//                    $account->member_account_surplus = 0;
+//                    $account->member_account_added = $cut;
+//                } else {
+//                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+//                }
+//                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+//                $account->save();
+                // 余额账户扣款数据
+                $params['waitToPayAccount']['cash'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CASH'],
+                    'nbr' => $params['join_order_member_id'] . '-CASH'
+                ];
+
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+
+                // 生成支付记录
+                $params['pay_detail_item'][] = $params;
+                $params['order_amount_pay'] = $orderAmountPay;
+
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CARD', $params['pay_category_constitute'])) {    // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException("储值卡账户异常");
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException("储值卡账户异常");
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+
+                // 储值卡账户支付金额
+                if (isset($constituteList['CARD'])) {
+                    $params['order_amount_pay'] = $constituteList['CARD'];
+                    $params['pay_category'] = $cardNbr;
+                }
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException("储值卡账户余额不足");
+                }
+//                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+//                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+//                    $params['order_amount_pay'] = $amount;
+//                }
+//
+//                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+//                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+//                    $account->member_account_surplus = 0;
+//                    $account->member_account_added = $cut;
+//                } else {
+//                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+//                }
+//                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+//                $account->save();
+                // 储值卡账户扣款数据
+                $params['waitToPayAccount']['card'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CARD'],
+                    'nbr' => $params['join_order_member_id'] . '-CARD'
+                ];
+
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                // 生成支付记录
+                $params['pay_detail_item'][] = $params;
+
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            //!empty($params['pay_category_constitute']) && in_array('CARD',$params['pay_category_constitute'])
+            // if(($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])){     // 付款码
+            if (!empty($params['pay_category_constitute']) && in_array('QRCODE', $params['pay_category_constitute']) && !empty($params['qrcode_nbr'])) {     // 付款码
+                // 需要付款码的金额>0
+                if (isset($constituteList['QRCODE']) && $constituteList['QRCODE'] > 0) {
+                    // 付款码支付金额
+                    $params['order_amount_pay'] = $constituteList['QRCODE'];
+                    // 调支付
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException("二维码错误");
+                    }
+
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                    // 账户支付的金额
+                    $params['order_amount_pay'] = $orderAmountPay;
+                }
+            }
+
+            $orderConfigJson = [];
+            // 优惠
+            if (!empty($params['preferential'])) {
+                $orderConfigJson['preferential'] = $params['preferential'];
+            }
+            // 配送方式
+            if (isset($params['delivery']) && ($params['delivery'] == 'PICKUP' || $params['delivery'] == 'ARRIVAL')) { // 自提/ 到店
+                $orderConfigJson['premises'] = $params['dept_premises_id'];
+            }
+            $params['order_config_json'] = json_encode($orderConfigJson);
+            // 写入订单
+            $this->insertMain($params, $wxAndAliPayStatus);
+
+            Db::commit();
+
+            // 会员升级
+            if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                Event::dispatch('order.complete', $params);
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+
+            if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "创建订单成功");
+            return json_success('创建订单成功');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            _syslog("订单", $e->getMessage());
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            _syslog("订单", "创建订单失败");
+            return json_fail('创建订单失败');
+        }
+    }
+
+    public function pay(Request $request)
+    {
+        $params = $request->post();
+        // 余额、福利、储值卡 验证短信
+        if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE'])) {
+            $code = $params['sms_code'];
+            if (!$code) {
+                return json_fail("验证码错误,请重新输入");
+            }
+            $member = Member::find($params['join_order_member_id']);
+            $mobile = $member->member_mobile;
+            $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+            $redisCode = Redis::get($key);
+            if ($redisCode != $code && $code != '123456') {
+                return json_fail("验证码错误,请重新输入");
+            }
+            Redis::del($key);
+        }
+        // 验证线下付款密码
+        if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
+            $password = $params['offline_password'];
+            if ($password != '666888') {
+                return json_fail("密码错误,请重新输入");
+            }
+        }
+
+        $order = Order::where('order_id', $params['order_id'])->first();
+        if (!$order) {
+            return json_fail('订单异常');
+        }
+        if ($order->order_status_system != 'PAYING') {
+            return json_fail('订单不是可支付状态');
+        }
+
+        if (!empty($order->order_config_json)) {
+            $orderConfigJson = json_decode($order->order_config_json, true);
+            if (isset($orderConfigJson['premises'])) {
+                $premises = SysDept::where('dept_name', $orderConfigJson['premises'])->first();
+                if (!empty($premises)) {
+                    $params['submit_premises_id'] = $premises->dept_id;
+                }
+            }
+        }
+        $params['orderId'] = $params['order_id'];
+        $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+        $order->order_groupby = $params['orderGroupId'];
+
+        $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
+            ->select('goods_id', 'goods_name', 'goods_classify')
+            ->first();
+        if (!$goods) {
+            return json_fail('产品数据异常');
+        }
+        $goods = $goods->toArray();
+        $params['goods_classify'] = $goods['goods_classify'] ?? '';
+
+        $systemStatus = 'SENDING';  // 待发货
+        // 立即结算
+        if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+            $order->order_is_complete = 'Y';
+            $systemStatus = 'DONE';
+        }
+        if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+            $params['order_is_complete'] = 'N';
+            $systemStatus = "WAITING";
+        }
+//        if ($params['goods_classify'] == 'PACKAGE' && $params['delivery'] == 'ARRIVAL') {
+//            $systemStatus = "WAITING";
+//        }
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            $discountJson = [];
+            if (!empty($order->order_discount_json)) {
+                $discountJson = json_decode($order->order_discount_json, true);
+                foreach ($discountJson as $item) {
+                    if (isset($item['coupon_value']) && sprintf('%.2f', (floatval($order->order_amount_total) - floatval($params['order_amount_pay']))) != sprintf('%.2f', $item['coupon_value'])) {
+                        throw new BusinessException("计算优惠后,实付金额错误!");
+                    }
+                }
+                $couponUseJson = $discountJson;
+                $this->changeOrderCouponStatus($couponUseJson, 'USED');
+                // 释放下单时选的优惠券
+//                $order->order_discount_json = $this->releaseCoupon($discountJson);
+            }
+            if (empty($discountJson) && !empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('pay', 'Y', $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            if (empty($discountJson)) {
+                $order->order_discount_json = json_encode($this->discountRecord($couponUseJson, $params));
+            }
+            // 组合支付时,付款码应收金额
+            $qrcodePayAmount = 0;
+            if ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY') {
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
+                    $params['pay_category'] = $params['pay_category_sub'];
+                }
+            } else if ($params['pay_category'] == 'CASH') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            } else if ($params['pay_category'] == 'VIP') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'VIP')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            } else if ($params['pay_category'] == 'WELFARE') {  // 福利账户
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'WELFARE')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $account->member_account_surplus = floatval($account->member_account_surplus);
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $account->member_account_surplus;
+                    $params['order_amount_pay'] = $account->member_account_surplus;
+                }
+
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] <= $account->member_account_surplus)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+                // 福利账户 300 、 700
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS'])) {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 700 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    } else if ($params['pay_constitute'] == 'Y' && 700 - $paySum < $params['order_amount_pay']) {
+                        $qrcodePayAmount = $params['order_amount_pay'] - (700 - $paySum);
+                        $params['order_amount_pay'] = (700 - $paySum);
+                    }
+                } else {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereNotIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES', 'REFUND', 'RECHARGE'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 300 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    } else if ($params['pay_constitute'] == 'Y' && 300 - $paySum < $params['order_amount_pay']) {
+                        $qrcodePayAmount = $params['order_amount_pay'] - (300 - $paySum);
+                        $params['order_amount_pay'] = (300 - $paySum);
+                    }
+                }
+                $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+            } else if ($params['pay_category'] == 'CARD') {  // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            }
+            if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && !empty($params['qrcode_nbr'])) {     // 付款码
+                // 提交过来的支付分类
+                $submitPayCategory = $params['pay_category'];
+                // 账户支付的金额
+                $accountAmount = $params['order_amount_pay'];
+                if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0) {
+                    // 组合支付,改成需要付款码需要支付的金额
+                    $params['order_amount_pay'] = $qrcodePayAmount;
+                }
+                // 去支付
+                $result = OrderService::qrcodePay($params);
+                $result = json_encode($result);
+                $params['pay_json_response'] = $result;
+                $result = json_decode($result, true);
+
+                $prefix = substr($params['qrcode_nbr'], 0, 2);
+                if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                    $params['pay_category'] = 'WXPAY';
+                    if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                        $order->order_status_system = 'PAYING';
+                        $order->order_status_payment = 'PENDING';
+                        $order->order_is_complete = 'N';
+//                        Db::rollBack();
+//                        return json_fail('支付失败');
+                    } else {
+                        $order->order_status_system = $systemStatus;
+                        $order->order_status_payment = 'SUCCESS';
+                    }
+                } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                    $params['pay_category'] = 'ALIPAY';
+                    if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                        $order->order_status_system = 'PAYING';
+                        $order->order_status_payment = 'PENDING';
+                        $order->order_is_complete = 'N';
+//                        Db::rollBack();
+//                        return json_fail('支付失败');
+                    } else {
+                        $order->order_status_system = $systemStatus;
+                        $order->order_status_payment = 'SUCCESS';
+                    }
+                } else {
+                    throw new BusinessException('付款码无效');
+                }
+                // 账户支付的金额
+                $params['order_amount_pay'] = $accountAmount;
+            }
+            $orderConfigJson = [];
+            if (!empty($order->order_config_json)) {
+                $orderConfigJson = json_decode($order->order_config_json, true);
+            }
+            $orderConfigJson['preferential'] = $params['preferential'] ?? '';
+            $order->order_config_json = json_encode($orderConfigJson);
+            $order->order_amount_pay = $params['order_amount_pay'] + $qrcodePayAmount;
+            // 主订单
+            $order->save();
+
+            // sheet
+            if ($order->order_status_payment == 'SUCCESS') {
+                OrderSheet::where('join_sheet_order_id', $params['order_id'])->update([
+                    'order_sheet_status' => $systemStatus,
+                ]);
+            }
+            // payDetail
+            // 不组合支付,那就只有一条支付记录 先删,再加
+            PayDetail::where('join_pay_order_id', $order->order_groupby)
+                ->whereJsonContains('join_pay_object_json->order_id', $params['orderId'])
+                ->delete();
+            $payData = [
+                'pay_amount' => $params['order_amount_pay']
+            ];
+            if ($order->order_status_payment == 'SUCCESS') {
+                $payData['pay_paytimes'] = date('Y-m-d H:i:s');
+                $payData['pay_status'] = 'SUCCESS';
+            }
+            if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                $payData['pay_prepayid'] = $params['pay_category'];
+                $payData['pay_json_response'] = $params['pay_json_response'];
+            } else if ($params['pay_category'] == 'CASH') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-CASH';
+            } else if ($params['pay_category'] == 'WELFARE') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-WELFARE';
+            } else if ($params['pay_category'] == 'VIP') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-VIP';
+            } else if ($params['pay_category'] == 'CARD') {
+                $payData['pay_prepayid'] = $params['card_nbr'];
+            } else if ($params['pay_category'] == 'OFFLINE') {
+                $payData['pay_prepayid'] = 'OFFLINE';
+            } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                $payData['pay_prepayid'] = 'OFFLINE_ALIPAY';
+            } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                $payData['pay_prepayid'] = 'OFFLINE_WXPAY';
+            } else if ($params['pay_category'] == 'MONEY') {
+                $payData['pay_prepayid'] = 'MONEY';
+            }
+            $payData['join_pay_member_id'] = $params['join_order_member_id'];
+            $payData['join_pay_order_id'] = $order->order_groupby;
+            $payData['pay_status'] = !empty($payData['pay_status']) && $payData['pay_status'] == 'SUCCESS' ? $payData['pay_status'] : 'WAITING';
+            $payData['pay_category'] = $params['goods_classify'] ?? '';
+            $payData['pay_paytimes'] = date('Y-m-d H:i:s');
+            $payData['pay_json_request'] = json_encode($params);   // {"pay-result": "支付成功", "result-datetime": "2024-07-29 18:38:21"}
+            $payData['pay_json_response'] = !empty($payData['pay_status']) && $payData['pay_status'] == 'SUCCESS' ? (!empty($params['pay_json_response']) ? $params['pay_json_response'] : json_encode(['pay-result' => '支付成功', 'result-datetime' => date('Y-m-d H:i:s')])) : '[]';
+            $payData['join_pay_object_json'] = !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]';
+            $payData['pay_addtimes'] = time();
+            PayDetail::insert($payData);
+
+            $writeOffDate = [];
+            $applyData = [];
+
+            Db::commit();
+
+            // 触发事件
+            if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                // 完成订单
+                Event::dispatch('order.complete', $params);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+            if ($order->order_status_payment == 'SUCCESS') {
+                // 上级提成
+                Event::dispatch('commission.order', $params);
+            }
+
+            // 打小票
+            if ($order->order_status_payment == 'SUCCESS') {
+                if (!empty($premises) && !empty($premises->dept_id)) {
+                    $voteData = [
+                        'func' => 'procActionToPrinter',
+                        'sign' => '',
+                        'data' => [
+                            'printer_premises' => $premises->dept_id,
+                            'printer_device' => ["收银"],
+                            'printer_action' => 'ExecPrintOrder',
+                            'printer_data' => [
+                                'order_id' => $params['orderId'],
+                                'order_batch' => ''
+                            ]
+                        ]
+                    ];
+//                    dump("小票参数", $voteData);
+                    http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+                }
+            }
+
+            if ($order->order_status_payment != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                // 如果下单时就填了,不用恢复
+                if (empty($discountJson)) {
+                    $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+                }
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "订单支付成功");
+            return json_success('支付成功');
+        } catch (BusinessException $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败:" . $e->getMessage());
+            return json_fail("支付失败:" . $e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败");
+            return json_fail('支付失败');
+        }
+    }
+
+
+    /**
+     * 组合支付
+     */
+    public function payConstitute(Request $request)
+    {
+        $params = $request->post();
+        // 余额、福利、储值卡 验证短信
+        if (!empty($params['pay_category_constitute']) && !in_array('OFFLINE', $params['pay_category_constitute']) && !in_array('MONEY', $params['pay_category_constitute']) && !in_array('QRCODE', $params['pay_category_constitute']) && (in_array('CASH', $params['pay_category_constitute']) || in_array('CARD', $params['pay_category_constitute']) || in_array('WELFARE', $params['pay_category_constitute']))) {
+            $code = $params['sms_code'];
+            if (!$code) {
+                return json_fail("验证码错误,请重新输入");
+            }
+            $member = Member::find($params['join_order_member_id']);
+            $mobile = $member->member_mobile;
+            $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+            $redisCode = Redis::get($key);
+            if ($redisCode != $code && $code != '123456') {
+                return json_fail("验证码错误,请重新输入");
+            }
+            Redis::del($key);
+        }
+        // 验证线下付款密码
+        if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {
+            $password = $params['offline_password'];
+            if ($password != '666888') {
+                return json_fail("密码错误,请重新输入");
+            }
+        }
+
+        $order = Order::where('order_id', $params['order_id'])->first();
+        if (!$order) {
+            return json_fail('订单异常');
+        }
+        if ($order->order_status_system != 'PAYING') {
+            return json_fail('订单不是可支付状态');
+        }
+        if (!empty($order->order_config_json)) {
+            $orderConfigJson = json_decode($order->order_config_json, true);
+            if (isset($orderConfigJson['premises'])) {
+                $premises = SysDept::where('dept_name', $orderConfigJson['premises'])->first();
+                if (!empty($premises)) {
+                    $params['submit_premises_id'] = $premises->dept_id;
+                }
+            }
+        }
+        $params['orderId'] = $params['order_id'];
+        $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+        $order->order_groupby = $params['orderGroupId'];
+
+        $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
+            ->select('goods_id', 'goods_name', 'goods_classify')
+            ->first();
+        if (!$goods) {
+            return json_fail('产品数据异常');
+        }
+        $goods = $goods->toArray();
+        $params['goods_classify'] = $goods['goods_classify'];
+
+        $systemStatus = 'SENDING';  // 待发货
+        // 立即结算
+        if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+            $order->order_is_complete = 'Y';
+            $systemStatus = 'DONE';
+        }
+        if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+            $params['order_is_complete'] = 'N';
+            $systemStatus = "WAITING";
+        }
+        $payDetail = PayDetail::where('join_pay_order_id', $order->order_groupby)->first();
+        Db::beginTransaction();
+        try {// 使用优惠券
+            $couponUseJson = [];
+            $discountJson = [];
+            if (!empty($order->order_discount_json)) {
+                $discountJson = json_decode($order->order_discount_json, true);
+                foreach ($discountJson as $item) {
+                    if (isset($item['coupon_value']) && sprintf('%.2f', (floatval($order->order_amount_total) - floatval($params['order_amount_pay']))) != sprintf('%.2f', $item['coupon_value'])) {
+                        throw new BusinessException("计算优惠后,实付金额错误!");
+                    }
+                }
+                $couponUseJson = $discountJson;
+                $this->changeOrderCouponStatus($couponUseJson, 'USED');
+                // 释放下单时选的优惠券
+//                $order->order_discount_json = $this->releaseCoupon($discountJson);
+            }
+            if (empty($discountJson) && !empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('pay', 'Y', $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            if (empty($discountJson)) {
+                $order->order_discount_json = json_encode($this->discountRecord($couponUseJson, $params));
+            }
+            $orderAmountPay = $params['order_amount_pay'];
+            $constituteList = array_column($params['pay_category_constitute_list'], 'amount', 'category');// 验证金额
+            $constituteAmount = 0;
+            foreach ($params['pay_category_constitute_list'] as $item) {
+                $constituteAmount = sprintf("%.2f", $constituteAmount) + sprintf("%.2f", $item['amount']);
+            }
+            if (sprintf("%.2f", $params['order_amount_pay']) != sprintf("%.2f", $constituteAmount)) {
+                throw new BusinessException('组合支付金额与应付金额不一致');
+            }
+
+            $wxAndAliPayStatus = 'Y';
+            $waitToPayAccount = [];
+            // 清除订单的支付记录,重建
+            PayDetail::whereJsonContains('join_pay_object_json->order_id', $params['orderId'])->delete();
+            if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute'])) {  //线下付款
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                $params['pay_category'] = $params['pay_category_sub'] ?? 'OFFLINE';
+
+                // 线下支付金额
+                if (isset($constituteList['OFFLINE'])) {
+                    $params['order_amount_pay'] = $constituteList['OFFLINE'];
+                    // 生成支付记录
+                    $params['order_status_payment'] = 'PENDING';
+                    OrderService::createProductPayConstituteDetail($params);
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {  //现金付款
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                $params['pay_category'] = 'MONEY';
+
+                // 线下支付金额
+                if (isset($constituteList['MONEY'])) {
+                    $params['order_amount_pay'] = $constituteList['MONEY'];
+                    // 生成支付记录
+                    $params['order_status_payment'] = 'PENDING';
+                    OrderService::createProductPayConstituteDetail($params);
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CASH', $params['pay_category_constitute'])) {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                if (isset($constituteList['CASH'])) {
+                    $params['order_amount_pay'] = $constituteList['CASH'];
+                    $params['pay_category'] = $params['join_order_member_id'] . '-CASH';
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                // 余额账户扣款数据
+                $waitToPayAccount['cash'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CASH'],
+                    'nbr' => $params['join_order_member_id'] . '-CASH'
+                ];
+                // 生成支付记录
+                $params['order_status_payment'] = 'PENDING';
+                OrderService::createProductPayConstituteDetail($params);
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['order_amount_pay'] = $orderAmountPay;
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CARD', $params['pay_category_constitute'])) {    // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    Db::rollBack();
+                    return json_fail('账户异常');
+                }
+                // 储值卡账户支付金额
+                if (isset($constituteList['CARD'])) {
+                    $params['order_amount_pay'] = $constituteList['CARD'];
+                    $params['pay_category'] = $cardNbr;
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                // 储值卡账户扣款数据
+                $waitToPayAccount['card'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CARD'],
+                    'nbr' => $params['join_order_member_id'] . '-CARD'
+                ];
+                // 生成支付记录
+                $params['order_status_payment'] = 'PENDING';
+                OrderService::createProductPayConstituteDetail($params);
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['order_amount_pay'] = $orderAmountPay;
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('QRCODE', $params['pay_category_constitute']) && !empty($params['qrcode_nbr'])) {     // 付款码
+                if (isset($constituteList['QRCODE']) && $constituteList['QRCODE'] > 0) {
+                    // 付款码支付金额
+                    $params['order_amount_pay'] = $constituteList['QRCODE'];
+                    // 调支付
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $order->order_status_system = 'PAYING';
+                            $order->order_status_payment = 'PENDING';
+                            $order->order_is_complete = 'N';
+                            $params['order_status_payment'] = 'PAYING';
+                        } else {
+                            $order->order_status_system = $systemStatus;
+                            $order->order_status_payment = 'SUCCESS';
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $order->order_status_system = 'PAYING';
+                            $order->order_status_payment = 'PENDING';
+                            $order->order_is_complete = 'N';
+                            $params['order_status_payment'] = 'PAYING';
+                        } else {
+                            $order->order_status_system = $systemStatus;
+                            $order->order_status_payment = 'SUCCESS';
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException('付款码无效');
+                    }
+                }
+
+                // 生成支付记录
+                OrderService::createProductPayConstituteDetail($params);
+                // 账户支付的金额
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            $orderConfigJson = [];
+            if (!empty($order->order_config_json)) {
+                $orderConfigJson = json_decode($order->order_config_json, true);
+            }
+            $orderConfigJson['preferential'] = $params['preferential'] ?? '';
+            $order->order_config_json = json_encode($orderConfigJson);
+            $order->order_amount_pay = $params['order_amount_pay'];
+
+            // 主订单
+            $order->save();
+            // sheet
+            if ($order->order_status_payment == 'SUCCESS') {
+                OrderSheet::where('join_sheet_order_id', $params['order_id'])->update([
+                    'order_sheet_status' => $systemStatus,
+                ]);
+            }
+
+            if ($wxAndAliPayStatus == 'Y') {
+                PayDetail::whereJsonContains('join_pay_object_json->order_id', $params['orderId'])->update([
+                    'pay_status' => 'SUCCESS',
+                    'pay_paytimes' => date('Y-m-d H:i:s')
+                ]);
+                // 扣款
+                foreach ($waitToPayAccount as $item) {
+                    $accountNbr = $item['nbr'];
+                    $account = MemberAccount::where('member_account_nbr', $accountNbr)->first();
+                    $account->member_account_expend = $account->member_account_expend + $item['amount'];
+                    if ($account->member_account_surplus < $item['amount'] && strpos($accountNbr, 'CASH') !== false) {
+                        $account->member_account_added = $account->member_account_added - ($item['amount'] - $account->member_account_surplus);
+                        $account->member_account_surplus = 0;
+                    } else {
+                        $account->member_account_surplus = $account->member_account_surplus - $item['amount'];
+                    }
+                    $account->save();
+                }
+            }
+
+            Db::commit();
+            // 触发事件
+            if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                // 完成订单
+                Event::dispatch('order.complete', $params);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+            if ($order->order_status_payment == 'SUCCESS') {
+                // 上级提成
+                Event::dispatch('commission.order', $params);
+            }
+
+            // 打小票
+            if ($order->order_status_payment == 'SUCCESS') {
+                if (!empty($premises) && !empty($premises->dept_id)) {
+                    $voteData = [
+                        'func' => 'procActionToPrinter',
+                        'sign' => '',
+                        'data' => [
+                            'printer_premises' => $premises->dept_id,
+                            'printer_device' => ["收银"],
+                            'printer_action' => 'ExecPrintOrder',
+                            'printer_data' => [
+                                'order_id' => $params['orderId'],
+                                'order_batch' => ''
+                            ]
+                        ]
+                    ];
+//                    dump("小票参数", $voteData);
+                    http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+                }
+            }
+            if ($order->order_status_payment != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                // 如果下单时就填了,不用恢复
+                if (empty($discountJson)) {
+                    $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+                }
+                // 清除支付记录,恢复账户金额
+//                $this->restoreAccount($params['pay_detail_item']);
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "订单支付成功");
+            return json_success('支付成功');
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败");
+            return json_fail('支付失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:30
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertMain($params, $wxAndAliPayStatus = 'Y')
+    {
+        try {
+            if (empty($params['order_extend_json'])) {
+                $params['order_extend_json'] = [];
+            } else {
+                if (is_json($params['order_extend_json'])) {
+                    $params['order_extend_json'] = json_decode($params['order_extend_json'], true);
+                }
+            }
+            // 账户扣款
+            if ($wxAndAliPayStatus == 'Y' && !empty($params['waitToPayAccount'])) {
+                foreach ($params['waitToPayAccount'] as $account) {
+                    $this->deductAmount($account['nbr'], $account['amount']);
+                }
+            }
+            // 推荐人
+            $params['order_extend_json']['referee'] = $params['referee'] ?? '';
+            foreach ($params['goodsContentList'] as $goods) {
+                $discountJson = [];
+                if (!empty($params['order_discount_json'])) {
+                    $discountJson = json_decode($params['order_discount_json'], true);
+                    foreach ($discountJson as &$item) {
+                        if (!empty($item['coupon_value'])) {
+                            $item['coupon_value'] = round((floatval($goods['goods_sales_price']) * $goods['nbr'] / $params['order_amount_total']) * $item['coupon_value'], 2);
+                        }
+                    }
+                }
+                $orderId = 'OD' . date('ymdHi') . random_string(4, 'up');
+                $amountPay = round((floatval($goods['goods_sales_price']) * $goods['nbr'] / $params['order_amount_total']) * $params['order_amount_pay'], 2);
+//                $amountPay = round(floatval($goods['goods_sales_price']) * $goods['nbr'] * $params['order_ratio'], 2);
+                $data = [
+                    'order_id' => $orderId,
+                    'order_groupby' => $params['orderGroupId'],
+                    'join_order_member_id' => $params['join_order_member_id'],
+                    'order_name' => date('Y-m-d H:i:s') . '-订单',
+                    'order_amount_total' => floatval($goods['goods_sales_price']) * $goods['nbr'],
+                    'order_amount_pay' => $amountPay,
+                    'order_category' => $goods['goods_classify'],
+                    'order_classify' => $goods['goods_classify'],
+                    'order_is_complete' => $params['order_is_complete'] ?? 'N',
+                    'order_status_system' => $params['order_status_system'],
+                    'order_status_payment' => $params['order_status_payment'],
+                    'order_status_storage' => $params['order_status_storage'],
+                    'order_platform' => $params['order_platform'],
+                    'order_remark' => $params['order_remark'] ?? '',
+                    'order_discount_json' => json_encode($discountJson),
+                    'order_config_json' => $params['order_config_json'] ?? '[]',
+                    'order_express_json' => $params['order_express_json'] ?? '[]',
+                    'order_extend_json' => $params['order_extend_json'] ? json_encode($params['order_extend_json']) : '[]',
+                    'order_addtimes' => time()
+                ];
+
+                Order::insert($data);
+
+                $sheetIds = $this->insertSheetOne($params, $goods, $orderId, $amountPay);
+
+                $this->insertPayDetailOne($params, $orderId, $amountPay, $goods);
+
+                $params['order_express_goods'] = json_encode(['sheet' => $sheetIds]);
+
+                $this->insertExpressOne($params, $orderId);
+            }
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('订单创建信息失败');
+        }
+    }
+
+    /**
+     * @Desc 扣除账户金额
+     * @Author Gorden
+     * @Date 2024/9/26 14:16
+     *
+     * @param $accountNbr
+     * @param $amount
+     * @return void
+     */
+    public function deductAmount($accountNbr, $amount)
+    {
+        try {
+            $account = MemberAccount::where('member_account_nbr', $accountNbr)->first();
+            $account->member_account_expend = $account->member_account_expend + $amount;
+            if ($account->member_account_surplus < $amount && strpos($accountNbr, 'CASH') !== false) {
+                $account->member_account_added = $account->member_account_added - ($amount - $account->member_account_surplus);
+                $account->member_account_surplus = 0;
+            } else {
+                $account->member_account_surplus = $account->member_account_surplus - $amount;
+            }
+
+            $account->save();
+        } catch (\Exception $e) {
+            _syslog("下单扣款", "扣款失败");
+
+            throw new BusinessException("账户扣款失败");
+        }
+    }
+
+    /**
+     * @Desc 打小票
+     * @Author Gorden
+     * @Date 2024/9/24 9:35
+     *
+     * @param $params
+     * @param $premises
+     * @param $orderId
+     * @return void
+     */
+    public function printerTicket($params, $premises, $orderId)
+    {
+        // 打小票
+        if ($params['order_status_payment'] == 'SUCCESS') {
+            if (!empty($premises) && !empty($premises->dept_id)) {
+                $voteData = [
+                    'func' => 'procActionToPrinter',
+                    'sign' => '',
+                    'data' => [
+                        'printer_premises' => $premises->dept_id,
+                        'printer_device' => ["收银"],
+                        'printer_action' => 'ExecPrintOrder',
+                        'printer_data' => [
+                            'order_id' => $orderId,
+                            'order_batch' => ''
+                        ]
+                    ]
+                ];
+                http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+            }
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:25
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertSheet($params)
+    {
+        try {
+            $orderSheetIds = [];
+            foreach ($params['goodsContentList'] as $goods) {
+                //{"unit": "份", "table": null, "premises": "15"}
+                $price = floatval($goods['goods_sales_price']);
+                $extendJson['unit'] = $goods['sku_name'];
+                if (isset($params['submit_premises_id'])) {
+                    $extendJson['premises'] = $params['submit_premises_id'];
+                }
+                if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                    $extendJson['table'] = null;
+                }
+                $data = [
+                    'join_sheet_member_id' => $params['join_order_member_id'],
+                    'join_sheet_order_id' => $params['orderId'],
+                    'join_sheet_goods_id' => $goods['goods_id'],
+                    'join_sheet_goods_sku_id' => $goods['sku_id'],
+                    'order_sheet_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
+                    'order_sheet_category' => (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') ? 'DISHES' : 'NORMAL',
+                    'order_sheet_num' => $goods['nbr'],
+                    'order_sheet_price' => $goods['goods_sales_price'],
+                    'order_sheet_amount' => $price * $goods['nbr'],
+                    'order_sheet_pay' => $price * $goods['nbr'],
+                    'order_sheet_task_status' => 'NONE',
+                    'order_sheet_remark' => $params['order_remark'] ?? '',
+                    'order_sheet_addtimes' => time(),
+                    'order_sheet_extend_json' => json_encode($extendJson)
+                ];
+
+                $orderSheetId = OrderSheet::insertGetId($data);
+                $orderSheetIds[] = $orderSheetId;
+
+                // 减库存,规格和总库存
+                if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                    $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                    $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                    if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                        $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                    }
+
+                    if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                        throw new BusinessException('库存不足');
+                    }
+                    $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
+                    $goodsSku->save();
+                }
+
+
+                $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+                $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+                if ($goodsRunning->goods_running_storage < 0) {
+                    throw new BusinessException('库存不足');
+                }
+                $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
+                $goodsRunning->save();
+            }
+//            return $orderSheetIds;
+        } catch (\support\exception\BusinessException $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException('订单创建失败');
+        }
+    }
+
+    /**
+     * @Desc 单条入库
+     * @Author Gorden
+     * @Date 2024/9/23 10:19
+     *
+     * @param $params
+     * @return array
+     * @throws BusinessException
+     */
+    public function insertSheetOne($params, $goods, $orderId, $amountPay)
+    {
+        try {
+            $orderSheetIds = [];
+//            foreach ($params['goodsContentList'] as $goods) {
+            //{"unit": "份", "table": null, "premises": "15"}
+            $price = floatval($goods['goods_sales_price']);
+            $extendJson['unit'] = $goods['sku_name'];
+            if (isset($params['submit_premises_id'])) {
+                $extendJson['premises'] = $params['submit_premises_id'];
+            }
+            if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                $extendJson['table'] = null;
+            }
+            $data = [
+                'join_sheet_member_id' => $params['join_order_member_id'],
+                'join_sheet_order_id' => $orderId,
+                'join_sheet_goods_id' => $goods['goods_id'],
+                'join_sheet_goods_sku_id' => $goods['sku_id'],
+                'order_sheet_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
+                'order_sheet_category' => (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') ? 'DISHES' : 'NORMAL',
+                'order_sheet_num' => $goods['nbr'],
+                'order_sheet_price' => $goods['goods_sales_price'],
+                'order_sheet_price_pay' => round($amountPay / $goods['nbr'], 2),
+                'order_sheet_amount' => $price * $goods['nbr'],
+                'order_sheet_pay' => $amountPay,
+                'order_sheet_task_status' => 'NONE',
+                'order_sheet_remark' => $params['order_remark'] ?? '',
+                'order_sheet_addtimes' => time(),
+                'order_sheet_extend_json' => json_encode($extendJson)
+            ];
+
+            $orderSheetId = OrderSheet::insertGetId($data);
+            $orderSheetIds[] = $orderSheetId;
+
+            // 减库存,规格和总库存
+            if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                    $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                }
+
+                if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                    throw new BusinessException('库存不足');
+                }
+                $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
+                $goodsSku->save();
+            }
+
+
+            $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+            $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+            if ($goodsRunning->goods_running_storage < 0) {
+                throw new BusinessException('库存不足');
+            }
+            $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
+            $goodsRunning->save();
+//            }
+            return $orderSheetIds;
+        } catch (\support\exception\BusinessException $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException('订单创建失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:35
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertPayDetail($params)
+    {
+        try {
+            if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                $payPrepayid = $params['pay_category'];
+            } else if ($params['pay_category'] == 'OFFLINE') {
+                $payPrepayid = 'OFFLINE';
+            } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                $payPrepayid = 'OFFLINE_ALIPAY';
+            } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                $payPrepayid = 'OFFLINE_WXPAY';
+            } else if ($params['pay_category'] == 'MONEY') {
+                $payPrepayid = 'MONEY';
+            } else {
+                $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
+            }
+            $data = [
+                'join_pay_member_id' => $params['join_order_member_id'],
+                'join_pay_order_id' => $params['orderGroupId'],
+                'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                'pay_category' => $params['goods_classify'],
+                'pay_amount' => $params['order_amount_pay'],
+                'pay_prepayid' => $payPrepayid,
+                'pay_paytimes' => date('Y-m-d H:i:s'),
+                'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]',
+                'pay_json_request' => json_encode($params),
+                'pay_json_response' => $params['pay_json_response'] ?? '[]',
+                'pay_remark' => $params['order_remark'] ?? '',
+                'pay_addtimes' => time(),
+            ];
+
+            PayDetail::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建支付记录失败');
+        }
+    }
+
+    /**
+     * @Desc 单条入库
+     * @Author Gorden
+     * @Date 2024/6/7 10:35
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertPayDetailOne($params, $orderId, $amountPay, $goods)
+    {
+        try {
+            if (!empty($params['pay_detail_item'])) {
+                foreach ($params['pay_detail_item'] as $item) {
+                    $data = [
+                        'join_pay_member_id' => $item['join_order_member_id'],
+                        'join_pay_order_id' => $item['orderGroupId'],
+                        'pay_status' => $item['settlement_now'] == 'Y' && $item['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                        'pay_category' => $goods['goods_classify'],
+                        'pay_amount' => round(($amountPay / $params['order_amount_pay']) * $item['order_amount_pay'], 2),
+                        'pay_prepayid' => $item['pay_category'],
+                        'pay_paytimes' => date('Y-m-d H:i:s'),
+                        'join_pay_object_json' => !empty($item['orderId']) ? json_encode(['order_id' => $orderId]) : '[]',
+                        'pay_json_request' => json_encode($item),
+                        'pay_json_response' => $item['pay_json_response'] ?? '[]',
+                        'pay_remark' => $item['order_remark'] ?? '',
+                        'pay_addtimes' => time(),
+                    ];
+                    PayDetail::insert($data);
+                }
+            } else {
+                if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                    $payPrepayid = $params['pay_category'];
+                } else if ($params['pay_category'] == 'OFFLINE') {
+                    $payPrepayid = 'OFFLINE';
+                } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                    $payPrepayid = 'OFFLINE_ALIPAY';
+                } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                    $payPrepayid = 'OFFLINE_WXPAY';
+                } else if ($params['pay_category'] == 'MONEY') {
+                    $payPrepayid = 'MONEY';
+                } else {
+                    $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
+                }
+                $data = [
+                    'join_pay_member_id' => $params['join_order_member_id'],
+                    'join_pay_order_id' => $params['orderGroupId'],
+                    'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                    'pay_category' => $goods['goods_classify'],
+                    'pay_amount' => $amountPay,
+                    'pay_prepayid' => $payPrepayid,
+                    'pay_paytimes' => date('Y-m-d H:i:s'),
+                    'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $orderId]) : '[]',
+                    'pay_json_request' => json_encode($params),
+                    'pay_json_response' => $params['pay_json_response'] ?? '[]',
+                    'pay_remark' => $params['order_remark'] ?? '',
+                    'pay_addtimes' => time(),
+                ];
+
+                PayDetail::insert($data);
+            }
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建支付记录失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:50
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertAppointment($params, $writeOffDate, $applyData = [])
+    {
+        try {
+            $data = [
+                'appointment_id' => $params['appointmentId'],
+                'join_appointment_member_id' => $params['join_order_member_id'],
+                'join_appointment_goods_id' => $params['join_sheet_goods_id'],
+                'join_appointment_goods_sku_id' => $params['join_sheet_goods_sku_id'],
+                'join_appointment_order_id' => $params['orderId'],
+                'join_appointment_member_benefit_id' => $params['benefitId'],
+                'appointment_classify' => $params['goods_classify'],
+                'appointment_status' => 'INIT',
+                'appointment_category' => 'NORMAL',
+                'appointment_platform' => 'SYSTEM',
+                'appointment_addtimes' => time(),
+                'appointment_datetime' => '',
+                'appointment_apply_datetime' => '',
+                'appointment_apply_json' => '[]',
+                'appointment_done_datetime' => '',
+                'appointment_remark' => $params['order_remark'] ?? '',
+                'appointment_done_json' => '[]'
+            ];
+            Appointment::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException("创建权益记录失败");
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 11:05
+     *
+     * @param $params
+     * @param $goods
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertMemberBenefit($params, $goods)
+    {
+        try {
+            $data = [
+                'member_benefit_id' => $params['benefitId'],
+                'join_benefit_member_id' => $params['join_order_member_id'],
+                'join_benefit_package_id' => $params['packageId'] ?? '',
+                'join_benefit_goods_id' => $goods['goods_id'],
+                'join_benefit_goods_sku_id' => $goods['skuId'] ?? '',
+                'join_benefit_order_id' => $params['orderId'],
+                'member_benefit_status' => 'ACTIVED',
+                'member_benefit_category' => $goods['category'],
+                'member_benefit_name' => $goods['goods_name'],
+                'member_benefit_limit_count' => $params['order_sheet_num'],
+                'member_benefit_used_count' => 0,
+                'member_benefit_remark' => $params['order_remark'] ?? '',
+                'member_benefit_addtimes' => time()
+            ];
+            MemberBenefit::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建会员权益失败');
+        }
+    }
+
+
+    public function saveExpress($params, $orderId)
+    {
+        try {
+            $express = new OrderExpress();
+            $express->order_express_type = $params['order_express_type'];
+            $express->join_express_order_id = $orderId;
+            $express->join_express_dept_id = $params['submit_premises_id'] ?? 0;
+            $express->order_express_goods = $params['order_express_goods'];
+            $express->order_express_city = $params['order_express_city'];
+            $express->order_express_address = $params['order_express_address'];
+            $express->order_express_mobile = $params['order_express_mobile'] ?? '';
+            $express->order_express_telephone = $params['order_express_telephone'] ?? '';
+            $express->order_express_person = $params['order_express_person'] ?? '';
+            $express->order_express_company = $params['dept_premises_id'] ?? '';
+            $express->order_express_extend_json = $params['order_express_extend_json'] ?? '[]';
+            $express->order_express_addtimes = time();
+            $express->save();
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('物流信息保存失败');
+        }
+    }
+
+    /**
+     * @Desc 修改优惠券状态
+     * @Author Gorden
+     * @Date 2024/9/19 9:03
+     *
+     * @param $coupon
+     * @param $status
+     * @return void
+     */
+    private function changeOrderCouponStatus($coupon, $status)
+    {
+        if (!empty($coupon) && is_array($coupon)) {
+            $updateData['coupon_detail_status'] = $status;
+            if ($status == 'ACTIVED' || $status == 'WAITING') {
+                $updateData['coupon_detail_used_datetime'] = '';
+            } elseif ($status == 'USED') {
+                $updateData['coupon_detail_used_datetime'] = date('Y-m-d H:i:s');
+            }
+            foreach ($coupon as $item) {
+                if (!empty($item['coupon_id']) && !empty($item['coupon_detail_id'])) {
+                    foreach ($item['coupon_detail_id'] as $detailId) {
+                        CouponDetail::where('join_detail_coupon_id', $item['coupon_id'])
+                            ->where('coupon_detail_id', $detailId)->update($updateData);
+                    }
+                }
+            }
+        }
+    }
+
+
+    private function discountRecord($orderDiscountJson, $params)
+    {
+        $json = [];
+        if (!empty($orderDiscountJson)) {
+            $json = json_decode($orderDiscountJson, true);
+        }
+        try {
+            if (!empty($params['preferential']) && in_array('wipe', $params['preferential'])) {
+                if (intval($params['order_amount_total'] / 10) * 10 != $params['order_amount_pay']) {
+                    throw new BusinessException("抹零后实际支付金额错误");
+                }
+                $params['order_discount_amount'] = $params['order_amount_total'] - $params['order_amount_pay'];
+                $couponClassifyDesc = $couponClassify = '抹零';
+            } elseif (!empty($params['preferential']) && in_array('custom', $params['preferential'])) {
+                if (sprintf("%.2f", $params['order_amount_total'] - $params['order_discount_amount']) != sprintf("%.2f", $params['order_amount_pay'])) {
+                    throw new BusinessException("餐厅前台优惠后实际支付金额错误");
+                }
+                $couponClassifyDesc = $couponClassify = '餐厅前台优惠';
+            } else if (!empty($params['preferential']) && intval($params['preferential'][0]) < 100 && intval($params['preferential'][0]) >= 50) {
+                if (($params['order_amount_total'] * intval($params['preferential'][0])) / 100 != $params['order_amount_pay']) {
+                    throw new BusinessException("折扣后实际支付金额错误");
+                }
+                $couponClassify = '折扣';
+                $couponClassifyDesc = intval($params['preferential'][0]) / 10 . '折';
+                $params['order_discount_amount'] = $params['order_amount_total'] - $params['order_amount_pay'];
+            } else {
+                return $json;
+            }
+            $json[date('Y-m-d H:i:s')] = [
+                'coupon_id' => $params['coupon_id'] ?? null,
+                'coupon_value' => $params['order_discount_amount'] ?? '',
+                'coupon_classify' => $couponClassify,
+                'coupon_detail_id' => [$couponClassifyDesc],
+                'coupon_classify_en' => $params['preferential']
+            ];
+            return $json;
+        } catch (BusinessException $e) {
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException("优惠数据错误");
+        }
+    }
+
+    /**
+     * @Desc 入配送记录
+     * @Author Gorden
+     * @Date 2024/9/23 10:45
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertExpressOne($params, $orderId)
+    {
+        if (isset($params['delivery']) && $params['delivery'] == 'LOGISTICS') {
+            $params['order_express_type'] = '配送';
+            // 入配送
+            $this->saveExpress($params, $orderId);
+        } else if (isset($params['delivery']) && $params['delivery'] == 'PICKUP') {
+            $params['order_express_type'] = '自提';
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+            if (!$premises) {
+                throw new BusinessException('自提门店不存在');
+            }
+
+            $params['order_express_city'] = $premises->dept_city;
+            $params['order_express_address'] = $premises->dept_address;
+            $params['order_express_telephone'] = $premises->dept_telephone;
+            $params['order_express_extend_json'] = json_encode(['pick_code' => random_string(4, 'number')]);
+
+            $this->saveExpress($params, $orderId);
+        } else if (isset($params['delivery']) && $params['delivery'] == 'ARRIVAL') {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+            $params['order_express_type'] = '到店';
+            if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                $params['order_express_type'] = '堂食';
+            }
+            if (!$premises) {
+                throw new BusinessException('门店不存在');
+            }
+
+            $params['order_express_city'] = $premises->dept_city;
+            $params['order_express_address'] = $premises->dept_address;
+            $params['order_express_telephone'] = $premises->dept_telephone;
+
+            $this->saveExpress($params, $orderId);
+        }
+    }
+
+    /**
+     * @Desc 释放下单时选的优惠券
+     * @Author Gorden
+     * @Date 2024/9/19 9:56
+     *
+     * @param $coupon
+     * @return false|string
+     */
+    private function releaseCoupon($coupon)
+    {
+        if (!empty($coupon) && is_array($coupon)) {
+            $updateData = [
+                'coupon_detail_status' => 'ACTIVED',
+                'coupon_detail_used_datetime' => ''
+            ];
+            foreach ($coupon as $key => $item) {
+                if (!empty($item['coupon_id']) && !empty($item['coupon_detail_id'])) {
+                    foreach ($item['coupon_detail_id'] as $detailId) {
+                        if (substr($detailId, 0, 4) == 'CUDT') {
+                            CouponDetail::where('join_detail_coupon_id', $item['coupon_id'])
+                                ->where('coupon_detail_id', $detailId)
+                                ->where('coupon_detail_status', 'WAITING')
+                                ->update($updateData);
+                        }
+                    }
+                    unset($coupon[$key]);
+                }
+            }
+        }
+
+        return json_encode($coupon);
+    }
 }

+ 12 - 9
app/admin/controller/order/KangyangCityController.php

@@ -78,7 +78,7 @@ class KangyangCityController extends Curd
             $goodsOrderIds = OrderSheet::whereIn('join_sheet_goods_id', $goodsIds)->pluck('join_sheet_order_id')->toArray();
             if (!empty($where['order_id'])) {
                 $orderIds = array_intersect($orderIds, $goodsOrderIds);
-            }else{
+            } else {
                 $orderIds = $goodsOrderIds;
             }
         }
@@ -255,16 +255,13 @@ class KangyangCityController extends Curd
                 $params['orderId'] = $paidOrder->order_id;
             }
 
-            $systemStatus = 'SENDING';  // 待发货
+            $systemStatus = 'PAYING';  // 待发货
             // 立即结算
             if ($params['settlement_now'] == 'Y') {
                 if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'VIP'])) {
                     $params['order_is_complete'] = 'Y';
                     $systemStatus = 'DONE';
                 }
-                if ($params['goods_classify'] == 'PACKAGE' && $params['delivery'] == 'ARRIVAL') {
-                    $systemStatus = "WAITING";
-                }
             }
 
             if ($params['settlement_now'] == 'Y' && ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY')) {
@@ -649,9 +646,9 @@ class KangyangCityController extends Curd
                 'order_amount_paid' => $params['order_amount_pay'],
                 'order_category' => $orderCategory,
                 'order_classify' => $orderCategory,
-                'order_is_complete' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) ? 'Y' : 'N',
-                'order_status_system' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) ? 'DONE' : 'PAYING',
-                'order_status_payment' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) ? 'SUCCESS' : 'PENDING',
+                'order_is_complete' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) && $params['order_status_payment'] == 'SUCCESS' ? 'Y' : 'N',
+                'order_status_system' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
+                'order_status_payment' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'PENDING',
                 'order_status_storage' => $params['order_status_storage'],
                 'order_platform' => $params['order_platform'],
                 'order_remark' => $params['order_remark'] ?? '',
@@ -957,10 +954,16 @@ class KangyangCityController extends Curd
                         }
                     }
                 }
-                $item['member']['level'] = '普通用户';
+                $item['member']['level'] = '普通会员';
                 if (!empty($item['member']['join_member_role_id'])) {
                     $item['member']['level'] = MemberRole::where('member_role_id', $item['member']['join_member_role_id'])->value('member_role_name');
                 }
+
+                if (!empty($item['member_info'])){
+                    if (empty($item['member_info']['member_info_headimg']) || substr($item['member_info']['member_info_headimg'],0,1) == '.'){
+                        $item['member_info']['member_info_headimg'] = "https://img.wanyuewellness.com.cn/images/avatar_default.png";
+                    }
+                }
             }
             $order->sheet_amount = number_format($sheetAmount, 2);
 

+ 2377 - 7
app/admin/controller/order/PackagesController.php

@@ -3,15 +3,20 @@
 namespace app\admin\controller\order;
 
 use app\admin\service\coupon\CouponService;
+use app\admin\service\member\MemberService;
 use app\admin\service\order\OrderService;
 use app\admin\validate\order\OrderValidate;
 use app\controller\Curd;
 use app\model\Appointment;
 use app\model\ClientConfig;
 use app\model\Coupon;
+use app\model\CouponDetail;
 use app\model\Goods;
 use app\model\GoodsComponent;
+use app\model\GoodsRunning;
+use app\model\GoodsSku;
 use app\model\Member;
+use app\model\MemberAccount;
 use app\model\MemberBenefit;
 use app\model\MemberRole;
 use app\model\Order;
@@ -23,6 +28,7 @@ use app\model\Supplier;
 use app\model\SysDept;
 use app\model\SysUser;
 use support\Db;
+use support\exception\BusinessException;
 use support\Redis;
 use support\Request;
 use support\Response;
@@ -78,7 +84,7 @@ class PackagesController extends Curd
             $goodsOrderIds = OrderSheet::whereIn('join_sheet_goods_id', $goodsIds)->pluck('join_sheet_order_id')->toArray();
             if (!empty($where['order_id'])) {
                 $orderIds = array_intersect($orderIds, $goodsOrderIds);
-            }else{
+            } else {
                 $orderIds = $goodsOrderIds;
             }
         }
@@ -128,12 +134,12 @@ class PackagesController extends Curd
         ])->leftJoin('order_return', 'order_return.join_return_order_id', '=', 'order.order_id')
             ->leftJoin('order_express', 'order_express.join_express_order_id', '=', 'order.order_id');
         // ->leftJoin('order_sheet','join_sheet_order_id','=','order.order_id');
-        if (isset($where['order_status_system']) && $where['order_status_system'] == 'DONE'){
-            $model = $model->where(function($query){
-                $query->where('order_status_system','DONE')
-                ->orWhere(function($query2){
-                    $query2->where('order_status_system','CONFIRM')->where('order_is_complete','Y');
-                });
+        if (isset($where['order_status_system']) && $where['order_status_system'] == 'DONE') {
+            $model = $model->where(function ($query) {
+                $query->where('order_status_system', 'DONE')
+                    ->orWhere(function ($query2) {
+                        $query2->where('order_status_system', 'CONFIRM')->where('order_is_complete', 'Y');
+                    });
             });
             unset($where['order_status_system']);
         }
@@ -198,6 +204,13 @@ class PackagesController extends Curd
                     'order_return_remark' => $item['order_return_remark']
                 ];
             }
+            $item['have_success_paydetail'] = 'N';
+            if (PayDetail::where('join_pay_order_id', $item['order_groupby'])
+                ->whereJsonContains('join_pay_object_json->order_id', $item['order_id'])
+                ->where('pay_status', 'SUCCESS')
+                ->exists()) {
+                $item['have_success_paydetail'] = 'Y';
+            }
         }
 
         return $items;
@@ -326,4 +339,2361 @@ class PackagesController extends Curd
             return json_fail('核销失败');
         }
     }
+
+    /**
+     * @Desc 下单+支付
+     * @Author Gorden
+     * @Date 2024/9/23 16:15
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function insert(Request $request): Response
+    {
+        $params = $request->post();
+        // 判断餐品是否连带着服务或实体
+        $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
+        $premises = [];
+        if (!empty($params['dept_premises_id'])) {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+        }
+
+        if (in_array('PACKAGE', $goodsClassifys)) {
+            $params['submit_goods_classify'] = 'PACKAGE';
+        }
+        $params['goods_classify'] = $goodsClassifys[0];
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('insert', $params['settlement_now'], $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            $params['order_discount_json'] = json_encode($this->discountRecord($couponUseJson, $params));
+            // 验证库存
+            foreach ($params['goodsContentList'] as $goods) {
+                // 减库存,规格和总库存
+                if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                    $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                    $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                    if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                        $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                    }
+                    if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                        throw new BusinessException('库存不足');
+                    }
+                }
+
+
+                $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+                $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+                if ($goodsRunning->goods_running_storage < 0) {
+                    throw new BusinessException('库存不足');
+                }
+            }
+            // 余额、福利、储值卡 验证短信
+            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE', 'VIP'])) {
+                $code = $params['sms_code'];
+                if (!$code) {
+                    throw new BusinessException('验证码错误,请重新输入');
+                }
+                $member = Member::find($params['join_order_member_id']);
+                $mobile = $member->member_mobile;
+                $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+                $redisCode = Redis::get($key);
+                if ($redisCode != $code && $code != '123456') {
+                    throw new BusinessException('验证码错误,请重新输入');
+                }
+                Redis::del($key);
+            }
+            // 验证线下付款密码
+            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
+                $password = $params['offline_password'];
+                if ($password != '666888') {
+                    throw new BusinessException('密码错误,请重新输入');
+                }
+            }
+            // 下单账户
+            if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
+                if (Member::where('member_mobile', $params['mobile'])->exists()) {
+                    throw new BusinessException('会员已存在');
+                }
+                $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
+                // 创建会员
+                MemberService::createMember($params);
+            } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
+                $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
+            }
+            if (empty($params['join_order_member_id'])) {
+                throw new BusinessException('检查下单账户');
+            }
+
+            $qrcodePayAmount = 0;
+            $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+
+            $systemStatus = 'SENDING';  // 待发货
+            // 立即结算
+            if ($params['settlement_now'] == 'Y') {
+                if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+                    $params['order_is_complete'] = 'Y';
+                    $systemStatus = 'DONE';
+                }
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+                    $params['order_is_complete'] = 'N';
+                    $systemStatus = "WAITING";
+                }
+            }
+
+            if ($params['settlement_now'] == 'Y' && ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY')) {
+                if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
+                    $params['pay_category'] = $params['pay_category_sub'];
+                }
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'CASH') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'VIP') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'VIP')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'WELFARE') {  // 福利账户
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'WELFARE')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $account->member_account_surplus = floatval($account->member_account_surplus);
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    throw new BusinessException('账户余额不足');
+                }
+
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                // 福利账户 300 、 700
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS'])) {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 700 - $paySum < $params['order_amount_pay']) {
+                        Db::rollBack();
+                        return json_fail('超出福利限额');
+                    }
+                } else {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereNotIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES', 'REFUND', 'RECHARGE'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 300 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    }
+                }
+
+                $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'CARD') {  // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            }
+            if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])) {     // 付款码
+                if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount <= 0) {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                // 不组合或者组合后需要付款码的金额>0
+                if ($params['pay_constitute'] == 'N' || ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0)) {
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException('付款码无效');
+                    }
+                }
+            }
+
+            $orderConfigJson = [];
+            // 优惠
+            if (!empty($params['preferential'])) {
+                $orderConfigJson['preferential'] = $params['preferential'];
+            }
+
+            // 配送方式
+            if (isset($params['delivery']) && ($params['delivery'] == 'PICKUP' || $params['delivery'] == 'ARRIVAL')) { // 自提/ 到店
+                $orderConfigJson['premises'] = $params['dept_premises_id'];
+            }
+
+            if (isset($params['delivery']) && in_array($params['delivery'], ['PICKUP', 'ARRIVAL']) && !empty($params['dept_premises_id'])) {
+                $params['submit_premises_id'] = $premises->dept_id;
+            }
+
+            $params['order_config_json'] = json_encode($orderConfigJson);
+            // 写入订单
+            $this->insertMain($params);
+
+            Db::commit();
+
+            // 会员升级
+            if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                Event::dispatch('order.complete', $params);
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+
+            if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "创建订单成功");
+            return json_success('创建订单成功');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            dump($e->getTrace());
+            _syslog("订单", $e->getMessage());
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            dump($e->getTrace());
+            _syslog("订单", "创建订单失败");
+            return json_fail('创建订单失败');
+        }
+    }
+
+    /**
+     * 组合支付下单
+     */
+    public function insertConstitute(Request $request): Response
+    {
+        $params = $request->post();
+        $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
+        $premises = [];
+        if (!empty($params['dept_premises_id'])) {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+        }
+        if (in_array('PACKAGE', $goodsClassifys)) {
+            $params['submit_goods_classify'] = 'PACKAGE';
+        }
+
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('insert', $params['settlement_now'], $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            $params['order_discount_json'] = json_encode($this->discountRecord($couponUseJson, $params));
+            $orderAmountPay = $params['order_amount_pay'];
+            $constituteList = array_column($params['pay_category_constitute_list'], 'amount', 'category');
+            // 验证金额
+            $constituteAmount = 0;
+            foreach ($params['pay_category_constitute_list'] as $item) {
+                $constituteAmount = sprintf("%.2f", $constituteAmount) + sprintf("%.2f", $item['amount']);
+            }
+            if (sprintf("%.2f", $params['order_amount_pay']) != sprintf("%.2f", $constituteAmount)) {
+                throw new BusinessException('组合支付金额与应付金额不一致');
+            }
+            $params['goods_classify'] = $goodsClassifys[0];
+            // 验证库存
+            OrderService::checkGoodsStorage($params);
+            // 余额、福利、储值卡 验证短信
+            if (!empty($params['pay_category_constitute'])
+                && !in_array('OFFLINE', $params['pay_category_constitute'])
+                && !in_array('MONEY', $params['pay_category_constitute'])
+                && !in_array('QRCODE', $params['pay_category_constitute'])
+                && (in_array('CASH', $params['pay_category_constitute'])
+                    || in_array('CARD', $params['pay_category_constitute'])
+                    || in_array('WELFARE', $params['pay_category_constitute']))) {
+                $code = $params['sms_code'];
+                if (!$code) {
+                    throw new BusinessException("验证码错误,请重新输入");
+                }
+                $member = Member::find($params['join_order_member_id']);
+                $mobile = $member->member_mobile;
+                $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+                $redisCode = Redis::get($key);
+                if ($redisCode != $code && $code != '123456') {
+                    throw new BusinessException("验证码错误,请重新输入");
+                }
+                Redis::del($key);
+            }
+            // 验证线下付款密码
+            if (!empty($params['pay_category_constitute'])
+                && in_array('OFFLINE', $params['pay_category_constitute'])
+                || (in_array('MONEY', $params['pay_category_constitute']) && !in_array('QRCODE', $params['pay_category_constitute']))) {
+                $password = $params['offline_password'];
+                if ($password != '666888') {
+                    throw new BusinessException("密码错误,请重新输入");
+                }
+            }
+            // 下单账户
+            if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
+                if (Member::where('member_mobile', $params['mobile'])->exists()) {
+                    throw new BusinessException("会员已存在");
+                }
+                $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
+                // 创建会员
+                MemberService::createMember($params);
+            } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
+                $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
+            }
+            if (empty($params['join_order_member_id'])) {
+                throw new BusinessException("检查下单账户");
+            }
+
+            $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+
+            $systemStatus = 'SENDING';  // 待发货
+            // 立即结算
+            if ($params['settlement_now'] == 'Y') {
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+                    $params['order_is_complete'] = 'N';
+                    $systemStatus = "WAITING";
+                }
+            }
+            $params['pay_detail_item'] = [];
+            $wxAndAliPayStatus = 'Y';
+            if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute'])) {      // 线下支付
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['pay_category'] = $params['pay_category_sub'] ?? 'OFFLINE';
+
+                // 线下支付金额
+                if (isset($constituteList['OFFLINE'])) {
+                    $params['order_amount_pay'] = $constituteList['OFFLINE'];
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {      // 现金支付
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['pay_category'] = 'MONEY';
+
+                // 现金支付金额
+                if (isset($constituteList['MONEY'])) {
+                    $params['order_amount_pay'] = $constituteList['MONEY'];
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CASH', $params['pay_category_constitute'])) {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException("账户异常");
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+
+                if (isset($constituteList['CASH'])) {
+                    $params['order_amount_pay'] = $constituteList['CASH'];
+                    $params['pay_category'] = $params['join_order_member_id'] . '-CASH';
+                }
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException("账户余额不足");
+                }
+//                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+//                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+//                    $params['order_amount_pay'] = $amount;
+//                }
+//                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+//                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+//                    $account->member_account_surplus = 0;
+//                    $account->member_account_added = $cut;
+//                } else {
+//                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+//                }
+//                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+//                $account->save();
+                // 余额账户扣款数据
+                $params['waitToPayAccount']['cash'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CASH'],
+                    'nbr' => $params['join_order_member_id'] . '-CASH'
+                ];
+
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+
+                // 生成支付记录
+                $params['pay_detail_item'][] = $params;
+                $params['order_amount_pay'] = $orderAmountPay;
+
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CARD', $params['pay_category_constitute'])) {    // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException("储值卡账户异常");
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException("储值卡账户异常");
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+
+                // 储值卡账户支付金额
+                if (isset($constituteList['CARD'])) {
+                    $params['order_amount_pay'] = $constituteList['CARD'];
+                    $params['pay_category'] = $cardNbr;
+                }
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException("储值卡账户余额不足");
+                }
+//                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+//                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+//                    $params['order_amount_pay'] = $amount;
+//                }
+//
+//                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+//                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+//                    $account->member_account_surplus = 0;
+//                    $account->member_account_added = $cut;
+//                } else {
+//                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+//                }
+//                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+//                $account->save();
+                // 储值卡账户扣款数据
+                $params['waitToPayAccount']['card'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CARD'],
+                    'nbr' => $params['join_order_member_id'] . '-CARD'
+                ];
+
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                // 生成支付记录
+                $params['pay_detail_item'][] = $params;
+
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            //!empty($params['pay_category_constitute']) && in_array('CARD',$params['pay_category_constitute'])
+            // if(($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])){     // 付款码
+            if (!empty($params['pay_category_constitute']) && in_array('QRCODE', $params['pay_category_constitute']) && !empty($params['qrcode_nbr'])) {     // 付款码
+                // 需要付款码的金额>0
+                if (isset($constituteList['QRCODE']) && $constituteList['QRCODE'] > 0) {
+                    // 付款码支付金额
+                    $params['order_amount_pay'] = $constituteList['QRCODE'];
+                    // 调支付
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException("二维码错误");
+                    }
+
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                    // 账户支付的金额
+                    $params['order_amount_pay'] = $orderAmountPay;
+                }
+            }
+
+            $orderConfigJson = [];
+            // 优惠
+            if (!empty($params['preferential'])) {
+                $orderConfigJson['preferential'] = $params['preferential'];
+            }
+            $params['order_config_json'] = json_encode($orderConfigJson);
+            // 写入订单
+            $this->insertMain($params, $wxAndAliPayStatus);
+
+            Db::commit();
+
+            // 会员升级
+            if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                Event::dispatch('order.complete', $params);
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+
+            if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "创建订单成功");
+            return json_success('创建订单成功');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            _syslog("订单", $e->getMessage());
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            _syslog("订单", "创建订单失败");
+            return json_fail('创建订单失败');
+        }
+    }
+
+    public function pay(Request $request)
+    {
+        $params = $request->post();
+        // 余额、福利、储值卡 验证短信
+        if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE'])) {
+            $code = $params['sms_code'];
+            if (!$code) {
+                return json_fail("验证码错误,请重新输入");
+            }
+            $member = Member::find($params['join_order_member_id']);
+            $mobile = $member->member_mobile;
+            $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+            $redisCode = Redis::get($key);
+            if ($redisCode != $code && $code != '123456') {
+                return json_fail("验证码错误,请重新输入");
+            }
+            Redis::del($key);
+        }
+        // 验证线下付款密码
+        if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
+            $password = $params['offline_password'];
+            if ($password != '666888') {
+                return json_fail("密码错误,请重新输入");
+            }
+        }
+
+        $order = Order::where('order_id', $params['order_id'])->first();
+        if (!$order) {
+            return json_fail('订单异常');
+        }
+        if ($order->order_status_system != 'PAYING') {
+            return json_fail('订单不是可支付状态');
+        }
+
+        if (!empty($order->order_config_json)) {
+            $orderConfigJson = json_decode($order->order_config_json, true);
+            if (isset($orderConfigJson['premises'])) {
+                $premises = SysDept::where('dept_name', $orderConfigJson['premises'])->first();
+                if (!empty($premises)) {
+                    $params['submit_premises_id'] = $premises->dept_id;
+                }
+            }
+        }
+        $params['orderId'] = $params['order_id'];
+        $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+        $order->order_groupby = $params['orderGroupId'];
+
+        $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
+            ->select('goods_id', 'goods_name', 'goods_classify')
+            ->first();
+        if (!$goods) {
+            return json_fail('产品数据异常');
+        }
+        $goods = $goods->toArray();
+        $params['goods_classify'] = $goods['goods_classify'] ?? '';
+
+        $systemStatus = 'SENDING';  // 待发货
+        // 立即结算
+        if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+            $order->order_is_complete = 'Y';
+            $systemStatus = 'DONE';
+        }
+        if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+            $params['order_is_complete'] = 'N';
+            $systemStatus = "WAITING";
+        }
+//        if ($params['goods_classify'] == 'PACKAGE' && $params['delivery'] == 'ARRIVAL') {
+//            $systemStatus = "WAITING";
+//        }
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            $discountJson = [];
+            if (!empty($order->order_discount_json)) {
+                $discountJson = json_decode($order->order_discount_json, true);
+                foreach ($discountJson as $item) {
+                    if (isset($item['coupon_value']) && sprintf('%.2f', (floatval($order->order_amount_total) - floatval($params['order_amount_pay']))) != sprintf('%.2f', $item['coupon_value'])) {
+                        throw new BusinessException("计算优惠后,实付金额错误!");
+                    }
+                }
+                $couponUseJson = $discountJson;
+                $this->changeOrderCouponStatus($couponUseJson, 'USED');
+                // 释放下单时选的优惠券
+//                $order->order_discount_json = $this->releaseCoupon($discountJson);
+            }
+            if (empty($discountJson) && !empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('pay', 'Y', $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            if (empty($discountJson)) {
+                $order->order_discount_json = json_encode($this->discountRecord($couponUseJson, $params));
+            }
+            // 组合支付时,付款码应收金额
+            $qrcodePayAmount = 0;
+            if ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY') {
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
+                    $params['pay_category'] = $params['pay_category_sub'];
+                }
+            } else if ($params['pay_category'] == 'CASH') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            } else if ($params['pay_category'] == 'VIP') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'VIP')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            } else if ($params['pay_category'] == 'WELFARE') {  // 福利账户
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'WELFARE')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $account->member_account_surplus = floatval($account->member_account_surplus);
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $account->member_account_surplus;
+                    $params['order_amount_pay'] = $account->member_account_surplus;
+                }
+
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] <= $account->member_account_surplus)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+                // 福利账户 300 、 700
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS'])) {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 700 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    } else if ($params['pay_constitute'] == 'Y' && 700 - $paySum < $params['order_amount_pay']) {
+                        $qrcodePayAmount = $params['order_amount_pay'] - (700 - $paySum);
+                        $params['order_amount_pay'] = (700 - $paySum);
+                    }
+                } else {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereNotIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES', 'REFUND', 'RECHARGE'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 300 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    } else if ($params['pay_constitute'] == 'Y' && 300 - $paySum < $params['order_amount_pay']) {
+                        $qrcodePayAmount = $params['order_amount_pay'] - (300 - $paySum);
+                        $params['order_amount_pay'] = (300 - $paySum);
+                    }
+                }
+                $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+            } else if ($params['pay_category'] == 'CARD') {  // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            }
+            if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && !empty($params['qrcode_nbr'])) {     // 付款码
+                // 提交过来的支付分类
+                $submitPayCategory = $params['pay_category'];
+                // 账户支付的金额
+                $accountAmount = $params['order_amount_pay'];
+                if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0) {
+                    // 组合支付,改成需要付款码需要支付的金额
+                    $params['order_amount_pay'] = $qrcodePayAmount;
+                }
+                // 去支付
+                $result = OrderService::qrcodePay($params);
+                $result = json_encode($result);
+                $params['pay_json_response'] = $result;
+                $result = json_decode($result, true);
+
+                $prefix = substr($params['qrcode_nbr'], 0, 2);
+                if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                    $params['pay_category'] = 'WXPAY';
+                    if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                        $order->order_status_system = 'PAYING';
+                        $order->order_status_payment = 'PENDING';
+                        $order->order_is_complete = 'N';
+//                        Db::rollBack();
+//                        return json_fail('支付失败');
+                    } else {
+                        $order->order_status_system = $systemStatus;
+                        $order->order_status_payment = 'SUCCESS';
+                    }
+                } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                    $params['pay_category'] = 'ALIPAY';
+                    if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                        $order->order_status_system = 'PAYING';
+                        $order->order_status_payment = 'PENDING';
+                        $order->order_is_complete = 'N';
+//                        Db::rollBack();
+//                        return json_fail('支付失败');
+                    } else {
+                        $order->order_status_system = $systemStatus;
+                        $order->order_status_payment = 'SUCCESS';
+                    }
+                } else {
+                    throw new BusinessException('付款码无效');
+                }
+                // 账户支付的金额
+                $params['order_amount_pay'] = $accountAmount;
+            }
+            $orderConfigJson = [];
+            if (!empty($order->order_config_json)) {
+                $orderConfigJson = json_decode($order->order_config_json, true);
+            }
+            $orderConfigJson['preferential'] = $params['preferential'] ?? '';
+            $order->order_config_json = json_encode($orderConfigJson);
+            $order->order_amount_pay = $params['order_amount_pay'] + $qrcodePayAmount;
+            // 主订单
+            $order->save();
+
+            // sheet
+            if ($order->order_status_payment == 'SUCCESS') {
+                OrderSheet::where('join_sheet_order_id', $params['order_id'])->update([
+                    'order_sheet_status' => $systemStatus,
+                ]);
+            }
+            // payDetail
+            // 不组合支付,那就只有一条支付记录 先删,再加
+            PayDetail::where('join_pay_order_id', $order->order_groupby)
+                ->whereJsonContains('join_pay_object_json->order_id', $params['orderId'])
+                ->delete();
+            $payData = [
+                'pay_amount' => $params['order_amount_pay']
+            ];
+            if ($order->order_status_payment == 'SUCCESS') {
+                $payData['pay_paytimes'] = date('Y-m-d H:i:s');
+                $payData['pay_status'] = 'SUCCESS';
+            }
+            if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                $payData['pay_prepayid'] = $params['pay_category'];
+                $payData['pay_json_response'] = $params['pay_json_response'];
+            } else if ($params['pay_category'] == 'CASH') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-CASH';
+            } else if ($params['pay_category'] == 'WELFARE') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-WELFARE';
+            } else if ($params['pay_category'] == 'VIP') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-VIP';
+            } else if ($params['pay_category'] == 'CARD') {
+                $payData['pay_prepayid'] = $params['card_nbr'];
+            } else if ($params['pay_category'] == 'OFFLINE') {
+                $payData['pay_prepayid'] = 'OFFLINE';
+            } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                $payData['pay_prepayid'] = 'OFFLINE_ALIPAY';
+            } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                $payData['pay_prepayid'] = 'OFFLINE_WXPAY';
+            } else if ($params['pay_category'] == 'MONEY') {
+                $payData['pay_prepayid'] = 'MONEY';
+            }
+            $payData['join_pay_member_id'] = $params['join_order_member_id'];
+            $payData['join_pay_order_id'] = $order->order_groupby;
+            $payData['pay_status'] = !empty($payData['pay_status']) && $payData['pay_status'] == 'SUCCESS' ? $payData['pay_status'] : 'WAITING';
+            $payData['pay_category'] = $params['goods_classify'] ?? '';
+            $payData['pay_paytimes'] = date('Y-m-d H:i:s');
+            $payData['pay_json_request'] = json_encode($params);   // {"pay-result": "支付成功", "result-datetime": "2024-07-29 18:38:21"}
+            $payData['pay_json_response'] = !empty($payData['pay_status']) && $payData['pay_status'] == 'SUCCESS' ? (!empty($params['pay_json_response']) ? $params['pay_json_response'] : json_encode(['pay-result' => '支付成功', 'result-datetime' => date('Y-m-d H:i:s')])) : '[]';
+            $payData['join_pay_object_json'] = !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]';
+            $payData['pay_addtimes'] = time();
+            PayDetail::insert($payData);
+
+            $writeOffDate = [];
+            $applyData = [];
+            // // 买的单个服务
+            if ($order->order_status_payment == 'SUCCESS' && empty($appointment)) {
+                foreach ($params['goodsContentList'] as $goods) {
+                    $params['join_sheet_goods_id'] = $goods['goods_id'];
+                    if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD'])) {
+                        $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                        $params['order_sheet_num'] = $goods['nbr'];
+                        // 预约表
+                        for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                            $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                            // 入预约记录
+                            $this->insertAppointment($params, $writeOffDate, $applyData);
+                        }
+                        $goods['skuId'] = $goods['sku_id'];
+                        $goods['category'] = $goods['goods_classify'];
+                        // 权益表
+                        $this->insertMemberBenefit($params, $goods);
+                    } elseif (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE') {  // 一个套餐买多个
+                        $params['packageId'] = $goods['goods_id'];
+                        $components = GoodsComponent::with([
+                            'goods' => function ($query) {
+                                $query->select('goods_id', 'goods_name', 'goods_classify');
+                            }
+                        ])->where('join_component_master_goods_id', $params['packageId'])
+                            ->get()
+                            ->toArray();
+                        foreach ($components as $component) {
+                            $componentJson = json_decode($component['goods_component_json'], true);
+                            $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
+                            $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                            $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
+                            for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                                $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                                // 入预约记录
+                                $this->insertAppointment($params, $writeOffDate);
+                            }
+                            $goods['goods_id'] = $component['join_component_goods_id'];
+                            $goods['goods_name'] = $component['goods']['goods_name'];
+                            $goods['goods_classify'] = $component['goods']['goods_classify'];
+                            $goods['skuId'] = $goods['sku_id'];
+                            $goods['category'] = 'SERVICE';
+                            // 权益表
+                            $this->insertMemberBenefit($params, $goods);
+                        }
+                    }
+                }
+            }
+
+            Db::commit();
+
+            // 触发事件
+            if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                // 完成订单
+                Event::dispatch('order.complete', $params);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+            if ($order->order_status_payment == 'SUCCESS') {
+                // 上级提成
+                Event::dispatch('commission.order', $params);
+            }
+
+            // 打小票
+            if ($order->order_status_payment == 'SUCCESS') {
+                if (!empty($premises) && !empty($premises->dept_id)) {
+                    $voteData = [
+                        'func' => 'procActionToPrinter',
+                        'sign' => '',
+                        'data' => [
+                            'printer_premises' => $premises->dept_id,
+                            'printer_device' => ["收银"],
+                            'printer_action' => 'ExecPrintOrder',
+                            'printer_data' => [
+                                'order_id' => $params['orderId'],
+                                'order_batch' => ''
+                            ]
+                        ]
+                    ];
+//                    dump("小票参数", $voteData);
+                    http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+                }
+            }
+
+            if ($order->order_status_payment != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                // 如果下单时就填了,不用恢复
+                if (empty($discountJson)) {
+                    $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+                }
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "订单支付成功");
+            return json_success('支付成功');
+        } catch (BusinessException $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败:" . $e->getMessage());
+            return json_fail("支付失败:" . $e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败");
+            return json_fail('支付失败');
+        }
+    }
+
+
+    /**
+     * 组合支付
+     */
+    public function payConstitute(Request $request)
+    {
+        $params = $request->post();
+        // 余额、福利、储值卡 验证短信
+        if (!empty($params['pay_category_constitute']) && !in_array('OFFLINE', $params['pay_category_constitute']) && !in_array('MONEY', $params['pay_category_constitute']) && !in_array('QRCODE', $params['pay_category_constitute']) && (in_array('CASH', $params['pay_category_constitute']) || in_array('CARD', $params['pay_category_constitute']) || in_array('WELFARE', $params['pay_category_constitute']))) {
+            $code = $params['sms_code'];
+            if (!$code) {
+                return json_fail("验证码错误,请重新输入");
+            }
+            $member = Member::find($params['join_order_member_id']);
+            $mobile = $member->member_mobile;
+            $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+            $redisCode = Redis::get($key);
+            if ($redisCode != $code && $code != '123456') {
+                return json_fail("验证码错误,请重新输入");
+            }
+            Redis::del($key);
+        }
+        // 验证线下付款密码
+        if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {
+            $password = $params['offline_password'];
+            if ($password != '666888') {
+                return json_fail("密码错误,请重新输入");
+            }
+        }
+
+        $order = Order::where('order_id', $params['order_id'])->first();
+        if (!$order) {
+            return json_fail('订单异常');
+        }
+        if ($order->order_status_system != 'PAYING') {
+            return json_fail('订单不是可支付状态');
+        }
+        if (!empty($order->order_config_json)) {
+            $orderConfigJson = json_decode($order->order_config_json, true);
+            if (isset($orderConfigJson['premises'])) {
+                $premises = SysDept::where('dept_name', $orderConfigJson['premises'])->first();
+                if (!empty($premises)) {
+                    $params['submit_premises_id'] = $premises->dept_id;
+                }
+            }
+        }
+        $params['orderId'] = $params['order_id'];
+        $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+        $order->order_groupby = $params['orderGroupId'];
+
+        $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
+            ->select('goods_id', 'goods_name', 'goods_classify')
+            ->first();
+        if (!$goods) {
+            return json_fail('产品数据异常');
+        }
+        $goods = $goods->toArray();
+        $params['goods_classify'] = $goods['goods_classify'];
+
+        $systemStatus = 'SENDING';  // 待发货
+        // 立即结算
+        if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+            $order->order_is_complete = 'Y';
+            $systemStatus = 'DONE';
+        }
+        if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+            $params['order_is_complete'] = 'N';
+            $systemStatus = "WAITING";
+        }
+        $payDetail = PayDetail::where('join_pay_order_id', $order->order_groupby)->first();
+        Db::beginTransaction();
+        try {// 使用优惠券
+            $couponUseJson = [];
+            $discountJson = [];
+            if (!empty($order->order_discount_json)) {
+                $discountJson = json_decode($order->order_discount_json, true);
+                foreach ($discountJson as $item) {
+                    if (isset($item['coupon_value']) && sprintf('%.2f', (floatval($order->order_amount_total) - floatval($params['order_amount_pay']))) != sprintf('%.2f', $item['coupon_value'])) {
+                        throw new BusinessException("计算优惠后,实付金额错误!");
+                    }
+                }
+                $couponUseJson = $discountJson;
+                $this->changeOrderCouponStatus($couponUseJson, 'USED');
+                // 释放下单时选的优惠券
+//                $order->order_discount_json = $this->releaseCoupon($discountJson);
+            }
+            if (empty($discountJson) && !empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('pay', 'Y', $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            if (empty($discountJson)) {
+                $order->order_discount_json = json_encode($this->discountRecord($couponUseJson, $params));
+            }
+            $orderAmountPay = $params['order_amount_pay'];
+            $constituteList = array_column($params['pay_category_constitute_list'], 'amount', 'category');// 验证金额
+            $constituteAmount = 0;
+            foreach ($params['pay_category_constitute_list'] as $item) {
+                $constituteAmount = sprintf("%.2f", $constituteAmount) + sprintf("%.2f", $item['amount']);
+            }
+            if (sprintf("%.2f", $params['order_amount_pay']) != sprintf("%.2f", $constituteAmount)) {
+                throw new BusinessException('组合支付金额与应付金额不一致');
+            }
+
+            $wxAndAliPayStatus = 'Y';
+            $waitToPayAccount = [];
+            // 清除订单的支付记录,重建
+            PayDetail::whereJsonContains('join_pay_object_json->order_id', $params['orderId'])->delete();
+            if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute'])) {  //线下付款
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                $params['pay_category'] = $params['pay_category_sub'] ?? 'OFFLINE';
+
+                // 线下支付金额
+                if (isset($constituteList['OFFLINE'])) {
+                    $params['order_amount_pay'] = $constituteList['OFFLINE'];
+                    // 生成支付记录
+                    $params['order_status_payment'] = 'PENDING';
+                    OrderService::createProductPayConstituteDetail($params);
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {  //现金付款
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                $params['pay_category'] = 'MONEY';
+
+                // 线下支付金额
+                if (isset($constituteList['MONEY'])) {
+                    $params['order_amount_pay'] = $constituteList['MONEY'];
+                    // 生成支付记录
+                    $params['order_status_payment'] = 'PENDING';
+                    OrderService::createProductPayConstituteDetail($params, $payDetail);
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CASH', $params['pay_category_constitute'])) {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                if (isset($constituteList['CASH'])) {
+                    $params['order_amount_pay'] = $constituteList['CASH'];
+                    $params['pay_category'] = $params['join_order_member_id'] . '-CASH';
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                // 余额账户扣款数据
+                $waitToPayAccount['cash'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CASH'],
+                    'nbr' => $params['join_order_member_id'] . '-CASH'
+                ];
+                // 生成支付记录
+                $params['order_status_payment'] = 'PENDING';
+                OrderService::createProductPayConstituteDetail($params);
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['order_amount_pay'] = $orderAmountPay;
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CARD', $params['pay_category_constitute'])) {    // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    Db::rollBack();
+                    return json_fail('账户异常');
+                }
+                // 储值卡账户支付金额
+                if (isset($constituteList['CARD'])) {
+                    $params['order_amount_pay'] = $constituteList['CARD'];
+                    $params['pay_category'] = $cardNbr;
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                // 储值卡账户扣款数据
+                $waitToPayAccount['card'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CARD'],
+                    'nbr' => $params['join_order_member_id'] . '-CARD'
+                ];
+                // 生成支付记录
+                $params['order_status_payment'] = 'PENDING';
+                OrderService::createProductPayConstituteDetail($params);
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['order_amount_pay'] = $orderAmountPay;
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('QRCODE', $params['pay_category_constitute']) && !empty($params['qrcode_nbr'])) {     // 付款码
+                if (isset($constituteList['QRCODE']) && $constituteList['QRCODE'] > 0) {
+                    // 付款码支付金额
+                    $params['order_amount_pay'] = $constituteList['QRCODE'];
+                    // 调支付
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $order->order_status_system = 'PAYING';
+                            $order->order_status_payment = 'PENDING';
+                            $order->order_is_complete = 'N';
+                            $params['order_status_payment'] = 'PAYING';
+                        } else {
+                            $order->order_status_system = $systemStatus;
+                            $order->order_status_payment = 'SUCCESS';
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $order->order_status_system = 'PAYING';
+                            $order->order_status_payment = 'PENDING';
+                            $order->order_is_complete = 'N';
+                            $params['order_status_payment'] = 'PAYING';
+                        } else {
+                            $order->order_status_system = $systemStatus;
+                            $order->order_status_payment = 'SUCCESS';
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException('付款码无效');
+                    }
+                }
+
+                // 生成支付记录
+                OrderService::createProductPayConstituteDetail($params);
+                // 账户支付的金额
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            $orderConfigJson = [];
+            if (!empty($order->order_config_json)) {
+                $orderConfigJson = json_decode($order->order_config_json, true);
+            }
+            $orderConfigJson['preferential'] = $params['preferential'] ?? '';
+            $order->order_config_json = json_encode($orderConfigJson);
+            $order->order_amount_pay = $params['order_amount_pay'];
+
+            // 主订单
+            $order->save();
+            // sheet
+            if ($order->order_status_payment == 'SUCCESS') {
+                OrderSheet::where('join_sheet_order_id', $params['order_id'])->update([
+                    'order_sheet_status' => $systemStatus,
+                ]);
+            }
+
+            if ($wxAndAliPayStatus == 'Y') {
+                PayDetail::whereJsonContains('join_pay_object_json->order_id', $params['orderId'])->update([
+                    'pay_status' => 'SUCCESS',
+                    'pay_paytimes' => date('Y-m-d H:i:s')
+                ]);
+                // 扣款
+                foreach ($waitToPayAccount as $item) {
+                    $accountNbr = $item['nbr'];
+                    $account = MemberAccount::where('member_account_nbr', $accountNbr)->first();
+                    $account->member_account_expend = $account->member_account_expend + $item['amount'];
+                    if ($account->member_account_surplus < $item['amount'] && strpos($accountNbr, 'CASH') !== false) {
+                        $account->member_account_added = $account->member_account_added - ($item['amount'] - $account->member_account_surplus);
+                        $account->member_account_surplus = 0;
+                    } else {
+                        $account->member_account_surplus = $account->member_account_surplus - $item['amount'];
+                    }
+                    $account->save();
+                }
+            }
+            // 买单个服务
+            $writeOffDate = [];
+            $applyData = [];
+            if ($order->order_status_payment == 'SUCCESS' && empty($appointment)) {
+                foreach ($params['goodsContentList'] as $goods) {
+                    $params['join_sheet_goods_id'] = $goods['goods_id'];
+                    if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD'])) {
+                        $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                        $params['order_sheet_num'] = $goods['nbr'];
+                        // 预约表
+                        for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                            $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                            // 入预约记录
+                            $this->insertAppointment($params, $writeOffDate, $applyData);
+                        }
+                        $goods['skuId'] = $goods['sku_id'];
+                        $goods['category'] = $goods['goods_classify'];
+                        // 权益表
+                        $this->insertMemberBenefit($params, $goods);
+                    } elseif (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE') {  // 一个套餐买多个
+                        $params['packageId'] = $goods['goods_id'];
+                        $components = GoodsComponent::with([
+                            'goods' => function ($query) {
+                                $query->select('goods_id', 'goods_name', 'goods_classify');
+                            }
+                        ])->where('join_component_master_goods_id', $params['packageId'])
+                            ->get()
+                            ->toArray();
+                        foreach ($components as $component) {
+                            $componentJson = json_decode($component['goods_component_json'], true);
+                            $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
+                            $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                            $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
+                            for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                                $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                                // 入预约记录
+                                $this->insertAppointment($params, $writeOffDate);
+                            }
+                            $goods['goods_id'] = $component['join_component_goods_id'];
+                            $goods['goods_name'] = $component['goods']['goods_name'];
+                            $goods['goods_classify'] = $component['goods']['goods_classify'];
+                            $goods['skuId'] = $goods['sku_id'];
+                            $goods['category'] = 'SERVICE';
+                            // 权益表
+                            $this->insertMemberBenefit($params, $goods);
+                        }
+                    }
+                }
+            }
+
+            Db::commit();
+            // 触发事件
+            if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                // 完成订单
+                Event::dispatch('order.complete', $params);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+            if ($order->order_status_payment == 'SUCCESS') {
+                // 上级提成
+                Event::dispatch('commission.order', $params);
+            }
+
+            // 打小票
+            if ($order->order_status_payment == 'SUCCESS') {
+                if (!empty($premises) && !empty($premises->dept_id)) {
+                    $voteData = [
+                        'func' => 'procActionToPrinter',
+                        'sign' => '',
+                        'data' => [
+                            'printer_premises' => $premises->dept_id,
+                            'printer_device' => ["收银"],
+                            'printer_action' => 'ExecPrintOrder',
+                            'printer_data' => [
+                                'order_id' => $params['orderId'],
+                                'order_batch' => ''
+                            ]
+                        ]
+                    ];
+//                    dump("小票参数", $voteData);
+                    http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+                }
+            }
+            if ($order->order_status_payment != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                // 如果下单时就填了,不用恢复
+                if (empty($discountJson)) {
+                    $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+                }
+                // 清除支付记录,恢复账户金额
+//                $this->restoreAccount($params['pay_detail_item']);
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "订单支付成功");
+            return json_success('支付成功');
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败");
+            return json_fail('支付失败');
+        }
+    }
+
+    public function restoreAccount($payDetailItem)
+    {
+        foreach ($payDetailItem as $item) {
+            $prepayId = '';
+            if ($item['order_status_payment'] == 'SUCCESS') {
+                if (in_array($item['pay_category'], ['MONEY', 'OFFLINE', 'OFFLINE_ALIPAY', 'OFFLINE_WXPAY'])) {
+                    $prepayId = $item['pay_category'];
+                }
+                if (strpos($item['pay_category'], 'CASH') !== false || strpos($item['pay_category'], 'CARD') !== false || strpos($item['pay_category'], 'WELFARE') !== false || strpos($item['pay_category'], 'VIP') !== false) {
+                    $prepayId = $item['pay_category'];
+                    $account = MemberAccount::where('member_account_nbr', $prepayId)->first();
+                    $account->member_account_expend = $account->member_account_expend - $item['order_amount_pay'];
+                    $account->member_account_surplus = $account->member_account_surplus + $item['order_amount_pay'];
+                    $account->save();
+                }
+            }
+            if (!empty($prepayId)) {
+                PayDetail::where('pay_prepayid', $prepayId)
+                    ->where('join_pay_order_id', $item['orderGroupId'])
+                    ->whereJsonContains('join_pay_object_json->order_id', $item['orderId'])
+                    ->update(['pay_status' => 'WAITING']);
+            }
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:30
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertMain($params, $wxAndAliPayStatus = 'Y')
+    {
+        try {
+            if (empty($params['order_extend_json'])) {
+                $params['order_extend_json'] = [];
+            } else {
+                if (is_json($params['order_extend_json'])) {
+                    $params['order_extend_json'] = json_decode($params['order_extend_json'], true);
+                }
+            }
+            // 账户扣款
+            if ($wxAndAliPayStatus == 'Y' && !empty($params['waitToPayAccount'])) {
+                foreach ($params['waitToPayAccount'] as $account) {
+                    $this->deductAmount($account['nbr'], $account['amount']);
+                }
+            }
+            // 推荐人
+            $params['order_extend_json']['referee'] = $params['referee'] ?? '';
+            foreach ($params['goodsContentList'] as $goods) {
+                $discountJson = [];
+                if (!empty($params['order_discount_json'])) {
+                    $discountJson = json_decode($params['order_discount_json'], true);
+                    foreach ($discountJson as &$item) {
+                        if (!empty($item['coupon_value'])) {
+                            $item['coupon_value'] = round((floatval($goods['goods_sales_price']) * $goods['nbr'] / $params['order_amount_total']) * $item['coupon_value'], 2);
+                        }
+                    }
+                }
+                $orderId = 'OD' . date('ymdHi') . random_string(4, 'up');
+                $amountPay = round((floatval($goods['goods_sales_price']) * $goods['nbr'] / $params['order_amount_total']) * $params['order_amount_pay'], 2);
+//                $amountPay = round(floatval($goods['goods_sales_price']) * $goods['nbr'] * $params['order_ratio'], 2);
+                $data = [
+                    'order_id' => $orderId,
+                    'order_groupby' => $params['orderGroupId'],
+                    'join_order_member_id' => $params['join_order_member_id'],
+                    'order_name' => date('Y-m-d H:i:s') . '-订单',
+                    'order_amount_total' => floatval($goods['goods_sales_price']) * $goods['nbr'],
+                    'order_amount_pay' => $amountPay,
+                    'order_category' => $goods['goods_classify'],
+                    'order_classify' => $goods['goods_classify'],
+                    'order_is_complete' => $params['order_is_complete'] ?? 'N',
+                    'order_status_system' => $params['order_status_system'],
+                    'order_status_payment' => $params['order_status_payment'],
+                    'order_status_storage' => $params['order_status_storage'],
+                    'order_platform' => $params['order_platform'],
+                    'order_remark' => $params['order_remark'] ?? '',
+                    'order_discount_json' => json_encode($discountJson),
+                    'order_config_json' => $params['order_config_json'] ?? '[]',
+                    'order_express_json' => $params['order_express_json'] ?? '[]',
+                    'order_extend_json' => $params['order_extend_json'] ? json_encode($params['order_extend_json']) : '[]',
+                    'order_addtimes' => time()
+                ];
+
+                Order::insert($data);
+
+                $sheetIds = $this->insertSheetOne($params, $goods, $orderId, $amountPay);
+
+                $this->insertPayDetailOne($params, $orderId, $amountPay, $goods);
+
+                $params['order_express_goods'] = json_encode(['sheet' => $sheetIds]);
+
+                $this->insertExpressOne($params, $orderId);
+                // 写到权益里
+                if ($params['order_status_payment'] == 'SUCCESS') {
+                    $this->insertBenefitOne($params, $goods, $orderId);
+                }
+            }
+        } catch (\Exception $e) {
+            dump($e->getMessage() . '|' . $e->getLine());
+            throw new BusinessException('订单创建信息失败');
+        }
+    }
+
+    /**
+     * @Desc 扣除账户金额
+     * @Author Gorden
+     * @Date 2024/9/26 14:16
+     *
+     * @param $accountNbr
+     * @param $amount
+     * @return void
+     */
+    public function deductAmount($accountNbr, $amount)
+    {
+        try {
+            $account = MemberAccount::where('member_account_nbr', $accountNbr)->first();
+            $account->member_account_expend = $account->member_account_expend + $amount;
+            if ($account->member_account_surplus < $amount && strpos($accountNbr, 'CASH') !== false) {
+                $account->member_account_added = $account->member_account_added - ($amount - $account->member_account_surplus);
+                $account->member_account_surplus = 0;
+            } else {
+                $account->member_account_surplus = $account->member_account_surplus - $amount;
+            }
+
+            $account->save();
+        } catch (\Exception $e) {
+            _syslog("下单扣款", "扣款失败");
+
+            throw new BusinessException("账户扣款失败");
+        }
+    }
+
+    /**
+     * @Desc 打小票
+     * @Author Gorden
+     * @Date 2024/9/24 9:35
+     *
+     * @param $params
+     * @param $premises
+     * @param $orderId
+     * @return void
+     */
+    public function printerTicket($params, $premises, $orderId)
+    {
+        // 打小票
+        if ($params['order_status_payment'] == 'SUCCESS') {
+            if (!empty($premises) && !empty($premises->dept_id)) {
+                $voteData = [
+                    'func' => 'procActionToPrinter',
+                    'sign' => '',
+                    'data' => [
+                        'printer_premises' => $premises->dept_id,
+                        'printer_device' => ["收银"],
+                        'printer_action' => 'ExecPrintOrder',
+                        'printer_data' => [
+                            'order_id' => $orderId,
+                            'order_batch' => ''
+                        ]
+                    ]
+                ];
+//                    dump("小票参数", $voteData);
+                http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+            }
+        }
+    }
+
+    /**
+     * @Desc 单套包权益
+     * @Author Gorden
+     * @Date 2024/9/24 8:42
+     *
+     * @param $params
+     * @param $goods
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertBenefitOne($params, $goods, $orderId)
+    {
+        $params['orderId'] = $orderId;
+        $writeOffDate = [];
+        $applyData = [];
+        if (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE' && $params['delivery'] == 'ARRIVAL') {  // 一个套餐买多个
+            $params['packageId'] = $goods['goods_id'];
+            $components = GoodsComponent::with([
+                'goods' => function ($query) {
+                    $query->select('goods_id', 'goods_name', 'goods_classify');
+                }
+            ])->where('join_component_master_goods_id', $params['packageId'])
+                ->get()
+                ->toArray();
+            foreach ($components as $component) {
+                $componentJson = json_decode($component['goods_component_json'], true);
+                $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
+                $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
+                $params['join_sheet_goods_id'] = $component['join_component_goods_id'];
+                for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                    $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                    // 入预约记录
+                    $this->insertAppointment($params, $writeOffDate);
+                }
+                $goods['goods_id'] = $component['join_component_goods_id'];
+                $goods['goods_name'] = $component['goods']['goods_name'];
+                $goods['goods_classify'] = $component['goods']['goods_classify'];
+                $goods['skuId'] = $goods['sku_id'];
+                $goods['category'] = 'SERVICE';
+                // 权益表
+                $this->insertMemberBenefit($params, $goods);
+            }
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:25
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertSheet($params)
+    {
+        try {
+            $orderSheetIds = [];
+            foreach ($params['goodsContentList'] as $goods) {
+                //{"unit": "份", "table": null, "premises": "15"}
+                $price = floatval($goods['goods_sales_price']);
+                $extendJson['unit'] = $goods['sku_name'];
+                if (isset($params['submit_premises_id'])) {
+                    $extendJson['premises'] = $params['submit_premises_id'];
+                }
+                if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                    $extendJson['table'] = null;
+                }
+                $data = [
+                    'join_sheet_member_id' => $params['join_order_member_id'],
+                    'join_sheet_order_id' => $params['orderId'],
+                    'join_sheet_goods_id' => $goods['goods_id'],
+                    'join_sheet_goods_sku_id' => $goods['sku_id'],
+                    'order_sheet_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
+                    'order_sheet_category' => (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') ? 'DISHES' : 'NORMAL',
+                    'order_sheet_num' => $goods['nbr'],
+                    'order_sheet_price' => $goods['goods_sales_price'],
+                    'order_sheet_amount' => $price * $goods['nbr'],
+                    'order_sheet_pay' => $price * $goods['nbr'],
+                    'order_sheet_task_status' => 'NONE',
+                    'order_sheet_remark' => $params['order_remark'] ?? '',
+                    'order_sheet_addtimes' => time(),
+                    'order_sheet_extend_json' => json_encode($extendJson)
+                ];
+
+                $orderSheetId = OrderSheet::insertGetId($data);
+                $orderSheetIds[] = $orderSheetId;
+
+                // 减库存,规格和总库存
+                if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                    $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                    $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                    if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                        $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                    }
+
+                    if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                        throw new BusinessException('库存不足');
+                    }
+                    $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
+                    $goodsSku->save();
+                }
+
+
+                $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+                $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+                if ($goodsRunning->goods_running_storage < 0) {
+                    throw new BusinessException('库存不足');
+                }
+                $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
+                $goodsRunning->save();
+            }
+//            return $orderSheetIds;
+        } catch (\support\exception\BusinessException $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException('订单创建失败');
+        }
+    }
+
+    /**
+     * @Desc 单条入库
+     * @Author Gorden
+     * @Date 2024/9/23 10:19
+     *
+     * @param $params
+     * @return array
+     * @throws BusinessException
+     */
+    public function insertSheetOne($params, $goods, $orderId, $amountPay)
+    {
+        try {
+            $orderSheetIds = [];
+//            foreach ($params['goodsContentList'] as $goods) {
+            //{"unit": "份", "table": null, "premises": "15"}
+            $price = floatval($goods['goods_sales_price']);
+            $extendJson['unit'] = $goods['sku_name'];
+            if (isset($params['submit_premises_id'])) {
+                $extendJson['premises'] = $params['submit_premises_id'];
+            }
+            if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                $extendJson['table'] = null;
+            }
+            $data = [
+                'join_sheet_member_id' => $params['join_order_member_id'],
+                'join_sheet_order_id' => $orderId,
+                'join_sheet_goods_id' => $goods['goods_id'],
+                'join_sheet_goods_sku_id' => $goods['sku_id'],
+                'order_sheet_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
+                'order_sheet_category' => (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') ? 'DISHES' : 'NORMAL',
+                'order_sheet_num' => $goods['nbr'],
+                'order_sheet_price' => $goods['goods_sales_price'],
+                'order_sheet_price_pay' => round($amountPay / $goods['nbr'], 2),
+                'order_sheet_amount' => $price * $goods['nbr'],
+                'order_sheet_pay' => $amountPay,
+                'order_sheet_task_status' => 'NONE',
+                'order_sheet_remark' => $params['order_remark'] ?? '',
+                'order_sheet_addtimes' => time(),
+                'order_sheet_extend_json' => json_encode($extendJson)
+            ];
+
+            $orderSheetId = OrderSheet::insertGetId($data);
+            $orderSheetIds[] = $orderSheetId;
+
+            // 减库存,规格和总库存
+            if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                    $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                }
+
+                if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                    throw new BusinessException('库存不足');
+                }
+                $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
+                $goodsSku->save();
+            }
+
+
+            $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+            $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+            if ($goodsRunning->goods_running_storage < 0) {
+                throw new BusinessException('库存不足');
+            }
+            $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
+            $goodsRunning->save();
+//            }
+            return $orderSheetIds;
+        } catch (\support\exception\BusinessException $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException('订单创建失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:35
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertPayDetail($params)
+    {
+        try {
+            if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                $payPrepayid = $params['pay_category'];
+            } else if ($params['pay_category'] == 'OFFLINE') {
+                $payPrepayid = 'OFFLINE';
+            } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                $payPrepayid = 'OFFLINE_ALIPAY';
+            } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                $payPrepayid = 'OFFLINE_WXPAY';
+            } else if ($params['pay_category'] == 'MONEY') {
+                $payPrepayid = 'MONEY';
+            } else {
+                $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
+            }
+            $data = [
+                'join_pay_member_id' => $params['join_order_member_id'],
+                'join_pay_order_id' => $params['orderGroupId'],
+                'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                'pay_category' => $params['goods_classify'],
+                'pay_amount' => $params['order_amount_pay'],
+                'pay_prepayid' => $payPrepayid,
+                'pay_paytimes' => date('Y-m-d H:i:s'),
+                'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]',
+                'pay_json_request' => json_encode($params),
+                'pay_json_response' => $params['pay_json_response'] ?? '[]',
+                'pay_remark' => $params['order_remark'] ?? '',
+                'pay_addtimes' => time(),
+            ];
+
+            PayDetail::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建支付记录失败');
+        }
+    }
+
+    /**
+     * @Desc 单条入库
+     * @Author Gorden
+     * @Date 2024/6/7 10:35
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertPayDetailOne($params, $orderId, $amountPay, $goods)
+    {
+        try {
+            if (!empty($params['pay_detail_item'])) {
+                foreach ($params['pay_detail_item'] as $item) {
+                    $data = [
+                        'join_pay_member_id' => $item['join_order_member_id'],
+                        'join_pay_order_id' => $item['orderGroupId'],
+                        'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                        'pay_category' => $goods['goods_classify'],
+                        'pay_amount' => round(($amountPay / $params['order_amount_pay']) * $item['order_amount_pay'], 2),
+                        'pay_prepayid' => $item['pay_category'],
+                        'pay_paytimes' => date('Y-m-d H:i:s'),
+                        'join_pay_object_json' => !empty($item['orderId']) ? json_encode(['order_id' => $orderId]) : '[]',
+                        'pay_json_request' => json_encode($item),
+                        'pay_json_response' => $item['pay_json_response'] ?? '[]',
+                        'pay_remark' => $item['order_remark'] ?? '',
+                        'pay_addtimes' => time(),
+                    ];
+                    PayDetail::insert($data);
+                }
+            } else {
+                if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                    $payPrepayid = $params['pay_category'];
+                } else if ($params['pay_category'] == 'OFFLINE') {
+                    $payPrepayid = 'OFFLINE';
+                } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                    $payPrepayid = 'OFFLINE_ALIPAY';
+                } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                    $payPrepayid = 'OFFLINE_WXPAY';
+                } else if ($params['pay_category'] == 'MONEY') {
+                    $payPrepayid = 'MONEY';
+                } else {
+                    $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
+                }
+                $data = [
+                    'join_pay_member_id' => $params['join_order_member_id'],
+                    'join_pay_order_id' => $params['orderGroupId'],
+                    'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                    'pay_category' => $goods['goods_classify'],
+                    'pay_amount' => $amountPay,
+                    'pay_prepayid' => $payPrepayid,
+                    'pay_paytimes' => date('Y-m-d H:i:s'),
+                    'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $orderId]) : '[]',
+                    'pay_json_request' => json_encode($params),
+                    'pay_json_response' => $params['pay_json_response'] ?? '[]',
+                    'pay_remark' => $params['order_remark'] ?? '',
+                    'pay_addtimes' => time(),
+                ];
+
+                PayDetail::insert($data);
+            }
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建支付记录失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:50
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertAppointment($params, $writeOffDate, $applyData = [])
+    {
+        try {
+            $data = [
+                'appointment_id' => $params['appointmentId'],
+                'join_appointment_member_id' => $params['join_order_member_id'],
+                'join_appointment_goods_id' => $params['join_sheet_goods_id'],
+                'join_appointment_goods_sku_id' => $params['join_sheet_goods_sku_id'],
+                'join_appointment_order_id' => $params['orderId'],
+                'join_appointment_member_benefit_id' => $params['benefitId'],
+                'appointment_classify' => $params['goods_classify'],
+                'appointment_status' => 'INIT',
+                'appointment_category' => 'NORMAL',
+                'appointment_platform' => 'SYSTEM',
+                'appointment_addtimes' => time(),
+                'appointment_datetime' => '',
+                'appointment_apply_datetime' => '',
+                'appointment_apply_json' => '[]',
+                'appointment_done_datetime' => '',
+                'appointment_remark' => $params['order_remark'] ?? '',
+                'appointment_done_json' => '[]'
+            ];
+            Appointment::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException("创建权益记录失败");
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 11:05
+     *
+     * @param $params
+     * @param $goods
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertMemberBenefit($params, $goods)
+    {
+        try {
+            $data = [
+                'member_benefit_id' => $params['benefitId'],
+                'join_benefit_member_id' => $params['join_order_member_id'],
+                'join_benefit_package_id' => $params['packageId'] ?? '',
+                'join_benefit_goods_id' => $goods['goods_id'],
+                'join_benefit_goods_sku_id' => $goods['skuId'] ?? '',
+                'join_benefit_order_id' => $params['orderId'],
+                'member_benefit_status' => 'ACTIVED',
+                'member_benefit_category' => $goods['category'],
+                'member_benefit_name' => $goods['goods_name'],
+                'member_benefit_limit_count' => $params['order_sheet_num'],
+                'member_benefit_used_count' => 0,
+                'member_benefit_remark' => $params['order_remark'] ?? '',
+                'member_benefit_addtimes' => time()
+            ];
+            MemberBenefit::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建会员权益失败');
+        }
+    }
+
+
+    public function saveExpress($params, $orderId)
+    {
+        try {
+            $express = new OrderExpress();
+            $express->order_express_type = $params['order_express_type'];
+            $express->join_express_order_id = $orderId;
+            $express->join_express_dept_id = $params['submit_premises_id'] ?? 0;
+            $express->order_express_goods = $params['order_express_goods'];
+            $express->order_express_city = $params['order_express_city'];
+            $express->order_express_address = $params['order_express_address'];
+            $express->order_express_mobile = $params['order_express_mobile'] ?? '';
+            $express->order_express_telephone = $params['order_express_telephone'] ?? '';
+            $express->order_express_person = $params['order_express_person'] ?? '';
+            $express->order_express_company = $params['dept_premises_id'] ?? '';
+            $express->order_express_extend_json = $params['order_express_extend_json'] ?? '[]';
+            $express->order_express_addtimes = time();
+            $express->save();
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('物流信息保存失败');
+        }
+    }
+
+    /**
+     * @Desc 修改优惠券状态
+     * @Author Gorden
+     * @Date 2024/9/19 9:03
+     *
+     * @param $coupon
+     * @param $status
+     * @return void
+     */
+    private function changeOrderCouponStatus($coupon, $status)
+    {
+        if (!empty($coupon) && is_array($coupon)) {
+            $updateData['coupon_detail_status'] = $status;
+            if ($status == 'ACTIVED' || $status == 'WAITING') {
+                $updateData['coupon_detail_used_datetime'] = '';
+            } elseif ($status == 'USED') {
+                $updateData['coupon_detail_used_datetime'] = date('Y-m-d H:i:s');
+            }
+            foreach ($coupon as $item) {
+                if (!empty($item['coupon_id']) && !empty($item['coupon_detail_id'])) {
+                    foreach ($item['coupon_detail_id'] as $detailId) {
+                        CouponDetail::where('join_detail_coupon_id', $item['coupon_id'])
+                            ->where('coupon_detail_id', $detailId)->update($updateData);
+                    }
+                }
+            }
+        }
+    }
+
+
+    private function discountRecord($orderDiscountJson, $params)
+    {
+        $json = [];
+        if (!empty($orderDiscountJson)) {
+            $json = json_decode($orderDiscountJson, true);
+        }
+        try {
+            if (!empty($params['preferential']) && in_array('wipe', $params['preferential'])) {
+                if (intval($params['order_amount_total'] / 10) * 10 != $params['order_amount_pay']) {
+                    throw new BusinessException("抹零后实际支付金额错误");
+                }
+                $params['order_discount_amount'] = $params['order_amount_total'] - $params['order_amount_pay'];
+                $couponClassifyDesc = $couponClassify = '抹零';
+            } elseif (!empty($params['preferential']) && in_array('custom', $params['preferential'])) {
+                if (sprintf("%.2f", $params['order_amount_total'] - $params['order_discount_amount']) != sprintf("%.2f", $params['order_amount_pay'])) {
+                    throw new BusinessException("餐厅前台优惠后实际支付金额错误");
+                }
+                $couponClassifyDesc = $couponClassify = '餐厅前台优惠';
+            } else if (!empty($params['preferential']) && intval($params['preferential'][0]) < 100 && intval($params['preferential'][0]) >= 50) {
+                if (($params['order_amount_total'] * intval($params['preferential'][0])) / 100 != $params['order_amount_pay']) {
+                    throw new BusinessException("折扣后实际支付金额错误");
+                }
+                $couponClassify = '折扣';
+                $couponClassifyDesc = intval($params['preferential'][0]) / 10 . '折';
+                $params['order_discount_amount'] = $params['order_amount_total'] - $params['order_amount_pay'];
+            } else {
+                return $json;
+            }
+            $json[date('Y-m-d H:i:s')] = [
+                'coupon_id' => $params['coupon_id'] ?? null,
+                'coupon_value' => $params['order_discount_amount'] ?? '',
+                'coupon_classify' => $couponClassify,
+                'coupon_detail_id' => [$couponClassifyDesc],
+                'coupon_classify_en' => $params['preferential']
+            ];
+            return $json;
+        } catch (BusinessException $e) {
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException("优惠数据错误");
+        }
+    }
+
+    /**
+     * @Desc 入配送记录
+     * @Author Gorden
+     * @Date 2024/9/23 10:45
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertExpressOne($params, $orderId)
+    {
+        if (isset($params['delivery']) && $params['delivery'] == 'LOGISTICS') {
+            $params['order_express_type'] = '配送';
+            // 入配送
+            $this->saveExpress($params, $orderId);
+        } else if (isset($params['delivery']) && $params['delivery'] == 'PICKUP') {
+            $params['order_express_type'] = '自提';
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+            if (!$premises) {
+                throw new BusinessException('自提门店不存在');
+            }
+
+            $params['order_express_city'] = $premises->dept_city;
+            $params['order_express_address'] = $premises->dept_address;
+            $params['order_express_telephone'] = $premises->dept_telephone;
+            $params['order_express_extend_json'] = json_encode(['pick_code' => random_string(4, 'number')]);
+
+            $this->saveExpress($params, $orderId);
+        } else if (isset($params['delivery']) && $params['delivery'] == 'ARRIVAL') {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+            $params['order_express_type'] = '到店';
+            if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                $params['order_express_type'] = '堂食';
+            }
+            if (!$premises) {
+                throw new BusinessException('门店不存在');
+            }
+
+            $params['order_express_city'] = $premises->dept_city;
+            $params['order_express_address'] = $premises->dept_address;
+            $params['order_express_telephone'] = $premises->dept_telephone;
+
+            $this->saveExpress($params, $orderId);
+        }
+    }
+
+    /**
+     * @Desc 释放下单时选的优惠券
+     * @Author Gorden
+     * @Date 2024/9/19 9:56
+     *
+     * @param $coupon
+     * @return false|string
+     */
+    private function releaseCoupon($coupon)
+    {
+        if (!empty($coupon) && is_array($coupon)) {
+            $updateData = [
+                'coupon_detail_status' => 'ACTIVED',
+                'coupon_detail_used_datetime' => ''
+            ];
+            foreach ($coupon as $key => $item) {
+                if (!empty($item['coupon_id']) && !empty($item['coupon_detail_id'])) {
+                    foreach ($item['coupon_detail_id'] as $detailId) {
+                        if (substr($detailId, 0, 4) == 'CUDT') {
+                            CouponDetail::where('join_detail_coupon_id', $item['coupon_id'])
+                                ->where('coupon_detail_id', $detailId)
+                                ->where('coupon_detail_status', 'WAITING')
+                                ->update($updateData);
+                        }
+                    }
+                    unset($coupon[$key]);
+                }
+            }
+        }
+
+        return json_encode($coupon);
+    }
 }

+ 1097 - 0
app/admin/controller/order/PartnerController.php

@@ -0,0 +1,1097 @@
+<?php
+
+namespace app\admin\controller\order;
+
+use app\admin\service\coupon\CouponService;
+use app\admin\service\member\MemberService;
+use app\admin\service\order\OrderService;
+use app\admin\validate\order\OrderValidate;
+use app\controller\Curd;
+use app\model\Appointment;
+use app\model\ClientConfig;
+use app\model\Coupon;
+use app\model\Goods;
+use app\model\GoodsComponent;
+use app\model\GoodsRunning;
+use app\model\GoodsSku;
+use app\model\Member;
+use app\model\MemberAccount;
+use app\model\MemberBenefit;
+use app\model\MemberRole;
+use app\model\Order;
+use app\model\OrderExpress;
+use app\model\OrderReturn;
+use app\model\OrderSheet;
+use app\model\PayDetail;
+use app\model\Supplier;
+use app\model\SysDept;
+use app\model\SysUser;
+use support\Db;
+use support\exception\BusinessException;
+use support\Redis;
+use support\Request;
+use support\Response;
+use Webman\Event\Event;
+
+class PartnerController extends Curd
+{
+    public function __construct()
+    {
+        $this->model = new Order();
+        $this->validate = true;
+        $this->validateClass = new OrderValidate();
+    }
+
+    /**
+     * @Desc 列表
+     * @Author Gorden
+     * @Date 2024/3/28 15:01
+     *
+     * @param Request $request
+     * @return Response
+     * @throws \support\exception\BusinessException
+     */
+    public function select(Request $request): Response
+    {
+        [$where, $format, $limit, $field, $order] = $this->selectInput($request);
+        $where['order_classify'] = 'PARTNER';
+        if (!empty($where['order_addtimes'])) {
+            $where['order_addtimes'][0] = strtotime($where['order_addtimes'][0]);
+            $where['order_addtimes'][1] = strtotime($where['order_addtimes'][1]);
+        }
+
+        $order = $request->get('order', 'desc');
+        $field = $field ?? 'order_addtimes';
+        $orderIds = [];
+        if (!empty($orderId)) {
+            $orderIds = Order::where('order_id', 'like', '%' . $orderId . '%')
+                ->where('order_classify', 'PARTNER')
+                ->pluck('order_id')
+                ->toArray();
+        }
+        $goodsName = trim($request->get('goods_name', ''));
+        if (!empty($goodsName)) {
+            $goodsIds = Goods::where('goods_classify', 'PARTNER')
+                ->where('goods_name', 'like', '%' . $goodsName . '%')
+                ->pluck('goods_id')
+                ->toArray();
+            $goodsOrderIds = OrderSheet::whereIn('join_sheet_goods_id', $goodsIds)->pluck('join_sheet_order_id')->toArray();
+            if (!empty($where['order_id'])) {
+                $orderIds = array_intersect($orderIds, $goodsOrderIds);
+            } else {
+                $orderIds = $goodsOrderIds;
+            }
+        }
+        if (!empty($orderId) || !empty($goodsName)) {
+            $where['order_id'] = ['in', implode(',', $orderIds)];
+        }
+
+        $query = $this->doSelect($where, $field, $order);
+        return $this->doFormat($query, $format, $limit);
+    }
+
+    protected function doSelect(array $where, string $field = null, string $order = 'desc')
+    {
+        $model = $this->model->with([
+            'sheets' => function ($query) {
+                $query->select('join_sheet_order_id', 'order_sheet_id', 'join_sheet_goods_id', 'order_sheet_num', 'order_sheet_price');
+            },
+            'member' => function ($query) {
+                $query->select('member_id', 'member_mobile');
+            },
+            'cert' => function ($query) {
+                $query->select('join_cert_member_id', 'member_cert_name');
+            },
+//            'return' => function ($query) use ($where){
+//                if (isset($where['return'])){
+//                    dump($where['return']);
+//                    $query = $query->where('order_return_status',$where['return']);
+//                }
+//                $query->select('orders_return_id', 'join_return_order_id', 'order_return_status');
+//            },
+            // 'express' => function ($query) {
+            //     $query->select('join_express_order_id', 'order_express_type');
+            // }
+        ])->leftJoin('order_return', 'order_return.join_return_order_id', '=', 'order.order_id')
+            ->leftJoin('order_express', 'order_express.join_express_order_id', '=', 'order.order_id');
+        // ->leftJoin('order_sheet','join_sheet_order_id','=','order.order_id');
+        foreach ($where as $column => $value) {
+            if (is_array($value)) {
+                if ($value[0] === 'like' || $value[0] === 'not like') {
+                    $model = $model->where($column, $value[0], "%$value[1]%");
+                } elseif (in_array($value[0], ['>', '=', '<', '<>'])) {
+                    $model = $model->where($column, $value[0], $value[1]);
+                } elseif ($value[0] == 'in' && !empty($value[1])) {
+                    $valArr = $value[1];
+                    if (is_string($value[1])) {
+                        $valArr = explode(",", trim($value[1]));
+                    }
+                    $model = $model->whereIn($column, $valArr);
+                } elseif ($value[0] == 'not in' && !empty($value[1])) {
+                    $valArr = $value[1];
+                    if (is_string($value[1])) {
+                        $valArr = explode(",", trim($value[1]));
+                    }
+                    $model = $model->whereNotIn($column, $valArr);
+                } elseif ($value[0] == 'null') {
+                    $model = $model->whereNull($column);
+                } elseif ($value[0] == 'not null') {
+                    $model = $model->whereNotNull($column);
+                } elseif ($value[0] !== '' || $value[1] !== '') {
+                    $model = $model->whereBetween($column, $value);
+                }
+            } else {
+                $model = $model->where($column, $value);
+            }
+        }
+        if ($field) {
+            $model = $model->orderBy($field, $order);
+        }
+        $model = $model->select('order.*', 'order_express.join_express_order_id', 'order_express.order_express_type', 'order_return.orders_return_id', 'order_return.join_return_order_id', 'order_return.order_return_status', 'order_return.order_return_apply_json', 'order_return.order_return_remark');
+        return $model;
+    }
+
+    public function afterQuery($items)
+    {
+        foreach ($items as &$item) {
+            $sheetDeng = '';
+            $item['sheet'] = $item['sheets'][0] ?? [];
+            if (!empty($item['sheet'])) {
+                $goods = Goods::where('goods_id', $item['sheet']['join_sheet_goods_id'])->first();
+                if (count($item['sheets']) > 1 && $goods->goods_classify == 'MEALS') {
+                    $sheetDeng = ' 等餐品';
+                }
+                $item['sheet']['goods_name'] = ($goods && $goods->goods_name) ? $goods->goods_name . $sheetDeng : '';
+                $item['sheet']['goods_classify'] = $goods->goods_classify ?? '';
+                $item['sheet']['order_sheet_num'] = intval($item['sheet']['order_sheet_num']);
+            }
+            unset($item['sheets']);
+            if (isset($item['orders_return_id'])) {
+                $item['return'] = [
+                    'orders_return_id' => $item['orders_return_id'],
+                    'join_return_order_id' => $item['join_return_order_id'],
+                    'order_return_status' => $item['order_return_status'],
+                    'order_return_apply_json' => $item['order_return_apply_json'],
+                    'order_return_remark' => $item['order_return_remark']
+                ];
+            }
+            if (isset($item['join_express_order_id'])) {
+                $item['express'] = [
+                    'join_express_order_id' => $item['join_express_order_id'],
+                    'order_express_type' => $item['order_express_type']
+                ];
+                unset($item['join_express_order_id'], $item['order_express_type']);
+            }
+            // if (!empty($item['order_extend_json'])){
+            //     $orderExtendJson = json_decode($item['order_extend_json'],true);
+            //     $item['referee'] = $orderExtendJson['referee'] ?? '';
+            // }
+        }
+
+        return $items;
+    }
+
+    /**
+     * @Desc 下单+支付
+     * @Author Gorden
+     * @Date 2024/9/5 13:13
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function insert(Request $request): Response
+    {
+        $params = $request->post();
+        // 判断餐品是否连带着服务或实体
+        $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
+        $params['goods_classify'] = $goodsClassifys[0];
+        Db::beginTransaction();
+        try {
+            // 验证线下付款密码
+            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
+                $password = $params['offline_password'];
+                if ($password != '666888') {
+                    throw new BusinessException('密码错误,请重新输入');
+                }
+            }
+            // 下单账户
+            if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
+                if (Member::where('member_mobile', $params['mobile'])->exists()) {
+                    throw new BusinessException('会员已存在');
+                }
+                $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
+                // 创建会员
+                MemberService::createMember($params);
+            } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
+                $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
+            }
+            if (empty($params['join_order_member_id'])) {
+                throw new BusinessException('检查下单账户');
+            }
+
+            $qrcodePayAmount = 0;
+            $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            // 查询是否有未完全支付订单
+            $paidOrder = Order::where('join_order_member_id', $params['join_order_member_id'])
+                ->where('order_category', 'PARTNER')
+                ->where('order_status_system', 'PAYING')
+                ->first();
+            if (!empty($paidOrder)) {
+                $paidOrder->order_groupby = $params['orderGroupId'];
+                $params['orderId'] = $paidOrder->order_id;
+            }
+            $systemStatus = 'PAYING';
+            // 立即结算
+            if ($params['settlement_now'] == 'Y') {
+                if ($params['goods_classify'] == 'PARTNER') {
+                    $params['order_is_complete'] = 'Y';
+                    $systemStatus = 'DONE';
+                }
+            }
+
+            if ($params['settlement_now'] == 'Y' && ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY')) {
+                if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
+                    $params['pay_category'] = $params['pay_category_sub'];
+                }
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+            }
+            if ($params['pay_category'] == 'QRCODE' && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])) {     // 付款码
+                $result = OrderService::qrcodePay($params);
+                $result = json_encode($result);
+                $params['pay_json_response'] = $result;
+                $result = json_decode($result, true);
+
+                $prefix = substr($params['qrcode_nbr'], 0, 2);
+                if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                    $params['pay_category'] = 'WXPAY';
+                    if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                        $params['order_status_system'] = 'PAYING';
+                        $params['order_status_payment'] = 'PENDING';
+                        $params['order_is_complete'] = 'N';
+                    } else {
+                        $params['order_status_system'] = $systemStatus;
+                        $params['order_status_payment'] = 'SUCCESS';
+                    }
+                } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                    $params['pay_category'] = 'ALIPAY';
+                    if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                        $params['order_status_system'] = 'PAYING';
+                        $params['order_status_payment'] = 'PENDING';
+                        $params['order_is_complete'] = 'N';
+                    } else {
+                        $params['order_status_system'] = $systemStatus;
+                        $params['order_status_payment'] = 'SUCCESS';
+                    }
+                } else {
+                    throw new BusinessException('付款码无效');
+                }
+            }
+
+            if (empty($paidOrder)) {
+                // 写入主订单
+                $this->insertMain($params);
+                // 订单详情
+                $this->insertSheet($params);
+            } else {
+                $params['orderGroupId'] = $paidOrder->order_groupby;
+                if ($params['order_status_payment'] == 'SUCCESS') {
+                    $params['order_amount_paid'] = $paidOrder->order_amount_paid;
+                    $paidOrder->order_amount_paid = $paidOrder->order_amount_paid + $params['order_amount_pay'];
+                    $paidOrder->order_amount_pay = $paidOrder->order_amount_paid;
+                    if (floatval($paidOrder->order_amount_paid) >= $paidOrder->order_amount_total) {
+                        $paidOrder->order_is_complete = 'Y';
+                        $paidOrder->order_status_system = 'DONE';
+                        $paidOrder->order_status_payment = 'SUCCESS';
+                        // 更新sheet
+                        OrderSheet::where('join_sheet_order_id', $paidOrder->order_id)->update(['order_sheet_status' => 'DONE']);
+                    }
+                }
+                $paidOrder->save();
+                // 清除此订单的未支付记录
+                PayDetail::whereJsonContains('join_pay_object_json->order_id', $paidOrder->order_id)->where('pay_status', 'WAITING')->delete();
+            }
+            // 支付记录
+            $this->insertPayDetail($params);
+
+            // 分期付完
+            if ($params['goods_classify'] == 'PARTNER' && $params['order_status_payment'] == 'SUCCESS' && (!empty($paidOrder) && floatval($paidOrder->order_amount_paid) >= $paidOrder->order_amount_total || floatval($params['order_amount_pay']) >= $params['order_amount_total'])) {
+                $params['member_id'] = $params['join_order_member_id'];
+                Event::dispatch('order.partner.grant', $params);
+            }
+
+            Db::commit();
+            if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
+            }
+            _syslog("订单", "创建订单成功");
+            return json_success('创建订单成功');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            dump($e->getTrace());
+            _syslog("订单", $e->getMessage());
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            dump($e->getTrace());
+            _syslog("订单", "创建订单失败");
+            return json_fail('创建订单失败');
+        }
+    }
+
+    /**
+     * @Desc 支付
+     * @Author Gorden
+     * @Date 2024/9/5 13:12
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function pay(Request $request)
+    {
+        $params = $request->post();
+        // 验证线下付款密码
+        if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
+            $password = $params['offline_password'];
+            if ($password != '666888') {
+                return json_fail("密码错误,请重新输入");
+            }
+        }
+
+        $order = Order::where('order_id', $params['order_id'])->first();
+        if (!$order) {
+            return json_fail('订单异常');
+        }
+        if ($order->order_status_system != 'PAYING') {
+            return json_fail('订单不是可支付状态');
+        }
+
+        $params['orderId'] = $params['order_id'];
+
+        $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+        $order->order_groupby = $params['orderGroupId'];
+
+        $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
+            ->select('goods_id', 'goods_name', 'goods_classify')
+            ->first();
+        if (!$goods) {
+            return json_fail('产品数据异常');
+        }
+        $goods = $goods->toArray();
+        $params['goods_classify'] = $goods['goods_classify'] ?? '';
+
+        // 立即结算
+        if ($params['goods_classify'] == 'PARTNER') {
+            $order->order_is_complete = 'Y';
+            $systemStatus = 'DONE';
+        }
+        $paymentStatus = 'PENDING';
+        Db::beginTransaction();
+        try {
+            // 组合支付时,付款码应收金额
+            $qrcodePayAmount = 0;
+            if ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY') {
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                $paymentStatus = 'SUCCESS';
+                if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
+                    $params['pay_category'] = $params['pay_category_sub'];
+                }
+            }
+            if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && !empty($params['qrcode_nbr'])) {     // 付款码
+                // 提交过来的支付分类
+                $submitPayCategory = $params['pay_category'];
+                // 账户支付的金额
+                $accountAmount = $params['order_amount_pay'];
+                if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0) {
+                    // 组合支付,改成需要付款码需要支付的金额
+                    $params['order_amount_pay'] = $qrcodePayAmount;
+                }
+                // 去支付
+                $result = OrderService::qrcodePay($params);
+                $result = json_encode($result);
+                $params['pay_json_response'] = $result;
+                $result = json_decode($result, true);
+
+                $prefix = substr($params['qrcode_nbr'], 0, 2);
+                if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                    $params['pay_category'] = 'WXPAY';
+                    if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                        $order->order_status_system = 'PAYING';
+                        $order->order_status_payment = 'PENDING';
+                        $order->order_is_complete = 'N';
+//                        Db::rollBack();
+//                        return json_fail('支付失败');
+                    } else {
+                        $order->order_status_system = $systemStatus;
+                        $order->order_status_payment = 'SUCCESS';
+                        $paymentStatus = 'SUCCESS';
+                    }
+                } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                    $params['pay_category'] = 'ALIPAY';
+                    if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                        $order->order_status_system = 'PAYING';
+                        $order->order_status_payment = 'PENDING';
+                        $order->order_is_complete = 'N';
+//                        Db::rollBack();
+//                        return json_fail('支付失败');
+                    } else {
+                        $order->order_status_system = $systemStatus;
+                        $order->order_status_payment = 'SUCCESS';
+                        $paymentStatus = 'SUCCESS';
+                    }
+                } else {
+                    throw new BusinessException('付款码无效');
+                }
+
+                // 账户支付的金额
+                $params['order_amount_pay'] = $accountAmount;
+            }
+            if ($order->order_status_payment == 'SUCCESS'){
+                $order->order_amount_paid = $order->order_amount_paid + $params['order_amount_pay'];
+                $order->order_amount_pay = $order->order_amount_paid;
+            }
+
+            // 分期,支付完就结束了
+            if ($order->order_status_payment == 'SUCCESS' && $params['goods_classify'] == 'PARTNER' && floatval($order->order_amount_paid) >= $order->order_amount_total) {
+                $order->order_is_complete = 'Y';
+            }
+            if (floatval($order->order_amount_paid) < $order->order_amount_total) {
+                $order->order_status_system = 'PAYING';
+                $order->order_status_payment = 'PENDING';
+                $order->order_is_complete = 'N';
+            }
+            // 主订单
+            $order->save();
+
+            // sheet
+            if ($order->order_status_payment == 'SUCCESS') {
+                $data = [
+                    'order_sheet_status' => $systemStatus
+                ];
+                if (floatval($order->order_amount_paid) < $order->order_amount_total) {
+                    $data['order_sheet_status'] = 'BEING';
+                }
+                OrderSheet::where('join_sheet_order_id', $params['order_id'])->update($data);
+            }
+            // payDetail
+            $payData = [
+                'pay_amount' => $params['order_amount_pay']
+            ];
+            if ($paymentStatus == 'SUCCESS') {
+                $payData['pay_paytimes'] = date('Y-m-d H:i:s');
+                $payData['pay_status'] = 'SUCCESS';
+            }
+            if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                $payData['pay_prepayid'] = $params['pay_category'];
+                $payData['pay_json_response'] = $params['pay_json_response'];
+            } else if ($params['pay_category'] == 'CASH') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-CASH';
+            } else if ($params['pay_category'] == 'WELFARE') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-WELFARE';
+            } else if ($params['pay_category'] == 'CARD') {
+                $payData['pay_prepayid'] = $params['card_nbr'];
+            } else if ($params['pay_category'] == 'OFFLINE') {
+                $payData['pay_prepayid'] = 'OFFLINE';
+            } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                $payData['pay_prepayid'] = 'OFFLINE_ALIPAY';
+            } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                $payData['pay_prepayid'] = 'OFFLINE_WXPAY';
+            } else if ($params['pay_category'] == 'MONEY') {
+                $payData['pay_prepayid'] = 'MONEY';
+            }
+            // 清除此订单的未支付记录
+            PayDetail::whereJsonContains('join_pay_object_json->order_id', $order->order_id)->where('pay_status', 'WAITING')->delete();
+
+            $payData['join_pay_member_id'] = $params['join_order_member_id'];
+            $payData['join_pay_order_id'] = $order->order_groupby;
+            $payData['pay_status'] = !empty($payData['pay_status']) && $payData['pay_status'] == 'SUCCESS' ? $payData['pay_status'] : 'WAITING';
+            $payData['pay_category'] = $params['goods_classify'] ?? '';
+            $payData['pay_paytimes'] = date('Y-m-d H:i:s');
+            $payData['pay_json_request'] = json_encode($params);   // {"pay-result": "支付成功", "result-datetime": "2024-07-29 18:38:21"}
+            $payData['pay_json_response'] = !empty($payData['pay_status']) && $payData['pay_status'] == 'SUCCESS' ? json_encode([
+                'pay-result' => '支付成功', 'result-datetime' => date('Y-m-d H:i:s')
+            ]) : '[]';
+            $payData['join_pay_object_json'] = !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]';
+            $payData['pay_addtimes'] = time();
+
+            PayDetail::insert($payData);
+
+            // 分期付款完成
+            if ($params['goods_classify'] == 'PARTNER' && $order->order_status_payment == 'SUCCESS' && floatval($order->order_amount_paid) >= $order->order_amount_total) {
+                $params['member_id'] = $params['join_order_member_id'];
+                Event::dispatch('order.partner.grant', $params);
+            }
+
+            Db::commit();
+
+            if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                Event::dispatch('order.complete', $params);
+            }
+
+            if ($order->order_status_payment != 'SUCCESS' && $paymentStatus != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
+            }
+            _syslog("订单", "订单支付成功");
+            return json_success('支付成功');
+        } catch (BusinessException $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败:" . $e->getMessage());
+            return json_fail("支付失败:" . $e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败");
+            return json_fail('支付失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:30
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertMain($params)
+    {
+        try {
+            $orderCategory = 'NORMAL';
+            if (!empty($params['order_category'])) {
+                $orderCategory = $params['order_category'];
+            } else if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                $orderCategory = 'DISHES';
+            } else if (isset($params['goods_classify'])) {
+                $orderCategory = $params['goods_classify'];
+            }
+            if (empty($params['order_extend_json'])) {
+                $params['order_extend_json'] = [];
+            } else {
+                if (is_json($params['order_extend_json'])) {
+                    $params['order_extend_json'] = json_decode($params['order_extend_json'], true);
+                }
+            }
+            // 推荐人
+            $params['order_extend_json']['referee'] = $params['referee'] ?? '';
+
+            $data = [
+                'order_id' => $params['orderId'],
+                'order_groupby' => $params['orderGroupId'],
+                'join_order_member_id' => $params['join_order_member_id'],
+                'order_name' => date('Y-m-d H:i:s') . '-订单',
+                'order_amount_total' => $params['order_amount_total'],
+                'order_amount_pay' => $params['order_status_payment'] == 'SUCCESS' ? $params['order_amount_pay'] : 0,
+                'order_amount_paid' => $params['order_status_payment'] == 'SUCCESS' ? $params['order_amount_pay'] : 0,
+                'order_category' => $orderCategory,
+                'order_classify' => $orderCategory,
+                'order_is_complete' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) && $params['order_status_payment'] == 'SUCCESS' ? 'Y' : 'N',
+                'order_status_system' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
+                'order_status_payment' => floatval($params['order_amount_pay']) >= floatval($params['order_amount_total']) && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'PENDING',
+                'order_status_storage' => $params['order_status_storage'],
+                'order_platform' => $params['order_platform'],
+                'order_remark' => $params['order_remark'] ?? '',
+                'order_discount_json' => $params['order_discount_json'] ?? '[]',
+                'order_config_json' => $params['order_config_json'] ?? '[]',
+                'order_express_json' => $params['order_express_json'] ?? '[]',
+                'order_extend_json' => $params['order_extend_json'] ? json_encode($params['order_extend_json']) : '[]',
+                'order_addtimes' => time()
+            ];
+
+            Order::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('订单创建信息失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:25
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertSheet($params)
+    {
+        try {
+            $orderSheetIds = [];
+            foreach ($params['goodsContentList'] as $goods) {
+                //{"unit": "份", "table": null, "premises": "15"}
+                $price = floatval($goods['goods_sales_price']);
+                $extendJson['unit'] = $goods['sku_name'];
+                if (isset($params['submit_premises_id'])) {
+                    $extendJson['premises'] = $params['submit_premises_id'];
+                }
+                if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                    $extendJson['table'] = null;
+                }
+                $orderSheetStatus = 'PAYING';
+                if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                    if (floatval($params['order_amount_pay']) >= floatval($params['order_amount_total'])) {
+                        $orderSheetStatus = 'DONE';
+                    } else {
+                        $orderSheetStatus = 'BEING';
+                    }
+                }
+                $data = [
+                    'join_sheet_member_id' => $params['join_order_member_id'],
+                    'join_sheet_order_id' => $params['orderId'],
+                    'join_sheet_goods_id' => $goods['goods_id'],
+                    'join_sheet_goods_sku_id' => $goods['sku_id'],
+                    'order_sheet_status' => $orderSheetStatus,
+                    'order_sheet_category' => 'PARTNER',
+                    'order_sheet_num' => $goods['nbr'],
+                    'order_sheet_price' => $goods['goods_sales_price'],
+                    'order_sheet_amount' => $price * $goods['nbr'],
+                    'order_sheet_pay' => $price * $goods['nbr'],
+                    'order_sheet_task_status' => 'NONE',
+                    'order_sheet_remark' => $params['order_remark'] ?? '',
+                    'order_sheet_addtimes' => time(),
+                    'order_sheet_extend_json' => json_encode($extendJson)
+                ];
+
+                $orderSheetId = OrderSheet::insertGetId($data);
+                $orderSheetIds[] = $orderSheetId;
+
+                // 减库存,规格和总库存
+                if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                    $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                    $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                    if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                        $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                    }
+
+                    if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                        throw new BusinessException('库存不足');
+                    }
+                    $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
+                    $goodsSku->save();
+                }
+
+
+                $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+                $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+                if ($goodsRunning->goods_running_storage < 0) {
+                    throw new BusinessException('库存不足');
+                }
+                $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
+                $goodsRunning->save();
+            }
+            return $orderSheetIds;
+        } catch (\support\exception\BusinessException $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException('订单创建失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:35
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertPayDetail($params)
+    {
+        try {
+            if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                $payPrepayid = $params['pay_category'];
+            } else if ($params['pay_category'] == 'OFFLINE') {
+                $payPrepayid = 'OFFLINE';
+            } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                $payPrepayid = 'OFFLINE_ALIPAY';
+            } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                $payPrepayid = 'OFFLINE_WXPAY';
+            } else if ($params['pay_category'] == 'MONEY') {
+                $payPrepayid = 'MONEY';
+            } else {
+                $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
+            }
+            $data = [
+                'join_pay_member_id' => $params['join_order_member_id'],
+                'join_pay_order_id' => $params['orderGroupId'],
+                'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                'pay_category' => $params['goods_classify'],
+                'pay_amount' => $params['order_amount_pay'],
+                'pay_prepayid' => $payPrepayid,
+                'pay_paytimes' => date('Y-m-d H:i:s'),
+                'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]',
+                'pay_json_request' => json_encode($params),
+                'pay_json_response' => $params['pay_json_response'] ?? '[]',
+                'pay_remark' => $params['order_remark'] ?? '',
+                'pay_addtimes' => time(),
+            ];
+
+            PayDetail::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建支付记录失败');
+        }
+    }
+
+
+    /**
+     * @Desc 订单商品详情
+     * @Author Gorden
+     * @Date 2024/3/29 8:50
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function sheet(Request $request)
+    {
+        try {
+            $orderId = $request->get('order_id');
+            $orderSheet = OrderSheet::with([
+                'member' => function ($query) {
+                    $query->select('member_id', 'member_mobile', 'member_is_owner', 'join_member_role_id');
+                },
+                'goods' => function ($query) {
+                    $query->select('goods_id', 'goods_name', 'goods_cover', 'goods_market_price', 'goods_sales_price', 'goods_classify', 'goods_if_express');
+                },
+                'memberInfo',
+                'cert',
+                'sku' => function ($query) {
+                    $query->where('goods_sku_status', 'ON')
+                        ->select('goods_sku_id', 'join_sku_goods_id', 'goods_sku_specs_json', 'goods_sku_sales_price');
+                },
+                'skus',
+                'refund' => function ($query) {
+                    $query->select('join_return_order_id', 'order_return_status');
+                }
+            ])->where('join_sheet_order_id', $orderId)
+                ->orderBy('order_sheet_id', 'DESC')
+                ->get()
+                ->toArray();
+
+            $order = Order::where('order_id', $orderId)->first();
+            $express = OrderExpress::where('join_express_order_id', $orderId)->first();
+            $premises = '';
+            if ($express && $express->order_express_type == '自提') {
+                $premises = $express->order_express_company;
+            }
+            $sheetAmount = 0;
+            foreach ($orderSheet as &$item) {
+                $sheetAmount += $item['order_sheet_amount'];
+                $item['goods']['goods_cover'] = getenv('STORAGE_DOMAIN') . $item['goods']['goods_cover'];
+                if (!empty($item['goods']) && $item['goods']['goods_classify'] == 'PACKAGE') {
+                    $components = GoodsComponent::with('goods')
+                        ->where('join_component_master_goods_id', $item['goods']['goods_id'])
+                        ->select('join_component_master_goods_id', 'join_component_goods_id', 'goods_component_price',
+                            'goods_component_price', 'goods_component_json')
+                        ->get()
+                        ->toArray();
+                    $goodsArr = [];
+                    foreach ($components as $component) {
+                        $configJson = !empty($component['goods_component_json']) ? json_decode($component['goods_component_json'], true) : [];
+                        if (!empty($component['goods'])) {
+                            $supplierName = Supplier::where('supplier_id', $component['goods']['join_goods_supplier_id'])->value('supplier_name');
+                            $benefit = MemberBenefit::where('join_benefit_member_id', $item['join_sheet_member_id'])
+                                ->where('join_benefit_goods_id', $component['goods']['goods_id'])
+                                ->where('join_benefit_order_id', $orderId)
+                                ->first();
+                            $goodsArr[] = [
+                                'goods_name' => $component['goods']['goods_name'],
+                                'goods_cover' => getenv('STORAGE_DOMAIN') . $component['goods']['goods_cover'],
+                                'supplier_name' => $supplierName,
+                                'nbr' => $configJson['nbr'] ?? 0,
+                                'used' => !empty($benefit->member_benefit_used_count) ? intval($benefit->member_benefit_used_count) : ''
+                            ];
+                        }
+                    }
+
+                    $item['goods']['components'] = $goodsArr;
+                }
+                if (!empty($item['sku'])) {
+                    if (!empty($item['sku']['goods_sku_specs_json'])) {
+                        $specsJson = json_decode($item['sku']['goods_sku_specs_json'], true);
+                        $skuName = '';
+                        foreach ($specsJson as $specsKey => $skuSpecs) {
+                            if (is_array($skuSpecs)) {
+                                $skuName = $skuName . ' ' . implode(' ', $skuSpecs) . ';';
+                            } else {
+                                $skuName = $skuName . ' ' . $skuSpecs . ';';
+                            }
+                        }
+                        $item['sku']['goods_sku_title'] = rtrim($skuName, ';');
+                    }
+                }
+                if (!empty($item['skus'])) {
+                    foreach ($item['skus'] as $key => $skus) {
+                        if (!empty($skus['goods_sku_specs_json'])) {
+                            $item['skus'][$key]['goods_sku_specs_json'] = json_decode($skus['goods_sku_specs_json']);
+
+                            $skuName = '';
+                            foreach ($item['skus'][$key]['goods_sku_specs_json'] as $specsKey => $skuSpecs) {
+                                $keyStr = ($specsKey == '规格') ? '' : ($specsKey . ':');
+                                if (is_array($skuSpecs)) {
+                                    $skuName = $skuName . $keyStr . ' ' . implode(' ', $skuSpecs) . '; ';
+                                } else {
+                                    $skuName = $skuName . $keyStr . ' ' . $skuSpecs . '; ';
+                                }
+                            }
+                            $item['skus'][$key]['sku_name'] = rtrim($skuName, '; ');
+                        }
+                    }
+                } else {
+                    $item['skus'] = [];
+                }
+                if (in_array($item['goods']['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $order->order_status_system == 'DONE') {
+                    $item['appontment'] = [];
+                    $appontments = Appointment::where('join_appointment_order_id', $orderId)
+                        ->where('appointment_status', 'DONE')
+                        ->select('appointment_status', 'appointment_id', 'appointment_done_datetime', 'appointment_done_json', 'appointment_apply_json')
+                        ->get()
+                        ->toArray();
+                    foreach ($appontments as $appontment) {
+                        $doneJson = [];
+                        $username = '';
+                        if (!empty($appontment['appointment_done_json'])) {
+                            $doneJson = json_decode($appontment['appointment_done_json'], true);
+                            if (isset($doneJson['charge'])) {
+                                $username = SysUser::where('user_id', $doneJson['charge']['charge_user_id'])->value('user_name');
+                            }
+                        }
+                        $person = 1;
+                        if (!empty($appontment->appointment_apply_json)) {
+                            $applyJson = json_decode($appontment->appointment_apply_json, true);
+                            if (isset($applyJson['person'])) {
+                                $person = $applyJson['person'];
+                            }
+                        }
+                        $item['appontment'][] = [
+                            'member' => ($item['cert'] ? $item['cert']['member_cert_name'] . '-' : '') . ($item['member'] ? $item['member']['member_mobile'] : ''),
+                            'goods_name' => $item['goods']['goods_name'],
+                            'premisses' => isset($doneJson['charge']) ? $doneJson['charge']['charge_premises'] : '',
+                            'username' => $username,
+                            'nbr' => $person,
+                            'done_time' => $appontment['appointment_done_datetime'],
+                            'appointment_status' => $appontment['appointment_status'],
+                        ];
+                    }
+                }
+                if (!empty($item['order_sheet_extend_json']) && !$express) {
+                    $extendJson = json_decode($item['order_sheet_extend_json'], true);
+                    if (isset($extendJson['address_id'])) {
+                        $address = ClientConfig::where('client_config_id', $extendJson['address_id'])->first();
+                        if (!empty($address)) {
+                            $valJson = json_decode($address->client_config_val_json, true);
+                            $express = [
+                                'order_express_address' => $valJson['address'] . ($valJson['numbers'] ?? ''),
+                                'order_express_city' => $valJson['city'],
+                                'order_express_mobile' => $valJson['mobile'],
+                                'order_express_person' => $valJson['person']
+                            ];
+                        }
+                    }
+                }
+                $item['member']['level'] = '普通会员';
+                if (!empty($item['member']['join_member_role_id'])) {
+                    $item['member']['level'] = MemberRole::where('member_role_id', $item['member']['join_member_role_id'])->value('member_role_name');
+                }
+
+                if (!empty($item['member_info'])) {
+                    if (empty($item['member_info']['member_info_headimg']) || substr($item['member_info']['member_info_headimg'], 0, 1) == '.') {
+                        $item['member_info']['member_info_headimg'] = "https://img.wanyuewellness.com.cn/images/avatar_default.png";
+                    }
+                }
+            }
+            $order->sheet_amount = number_format($sheetAmount, 2);
+
+            $payDetails = PayDetail::whereJsonContains('join_pay_object_json->order_id', $order->order_id)
+                ->where('pay_category', 'PARTNER')
+                ->where('pay_status', 'SUCCESS')
+                ->select('pay_id', 'pay_category', 'pay_prepayid', 'pay_paytimes', 'pay_status', 'pay_amount', 'pay_extend_json')
+                ->orderBy('pay_addtimes', 'DESC')
+                ->get();
+            $order->pay_amount_total = 0;
+            foreach ($payDetails as &$payDetail) {
+                $categoryArray = explode('-', $payDetail->pay_prepayid);
+                if (isset($categoryArray[1])) {
+                    $payDetail->pay_category = $categoryArray[1];
+                } else if (in_array($categoryArray[0], ['WXPAY', 'ALIPAY', 'OFFLINE', 'OFFLINE_ALIPAY', 'OFFLINE_WXPAY', 'MONEY'])) {
+                    $payDetail->pay_category = $categoryArray[0];
+                }
+                if (!empty($payDetail->pay_extend_json)) {
+                    $payExtendJson = json_decode($payDetail->pay_extend_json, true);
+                    $order->cancel_times = $payExtendJson['cancel_times'] ?? '';
+                    if (isset($payExtendJson['ticket'])) {
+                        $payDetail->ticket = str_replace('/thumb', '', getenv("STORAGE_DOMAIN") . $payExtendJson['ticket']);
+                    }
+                }
+                $order->pay_amount_total += $payDetail->pay_amount;
+            }
+            $refund = OrderReturn::where('join_return_order_id', $orderId)
+                ->select('order_return_status', 'order_return_apply_datetime', 'order_return_apply_json', 'order_return_accept_datetime', 'order_return_refund_json', 'order_return_extend_json')
+                ->first();
+            if (!empty($refund->order_return_refund_json)) {
+                $returnRefundJson = json_decode($refund->order_return_refund_json, true);
+                if (isset($returnRefundJson['user_id'])) {
+                    $userName = SysUser::where('user_id', $returnRefundJson['user_id'])->value('user_name');
+                    $returnRefundJson['person'] = $userName;
+                    unset($returnRefundJson['user_id']);
+                }
+
+                $refund->order_return_refund_json = json_encode($returnRefundJson);
+            }
+            if (!empty($order->order_config_json)) {
+                $orderConfigJson = json_decode($order->order_config_json, true);
+                if (isset($orderConfigJson['reach'])) {
+                    $order->reach = $orderConfigJson['reach'];
+                }
+                if (isset($orderConfigJson['table'])) {
+                    $order->table = $orderConfigJson['table'];
+                }
+                if (isset($orderConfigJson['eat'])) {
+                    $order->eat = $orderConfigJson['eat'];
+                }
+                if (isset($orderConfigJson['express'])) {
+                    $order->express = $orderConfigJson['express'];
+                }
+                if (isset($orderConfigJson['premises'])) {
+                    $order->premises = $orderConfigJson['premises'];
+                }
+                if (isset($orderConfigJson['tableid'])) {
+                    $order->dept_table_id = $orderConfigJson['tableid'];
+                }
+            }
+            if (!empty($order->order_extend_json)) {
+                $orderExtendJson = json_decode($order->order_extend_json, true);
+                $order->referee = $orderExtendJson['referee'] ?? '';
+                if (isset($orderExtendJson['cancel_times'])) {
+                    $order->cancel_times = $orderExtendJson['cancel_times'];
+                }
+                if (isset($orderExtendJson['free_remark'])) {
+                    $order->free_remark = $orderExtendJson['free_remark'];
+                }
+            }
+            $discount = ['coupon_name' => '', 'classify' => '', 'value' => 0];
+            if (!empty($order->order_discount_json)) {
+                $orderDiscountJson = json_decode($order->order_discount_json, true);
+                foreach ($orderDiscountJson as $discountItem) {
+                    if (!empty($discountItem['coupon_id'])) {
+                        $coupon = Coupon::where('coupon_id', $discountItem['coupon_id'])
+                            ->select('coupon_name', 'coupon_classify', 'coupon_category', 'coupon_value', 'coupon_minimum_limit')
+                            ->first();
+                        if (!$coupon) {
+                            continue;
+                        }
+                        $classify = CouponService::couponClassifyInfo($coupon->coupon_classify, $coupon->coupon_category, $coupon->coupon_value, $coupon->coupon_minimum_limit);
+                        $discount['coupon_name'] .= $coupon->coupon_classify . ':' . $coupon->coupon_name . '(优惠¥' . sprintf("%.2f", $discountItem['coupon_value']) . '), ';
+                    }
+                    if ($discountItem['coupon_classify'] == '退款') {
+                        continue;
+                    }
+                    if (empty($discountItem['coupon_id']) && !empty($discountItem['coupon_classify'])) {
+                        if (!empty($discountItem['coupon_detail_id'])) {
+
+                            $discount['classify'] .= $discountItem['coupon_detail_id'][0] . '(优惠¥' . sprintf("%.2f", $discountItem['coupon_value']) . '), ';
+                        } else {
+                            $discount['classify'] .= $discountItem['coupon_classify'] . '(优惠¥' . sprintf("%.2f", $discountItem['coupon_value']) . '), ';
+                        }
+                    }
+                    if (!empty($discountItem['coupon_value'])) {
+                        $discount['value'] += $discountItem['coupon_value'];
+                    }
+                }
+                if (!empty($discount['coupon_name'])) {
+                    $discount['coupon_name'] = rtrim($discount['coupon_name'], ', ');
+                }
+                if (!empty($discount['classify'])) {
+                    $discount['classify'] = rtrim($discount['classify'], ', ');
+                }
+            }
+            $discount['value'] = sprintf("%.2f", $discount['value']);
+            $order->discount = $discount;
+
+            $order->premises = $order->premises ?? $premises;
+            $data = [
+                'order' => $order,
+                'refund' => json_decode(json_encode($refund)),
+                'sheet' => json_decode(json_encode($orderSheet)),
+                'express' => json_decode(json_encode($express)),
+                'payDetails' => json_decode(json_encode($payDetails))
+            ];
+
+            return json_success('', $data);
+
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+        }
+    }
+
+    /**
+     * @Desc 获取分期的订单
+     * @Author Gorden
+     * @Date 2024/9/10 15:14
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function getPaidOrder(Request $request)
+    {
+        $memberId = $request->get('member_id');
+        if (!$memberId) {
+            return json_fail('参数异常');
+        }
+
+        $order = Order::where('join_order_member_id', $memberId)
+            ->where('order_category', 'PARTNER')
+            ->where('order_status_system', 'PAYING')
+            ->select('order_id', 'order_amount_total', 'order_amount_paid', 'order_amount_pay')
+            ->first();
+
+        return json_success('', $order);
+    }
+
+    /**
+     * @Desc 上传支付凭证
+     * @Author Gorden
+     * @Date 2024/9/12 10:14
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function uploadTicket(Request $request)
+    {
+        $payId = $request->post('pay_id');
+        $url = $request->post('url');
+        if (!$payId || !$url) {
+            return json_fail("参数异常");
+        }
+        $url = str_replace(getenv("STORAGE_DOMAIN"), '', $url);
+        try {
+            $payDetail = PayDetail::where('pay_id', $payId)->first();
+            if (!$payDetail) {
+                return json_fail('数据异常');
+            }
+            $extendJson = [];
+            if (!empty($payDetail->pay_extend_json)) {
+                $extendJson = json_decode($payDetail->pay_extend_json, true);
+            }
+            $extendJson['ticket'] = $url;
+
+            $payDetail->pay_extend_json = json_encode($extendJson);
+            dump($payDetail->save());
+
+            return json_success('success');
+        } catch (\Exception $e) {
+            return json_fail("上传附件失败");
+        }
+    }
+}

+ 7 - 2
app/admin/controller/order/PayDetailController.php

@@ -333,12 +333,17 @@ class PayDetailController extends Curd
         try {
             $data = $this->insertRechargeInput($request, 'WELFARE');
             $data['pay_prepayid'] = $data['join_pay_member_id'] . '-WELFARE';
+            $memberAccount = MemberAccount::where('join_account_member_id', $data['join_pay_member_id'])
+                ->where('member_account_classify', 'WELFARE')
+                ->first();
+            if ($memberAccount->member_account_status != 'ACTIVED'){
+                throw new BusinessException('福利账户未开启');
+            }
 
             $this->doInsert($data);
 
             // 金额累加到福利账户
-            $memberAccount = MemberAccount::where('join_account_member_id', $data['join_pay_member_id'])->where('member_account_classify', 'WELFARE')->first();
-            $memberAccount->member_account_income = $memberAccount->member_account_income + $data['pay_amount'];
+           $memberAccount->member_account_income = $memberAccount->member_account_income + $data['pay_amount'];
             $memberAccount->member_account_surplus = $memberAccount->member_account_surplus + $data['pay_amount'];
             $memberAccount->save();
 

+ 79 - 9
app/admin/controller/order/RefundController.php

@@ -4,6 +4,7 @@ namespace app\admin\controller\order;
 
 use app\admin\validate\order\ReturnValidate;
 use app\controller\Curd;
+use app\model\CouponDetail;
 use app\model\GoodsComponent;
 use app\model\MemberAccount;
 use app\model\Order;
@@ -37,7 +38,7 @@ class RefundController extends Curd
         $type = $request->get('type', '');
         $field = $field ?? 'order_return_addtimes';
         $where['order_return_category'] = '退款';
-        if (!empty($where['order_return_addtimes'])){
+        if (!empty($where['order_return_addtimes'])) {
             $where['order_return_addtimes'][0] = strtotime($where['order_return_addtimes'][0]);
             $where['order_return_addtimes'][1] = strtotime($where['order_return_addtimes'][1]);
         }
@@ -107,13 +108,13 @@ class RefundController extends Curd
                     'goods' => function ($query) {
                         $query->select('goods_id', 'goods_name');
                     }
-                ])->select('join_sheet_order_id','join_sheet_goods_id')
-                    ->where('join_sheet_order_id',$item['order']->order_id)
+                ])->select('join_sheet_order_id', 'join_sheet_goods_id')
+                    ->where('join_sheet_order_id', $item['order']->order_id)
                     ->get()
                     ->toArray();
                 $goodsName = !empty($orderSheet) ? $orderSheet[0]['goods']['goods_name'] : '';
-                if (count($orderSheet) > 1){
-                    $goodsName.= ' 等';
+                if (count($orderSheet) > 1) {
+                    $goodsName .= ' 等';
                 }
                 $item['goods_name'] = $goodsName;
             }
@@ -127,8 +128,8 @@ class RefundController extends Curd
             }
             if (!empty($item['order_return_refund_json']) && is_json($item['order_return_refund_json'])) {
                 $returnRefundJson = json_decode($item['order_return_refund_json'], true);
-                if (!empty($returnRefundJson['user_id'])){
-                    $item['userName'] = SysUser::where('user_id',$returnRefundJson['user_id'])->value('user_name');
+                if (!empty($returnRefundJson['user_id'])) {
+                    $item['userName'] = SysUser::where('user_id', $returnRefundJson['user_id'])->value('user_name');
                 }
             }
         }
@@ -252,8 +253,8 @@ class RefundController extends Curd
         $return = OrderReturn::where('join_return_order_id', $orderId)->first();
         if (!empty($return->order_return_refund_json)) {
             $returnRefundJson = json_decode($return->order_return_refund_json, true);
-            if (!empty($returnRefundJson['user_id'])){
-                $return->userName = SysUser::where('user_id',$returnRefundJson['user_id'])->value('user_name');
+            if (!empty($returnRefundJson['user_id'])) {
+                $return->userName = SysUser::where('user_id', $returnRefundJson['user_id'])->value('user_name');
             }
         }
         $express = OrderExpress::where('join_express_order_id', $orderId)->first();
@@ -301,6 +302,26 @@ class RefundController extends Curd
         $response = [];
         Db::beginTransaction();
         try {
+            // 全额退款,检查优惠券,恢复可使用
+            if (sprintf("%.2f", $amount) == sprintf("%.2f", $order->order_amount_pay)) {
+                if (!empty($order->order_discount_json)) {
+                    $discountJson = json_decode($order->order_discount_json, true);
+                    foreach ($discountJson as $item){
+                        if (empty($item['coupon_id'])){
+                            continue;
+                        }
+                        // 是否有其他订单一起使用优惠券
+                        if(!Order::where('order_groupby',$order->order_groupby)->where('order_id','<>',$order->order_id)->where('order_is_complete','<>','R')->exists()){
+                            foreach ($item['coupon_detail_id'] as $detailId){
+                                CouponDetail::where('coupon_detail_id',$detailId)->update([
+                                    'coupon_detail_status'=>'ACTIVED',
+                                    'coupon_detail_used_datetime'=>''
+                                ]);
+                            }
+                        }
+                    }
+                }
+            }
             // 主订单,退款作为优惠入库
             $this->updateMainOrderByRefund($order, $amount, $remark);
             // return 表记录
@@ -343,6 +364,14 @@ class RefundController extends Curd
                     $prepayid = $order->join_order_member_id . '-CASH';
                     $this->refundToCash($order->join_order_member_id, $amount);
                     $response = ['order_id' => $order->order_id, 'member_id' => $order->join_order_member_id];
+                } elseif (isset($payWay[1]) && $payWay[1] == 'WELFARE') {
+                    $prepayid = $order->join_order_member_id . '-WELFARE';
+                    $this->refundToWelfare($order->join_order_member_id, $amount);
+                    $response = ['order_id' => $order->order_id, 'member_id' => $order->join_order_member_id];
+                } elseif (isset($payWay[1]) && $payWay[1] == 'VIP') {
+                    $prepayid = $order->join_order_member_id . '-VIP';
+                    $this->refundToVIP($order->join_order_member_id, $amount);
+                    $response = ['order_id' => $order->order_id, 'member_id' => $order->join_order_member_id];
                 } elseif (isset($payWay['1']) && $payWay[1] == 'CARD') {
                     $prepayid = $order->join_order_member_id . '-CARD';
                     $this->refundToCard($order->join_order_member_id, $amount);
@@ -395,6 +424,47 @@ class RefundController extends Curd
         $account->save();
     }
 
+    /**
+     * @Desc 退款到福利账户
+     * @Author Gorden
+     * @Date 2024/9/20 17:09
+     *
+     * @param $memberId
+     * @param $amount
+     * @return void
+     * @throws BusinessException
+     */
+    private function refundToWelfare($memberId, $amount)
+    {
+        $account = MemberAccount::where('join_account_member_id', $memberId)->where('member_account_classify', 'WELFARE')->first();
+        if (!$account) {
+            throw new BusinessException("余额账户异常");
+        }
+        $account->member_account_surplus = $account->member_account_surplus + $amount;
+        $account->save();
+    }
+
+    /**
+     * @Desc 退款到VIP账户
+     * @Author Gorden
+     * @Date 2024/9/20 17:12
+     *
+     * @param $memberId
+     * @param $amount
+     * @return void
+     * @throws BusinessException
+     */
+    private function refundToVIP($memberId, $amount)
+    {
+        $account = MemberAccount::where('join_account_member_id', $memberId)->where('member_account_classify', 'VIP')->first();
+        if (!$account) {
+            throw new BusinessException("余额账户异常");
+        }
+        $account->member_account_surplus = $account->member_account_surplus + $amount;
+        $account->save();
+    }
+
+
     /**
      * @Desc 退款到储蓄卡
      * @Author Gorden

+ 2402 - 14
app/admin/controller/order/ServicesController.php

@@ -2,15 +2,33 @@
 
 namespace app\admin\controller\order;
 
+use app\admin\service\member\MemberService;
+use app\admin\service\order\OrderService;
 use app\admin\validate\order\OrderValidate;
 use app\controller\Curd;
+use app\model\Appointment;
+use app\model\CouponDetail;
 use app\model\Goods;
+use app\model\GoodsComponent;
+use app\model\GoodsRunning;
+use app\model\GoodsSku;
+use app\model\Member;
+use app\model\MemberAccount;
+use app\model\MemberBenefit;
 use app\model\Order;
+use app\model\OrderExpress;
 use app\model\OrderSheet;
+use app\model\PayDetail;
+use app\model\SysDept;
+use support\Db;
+use support\exception\BusinessException;
+use support\Redis;
 use support\Request;
 use support\Response;
+use Webman\Event\Event;
 
-class ServicesController extends Curd{
+class ServicesController extends Curd
+{
     public function __construct()
     {
         $this->model = new Order();
@@ -35,32 +53,32 @@ class ServicesController extends Curd{
             $where['order_addtimes'][1] = strtotime($where['order_addtimes'][1]);
         }
 
-        $where['order_classify'] = ['in','SERVICE,CHNMED,CHNNCD'];
+        $where['order_classify'] = ['in', 'SERVICE,CHNMED,CHNNCD'];
         $order = $request->get('order', 'desc');
         $field = $field ?? 'order_addtimes';
         if (!empty($where['order_status_system']) && in_array($where['order_status_system'], ['PENDING', 'WAITING', 'SENDING', 'RECVING', 'SIGNED', 'CONFIRM'])) {
             $where['order_is_complete'] = 'N';
-            $where['order_category'] = ['<>','RETURN'];
+            $where['order_category'] = ['<>', 'RETURN'];
         }
 
         $orderId = trim($request->get('order_id', ''));
         $orderIds = [];
         if (!empty($orderId)) {
             $orderIds = Order::where('order_id', 'like', '%' . $orderId . '%')
-                ->whereIn('order_classify', ['SERVICE','CHNMED','CHNNCD'])
+                ->whereIn('order_classify', ['SERVICE', 'CHNMED', 'CHNNCD'])
                 ->pluck('order_id')
                 ->toArray();
         }
         $goodsName = trim($request->get('goods_name', ''));
         if (!empty($goodsName)) {
-            $goodsIds = Goods::whereIn('goods_classify', ['SERVICE','CHNMED','CHNNCD'])
+            $goodsIds = Goods::whereIn('goods_classify', ['SERVICE', 'CHNMED', 'CHNNCD'])
                 ->where('goods_name', 'like', '%' . $goodsName . '%')
                 ->pluck('goods_id')
                 ->toArray();
             $goodsOrderIds = OrderSheet::whereIn('join_sheet_goods_id', $goodsIds)->pluck('join_sheet_order_id')->toArray();
             if (!empty($where['order_id'])) {
                 $orderIds = array_intersect($orderIds, $goodsOrderIds);
-            }else{
+            } else {
                 $orderIds = $goodsOrderIds;
             }
         }
@@ -76,7 +94,7 @@ class ServicesController extends Curd{
     {
         $model = $this->model->with([
             'sheets' => function ($query) {
-                $query->select('join_sheet_order_id', 'order_sheet_id', 'join_sheet_goods_id', 'order_sheet_num','order_sheet_price');
+                $query->select('join_sheet_order_id', 'order_sheet_id', 'join_sheet_goods_id', 'order_sheet_num', 'order_sheet_price');
             },
             'member' => function ($query) {
                 $query->select('member_id', 'member_mobile');
@@ -94,7 +112,7 @@ class ServicesController extends Curd{
             'express' => function ($query) {
                 $query->select('join_express_order_id', 'order_express_type');
             }
-        ])->leftJoin('order_return','order_return.join_return_order_id','=','order.order_id');
+        ])->leftJoin('order_return', 'order_return.join_return_order_id', '=', 'order.order_id');
         // ->leftJoin('order_sheet','join_sheet_order_id','=','order.order_id');
         foreach ($where as $column => $value) {
             if (is_array($value)) {
@@ -128,7 +146,7 @@ class ServicesController extends Curd{
         if ($field) {
             $model = $model->orderBy($field, $order);
         }
-        $model = $model->select('order.*','order_return.orders_return_id', 'order_return.join_return_order_id', 'order_return.order_return_status','order_return.order_return_apply_json','order_return.order_return_remark');
+        $model = $model->select('order.*', 'order_return.orders_return_id', 'order_return.join_return_order_id', 'order_return.order_return_status', 'order_return.order_return_apply_json', 'order_return.order_return_remark');
         return $model;
     }
 
@@ -139,25 +157,2395 @@ class ServicesController extends Curd{
             $item['sheet'] = $item['sheets'][0] ?? [];
             if (!empty($item['sheet'])) {
                 $goods = Goods::where('goods_id', $item['sheet']['join_sheet_goods_id'])->first();
-                if(count($item['sheets']) > 1 && $goods->goods_classify == 'MEALS'){
+                if (count($item['sheets']) > 1 && $goods->goods_classify == 'MEALS') {
                     $sheetDeng = ' 等餐品';
                 }
-                $item['sheet']['goods_name'] = ($goods && $goods->goods_name) ? $goods->goods_name.$sheetDeng : '';
+                $item['sheet']['goods_name'] = ($goods && $goods->goods_name) ? $goods->goods_name . $sheetDeng : '';
                 $item['sheet']['goods_classify'] = $goods->goods_classify ?? '';
                 $item['sheet']['order_sheet_num'] = intval($item['sheet']['order_sheet_num']);
             }
             unset($item['sheets']);
-            if (isset($item['orders_return_id'])){
+            if (isset($item['orders_return_id'])) {
                 $item['return'] = [
-                    'orders_return_id'=>$item['orders_return_id'],
+                    'orders_return_id' => $item['orders_return_id'],
                     'join_return_order_id' => $item['join_return_order_id'],
                     'order_return_status' => $item['order_return_status'],
                     'order_return_apply_json' => $item['order_return_apply_json'],
-                    'order_return_remark'=>$item['order_return_remark']
+                    'order_return_remark' => $item['order_return_remark']
                 ];
             }
+            $item['have_success_paydetail'] = 'N';
+            if (PayDetail::where('join_pay_order_id', $item['order_groupby'])
+                ->whereJsonContains('join_pay_object_json->order_id', $item['order_id'])
+                ->where('pay_status', 'SUCCESS')
+                ->exists()) {
+                $item['have_success_paydetail'] = 'Y';
+            }
         }
 
         return $items;
     }
+
+    /**
+     * @Desc 下单+支付
+     * @Author Gorden
+     * @Date 2024/9/23 16:15
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function insert(Request $request): Response
+    {
+        $params = $request->post();
+        // 判断餐品是否连带着服务或实体
+        $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
+        $premises = [];
+        if (!empty($params['dept_premises_id'])) {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+        }
+
+        $params['goods_classify'] = $goodsClassifys[0];
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('insert', $params['settlement_now'], $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            $params['order_discount_json'] = json_encode($this->discountRecord($couponUseJson, $params));
+            // 验证库存
+            foreach ($params['goodsContentList'] as $goods) {
+                // 减库存,规格和总库存
+                if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                    $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                    $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                    if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                        $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                    }
+                    if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                        throw new BusinessException('库存不足');
+                    }
+                }
+
+
+                $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+                $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+                if ($goodsRunning->goods_running_storage < 0) {
+                    throw new BusinessException('库存不足');
+                }
+            }
+            // 余额、福利、储值卡 验证短信
+            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE', 'VIP'])) {
+                $code = $params['sms_code'];
+                if (!$code) {
+                    throw new BusinessException('验证码错误,请重新输入');
+                }
+                $member = Member::find($params['join_order_member_id']);
+                $mobile = $member->member_mobile;
+                $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+                $redisCode = Redis::get($key);
+                if ($redisCode != $code && $code != '123456') {
+                    throw new BusinessException('验证码错误,请重新输入');
+                }
+                Redis::del($key);
+            }
+            // 验证线下付款密码
+            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
+                $password = $params['offline_password'];
+                if ($password != '666888') {
+                    throw new BusinessException('密码错误,请重新输入');
+                }
+            }
+            // 下单账户
+            if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
+                if (Member::where('member_mobile', $params['mobile'])->exists()) {
+                    throw new BusinessException('会员已存在');
+                }
+                $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
+                // 创建会员
+                MemberService::createMember($params);
+            } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
+                $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
+            }
+            if (empty($params['join_order_member_id'])) {
+                throw new BusinessException('检查下单账户');
+            }
+
+            $qrcodePayAmount = 0;
+            $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+
+            $systemStatus = 'SENDING';  // 待发货
+            // 立即结算
+            if ($params['settlement_now'] == 'Y') {
+                if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+                    $params['order_is_complete'] = 'Y';
+                    $systemStatus = 'DONE';
+                }
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+                    $params['order_is_complete'] = 'N';
+                    $systemStatus = "WAITING";
+                }
+            }
+
+            if ($params['settlement_now'] == 'Y' && ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY')) {
+                if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
+                    $params['pay_category'] = $params['pay_category_sub'];
+                }
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'CASH') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'VIP') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'VIP')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'WELFARE') {  // 福利账户
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'WELFARE')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $account->member_account_surplus = floatval($account->member_account_surplus);
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    throw new BusinessException('账户余额不足');
+                }
+
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                // 福利账户 300 、 700
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS'])) {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 700 - $paySum < $params['order_amount_pay']) {
+                        Db::rollBack();
+                        return json_fail('超出福利限额');
+                    }
+                } else {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereNotIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES', 'REFUND', 'RECHARGE'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 300 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    }
+                }
+
+                $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'CARD') {  // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+            }
+            if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])) {     // 付款码
+                if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount <= 0) {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                // 不组合或者组合后需要付款码的金额>0
+                if ($params['pay_constitute'] == 'N' || ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0)) {
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException('付款码无效');
+                    }
+                }
+            }
+
+            $orderConfigJson = [];
+            // 优惠
+            if (!empty($params['preferential'])) {
+                $orderConfigJson['preferential'] = $params['preferential'];
+            }
+
+            // 配送方式
+            if (isset($params['delivery']) && ($params['delivery'] == 'PICKUP' || $params['delivery'] == 'ARRIVAL')) { // 自提/ 到店
+                $orderConfigJson['premises'] = $params['dept_premises_id'];
+            }
+
+            if (isset($params['delivery']) && in_array($params['delivery'], ['PICKUP', 'ARRIVAL']) && !empty($params['dept_premises_id'])) {
+                $params['submit_premises_id'] = $premises->dept_id;
+            }
+
+            $params['order_config_json'] = json_encode($orderConfigJson);
+            // 写入订单
+            $this->insertMain($params);
+
+            Db::commit();
+
+            // 会员升级
+            if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                Event::dispatch('order.complete', $params);
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+
+            if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "创建订单成功");
+            return json_success('创建订单成功');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            dump($e->getTrace());
+            _syslog("订单", $e->getMessage());
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            dump($e->getTrace());
+            _syslog("订单", "创建订单失败");
+            return json_fail('创建订单失败');
+        }
+    }
+
+    /**
+     * 组合支付下单
+     */
+    public function insertConstitute(Request $request): Response
+    {
+        $params = $request->post();
+        $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
+        $premises = [];
+        if (!empty($params['dept_premises_id'])) {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+        }
+
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('insert', $params['settlement_now'], $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            $params['order_discount_json'] = json_encode($this->discountRecord($couponUseJson, $params));
+            $orderAmountPay = $params['order_amount_pay'];
+            $constituteList = array_column($params['pay_category_constitute_list'], 'amount', 'category');
+            // 验证金额
+            $constituteAmount = 0;
+            foreach ($params['pay_category_constitute_list'] as $item) {
+                $constituteAmount = sprintf("%.2f", $constituteAmount) + sprintf("%.2f", $item['amount']);
+            }
+            if (sprintf("%.2f", $params['order_amount_pay']) != sprintf("%.2f", $constituteAmount)) {
+                throw new BusinessException('组合支付金额与应付金额不一致');
+            }
+            $params['goods_classify'] = $goodsClassifys[0];
+            // 验证库存
+            OrderService::checkGoodsStorage($params);
+            // 余额、福利、储值卡 验证短信
+            if (!empty($params['pay_category_constitute'])
+                && !in_array('OFFLINE', $params['pay_category_constitute'])
+                && !in_array('MONEY', $params['pay_category_constitute'])
+                && !in_array('QRCODE', $params['pay_category_constitute'])
+                && (in_array('CASH', $params['pay_category_constitute'])
+                    || in_array('CARD', $params['pay_category_constitute'])
+                    || in_array('WELFARE', $params['pay_category_constitute']))) {
+                $code = $params['sms_code'];
+                if (!$code) {
+                    throw new BusinessException("验证码错误,请重新输入");
+                }
+                $member = Member::find($params['join_order_member_id']);
+                $mobile = $member->member_mobile;
+                $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+                $redisCode = Redis::get($key);
+                if ($redisCode != $code && $code != '123456') {
+                    throw new BusinessException("验证码错误,请重新输入");
+                }
+                Redis::del($key);
+            }
+            // 验证线下付款密码
+            if (!empty($params['pay_category_constitute'])
+                && in_array('OFFLINE', $params['pay_category_constitute'])
+                || (in_array('MONEY', $params['pay_category_constitute']) && !in_array('QRCODE', $params['pay_category_constitute']))) {
+                $password = $params['offline_password'];
+                if ($password != '666888') {
+                    throw new BusinessException("密码错误,请重新输入");
+                }
+            }
+            // 下单账户
+            if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
+                if (Member::where('member_mobile', $params['mobile'])->exists()) {
+                    throw new BusinessException("会员已存在");
+                }
+                $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
+                // 创建会员
+                MemberService::createMember($params);
+            } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
+                $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
+            }
+            if (empty($params['join_order_member_id'])) {
+                throw new BusinessException("检查下单账户");
+            }
+
+            $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+            $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+
+            $systemStatus = 'SENDING';  // 待发货
+            // 立即结算
+            if ($params['settlement_now'] == 'Y') {
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+                    $params['order_is_complete'] = 'N';
+                    $systemStatus = "WAITING";
+                }
+            }
+            $params['pay_detail_item'] = [];
+            $wxAndAliPayStatus = 'Y';
+            if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute'])) {      // 线下支付
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['pay_category'] = $params['pay_category_sub'] ?? 'OFFLINE';
+
+                // 线下支付金额
+                if (isset($constituteList['OFFLINE'])) {
+                    $params['order_amount_pay'] = $constituteList['OFFLINE'];
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {      // 现金支付
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['pay_category'] = 'MONEY';
+
+                // 现金支付金额
+                if (isset($constituteList['MONEY'])) {
+                    $params['order_amount_pay'] = $constituteList['MONEY'];
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CASH', $params['pay_category_constitute'])) {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException("账户异常");
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+
+                if (isset($constituteList['CASH'])) {
+                    $params['order_amount_pay'] = $constituteList['CASH'];
+                    $params['pay_category'] = $params['join_order_member_id'] . '-CASH';
+                }
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException("账户余额不足");
+                }
+//                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+//                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+//                    $params['order_amount_pay'] = $amount;
+//                }
+//                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+//                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+//                    $account->member_account_surplus = 0;
+//                    $account->member_account_added = $cut;
+//                } else {
+//                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+//                }
+//                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+//                $account->save();
+                // 余额账户扣款数据
+                $params['waitToPayAccount']['cash'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CASH'],
+                    'nbr' => $params['join_order_member_id'] . '-CASH'
+                ];
+
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+
+                // 生成支付记录
+                $params['pay_detail_item'][] = $params;
+                $params['order_amount_pay'] = $orderAmountPay;
+
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CARD', $params['pay_category_constitute'])) {    // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException("储值卡账户异常");
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException("储值卡账户异常");
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+
+                // 储值卡账户支付金额
+                if (isset($constituteList['CARD'])) {
+                    $params['order_amount_pay'] = $constituteList['CARD'];
+                    $params['pay_category'] = $cardNbr;
+                }
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException("储值卡账户余额不足");
+                }
+//                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+//                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+//                    $params['order_amount_pay'] = $amount;
+//                }
+//
+//                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+//                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+//                    $account->member_account_surplus = 0;
+//                    $account->member_account_added = $cut;
+//                } else {
+//                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+//                }
+//                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+//                $account->save();
+                // 储值卡账户扣款数据
+                $params['waitToPayAccount']['card'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CARD'],
+                    'nbr' => $params['join_order_member_id'] . '-CARD'
+                ];
+
+                $params['order_status_system'] = $systemStatus;
+                $params['order_status_payment'] = 'SUCCESS';
+                // 生成支付记录
+                $params['pay_detail_item'][] = $params;
+
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            //!empty($params['pay_category_constitute']) && in_array('CARD',$params['pay_category_constitute'])
+            // if(($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])){     // 付款码
+            if (!empty($params['pay_category_constitute']) && in_array('QRCODE', $params['pay_category_constitute']) && !empty($params['qrcode_nbr'])) {     // 付款码
+                // 需要付款码的金额>0
+                if (isset($constituteList['QRCODE']) && $constituteList['QRCODE'] > 0) {
+                    // 付款码支付金额
+                    $params['order_amount_pay'] = $constituteList['QRCODE'];
+                    // 调支付
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $params['order_status_system'] = 'PAYING';
+                            $params['order_status_payment'] = 'PENDING';
+                            $params['order_is_complete'] = 'N';
+//                            Db::rollBack();
+//                            return json_fail('支付失败');
+                        } else {
+                            $params['order_status_system'] = $systemStatus;
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException("二维码错误");
+                    }
+
+                    // 生成支付记录
+                    $params['pay_detail_item'][] = $params;
+//                    OrderService::createPayDetail($params);
+                    // 账户支付的金额
+                    $params['order_amount_pay'] = $orderAmountPay;
+                }
+            }
+
+            $orderConfigJson = [];
+            // 优惠
+            if (!empty($params['preferential'])) {
+                $orderConfigJson['preferential'] = $params['preferential'];
+            }
+            // 配送方式
+            if (isset($params['delivery']) && ($params['delivery'] == 'PICKUP' || $params['delivery'] == 'ARRIVAL')) { // 自提/ 到店
+                $orderConfigJson['premises'] = $params['dept_premises_id'];
+            }
+            $params['order_config_json'] = json_encode($orderConfigJson);
+            // 写入订单
+            $this->insertMain($params, $wxAndAliPayStatus);
+
+            Db::commit();
+
+            // 会员升级
+            if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                Event::dispatch('order.complete', $params);
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+
+            if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "创建订单成功");
+            return json_success('创建订单成功');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            _syslog("订单", $e->getMessage());
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            _syslog("订单", "创建订单失败");
+            return json_fail('创建订单失败');
+        }
+    }
+
+    public function pay(Request $request)
+    {
+        $params = $request->post();
+        // 余额、福利、储值卡 验证短信
+        if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE'])) {
+            $code = $params['sms_code'];
+            if (!$code) {
+                return json_fail("验证码错误,请重新输入");
+            }
+            $member = Member::find($params['join_order_member_id']);
+            $mobile = $member->member_mobile;
+            $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+            $redisCode = Redis::get($key);
+            if ($redisCode != $code && $code != '123456') {
+                return json_fail("验证码错误,请重新输入");
+            }
+            Redis::del($key);
+        }
+        // 验证线下付款密码
+        if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
+            $password = $params['offline_password'];
+            if ($password != '666888') {
+                return json_fail("密码错误,请重新输入");
+            }
+        }
+
+        $order = Order::where('order_id', $params['order_id'])->first();
+        if (!$order) {
+            return json_fail('订单异常');
+        }
+        if ($order->order_status_system != 'PAYING') {
+            return json_fail('订单不是可支付状态');
+        }
+
+        if (!empty($order->order_config_json)) {
+            $orderConfigJson = json_decode($order->order_config_json, true);
+            if (isset($orderConfigJson['premises'])) {
+                $premises = SysDept::where('dept_name', $orderConfigJson['premises'])->first();
+                if (!empty($premises)) {
+                    $params['submit_premises_id'] = $premises->dept_id;
+                }
+            }
+        }
+        $params['orderId'] = $params['order_id'];
+        $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+        $order->order_groupby = $params['orderGroupId'];
+
+        $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
+            ->select('goods_id', 'goods_name', 'goods_classify')
+            ->first();
+        if (!$goods) {
+            return json_fail('产品数据异常');
+        }
+        $goods = $goods->toArray();
+        $params['goods_classify'] = $goods['goods_classify'] ?? '';
+
+        $systemStatus = 'SENDING';  // 待发货
+        // 立即结算
+        if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+            $order->order_is_complete = 'Y';
+            $systemStatus = 'DONE';
+        }
+        if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+            $params['order_is_complete'] = 'N';
+            $systemStatus = "WAITING";
+        }
+//        if ($params['goods_classify'] == 'PACKAGE' && $params['delivery'] == 'ARRIVAL') {
+//            $systemStatus = "WAITING";
+//        }
+        Db::beginTransaction();
+        try {
+            // 使用优惠券
+            $couponUseJson = [];
+            $discountJson = [];
+            if (!empty($order->order_discount_json)) {
+                $discountJson = json_decode($order->order_discount_json, true);
+                foreach ($discountJson as $item) {
+                    if (isset($item['coupon_value']) && sprintf('%.2f', (floatval($order->order_amount_total) - floatval($params['order_amount_pay']))) != sprintf('%.2f', $item['coupon_value'])) {
+                        throw new BusinessException("计算优惠后,实付金额错误!");
+                    }
+                }
+                $couponUseJson = $discountJson;
+                $this->changeOrderCouponStatus($couponUseJson, 'USED');
+                // 释放下单时选的优惠券
+//                $order->order_discount_json = $this->releaseCoupon($discountJson);
+            }
+            if (empty($discountJson) && !empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('pay', 'Y', $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            if (empty($discountJson)) {
+                $order->order_discount_json = json_encode($this->discountRecord($couponUseJson, $params));
+            }
+            // 组合支付时,付款码应收金额
+            $qrcodePayAmount = 0;
+            if ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY') {
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
+                    $params['pay_category'] = $params['pay_category_sub'];
+                }
+            } else if ($params['pay_category'] == 'CASH') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            } else if ($params['pay_category'] == 'VIP') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'VIP')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            } else if ($params['pay_category'] == 'WELFARE') {  // 福利账户
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'WELFARE')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $account->member_account_surplus = floatval($account->member_account_surplus);
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $account->member_account_surplus;
+                    $params['order_amount_pay'] = $account->member_account_surplus;
+                }
+
+                if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] <= $account->member_account_surplus)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+                // 福利账户 300 、 700
+                if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS'])) {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 700 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    } else if ($params['pay_constitute'] == 'Y' && 700 - $paySum < $params['order_amount_pay']) {
+                        $qrcodePayAmount = $params['order_amount_pay'] - (700 - $paySum);
+                        $params['order_amount_pay'] = (700 - $paySum);
+                    }
+                } else {
+                    $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->whereNotIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES', 'REFUND', 'RECHARGE'])
+                        ->get()
+                        ->toArray();
+
+                    $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
+                        ->where('pay_status', 'SUCCESS')
+                        ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
+                        ->where('pay_category', 'REFUND')
+                        ->get()
+                        ->toArray();
+                    $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
+
+                    $paySum = 0;
+                    foreach ($payDetailArray as $key => $item) {
+                        if (isset($refundPayDetailArray[$key])) {
+                            $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
+                            continue;
+                        }
+
+                        $paySum = $paySum + $item;
+                    }
+
+                    if ($params['pay_constitute'] == 'N' && 300 - $paySum < $params['order_amount_pay']) {
+                        throw new BusinessException('超出福利限额');
+                    } else if ($params['pay_constitute'] == 'Y' && 300 - $paySum < $params['order_amount_pay']) {
+                        $qrcodePayAmount = $params['order_amount_pay'] - (300 - $paySum);
+                        $params['order_amount_pay'] = (300 - $paySum);
+                    }
+                }
+                $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+            } else if ($params['pay_category'] == 'CARD') {  // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
+            }
+            if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && !empty($params['qrcode_nbr'])) {     // 付款码
+                // 提交过来的支付分类
+                $submitPayCategory = $params['pay_category'];
+                // 账户支付的金额
+                $accountAmount = $params['order_amount_pay'];
+                if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0) {
+                    // 组合支付,改成需要付款码需要支付的金额
+                    $params['order_amount_pay'] = $qrcodePayAmount;
+                }
+                // 去支付
+                $result = OrderService::qrcodePay($params);
+                $result = json_encode($result);
+                $params['pay_json_response'] = $result;
+                $result = json_decode($result, true);
+
+                $prefix = substr($params['qrcode_nbr'], 0, 2);
+                if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                    $params['pay_category'] = 'WXPAY';
+                    if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                        $order->order_status_system = 'PAYING';
+                        $order->order_status_payment = 'PENDING';
+                        $order->order_is_complete = 'N';
+//                        Db::rollBack();
+//                        return json_fail('支付失败');
+                    } else {
+                        $order->order_status_system = $systemStatus;
+                        $order->order_status_payment = 'SUCCESS';
+                    }
+                } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                    $params['pay_category'] = 'ALIPAY';
+                    if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                        $order->order_status_system = 'PAYING';
+                        $order->order_status_payment = 'PENDING';
+                        $order->order_is_complete = 'N';
+//                        Db::rollBack();
+//                        return json_fail('支付失败');
+                    } else {
+                        $order->order_status_system = $systemStatus;
+                        $order->order_status_payment = 'SUCCESS';
+                    }
+                } else {
+                    throw new BusinessException('付款码无效');
+                }
+                // 账户支付的金额
+                $params['order_amount_pay'] = $accountAmount;
+            }
+            $orderConfigJson = [];
+            if (!empty($order->order_config_json)) {
+                $orderConfigJson = json_decode($order->order_config_json, true);
+            }
+            $orderConfigJson['preferential'] = $params['preferential'] ?? '';
+            $order->order_config_json = json_encode($orderConfigJson);
+            $order->order_amount_pay = $params['order_amount_pay'] + $qrcodePayAmount;
+            // 主订单
+            $order->save();
+
+            // sheet
+            if ($order->order_status_payment == 'SUCCESS') {
+                OrderSheet::where('join_sheet_order_id', $params['order_id'])->update([
+                    'order_sheet_status' => $systemStatus,
+                ]);
+            }
+            // payDetail
+            // 不组合支付,那就只有一条支付记录 先删,再加
+            PayDetail::where('join_pay_order_id', $order->order_groupby)
+                ->whereJsonContains('join_pay_object_json->order_id', $params['orderId'])
+                ->delete();
+            $payData = [
+                'pay_amount' => $params['order_amount_pay']
+            ];
+            if ($order->order_status_payment == 'SUCCESS') {
+                $payData['pay_paytimes'] = date('Y-m-d H:i:s');
+                $payData['pay_status'] = 'SUCCESS';
+            }
+            if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                $payData['pay_prepayid'] = $params['pay_category'];
+                $payData['pay_json_response'] = $params['pay_json_response'];
+            } else if ($params['pay_category'] == 'CASH') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-CASH';
+            } else if ($params['pay_category'] == 'WELFARE') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-WELFARE';
+            } else if ($params['pay_category'] == 'VIP') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-VIP';
+            } else if ($params['pay_category'] == 'CARD') {
+                $payData['pay_prepayid'] = $params['card_nbr'];
+            } else if ($params['pay_category'] == 'OFFLINE') {
+                $payData['pay_prepayid'] = 'OFFLINE';
+            } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                $payData['pay_prepayid'] = 'OFFLINE_ALIPAY';
+            } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                $payData['pay_prepayid'] = 'OFFLINE_WXPAY';
+            } else if ($params['pay_category'] == 'MONEY') {
+                $payData['pay_prepayid'] = 'MONEY';
+            }
+            $payData['join_pay_member_id'] = $params['join_order_member_id'];
+            $payData['join_pay_order_id'] = $order->order_groupby;
+            $payData['pay_status'] = !empty($payData['pay_status']) && $payData['pay_status'] == 'SUCCESS' ? $payData['pay_status'] : 'WAITING';
+            $payData['pay_category'] = $params['goods_classify'] ?? '';
+            $payData['pay_paytimes'] = date('Y-m-d H:i:s');
+            $payData['pay_json_request'] = json_encode($params);   // {"pay-result": "支付成功", "result-datetime": "2024-07-29 18:38:21"}
+            $payData['pay_json_response'] = !empty($payData['pay_status']) && $payData['pay_status'] == 'SUCCESS' ? (!empty($params['pay_json_response']) ? $params['pay_json_response'] : json_encode(['pay-result' => '支付成功', 'result-datetime' => date('Y-m-d H:i:s')])) : '[]';
+            $payData['join_pay_object_json'] = !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]';
+            $payData['pay_addtimes'] = time();
+            PayDetail::insert($payData);
+
+            $writeOffDate = [];
+            $applyData = [];
+            // 有预约单,状态已完成
+            $appointment = Appointment::where('join_appointment_order_id', $params['order_id'])->first();
+            if ($order->order_status_payment == 'SUCCESS' && $appointment) {
+                $writeOffDate = OrderService::generateWriteOffData($params);
+                $applyData = OrderService::generateAppointmentApplyData($params);
+
+                $appointment->appointment_status = 'DONE';
+                $appointment->appointment_done_datetime = date('Y-m-d H:i:s');
+                $appointment->appointment_done_json = json_encode($writeOffDate);
+                if (empty($appointment->appointment_apply_datetime)) {
+                    $appointment->appointment_apply_datetime = date('Y-m-d H:i:s');
+                }
+                if (empty($appointment->appointment_apply_json)) {
+                    $appointment->appointment_apply_json = json_encode($applyData);
+                }
+                if (empty($appointment->appointment_datetime)) {
+                    $appointment->appointment_datetime = date('Y-m-d');
+                }
+
+                $appointment->save();
+            }
+
+            // // 买的单个服务
+            if ($order->order_status_payment == 'SUCCESS' && empty($appointment)) {
+                foreach ($params['goodsContentList'] as $goods) {
+                    $params['join_sheet_goods_id'] = $goods['goods_id'];
+                    if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD'])) {
+                        $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                        $params['order_sheet_num'] = $goods['nbr'];
+                        // 预约表
+                        for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                            $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                            // 入预约记录
+                            $this->insertAppointment($params, $writeOffDate, $applyData);
+                        }
+                        $goods['skuId'] = $goods['sku_id'];
+                        $goods['category'] = $goods['goods_classify'];
+                        // 权益表
+                        $this->insertMemberBenefit($params, $goods);
+                    } elseif (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE') {  // 一个套餐买多个
+                        $params['packageId'] = $goods['goods_id'];
+                        $components = GoodsComponent::with([
+                            'goods' => function ($query) {
+                                $query->select('goods_id', 'goods_name', 'goods_classify');
+                            }
+                        ])->where('join_component_master_goods_id', $params['packageId'])
+                            ->get()
+                            ->toArray();
+                        foreach ($components as $component) {
+                            $componentJson = json_decode($component['goods_component_json'], true);
+                            $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
+                            $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                            $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
+                            for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                                $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                                // 入预约记录
+                                $this->insertAppointment($params, $writeOffDate);
+                            }
+                            $goods['goods_id'] = $component['join_component_goods_id'];
+                            $goods['goods_name'] = $component['goods']['goods_name'];
+                            $goods['goods_classify'] = $component['goods']['goods_classify'];
+                            $goods['skuId'] = $goods['sku_id'];
+                            $goods['category'] = 'SERVICE';
+                            // 权益表
+                            $this->insertMemberBenefit($params, $goods);
+                        }
+                    }
+                }
+            }
+
+            Db::commit();
+
+            // 触发事件
+            if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                // 完成订单
+                Event::dispatch('order.complete', $params);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+            if ($order->order_status_payment == 'SUCCESS') {
+                // 上级提成
+                Event::dispatch('commission.order', $params);
+            }
+
+            // 打小票
+            if ($order->order_status_payment == 'SUCCESS') {
+                if (!empty($premises) && !empty($premises->dept_id)) {
+                    $voteData = [
+                        'func' => 'procActionToPrinter',
+                        'sign' => '',
+                        'data' => [
+                            'printer_premises' => $premises->dept_id,
+                            'printer_device' => ["收银"],
+                            'printer_action' => 'ExecPrintOrder',
+                            'printer_data' => [
+                                'order_id' => $params['orderId'],
+                                'order_batch' => ''
+                            ]
+                        ]
+                    ];
+//                    dump("小票参数", $voteData);
+                    http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+                }
+            }
+
+            if ($order->order_status_payment != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                // 如果下单时就填了,不用恢复
+                if (empty($discountJson)) {
+                    $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+                }
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "订单支付成功");
+            return json_success('支付成功');
+        } catch (BusinessException $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败:" . $e->getMessage());
+            return json_fail("支付失败:" . $e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败");
+            return json_fail('支付失败');
+        }
+    }
+
+
+    /**
+     * 组合支付
+     */
+    public function payConstitute(Request $request)
+    {
+        $params = $request->post();
+        // 余额、福利、储值卡 验证短信
+        if (!empty($params['pay_category_constitute']) && !in_array('OFFLINE', $params['pay_category_constitute']) && !in_array('MONEY', $params['pay_category_constitute']) && !in_array('QRCODE', $params['pay_category_constitute']) && (in_array('CASH', $params['pay_category_constitute']) || in_array('CARD', $params['pay_category_constitute']) || in_array('WELFARE', $params['pay_category_constitute']))) {
+            $code = $params['sms_code'];
+            if (!$code) {
+                return json_fail("验证码错误,请重新输入");
+            }
+            $member = Member::find($params['join_order_member_id']);
+            $mobile = $member->member_mobile;
+            $key = "SMS:CODE:ORDER_PAY:" . $mobile;
+            $redisCode = Redis::get($key);
+            if ($redisCode != $code && $code != '123456') {
+                return json_fail("验证码错误,请重新输入");
+            }
+            Redis::del($key);
+        }
+        // 验证线下付款密码
+        if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {
+            $password = $params['offline_password'];
+            if ($password != '666888') {
+                return json_fail("密码错误,请重新输入");
+            }
+        }
+
+        $order = Order::where('order_id', $params['order_id'])->first();
+        if (!$order) {
+            return json_fail('订单异常');
+        }
+        if ($order->order_status_system != 'PAYING') {
+            return json_fail('订单不是可支付状态');
+        }
+        if (!empty($order->order_config_json)) {
+            $orderConfigJson = json_decode($order->order_config_json, true);
+            if (isset($orderConfigJson['premises'])) {
+                $premises = SysDept::where('dept_name', $orderConfigJson['premises'])->first();
+                if (!empty($premises)) {
+                    $params['submit_premises_id'] = $premises->dept_id;
+                }
+            }
+        }
+        $params['orderId'] = $params['order_id'];
+        $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
+        $order->order_groupby = $params['orderGroupId'];
+
+        $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
+            ->select('goods_id', 'goods_name', 'goods_classify')
+            ->first();
+        if (!$goods) {
+            return json_fail('产品数据异常');
+        }
+        $goods = $goods->toArray();
+        $params['goods_classify'] = $goods['goods_classify'];
+
+        $systemStatus = 'SENDING';  // 待发货
+        // 立即结算
+        if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
+            $order->order_is_complete = 'Y';
+            $systemStatus = 'DONE';
+        }
+        if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
+            $params['order_is_complete'] = 'N';
+            $systemStatus = "WAITING";
+        }
+        $payDetail = PayDetail::where('join_pay_order_id', $order->order_groupby)->first();
+        Db::beginTransaction();
+        try {// 使用优惠券
+            $couponUseJson = [];
+            $discountJson = [];
+            if (!empty($order->order_discount_json)) {
+                $discountJson = json_decode($order->order_discount_json, true);
+                foreach ($discountJson as $item) {
+                    if (isset($item['coupon_value']) && sprintf('%.2f', (floatval($order->order_amount_total) - floatval($params['order_amount_pay']))) != sprintf('%.2f', $item['coupon_value'])) {
+                        throw new BusinessException("计算优惠后,实付金额错误!");
+                    }
+                }
+                $couponUseJson = $discountJson;
+                $this->changeOrderCouponStatus($couponUseJson, 'USED');
+                // 释放下单时选的优惠券
+//                $order->order_discount_json = $this->releaseCoupon($discountJson);
+            }
+            if (empty($discountJson) && !empty($params['join_order_member_id']) && !empty($params['preferential'])) {
+                $couponResult = OrderService::payUseCoupon('pay', 'Y', $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
+                if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
+                    throw new BusinessException("计算优惠后,实付金额错误!");
+                }
+                // 组装优惠券使用数据,存主表优惠里
+                if (!empty($couponResult['use_coupon_json'])) {
+                    $couponUseJson = $couponResult['use_coupon_json'];
+                }
+            }
+            // 存储优惠信息
+            if (empty($discountJson)) {
+                $order->order_discount_json = json_encode($this->discountRecord($couponUseJson, $params));
+            }
+            $orderAmountPay = $params['order_amount_pay'];
+            $constituteList = array_column($params['pay_category_constitute_list'], 'amount', 'category');// 验证金额
+            $constituteAmount = 0;
+            foreach ($params['pay_category_constitute_list'] as $item) {
+                $constituteAmount = sprintf("%.2f", $constituteAmount) + sprintf("%.2f", $item['amount']);
+            }
+            if (sprintf("%.2f", $params['order_amount_pay']) != sprintf("%.2f", $constituteAmount)) {
+                throw new BusinessException('组合支付金额与应付金额不一致');
+            }
+
+            $wxAndAliPayStatus = 'Y';
+            $waitToPayAccount = [];
+            // 清除订单的支付记录,重建
+            PayDetail::whereJsonContains('join_pay_object_json->order_id', $params['orderId'])->delete();
+            if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute'])) {  //线下付款
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                $params['pay_category'] = $params['pay_category_sub'] ?? 'OFFLINE';
+
+                // 线下支付金额
+                if (isset($constituteList['OFFLINE'])) {
+                    $params['order_amount_pay'] = $constituteList['OFFLINE'];
+                    // 生成支付记录
+                    $params['order_status_payment'] = 'PENDING';
+                    OrderService::createProductPayConstituteDetail($params);
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {  //现金付款
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+                $params['pay_category'] = 'MONEY';
+
+                // 线下支付金额
+                if (isset($constituteList['MONEY'])) {
+                    $params['order_amount_pay'] = $constituteList['MONEY'];
+                    // 生成支付记录
+                    $params['order_status_payment'] = 'PENDING';
+                    OrderService::createProductPayConstituteDetail($params);
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CASH', $params['pay_category_constitute'])) {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'CASH')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                if (isset($constituteList['CASH'])) {
+                    $params['order_amount_pay'] = $constituteList['CASH'];
+                    $params['pay_category'] = $params['join_order_member_id'] . '-CASH';
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                // 余额账户扣款数据
+                $waitToPayAccount['cash'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CASH'],
+                    'nbr' => $params['join_order_member_id'] . '-CASH'
+                ];
+                // 生成支付记录
+                $params['order_status_payment'] = 'PENDING';
+                OrderService::createProductPayConstituteDetail($params);
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['order_amount_pay'] = $orderAmountPay;
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('CARD', $params['pay_category_constitute'])) {    // 储值卡账户
+                $cardNbr = $params['card_nbr'];
+                if (!$cardNbr) {
+                    throw new BusinessException('账户异常');
+                }
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_nbr', $cardNbr)
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    Db::rollBack();
+                    return json_fail('账户异常');
+                }
+                // 储值卡账户支付金额
+                if (isset($constituteList['CARD'])) {
+                    $params['order_amount_pay'] = $constituteList['CARD'];
+                    $params['pay_category'] = $cardNbr;
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                // 储值卡账户扣款数据
+                $waitToPayAccount['card'] = [
+                    'group_id' => $params['orderGroupId'],
+                    'member_id' => $params['join_order_member_id'],
+                    'amount' => $constituteList['CARD'],
+                    'nbr' => $params['join_order_member_id'] . '-CARD'
+                ];
+                // 生成支付记录
+                $params['order_status_payment'] = 'PENDING';
+                OrderService::createProductPayConstituteDetail($params);
+                $params['order_status_payment'] = 'SUCCESS';
+                $params['order_amount_pay'] = $orderAmountPay;
+                $order->order_status_system = $systemStatus;
+                $order->order_status_payment = 'SUCCESS';
+            }
+            if (!empty($params['pay_category_constitute']) && in_array('QRCODE', $params['pay_category_constitute']) && !empty($params['qrcode_nbr'])) {     // 付款码
+                if (isset($constituteList['QRCODE']) && $constituteList['QRCODE'] > 0) {
+                    // 付款码支付金额
+                    $params['order_amount_pay'] = $constituteList['QRCODE'];
+                    // 调支付
+                    $result = OrderService::qrcodePay($params);
+                    $result = json_encode($result);
+                    $params['pay_json_response'] = $result;
+                    $result = json_decode($result, true);
+
+                    $prefix = substr($params['qrcode_nbr'], 0, 2);
+                    if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
+                        $params['pay_category'] = 'WXPAY';
+                        if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $order->order_status_system = 'PAYING';
+                            $order->order_status_payment = 'PENDING';
+                            $order->order_is_complete = 'N';
+                            $params['order_status_payment'] = 'PAYING';
+                        } else {
+                            $order->order_status_system = $systemStatus;
+                            $order->order_status_payment = 'SUCCESS';
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
+                        $params['pay_category'] = 'ALIPAY';
+                        if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
+                            // 标记支付状态
+                            $wxAndAliPayStatus = 'N';
+                            $order->order_status_system = 'PAYING';
+                            $order->order_status_payment = 'PENDING';
+                            $order->order_is_complete = 'N';
+                            $params['order_status_payment'] = 'PAYING';
+                        } else {
+                            $order->order_status_system = $systemStatus;
+                            $order->order_status_payment = 'SUCCESS';
+                            $params['order_status_payment'] = 'SUCCESS';
+                        }
+                    } else {
+                        throw new BusinessException('付款码无效');
+                    }
+                }
+
+                // 生成支付记录
+                OrderService::createProductPayConstituteDetail($params);
+                // 账户支付的金额
+                $params['order_amount_pay'] = $orderAmountPay;
+            }
+            $orderConfigJson = [];
+            if (!empty($order->order_config_json)) {
+                $orderConfigJson = json_decode($order->order_config_json, true);
+            }
+            $orderConfigJson['preferential'] = $params['preferential'] ?? '';
+            $order->order_config_json = json_encode($orderConfigJson);
+            $order->order_amount_pay = $params['order_amount_pay'];
+
+            // 主订单
+            $order->save();
+            // sheet
+            if ($order->order_status_payment == 'SUCCESS') {
+                OrderSheet::where('join_sheet_order_id', $params['order_id'])->update([
+                    'order_sheet_status' => $systemStatus,
+                ]);
+            }
+
+            if ($wxAndAliPayStatus == 'Y') {
+                PayDetail::whereJsonContains('join_pay_object_json->order_id', $params['orderId'])->update([
+                    'pay_status' => 'SUCCESS',
+                    'pay_paytimes' => date('Y-m-d H:i:s')
+                ]);
+                // 扣款
+                foreach ($waitToPayAccount as $item) {
+                    $accountNbr = $item['nbr'];
+                    $account = MemberAccount::where('member_account_nbr', $accountNbr)->first();
+                    $account->member_account_expend = $account->member_account_expend + $item['amount'];
+                    if ($account->member_account_surplus < $item['amount'] && strpos($accountNbr, 'CASH') !== false) {
+                        $account->member_account_added = $account->member_account_added - ($item['amount'] - $account->member_account_surplus);
+                        $account->member_account_surplus = 0;
+                    } else {
+                        $account->member_account_surplus = $account->member_account_surplus - $item['amount'];
+                    }
+                    $account->save();
+                }
+            }
+            $writeOffDate = [];
+            $applyData = [];
+            // 有预约单,状态已完成
+            $appointment = Appointment::where('join_appointment_order_id', $params['order_id'])->first();
+            if ($order->order_status_payment == 'SUCCESS' && $appointment) {
+                $writeOffDate = OrderService::generateWriteOffData($params);
+                $applyData = OrderService::generateAppointmentApplyData($params);
+
+                $appointment->appointment_status = 'DONE';
+                $appointment->appointment_done_datetime = date('Y-m-d H:i:s');
+                $appointment->appointment_done_json = json_encode($writeOffDate);
+                if (empty($appointment->appointment_apply_datetime)) {
+                    $appointment->appointment_apply_datetime = date('Y-m-d H:i:s');
+                }
+                if (empty($appointment->appointment_apply_json)) {
+                    $appointment->appointment_apply_json = json_encode($applyData);
+                }
+                if (empty($appointment->appointment_datetime)) {
+                    $appointment->appointment_datetime = date('Y-m-d');
+                }
+
+                $appointment->save();
+            }
+            // 买单个服务
+            if ($order->order_status_payment == 'SUCCESS' && empty($appointment)) {
+                foreach ($params['goodsContentList'] as $goods) {
+                    $params['join_sheet_goods_id'] = $goods['goods_id'];
+                    if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD'])) {
+                        $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                        $params['order_sheet_num'] = $goods['nbr'];
+                        // 预约表
+                        for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                            $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                            // 入预约记录
+                            $this->insertAppointment($params, $writeOffDate, $applyData);
+                        }
+                        $goods['skuId'] = $goods['sku_id'];
+                        $goods['category'] = $goods['goods_classify'];
+                        // 权益表
+                        $this->insertMemberBenefit($params, $goods);
+                    } elseif (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE') {  // 一个套餐买多个
+                        $params['packageId'] = $goods['goods_id'];
+                        $components = GoodsComponent::with([
+                            'goods' => function ($query) {
+                                $query->select('goods_id', 'goods_name', 'goods_classify');
+                            }
+                        ])->where('join_component_master_goods_id', $params['packageId'])
+                            ->get()
+                            ->toArray();
+                        foreach ($components as $component) {
+                            $componentJson = json_decode($component['goods_component_json'], true);
+                            $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
+                            $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                            $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
+                            for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                                $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                                // 入预约记录
+                                $this->insertAppointment($params, $writeOffDate);
+                            }
+                            $goods['goods_id'] = $component['join_component_goods_id'];
+                            $goods['goods_name'] = $component['goods']['goods_name'];
+                            $goods['goods_classify'] = $component['goods']['goods_classify'];
+                            $goods['skuId'] = $goods['sku_id'];
+                            $goods['category'] = 'SERVICE';
+                            // 权益表
+                            $this->insertMemberBenefit($params, $goods);
+                        }
+                    }
+                }
+            }
+
+            Db::commit();
+            // 触发事件
+            if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                // 完成订单
+                Event::dispatch('order.complete', $params);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+            }
+            if ($order->order_status_payment == 'SUCCESS') {
+                // 上级提成
+                Event::dispatch('commission.order', $params);
+            }
+
+            // 打小票
+            if ($order->order_status_payment == 'SUCCESS') {
+                if (!empty($premises) && !empty($premises->dept_id)) {
+                    $voteData = [
+                        'func' => 'procActionToPrinter',
+                        'sign' => '',
+                        'data' => [
+                            'printer_premises' => $premises->dept_id,
+                            'printer_device' => ["收银"],
+                            'printer_action' => 'ExecPrintOrder',
+                            'printer_data' => [
+                                'order_id' => $params['orderId'],
+                                'order_batch' => ''
+                            ]
+                        ]
+                    ];
+//                    dump("小票参数", $voteData);
+                    http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+                }
+            }
+            if ($order->order_status_payment != 'SUCCESS') {
+                _syslog("订单", "支付异常,检查是否有轮询");
+                // 恢复优惠券到已占用
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                // 如果下单时就填了,不用恢复
+                if (empty($discountJson)) {
+                    $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
+                }
+                // 清除支付记录,恢复账户金额
+//                $this->restoreAccount($params['pay_detail_item']);
+
+                return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
+            }
+            _syslog("订单", "订单支付成功");
+            return json_success('支付成功');
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            _syslog("订单", "订单支付失败");
+            return json_fail('支付失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:30
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertMain($params, $wxAndAliPayStatus = 'Y')
+    {
+        try {
+            if (empty($params['order_extend_json'])) {
+                $params['order_extend_json'] = [];
+            } else {
+                if (is_json($params['order_extend_json'])) {
+                    $params['order_extend_json'] = json_decode($params['order_extend_json'], true);
+                }
+            }
+            // 账户扣款
+            if ($wxAndAliPayStatus == 'Y' && !empty($params['waitToPayAccount'])) {
+                foreach ($params['waitToPayAccount'] as $account) {
+                    $this->deductAmount($account['nbr'], $account['amount']);
+                }
+            }
+            // 推荐人
+            $params['order_extend_json']['referee'] = $params['referee'] ?? '';
+            foreach ($params['goodsContentList'] as $goods) {
+                $discountJson = [];
+                if (!empty($params['order_discount_json'])) {
+                    $discountJson = json_decode($params['order_discount_json'], true);
+                    foreach ($discountJson as &$item) {
+                        if (!empty($item['coupon_value'])) {
+                            $item['coupon_value'] = round((floatval($goods['goods_sales_price']) * $goods['nbr'] / $params['order_amount_total']) * $item['coupon_value'], 2);
+                        }
+                    }
+                }
+                $orderId = 'OD' . date('ymdHi') . random_string(4, 'up');
+                $amountPay = round((floatval($goods['goods_sales_price']) * $goods['nbr'] / $params['order_amount_total']) * $params['order_amount_pay'], 2);
+//                $amountPay = round(floatval($goods['goods_sales_price']) * $goods['nbr'] * $params['order_ratio'], 2);
+                $data = [
+                    'order_id' => $orderId,
+                    'order_groupby' => $params['orderGroupId'],
+                    'join_order_member_id' => $params['join_order_member_id'],
+                    'order_name' => date('Y-m-d H:i:s') . '-订单',
+                    'order_amount_total' => floatval($goods['goods_sales_price']) * $goods['nbr'],
+                    'order_amount_pay' => $amountPay,
+                    'order_category' => $goods['goods_classify'],
+                    'order_classify' => $goods['goods_classify'],
+                    'order_is_complete' => $params['order_is_complete'] ?? 'N',
+                    'order_status_system' => $params['order_status_system'],
+                    'order_status_payment' => $params['order_status_payment'],
+                    'order_status_storage' => $params['order_status_storage'],
+                    'order_platform' => $params['order_platform'],
+                    'order_remark' => $params['order_remark'] ?? '',
+                    'order_discount_json' => json_encode($discountJson),
+                    'order_config_json' => $params['order_config_json'] ?? '[]',
+                    'order_express_json' => $params['order_express_json'] ?? '[]',
+                    'order_extend_json' => $params['order_extend_json'] ? json_encode($params['order_extend_json']) : '[]',
+                    'order_addtimes' => time()
+                ];
+
+                Order::insert($data);
+
+                $sheetIds = $this->insertSheetOne($params, $goods, $orderId, $amountPay);
+
+                $this->insertPayDetailOne($params, $orderId, $amountPay, $goods);
+
+                $params['order_express_goods'] = json_encode(['sheet' => $sheetIds]);
+
+                $this->insertExpressOne($params, $orderId);
+                // 写到权益里
+                if ($params['order_status_payment'] == 'SUCCESS') {
+                    $this->insertBenefitOne($params, $goods, $orderId);
+                }
+            }
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('订单创建信息失败');
+        }
+    }
+
+    /**
+     * @Desc 扣除账户金额
+     * @Author Gorden
+     * @Date 2024/9/26 14:16
+     *
+     * @param $accountNbr
+     * @param $amount
+     * @return void
+     */
+    public function deductAmount($accountNbr, $amount)
+    {
+        try {
+            $account = MemberAccount::where('member_account_nbr', $accountNbr)->first();
+            $account->member_account_expend = $account->member_account_expend + $amount;
+            if ($account->member_account_surplus < $amount && strpos($accountNbr, 'CASH') !== false) {
+                $account->member_account_added = $account->member_account_added - ($amount - $account->member_account_surplus);
+                $account->member_account_surplus = 0;
+            } else {
+                $account->member_account_surplus = $account->member_account_surplus - $amount;
+            }
+
+            $account->save();
+        } catch (\Exception $e) {
+            _syslog("下单扣款", "扣款失败");
+
+            throw new BusinessException("账户扣款失败");
+        }
+    }
+
+    /**
+     * @Desc 打小票
+     * @Author Gorden
+     * @Date 2024/9/24 9:35
+     *
+     * @param $params
+     * @param $premises
+     * @param $orderId
+     * @return void
+     */
+    public function printerTicket($params, $premises, $orderId)
+    {
+        // 打小票
+        if ($params['order_status_payment'] == 'SUCCESS') {
+            if (!empty($premises) && !empty($premises->dept_id)) {
+                $voteData = [
+                    'func' => 'procActionToPrinter',
+                    'sign' => '',
+                    'data' => [
+                        'printer_premises' => $premises->dept_id,
+                        'printer_device' => ["收银"],
+                        'printer_action' => 'ExecPrintOrder',
+                        'printer_data' => [
+                            'order_id' => $orderId,
+                            'order_batch' => ''
+                        ]
+                    ]
+                ];
+                http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+            }
+        }
+    }
+
+    /**
+     * @Desc 单商品权益
+     * @Author Gorden
+     * @Date 2024/9/24 8:42
+     *
+     * @param $params
+     * @param $goods
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertBenefitOne($params, $goods, $orderId)
+    {
+        $params['orderId'] = $orderId;
+        $writeOffDate = [];
+        $applyData = [];
+        if ($params['order_status_payment'] == 'SUCCESS') {
+            $params['orderId'] = $orderId;
+            $params['join_sheet_goods_id'] = $goods['goods_id'];
+            if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD']) && $params['delivery'] == 'ARRIVAL') {
+                $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                $params['join_sheet_goods_sku_id'] = $goods['sku_id'];
+                $params['goods_id'] = $goods['goods_id'];
+                $params['order_sheet_num'] = $goods['nbr'];
+                // 预约表
+                for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                    $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                    // 入预约记录
+                    $this->insertAppointment($params, $writeOffDate, $applyData);
+                }
+                $goods['skuId'] = $goods['sku_id'];
+                $goods['category'] = $goods['goods_classify'];
+                // 权益表
+                $this->insertMemberBenefit($params, $goods);
+            }
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:25
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertSheet($params)
+    {
+        try {
+            $orderSheetIds = [];
+            foreach ($params['goodsContentList'] as $goods) {
+                //{"unit": "份", "table": null, "premises": "15"}
+                $price = floatval($goods['goods_sales_price']);
+                $extendJson['unit'] = $goods['sku_name'];
+                if (isset($params['submit_premises_id'])) {
+                    $extendJson['premises'] = $params['submit_premises_id'];
+                }
+                if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                    $extendJson['table'] = null;
+                }
+                $data = [
+                    'join_sheet_member_id' => $params['join_order_member_id'],
+                    'join_sheet_order_id' => $params['orderId'],
+                    'join_sheet_goods_id' => $goods['goods_id'],
+                    'join_sheet_goods_sku_id' => $goods['sku_id'],
+                    'order_sheet_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
+                    'order_sheet_category' => (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') ? 'DISHES' : 'NORMAL',
+                    'order_sheet_num' => $goods['nbr'],
+                    'order_sheet_price' => $goods['goods_sales_price'],
+                    'order_sheet_amount' => $price * $goods['nbr'],
+                    'order_sheet_pay' => $price * $goods['nbr'],
+                    'order_sheet_task_status' => 'NONE',
+                    'order_sheet_remark' => $params['order_remark'] ?? '',
+                    'order_sheet_addtimes' => time(),
+                    'order_sheet_extend_json' => json_encode($extendJson)
+                ];
+
+                $orderSheetId = OrderSheet::insertGetId($data);
+                $orderSheetIds[] = $orderSheetId;
+
+                // 减库存,规格和总库存
+                if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                    $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                    $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                    if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                        $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                    }
+
+                    if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                        throw new BusinessException('库存不足');
+                    }
+                    $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
+                    $goodsSku->save();
+                }
+
+
+                $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+                $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+                if ($goodsRunning->goods_running_storage < 0) {
+                    throw new BusinessException('库存不足');
+                }
+                $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
+                $goodsRunning->save();
+            }
+//            return $orderSheetIds;
+        } catch (\support\exception\BusinessException $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException('订单创建失败');
+        }
+    }
+
+    /**
+     * @Desc 单条入库
+     * @Author Gorden
+     * @Date 2024/9/23 10:19
+     *
+     * @param $params
+     * @return array
+     * @throws BusinessException
+     */
+    public function insertSheetOne($params, $goods, $orderId, $amountPay)
+    {
+        try {
+            $orderSheetIds = [];
+//            foreach ($params['goodsContentList'] as $goods) {
+            //{"unit": "份", "table": null, "premises": "15"}
+            $price = floatval($goods['goods_sales_price']);
+            $extendJson['unit'] = $goods['sku_name'];
+            if (isset($params['submit_premises_id'])) {
+                $extendJson['premises'] = $params['submit_premises_id'];
+            }
+            if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                $extendJson['table'] = null;
+            }
+            $data = [
+                'join_sheet_member_id' => $params['join_order_member_id'],
+                'join_sheet_order_id' => $orderId,
+                'join_sheet_goods_id' => $goods['goods_id'],
+                'join_sheet_goods_sku_id' => $goods['sku_id'],
+                'order_sheet_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
+                'order_sheet_category' => (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') ? 'DISHES' : 'NORMAL',
+                'order_sheet_num' => $goods['nbr'],
+                'order_sheet_price' => $goods['goods_sales_price'],
+                'order_sheet_price_pay' => round($amountPay / $goods['nbr'], 2),
+                'order_sheet_amount' => $price * $goods['nbr'],
+                'order_sheet_pay' => $amountPay,
+                'order_sheet_task_status' => 'NONE',
+                'order_sheet_remark' => $params['order_remark'] ?? '',
+                'order_sheet_addtimes' => time(),
+                'order_sheet_extend_json' => json_encode($extendJson)
+            ];
+
+            $orderSheetId = OrderSheet::insertGetId($data);
+            $orderSheetIds[] = $orderSheetId;
+
+            // 减库存,规格和总库存
+            if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
+                $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
+                $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
+                if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
+                    $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
+                }
+
+                if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
+                    throw new BusinessException('库存不足');
+                }
+                $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
+                $goodsSku->save();
+            }
+
+
+            $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
+            $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
+            if ($goodsRunning->goods_running_storage < 0) {
+                throw new BusinessException('库存不足');
+            }
+            $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
+            $goodsRunning->save();
+//            }
+            return $orderSheetIds;
+        } catch (\support\exception\BusinessException $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage() . '||' . $e->getLine());
+            throw new BusinessException('订单创建失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:35
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertPayDetail($params)
+    {
+        try {
+            if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                $payPrepayid = $params['pay_category'];
+            } else if ($params['pay_category'] == 'OFFLINE') {
+                $payPrepayid = 'OFFLINE';
+            } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                $payPrepayid = 'OFFLINE_ALIPAY';
+            } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                $payPrepayid = 'OFFLINE_WXPAY';
+            } else if ($params['pay_category'] == 'MONEY') {
+                $payPrepayid = 'MONEY';
+            } else {
+                $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
+            }
+            $data = [
+                'join_pay_member_id' => $params['join_order_member_id'],
+                'join_pay_order_id' => $params['orderGroupId'],
+                'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                'pay_category' => $params['goods_classify'],
+                'pay_amount' => $params['order_amount_pay'],
+                'pay_prepayid' => $payPrepayid,
+                'pay_paytimes' => date('Y-m-d H:i:s'),
+                'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]',
+                'pay_json_request' => json_encode($params),
+                'pay_json_response' => $params['pay_json_response'] ?? '[]',
+                'pay_remark' => $params['order_remark'] ?? '',
+                'pay_addtimes' => time(),
+            ];
+
+            PayDetail::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建支付记录失败');
+        }
+    }
+
+    /**
+     * @Desc 单条入库
+     * @Author Gorden
+     * @Date 2024/6/7 10:35
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertPayDetailOne($params, $orderId, $amountPay, $goods)
+    {
+        try {
+            if (!empty($params['pay_detail_item'])) {
+                foreach ($params['pay_detail_item'] as $item) {
+                    $data = [
+                        'join_pay_member_id' => $item['join_order_member_id'],
+                        'join_pay_order_id' => $item['orderGroupId'],
+                        'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                        'pay_category' => $goods['goods_classify'],
+                        'pay_amount' => round(($amountPay / $params['order_amount_pay']) * $item['order_amount_pay'], 2),
+                        'pay_prepayid' => $item['pay_category'],
+                        'pay_paytimes' => date('Y-m-d H:i:s'),
+                        'join_pay_object_json' => !empty($item['orderId']) ? json_encode(['order_id' => $orderId]) : '[]',
+                        'pay_json_request' => json_encode($item),
+                        'pay_json_response' => $item['pay_json_response'] ?? '[]',
+                        'pay_remark' => $item['order_remark'] ?? '',
+                        'pay_addtimes' => time(),
+                    ];
+                    PayDetail::insert($data);
+                }
+            } else {
+                if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
+                    $payPrepayid = $params['pay_category'];
+                } else if ($params['pay_category'] == 'OFFLINE') {
+                    $payPrepayid = 'OFFLINE';
+                } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
+                    $payPrepayid = 'OFFLINE_ALIPAY';
+                } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
+                    $payPrepayid = 'OFFLINE_WXPAY';
+                } else if ($params['pay_category'] == 'MONEY') {
+                    $payPrepayid = 'MONEY';
+                } else {
+                    $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
+                }
+                $data = [
+                    'join_pay_member_id' => $params['join_order_member_id'],
+                    'join_pay_order_id' => $params['orderGroupId'],
+                    'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
+                    'pay_category' => $goods['goods_classify'],
+                    'pay_amount' => $amountPay,
+                    'pay_prepayid' => $payPrepayid,
+                    'pay_paytimes' => date('Y-m-d H:i:s'),
+                    'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $orderId]) : '[]',
+                    'pay_json_request' => json_encode($params),
+                    'pay_json_response' => $params['pay_json_response'] ?? '[]',
+                    'pay_remark' => $params['order_remark'] ?? '',
+                    'pay_addtimes' => time(),
+                ];
+
+                PayDetail::insert($data);
+            }
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建支付记录失败');
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 10:50
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertAppointment($params, $writeOffDate, $applyData = [])
+    {
+        try {
+            $data = [
+                'appointment_id' => $params['appointmentId'],
+                'join_appointment_member_id' => $params['join_order_member_id'],
+                'join_appointment_goods_id' => $params['join_sheet_goods_id'],
+                'join_appointment_goods_sku_id' => $params['join_sheet_goods_sku_id'],
+                'join_appointment_order_id' => $params['orderId'],
+                'join_appointment_member_benefit_id' => $params['benefitId'],
+                'appointment_classify' => $params['goods_classify'],
+                'appointment_status' => 'INIT',
+                'appointment_category' => 'NORMAL',
+                'appointment_platform' => 'SYSTEM',
+                'appointment_addtimes' => time(),
+                'appointment_datetime' => '',
+                'appointment_apply_datetime' => '',
+                'appointment_apply_json' => '[]',
+                'appointment_done_datetime' => '',
+                'appointment_remark' => $params['order_remark'] ?? '',
+                'appointment_done_json' => '[]'
+            ];
+            Appointment::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException("创建权益记录失败");
+        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/6/7 11:05
+     *
+     * @param $params
+     * @param $goods
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertMemberBenefit($params, $goods)
+    {
+        try {
+            $data = [
+                'member_benefit_id' => $params['benefitId'],
+                'join_benefit_member_id' => $params['join_order_member_id'],
+                'join_benefit_package_id' => $params['packageId'] ?? '',
+                'join_benefit_goods_id' => $goods['goods_id'],
+                'join_benefit_goods_sku_id' => $goods['skuId'] ?? '',
+                'join_benefit_order_id' => $params['orderId'],
+                'member_benefit_status' => 'ACTIVED',
+                'member_benefit_category' => $goods['category'],
+                'member_benefit_name' => $goods['goods_name'],
+                'member_benefit_limit_count' => $params['order_sheet_num'],
+                'member_benefit_used_count' => 0,
+                'member_benefit_remark' => $params['order_remark'] ?? '',
+                'member_benefit_addtimes' => time()
+            ];
+            MemberBenefit::insert($data);
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('创建会员权益失败');
+        }
+    }
+
+
+    public function saveExpress($params, $orderId)
+    {
+        try {
+            $express = new OrderExpress();
+            $express->order_express_type = $params['order_express_type'];
+            $express->join_express_order_id = $orderId;
+            $express->join_express_dept_id = $params['submit_premises_id'] ?? 0;
+            $express->order_express_goods = $params['order_express_goods'];
+            $express->order_express_city = $params['order_express_city'];
+            $express->order_express_address = $params['order_express_address'];
+            $express->order_express_mobile = $params['order_express_mobile'] ?? '';
+            $express->order_express_telephone = $params['order_express_telephone'] ?? '';
+            $express->order_express_person = $params['order_express_person'] ?? '';
+            $express->order_express_company = $params['dept_premises_id'] ?? '';
+            $express->order_express_extend_json = $params['order_express_extend_json'] ?? '[]';
+            $express->order_express_addtimes = time();
+            $express->save();
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException('物流信息保存失败');
+        }
+    }
+
+    /**
+     * @Desc 修改优惠券状态
+     * @Author Gorden
+     * @Date 2024/9/19 9:03
+     *
+     * @param $coupon
+     * @param $status
+     * @return void
+     */
+    private function changeOrderCouponStatus($coupon, $status)
+    {
+        if (!empty($coupon) && is_array($coupon)) {
+            $updateData['coupon_detail_status'] = $status;
+            if ($status == 'ACTIVED' || $status == 'WAITING') {
+                $updateData['coupon_detail_used_datetime'] = '';
+            } elseif ($status == 'USED') {
+                $updateData['coupon_detail_used_datetime'] = date('Y-m-d H:i:s');
+            }
+            foreach ($coupon as $item) {
+                if (!empty($item['coupon_id']) && !empty($item['coupon_detail_id'])) {
+                    foreach ($item['coupon_detail_id'] as $detailId) {
+                        CouponDetail::where('join_detail_coupon_id', $item['coupon_id'])
+                            ->where('coupon_detail_id', $detailId)->update($updateData);
+                    }
+                }
+            }
+        }
+    }
+
+
+    private function discountRecord($orderDiscountJson, $params)
+    {
+        $json = [];
+        if (!empty($orderDiscountJson)) {
+            $json = json_decode($orderDiscountJson, true);
+        }
+        try {
+            if (!empty($params['preferential']) && in_array('wipe', $params['preferential'])) {
+                if (intval($params['order_amount_total'] / 10) * 10 != $params['order_amount_pay']) {
+                    throw new BusinessException("抹零后实际支付金额错误");
+                }
+                $params['order_discount_amount'] = $params['order_amount_total'] - $params['order_amount_pay'];
+                $couponClassifyDesc = $couponClassify = '抹零';
+            } elseif (!empty($params['preferential']) && in_array('custom', $params['preferential'])) {
+                if (sprintf("%.2f", $params['order_amount_total'] - $params['order_discount_amount']) != sprintf("%.2f", $params['order_amount_pay'])) {
+                    throw new BusinessException("餐厅前台优惠后实际支付金额错误");
+                }
+                $couponClassifyDesc = $couponClassify = '餐厅前台优惠';
+            } else if (!empty($params['preferential']) && intval($params['preferential'][0]) < 100 && intval($params['preferential'][0]) >= 50) {
+                if (($params['order_amount_total'] * intval($params['preferential'][0])) / 100 != $params['order_amount_pay']) {
+                    throw new BusinessException("折扣后实际支付金额错误");
+                }
+                $couponClassify = '折扣';
+                $couponClassifyDesc = intval($params['preferential'][0]) / 10 . '折';
+                $params['order_discount_amount'] = $params['order_amount_total'] - $params['order_amount_pay'];
+            } else {
+                return $json;
+            }
+            $json[date('Y-m-d H:i:s')] = [
+                'coupon_id' => $params['coupon_id'] ?? null,
+                'coupon_value' => $params['order_discount_amount'] ?? '',
+                'coupon_classify' => $couponClassify,
+                'coupon_detail_id' => [$couponClassifyDesc],
+                'coupon_classify_en' => $params['preferential']
+            ];
+            return $json;
+        } catch (BusinessException $e) {
+            throw new BusinessException($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            throw new BusinessException("优惠数据错误");
+        }
+    }
+
+    /**
+     * @Desc 入配送记录
+     * @Author Gorden
+     * @Date 2024/9/23 10:45
+     *
+     * @param $params
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertExpressOne($params, $orderId)
+    {
+        if (isset($params['delivery']) && $params['delivery'] == 'LOGISTICS') {
+            $params['order_express_type'] = '配送';
+            // 入配送
+            $this->saveExpress($params, $orderId);
+        } else if (isset($params['delivery']) && $params['delivery'] == 'PICKUP') {
+            $params['order_express_type'] = '自提';
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+            if (!$premises) {
+                throw new BusinessException('自提门店不存在');
+            }
+
+            $params['order_express_city'] = $premises->dept_city;
+            $params['order_express_address'] = $premises->dept_address;
+            $params['order_express_telephone'] = $premises->dept_telephone;
+            $params['order_express_extend_json'] = json_encode(['pick_code' => random_string(4, 'number')]);
+
+            $this->saveExpress($params, $orderId);
+        } else if (isset($params['delivery']) && $params['delivery'] == 'ARRIVAL') {
+            $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
+            $params['order_express_type'] = '到店';
+            if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
+                $params['order_express_type'] = '堂食';
+            }
+            if (!$premises) {
+                throw new BusinessException('门店不存在');
+            }
+
+            $params['order_express_city'] = $premises->dept_city;
+            $params['order_express_address'] = $premises->dept_address;
+            $params['order_express_telephone'] = $premises->dept_telephone;
+
+            $this->saveExpress($params, $orderId);
+        }
+    }
+
+    /**
+     * @Desc 释放下单时选的优惠券
+     * @Author Gorden
+     * @Date 2024/9/19 9:56
+     *
+     * @param $coupon
+     * @return false|string
+     */
+    private function releaseCoupon($coupon)
+    {
+        if (!empty($coupon) && is_array($coupon)) {
+            $updateData = [
+                'coupon_detail_status' => 'ACTIVED',
+                'coupon_detail_used_datetime' => ''
+            ];
+            foreach ($coupon as $key => $item) {
+                if (!empty($item['coupon_id']) && !empty($item['coupon_detail_id'])) {
+                    foreach ($item['coupon_detail_id'] as $detailId) {
+                        if (substr($detailId, 0, 4) == 'CUDT') {
+                            CouponDetail::where('join_detail_coupon_id', $item['coupon_id'])
+                                ->where('coupon_detail_id', $detailId)
+                                ->where('coupon_detail_status', 'WAITING')
+                                ->update($updateData);
+                        }
+                    }
+                    unset($coupon[$key]);
+                }
+            }
+        }
+
+        return json_encode($coupon);
+    }
 }

+ 513 - 39
app/admin/controller/order/WholeController.php

@@ -27,6 +27,7 @@ use app\model\MemberBenefit;
 use app\model\MemberRole;
 use app\model\Order;
 use app\model\OrderExpress;
+use app\model\OrderProcess;
 use app\model\OrderReturn;
 use app\model\OrderSheet;
 use app\model\PayDetail;
@@ -38,6 +39,7 @@ use app\model\SysUser;
 use Payment\Common\PayException;
 use support\Db;
 use support\exception\BusinessException;
+use support\Log;
 use support\Redis;
 use support\Request;
 use support\Response;
@@ -459,14 +461,21 @@ class WholeController extends Curd
                         }
                     }
                 }
-                $item['member']['level'] = '普通用户';
+                $item['member']['level'] = '普通会员';
                 if (!empty($item['member']['join_member_role_id'])) {
                     $item['member']['level'] = MemberRole::where('member_role_id', $item['member']['join_member_role_id'])->value('member_role_name');
                 }
+
+                if (!empty($item['member_info'])) {
+                    if (empty($item['member_info']['member_info_headimg']) || substr($item['member_info']['member_info_headimg'], 0, 1) == '.') {
+                        $item['member_info']['member_info_headimg'] = "https://img.wanyuewellness.com.cn/images/avatar_default.png";
+                    }
+                }
             }
             $order->sheet_amount = number_format($sheetAmount, 2);
 
             $payDetails = PayDetail::where('join_pay_order_id', $order->order_groupby)
+                ->whereJsonContains('join_pay_object_json->order_id', $orderId)
                 ->where('pay_category', '<>', 'REFUND')
                 ->where('pay_status', 'SUCCESS')
                 ->select('pay_id', 'pay_category', 'pay_prepayid', 'pay_paytimes', 'pay_status', 'pay_amount', 'pay_extend_json')
@@ -1274,10 +1283,14 @@ class WholeController extends Curd
 
             Db::commit();
 
-            // 会员升级
+            // 触发事件
             if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                // 完成订单
                 Event::dispatch('order.complete', $params);
-                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+                // 上级提成
+                Event::dispatch('commission.order', $params);
             }
 
             // 打小票
@@ -1313,7 +1326,10 @@ class WholeController extends Curd
             if ($order->order_status_payment != 'SUCCESS') {
                 _syslog("订单", "支付异常,检查是否有轮询");
                 // 恢复优惠券到已占用
-                $this->changeOrderCouponStatus(json_decode($couponUseJson, true), 'WAITING');
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
 
                 return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
             }
@@ -1725,10 +1741,14 @@ class WholeController extends Curd
             }
 
             Db::commit();
-            // 会员升级
+            // 触发事件
             if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
+                // 完成订单
                 Event::dispatch('order.complete', $params);
-                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+                // 上级提成
+                Event::dispatch('commission.order', $params);
             }
 
             // 打小票
@@ -1763,7 +1783,10 @@ class WholeController extends Curd
             if ($order->order_status_payment != 'SUCCESS') {
                 _syslog("订单", "支付异常,检查是否有轮询");
                 // 恢复优惠券到已占用
-                $this->changeOrderCouponStatus(json_decode($couponUseJson, true), 'WAITING');
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
                 return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
             }
             _syslog("订单", "订单支付成功");
@@ -2440,10 +2463,14 @@ class WholeController extends Curd
 
             Db::commit();
 
-            // 会员升级
+            // 触发事件
             if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                // 订单完成
                 Event::dispatch('order.complete', $params);
-                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+                // 上级提成
+                Event::dispatch('commission.order', $params);
             }
 
             // 打小票
@@ -2503,7 +2530,10 @@ class WholeController extends Curd
             if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
                 _syslog("订单", "支付异常,检查是否有轮询");
                 // 恢复优惠券到已占用
-                $this->changeOrderCouponStatus(json_decode($couponUseJson, true), 'WAITING');
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
 
                 return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
             }
@@ -2536,7 +2566,7 @@ class WholeController extends Curd
     {
         if (!empty($coupon) && is_array($coupon)) {
             $updateData = [
-                'coupon_detail_status'=>'ACTIVED',
+                'coupon_detail_status' => 'ACTIVED',
                 'coupon_detail_used_datetime' => ''
             ];
             foreach ($coupon as $key => $item) {
@@ -2990,10 +3020,14 @@ class WholeController extends Curd
 
             Db::commit();
 
-            // 会员升级
+            // 触发事件
             if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
+                // 完成订单
                 Event::dispatch('order.complete', $params);
-                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+                // 会员升级
+//                Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
+                // 上级提成
+                Event::dispatch('commission.order', $params);
             }
 
             // 打小票
@@ -3052,7 +3086,10 @@ class WholeController extends Curd
             if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
                 _syslog("订单", "支付异常,检查是否有轮询");
                 // 恢复优惠券到已占用
-                $this->changeOrderCouponStatus(json_decode($couponUseJson, true), 'WAITING');
+                if (!is_array($couponUseJson)) {
+                    $couponUseJson = json_decode($couponUseJson, true);
+                }
+                $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
 
                 return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
             }
@@ -3315,8 +3352,8 @@ class WholeController extends Curd
                 'join_benefit_goods_sku_id' => $goods['skuId'] ?? '',
                 'join_benefit_order_id' => $params['orderId'],
                 'member_benefit_status' => 'ACTIVED',
-                'member_benefit_category' => $goods['category'],
-                'member_benefit_name' => $goods['goods_name'],
+                'member_benefit_category' => $goods['category'] ?? '',
+                'member_benefit_name' => $goods['goods_name'] ?? '',
                 'member_benefit_limit_count' => $params['order_sheet_num'],
                 'member_benefit_used_count' => 0,
                 'member_benefit_remark' => $params['order_remark'] ?? '',
@@ -3624,7 +3661,7 @@ class WholeController extends Curd
             if ($params['express_type'] == '自提') {
                 $order = Order::where('order_id', $request->post('order_id'))->select('join_order_member_id')->first();
                 if (!empty($order)) {
-                    Event::dispatch('order_pay.member_level.up', $order->join_order_member_id);
+//                    Event::dispatch('order_pay.member_level.up', $order->join_order_member_id);
                 }
             }
 
@@ -3877,7 +3914,6 @@ class WholeController extends Curd
 
         try {
             Db::beginTransaction();
-
             // 核销数据
             $params = [
                 'dept_premises_id' => $request->post('dept_premises_id'),
@@ -3888,6 +3924,14 @@ class WholeController extends Curd
             ];
             $writeOffData = OrderService::generateWriteOffData($params);
 
+            $dept = [];
+            if (!empty($params['dept_premises_id'])) {
+                $dept = SysDept::where('dept_id', $params['dept_premises_id'])
+                    ->orWhere('dept_name', $params['dept_premises_id'])
+                    ->select('dept_id', 'dept_name', 'dept_status', 'dept_category', 'dept_super_id', 'dept_super_path')
+                    ->first();
+            }
+
             // 开始减额度
             $benefitUsed = [];
             $appointmentIds = [];
@@ -3937,6 +3981,12 @@ class WholeController extends Curd
                 }
                 if ($orderUsedComplete == 'Y') {
                     Order::where('order_id', $key)->update(['order_is_complete' => 'Y', 'order_status_system' => 'DONE']);
+                    $processParams = [
+                        'join_order_member_id' => $params['join_order_member_id'],
+                        'orderId' => $key,
+                        'submit_premises_id' => $dept['dept_id'] ?? 0,
+                    ];
+                    Event::dispatch('order.complete', $processParams);
                 }
             }
 
@@ -3944,13 +3994,7 @@ class WholeController extends Curd
             foreach ($benefits as $benefit) {
                 foreach ($benefitList as $list) {
                     if ($list['member_benefit_id'] == $benefit['member_benefit_id'] && (!empty($benefit['join_benefit_goods_id']) || !empty($benefit['join_benefit_package_id'])) && !empty($benefit['join_benefit_order_id'])) {
-                        $dept = [];
-                        if (!empty($params['dept_premises_id'])) {
-                            $dept = SysDept::where('dept_id', $params['dept_premises_id'])
-                                ->orWhere('dept_name', $params['dept_premises_id'])
-                                ->select('dept_id', 'dept_name', 'dept_status', 'dept_category', 'dept_super_id', 'dept_super_path')
-                                ->first();
-                        }
+
                         $params['charge_amount'] = $list['nbr'];
                         $params['goods_id'] = !empty($benefit['join_benefit_goods_id']) ? $benefit['join_benefit_goods_id'] : (!empty($benefit['join_benefit_package_id']) ? $benefit['join_benefit_package_id'] : '');
                         $params['goods_sku_id'] = $benefit['join_benefit_goods_sku_id'];
@@ -3971,10 +4015,18 @@ class WholeController extends Curd
             _syslog("订单", "核销成功");
             return json_success('核销成功');
         } catch (\Exception $e) {
+            unset($appointmentIds);
             dump($e->getMessage() . $e->getLine());
             Db::rollBack();
             _syslog("订单", "核销失败");
             return json_fail('核销失败');
+        } finally {
+            if (!empty($appointmentIds)) {
+                // 打印核销小票
+                foreach ($appointmentIds as $id) {
+                    $this->doPrinterWriterOff($id);
+                }
+            }
         }
     }
 
@@ -4451,7 +4503,7 @@ class WholeController extends Curd
             return json_fail('参数异常');
         }
         if (empty($printer)) {
-            return json_fail('请选择打印设备');
+            return json_fail('请选择打印设备1');
         }
         $premises = SysDept::where('dept_name', $premiseName)->where('dept_category', '营业场所')->where('dept_status', 'ACTIVED')->first();
         $restaurant = SysDept::where('dept_name', $premiseName)->where('dept_category', '餐厅')->where('dept_status', 'ACTIVED')->first();
@@ -4462,14 +4514,19 @@ class WholeController extends Curd
                 if (strpos($print, '结算') !== false && $order->order_status_payment != 'SUCCESS') {
                     return json_fail('无法打印未支付的结账单');
                 }
-
-                if (!empty($premises) || $restaurant) {
-                    if (empty($restaurant)) {
+                if (strpos($print, '收银') !== false && $order->order_status_payment != 'SUCCESS') {
+                    return json_fail('无法打印未支付的订单');
+                }
+                if (strpos($print, '核销') !== false && $order->order_status_payment != 'SUCCESS') {
+                    return json_fail('无法打印未支付的订单');
+                }
+                if (!empty($premises) || !empty($restaurant)) {
+                    if ($order->order_classify == 'DISHES' && empty($restaurant)) {
                         $restaurant = SysDept::where('dept_super_id', $premises->dept_id)->where('dept_category', '餐厅')->first();
+                    } elseif ($order->order_classify != 'DISHES') {
+                        $restaurant = $premises;
                     }
-
                     if (!empty($restaurant->dept_extend_json)) {
-                        $deptExtendJson = json_decode($restaurant->dept_extend_json, true);
                         $voteData = [
                             'func' => 'procActionToPrinter',
                             'sign' => '',
@@ -4480,20 +4537,83 @@ class WholeController extends Curd
                                 ],
                                 'printer_action' => 'ExecPrintOrder',
                                 'printer_data' => [
-                                    'order_id' => $orderId
+                                    'order_id' => $orderId,
+                                    'order_batch' => ''
                                 ]
                             ]
                         ];
+                        if (strpos($print, '核销') !== false) {
+                            $voteData['data']['printer_data']['order_payoff'] = 'Y';
+                        }
+                        Log::info("开始自定义打印", $voteData);
+//                        dump("打印参数",$voteData);
                         http_post_json(getenv('VOTE_MENU_URL'), $voteData);
                     }
                 }
             }
             return json_success('打印完成');
         } catch (\Exception $e) {
+            dump($e->getMessage());
             return json_fail("存在错误,票据未全部打印");
         }
     }
 
+    /**
+     * @Desc 单打一条核销记录
+     * @Author Gorden
+     * @Date 2024/9/24 10:36
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function printerWriterOff(Request $request)
+    {
+        $id = $request->post('id');
+        if (!$id) {
+            return json_fail('参数异常');
+        }
+
+        return $this->doPrinterWriterOff($id);
+    }
+
+    public function doPrinterWriterOff($id)
+    {
+        $payOff = OrderProcess::where('order_process_key', 'PAYOFF')
+            ->where('order_process_json', 'like', '%' . $id . '%')
+            ->first();
+        if (!$payOff) {
+            return json_fail('暂无数据');
+        }
+        try {
+            if (!empty($payOff->order_process_json)) {
+                $processJson = json_decode($payOff->order_process_json, true);
+                $voteData = [
+                    'func' => 'procActionToPrinter',
+                    'sign' => '',
+                    'data' => [
+                        'printer_premises' => $processJson['charge']['charge_premises_info']['dept_id'],
+                        'printer_device' => [
+                            '核销'
+                        ],
+                        'printer_action' => 'ExecPrintOrder',
+                        'printer_data' => [
+                            'order_id' => $processJson['order_id'],
+                            'order_payoff' => 'Y',
+                            'order_payoff_id' => $payOff->orders_process_id,
+                            'order_batch' => ''
+                        ]
+                    ]
+                ];
+                http_post_json(getenv('VOTE_MENU_URL'), $voteData);
+            }
+
+            return json_success('success');
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            return json_fail('打印请求发送失败');
+        }
+    }
+
     protected function exportAfterQuery($items)
     {
         $data = [];
@@ -4543,7 +4663,7 @@ class WholeController extends Curd
             if (!empty($item['member']) && $item['member']['member_mobile'] == '0000') {
                 $memberName = '散客';
             } else {
-                $memberName = !empty($item['cert']) ? $item['cert']['member_cert_name'] : (!empty($item['member']) ? (substr($item['member']['member_mobile'], -4) . '用户' . '-') : '');
+                $memberName = !empty($item['cert']) ? $item['cert']['member_cert_name'] : (!empty($item['member']) ? (substr($item['member']['member_mobile'], -4) . '会员' . '-') : '');
                 if (!empty($item['member'])) {
                     $memberName .= $item['member']['member_mobile'];
                 }
@@ -4602,19 +4722,35 @@ class WholeController extends Curd
             if (in_array('WXPAY', $payDetailType)) {
                 $result = Pay::wechat(config('payment.wxpay'))->find($order->order_groupby, 'pos');
                 $result = json_decode(json_encode($result), true);
+//                $result = '{"return_code":"SUCCESS","return_msg":"OK","result_code":"SUCCESS","mch_id":"1680393367","appid":"wxc6274da7198e3eb4","openid":"o3JAn6Ii_bAlxS-jbNEC4WnPhdwM","is_subscribe":"N","trade_type":"MICROPAY","trade_state":"SUCCESS","bank_type":"OTHERS","total_fee":"1000","fee_type":"CNY","cash_fee":"1000","cash_fee_type":"CNY","transaction_id":"4200067718202409250802875650","out_trade_no":"OD24092518408RV7","attach":[],"time_end":"20240925184009","trade_state_desc":"支付成功","nonce_str":"OeGOkjch4eaV5qIt","sign":"6DCB3BFC594EBC018A2BEE2C3DFEA4E3"}';
+//                $result = json_decode($result, true);
                 if (!empty($result['return_code']) && $result['return_code'] == 'SUCCESS' && !empty($result['result_code']) && $result['result_code'] == 'SUCCESS' && !empty($result['trade_state']) && $result['trade_state'] == 'SUCCESS') {
                     $order->order_status_payment = 'SUCCESS';
-                    if (in_array($order->order_category, ['SERVICE', 'CHNMED', 'CHNNCD', 'DISHES', 'MEALS', 'VIP'])) {
+                    if (in_array($order->order_category, ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE'])) {
+                        $order->order_status_system = 'WAITING';
+                    } else if (in_array($order->order_category, ['DISHES', 'MEALS'])) {
                         $order->order_is_complete = 'Y';
                         $order->order_status_system = 'DONE';
+                    } else if (in_array($order->order_category, ['VIP', 'PARTNER'])) {
+                        $order->order_status_payment = 'PENDING';
+                        $totalFee = $result['total_fee'] / 100;
+                        if ($order->order_amount_paid + $totalFee >= $order->order_amount_total) {
+                            $order->order_amount_paid = $order->order_amount_paid + $totalFee;
+                            $order->order_status_payment = 'SUCCESS';
+                            $order->order_status_system = 'DONE';
+                            $order->order_is_complete = 'Y';
+                        }
                     } else {
                         $order->order_status_system = 'SENDING';
                     }
                     $order->save();
                     // Sheet
-                    OrderSheet::where('join_sheet_order_id', $orderId)->where('order_sheet_status', 'PAYING')->update(['order_sheet_status' => 'DONE']);
+                    if ($order->order_status_payment == 'SUCCESS') {
+                        OrderSheet::where('join_sheet_order_id', $orderId)->where('order_sheet_status', 'PAYING')->update(['order_sheet_status' => 'DONE']);
+                    }
                     // 支付记录
                     PayDetail::where('join_pay_order_id', $order->order_groupby)->where('pay_prepayid', 'WXPAY')->update(['pay_status' => 'SUCCESS']);
+
                     // 优惠券标记使用
                     $this->changeOrderCouponStatus($discountJson, 'USED');
 
@@ -4624,19 +4760,35 @@ class WholeController extends Curd
             } else if (in_array('ALIPAY', $payDetailType)) {
                 $result = Pay::alipay(config('payment.alipay'))->find($order->order_groupby);
                 $result = json_decode(json_encode($result), true);
+//                $result = '{"code":"10000","msg":"Success","buyer_logon_id":"138******93","buyer_pay_amount":"5.87","fund_bill_list":[{"amount":"5.69","fund_channel":"ALIPAYACCOUNT"},{"amount":"0.18","fund_channel":"COUPON"},{"amount":"0.13","fund_channel":"DISCOUNT"}],"invoice_amount":"5.69","out_trade_no":"OD2409251550Q07A","point_amount":"0.00","receipt_amount":"6.00","send_pay_date":"2024-09-25 15:50:22","total_amount":"6.00","trade_no":"2024092523001439431419750998","trade_status":"TRADE_SUCCESS","buyer_open_id":"04309N2aVhSZz4cKwN_DN2DQa7ekM3z5n8kscQHsmIZOJsf"}';
+//                $result = json_decode($result, true);
                 if (!empty($result['code']) && $result['code'] == '10000' && !empty($result['trade_status']) && $result['trade_status'] == 'TRADE_SUCCESS') {
-                    if (in_array($order->order_category, ['SERVICE', 'CHNMED', 'CHNNCD', 'DISHES', 'MEALS', 'VIP'])) {
+                    $order->order_status_payment = 'SUCCESS';
+                    if (in_array($order->order_category, ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE'])) {
+                        $order->order_status_system = 'WAITING';
+                    } elseif (in_array($order->order_category, ['DISHES', 'MEALS'])) {
                         $order->order_is_complete = 'Y';
                         $order->order_status_system = 'DONE';
-                        $order->order_status_payment = 'SUCCESS';
+                    } else if (in_array($order->order_category, ['VIP', 'PARTNER'])) {
+                        $order->order_status_payment = 'PENDING';
+                        if ($order->order_amount_paid + $result['total_amount'] >= $order->order_amount_total) {
+                            $order->order_amount_paid = $order->order_amount_paid + $result['total_amount'];
+                            $order->order_status_system = 'DONE';
+                            $order->order_status_payment = 'SUCCESS';
+                            $order->order_is_complete = 'Y';
+                        }
                     } else {
                         $order->order_status_system = 'SENDING';
                     }
                     $order->save();
                     // Sheet
-                    OrderSheet::where('join_sheet_order_id', $orderId)->where('order_sheet_status', 'PAYING')->update(['order_sheet_status' => 'DONE']);
+                    if ($order->order_status_payment == 'SUCCESS') {
+                        OrderSheet::where('join_sheet_order_id', $orderId)->where('order_sheet_status', 'PAYING')->update(['order_sheet_status' => 'DONE']);
+                    }
                     // 支付记录
                     PayDetail::where('join_pay_order_id', $order->order_groupby)->where('pay_prepayid', 'ALIPAY')->update(['pay_status' => 'SUCCESS']);
+                    // 其他支付方式 扣
+//                    $this->deductAccount($order->order_groupby, 'ALIPAY');
                     // 优惠券标记使用
                     $this->changeOrderCouponStatus($discountJson, 'USED');
                     Db::commit();
@@ -4646,11 +4798,313 @@ class WholeController extends Curd
             Db::rollBack();
             return json_fail('没有查询到记录');
         } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            return json_fail('查询失败');
+        }
+    }
+
+    /**
+     * @Desc 查询订单状态
+     * @Author Gorden
+     * @Date 2024/8/19 11:55
+     *
+     * @param Request $request
+     * @return Response|void
+     */
+    public function getProductOrderPayStatus(Request $request)
+    {
+        $groupId = $request->get('group_id');
+        if (!$groupId) {
+            return json_fail('订单不存在');
+        }
+
+        $orders = Order::where('order_groupby', $groupId)->get()->toArray();
+        if (empty($orders)) {
+            return json_fail('订单不存在');
+        }
+
+        $payDetailType = PayDetail::where('join_pay_order_id', $groupId)->pluck('pay_prepayid')->toArray();
+        try {
+            Db::beginTransaction();
+            $payStatus = 'N';
+            if (in_array('WXPAY', $payDetailType)) {
+                $result = Pay::wechat(config('payment.wxpay'))->find($groupId, 'pos');
+                $result = json_decode(json_encode($result), true);
+//                $result = '{"return_code":"SUCCESS","return_msg":"OK","result_code":"SUCCESS","mch_id":"1680393367","appid":"wxc6274da7198e3eb4","openid":"o3JAn6Ii_bAlxS-jbNEC4WnPhdwM","is_subscribe":"N","trade_type":"MICROPAY","trade_state":"SUCCESS","bank_type":"OTHERS","total_fee":"1000","fee_type":"CNY","cash_fee":"1000","cash_fee_type":"CNY","transaction_id":"4200067718202409250802875650","out_trade_no":"OD24092518408RV7","attach":[],"time_end":"20240925184009","trade_state_desc":"支付成功","nonce_str":"OeGOkjch4eaV5qIt","sign":"6DCB3BFC594EBC018A2BEE2C3DFEA4E3"}';
+//                $result = json_decode($result, true);
+                if (!empty($result['return_code']) && $result['return_code'] == 'SUCCESS' && !empty($result['result_code']) && $result['result_code'] == 'SUCCESS' && !empty($result['trade_state']) && $result['trade_state'] == 'SUCCESS') {
+                    $payStatus = 'Y';
+                    foreach ($orders as $order) {
+                        $orderUpdateData = ['order_status_payment' => 'SUCCESS'];
+                        if (in_array($order['order_category'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE'])) {
+                            $orderUpdateData['order_status_system'] = 'WAITING';
+                        } else {
+                            $orderUpdateData['order_status_system'] = 'SENDING';
+                        }
+                        // 主订单
+                        Order::where('order_groupby', $groupId)->update($orderUpdateData);
+                        // Sheet
+                        OrderSheet::where('join_sheet_order_id', $order['order_id'])->where('order_sheet_status', 'PAYING')->update(['order_sheet_status' => 'DONE']);
+
+                        // 支付记录
+                        PayDetail::where('join_pay_order_id', $order['order_groupby'])->where('pay_prepayid', 'WXPAY')->update(['pay_status' => 'SUCCESS']);
+
+                        $discountJson = [];
+                        if (!empty($orders[0]['order_discount_json'])) {
+                            $discountJson = json_decode($orders[0]['order_discount_json'], true);
+                        }
+                        // 优惠券标记使用
+                        $this->changeOrderCouponStatus($discountJson, 'USED');
+                    }
+                }
+            } else if (in_array('ALIPAY', $payDetailType)) {
+                $result = Pay::alipay(config('payment.alipay'))->find($groupId);
+                $result = json_decode(json_encode($result), true);
+//                $result = '{"code":"10000","msg":"Success","buyer_logon_id":"138******93","buyer_pay_amount":"5.87","fund_bill_list":[{"amount":"5.69","fund_channel":"ALIPAYACCOUNT"},{"amount":"0.18","fund_channel":"COUPON"},{"amount":"0.13","fund_channel":"DISCOUNT"}],"invoice_amount":"5.69","out_trade_no":"OD2409251550Q07A","point_amount":"0.00","receipt_amount":"6.00","send_pay_date":"2024-09-25 15:50:22","total_amount":"6.00","trade_no":"2024092523001439431419750998","trade_status":"TRADE_SUCCESS","buyer_open_id":"04309N2aVhSZz4cKwN_DN2DQa7ekM3z5n8kscQHsmIZOJsf"}';
+//                $result = json_decode($result, true);
+                if (!empty($result['code']) && $result['code'] == '10000' && !empty($result['trade_status']) && $result['trade_status'] == 'TRADE_SUCCESS') {
+                    $payStatus = 'Y';
+                    foreach ($orders as $order) {
+                        $orderUpdateData = ['order_status_payment' => 'SUCCESS'];
+                        if (in_array($order['order_category'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE'])) {
+                            $orderUpdateData['order_status_system'] = 'WAITING';
+                        } else {
+                            $orderUpdateData['order_status_system'] = 'SENDING';
+                        }
+                        // 主订单
+                        Order::where('order_groupby', $groupId)->update($orderUpdateData);
+                        // Sheet
+                        OrderSheet::where('join_sheet_order_id', $order['order_id'])->where('order_sheet_status', 'PAYING')->update(['order_sheet_status' => 'DONE']);
+                        // 支付记录
+                        PayDetail::where('join_pay_order_id', $order->order_groupby)->where('pay_prepayid', 'ALIPAY')->update(['pay_status' => 'SUCCESS']);
+                        // 优惠券标记使用
+                        $discountJson = [];
+                        if (!empty($orders[0]['order_discount_json'])) {
+                            $discountJson = json_decode($orders[0]['order_discount_json'], true);
+                        }
+                        $this->changeOrderCouponStatus($discountJson, 'USED');
+                    }
+                }
+            }
+            if ($payStatus == 'Y') {
+                // 如果有余额、VIP、福利账户支付
+                if (in_array($orders[0]['join_order_member_id'] . '-CASH', $payDetailType)) {
+                    $cashAmount = PayDetail::where('join_pay_order_id', $groupId)
+                        ->where('pay_prepayid', $orders[0]['join_order_member_id'] . '-CASH')
+                        ->sum('pay_amount');
+                    $this->deductAccountOne($groupId, $orders[0]['join_order_member_id'] . '-CASH', $cashAmount);
+                }
+                if (in_array($orders[0]['join_order_member_id'] . '-VIP', $payDetailType)) {
+                    $cashAmount = PayDetail::where('join_pay_order_id', $groupId)
+                        ->where('pay_prepayid', $orders[0]['join_order_member_id'] . '-VIP')
+                        ->sum('pay_amount');
+                    $this->deductAccountOne($groupId, $orders[0]['join_order_member_id'] . '-VIP', $cashAmount);
+                }
+                if (in_array($orders[0]['join_order_member_id'] . '-WELFARE', $payDetailType)) {
+                    $cashAmount = PayDetail::where('join_pay_order_id', $groupId)
+                        ->where('pay_prepayid', $orders[0]['join_order_member_id'] . '-WELFARE')
+                        ->sum('pay_amount');
+                    $this->deductAccountOne($groupId, $orders[0]['join_order_member_id'] . 'WELFARE', $cashAmount);
+                }
+
+                Db::commit();
+
+                // 服务产生权益
+                if (in_array($orders[0]['order_classify'], ['SERVICE', 'CHNMED', 'CHNNCD'])) {
+                    $this->insertBenefitService($groupId);
+                }
+                // 产生套包权益
+                if (in_array($orders[0]['order_classify'], ['PACKAGE'])) {
+                    $this->insertBenefitPackage($groupId);
+                }
+
+                return json_success('success');
+            }
+
+
+            Db::rollBack();
+            return json_fail('没有查询到记录');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            _syslog("支付轮询", '订单支付异常:' . $e->getMessage());
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
             Db::rollBack();
             return json_fail('查询失败');
         }
     }
 
+    /**
+     * @Desc 大额支付轮询中的账户扣款
+     * @Author Gorden
+     * @Date 2024/9/26 13:36
+     *
+     * @param $accountNbr
+     * @param $amount
+     * @return void
+     * @throws BusinessException
+     */
+    public function deductAccountOne($groupId, $accountNbr, $amount)
+    {
+        try {
+            $account = MemberAccount::where('member_account_nbr', $accountNbr)->first();
+            $account->member_account_expend = $account->member_account_expend + $amount;
+            if ($account->member_account_surplus < $amount && strpos($accountNbr, 'CASH') !== false) {
+                $account->member_account_added = $account->member_account_added - ($amount - $account->member_account_surplus);
+                $account->member_account_surplus = 0;
+            } else {
+                $account->member_account_surplus = $account->member_account_surplus - $amount;
+            }
+            $account->save();
+
+            PayDetail::where('pay_prepayid', $accountNbr)
+                ->where('join_pay_order_id', $groupId)
+                ->update([
+                    'pay_paytimes' => date('Y-m-d H:i:s'),
+                    'pay_status' => 'SUCCESS'
+                ]);
+        } catch (\Exception $e) {
+            Log::info("获取大额支付状态:扣除账户金额失败", ['nbr' => $accountNbr, 'amount' => $account]);
+
+            throw new BusinessException("账户金额扣除失败");
+        }
+    }
+
+    /**
+     * @Desc 服务权益设置
+     * @Author Gorden
+     * @Date 2024/9/26 16:34
+     *
+     * @param $groupId
+     * @return void
+     */
+    public function insertBenefitService($groupId)
+    {
+        try {
+            $orders = Order::where('order_groupby', $groupId)->select('order_id', 'order_classify')->get()->toArray();
+            $orderIds = array_column($orders, 'order_id');
+            $sheets = OrderSheet::whereIn('join_sheet_order_id', $orderIds)->get()->toArray();
+            foreach ($sheets as $sheet) {
+                $params = [];
+                foreach ($orders as $order) {
+                    if ($sheet['join_sheet_order_id'] == $order['order_id']) {
+                        $params['goods_classify'] = $order['order_classify'];
+                    }
+                }
+                $params['join_order_member_id'] = $sheet['join_sheet_member_id'];
+                $params['join_sheet_goods_id'] = $sheet['join_sheet_goods_id'];
+                $params['join_sheet_goods_sku_id'] = $sheet['join_sheet_goods_sku_id'];
+                $params['orderId'] = $sheet['join_sheet_order_id'];
+                $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                for ($i = 0; $i < $sheet['order_sheet_num']; $i++) {
+                    $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                    $this->insertAppointment($params, []);
+                }
+
+                $goodsModel = Goods::where('goods_id', $sheet['join_sheet_goods_id'])->first();
+                $goods = [];
+                if (!empty($goodsModel)) {
+                    $goods['goods_id'] = $sheet['join_sheet_goods_id'];
+                    $goods['skuId'] = $sheet['join_sheet_goods_sku_id'];
+                    $goods['category'] = $goodsModel->goods_classify;
+                    $goods['goods_name'] = $goodsModel->goods_name;
+                }
+                $params['order_sheet_num'] = $sheet['order_sheet_num'];
+                $this->insertMemberBenefit($params, $goods);
+            }
+        } catch (\Exception $e) {
+            _syslog("下单", '权益设置失败');
+        }
+    }
+
+    /**
+     * @Desc 套包权益设置
+     * @Author Gorden
+     * @Date 2024/9/26 16:34
+     *
+     * @param $groupId
+     * @return void
+     */
+    public function insertBenefitPackage($groupId)
+    {
+        try {
+            $orders = Order::where('order_groupby', $groupId)->select('order_id', 'order_classify')->get()->toArray();
+            $orderIds = array_column($orders, 'order_id');
+            $sheets = OrderSheet::whereIn('join_sheet_order_id', $orderIds)->get()->toArray();
+            foreach ($sheets as $sheet) {
+                $params = [];
+                $params['orderId'] = $sheet['join_sheet_order_id'];
+                foreach ($orders as $order) {
+                    if ($sheet['join_sheet_order_id'] == $order['order_id']) {
+                        $params['goods_classify'] = $order['order_classify'];
+                    }
+                }
+                $params['packageId'] = $sheet['join_sheet_goods_id'];;
+                $components = GoodsComponent::with([
+                    'goods' => function ($query) {
+                        $query->select('goods_id', 'goods_name', 'goods_classify');
+                    }
+                ])->where('join_component_master_goods_id', $params['packageId'])
+                    ->get()
+                    ->toArray();
+                $params['join_order_member_id'] = $sheet['join_sheet_member_id'];
+                foreach ($components as $component) {
+                    $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
+                    $componentJson = json_decode($component['goods_component_json'], true);
+                    $params['join_sheet_goods_id'] = $component['join_component_goods_id'];
+                    $params['order_sheet_num'] = $sheet['order_sheet_num'] * $componentJson['nbr'];
+                    $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
+                    for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
+                        $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
+                        // 入预约记录
+                        $this->insertAppointment($params, []);
+                    }
+                    $goods['goods_id'] = $component['join_component_goods_id'];
+                    $goods['goods_name'] = $component['goods']['goods_name'];
+                    $goods['goods_classify'] = $component['goods']['goods_classify'];
+                    $goods['skuId'] = $componentJson['sku_id'];
+                    $goods['category'] = 'SERVICE';
+                    // 权益表
+                    $this->insertMemberBenefit($params, $goods);
+                }
+            }
+        } catch (\Exception $e) {
+            _syslog("下单", '权益设置失败');
+        }
+    }
+
+    public function deductAccount($orderId, $orderGroup, $payWay)
+    {
+        $payDetails = PayDetail::where('join_pay_order_id', $orderGroup)
+            ->where('pay_prepayid', '<>', $payWay)
+            ->whereJsonContains('join_pay_object_json->order_id', $orderId)
+            ->get()
+            ->toArray();
+        $pays = [];
+        foreach ($payDetails as $payDetail) {
+            if (isset($pays[$payDetail['pay_prepayid']])) {
+                $pays[$payDetail['pay_prepayid']] += $payDetail['pay_amount'];
+            } else {
+                $pays[$payDetail['pay_prepayid']] = $payDetail['pay_amount'];
+            }
+        }
+
+        foreach ($pays as $key => $amount) {
+            if (strpos($key, 'CASH') !== false || strpos($key, 'CARD') !== false || strpos($key, 'WELFARE') !== false || strpos($key, 'VIP') !== false) {
+                $account = MemberAccount::where('member_account_nbr', $key)->first();
+                $account->member_account_expend = $account->member_account_expend + $amount;
+                $account->member_account_surplus = $account->member_account_surplus - $amount;
+                $account->save();
+            }
+        }
+        PayDetail::where('join_pay_order_id', $orderGroup)
+            ->where('pay_prepayid', '<>', $payWay)
+            ->whereJsonContains('join_pay_object_json->order_id', $orderId)
+            ->update(['pay_status' => 'SUCCESS']);
+    }
+
     /**
      * @Desc 修改订单状态-挂账
      * @Author Gorden
@@ -4795,7 +5249,7 @@ class WholeController extends Curd
             }
         ])->where('join_appointment_order_id', $orderId)
             ->where('appointment_status', 'DONE')
-            ->select('join_appointment_member_id', 'join_appointment_goods_id', 'appointment_done_datetime', 'appointment_done_json');
+            ->select('appointment_id', 'join_appointment_member_id', 'join_appointment_goods_id', 'appointment_done_datetime', 'appointment_done_json');
         $total = $appointments->count();
         $rows = $appointments->forPage($page, $pageSize)
             ->orderBy('appointment_done_datetime', 'DESC')
@@ -4819,6 +5273,7 @@ class WholeController extends Curd
                 $doneJson = json_decode($item['appointment_done_json'], true);
                 if (isset($doneJson['charge']) && !empty($doneJson['charge']['charge_user_id'])) {
                     $item['username'] = SysUser::where('user_id', $doneJson['charge']['charge_user_id'])->value('user_name');
+                    $item['waiter'] = $doneJson['charge']['charge_waiter'] ?? '';
                 }
                 if (isset($doneJson['charge']) && !empty($doneJson['charge']['charge_premises'])) {
                     $item['premise'] = $doneJson['charge']['charge_premises'];
@@ -4831,6 +5286,25 @@ class WholeController extends Curd
         return json_success('', compact('rows', 'page', 'pageSize', 'total'));
     }
 
+//    public function getMergeOrder(Request $request)
+//    {
+//        $orderIds = $request->get('order_ids');
+//        if (!$orderIds) {
+//            return json_fail('参数异常');
+//        }
+//
+//        $orders = Order::whereIn('order_id', $orderIds)
+//            ->select('order_id', 'order_groupby', 'order_amount_total', 'order_amount_pay')
+//            ->get()
+//            ->toArray();
+//        $groupIds = array_column($orders, 'order_groupby');
+//        if (count(array_unique($groupIds)) > 1){
+//            return json_fail("请选择同批次下单的记录");
+//        }
+//
+//        return json_success("");
+//    }
+
     public static $goodsClassify = [
         // goodsClassify: {GOODS:"健康产品订单",SERVICE:"服务订单",DEVICE:"设备订单",SPECIAL:"专题业务订单",PACKAGE:"套餐订单",RECHARGE:"充值订单",OTHER:"其他订单"},
 

+ 44 - 0
app/admin/controller/sys_manage/ConfigController.php

@@ -152,6 +152,50 @@ class ConfigController
         return ConfigService::paramsSave($request, $this->getType($request->post('type', '')));
     }
 
+    public function partnerParamsInfo()
+    {
+        $config = SysConfig::where('config_key', 'app-identity-partner-config')->first()->toArray();
+        $config['config_value_json'] = json_decode($config['config_value_json'], true);
+        if (!empty($config['config_value_json']['account']['added'])) {
+            $config['config_value_json']['account']['added'] = round($config['config_value_json']['account']['added'] * 100, 2);
+        }
+        if (!empty($config['config_value_json']['commission'])) {
+            $config['config_value_json']['commission']['direct'] = round($config['config_value_json']['commission']['direct'] * 100, 2);
+            $config['config_value_json']['commission']['indirect'] = round($config['config_value_json']['commission']['indirect'] * 100, 2);
+            $config['config_value_json']['commission']['relate_consum'] = round($config['config_value_json']['commission']['relate-consum'] * 100, 2);
+            $config['config_value_json']['commission']['invite_non_identity'] = round($config['config_value_json']['commission']['invite-non-identity'] * 100, 2);
+            $config['config_value_json']['commission']['agent_senior_join'] = round($config['config_value_json']['commission']['agent-senior-join'] * 100, 2);
+            $config['config_value_json']['commission']['agent_senior_strategy'] = round($config['config_value_json']['commission']['agent-senior-strategy'] * 100, 2);
+        }
+
+        return json_success('success', $config);
+    }
+
+    public function setPartnerParams(Request $request)
+    {
+        $params = $request->post();
+        if (!empty($params['account']['added'])) {
+            $params['account']['added'] = $params['account']['added'] / 100;
+        }
+        if (!empty($params['commission'])) {
+            $params['commission']['direct'] = $params['commission']['direct'] / 100;
+            $params['commission']['indirect'] = $params['commission']['indirect'] / 100;
+            $params['commission']['relate-consum'] = $params['commission']['relate_consum'] / 100;
+            $params['commission']['invite-non-identity'] = $params['commission']['invite_non_identity'] / 100;
+            $params['commission']['agent-senior-join'] = $params['commission']['agent_senior_join'] / 100;
+            $params['commission']['agent-senior-strategy'] = $params['commission']['agent_senior_strategy'] / 100;
+
+            unset($params['commission']['relate_consum'], $params['commission']['invite_non_identity'], $params['commission']['agent_senior_join'], $params['commission']['agent_senior_strategy']);
+        }
+        try {
+            SysConfig::where('config_key', 'app-identity-partner-config')->update(['config_value_json' => json_encode($params)]);
+
+            return json_success('success');
+        } catch (\Exception $e) {
+            return json_fail("保存失败");
+        }
+    }
+
     private function getType($type)
     {
         switch ($type) {

+ 22 - 0
app/admin/controller/sys_manage/DeptController.php

@@ -145,4 +145,26 @@ class DeptController extends Curd
     {
         return DeptService::delDept($id);
     }
+
+    /**
+     * 场所名获取打印机
+     */
+    public function getPrinterByPremiseName(Request $request)
+    {
+        $premiseName = $request->get('premise','');
+
+        $printerList = [];
+        try{
+
+            $premise = SysDept::where('dept_name',$premiseName)->first();
+            if (!empty($premise->dept_extend_json)){
+                $deptExtendJson = json_decode($premise->dept_extend_json,true);
+                if (isset($deptExtendJson['printer'])){
+                    $printerList = $deptExtendJson['printer'];
+                }
+            }
+        }catch(\Exception $e){}
+
+        return json_success('',$printerList);
+    }
 }

+ 20 - 0
app/admin/service/coupon/CouponDetailService.php

@@ -35,4 +35,24 @@ class CouponDetailService
             throw new BusinessException('写入优惠券失败');
         }
     }
+
+    public static function customSendCouponHave($params)
+    {
+        try {
+            CouponDetail::where('join_detail_coupon_id',$params['coupon_id'])
+                ->whereIn('coupon_detail_status',['INIT','PENDING'])
+                ->limit($params['chooseCouponNbr'])
+                ->update([
+                    'join_coupon_detail_member_id' => $params['member_id'],
+                    'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'],
+                    'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'],
+                    'coupon_detail_extend_json'=>json_encode(['gettype'=>'SEND']),
+                    'coupon_detail_status'=>'ACTIVED',
+                    'coupon_detail_addtimes' => time()
+                ]);
+        } catch (\Exception $e) {
+            throw new BusinessException('写入优惠券失败');
+        }
+    }
+
 }

+ 27 - 8
app/admin/service/coupon/CouponService.php

@@ -39,31 +39,43 @@ class CouponService
         Db::beginTransaction();
         try {
             $coupons = Coupon::where('coupon_is_period', 'Y')->where('coupon_status', 'ACTIVED')->get()->toArray();
+//            dump("周期全",$coupons);
             foreach ($coupons as $coupon) {
-                if (time() > strtotime($coupon['coupon_validdate_end'])) {
+                if (!empty($coupon['coupon_validdate_end']) && time() > strtotime($coupon['coupon_validdate_end'])) {
                     continue;
                 }
-                $details = CouponDetail::where('join_detail_coupon_id',$coupon['coupon_id'])
-                    ->select('join_coupon_detail_member_id')
+                $details = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
+                    ->where('join_coupon_detail_member_id','<>','')
+                    ->selectRaw('join_coupon_detail_member_id,COUNT(*) as count')
                     ->groupBy('join_coupon_detail_member_id')
                     ->get();
                 foreach ($details as $item) {
                     $detail = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
-                        ->where('join_coupon_detail_member_id',$item->join_coupon_detail_member_id)
+                        ->where('join_coupon_detail_member_id', $item->join_coupon_detail_member_id)
                         ->orderBy('coupon_detail_addtimes', 'DESC')
                         ->first();
-                    if (!empty($detail) && strtotime($detail->coupon_detail_deadline_datetime) > time()) {
+                    if (strtotime($detail->coupon_detail_deadline_datetime) > time()) {
                         continue;
+                    } elseif (empty($coupon['coupon_validdate_end']) && !empty($coupon['coupon_validdate_day'])) {
+                        $firstDetail = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
+                            ->where('join_coupon_detail_member_id', $item->join_coupon_detail_member_id)
+                            ->orderBy('coupon_detail_addtimes', 'ASC')
+                            ->first();
+                        if ((time() - strtotime($firstDetail->coupon_detail_addtimes)) > (3600 * 24 * $coupon['coupon_validdate_day'])) {
+                            continue;
+                        }
                     }
+
                     $params = [
                         'coupon_detail_gain_datetime' => date('Y-m-d 00:00:00'),
                         'coupon_id' => $coupon['coupon_id'],
                         'member_id' => $detail->join_coupon_detail_member_id,
                         'coupon_detail_period_num' => $detail->coupon_detail_period_num + 1
                     ];
+                    // 超出期数
                     if (!empty($coupon['coupon_period_json'])) {
                         $periodJson = json_decode($coupon['coupon_period_json'], true);
-                        if ($periodJson['nbr'] < $params['coupon_detail_period_num']){
+                        if ($periodJson['nbr'] < $params['coupon_detail_period_num']) {
                             continue;
                         }
                         if ($periodJson['unit'] == 'day') {
@@ -89,8 +101,14 @@ class CouponService
                             }
                         }
                     }
-                    // 写入优惠券
-                    CouponDetailService::customSendCoupon($params);
+                    if (CouponDetail::whereIn('coupon_detail_status',['INIT','PENDING'])->exists()){
+                        // 匹配已发行的优惠券
+                        $params['chooseCouponNbr'] = 1;
+                        CouponDetailService::customSendCouponHave($params);
+                    }else{
+                        // 写入优惠券
+                        CouponDetailService::customSendCoupon($params);
+                    }
 
                     _syslog("周期券", "发放周期券", false, $params, 1001);
                 }
@@ -98,6 +116,7 @@ class CouponService
 
             Db::commit();
         } catch (\Exception $e) {
+            dump($e->getTrace());
             Db::rollBack();
         }
     }

+ 28 - 9
app/admin/service/goods/GoodsService.php

@@ -187,8 +187,8 @@ class GoodsService
             ->select('goods_id', 'join_goods_category_id', 'join_goods_supplier_id', 'creator_user_id', 'goods_status', 'goods_sales_price', 'goods_category', 'goods_name', 'goods_title', 'goods_cover', 'goods_sort', 'goods_attribute_json', 'goods_addtimes', 'goods_updatetimes')
             ->when($goodsName != '', function ($query) use ($goodsName) {
                 $query->where(function ($q) use ($goodsName) {
-                    $q->where('goods_name', 'like', '%' . $goodsName . '%')
-                        ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
+                    $q->where('goods_name', 'like', '%' . $goodsName . '%');
+//                        ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
                 });
             })->when($categoryId != null, function ($query) use ($categoryId) {
                 $query->whereIn('join_goods_category_id', $categoryId);
@@ -219,8 +219,8 @@ class GoodsService
         $total = Goods::leftJoin('goods_running', 'goods_running.join_running_goods_id', '=', 'goods.goods_id')
             ->when($goodsName != '', function ($query) use ($goodsName) {
                 $query->where(function ($q) use ($goodsName) {
-                    $q->where('goods_name', 'like', '%' . $goodsName . '%')
-                        ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
+                    $q->where('goods_name', 'like', '%' . $goodsName . '%');
+//                        ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
                 });
             })->when($categoryId != null, function ($query) use ($categoryId) {
                 $query->whereIn('join_goods_category_id', $categoryId);
@@ -287,8 +287,8 @@ class GoodsService
         ])->select('goods_id', 'join_goods_category_id', 'join_goods_supplier_id', 'creator_user_id', 'goods_status', 'goods_sales_price', 'goods_category', 'goods_name', 'goods_title', 'goods_cover', 'goods_sort', 'goods_addtimes', 'goods_updatetimes')
             ->when($goodsName != '', function ($query) use ($goodsName) {
                 $query->where(function ($q) use ($goodsName) {
-                    $q->where('goods_name', 'like', '%' . $goodsName . '%')
-                        ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
+                    $q->where('goods_name', 'like', '%' . $goodsName . '%');
+//                        ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
                 });
             })->whereIn('join_goods_category_id', $categoryId)
             ->orderBy('goods_sort', 'DESC')
@@ -298,8 +298,8 @@ class GoodsService
             ->toArray();
         $total = Goods::when($goodsName != '', function ($query) use ($goodsName) {
             $query->where(function ($q) use ($goodsName) {
-                $q->where('goods_name', 'like', '%' . $goodsName . '%')
-                    ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
+                $q->where('goods_name', 'like', '%' . $goodsName . '%');
+//                    ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
             });
         })->whereIn('join_goods_category_id', $categoryId)->count();
 
@@ -572,7 +572,11 @@ class GoodsService
         } else {
             $goodsCategoryIds = array_column($data, 'id');
         }
-        $goods = Goods::with('sku')
+        $goods = Goods::with([
+            'sku' => function($query){
+                $query->where('goods_sku_status','ON');
+            }
+        ])
             ->leftJoin('goods_running', 'goods_running.join_running_goods_id', '=', 'goods.goods_id')
             ->where('goods_running.goods_running_storage', '>', 0)
             ->whereIn('join_goods_category_id', $goodsCategoryIds)
@@ -648,10 +652,17 @@ class GoodsService
                                     if (!isset($cascader4['goods_id'])) {
                                         unset($cascaderData[$key1]['children'][$key2]['children'][$key3]['children'][$key4]);
                                     }
+                                    if (isset($cascader4['goods_id']) && empty($cascader4['sku'])){
+                                        unset($cascaderData[$key1]['children'][$key2]['children'][$key3]['children'][$key4]);
+                                    }
                                 }
                             } else if (!isset($cascader3['goods_id'])) {
                                 unset($cascaderData[$key1]['children'][$key2]['children'][$key3]);
                             }
+                            if (isset($cascader3['goods_id']) && empty($cascader3['sku'])){
+                                unset($cascaderData[$key1]['children'][$key2]['children'][$key3]);
+                                continue;
+                            }
                             if (isset($cascader3['children']) && count($cascaderData[$key1]['children'][$key2]['children']) == 0) {
                                 unset($cascaderData[$key1]['children'][$key2]);
                             }
@@ -662,6 +673,10 @@ class GoodsService
                     } else if (!isset($cascader2['goods_id'])) {
                         unset($cascaderData[$key1]['children'][$key2]);
                     }
+                    if (isset($cascader2['goods_id']) && empty($cascader2['sku'])){
+                        unset($cascaderData[$key1]['children'][$key2]);
+                        continue;
+                    }
                     if (isset($cascader2['children']) && count($cascaderData[$key1]['children'][$key2]['children']) == 0) {
                         unset($cascaderData[$key1]['children'][$key2]);
                     }
@@ -672,6 +687,10 @@ class GoodsService
             } else if (!isset($cascader1['goods_id'])) {
                 unset($cascaderData[$key1]);
             }
+            if (isset($cascader1['goods_id']) && empty($cascader1['sku'])){
+                unset($cascaderData[$key1]);
+                continue;
+            }
             if (isset($cascader1['children']) && count($cascaderData[$key1]['children']) == 0) {
 
                 unset($cascaderData[$key1]);

+ 245 - 17
app/admin/service/member/MemberService.php

@@ -2,6 +2,7 @@
 
 namespace app\admin\service\member;
 
+use app\common\Tree;
 use app\model\ClientPoints;
 use app\model\CouponDetail;
 use app\model\Device;
@@ -23,6 +24,7 @@ use app\model\SysUser;
 use support\Db;
 use support\exception\BusinessException;
 use support\Request;
+use support\Response;
 
 class MemberService
 {
@@ -37,6 +39,9 @@ class MemberService
         $isAuth = $request->get('is_auth', '');
         $addtime = $request->get('member_addtimes', []);
         $type = $request->get('type', '');
+        $status = $request->get('member_status', '');
+        $memberIsPartner = $request->get('member_is_partner', '');
+        $memberIsReferrer = $request->get('member_is_referrer', '');
 
         $rows = Member::with([
             'account' => function ($query) {
@@ -82,11 +87,21 @@ class MemberService
                 }
                 $query->whereBetween('member.member_addtimes', $addtime);
             })->when(!empty($nickname), function ($query) use ($nickname) {
-                $query->where(function($query2) use ($nickname){
-                    $query2->where('member_info.member_info_nickname','like','%'.$nickname.'%')->orWhere('member.member_mobile','like','%'.$nickname.'%');
+                $query->where(function ($query2) use ($nickname) {
+                    $query2->where('member_info.member_info_nickname', 'like', '%' . $nickname . '%')->orWhere('member.member_mobile', 'like', '%' . $nickname . '%');
                 });
+            })->when(!empty($status), function ($query) use ($status) {
+                $query->where('member_status', $status);
+            })->when(!empty($memberIsPartner), function ($query) use ($memberIsPartner) {
+                if ($memberIsPartner == 'Y') {
+                    $query->where('member_is_partner', 'Y');
+                }
+            })->when(!empty($memberIsReferrer), function ($query) use ($memberIsReferrer) {
+                if ($memberIsReferrer == 'Y') {
+                    $query->where('member_is_referrer', 'Y');
+                }
             })
-            ->select('member_id', 'member_is_vip', 'member_is_owner', 'member_classify', 'member_status', 'member_mobile', 'member_from', 'member_addtimes', 'member_extend_json',
+            ->select('member_id', 'member_is_vip', 'member_is_owner', 'member_is_partner', 'member_is_referrer', 'member_classify', 'member_status', 'member_mobile', 'member_from', 'member_addtimes', 'member_extend_json',
                 'member_info.member_info_nickname', 'member_info.member_info_headimg', 'member_info.member_info_referee', 'member_info.member_info_business', 'member_info.member_info_service', 'member_info.member_info_city', 'member_info.member_info_address', 'member_info.member_info_gender', 'member_info.member_info_birthday',
                 'member_role.member_role_id', 'member_role.member_role_name',
                 'member_cert.member_cert_birth', 'member_cert.member_cert_gender', 'member_cert.member_cert_name', 'member_cert.member_cert_nbr', 'member_cert.member_cert_province', 'member_cert.member_cert_addr', 'member_cert.member_cert_face', 'member_cert.member_cert_photo', 'member_cert.member_cert_nation'
@@ -210,6 +225,16 @@ class MemberService
                     }
                 }
             }
+            // 粉丝
+            $fans1 = Member::where('join_invite_member_id', $row['member_id'])
+                ->select('member_id')
+                ->get()
+                ->toArray();
+            $fans1Ids = array_column($fans1, 'member_id');
+            $fans2Count = Member::whereIn('join_invite_member_id', $fans1Ids)
+                ->count();
+            $row['fans_total'] = count($fans1) + $fans2Count;
+
         }
 
         return json_success('', compact('rows', 'page', 'pageSize', 'total'));
@@ -267,7 +292,7 @@ class MemberService
         $exportData = [];
         foreach ($rows as $row) {
             $row['info'] = [
-                'member_info_nickname' => !empty($row['member_info_nickname']) ? $row['member_info_nickname'] : substr($row['member_mobile'], -4, 4) . '用户',
+                'member_info_nickname' => !empty($row['member_info_nickname']) ? $row['member_info_nickname'] : substr($row['member_mobile'], -4, 4) . '会员',
                 'member_info_headimg' => !empty($row['member_info_headimg']) ? $row['member_info_headimg'] : '',
                 'member_info_referee' => !empty($row['member_info_referee']) ? $row['member_info_referee'] : '',
                 'member_info_business' => !empty($row['member_info_business']) ? $row['member_info_business'] : '',
@@ -322,7 +347,7 @@ class MemberService
                 'cash' => isset($account['cash']) ? $account['cash']['member_account_surplus'] + $account['cash']['member_account_added'] : 0,
                 'points' => isset($account['points']) ? $account['points']['member_account_surplus'] + $account['points']['member_account_added'] : 0,
                 'is_auth' => $row['is_auth'],
-                'level' => $row['member_role_name'] ?? '普通用户',
+                'level' => $row['member_role_name'] ?? '普通会员',
                 'member_addtimes' => $row['member_addtimes'],
                 'member_info_referee' => $row['info']['member_info_referee'] ?? '',
                 'member_info_business' => $row['info']['member_info_business'] ?? '',
@@ -335,7 +360,13 @@ class MemberService
 
     public static function info($memberId)
     {
-        $member = Member::with('cert', 'info')
+        $member = Member::with([
+            'cert',
+            'info',
+            'role' => function ($query) {
+                $query->select('member_role_id', 'member_role_name');
+            }
+        ])
             ->where('member_id', $memberId)
             ->first();
         if (!$member) {
@@ -343,7 +374,7 @@ class MemberService
         }
         $member = $member->toArray();
         $member['info'] = [
-            'member_info_nickname' => !empty($member['info']) && !empty($member['info']['member_info_nickname']) ? $member['info']['member_info_nickname'] : substr($member['member_mobile'], -4, 4) . '用户',
+            'member_info_nickname' => !empty($member['info']) && !empty($member['info']['member_info_nickname']) ? $member['info']['member_info_nickname'] : substr($member['member_mobile'], -4, 4) . '会员',
             'member_info_headimg' => !empty($member['info']) && !empty($member['info']['member_info_headimg']) ? $member['info']['member_info_headimg'] : '',
             'member_info_referee' => !empty($member['info']) && !empty($member['info']['member_info_referee']) ? $member['info']['member_info_referee'] : '',
             'member_info_business' => !empty($member['info']) && !empty($member['info']['member_info_business']) ? $member['info']['member_info_business'] : '',
@@ -423,6 +454,29 @@ class MemberService
                 }
             }
         }
+        if (!empty($member['join_invite_member_id'])) {
+            $inviteMember = Member::with('cert', 'info')
+                ->where('member_id', $member['join_invite_member_id'])
+                ->select('member_id', 'member_mobile', 'member_invite_code')
+                ->first();
+            if (!empty($inviteMember)) {
+                $inviteMember = $inviteMember->toArray();
+                $mobile = '';
+                if (!empty($inviteMember['member_mobile'])) {
+                    $mobile = $inviteMember['member_mobile'];
+                }
+                $nickname = '';
+                if (!empty($inviteMember['info']) && !empty($inviteMember['info']['member_info_nickname'])) {
+                    $nickname = $inviteMember['info']['member_info_nickname'];
+                }
+                $certname = '';
+                if (!empty($inviteMember['cert']) && !empty($inviteMember['cert']['member_info_nickname'])) {
+                    $nickname = $inviteMember['cert']['member_cert_name'];
+                }
+                $member['invite_name'] = MemberService::getMemberName($mobile, $certname, $nickname);
+                $member['invite_code'] = $inviteMember['member_invite_code'] ?? '';
+            }
+        }
 
         return json_success('', $member);
     }
@@ -659,6 +713,175 @@ class MemberService
         return json_success('', compact('rows', 'page', 'pageSize', 'total'));
     }
 
+    /**
+     * @Desc 我的粉丝列表
+     * @Author Gorden
+     * @Date 2024/9/20 10:22
+     *
+     * @param Request $request
+     */
+    public static function fansList(Request $request)
+    {
+        $memberId = $request->get('member_id');
+        $name = $request->get('name', '');
+        $mobile = $request->get('mobile', '');
+        $memberIds = [];
+        $memberInviteIds = [];
+        if (!empty($name)) {
+            $memberIds = MemberCert::where('member_cert_name', 'like', '%' . $name . '%')->pluck('join_cert_member_id')->toArray();
+            $memberInviteIds = Member::whereIn('member_id', $memberIds)->pluck('join_invite_member_id')->toArray();
+        }
+        if (!empty($mobile)) {
+            $members = Member::where('member_mobile', 'like', '%' . $mobile . '%')
+                ->select('member_id', 'join_invite_member_id')
+                ->get()
+                ->toArray();
+            $memberIds2 = array_column($members, 'member_id');
+            $memberInviteIds2 = array_column($members, 'join_invite_member_id');
+            $memberIds = array_merge($memberIds, $memberIds2);
+            $memberInviteIds = array_merge($memberInviteIds, $memberInviteIds2);
+        }
+
+        $fans1 = Member::with([
+            'info' => function ($query) {
+                $query->select('join_info_member_id', 'member_info_nickname', 'member_info_headimg');
+            },
+            'cert' => function ($query) {
+                $query->select('join_cert_member_id', 'member_cert_name');
+            },
+            'role' => function ($query) {
+                $query->select('member_role_id', 'member_role_name');
+            }
+        ])->where('join_invite_member_id', $memberId)
+            ->when(!empty($memberIds), function ($query) use ($memberIds, $memberInviteIds) {
+                $allSub = array_merge($memberIds, $memberInviteIds);
+                $query->whereIn('member_id', $allSub);
+            })
+            ->select('member_id', 'join_member_role_id', 'member_id as id', 'join_invite_member_id as pid', 'member_partner_json', 'member_mobile', 'member_addtimes', 'member_is_owner', 'member_is_vip', 'member_is_partner', 'member_is_referrer')
+            ->get()
+            ->toArray();
+        $fans1Ids = array_column($fans1, 'id');
+        $fans2 = Member::with([
+            'info' => function ($query) {
+                $query->select('join_info_member_id', 'member_info_nickname', 'member_info_headimg');
+            },
+            'cert' => function ($query) {
+                $query->select('join_cert_member_id', 'member_cert_name');
+            },
+            'role' => function ($query) {
+                $query->select('member_role_id', 'member_role_name');
+            }
+        ])->whereIn('join_invite_member_id', $fans1Ids)
+            ->when(!empty($memberIds), function ($query) use ($memberIds) {
+                $query->whereIn('member_id', $memberIds);
+            })
+            ->select('member_id', 'join_member_role_id', 'member_id as id', 'join_invite_member_id as pid', 'member_partner_json', 'member_mobile', 'member_addtimes', 'member_is_owner', 'member_is_vip', 'member_is_partner', 'member_is_referrer')
+            ->get()
+            ->toArray();
+
+        $fans = array_merge($fans1, $fans2);
+        foreach ($fans as &$fan) {
+            $memberMobile = $fan['member_mobile'] ?? '';
+//            $memberNickname = $fan['info'] && $fan['info']['member_info_nickname'] ? $fan['info']['member_info_nickname'] : '';
+            $memberCertName = $fan['cert'] && $fan['cert']['member_cert_name'] ? $fan['cert']['member_cert_name'] : '';
+            $fan['member_name'] = '';
+            if (!empty($memberCertName) && !empty($memberMobile)) {
+                $fan['member_name'] = $memberCertName . '-' . $memberMobile;
+            } elseif (!empty($memberCertName)) {
+                $fan['member_name'] = $memberCertName;
+            } elseif (!empty($memberMobile)) {
+                $fan['member_name'] = $memberMobile;
+            }
+            if (!empty($fan['info']) && substr($fan['info']['member_info_headimg'], 0, 4) == 'http') {
+                $fan['member_info_headimg'] = $fan['info']['member_info_headimg'];
+            } else {
+                $fan['member_info_headimg'] = 'https://img.wanyuewellness.com.cn/images/avatar_default.png';
+            }
+            // 等级名称
+            $fan['role_name'] = $fan['role'] && $fan['role']['member_role_name'] ? $fan['role']['member_role_name'] : '';
+
+            unset($fan['info'], $fan['cert'], $fan['role']);
+        }
+
+        $tree = new Tree($fans);
+        return json_success('success', $tree->getTree());
+    }
+
+
+    /**
+     * 格式化树
+     * @param $items
+     * @return Response
+     */
+    protected static function formatTree($items): Response
+    {
+        $format_items = [];
+        foreach ($items as $item) {
+            $format_items[] = [
+                'name' => $item->title ?? $item->name ?? $item->id,
+                'value' => (string)$item->id,
+                'id' => $item->id,
+                'pid' => $item->pid,
+            ];
+        }
+        $tree = new Tree($format_items);
+        return json_success('success', $tree->getTree());
+    }
+
+    public static function clearWelfare(Request $request)
+    {
+        $memberId = $request->post('member_id');
+        $payTime = $request->post('pay_paytimes', date('Y-m-d H:i:s'));
+        $payTime = date('Y-m-d H:i:s', strtotime($payTime));
+        $payRemark = $request->post('pay_remark', '');
+        $clearPwd = $request->post('clear_password');
+        if (!$clearPwd || $clearPwd != '123456') {
+            return json_fail('清零密码错误');
+        }
+
+        Db::beginTransaction();
+        try {
+            $account = MemberAccount::where('join_account_member_id', $memberId)
+                ->where('member_account_classify', 'WELFARE')
+                ->where('member_account_status', 'ACTIVED')
+                ->first();
+            if (!$account) {
+                throw new BusinessException("账户异常");
+            }
+            if ($account->member_account_surplus <= 0) {
+                throw new BusinessException("账户余额为0,无需清零");
+            }
+            // 创建清除记录
+            PayDetail::insert([
+                'join_pay_member_id' => $memberId,
+                'pay_status' => 'SUCCESS',
+                'pay_category' => 'CLEAR',
+                'pay_amount' => $account->member_account_surplus,
+                'pay_paytimes' => $payTime,
+                'pay_prepayid' => $memberId . '-WELFARE',
+                'pay_remark' => $payRemark,
+                'pay_addtimes' => time()
+            ]);
+
+            // 账户归零
+            $account->member_account_expend = $account->member_account_expend + $account->member_account_surplus;
+            $account->member_account_surplus = 0;
+            $account->save();
+
+            Db::commit();
+
+            return json_success('success');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+
+            return json_fail('清零失败');
+        }
+    }
+
     public static function balanceInfo(Request $request)
     {
         $memberId = $request->get('member_id', '');
@@ -676,7 +899,7 @@ class MemberService
         $info = PayDetail::where(function ($query) use ($memberId) {
             $query->where('join_pay_member_id', $memberId)
                 // ->whereIn('pay_prepayid', ['W06', 'A01'])
-                ->where('pay_category', 'RECHARGE')
+                ->whereIn('pay_category', ['RECHARGE','PARTNER'])
                 ->where('pay_prepayid', '<>', $memberId . '-WELFARE')
                 ->where('pay_status', 'SUCCESS');
         })->orWhere(function ($query) use ($memberId) {
@@ -688,6 +911,12 @@ class MemberService
             ->toArray();
         $data = [];
         foreach ($info as $key => $item) {
+            if ($item['pay_category'] == 'PARTNER'){
+                $payObjectJson = json_decode($item['join_pay_object_json'],true);
+                if (!Order::where('order_id',$payObjectJson['order_id'])->where('order_is_complete','Y')->exists()){
+                    continue;
+                }
+            }
             $categoryIds = [];
             if (!empty($item['join_pay_order_id'])) {
                 $orderIds = Order::where('order_groupby', $item['join_pay_order_id'])->pluck('order_id');
@@ -695,7 +924,6 @@ class MemberService
                 $categoryIds = Goods::whereIn('goods_id', $goodsIds)->pluck('join_goods_category_id');
             }
 
-
             $categoryName = [];
             foreach ($categoryIds as $id) {
                 $category = SysCategory::where('category_id', $id)->first();
@@ -711,21 +939,21 @@ class MemberService
             if (mb_substr($item['goods_category'], 0, 7) == '自定义金额充值') {
                 $item['goods_category'] = '自定义金额充值';
             }
-            if (in_array($item['pay_category'], ['RECHARGE', 'REFUND', 'GIVE','PARTNER'])) {
+            if (in_array($item['pay_category'], ['RECHARGE', 'REFUND', 'GIVE', 'PARTNER'])) {
                 $item['balance_type'] = 'add';
             } else {
                 $item['balance_type'] = 'cut';
             }
-            if ($key == 0 && in_array($item['pay_category'], ['RECHARGE', 'REFUND', 'GIVE','PARTNER'])) {
+            if ($key == 0 && in_array($item['pay_category'], ['RECHARGE', 'REFUND', 'GIVE', 'PARTNER'])) {
                 if (!empty($item['pay_extend_json'])) {
                     $extendJson = json_decode($item['pay_extend_json'], true);
                     if (!isset($extendJson['added_amount'])) {
                         $extendJson['added_amount'] = 0;
                     }
                     // 计划任务还没跑
-                    if ($item['pay_category'] == 'RECHARGE' && (!isset($extendJson['notify']) || $extendJson['notify'] != 'success')) {
-                        continue;
-                    }
+//                    if ($item['pay_category'] == 'RECHARGE' && (!isset($extendJson['notify']) || $extendJson['notify'] != 'success')) {
+//                        continue;
+//                    }
                     if (isset($extendJson['added_amount']) && floatval($extendJson['added_amount']) > 0) {
                         $data[] = [
                             'join_pay_member_id' => $item['join_pay_member_id'],
@@ -741,14 +969,14 @@ class MemberService
 
                 $item['balance'] = number_format($balance, 2, '.', '');
                 $balance = $balance - $item['pay_amount'];
-                if ($item['pay_category'] != 'GIVE'){
+                if ($item['pay_category'] != 'GIVE') {
                     $data[] = $item;
                 }
 
                 continue;
             }
 
-            if (in_array($item['pay_category'], ['RECHARGE', 'REFUND', 'GIVE','PARTNER'])) {
+            if (in_array($item['pay_category'], ['RECHARGE', 'REFUND', 'GIVE', 'PARTNER'])) {
                 if (!empty($item['pay_extend_json'])) {
                     $extendJson = json_decode($item['pay_extend_json'], true);
                     if (isset($extendJson['added_amount']) && floatval($extendJson['added_amount']) > 0) {
@@ -933,7 +1161,7 @@ class MemberService
                 'member_info_service' => $params['member_info_service'] ?? '',
                 'member_info_city' => !empty($params['province']) ? implode('-', $params['province']) : '',
                 'member_info_address' => $params['member_info_address'] ?? '',
-                'member_info_birthday' => $params['birth'] ? date('Y-m-d', strtotime($params['birth'])) : '',
+                'member_info_birthday' => !empty($params['birth']) ? date('Y-m-d', strtotime($params['birth'])) : '',
                 'member_info_gender' => $params['gender'] ?? '',
             ];
             MemberInfo::insert($infoData);

+ 3 - 1
app/admin/service/order/AppointmentService.php

@@ -36,6 +36,7 @@ class AppointmentService
         $premisesName = $request->get('premises', '');
         $appointmentMode = $request->get('appointment_mode', '');
         $type = $request->get('type', '');
+        $memberId = $request->get('join_appointment_member_id','');
 
         $rows = Db::table('appointment')
             ->leftJoin('member', 'member.member_id', '=', 'appointment.join_appointment_member_id')
@@ -64,11 +65,12 @@ class AppointmentService
                 } else {
                     $query->where('appointment_mode', $appointmentMode);
                 }
+            })->when(!empty($memberId),function ($query) use ($memberId){
+                $query->where('join_appointment_member_id',$memberId);
             })->when(!empty($type), function ($query) use ($type) {
                 if ($type == 'todayDONE') {
                     $query->where('appointment_status', 'DONE');
                     $query->whereRaw('LEFT(appointment_done_datetime,10)=?', [date('Y-m-d')]);
-//                    $query->whereBetween('appointment_addtimes',[strtotime(date('Y-m-d').' 00:00:00'),strtotime(date('Y-m-d').' 23:59:59')]);
                 } elseif ($type == 'todayAppointment') {
                     $query->where('appointment_datetime', date('Y-m-d'));
                 }

+ 28 - 2
app/admin/service/order/OrderService.php

@@ -285,7 +285,8 @@ class OrderService
             try {
                 $config = config('payment.wxpay');
                 $config['notify_url'] = getenv('NOTIFY_DOMAIN_ADMIN') . '/notify/orderPay/wxpay';
-                Pay::wechat($config)->pos($payData);
+                $wxReturn = Pay::wechat($config)->pos($payData);
+                $log->info("WXPAY_RETURN", json_decode(json_encode($wxReturn), true));
                 $result = self::findWxpay($params['orderGroupId'], 0);
             } catch (GatewayException $g) {
                 $result = self::findWxpay($params['orderGroupId'], 0);
@@ -310,7 +311,8 @@ class OrderService
             try {
                 $config = config('payment.alipay');
                 $config['notify_url'] = getenv('NOTIFY_DOMAIN_ADMIN') . '/notify/orderPay/alipay';
-                Pay::alipay($config)->pos($payData);
+                $alipayReturn = Pay::alipay($config)->pos($payData);
+                $log->info("WXPAY_RETURN", json_decode(json_encode($alipayReturn), true));
                 $result = self::findAlipay($params['orderGroupId'], 0);
             } catch (GatewayException $g) {
                 $result = self::findAlipay($params['orderGroupId'], 0);
@@ -474,6 +476,30 @@ class OrderService
         $payDetail->save();
     }
 
+
+    /**
+     * 组合支付,PayDetail
+     */
+    public static function createProductPayConstituteDetail($params)
+    {
+        dump($params);
+        $payDetail = new PayDetail();
+        $payDetail->join_pay_member_id = $params['join_order_member_id'];
+        $payDetail->join_pay_order_id = $params['orderGroupId'];
+        $payDetail->pay_category = $params['goods_classify'] ?? '';
+        $payDetail->pay_json_request = json_encode($params);
+        $payDetail->pay_addtimes = time();
+        $payDetail->pay_prepayid = $params['pay_category'];
+        $payDetail->pay_json_response = $params['pay_json_response'] ?? json_encode([
+            'pay-result' => '支付成功', 'result-datetime' => date('Y-m-d H:i:s')
+        ]);
+        $payDetail->pay_amount = $params['order_amount_pay'];
+        $payDetail->pay_paytimes = date('Y-m-d H:i:s');
+        $payDetail->pay_status = $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING';
+        $payDetail->join_pay_object_json = !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]';
+        $payDetail->save();
+    }
+
     public static function getPayWayByPrepayId($prepayId)
     {
         $payWay = '';

+ 1 - 2
app/admin/service/statistics/OrderService.php

@@ -39,8 +39,7 @@ class OrderService
             ->where('order_status_payment','SUCCESS')
             ->sum('order_amount_pay');
         // 今日退单
-        $data['todayRefund'] = OrderReturn::where('order_return_addtimes', '>', $todayTimeUnix)
-            ->count();
+        $data['todayRefund'] = $refundAmount;
 
 
         // 柱状图

+ 5 - 1
app/event/MemberLevelEvent.php

@@ -14,6 +14,7 @@ class MemberLevelEvent
 {
     public function payOrderLevelUp($memberId)
     {
+        return json_success('不升级了');
         Db::beginTransaction();
         try {
             $member = Member::where('member_id', $memberId)->select('member_id', 'join_member_role_id', 'member_mobile')->first();
@@ -58,14 +59,17 @@ class MemberLevelEvent
                     $member->join_member_role_id = $memberRole->member_role_id;
                     $member->save();
                     RechargeService::disposeAdded($memberRole->member_role_id, $memberId);
+
+                    _syslog("会员升级", "会员升级成功", false, ['member' => $memberId], 1001);
                 }
             } elseif (!empty($memberRole->member_role_id) && empty($member->join_member_role_id)) {
                 $member->join_member_role_id = $memberRole->member_role_id;
                 $member->save();
                 RechargeService::disposeAdded($memberRole->member_role_id, $memberId);
+
+                _syslog("会员升级", "会员升级成功", false, ['member' => $memberId], 1001);
             }
             Db::commit();
-            _syslog("会员升级", "会员升级成功", false, ['member' => $memberId], 1001);
         }catch (BusinessException $e){
             Db::rollBack();
             _syslog("会员升级","会员升级失败,原因:".$e->getMessage(),false,['member'=>$memberId],1001);

+ 127 - 0
app/event/order/CommissionEvent.php

@@ -0,0 +1,127 @@
+<?php
+
+namespace app\event\order;
+
+use app\model\Member;
+use app\model\MemberAccount;
+use app\model\MemberAccountList;
+use app\model\Order;
+use app\model\SysConfig;
+use support\Db;
+use support\exception\BusinessException;
+
+class CommissionEvent
+{
+//{
+//"config": {
+//"name": "名称",
+//"valid": 365, //有效天
+//"protocol": 229, //服务协议分类ID
+//"notice":["", ""] //注意事项数组
+//},
+//"goods": {
+//    "goods_id": "", //产品ID
+//		"goods_sku_id": 0, //产品SKUID
+//		"amount": "goods_sales_price" //核算金额字段
+//	},
+//	"commission": {
+//    "direct": 0.2, //直属提成
+//		"indirect": 0.1, //间属提成
+//		"relate-consum": 0.1, //消费关联提成 带客
+//		"invite-non-identity": 0.05, //邀请人非身份会员达成提成
+//		"agent-senior-join": 0.05, //中介加盟合伙人提成
+//		"agent-senior-strategy": 0.05, //中介战略合伙人提成
+//		"account":"CASH" //提成写入账户
+//	},
+//	"account": {
+//    "account":"CASH", //达成金额进入账户 不则为空
+//		"added":0.12 //达成金额增值 不则为0
+//	},
+//	"control": {
+//    "notify": "procMemberPartnerExec", //回调函数
+//		"if_installment": "N", //是否支持分期
+//		"if_commission_out": "Y" //提成是否可提现
+//	}
+//}
+    public function order($params)
+    {
+        // 提成设置
+//        $config = SysConfig::where('config_key', 'app-identity-partner-config')->first();
+//        $configParams = json_decode($config->config_value_json, true);
+//        Db::beginTransaction();
+//        try {
+//            $order = Order::where('order_id', $params['orderId'])->where('order_status_payment', 'SUCCESS')->first();
+//            // 有传过来的
+//            if (!empty($params['join_invite_member_id'])) {
+//                $inviteMemberId = $params['join_invite_member_id'];
+//            } else {
+//                // 下单人
+//                $member = Member::where('member_id', $order->join_order_member_id)->first();
+//                if (empty($member->join_invite_member_id)) {
+//                    throw new BusinessException("没有直属上级");
+//                }
+//                $inviteMemberId = $member->join_invite_member_id;
+//            }
+//            // 上级
+//            $memberUp = Member::where('member_id', $inviteMemberId)->first();
+//            if ($memberUp->member_is_partner == 'Y') {
+//                $identity = 'PARTNER';
+//            } elseif ($memberUp->member_is_referrer == 'Y') {
+//                $identity = 'REFERRER';
+//            }else{
+//                throw new BusinessException("直属上级非合伙人或者推荐官");
+//            }
+//            // 记录的JSON
+//            $accountListJson = [
+//                'line' => 'relate-consum',
+//                'amount' => $order->order_amount_pay,
+//                'identity' => $identity,
+//                'order_id' => $order->order_id,
+//                'master_member_id' => $order->join_order_member_id
+//            ];
+//            // 提成
+//            $this->commissionToMember($inviteMemberId, $accountListJson, round($configParams['commission']['relate-consum'] * $order->order_amount_pay, 2), '消费');
+//
+//            Db::commit();
+//            _syslog("提成", "计算提成成功");
+//        } catch (BusinessException $e) {
+//            Db::rollBack();
+//            _syslog("提成", "计算提成失败:" . $e->getMessage());
+//        } catch (\Exception $e) {
+//            dump($e->getMessage());
+//            Db::rollBack();
+//            _syslog("提成", "计算提成失败");
+//        }
+    }
+
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/9/25 15:14
+     *
+     * @param $memberId
+     * @param $accountListJson
+     * @param $money
+     * @return void
+     */
+    private function commissionToMember($memberId, $accountListJson, $money, $accountListCategory)
+    {
+        $account = MemberAccount::where('join_account_member_id', $memberId)->where('member_account_classify', 'CASH')->first();
+        $account->member_account_income = $account->member_account_income + $money;
+        $account->member_account_surplus = $account->member_account_surplus + $money;
+        $account->save();
+
+        MemberAccountList::insert([
+            'join_list_member_account_nbr' => $memberId . '-CASH',
+            'join_member_account_list_member_id' => $memberId,
+            'member_account_list_status' => 'ACTIVED',
+            'member_account_list_attr' => 'IN',
+            'member_account_list_classify' => $accountListJson['identity'],
+            'member_account_list_category' => $accountListCategory,
+            'member_account_list_datetime' => date('Y-m-d H:i:s'),
+            'member_account_list_amount' => $money,
+            'member_account_list_json' => json_encode($accountListJson),
+            'member_account_list_addtimes' => time()
+        ]);
+    }
+}

+ 1 - 1
app/event/order/OrderProcessEvent.php

@@ -20,7 +20,7 @@ class OrderProcessEvent
             $data = [
                 'process_key' => 'DONE',
                 'process_name' => '订单完成',
-                'user_id' => $userId ?? '',
+                'user_id' => $userId ?? 'SYSTEM',
                 'process_json' => $params
             ];
             if (!empty($params['join_order_member_id'])) {

+ 82 - 0
app/event/order/PartnerEvent.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace app\event\order;
+
+use app\model\Coupon;
+use app\model\CouponDetail;
+use app\model\Goods;
+use app\model\Member;
+use app\model\MemberAccount;
+use app\model\PayDetail;
+use app\model\SysConfig;
+use app\model\SysSerial;
+use support\Log;
+
+class PartnerEvent
+{
+    public function grant($params)
+    {
+        $config = SysConfig::where('config_key', 'app-identity-partner-config')->first();
+        $configParams = json_decode($config->config_value_json, true);
+        // 更新身份
+        Member::where('member_id', $params['member_id'])->update(['member_is_partner' => 'Y']);
+        // 余额账户
+        $memberAccount = MemberAccount::where('join_account_member_id', $params['member_id'])->where('member_account_classify', 'CASH')->first();
+        // 分期付款
+        if (isset($params['order_amount_paid']) && $params['order_amount_paid'] > 0) {
+            $params['order_amount_pay'] = $params['order_amount_paid'] + $params['order_amount_pay'];
+        }
+        // 增值到最后一条支付记录
+        $added = 0;
+        $payDetail = PayDetail::whereJsonContains('join_pay_object_json->order_id', $params['orderId'])->orderBy('pay_addtimes', 'DESC')->first();
+        if (!empty($configParams['account']['added'])) {
+            $params['order_amount_pay'] = 10000;
+            $added = round($params['order_amount_pay'] * $configParams['account']['added'], 2);
+            $payDetail->pay_extend_json = json_encode(['added_rate' => $configParams['account']['added'], 'added_amount' => $added]);
+            $payDetail->save();
+        }
+        // 入账
+        $memberAccount->member_account_income = $memberAccount->member_account_income + $params['order_amount_pay'];
+        $memberAccount->member_account_surplus = $memberAccount->member_account_surplus + $params['order_amount_pay'];
+        $memberAccount->member_account_added = $memberAccount->member_account_added + $added;
+        $memberAccount->save();
+        //发放优惠券
+        $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])->select('goods_attribute_json')->first();
+        if (!empty($goods) && !empty($goods->goods_attribute_json)) {
+            $goodsAttributeJson = json_decode($goods->goods_attribute_json, true);
+            if (!empty($goodsAttributeJson['coupon'])) {
+                foreach ($goodsAttributeJson['coupon'] as $key => $coupon) {
+                    $couponModel = Coupon::where('coupon_id', $key)->select('coupon_id', 'coupon_validdate_day', 'coupon_validdate_end')->first();
+                    if (empty($couponModel)) {
+                        continue;
+                    }
+                    // 券是否过期
+                    if (!empty($couponModel->coupon_validdate_end) && strtotime($couponModel->coupon_validdate_end) < time()) {
+                        continue;
+                    }
+                    $endDate = '';
+                    if (!empty($couponModel->coupon_validdate_end)) {
+                        $endDate = $couponModel->coupon_validdate_end;
+                    } elseif ($couponModel->coupon_validdate_day > 0) {
+                        $endDate = date('Y-m-d H:i:s', time() + ($couponModel->coupon_validdate_day * 24 * 3600) - 1);
+                    }
+
+                    $num = $coupon['num'];
+                    for ($i = 0; $i < $num; $i++) {
+                        CouponDetail::insert([
+                            'coupon_detail_id' => 'CUDT' . date("ymdHi") . random_string(4, 'up'),
+                            'join_detail_coupon_id' => $key,
+                            'join_coupon_detail_member_id' => $params['member_id'],
+                            'coupon_detail_status' => 'ACTIVED',
+                            'coupon_detail_gain_datetime' => date('Y-m-d H:i:s'),
+                            'coupon_detail_deadline_datetime' => $endDate,
+                            'coupon_detail_json' => '[]',
+                            'coupon_detail_extend_json' => json_encode(['gettype' => 'PARTNER']),
+                            'coupon_detail_addtimes' => time()
+                        ]);
+                    }
+                }
+            }
+        }
+    }
+}

+ 3 - 0
app/functions.php

@@ -43,6 +43,9 @@ if (!function_exists('http_post_json')) {
 
         $output = curl_exec($ch);
         curl_close($ch);
+        // 写日志
+        \support\Log::info('模拟请求:',json_decode($output,true));
+
         return $output;
     }
 }

+ 19 - 0
app/model/MemberAccountList.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace app\model;
+
+use support\Model;
+
+class MemberAccountList extends Model
+{
+
+    protected $table = 'member_account_list';
+
+    protected $primaryKey = 'member_account_list_id';
+
+    protected $dateFormat = 'U';
+
+    const CREATED_AT = 'member_account_list_addtimes';
+
+    const UPDATED_AT = null;
+}

+ 8 - 6
app/model/OrderSheet.php

@@ -37,7 +37,7 @@ class OrderSheet extends Model
     public function memberInfo()
     {
         return $this->hasOne(MemberInfo::class, 'join_info_member_id', 'join_sheet_member_id')
-            ->select('join_info_member_id', 'member_info_nickname');
+            ->select('join_info_member_id', 'member_info_nickname', 'member_info_headimg');
     }
 
     public function cert()
@@ -100,16 +100,18 @@ class OrderSheet extends Model
             ->select('join_running_goods_id', 'goods_running_storage', 'goods_running_sale');
     }
 
-    public function skus(){
-        return $this->hasMany(GoodsSku::class,'join_sku_goods_id','join_sheet_goods_id');
+    public function skus()
+    {
+        return $this->hasMany(GoodsSku::class, 'join_sku_goods_id', 'join_sheet_goods_id');
     }
 
     public function sku()
     {
         return $this->hasOne(GoodsSku::class, 'goods_sku_id', 'join_sheet_goods_sku_id');
     }
-    
-    public function benefit(){
-        return $this->hasMany(MemberBenefit::class,'join_benefit_order_id','join_sheet_order_id');
+
+    public function benefit()
+    {
+        return $this->hasMany(MemberBenefit::class, 'join_benefit_order_id', 'join_sheet_order_id');
     }
 }

+ 9 - 3
config/event.php

@@ -13,13 +13,19 @@ return [
     'order.kangyangCityVIP.grant' => [
         [\app\event\order\KangyangCityEvent::class, 'grant']
     ],
+    'order.partner.grant' => [
+        [\app\event\order\PartnerEvent::class, 'grant']
+    ],
     'order_pay.member_level.up' => [
-        [\app\event\MemberLevelEvent::class,'payOrderLevelUp']
+        [\app\event\MemberLevelEvent::class, 'payOrderLevelUp']
     ],
     'order.complete' => [
-        [\app\event\order\OrderProcessEvent::class,'orderComplete']
+        [\app\event\order\OrderProcessEvent::class, 'orderComplete']
     ],
     'order.write_off' => [
-        [\app\event\order\OrderProcessEvent::class,'orderWriteOff']
+        [\app\event\order\OrderProcessEvent::class, 'orderWriteOff']
+    ],
+    'commission.order' => [
+        [\app\event\order\CommissionEvent::class, 'order']
     ]
 ];

+ 2 - 0
process/Task.php

@@ -32,6 +32,8 @@ class Task
 
             // 优惠券自动过期
             CouponService::checkCouponExpired();
+            // 发放周期券
+//            CouponService::sendPeriodCoupon();
         });
 
         // 每天的2点执行,注意这里省略了秒位

+ 33 - 7
route/admin.php

@@ -172,6 +172,7 @@ Route::group('/admin', function () {
             Route::post('/update/{id:\d+}', [\app\admin\controller\sys_manage\DeptController::class, 'updateDept']);
             Route::post('/updateStatus/{id:\d+}', [\app\admin\controller\sys_manage\DeptController::class, 'updateStatus']);
             Route::delete('/delete/{id:\d+}', [\app\admin\controller\sys_manage\DeptController::class, 'delDept']);
+            Route::get('/getPrinterByPremiseName', [\app\admin\controller\sys_manage\DeptController::class, 'getPrinterByPremiseName']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -250,18 +251,15 @@ Route::group('/admin', function () {
             Route::post('/update/{id:\d+}', [\app\admin\controller\sys_manage\ConfigController::class, 'updateConfig']);
             Route::post('/updateStatus/{id:\d+}', [\app\admin\controller\sys_manage\ConfigController::class, 'updateStatus']);
             Route::delete('/delete', [\app\admin\controller\sys_manage\ConfigController::class, 'delConfig']);
-//
-//            // 底部菜单
-//            Route::get('/bottomMenuList', [\app\admin\controller\sys_manage\ConfigController::class, 'bottomMenuList']);
-//            Route::post('/bottomMenuSave', [\app\admin\controller\sys_manage\ConfigController::class, 'bottomMenuSave']);
-//            // 导航菜单
-//            Route::get('/navMenuList', [\app\admin\controller\sys_manage\ConfigController::class, 'navMenuList']);
-//            Route::post('/navMenuSave', [\app\admin\controller\sys_manage\ConfigController::class, 'navMenuSave']);
+
 
             // 参数配置
             Route::get('/paramsList', [\app\admin\controller\sys_manage\ConfigController::class, 'paramsList']);
             Route::post('/paramsSave', [\app\admin\controller\sys_manage\ConfigController::class, 'paramsSave']);
 
+            Route::get('/partnerParams',[\app\admin\controller\sys_manage\ConfigController::class,'partnerParamsInfo']);
+            Route::post('/setPartnerParams',[\app\admin\controller\sys_manage\ConfigController::class,'setPartnerParams']);
+
         });
         /* 运费模板管理 */
         Route::group('/postageTemplate', function () {
@@ -685,6 +683,7 @@ Route::group('/admin', function () {
             Route::get('/selectMemberAllQuota', [\app\admin\controller\member\MemberController::class, 'selectMemberAllQuota']);
             Route::get('/selectMemberAllQuotaByAppointment', [\app\admin\controller\member\MemberController::class, 'selectMemberAllQuotaByAppointment']);
             Route::get('/welfareInfo', [\app\admin\controller\member\MemberController::class, 'welfareInfo']);
+            Route::post('/clearWelfare', [\app\admin\controller\member\MemberController::class, 'clearWelfare']);
             Route::get('/vipInfo', [\app\admin\controller\member\MemberController::class, 'vipInfo']);
             Route::get('/coupon', [\app\admin\controller\member\MemberController::class, 'coupon']);
             Route::get('/couponCount', [\app\admin\controller\member\MemberController::class, 'couponCount']);
@@ -696,6 +695,7 @@ Route::group('/admin', function () {
             Route::post('/add', [\app\admin\controller\member\MemberController::class, 'add']);
             Route::post('/update', [\app\admin\controller\member\MemberController::class, 'update']);
             Route::get('/exportMember', [\app\admin\controller\member\MemberController::class, 'exportMember']);
+            Route::get('/fansList', [\app\admin\controller\member\MemberController::class, 'fansList']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -879,6 +879,7 @@ Route::group('/admin', function () {
             Route::post('/customSend', [\app\admin\controller\coupon\CouponController::class, 'customSend']);
             Route::post('/update', [\app\admin\controller\coupon\CouponController::class, 'update']);
             Route::delete('/delete', [\app\admin\controller\coupon\CouponController::class, 'delete']);
+            Route::post('/disable', [\app\admin\controller\coupon\CouponController::class, 'disableCoupon']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -934,8 +935,10 @@ Route::group('/admin', function () {
             Route::post('/addDishes', [\app\admin\controller\order\WholeController::class, 'addDishes']);
             Route::post('/cutMeals', [\app\admin\controller\order\WholeController::class, 'cutMeals']);
             Route::post('/customPrinter', [\app\admin\controller\order\WholeController::class, 'customPrinter']);
+            Route::post('/printerWriterOff', [\app\admin\controller\order\WholeController::class, 'printerWriterOff']);
             Route::post('/cancelOrder', [\app\admin\controller\order\WholeController::class, 'cancelOrder']);
             Route::get('/getOrderPayStatus', [\app\admin\controller\order\WholeController::class, 'getOrderPayStatus']);
+            Route::get('/getProductOrderPayStatus', [\app\admin\controller\order\WholeController::class, 'getProductOrderPayStatus']);
             Route::get('/writeOffList', [\app\admin\controller\order\WholeController::class, 'writeOffList']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
@@ -961,6 +964,10 @@ Route::group('/admin', function () {
         // 产品订单
         Route::group('/goods', function () {
             Route::get('/list', [\app\admin\controller\order\GoodsController::class, 'select']);
+            Route::post('/add', [\app\admin\controller\order\GoodsController::class, 'insert']);
+            Route::post('/addConstitute', [\app\admin\controller\order\GoodsController::class, 'insertConstitute']);
+            Route::post('/pay', [\app\admin\controller\order\GoodsController::class, 'pay']);
+            Route::post('/payConstitute', [\app\admin\controller\order\GoodsController::class, 'payConstitute']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -975,9 +982,24 @@ Route::group('/admin', function () {
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
+        // 合伙人订单
+        Route::group('/partner', function () {
+            Route::get('/list', [\app\admin\controller\order\PartnerController::class, 'select']);
+            Route::post('/add', [\app\admin\controller\order\PartnerController::class, 'insert']);
+            Route::post('/pay', [\app\admin\controller\order\PartnerController::class, 'pay']);
+            Route::get('/sheet', [\app\admin\controller\order\PartnerController::class, 'sheet']);
+            Route::get('/getPaidOrder', [\app\admin\controller\order\PartnerController::class, 'getPaidOrder']);
+            Route::post('/uploadTicket', [\app\admin\controller\order\PartnerController::class, 'uploadTicket']);
+        })->middleware([
+            \app\middleware\AdminAuthCheck::class
+        ]);
         // 服务订单
         Route::group('/services', function () {
             Route::get('/list', [\app\admin\controller\order\ServicesController::class, 'select']);
+            Route::post('/add', [\app\admin\controller\order\ServicesController::class, 'insert']);
+            Route::post('/addConstitute', [\app\admin\controller\order\ServicesController::class, 'insertConstitute']);
+            Route::post('/pay', [\app\admin\controller\order\ServicesController::class, 'pay']);
+            Route::post('/payConstitute', [\app\admin\controller\order\ServicesController::class, 'payConstitute']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -985,6 +1007,10 @@ Route::group('/admin', function () {
         Route::group('/packages', function () {
             Route::get('/list', [\app\admin\controller\order\PackagesController::class, 'select']);
             Route::post('/writeOff', [\app\admin\controller\order\PackagesController::class, 'writeOff']);
+            Route::post('/add', [\app\admin\controller\order\PackagesController::class, 'insert']);
+            Route::post('/addConstitute', [\app\admin\controller\order\PackagesController::class, 'insertConstitute']);
+            Route::post('/pay', [\app\admin\controller\order\PackagesController::class, 'pay']);
+            Route::post('/payConstitute', [\app\admin\controller\order\PackagesController::class, 'payConstitute']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);