Преглед на файлове

Merge branch 'master' of http://git.derkj.com:9095/waibao/NN2025112501

# Conflicts:
#	app/Models/OrderModel.php
罗永浩 преди 3 месеца
родител
ревизия
399f377341
променени са 60 файла, в които са добавени 2471 реда и са изтрити 487 реда
  1. 2 1
      addons/admin/src/config/setting.js
  2. 1 4
      addons/admin/src/views/dashboard/workplace.vue
  3. 3 2
      app/Helpers/common.php
  4. 1 0
      app/Http/Controllers/Admin/IndexController.php
  5. 68 11
      app/Http/Controllers/Api/v1/AccountController.php
  6. 20 0
      app/Http/Controllers/Api/v1/AddressController.php
  7. 2 2
      app/Http/Controllers/Api/v1/CartController.php
  8. 24 12
      app/Http/Controllers/Api/v1/GoodsController.php
  9. 3 1
      app/Http/Controllers/Api/v1/IndexController.php
  10. 30 0
      app/Http/Controllers/Api/v1/MemberController.php
  11. 59 4
      app/Http/Controllers/Api/v1/NotifyController.php
  12. 120 26
      app/Http/Controllers/Api/v1/OrderController.php
  13. 27 1
      app/Http/Controllers/Api/v1/TestController.php
  14. 5 3
      app/Http/Validator/OrderValidator.php
  15. 43 0
      app/Models/GoodsCollectModel.php
  16. 24 0
      app/Models/MemberBankModel.php
  17. 16 0
      app/Models/OrderGoodsModel.php
  18. 2 10
      app/Models/OrderModel.php
  19. 201 6
      app/Services/Api/AccountService.php
  20. 1 0
      app/Services/Api/AgentService.php
  21. 30 38
      app/Services/Api/BalanceLogService.php
  22. 4 3
      app/Services/Api/CartService.php
  23. 98 3
      app/Services/Api/GoodsService.php
  24. 240 145
      app/Services/Api/MemberService.php
  25. 613 138
      app/Services/Api/OrderService.php
  26. 228 0
      app/Services/Api/SettleService.php
  27. 34 8
      app/Services/Api/StoreService.php
  28. 1 1
      app/Services/Common/AdService.php
  29. 1 0
      app/Services/Common/UserService.php
  30. 119 0
      app/Services/DyrPayService.php
  31. 86 0
      app/Services/Kd100Service.php
  32. 5 5
      app/Services/MpService.php
  33. 177 12
      app/Services/PaymentService.php
  34. 1 1
      config/database.php
  35. 24 5
      config/payment.php
  36. BIN
      public/uploads/images/base64/20251226/image_e27537109140362782f1dbc5beeb8b80.jpeg
  37. BIN
      public/uploads/temp/20210410081010.xlsx
  38. BIN
      public/uploads/temp/20251226/Mi5wbmc.png
  39. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMjU3MS5wbmc.png
  40. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzA0MS5wbmc.png
  41. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAwMS5wbmc.png
  42. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAwMi5wbmc.png
  43. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAwMy5wbmc.png
  44. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAwNC5wbmc.png
  45. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAxMS5wbmc.png
  46. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAxMi5wbmc.png
  47. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAxMy5wbmc.png
  48. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAxNi5wbmc.png
  49. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAyMi5wbmc.png
  50. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAyNC5wbmc.png
  51. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAyNS5wbmc.png
  52. BIN
      public/uploads/temp/20251226/MjAyNTEyMjYwMzAyNi5wbmc.png
  53. BIN
      public/uploads/temp/20251226/My5wbmc.png
  54. BIN
      public/uploads/temp/20251226/NC5wbmc.png
  55. BIN
      resources/certs/wechat/apiclient_cert.p12
  56. 17 17
      resources/certs/wechat/apiclient_cert.pem
  57. 26 26
      resources/certs/wechat/apiclient_key.pem
  58. 9 0
      resources/certs/wechat/pub_key.pem
  59. 17 2
      routes/api.php
  60. 89 0
      物流.txt

+ 2 - 1
addons/admin/src/config/setting.js

@@ -5,7 +5,8 @@ export default {
     version: '1.0',
     name: '后台管理系统',  // 项目名称
     loginName: '后台登录',  // 项目名称
-    baseURL: 'http://129.204.44.254:8001/',  // 本地接口地址
+    baseURL: 'http://127.0.5.26/',  // 本地接口地址
+    // baseURL: 'http://129.204.44.254:8001/',  // 本地接口地址
     signKey: 'dshApp&688', // 签名密钥
     whiteList: ['/login', '/forget'],  // 路由白名单(不需要登录的)
     keepAliveList: [],  // 需要缓存的组件名称

+ 1 - 4
addons/admin/src/views/dashboard/workplace.vue

@@ -167,14 +167,11 @@
           </div>
         </el-card>
       </el-col>
-    </el-row>
 
-    <!-- 商家、代理、提现统计 -->
-    <el-row :gutter="15">
       <el-col :md="6" :sm="6" :xs="12" v-if="!isStoreUser">
         <el-card shadow="hover" body-style="padding:0;">
           <div class="app-link-block" @click="$router.push('/store/store')">
-            <i class="app-link-icon el-icon-store" style="color: #67c23a;"></i>
+            <i class="app-link-icon el-icon-place" style="color: #67c23a;"></i>
             <div class="app-link-title countFont">{{ datas.stores.count || 0 }}</div>
             <div class="app-link-title">总商家数</div>
           </div>

+ 3 - 2
app/Helpers/common.php

@@ -759,7 +759,7 @@ if (!function_exists('get_order_num')) {
     function get_order_num($prefix = '')
     {
         $micro = substr(microtime(), 2, 2);
-        return $prefix . date("YmdHis") . $micro . rand(1000, 9999);
+        return $prefix . date("ymdHis") . $micro . rand(100, 999);
     }
 
 }
@@ -1835,7 +1835,7 @@ if (!function_exists('upload_image')) {
         }
 
         // 文件名称
-        $file_name = ($userId? $userId.'_'.str_replace('=','',base64_encode($userId.$original_name)): str_replace('=','',base64_encode($original_name)));
+        $file_name = ($userId? $userId.'_'.str_replace('=','',base64_encode(date('YmdHi').$userId.$original_name)): str_replace('=','',base64_encode(date('YmdHi').$original_name)));
         $file_name =  $file_name. '.' . $ext;
 
         // 重命名保存
@@ -2150,6 +2150,7 @@ if (!function_exists('httpRequest')) {
             if (!empty($cookie)) {
                 curl_setopt($ch, CURLOPT_COOKIE, $cookie);
             }
+
             if ($type == 'post') {
                 curl_setopt($ch, CURLOPT_POST, 1);
                 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

+ 1 - 0
app/Http/Controllers/Admin/IndexController.php

@@ -100,6 +100,7 @@ class IndexController extends Backend
         RedisService::keyDel("caches:index*");
         RedisService::keyDel("caches:good*");
         RedisService::keyDel("caches:advert*");
+        RedisService::keyDel("caches:accounts*");
         RedisService::keyDel("caches:count*");
         RedisService::keyDel("caches:account*");
         RedisService::keyDel("caches:article*");

+ 68 - 11
app/Http/Controllers/Api/v1/AccountController.php

@@ -20,13 +20,46 @@ class AccountController extends webApp
      */
     public function index()
     {
-        $params =request()->post();
+        $params = request()->post();
         $pageSize = request()->post('pageSize', 15);
-        $params['user_id'] = isset($params['user_id'])? $params['user_id'] : $this->userId;
+        $params['user_id'] = isset($params['user_id']) ? $params['user_id'] : $this->userId;
         $datas = AccountService::make()->getDataList($params, $pageSize);
-        if($datas){
+        if ($datas) {
             return message(1010, true, $datas);
-        }else{
+        } else {
+            return message(1009, false);
+        }
+    }
+
+    /**
+     * 充值套餐
+     * @return array
+     */
+    public function payMeal()
+    {
+        $params = request()->post();
+        $type = isset($params['type']) ? $params['type'] : 1;
+        $datas = AccountService::make()->getPayMealList($type);
+        if ($datas) {
+            return message(1010, true, $datas);
+        } else {
+            return message(1009, false);
+        }
+    }
+
+    /**
+     * 充值记录
+     * @return array
+     */
+    public function payLog()
+    {
+        $params = request()->post();
+        $pageSize = request()->post('pageSize', 15);
+        $params['user_id'] = isset($params['user_id']) ? $params['user_id'] : $this->userId;
+        $datas = AccountService::make()->getPayLog($params, $pageSize);
+        if ($datas) {
+            return message(1010, true, $datas);
+        } else {
             return message(1009, false);
         }
     }
@@ -37,24 +70,48 @@ class AccountController extends webApp
      */
     public function balance()
     {
-        $params =request()->post();
+        $params = request()->post();
         $pageSize = request()->post('pageSize', 15);
-        $params['user_id'] = isset($params['user_id'])? $params['user_id'] : $this->userId;
+        $params['user_id'] = isset($params['user_id']) ? $params['user_id'] : $this->userId;
         $datas = BalanceLogService::make()->getDataList($params, $pageSize);
         return message(1010, true, $datas);
     }
 
     /**
+     * 生活充值
+     * @return array
+     */
+    public function pay()
+    {
+        $params = request()->all();
+        try {
+            if (!$result = AccountService::make()->recharge($this->userId, $params)) {
+                return showJson(AccountService::make()->getError(), false);
+            } else {
+                return showJson(AccountService::make()->getError(), true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
+        }
+    }
+
+    /**
      * 收入提现
      * @return array
      */
     public function withdraw()
     {
-        $params = request()->all();
-        if (!$result = BalanceLogService::make()->withdraw($this->userId, $params)) {
-            return showJson(BalanceLogService::make()->getError(), false);
-        } else {
-            return showJson(BalanceLogService::make()->getError(), true, $result);
+        try {
+            $params = request()->all();
+            if (!$result = BalanceLogService::make()->withdraw($this->userId, $params)) {
+                return showJson(BalanceLogService::make()->getError(), false);
+            } else {
+                return showJson(BalanceLogService::make()->getError(), true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
         }
     }
 }

+ 20 - 0
app/Http/Controllers/Api/v1/AddressController.php

@@ -100,6 +100,26 @@ class AddressController extends webApp
     }
 
     /**
+     * 绑定的地址
+     * @return array
+     */
+    public function getBindInfo()
+    {
+        $params = request()->all();
+        $id = isset($params['id'])? $params['id'] :0;
+        try {
+            if(!$result = MemberAddressService::make()->getBindInfo($this->userId, $id)){
+                return showJson(1009, false);
+            }else{
+                return showJson(1010, true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
+        }
+    }
+
+    /**
      * 删除
      * @return array|mixed
      */

+ 2 - 2
app/Http/Controllers/Api/v1/CartController.php

@@ -103,9 +103,9 @@ class CartController extends webApp
         try {
 
             if ($result = CartService::make()->getCount($this->userId)) {
-                return message(CartService::make()->getError(), true, $result);
+                return message(1010, true, $result);
             } else {
-                return message(CartService::make()->getError(), false);
+                return message(1009, false);
             }
         } catch (\Exception $exception) {
             $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];

+ 24 - 12
app/Http/Controllers/Api/v1/GoodsController.php

@@ -47,21 +47,33 @@ class GoodsController extends webApp
         if(empty($id)){
             return message(1036, false);
         }
-
-        $userInfo = MemberService::make()->getInfo($this->userId,[], true);
-        $confirmStatus = isset($userInfo['confirm_status'])? $userInfo['confirm_status'] : 0;
-        $pickerStatus = isset($userInfo['picker_status'])? $userInfo['picker_status'] : 0;
-        if($confirmStatus != 1){
-            return message(2043, false,[],405);
-        }
-
-        if($pickerStatus!= 1){
-            return message(2063, false,[],406);
-        }
-        if($info = GoodsService::make()->getInfo($id)){
+        if($info = GoodsService::make()->getInfo($id, $this->userId)){
             return message(1010, true, $info);
         }else{
             return message(1009, false);
         }
     }
+
+    /**
+     * 收藏
+     */
+    public function collect()
+    {
+        $params = request()->all();
+        $id = isset($params['id']) ? intval($params['id']) : 0;
+        if (empty($id)) {
+            return message(1036, false);
+        }
+        try {
+
+            if ($result = GoodsService::make()->collect($this->userId, $id)) {
+                return message(GoodsService::make()->getError(), true, $result);
+            } else {
+                return message(GoodsService::make()->getError(), false);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
+        }
+    }
 }

+ 3 - 1
app/Http/Controllers/Api/v1/IndexController.php

@@ -33,7 +33,9 @@ class IndexController extends webApp
                     'app_version' => ConfigService::make()->getConfigByCode('app_version'),
                     'app_android_url' => ConfigService::make()->getConfigByCode('app_android_url'),
                     'alipay_open' => ConfigService::make()->getConfigByCode('alipay_open', 0),
-                    'agent_apply_desc' => ConfigService::make()->getConfigByCode('agent_apply_desc', ''),
+                    'agent_apply_desc' => format_content(ConfigService::make()->getConfigByCode('agent_apply_desc', '')),
+                    'withdraw_desc' => format_content(ConfigService::make()->getConfigByCode('withdraw_desc', '')),
+                    'recharge_desc' => format_content(ConfigService::make()->getConfigByCode('recharge_desc', '')),
                     'wxpay_open' => ConfigService::make()->getConfigByCode('wxpay_open', 0),
                     'withdraw_open' => ConfigService::make()->getConfigByCode('withdraw_open', 0),
                     'withdraw_min' => ConfigService::make()->getConfigByCode('withdraw_min', 0),

+ 30 - 0
app/Http/Controllers/Api/v1/MemberController.php

@@ -30,6 +30,36 @@ class MemberController extends webApp
     }
 
     /**
+     * 收款账号
+     * @return array
+     */
+    public function account()
+    {
+        $type = request()->post('type',0);
+        $info = MemberService::make()->accountInfo($this->userId,$type);
+        if ($info) {
+            return showJson(1010, true, $info);
+        } else {
+            return showJson(1004, false, [], '403');
+        }
+    }
+
+    /**
+     * 绑定收款账号
+     * @return array
+     */
+    public function bindAccount()
+    {
+        $params = request()->all();
+        $info = MemberService::make()->bindAccount($this->userId, $params);
+        if ($info) {
+            return showJson(MemberService::make()->getError(), true, $info);
+        } else {
+            return showJson(1004, false);
+        }
+    }
+
+    /**
      * 设置资料
      * @return array
      */

+ 59 - 4
app/Http/Controllers/Api/v1/NotifyController.php

@@ -3,6 +3,7 @@
 namespace App\Http\Controllers\Api\v1;
 
 use App\Http\Controllers\Api\webApp;
+use App\Services\DyrPayService;
 use App\Services\PaymentService;
 use App\Services\RedisService;
 
@@ -40,7 +41,7 @@ class NotifyController extends webApp
                 }
 
                 RedisService::set("caches:payments:notify_{$scene}:error_" . $key, ['all' => request()->all(), 'scene' => $scene, 'payType' => $payType, 'result' => $result], 7200);
-                return false;
+                return response('failed');
             }
 
             // 验签和重组参数
@@ -67,21 +68,75 @@ class NotifyController extends webApp
         }
     }
 
+    /**
+     * 支付回调
+     * @param int $productId 产品
+     * @return array|false|\Psr\Http\Message\ResponseInterface
+     */
+    public function payCallback($productId)
+    {
+        $date = date('Y-m-d H:i:s');
+        $result = isset($_POST)? $_POST : request()->post();
+        $key = date('YmdHis') . '_' . rand(1000, 9999);
+        $channel = 'dryPay';
+        if (empty($result)) {
+            $result = file_get_contents('php://input');
+            $result = $result ? json_decode($result, true) : [];
+        }
+
+        try {
+            $sign = isset($result['sign'])?$result['sign']:'';
+            unset($result['sign']);//删除掉sign字段
+            $checkSign = DyrPayService::make()->makeSign($result, 2);
+            RedisService::set("caches:payments:payNotify_{$productId}:result_".date('YmdHis').rand(10,99), ['all' => request()->all(), 'sign'=>$sign,'checkSign'=>$checkSign, 'product_id' => $productId, 'result' => $result], 7200);
+            if($sign != $checkSign){
+                if (env('APP_DEBUG')) {
+                    logger()->channel($channel)->error("【{$date} 支付回调】签名错误:" . json_encode([ 'product_id' => $productId,'data' => $result], 256));
+                }
+
+                RedisService::set("caches:payments:payNotify_{$productId}:sign_" . $key, ['all' => request()->all(),  'product_id' => $productId, 'result' => $result], 7200);
+                return response('failed');
+            }
+
+            // 验签和重组参数
+            $data = $result;
+            RedisService::set("caches:payments:notify_{$productId}:data_" . $key, ['all' => request()->all(),'product_id' => $productId, 'result' => $result], 7200);
+            if (env('APP_DEBUG')) {
+                logger()->channel($channel)->info("【{$date} 支付回调】验证结果:" . json_encode(['data' => $data,'product_id' => $productId],256));
+            }
+
+            // 回调处理
+            if (PaymentService::make()->catchPayNotify($productId, $data)) {
+                RedisService::set("caches:payments:notify_{$productId}:success_" . $key, ['all' => request()->all(), 'product_id' => $productId, 'result' => $result], 7200);
+                logger()->channel('alipay')->info("【{$date} 支付回调】回调成功:" . json_encode(['data' => $data,'product_id' => $productId],256));
+                return response('success');
+            } else {
+                $msg = PaymentService::make()->getError();
+                logger()->channel($channel)->info("【{$date} 支付回调】回调失败:" . json_encode(['data' => $data,'product_id' => $productId, 'error' => lang($msg)], 256));
+                return message($msg ? $msg : 2635, false);
+            }
+        } catch (\Exception $exception) {
+            RedisService::set("caches:payments:notify_{$productId}:error_" . $key, ['all' => request()->all(), 'product_id' => $productId, 'error' => $exception->getMessage(), 'data' => $result], 7200);
+            logger()->channel($channel)->error("【{$date} 支付回调】回调错误:" . json_encode(['data' => $result,'product_id' => $productId, 'error' => $exception->getMessage()], 256));
+            return message(2635, false, ['error' => $exception->getMessage()]);
+        }
+    }
+
 
     /**
      * 退款回调
-     * @param string $scene 场景,deposit-保证金,depositRefund-保证金退款,withdraw-收入提现
+     * @param string $scene 场景,refund-退款
      * @param int $payType 支付方式:10-微信,20-支付宝
      * @return array|false
      * @throws \Yansongda\Pay\Exception\ContainerException
      * @throws \Yansongda\Pay\Exception\InvalidParamsException
      */
-    public function depositRefund($payType = 10)
+    public function refund($payType = 10)
     {
         $scene = 'depositRefund';
         $date = date('Y-m-d H:i:s');
         $result = request()->post();
-        $pay = PaymentService::make()->createPay('depositRefund', $payType);
+        $pay = PaymentService::make()->createPay('refund', $payType);
         $channel = $payType == 10? 'wechat':'alipay';
         if (empty($pay) || empty($scene) || empty($payType)) {
             if (env('APP_DEBUG')) {

+ 120 - 26
app/Http/Controllers/Api/v1/OrderController.php

@@ -6,6 +6,7 @@ use App\Http\Controllers\Api\webApp;
 use App\Http\Validator\OrderValidator;
 use App\Services\Api\MemberService;
 use App\Services\Api\OrderService;
+use App\Services\Kd100Service;
 
 /**
  * 订单
@@ -20,18 +21,7 @@ class OrderController extends webApp
      */
     public function index()
     {
-        $userInfo = MemberService::make()->getInfo($this->userId);
-        $confirmStatus = isset($userInfo['confirm_status'])? $userInfo['confirm_status'] : 0;
-        $pickerStatus = isset($userInfo['picker_status'])? $userInfo['picker_status'] : 0;
-        if($confirmStatus != 1){
-            return message(2043, false,[],405);
-        }
-
-        if($pickerStatus!= 1){
-            return message(2063, false,[],406);
-        }
-
-        $params =request()->post();
+        $params = request()->post();
         $pageSize = request()->post('pageSize', 15);
         $params['user_id'] = $this->userId;
         $datas = OrderService::make()->getDataList($params, $pageSize);
@@ -45,9 +35,8 @@ class OrderController extends webApp
      */
     public function check()
     {
-        if($data = OrderService::make()->checkOrderStatus($this->userId))
-        {
-            return showJson(1010, true,$data);
+        if ($data = OrderService::make()->checkOrderStatus($this->userId)) {
+            return showJson(1010, true, $data);
         } else {
             return showJson(1009, false);
         }
@@ -59,7 +48,7 @@ class OrderController extends webApp
      */
     public function count()
     {
-        $status =  request()->post('status', 1);
+        $status = request()->post('status', 1);
         $data = OrderService::make()->getCountByStatus($this->userId, $status);
         return showJson(1010, true, $data);
     }
@@ -78,12 +67,12 @@ class OrderController extends webApp
             return showJson($params, false);
         }
 
-        $id = isset($params['order_id'])? intval($params['order_id']) : 0;
-        if($id<=0){
-            return showJson(1036,false);
+        $id = isset($params['id']) ? intval($params['id']) : 0;
+        if ($id <= 0) {
+            return showJson(1036, false);
         }
-        $data = OrderService::make()->getOrderInfo($id, $this->userId);
-        if(empty($data)){
+        $data = OrderService::make()->getOrderInfo($id);
+        if (empty($data)) {
             return showJson(1009, false);
         }
         return showJson(1010, true, $data);
@@ -102,12 +91,117 @@ class OrderController extends webApp
             return showJson($params, false);
         }
 
-        if (!$result = OrderService::make()->createOrder($this->userId, $params)) {
-            $error = OrderService::make()->getError();
-            return showJson($error, false,'',$error==2206?'405':-1);
-        } else {
-            return showJson(OrderService::make()->getError(), true, $result);
+        try {
+            if (!$result = OrderService::make()->createOrder($this->userId, $params)) {
+                $error = OrderService::make()->getError();
+                return showJson($error, false, '', $error == 2206 ? '405' : -1);
+            } else {
+                return showJson(OrderService::make()->getError(), true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
+        }
+    }
+
+    /**
+     * 支付
+     * @return array
+     */
+    public function pay()
+    {
+        $params = request()->all();
+        $id = isset($params['id'])? $params['id'] : 0;
+        try {
+            if (!$result = OrderService::make()->pay($this->userId, $id)) {
+                $error = OrderService::make()->getError();
+                return showJson($error, false, '', $error == 2206 ? '405' : -1);
+            } else {
+                return showJson(OrderService::make()->getError(), true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
+        }
+    }
+
+    /**
+     * 取消
+     * @return array
+     */
+    public function cancel()
+    {
+        $params = request()->all();
+        $id = isset($params['id'])? $params['id'] : 0;
+        try {
+            if (!$result = OrderService::make()->cancel($this->userId, $id)) {
+                $error = OrderService::make()->getError();
+                return showJson($error, false, '', $error == 2206 ? '405' : -1);
+            } else {
+                return showJson(1002, true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
         }
     }
 
+    /**
+     * 收货
+     * @return array
+     */
+    public function complete()
+    {
+        $params = request()->all();
+        $id = isset($params['id'])? $params['id'] : 0;
+        try {
+            if (!$result = OrderService::make()->complete($this->userId, $id)) {
+                $error = OrderService::make()->getError();
+                return showJson($error, false, '', $error == 2206 ? '405' : -1);
+            } else {
+                return showJson(OrderService::make()->getError(), true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
+        }
+    }
+
+
+    /**
+     * 售后/退款
+     * @return array
+     */
+    public function after()
+    {
+        $params = request()->all();
+        try {
+            if (!$result = OrderService::make()->after($this->userId, $params)) {
+                $error = OrderService::make()->getError();
+                return showJson($error, false, '', $error == 2206 ? '405' : -1);
+            } else {
+                return showJson(OrderService::make()->getError(), true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
+        }
+    }
+
+    public function logistics()
+    {
+        $params = request()->all();
+        $id = isset($params['id'])? $params['id'] : 0;
+        try {
+            if (!$result = OrderService::make()->getDelivery($id)) {
+                $error = OrderService::make()->getError();
+                return showJson($error, false, '', $error == 2206 ? '405' : -1);
+            } else {
+                return showJson(1010, true, $result);
+            }
+        } catch (\Exception $exception) {
+            $error = ['data' => $exception->getTrace(), 'err' => $exception->getMessage()];
+            return showJson(1046, false, $error);
+        }
+    }
 }

+ 27 - 1
app/Http/Controllers/Api/v1/TestController.php

@@ -3,8 +3,12 @@
 namespace App\Http\Controllers\Api\v1;
 
 use App\Http\Controllers\Api\webApp;
+use App\Services\Api\MemberService;
 use App\Services\Api\MessageService;
+use App\Services\DyrPayService;
+use App\Services\Kd100Service;
 use App\Services\MapService;
+use App\Services\MpService;
 use App\Services\RedisService;
 
 /**
@@ -18,6 +22,28 @@ class TestController extends webApp
 
     public function check()
     {
-
+//        $result = Kd100Service::make()->query('YT8824762286422','17877188025','yuantong');
+        $productId = '1105';
+        $amount = 50;
+        $orderNo = get_order_num('PR');
+$result = DyrPayService::make()->recharge($orderNo, '17877188025', $productId, $amount);
+        dump(DyrPayService::make()->getError());
+        dump($result);
+        //array:3 [▼
+        //  "errno" => 0
+        //  "errmsg" => "提交成功"
+        //  "data" => array:9 [▼
+        //    "id" => 505535
+        //    "order_number" => "QWE251227505535"
+        //    "mobile" => "17877188025"
+        //    "product_id" => 1105
+        //    "total_price" => "47.00"
+        //    "create_time" => 1766804483
+        //    "guishu" => "广西南宁"
+        //    "title" => "苹果快充三网50话费快充"
+        //    "out_trade_num" => "PR25122711012274882"
+        //  ]
+        //]
+        return showJson('操作成功', true, $result);
     }
 }

+ 5 - 3
app/Http/Validator/OrderValidator.php

@@ -5,7 +5,8 @@ class OrderValidator extends BaseValidator
     // 当前模型所有验证规则
     public static $rules = [
         'id' => 'required',
-        'goods_id' => 'required',
+        'goods' => 'required',
+        'address_id' => 'required',
         'remark' => 'required|max:10',
     ];
 
@@ -23,7 +24,8 @@ class OrderValidator extends BaseValidator
     // 当前模型所有验证字段
     public static $fields = [
         'id' => '订单ID',
-        'goods_id' => '接单信息',
+        'address_id' => '收货地址',
+        'goods' => '商品参数',
         'remark' => '备注说明',
     ];
 
@@ -33,7 +35,7 @@ class OrderValidator extends BaseValidator
         'cancel'=> ['id','remark'],
         'confirm'=> ['id'],
         'complete'=> ['id'],
-        'submit'=> ['goods_id'],
+        'submit'=> ['address_id','goods'],
     ];
 
     /**

+ 43 - 0
app/Models/GoodsCollectModel.php

@@ -0,0 +1,43 @@
+<?php
+// +----------------------------------------------------------------------
+// | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
+// +----------------------------------------------------------------------
+// | 版权所有 2017~2021 LARAVEL研发中心
+// +----------------------------------------------------------------------
+// | 官方网站: http://www.laravel.cn
+// +----------------------------------------------------------------------
+// | Author: laravel开发员 <laravel.qq.com>
+// +----------------------------------------------------------------------
+
+namespace App\Models;
+
+/**
+ * 商品收藏管理-模型
+ * @author laravel开发员
+ * @since 2020/11/11
+ * @package App\Models
+ */
+class GoodsCollectModel extends BaseModel
+{
+    // 设置数据表
+    protected $table = 'goods_collects';
+
+    /**
+     * 用户
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    public function member()
+    {
+        return $this->hasOne(MemberModel::class, 'id', 'user_id')
+            ->select(['id', 'realname', 'nickname', 'mobile', 'status']);
+    }
+
+    /**
+     * 商品
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    public function goods()
+    {
+        return $this->hasOne(GoodsModel::class, 'id', 'goods_id');
+    }
+}

+ 24 - 0
app/Models/MemberBankModel.php

@@ -0,0 +1,24 @@
+<?php
+// +----------------------------------------------------------------------
+// | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
+// +----------------------------------------------------------------------
+// | 版权所有 2017~2021 LARAVEL研发中心
+// +----------------------------------------------------------------------
+// | 官方网站: http://www.laravel.cn
+// +----------------------------------------------------------------------
+// | Author: laravel开发员 <laravel.qq.com>
+// +----------------------------------------------------------------------
+
+namespace App\Models;
+
+/**
+ * 收款账户-模型
+ * @author laravel开发员
+ * @since 2020/11/11
+ * @package App\Models
+ */
+class MemberBankModel extends BaseModel
+{
+    // 设置数据表
+    protected $table = 'member_banks';
+}

+ 16 - 0
app/Models/OrderGoodsModel.php

@@ -9,5 +9,21 @@ class OrderGoodsModel extends BaseModel
 {
     // 设置数据表
     protected $table = 'orders_goods';
+
+    // 封面图
+    public function getThumbAttribute($value)
+    {
+        $thumb = $value ? get_image_url($value) : get_image_url('/images/goods/goods.jpeg');
+        return $thumb;
+    }
+
+    /**
+     * 关联商品分类
+     */
+    public function category()
+    {
+        return $this->hasOne(GoodsCategoryModel::class, 'id', 'category_id')
+            ->select(['id', 'name', 'icon', 'status']);
+    }
 }
 

+ 2 - 10
app/Models/OrderModel.php

@@ -42,6 +42,7 @@ class OrderModel extends BaseModel
     public function orderGoods()
     {
         return $this->hasMany(OrderGoodsModel::class, 'order_no', 'order_no')
+            ->with(['category'])
             ->where('mark', 1);
     }
 
@@ -52,7 +53,7 @@ class OrderModel extends BaseModel
     public function store()
     {
         return $this->hasOne(StoreModel::class, 'id', 'store_id')
-            ->select(['id', 'name']);
+            ->select(['id', 'name', 'logo']);
     }
 
     /**
@@ -77,13 +78,4 @@ class OrderModel extends BaseModel
             ->where(['mark' => 1])
             ->select(['id', 'order_no', 'goods_id', 'confirm_at', 'status']);
     }
-
-    /**
-     * 订单商品
-     * @return \Illuminate\Database\Eloquent\Relations\HasOne
-     */
-    public function goods()
-    {
-        return $this->hasOne(GoodsModel::class, 'id', 'goods_id')->with(['shipperCity', 'shipperDistrict', 'receiverCity', 'receiverDistrict']);
-    }
 }

+ 201 - 6
app/Services/Api/AccountService.php

@@ -12,8 +12,14 @@
 namespace App\Services\Api;
 
 use App\Models\AccountLogModel;
+use App\Models\MemberModel;
+use App\Models\PayMealsModel;
+use App\Models\PayOrdersModel;
 use App\Services\BaseService;
+use App\Services\PaymentService;
 use App\Services\RedisService;
+use Illuminate\Support\Facades\DB;
+use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\F;
 
 /**
  * 交易管理-服务类
@@ -65,16 +71,61 @@ class AccountService extends BaseService
             $accountTypes = config('payment.accountTypes');
             foreach($list['data'] as &$item){
                 $item['create_time'] = $item['create_time']? datetime($item['create_time'],'Y-m-d H:i:s') : '';
-                $item['time_text'] = $item['create_time']? datetime($item['create_time'],'Y年m月d日') : '';
+                $item['time_text'] = $item['create_time']? dateFormat($item['create_time'],'Y年m月d日') : '';
                 $type = isset($item['type'])? intval($item['type']) : 0;
                 $item['type_text'] = isset($item['remark'])? trim($item['remark']) : '';
                 if(empty($item['type_text'])){
                     $item['type_text'] = isset($accountTypes[$type])? $accountTypes[$type] : '收支明细';
                 }
+
                 $item['change_type'] = 1;
-                if(in_array($type,[3,4])){
+                if(in_array($type,[1,2,4])){
                     $item['change_type'] = 2;
                 }
+
+            }
+        }
+
+        return [
+            'pageSize'=> $pageSize,
+            'total'=>isset($list['total'])? $list['total'] : 0,
+            'list'=> isset($list['data'])? $list['data'] : []
+        ];
+    }
+
+    /**
+     * 充值记录
+     * @param $params
+     * @param int $pageSize
+     * @return array
+     */
+    public function getPayLog($params, $pageSize = 15)
+    {
+        $userId = isset($params['user_id'])?$params['user_id'] : 0;
+        $list = PayOrdersModel::from('pay_orders as a')
+            ->where(function($query){
+                $query->where('a.status','>',1)->orWhere(function($query){
+                    $query->where('a.status',1)->orWhere('a.create_time','>=', time() - 300);
+                });
+            })
+            ->where(['user_id'=> $userId,'mark'=>1])
+            ->select(['a.*'])
+            ->orderBy('a.create_time','desc')
+            ->orderBy('a.id','desc')
+            ->paginate($pageSize > 0 ? $pageSize : 9999999);
+        $list = $list? $list->toArray() :[];
+        if($list){
+            $types = [1=>'话费充值',2=>'电费充值',3=>'燃气充值'];
+            $statusArr = [1=>'未支付',2=>'已支付',3=>'充值中',4=>'充值成功',5=>'充值失败资金原路退回',6=>'充值成功部分其他原路退回'];
+            foreach($list['data'] as &$item){
+                $item['time_text'] = $item['create_time']? datetime($item['create_time'],'Y/m/d H:i:s') : '';
+                $type = isset($item['type'])? intval($item['type']) : 0;
+                $status = isset($item['status'])? intval($item['status']) : 0;
+                $item['type_text'] = isset($types[$type])? $types[$type] : '充值';
+                $item['status_text'] = isset($statusArr[$status])? $statusArr[$status] : '充值中';
+                if($status != 4 && $item['failed_remark']){
+                    $item['status_text'] = $item['failed_remark'];
+                }
             }
         }
 
@@ -88,11 +139,7 @@ class AccountService extends BaseService
     public function getQuery($params)
     {
         $where = ['a.mark' => 1];
-        $status = isset($params['status'])? $params['status'] : 0;
         $type = isset($params['type'])? $params['type'] : 0;
-        if($status>0){
-            $where['a.status'] = $status;
-        }
         if($type>0){
             $where['a.type'] = $type;
         }
@@ -107,6 +154,13 @@ class AccountService extends BaseService
                     $query->where('a.user_id',$userId);
                 }
 
+                $status = isset($params['status'])? $params['status'] : 0;
+                if($status){
+                    $query->where('a.status',$status);
+                }else{
+                    $query->whereNotIn('a.status',[2]);
+                }
+
                 if ($keyword) {
                     $query->where(function($query) use($keyword){
                         $query->where('b.nickname','like',"%{$keyword}%")
@@ -161,4 +215,145 @@ class AccountService extends BaseService
 
         return $data;
     }
+
+    /**
+     * 充值套餐
+     * @param $type
+     * @return array|mixed
+     */
+    public function getPayMealList($type)
+    {
+        $cacheKey = "caches:accounts:mealList_{$type}";
+        $datas = RedisService::get($cacheKey);
+        if($datas){
+            return $datas;
+        }
+
+        $datas = PayMealsModel::where(['type'=>$type,'status'=>1,'mark'=>1])
+            ->orderBy('sort','desc')
+            ->orderBy('id','asc')
+            ->get();
+        $datas = $datas? $datas->toArray() :[];
+        if($datas){
+            RedisService::set($cacheKey, $datas, rand(300,600));
+        }
+
+        return $datas;
+    }
+
+    /**
+     * 生活充值
+     * @param $userId 用户ID
+     * @param $params
+     * @return array|false
+     */
+    public function recharge($userId, $params)
+    {
+        $mealId = isset($params['id']) ? $params['id'] : 0; // 套餐ID
+        $account = isset($params['account']) ? $params['account'] : ''; // 充值账号/手机号
+        $cacheKey = "caches:members:pay:{$userId}_{$mealId}";
+        if (RedisService::get($cacheKey . '_lock')) {
+            $this->error = '请不要频繁提交~';
+            return false;
+        }
+
+        if(empty($account)){
+            $this->error = '请输入充值账号';
+            return false;
+        }
+
+        RedisService::set($cacheKey, ['date' => date('Y-m-d H:i:s')], rand(2, 3));
+        $mealInfo = PayMealsModel::where(['id' => $mealId, 'status' => 1, 'mark' => 1])
+            ->select(['id','product_id', 'money', 'type', 'discount', 'remark', 'status'])
+            ->first();
+        $money = isset($mealInfo['money']) ? floatval($mealInfo['money']) : 0;
+        $discount = isset($mealInfo['discount']) ? intval($mealInfo['discount']) : 0;
+        $mealType = isset($mealInfo['type']) && $mealInfo['type'] ? intval($mealInfo['type']) : 1;
+        $productId= isset($mealInfo['product_id']) ? $mealInfo['product_id'] : 0;
+        $remark= isset($mealInfo['remark']) ? $mealInfo['remark'] : '';
+        $price = $discount?moneyFormat($money*$discount/100,2): $money;
+        if (empty($mealInfo)) {
+            $this->error = '该套餐不存在';
+            RedisService::clear($cacheKey . '_lock');
+            return false;
+        }
+
+        if ($price <= 0 || $money <= 0 || $productId<=0) {
+            $this->error = '该套餐参数错误';
+            RedisService::clear($cacheKey . '_lock');
+            return false;
+        }
+
+        $info = MemberModel::where(['id' => $userId, 'mark' => 1])
+            ->select(['id', 'openid', 'mobile', 'status'])
+            ->first();
+        $openid = isset($info['openid']) ? $info['openid'] : '';
+        if (!$info || $info['status'] != 1) {
+            $this->error = 1045;
+            RedisService::clear($cacheKey . '_lock');
+            return false;
+        }
+
+        if (empty($openid)) {
+            $this->error = '用户参数错误,请重新授权登录后尝试~';
+            RedisService::clear($cacheKey . '_lock');
+            return false;
+        }
+
+        // 创建订单
+        $orderNo = get_order_num('PR');
+        $types = ['','话费充值','电费充值','燃气充值'];
+        $remark = isset($types[$mealType])? $types[$mealType] : '生活充值';
+        $order = [
+            'order_no' => $orderNo,
+            'user_id' => $userId,
+            'meal_id' => $mealId,
+            'product_id' => $productId,
+            'total' => $price,
+            'type' => $mealType,
+            'account' => $account,
+            'discount' => $discount,
+            'create_time' => time(),
+            'remark' => $remark,
+            'status' => 1,
+            'mark' => 1
+        ];
+
+        DB::beginTransaction();
+        if (!$orderId = PayOrdersModel::insertGetId($order)) {
+            $this->error = '创建充值订单失败';
+            return false;
+        }
+
+        /* TODO 支付处理 */
+        $payOrder = [
+            'type' => 1,
+            'order_no' => $orderNo,
+            'pay_money' => $price,
+            'body' => $remark,
+            'openid' => $openid
+        ];
+
+        // 调起支付
+        $payment = PaymentService::make()->minPay($info, $payOrder, 'pay');
+        if (empty($payment)) {
+            DB::rollBack();
+            RedisService::clear($cacheKey . '_lock');
+            $this->error = PaymentService::make()->getError();
+            return false;
+        }
+
+        // 用户操作记录
+        DB::commit();
+        $this->error = '创建充值订单成功,请前往支付~';
+        // 删除超时订单
+        PayOrdersModel::where(['status'=>1])->where('create_time','<=', time() - 6 * 3600)->delete();
+        RedisService::clear($cacheKey . '_lock');
+        return [
+            'order_id' => $orderId,
+            'payment' => $payment,
+            'total' => $payOrder['pay_money'],
+            'pay_type' => 10,
+        ];
+    }
 }

+ 1 - 0
app/Services/Api/AgentService.php

@@ -145,6 +145,7 @@ class AgentService extends BaseService
         $info = $this->model->with(['user'])->where($where)->first();
         $info = $info? $info->toArray() : [];
         if($info){
+
             RedisService::set($cacheKey, $info, rand(5, 10));
         }
 

+ 30 - 38
app/Services/Api/BalanceLogService.php

@@ -13,6 +13,7 @@ namespace App\Services\Api;
 
 use App\Models\AccountLogModel;
 use App\Models\ActionLogModel;
+use App\Models\AgentModel;
 use App\Models\BalanceLogModel;
 use App\Models\MemberModel;
 use App\Services\BaseService;
@@ -150,8 +151,9 @@ class BalanceLogService extends BaseService
     public function withdraw($userId, $params)
     {
         // 参数验证
+        $accountType = isset($params['account_type']) && $params['account_type']? intval($params['account_type']) : 2;
         $money = isset($params['money'])? floatval($params['money']) : 0;
-        $remark = isset($params['remark'])? trim($params['remark']) : '';
+        $accountRemark = isset($params['account_remark'])? trim($params['account_remark']) : '';
         $account = isset($params['account'])? trim($params['account']) : '';
         $realname = isset($params['realname'])? trim($params['realname']) : '';
         if($money<=0){
@@ -175,7 +177,6 @@ class BalanceLogService extends BaseService
             return false;
         }
 
-
         // 锁
         $cacheLockKey = "caches:members:withdraw:{$userId}";
         if(RedisService::get($cacheLockKey)){
@@ -186,48 +187,58 @@ class BalanceLogService extends BaseService
         // 判断用户账号状态
         RedisService::set($cacheLockKey, ['user_id'=>$userId,'params'=>$params], rand(10,20));
         $userInfo = MemberService::make()->getInfo($userId,[], true);
-        $confirmStatus = isset($userInfo['confirm_status'])? $userInfo['confirm_status'] : 0;
         $status = isset($userInfo['status'])? $userInfo['status'] : 0;
         $balance = isset($userInfo['balance'])? $userInfo['balance'] : 0;
+        $agent = isset($userInfo['agent'])? $userInfo['agent'] : [];
+        $agentBalance = isset($agent['balance'])? $agent['balance'] : 0;
         $nickname = isset($userInfo['nickname'])? $userInfo['nickname'] : '';
+        $balance = $accountType==2?$agentBalance:$balance;
         if(empty($userInfo) || $status != 1){
-            $this->error = 2016;
+            $this->error = 1045;
             RedisService::clear($cacheLockKey);
             return false;
         }
 
-        // 账号审核情况
-        if($confirmStatus != 1){
-            $this->error = 2042;
+        if($accountType==2 && empty($agent)){
+            $this->error = '代理账号或已被冻结,请联系客服';
             RedisService::clear($cacheLockKey);
             return false;
         }
 
-        if($money> $balance){
-            $this->error = 2303;
+        if($money > $balance){
+            $this->error = '可提现金额不足';
             RedisService::clear($cacheLockKey);
             return false;
         }
 
+
         // 提现处理
         DB::beginTransaction();
         $updateData = ['balance'=>DB::raw("balance - {$money}"),'update_time'=>time()];
-        if(!MemberModel::where(['id'=> $userId])->update($updateData)){
+        // 会员账户
+        if($accountType==1 && !MemberModel::where(['id'=> $userId])->update($updateData)){
+            DB::rollBack();
+            $this->error = '提现处理失败';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+        // 代理账户
+        else if($accountType==2 && !AgentModel::where(['user_id'=> $userId])->update($updateData)){
             DB::rollBack();
-            $this->error = 2306;
+            $this->error = '提现处理失败';
             RedisService::clear($cacheLockKey);
             return false;
         }
 
-        $orderNo = get_order_num('JW');
+        $orderNo = get_order_num('LW');
         $order = [
             'user_id'=> $userId,
             'order_no'=> $orderNo,
             'money'=> $money,
-            'before_money'=> $balance,
             'type'=>2,
+            'account_type'=> $accountType,
             'pay_type'=>0,
-            'remark'=> $remark,
+            'account_remark'=> $accountRemark,
             'realname'=> $realname,
             'account'=> $account,
             'create_time'=> time(),
@@ -236,7 +247,7 @@ class BalanceLogService extends BaseService
         ];
         if(!$orderId = $this->model::insertGetId($order)){
             DB::rollBack();
-            $this->error = 2307;
+            $this->error = '提现处理失败';
             RedisService::clear($cacheLockKey);
             return false;
         }
@@ -245,7 +256,7 @@ class BalanceLogService extends BaseService
             'user_id' => $userId,
             'source_order_no' => $orderNo,
             'type' => 4,
-            'money' => $money,
+            'money' => -$money,
             'before_money' => $balance,
             'date'=> date('Y-m-d'),
             'create_time' => time(),
@@ -255,37 +266,18 @@ class BalanceLogService extends BaseService
         ];
         if(!AccountLogModel::insertGetId($log)){
             DB::rollBack();
-            $this->error = 2307;
+            $this->error = '提现处理失败';
             RedisService::clear($cacheLockKey);
             return false;
         }
 
         DB::commit();
 
-        $title = "用户[{$nickname}]申请了提现";
-        $message = [
-            'from_uid'=> $userId,
-            'to_uid'=> 1,
-            'op'=> 'notice',
-            'scene'=> 'withdraw',
-            'message'=> '提现消息',
-            'type'=> 6,
-            'order'=>[
-                'title'=> $title.'<span class="ele-text-primary">查看订单</span>',
-                'order_no'=> $orderNo,
-                'money'=> $money,
-                'date'=> date('Y-m-d H:i:s'),
-                'user_id'=> $userId,
-                'type'=> 'withdraw',
-                'remark'=> '提现消息',
-            ]
-        ];
-
         // 操作日志
         ActionLogModel::setRecord($userId,['type'=>2,'title'=>'收入提现','content'=>"姓名:{$realname},账号:{$account},提现{$money}元,单号:{$orderNo}",'module'=>'balanceLog']);
         ActionLogModel::record();
 
-        $this->error = 2308;
-        return ['id'=>$orderId,'message'=>$message,'money'=>$money];
+        $this->error = '提现申请成功,请耐心等候审核~';
+        return ['id'=>$orderId,'money'=>$money];
     }
 }

+ 4 - 3
app/Services/Api/CartService.php

@@ -12,10 +12,10 @@
 namespace App\Services\Api;
 
 use App\Models\CartModel;
-use App\Models\GoodsCategoryModel;
 use App\Models\GoodsModel;
 use App\Services\BaseService;
 use App\Services\RedisService;
+use Illuminate\Support\Facades\DB;
 
 /**
  * 购物车管理-服务类
@@ -163,11 +163,11 @@ class CartService extends BaseService
         }
 
         // 去除其他店铺购物车
-        $this->model->where(['user_id' => $userId, 'mark' => 1])->whereNotIn('store_id', $storeId)->update(['mark' => 0, 'update_time' => time()]);
+        $this->model->where(['user_id' => $userId, 'mark' => 1])->whereNotIn('store_id', [$storeId])->update(['mark' => 0, 'update_time' => time()]);
 
         // 添加购物型
         if ($id = $this->model->where(['user_id' => $userId, 'goods_id' => $goodsId])->value('id')) {
-            $this->model->where(['id' => $id])->update(['store_id' => $storeId,'num'=> $num, 'sku_id' => $skuType == 1 ? 0 : $skuId, 'status' => 1, 'mark' => 1, 'create_time' => time()]);
+            $this->model->where(['id' => $id])->update(['store_id' => $storeId,'num'=> DB::raw("num+{$num}"), 'sku_id' => $skuType == 1 ? 0 : $skuId, 'status' => 1, 'mark' => 1, 'create_time' => time()]);
         } else {
             $data = [
                 'user_id' => $userId,
@@ -182,6 +182,7 @@ class CartService extends BaseService
             $id = $this->model->insertGetId($data);
         }
 
+        $this->error = '添加成功';
         RedisService::clear($cacheKey.'_lock');
         RedisService::clear("caches:goods:cartCount:{$userId}");
         return ['id' => $id, 'count' => $this->getCount($userId)];

+ 98 - 3
app/Services/Api/GoodsService.php

@@ -12,7 +12,9 @@
 namespace App\Services\Api;
 
 use App\Models\GoodsCategoryModel;
+use App\Models\GoodsCollectModel;
 use App\Models\GoodsModel;
+use App\Models\GoodsSkuModel;
 use App\Services\BaseService;
 use App\Services\RedisService;
 
@@ -156,20 +158,113 @@ class GoodsService extends BaseService
      * @param $id
      * @return mixed
      */
-    public function getInfo($id)
+    public function getInfo($id,$userId=0)
     {
-        $cacheKey = "caches:goods:info_{$id}";
+        $cacheKey = "caches:goods:info_{$id}_{$userId}";
         $info = RedisService::get($cacheKey);
         if ($info) {
             return $info;
         }
 
-        $info = $this->model->with(['store','category'])->where(['id' => $id])->first();
+        $info = $this->model->with(['store','category','skus'])->where(['id' => $id])->first();
         $info = $info ? $info->toArray() : [];
         if ($info) {
+            $checkId = GoodsCollectModel::where(['user_id'=>$userId,'goods_id'=>$id])->value('id');
+            $info['is_collect'] = $checkId? 1 : 0;
             RedisService::set($cacheKey, $info, rand(10, 20));
         }
         return $info;
     }
 
+    /**
+     * 收藏
+     * @param $userId
+     * @param $goodsId
+     * @return array|false
+     */
+    public function collect($userId, $goodsId)
+    {
+        $info = $this->model->where(['id' => $goodsId,'status'=>1,'mark'=>1])->first();
+        $info = $info ? $info->toArray() : [];
+        if(empty($info)){
+            $this->error = '商品已下架';
+            return false;
+        }
+
+
+        if($id = GoodsCollectModel::where(['user_id'=>$userId,'goods_id'=>$goodsId,'mark'=>1])->value('id')){
+            GoodsCollectModel::where(['id'=>$id])->update(['mark'=>0,'update_time'=>time()]);
+            $this->error = '取消收藏';
+            RedisService::clear("caches:goods:info_{$id}_{$userId}");
+            return ['id'=>$id,'is_collect'=>0];
+        }else{
+            if(!$id = GoodsCollectModel::insertGetId(['user_id'=>$userId,'goods_id'=>$goodsId,'status'=>1,'mark'=>1,'create_time'=>time(),'update_time'=>time()])){
+                $this->error = '收藏失败';
+                return false;
+            }
+
+            $this->error = '收藏成功';
+            RedisService::clear("caches:goods:info_{$id}_{$userId}");
+            return ['id'=>$id,'is_collect'=>1];
+        }
+    }
+
+    /**
+     * @param $ids
+     * @param $goods
+     * @param $orderNo
+     * @return array|false
+     */
+    public function getOrderGoods($ids, $goods, $orderNo, $userId=0)
+    {
+        $list = $this->model->whereIn('id', $ids)
+            ->where(['status'=>1,'mark'=>1])
+            ->select(['id as goods_id','goods_name','category_id','store_id','price','stock','unit','weight','thumb','sku_type'])
+            ->get();
+        $list = $list? $list->toArray() : [];
+        if($list){
+            $skus = GoodsSkuModel::whereIn('goods_id', $ids)->select(['id','price','stock'])->get()->keyBy('id');
+            $skus = $skus?$skus->toArray() :[];
+            $result = ['store_id'=>0,'total'=>0,'count'=>0,'goods'=>[]];
+//            var_dump($skus);
+//            var_dump($list);
+//            var_dump($goods);
+            foreach ($list as $item){
+                $item['order_no'] = $orderNo;
+                $id = isset($item['goods_id'])?$item['goods_id']:0;
+                $params = isset($goods['id_'.$id])? $goods['id_'.$id]:[];
+                $goodsId = isset($params['id'])?$params['id']:0;
+                $storeId = isset($item['store_id'])?$item['store_id']:0;
+                $num = isset($params['num'])?$params['num']:0;
+                $skuId = isset($params['sku_id'])?$params['sku_id']:0;
+                $skuType = isset($item['sku_type'])?$item['sku_type']: 1;
+                $skuData = isset($skus[$skuId])? $skus[$skuId]:[];
+                $skuPrice = isset($skuData['price'])?$skuData['price']:0;
+                $price = $skuType==2 ? $skuPrice : $item['price'];
+                unset($item['skus']);
+                if($result['store_id'] && $storeId != $result['store_id']){
+                    $this->error = '一次只能购买同一个商家的商品,请核对后重试~';
+                    return false;
+                }
+                if($num>0 && $goodsId == $id && $price>0){
+                    $result['store_id'] = $storeId;
+                    $item['user_id'] = $userId;
+                    $item['sku_id'] = $skuId;
+                    $item['price'] = $price;
+                    $item['total'] = $price;
+                    $item['num'] = $num;
+                    $total = round($price * $num,2);
+                    $item['total'] = $total;
+                    $item['thumb'] = get_image_path($item['thumb']);
+                    $result['goods'][] = $item;
+                    $result['total'] += $total;
+                    $result['count']++;
+                }
+            }
+
+            return $result;
+        }
+
+        return false;
+    }
 }

+ 240 - 145
app/Services/Api/MemberService.php

@@ -14,6 +14,7 @@ namespace App\Services\Api;
 use App\Helpers\Jwt;
 use App\Models\ActionLogModel;
 use App\Models\BalanceLogModel;
+use App\Models\MemberBankModel;
 use App\Models\MemberModel;
 use App\Models\OrderModel;
 use App\Services\BaseService;
@@ -102,23 +103,23 @@ class MemberService extends BaseService
         }
 
         // 更新
-        if(!RedisService::get("caches:members:login_{$userId}")){
-            $system = isset($params['system'])? $params['system'] : [];
-            $system = $system && !is_array($system)? json_decode($system,true) : $system;
-            $appSources = isset($system['app_sources']) && $system['app_sources']? $system['app_sources'] : 'ios';
-            $uuid = isset($system['uuid'])? $system['uuid'] : '';
-            $version = isset($system['app_version'])? $system['app_version'] : '';
+        if (!RedisService::get("caches:members:login_{$userId}")) {
+            $system = isset($params['system']) ? $params['system'] : [];
+            $system = $system && !is_array($system) ? json_decode($system, true) : $system;
+            $appSources = isset($system['app_sources']) && $system['app_sources'] ? $system['app_sources'] : 'ios';
+            $uuid = isset($system['uuid']) ? $system['uuid'] : '';
+            $version = isset($system['app_version']) ? $system['app_version'] : '';
             $updateData = [
-                'update_time'=> time(),
-                'login_ip'=> get_client_ip(),
-                'login_time'=> time(),
-                'device_code'=> $uuid,
-                'login_count'=> DB::raw("login_count+1"),
-                'app_version'=> $version,
-                'device'=> $appSources=='ios'? 1 : 2,
+                'update_time' => time(),
+                'login_ip' => get_client_ip(),
+                'login_time' => time(),
+                'device_code' => $uuid,
+                'login_count' => DB::raw("login_count+1"),
+                'app_version' => $version,
+                'device' => $appSources == 'ios' ? 1 : 2,
             ];
-            $this->model->where(['id'=> $userId])->update($updateData);
-            RedisService::set("caches:members:login_{$userId}",$updateData, rand(300,600));
+            $this->model->where(['id' => $userId])->update($updateData);
+            RedisService::set("caches:members:login_{$userId}", $updateData, rand(300, 600));
         }
 
 
@@ -129,7 +130,7 @@ class MemberService extends BaseService
         // 结果返回
         $result = [
             'access_token' => $token,
-            'info' => ['uid' => $userId,'nickname' => $data['nickname']],
+            'info' => ['uid' => $userId, 'nickname' => $data['nickname']],
         ];
 
         // 用户缓存信息
@@ -168,7 +169,7 @@ class MemberService extends BaseService
             $this->error = MpService::make()->getError();
             return false;
         }
-        
+
         $userInfo = MpService::make()->getUserInfo($code);
         $openid = isset($userInfo['openid']) ? $userInfo['openid'] : '';
         if (empty($userInfo)) {
@@ -184,7 +185,7 @@ class MemberService extends BaseService
         // 验证是否注册,没有则注册
         $where = ['mobile' => $phone];
         $data = $this->model->where($where)
-            ->select(['id', 'openid', 'mobile', 'user_type', 'nickname','avatar', 'code', 'status','mark'])
+            ->select(['id', 'openid', 'mobile', 'user_type', 'nickname', 'avatar', 'code', 'status', 'mark'])
             ->first();
         $data = $data ? $data->toArray() : [];
         $userId = isset($data['id']) ? $data['id'] : 0;
@@ -192,7 +193,7 @@ class MemberService extends BaseService
         $nickName = isset($data['nickname']) ? $data['nickname'] : '';
         $status = isset($data['status']) ? $data['status'] : 0;
         $mark = isset($data['mark']) ? $data['mark'] : 0;
-        if ($data && $userId && $status != 1 && $mark==1) {
+        if ($data && $userId && $status != 1 && $mark == 1) {
             $this->error = 2011;
             return false;
         }
@@ -207,15 +208,15 @@ class MemberService extends BaseService
             $userId = $this->model->max('id') + 1;
 
             // 推荐人
-            $rid = isset($params['rid'])? intval($params['rid']) : 0;
+            $rid = isset($params['rid']) ? intval($params['rid']) : 0;
             $parents = '';
-            if($rid){
-                $inviteInfo = $this->model->where(['id'=> $rid,'mark'=>1])
-                    ->select(['id','parent_id','parents','status'])
+            if ($rid) {
+                $inviteInfo = $this->model->where(['id' => $rid, 'mark' => 1])
+                    ->select(['id', 'parent_id', 'parents', 'status'])
                     ->first();
-                $parents = isset($inviteInfo['parents'])? $inviteInfo['parents'] : '';
-                if($inviteInfo){
-                    $parents = $parents? $parents.$rid.',' : ",{$rid},";
+                $parents = isset($inviteInfo['parents']) ? $inviteInfo['parents'] : '';
+                if ($inviteInfo) {
+                    $parents = $parents ? $parents . $rid . ',' : ",{$rid},";
                 }
             }
 
@@ -242,7 +243,7 @@ class MemberService extends BaseService
                 return false;
             }
         } // 更新登录信息
-        else if ($mark==0 || !RedisService::get("caches:members:login_{$userId}")) {
+        else if ($mark == 0 || !RedisService::get("caches:members:login_{$userId}")) {
             $updateData = [
                 'login_ip' => get_client_ip(),
                 'create_time' => time(),
@@ -257,7 +258,7 @@ class MemberService extends BaseService
                 $updateData['openid'] = $openid;
             }
 
-            if($mark==0){
+            if ($mark == 0) {
                 $data['mobile'] = $phone;
                 $data['openid'] = $openid;
                 $avatar = '';
@@ -274,7 +275,7 @@ class MemberService extends BaseService
         // 结果返回
         $result = [
             'access_token' => $token,
-            'info' => ['uid' => $userId, 'openid' => $openid, 'has_info' => $avatar && $nickName?1 :0, 'nickname' => $data['nickname']],
+            'info' => ['uid' => $userId, 'openid' => $openid, 'has_info' => $avatar && $nickName ? 1 : 0, 'nickname' => $data['nickname']],
         ];
 
         // 用户缓存信息
@@ -314,13 +315,13 @@ class MemberService extends BaseService
             return false;
         }
 
-        if(!$this->model->where(['id'=>$userId])->update(['password'=> get_password($password),'update_time'=>time()])){
+        if (!$this->model->where(['id' => $userId])->update(['password' => get_password($password), 'update_time' => time()])) {
             $this->error = 2030;
             return false;
         }
 
         // 操作日志
-        ActionLogModel::setRecord($userId,['type'=>2,'title'=>'重置密码','content'=>'重置登录密码','module'=>'member']);
+        ActionLogModel::setRecord($userId, ['type' => 2, 'title' => '重置密码', 'content' => '重置登录密码', 'module' => 'member']);
         ActionLogModel::record();
 
         $this->error = 2031;
@@ -344,52 +345,52 @@ class MemberService extends BaseService
         }
 
         // 验证码验证
-        $smsCode = isset($params['sms_code'])? trim($params['sms_code']) : '';
+        $smsCode = isset($params['sms_code']) ? trim($params['sms_code']) : '';
         if (!SmsService::make()->check($mobile, $smsCode, 'register')) {
             $this->error = SmsService::make()->getError();
             return false;
         }
 
         // 验证是否注册
-        if($this->model->where(['mobile' => $mobile, 'mark' => 1])->value('id')){
+        if ($this->model->where(['mobile' => $mobile, 'mark' => 1])->value('id')) {
             $this->error = 2002;
             return false;
         }
 
         // 驾驶证
-        $drivingLicense = isset($params['driving_license']) && $params['driving_license']? get_image_path($params['driving_license']) : '';
+        $drivingLicense = isset($params['driving_license']) && $params['driving_license'] ? get_image_path($params['driving_license']) : '';
         if (empty($drivingLicense)) {
-            $this-> error = 2007;
+            $this->error = 2007;
             return false;
         }
 
         // 行驶证
-        $driversLicense = isset($params['drivers_license']) && $params['drivers_license']? get_image_path($params['drivers_license'])  : '';
+        $driversLicense = isset($params['drivers_license']) && $params['drivers_license'] ? get_image_path($params['drivers_license']) : '';
         if (empty($driversLicense)) {
-            $this-> error = 2008;
+            $this->error = 2008;
             return false;
         }
 
         $id = $this->model->max('id') + 1;
-        $system = isset($params['system'])? $params['system'] : [];
-        $system = $system && !is_array($system)? json_decode($system,true) : $system;
+        $system = isset($params['system']) ? $params['system'] : [];
+        $system = $system && !is_array($system) ? json_decode($system, true) : $system;
         $appSources = isset($system['app_sources']) ? $system['app_sources'] : '';
         $uuid = isset($system['uuid']) ? $system['uuid'] : '';
         $data = [
-            'mobile'=> $mobile,
-            'user_type'=> 2,
-            'avatar'=> '',
-            'nickname'=> $nickname ? $nickname : 'DU'.rand(10,99).substr($mobile,-6,6),
-            'realname'=> isset($params['realname'])? trim($params['realname']) : '',
-            'password'=> get_password($password),
-            'car_number'=> isset($params['car_number'])? trim($params['car_number']) : '',
-            'car_type'=> isset($params['car_type'])? trim($params['car_type']) : '',
-            'driving_license'=> $drivingLicense,
-            'drivers_license'=> $driversLicense,
-            'code'=> strtoupper(get_random_code(9, 'D', "{$id}")),
+            'mobile' => $mobile,
+            'user_type' => 2,
+            'avatar' => '',
+            'nickname' => $nickname ? $nickname : 'DU' . rand(10, 99) . substr($mobile, -6, 6),
+            'realname' => isset($params['realname']) ? trim($params['realname']) : '',
+            'password' => get_password($password),
+            'car_number' => isset($params['car_number']) ? trim($params['car_number']) : '',
+            'car_type' => isset($params['car_type']) ? trim($params['car_type']) : '',
+            'driving_license' => $drivingLicense,
+            'drivers_license' => $driversLicense,
+            'code' => strtoupper(get_random_code(9, 'D', "{$id}")),
             'app_uuid' => $uuid,
             'device' => $appSources == 'android' ? 2 : 1,
-            'create_time'=> time(),
+            'create_time' => time(),
             'status' => 1,
             'picker_status' => 1,
             'confirm_remark' => '',
@@ -400,8 +401,8 @@ class MemberService extends BaseService
             'login_ip' => get_client_ip(),
         ];
 
-        if(!$userId = $this->model->insertGetId($data)){
-            $this-> error = 2003;
+        if (!$userId = $this->model->insertGetId($data)) {
+            $this->error = 2003;
             return false;
         }
 
@@ -412,7 +413,7 @@ class MemberService extends BaseService
         // 结果返回
         $result = [
             'access_token' => $token,
-            'info' => ['uid' => $userId,'nickname' => $data['nickname']],
+            'info' => ['uid' => $userId, 'nickname' => $data['nickname']],
         ];
 
         // 注册成功
@@ -452,8 +453,8 @@ class MemberService extends BaseService
 
         // 获取头像
         $avatar = '';
-        if(isset($params['avatar']) && $params['avatar']){
-           $avatar = save_base64_image($params['avatar'],'avatar');
+        if (isset($params['avatar']) && $params['avatar']) {
+            $avatar = save_base64_image($params['avatar'], 'avatar');
         }
 
         //
@@ -482,93 +483,29 @@ class MemberService extends BaseService
 
 
     /**
-     * 注册资料重新提交
-     * @param $userId
-     * @param $params
-     * @return bool
-     */
-    public function profileModify($userId, $params)
-    {
-        $cacheLockKey = "caches:members:profile_modify_{$userId}";
-        if(RedisService::get($cacheLockKey)){
-            $this->error = 1034;
-            return false;
-        }
-
-        // 用户验证
-        RedisService::set($cacheLockKey, ['user_id'=> $userId,'params'=>$params], rand(2,3));
-        $info = $this->model->where(['id' => $userId, 'mark' => 1])
-            ->select(['id', 'password','confirm_status', 'status'])
-            ->first();
-        $confirmStatus = isset($info['confirm_status']) ? $info['confirm_status'] : 0;
-        if (!$info || $info['status'] != 1) {
-            $this->error = 2016;
-            RedisService::clear($cacheLockKey);
-            return false;
-        }
-
-        if($confirmStatus == 1){
-            $this->error = 2041;
-            RedisService::clear($cacheLockKey);
-            return false;
-        }
-
-        // 验证码验证(不传不验证)
-        $mobile = isset($params['mobile'])? trim($params['mobile']) : '';
-        $smsCode = isset($params['sms_code'])? trim($params['sms_code']) : '';
-        if (isset($params['sms_code']) && !SmsService::make()->check($mobile, $smsCode, 'profile')) {
-            $this->error = SmsService::make()->getError();
-            return false;
-        }
-
-        //
-        $data = ['confirm_status'=>2,'confirm_remark'=>'','create_time'=>time(),'update_time' => time()];
-
-        // 修改数据(不传不修改)
-        if (isset($params['mobile']) && $mobile) {
-            $data['mobile'] = $mobile;
-        }
-
-        $realname = isset($params['realname']) ? trim($params['realname']) : '';
-        if (isset($params['realname']) && $realname) {
-            $data['realname'] = $realname;
-        }
-
-        if (!$this->model->where(['id' => $userId])->update($data)) {
-            $this->error = 2010;
-            RedisService::clear($cacheLockKey);
-            return false;
-        }
-
-        $this->error = 2011;
-        RedisService::clear($cacheLockKey);
-        return true;
-    }
-
-    /**
      * 获取资料详情
      * @param $where
      * @param array $field
      */
-    public function getInfo($where, array $field = [], $refresh=true)
+    public function getInfo($where, array $field = [], $refresh = true)
     {
-        if(empty($where)){
+        if (empty($where)) {
             return false;
         }
 
-        $fieldKey = $field? '_'.md5(json_encode($field)) : '';
-        $cacheKey = "caches:members:info_".(!is_array($where)? $where.$fieldKey: md5(json_encode($where).$fieldKey));
+        $fieldKey = $field ? '_' . md5(json_encode($field)) : '';
+        $cacheKey = "caches:members:info_" . (!is_array($where) ? $where . $fieldKey : md5(json_encode($where) . $fieldKey));
         $info = RedisService::get($cacheKey);
-        if($info && !$refresh){
+        if ($info && !$refresh) {
             return $info;
         }
 
-        $defaultField = ['id', 'user_type', 'realname', 'mobile', 'nickname','balance', 'code', 'openid', 'status', 'avatar'];
+        $defaultField = ['id', 'user_type', 'realname', 'mobile', 'nickname', 'balance', 'code', 'openid', 'status', 'avatar'];
         $field = $field ? $field : $defaultField;
         if (is_array($where)) {
-            $info = $this->model->with(['store','agent'])->where(['mark' => 1])->where($where)->select($field)->first();
+            $info = $this->model->with(['store', 'agent'])->where(['mark' => 1])->where($where)->select($field)->first();
         } else {
-            $info = $this->model->with(['store','agent'])->where(['mark' => 1])->where(['id' => (int)$where])->select($field)->first();
+            $info = $this->model->with(['store', 'agent'])->where(['mark' => 1])->where(['id' => (int)$where])->select($field)->first();
         }
 
         $info = $info ? $info->toArray() : [];
@@ -581,12 +518,28 @@ class MemberService extends BaseService
                 $info['mobile_text'] = $info['mobile'] ? format_mobile($info['mobile']) : '';
             }
 
-            if(isset($info['create_time'])){
+            if (isset($info['create_time'])) {
                 $info['create_at'] = datetime(strtotime($info['create_time']));
             }
 
-            $info['store'] = isset($info['store'])? $info['store'] : [];
-            $info['agent'] = isset($info['agent'])? $info['agent'] : [];
+            $info['store'] = isset($info['store']) ? $info['store'] : [];
+            $info['agent'] = isset($info['agent']) ? $info['agent'] : [];
+
+            $info['agent_level'] = 0;
+            $info['team_count'] = 0;
+            $params = request()->all();
+            $type = isset($params['type'])?$params['type']:'';
+            if ($type == 'agent' && $info['agent']) {
+                $info['agent_level'] = $this->getAgentLevel($info['id']);
+                $info['agent_level'] = $info['agent_level']>=2?2 : 1;
+                $info['team_count'] = $this->getTeamCount($info['id']);
+            }
+
+            if($type == 'agent'){
+                $info['qrcode'] = MpService::make()->getMiniQrcode('pages/login/login',"rid={$info['id']}");
+                $info['qrcode'] = $info['qrcode']? get_image_url($info['qrcode']):'';
+            }
+
             RedisService::set($cacheKey, $info, rand(30, 60));
         }
 
@@ -594,6 +547,151 @@ class MemberService extends BaseService
     }
 
     /**
+     * 收款账户
+     * @param $userId
+     * @return array|mixed
+     */
+    public function accountInfo($userId,$type=0)
+    {
+        $cacheKey = "caches:members:account:{$userId}_{$type}";
+        $datas = RedisService::get($cacheKey);
+        if ($datas) {
+            return $type?(isset($datas[$type-1])?$datas[$type-1]:[]):$datas;
+        }
+
+        $datas[0] = MemberBankModel::where(['type'=>1,'user_id'=>$userId,'status'=>1,'mark'=>1])
+            ->select(['id','user_id','type','realname','account','account_remark','status'])
+            ->first();
+        $datas[0] = $datas[0]? $datas[0] : ['id'=>0,'type'=>1];
+        $datas[1] = MemberBankModel::where(['type'=>2,'user_id'=>$userId,'status'=>1,'mark'=>1])
+            ->select(['id','user_id','type','realname','account','account_remark','status'])
+            ->first();
+        $datas[1] = $datas[1]? $datas[1] : ['id'=>0,'type'=>2];
+        if($datas){
+            RedisService::set($cacheKey, $datas, rand(5,10));
+        }else{
+            $datas = [['id'=>0,'type'=>1],['id'=>0,'type'=>2]];
+        }
+
+        return $type?(isset($datas[$type-1])?$datas[$type-1]:[]):$datas;
+    }
+
+    /**
+     * 绑定收款账户
+     * @param $userId
+     * @return array|mixed
+     */
+    public function bindAccount($userId, $params)
+    {
+        if($params['type']==1){
+            $alipay = MemberBankModel::where(['type'=>1,'user_id'=>$userId,'mark'=>1])
+                ->select(['id','user_id','type','realname','account','account_remark','status'])
+                ->first();
+            $alipayId = isset($alipay['id'])?$alipay['id'] : 0;
+            $data = [
+                'type'=> 1,
+                'user_id'=> $userId,
+                'realname'=>$params['realname'],
+                'account'=>$params['account'],
+                'account_remark'=>isset($params['account_remark']) && $params['account_remark']?$params['account_remark']:'支付宝',
+                'status'=>1
+            ];
+            if($alipayId){
+                $data['update_time']=time();
+                MemberBankModel::where(['id'=>$alipayId])->update($data);
+            }else {
+                $data['create_time']=time();
+                MemberBankModel::insertGetId($data);
+            }
+
+        } else if($params['type']==2){
+            $banks = MemberBankModel::where(['type'=>2,'user_id'=>$userId,'mark'=>1])
+                ->select(['id','user_id','type','realname','account','account_remark','status'])
+                ->first();
+            $bankId = isset($banks['id'])?$banks['id'] : 0;
+            $data = [
+                'type'=>2,
+                'user_id'=> $userId,
+                'realname'=>$params['realname'],
+                'account'=>$params['account'],
+                'account_remark'=>$params['account_remark'],
+                'status'=>1
+            ];
+            if($bankId){
+                $data['update_time']=time();
+                MemberBankModel::where(['id'=>$bankId])->update($data);
+            }else {
+                $data['create_time']=time();
+                MemberBankModel::insertGetId($data);
+            }
+        }else{
+            $this->error = '账号类型错误';
+            return false;
+        }
+
+        RedisService::keyDel("caches:members:account:{$userId}*");
+        $this->error = '绑定收款账号成功';
+        return true;
+    }
+    /**
+     * 获取代理等级
+     * @param $uid
+     * @return array|int|mixed
+     */
+    public function getAgentLevel($uid)
+    {
+        $cacheKey = "caches:members:agentLevel:{$uid}";
+        $data = RedisService::get($cacheKey);
+        if ($data) {
+            return $data;
+        }
+
+        $data = $this->model->from('member as a')
+            ->leftJoin('agents as b', function ($join) {
+                $join->on('b.user_id', '=', 'a.id')->where(['b.status' => 1, 'b.mark' => 1]);
+            })
+            ->where('b.id', '>', 0)
+            ->where('a.parents', 'like', "%,{$uid},%")
+            ->where(['a.status' => 1, 'a.mark' => 1])
+            ->select(['a.id', 'a.parents'])
+            ->orderBy('a.parents', 'desc')
+            ->first();
+        $data = $data ? $data->toArray() : [];
+        $parents = isset($data['parents']) && $data['parents'] ? trim($data['parents'], ',') : '';
+        $parents = $parents ? explode(',', $parents) : [];
+        $level = $parents ? count($parents) : 0;
+        if($level){
+            RedisService::set($cacheKey, $level, rand(5,10));
+        }
+
+        return $level;
+    }
+
+    /**
+     * 团队人数
+     * @param $uid
+     * @return array|int|mixed
+     */
+    public function getTeamCount($uid)
+    {
+        $cacheKey = "caches:members:teamCount:{$uid}";
+        $data = RedisService::get($cacheKey);
+        if ($data) {
+            return $data;
+        }
+
+        $data = $this->model->from('member as a')
+            ->where('a.parents', 'like', "%,{$uid},%")
+            ->where(['a.status' => 1, 'a.mark' => 1])
+            ->count('id');
+        if($data){
+            RedisService::set($cacheKey, $data, rand(5,10));
+        }
+
+        return $data;
+    }
+
+    /**
      * 生成普通参数二维码
      * @param $str 参数
      * @param bool $refresh 是否重新生成
@@ -650,13 +748,13 @@ class MemberService extends BaseService
     public function modify($userId, $params)
     {
         $cacheLockKey = "caches:members:modify_{$userId}";
-        if(RedisService::get($cacheLockKey)){
+        if (RedisService::get($cacheLockKey)) {
             $this->error = 1034;
             return false;
         }
 
         // 用户验证
-        RedisService::set($cacheLockKey, ['user_id'=> $userId,'params'=>$params], rand(2,3));
+        RedisService::set($cacheLockKey, ['user_id' => $userId, 'params' => $params], rand(2, 3));
         $info = $this->model->where(['id' => $userId, 'mark' => 1])
             ->select(['id', 'password', 'status'])
             ->first();
@@ -694,7 +792,7 @@ class MemberService extends BaseService
                 return false;
             }
 
-            if(empty($newPassword)){
+            if (empty($newPassword)) {
                 $this->error = 1039;
                 RedisService::clear($cacheLockKey);
                 return false;
@@ -734,43 +832,40 @@ class MemberService extends BaseService
         $info = $this->model->where(['id' => $userId, 'mark' => 1])
             ->select(['id', 'password', 'status'])
             ->first();
-        $status = isset($info['status'])? $info['status'] : 0;
-        if(empty($info)){
+        $status = isset($info['status']) ? $info['status'] : 0;
+        if (empty($info)) {
             $this->error = 2044;
             return false;
         }
 
-        if($status != 1){
+        if ($status != 1) {
             $this->error = 2044;
             return false;
         }
 
-        if(OrderModel::whereIn('status',[1,2])->where(['user_id'=>$userId,'mark'=>1])->value('id'))
-        {
+        if (OrderModel::whereIn('status', [1, 2])->where(['user_id' => $userId, 'mark' => 1])->value('id')) {
             $this->error = 2045;
             return false;
         }
 
-        if(DepositModel::where('refund_status',1)->where(['user_id'=>$userId,'mark'=>1])->value('id'))
-        {
+        if (DepositModel::where('refund_status', 1)->where(['user_id' => $userId, 'mark' => 1])->value('id')) {
             $this->error = 2046;
             return false;
         }
 
-        if(BalanceLogModel::where('status',1)->where(['user_id'=>$userId,'type'=>2,'mark'=>1])->value('id'))
-        {
+        if (BalanceLogModel::where('status', 1)->where(['user_id' => $userId, 'type' => 2, 'mark' => 1])->value('id')) {
             $this->error = 2047;
             return false;
         }
 
-        if(!$this->model->where(['id'=> $userId])->update(['status'=>3,'update_time'=>time()])){
+        if (!$this->model->where(['id' => $userId])->update(['status' => 3, 'update_time' => time()])) {
             $this->error = 2049;
             return false;
         }
 
 
         $this->error = 2048;
-        RedisService::clear("auths:info:".$userId);
+        RedisService::clear("auths:info:" . $userId);
         return true;
     }
 

+ 613 - 138
app/Services/Api/OrderService.php

@@ -13,9 +13,13 @@ namespace App\Services\Api;
 
 use App\Models\GoodsModel;
 use App\Models\MemberModel;
+use App\Models\OrderGoodsModel;
 use App\Models\OrderModel;
+use App\Models\StoreModel;
 use App\Services\BaseService;
 use App\Services\ConfigService;
+use App\Services\Kd100Service;
+use App\Services\PaymentService;
 use App\Services\RedisService;
 use Illuminate\Support\Facades\DB;
 
@@ -65,30 +69,37 @@ class OrderService extends BaseService
         $list = $model->where(function ($query) use ($params) {
             $status = isset($params['status']) ? $params['status'] : 0;
             // 进行中
-            if ($status > 0 && is_array($status)) {
-                $query->whereIn('a.status', $status);
-            }else if($status>0){
-                $query->where('a.status', $status);
+            if ($status == 9) {
+                $query->where('a.refund_status', '>', 0);
+            } elseif ($status > 0 && is_array($status)) {
+                $query->whereIn('a.status', $status)->where('a.refund_status', 0);
+            } else if ($status == 4) {
+                $query->where('a.status', $status)->where('a.refund_status', 0);
+            } else if ($status > 0) {
+                $query->where('a.status', $status)->where('a.refund_status', 0);
             }
         })->select(['a.*'])
-            ->orderBy('a.status', 'desc')
+            ->orderBy('a.status', 'asc')
             ->orderBy('a.create_time', 'desc')
             ->orderBy('a.id', 'desc')
             ->paginate($pageSize > 0 ? $pageSize : 9999999);
         $list = $list ? $list->toArray() : [];
         if ($list) {
-            $statusArr = [1 => '接单中', 2 => '进行中', 3 => '已完成'];
+            $statusArr = [1 => '待支付', 2 => '待发货', 3 => '待收货', 4 => '确认收货'];
+            $refundStatusArr = [1 => '已退款', 2 => '退款中', 3 => '退款审核', 4 => '退款驳回'];
             foreach ($list['data'] as &$item) {
-                $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y-m-d H:i:s') : '';
+                $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y/m/d H:i') : '';
                 $status = isset($item['status']) ? $item['status'] : 0;
-                $item['status_text'] = '接单中';
+                $item['status_text'] = '待支付';
                 if ($status) {
                     $item['status_text'] = isset($statusArr[$status]) ? $statusArr[$status] : '';
                 }
 
+                if ($item['refund_status'] > 0) {
+                    $item['status_text'] = '退款/售后';
+                }
+
                 $item['goods'] = isset($item['goods']) && $item['goods'] ? $item['goods'] : [];
-                $item['goods']['shipper_phone_text'] = $item['goods']['shipper_phone']?format_mobile($item['goods']['shipper_phone']) : '';
-                $item['goods']['receiver_phone_text'] = $item['goods']['receiver_phone']?format_mobile($item['goods']['receiver_phone']) : '';
             }
             unset($item);
         }
@@ -108,12 +119,12 @@ class OrderService extends BaseService
     public function getQuery($params)
     {
         $where = ['a.mark' => 1];
-        return $this->model->from('orders as a')->with(['goods'])
+        return $this->model->from('orders as a')->with(['orderGoods', 'store'])
             ->leftJoin('member as b', 'b.id', '=', 'a.user_id')
             ->where($where)
-            ->where(function($query) use($params){
+            ->where(function ($query) use ($params) {
                 $userId = isset($params['user_id']) ? intval($params['user_id']) : 0;
-                if($userId>0){
+                if ($userId > 0) {
                     $query->where('a.user_id', $userId);
                 }
             })
@@ -121,7 +132,6 @@ class OrderService extends BaseService
                 $keyword = isset($params['keyword']) ? $params['keyword'] : '';
                 if ($keyword) {
                     $query->where('a.order_no', 'like', "%{$keyword}%")
-                        ->orWhere('b.nickname', 'like', "%{$keyword}%")
                         ->orWhere('b.mobile', 'like', "%{$keyword}%");
                 }
             });
@@ -133,8 +143,8 @@ class OrderService extends BaseService
      */
     public function getOrderInfo($id)
     {
-        $statusArr = [1 => '待审核', 2 => '进行中', 3 => '已完成'];
-        $info = $this->model->from('orders as a')->with(['goods'])
+        $statusArr = [1 => '待支付', 2 => '待发货', 3 => '待收货', 4 => '已完成'];
+        $info = $this->model->from('orders as a')->with(['orderGoods','store'])
             ->leftJoin('member as b', 'b.id', '=', 'a.user_id')
             ->where(['a.id' => $id, 'a.mark' => 1])
             ->select(['a.*'])
@@ -148,10 +158,6 @@ class OrderService extends BaseService
             if ($status) {
                 $info['status_text'] = isset($statusArr[$status]) ? $statusArr[$status] : '';
             }
-
-            $info['goods'] = isset($info['goods']) && $info['goods'] ? $info['goods'] : [];
-            $info['goods']['shipper_phone_text'] = $info['goods']['shipper_phone']?format_mobile($info['goods']['shipper_phone']) : '';
-            $info['goods']['receiver_phone_text'] = $info['goods']['receiver_phone']?format_mobile($info['goods']['receiver_phone']) : '';
         }
 
         return $info;
@@ -165,105 +171,115 @@ class OrderService extends BaseService
      */
     public function createOrder($userId, $params)
     {
-        $goodsId = isset($params['goods_id']) && $params['goods_id'] ? intval($params['goods_id']) : 0;
+        $addressId = isset($params['address_id']) && $params['address_id'] ? $params['address_id'] : 0;
+        $goods = isset($params['goods']) && $params['goods'] ? $params['goods'] : [];
+        $ids = $goods ? array_column($goods, 'id') : [];
         // 参数验证
-        if (empty($goodsId)) {
-            $this->error = 2103;
+        if (empty($goods) || empty($ids)) {
+            $this->error = '商品参数不为空';
+            return false;
+        }
+
+        if ($addressId <= 0) {
+            $this->error = '请选择收货地址';
             return false;
         }
 
         // 缓存锁
-        $cacheLockKey = "caches:orders:submit_lock:{$userId}_{$goodsId}";
+        $cacheLockKey = "caches:orders:submit_lock:{$userId}";
         if (RedisService::get($cacheLockKey)) {
-            $this->error = 2107;
+            $this->error = '订单处理中~';
             return false;
         }
 
-        // 货物信息
-        RedisService::set($cacheLockKey, ['params' => $params, 'user_id' => $userId], rand(2, 3));
-        $goodsInfo = GoodsModel::where(['id' => $goodsId,'status'=>1, 'mark' => 1])
-            ->select(['id','num', 'price','picker_status', 'status'])
-            ->first();
-        $pickerStatus = isset($goodsInfo['picker_status']) ? $goodsInfo['picker_status'] : 0;
-        $price = isset($goodsInfo['price']) ? floatval($goodsInfo['price']) : 0;
-        $num = isset($goodsInfo['num']) ? intval($goodsInfo['num']) : 0;
-        if(empty($goodsInfo)){
-            $this->error = 2201;
+        // 商品数据
+        $orderNo = get_order_num('GX');
+        RedisService::set($cacheLockKey, ['params' => $params, 'user_id' => $userId], rand(3, 5));
+        $result = GoodsService::make()->getOrderGoods($ids, $goods, $orderNo, $userId);
+        if (empty($result)) {
             RedisService::clear($cacheLockKey);
+            $this->error = GoodsService::make()->getError();
             return false;
         }
 
-        if(in_array($pickerStatus,[2,3])){
-            $this->error = "220{$pickerStatus}";
+        $orderGoods = isset($result['goods']) ? $result['goods'] : [];
+        $orderTotal = isset($result['total']) ? $result['total'] : 0;
+        $orderCount = isset($result['count']) ? $result['count'] : 0;
+        $storeId = isset($result['store_id']) ? $result['store_id'] : 0;
+        if (empty($orderGoods)) {
             RedisService::clear($cacheLockKey);
+            $this->error = '获取订单商品错误~';
             return false;
         }
 
-        if($price<=0){
-            $this->error = 2204;
+        if ($orderTotal <= 0) {
             RedisService::clear($cacheLockKey);
+            $this->error = '订单金额错误~';
+            return false;
+        }
+
+        if ($orderCount <= 0) {
+            RedisService::clear($cacheLockKey);
+            $this->error = '订单商品数量错误~';
             return false;
         }
 
         // 用户信息
         $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
-            ->select(['id', 'mobile', 'nickname','realname','deposit','picker_status','confirm_status', 'status'])
+            ->select(['id', 'openid', 'mobile', 'nickname', 'realname', 'balance', 'status'])
             ->first();
         $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
-        $nickname = isset($userInfo['nickname']) ? $userInfo['nickname'] : '';
-        $realname = isset($userInfo['realname']) ? $userInfo['realname'] : '';
-        $mobile = isset($userInfo['mobile']) ? $userInfo['mobile'] : '';
-        $confirmStatus = isset($userInfo['confirm_status']) ? $userInfo['confirm_status'] : 0;
-        $userPickerStatus = isset($userInfo['picker_status']) ? $userInfo['picker_status'] : 0;
-        $userDeposit = isset($userInfo['deposit']) ? floatval($userInfo['deposit']) : 0;
-        if(empty($userInfo) || $status != 1){
-            $this->error = 2016;
+        $openid = isset($userInfo['openid']) ? $userInfo['openid'] : '';
+        if (empty($userInfo) || $status != 1) {
+            $this->error = 1045;
             RedisService::clear($cacheLockKey);
             return false;
         }
 
-        // 账号审核情况
-        if($confirmStatus != 1){
-            $this->error = 2042;
+        if (empty($openid)) {
+            $this->error = '用户微信未授权,请重新授权登录';
             RedisService::clear($cacheLockKey);
             return false;
         }
 
-        if($userPickerStatus != 1){
-            $this->error = 2205;
+        // 收货地址信息
+        $addressInfo = MemberAddressService::make()->getBindInfo($userId, $addressId);
+        $realname = isset($addressInfo['realname']) ? $addressInfo['realname'] : '';
+        $mobile = isset($addressInfo['mobile']) ? $addressInfo['mobile'] : '';
+        $area = isset($addressInfo['area']) ? $addressInfo['area'] : '';
+        $address = isset($addressInfo['address']) ? $addressInfo['address'] : '';
+        if (empty($addressInfo) || empty($realname) || empty($mobile) || empty($area) || empty($address)) {
             RedisService::clear($cacheLockKey);
+            $this->error = '收货地址信息错误,请核对后重试~';
             return false;
         }
 
-        // 缴纳保证金验证
-        $depositMoney = ConfigService::make()->getConfigByCode('deposit_money',0);
-        if($depositMoney>0 && ($userDeposit < $depositMoney)){
-            $this->error = 2206;
-            RedisService::clear($cacheLockKey);
-            return false;
+        // 商家佣金
+        $storeInfo = StoreModel::where(['id' => $storeId])->first();
+        $bonusRate = isset($storeInfo['bonus_rate']) ? floatval($storeInfo['bonus_rate']) : 0;
+        $storeBonusRate = ConfigService::make()->getConfigByCode('store_bonus_rate', 0);
+        $storeBonusRate = $storeBonusRate > 0 && $storeBonusRate <= 100 ? $storeBonusRate : 0;
+        $bonusRate = $bonusRate > 0 && $bonusRate <= 100 ? $bonusRate : $storeBonusRate;
+        $bonus = moneyFormat($orderTotal * $bonusRate / 100, 2);
+
+        $total = $orderTotal;
+        if (env('PAY_DEBUG')) {
+            $orderTotal = 0.1;
         }
 
+
         // 订单数据
-        $pickerCount = $this->model->where(['goods_id'=> $goodsId,'mark'=>1])->whereIn('status',[1,2])->count('id');
-        if($this->model->where(['user_id'=>$userId,'goods_id'=>$goodsId,'mark'=>1])->whereIn('status',[1,2,3])->value('id')){
-            $this->error = 2209;
-            RedisService::clear($cacheLockKey);
-            return false;
-        }
-        if($this->model->where(['user_id'=>$userId,'mark'=>1])->whereIn('status',[1,2])->value('id')){
-            $this->error = 2209;
-            RedisService::clear($cacheLockKey);
-            return false;
-        }
-        $bonusRate = ConfigService::make()->getConfigByCode('picker_bonus_rate',100);
-        $bonusRate = $bonusRate>0 && $bonusRate<=100? intval($bonusRate) : 100;
-        $bonus = moneyFormat($price * $bonusRate/100,2);
-        $orderNo = get_order_num('PD');
         $order = [
             'order_no' => $orderNo,
             'user_id' => $userId,
-            'goods_id' => $goodsId,
-            'total' => $price,
+            'store_id' => $storeId,
+            'total' => $total,
+            'num' => $orderCount,
+            'pay_total' => $orderTotal,
+            'receiver_name' => $realname,
+            'receiver_mobile' => $mobile,
+            'receiver_area' => $area,
+            'receiver_address' => $address,
             'bonus' => $bonus,
             'create_time' => time(),
             'update_time' => time(),
@@ -275,36 +291,409 @@ class OrderService extends BaseService
         DB::beginTransaction();
         if (!$orderId = $this->model->insertGetId($order)) {
             DB::rollBack();
-            $this->error = 2207;
+            $this->error = '创建订单失败';
             RedisService::clear($cacheLockKey);
             return false;
         }
 
-        $title = "用户【{$realname}-{$mobile}】有新的抢单";
-        $message = [
-            'from_uid'=> $userId,
-            'to_uid'=> 1,
-            'op'=> 'notice',
-            'scene'=> 'picker',
-            'message'=> '接单消息',
-            'type'=> 5,
-            'order'=>[
-                'title'=> $title.'<span class="ele-text-primary">查看订单</span>',
-                'order_no'=> $orderNo,
-                'money'=> $bonus,
-                'date'=> date('Y-m-d H:i:s'),
-                'user_id'=> $userId,
-                'type'=> 'deposit',
-                'remark'=> '接单消息',
-            ]
+        // 订单商品
+        if ($orderGoods && !OrderGoodsModel::insert($orderGoods)) {
+            DB::rollBack();
+            $this->error = '处理订单商品错误';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        // 获取支付参数
+        /* TODO 支付处理 */
+        $payOrder = [
+            'type' => 1,
+            'order_no' => $orderNo,
+            'pay_money' => $orderTotal,
+            'body' => '购物消费',
+            'openid' => $openid
         ];
 
+        // 调起支付
+        $payment = PaymentService::make()->minPay($userInfo, $payOrder, 'store');
+        if (empty($payment)) {
+            DB::rollBack();
+            RedisService::clear($cacheLockKey);
+            $this->error = PaymentService::make()->getError();
+            return false;
+        }
+
+        // 用户操作记录
         DB::commit();
-        $pickerCount = $pickerCount+1;
-        $this->error = lang('2210');
+        $this->error = '订单创建成功,请前往支付~';
         RedisService::clear($cacheLockKey);
-        RedisService::keyDel("caches:goods:picker*");
-        return ['order_id' => $orderId,'message'=>$message, 'total' => $price, 'num' => $pickerCount<=3?3:$pickerCount, 'goods' => $goodsId];
+        return [
+            'order_id' => $orderId,
+            'payment' => $payment,
+            'total' => $payOrder['pay_money'],
+            'pay_type' => 10,
+        ];
+    }
+
+    /**
+     * 订单支付
+     * @param $userId
+     * @param $id
+     * @return array|false
+     */
+    public function pay($userId, $id)
+    {
+        if ($id <= 0) {
+            $this->error = '请选择支付订单';
+            return false;
+        }
+
+        // 缓存锁
+        $cacheLockKey = "caches:orders:pay_lock:{$userId}_{$id}";
+        if (RedisService::get($cacheLockKey)) {
+            $this->error = '订单处理中~';
+            return false;
+        }
+
+        // 商品数据
+        RedisService::set($cacheLockKey, ['order_id' => $id, 'user_id' => $userId], rand(3, 5));
+
+        // 用户信息
+        $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
+            ->select(['id', 'openid', 'mobile', 'nickname', 'realname', 'balance', 'status'])
+            ->first();
+        $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
+        $openid = isset($userInfo['openid']) ? $userInfo['openid'] : '';
+        if (empty($userInfo) || $status != 1) {
+            $this->error = 1045;
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if (empty($openid)) {
+            $this->error = '用户微信未授权,请重新授权登录';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        // 订单信息
+        $info = $this->model->where(['id' => $id, 'mark' => 1])
+            ->select(['id', 'order_no', 'pay_total', 'status'])
+            ->first();
+        $orderTotal = isset($info['pay_total']) ? $info['pay_total'] : 0;
+        $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
+        $status = isset($info['status']) ? $info['status'] : 0;
+        if (empty($info) || empty($orderNo)) {
+            $this->error = '订单信息不存在';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if ($status != 1) {
+            $this->error = '订单已支付';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        // 获取支付参数
+        /* TODO 支付处理 */
+        $payOrder = [
+            'type' => 1,
+            'order_no' => $orderNo,
+            'pay_money' => $orderTotal,
+            'body' => '购物消费',
+            'openid' => $openid
+        ];
+
+        // 调起支付
+        $payment = PaymentService::make()->minPay($userInfo, $payOrder, 'store');
+        if (empty($payment)) {
+            DB::rollBack();
+            RedisService::clear($cacheLockKey);
+            $this->error = PaymentService::make()->getError();
+            return false;
+        }
+
+        // 用户操作记录
+        DB::commit();
+        $this->error = '支付请求成功,请前往支付~';
+        RedisService::clear($cacheLockKey);
+        return [
+            'order_id' => $id,
+            'payment' => $payment,
+            'total' => $payOrder['pay_money'],
+            'pay_type' => 10,
+        ];
+    }
+
+    /**
+     * 订单取消
+     * @param $userId
+     * @param $id
+     * @return array|false
+     */
+    public function cancel($userId, $id)
+    {
+        if ($id <= 0) {
+            $this->error = '请选择订单';
+            return false;
+        }
+
+        // 缓存锁
+        $cacheLockKey = "caches:orders:cancel_lock:{$userId}_{$id}";
+        if (RedisService::get($cacheLockKey)) {
+            $this->error = '订单处理中~';
+            return false;
+        }
+
+        // 商品数据
+        RedisService::set($cacheLockKey, ['order_id' => $id, 'user_id' => $userId], rand(3, 5));
+
+        // 用户信息
+        $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
+            ->select(['id', 'openid', 'mobile', 'nickname', 'realname', 'balance', 'status'])
+            ->first();
+        $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
+        if (empty($userInfo) || $status != 1) {
+            $this->error = 1045;
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        // 订单信息
+        $info = $this->model->where(['id' => $id, 'mark' => 1])
+            ->select(['id', 'order_no', 'pay_total', 'status'])
+            ->first();
+        $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
+        $status = isset($info['status']) ? $info['status'] : 0;
+        if (empty($info) || empty($orderNo)) {
+            $this->error = '订单信息不存在';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if ($status != 1) {
+            $this->error = '订单已支付';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        $this->error = '取消订单成功';
+        $this->model->where(['user_id' => $userId, 'mark' => 0])->where('update_time', '<=', time() - 300)->delete();
+        $this->model->where(['id' => $id])->update(['mark' => 0, 'update_time' => time()]);
+        return ['id' => $id];
+    }
+
+    /**
+     * 订单完成
+     * @param $userId 订单用户ID
+     * @param $id 订单ID
+     * @return array|false
+     */
+    public function complete($userId, $id)
+    {
+        if ($id <= 0) {
+            $this->error = '请选择订单';
+            return false;
+        }
+
+        // 缓存锁
+        $cacheLockKey = "caches:orders:complete_lock:{$userId}_{$id}";
+        if (RedisService::get($cacheLockKey)) {
+            $this->error = '订单处理中~';
+            return false;
+        }
+
+        // 商品数据
+        RedisService::set($cacheLockKey, ['order_id' => $id, 'user_id' => $userId], rand(3, 5));
+
+        // 用户信息
+        $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
+            ->select(['id', 'openid', 'mobile', 'parent_id', 'nickname', 'realname', 'balance', 'status'])
+            ->first();
+        $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
+        $parentId = isset($userInfo['parent_id']) ? $userInfo['parent_id'] : 0;
+        if (empty($userInfo) || $status != 1) {
+            $this->error = 1045;
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        // 订单信息
+        $info = $this->model->with(['orderGoods'])->where(['id' => $id, 'mark' => 1])
+            ->select(['id', 'order_no', 'store_id', 'pay_total', 'bonus', 'delivery_no', 'delivery_company', 'delivery_code', 'status'])
+            ->first();
+        $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
+        $deliveryNo = isset($info['delivery_no']) ? $info['delivery_no'] : '';
+        $deliverCompany = isset($info['delivery_company']) ? $info['delivery_company'] : '';
+        $deliverCode = isset($info['delivery_code']) ? $info['delivery_code'] : '';
+        $storeId = isset($info['store_id']) ? $info['store_id'] : 0;
+        $orderTotal = isset($info['pay_total']) ? $info['pay_total'] : 0;
+        $bonus = isset($info['bonus']) ? $info['bonus'] : 0;
+        $status = isset($info['status']) ? $info['status'] : 0;
+        $orderGoods = isset($info['order_goods']) ? $info['order_goods'] : [];
+        if (empty($info) || empty($orderNo)) {
+            $this->error = '订单信息不存在';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if ($status != 3) {
+            $this->error = '订单未发货';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if ((empty($deliveryNo) || empty($deliverCompany) || empty($deliverCode))) {
+            $this->error = '订单发货信息错误';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if (empty($deliveryNo) || empty($deliverCompany) || empty($deliverCode)) {
+            $this->error = '订单发货信息错误,请联系客服';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        DB::beginTransaction();
+        $this->model->where(['id' => $id])->update(['status' => '4', 'update_time' => time()]);
+
+        // 商家订单数据统计
+        $updateData = ['order_count' => DB::raw('order_count+1'), 'order_total' => DB::raw("order_total + {$orderTotal}")];
+        StoreModel::where(['id' => $storeId])->update($updateData);
+
+
+        // 商品销量数据
+        if ($orderGoods) {
+            $counts = [];
+            foreach ($orderGoods as $item) {
+                $counts[$item['goods_id']] = isset($counts[$item['goods_id']]) ? $counts[$item['goods_id']] : 0;
+                $counts[$item['goods_id']] += $item['num'];
+            }
+
+            if ($counts) {
+                foreach ($counts as $id => $v) {
+                    GoodsModel::where(['id' => $id])->update(['sales' => DB::raw("sales + {$v}"), 'update_time' => time()]);
+                }
+            }
+        }
+
+        // 结算商家收益
+        if (SettleService::make()->storeBonus($storeId, $bonus, $info) < 0) {
+            DB::rollBack();
+            $this->error = SettleService::make()->getError();
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+
+        // 代理佣金结算
+        if (SettleService::make()->agentBonus($userId, $orderTotal, $info, $parentId) < 0) {
+            DB::rollBack();
+            $this->error = SettleService::make()->getError();
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        DB::commit();
+
+        $this->error = '确认收货成功';
+        return ['id' => $id];
+    }
+
+    /**
+     * 售后或退款
+     * @param $userId
+     * @param $params
+     * @return array|false
+     */
+    public function after($userId, $params)
+    {
+        $id = isset($params['id']) ? $params['id'] : 0;
+        $afterType = isset($params['after_type']) ? $params['after_type'] : 1;
+        if ($id <= 0) {
+            $this->error = '请选择订单';
+            return false;
+        }
+
+        // 缓存锁
+        $cacheLockKey = "caches:orders:after_lock:{$userId}_{$id}";
+        if (RedisService::get($cacheLockKey)) {
+            $this->error = '订单处理中~';
+            return false;
+        }
+
+        // 商品数据
+        RedisService::set($cacheLockKey, ['params' => $params, 'user_id' => $userId], rand(3, 5));
+
+        // 用户信息
+        $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
+            ->select(['id', 'openid', 'mobile', 'nickname', 'realname', 'balance', 'status'])
+            ->first();
+        $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
+        if (empty($userInfo) || $status != 1) {
+            $this->error = 1045;
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        // 订单信息
+        $info = $this->model->where(['id' => $id, 'mark' => 1])
+            ->select(['id', 'order_no', 'after_type', 'refund_status', 'pay_total', 'status'])
+            ->first();
+        $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
+        $status = isset($info['status']) ? $info['status'] : 0;
+        $refundStatus = isset($info['refund_status']) ? $info['refund_status'] : 0;
+        if (empty($info) || empty($orderNo)) {
+            $this->error = '订单信息不存在';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if ($status == 1) {
+            $this->error = '订单未支付';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if ($status == 4 && $afterType==2) {
+            $this->error = '订单已完成';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+        if ($refundStatus > 0 && $refundStatus != 4) {
+            $this->error = '订单售后处理中';
+            RedisService::clear($cacheLockKey);
+            return false;
+        }
+
+
+        $afterRealname = isset($params['after_realname']) ? $params['after_realname'] : '';
+        $afterPhone = isset($params['after_phone']) ? $params['after_phone'] : '';
+        $afterRemark = isset($params['after_remark']) ? $params['after_remark'] : '';
+        if ($afterType == 1) {
+            if (empty($afterRealname) || empty($afterPhone) || empty($afterRemark)) {
+                $this->error = '请填写售后信息';
+                RedisService::clear($cacheLockKey);
+                return false;
+            }
+        }
+
+        $data = [
+            'after_type' => $afterType,
+            'after_realname' => $afterRealname,
+            'after_phone' => $afterPhone,
+            'after_remark' => $afterRemark,
+            'refund_remark' => isset($params['refund_remark']) ? $params['refund_remark'] : '',
+            'refund_status' => 3,
+            'update_time' => time()
+        ];
+        $this->model->where(['id' => $id])->update($data);
+
+        $this->error = '订单申请售后成功';
+        return ['id' => $id];
     }
 
     /**
@@ -313,19 +702,19 @@ class OrderService extends BaseService
      * @param int $type
      * @return array|mixed
      */
-    public function getCountByDay($userId, $status=3)
+    public function getCountByDay($userId, $status = 3)
     {
         $cacheKey = "caches:orders:count_day_{$userId}_{$status}";
         $data = RedisService::get($cacheKey);
-        if($data){
+        if ($data) {
             return $data;
         }
 
-        $data = $this->model->where(['user_id'=> $userId,'status'=>$status,'mark'=>1])
-            ->where('create_time','>=', strtotime(date('Y-m-d')))
+        $data = $this->model->where(['user_id' => $userId, 'status' => $status, 'mark' => 1])
+            ->where('create_time', '>=', strtotime(date('Y-m-d')))
             ->count('id');
-        if($data){
-            RedisService::set($cacheKey, $data, rand(5,10));
+        if ($data) {
+            RedisService::set($cacheKey, $data, rand(5, 10));
         }
 
         return $data;
@@ -337,18 +726,18 @@ class OrderService extends BaseService
      * @param int $status
      * @return array|mixed
      */
-    public function getCountByStatus($userId, $status=3)
+    public function getCountByStatus($userId, $status = 3)
     {
         $cacheKey = "caches:orders:count_status_{$userId}_{$status}";
         $data = RedisService::get($cacheKey);
-        if($data){
+        if ($data) {
             return $data;
         }
 
-        $data = $this->model->where(['user_id'=> $userId,'status'=>$status,'mark'=>1])
+        $data = $this->model->where(['user_id' => $userId, 'status' => $status, 'mark' => 1])
             ->count('id');
-        if($data){
-            RedisService::set($cacheKey, $data, rand(5,10));
+        if ($data) {
+            RedisService::set($cacheKey, $data, rand(5, 10));
         }
 
         return $data;
@@ -363,48 +752,134 @@ class OrderService extends BaseService
     {
         $cacheKey = "caches:orders:checkOrder:{$userId}";
         $data = RedisService::get($cacheKey);
-        if($data){
+        if ($data) {
             return $data;
         }
 
-        $data = $this->model->with(['confirm'])->where(function($query){
-                $query->where(function($query){
-                    $query->where('status',2)->where('confirm_at','>=', date('Y-m-d H:i:s', time() - 3600));
-                })->orWhere(function($query){
-                    $query->where('status', 9)->where('confirm_at','>=', date('Y-m-d H:i:s', time() - 600));
-                })->orWhere(function($query){
-                    $query->where('status', 3)->where('confirm_at','>=', date('Y-m-d H:i:s', time() - 600));
-                })->orWhere('status', 1);
-            })
-            ->where(['user_id'=> $userId,'mark'=>1])
-            ->select(['id','order_no','user_id','goods_id','status'])
-            ->orderBy('id','desc')
+        $data = $this->model->with(['confirm'])->where(function ($query) {
+            $query->where(function ($query) {
+                $query->where('status', 2)->where('confirm_at', '>=', date('Y-m-d H:i:s', time() - 3600));
+            })->orWhere(function ($query) {
+                $query->where('status', 9)->where('confirm_at', '>=', date('Y-m-d H:i:s', time() - 600));
+            })->orWhere(function ($query) {
+                $query->where('status', 3)->where('confirm_at', '>=', date('Y-m-d H:i:s', time() - 600));
+            })->orWhere('status', 1);
+        })
+            ->where(['user_id' => $userId, 'mark' => 1])
+            ->select(['id', 'order_no', 'user_id', 'goods_id', 'status'])
+            ->orderBy('id', 'desc')
             ->first();
-        $data = $data? $data->toArray() : [];
+        $data = $data ? $data->toArray() : [];
         $result = [];
-        if($data){
-            $orderId = isset($data['id'])? $data['id'] : 0;
-            $status = isset($data['status'])? $data['status'] : 0;
-            $goodsId = isset($data['goods_id'])? $data['goods_id'] : 0;
-            $confirmOrder = isset($data['confirm'])? $data['confirm'] : [];
-            $confirmOrderId = isset($confirmOrder['id'])? $confirmOrder['id'] : 0;
-            $confirmOrderUser = isset($confirmOrder['user'])? $confirmOrder['user'] : [];
-            $realname = isset($confirmOrderUser['realname'])? $confirmOrderUser['realname'] : '';
-            if($status==9){
+        if ($data) {
+            $orderId = isset($data['id']) ? $data['id'] : 0;
+            $status = isset($data['status']) ? $data['status'] : 0;
+            $goodsId = isset($data['goods_id']) ? $data['goods_id'] : 0;
+            $confirmOrder = isset($data['confirm']) ? $data['confirm'] : [];
+            $confirmOrderId = isset($confirmOrder['id']) ? $confirmOrder['id'] : 0;
+            $confirmOrderUser = isset($confirmOrder['user']) ? $confirmOrder['user'] : [];
+            $realname = isset($confirmOrderUser['realname']) ? $confirmOrderUser['realname'] : '';
+            if ($status == 9) {
                 $message = "抱歉,订单已被其他师傅接走";
-            }else if($status == 2){
+            } else if ($status == 2) {
                 $message = "恭喜您,抢单成功,请前往完成订单!";
-            }else if($status == 3){
+            } else if ($status == 3) {
                 $message = "恭喜您,订单已经完成!";
-            }else {
-                $pickerCount = $this->model->where(['goods_id'=> $goodsId,'mark'=>1])->whereIn('status',[1,2])->count('id');
-                $pickerCount = $pickerCount<=3? 3 : $pickerCount;
+            } else {
+                $pickerCount = $this->model->where(['goods_id' => $goodsId, 'mark' => 1])->whereIn('status', [1, 2])->count('id');
+                $pickerCount = $pickerCount <= 3 ? 3 : $pickerCount;
                 $message = "<p style='padding: 5px 0;'>正在抢单</p><p>({$pickerCount}位师傅正在抢单中)</p>";
             }
-            $result = ['order_id'=>$orderId,'goods_id'=>$goodsId,'confirm_order_id'=>$confirmOrderId,'status'=>$status, 'message'=> $message];
+            $result = ['order_id' => $orderId, 'goods_id' => $goodsId, 'confirm_order_id' => $confirmOrderId, 'status' => $status, 'message' => $message];
             RedisService::set($cacheKey, $result, rand(10, 20));
         }
 
         return $result;
     }
+
+
+    /**
+     * 物流查询
+     * @param $id
+     * @return array|false|mixed
+     */
+    public function getDelivery($id)
+    {
+        $info = $this->model->where(['id' => $id, 'mark' => 1])->first();
+        $deliveryNo = isset($info['delivery_no']) ? $info['delivery_no'] : '';
+        $deliveryCode = isset($info['delivery_code']) ? $info['delivery_code'] : '';
+        $mobile = isset($info['receiver_mobile']) ? $info['receiver_mobile'] : '';
+        if (empty($info)) {
+            $this->error = '请选择订单';
+            return false;
+        }
+
+        $cacheKey = "caches:kd100_{$id}";
+        $data = RedisService::get($cacheKey);
+        $data = [
+            [
+                "time" => "2025-12-24 11:29:23",
+      "context" => "您的快件已投递,收件人在[沙岗镇绕城路天猫1号店妈妈驿站]取件(凭取件码签收),如有疑问请联系站点:13086796129,快递员电话:13086796129,投诉电话:15278929512。感谢使用圆通速递,期待再次为您服务!",
+      "ftime" => "2025-12-24 11:29:23",
+      "areaCode" => "CN450521000000",
+      "areaName" => "广西,北海市,合浦县",
+      "status" => "签收",
+            ],
+            [
+                "time" => "2025-12-22 17:29:40",
+      "context" => "您的快件已到达[妈妈驿站]沙岗镇绕城路1号天猫店,请您及时取件,如有取件码问题或找不到包裹等问题,请联系站点:13086796129,快递员电话:13086796129,投诉电话:15278929512。感谢使用圆通速递,期待再次为您服务!",
+      "ftime" => "2025-12-22 17:29:40",
+      "areaCode" => "CN450521000000",
+      "areaName" => "广西,北海市,合浦县",
+      "status" => "派件",
+            ],[
+                "time" => "2025-12-22 17:28:40",
+      "context" => "【广西北海市合浦县沙岗镇】的莫业琨(13086796129)正在派件,(有事先呼我,勿找平台,少一次投诉,多一份感恩)!如有疑问请联系网点:15278929512,投诉电话:15278929512。[95161和18521号段的上海号码为圆通快递员专属号码,请放心接听]",
+      "ftime" => "2025-12-22 17:28:40",
+      "areaCode" => "CN450521100000",
+      "areaName" => "广西,北海市,合浦县,廉州镇",
+      "status" => "派件",
+            ],[
+                "time" => "2025-12-22 02:44:12",
+      "context" => "您的快件离开【南宁转运中心】,已发往【广西北海市合浦】",
+      "ftime" => "2025-12-22 02:44:12",
+      "areaCode" => "CN450108000000",
+      "areaName" => "广西,南宁市,良庆区",
+      "status" => "在途",
+            ],[
+                "time" => "2025-12-22 02:21:21",
+      "context" => "您的快件已经到达【南宁转运中心】【物流问题无需找商家或平台,请致电(专属热线:95554)更快解决】",
+      "ftime" => "2025-12-22 02:21:21",
+      "areaCode" => "CN450108000000",
+      "areaName" => "广西,南宁市,良庆区",
+      "status" => "在途",
+            ],[
+                "time" => "2025-12-20 23:47:58",
+      "context" => "您的快件离开【临海转运中心】,已发往【南宁转运中心】。预计【12月22日】到达【南宁市】,因运输距离较远,预计将在【22日晚上】为您更新快件状态,请您放心!",
+      "ftime" => "2025-12-20 23:47:58",
+      "areaCode" => "CN331082000000",
+      "areaName" => "浙江,台州市,临海市",
+      "status" => "在途",
+            ],[
+                "time" => "2025-12-20 23:45:58",
+      "context" => "您的快件已经到达【临海转运中心】【物流问题无需找商家或平台,请致电(专属热线:95554)更快解决】",
+      "ftime" => "2025-12-20 23:45:58",
+      "areaCode" => "CN331082000000",
+      "areaName" => "浙江,台州市,临海市",
+      "status" => "在途",
+            ]
+        ];
+        if ($data) {
+            return $data;
+        }
+        $result = Kd100Service::make()->query($deliveryNo, $mobile, $deliveryCode);
+        $status = isset($result['status'])?$result['status']:0;
+        $data = isset($result['data'])?$result['data']:[];
+        if ($data && $status==200) {
+            RedisService::set($cacheKey, $data, 300);
+        }
+
+        return $data;
+
+    }
 }

+ 228 - 0
app/Services/Api/SettleService.php

@@ -0,0 +1,228 @@
+<?php
+// +----------------------------------------------------------------------
+// | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
+// +----------------------------------------------------------------------
+// | 版权所有 2017~2021 LARAVEL研发中心
+// +----------------------------------------------------------------------
+// | 官方网站: http://www.laravel.cn
+// +----------------------------------------------------------------------
+// | Author: laravel开发员 <laravel.qq.com>
+// +----------------------------------------------------------------------
+
+namespace App\Services\Api;
+
+use App\Models\AccountLogModel;
+use App\Models\AgentModel;
+use App\Models\MemberModel;
+use App\Models\StoreCategoryModel;
+use App\Models\StoreModel;
+use App\Services\BaseService;
+use App\Services\ConfigService;
+use App\Services\RedisService;
+use Illuminate\Support\Facades\DB;
+
+/**
+ * 结算管理-服务类
+ * @author laravel开发员
+ * @since 2020/11/11
+ * @package App\Services\Common
+ */
+class SettleService extends BaseService
+{
+    /**
+     * 构造函数
+     * @author laravel开发员
+     * @since 2020/11/11
+     */
+    public function __construct()
+    {
+        $this->model = new AccountLogModel();
+    }
+
+    /**
+     * 静态入口
+     * @return static|null
+     */
+    public static function make()
+    {
+        if (!self::$instance) {
+            self::$instance = (new static());
+        }
+        return self::$instance;
+    }
+
+
+    /**
+     * 商家收益结算
+     * @param $storeId
+     * @param $money 收益
+     * @param $order 订单数据
+     * @return array|false|int
+     */
+    public function storeBonus($storeId, $money, $order)
+    {
+        $orderNo = isset($order['order_no'])? $order['order_no'] : '';
+        if($money<=0 && $storeId<=0){
+            $this->error = '无商家佣金可结算';
+            return false;
+        }
+
+        $storeInfo = StoreModel::where(['id'=> $storeId,'mark'=>1])->first();
+        $balance = isset($storeInfo['balance'])? $storeInfo['balance'] : 0;
+        $storeUserId = isset($storeInfo['user_id'])? $storeInfo['user_id'] : 0;
+        if($storeUserId<=0){
+            $this->error = '商家账号错误';
+            return false;
+        }
+
+        if(!StoreModel::where(['id'=> $storeId])->update(['balance'=>DB::raw("balance + {$money}"),'income'=>DB::raw("income + {$money}"),'update_time'=>time()])){
+            $this->error = '收货错误,商家结算错误,请联系客服处理';
+            return -1;
+        }
+
+        $log = [
+            'user_id'=> $storeUserId,
+            'source_order_no'=> isset($order['order_no'])? $order['order_no'] : '',
+            'type'=> 7,
+            'money'=> $money,
+            'before_money'=> $balance,
+            'date'=>date('Y-m-d'),
+            'create_time'=>time(),
+            'remark'=> '商家收益',
+            'status'=>1
+        ];
+        if(!$id = $this->model->insertGetId($log)){
+            $this->error = '商家收益结算失败,请联系客服处理';
+            return -1;
+        }
+
+        $result = ['id'=>$id,'store_id'=>$storeId,'bonus'=>$money];
+        if(env('APP_DEBUG')){
+            RedisService::set("caches:settle:{$orderNo}:store_{$storeId}", $result, 7200);
+        }
+
+        return $result;
+    }
+
+    public function agentBonus($userId, $money, $order, $parentId)
+    {
+        $orderNo = isset($order['order_no'])? $order['order_no'] : '';
+        if($money<=0 || $userId<=0 || $parentId<=0){
+            $this->error = '无收益可结算';
+            return false;
+        }
+
+        $parent = AgentModel::with(['user'])->where(['user_id'=> $parentId,'status'=>1,'mark'=>1])
+            ->select(['id','balance','income','status'])
+            ->first();
+        $agentId = isset($parent['id'])? $parent['id'] : 0;
+        $balance = isset($parent['balance'])? $parent['balance'] : 0;
+        $parentInfo = isset($parent['user'])? $parent['user'] : [];
+        $parentOneId = isset($parentInfo['parent_id'])? $parentInfo['parent_id'] :0;
+
+
+        // 推荐消费者的佣金
+        $logs = [];
+        $agentDirectBonusRate = ConfigService::make()->getConfigByCode('agent_direct_bonus_rate', 0);
+        $agentDirectBonusRate = $agentDirectBonusRate>0 && $agentDirectBonusRate<100? $agentDirectBonusRate : 0;
+        $bonus = moneyFormat($agentDirectBonusRate * $money/100, 2);
+        if(empty($parent) || $bonus<=0 || $agentId<=0){
+            $this->error = '上级代理无效';
+            return 0;
+        }
+
+        if(!AgentModel::where(['id'=> $agentId])->update(['balance'=>DB::raw("balance + {$bonus}"),'income'=>DB::raw("income + {$bonus}"),'order_count'=>DB::raw("order_count + 1"),'update_time'=>time()])){
+            $this->error = '推荐消费者收益结算错误,请联系客服处理';
+            return -1;
+        }
+
+        $logs[] = [
+            'user_id'=> $parentId,
+            'source_order_no'=> isset($order['order_no'])? $order['order_no'] : '',
+            'type'=> 9,
+            'money'=> $bonus,
+            'before_money'=> $balance,
+            'date'=>date('Y-m-d'),
+            'create_time'=>time(),
+            'remark'=> '推广收益',
+            'status'=>1
+        ];
+
+
+        // 一级代理收益
+        $parentTwoId = 0;
+        $oneBonus = 0;
+        if($bonus>0 && $parentOneId){
+            $parentOne = AgentModel::with(['user'])->where(['user_id'=> $parentOneId,'status'=>1,'mark'=>1])
+                ->select(['id','balance','income','status'])
+                ->first();
+            $oneId = isset($parentOne['id'])? $parentOne['id'] : 0;
+            $oneBalance = isset($parentOne['balance'])? $parentOne['balance'] : 0;
+            $oneInfo = isset($parentOne['user'])? $parentOne['user'] : [];
+            $parentTwoId = isset($oneInfo['parent_id'])? $oneInfo['parent_id'] :0;
+
+            $agentBonusLevel1Rate = ConfigService::make()->getConfigByCode('agent_bonus_level1_rate', 0);
+            $agentBonusLevel1Rate = $agentBonusLevel1Rate>0 && $agentBonusLevel1Rate<100? $agentBonusLevel1Rate : 0;
+            $oneBonus = moneyFormat($agentBonusLevel1Rate * $bonus/100, 2);
+            if(!AgentModel::where(['id'=> $oneId])->update(['balance'=>DB::raw("balance + {$oneBonus}"),'income'=>DB::raw("income + {$oneBonus}"),'order_count'=>DB::raw("order_count + 1"),'update_time'=>time()])){
+                $this->error = '推荐代理收益结算错误,请联系客服处理';
+                return -1;
+            }
+
+            $logs[] = [
+                'user_id'=> $parentOneId,
+                'source_order_no'=> isset($order['order_no'])? $order['order_no'] : '',
+                'type'=> 8,
+                'money'=> $oneBonus,
+                'before_money'=> $oneBalance,
+                'date'=>date('Y-m-d'),
+                'create_time'=>time()+1,
+                'remark'=> '一级代理收益',
+                'status'=>1
+            ];
+        }
+
+        // 二级代理收益
+        $twoBonus = 0;
+        if($bonus>0 && $parentTwoId){
+            $parentTwo = AgentModel::with(['user'])->where(['user_id'=> $parentTwoId,'status'=>1,'mark'=>1])
+                ->select(['id','balance','income','status'])
+                ->first();
+            $twoId = isset($parentTwo['id'])? $parentTwo['id'] : 0;
+            $twoBalance = isset($parentTwo['balance'])? $parentTwo['balance'] : 0;
+
+            $agentBonusLevel2Rate = ConfigService::make()->getConfigByCode('agent_bonus_level2_rate', 0);
+            $agentBonusLevel2Rate = $agentBonusLevel2Rate>0 && $agentBonusLevel2Rate<100? $agentBonusLevel2Rate : 0;
+            $twoBonus = moneyFormat($agentBonusLevel2Rate * $bonus/100, 2);
+            if(!AgentModel::where(['id'=> $twoId])->update(['balance'=>DB::raw("balance + {$twoBonus}"),'income'=>DB::raw("income + {$twoBonus}"),'order_count'=>DB::raw("order_count + 1"),'update_time'=>time()])){
+                $this->error = '推荐代理收益结算错误,请联系客服处理';
+                return -1;
+            }
+
+            $logs[] = [
+                'user_id'=> $parentTwoId,
+                'source_order_no'=> isset($order['order_no'])? $order['order_no'] : '',
+                'type'=> 8,
+                'money'=> $twoBonus,
+                'before_money'=> $twoBalance,
+                'date'=>date('Y-m-d'),
+                'create_time'=>time()+2,
+                'remark'=> '二级代理收益',
+                'status'=>1
+            ];
+        }
+
+        if($logs && !$this->model->insert($logs)){
+            $this->error = '推荐代理收益结算错误,请联系客服处理';
+            return -1;
+        }
+
+        $result = ['user_id'=>$userId,'total'=> $money,'bonus'=>$bonus,'parent_id'=>$parentId,'oneId'=>$parentOneId,'oneBonus'=>$oneBonus,'twoId'=>$parentTwoId,'twoBonus'=>$twoBonus];
+        if(env('APP_DEBUG')){
+            RedisService::set("caches:settle:{$orderNo}:agent_{$userId}", $result, 7200);
+        }
+
+        return $result;
+    }
+
+}

+ 34 - 8
app/Services/Api/StoreService.php

@@ -13,8 +13,11 @@ namespace App\Services\Api;
 
 use App\Models\StoreCategoryModel;
 use App\Models\StoreModel;
+use App\Models\UserModel;
 use App\Services\BaseService;
+use App\Services\Common\UserRoleService;
 use App\Services\RedisService;
+use Illuminate\Support\Facades\DB;
 
 /**
  * 商家管理-服务类
@@ -107,21 +110,41 @@ class StoreService extends BaseService
         if ($status > 0) {
             $where['a.status'] = $status;
         }
-        $list = $this->model->with(['goods'])->from('stores as a')
-            ->leftJoin('goods as b', function($join){
-                $join->on('b.store_id', '=', 'a.id')->where(['b.status'=>1,'b.mark'=>1]);
+        $list = $this->model->with(['goods'=>function($query)use($params){
+            $categoryId = isset($params['category_id']) ? $params['category_id'] : 0;
+            if ($categoryId>0) {
+                $query->where('goods.category_id', $categoryId);
+            }
+
+            $keyword = isset($params['keyword']) ? $params['keyword'] : '';
+            if ($keyword) {
+                $query->where(function($query) use($keyword){
+                    $query->where('a.name', 'like', "%{$keyword}%")
+                        ->orWhere('goods.goods_name', 'like', "%{$keyword}%")
+                        ->orWhere('goods.tags', 'like', "%{$keyword}%");
+                });
+            }
+        }])->from('stores as a')
+            ->leftJoin('goods', function($join){
+                $join->on('goods.store_id', '=', 'a.id')->where(['goods.status'=>1,'goods.mark'=>1]);
             })
             ->where($where)
-            ->where('b.id','>',0)
+            ->where('goods.id','>',0)
             ->where(function ($query) use ($params) {
                 $keyword = isset($params['keyword']) ? $params['keyword'] : '';
                 if ($keyword) {
                     $query->where('a.name', 'like', "%{$keyword}%")
-                        ->orWhere('b.goods_name', 'like', "%{$keyword}%")
-                        ->orWhere('b.tags', 'like', "%{$keyword}%");
+                        ->orWhere('goods.goods_name', 'like', "%{$keyword}%")
+                        ->orWhere('goods.tags', 'like', "%{$keyword}%");
+                }
+            })
+            ->where(function ($query) use ($params) {
+                $categoryId = isset($params['category_id']) ? $params['category_id'] : 0;
+                if ($categoryId>0) {
+                    $query->where('goods.category_id', $categoryId);
                 }
             })
-            ->select(['a.id','a.logo','a.name','a.user_id','a.status','b.id as goods_id'])
+            ->select(['a.id','a.logo','a.name','a.user_id','a.status','a.sort','goods.id as goods_id'])
             ->groupBy('a.id')
             ->orderBy('a.sort', 'desc')
             ->orderBy('a.id', 'desc')
@@ -205,11 +228,12 @@ class StoreService extends BaseService
             'mark' => 1,
         ];
 
-
+        DB::beginTransaction();
         if($id = $this->model->where(['user_id'=>$userId])->value('id')){
             $this->model->where(['id'=>$id])->update($data);
         }else{
             if (!$id = $this->model->insertGetId($data)) {
+                DB::rollBack();
                 $this->error = '申请入驻失败';
                 return false;
             }
@@ -268,4 +292,6 @@ class StoreService extends BaseService
 
         return $info;
     }
+
+
 }

+ 1 - 1
app/Services/Common/AdService.php

@@ -52,7 +52,7 @@ class AdService extends BaseService
         $showNum = \App\Services\ConfigService::make()->getConfigByCode('show_banner_num', 6);
         $num = $num? $num : $showNum;
         $datas = $this->model->where(['position'=> $position,'status'=> 1,'mark'=>1])
-            ->select(['id','cover','title','url','description','type'])
+            ->select(['id','cover','title','url','description'])
             ->limit($num)
             ->get()
             ->each(function($item, $k){

+ 1 - 0
app/Services/Common/UserService.php

@@ -152,6 +152,7 @@ class UserService extends BaseService
         if (isset($data['store_id'])) {
             $this->updateStoreRelation($result, $data['store_id']);
         }
+
         // 删除已存在的用户角色关系数据
         $userRoleService = new UserRoleService();
         $userRoleService->deleteUserRole($result);

+ 119 - 0
app/Services/DyrPayService.php

@@ -0,0 +1,119 @@
+<?php
+// +----------------------------------------------------------------------
+// | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
+// +----------------------------------------------------------------------
+// | 版权所有 2017~2021 LARAVEL研发中心
+// +----------------------------------------------------------------------
+// | 官方网站: http://www.laravel.cn
+// +----------------------------------------------------------------------
+// | Author: laravel开发员 <laravel.qq.com>
+// +----------------------------------------------------------------------
+
+namespace App\Services;
+
+/**
+ * 生活充值接口管理-服务类
+ * @author laravel开发员
+ * @since 2020/11/11
+ * @package App\Services
+ */
+class DyrPayService extends BaseService
+{
+    // 静态对象
+    protected static $instance = null;
+    protected $apiUrl = 'http://1.huichikeji.cn/yrapi.php';
+    protected $apiKey = '';
+    protected $apiClientId = '';
+    protected $apiUrls = [
+        'recharge' => '/index/recharge'
+    ];
+
+    public function __construct()
+    {
+        $apiUrl = ConfigService::make()->getConfigByCode('pay_api_url');
+        $this->apiUrl = $apiUrl ? $apiUrl : $this->apiUrl;
+        $this->apiKey = ConfigService::make()->getConfigByCode('pay_api_key');
+        $this->apiClientId = ConfigService::make()->getConfigByCode('pay_ userid');
+    }
+
+    /**
+     * 静态入口
+     */
+    public static function make()
+    {
+        if (!self::$instance) {
+            self::$instance = new static();
+        }
+
+        return self::$instance;
+    }
+
+
+    /**
+     * 查询
+     * @param $no 快递单号
+     * @param string $phone // 手机号
+     * @param string $code 快递公司编号
+     * @return bool
+     */
+    public function recharge($no, $account, $productId, $amount)
+    {
+        if (empty($this->apiUrl) || empty($this->apiKey) || empty($this->apiClientId)) {
+            $this->error = '接口参数未配置';
+            return false;
+        }
+
+        $cacheKey = "caches:kd100:{$no}_{$productId}_{$account}";
+        if (RedisService::get($cacheKey . '_lock')) {
+            $this->error = '充值处理中~';
+            return false;
+        }
+
+        $param = [
+            'userid' => $this->apiClientId,             // 商户ID
+            'product_id' => $productId,             // 产品ID
+            'out_trade_num' => $no,     // 单号
+            'amount' => $amount,                // 金额
+            'mobile' => $account,                // 手机号
+            'notify_url' => url('/api/notify/dyr/' . $productId),            // 回调地址
+
+        ];
+
+        //请求参数
+        $param['sign'] = $this->makeSign($param);
+        $url = $this->apiUrl.$this->apiUrls['recharge'];
+        $result = httpRequest($url, $param, 'post', '', 5);
+        $this->saveLog($cacheKey,  ['url'=>$url,'param'=>$param,'result'=>$result]);
+        return $result;
+    }
+
+    /**
+     * 日志
+     * @param $key
+     * @param $data
+     */
+    public function saveLog($key, $data)
+    {
+        if(env('APP_DEBUG')){
+            RedisService::set($key,$data, 7200);
+        }
+    }
+
+    /**
+     * 生成签名
+     * @param $param
+     * @return string
+     */
+    public function makeSign($param,$type=1)
+    {
+        // 字典排序
+        ksort($param);
+
+        // 拼接签名串
+        $param = $type==2?urldecode(http_build_query($param)) : http_build_query($param);
+        $sign_str =  $param . '&apikey=' . $this->apiKey;
+        // 签名
+        $sign = strtoupper(md5($type==2? $sign_str : urldecode($sign_str)));
+        return $sign;
+    }
+}

+ 86 - 0
app/Services/Kd100Service.php

@@ -0,0 +1,86 @@
+<?php
+// +----------------------------------------------------------------------
+// | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
+// +----------------------------------------------------------------------
+// | 版权所有 2017~2021 LARAVEL研发中心
+// +----------------------------------------------------------------------
+// | 官方网站: http://www.laravel.cn
+// +----------------------------------------------------------------------
+// | Author: laravel开发员 <laravel.qq.com>
+// +----------------------------------------------------------------------
+
+namespace App\Services;
+
+/**
+ * 快递100接口管理-服务类
+ * @author laravel开发员
+ * @since 2020/11/11
+ * @package App\Services
+ */
+class Kd100Service extends BaseService
+{
+    // 静态对象
+    protected static $instance = null;
+    protected $apiUrl = 'https://poll.kuaidi100.com/poll/query.do';
+    protected $apiKey = '';
+    protected $apiCode = '';
+
+    public function __construct()
+    {
+        $this->apiKey = ConfigService::make()->getConfigByCode('kd_customer_key');
+        $this->apiCode = ConfigService::make()->getConfigByCode('kd_customer_code');
+    }
+
+    /**
+     * 静态入口
+     */
+    public static function make(){
+        if(!self::$instance){
+            self::$instance = new static();
+        }
+
+        return self::$instance;
+    }
+
+
+    /**
+     * 查询
+     * @param $no 快递单号
+     * @param string $phone // 手机号
+     * @param string $code 快递公司编号
+     * @return bool
+     */
+    public function query($no, $phone, $code)
+    {
+        if(empty($this->apiKey) || empty($this->apiCode)){
+            $this->error = '接口参数未配置';
+            return false;
+        }
+
+        $cacheKey = "caches:kd100:{$no}_{$code}";
+        if(RedisService::get($cacheKey.'_lock')){
+            $this->error = '2011';
+            return false;
+        }
+
+        $param =  [
+            'com' => $code,             // 快递公司编码
+            'num' => $no,     // 快递单号
+            'phone' => $phone,                // 手机号
+            'from' => '',                 // 出发地城市
+            'to' => '',                   // 目的地城市
+            'resultv2' => '1',            // 开启行政区域解析
+            'show' => '0',                // 返回格式:0:json格式(默认),1:xml,2:html,3:text
+            'order' => 'desc'             // 返回结果排序:desc降序(默认),asc 升序
+        ];
+
+        //请求参数
+        $data = [];
+        $data['customer'] = $this->apiCode;
+        $data['param'] = json_encode($param, JSON_UNESCAPED_UNICODE);
+        $sign = md5($data['param'].$this->apiKey.$data['customer']);
+        $data['sign'] = strtoupper($sign);
+        $result = httpRequest($this->apiUrl, $data,'post','',5);
+        return $result;
+    }
+}

+ 5 - 5
app/Services/MpService.php

@@ -164,10 +164,10 @@ class MpService extends BaseService
                 return false;
             }
 
-            $cacheKey = "caches:mpQrcode:mp_{$this->mpAppid}:";
+            $cacheKey = "caches:members:mp_{$this->mpAppid}:";
             $filePath = base_path('public/uploads');
             $qrFile = '/qrcodes/mp_'.date("YmdHis")."_".md5($page.$scene).".png";
-            $qrKey = md5($qrFile);
+            $qrKey = md5(date("Ym").$page.$scene);
             if(RedisService::get($cacheKey.$qrKey) && file_exists($filePath.'/'.$qrFile) && !$refresh){
                 return $qrFile;
             }
@@ -176,8 +176,9 @@ class MpService extends BaseService
                 @mkdirs($filePath.'/qrcodes/');
             }
 
+            $data=['page' => $page,'scene'=>$scene,'check_path'=>false,'env_version'=>$version];
             $url = sprintf($this->apiUrls['getQrcode'], $token, $scene, $page, $version);
-            $result = curl_post($url, '');
+            $result = curl_post($url, json_encode($data));
             $datas = $result? json_decode($result, true) : [];
             $this->saveLog($cacheKey.'qrcode:request', ['page'=>$page,'scene'=>$scene,'url'=>$url,'result'=>$result,'date'=>date('Y-m-d H:i:s')]);
             $errcode = isset($datas['errcode'])? $datas['errcode'] : '';
@@ -189,11 +190,10 @@ class MpService extends BaseService
 
             file_put_contents($filePath.'/'.$qrFile, $result);
             if(!file_exists($filePath.'/'.$qrFile)){
-                $this->error = '保存二维码失败';
+                $this->error = '生成二维码失败';
                 return false;
             }
 
-            $result['date'] = date('Y-m-d H:i:s');
             RedisService::set($cacheKey.$qrKey, ['page'=>$page,'scene'=>$scene,'qrcode'=>$qrFile,'date'=>date('Y-m-d H:i:s')], 30 * 86400);
             return $qrFile;
         }catch (\Exception $e){

+ 177 - 12
app/Services/PaymentService.php

@@ -15,6 +15,7 @@ use App\Models\AccountLogModel;
 use App\Models\MemberModel;
 use App\Models\OrderModel;
 use App\Models\PaymentModel;
+use App\Models\PayOrdersModel;
 use Illuminate\Support\Facades\DB;
 use Yansongda\Pay\Pay;
 use Yansongda\Pay\Provider\Wechat;
@@ -57,7 +58,7 @@ class PaymentService extends BaseService
 
     /**
      * 创建支付
-     * @param string $scene 场景,vip-VIP会员
+     * @param string $scene 场景,store-购物消费,pay-生活充值,refund-退款
      * @param int $payType
      * @param int $isMin 是否是小程序
      * @return false|\Yansongda\Pay\Provider\Alipay|Wechat
@@ -153,7 +154,7 @@ class PaymentService extends BaseService
      * @param string $scene
      * @return false|\Yansongda\Supports\Collection
      */
-    public function minPay($userInfo, $order, $scene = 'pay')
+    public function minPay($userInfo, $order, $scene = 'store')
     {
         $amount = isset($order['pay_money']) ? $order['pay_money'] : 0;
         $openid = isset($order['openid']) ? $order['openid'] : '';
@@ -230,7 +231,7 @@ class PaymentService extends BaseService
      * @param string $scene
      * @return false|\Yansongda\Supports\Collection
      */
-    public function wechatPay($userInfo, $order, $scene = 'pay')
+    public function wechatPay($userInfo, $order, $scene = 'store')
     {
         $amount = isset($order['pay_money']) ? $order['pay_money'] : 0;
         if ($amount < 0) {
@@ -298,7 +299,7 @@ class PaymentService extends BaseService
      * @param $order
      * @return bool
      */
-    public function aliPay($userInfo, $order, $scene = 'deposit')
+    public function aliPay($userInfo, $order, $scene = 'shop')
     {
         $amount = isset($order['pay_money']) ? $order['pay_money'] : 0;
         if ($amount < 0) {
@@ -351,7 +352,7 @@ class PaymentService extends BaseService
 
     /**
      * 订单支付回调处理
-     * @param string $scene 场景 deposit-保证金,depositRefund-保证金退款,withdraw-收入提现
+     * @param string $scene 场景 store-购物消费,pay-充值,refund-退款
      * @param int $payType 支付方式,10-微信支付,20-支付宝支付
      * @param array $data 回调数据
      * @return bool
@@ -422,7 +423,6 @@ class PaymentService extends BaseService
             $status = isset($paymentInfo['status']) ? $paymentInfo['status'] : 0;
             $totalFee = isset($paymentInfo['total_fee']) ? $paymentInfo['total_fee'] : 0;
             $paymentPayType = isset($paymentInfo['pay_type']) ? $paymentInfo['pay_type'] : 0;
-            $orderType = isset($paymentInfo['order_type']) ? $paymentInfo['order_type'] : 0;
             $orderNo = isset($paymentInfo['order_no']) ? $paymentInfo['order_no'] : '';
             $payUserId = isset($paymentInfo['user_id']) ? $paymentInfo['user_id'] : 0;
             if (empty($paymentInfo) || empty($orderNo) || $payUserId <= 0) {
@@ -464,7 +464,7 @@ class PaymentService extends BaseService
             // 商城订单支付
             if ($scene == 'store') {
                 $orderInfo = OrderModel::with(['member'])->where(['order_no' => $orderNo, 'mark' => 1])
-                    ->select(['id as order_id', 'user_id', 'expired_at', 'order_no', 'total as pay_money', 'pay_at as pay_time', 'remark', 'status'])
+                    ->select(['id as order_id', 'user_id', 'order_no', 'total as pay_money', 'pay_at as pay_time', 'remark', 'status'])
                     ->first();
                 $orderStatus = isset($orderInfo['status']) ? $orderInfo['status'] : 0;
                 // 验证订单
@@ -488,6 +488,33 @@ class PaymentService extends BaseService
                     return false;
                 }
             }
+            // 生活充值
+            else if ($scene == 'pay') {
+                $orderInfo = PayOrdersModel::where(['order_no' => $orderNo, 'mark' => 1])
+                    ->select(['id as order_id', 'user_id','meal_id','product_id', 'order_no','transaction_id','account', 'total as pay_money', 'pay_at as pay_time', 'remark', 'status'])
+                    ->first();
+                $orderStatus = isset($orderInfo['status']) ? $orderInfo['status'] : 0;
+                // 验证订单
+                if (empty($orderInfo)) {
+                    DB::rollBack();
+                    $this->error = 2629;
+                    return false;
+                }
+
+                // 订单状态
+                if ($orderStatus != 1) {
+                    DB::rollBack();
+                    $this->error = 2630;
+                    return false;
+                }
+
+                $updateData = ['pay_at' => $payAt, 'transaction_id' => $transactionId, 'status' => 2, 'update_time' => time()];
+                if (!PayOrdersModel::where(['order_no' => $orderNo, 'mark' => 1])->update($updateData)) {
+                    $this->error = 2633;
+                    DB::rollBack();
+                    return false;
+                }
+            }
             // 退款
             else if ($scene == 'refund') {
                 $orderInfo = OrderModel::where(['order_no' => $orderNo, 'mark' => 1])
@@ -526,15 +553,62 @@ class PaymentService extends BaseService
 
             // TODO 场景业务回调处理
             $orderUserId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0;
-            RedisService::set("caches:payments:notify_{$scene}:catch_{$orderNo}_{$orderUserId}", ['order' => $orderInfo, 'notify' => $data], 7200);
+            $this->saveLog("caches:payments:notify_{$scene}:catch_{$orderNo}_{$orderUserId}", ['order' => $orderInfo, 'notify' => $data]);
             switch ($scene) {
                 case 'store': //
                     break;
+                case 'pay': //
+                    // 调起 接口充值
+                    $orderId = isset($orderInfo['order_id'])? $orderInfo['order_id'] : 0;
+                    $productId = isset($orderInfo['product_id'])? $orderInfo['product_id'] : '';
+                    $orderNo = isset($orderInfo['order_no'])? $orderInfo['order_no'] : '';
+                    $account = isset($orderInfo['account'])? $orderInfo['account'] : '';
+                    $total = isset($orderInfo['pay_money'])? $orderInfo['pay_money'] : 0;
+                    $amount = $total;
+                    if(env('PAY_DEBUG')){
+                        $amount = 50;
+                    }
+
+                    $result = DyrPayService::make()->recharge($orderNo, $account, $productId, $amount);
+                    $errno = isset($result['errno'])?$result['errno'] : -1;
+                    $errmsg = isset($result['errmsg'])?$result['errmsg'] : '';
+                    $res = isset($result['data'])?$result['data']:[];
+                    $order_number = isset($res['order_number'])?$res['order_number']:'';
+                    $total_price = isset($res['total_price'])?$res['total_price']:'';
+                    if(empty($result) || $errno != 0 || empty($order_number)){
+
+                        $this->error = '充值调用失败:'.$errmsg;
+
+                        // 退款
+                        $orderInfo['money'] = $total;
+                        $orderInfo['remark'] = '充值失败退款';
+                        $refundStatus = PaymentService::make()->refund($orderInfo,'pay');
+                        $updateData = ['refund_status'=> $refundStatus?1:3,'status'=>5,'failed_remark'=> $errmsg,'refund_money'=>$refundStatus?$total:0,'update_time'=>time()];
+                        $this->saveLog("caches:payments:notify_{$scene}:pay_failed_{$orderNo}_{$orderUserId}", ['error'=>$this->error,'update'=>$updateData,'order' => $orderInfo,'result'=>$result, 'notify' => $data]);
+                        if(!PayOrdersModel::where(['id'=>$orderId])->update($updateData)){
+                            $this->error = '订单退款状态更新错误~';
+                        }
+
+                        DB::commit();
+                        return false;
+                    }
+
+                    $updateData = ['status'=>3,'out_trade_no'=>$order_number,'pay_total'=>$total_price,'update_time'=>time()+1];
+                    $this->saveLog("caches:payments:notify_{$scene}:pay_success_{$orderNo}_{$orderUserId}", ['error'=> '充值调用成功','id'=>$orderId,'update'=>$updateData,'order' => $orderInfo,'result'=>$result, 'notify' => $data]);
+                    if(!PayOrdersModel::where(['id'=>$orderId])->update($updateData)){
+                        DB::commit();
+                        $this->error = '更新充值订单失败';
+                        $this->saveLog("caches:payments:notify_{$scene}:pay_failed_{$orderNo}_{$orderUserId}", ['error'=>$this->error,'update'=>$updateData,'order' => $orderInfo,'result'=>$result, 'notify' => $data]);
+                        return false;
+                    }
+
+                    DB::commit();
+                    return true;
                 default:
                     break;
             }
 
-            $this->error = 2638;
+            $this->error = '回调处理成功';
             DB::commit();
             return true;
         } catch (\Exception $exception) {
@@ -545,6 +619,97 @@ class PaymentService extends BaseService
     }
 
     /**
+     * 充值回调
+     * @param $productId
+     * @param $data
+     * @return bool
+     * @throws \Yansongda\Pay\Exception\ContainerException
+     * @throws \Yansongda\Pay\Exception\InvalidParamsException
+     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
+     */
+    public function catchPayNotify($productId, $data)
+    {
+        $out_trade_num = isset($data['out_trade_num'])?$data['out_trade_num']:'';
+        $state = isset($data['state'])? intval($data['state']) : 0;
+        $charge_kami = isset($data['charge_kami'])?$data['charge_kami'] : '';
+        $amount = isset($data['charge_amount'])?floatval($data['charge_amount']) : 0;
+        if($state<=0){
+            $this->error = '充值处理中~';
+            return false;
+        }
+
+        $orderInfo = PayOrdersModel::where(['order_no'=>$out_trade_num,'mark'=>1])->first();
+        $orderId = isset($orderInfo['id'])? $orderInfo['id'] : 0;
+        $status = isset($orderInfo['status'])? $orderInfo['status'] : 0;
+        $total = isset($orderInfo['total'])? $orderInfo['total'] : 0;
+        if(empty($orderInfo) || $orderId<=0 || $total<=0){
+            $this->error = '充值订单不存在';
+            $this->saveLog("caches:payments:payNotify_{$productId}:notify_{$out_trade_num}_error", ['error'=>$this->error,'order' => $orderInfo, 'notify' => $data]);
+            return false;
+        }
+
+        if($status!=3){
+            $this->error = '充值订单状态错误,状态非充值中';
+            $this->saveLog("caches:payments:payNotify_{$productId}:notify_{$out_trade_num}_error", ['error'=>$this->error,'order' => $orderInfo, 'notify' => $data]);
+            return false;
+        }
+
+        // 成功
+        $status = 4;
+        $refundAmount = 0;
+        if($state == 1){
+            $this->error = '充值成功~';
+        }
+        //部分成功,退部分
+        else if($state == 3) {
+            $status = 6;
+            $refundAmount = moneyFormat($total - $amount,2);
+            $this->error = '充值成功部分退款';
+        }
+        //失败,退全款
+        else if(in_array($state,[-1,2])){
+            $status = 5;
+            $refundAmount = $total;
+            $this->error = '充值失败退款';
+        }
+
+        // 更新订单状态
+        $this->saveLog("caches:payments:payNotify_{$productId}:notify_{$out_trade_num}", ['error'=>$this->error,'order' => $orderInfo, 'notify' => $data]);
+        if(!PayOrdersModel::where(['id'=>$orderId])->update(['status'=>$status,'charge_kami'=>$charge_kami,'refund_status'=>$status!=4?2:0,'charge_amount'=>$amount,'update_time'=>time()])){
+            $this->error = '更新订单状态错误~';
+            return false;
+        }
+
+        // 是否要退款
+        if($refundAmount>0){
+            $orderInfo['money'] = $refundAmount;
+            $orderInfo['remark'] = $this->error;
+            $refundStatus = PaymentService::make()->refund($orderInfo,'pay');
+            if(!PayOrdersModel::where(['id'=>$orderId])->update(['refund_status'=> $refundStatus?1:3,'refund_money'=>$refundStatus?$refundAmount:0,'update_time'=>time()])){
+                $this->saveLog("caches:payments:payNotify_{$productId}:notify_{$out_trade_num}_error", ['error'=>$this->error,'order' => $orderInfo, 'notify' => $data]);
+                $this->error = '订单退款状态更新错误~';
+                return false;
+            }
+
+        }
+
+        $this->error = '充值订单处理成功~';
+        return true;
+    }
+
+    /**
+     * 日志
+     * @param $key
+     * @param $data
+     */
+    public function saveLog($key, $data)
+    {
+        if(env('APP_DEBUG')){
+            RedisService::set($key,$data,7200);
+        }
+    }
+
+    /**
      * 退款请求
      * @param $order
      * @param string $scene
@@ -553,10 +718,10 @@ class PaymentService extends BaseService
      * @throws \Yansongda\Pay\Exception\InvalidParamsException
      * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
      */
-    public function refund($order, $scene = 'vip')
+    public function refund($order, $scene = 'store')
     {
         $money = isset($order['money']) ? $order['money'] : 0;
-        $payType = isset($order['pay_type']) ? $order['pay_type'] : 0;
+        $payType = isset($order['pay_type']) && $order['pay_type']? $order['pay_type'] : 10;
         $orderNo = isset($order['order_no']) ? $order['order_no'] : '';
         $outTradeNo = isset($order['out_trade_no']) ? $order['out_trade_no'] : '';
         $transactionId = isset($order['transaction_id']) ? $order['transaction_id'] : '';
@@ -565,7 +730,7 @@ class PaymentService extends BaseService
         $pay = PaymentService::make()->createPay($scene, $payType);
         if (empty($pay)) {
             DB::rollBack();
-            $this->error = 2171;
+            $this->error = '创建退款支付失败';
             return false;
         }
         // 保证金退款处理

+ 1 - 1
config/database.php

@@ -148,7 +148,7 @@ return [
             'host' => env('REDIS_HOST', '127.0.0.1'),
             'password' => env('REDIS_PASSWORD', null),
             'port' => env('REDIS_PORT', '6379'),
-            'database' => env('REDIS_CACHE_DB', '1'),
+            'database' => env('REDIS_DB', '0'),
         ],
 
     ],

+ 24 - 5
config/payment.php

@@ -1,11 +1,30 @@
 <?php
 return [
     'accountTypes'=>[
-        1=>'订单收入',
-        2=>'充值保证金',
-        3=>'退保申请',
-        4=>'收入提现',
+        1=>'商城消费',
+        2=>'充值缴费',
+        3=>'退',
+        4=>'佣金提现',
         5=>'提现驳回',
+        6=>'平台入款',
+        7=>'商家佣金',
+        8=>'代理收益',
+        9=>'推广收益',
+    ],
+    'kdCodes'=>[
+        'jd'=>'京东快递',
+        'shentong'=>'申通快递',
+        'shunfengkuaiyun'=>'顺丰快运',
+        'shunfeng'=>'顺丰',
+        'yuantong'=>'圆通快递',
+        'zhongtong'=>'中通快递',
+        'jtexpress'=>'极兔速递',
+        'yunda'=>'韵达快递',
+        'debangkuaidi'=>'德邦快递',
+        'debangwuliu'=>'德邦物流',
+        'huitongkuaidi'=>'百世快递',
+        'youzhengguonei'=>'邮政快递包裹',
+        'zhaijisong'=>'宅急送',
     ],
     'wechat' => [
         'wechat'=>[
@@ -22,7 +41,7 @@ return [
                 'wechat_public_cert_path' => [
                     //前面是证书***,登录商户平台【API安全】->【API证书】->【查看证书】,可查看商户API证书***
                     //后面是通过前面的配置生成的文件 参考:http://www.liziyu.com/archives/309/
-                    'PUB_KEY_ID_0117250041532025081400112188001803' => base_path().'/resources/certs/wechat/pub_key.pem',
+                    'PUB_KEY_ID_0111032309772025121600111926001205' => base_path().'/resources/certs/wechat/pub_key.pem',
                 ],
                 // 必填
                 'notify_url' => '',

BIN
public/uploads/images/base64/20251226/image_e27537109140362782f1dbc5beeb8b80.jpeg


BIN
public/uploads/temp/20210410081010.xlsx


BIN
public/uploads/temp/20251226/Mi5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMjU3MS5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzA0MS5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAwMS5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAwMi5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAwMy5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAwNC5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAxMS5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAxMi5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAxMy5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAxNi5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAyMi5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAyNC5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAyNS5wbmc.png


BIN
public/uploads/temp/20251226/MjAyNTEyMjYwMzAyNi5wbmc.png


BIN
public/uploads/temp/20251226/My5wbmc.png


BIN
public/uploads/temp/20251226/NC5wbmc.png


BIN
resources/certs/wechat/apiclient_cert.p12


+ 17 - 17
resources/certs/wechat/apiclient_cert.pem

@@ -1,25 +1,25 @@
 -----BEGIN CERTIFICATE-----
-MIIEJDCCAwygAwIBAgIUSOv+i4QZUBvc0mKBltA02WiuHFswDQYJKoZIhvcNAQEL
+MIIEJDCCAwygAwIBAgIUQ0WVnjc8u5rstN9KiGdfG/lUVB8wDQYJKoZIhvcNAQEL
 BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
 FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
-Q0EwHhcNMjUwODE1MTE0NzU1WhcNMzAwODE0MTE0NzU1WjB+MRMwEQYDVQQDDAox
-NzI1MDA0MTUzMRswGQYDVQQKDBLlvq7kv6HllYbmiLfns7vnu58xKjAoBgNVBAsM
-IeS6s+W3nuW4guS4sOiDnOWVhui0uOaciemZkOWFrOWPuDELMAkGA1UEBhMCQ04x
+Q0EwHhcNMjUxMjE2MDUyMTAzWhcNMzAxMjE1MDUyMTAzWjB+MRMwEQYDVQQDDAox
+MTAzMjMwOTc3MRswGQYDVQQKDBLlvq7kv6HllYbmiLfns7vnu58xKjAoBgNVBAsM
+IeW5v+ilv+aCpuiOseebiuenkeaKgOaciemZkOWFrOWPuDELMAkGA1UEBhMCQ04x
 ETAPBgNVBAcMCFNoZW5aaGVuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEA1V/u0pTbyBYI+qw7MexFU3ahHvKf3ih0UQ3ue4d0ru/ZZ42qigwC4Tbo+fpJ
-2GNqRiJew8OZY6HWLOBiwBy2aXkxLH2dDcWgDHekhVGZag57kFMiNgvb/LeS0OpC
-bsFj5HgvSU+s9IrgmdImXJlaJSJROb2mFiTmbTy/OzP08GXFpaog/cR59JGTVlLW
-S5C9WhSWiIzpMEqpE7VSM9dffBstvVoXW8jT1NrREnG3Zq6fLwpkVKjXwuQhyJXD
-PZHcghiqr2E1F4R8J/apYd6969KflhMyCn5l/p7kA6clyJml3Ju5i3ZdKAMdMRMt
-RoBrJxdavij9YR7m2Zn1EvItjwIDAQABo4G5MIG2MAkGA1UdEwQCMAAwCwYDVR0P
+AQEA0VfC/ciZ/VC9AzGIFKb69vLB/zt0FTD7pyrUqjTO1aqkyCyAuBoMyKKs2wJF
+FxfELxrlbrQZSuBqoGx0dOMthBiphJIGAjHl2nKdEL9zno/sTn1/6O8ba3YF8Tqs
+t4CxhoCyudig9yvAwZdSegw7hQHy0sgPH7+8nNHReWAJ3WydeYjFVhwG1qIztIPu
+WKmCzKNeNe2vCYKjiYsYLy1NdKLZMrIiH59jKNuQHzm2X7SF0Mur+1HnUr47kyD1
+hHfZXMvv/FG56oPTl1n0GO01j1JDh+/5ePncuH59ME79hOMLcgLc4zdcuoCafYY9
+9nrilYvdcFe7sMCQXbRGrHJnwwIDAQABo4G5MIG2MAkGA1UdEwQCMAAwCwYDVR0P
 BAQDAgP4MIGbBgNVHR8EgZMwgZAwgY2ggYqggYeGgYRodHRwOi8vZXZjYS5pdHJ1
 cy5jb20uY24vcHVibGljL2l0cnVzY3JsP0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFE
 Mzk3NTQ5ODQ2QzAxQzNFOEVCRDImc2c9SEFDQzQ3MUI2NTQyMkUxMkIyN0E5RDMz
-QTg3QUQxQ0RGNTkyNkUxNDAzNzEwDQYJKoZIhvcNAQELBQADggEBABcrQNMXiJ36
-qmcdl88RvLlhHU8N/kIxo31MNZDEbCIpS/ncMyJLyoDEMp6LK30IopE5SOT+E9/K
-b3qX0lXJYrNYos0y7xnRssPsM0JtVOHVk/3WcJ5bxz4yeEqoUT02IeLewo3vVGkV
-/liXFr1MDmU2pOzXMVYDOpN/47NtBzWdGEUShuJQUOl5WFw4UiPlObvFUs1LiY1O
-am/l7k6fLAR8giMUlEqoiFgZi/JpzbWkgv6T2VnkzqYJqjYOdZgimoztTYVDkR6D
-IyfHkQ03S8F3PMOegRhrrtXB9njjjSg3RULf/wXtG6KAA7Up3nOQQ2HjdHK0LQlG
-RX2ji/DUFQs=
+QTg3QUQxQ0RGNTkyNkUxNDAzNzEwDQYJKoZIhvcNAQELBQADggEBAJY/I6kroFiQ
+gw/hphUExwhuwwYivZ1uzySysIprblq/cSAaqaVyUnymSNhq74jegJXMtT+9FmrI
+vihZplQcux06G1xKGSbpu/KqDXxkpp+Gntmet+oWxWeAq+/zrbQ6mfGBeknqsQNm
+0b/zSn5N1issjTZvif6uqs6Qc44Ltdn3Mt05AIZenyUbKaYiz2MNMNA5ZM670RoH
+RsHwuTNebMcbFku8eb6aRfd4TN/zrk1qiEY+veQu7Vvdghy4Juzh369PIaMJwv5r
+H5JSbR5GeRCF3YO43SBdoCE+xh1B6eppuDrgnNBfg7KtrQcd/Jbo/zNBOtxvrXvP
+bICiOw5urmc=
 -----END CERTIFICATE-----

+ 26 - 26
resources/certs/wechat/apiclient_key.pem

@@ -1,28 +1,28 @@
 -----BEGIN PRIVATE KEY-----
-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDVX+7SlNvIFgj6
-rDsx7EVTdqEe8p/eKHRRDe57h3Su79lnjaqKDALhNuj5+knYY2pGIl7Dw5ljodYs
-4GLAHLZpeTEsfZ0NxaAMd6SFUZlqDnuQUyI2C9v8t5LQ6kJuwWPkeC9JT6z0iuCZ
-0iZcmVolIlE5vaYWJOZtPL87M/TwZcWlqiD9xHn0kZNWUtZLkL1aFJaIjOkwSqkT
-tVIz1198Gy29WhdbyNPU2tEScbdmrp8vCmRUqNfC5CHIlcM9kdyCGKqvYTUXhHwn
-9qlh3r3r0p+WEzIKfmX+nuQDpyXImaXcm7mLdl0oAx0xEy1GgGsnF1q+KP1hHubZ
-mfUS8i2PAgMBAAECggEAUReLgTaXrJxLP1Fzkc6Urlq4czWMcnb3ddKQnxvkyZNY
-EZXyiVJ1Sbh/pHlt1TI7Mnpff5D327im2BlTDmYbIUyw1pLKvHAuGm7h9NUFNBxa
-84fUyauKKKpvvrw5ETSoTS0r83W3apzZLTyD3c9eRhybuBEObP4LINrkZpChdzbU
-Jk6U7E81/iOIWKPm2n821I00isN7czJQA3wFiQPA2qBLxpQLBoJyQrZtMZePgmAU
-rW1hHgvonL6ahKO75mHLsQMzUFI9IeUChwa6ouRoOHI+Y/hvAp2paNFcqwPUvj5B
-A543VCfHymh2xQQV5MyK19jHY/y3ygklB2woWrpcoQKBgQD/SpESKjndw2WAZMI0
-5sO7IyCJTlD3F1Wmwsp1nB269W4aTceeNSKfuJmXrZMomU7Y3V+zh7WFW77ihMsQ
-l3RuxttpbtxBAaKtRQVPd1IU8trvgpDYKyyel/jAyqKOzWmhRnoUlAaM5xllR7OJ
-yLvqTS45sHT9191JQWewk2dHnwKBgQDV95OVF4+5v6oJ//EQ6JPOkaXqYnPgrd7e
-GQDjQ0v5qsWN9sYgHX8rT4FZ34BjOSKmRCkbeVjX8Ply6RLQjq8HhC4Mzp7cN9G/
-zDRmTi0KXD1/zrK9vtVUbHgDn6F1bAhHlNA9x49D9CcJWfZ+Q8NV1TJj0sbhsNFj
-Czp7b8IUEQKBgFSPknX93qUCMADTXzC+r16xR/mzI0Z1SD2wj/dc+swOt6Wm1dQl
-rY5SSy3epLvx7BgRW73P2eSOey/05H5ebIa0/8BwpCw0KnpSPmwQDfQ6bSKgkPHJ
-e0Ic/Jx/glDi4XY2LgHa9kB92/+cPHALOZNmdUVOmbHrarT1IS9v4+npAoGAJ/b7
-QODKvqYXC5EbpM3cNbwsok/LVw8Czrca3FgIi9Si27ZZIUyBIUTTY0cEwwO7/hRD
-HVeYCZV/8j+ofP35oUzGESxSrc1bRxjMPMOjVAkQj5u69Qf87qzn6b1aOgV4sm4Q
-S0nH76hd1jhQexsLFDAjHlQTQ7p0EazaOo4QURECgYATk4auSeajv+oI3dgSW80/
-4odNlxYSARLrBv43/0sexF2zxXDgv8gQlhj9LUKZ5iWR3JLuhUmZe7kXau/HiW/e
-2mqMLccJJ0KBgda1q1JprE5A7cp3y4MXmwuiPJC+4lqf1ZU0K4IwaDVS86syvzVU
-sjj0o4D/BdETHnD9mCt9WQ==
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRV8L9yJn9UL0D
+MYgUpvr28sH/O3QVMPunKtSqNM7VqqTILIC4GgzIoqzbAkUXF8QvGuVutBlK4Gqg
+bHR04y2EGKmEkgYCMeXacp0Qv3Oej+xOfX/o7xtrdgXxOqy3gLGGgLK52KD3K8DB
+l1J6DDuFAfLSyA8fv7yc0dF5YAndbJ15iMVWHAbWojO0g+5YqYLMo1417a8JgqOJ
+ixgvLU10otkysiIfn2Mo25AfObZftIXQy6v7UedSvjuTIPWEd9lcy+/8Ubnqg9OX
+WfQY7TWPUkOH7/l4+dy4fn0wTv2E4wtyAtzjN1y6gJp9hj32euKVi91wV7uwwJBd
+tEascmfDAgMBAAECggEAU5Wd9mR9D4aIIVlKgyx0sdsVmEntvHRVVlakmN0C5I8A
+wif6sQc9qXJCYCOU4HaNz10G1F+2ZY4bJLiI+w6l4sNSE+uV2JSBuOngSoqWqG3A
+pUo4oxGtOgfisYGC6rXIq/KA6fFTu7zNdr5roO13alDv2jckysFslpSz9alh5vU4
+WjjSRfLvP/rMvGR1175TgOaxqm2Mtoh1u3tDG4elnTPLhVikdBazuXavMlvV5NG7
+14eJnHaF+sCoekwNfhRdULp9ynB8iTeCVCvMxSk38UPAE8V/HaIcdKiQGv6Amg/m
+gBlr3yvYet3OL11wM//N7qlCFqwI9kfEBtdERkmMAQKBgQD/j2ry/2+XkiQqhuzk
+n84p9ltqqkBnSuqcCm9j30UtAb/I6ma67TlISNFgKQ3q5XGZFBDJkc8h8+4N6z77
+GHk7TiUvTY2QUXJtVniDV5d/UOX9wVm/0kgBk/2R+7I3LKi0uyOG33HYuSyhZXXU
+QIYjhfdodTHtF55y3+eT5nUqAQKBgQDRs/vUXa+pQ416CVnFxmUxBsjo0mh7i92d
+izXR7aLAedbCR1WM5QVmE++wC1oEviHFvQUR5n3JdQPcgO4fEaClEipczjUF5slC
+/1xKRJ4Cc32a8bTAEBaTCrRuI9P8aVgBinJ3sWEVY1ghY8poYr+2Ls5vccJm/+Pc
+aCfyOPlpwwKBgDaNwQDaclHiyoGhh9ROIM5oXp9odJMYNPjWaWzibnvrEausDf39
+QesiUD+8w9HO5O8Oj37X92WCEuE5xJoJYWe9iMaOQZf7KvgYK2WuPxLYjCAdNDF0
+jBZ6JvkQx7xrdiAOisjxzfW7ocFaTUrf80KGCIht7Bh2oEZZca/q1DwBAoGBAJ8M
+LVIShGqSi7klYms4YANhK/w5qXkaycj1jqpb2/az8giD5gTopsGXGVGiKnIyapb5
+F+FNudWT5IvXVcNGsVrBflPJKjoBomAoIa1KgbVGNtvPutF44kY/9j0a+2sT0uXI
+Ra02YXXBVVRtxVSKoPDiazvnQhSwu/etH679O13VAoGBAJ3wngGP+IndoL7gW+wm
+R6wN/suvbQE1tf5tLhIVe4fn8SFWWzx1bFBYPY7lNhHDQXxk8UpP2fmvQZW9ADPQ
+fL5plRzMb4x/z5y2oTxmPXZyEE9OC7Jx7civV6FiyXbZOq9BrZldmZGsFocnNsBg
+K9FqLWqgqiHaXvTf/zx7+s6s
 -----END PRIVATE KEY-----

+ 9 - 0
resources/certs/wechat/pub_key.pem

@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAopUi58QtwTrGJP1yCfL/
+65ICHlTkedsN1zghhh9eurBD4jX41BNL7YnFVXrV8+TDPlc7xqIzwZNWbOmNeIlj
+XGE81kKUxRkTh4laVpZvVmIYOmz9QiTcJbqXrEfMn4yLGJlz5fXbDesqzs/JGbdH
+mAHWZ2rdPD4QxvuF8LgvKgQtlIKdG2SO7XjQiAyZAYA4r5YZF2/fQix58UEasVvv
+00kcxSNYKOPsQbAvPUhxmu3LfH5xlaRRooinV93M42MFyrmYpD9LLYxUlM1xVr/P
+WxlVWmoJX8wl5MvckB7GRBkNcmUoqi8g+kvsaIkSf5qtX2S/e/mmGVk+OJAuTgms
+9QIDAQAB
+-----END PUBLIC KEY-----

+ 17 - 2
routes/api.php

@@ -53,19 +53,31 @@ Route::prefix('v1')->middleware('web.login')->group(function() {
     // 用户信息
     Route::get('/user/info', [\App\Http\Controllers\Api\v1\MemberController::class, 'info']);
     Route::post('/user/setEntry', [\App\Http\Controllers\Api\v1\MemberController::class, 'setEntry']);
+    Route::post('/user/account', [\App\Http\Controllers\Api\v1\MemberController::class, 'account']);
+    Route::post('/user/bindAccount', [\App\Http\Controllers\Api\v1\MemberController::class, 'bindAccount']);
     Route::post('/user/modify', [\App\Http\Controllers\Api\v1\MemberController::class, 'modify']);
     Route::post('/user/logOff', [\App\Http\Controllers\Api\v1\MemberController::class, 'logOff']);
 
-    // 账户
+    // 账户明细
     Route::post('/account/index', [\App\Http\Controllers\Api\v1\AccountController::class, 'index']);
     Route::post('/account/withdraw', [\App\Http\Controllers\Api\v1\AccountController::class, 'withdraw']);
     Route::post('/account/balance', [\App\Http\Controllers\Api\v1\AccountController::class, 'balance']);
 
+    // 生活充值
+    Route::post('/account/payMeal', [\App\Http\Controllers\Api\v1\AccountController::class, 'payMeal']);
+    Route::post('/account/pay', [\App\Http\Controllers\Api\v1\AccountController::class, 'pay']);
+    Route::post('/account/payLog', [\App\Http\Controllers\Api\v1\AccountController::class, 'payLog']);
+
     // 订单列表
     Route::post('/order/index', [\App\Http\Controllers\Api\v1\OrderController::class, 'index']);
     Route::get('/order/info', [\App\Http\Controllers\Api\v1\OrderController::class, 'info']);
     Route::post('/order/count', [\App\Http\Controllers\Api\v1\OrderController::class, 'count']);
     Route::post('/order/submit', [\App\Http\Controllers\Api\v1\OrderController::class, 'submit']);
+    Route::post('/order/pay', [\App\Http\Controllers\Api\v1\OrderController::class, 'pay']);
+    Route::post('/order/complete', [\App\Http\Controllers\Api\v1\OrderController::class, 'complete']);
+    Route::post('/order/after', [\App\Http\Controllers\Api\v1\OrderController::class, 'after']);
+    Route::post('/order/cancel', [\App\Http\Controllers\Api\v1\OrderController::class, 'cancel']);
+    Route::post('/order/logistics', [\App\Http\Controllers\Api\v1\OrderController::class, 'logistics']);
 
     // 购物车
     Route::post('/cart/index', [\App\Http\Controllers\Api\v1\CartController::class, 'index']);
@@ -77,6 +89,7 @@ Route::prefix('v1')->middleware('web.login')->group(function() {
     // 商品
     Route::post('/goods/index', [\App\Http\Controllers\Api\v1\GoodsController::class, 'index']);
     Route::post('/goods/info', [\App\Http\Controllers\Api\v1\GoodsController::class, 'info']);
+    Route::post('/goods/collect', [\App\Http\Controllers\Api\v1\GoodsController::class, 'collect']);
 
     // 店铺
     Route::post('/store/index', [\App\Http\Controllers\Api\v1\StoreController::class, 'index']);
@@ -89,7 +102,8 @@ Route::prefix('v1')->middleware('web.login')->group(function() {
     // 收货地址
     Route::post('/address/index', [\App\Http\Controllers\Api\v1\AddressController::class, 'index']);
     Route::post('/address/info', [\App\Http\Controllers\Api\v1\AddressController::class, 'info']);
-    Route::post('/address/default', [\App\Http\Controllers\Api\v1\AddressController::class, 'setDefault']);
+    Route::post('/address/bindInfo', [\App\Http\Controllers\Api\v1\AddressController::class, 'getBindInfo']);
+    Route::post('/address/setDefault', [\App\Http\Controllers\Api\v1\AddressController::class, 'setDefault']);
     Route::post('/address/save', [\App\Http\Controllers\Api\v1\AddressController::class, 'save']);
     Route::post('/address/delete', [\App\Http\Controllers\Api\v1\AddressController::class, 'delete']);
 
@@ -107,6 +121,7 @@ Route::prefix('v1')->middleware('web.login')->group(function() {
 
 // 回调处理
 Route::match(['get','post'],'/notify/refund/{payType}', [\App\Http\Controllers\Api\v1\NotifyController::class, 'refund']);
+Route::match(['get','post'],'/notify/dry', [\App\Http\Controllers\Api\v1\NotifyController::class, 'payCallback']);
 Route::match(['get','post'],'/notify/{scene}/{payType}', [\App\Http\Controllers\Api\v1\NotifyController::class, 'callback']);
 
 Route::match(['get','post'],'/test/check', [\App\Http\Controllers\Api\v1\TestController::class, 'check']);

+ 89 - 0
物流.txt

@@ -0,0 +1,89 @@
+
+        'array:3 [
+  "customer" => "1DC402CCEE1390AE319DD82172992F6E"
+  "param" => "{"com":"yuantong","num":"YT8824762286422","phone":"17877188025","from":"","to":"","resultv2":"1","show":"0","order":"desc"}"
+  "sign" => "240CC64180AFAB00613BCD4792A357BF"
+]
+array:8 [
+  "message" => "ok"
+  "nu" => "YT8824762286422"
+  "ischeck" => "1"
+  "com" => "yuantong"
+  "status" => "200"
+  "data" => array:9 [
+    0 => array:6 [
+      "time" => "2025-12-24 11:29:23"
+      "context" => "您的快件已投递,收件人在[沙岗镇绕城路天猫1号店妈妈驿站]取件(凭取件码签收),如有疑问请联系站点:13086796129,快递员电话:13086796129,投诉电话:15278929512。感谢使用圆通速递,期待再次为您服务!"
+      "ftime" => "2025-12-24 11:29:23"
+      "areaCode" => "CN450521000000"
+      "areaName" => "广西,北海市,合浦县"
+      "status" => "签收"
+    ]
+    1 => array:6 [
+      "time" => "2025-12-22 17:29:40"
+      "context" => "您的快件已到达[妈妈驿站]沙岗镇绕城路1号天猫店,请您及时取件,如有取件码问题或找不到包裹等问题,请联系站点:13086796129,快递员电话:13086796129,投诉电话:15278929512。感谢使用圆通速递,期待再次为您服务!"
+      "ftime" => "2025-12-22 17:29:40"
+      "areaCode" => "CN450521000000"
+      "areaName" => "广西,北海市,合浦县"
+      "status" => "派件"
+    ]
+    2 => array:6 [
+      "time" => "2025-12-22 17:28:40"
+      "context" => "【广西北海市合浦县沙岗镇】的莫业琨(13086796129)正在派件,(有事先呼我,勿找平台,少一次投诉,多一份感恩)!如有疑问请联系网点:15278929512,投诉电话:15278929512。[95161和18521号段的上海号码为圆通快递员专属号码,请放心接听]"
+      "ftime" => "2025-12-22 17:28:40"
+      "areaCode" => "CN450521100000"
+      "areaName" => "广西,北海市,合浦县,廉州镇"
+      "status" => "派件"
+    ]
+    3 => array:6 [
+      "time" => "2025-12-22 02:44:12"
+      "context" => "您的快件离开【南宁转运中心】,已发往【广西北海市合浦】"
+      "ftime" => "2025-12-22 02:44:12"
+      "areaCode" => "CN450108000000"
+      "areaName" => "广西,南宁市,良庆区"
+      "status" => "在途"
+    ]
+    4 => array:6 [
+      "time" => "2025-12-22 02:21:21"
+      "context" => "您的快件已经到达【南宁转运中心】【物流问题无需找商家或平台,请致电(专属热线:95554)更快解决】"
+      "ftime" => "2025-12-22 02:21:21"
+      "areaCode" => "CN450108000000"
+      "areaName" => "广西,南宁市,良庆区"
+      "status" => "在途"
+    ]
+    5 => array:6 [
+      "time" => "2025-12-20 23:47:58"
+      "context" => "您的快件离开【临海转运中心】,已发往【南宁转运中心】。预计【12月22日】到达【南宁市】,因运输距离较远,预计将在【22日晚上】为您更新快件状态,请您放心!"
+      "ftime" => "2025-12-20 23:47:58"
+      "areaCode" => "CN331082000000"
+      "areaName" => "浙江,台州市,临海市"
+      "status" => "在途"
+    ]
+    6 => array:6 [
+      "time" => "2025-12-20 23:45:58"
+      "context" => "您的快件已经到达【临海转运中心】【物流问题无需找商家或平台,请致电(专属热线:95554)更快解决】"
+      "ftime" => "2025-12-20 23:45:58"
+      "areaCode" => "CN331082000000"
+      "areaName" => "浙江,台州市,临海市"
+      "status" => "在途"
+    ]
+    7 => array:6 [
+      "time" => "2025-12-20 22:59:54"
+      "context" => "您的快件离开【浙江省台州市临海市】,已发往【临海转运中心】"
+      "ftime" => "2025-12-20 22:59:54"
+      "areaCode" => "CN331082001000"
+      "areaName" => "浙江,台州市,临海市,古城"
+      "status" => "在途"
+    ]
+    8 => array:6 [
+      "time" => "2025-12-20 22:01:39"
+      "context" => "您的快件在【浙江省台州市临海市】已揽收,揽收人: 尤福伟(13958563820)【物流问题无需找商家或平台,请致电(057685125900)(专属热线:95554)更快解决】"
+      "ftime" => "2025-12-20 22:01:39"
+      "areaCode" => "CN331082001000"
+      "areaName" => "浙江,台州市,临海市,古城"
+      "status" => "揽收"
+    ]
+  ]
+  "state" => "3"
+  "condition" => "B00"
+]'