jun 6 päivää sitten
vanhempi
sitoutus
241d78f74c
100 muutettua tiedostoa jossa 6405 lisäystä ja 0 poistoa
  1. 131 0
      .env
  2. 13 0
      .styleci.yml
  3. 77 0
      app/Console/Commands/CollectEquipmentHeartbeatCheckCommand.php
  4. 160 0
      app/Console/Commands/CollectTaskAllocateAgainCommand.php
  5. 165 0
      app/Console/Commands/CollectTaskAllocateCommand.php
  6. 91 0
      app/Console/Commands/CollectTaskCommand.php
  7. 52 0
      app/Console/Kernel.php
  8. 68 0
      app/Events/ExternalAndFollowOperateEvent.php
  9. 93 0
      app/Events/ExternalAndGroupOperateEvent.php
  10. 64 0
      app/Exceptions/Api/ApiException.php
  11. 11 0
      app/Exceptions/Api/LoginException.php
  12. 15 0
      app/Exceptions/Api/ValidException.php
  13. 15 0
      app/Exceptions/Api/VerifySignException.php
  14. 13 0
      app/Exceptions/Company/ShopException.php
  15. 80 0
      app/Exceptions/Handler.php
  16. 21 0
      app/Facades/Servers/Aliyun/IpLocation.php
  17. 27 0
      app/Facades/Servers/Aliyun/Sms.php
  18. 28 0
      app/Facades/Servers/Encrypts/AccessToken.php
  19. 26 0
      app/Facades/Servers/Encrypts/ApiSign.php
  20. 24 0
      app/Facades/Servers/Encrypts/Simple.php
  21. 29 0
      app/Facades/Servers/Logs/Log.php
  22. 33 0
      app/Facades/Servers/Redis/Redis.php
  23. 23 0
      app/Facades/Servers/Redis/RedisLock.php
  24. 27 0
      app/Facades/Servers/Safe/TextModeration.php
  25. 26 0
      app/Facades/Servers/ShortUrl/Client.php
  26. 28 0
      app/Facades/Servers/Sms/GuoDu.php
  27. 28 0
      app/Facades/Servers/Sms/VerifyCode.php
  28. 28 0
      app/Facades/Servers/Tencent/Cos.php
  29. 26 0
      app/Facades/Servers/Tencent/Sms.php
  30. 31 0
      app/Facades/Servers/Wechat/Mini.php
  31. 31 0
      app/Facades/Servers/Wechat/Official.php
  32. 50 0
      app/Facades/Servers/Wechat/OpenPlat.php
  33. 30 0
      app/Facades/Servers/Wechat/OpenWork.php
  34. 30 0
      app/Facades/Servers/Wechat/OpenWorkWeb.php
  35. 31 0
      app/Facades/Servers/Wechat/QuestionMini.php
  36. 32 0
      app/Facades/Servers/WeiBan/OpenApi.php
  37. 402 0
      app/Helpers/functions.php
  38. BIN
      app/Http/Controllers/Api.zip
  39. 201 0
      app/Http/Controllers/Api/Api.php
  40. 81 0
      app/Http/Controllers/Api/CollectEquipment.php
  41. 86 0
      app/Http/Controllers/Api/CollectEquipmentAccount.php
  42. 168 0
      app/Http/Controllers/Api/CollectEquipmentExecute.php
  43. 90 0
      app/Http/Controllers/Api/CollectPlatformConfig.php
  44. 82 0
      app/Http/Controllers/Api/CollectTask.php
  45. 82 0
      app/Http/Controllers/Api/CollectTaskAllocate.php
  46. 82 0
      app/Http/Controllers/Api/CollectTaskRecord.php
  47. 47 0
      app/Http/Controllers/Api/Login.php
  48. 57 0
      app/Http/Controllers/Controller.php
  49. 64 0
      app/Http/Kernel.php
  50. 80 0
      app/Http/Middleware/Api/SwitchCompanyDb.php
  51. 111 0
      app/Http/Middleware/Company/AccessAuth.php
  52. 70 0
      app/Http/Middleware/Company/Login.php
  53. 22 0
      app/Http/Middleware/EncryptCookies.php
  54. 69 0
      app/Http/Middleware/LoadLocale.php
  55. 17 0
      app/Http/Middleware/PreventRequestsDuringMaintenance.php
  56. 32 0
      app/Http/Middleware/RedirectIfAuthenticated.php
  57. 23 0
      app/Http/Middleware/TrimStrings.php
  58. 20 0
      app/Http/Middleware/TrustHosts.php
  59. 24 0
      app/Http/Middleware/TrustProxies.php
  60. 52 0
      app/Http/Requests/Api/Coupon.php
  61. 45 0
      app/Http/Requests/Api/Coupon/Active.php
  62. 45 0
      app/Http/Requests/Api/Coupon/Custom.php
  63. 45 0
      app/Http/Requests/Api/Custom.php
  64. 70 0
      app/Http/Requests/Api/CustomAddr.php
  65. 64 0
      app/Http/Requests/Api/CustomCompany.php
  66. 71 0
      app/Http/Requests/Api/CustomShopResource.php
  67. 69 0
      app/Http/Requests/Api/CustomerForm/Company/CustomerForm.php
  68. 176 0
      app/Http/Requests/Api/DynamicQrcode/Templates.php
  69. 52 0
      app/Http/Requests/Api/LiveReward/Order.php
  70. 46 0
      app/Http/Requests/Api/Login.php
  71. 39 0
      app/Http/Requests/Api/Login/Phone.php
  72. 67 0
      app/Http/Requests/Api/Lottery/LiveRecord.php
  73. 56 0
      app/Http/Requests/Api/Lottery/OrderRecord.php
  74. 56 0
      app/Http/Requests/Api/Lottery/ScoreRecord.php
  75. 58 0
      app/Http/Requests/Api/Orders.php
  76. 50 0
      app/Http/Requests/Api/Orders/Receipt.php
  77. 62 0
      app/Http/Requests/Api/Product.php
  78. 71 0
      app/Http/Requests/Api/Promoter/ApplicationForm.php
  79. 69 0
      app/Http/Requests/Api/Promoter/CommonProduct.php
  80. 74 0
      app/Http/Requests/Api/Promoter/Configuration.php
  81. 69 0
      app/Http/Requests/Api/Promoter/Customers.php
  82. 70 0
      app/Http/Requests/Api/Promoter/EarningsRecord.php
  83. 69 0
      app/Http/Requests/Api/Promoter/Product.php
  84. 69 0
      app/Http/Requests/Api/Promoter/RecruitCustomers.php
  85. 77 0
      app/Http/Requests/Api/Promoter/Users.php
  86. 45 0
      app/Http/Requests/Api/Redpacket.php
  87. 51 0
      app/Http/Requests/Api/Redpacket/ActiveRecord.php
  88. 56 0
      app/Http/Requests/Api/Score/Orders.php
  89. 53 0
      app/Http/Requests/Api/Score/Product.php
  90. 61 0
      app/Http/Requests/Api/ShopCart.php
  91. 56 0
      app/Http/Requests/Api/WeiZan/Orders.php
  92. 47 0
      app/Http/Requests/Api/WorkBind.php
  93. 268 0
      app/Http/Requests/BaseRequest.php
  94. 82 0
      app/Http/Requests/Community/CommBackend/Topic.php
  95. 69 0
      app/Http/Requests/Community/CommBackend/TopicAttachment.php
  96. 71 0
      app/Http/Requests/Community/CommBackend/TopicComment.php
  97. 70 0
      app/Http/Requests/Community/CommBackend/TopicExamine.php
  98. 82 0
      app/Http/Requests/Community/CommBackend/TopicNotice.php
  99. 71 0
      app/Http/Requests/Community/CommBackend/TopicRule.php
  100. 65 0
      app/Http/Requests/Community/CommBackend/TopicType.php

+ 131 - 0
.env

@@ -0,0 +1,131 @@
+# 应用配置
+APP_NAME=开邻智数saas系统
+APP_ENV=local    
+APP_KEY=base64:n4pAxrgybm67B78fRhuaZzvioRSWj29Ivyhtb4SeCuo=
+APP_DEBUG=true
+APP_URL=https://openwork.dfwy.tech
+H5_URL=https://openwork.dfwy.tech/h5
+LOCAL_URL=https://openwork.dfwy.tech
+
+# 日志配置
+LOG_CHANNEL=stack
+LOG_LEVEL=debug
+
+# 数据库配置
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=drug_retrieve
+#DB_USERNAME=kailin
+#DB_PASSWORD=eDDi8NGLxLn7cDS2
+DB_USERNAME=drug_retrieve
+DB_PASSWORD=Pem287cwM58jNpe2
+
+# 缓存队列配置
+CACHE_DRIVER=file
+MEMCACHED_HOST=127.0.0.1
+
+# 队列配置
+BROADCAST_DRIVER=log
+QUEUE_CONNECTION=sync
+
+# 会话配置
+SESSION_DRIVER=file
+SESSION_LIFETIME=1440
+
+# Redis配置
+REDIS_HOST=127.0.0.1
+REDIS_PASSWORD=null
+REDIS_PORT=6379
+REDIS_PREFIX=saas::
+
+#订单超时时间
+ORDER_OUT_TIME = 30
+
+# 阿里云直播
+ALIYUN_LIVE_PUSH_DOMAIN=livepush.kailin.com.cn
+ALIYUN_LIVE_PUSH_KEY=VDHChNNp6EhgSGt2
+ALIYUN_LIVE_PLAY_DOMAIN=livepull.kailin.com.cn
+ALIYUN_LIVE_PLAY_KEY=lD40pBWWGT41BN49
+
+
+# 微信小程序
+WECHAT_APP_ID=wx3594f896a370e4e1
+
+#微信支付
+MERCHANT_CERTIFICATE_SERIAL=7AE7D93E187F61A69E987BBC461469251FC80146
+PLATFORM_CERTIFICATE_SERIAL_OR_PUBLIC_KEY_ID=PUB_KEY_ID_0117174401542025072900211974000205
+MCHID=1717440154
+CERTIFICATE=7AE7D93E187F61A69E987BBC461469251FC80146
+APIV3=0BpUgvkg9R5491VHFgBkT7t4mlgtKiKi
+PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7OBLiTiWGmTPX
+fEWfxY/tJbQBPWd6hFjUzIXgEOqVGBkIz1tolddiyuKgvfaLTd/++Q7lHR6siOfK
+U2+++knKw3pZqzqHxnr2GzsGmjKd3rjOMtJpJShQg1cyJF2f2mF6JzqT6fNgR+gq
+kDGJKSLllC8AGun53g9IzBrkw2i5XdyYIvI3IiBOBiZZ/koxXY6A0Iy4m1WToKRz
+u2hSpEG1gCKv57H6w+OeEl+NGaF+vf63RVlgh9k32rXQvgR+dzpqHJNuRnY85+4Z
+zUYKQRg8skTuO04B/Y5Ow+cxe0bnSgxQQ6nOWpnPbeYbkHN/ZxWexop4pIRjDXnA
+6CLjcVHXAgMBAAECggEBAKUVILGkLrqsxGWyEsJ7NhnqMPsW5fPGV33sie+1euPU
+x95Y2UUzOyTFuWf7mTXkiSsO+e9U6gNBBQIG6HYBxKeiDnSa45VtkmcIQ9fih9dk
+2JgZgCduuEmmRnDUWCnoKiPIC4L5u7yeKz28v7EuMLM3Iup40O+euuN59gzZsbIg
+as2IAcILwCA0kqShpBZeolWujOQ1l3atW3fG5LlWc2NfltvRTjd2anNeXl0bIjiA
+VJmohDc159twsYBLAQ25FSf9oXUdsRY+MQM0nU9+V3+KVp/XmP2PeDh3Ll/WKJpW
+aQS+HDV4mEjc0qacOYfe8RfIKu+t6EtK/TYvmUmQqoECgYEA6XOeO29O2EX4gOXm
+MsH0ErbydOPStA8ru4UZsFZl01187ViF2fpG7teTg5oYNw0+UgvSgVxbtndUb6oQ
+b7mWOj3bNUkERlIHHdfyTGAvQZ8yfBqSPxySALcpeyAtyP8WTHU7rOGA+G7sVF39
+Ctm4BdfrKq9OeuoMNRb+FnDTJOcCgYEAzU1MGhd8zGZNdf6A2UGBXe3VyewOhRNh
+0OYdnUM7ziW+3tFG5oLZ1erDvyORuuAznZlVeTvJMRTedkYqBbZ2j9vvrCL1bq6L
+g1Qrq2mfsOGSL5fB07TZBN2L5Zzu+MHXxKBCDVFoQBsTEeTG/avmxNO71p34vds6
+0gKwBKVS3ZECgYEAoV1dnk+N/EhBQTeoKqWOA/GZHdrsJbHm1LNn0k+mCrewRo7N
+1qH8rdMtD+ZPnp302dl6JBim/DT3lEfFHLT3dkKTZv2VitXgPWyq+sfxYjacOtRT
+CnTBJuV0MrtHaouH6kmOei1VbGOfz6E362wam09oKhUK9kMZNQkzkGdkSzkCgYEA
+xbPFMG8j4BY4TAN9AzqAoPpy4VNwHBixHqErLZFcW0WgDCSOWVby/XxpanyPTt2u
+9vp9BBVdxuUo4c7pkrzGafzLTgIQRbjSYvLAZv59KLHgu/IxVnUWdAgBO2mn+2d4
+KEKHuRmHAgzQjW+5bPmIbkzT23Ye3n3qo+iwppiqNvECgYAa017z5kV/jk7tOWPo
+P0bLW2JfXUu52vBL31e4975n9JBqC0u+XA4vbW11K4qkPGSrBjlLZOf9uMRr858u
+7E45ygJNGdNhKvuDnA1R0eDUIJoZDmF/DwfJpsXl8fj4wd2IXMJ2pWZJXnrw7SS8
+Q3gQQgPTYmqV5GNHyUWWJTDwcw==
+-----END PRIVATE KEY-----"
+PLATFORM_CERTIFICATE="-----BEGIN CERTIFICATE-----
+MIIEKDCCAxCgAwIBAgIUeufZPhh/YaaemHu8RhRpJR/IAUYwDQYJKoZIhvcNAQEL
+BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
+FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
+Q0EwHhcNMjUwNzI5MDIyNzMzWhcNMzAwNzI4MDIyNzMzWjCBgTETMBEGA1UEAwwK
+MTcxNzQ0MDE1NDEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMS0wKwYDVQQL
+DCTmsZ/oi4/lsJrnibnkv6Hmga/np5HmioDmnInpmZDlhazlj7gxCzAJBgNVBAYT
+AkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBALs4EuJOJYaZM9d8RZ/Fj+0ltAE9Z3qEWNTMheAQ6pUYGQjPW2iV12LK
+4qC99otN3/75DuUdHqyI58pTb776ScrDelmrOofGevYbOwaaMp3euM4y0mklKFCD
+VzIkXZ/aYXonOpPp82BH6CqQMYkpIuWULwAa6fneD0jMGuTDaLld3Jgi8jciIE4G
+Jln+SjFdjoDQjLibVZOgpHO7aFKkQbWAIq/nsfrD454SX40ZoX69/rdFWWCH2Tfa
+tdC+BH53Omock25Gdjzn7hnNRgpBGDyyRO47TgH9jk7D5zF7RudKDFBDqc5amc9t
+5huQc39nFZ7GinikhGMNecDoIuNxUdcCAwEAAaOBuTCBtjAJBgNVHRMEAjAAMAsG
+A1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2Y2Eu
+aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRC
+MDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJCMjdB
+OUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQCc5Bqi
+3axCQZzZx+LdGN4cSEiiw3yJKh/rM54EPiqp/TPl3yxWk8KpNWtvtGKGw1rI8P7C
+lFg5n0IHwbpftu9JAYubYQe+m22QGPo/4P3CQUcILMnKjSCahfCt3BLbw992mVyj
+I3ZwoJF1E7I7pg2tJzSW6Tl/vBnvFJ2Bu2atur4fpb/Jps90rM67OHK7GmlzH40J
+FaOpvZj6oCsGWACpY9kfrbTXuIYdj9YhT5BrMSs43h1lNbqcOKL6my7JmhxGX/Ay
+l0f1sqn5HXRW2gSGRWQRo4kjMWcX8PtJJNFFwFmBu+Yf80XTRQF5ab7p0yJh4rHW
+Gx/kCQDjwiRRWKFb
+-----END CERTIFICATE-----
+"
+#微信公众号
+OFFICIAL_APP_ID=wx554ee14e7862bf97
+#邮件SMTP配置
+MAIL_HOST=smtp.exmail.qq.com
+MAIL_USERNAME=notice@kirin.wiki
+MAIL_PASSWORD=e3kEXjg24kpQgcs2
+MAIL_FROM_ADDRESS=notice@kirin.wiki
+MAIL_FROM_NAME=kailin
+
+TAOBAO_APP_KEY=35132815
+TAOBAO_SECRET_KEY=89e7c226c508cf3872037d3d36ec5537
+#TAOBAO_ENTERPRISE_ID=320000000000016743
+TAOBAO_ENTERPRISE_ID=1cda8eaf3c904cdb9257a050527060c0
+
+
+
+

+ 13 - 0
.styleci.yml

@@ -0,0 +1,13 @@
+php:
+  preset: laravel
+  disabled:
+    - no_unused_imports
+  finder:
+    not-name:
+      - index.php
+      - server.php
+js:
+  finder:
+    not-name:
+      - webpack.mix.js
+css: true

+ 77 - 0
app/Console/Commands/CollectEquipmentHeartbeatCheckCommand.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Facades\Servers\Logs\Log;
+use App\Models\CollectEquipment;
+use App\Models\CollectTaskAllocate;
+use Illuminate\Console\Command;
+
+class CollectEquipmentHeartbeatCheckCommand extends Command
+{
+    protected $signature = 'collect-equipment-heartbeat-check {--timeout=180}';
+
+    protected $description = '巡检设备心跳,超时自动释放设备占用状态';
+
+    private const HEARTBEAT_CACHE_PREFIX = 'collect:equipment:heartbeat:';
+
+    public function handle()
+    {
+        $timeout = (int)$this->option('timeout');
+        if ($timeout < 60) {
+            $timeout = 60;
+        }
+        if ($timeout > 3600) {
+            $timeout = 3600;
+        }
+
+        Log::info('collect-equipment-heartbeat-check', '设备心跳巡检开始');
+        $now = time();
+
+        $occupiedEquipmentList = CollectEquipment::query()
+            ->where('status', '=', 0)
+            ->where('task_status', '=', 1)
+            ->select('id')
+            ->get()
+            ->toArray();
+
+        if (!$occupiedEquipmentList) {
+            Log::info('collect-equipment-heartbeat-check', '暂无占用设备,巡检结束');
+            return 0;
+        }
+
+        $releasedNumber = 0;
+        foreach ($occupiedEquipmentList as $equipment) {
+            $collectEquipmentId = (int)$equipment['id'];
+            $heartbeatTime = (int)cache()->get($this->heartbeatCacheKey($collectEquipmentId), 0);
+            if ($heartbeatTime > 0 && ($now - $heartbeatTime) <= $timeout) {
+                continue;
+            }
+
+            $releaseRes = CollectEquipment::query()
+                ->where('id', '=', $collectEquipmentId)
+                ->where('task_status', '=', 1)
+                ->update(['task_status' => 0, 'update_time' => $now]);
+            if (!$releaseRes) {
+                continue;
+            }
+
+            // 设备中断后,将运行中的子任务置为失败,交给重分配命令处理
+            CollectTaskAllocate::query()
+                ->where('collect_equipment_id', '=', $collectEquipmentId)
+                ->where('status', '=', 1)
+                ->update(['status' => 4, 'update_time' => $now]);
+
+            cache()->forget($this->heartbeatCacheKey($collectEquipmentId));
+            $releasedNumber++;
+        }
+
+        Log::info('collect-equipment-heartbeat-check', '设备心跳巡检结束,释放设备数量:'.$releasedNumber);
+        return 0;
+    }
+
+    private function heartbeatCacheKey($collectEquipmentId)
+    {
+        return self::HEARTBEAT_CACHE_PREFIX.$collectEquipmentId;
+    }
+}

+ 160 - 0
app/Console/Commands/CollectTaskAllocateAgainCommand.php

@@ -0,0 +1,160 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Facades\Servers\Logs\Log;
+use App\Http\Controllers\Api\CollectEquipmentAccount;
+use App\Models\CollectProduct;
+use App\Models\CollectEquipment;
+use App\Models\CollectTask;
+use App\Models\CollectTaskRecord;
+use App\Models\CollectTaskAllocate;
+use App\Models\CollectPlatformConfig;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class CollectTaskAllocateAgainCommand extends Command
+{
+    protected $signature = 'collect-task-allocate-again';
+
+    protected $description = '定时重新分配采集失败任务设备';
+    public function __construct()
+    {
+        parent::__construct();
+    }
+    public function handle()
+    {
+        Log::info('collect-task-allocate-again','分配采集任务开始');
+        $time               = time();
+        $collectEquipmentList = CollectEquipment::query()
+            ->where([['status','=',0],['task_status','=',0]])
+            ->get()
+            ->toArray();
+        if (!$collectEquipmentList){
+            Log::info('collect-task-allocate-again','暂无可使用设备,分配结束');
+            return 0;
+        }
+        $today = date("Y-m-d");
+        $timestamp = strtotime($today);
+        $map                = [
+            ['status','=',4],
+            ['insert_time','>=',$timestamp],
+        ];
+        $collectTaskList = CollectTaskAllocate::query()
+                            ->where($map)
+                            ->get()
+                            ->toArray();
+        if(!$collectTaskList){
+            Log::info('collect-task-allocate-again','暂无待分配任务,分配结束');
+            return 0;
+        }
+        $result = $this->allocate($collectTaskList);
+        if ($result){
+            Log::info('collect-task-allocate-again','分配成功');
+        }
+        return $result;
+    }
+    public function allocate($collectTaskList)
+    {
+        Log::info('collect-task-allocate-again','重新分配采集任务开始');
+        $CollectPlatformConfig   = new CollectPlatformConfig();
+        $CollectTaskAllocate     = new CollectTaskAllocate();
+        $CollectEquipment        = new CollectEquipment();
+        foreach ($collectTaskList as $collectTask){
+            $page                   = 1;
+            $platformConfig         = $CollectPlatformConfig->getOne($collectTask['platform']);
+            if (!$platformConfig){
+                Log::info('collect-task-allocate-again','暂无配置平台参数,分配结束');
+                continue;
+            }
+            //设备每次执行能采集页数
+            $pageNumber             = ceil((($platformConfig['duration']*$platformConfig['minute_size'])/$platformConfig['page_size']));
+            //获取任务已分配的最大页数
+            $maxPage                = CollectTaskAllocate::query()
+                                    ->where('collect_task_id','=',$collectTask['id'])
+                                    ->select('end_page as max_page')
+                                    ->orderBy('end_page','desc')
+                                    ->first();
+            if ($maxPage){
+                $page               = $maxPage['max_page'] + 1;
+            }
+            //查询可用设备
+            $collectEquipmentList   = CollectEquipment::query()
+                ->join('collect_equipment_account','collect_equipment_account.collect_equipment_id','=','collect_equipment.id')
+                ->where([['collect_equipment.status','=',0],
+                    ['collect_equipment.task_status','=',0],
+                    ['collect_equipment_account.status','=',0],
+                    ['collect_equipment_account.platform','=',$collectTask['platform']],
+                ])
+                ->select('collect_equipment.*','collect_equipment_account.username','collect_equipment_account.password')
+                ->get()
+                ->toArray();
+            if (!$collectEquipmentList){
+                Log::info('collect-task-allocate','暂无可使用设备,分配结束');
+                continue;
+            }
+            if (!$collectEquipmentList){
+                Log::info('collect-task-allocate_again','暂无可使用设备,分配结束');
+                continue;
+            }
+            //查询设备当日的使用次数
+            $collectEquipmentIds = array_column($collectEquipmentList,'id');
+            $collectEquipmentRecordCount = CollectTaskRecord::query()
+                ->whereIn('collect_equipment_id',$collectEquipmentIds)
+                ->where([['start_time','>=',strtotime(date('Y-m-d'))],
+                    ['start_time','<=',strtotime(date('Y-m-d',strtotime('+1 day')))],
+                    ['platform','=',$collectTask['platform']]])
+                ->groupBy('collect_equipment_id')
+                ->select('collect_equipment_id',DB::raw('count(*) as count'))
+                ->get()
+                ->toArray();
+            //重组使用次数,设备id作为键
+            if ($collectEquipmentRecordCount){
+                $collectEquipmentRecordCount = array_column($collectEquipmentRecordCount,'count','collect_equipment_id');
+            }
+            //分配设备数量
+            $allocateNumber = 0;
+            foreach ($collectEquipmentList as $collectEquipment){
+                if ($platformConfig){
+                    //查询设备最后执行时间
+                    $collectEquipmentRecord = CollectTaskRecord::query()->where([['collect_equipment_id','=',$collectEquipment['id']]])->select('end_time')->orderBy('end_time','desc')->first();
+                    if($collectEquipmentRecord){
+                        if (($platformConfig['rest_duration'] * 60) > (time()-$collectEquipmentRecord['end_time'])){
+                            Log::info('collect-task-allocate-again','设备处于休息时间');
+                            continue;
+                        }
+                    }
+
+                    if (isset($collectEquipmentRecordCount[$collectEquipment['id']])){
+                        if ($platformConfig['day_number'] <= $collectEquipmentRecordCount[$collectEquipment['id']]){
+                            Log::info('collect-task-allocate-again','设备当天该平台可执行次数已用完');
+                            continue;
+                        }
+                    }
+                }
+                //分配设备
+                $data                       = $collectTask;
+                unset($data['id']);
+                $res = $CollectTaskAllocate->add($data);
+                if (!$res){
+                    Log::info('collect-task-allocate-again','添加采集任务分配失败');
+                }
+                //修改设备占用状态
+                $res = $CollectEquipment->edit($collectEquipment['id'],['task_status'=>1]);
+                if (!$res){
+                    Log::info('collect-task-allocate-again','修改设备占用状态失败');
+                }
+                //修改任务状态
+                $res = $CollectTaskAllocate->edit($collectTask['id'],['status'=>5]);
+                if (!$res){
+                    Log::info('collect-task-allocate-again','修改任务状态失败');
+                }
+            }
+            Log::info('collect-task-allocate-again','分配成功');
+        }
+        Log::info('collect-task-allocate-again','分配结束');
+        return true;
+    }
+
+}

+ 165 - 0
app/Console/Commands/CollectTaskAllocateCommand.php

@@ -0,0 +1,165 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Facades\Servers\Logs\Log;
+use App\Models\CollectProduct;
+use App\Models\CollectEquipment;
+use App\Models\CollectTask;
+use App\Models\CollectTaskRecord;
+use App\Models\CollectTaskAllocate;
+use App\Models\CollectPlatformConfig;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class CollectTaskAllocateCommand extends Command
+{
+    protected $signature = 'collect-task-allocate';
+
+    protected $description = '定时分配采集任务设备';
+    public function __construct()
+    {
+        parent::__construct();
+    }
+    public function handle()
+    {
+        Log::info('collect-task-allocate','分配采集任务开始');
+        $time               = time();
+        $day = date("Y-m-d",strtotime("-1 day"));
+        $timestamp = strtotime($day);
+        $collectTaskList = CollectTask::query()
+            ->where('insert_time','>=',$timestamp)
+            ->whereIn('status',[0])
+            #->whereIn('allocate_status',[0,1])
+            ->orderBy('allocate_status', 'desc')
+            ->get()
+            ->toArray();
+        if(!$collectTaskList){
+            Log::info('collect-task-allocate','暂无待分配任务,分配结束');
+            return 0;
+        }
+        $result = $this->allocate($collectTaskList);
+        if ($result){
+            Log::info('collect-task-allocate','分配成功');
+        }
+        return $result;
+    }
+    public function allocate($collectTaskList)
+    {
+        $CollectTaskAllocateModel   = new CollectTaskAllocate();
+        $CollectEquipmentModel      = new CollectEquipment();
+        $CollectTaskModel           = new CollectTask();
+        Log::info('collect-task-allocate','分配采集任务开始');
+        foreach ($collectTaskList as $collectTask){
+            $page                   = 1;
+            $CollectPlatformConfigModel = new CollectPlatformConfig();
+            $platformConfig         = $CollectPlatformConfigModel->getOne($collectTask['platform']);
+            if (!$platformConfig){
+                Log::info('collect-task-allocate','暂无配置平台参数,分配结束');
+                continue;
+            }
+            //设备每次执行能采集页数
+            $pageNumber             = ceil((($platformConfig['duration']*$platformConfig['minute_size'])/$platformConfig['page_size']));
+            //获取任务已分配的最大页数
+            $maxPage               = CollectTaskAllocate::query()
+                ->where('collect_task_id','=',$collectTask['id'])
+                ->select(Db::raw('max(end_page) as max_page'))
+                ->first();
+            if ($maxPage){
+                $page               = $maxPage['max_page'] + 1;
+            }
+            //查询可用设备
+            $collectEquipmentList   = CollectEquipment::query()
+                ->join('collect_equipment_account','collect_equipment_account.collect_equipment_id','=','collect_equipment.id')
+                ->where([['collect_equipment.status','=',0],
+                    ['collect_equipment.task_status','=',0],
+                    ['collect_equipment_account.status','=',0],
+                    ['collect_equipment_account.platform','=',$collectTask['platform']],
+                ])
+                ->select('collect_equipment.*','collect_equipment_account.username','collect_equipment_account.password')
+                ->get()
+                ->toArray();
+            if (!$collectEquipmentList){
+                Log::info('collect-task-allocate','暂无可使用设备,分配结束');
+                continue;
+            }
+            //查询设备当日的使用次数
+            $collectEquipmentIds = array_column($collectEquipmentList,'id');
+            $collectEquipmentRecordCount = CollectTaskRecord::query()
+                ->whereIn('collect_equipment_id',$collectEquipmentIds)
+                ->where([['start_time','>=',strtotime(date('Y-m-d'))],
+                    ['start_time','<=',strtotime(date('Y-m-d',strtotime('+1 day')))],
+                    ['platform','=',$collectTask['platform']]])
+                ->groupBy('collect_equipment_id')
+                ->select('collect_equipment_id',DB::raw('count(*) as count'))
+                ->get()
+                ->toArray();
+            //重组使用次数,设备id作为键
+            if ($collectEquipmentRecordCount){
+                $collectEquipmentRecordCount = array_column($collectEquipmentRecordCount,'count','collect_equipment_id');
+            }
+            //分配设备数量
+            $allocateNumber = 0;
+            foreach ($collectEquipmentList as $collectEquipment){
+                if ($platformConfig){
+                    //查询设备最后执行时间
+                    $collectEquipmentRecord = CollectTaskRecord::query()->where([['collect_equipment_id','=',$collectEquipment['id']]])->select('end_time')->orderBy('end_time','desc')->first();
+                    if($collectEquipmentRecord){
+                        if (($platformConfig['rest_duration'] * 60) > (time()-$collectEquipmentRecord['end_time'])){
+                            continue;
+                        }
+                    }
+
+                    if (isset($collectEquipmentRecordCount[$collectEquipment['id']])){
+                        if ($platformConfig['day_number'] <= $collectEquipmentRecordCount[$collectEquipment['id']]){
+                            continue;
+                        }
+                    }
+                }
+                //分配设备
+                $start_page = $page;
+                $end_page = $page + $pageNumber - 1;
+                $data = [
+                    'collect_task_id'       => $collectTask['id'],
+                    'collect_equipment_id'  => $collectEquipment['id'],
+                    'company_id'            => $collectTask['company_id'],
+                    'platform'              => $collectTask['platform'],
+                    'product_name'          => $collectTask['product_name'],
+                    'product_specs'         => $collectTask['product_specs'],
+                    'product_brand'         => $collectTask['product_brand'],
+                    'product_keyword'         => $collectTask['product_keyword'],
+                    'minimum_order_quantity'=> $collectTask['minimum_order_quantity'],
+                    'count'                 => $platformConfig['page_size'] * $pageNumber,
+                    'start_page'            => $start_page,
+                    'end_page'              => $end_page,
+                    'status'                => 1,
+                    'duration'              => $platformConfig['duration'],
+                ];
+                $res = $CollectTaskAllocateModel->add($data);
+                if (!$res){
+                    Log::info('collect-task-allocate','添加采集任务分配失败');
+                }
+                //修改设备占用状态
+                $res = $CollectEquipmentModel->edit($collectEquipment['id'],['task_status'=>1]);
+                if (!$res){
+                    Log::info('collect-task-allocate','修改设备占用状态失败');
+                }
+                $allocateNumber++;
+                if ($allocateNumber >= ($collectTask['max_equipment_number'] - $collectTask['equipment_number'])){
+                    break;
+                }
+                $page = $end_page + 1;
+            }
+            //修改任务状态
+            $res = $CollectTaskModel->edit($collectTask['id'],['status'=>1,'allocate_status'=>1,'equipment_number'=>($allocateNumber+$collectTask['equipment_number'])]);
+            if (!$res){
+                Log::info('collect-task-allocate','修改任务状态失败');
+            }
+            Log::info('collect-task-allocate','分配成功');
+        }
+        Log::info('collect-task-allocate','分配结束');
+        return true;
+    }
+
+}

+ 91 - 0
app/Console/Commands/CollectTaskCommand.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Facades\Servers\Logs\Log;
+use App\Models\CollectProduct;
+use App\Models\CollectEquipment;
+use App\Models\CollectTask;
+use App\Models\CollectTaskAllocate;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class CollectTaskCommand extends Command
+{
+    protected $signature = 'collect-task';
+
+    protected $description = '定时分配采集任务设备';
+    public function __construct()
+    {
+        parent::__construct();
+    }
+    public function handle()
+    {
+        Log::info('collect-task','分配采集任务开始');
+        $CollectTaskModel   = new CollectTask();
+        $endTime            = strtotime(date('Y-m-d',time())) + 86400;
+        $time               = time();
+        $map                = [
+            ['collect_product.status','=',0],
+            ['collect_product.sampling_start_time','<=',$time],
+        ];
+        $collectProductList = CollectProduct::query()
+            ->leftJoin('collect_product_keyword','collect_product.id','=','collect_product_keyword.collect_product_id')
+            ->where($map)
+            ->where(function ($query) use ($time) {
+                $query->where('collect_product.sampling_end_time', '>=', $time)
+                    ->orWhere('collect_product.sampling_end_time', 0);
+            })
+            ->select(
+                'collect_product.*',
+                DB::raw('GROUP_CONCAT(collect_product_keyword.keyword SEPARATOR ", ") as product_keyword')
+            )
+            ->groupBy('collect_product.id')
+            ->get()
+            ->toArray();
+        if ($collectProductList){
+            foreach ($collectProductList as $collectProduct){
+                if ($collectProduct['sampling_cycle']){
+                    //查询任务最新执行时间
+                    $collectTask = $CollectTaskModel::query()->where([['collect_product_id','=',$collectProduct['id']]])->select('insert_time')->orderBy('insert_time','desc')->first();
+                    if($collectTask){
+                        if (($collectProduct['sampling_cycle']*86400) > ($endTime - $collectTask['insert_time'])){
+                            continue;
+                        }
+                    }
+                }
+                if (!$collectProduct['platform']){
+                    continue;
+                }
+                $platforms      =   explode(',',$collectProduct['platform']);
+                $data           =  [];
+                foreach ($platforms as $platform){
+                    $data[]           = [
+                        'collect_product_id'    => $collectProduct['id'],
+                        'platform'              => $platform,
+                        'product_name'          => $collectProduct['product_name'] ?? '',
+                        'product_specs'         => $collectProduct['product_specs'] ?? '',
+                        'product_brand'         => $collectProduct['product_brand'] ?? '',
+                        'product_keyword'       => $collectProduct['product_keyword'] ?? '',
+                        'company_id'            => $collectProduct['company_id'],
+                        'max_equipment_number'  => 1,
+                        'status'                => 1,
+                        'insert_time'           => time(),
+                    ];
+                }
+
+                //添加到任务
+                $res = $CollectTaskModel::query()->insert($data);
+                if (!$res){
+                    Log::info('collect-task','添加采集任务失败');
+                }
+            }
+        }else{
+            Log::info('collect-task','暂无采集任务');
+        }
+        Log::info('collect-task','分配采集任务结束');
+        return 0;
+    }
+
+}

+ 52 - 0
app/Console/Kernel.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Console;
+
+use App\Console\Commands\CollectTaskAllocateAgainCommand;
+use App\Console\Commands\CollectTaskAllocateCommand;
+use App\Console\Commands\CollectTaskCommand;
+use App\Console\Commands\CollectEquipmentHeartbeatCheckCommand;
+use Illuminate\Console\Scheduling\Schedule;
+use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
+
+class Kernel extends ConsoleKernel
+{
+    /**
+     * The Artisan commands provided by your application.
+     *
+     * @var array
+     */
+    protected $commands = [
+        CollectTaskAllocateAgainCommand::class,
+        CollectTaskAllocateCommand::class,
+        CollectTaskCommand::class,
+        CollectEquipmentHeartbeatCheckCommand::class,
+    ];
+
+    /**
+     * Define the application's command schedule.
+     *
+     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
+     * @return void
+     */
+    protected function schedule(Schedule $schedule)
+    {
+        $schedule->command('collect-task')->everyThirtyMinutes();
+        $schedule->command('collect-task-allocate')->everyThirtyMinutes();
+        $schedule->command('collect-task-allocate-again')->everyThirtyMinutes();
+        $schedule->command('collect-equipment-heartbeat-check')->everyMinute();
+    }
+
+    /**
+     * Register the commands for the application.
+     *
+     * @return void
+     */
+    protected function commands()
+    {
+        // 自动引入任务命令
+        $this->load(__DIR__.'/Commands');
+        // 引入任务路由
+        require base_path('routes/console.php');
+    }
+}

+ 68 - 0
app/Events/ExternalAndFollowOperateEvent.php

@@ -0,0 +1,68 @@
+<?php
+
+
+namespace App\Events;
+
+//外部人员与跟进员工操作事件新增,删除外部人员,删除跟进员工
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class ExternalAndFollowOperateEvent
+{
+    use Dispatchable, InteractsWithSockets,SerializesModels;
+
+    /*
+     * 企微ID
+     */
+    public $corpId;
+
+    /*
+    * 跟进成员ID
+    */
+    public $followUserId;
+
+    /*
+    * 外部联系人ID
+    */
+    public $externalUserId;
+
+    /*
+     * 事件类型:1:添加好友、2:删除企业客户(用户)、3:删除跟进人员(内部员工)
+    */
+    public $eventType;
+    /*
+     * 企业自定义的state参数,用于区分不同的添加渠道
+    */
+    public $state = '';
+
+    /**
+     * Create a new event instance.
+     *
+     * @param $corpId
+     * @param $followUserId
+     * @param $externalUserId
+     * @param $eventType
+     * @param $state
+     */
+    public function __construct($corpId, $followUserId , $externalUserId, $eventType, $state='')
+    {
+        $this->corpId = $corpId;
+        $this->followUserId = $followUserId;
+        $this->externalUserId = $externalUserId;
+        $this->eventType = $eventType;
+        $this->state     = $state;
+    }
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+
+}

+ 93 - 0
app/Events/ExternalAndGroupOperateEvent.php

@@ -0,0 +1,93 @@
+<?php
+
+
+namespace App\Events;
+
+
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+//外部人员群操作事件进群,退群
+class ExternalAndGroupOperateEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    /*
+    * 企微ID
+    */
+    public $corpId;
+
+    /*
+    * 群ID
+    */
+    public $chatId;
+
+    /*
+    * 变更的群成员数组
+    */
+    public $memChangeArray;
+
+    /*
+    * 外部联系人ID
+    */
+    public $externalUserId;
+
+    /*
+    * 变更类型,当前默认update
+    */
+    public $changeType;
+
+    /*
+    * 变更详情类型:1:成员入群、2:成员退群
+    */
+    public $updateDetailType;
+
+    /*
+    * 入群时有值,0:成员邀请入群、3:扫描群二维码入群
+    */
+    public $joinScene;
+
+    /*
+    * 退群时有值,0:自己退群、1:群主/群管理员移出
+    */
+    public $quitScene;
+
+
+    /**
+     * Create a new event instance.
+     *
+     * @param $corpId
+     * @param $chatId
+     * @param $memChangeArray
+     * @param $changeType
+     * @param $updateDetailType
+     * @param $joinScene
+     * @param $quitScene
+     */
+    public function __construct($corpId, $chatId, $memChangeArray, $changeType, $updateDetailType, $joinScene, $quitScene)
+    {
+        $this->corpId               = $corpId;
+        $this->chatId               = $chatId;
+        $this->memChangeArray       = $memChangeArray;
+        $this->changeType           = $changeType;
+        $this->updateDetailType     = $updateDetailType;
+        $this->joinScene            = $joinScene;
+        $this->quitScene            = $quitScene;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+
+
+
+}

+ 64 - 0
app/Exceptions/Api/ApiException.php

@@ -0,0 +1,64 @@
+<?php namespace App\Exceptions\Api;
+
+use Exception;
+use Throwable;
+/**
+ * 接口异常
+ */
+class ApiException extends Exception
+{
+
+    // 错误返回码
+    protected $errCode   = 'error';
+    // 错误返回数据
+    protected $errData   = '';
+    // 本地化前缀
+    protected $langkey   = 'message';
+    
+    /**
+     * 抛出错误信息
+     * 
+     * @param   String          $message    — [optional] The Exception message to throw.
+     * @param   Mixed           $errData    — 错误返回数据
+     * @param   Int             $code       — [optional] The Exception code.
+     * @param   Throwable       $previous   — [optional] The previous throwable used for the exception chaining.
+     * @return  Mixed
+     * 
+     */
+    public function __construct( $message="",$errData='',$code=0,?Throwable $previous=null )
+    {
+        // 如果本地化前缀存在则本地化处理
+        if( $this->langkey ) {
+            // 消息key
+            $msgKey             = $this->langkey.'.'.$message;
+            // 提示信息本地化
+            $trans              = trans($msgKey);
+            // 如果没有找到对应的提示,使用原提示信息
+            $message            = ($trans == $msgKey) ? $message : $trans;
+        }
+        // 传递数据到父级
+        parent::__construct($message, $code, $previous);
+        // 错误信息说
+        if( $errData )          $this->errData = $errData;
+    }
+
+    /**
+     * 获取错误返回码
+     * 
+     */
+    public function getErrCode()
+    {
+        return $this->errCode;
+    }
+
+    /**
+     * 获取返回数据
+     * 
+     */
+    public function getErrData()
+    {
+        return $this->errData;
+    }
+
+
+}

+ 11 - 0
app/Exceptions/Api/LoginException.php

@@ -0,0 +1,11 @@
+<?php namespace App\Exceptions\Api;
+
+
+class LoginException extends ApiException
+{
+
+    // 错误返回码
+    protected $errCode   = 'no_login';
+    // 本地化前缀
+    protected $langkey   = 'api_login';
+}

+ 15 - 0
app/Exceptions/Api/ValidException.php

@@ -0,0 +1,15 @@
+<?php namespace App\Exceptions\Api;
+
+
+/**
+ * 接口验证签名错误抛出
+ * 
+ */
+class ValidException extends ApiException
+{
+
+    // 错误返回码
+    protected $errCode   = 'error';
+    // 本地化前缀
+    protected $langkey   = '';
+}

+ 15 - 0
app/Exceptions/Api/VerifySignException.php

@@ -0,0 +1,15 @@
+<?php namespace App\Exceptions\Api;
+
+
+/**
+ * 接口验证签名错误抛出
+ * 
+ */
+class VerifySignException extends ApiException
+{
+
+    // 错误返回码
+    protected $errCode   = 'no_access';
+    // 本地化前缀
+    protected $langkey   = 'api_access';
+}

+ 13 - 0
app/Exceptions/Company/ShopException.php

@@ -0,0 +1,13 @@
+<?php namespace App\Exceptions\Company;
+
+
+use App\Exceptions\Api\ApiException;
+
+class ShopException extends ApiException
+{
+
+    // 错误返回码
+    protected $errCode   = 'error';
+    // 本地化前缀
+    protected $langkey   = 'company_shop';
+}

+ 80 - 0
app/Exceptions/Handler.php

@@ -0,0 +1,80 @@
+<?php
+
+namespace App\Exceptions;
+
+use App\Exceptions\Api\ApiException;
+use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
+use App\Facades\Servers\Logs\Log;
+use Throwable;
+
+class Handler extends ExceptionHandler
+{
+    /**
+     * 不报告的异常类型的列表
+     *
+     * @var array
+     */
+    protected $dontReport = [
+        //
+    ];
+
+    /**
+     * A list of the inputs that are never flashed for validation exceptions.
+     *
+     * @var array
+     */
+    protected $dontFlash = [
+        'current_password',
+        'password',
+        'password_confirmation',
+    ];
+
+    /**
+     * Register the exception handling callbacks for the application.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        $this->reportable(function (Throwable $e) {})->stop();
+    }
+
+
+    /**
+     * 将异常呈现到HTTP响应中
+     * 
+     * 
+     * @return \Illuminate\Http\JsonResponse
+     */
+    public function render($request, Throwable $e){
+        // 如果是异常类型,获取异常的消息
+        $msg            = $e->getMessage();
+        // 错误信息
+        $msg            = $msg ? $msg : '404';
+        // 错误数据
+        $data           = '';
+        // 错误码
+        $code           = 'sys_error';
+        // http状态码
+        $status         = 200;
+        // 日志信息
+        $message        = request()->ip().' ' .request()->method().' '. request()->getPathInfo().' '.$msg .' of file '.$e->getFile().' on line '.$e->getLine();
+        // 如果是接口异常
+        if( $e instanceof ApiException ){
+            // 错误码
+            $code       = $e->getErrCode();
+            // 错误数据
+            $data       = $e->getErrData();
+        }else{
+            // 拼接报错文件位置
+            $message    .= ' of file '.$e->getFile().' on line '.$e->getLine();
+        }
+        // 要返回的数据
+        $data           = ['code'=>($code == 'sys_error' ? 'error' : $code),'msg'=>$msg,'data'=>$data];
+        // 记录日志
+        Log::info($code,$message,['param'=>request()->all(),'return'=>$data,'user_agent'=>request()->header('user-agent')],['filename'=>str_ireplace('/','_',trim(request()->getPathInfo(),'/'))]);
+        // 返回结果
+        return          response()->json($data,$status,[],JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
+    }
+
+}

+ 21 - 0
app/Facades/Servers/Aliyun/IpLocation.php

@@ -0,0 +1,21 @@
+<?php namespace App\Facades\Servers\Aliyun;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * @method string|array getCityByIp(string $ip='',string $field='') 获取IP归属地
+ * 
+ * @see \App\Servers\Aliyun\IpLocation
+ */
+class IpLocation extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Aliyun\IpLocation';
+    }
+}

+ 27 - 0
app/Facades/Servers/Aliyun/Sms.php

@@ -0,0 +1,27 @@
+<?php namespace App\Facades\Servers\Aliyun;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 短信发送
+ * 
+ * @method static array sendSms(string $phone,string $signName,string $templateCode,array $param=[]) 发送短信
+ * 
+ * @see \App\Servers\Aliyun\Sms
+ * 
+ * 
+ */
+class Sms extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Aliyun\Sms';
+    }
+}
+
+?>

+ 28 - 0
app/Facades/Servers/Encrypts/AccessToken.php

@@ -0,0 +1,28 @@
+<?php namespace App\Facades\Servers\Encrypts;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 用户权限令牌(JWT)
+ * 
+ * @method static string    encode(array $data)             加密数据
+ * @method static array     decode(string $access_token)    解密数据
+ * 
+ * @author  liuxaingxin
+ * @see \App\Servers\Encrypts\AccessToken
+ * 
+ */
+class AccessToken extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Encrypts\AccessToken';
+    }
+}
+
+?>

+ 26 - 0
app/Facades/Servers/Encrypts/ApiSign.php

@@ -0,0 +1,26 @@
+<?php namespace App\Facades\Servers\Encrypts;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 接口签名
+ * 
+ * @method static array encode( array $contents ,string $appid, string $appkey)  加密
+ * 
+ * @see \App\Servers\Encrypts\ApiSign
+ * 
+ */
+class ApiSign extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Encrypts\ApiSign';
+    }
+}
+
+?>

+ 24 - 0
app/Facades/Servers/Encrypts/Simple.php

@@ -0,0 +1,24 @@
+<?php namespace App\Facades\Servers\Encrypts;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 自定义简单对称加密
+ * 
+ * @see \App\Servers\Encrypts\Simple
+ * 
+ */
+class Simple extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Encrypts\Simple';
+    }
+}
+
+?>

+ 29 - 0
app/Facades/Servers/Logs/Log.php

@@ -0,0 +1,29 @@
+<?php namespace App\Facades\Servers\Logs;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * @method static mixed log(string $name,string $message,array $content=[],int $level=Logger::INFO,array $options=[])
+ * @method static mixed  debug(string $name,string $message,array $content=[],array $options=[])
+ * @method static mixed  info(string $name,string $message,array $content=[],array $options=[])
+ * @method static mixed  notice(string $name,string $message,array $content=[],array $options=[])
+ * @method static mixed  warning(string $name,string $message,array $content=[],array $options=[])
+ * @method static mixed  error(string $name,string $message,array $content=[],array $options=[])
+ * @method static mixed  critical(string $name,string $message,array $content=[],array $options=[])
+ * @method static mixed  alert(string $name,string $message,array $content=[],array $options=[])
+ * @method static mixed  emergency(string $name,string $message,array $content=[],array $options=[])
+ * 
+ * @see \App\Servers\Logs\Log
+ */
+class Log extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return 'App\Servers\Logs\Log';
+    }
+}

+ 33 - 0
app/Facades/Servers/Redis/Redis.php

@@ -0,0 +1,33 @@
+<?php namespace App\Facades\Servers\Redis;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * @method static  \Illuminate\Redis\Connections\Connection connection(string $name = null)
+ * @method static  \Illuminate\Redis\Limiters\ConcurrencyLimiterBuilder funnel(string $name)
+ * @method static  \Illuminate\Redis\Limiters\DurationLimiterBuilder throttle(string $name)
+ * @method static bool     set(string $key,string $value,['EX'|'PX'],[$expire],['NX'|'XX'])   设置指定key的值 
+ * @method static mixed    get(string $key)      获取指定key的值 
+ * @method static bool setex(string $key,int $seconds,string $value) 将值value关联到key,并将key的过期时间设为seconds(以秒为单位)。
+ * @method static bool pErsist(string $key)     移除给定key的过期时间,使得key永不过期
+ * @method static bool expire(string $key,int $expire)     为给定key设置生存时间
+ * @method static bool del(mixed $key,...$otherkey)   删除已存在的键。不存在的 key 会被忽略
+ * @method static int setBit(string $key,int $offset, int$value)   设置或清除指定偏移量上的位(bit)。返回值是:指定偏移量原来储存的位$value
+ * @method static int getBit(string $key,int $offset)          获取指定偏移量上的位(bit)。返回值是:字符串值指定偏移量上的位(bit)。当偏移量 OFFSET 比字符串值的长度大,或者 key 不存在时,返回 0 。
+ * @method static int exists(string $key)         检查给定 key 是否存在,若 key 存在返回 1 ,否则返回 0 。
+ * 
+ * @see \Illuminate\Redis\RedisManager
+ * @see \Illuminate\Contracts\Redis\Factory
+ */
+class Redis extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return 'redis';
+    }
+}

+ 23 - 0
app/Facades/Servers/Redis/RedisLock.php

@@ -0,0 +1,23 @@
+<?php namespace App\Facades\Servers\Redis;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * @method static miexd lock(string $key,string $value, int $ex=20)     上异步锁
+ * @method static miexd unlock($key,$value)          释放锁
+ * 
+ * @see \App\Servers\Redis\RedisLock
+ * 
+ */
+class RedisLock extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return 'App\Servers\Redis\RedisLock';
+    }
+}

+ 27 - 0
app/Facades/Servers/Safe/TextModeration.php

@@ -0,0 +1,27 @@
+<?php namespace App\Facades\Servers\Safe;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 反欺诈
+ * 
+ * @method mixed localCheck($content)           只用本地词库检测
+ * @method mixed textModeration(string $content)检测内容
+ * 
+ * @see \App\Servers\Safe\TextModeration
+ * 
+ */
+class TextModeration extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Safe\TextModeration';
+    }
+}
+
+?>

+ 26 - 0
app/Facades/Servers/ShortUrl/Client.php

@@ -0,0 +1,26 @@
+<?php namespace App\Facades\Servers\ShortUrl;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 短链
+ * 
+ * @method mixed createUrl(string $originUrl) 获取短链
+ * 
+ * @see \App\Servers\ShortUrl\Client
+ * 
+ */
+class Client extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\ShortUrl\Client';
+    }
+}
+
+?>

+ 28 - 0
app/Facades/Servers/Sms/GuoDu.php

@@ -0,0 +1,28 @@
+<?php namespace App\Facades\Servers\Sms;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 短信发送
+ * 
+ * @method static array sendSms($desMobile,$content,$sign) 发送短信
+ * @method static int|array surplus() 短信余额
+ * 
+ * @see \App\Servers\Sms\GuoDu
+ * 
+ * 
+ */
+class GuoDu extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Sms\GuoDu';
+    }
+}
+
+?>

+ 28 - 0
app/Facades/Servers/Sms/VerifyCode.php

@@ -0,0 +1,28 @@
+<?php namespace App\Facades\Servers\Sms;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 短信发送
+ * 
+ * @method static array sendCode($phone,$verifyCode) 发送短信验证码
+ * @method static array sendRemind($phone,$verifyCode) 发送短信
+ *
+ * @see \App\Servers\Sms\VerifyCode
+ * 
+ * 
+ */
+class VerifyCode extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Sms\VerifyCode';
+    }
+}
+
+?>

+ 28 - 0
app/Facades/Servers/Tencent/Cos.php

@@ -0,0 +1,28 @@
+<?php namespace App\Facades\Servers\Tencent;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 对象存储
+ * 
+ * @method  array listObjectsAll($prefix='',$filter_name='',$marker='',$maxkeys=16,$delimiter='/',$result=[])   获取指定目录下的所有对象
+ * @method  array|string upload($key,$body,$headers=[])     上传对象
+ * @method  array|bool deleteObject($key,$versionId=null)   删除单个对象
+ * 
+ * @see \App\Servers\Tencent\Cos
+ * 
+ */
+class Cos extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Tencent\Cos';
+    }
+}
+
+?>

+ 26 - 0
app/Facades/Servers/Tencent/Sms.php

@@ -0,0 +1,26 @@
+<?php namespace App\Facades\Servers\Tencent;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 短信发送
+ * 
+ * @method static array sendSms(string $phone,string $signName,string $templateCode,array $param=[]) 发送短信
+ * 
+ * @see \App\Servers\Tencent\Sms
+ * 
+ */
+class Sms extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Tencent\Sms';
+    }
+}
+
+?>

+ 31 - 0
app/Facades/Servers/Wechat/Mini.php

@@ -0,0 +1,31 @@
+<?php namespace App\Facades\Servers\Wechat;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 对象存储
+ * 
+ * @method static string getUrlLink($path,$query='')     获取UrlLink
+ * @method static array  getUserPhone($code)        手机号授权
+ * @method static string  getAccessToken()          获取AccessToken
+ * @method static mixed  queryUrlLink($urlLink)     查询加密UrlLink
+ * @method static mixed  getUnlimit(string $scene, array $optional = [])                获取小程序码
+ * 
+ * 
+ * @see \App\Servers\Wechat\Mini
+ * 
+ */
+class Mini extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Wechat\Mini';
+    }
+}
+
+?>

+ 31 - 0
app/Facades/Servers/Wechat/Official.php

@@ -0,0 +1,31 @@
+<?php namespace App\Facades\Servers\Wechat;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 对象存储
+ *
+ * @method static \EasyWeChat\OfficialAccount\Application   getApp()                   公众号
+ * @method static array                                     userFromCode($code)        获取用户授权信息
+ * @method static array                                     getJssdkConfig($url='')    获取JSSDK的配置数组
+ * @method static array                                     sendSubscription($params)  发送一次性订阅消息
+ * @method static array                                     send($params)              发送模板消息
+ *
+ * 
+ * @see \App\Servers\Wechat\Official
+ * 
+ */
+class Official extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Wechat\Official';
+    }
+}
+
+?>

+ 50 - 0
app/Facades/Servers/Wechat/OpenPlat.php

@@ -0,0 +1,50 @@
+<?php namespace App\Facades\Servers\Wechat;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 对象存储
+ * 
+ * @method static \EasyWeChat\OpenPlatform\Application                                  getApp()                                                    获取应用实例
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\OfficialAccount\Application       getOfficial(string $appId)                                  获取授权公众号实例
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getMini(string $appId)                                      获取授权小程序实例
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getUserPhone(string $appId, string $refreshToken)           手机号授权
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getTrialQRCode(string $appId, string $fileName, string $path)  生产小程序体验版二维码
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           commit(string $appId, int $templateId, string $extJson, string $version, string $description)    提交小程序体验版
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           userFromCode(string $code, string $appId,)    获取user  公众号
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           modify(string $appId,array $params)    配置小程序服务器域名
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getUrlLink(string $appId,string $path,string $query)    获取UrlLink
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getUnlimit(string $appId,string $scene, array $optional = [])         获取小程序码
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           release(string $appId)      发布最后一个审核通过的小程序代码版本
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           submitAudit(string $appId,array $data)      提交代码审核
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getAllCategoryName(string $appId)      获取类目名称信息
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getMaterial(string $appId, int $mediaId)      获取永久素材
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           jscode2session(string $code, string $appId)    登录获取用户openid
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           setPrivacySetting(string $appId, array $data)    登录获取用户openid
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getAccountBasicInfo(string $appId)    获取小程序信息
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getVersionInfo(string $appId)    获取小程序版本信息
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           modifyJumpDomain(string $appId,array $params)   配置小程序业务域名
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getLatestAuditStatus(string $appId)   查询审核结果
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getAccessToken(string $appId)   查询审核结果
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getOfficialAccessToken(string $appId)   查询审核结果
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           getScheme(string $appId,string $path,string $query)    获取小程序 scheme 码
+ *
+ * @method static \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Application           applyMsgPlugin(string $appId)   申请物流信息
+ *
+ * @see \App\Servers\Wechat\OpenPlat
+ * 
+ */
+class OpenPlat extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Wechat\OpenPlat';
+    }
+}
+
+?>

+ 30 - 0
app/Facades/Servers/Wechat/OpenWork.php

@@ -0,0 +1,30 @@
+<?php namespace App\Facades\Servers\Wechat;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 对象存储
+ * 
+ * @method static \EasyWeChat\OpenWork\Application  getApp()                                获取应用实例
+ * @method static \EasyWeChat\Work\Application      getWork(string $authCorpId)             获取授权企企微实例
+ * @method static string                            getPermanentCode(string $authCorpId)    通过授权方企微ID获取永久授权码
+ * @method static array                             getAuthorization($authCorpId)           获取授权企业授权授权信息
+ * @method static string                            getErrmsg($errcode)                     获取错误信息
+ * 
+ * @see \App\Servers\Wechat\OpenWork
+ * 
+ */
+class OpenWork extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Wechat\OpenWork';
+    }
+}
+
+?>

+ 30 - 0
app/Facades/Servers/Wechat/OpenWorkWeb.php

@@ -0,0 +1,30 @@
+<?php namespace App\Facades\Servers\Wechat;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 对象存储
+ * 
+ * @method static \EasyWeChat\OpenWork\Application  getApp()                                获取应用实例
+ * @method static \EasyWeChat\Work\Application      getWork(string $authCorpId)             获取授权企企微实例
+ * @method static string                            getPermanentCode(string $authCorpId)    通过授权方企微ID获取永久授权码
+ * @method static array                             getAuthorization($authCorpId)           获取授权企业授权授权信息
+ * @method static string                            getErrmsg($errcode)                     获取错误信息
+ * 
+ * @see \App\Servers\Wechat\OpenWorkWeb
+ * 
+ */
+class OpenWorkWeb extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Wechat\OpenWorkWeb';
+    }
+}
+
+?>

+ 31 - 0
app/Facades/Servers/Wechat/QuestionMini.php

@@ -0,0 +1,31 @@
+<?php namespace App\Facades\Servers\Wechat;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 对象存储
+ * 
+ * @method static string getUrlLink($path,$query='')     获取UrlLink
+ * @method static array  getUserPhone($code)        手机号授权
+ * @method static string  getAccessToken()          获取AccessToken
+ * @method static mixed  queryUrlLink($urlLink)     查询加密UrlLink
+ * @method static mixed  getUnlimit(string $scene, array $optional = [])                获取小程序码
+ * 
+ * 
+ * @see \App\Servers\Wechat\QuestionMini
+ * 
+ */
+class QuestionMini extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\Wechat\QuestionMini';
+    }
+}
+
+?>

+ 32 - 0
app/Facades/Servers/WeiBan/OpenApi.php

@@ -0,0 +1,32 @@
+<?php namespace App\Facades\Servers\WeiBan;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * 对象存储
+ * 
+ * @method static string getAccessToken()                                                                   获取凭证
+ * @method static array  getUserList(int $limit,int $offset,int $startTime=0,string $source='remark')       获取用户列表
+ * @method static array  getUserDetail(string $id)                                                          获取用户详情
+ * @method static array  getUserListByPhone($phone)                                                         通过手机获取用户列表
+ * @method static array  getTagList(int $limit=100,int $offset=0)                                           获取标签列表
+ * @method static array  markTags($extUserid,$addTags,$rmTags,$staffId)                                     给客户打标签
+ * @method static array  addTag($staffId,$extUserid,$tagGroup,$tagName)                                     给客户添加企业标签
+ * 
+ * @see \App\Servers\WeiBan\OpenApi
+ * 
+ */
+class OpenApi extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor()
+    {
+        return '\App\Servers\WeiBan\OpenApi';
+    }
+}
+
+?>

+ 402 - 0
app/Helpers/functions.php

@@ -0,0 +1,402 @@
+<?php
+
+use App\Facades\Servers\Logs\Log;
+use Illuminate\Support\Facades\DB;
+use Intervention\Image\Facades\Image;
+/**
+ * 响应请求
+ * @param	mixed		$data	数据
+ * @param	string		$code	状态码
+ * @param	mixed		$log	是否记录日志
+ * 
+ * */
+function json_send($data,$code=200){
+    // 日志名称
+    $name                   = empty($data['code']) ? 'unknown' : $data['code'];
+    // 获取提示消息
+    $msg                    = empty($data['msg']) ? '' : $data['msg'];
+    // 如果提示数据不是成功或者是local 
+    if( ($name != 'success' && $name != 'retry' ) || config('app.env') == 'local' ) {
+        // 消息key
+        $msgKey             = 'message.'.$msg;
+        // 提示信息本地化
+        $trans              = trans($msgKey);
+        // 如果没有找到对应的提示,使用原提示信息
+        $data['msg']        = ( $trans == $msgKey ) ? $msg : $trans;
+        // 消息
+        $msg                = request()->ip().' ' .request()->method().' '. request()->getPathInfo().' '.$msg;
+        // 记录内容
+        $content            = ['param'=>request()->all(),'return'=>$data,'user_agent'=>request()->header('user-agent')];
+        // 记录日志
+        Log::info($name,$msg,$content,['filename'=>str_ireplace('/','_',trim(request()->getPathInfo(),'/'))]);
+    }
+    // 默认返回数据
+    $data['data']           = isset($data['data']) ? $data['data'] : '';
+	// 返回数据
+	return			        response()->json($data,$code,[],JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
+}
+
+/**
+ * 雪花算法生成分布式ID
+ * 
+ * @param	int		    $dataCenterId   数据中心ID 0-31
+ * @param	int		    $machineId     任务进程ID 0-31
+ * 
+ * @return	string		分布式ID
+ * */
+function make_snow_flake($dataCenterID=0,$machineId=0){
+    // 获取redis配置
+    $redis              = config('database.redis.default');
+    // 主机地址
+    $config['host']     = empty($redis['host'])  ? '127.0.0.1' : $redis['host'];
+    // 端口
+    $config['port']     = empty($redis['port'])  ? 6379 : $redis['port'];
+    // 密码
+    if( !empty($redis['password']) )  $config['auth']       = $redis['password'];
+    // 数据库
+    if( !empty($redis['database']) )  $config['dbIndex']    = $redis['database'];
+    // 实例化
+    $IdWorker           = \wantp\Snowflake\IdWorker::getIns($dataCenterID,$machineId);
+    // 生成
+    return              $IdWorker->setRedisCountServer($config)->id();
+}
+
+
+/**
+ * 终端设备系统
+ * 
+ * @param	string		$agent 		HTTP_USER_AGENT数据
+ * 
+ * */
+function get_agent_system($agent=''){
+    //HTTP_USER_AGENT数据
+    $agent								= $agent ? $agent : request()->header('user-agent');
+    //iOS
+    if( stripos($agent, 'iphone') || stripos($agent, 'ipad') ) return 'iOS';
+    //iOS
+    if( stripos($agent, 'macintosh') )	return 'MacOS';
+    //安卓
+    if( stripos($agent, 'android') ) 	return 'Android';
+    //安卓
+    if( stripos($agent, 'okhttp') ) 	return 'Android';
+    //Windows
+    if( stripos($agent, 'win') ) 		return 'Windows';
+    //Linux
+    if( stripos($agent, 'linux') )		return 'Linux';
+    //Unix
+    if( stripos($agent, 'unix') )		return 'Unix';
+    //Other
+    return 'Other';
+}
+
+/**
+ * 路径兼容输出
+ * 
+ * @param	string	    $url	文件路径
+ * @param	int|null	$width  新图片宽度
+ * @param	int|null	$height 新图片高度(如果没有填写高度,把高度等比例缩小)
+ * @param	string		$type 	文件类型
+ * 
+ * @author	刘相欣
+ * */
+function path_compat( $url,$witdh=null,$higth=null,$type='') {
+    // 没有路径的统一返回原数据
+    if( !$url )             return $type ? $url : request()->root().'/'.ltrim(resize($url,$witdh,$higth),'/');
+    // 如果是带有http的路径,直接返回
+    if( stripos('$'.$url, 'http') ) {
+        // 腾讯云链
+        if( stripos( $url, 'myqcloud.com') ){
+            // 开启全球域名全球加速时, 替换COS全球加速域名
+            if( config('open_accelerate','') )  $url = str_ireplace('.cos.'.config('tencent.cos.region','').'.myqcloud.com','.cos.accelerate.myqcloud.com',$url);
+            // 如果需要开启CDN,局部开启,全局开启
+            if( request()->is('api/*') && (request('open_cdn',0) || config('open_cdn',0) ) && config('open_cdn_domain','') ){
+                // 先把https 换成 http
+                $url = str_ireplace('https','http',$url);
+                // 替换域名
+                $url = str_ireplace(config('tencent.cos.bucket','').'-'.config('tencent.cos.app_id','').'.cos.'.config('tencent.cos.region','').'.myqcloud.com',config('open_cdn_domain',''),$url);
+            }
+        }
+        // 获取扩展信息
+        $type		        = strtolower(pathinfo($url, PATHINFO_EXTENSION));
+        // 如果信息不存在
+        if( !$type )        return $url;
+        // 不是图片直接返回路径
+        if( !in_array($type,['jpg','png','jpeg','gif','bmp']) ) return $url;
+        // 需要后缀的OSS参数
+        $param		        = '';
+        // 阿里云的OSS
+        if( stripos( $url, 'aliyuncs.com') ){
+            // 判断图片的宽高进行缩放处理
+            if( $witdh && $higth ){
+                // 宽高都存在时,固定宽高,将延伸出指定w与h的矩形框外的最小图片进行居中裁剪
+                $param      = '?x-oss-process=image/resize,m_fill,limit_0,w_'.$witdh.',h_'.$higth;
+            }else if($witdh){
+                $param      = '?x-oss-process=image/resize,w_'.$witdh;
+            }else if($higth){
+                $param      = '?x-oss-process=image/resize,h_'.$higth;
+            }
+        }
+        // 腾讯云的COS
+        if( stripos( $url, 'myqcloud.com') ){
+            if( $witdh && $higth ){
+                // 宽高都存在时,固定宽高,将延伸出指定w与h的矩形框外的最小图片进行居中裁剪
+                $param	= '?imageView2/2/w/'.$witdh.'/h/'.$higth;
+            }else if($witdh){
+                $param	= '?imageView2/2/w/'.$witdh;
+            }else if($higth){
+                $param	= '?imageView2/2/h/'.$higth;
+            }
+        }
+        // 路径
+        return $param ? $url.$param : $url;
+    }
+    // 类型
+    $type		        = strtolower(pathinfo($url, PATHINFO_EXTENSION));
+    // 是图片则返回缩略图
+    if( in_array($type,['jpg','png','jpeg','gif','bmp']) )  return rtrim((config('img_cdn_domain')?config('img_cdn_domain'):request()->root()),'/').'/'.ltrim(resize($url,$witdh,$higth),'/');
+    // 判断是否存在文件
+    if( file_exists('uploads/'.$url) )                      return request()->root().'/uploads/'.ltrim($url,'/');
+    // 其他类型文件,统一返回
+    return              request()->root().'/'.ltrim($url,'/');
+}
+
+/**
+ * 自动生成新尺寸 的图片
+ * @param string $filename 文件名
+ * @param int $width 新图片宽度
+ * @param int $height 新图片高度(如果没有填写高度,把高度等比例缩小)
+ */
+function resize( $filename, $width=null, $height=null) {
+    // 如果不存在图片路径
+    if( !is_file(DIR_IMAGE.$filename)||empty($filename) )  $filename = config('app.no_pic');
+    // 如果没有宽高,给原图
+    if( !$width && !$height ) return 'uploads/'.$filename;
+    // 调整当前图像的边界到给定的宽和高
+    $img        = Image::make(DIR_IMAGE.$filename)->resizeCanvas($width, $height);
+    // 获取文件名称
+    $name       = pathinfo($filename,PATHINFO_FILENAME);
+    // 缓存名
+    $cacheName  = $width ? $name.'_w' .$width : $name;
+    $cacheName  = $height ? $cacheName.'_h' .$height : $cacheName;
+    // 名称拼接宽高
+    $filename   = str_replace($name,$cacheName,$filename);
+    // 缓存文件路径
+    $newFile    = 'cache/'.$filename;
+    // 如果目录不存在,创建目录
+    if( !is_dir(dirname(DIR_IMAGE.$newFile)) ) mkdir(dirname(DIR_IMAGE.$newFile),0755,true);
+    // 保存新图
+    $img->save(DIR_IMAGE.$newFile);
+    // 返回结果
+    return      'uploads/'.$newFile;
+}
+
+
+/**
+ * 新检查用户操作权限
+ *
+ * @param int        $uid  账号ID
+ * @param string     $module  模块
+ * 
+ */
+function is_super($uid,$module='manager'){
+    switch ($module){
+        case 'manager':
+            $AdminUserModel      = new App\Models\Manager\AdminUser();
+            break;
+        case 'company':
+            $AdminUserModel      = new App\Models\Manager\AdminUserCompany();
+            break;
+        case 'shop':
+            $AdminUserModel      = new App\Models\Manager\AdminUserShop();
+            break;
+    }
+    // 返回结果
+    $isSuper                    = $AdminUserModel->query()->where([['uid','=',$uid]])->value('is_super');
+    // 默认无权限
+    return                      $isSuper ? true : false;
+}
+
+/**
+ * 新检查用户操作权限
+ *
+ * @param int        $uid  账号ID
+ * @param string     $uid  模块
+ */
+function allow_show_phone($uid,$module='manager'){
+    switch ($module){
+        case 'manager':
+            $AuthGroupAccess      =   new App\Models\Manager\AuthGroupAccess();
+            break;
+        case 'company':
+            $AuthGroupAccess      =   new App\Models\Manager\AuthGroupAccessCompany();
+            break;
+        case 'shop':
+            $AuthGroupAccess      =   new App\Models\Manager\AuthGroupAccessShop();
+            break;
+    }
+    // 返回结果
+    return                        $AuthGroupAccess->showPhoneByUid($uid);
+}
+
+
+/**
+ * 把返回的数据集转换成Tree
+ * @param	array		$list	要转换的数据集
+ * @param	string	    $pid	parent标记字段
+ * @param	string	    $level	level标记字段
+ * @return	array
+ * 
+ * @author	麦当苗儿 <zuojiazi@vip.qq.com>
+ * 
+ */
+function list_to_tree($list, $pk='id', $pid = 'pid', $child = 'children', $root = 0) {
+    // 创建Tree
+    $tree = array();
+    if(is_array($list)) {
+        // 创建基于主键的数组引用
+        $refer = array();
+        foreach ($list as $key => $data) {
+            $refer[$data[$pk]] =& $list[$key];
+        }
+        foreach ($list as $key => $data) {
+            // 判断是否存在parent
+            $parentId =  $data[$pid];
+            if ($root == $parentId) {
+                $tree[] =& $list[$key];
+            }else{
+                if (isset($refer[$parentId])) {
+                    $parent =& $refer[$parentId];
+                    $parent[$child][] =& $list[$key];
+                }
+            }
+        }
+    }
+    return $tree;
+}
+
+/**
+ * 格式化字节
+ * @param	int  $byte 		字节数值
+ * 
+ * */
+function byte_format($byte){
+    // 如果是GB
+    if( $byte >= (1024 * 1024 * 1024) )		return round( $byte / (1024 * 1024 * 1024),2 ).' GB';
+    // 如果是MB
+    if( $byte >= (1024 * 1024) )			return round( $byte / (1024 * 1024),2 ).' MB';
+    // 如果是KB
+    if( $byte >= 1024 )					    return round( $byte / (1024),2 ).' KB';
+    // 如果是字节
+    return $byte.' B';
+}
+
+/**
+ * 二维数组排序,根据某个字段
+ * @param   array       $array      要排序的数组
+ * @param   string      $key        要排序的键字段
+ * @param   string      $sort       排序类型 SORT_ASC SORT_DESC 
+ * @return  array       排序后的数组
+ */
+function array_sort($array, $key, $sort = SORT_DESC) {
+    // 获取字段数据
+    $keys       = array_column($array,$key);
+    // 进行排序
+    array_multisort($keys, $sort, $array);
+    // 返回结果
+    return      $array;
+}
+
+/**
+ * 二维数组排序,根据某个字段
+ * @param   string      $phoneNumber        手机号
+ */
+function hide_phone($phoneNumber) {
+    return substr_replace($phoneNumber, '****', 3, 4);
+}
+
+
+/**
+ * 省份去除自治区等后缀
+ * 
+ * @param   string      $province       省份
+ * 
+ */
+function province_rtrim($province) {
+    // 长度2个字的不处理
+    if( mb_strlen($province) <= 2 ) return $province;
+    // 省份信息
+    $province   = str_ireplace(['省','回族','维吾尔','壮族','自治区','特别行政区'],'',$province);
+    // 返回结果
+    return      $province;
+}
+
+/**
+ * 城市去除自治州等后缀
+ * 
+ * 
+ * @param   string      $city       地级市单位
+ * 
+ */
+function city_rtrim($city) {
+    // 长度2个字的不处理
+    if( mb_strlen($city) <= 2 ) return $city;
+    // 名称
+    $result             = mb_strrchr($city,'市',true);
+    // 返回结果
+    if( $result )       return $result;
+    // 名称
+    $result             = mb_strrchr($city,'自治州',true);
+    // 返回结果
+    if( $result )       return $result;
+    // 名称
+    $result             = mb_strrchr($city,'盟',true);
+    // 返回结果
+    if( $result )       return $result;
+    // 名称
+    $result             = mb_strrchr($city,'地区‌',true);
+    // 返回结果
+    if( $result )       return $result;
+    // 返回结果
+    return              $city;
+}
+
+/**
+ * 将字符串追加到某个需要切割成数组的字符串数组
+ * 
+ * 
+ * @param   string      $dest    目标字符串
+ * @param   string      $source  需要追加的字符串
+ * @param   string      $sep     目标字符串切割方式
+ * 
+ */
+function push_str_arr($dest,$source,$sep=',') {
+    // 转数组
+    $result			= $dest ? explode($sep,$dest) : [];
+    $result[]		= $source;
+    $result			= array_values(array_unique($result));
+    // 返回结果
+    return          $result;
+}
+
+
+/**
+ * 多行多条数据范围转数组
+ * 
+ * @param   string      $scope      范围字符串
+ * 
+ * @return  array       范围数组
+ */
+function scope_to_array($scope){
+    // 兼容逗号问题
+    $scope				= str_ireplace(',',',',$scope);
+    $scope				= str_ireplace("\r\n",',',$scope);
+    $scope				= str_ireplace("\n",',',$scope);
+    // 转数组处理
+    $scope				= explode(',',$scope);
+    // 去重
+    $scope				= array_unique($scope);
+    // 返回结果
+    return              array_values($scope);
+}
+
+?>

BIN
app/Http/Controllers/Api.zip


+ 201 - 0
app/Http/Controllers/Api/Api.php

@@ -0,0 +1,201 @@
+<?php namespace App\Http\Controllers\Api;
+
+use App\Exceptions\Api\VerifySignException;
+use App\Exceptions\Api\LoginException;
+use App\Exceptions\Api\ApiException;
+use App\Facades\Servers\Encrypts\AccessToken;
+use App\Facades\Servers\Encrypts\ApiSign;
+use App\Http\Controllers\Controller;
+
+/**
+ * 接口控制器
+ * 
+ * @author 刘相欣
+ * 
+ * */
+class Api extends Controller{
+
+	/**
+	 * 登录验证
+	 * 
+	 * @return	Int			$authcode		登录信息
+	 * 
+	 */
+	public function checkLogin($authcode=''){
+		// 默认接参
+		$authcode											= $authcode ? $authcode : request('authcode','');
+        $port                                               = request('port','');
+		// 如果没有有登录信息
+		if( !$authcode )									throw new LoginException("please_login");
+		// 解码
+		$decode												= AccessToken::decode($authcode);
+		// 错误返回
+		if( isset($decode['error']) )						throw new LoginException("login_error");
+		// 如果没有过期时间,过期处理
+		if( empty($decode['exp']) )							throw new LoginException("login_exprie");
+		// 如果过期,过期处理
+		if( $decode['exp'] <= time() )						throw new LoginException("login_exprie");
+		// 登录的商户ID
+		$loginCompanyId										= empty($decode['company_id']) ? 0 : $decode['company_id'];
+		// 如果登录的商户不一致,提醒重新登录
+		if( $loginCompanyId != request('company_id',0) )	throw new LoginException("please_login");
+		// 从缓存获取登录数据
+		$memAuthcode 										= (new Custom())->getLoginAuthCodeByUid($decode['sub'],$port);
+		// 不存在登录信息,提示失败
+		if( !$memAuthcode )									throw new LoginException("login_miss");
+		// 如果是32位的话
+		if( strlen($memAuthcode) == 32 )					$authcode = md5($authcode);
+		// 如果存在登录数据,并且不是当前用户的缓存登录,提示失败
+		if( $authcode != $memAuthcode )						throw new LoginException("login_miss");
+		// 返回用户ID
+		return												$decode['sub'];
+	}
+
+	/**
+	 * 登录验证
+	 * 
+	 * @return	Int		用户ID
+	 * 
+	 */
+	public function getUid($authcode=''){
+		// 默认接参
+		$authcode											= $authcode ? $authcode : request('authcode','');
+		// 如果没有有登录信息
+		if( !$authcode )									return 0;
+		// 尝试执行
+		try {
+			// 解码
+			$decode											= AccessToken::decode($authcode);
+			// 错误返回
+			if( isset($decode['error']) )					return 0;
+			// 如果没有过期时间,过期处理
+			if( empty($decode['exp']) )						return 0;
+			// 如果过期,过期处理
+			if( $decode['exp'] <= time() )					return 0;
+			// 登录的商户ID
+			$loginCompanyId									= empty($decode['company_id']) ? 0 : $decode['company_id'];
+			// 如果登录的商户不一致,提醒重新登录
+			if( $loginCompanyId != request('company_id',0)) return 0;
+			// 返回用户ID
+			return											$decode['sub'];
+		} catch (\Throwable $th) {
+			// 返回0
+			return											0;
+		}
+	}
+
+	/**
+	 * 接口验签
+	 * 
+	 * @param		[Array]		$data		参与验证的参数
+	 * 
+	 * 
+	 * */
+	public function verify_sign($data=[]){
+		// 获取参数
+		$data									= $data ? $data : request()->all();
+		// 没有签名
+		if( empty($data['sign']) )				throw new VerifySignException('sign_miss');
+		// 没有签名
+		if( empty($data['appid']) )				throw new VerifySignException('appid_miss');
+		// 传了key
+		if( !empty($data['key']) )				throw new VerifySignException('appkey_no_allow');
+		// 没有请求时间
+		if( empty($data['timestamp'])  )        throw new VerifySignException('sign_timeout');
+        // 请求过期
+		if( abs(time() -$data['timestamp'] ) > 86400 ) throw new VerifySignException('sign_timeout');
+        // 已使用过的签名不允许二次使用
+		$this->checkSignUsed($data['sign']);
+		// 从配置读取接口验签应用数据
+		$verify 								= ['2DEA6A19BDCA383B'=>'FD6F87E89EABAF1063A849D971B68618'];
+		// 是否有对应的appid
+		if( !isset($verify[$data['appid']]) )	throw new VerifySignException('appid_nofund');
+		// appkey
+		$appkey									= $verify[$data['appid']];
+		// 获得签名参数数据
+		$sign									= $data['sign'];
+		// 删除传入签名参数
+		unset($data['sign']);
+		// 删除上传文件的字段
+		if( isset($data['file']))				unset($data['file']);
+		// 键名字典排序
+		ksort($data);
+		// 空字符串
+		$param									= '';
+		// 循环参数对象,拼接url字符串
+		foreach ( $data as $key => $value ) {
+			// 如果键值为空(空字符串 空数组 空集合 空对象 字符串0 数字0 NULL FALSE),此参数省略;另 '000' 这类0组成的字符串 不为空
+			if( strtolower($value)  == 'false' || strtolower($value)  == 'null' || empty($value) || ( is_numeric($value) && $value == 0 && substr_count($value,'.') == 1 ) ) continue;
+			// 判断键值是否是数组,对象 ,如果是的话,键值转json字符串
+			if( is_array( $value ) || is_object($value) ) $value = json_encode($value,JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
+			// 如果键值为真则 键值转md5加密(此处小写) 为假则直接拼接,0特殊处理
+			$param  .= '&'.$key.'='.$value;
+		}
+		// 转码
+		$param									= ltrim($param,'&');
+		// 解码
+		$param									= rawurldecode($param);
+		// 拼接私钥数据
+		$param									.= '&key='.$appkey;
+		// 比对签名,数据加密(MD5后转大写),$param.'=>'.strtoupper(md5($param)).'=>'.$sign
+		if( strtoupper(md5($param)) != $sign)	throw new VerifySignException('sign_error');
+		// 验签通过
+		return									['success'=>'验签成功'];
+	}
+
+	/**
+	 * 判断签名是否已用
+	 * 
+	 * @param		[Array]		$data		参与验证的参数
+	 * 
+	 * 
+	 * */
+	public  function checkSignUsed($sign='')	{
+		// 获取签名
+		$is_used								= cache('ApiSign:'.$sign);
+		// 如果签名已用
+		if( $is_used )							throw new VerifySignException('sign_used');
+		// 存储已经验证过的签名
+		cache(['ApiSign:'.$sign=>$sign],60);
+		// 成功返回
+		return									['success'=>'签名可用'];
+	}
+
+	/**
+	 * 接口验签
+	 * 
+	 * @param	Array		$data		参与验证的参数
+	 * 
+	 * 
+	 * */
+	public function sign($data)					{
+		// 返回加密结果
+		return									ApiSign::encode($data);
+	}
+
+    /**
+     * 店铺验证
+     *
+     */
+    public function checkShop($uid='', $shopId=''){
+		// 商户ID
+		$companyId										    = request('company_id',0);
+        // 默认接参
+        $shopId											    = $shopId ? $shopId : request('shop_id',0);
+		// 访问记录
+		$CustomShopRecord									= (new CustomShopRecord());
+		// 如果没有店铺,获取用户记录最后访问的店铺
+        if (!$shopId)  										$shopId = $uid ? $CustomShopRecord->query()->where(['company_id'=>$companyId,'custom_uid'=>$uid])->orderByDesc('visit_time')->value('shop_id') : $shopId;
+		// 如果还是没有店铺,获取商户下的第一个店铺
+		if (!$shopId)                                       $shopId = (new Shop())->query()->where(['company_id'=>$companyId])->orderBy('id')->value('id');
+		// 如果有shopId
+        if ( $shopId && $uid )                     			{
+            // 判断是不是有对应的店铺数据
+            $recordId                       				= $CustomShopRecord->where(['custom_uid'=>$uid,'company_id'=>$companyId,'shop_id'=>$shopId])->value('id');
+            // 更新还是新增
+            $recordId                       				? $CustomShopRecord->edit($recordId,['visit_time'=>time()]) : $CustomShopRecord->add(['custom_uid'=>$uid,'shop_id'=>$shopId,'company_id'=>$companyId,'visit_time'=>time()]); 
+        }
+        // 返回
+        return												['shop_id'=>$shopId,'company_id'=>$companyId];
+    }
+}

+ 81 - 0
app/Http/Controllers/Api/CollectEquipment.php

@@ -0,0 +1,81 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Servers\Aliyun\Oss;
+use App\Models\CollectEquipment as Model;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+class CollectEquipment extends Api
+{
+    /**
+     * 首页列表
+     *
+     * */
+    public function index(Model $Model){
+        // 接受参数
+        $name					= request('name','');
+        // 查询条件
+        $map 					= [];
+        // 编码ID
+        if( $name )				$map[] = ['name','=',$name];
+        $uid                    = request('access_token.uid',0);
+        // 查询数据
+        $list					= $Model->query()->where($map);
+        $list                   = $list->orderByDesc('id')->paginate(request('limit',config('page_num',10)))->appends(request()->all());
+        return					json_send(['code'=>'success','msg'=>'成功','data'=>$list]);
+    }
+
+    /**
+     * 添加
+     *
+     * */
+    public function add( Model $Model){
+        // 组合数据
+        $data['name']			= request('name','');
+        $data['device_id']		= request('device_id',0);
+        // 写入
+        $id						= $Model->add($data);
+        // 提示新增失败
+        if( !$id )				return json_send(['code'=>'error','msg'=>'新增失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']);
+    }
+
+    /**
+     * 编辑
+     *
+     * */
+    public function edit(Model $Model){
+        // 组合数据
+        $id						= request('id',0);
+        // 组合数据
+        $data['name']			= request('name','');
+        $data['device_id']		= request('device_id',0);
+        // 写入
+        $result					= $Model->edit($id,$data);
+        // 提示新增失败
+        if( !$result )			return json_send(['code'=>'error','msg'=>'修改失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']);
+    }
+
+    /**
+     * 状态
+     *
+     * */
+    public function set_status( Model $Model ){
+        // 接收参数
+        $id				= request('id',0);
+        $status			= request('status',0);
+        // 查询数据
+        $result			= $Model->edit($id,['status'=>$status]);
+        // 提示新增失败
+        if( !$result )	return json_send(['code'=>'error','msg'=>'设置失败']);
+        // 记录行为
+        //$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,[],['status'=>$status]);
+        // 告知结果
+        return			json_send(['code'=>'success','msg'=>'设置成功','path'=>'']);
+    }
+}

+ 86 - 0
app/Http/Controllers/Api/CollectEquipmentAccount.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Servers\Aliyun\Oss;
+use App\Models\CollectEquipmentAccount as Model;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+class CollectEquipmentAccount extends Api
+{
+    /**
+     * 首页列表
+     *
+     * */
+    public function index(Model $Model){
+        // 接受参数
+        $name					= request('name','');
+        // 查询条件
+        $map 					= [];
+        // 编码ID
+        if( $name )				$map[] = ['name','=',$name];
+        $uid                    = request('access_token.uid',0);
+        // 查询数据
+        $list					= $Model->query()->where($map);
+        $list                   = $list->orderByDesc('id')->paginate(request('limit',config('page_num',10)))->appends(request()->all());
+        return					json_send(['code'=>'success','msg'=>'成功','data'=>$list]);
+    }
+
+    /**
+     * 添加
+     *
+     * */
+    public function add( Model $Model){
+        // 组合数据
+        $data['username']			= request('username','');
+        $data['password']			= request('password','');
+        $data['collect_equipment_id']		= request('collect_equipment_id',0);
+        $data['platform']		= request('platform',0);
+        // 写入
+        $id						= $Model->add($data);
+        // 提示新增失败
+        if( !$id )				return json_send(['code'=>'error','msg'=>'新增失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']);
+    }
+
+    /**
+     * 编辑
+     *
+     * */
+    public function edit(Model $Model){
+        // 组合数据
+        $id						= request('id',0);
+        // 组合数据
+        $data['username']		= request('username','');
+        $data['password']		= request('password','');
+        $data['collect_equipment_id']= request('collect_equipment_id',0);
+        $data['platform']		= request('platform',0);
+        // 写入
+        $result					= $Model->edit($id,$data);
+        // 提示新增失败
+        if( !$result )			return json_send(['code'=>'error','msg'=>'修改失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']);
+    }
+
+    /**
+     * 状态
+     *
+     * */
+    public function set_status( Model $Model ){
+        // 接收参数
+        $id				= request('id',0);
+        $status			= request('status',0);
+        // 查询数据
+        $result			= $Model->edit($id,['status'=>$status]);
+        // 提示新增失败
+        if( !$result )	return json_send(['code'=>'error','msg'=>'设置失败']);
+        // 记录行为
+        //$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,[],['status'=>$status]);
+        // 告知结果
+        return			json_send(['code'=>'success','msg'=>'设置成功','path'=>'']);
+    }
+}

+ 168 - 0
app/Http/Controllers/Api/CollectEquipmentExecute.php

@@ -0,0 +1,168 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Servers\Aliyun\Oss;
+use App\Models\CollectEquipment as Model;
+use App\Models\CollectTask;
+use App\Models\CollectTaskAllocate;
+use App\Models\CollectEquipmentAccount;
+use App\Models\CollectTaskRecord;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+class CollectEquipmentExecute extends Api
+{
+    private const HEARTBEAT_CACHE_PREFIX = 'collect:equipment:heartbeat:';
+    private const HEARTBEAT_DEFAULT_TTL = 180;
+
+    private function heartbeatCacheKey($collectEquipmentId)
+    {
+        return self::HEARTBEAT_CACHE_PREFIX.$collectEquipmentId;
+    }
+
+    /**
+     * 执行结果上报
+     *
+     * */
+    public function result_report(Model $Model, CollectTaskAllocate $CollectTaskAllocate, CollectTaskRecord $CollectTaskRecord){
+        // 接受参数
+        $collectTaskAllocateId		= request('collect_task_allocate_id','');
+        $status					    = request('status','');
+        $finishStatus				= request('finish_status',0);
+        $realCount				    = request('real_count','');
+        $startTime				    = request('start_time','');
+        $endTime				    = request('end_time','');
+        $startPage				    = request('start_page','');
+        $endPage				    = request('end_page','');
+        $remark				        = request('remark','');
+        $equipment_account_id		= request('equipment_account_id','');
+        $allocateInfo				= CollectTaskAllocate::query()->where([['id','=',$collectTaskAllocateId]])->first();
+        if (!$allocateInfo){
+            return json_send(['code'=>'error','msg'=>'执行任务ID参数错误']);
+        }
+        if($status == 2){
+            //修改任务状态
+            $res = CollectTaskAllocate::query()->where([['id','=',$collectTaskAllocateId]])->update(['status'=>$status]);
+            if (!$res){
+                return json_send(['code'=>'error','msg'=>'修改任务状态失败']);
+            }
+        } else {
+            //修改设备占用状态
+            $res                        = $Model->edit($allocateInfo['collect_equipment_id'],['task_status'=>0]);
+            if (!$res){
+                return json_send(['code'=>'error','msg'=>'修改设备占用状态失败']);
+            }
+            cache()->forget($this->heartbeatCacheKey($allocateInfo['collect_equipment_id']));
+            //修改任务状态
+            $res = CollectTaskAllocate::query()->where([['id','=',$collectTaskAllocateId]])->update(['status'=>$status]);
+            if (!$res){
+                return json_send(['code'=>'error','msg'=>'修改任务状态失败']);
+            }
+            if ($finishStatus){
+                //查询设备ids
+                $equipmentIds         = CollectTaskAllocate::query()->where([
+                    ['collect_task_id','=',$allocateInfo['collect_task_id']],
+                    ['id','><',$collectTaskAllocateId],
+                    ['status','=',1]
+                ])->pluck('collect_equipment_id')->toArray();
+                //更新子任状态为弃用
+                $allocateIds                  = CollectTaskAllocate::query()->where([
+                    ['collect_task_id','=',$allocateInfo['collect_task_id']],
+                    ['status','=',1]
+                ])->pluck('id')->toArray();
+                if ($allocateIds){
+                    $res                  = CollectTaskAllocate::query()->where([
+                        ['collect_task_id','=',$allocateInfo['collect_task_id']],
+                        ['status','=',1]
+                    ])->update(['status'=>6]);
+                    if (!$res){
+                        return json_send(['code'=>'error','msg'=>'修改子任务状态未弃用失败']);
+                    }
+                }
+                $res = CollectTask::query()->where([['id','=',$allocateInfo['collect_task_id']]])->update(['allocate_status'=>2,'status'=>2]);
+                if (!$res){
+                    return json_send(['code'=>'error','msg'=>'修改总任务状态失败']);
+                }
+                if ($equipmentIds){
+                    //更新设备状态为空闲
+                    $res = $Model::query()->whereIn('id',$equipmentIds)->update(['task_status'=>0]);
+                    if (!$res){
+                        return json_send(['code'=>'error','msg'=>'修改设备状态失败']);
+                    }
+                    foreach ($equipmentIds as $equipmentId){
+                        cache()->forget($this->heartbeatCacheKey($equipmentId));
+                    }
+                }
+            }
+            //添加任务执行记录
+            $data = [
+                'collect_task_id'	        => $allocateInfo['collect_task_id'],
+                'collect_equipment_id'		=> $allocateInfo['collect_equipment_id'],
+                'platform'				    => $allocateInfo['platform'],
+                'product_name'			    => $allocateInfo['product_name'],
+                'product_specs'			    => $allocateInfo['product_specs'],
+                'minimum_order_quantity'	=> $allocateInfo['minimum_order_quantity'],
+                'start_time'                => $startTime,
+                'end_time'                  => $endTime,
+                'start_page'                => $startPage,
+                'end_page'                  => $endPage,
+                'real_count'			    => $realCount,
+                'status'				    => ($status == 3) ? 2 : 1,
+                'count'		                => $allocateInfo['count'],
+                'remark'		            => $remark,
+            ];
+            $res = $CollectTaskRecord->add($data);
+            if (!$res){
+                return json_send(['code'=>'error','msg'=>'添加任务执行记录失败']);
+            }
+        }
+
+        if ($status == 4){
+            $CollectEquipmentAccount   = new CollectEquipmentAccount();
+            //修改设备账号状态
+            $res = $CollectEquipmentAccount::query()->where([['id','=',$allocateInfo['equipment_account_id']]])->update(['status'=>1]);
+            if (!$res){
+                return json_send(['code'=>'error','msg'=>'修改设备账号状态失败']);
+            }
+        }
+        return					    json_send(['code'=>'success','msg'=>'成功','data'=>[]]);
+    }
+
+    /**
+     * 设备心跳上报
+     *
+     * */
+    public function heartbeat(Model $Model)
+    {
+        $collectEquipmentId = (int)request('collect_equipment_id',0);
+        if (!$collectEquipmentId){
+            return json_send(['code'=>'error','msg'=>'设备ID参数错误']);
+        }
+
+        $equipment = $Model->query()
+            ->where('id','=',$collectEquipmentId)
+            ->select('id','task_status')
+            ->first();
+        if (!$equipment){
+            return json_send(['code'=>'error','msg'=>'设备不存在']);
+        }
+
+        if ((int)$equipment['task_status'] !== 1){
+            return json_send(['code'=>'success','msg'=>'设备当前未执行任务','data'=>[]]);
+        }
+
+        $ttl = (int)request('ttl',self::HEARTBEAT_DEFAULT_TTL);
+        if ($ttl < 60){
+            $ttl = 60;
+        }
+        if ($ttl > 3600){
+            $ttl = 3600;
+        }
+
+        $now = time();
+        cache()->put($this->heartbeatCacheKey($collectEquipmentId),$now,$ttl);
+
+        return json_send(['code'=>'success','msg'=>'心跳上报成功','data'=>['heartbeat_time'=>$now]]);
+    }
+}

+ 90 - 0
app/Http/Controllers/Api/CollectPlatformConfig.php

@@ -0,0 +1,90 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Servers\Aliyun\Oss;
+use App\Models\CollectPlatformConfig as Model;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+class CollectPlatformConfig extends Api
+{
+    /**
+     * 首页列表
+     *
+     * */
+    public function index(Model $Model){
+        // 接受参数
+        $name					= request('name','');
+        // 查询条件
+        $map 					= [];
+        // 编码ID
+        if( $name )				$map[] = ['name','=',$name];
+        $uid                    = request('access_token.uid',0);
+        // 查询数据
+        $list					= $Model->query()->where($map);
+        $list                   = $list->orderByDesc('id')->paginate(request('limit',config('page_num',10)))->appends(request()->all());
+        return					json_send(['code'=>'success','msg'=>'成功','data'=>$list]);
+    }
+
+    /**
+     * 添加
+     *
+     * */
+    public function add( Model $Model){
+        // 组合数据
+        $data['platform']		= request('platform',0);
+        $data['duration']		= request('duration',0);
+        $data['rest_duration']		= request('rest_duration',0);
+        $data['day_number']		= request('day_number',0);
+        $data['minute_size']		= request('minute_size',0);
+        $data['page_size']		= request('page_size',0);
+        // 写入
+        $id						= $Model->add($data);
+        // 提示新增失败
+        if( !$id )				return json_send(['code'=>'error','msg'=>'新增失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']);
+    }
+
+    /**
+     * 编辑
+     *
+     * */
+    public function edit(Model $Model){
+        // 组合数据
+        $id						= request('id',0);
+        // 组合数据
+        $data['platform']		= request('platform',0);
+        $data['duration']		= request('duration',0);
+        $data['rest_duration']		= request('rest_duration',0);
+        $data['day_number']		= request('day_number',0);
+        $data['minute_size']		= request('minute_size',0);
+        $data['page_size']		= request('page_size',0);
+        // 写入
+        $result					= $Model->edit($id,$data);
+        // 提示新增失败
+        if( !$result )			return json_send(['code'=>'error','msg'=>'修改失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']);
+    }
+
+    /**
+     * 状态
+     *
+     * */
+    public function set_status( Model $Model ){
+        // 接收参数
+        $id				= request('id',0);
+        $status			= request('status',0);
+        // 查询数据
+        $result			= $Model->edit($id,['status'=>$status]);
+        // 提示新增失败
+        if( !$result )	return json_send(['code'=>'error','msg'=>'设置失败']);
+        // 记录行为
+        //$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,[],['status'=>$status]);
+        // 告知结果
+        return			json_send(['code'=>'success','msg'=>'设置成功','path'=>'']);
+    }
+}

+ 82 - 0
app/Http/Controllers/Api/CollectTask.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Servers\Aliyun\Oss;
+use App\Models\CollectTask as Model;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+class CollectTask extends Api
+{
+    /**
+     * 首页列表
+     *
+     * */
+    public function index(Model $Model){
+        // 接受参数
+        $name					= request('name','');
+        // 查询条件
+        $map 					= [];
+        // 编码ID
+        if( $name )				$map[] = ['name','=',$name];
+        $uid                    = request('access_token.uid',0);
+        // 查询数据
+        $list					= $Model->query()->where($map);
+        $list                   = $list->orderByDesc('id')->paginate(request('limit',config('page_num',10)))->appends(request()->all());
+        return					json_send(['code'=>'success','msg'=>'成功','data'=>$list]);
+    }
+
+    /**
+     * 添加
+     *
+     * */
+    public function add( Model $Model){
+        // 组合数据
+        $data['name']			= request('name','');
+        $data['device_id']		= request('device_id',0);
+        // 写入
+        $id						= $Model->add($data);
+        // 提示新增失败
+        if( !$id )				return json_send(['code'=>'error','msg'=>'新增失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']);
+    }
+
+    /**
+     * 编辑
+     *
+     * */
+    public function edit(Model $Model){
+        // 组合数据
+        $id						= request('id',0);
+        // 组合数据
+        $data['name']			= request('name','');
+        $data['device_id']		= request('device_id',0);
+        // 写入
+        $result					= $Model->edit($id,$data);
+        // 提示新增失败
+        if( !$result )			return json_send(['code'=>'error','msg'=>'修改失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']);
+    }
+
+    /**
+     * 状态
+     *
+     * */
+    public function set_status( Model $Model ){
+        // 接收参数
+        $id				= request('id',0);
+        $status			= request('status',0);
+        // 查询数据
+        $result			= $Model->edit($id,['status'=>$status]);
+        // 提示新增失败
+        if( !$result )	return json_send(['code'=>'error','msg'=>'设置失败']);
+        // 记录行为
+        //$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,[],['status'=>$status]);
+        // 告知结果
+        return			json_send(['code'=>'success','msg'=>'设置成功','path'=>'']);
+    }
+}

+ 82 - 0
app/Http/Controllers/Api/CollectTaskAllocate.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Servers\Aliyun\Oss;
+use App\Models\CollectTaskAllocate as Model;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+class CollectTaskAllocate extends Api
+{
+    /**
+     * 首页列表
+     *
+     * */
+    public function index(Model $Model){
+        // 接受参数
+        $name					= request('name','');
+        // 查询条件
+        $map 					= [];
+        // 编码ID
+        if( $name )				$map[] = ['name','=',$name];
+        $uid                    = request('access_token.uid',0);
+        // 查询数据
+        $list					= $Model->query()->where($map);
+        $list                   = $list->orderByDesc('id')->paginate(request('limit',config('page_num',10)))->appends(request()->all());
+        return					json_send(['code'=>'success','msg'=>'成功','data'=>$list]);
+    }
+
+    /**
+     * 添加
+     *
+     * */
+    public function add( Model $Model){
+        // 组合数据
+        $data['name']			= request('name','');
+        $data['device_id']		= request('device_id',0);
+        // 写入
+        $id						= $Model->add($data);
+        // 提示新增失败
+        if( !$id )				return json_send(['code'=>'error','msg'=>'新增失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']);
+    }
+
+    /**
+     * 编辑
+     *
+     * */
+    public function edit(Model $Model){
+        // 组合数据
+        $id						= request('id',0);
+        // 组合数据
+        $data['name']			= request('name','');
+        $data['device_id']		= request('device_id',0);
+        // 写入
+        $result					= $Model->edit($id,$data);
+        // 提示新增失败
+        if( !$result )			return json_send(['code'=>'error','msg'=>'修改失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']);
+    }
+
+    /**
+     * 状态
+     *
+     * */
+    public function set_status( Model $Model ){
+        // 接收参数
+        $id				= request('id',0);
+        $status			= request('status',0);
+        // 查询数据
+        $result			= $Model->edit($id,['status'=>$status]);
+        // 提示新增失败
+        if( !$result )	return json_send(['code'=>'error','msg'=>'设置失败']);
+        // 记录行为
+        //$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,[],['status'=>$status]);
+        // 告知结果
+        return			json_send(['code'=>'success','msg'=>'设置成功','path'=>'']);
+    }
+}

+ 82 - 0
app/Http/Controllers/Api/CollectTaskRecord.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Servers\Aliyun\Oss;
+use App\Models\CollectTaskRecord as Model;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+class CollectTaskRecord extends Api
+{
+    /**
+     * 首页列表
+     *
+     * */
+    public function index(Model $Model){
+        // 接受参数
+        $name					= request('name','');
+        // 查询条件
+        $map 					= [];
+        // 编码ID
+        if( $name )				$map[] = ['name','=',$name];
+        $uid                    = request('access_token.uid',0);
+        // 查询数据
+        $list					= $Model->query()->where($map);
+        $list                   = $list->orderByDesc('id')->paginate(request('limit',config('page_num',10)))->appends(request()->all());
+        return					json_send(['code'=>'success','msg'=>'成功','data'=>$list]);
+    }
+
+    /**
+     * 添加
+     *
+     * */
+    public function add( Model $Model){
+        // 组合数据
+        $data['name']			= request('name','');
+        $data['device_id']		= request('device_id',0);
+        // 写入
+        $id						= $Model->add($data);
+        // 提示新增失败
+        if( !$id )				return json_send(['code'=>'error','msg'=>'新增失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']);
+    }
+
+    /**
+     * 编辑
+     *
+     * */
+    public function edit(Model $Model){
+        // 组合数据
+        $id						= request('id',0);
+        // 组合数据
+        $data['name']			= request('name','');
+        $data['device_id']		= request('device_id',0);
+        // 写入
+        $result					= $Model->edit($id,$data);
+        // 提示新增失败
+        if( !$result )			return json_send(['code'=>'error','msg'=>'修改失败']);
+        // 告知结果
+        return					json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']);
+    }
+
+    /**
+     * 状态
+     *
+     * */
+    public function set_status( Model $Model ){
+        // 接收参数
+        $id				= request('id',0);
+        $status			= request('status',0);
+        // 查询数据
+        $result			= $Model->edit($id,['status'=>$status]);
+        // 提示新增失败
+        if( !$result )	return json_send(['code'=>'error','msg'=>'设置失败']);
+        // 记录行为
+        //$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,[],['status'=>$status]);
+        // 告知结果
+        return			json_send(['code'=>'success','msg'=>'设置成功','path'=>'']);
+    }
+}

+ 47 - 0
app/Http/Controllers/Api/Login.php

@@ -0,0 +1,47 @@
+<?php namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Api\Api;
+use App\Models\Admin;
+
+/**
+ * 管理后台登录控制器
+ *
+ * @author 刘相欣
+ *
+ * */
+class Login extends Api {
+
+	/**
+	 * 登录方法				/api/login/index
+	 * 
+	 * @param string 	username	登录账号
+	 * @param string 	password	登录密码
+	 * 
+	 * */
+    public function index(Admin $AdminUser){
+		// 接收数据
+		$username							= request('username','');
+		// 接收数据
+		$password							= request('password','');
+		// 查询用户
+		$admin								= $AdminUser->orWhere('username',$username)->orWhere('phone',$username)->first(['uid','username','phone','status','password','insert_time','update_time']);
+        // 用户不存在
+		if( !$admin )	return json_send(['code'=>'error','msg'=>'密码错误或账号不存在']);
+		// 用户不存在
+		if( $admin['status'] ) 				return json_send(['code'=>'error','msg'=>'该账号已停用']);
+		// 转数组
+		$admin								= $admin->toArray();
+		// 比对密码
+		if( md5($password) != $admin['password']) return json_send(['code'=>'error','msg'=>'密码错误或账号不存在']);
+
+		// 登录
+		$accessToken 						= $AdminUser->Login($admin['uid'],'admin');
+		// 比对密码
+		if( isset($accessToken['error']) ) 	return json_send(['code'=>'error','msg'=>'登录失败','data'=>$accessToken['data']]);
+		// 登录名称
+		$accessToken['username']			= $admin['username'];
+		// 表单令牌
+		return								json_send(['code'=>'success','msg'=>'登录成功','data'=>$accessToken]);
+    }
+
+}

+ 57 - 0
app/Http/Controllers/Controller.php

@@ -0,0 +1,57 @@
+<?php namespace App\Http\Controllers;
+
+// 基础控制器
+use Illuminate\Routing\Controller as BaseController;
+/**
+ * 控制器总控
+ * 
+ */
+class Controller extends BaseController
+{
+    /**
+	 * 构造方法,初始化
+	 * 
+	 * */
+	public function __construct(){
+		// 初始化
+		if( method_exists($this, '_initialize') ) $this->_initialize();
+		// 初始化
+		if( method_exists($this, '__init') ) $this->__init();
+	}
+
+
+	/**
+     * 操作错误跳转的快捷方法
+     * @param  Mixed     $msg 提示信息
+     * @param  String    $url 跳转的URL地址
+     * @param  Int   $wait 跳转等待时间
+	 * 
+     * @return Void
+     */
+    protected function error($msg = '', $url = null, $wait = 3)
+	{
+		if ( is_null($url) ) {
+            $url = request()->ajax() ? '' : 'javascript:history.back(-1);';
+        } elseif ('' !== $url) {
+            $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : url($url);
+        }
+		// 返回结果
+		return		view('error',['msg'=>$msg,'url'=>$url,'wait'=>$wait]);
+	}
+    /**
+     * 保存用户操作历史
+     *
+     * @param   Int         $uid        用户ID
+     * @param   String      $table      操作表
+     * @param   Int         $type       操作类型
+     * @param   Array       $oldData    旧数据
+     * @param   Array       $oldData    新数据
+     *
+     */
+    protected function addAdminHistory($uid,$table,$id,$type,$oldData,$newData) {
+        //记录详细操作历史
+        $AdminHistory			= (new AdminHistory());
+        // 记录数据
+        $AdminHistory->addAll($uid,$table,$id,$type,$oldData,$newData);
+    }
+}

+ 64 - 0
app/Http/Kernel.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace App\Http;
+
+use Illuminate\Foundation\Http\Kernel as HttpKernel;
+/**
+ * Http请求核心
+ * @property  array   $middleware           全局中间件
+ * @property  array   $middlewareGroups     中间分组
+ * @property  array   $routeMiddleware      路由中间件
+ * 
+ */
+class Kernel extends HttpKernel
+{
+    /**
+     * 全局HTTP中间件堆栈
+     *
+     * 这些中间件在应用程序的每个请求期间都会运行.
+     *
+     * @var array
+     */
+    protected $middleware = [
+        // 获取应该信任的主机
+       // \App\Http\Middleware\TrustHosts::class,
+        // 关于设置信任代理有关的中间件
+        //\App\Http\Middleware\TrustProxies::class,
+        // 设置跨域请求  config/cors.php 可配置
+        \Fruitcake\Cors\HandleCors::class,
+        // post数据大小
+        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
+        // 修剪字符串
+        \App\Http\Middleware\TrimStrings::class,
+        // 将空字符串字段转换为 null
+        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
+        // 读取语言环境
+        \App\Http\Middleware\LoadLocale::class,
+    ];
+
+    /**
+     * 应用程序的路由中间件组
+     *
+     * 这些中间件在应用程序的每个路由分组请求期间都会运行.
+     * @var array
+     */
+    protected $middlewareGroups = [
+        'api' => [
+            // 动态路由绑定
+            \Illuminate\Routing\Middleware\SubstituteBindings::class,
+            // 先验证登录
+            \App\Http\Middleware\Company\Login::class,
+        ],
+    ];
+
+    /**
+     * 应用程序的路由中间件
+     *
+     * 这些中间件可以分配给组或单独使用
+     *
+     * @var array
+     */
+    protected $routeMiddleware = [
+        
+    ];
+}

+ 80 - 0
app/Http/Middleware/Api/SwitchCompanyDb.php

@@ -0,0 +1,80 @@
+<?php
+
+
+namespace App\Http\Middleware\Api;
+
+
+use Illuminate\Http\Request;
+
+use Closure;
+
+class SwitchCompanyDb
+{
+    // 无需验证的路径
+    protected   $except     = [
+        'api/wechat_pay/notify',    // 微信支付回调无需通过验证
+        'api/wechat_transfer/notify',    // 微信支付回调无需通过验证
+        'api/question_bank/question_reception/wechat_transfer/notify',    // 题库微信支付回调无需通过验证
+        'api/login/wxop_login_uri',      // 微信公众号登录
+        'api/login/wxop_auth',      // 微信公众号登录
+        'api/question_bank/question_reception/orders/jsapi_notify',  //题库小程序微信支付回调
+        'api/live_push_notify/notify',        //直播推流回调
+        'api/short_link/get_origin_url',        //解析短链
+        'api/short_link/create'        //创建短链
+    ];
+
+    public function handle(Request $request, Closure $next)
+    {
+        // 当前路径
+        $path                                                           = ltrim($request->getPathInfo(), '/');
+        // 判断是否需要切换数据库
+        if ( in_array($path, $this->except) )                           return $next($request);
+        // 提现通知需要单独判断
+        if( stripos('&'.$path,'api/wechat_transfer/notify') == 1 )      return $next($request);
+        // 题库提现通知需要单独判断
+        if( stripos('&'.$path,'api/question_bank/question_reception/wechat_transfer/notify') == 1 )      return $next($request);
+        // 退款回调需要单独判断
+        if( stripos('&'.$path,'api/wechat_pay/refund_notify') == 1 )    return $next($request);
+        // 退款回调需要单独判断
+        if( stripos('&'.$path,'api/login/wxop_auth') == 1 )             return $next($request);
+        // 判断有没有companyid
+        $companyId                                                      = $request->input('company_id', 0);
+        // 没有获取appid对应的
+        if( !$companyId )                                               {
+            //从请求中获取appid
+            $appId                                                      = $request->input('app_id', '');
+            //通过corpId获取company_id
+            $companyId                                                  = $appId ? (new Component)->getOne($appId,'company_id') :  $companyId;
+            // 没有获取appid对应的
+            if( !$companyId )                                           {
+                // 店铺ID
+                $shopId                                                 = $request->input('shop_id', 0);
+                // 店铺查询商户ID
+                $companyId                                              = $shopId ? (new Shop)->getOne($appId,'company_id') : $companyId;
+                // 如果还是没有company_id
+                if( !$companyId )                                       {
+                    // 获取请求的域名来源
+                    $domain                                             = $request->server('HTTP_REFERER');
+                    // 如果有来源
+                    if( $domain )                                       {
+                        // 获取数据
+                        $domain                                         = parse_url($domain, PHP_URL_HOST);
+                        // 从域名中获取company_id
+                        $companyId                                      = $domain ? (new CompanyDomainConfig)->getOne($domain,'company_id') : $companyId;
+                    }
+                }
+            }
+        }
+        // 测试服默认访问商户1  大方无隅测试,正式服默认访问商户3 大方无隅测试
+        $companyId                              = $companyId ? (int) $companyId : (config('app.env','') == 'local' ? 1 : 3);
+        // 切换数据库
+        $result                                 = (new CompanyDbConfig)->reconnectDb($companyId); 
+        // 如果有错误
+        if ( isset($result['error']) )          return json_send(['code'=>'no_company','msg'=>$result['error']]);
+        // 商户ID
+        $request['company_id']                  = $companyId;
+        // 下一个中间件
+        return                                  $next($request);
+    }
+
+}

+ 111 - 0
app/Http/Middleware/Company/AccessAuth.php

@@ -0,0 +1,111 @@
+<?php
+
+namespace App\Http\Middleware\Company;
+
+use Closure;
+use Illuminate\Http\Request;
+use App\Models\Manager\AuthRuleCompany;
+
+// 访问权限验证
+class AccessAuth
+{
+    // 无需验证的路径
+    protected   $except     = [
+                                'company/login/index',
+                                'company/upload/sign_url',
+                                'company/shop/list',
+                                'company/auth_rule/list',
+                                'company/city/list',
+                                'company/product/list_except',
+                                'company/custom/index_except',
+                                'company/coupon/index_except',
+                                'company/product_class/get_list',
+                                'company/open_plat/install/wxwork_auth',
+                                'company/product/get_spec_html',
+                                'company/charging_record/index',
+                                'company/charging_record/get_data',
+                                'company/charging_record/create',
+                                'company/charging_record/get_paycode_url',
+                                'company/charging_record/get_detail',
+                                'company/charging_record/get_use_record',
+                                'company/orders/express_list',
+                                'company/tag/tags/get_all',
+                                'company/short_link/create',
+                                'company/company_limit/get_remind',
+                            ];
+    //默认配置
+    protected   $_config    = [
+                                'auth_on'           => true, // 认证开关
+                                'auth_type'         => 1, // 认证方式,1为实时认证;2为登录认证。
+                                'auth_group'        => 'auth_group', // 用户组数据表名
+                                'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
+                                'auth_rule'         => 'auth_rule' // 权限规则表
+                            ];
+    /**
+	 * $prefix表前缀
+	 */
+    public function __construct()
+    {
+        // 判断配置
+        if ( config('AUTH_CONFIG') )        {
+            //可设置配置项 AUTH_CONFIG, 此配置项为数组。
+            $this->_config                  = array_merge($this->_config, config('AUTH_CONFIG'));
+        }
+    }
+
+
+
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        // 当前路径
+        $path  = ltrim($request->getPathInfo(), '/');
+        // 小程序/公众号的授权需要单独判断
+        if( stripos('&'.$path,'company/open_plat/install/wxwork_auth') == 1 ) return $next($request);
+        // 判断是否需要验证登录
+        if ( !in_array($path, $this->except) ) {
+            // 用户ID
+            $uid                                                    = request('access_token.uid',0);
+            // 如果未登录
+            if( !$uid )                                             return json_send(['code'=>'no_login','msg'=>'请登录账号','data'=>['请您登录']]);
+            // 如果不是超级管理员
+            if ( !request('access_token.is_super',0) )              {
+                // 进行验证
+                if ( !$this->check($path, $uid ) )                  return json_send(['code'=>'error','msg'=>'您没有操作权限','data'=>['没有操作权限']]);
+            }
+        }
+        // 返回下一个闭包
+        return                              $next($request);
+    }
+
+    /**
+     * 检查权限
+     * @param name string|array  需要验证的规则列表
+     * @param uid  int           认证用户的id
+     * @return boolean           通过验证返回true;失败返回false
+     */
+    private function check($path, $uid)
+    {	
+        // 未开启验证,直接通过
+        if ( !$this->_config['auth_on'] )   return true;
+        // 获取用户需要验证的所有有效规则列表
+        $authList                           = (new AuthRuleCompany())->getAuthList($uid,'company');
+        // 切割path
+        $path                               = explode('/', $path);
+        // 没有控制器
+        if( count($path) < 2 )              $path[] = 'index';
+        // 没有方法
+        if( count($path) < 3 )              $path[] = 'index';
+        // 切割path
+        $path                               = implode('/', $path);
+        // 判断是否通过验证
+        return                              in_array($path, $authList);
+    }
+
+}

+ 70 - 0
app/Http/Middleware/Company/Login.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Http\Middleware\Company;
+
+use App\Facades\Servers\Encrypts\AccessToken;
+use Closure;
+use Illuminate\Http\Request;
+use App\Models\Admin;
+
+class Login
+{
+    // 无需验证的路径
+    protected   $except     = [
+                                'api/login/index',
+                                'api/collect_equipment_execute/result_report',
+                            ];
+    //默认配置
+    protected   $_config    = [
+                                'auth_on'           => true, // 认证开关
+                                'auth_type'         => 1, // 认证方式,1为实时认证;2为登录认证。
+                                'auth_group'        => 'auth_group', // 用户组数据表名
+                                'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
+                                'auth_rule'         => 'auth_rule' // 权限规则表     
+                            ];
+    /**
+	 * $prefix表前缀
+	 */
+    public function __construct()
+    {
+        // 判断配置
+        if ( config('AUTH_CONFIG') )        {
+            //可设置配置项 AUTH_CONFIG, 此配置项为数组。
+            $this->_config                  = array_merge($this->_config, config('AUTH_CONFIG'));
+        }
+    }
+
+
+
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * 
+     * @return mixed
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        // 当前路径
+        $path  = ltrim($request->getPathInfo(), '/');
+        // 判断是否需要验证登录
+        if ( !in_array($path, $this->except) ) {
+            // 获取登录结果
+            $token                                  = (string) $request->input('access_token_admin','');
+            // 解码
+            $userInfo                               = AccessToken::decode($token);
+            // 判断登录时效
+            if( isset($userInfo['error']) )         return json_send(['code'=>'no_login','msg'=>'请您登录','data'=>$userInfo['error']]);
+            if( $userInfo['type'] != 'admin' )      return json_send(['code'=>'no_login','msg'=>'请您登录','data'=>'登录失效']);
+            if( $userInfo['expire'] < time() )      return json_send(['code'=>'no_login','msg'=>'登录失效,请您重新登录','data'=>'登录失效']);
+            // 是否是超管
+            //$userInfo['is_super']                   = is_super($userInfo['uid'],'admin') ? 1 : 0;
+            // 追加入
+            $request['access_token']                = $userInfo;
+        }
+        // 返回下一个闭包
+        return                                      $next($request);
+    }
+
+}

+ 22 - 0
app/Http/Middleware/EncryptCookies.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
+
+
+/**
+ * Cookies加密
+ */
+class EncryptCookies extends Middleware
+{
+
+    /**
+     * 不应加密的Cookie的名称
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

+ 69 - 0
app/Http/Middleware/LoadLocale.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\App;
+
+/**
+ * 读取语言环境
+ * 
+ */
+class LoadLocale
+{
+    /**
+     * 处理传入请求
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        // 设置语言
+        $request    = $this->setLocale($request);
+        // 返回结果
+        return      $next($request);
+    }
+    
+    /**
+     * 自动侦测当前语言
+     * @param  \Illuminate\Http\Request  $request
+     */
+    private function setLocale(Request $request){
+        // 默认语言
+        $langSet = config('lang.default_lang','en');
+        // 多语言自动侦测变量名
+        if ($request->get(config('lang.detect_var','lang'))) {
+            // url中设置了语言变量
+            $langSet = strtolower($request->get(config('lang.detect_var','lang')));
+        } elseif ($request->header(config('lang.header_var','lang'))) {
+            // Header中设置了语言变量
+            $langSet = strtolower($request->header(config('lang.header_var','lang')));
+            
+        } elseif ($request->cookie(config('lang.cookie_var','lang'))) {
+            // Cookie中设置了语言变量
+            $langSet = strtolower($request->cookie(config('lang.cookie_var','lang')));
+        } elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) {
+            $matches = [];
+            // 自动侦测浏览器语言
+            $match = preg_match('/^([a-z\d\-]+)/i', $request->server('HTTP_ACCEPT_LANGUAGE'), $matches);
+            // 如果有匹配语言,获取第一条语言
+            if ($match)  $langSet = strtolower($matches[1]);
+        }
+        // 统一分割符号
+        $langSet         = str_ireplace('_','-',$langSet);
+        // 允许语言列表
+        $allow_lang_list = config('lang.allow_lang_list');
+        // 如果不在允许语言内,使用默认语言
+        if( !empty($allow_lang_list) && !in_array($langSet,$allow_lang_list) ) $langSet = config('lang.default_lang','en');
+        // 请求语言设置为最终语言
+        $request->lang   = $langSet;
+        // 设置语言
+        App::setLocale($langSet);
+        // 返回结果
+        return $request;
+    }
+
+
+}

+ 17 - 0
app/Http/Middleware/PreventRequestsDuringMaintenance.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
+
+class PreventRequestsDuringMaintenance extends Middleware
+{
+    /**
+     * 启用维护模式时应可访问的URI。
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

+ 32 - 0
app/Http/Middleware/RedirectIfAuthenticated.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use App\Providers\RouteServiceProvider;
+use Closure;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+
+class RedirectIfAuthenticated
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @param  string|null  ...$guards
+     * @return mixed
+     */
+    public function handle(Request $request, Closure $next, ...$guards)
+    {
+        $guards = empty($guards) ? [null] : $guards;
+
+        foreach ($guards as $guard) {
+            if (Auth::guard($guard)->check()) {
+                return redirect(RouteServiceProvider::HOME);
+            }
+        }
+
+        return $next($request);
+    }
+}

+ 23 - 0
app/Http/Middleware/TrimStrings.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
+
+// 修剪字符串
+class TrimStrings extends Middleware
+{
+    /**
+     * 不应修剪的属性的名称。
+     *
+     * @var array
+     */
+    protected $except = [
+        // 密码空格不做修剪
+        'current_password',
+        'password',
+        'password_confirmation',
+        // 兼容App端 创建订单时候,终端名称误带后缀空格倒是签名失败
+        'client',
+    ];
+}

+ 20 - 0
app/Http/Middleware/TrustHosts.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Http\Middleware\TrustHosts as Middleware;
+
+class TrustHosts extends Middleware
+{
+    /**
+     * 获取应该信任的主机模式
+     *
+     * @return array
+     */
+    public function hosts()
+    {
+        return [
+            $this->allSubdomainsOfApplicationUrl(),
+        ];
+    }
+}

+ 24 - 0
app/Http/Middleware/TrustProxies.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Fideloper\Proxy\TrustProxies as Middleware;
+use Illuminate\Http\Request;
+
+// 关于设置信任代理有关的中间件
+class TrustProxies extends Middleware
+{
+    /**
+     * 此应用程序的受信任代理。
+     *
+     * @var array|string|null
+     */
+    protected $proxies;
+
+    /**
+     * 应用于检测代理的标头(headers)
+     *
+     * @var int
+     */
+    protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB;
+}

+ 52 - 0
app/Http/Requests/Api/Coupon.php

@@ -0,0 +1,52 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 优惠券验证器
+ * 
+ */
+class Coupon extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'       => 'string|max:20',
+            'coupon_id'     => 'required|integer|gt:0',
+            'page'          => 'integer|gte:0',
+            'limit'         => 'integer|gte:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_product'         => ['coupon_id','page','limit'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'coupon_id.required'   		=> '请选择优惠券',
+            'coupon_id.integer'   		=> '优惠券ID格式错误',
+            'coupon_id.gt'   		    => '优惠券ID格式错误',
+            'page.integer'   		    => '页码格式错误',
+            'page.gte'   		        => '页码格式错误',
+            'limit.integer'   		    => '取数格式错误',
+            'limit.gte'   		        => '取数格式错误',
+        ];
+    }
+
+}

+ 45 - 0
app/Http/Requests/Api/Coupon/Active.php

@@ -0,0 +1,45 @@
+<?php namespace App\Http\Requests\Api\Coupon;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 活动
+ * 
+ */
+class Active extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            'id'                => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_detail'            => ['id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'id.required'   	        => '请选择参与活动',
+            'id.integer'   	            => '活动ID有误',
+            'id.gt'   	                => '活动ID有误',
+        ];
+    }
+
+}

+ 45 - 0
app/Http/Requests/Api/Coupon/Custom.php

@@ -0,0 +1,45 @@
+<?php namespace App\Http\Requests\Api\Coupon;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 客户优惠券
+ * 
+ */
+class Custom extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            'coupon_id'         => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_coupon'            => ['coupon_id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'coupon_id.required'   	        => '请选择要领取的优惠券',
+            'coupon_id.integer'   	        => '优惠券ID有误',
+            'coupon_id.gt'   	            => '优惠券ID有误',
+        ];
+    }
+
+}

+ 45 - 0
app/Http/Requests/Api/Custom.php

@@ -0,0 +1,45 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 客户验证器
+ * 
+ */
+class Custom extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 地址
+            'city'                  => 'required|max:15',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes             = [
+        'set_city'                  => ['city'],
+        'get_city'                  => [],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'city.required'   	    => '请选择城市',
+        ];
+    }
+
+}

+ 70 - 0
app/Http/Requests/Api/CustomAddr.php

@@ -0,0 +1,70 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 地址验证器
+ * 
+ */
+class CustomAddr extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 地址
+            'id'                    => 'required|integer|gt:0',
+            'contact_province'      => 'required|max:15',
+            'contact_city'          => 'required|max:15',
+            'contact_area'          => 'required|max:15',
+            'contact_addr'          => 'required|max:64',
+            // 备注
+            'contact_name'          => 'required|max:20',
+            'contact_shop'          => 'max:20',
+            'contact_phone'         => 'required|phone',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'add'                   => ['contact_province','contact_city','contact_area','contact_name','contact_phone','contact_shop'],
+        'edit'                  => ['id','contact_province','contact_city','contact_area','contact_name','contact_phone','contact_shop'],
+        'del'                   => ['id'],
+        'set_default'           => ['id'],
+        'get_guess_addr'        => ['contact_shop'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'contact_province.required' => '请选择地区',
+            'contact_city.required'   	=> '请选择地区',
+            'contact_area.required'   	=> '请选择地区',
+            'contact_addr.required'   	=> '请填写地址',
+            'contact_province.max'   	=> '省份超长啦',
+            'contact_city.max'   	    => '城市超长啦',
+            'contact_area.max'   	    => '区县超长啦',
+            'contact_addr.max'   	    => '地址超长啦',
+            'contact_name.required'   	=> '请填写收件人',
+            'contact_shop.max'   	    => '店铺最多20字',
+            'contact_phone.required'    => '请填写收件人手机号',
+            'contact_phone.phone'       => '请填写正确的手机号',
+            'id.required'               => '请选择地址',
+            'id.integer'                => '地址格式有误',
+            'id.gt'                     => '地址格式有误',
+        ];
+    }
+
+}

+ 64 - 0
app/Http/Requests/Api/CustomCompany.php

@@ -0,0 +1,64 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 资质验证器
+ * 
+ */
+class CustomCompany extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 地址
+            'province'      => 'required|max:10',
+            'city'          => 'required|max:10',
+            'area'          => 'required|max:10',
+            'license_addr'  => 'required|max:64',
+            // 备注
+            'remark'        => 'required|max:20',
+            'remark_company'=> 'required|max:20',
+            // 资质
+            'license_name'  => 'required|max:20',
+            'license_code'  => 'required|size:18',
+            'legal_name'    => 'required|max:20',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'repre'               => ['remark','province','city'],
+        'custom'              => ['remark','remark_company','province','city','area','license_name','license_code','license_addr','legal_name'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'city.required'   		    => '请选择城市',
+            'province.required'   	    => '请选择省份',
+            'area.required'   		    => '请选择区县',
+            'remark.required'   	    => '请填写姓名',
+            'remark_company.required'   => '请填写终端名称',
+            'license_name.required'     => '请填写营业执照名称',
+            'license_code.required'     => '请填写营业执照编号',
+            'license_addr.required'   	=> '请填写地址',
+            'legal_name.required'       => '请填写法人代表姓名',
+            // 'legal_idcard.required'     => '请填写法人代表身份证号',
+        ];
+    }
+
+}

+ 71 - 0
app/Http/Requests/Api/CustomShopResource.php

@@ -0,0 +1,71 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 地址验证器
+ * 
+ */
+class CustomShopResource extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 地址
+            'id'                    => 'required|integer|gt:0',
+            'contact_province'      => 'required|max:15',
+            'contact_city'          => 'required|max:15',
+            'contact_area'          => 'required|max:15',
+            'contact_addr'          => 'required|max:64',
+            // 备注
+            'contact_name'          => 'required|max:20',
+            'contact_shop'          => 'max:20',
+            'contact_phone'         => 'required|phone',
+            'business_license_image'=> 'required',
+            'drug_business_license_image'=> 'required',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'add'                   => ['contact_province','contact_city','contact_area','contact_name','contact_phone','contact_shop','business_license_image','drug_business_license_image'],
+        'edit'                  => ['id','contact_province','contact_city','contact_area','contact_name','contact_phone','contact_shop','business_license_image','drug_business_license_image'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'contact_province.required' => '请选择地区',
+            'contact_city.required'   	=> '请选择地区',
+            'contact_area.required'   	=> '请选择地区',
+            'contact_addr.required'   	=> '请填写地址',
+            'contact_province.max'   	=> '省份超长啦',
+            'contact_city.max'   	    => '城市超长啦',
+            'contact_area.max'   	    => '区县超长啦',
+            'contact_addr.max'   	    => '地址超长啦',
+            'contact_name.required'   	=> '请填写收件人',
+            'contact_shop.max'   	    => '店铺最多20字',
+            'contact_phone.required'    => '请填写收件人手机号',
+            'contact_phone.phone'       => '请填写正确的手机号',
+            'id.required'               => '请选择地址',
+            'id.integer'                => '地址格式有误',
+            'id.gt'                     => '地址格式有误',
+            'business_license_image.required'   => '请上传营业执照图片',
+            'drug_business_license_image.required'   => '请上传药品经营许可证图片',
+        ];
+    }
+
+}

+ 69 - 0
app/Http/Requests/Api/CustomerForm/Company/CustomerForm.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Http\Requests\Api\CustomerForm\Company;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * SAAS自定义表单接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-10-29
+ * 
+ */
+class CustomerForm extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+        ];
+
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['page', 'limit'],
+        'add'                      => [],
+        'edit'                  => ['id', 'status'],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+        ];
+    }
+}

+ 176 - 0
app/Http/Requests/Api/DynamicQrcode/Templates.php

@@ -0,0 +1,176 @@
+<?php
+
+namespace App\Http\Requests\Api\DynamicQrcode;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 活码工具接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-08-22
+ * 
+ */
+class Templates extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules=      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'sort'              => 'required|integer|min:0',
+            'dynamic_qrcode_image_url' => 'required',
+            'link_url'           => 'required',
+            'switching_method'   => 'required|integer|in:1,2,3,4',
+            'restriction_type'   => 'required|integer|in:1,2',
+            'open_repeat_addition' => 'required|integer|in:0,1',
+            'domain_address'     => 'required',
+            'open_landing_page'   => 'required|integer|in:0,1',
+            'open_advanced_config'   => 'required|integer|in:0,1',
+            // 落地页条件规则
+            'open_safety_certification' => 'required_if:open_landing_page,1',
+            'open_guidance_prompt' => 'required_if:open_landing_page,1',
+            'activity_title' => 'required_if:open_landing_page,1',
+            'event_description' => 'required_if:open_landing_page,1',
+            'contact_event_organizer' => 'required_if:open_landing_page,1',
+            // 高级配置条件规则
+            'open_backup_content_display' => 'required_if:open_advanced_config,1',
+            'open_wechat_press_frequently_qrcode' => 'required_if:open_advanced_config,1',
+        ];
+        // 添加条件验证规则 - 使用Rule::requiredIf
+        $rules['customer_service_qrcode'] = [
+            Rule::requiredIf(function () {
+                return $this->input('open_landing_page') == 1 && 
+                       $this->input('contact_event_organizer') == 1;
+            })
+        ];
+        $rules['contact_phone'] = [
+            Rule::requiredIf(function () {
+                return $this->input('open_landing_page') == 1 && 
+                       $this->input('contact_event_organizer') == 2;
+            })
+        ];
+        $rules['backup_content'] = [
+            Rule::requiredIf(function () {
+                return $this->input('open_advanced_config') == 1 && 
+                       $this->input('open_backup_content_display') == 1;
+            })
+        ];
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['page', 'limit'],
+        'add'                      => [
+            'name',
+            'switching_method',
+            'restriction_type',
+            'open_repeat_addition',
+            'domain_address',
+            'open_landing_page',
+            'open_safety_certification',
+            'open_guidance_prompt',
+            'activity_title',
+            'event_description',
+            'contact_event_organizer',
+            'customer_service_qrcode',
+            'contact_phone',
+            'open_advanced_config',
+            'backup_content',
+            'open_wechat_press_frequently_qrcode',
+            'open_backup_content_display',
+            'status'
+        ],
+        'edit'                  => [
+            'id',
+            'name',
+            'switching_method',
+            'restriction_type',
+            'open_repeat_addition',
+            'domain_address',
+            'open_landing_page',
+            'open_safety_certification',
+            'open_guidance_prompt',
+            'activity_title',
+            'event_description',
+            'contact_event_organizer',
+            'customer_service_qrcode',
+            'contact_phone',
+            'open_advanced_config',
+            'backup_content',
+            'open_wechat_press_frequently_qrcode',
+            'open_backup_content_display',
+            'status'
+        ],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'sort.required'         => '排序未知',
+            'sort.integer'          => '排序格式错误',
+            'sort.min'              => '排序格式错误',
+            'dynamic_qrcode_image_url.required' => '活码二维码未知',
+            'link_url.required' => '活码链接地址未知',
+            'switching_method.required' => '切换方式未知',
+            'switching_method.integer' => '切换方式格式错误',
+            'switching_method.in' => '切换方式格式错误',
+            'restriction_type.required' => '上限类型未知',
+            'restriction_type.integer' => '上限类型格式错误',
+            'restriction_type.in' => '上限类型格式错误',
+            'open_repeat_addition.required' => '重复进群/加人未知',
+            'open_repeat_addition.integer' => '重复进群/加人格式错误',
+            'open_repeat_addition.in' => '重复进群/加人格式错误',
+            'domain_address.required' => '域名地址未知',
+            'open_landing_page.required' => '落地页开关未知',
+            'open_landing_page.integer' => '落地页开关格式错误',
+            'open_landing_page.in' => '落地页开关格式错误',
+            'open_advanced_config.required' => '高级开关未知',
+            'open_advanced_config.integer' => '高级开关格式错误',
+            'open_advanced_config.in' => '高级开关格式错误',
+            // 其他消息...
+            'open_safety_certification.required_if' => '当开启落地页时,安全认证标识必填',
+            'open_guidance_prompt.required_if' => '当开启落地页时,常按引导提示必填',
+            'activity_title.required_if' => '当开启落地页时,活动标题必填',
+            'event_description.required_if' => '当开启落地页时,活动描述必填',
+            'contact_event_organizer.required_if' => '当开启落地页时,联系活动方必填',
+            'customer_service_qrcode.required' => '当开启落地页并且联系活动方为客服时,客服二维码必填',
+            'contact_phone.required' => '当开启落地页时,联系活动方式为电话时,联系电话必填',
+            'open_backup_content_display.required_if' => '当开启高级配置时,备用内容显示必填',
+            'backup_content.required' => '当开启高级配置且备用内容显示开启时,备用内容必填',
+            'open_wechat_press_frequently_qrcode.required_if' => '当开启高级配置时,微信常按识别二维码必填',
+        ];
+    }
+}

+ 52 - 0
app/Http/Requests/Api/LiveReward/Order.php

@@ -0,0 +1,52 @@
+<?php namespace App\Http\Requests\Api\LiveReward;
+
+use App\Http\Requests\BaseRequest;
+use App\Rules\JsonArray;
+/**
+ * 订单验证器
+ * 
+ */
+class Order extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'       => 'string|max:20',
+            'id'                => 'required|integer|gt:0',
+            'live_id'           => 'required|integer|gt:0',
+            'gift_id'           => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'create'                => ['live_id','gift_id'],
+        'get_detail'            => ['id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'id.required'   	        => '请选择订单',
+            'id.integer'   	            => '请选择订单',
+            'id.gt'   	                => '请选择订单',
+            'live_id.required'   	    => '请选择直播间',
+            'gift_id.required'   	    => '请选择打赏礼物',
+        ];
+    }
+
+}

+ 46 - 0
app/Http/Requests/Api/Login.php

@@ -0,0 +1,46 @@
+<?php  namespace  App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 管理后台登录验证
+ * @author  liuxaingxin
+ *
+ * */
+class Login extends BaseRequest{
+
+    /**
+     *
+     * @return  array
+     */
+    public  function  rules(){
+        return [
+            'phone'     =>  'required|phone',
+            'code'      =>  'required',
+            'sms_code'  =>  'required|check_code',
+            'email_code'  =>  'required|check_code',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+		'login'  		        => ['phone','code'],
+        'phone'  		        => ['phone','sms_code'],
+        'email'  		        => ['email','email_code'],
+	];
+
+    /**
+     *
+     * @return  array
+     */
+    public  function  messages(){
+        return [
+            'phone.required'  =>  '请输入登录账号',
+            'email.required'  =>  '请输入登录邮箱账号',
+            'code.required'   =>  '请输入登录验证码',
+            'sms_code.required'   =>  '请输入登录验证码',
+            'email_code.required'   =>  '请输入登录验证码',
+        ];
+    }
+
+}

+ 39 - 0
app/Http/Requests/Api/Login/Phone.php

@@ -0,0 +1,39 @@
+<?php  namespace  App\Http\Requests\Api\Login;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 管理后台登录验证
+ * @author  liuxaingxin
+ *
+ * */
+class Phone extends BaseRequest{
+
+    /**
+     *
+     * @return  array
+     */
+    public  function  rules(){
+        return [
+            'phone'     =>  'required',
+            'code'      =>  'required|check_code',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+		'login'  		        => ['phone','code'],
+	];
+
+    /**
+     *
+     * @return  array
+     */
+    public  function  messages(){
+        return [
+            'phone.required'  =>  '请输入登录账号',
+            'code.required'   =>  '请输入登录验证码',
+        ];
+    }
+
+}

+ 67 - 0
app/Http/Requests/Api/Lottery/LiveRecord.php

@@ -0,0 +1,67 @@
+<?php namespace App\Http\Requests\Api\Lottery;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 积分记录
+ * 
+ */
+class LiveRecord extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'       => 'string|max:20',
+            'id'                => 'required|integer|gt:0',
+            'lottery_id'        => 'required|integer|gt:0',
+            'addr_id'           => 'required|integer|gt:0',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'live_id'           => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_list'              => ['lottery_id'],
+        'set_addr'              => ['addr_id','id'],
+        'get_user_list'       => ['page','limit'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'lottery_id.required'   	=> '请选择活动ID',
+            'lottery_id.integer'   	    => '活动ID有误',
+            'lottery_id.gt'   	        => '活动ID有误',
+            'id.required'   	        => '请选择奖品记录',
+            'id.integer'   	            => '奖品记录ID有误',
+            'id.gt'   	                => '奖品记录ID有误',
+            'addr_id.required'   	    => '请选择地址',
+            'addr_id.integer'   	    => '地址ID有误',
+            'addr_id.gt'   	            => '地址ID有误',
+            'page.integer'   	        => '页码有误',
+            'page.min'   	            => '页码有误',
+            'limit.integer'   	        => '每页数量有误',
+            'limit.min'   	            => '每页数量有误',
+            'live_id.required'   	    => '请选择直播间',
+            'live_id.integer'   	    => '直播间ID有误',
+            'live_id.gt'   	            => '直播间ID有误',
+        ];
+    }
+
+}

+ 56 - 0
app/Http/Requests/Api/Lottery/OrderRecord.php

@@ -0,0 +1,56 @@
+<?php namespace App\Http\Requests\Api\Lottery;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 积分记录
+ * 
+ */
+class OrderRecord extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'       => 'string|max:20',
+            'id'                => 'required|integer|gt:0',
+            'lottery_id'        => 'required|integer|gt:0',
+            'addr_id'           => 'required|integer|gt:0'
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_list'              => ['lottery_id'],
+        'set_addr'              => ['addr_id','id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'lottery_id.required'   	=> '请选择活动ID',
+            'lottery_id.integer'   	    => '活动ID有误',
+            'lottery_id.gt'   	        => '活动ID有误',
+            'id.required'   	        => '请选择奖品记录',
+            'id.integer'   	            => '奖品记录ID有误',
+            'id.gt'   	                => '奖品记录ID有误',
+            'addr_id.required'   	    => '请选择地址',
+            'addr_id.integer'   	    => '地址ID有误',
+            'addr_id.gt'   	            => '地址ID有误',
+        ];
+    }
+
+}

+ 56 - 0
app/Http/Requests/Api/Lottery/ScoreRecord.php

@@ -0,0 +1,56 @@
+<?php namespace App\Http\Requests\Api\Lottery;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 积分记录
+ * 
+ */
+class ScoreRecord extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'       => 'string|max:20',
+            'id'                => 'required|integer|gt:0',
+            'lottery_id'        => 'required|integer|gt:0',
+            'addr_id'           => 'required|integer|gt:0'
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_list'              => ['lottery_id'],
+        'set_addr'              => ['addr_id','id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'lottery_id.required'   	=> '请选择活动ID',
+            'lottery_id.integer'   	    => '活动ID有误',
+            'lottery_id.gt'   	        => '活动ID有误',
+            'id.required'   	        => '请选择奖品记录',
+            'id.integer'   	            => '奖品记录ID有误',
+            'id.gt'   	                => '奖品记录ID有误',
+            'addr_id.required'   	    => '请选择地址',
+            'addr_id.integer'   	    => '地址ID有误',
+            'addr_id.gt'   	            => '地址ID有误',
+        ];
+    }
+
+}

+ 58 - 0
app/Http/Requests/Api/Orders.php

@@ -0,0 +1,58 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+use App\Rules\JsonArray;
+/**
+ * 订单验证器
+ * 
+ */
+class Orders extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'       => 'string|max:20',
+            'id'                => 'required|integer|gt:0',
+            // 产品信息
+            'product_list' 	    => ['required','json',new JsonArray(['product_id'=>'required|numeric|gt:0','product_skuid'=>'numeric|gte:0','buy_num'=>'required|integer|gte:0'])],
+            // 下单地址
+            'addr_id' 	        => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_list'              => [],
+        'create'                => ['product_list','addr_id'],
+        'cancel'                => ['id'],
+        'get_item'              => ['id'],
+        'get_detail'            => ['id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'id.required'   	        => '请选择订单',
+            'id.integer'   	            => '请选择订单',
+            'id.gt'   	                => '请选择订单',
+            'product_list.required'   	=> '请选择需下单产品',
+            'product_list.json'   		=> '下单产品数据格式有误',
+            'addr_id.required'   	    => '请选择收货地址',
+        ];
+    }
+
+}

+ 50 - 0
app/Http/Requests/Api/Orders/Receipt.php

@@ -0,0 +1,50 @@
+<?php namespace App\Http\Requests\Api\Orders;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 活动
+ * 
+ */
+class Receipt extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            'order_id'          => 'required|integer|gt:0',
+            'file'              => 'required|file|image|max:5120',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'apply'            => ['order_id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'order_id.required'   	=> '请选择订单',
+            'order_id.integer'   	=> '订单ID有误',
+            'order_id.gt'   	    => '订单ID有误',
+            'file.required'   	    => '请上传图片',
+            'file.file'   	        => '请上传图片',
+            'file.image'   	        => '请上传图片',
+            'file.max'   	        => '图片请勿超过5MB',
+        ];
+    }
+
+}

+ 62 - 0
app/Http/Requests/Api/Product.php

@@ -0,0 +1,62 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 产品验证器
+ * 
+ */
+class Product extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'          => 'string|max:20',
+            'id'            => 'required|integer|gt:0',
+            'page'          => 'integer|gte:0',
+            'limit'         => 'integer|gte:0',
+            'class_id'      => 'required|integer|gt:0',
+            'code'          => 'required',
+            'shop_name'     => 'required',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_list'                      => ['page','limit'],
+        'get_detail'                    => ['id'],
+        'get_sku'                       => ['id'],
+        'get_product'                   => ['class_id'],
+        'get_product_by_code'           => ['code', 'shop_name'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'id.required'   		    => '请选择产品',
+            'id.integer'   		        => '产品ID格式错误',
+            'id.gt'   		            => '产品ID格式错误',
+            'page.integer'   		    => '页码格式错误',
+            'page.gte'   		        => '页码格式错误',
+            'limit.integer'   		    => '取数格式错误',
+            'limit.gte'   		        => '取数格式错误',
+            'class_id.required'         => '请选择产品分类',
+            'class_id.integer'          => '产品分类ID格式错误',
+            'class_id.gt'               => '产品分类ID格式错误',
+        ];
+    }
+
+}

+ 71 - 0
app/Http/Requests/Api/Promoter/ApplicationForm.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Http\Requests\Api\Promoter;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 推广员申请接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-09-04
+ * 
+ */
+class ApplicationForm extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'sort'              => 'required|integer|min:0',
+            'sms_code'  =>  'required',
+        ];
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => [],
+        'list'               => ['page', 'limit'],
+        'add'                      => ['sms_code'],
+        'edit'                  => [],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'sms_code.required'   =>  '请输入验证码',
+        ];
+    }
+}

+ 69 - 0
app/Http/Requests/Api/Promoter/CommonProduct.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Http\Requests\Api\Promoter;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 推广员公共商品接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-10-09
+ * 
+ */
+class CommonProduct extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'sort'              => 'required|integer|min:0',
+        ];
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => [],
+        'list'               => ['page', 'limit'],
+        'add'                      => [],
+        'edit'                  => [],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+        ];
+    }
+}

+ 74 - 0
app/Http/Requests/Api/Promoter/Configuration.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace App\Http\Requests\Api\Promoter;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 推广员配置接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-09-18
+ * 
+ */
+class Configuration extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'sort'              => 'required|integer|min:0',
+            'code_name'         => 'required|string',
+        ];
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => [],
+        'list'               => ['page', 'limit'],
+        'add'                      => [],
+        'edit'                  => [],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+        'detail'     => ['code_name'],
+        'progress'   => [],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'code_name.required'    => '配置编码code_name未知',
+            'code_name.string'    => '配置编码ode_name格式错误',
+        ];
+    }
+}

+ 69 - 0
app/Http/Requests/Api/Promoter/Customers.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Http\Requests\Api\Promoter;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 推广员客户接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-09-09
+ * 
+ */
+class Customers extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'sort'              => 'required|integer|min:0',
+        ];
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => [],
+        'list'               => ['page', 'limit'],
+        'add'                      => [],
+        'edit'                  => [],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+        ];
+    }
+}

+ 70 - 0
app/Http/Requests/Api/Promoter/EarningsRecord.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Http\Requests\Api\Promoter;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 推广员推广收益记录接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-09-15
+ * 
+ */
+class EarningsRecord extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'status '          => 'integer|in:0,1',
+            'promoter_userid'   => 'required|integer|gt:0',
+        ];
+
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'add'             => [],
+        'list'             => ['page', 'limit'],
+        'detail'          => ['id'],
+        'set_status'         => ['id', 'status'],
+    ];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'promoter_userid.required'   => '推广员ID未知',
+            'promoter_userid.integer'    => '推广员ID格式错误',
+            'promoter_userid.gt'         => '推广员ID格式错误',
+        ];
+    }
+}

+ 69 - 0
app/Http/Requests/Api/Promoter/Product.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Http\Requests\Api\Promoter;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 推广员商品接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-09-09
+ * 
+ */
+class Product extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'sort'              => 'required|integer|min:0',
+        ];
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => [],
+        'list'               => ['page', 'limit'],
+        'add'                      => [],
+        'edit'                  => [],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+        ];
+    }
+}

+ 69 - 0
app/Http/Requests/Api/Promoter/RecruitCustomers.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Http\Requests\Api\Promoter;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 推广员拉新客户
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-09-17
+ * 
+ */
+class RecruitCustomers extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'sort'              => 'required|integer|min:0',
+        ];
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => [],
+        'list'               => ['page', 'limit'],
+        'add'                      => [],
+        'edit'                  => [],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+        ];
+    }
+}

+ 77 - 0
app/Http/Requests/Api/Promoter/Users.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace App\Http\Requests\Api\Promoter;
+
+use App\Http\Requests\BaseRequest;
+use Illuminate\Validation\Rule;
+
+/**
+ * 推广员
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-09-17
+ * 
+ */
+class Users extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        $rules =      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'sort'              => 'required|integer|min:0',
+            'page_url'          => 'required|string',
+            'scene'          => 'required|string',
+        ];
+        return $rules;
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => [],
+        'list'               => ['page', 'limit'],
+        'add'                      => [],
+        'edit'                  => [],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+        'transfer_out'           => ['amount'],
+        'get_mini_qrcode'  => ['page_url','scene'],
+    ];
+
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'page_url.required' => '小程序页面地址不能为空',
+            'page_url.string' => '小程序页面地址格式错误',
+            'scene.required' => 'query 参数不能为空',
+            'scene.string' => 'query 参数格式错误',
+        ];
+    }
+}

+ 45 - 0
app/Http/Requests/Api/Redpacket.php

@@ -0,0 +1,45 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 客户优惠券
+ * 
+ */
+class Redpacket extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            'custom_redpacket_id'   => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_redpacket'          => ['custom_redpacket_id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'custom_redpacket_id.required'   	        => '请选择要领取的红包',
+            'custom_redpacket_id.integer'   	        => '红包ID有误',
+            'custom_redpacket_id.gt'   	                => '红包ID有误',
+        ];
+    }
+
+}

+ 51 - 0
app/Http/Requests/Api/Redpacket/ActiveRecord.php

@@ -0,0 +1,51 @@
+<?php namespace App\Http\Requests\Api\Redpacket;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 活动参与记录
+ * 
+ */
+class ActiveRecord extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'       => 'string|max:20',
+            'id'                => 'required|integer|gt:0',
+            'active_id'         => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_list'              => ['active_id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'active_id.required'   	    => '请选择活动ID',
+            'active_id.integer'   	    => '活动ID有误',
+            'active_id.gt'   	        => '活动ID有误',
+            'id.required'   	        => '请选择奖品记录',
+            'id.integer'   	            => '奖品记录ID有误',
+            'id.gt'   	                => '奖品记录ID有误',
+        ];
+    }
+
+}

+ 56 - 0
app/Http/Requests/Api/Score/Orders.php

@@ -0,0 +1,56 @@
+<?php namespace App\Http\Requests\Api\Score;
+
+use App\Http\Requests\BaseRequest;
+use App\Rules\JsonArray;
+/**
+ * 订单验证器
+ * 
+ */
+class Orders extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'       => 'string|max:20',
+            'id'                => 'required|integer|gt:0',
+            'product_id'        => 'required|integer|gt:0',
+            'buy_num'           => 'required|integer|gt:0',
+            'addr_id' 	        => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_list'              => [],
+        'create'                => ['product_id','buy_num','addr_id'],
+        'get_detail'            => ['id']
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'product_id.required'   	=> '请选择需兑换产品',
+            'product_id.integer'   	    => '产品ID有误',
+            'product_id.gt'   	        => '产品ID有误',
+            'buy_num.required'   		=> '兑换数量必填',
+            'buy_num.integer'   	    => '数量有误',
+            'buy_num.gt'   	            => '数量有误',
+            'addr_id.required'   	    => '请选择收货地址',
+        ];
+    }
+
+}

+ 53 - 0
app/Http/Requests/Api/Score/Product.php

@@ -0,0 +1,53 @@
+<?php namespace App\Http\Requests\Api\Score;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 积分产品验证器
+ * 
+ */
+class Product extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            // 'name'          => 'string|max:20',
+            'id'            => 'required|integer|gt:0',
+            'page'          => 'integer|gte:0',
+            'limit'         => 'integer|gte:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'get_list'            => ['page','limit'],
+        'get_detail'          => ['id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'id.required'   		    => '请选择产品',
+            'id.integer'   		        => '产品ID格式错误',
+            'id.gt'   		            => '产品ID格式错误',
+            'page.integer'   		    => '页码格式错误',
+            'page.gte'   		        => '页码格式错误',
+            'limit.integer'   		    => '取数格式错误',
+            'limit.gte'   		        => '取数格式错误',
+        ];
+    }
+
+}

+ 61 - 0
app/Http/Requests/Api/ShopCart.php

@@ -0,0 +1,61 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 购物车验证器
+ * 
+ */
+class ShopCart extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            'product_id'    => 'required|integer|gt:0',
+            'skuid'         => 'required|integer|gt:0',
+            'buy_num'       => 'required|integer|gt:0',
+            'id'            => 'required|integer|gt:0',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'add'                 => ['product_id','buy_num'],
+        'edit'                => ['id','buy_num'],
+        'del'                 => ['id'],
+        'get_list'            => [],
+        'check_list'          => [],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'product_id.required'   	=> '请选择产品',
+            'product_id.integer'   		=> '产品ID格式错误',
+            'product_id.gt'   		    => '产品ID格式错误',
+            'skuid.required'   	        => '请选择规格',
+            'skuid.integer'   		    => '规格ID格式错误',
+            'skuid.gt'   		        => '规格ID格式错误',
+            'buy_num.required'   		=> '请填写数量',
+            'buy_num.integer'   		=> '数量必须是数值',
+            'buy_num.gt'   		        => '数量必须大于1',
+            'id.required'   		    => '请选择ID',
+            'id.integer'   		        => 'ID格式错误',
+            'id.gt'   		            => 'ID格式错误',
+        ];
+    }
+
+}

+ 56 - 0
app/Http/Requests/Api/WeiZan/Orders.php

@@ -0,0 +1,56 @@
+<?php namespace App\Http\Requests\Api\WeiZan;
+
+use App\Http\Requests\BaseRequest;
+use App\Rules\JsonArray;
+
+/**
+ * 订单验证器
+ * 
+ */
+class Orders extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            'id'            => 'required|integer|gt:0',
+            'user_id'       => 'required|integer|gt:0',
+            'user_name'     => 'required',
+            'user_phone'    => 'required',
+            'pay_amount'    => 'required|numeric',
+            'order_amount'  => 'required|numeric',
+            'status'        => 'required',
+            'contact_name'  => 'required',
+            'contact_phone' => 'required',
+            'address'       => 'required',
+            'create_time'   => 'required',
+            'modify_time'   => 'required',
+            'order_items'   => ['required','json',new JsonArray(['id'=>'required','product_name'=>'required','product_price'=>'required|numeric','product_orgprice'=>'required|numeric','product_image'=>'required','sku_value'=>'required','number'=>'required|numeric','sub_total'=>'required|numeric','modify_time'=>'required'])],
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+
+        ];
+    }
+
+}

+ 47 - 0
app/Http/Requests/Api/WorkBind.php

@@ -0,0 +1,47 @@
+<?php namespace App\Http\Requests\Api;
+
+use App\Http\Requests\BaseRequest;
+/**
+ * 绑定
+ * 
+ */
+class WorkBind extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 编辑时排除ID
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+            'code'          => 'required',
+            'kailin_uid'    => 'required',
+            'work_userid'   => 'required',
+        ];
+    }
+
+    // 场景列表
+    protected   $scenes         = [
+        'custom'                => ['uid','work_userid','code'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'kailin_uid.required'   	=> '请求非法',
+            'work_userid.required'   	=> '无跟进人员',
+            'code.required'   		    => '请点击授权',
+        ];
+    }
+
+}

+ 268 - 0
app/Http/Requests/BaseRequest.php

@@ -0,0 +1,268 @@
+<?php namespace App\Http\Requests;
+
+// 表单验证
+
+use App\Exceptions\Api\ValidException;
+use Illuminate\Foundation\Http\FormRequest;
+// 验证器
+use Illuminate\Contracts\Validation\Validator;
+
+/**
+ * 基础验证器
+ * 
+ * 此验证器增加了验证场景的移除与添加等功能
+ * 
+ */
+class BaseRequest extends FormRequest
+{
+    // 场景列表
+    protected $scenes = [];
+    // 当前场景
+    protected $currentScene;
+    // 是否注入之后自动验证
+    protected $autoValidate = false;
+    // 场景需要移除的验证规则
+    protected $remove = [];
+    // 场景需要追加的验证规则
+    protected $append = [];
+
+    /**
+     * 自动认证
+     */
+    public function authorize()
+    {
+        return true;
+    }
+
+    /**
+     * 设置场景
+     * @param   string    $scene
+     * @return  $this
+     */
+    public function scene($scene)
+    {
+        $this->currentScene = $scene;
+        return $this;
+    }
+
+    /**
+     * 覆盖自动验证方法
+     */
+    public function validateResolved()
+    {
+        // 注入之后自动验证开启则执行最终验证方法
+        if ($this->autoValidate) $this->handleValidate();
+    }
+
+    /**
+     * 验证方法
+     * @param string $scene
+     */
+    public function validate($scene = '')
+    {
+        // 有场景参数。设置场景参数
+        if ($scene) $this->currentScene = $scene;
+        // 调用最终验证方法
+        $this->handleValidate();
+    }
+
+    /**
+     * 根据场景获取规则
+     * @return array|mixed
+     */
+    public function getRules()
+    {
+        // 获取验证规则
+        $rules      = $this->container->call([$this, 'rules']);
+        // 创建新规则
+        $newRules   = [];
+        // 如果当前有场景并且存在场景字段,使用场景规则
+        if ( $this->currentScene && isset($this->scenes[$this->currentScene]) ) {
+            // 如果需要验证的场景字段是数组格式直接使用,否则做字符串切割成数组
+            $sceneFields = is_array($this->scenes[$this->currentScene]) ? $this->scenes[$this->currentScene] : explode(',', $this->scenes[$this->currentScene]);
+            // 循环场景字段
+            foreach ($sceneFields as $field) {
+                // 如果场景字段存在于验证规则中,
+                if (array_key_exists($field, $rules)) $newRules[$field] = $rules[$field];
+            }
+            // 返回新规则
+            return $this->handleRules($newRules);
+        }
+        // 没有场景定义数据,使用原规则
+        return $this->handleRules($rules);
+    }
+
+    /**
+     * 处理规则数据
+     * 
+     * @return array|mixed
+     */
+    protected function handleRules($rules){
+        // 循环需要增加的验证字段
+        foreach ($this->append as $key => $rule) {
+            // 规则中不存在需要增加的验证字段
+            if ( !isset($rules[$key]) ) {
+                // 添加到验证规则中
+                $rules[$key] = $rule;
+            }else{
+                // 循环要添加规则数据
+                foreach ( $rule as $string ) {
+                    // 要添加的数据
+                    $append     = explode(':',$string);
+                    // 临时中转已存在的规则
+                    $tempRules  = [];
+                    // 循环规则中的数据
+                    foreach (explode('|',$rules[$key]) as $tkey => $string) {
+                        // 切割规则与参数
+                        $temp = explode(':',$string);
+                        $tempRules[$temp['0']] = isset($temp['1']) ? $temp['1'] : null;
+                    }
+                    // 不存在的话,增加参数
+                    $tempRules[$append[0]] = isset($append['1']) ? $append['1'] : null;
+                    // 重新写入
+                    $r   = [];
+                    // 循环规则中的数据
+                    foreach ( $tempRules as $tkey => $string) {
+                        $r[] = $tkey.':'.$string;
+                    }
+                    // 数据组合
+                    $rules[$key] = implode('|',$r);
+                }
+            }
+            // 添加后删除
+            unset($this->append[$key]);
+        }
+        // 循环删除的字段
+        foreach ($this->remove as $key => $rule) {
+            // 规则中存在字段才需要删除
+            if ( !isset($rules[$key]) )  continue;
+            // 如果字段为空,表示删除所有的验证规则
+            if( !$rule ) {
+                // 删除掉当前的字段
+                unset($rules[$key]);
+                // 跳出本次循环
+                continue;
+            }
+            // 当前规则
+            $newRule       = explode('|',$rules[$key]);
+            // 循环要删除规则数据
+            foreach ( $rule as $remove ) {
+                // 要移除的规则
+                $remove     = explode(':',$remove);
+                // 循环当前规则
+                foreach ( $newRule as $tkey => $string) {
+                    // 切割成数组
+                    $string = explode(':',$string);
+                    // 如果是要删除的规则
+                    if( $string[0]  == $remove[0]) unset($newRule[$tkey]);
+                }
+            }
+            // 重新赋值到规则
+            $rules[$key]  = implode('|',$newRule);
+            // 添加后删除
+            unset($this->remove[$key]);
+        }
+        // 返回最终规则
+        return $rules;
+    }
+
+    /**
+     * 移除某个字段的验证规则
+     * @access public
+     * @param string|array $field 字段名
+     * @param mixed        $rule  验证规则 null 移除所有规则
+     * @return $this
+     */
+    public function remove($field, $rule = null)
+    {
+        if (is_array($field)) {
+            foreach ($field as $key => $rule) {
+                if (is_int($key)) {
+                    $this->remove($rule);
+                } else {
+                    $this->remove($key, $rule);
+                }
+            }
+        } else {
+            if (is_string($rule)) {
+                $rule = explode('|', $rule);
+            }
+
+            $this->remove[$field] = $rule;
+        }
+        return $this;
+    }
+
+    /**
+     * 追加某个字段的验证规则
+     * @access public
+     * @param string|array $field 字段名
+     * @param mixed        $rule  验证规则
+     * @return $this
+     */
+    public function append($field, $rule = null)
+    {
+        if (is_array($field)) {
+            foreach ($field as $key => $rule) {
+                $this->append($key, $rule);
+            }
+        } else {
+            if (is_string($rule)) {
+                $rule = explode('|', $rule);
+            }
+
+            $this->append[$field] = $rule;
+        }
+
+        return $this;
+    }
+
+    /**
+     * 覆盖设置 自定义验证器
+     * @param $factory
+     * @return mixed
+     */
+    public function validator($factory)
+    {
+        return $factory->make(
+            $this->validationData(),
+            $this->getRules(),
+            $this->messages(),
+            $this->attributes()
+        );
+    }
+
+    /**
+     * 最终验证方法
+     * 
+     */
+    protected function handleValidate()
+    {
+        // 验证前准备
+        $this->prepareForValidation();
+        // 判断用户是否有请求权限,默认为有,如果没有权限,告知失败
+        if (!$this->passesAuthorization()) $this->failedAuthorization();
+        // 获取验证对象实例
+        $instance = $this->getValidatorInstance();
+        // 如果验证失败
+        if ($instance->fails()) $this->failedValidation($instance);
+        // 验证后处理
+        $this->passedValidation();
+    }
+
+    /**
+     * Handle a failed validation attempt.
+     *
+     * @param  \Illuminate\Contracts\Validation\Validator  $validator
+     *
+     * @throws \Illuminate\Validation\ValidationException
+     */
+    protected function failedValidation(Validator $validator)
+    {
+        // 获取提示信息
+        $error             = empty($validator->errors()->all()[0]) ? '' : $validator->errors()->all()[0];
+        // 响应抛出
+        throw               new ValidException($error,$validator->errors()->toArray());
+    }
+
+}

+ 82 - 0
app/Http/Requests/Community/CommBackend/Topic.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Http\Requests\Community\CommBackend;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 帖子接口验证
+ * @author 唐远望
+ * @version 1.0
+ * @date 2025-04-13
+ * 
+ */
+class Topic extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'title'             => 'required',
+            'content'           => 'required',
+            'type_id'           => 'required|integer|gt:0',
+            'content_type'      => 'required|integer|in:1,2',
+            'is_top'            => 'required|integer|in:0,1',
+        ];
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['page', 'limit'],
+        'add'                      => ['title', 'content', 'type_id', 'content_type'],
+        'edit'                  => ['id'],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+        'set_top'                => ['id', 'is_top'],
+    ];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'               => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'title.required'    => '标题必填',
+            'content.required'  => '内容必填',
+            'type_id.required'  => '分类未知',
+            'type_id.integer'   => '分类格式错误',
+            'type_id.gt'        => '分类格式错误',
+            'content_type.required'  => '内容类型未知',
+            'content_type.integer'   => '内容类型格式错误',
+            'content_type.in'        => '内容类型格式错误',
+            'is_top.required'   => '置顶未知',
+            'is_top.integer'    => '置顶格式错误',
+            'is_top.in'         => '置顶格式错误',
+        ];
+    }
+}

+ 69 - 0
app/Http/Requests/Community/CommBackend/TopicAttachment.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Http\Requests\Community\CommBackend;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 帖子附件验证器
+ * @author  唐远望
+ * @version 1.0
+ * @date 2025-05-06
+ * 
+ */
+class TopicAttachment extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'file'              => 'required|file',
+        ];
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['page', 'limit'],
+        'add'                      => ['name','status'],
+        'edit'                  => ['id', 'name'],
+        'set_status'              => ['id', 'status'],
+        'delete'  		        => ['id'],
+        'uploadimg'             => ['file'],
+    ];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'             => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'file.required'     => '文件未上传',
+            'file.file'         => '文件格式错误',
+        ];
+    }
+}

+ 71 - 0
app/Http/Requests/Community/CommBackend/TopicComment.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Http\Requests\Community\CommBackend;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 帖子评论验证器
+ * @author  唐远望
+ * @version 1.0
+ * @date 2025-04-11
+ * 
+ */
+class TopicComment extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'topic_id'          => 'required|integer|gt:0',
+            'content'           => 'required',
+        ];
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['topic_id','page', 'limit'],
+        'add'                      => ['topic_id', 'content', 'status'],
+        'edit'                  => ['id', 'content'],
+        'set_status'              => ['id', 'status'],
+        'delete'                  => ['id'],
+    ];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'             => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'topic_id.required' => '帖子ID未知',
+            'topic_id.integer'  => '帖子ID格式错误',
+            'topic_id.gt'       => '帖子ID格式错误',
+            'content.required'  => '评论内容必填',
+        ];
+    }
+}

+ 70 - 0
app/Http/Requests/Community/CommBackend/TopicExamine.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Http\Requests\Community\CommBackend;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 帖子审核验证器
+ * @author  唐远望
+ * @version 1.0
+ * @date 2025-04-21
+ * 
+ */
+class TopicExamine extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'topic_id'          => 'required|integer|gt:0'
+        ];
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['page', 'limit'],
+        'add'                      => ['topic_id','status'],
+        'edit'                  => ['id','status'],
+        'set_status'              => ['id', 'status'],
+        'delete'  		        => ['id'],
+    ];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'             => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'topic_id.required' => '帖子ID未知',
+            'topic_id.integer'  => '帖子ID格式错误',
+            'topic_id.gt'       => '帖子ID格式错误',
+            'examine_content.required' => '审核内容未知',
+        ];
+    }
+}

+ 82 - 0
app/Http/Requests/Community/CommBackend/TopicNotice.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Http\Requests\Community\CommBackend;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 系统通知验证器
+ * @author  唐远望
+ * @version 1.0
+ * @date 2025-04-11
+ * 
+ */
+class TopicNotice extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'topic_id'          => 'required|integer|gt:0',
+            'title'             => 'required',
+            'content'           => 'required',
+            'msg_type'          => 'required|integer|in:0,1',
+            'custom_uid'        => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+        ];
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['page', 'limit'],
+        'add'                      => ['topic_id','title','content','msg_type','custom_uid','status'],
+        'edit'                  => ['id','title','content','msg_type','custom_uid','status'],
+        'set_status'              => ['id', 'status'],
+        'delete'  		        => ['id'],
+    ];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'             => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'topic_id.required' => '帖子ID未知',
+            'topic_id.integer'  => '帖子ID格式错误',
+            'topic_id.gt'       => '帖子ID格式错误',
+            'title.required'    => '标题必填',
+            'content.required'  => '内容必填',
+            'msg_type.required' => '消息类型未知',
+            'msg_type.integer'  => '消息类型格式错误',
+            'msg_type.in'       => '消息类型格式错误',
+            'custom_uid.required' => '用户ID未知',
+            'custom_uid.integer'  => '用户ID格式错误',
+            'custom_uid.gt'       => '用户ID格式错误',
+        ];
+    }
+}

+ 71 - 0
app/Http/Requests/Community/CommBackend/TopicRule.php

@@ -0,0 +1,71 @@
+<?php 
+
+namespace App\Http\Requests\Community\CommBackend;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 帖子规则验证器
+ * @author  唐远望
+ * @version 1.0
+ * @date 2025-04-11
+ * 
+ */
+class TopicRule extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+	        'name' 			    => 'required',
+	        'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+            'content'           => 'required',
+            'title'             => 'required',
+        ];
+    }
+
+    
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['page','limit'],  
+		'add'  		            => ['title','content','status'],
+        'edit'  		        => ['id','title','content','status'],
+        'set_status'  		    => ['id','status'],
+        'delete'  		        => ['id'],
+        'update_config'          => ['content'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'   		    => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+            'content.required'  => '内容必填',
+            'title.required'    => '标题必填',
+        ];
+    }
+    
+}

+ 65 - 0
app/Http/Requests/Community/CommBackend/TopicType.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace App\Http\Requests\Community\CommBackend;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 帖子类型验证器
+ * @author  唐远望
+ * @version 1.0
+ * @date 2025-04-11
+ * 
+ */
+class TopicType extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            'name'                 => 'required',
+            'id'                => 'required|integer|gt:0',
+            'status'            => 'required|integer|in:0,1',
+            'page'              => 'integer|min:1',
+            'limit'             => 'integer|min:1',
+        ];
+    }
+
+
+    // 场景列表
+    protected   $scenes         = [
+        'detail'             => ['id'],
+        'list'               => ['page', 'limit'],
+        'add'                      => ['name','status'],
+        'edit'                  => ['id', 'name'],
+        'set_status'              => ['id', 'status'],
+        'delete'  		        => ['id'],
+    ];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '名称必填',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'             => 'ID格式错误',
+            'status.required'   => '状态未知',
+            'status.integer'    => '状态格式错误',
+            'status.in'         => '状态格式错误',
+            'page.integer'      => '页码格式错误',
+            'page.min'          => '页码格式错误',
+            'limit.integer'     => '每页数量格式错误',
+            'limit.min'         => '每页数量格式错误',
+        ];
+    }
+}

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä