瀏覽代碼

项目初始花

whj 4 年之前
當前提交
5d461b965f
共有 71 個文件被更改,包括 4350 次插入0 次删除
  1. 20 0
      app/Admin/Actions/Box/CloseDoor.php
  2. 27 0
      app/Admin/Actions/Box/getRule.php
  3. 47 0
      app/Admin/Actions/Box/sendRule.php
  4. 37 0
      app/Admin/Actions/Device/BatchDel.php
  5. 17 0
      app/Admin/Actions/Device/Box.php
  6. 58 0
      app/Admin/Actions/Device/DeviceOperator.php
  7. 18 0
      app/Admin/Actions/Device/Lock.php
  8. 18 0
      app/Admin/Actions/Device/Play.php
  9. 32 0
      app/Admin/Actions/Device/Reflash.php
  10. 80 0
      app/Admin/Actions/Device/downloadZip.php
  11. 36 0
      app/Admin/Actions/Device/getRule.php
  12. 52 0
      app/Admin/Actions/Device/sendRule.php
  13. 53 0
      app/Admin/Actions/Device/testRule.php
  14. 36 0
      app/Admin/Actions/Lock/sendRule.php
  15. 19 0
      app/Admin/Controllers/ApiController.php
  16. 10 0
      app/Admin/Controllers/AuthController.php
  17. 117 0
      app/Admin/Controllers/Config/ConfigController.php
  18. 304 0
      app/Admin/Controllers/Config/FormController.php
  19. 96 0
      app/Admin/Controllers/DeviceBoxController.php
  20. 176 0
      app/Admin/Controllers/DeviceController.php
  21. 92 0
      app/Admin/Controllers/DeviceTypeBoxController.php
  22. 81 0
      app/Admin/Controllers/DeviceTypeController.php
  23. 67 0
      app/Admin/Controllers/ExampleController.php
  24. 34 0
      app/Admin/Controllers/HomeController.php
  25. 171 0
      app/Admin/Controllers/LockController.php
  26. 26 0
      app/Admin/Extensions/Week.php
  27. 56 0
      app/Admin/bootstrap.php
  28. 27 0
      app/Admin/routes.php
  29. 217 0
      app/Console/Commands/Crawle.php
  30. 42 0
      app/Console/Kernel.php
  31. 37 0
      app/Events/DeviceEvent.php
  32. 37 0
      app/Events/LockEvent.php
  33. 55 0
      app/Exceptions/Handler.php
  34. 40 0
      app/Http/Controllers/Auth/ConfirmPasswordController.php
  35. 22 0
      app/Http/Controllers/Auth/ForgotPasswordController.php
  36. 40 0
      app/Http/Controllers/Auth/LoginController.php
  37. 73 0
      app/Http/Controllers/Auth/RegisterController.php
  38. 30 0
      app/Http/Controllers/Auth/ResetPasswordController.php
  39. 42 0
      app/Http/Controllers/Auth/VerificationController.php
  40. 13 0
      app/Http/Controllers/Controller.php
  41. 45 0
      app/Http/Controllers/IndexController.php
  42. 82 0
      app/Http/Kernel.php
  43. 21 0
      app/Http/Middleware/Authenticate.php
  44. 17 0
      app/Http/Middleware/CheckForMaintenanceMode.php
  45. 17 0
      app/Http/Middleware/EncryptCookies.php
  46. 27 0
      app/Http/Middleware/RedirectIfAuthenticated.php
  47. 18 0
      app/Http/Middleware/TrimStrings.php
  48. 23 0
      app/Http/Middleware/TrustProxies.php
  49. 24 0
      app/Http/Middleware/VerifyCsrfToken.php
  50. 34 0
      app/Jobs/ProcessTestRule.php
  51. 10 0
      app/Links.php
  52. 86 0
      app/Listeners/DeviceEventListener.php
  53. 59 0
      app/Listeners/LockEventListener.php
  54. 11 0
      app/Model/BuildInfo.php
  55. 11 0
      app/Model/Communite.php
  56. 29 0
      app/Model/DeviceBox.php
  57. 71 0
      app/Model/DeviceInfo.php
  58. 15 0
      app/Model/DeviceType.php
  59. 10 0
      app/Model/DeviceTypeBox.php
  60. 13 0
      app/Model/Last.php
  61. 11 0
      app/Model/Links.php
  62. 72 0
      app/Model/LockInfo.php
  63. 76 0
      app/Model/SystemConfig.php
  64. 28 0
      app/Providers/AppServiceProvider.php
  65. 30 0
      app/Providers/AuthServiceProvider.php
  66. 21 0
      app/Providers/BroadcastServiceProvider.php
  67. 40 0
      app/Providers/EventServiceProvider.php
  68. 80 0
      app/Providers/RouteServiceProvider.php
  69. 237 0
      app/Server/AliYunIotServer.php
  70. 638 0
      app/Server/DeviceServer.php
  71. 39 0
      app/User.php

+ 20 - 0
app/Admin/Actions/Box/CloseDoor.php

xqd
@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Admin\Actions\Box;
+
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Http\Request;
+
+class CloseDoor extends RowAction
+{
+    public $name  = '关闭设备';
+
+    public function handle(Model $model, Request $request)
+    {
+        // $request ...
+
+        return $this->response()->success('Success message...')->refresh();
+    }
+
+}

+ 27 - 0
app/Admin/Actions/Box/getRule.php

xqd
@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Admin\Actions\Box;
+
+use App\Model\LockInfo;
+use App\Server\DeviceServer;
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Http\Request;
+
+class getRule extends RowAction
+{
+    public $name = '属性上报';
+
+    public function handle(Model $model, Request $request)
+    {
+        $device_name = $this->row->devices->device_name;
+        $box_name = $this->row->name;
+        $rule = json_encode(['get'=>$box_name]);
+        $res = (new DeviceServer())->sendMsg(intval($device_name),$rule);
+        if($res['Success'] == true){
+            return $this->response()->success('获取规则成功')->refresh();
+        }
+        return $this->response()->error('获取规则失败');
+
+    }
+}

+ 47 - 0
app/Admin/Actions/Box/sendRule.php

xqd
@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Admin\Actions\Box;
+
+use App\Model\DeviceBox;
+use App\Model\LockInfo;
+use App\Server\DeviceServer;
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+class sendRule extends RowAction
+{
+    public $name = '下发协议';
+
+    public function handle(Model $model, Request $request)
+    {
+
+        $id = $this->row->id;
+        $box_name = $this->row->name;
+        $device_name = $this->row->devices->device_name;
+        $lock_info = LockInfo::where(['box_id'=>$id,'status'=>1])->get();
+        $rule = [];
+        foreach ($lock_info as $val){
+            $rule[$box_name][] =  [
+                'open'=>$val->open_time,
+                'close'=>$val->close_time,
+                'start'=>$val->start_time,
+                'type'=>$val->type,
+                'value'=>$val->value,
+            ];
+        }
+//        return $this->response()->success(json_encode($rule))->refresh();
+
+        if(!empty($rule)){
+            $rule['query'] = 1800;
+            Log::info(json_encode($rule).PHP_EOL);
+            $res = (new DeviceServer())->sendMsg($device_name,json_encode($rule));
+            if($res['Success'] == true){
+                return $this->response()->success('下发成功')->refresh();
+            }
+        }
+        return $this->response()->error('下发失败')->refresh();
+    }
+
+}

+ 37 - 0
app/Admin/Actions/Device/BatchDel.php

xqd
@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use App\Model\UserDevice;
+use App\Model\UserInfo;
+use Encore\Admin\Actions\BatchAction;
+use Illuminate\Database\Eloquent\Collection;
+
+class BatchDel extends BatchAction
+{
+    public $name = '批量解绑';
+
+    public function handle(Collection $collection)
+    {
+        $ids =[];
+        $uid =session('list_uid');
+        $user = UserInfo::find($uid);
+        if ($user->role == 2){
+            return $this->response()->error('请在设备中解绑')->refresh();
+        }
+
+        foreach ($collection as $model) {
+            $ids[]=$model->id;
+        }
+        $res = UserDevice::where('user_id',$uid)->whereIn('device_id',$ids)->delete();
+        if ($res)
+            return $this->response()->info('解除绑定成功')->refresh();
+        return $this->response()->error('操作失败,请重试')->refresh();
+    }
+
+    public function dialog()
+    {
+        $this->confirm('确定把该用户的所有设备解绑?');
+    }
+
+}

+ 17 - 0
app/Admin/Actions/Device/Box.php

xqd
@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use Encore\Admin\Actions\RowAction;
+
+class Box extends RowAction
+{
+    public $name = '设备盒子';
+
+
+    public function href()
+    {
+        $id = $this->row->id;
+        return '/admin/device_box?device_id='.$id;
+    }
+}

+ 58 - 0
app/Admin/Actions/Device/DeviceOperator.php

xqd
@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use App\Model\DeliverInfo;
+use App\Model\DeviceInfo;
+use App\Server\DeviceServer;
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Database\Eloquent\Model;
+
+class DeviceOperator extends RowAction
+{
+    public $name = '设备管理';
+
+    public function handle(Model $model)
+    {
+        // $model ...
+//        $row = $this->getRow();
+        $device = new DeviceServer();
+//        $s =  request('runningStatus');
+//        if ($row['runningStatus'] != $s)
+//            $device->switchDevice($row['iot_id'],$s);
+//        $s =  request('deliver_lock_switch');
+//        if ($row['deliver_lock_switch'] != $s)
+//            $device->doorInOperation($row['iot_id'],$s);
+//        $s =  request('lock_switch');
+//        if ($row['lock_switch'] != $s)
+//            $device->doorInOperation($row['iot_id'],$s);
+
+        return $this->response()->info('操作成功')->refresh();
+    }
+
+
+
+    public function form()
+    {
+        $row = $this->getRow();
+//        $s = 1;
+//        if ($row['runningStatus'] == DeviceInfo::DISABLE)
+//            $s = 0;
+//        $this->radio('runningStatus', '锁定设备')->options(['打开','关闭'])->default($s);
+//        $s = 1;
+//        if ($row['deliver_lock_switch'] == 0)
+//            $s = 0;
+//        $this->radio('deliver_lock_switch', '投递门状态')->options(['打开','关闭'])->default($s);
+//        $s = 1;
+//        if ($row['lock_switch'] == 0)
+//            $s = 0;
+//        $this->radio('lock_switch', '收运门状态')->options(['打开','关闭'])->default($s);
+        $this->html("<div>设备开关不会影响真实数据,只做临时调试用。不能用来收运,不能用来收运,不能用来收运,否者会导致后台账目混乱,并且称读数也不会清零!</div>",'提示:');
+//        $this->H("<div><a href='javascript:setDeviceStatus(\"switchDevice\",\"{$row['iot_id']}\",1);' class='btn btn-success'>启用</a>&nbsp;<a href='javascript:setDeviceStatus(\"switchDevice\",\"{$row['iot_id']}\",0);' class='btn btn-danger'>禁用</a></div>",'设备:');
+//        $this->H("<div><a href='javascript:setDeviceStatus(\"doorOperation\",\"{$row['iot_id']}\",2);' class='btn btn-success'>打开</a></div>",'收运门:');
+//        $this->H("<div><a href='javascript:setDeviceStatus(\"doorOperation\",\"{$row['iot_id']}\",1);' class='btn btn-success'>打开</a>&nbsp;<a href='javascript:setDeviceStatus(\"doorOperation\",\"{$row['iot_id']}\",0);' class='btn btn-danger'>关闭</a></div>",'投递门:');
+
+
+    }
+
+}

+ 18 - 0
app/Admin/Actions/Device/Lock.php

xqd
@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Http\Request;
+
+class Lock extends RowAction
+{
+    public $name = '设备锁';
+
+    public function href()
+    {
+        $id = $this->row->id;
+        return '/admin/lock_info?device_id='.$id;
+    }
+
+}

+ 18 - 0
app/Admin/Actions/Device/Play.php

xqd
@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Database\Eloquent\Model;
+
+class Play extends RowAction
+{
+    public $name = '<span class="text-danger">查看监控直播</span>';
+
+    public function href()
+    {
+//        dump($this);die;
+        return "/admin/play?serial_number={$this->row()->serial_number}";
+    }
+
+}

+ 32 - 0
app/Admin/Actions/Device/Reflash.php

xqd
@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use App\Server\DeviceServer;
+use Encore\Admin\Actions\Action;
+use Illuminate\Http\Request;
+
+class Reflash extends Action
+{
+    protected $selector = '.reflash';
+
+    public function handle(Request $request)
+    {
+        // $request ...
+
+       $res = (new DeviceServer())->refreshList();
+
+       if ($res !== true)
+           return $this->response()->error($res)->refresh();
+       return $this->response()->success('设备更新成功')->refresh();
+
+
+    }
+
+    public function html()
+    {
+        return <<<HTML
+        <a class="btn btn-sm btn-danger reflash" style="margin-right: 10px;"><i class="fa fa-refresh"></i>&nbsp;刷新设备信息</a>
+HTML;
+    }
+}

+ 80 - 0
app/Admin/Actions/Device/downloadZip.php

xqd
@@ -0,0 +1,80 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use App\Model\DeviceInfo;
+use App\Model\SystemConfig;
+use App\Server\DeviceServer;
+use EasyWeChat\Factory;
+use Encore\Admin\Actions\Action;
+use Illuminate\Http\Request;
+
+class downloadZip extends Action
+{
+    protected $selector = '.downloadZip';
+
+    public function handle(Request $request)
+    {
+        // $request ...
+
+       $devices = DeviceInfo::all(['device_name','id']);
+       $result = [];
+       $zip_file = public_path('qrcode.zip');
+       $zip = new \ZipArchive();
+       $zip->open($zip_file, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
+       foreach ($devices as $device){
+           $r = $this->generateImg($device->id,$device->device_city);
+           if ($r)
+           {
+               $str = str_replace(['/','\\',':','*','"','<','>','|','?'],'_',$device->device_name);
+               $zip->addFile($r, $str.".png");
+           }
+       }
+
+       $zip->close();
+
+       return $this->response()->download('/qrcode.zip');
+
+
+    }
+
+
+    public function generateImg($device_id,$device_city)
+    {
+        $wechat_app = SystemConfig::get('wechat_config');
+        if (!$wechat_app || !isset($wechat_app['appId']) || !isset($wechat_app['appSecret'])) {
+            return false;
+        }
+        $config = [
+            'app_id' => $wechat_app['appId'],
+            'secret' => $wechat_app['appSecret'],
+            'response_type' => 'array'
+        ];
+
+        $app = Factory::miniProgram($config);
+
+
+        try{
+            $response = $app->app_code->getQrCode('pages/qrcode/qrcode?id='.$device_id.'&community='.$device_city,300);
+        }catch (\Exception $exception){
+            return false;
+        }
+
+        $filename = "error";
+        if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
+            $filename = $response->saveAs(public_path('upload/DeviceQRCODE'), request('id').'.jpg');
+        }
+        if ($filename == "error")
+            return false;
+
+        return public_path("upload/DeviceQRCODE/{$filename}");
+
+    }
+
+    public function html()
+    {
+        return <<<HTML
+        <a href="javascript:$.admin.toastr.info('已经提交请求,处理完成会自动下载,请稍等!');" class="btn btn-sm btn-success downloadZip" style="margin-right: 10px;"><i class="fa fa-download"></i>&nbsp;下载设备图片</a>
+HTML;
+    }
+}

+ 36 - 0
app/Admin/Actions/Device/getRule.php

xqd
@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use App\Model\DeviceBox;
+use App\Server\DeviceServer;
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+class getRule extends RowAction
+{
+   public $name = '属性上报';
+
+
+    public function handle(Model $model, Request $request)
+    {
+        $id = $this->row->id;
+        $device_name = $this->row->device_name;
+        $box_info = DeviceBox::where(['device_id'=>$id])->get();
+        if(!empty($box_info)){
+            foreach ($box_info as $box){
+                $box_name = $box->name;
+                $rule = ['get'=>$box_name];
+                if(!empty($rule)){
+                    Log::info(json_encode($rule).PHP_EOL);
+                    $res = (new DeviceServer())->sendMsg($device_name,json_encode($rule));
+                    sleep(12);
+                }
+            }
+            return $this->response()->success('上报属性成功')->refresh();
+        }
+    }
+
+}

+ 52 - 0
app/Admin/Actions/Device/sendRule.php

xqd
@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use App\Model\DeviceBox;
+use App\Model\LockInfo;
+use App\Server\DeviceServer;
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+class sendRule extends RowAction
+{
+    public $name = '下发协议';
+
+
+    public function handle(Model $model, Request $request)
+    {
+        $id = $this->row->id;
+        $device_name = $this->row->device_name;
+        $box_info = DeviceBox::where(['device_id'=>$id])->get();
+        if(!empty($box_info)){
+            foreach ($box_info as $box){
+                $box_name = $box->name;
+                $lock_info = LockInfo::where(['box_id'=>$box->id,'status'=>1])->get();
+                $rule = [];
+                foreach ($lock_info as $val){
+                    $rule[$box_name][] =  [
+                        'open'=>$val->open_time,
+                        'close'=>$val->close_time,
+                        'start'=>$val->start_time,
+                        'type'=>$val->type,
+                        'value'=>$val->value,
+                    ];
+                }
+
+                if(!empty($rule)){
+                    $rule['query'] = 1800;
+                    Log::info(json_encode($rule).PHP_EOL);
+                    $res = (new DeviceServer())->sendMsg($device_name,json_encode($rule));
+                    if($res['Success'] != true){
+                        return $this->response()->error($box_name.'下发失败');
+                        continue;
+                    }
+                    sleep(22);
+                }
+            }
+            return $this->response()->success('下发成功')->refresh();
+        }
+    }
+}

+ 53 - 0
app/Admin/Actions/Device/testRule.php

xqd
@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Admin\Actions\Device;
+
+use App\Model\DeviceBox;
+use App\Server\DeviceServer;
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+class testRule extends RowAction
+{
+    public $name = '测试命令';
+
+    public function handle(Model $model, Request $request)
+    {
+        set_time_limit(1200);
+        $id = $this->row->id;
+        $device_name = $this->row->device_name;
+        $box_info = DeviceBox::where(['device_id'=>$id])->get();
+        if(!empty($box_info)){
+            foreach ($box_info as $box){
+                $box_name = $box->name;
+                $test_json = $request->get($box_name);
+                if(is_null(json_decode($test_json))){
+                    return $this->response()->error($box_name.'下发数据必须是json');
+                }
+                if(!empty($test_json) && json_decode($test_json)){
+                    Log::info($test_json.PHP_EOL);
+                    (new DeviceServer())->sendMsg($device_name,$test_json);
+                    sleep(18);
+                }
+            }
+            return $this->response()->success('下发成功')->refresh();
+
+        }
+    }
+
+
+    public function form()
+    {
+        $id = $this->row->id;
+        $box_info = DeviceBox::where(['device_id'=>$id])->get();
+        if(!empty($box_info)){
+            foreach ($box_info as $box){
+                $box_name = $box->name;
+                $this->textarea($box_name,'请输入'.$box_name.'测试json');
+            }
+        }
+    }
+
+}

+ 36 - 0
app/Admin/Actions/Lock/sendRule.php

xqd
@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Admin\Actions\Lock;
+
+use App\Model\LockInfo;
+use App\Server\DeviceServer;
+use Encore\Admin\Actions\RowAction;
+use Illuminate\Http\Request;
+
+class sendRule extends RowAction
+{
+    public $name = '更新规则';
+    public function handle(Request $request)
+    {
+        $rule = '{
+                    "box1": [
+                        {"open":"09:33", "close":"09:34", "type":2, "start":"2020-09-01 10:00:00","value":""},
+                        {"open":"09:35", "close":"09:36", "type":2, "start":"2020-09-01 10:00:00","value":""},
+                        {"open":"09:37", "close":"09:38", "type":3, "start":"2020-09-01 10:00:00","value":["6","7"]}
+                    ],
+                    "query":600
+                } ';
+        $locks = LockInfo::where(['device_id'=>$this->row->id])->get()->groupBy('box_name');
+
+        foreach ($locks as $lock ){
+
+        }
+        $res = (new DeviceServer())->sendMsg(868626044260522,$rule);
+        if($res['Success'] == true){
+            return $this->response()->success('更新设备规则成功')->refresh();
+        } else {
+            return $this->response()->error('更新命令失败');
+        }
+    }
+
+}

+ 19 - 0
app/Admin/Controllers/ApiController.php

xqd
@@ -0,0 +1,19 @@
+<?php
+
+
+namespace App\Admin\Controllers;
+
+
+use App\Model\DeviceBox;
+use Encore\Admin\Controllers\AuthController as BaseAuthController;
+use Illuminate\Http\Request;
+
+class ApiController extends BaseAuthController
+{
+    public function get_box(Request $request)
+    {
+        $id = $request->get('q');
+        return DeviceBox::where(['device_id'=>$id])->get(['name as text','id']);
+    }
+
+}

+ 10 - 0
app/Admin/Controllers/AuthController.php

xqd
@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use Encore\Admin\Controllers\AuthController as BaseAuthController;
+
+class AuthController extends BaseAuthController
+{
+
+}

+ 117 - 0
app/Admin/Controllers/Config/ConfigController.php

xqd
@@ -0,0 +1,117 @@
+<?php
+
+namespace App\Admin\Controllers\Config;
+
+use App\Base_Area;
+use App\Model\SystemConfig;
+use Encore\Admin\Controllers\AdminController;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+use Encore\Admin\Show;
+
+/**
+ * @author pxwei
+ * Class ConfigController
+ * @package App\Admin\Controllers\City
+ */
+class ConfigController extends AdminController
+{
+    /**
+     * Title for current resource.
+     *
+     * @var string
+     */
+    protected $title = '配置管理';
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        $grid = new Grid(new SystemConfig);
+
+        $grid->disableCreateButton(false);
+        $grid->column('id', __('ID'))->sortable();
+        $grid->column('group', __('分组'))->editable();
+        $grid->column('key', __('键'))->editable();
+        $grid->column('value', __('值'))->display(function (){
+            if (strlen($this->value)>30){
+                return mb_substr($this->value,0,20).'...';
+            }
+            return $this->value;
+        })->modal('值',function (){
+            return $this->value;
+        })->copyable();
+
+        $grid->column('chinese', __('中文名'))->editable();
+        $grid->column('fieldType', __('类型'))->editable('select',SystemConfig::getType());
+        $grid->column('comment', __('说明'))->editable();
+        $grid->column('sort', __('排序'))->editable()->sortable();
+        $grid->column('updated_at', __('更新时间'))->sortable();
+
+        $grid->filter(function (Grid\Filter $filter){
+            $filter->disableIdFilter();
+            $filter->column(1/2, function ($filter) {
+                $filter->like('group','分组');
+                $filter->like('key','键');
+
+            });
+            $filter->column(1/2, function ($filter) {
+                $filter->like('value','值');
+
+            });
+
+
+
+        });
+
+        return $grid;
+    }
+
+    /**
+     * Make a show builder.
+     *
+     * @param mixed   $id
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        $show = new Show(SystemConfig::findOrFail($id));
+
+        $show->field('id', __('ID'));
+        $show->field('group', __('分组'));
+        $show->field('key', __('key'));
+        $show->field('value', __('value'));
+        $show->field('fieldType', __('类型'))->using(SystemConfig::getType());
+        $show->field('chinese', __('标签名称'));
+        $show->field('comment', __('说明'));
+        $show->field('created_at', __('Created at'));
+        $show->field('updated_at', __('Updated at'));
+
+        return $show;
+    }
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        $form = new Form(new SystemConfig);
+        $form->display('id', __('ID'));
+        $form->text('group', __('group/分组'));
+        $form->text('key', __('key/键'));
+        $form->text('chinese', __('Label/标签名词'))->help('中文标签名词,方便用户查看');
+        $form->number('sort', __('Sort/排序'))->help('排序,越大越前')->default(0);
+        $form->select('fieldType', __('Type/字段类型'))->options(SystemConfig::getType());
+        $form->text('comment', __('comment/配置描述'));
+        $form->textarea('value', __('value/内容'));
+        $form->display('created_at', __('Created At'));
+        $form->display('updated_at', __('Updated At'));
+
+        return $form;
+    }
+}

+ 304 - 0
app/Admin/Controllers/Config/FormController.php

xqd
@@ -0,0 +1,304 @@
+<?php
+
+namespace App\Admin\Controllers\Config;
+
+use App\Model\BaseArea;
+use App\Model\Communities;
+use App\Model\SystemConfig;
+use App\Http\Controllers\Controller;
+use Encore\Admin\Form\Tab;
+use Encore\Admin\Grid;
+use Encore\Admin\Layout\Content;
+use Encore\Admin\Widgets\Form;
+use Encore\Admin\Widgets\Table;
+
+/**
+ * @author pxwei
+ * Class ConfigController
+ * @package App\Admin\Controllers\Form
+ */
+class FormController extends Controller
+{
+    public function form()
+    {
+        $dbs = SystemConfig::orderby('sort','desc')->orderby('created_at','asc')->get(['id','group','key','value','comment','chinese','fieldType'])->toArray();
+
+        $configs = [];
+
+        foreach ($dbs as $db){
+            $configs[$db['group']][] = $db;
+        }
+        $tab = new \Encore\Admin\Widgets\Tab();
+
+
+        foreach ($configs as $k => $config){
+            $form = new Form();
+            $form->action("/admin/setting_form_save");
+
+            foreach ($config as $value){
+                switch ($value['fieldType']){
+                    case SystemConfig::Field_textarea:
+                        $form->textarea($value['group'].'____'.$value['key'],$value['chinese'])->help($value['comment'])->rows(1)->default($value['value']);
+                        break;
+                    case  SystemConfig::Filed_richText:
+                        $form->editor($value['group'].'____'.$value['key'],$value['chinese'])->default($value['value']);
+                        break;
+                    case  SystemConfig::Field_Time:
+                        $form->time($value['group'].'____'.$value['key'],$value['chinese'])->default($value['value']);
+                        break;
+                    case  SystemConfig::Field_File:
+                        $form->file($value['group'].'____'.$value['key'],$value['chinese'])->help('当前文件:'.$value['value']);
+                        break;
+                    case  SystemConfig::Field_Switch:
+
+
+                            $states = [
+                                'on'  => ['value' => 1, 'text' => '开', 'color' => 'success'],
+                                'off' => ['value' => 0, 'text' => '关', 'color' => 'danger'],
+
+                            ];
+                            $s = $value['value'];
+
+                        if ($value['key']=='use_personal')
+                        {
+                            $s = $s==0?1:0;
+                        }
+
+
+                        $form->switch($value['group'].'____'.$value['key'].'____Switch',$value['chinese'])->help($value['comment'])->default($s)->states($states);
+                        break;
+                    case  SystemConfig::Field_Checkbox:
+                        $data = [];
+                        $default = [];
+                        foreach (json_decode($value['value'],true) as $v){
+                            $data[$v['key']] =$v['text'];
+                            if ($v['value'] == 1)
+                                $default[] = $v['key'];
+
+                        }
+
+                        $form->checkbox($value['group'].'____'.$value['key'].'____checkbox',$value['chinese'])->options($data)->default($default)->help($value['comment'])->canCheckAll();
+                        break;
+                    case SystemConfig::Field_Json:
+                        $json = json_decode($value['value'],true);
+                        if (!$json)
+                            $form->display('json',$value['chinese'])->default('字段JSON解析失败');
+                        else{
+                            $form->fieldset($value['chinese'].'_配置组', function (Form $form)use ($json,$value) {
+                                foreach ($json as $kk=> $v){
+                                    $form->text($value['group'].'____'.$value['key'].'____J____'.$kk,$kk)->default($v);
+                                }
+                            });
+                        }
+                        break;
+
+                    case SystemConfig::Field_Json_Array:
+                        $json = json_decode($value['value'],true);
+                        if (!$json)
+                            $form->display('json',$value['chinese'])->default('数组JSON解析失败');
+                        else{
+                            $form->fieldset($value['chinese'].'_配置组', function (Form $form)use ($json,$value) {
+                                foreach ($json as $kk=> $v){
+                                    $form->text($value['group'].'____'.$value['key'].'____JA____'.$kk,$v['text'])->default($v['value']);
+                                }
+                            });
+                        }
+
+                }
+            }
+
+            $tab->add(SystemConfig::$groups[$k]??$k,$form->render());
+            $form = null;
+
+
+
+        }
+        $c =  new Content();
+        return $c->title("配置")->description('设置')->row($tab->render());
+    }
+
+    public function setting_form_save()
+    {
+        $inputs = request()->input();
+        unset($inputs['_token']);
+        $data = [];
+        $json = [];
+        $jsonArr = [];
+        foreach ($inputs as $k => $v){
+            $groups = explode('____',$k);
+            $num = count($groups);
+            if ($num< 1)
+                continue;
+            else if ($num === 2){
+                //普通字段配置
+                SystemConfig::where(['group'=>$groups[0],'key'=>$groups[1]])->update(['value'=>$v]);
+            }else if ($num === 3){
+                if ($groups[2] == "Switch"){
+                    if ($v=="on")
+                        $v = 1;
+                    else
+                        $v = 0;
+
+                    if ($groups[1] =='use_personal')
+                    {
+                        $v = $v==0?1:0;
+                    }
+
+                    SystemConfig::where(['group'=>$groups[0],'key'=>$groups[1]])->update(['value'=>$v]);
+                }else if ($groups[2] == "checkbox"){
+                    $origin_data = SystemConfig::get($groups[0],$groups[1]);
+                    $origin_data = json_decode($origin_data,true);
+                    foreach ($origin_data as $kk => $datum){
+                        $origin_data[$kk]['value'] =0;
+                        foreach ($v as $vv){
+                            if ($datum['key'] == $vv)
+                                $origin_data[$kk]['value'] =1;
+                        }
+                    }
+
+                    SystemConfig::where(['group'=>$groups[0],'key'=>$groups[1]])->update(['value'=>json_encode($origin_data)]);
+                }
+
+            }else if ($num == 4){
+                if ($groups[2]=="JA"){
+                    $jsonArr[$groups[0]][$groups[1]][$groups[3]] = $v;
+                }else{
+                    //JSON字段配置
+                    $json[$groups[0]][$groups[1]][$groups[3]] = $v;
+                }
+
+            }
+        }
+
+        if (count($json)>0){
+            foreach ($json as $k =>$value){
+                foreach ($value as $kk => $item){
+                    SystemConfig::where(['group'=>$k,'key'=>$kk])->update(['value'=>json_encode($item)]);
+                }
+            }
+        }
+
+        if (count($jsonArr)>0){
+            foreach ($jsonArr as $k =>$value){
+                foreach ($value as $kk => $item){
+                    $res = SystemConfig::where(['group'=>$k,'key'=>$kk])->first();
+                    if (!$res)
+                        continue;
+                    $json = json_decode($res['value'],true);
+
+                    foreach ($item as $kkk => $item2){
+                        $json[$kkk]['value'] = $item2;
+                        $res->update(['value'=>json_encode($json)]);
+
+
+
+                }
+            }
+        }
+        }
+
+        $files = request()->file();
+
+        foreach ($files as $key => $file){
+            $groups = explode('____',$key);
+            $file_name ='upload/SystemFiles/'.uniqid().'.'.$file->getClientOriginalExtension();
+            file_put_contents(public_path($file_name),file_get_contents($file->getRealPath()));
+            SystemConfig::where(['group'=>$groups[0],'key'=>$groups[1]])->update(['value'=>$file_name]);
+
+        }
+
+
+        admin_info('保存成功');
+        return back();
+    }
+
+
+    public function setCommunity()
+    {
+        $id = request('pid')?:'1';
+        $grid = new Grid(new BaseArea());
+
+        $grid->model()->where('pid',$id);
+
+
+        $c =  new Content();
+        return $c->title("配置")->description('设置')->body($grid->render());
+    }
+
+
+    public function setAreaById()
+    {
+        $id = request('id');
+        $type = request('t');
+        $m = request('m');
+
+        if ($m == "0")
+        {
+            $rs = Communities::where('id',$id)->update(['is_door'=>$type]);
+            if ($rs)
+            {
+                admin_toastr('设置成功','info');
+                return back();
+            }
+            admin_toastr('设置失败','error');
+            return back();
+        }
+
+        $rs = BaseArea::where('relation','like',"%{$id}%")->orwhere('id',$id)->update(['is_door'=>intval($type)]);
+
+
+
+        $rs = BaseArea::where(['grade'=>5])->where('relation','like',"%{$id}%")->get(['id']);
+        $ds = [];
+        foreach ($rs as $r){
+            $ds[] = $r['id'];
+        }
+
+        $rs = Communities::whereIn('area_id',$ds)->update(['is_door'=>intval($type)]);
+
+
+            admin_toastr('设置成功','info');
+            return back();
+
+
+    }
+
+
+    public function setPrice()
+    {
+        $id = request('pid');
+        $key = request('key');
+        $p = request('price');
+        $m = request('m');
+        $text = request('text');
+
+        if ($m == "1")
+        {
+            $rs = Communities::where('id',$id)->update([$key=>($p/10)]);
+            if ($rs)
+            {
+                return response()->json(['status'=>'ok']);
+            }
+            return response()->json(['status'=>'error']);
+        }
+
+
+        $rs = BaseArea::where('merger_name','like',"%{$text}%")->update([$key=>$p/10]);
+       if(!$rs) return response()->json(['status'=>'error']);
+        $rs = BaseArea::where('merger_name','like',"%{$text}%")->get(['id']);
+        $ds = [];
+
+        foreach ($rs as $r){
+            $ds[] = $r['id'];
+        }
+
+        $rs = Communities::whereIn('area_id',$ds)->update([$key=>$p/10]);
+
+        if ($rs)
+        {
+            return response()->json(['status'=>'ok']);
+        }
+        return response()->json(['status'=>'error']);
+    }
+
+}

+ 96 - 0
app/Admin/Controllers/DeviceBoxController.php

xqd
@@ -0,0 +1,96 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Admin\Actions\Box\CloseDoor;
+use App\Admin\Actions\Box\getRule;
+use App\Admin\Actions\Box\sendRule;
+use App\Model\DeviceBox;
+use App\Model\DeviceInfo;
+use Encore\Admin\Controllers\AdminController;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+use Encore\Admin\Show;
+
+class DeviceBoxController extends AdminController
+{
+    /**
+     * Title for current resource.
+     *
+     * @var string
+     */
+    protected $title = '设备箱柜';
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        $grid = new Grid(new DeviceBox());
+
+        $device_id = request('device_id');
+        if(!empty($device_id)){
+            $grid->model()->where('device_id',$device_id);
+        }
+        $grid->column('id', __('箱柜编号'));
+        $grid->column('devices.device_name', __('设备名称'));
+        $grid->column('name', __('箱柜名称'));
+        $grid->column('volume', __('容量'));
+        $grid->column('status', __('状态'))->using(['禁用','启用'])->label(['danger','success']);
+        $grid->column('remark', __('备注'));
+        $grid->column('created_at', __('创建时间'));
+        $grid->column('updated_at', __('更新时间'));
+
+        $grid->actions(function ($actions){
+            $actions->add(new sendRule());
+            $actions->add(new getRule());
+            $actions->add(new CloseDoor());
+        });
+
+//        $grid->filter(function ($fliter){
+//            $fliter->equal('device_id','设备')->select([DeviceInfo::get('device_id','device_name')->toArray()]);
+//        });
+
+        return $grid;
+    }
+
+    /**
+     * Make a show builder.
+     *
+     * @param mixed $id
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        $show = new Show(DeviceBox::findOrFail($id));
+
+        $show->field('id', __('Id'));
+        $show->field('name', __('Name'));
+        $show->field('volume', __('Volume'));
+        $show->field('status', __('Status'));
+        $show->field('remark', __('Remark'));
+        $show->field('created_at', __('Created at'));
+        $show->field('updated_at', __('Updated at'));
+
+        return $show;
+    }
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        $form = new Form(new DeviceBox());
+
+        $form->display('name', __('名称'));
+        $form->text('volume', __('容积'));
+        $form->select('status', __('状态'))->options(DeviceBox::getStatus());
+        $form->textarea('remark', __('备注'));
+
+        return $form;
+    }
+}

+ 176 - 0
app/Admin/Controllers/DeviceController.php

xqd
@@ -0,0 +1,176 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Admin\Actions\Device\Box;
+use App\Admin\Actions\Device\getRule;
+use App\Admin\Actions\Device\Lock;
+use App\Admin\Actions\Device\Reflash;
+use App\Admin\Actions\Device\sendRule;
+use App\Admin\Actions\Device\testRule;
+use App\Admin\Actions\Users\InRecords;
+use App\Admin\Actions\Users\PutRecords;
+use App\Admin\Actions\Users\WithDraw;
+use App\Admin\Controllers\Sta;
+use App\Model\DeviceInfo;
+use App\Model\DeviceType;
+use App\Model\UserInfo;
+use Encore\Admin\Facades\Admin;
+use Encore\Admin\Controllers\AdminController;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+use Encore\Admin\Show;
+use Encore\Admin\Widgets\Echarts\Echarts;
+use function foo\func;
+use Zhusaidong\GridExporter\Exporter;
+
+/**
+ * @author pxwei
+ * Class DeviceController
+ * @package App\Admin\Controllers\Device
+ */
+class DeviceController extends AdminController
+{
+    /**
+     * Title for current resource.
+     *
+     * @var string
+     */
+    protected $title = '设备管理';
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+
+        $grid = new Grid(new DeviceInfo());
+        $status = DeviceInfo::getStatus();
+        $breakDown = DeviceInfo::getBrakdown();
+        $grid->disableCreateButton(false);
+
+//        $exporter = Exporter::get($grid);
+//        $exporter->setFileName('设备导出.xlsx');
+        $grid->tools(function (Grid\Tools $tools) {
+            $tools->append(new Reflash());
+        });
+        $grid->model()->orderBy('status','asc');
+        $grid->header(function (){
+            return "<script src='/js/loadMiniApp.js?24'></script><style>.dropdown-menu{}</style>";
+        });
+        $grid->column('id', __('ID'))->sortable();
+        $grid->column('device_name', __('设备名称'))->editable();
+        $grid->column('device_type', __('类型'))->display(function ($w){
+            if(empty($w)) return '无';
+            return DeviceType::where(['id'=>$w])->value('name');
+        });
+
+        $grid->column('query', __('刷新时间'));
+
+        $grid->column('status', __('设备状态'))->using($status)->sortable();;
+        $grid->column('runningStatus', __('运行状态'))->display(function ($s){
+            $arr = [['name'=>'正常','color'=>'success'],['name'=>'故障','color'=>'danger'],['name'=>'故障','color'=>'danger'],['name'=>'故障','color'=>'danger'],['name'=>'故障','color'=>'danger'],['name'=>'正常','color'=>'success']];
+            return "<span class='label label-{$arr[$s]['color']}'>{$arr[$s]['name']}</span>";
+        });
+
+
+
+
+        $grid->column('updated_at', __('更新时间'))->sortable();
+
+        $grid->actions(function ($actions){
+            $actions->disableDelete(false);
+            $actions->add(new Box());
+            $actions->add(new Lock());
+            $actions->add(new sendRule());
+            $actions->add(new getRule());
+            $actions->add(new testRule());
+        });
+        $grid->filter(function (Grid\Filter $filter){
+            $filter->column(1/2, function ($filter) {
+                $filter->like('device_name','设备名称');
+                $filter->like('device_type','设备类型')->select(function (){
+                    return DeviceType::pluck('name','id');
+                });
+                $filter->equal('status','状态')->select(DeviceInfo::getStatus());
+            });
+        });
+
+        return $grid;
+    }
+
+    /**
+     * Make a show builder.
+     *
+     * @param mixed   $id
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        $show = new Show(DeviceInfo::findOrFail($id));
+        $isLock = DeviceInfo::getLock();
+        $status = DeviceInfo::getStatus();
+        $breakDown = DeviceInfo::getBrakdown();
+
+        $show->field('id', __('ID'));
+        $show->field('device_name', __('阿里云设备编号'));
+        $show->field('device_comment', __('微信中名称'));
+        $show->field('device_type', __('型号'));
+        $show->field('iot_id', __('iot_id'));
+        $show->field('product_key', __('product_key'));
+        $show->field('device_secret', __('设备密匙'));
+        $show->field('imei', __('imei'));
+        $show->field('status', __('运行状态'))->using($status);
+        $show->field('runningStatus', __('设备状态'))->using($breakDown);
+        $show->field('lock_switch', __('是否锁定'))->using($isLock);
+
+        $show->field('device_position', __('详细位置'));
+        $show->field('device_weight', __('累计重量/kg'))->as(function ($w){
+            return round($w/1000,3);
+        });
+        $show->field('device_qrcode', __('二维码'))->image();
+        $show->field('device_tem', __('温度'));
+        $show->field('device_light_start', __('灯牌开始点亮时间'));
+        $show->field('device_light_end', __('灯牌结束点亮时间'));
+        $show->field('serial_number', __('海康卫视序列号'));
+        $show->field('device_memo', __('设备备注'));
+        $show->field('created_at', __('创建时间'));
+        $show->field('updated_at', __('更新时间'));
+
+        return $show;
+    }
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        $form = new Form(new DeviceInfo());
+        if(Admin::user()->isAdministrator()){
+            $form->text('id', __('ID'));
+        } else {
+            $form->display('id', __('ID'));
+        }
+        $form->select('device_type', __('设备类型'))->options(DeviceType::getType())->rules('required');
+        $form->display('device_name', __('(阿里云)设备编号'))->rules('required');
+        $form->display('iot_id', __('(阿里云)iot_id'))->rules('required');
+        $form->display('product_key', __('(阿里云)product_key'))->help('阿里产品密匙')->rules('required');
+        $form->display('device_secret', __('(阿里云)设备密匙'))->rules('required');
+        $form->display('imei', __('(阿里云)设备唯一码'))->rules('required');
+        $form->hidden('device_tem', __('设备温度'))->default(28)->rules('required');
+        $form->text('query', '刷新时间')->help('单位秒')->rules('required');
+//        $form->select('status', __('状态'))->options(['在营','离线','禁用','未激活']);
+        //$form->hidden('runningStatus', __('运行状态'))->options(['满溢','修复','清空','未知']);
+//        $form->latlong('device_latitude', 'device_longitude', '经纬度')->default(['lat' => 90, 'lng' => 90]);
+        $form->textarea('remark', '设备备注');
+
+        $form->display('created_at', __('创建时间'));
+        $form->display('updated_at', __('更新时间'));
+
+        return $form;
+    }
+}

+ 92 - 0
app/Admin/Controllers/DeviceTypeBoxController.php

xqd
@@ -0,0 +1,92 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Model\DeviceType;
+use App\Model\DeviceTypeBox;
+use Encore\Admin\Controllers\AdminController;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+use Encore\Admin\Show;
+
+class DeviceTypeBoxController extends AdminController
+{
+    /**
+     * Title for current resource.
+     *
+     * @var string
+     */
+    protected $title = '设备类型箱体';
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        $grid = new Grid(new DeviceTypeBox());
+
+        $grid->disableCreateButton(false);
+        $grid->column('id', __('编号'));
+        $grid->column('type', __('类型'))->display(function ($w){
+            return DeviceType::where(['id'=>$w])->value('name');
+        });
+        $grid->column('name', __('名称'));
+        $grid->column('volume', __('容积'));
+        $grid->column('status', __('状态'))->using([0=>'禁用',1=>'启用'])->label(['danger','success']);
+        $grid->column('remark', __('备注'));
+        $grid->column('created_at', __('创建时间'));
+        $grid->column('updated_at', __('更新时时间'));
+        $grid->actions(function($actions){
+            $actions->disableDelete(false);
+        });
+
+        return $grid;
+    }
+
+    /**
+     * Make a show builder.
+     *
+     * @param mixed $id
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        $show = new Show(DeviceTypeBox::findOrFail($id));
+        $show->field('id', __('Id'));
+        $show->field('type', __('类型'))->as(function ($w){
+            return DeviceType::where(['id'=>$w])->value('name');
+        });
+        $show->field('name', __('名称'));
+        $show->field('volume', __('容积'));
+        $show->field('status', __('状态'))->using([0=>'禁用',1=>'启用']);
+        $show->field('remark', __('备注'));
+        $show->field('created_at', __('创建时间'));
+        $show->field('updated_at', __('更新时间'));
+
+        return $show;
+    }
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        $form = new Form(new DeviceTypeBox());
+
+        $form->select('type', __('类型'))->options(DeviceType::getType())->rules('required',['请选择类型']);
+        $form->text('name', __('名称'))->rules('required',['required'=>'请输入箱子名称']);
+        $form->text('volume', __('容积'))->help('单位L')->rules('required',['required'=>'请输入容积']);
+        $states = [
+            'off'=>['text'=>'禁用','value'=>0,'color'=>'danger'],
+            'on'=>['text'=>'启用','value'=>1,'color'=>'success'],
+        ];
+        $form->switch('status', __('状态'))->states($states)->default(1);
+        $form->textarea('remark', __('备注'));
+
+        return $form;
+    }
+}

+ 81 - 0
app/Admin/Controllers/DeviceTypeController.php

xqd
@@ -0,0 +1,81 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Model\DeviceType;
+use Encore\Admin\Controllers\AdminController;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+use Encore\Admin\Show;
+
+class DeviceTypeController extends AdminController
+{
+    /**
+     * Title for current resource.
+     *
+     * @var string
+     */
+    protected $title = '设备类型';
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        $grid = new Grid(new DeviceType());
+        $grid->disableCreateButton(false);
+
+        $grid->column('id', __('编号'));
+        $grid->column('name', __('名称'));
+        $grid->column('number', __('箱体数量'));
+        $grid->column('image', __('图片'))->display(function ($w){
+            return '<img src="/upload/'.$w.'" style="width:50px;height:50px"/>';
+        });
+        $grid->column('created_at', __('创建时间'));
+        $grid->column('updated_at', __('更新时间'));
+        $grid->actions(function ($actions){
+           $actions->disableView(false);
+        });
+
+        return $grid;
+    }
+
+    /**
+     * Make a show builder.
+     *
+     * @param mixed $id
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        $show = new Show(DeviceType::findOrFail($id));
+        $show->field('id', __('编号'));
+        $show->field('name', __('名称'));
+        $show->field('number', __('箱体个数'));
+        $show->field('remark', __('备注'));
+        $show->field('image', __('图片'))->image();
+        $show->field('created_at', __('创建时间'));
+        $show->field('updated_at', __('更新时间'));
+
+        return $show;
+    }
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        $form = new Form(new DeviceType());
+
+        $form->text('name', __('名称'));
+        $form->text('number', __('箱体个数'));
+        $form->textarea('remark', __('备注'));
+        $form->image('image', __('图片'));
+
+        return $form;
+    }
+}

+ 67 - 0
app/Admin/Controllers/ExampleController.php

xqd
@@ -0,0 +1,67 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use Encore\Admin\Controllers\AdminController;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+use Encore\Admin\Show;
+
+class ExampleController extends AdminController
+{
+    /**
+     * Title for current resource.
+     *
+     * @var string
+     */
+    protected $title = 'Example controller';
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        $grid = new Grid(new ExampleModel);
+
+        $grid->column('id', __('ID'))->sortable();
+        $grid->column('created_at', __('Created at'));
+        $grid->column('updated_at', __('Updated at'));
+
+        return $grid;
+    }
+
+    /**
+     * Make a show builder.
+     *
+     * @param mixed   $id
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        $show = new Show(ExampleModel::findOrFail($id));
+
+        $show->field('id', __('ID'));
+        $show->field('created_at', __('Created at'));
+        $show->field('updated_at', __('Updated at'));
+
+        return $show;
+    }
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        $form = new Form(new ExampleModel);
+
+        $form->display('id', __('ID'));
+        $form->display('created_at', __('Created At'));
+        $form->display('updated_at', __('Updated At'));
+
+        return $form;
+    }
+}

+ 34 - 0
app/Admin/Controllers/HomeController.php

xqd
@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Http\Controllers\Controller;
+use Encore\Admin\Controllers\Dashboard;
+use Encore\Admin\Layout\Column;
+use Encore\Admin\Layout\Content;
+use Encore\Admin\Layout\Row;
+
+class HomeController extends Controller
+{
+    public function index(Content $content)
+    {
+        return $content
+//            ->title('Dashboard')
+//            ->description('Description...')
+//            ->row(Dashboard::title())
+            ->row(function (Row $row) {
+
+//                $row->column(4, function (Column $column) {
+//                    $column->append(Dashboard::environment());
+//                });
+//
+//                $row->column(4, function (Column $column) {
+//                    $column->append(Dashboard::extensions());
+//                });
+//
+//                $row->column(4, function (Column $column) {
+//                    $column->append(Dashboard::dependencies());
+//                });
+            });
+    }
+}

+ 171 - 0
app/Admin/Controllers/LockController.php

xqd
@@ -0,0 +1,171 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Model\DeviceBox;
+use App\Model\DeviceInfo;
+use App\Model\LockInfo;
+use App\Server\DeviceServer;
+use Encore\Admin\Controllers\AdminController;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+use Encore\Admin\Show;
+
+class LockController extends AdminController
+{
+    /**
+     * Title for current resource.
+     *
+     * @var string
+     */
+    protected $title = '远程所锁';
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+
+        $grid = new Grid(new LockInfo());
+        $rule = '{
+            "box1": [
+                {"open":"16:10", "close":"16:11", "type":1, "start":"2020-09-01 10:00:00","value":" " },
+                {"open":"16:12", "close":"16:13", "type":2, "start":"2020-09-01 10:00:00","value":" " },
+                {"open":"16:14", "close":"16:15", "type":3, "start":"2020-09-01 10:00:00","value":["5", "7"] },
+                {"open":"16:16", "close":"16:17", "type":4, "start":"2020-09-01 10:00:00","value":["25","26"]},
+                {"open":"16:18", "close":"16:19", "type":5, "start":"2020-09-01 10:00:00","value":["09-25","09-26"]}
+                ],
+
+            "box2": [
+                {"open":"16:10", "close":"16:11", "type":1, "start":"2020-09-01 10:00:00","value":" " },
+                {"open":"16:12", "close":"16:13", "type":2, "start":"2020-09-01 10:00:00","value":" " },
+                {"open":"16:14", "close":"16:15", "type":3, "start":"2020-09-01 10:00:00","value":["5", "7"] },
+                {"open":"16:16", "close":"16:17", "type":4, "start":"2020-09-01 10:00:00","value":["25","26"]},
+                {"open":"16:18", "close":"16:19", "type":5, "start":"2020-09-01 10:00:00","value":["09-25","09-26"]}
+                ],
+            "query":6
+        }';
+//        $rule = '{"cmd":"stop_test"}';
+//        $rule = '{"get":"box4"}';
+//        $res = (new DeviceServer())->doorOperation('rozl8eri3NwjyMrG6gYT000000 ', 0);
+//        $res = (new DeviceServer())->sendMsg(868626044260472 ,$rule);
+//        $res = (new DeviceServer())->sendMsg(868626044260522  ,$rule);
+//        $res = (new DeviceServer())->getProperty('rozl8eri3NwjyMrG6gYT000000 ');
+//        $res = (new DeviceServer())->getDeviceStatus('rozl8eri3NwjyMrG6gYT000000 ');//设备状态
+//        $res = (new DeviceServer())->switchDevice('rozl8eri3NwjyMrG6gYT000000 ',1);//启用禁用
+//        dd($res);
+        $grid->disableCreateButton(false);
+        $device_id = request('device_id');
+        $box_id = request('box_id');
+        if(!empty($device_id)){
+            $box = DeviceBox::where(['device_id'=>$device_id])->pluck('id');
+            $grid->model()->whereIn('box_id',$box);
+        }
+        if(!empty($box_id)){
+            $grid->model()->where('box_id',$box_id);
+        }
+        $grid->column('boxs.device_id','设备')->display(function ($w){
+           return DeviceInfo::where(['id'=>$w])->value('device_name');
+        });
+        $grid->column('boxs.name', __('锁位名称'));
+        $grid->column('open_time', __('开门时间'));
+        $grid->column('close_time', __('关门时间'));
+        $grid->column('start_time', __('启动时间'));
+        $grid->column('type', __('类型'))->using(LockInfo::get_type());
+        $grid->column('value','时间')->display(function ($is){
+            if($this->type !== 3){
+               return LockInfo::get_type()[$this->type];
+            } else {
+               $str = '';
+               foreach ($is as $i){
+                   $str .=LockInfo::week_day()[$i].',';
+               }
+               return $str;
+            }
+        });
+        $states= [
+            'off'=>['text'=>'禁用','value'=>0,'color'=>'danger'],
+            'on'=>['text'=>'启用','value'=>1,'color'=>'success']
+        ];
+        $grid->column('status', __('状态'))->switch($states);
+        $grid->filter(function ($fliter){
+            $fliter->where(function($query){
+                $query->whereHas('boxs',function($query){
+                   $query->where('name','like',"%{$this->input}%");
+                });
+            },'盒子名称');
+            $fliter->equal('status','状态')->select(['禁用','启用']);
+        });
+        return $grid;
+    }
+
+    /**
+     * Make a show builder.
+     *
+     * @param mixed $id
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        $show = new Show(LockInfo::findOrFail($id));
+        $show->field('id', __('Id'));
+        $show->field('device_id', __('Device id'));
+        $show->field('lock_key', __('Lock key'));
+        $show->field('lock_name', __('Lock name'));
+        $show->field('open_time', __('Open time'));
+        $show->field('close_time', __('Close time'));
+        $show->field('start_time', __('Start time'));
+        $show->field('rules', __('Rules'));
+        $show->field('status', __('Status'));
+        $show->field('created_at', __('Created at'));
+        $show->field('updated_at', __('Updated at'));
+
+        return $show;
+    }
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        $form = new Form(new LockInfo());
+
+
+        if($form->isEditing()){
+            $form->display('boxs.devices.device_name', __('设备'));
+            $form->select('box_id', __('锁位'))->options(function (){
+                return  DeviceBox::where('device_id','=',$this->boxs->device_id)->pluck('name','id')->toArray();
+            });
+        } else {
+            $form->select('device_id', __('设备'))->options(function (){
+                return DeviceInfo::pluck('device_name','id')->toArray();
+            })->load('box_id','/admin/get_box')->rules('required',['required'=>'设备必须选择']);
+            $form->select('box_id', __('锁位'))->options(function (){
+                return  DeviceBox::where('device_id','=',$this->device_id)->pluck('name','id')->toArray();
+            })->rules('required',['required'=>'请选择盒子']);
+        }
+        $form->datetime('open_time', __('开门时间'))->format("HH:mm")->rules('required',['required'=>'开门时间必须']);
+        $form->datetime('close_time', __('关闭时间'))->format("HH:mm")->rules('required',['required'=>'关门时间必须']);
+        $form->datetime('start_time', __('开启时间'))->rules('required',['required'=>'开启时间必须']);
+        $form->select('type', __('类型'))->options([
+            '1'=>'不重复',
+            '2'=>'每天',
+            '3'=>'每周',
+        ])->when(3,function (Form $form){
+            $form->multipleSelect('value','日期')->options(LockInfo::week_day());
+        })->rules('required',['required'=>'请选择类型']);
+
+        $states= [
+            'off'=>['text'=>'禁用','value'=>0,'color'=>'danger'],
+            'on'=>['text'=>'启用','value'=>1,'color'=>'success']
+        ];
+        $form->ignore(['device_id','boxs.id']);
+        $form->switch('status', __('状态'))->states($states)->default(1);
+
+        return $form;
+    }
+}

+ 26 - 0
app/Admin/Extensions/Week.php

xqd
@@ -0,0 +1,26 @@
+<?php
+
+
+namespace App\Admin\Extensions;
+
+
+use Encore\Admin\Form\Field;
+
+class Week extends Field
+{
+    protected $view = 'admin.week';
+
+    protected static $css = [
+//        'css/datetimepicker.min.css'
+    ];
+
+    protected static $js = [
+        'js/datetimepicker.min.js'
+    ];
+
+
+    public function render()
+    {
+        return parent::render();
+    }
+}

+ 56 - 0
app/Admin/bootstrap.php

xqd
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * Laravel-admin - admin builder based on Laravel.
+ * @author z-song <https://github.com/z-song>
+ *
+ * Bootstraper for Admin.
+ *
+ * Here you can remove builtin form field:
+ * Encore\Admin\Form::forget(['map', 'editor']);
+ *
+ * Or extend custom form field:
+ * Encore\Admin\Form::extend('php', PHPEditor::class);
+ *
+ * Or require js and css assets:
+ * Admin::css('/packages/prettydocs/css/styles.css');
+ * Admin::js('/packages/prettydocs/js/main.js');
+ *
+ */
+use App\Admin\Extensions\Week;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+Encore\Admin\Form::forget(['map', 'editor']);
+Form::extend('week', \App\Admin\Extensions\Week::class);
+Grid::init(function (Grid $grid) {
+
+//    $grid->disableActions();
+//    $grid->disablePagination();
+//    $grid->disableFilter();
+//    $grid->disableRowSelector();
+//    $grid->disableColumnSelector();
+//    $grid->disableTools();
+    $grid->disableExport();
+
+    $grid->disableCreateButton();
+    $grid->actions(function (Grid\Displayers\Actions $actions) {
+        $actions->disableView();
+//        $actions->disableEdit(s);
+        $actions->disableDelete();
+    });
+});
+
+Form::init(function (Form $form) {
+
+    $form->disableEditingCheck();
+
+    $form->disableCreatingCheck();
+
+    $form->disableViewCheck();
+
+    $form->tools(function (Form\Tools $tools) {
+        $tools->disableDelete();
+        $tools->disableView();
+//        $tools->disableList();
+    });
+});

+ 27 - 0
app/Admin/routes.php

xqd
@@ -0,0 +1,27 @@
+<?php
+
+use Illuminate\Routing\Router;
+
+Admin::routes();
+
+Route::group([
+    'prefix'        => config('admin.route.prefix'),
+    'namespace'     => config('admin.route.namespace'),
+    'middleware'    => config('admin.route.middleware'),
+    'as'            => config('admin.route.prefix') . '.',
+], function (Router $router) {
+
+    $router->get('/', 'HomeController@index')->name('home');
+    $router->resource('device_info', DeviceController::class);
+    $router->resource('lock_info', LockController::class);
+    $router->resource('device_type', DeviceTypeController::class);
+    $router->resource('device_box', DeviceBoxController::class);
+    $router->resource('device_type_box', DeviceTypeBoxController::class);
+    $router->get('get_box', 'ApiController@get_box');
+
+    $router->get('/setting_form', 'Config\FormController@form');
+    $router->post('/setting_form_save', 'Config\FormController@setting_form_save');
+    $router->resource('/setting', 'Config\ConfigController');
+
+
+});

+ 217 - 0
app/Console/Commands/Crawle.php

xqd
@@ -0,0 +1,217 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Model\BuildInfo;
+use App\Model\Last;
+use App\Model\Links;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+use QL\QueryList;
+
+class Crawle extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'crawle:{type}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    const DOMAIN = 'https://cd.lianjia.com';
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $type = $this->argument('type');
+        $count = explode('-',$type);
+        if(is_array($count) && count($count) == 3){
+            $start = $count[1];
+            $end = $count[2];
+        }
+
+        if($type == 'list'){
+            self::getList();
+        } else if($type == 'detail'){
+            self::getDetail($start,$end);
+        } else if($type == 'findlose'){
+            self::getloseinfo();
+        }
+    }
+
+    public static function getList()
+    {
+        $last = Last::where(['type'=>1])->first();
+        $communites = Links::where(['type'=>1]);
+        if(!empty($last) && $last->last_id !== 0 ){
+            $communites->where('id','>=',$last->last_id);
+        }
+        $communites = $communites->get(['links']);
+        foreach ($communites as  $communite){
+            if(empty($last)){
+                Last::insert(['type'=>2,'last_id'=>$communite->id]);
+            } else {
+                Last::where(['type'=>2])->update(['last_id'=>$communite->id]);
+            }
+            for($i=1;$i<100;$i++){
+                $areas = QueryList::get(self::DOMAIN.$communite->links.'pg'.$i,null,[
+                    'headers' => [
+                        'Referer'=>'http://www.baidu.com',
+                        'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
+                        'Accept-Encoding' => 'gzip, deflate, br',
+                    ]
+                ])->find('.xiaoquListItem .title a')->attrs('href');
+                if(empty($areas->toArray())){
+                    Log::info('失效页数'.self::DOMAIN.$communite->links.'pg'.$i);
+                    break;
+                }
+                foreach ($areas as $area){
+                    $is_have = Links::where(['links'=>$area])->value('id');
+                    if($is_have) continue;
+                    Links::insert(['links'=>$area,'type'=>2]);
+                }
+                sleep(rand(2,6));
+            }
+        }
+//        self::getDetail();
+        dd('end');
+    }
+
+    public static function getDetail($start=0,$end=0)
+    {
+        $rules = [
+            // 楼盘名称
+            'build_name' => ['.detailTitle','text'],
+            //市区
+            'district' => ['.l-txt a:eq(2)','text'],
+            //社区
+            'community' => ['.l-txt a:eq(3)','text'],
+            //简单地址
+            'sample_address' => ['.detailDesc','text'],
+            //小区价格
+            'price'=>['.xiaoquUnitPrice','text'],
+            //小区图片
+            'images' => ['.imgThumbnailList img','src'],
+            //建成年份
+            'completed' => ['.xiaoquInfo .xiaoquInfoItem:eq(0) span:eq(1)','text'],
+            //建筑结构
+            'structure_type' => ['.xiaoquInfo .xiaoquInfoItem:eq(1) span:eq(1)','text'],
+            //物业公司
+            'tenement' => ['.xiaoquInfo .xiaoquInfoItem:eq(3) span:eq(1)','text'],
+            //栋数
+            'bulid_num' => ['.xiaoquInfo .xiaoquInfoItem:eq(5) span:eq(1)','text'],
+            //户数
+            'households' => ['.xiaoquInfo .xiaoquInfoItem:eq(6) span:eq(1)','text'],
+        ];
+
+        if($start > $end){
+            dd('最后的数必须大于前面的数字');
+        }
+        if($end==5000){
+            $type = 2;
+        } else if($end == 10000) {
+            $type = 3;
+        } else if($end == 15200){
+            $type = 4;
+        } else {
+            dd('位置类型');
+        }
+        $last = Last::where(['type'=>$type])->first();
+//        dd($last->toArray());
+        if(!empty($last) && $last->last_id !== 0 ){
+            $start = $last->last_id ;
+        }
+        $link_info = Links::whereBetween('id',[$start,$end]);
+
+        $link_info->where(['type'=>2])->chunk(100,function ($links) use ($rules,$last,$type){
+            dd($links->toArray());
+            try{
+                foreach ($links as  $link){
+                    echo '爬取详情链接'.$link->links.PHP_EOL;
+                    $html = QueryList::get($link->links,null,[
+                        'headers' => [
+                            'Referer'=>'http://www.baidu.com',
+                            'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
+                            'Accept-Encoding' => 'gzip, deflate, br',
+                        ]
+                    ]);
+                    $build = $html->rules($rules)->query()->getData();
+                    $images = $html->find('.imgThumbnailList img')->attrs('src');
+                    sleep(rand(3,10));
+                    if(!empty($images)) $build['images'] = json_encode($images);
+                    if(empty($build->toArray())) continue;
+                    (!empty($build['bulid_num'])) ? $build['bulid_num'] = intval($build['bulid_num']) : $build['bulid_num'] = 0;
+                    (!empty($build['completed'])) ? $build['completed'] = intval($build['completed']) : $build['completed'] = 0;
+                    (!empty($build['price'])) ? $build['price'] = intval($build['price']) : $build['price'] = 0;
+                    if(empty($build['households'])) continue;
+                    if(!empty($build['households'])) $build['households'] = intval($build['households']);
+                    $is_have = BuildInfo::where(['build_name'=>$build['build_name']])->value('id');
+                    if($is_have){continue;}
+                    if(empty($last)){
+                        Last::insert(['type'=>$type,'last_id'=>$link->id]);
+                    } else {
+                        Last::where(['type'=>$type])->update(['last_id'=>$link->id]);
+                    }
+                    $build['link_id'] = $link->id;
+                    BuildInfo::insert($build->toArray());
+                }
+            } catch(Exception $e) {
+                Log::info('爬取详情链接'.$link->links.PHP_EOL.'报错');
+                dd($e->getMessage());
+            }
+        });
+        dd('end');
+    }
+
+    public function getloseinfo(){
+        $rules = [
+            //小区价格
+            'price'=>['.xiaoquUnitPrice','text'],
+        ];
+
+        BuildInfo::where('price','=',null)->chunk(100,function ($builds) use ($rules){
+            try{
+                foreach ($builds as  $build){
+                    sleep(rand(3,10));
+                    $linkInfo = Links::where(['id'=>$build->link_id])->first();
+                    echo '爬取详情链接'.$linkInfo->links.PHP_EOL;
+                    $html = QueryList::get($linkInfo->links,null,[
+                        'headers' => [
+                            'Referer'=>'http://www.baidu.com',
+                            'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
+                            'Accept-Encoding' => 'gzip, deflate, br',
+                        ]
+                    ]);
+                    $price = $html->find('.xiaoquUnitPrice')->text();
+                    if(empty($price)){
+                         echo '没有价格'.$build->id;
+                         continue;
+                    }
+                    BuildInfo::where(['id'=>$build->id])->update(['price'=>$price]);
+                }
+            } catch(Exception $e) {
+                dd('爬取详情链接'.$linkInfo->links.PHP_EOL.'报错'.$e->getMessage());
+            }
+        });
+    }
+}

+ 42 - 0
app/Console/Kernel.php

xqd
@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Console;
+
+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 = [
+        \App\Console\Commands\Crawle::class,
+    ];
+
+    /**
+     * Define the application's command schedule.
+     *
+     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
+     * @return void
+     */
+    protected function schedule(Schedule $schedule)
+    {
+        // $schedule->command('inspire')
+        //          ->hourly();
+    }
+
+    /**
+     * Register the commands for the application.
+     *
+     * @return void
+     */
+    protected function commands()
+    {
+        $this->load(__DIR__.'/Commands');
+
+        require base_path('routes/console.php');
+    }
+}

+ 37 - 0
app/Events/DeviceEvent.php

xqd
@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Events;
+
+use App\Model\DeviceInfo;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class DeviceEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct(DeviceInfo $device)
+    {
+        $this->device = $device;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 37 - 0
app/Events/LockEvent.php

xqd
@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Events;
+
+use App\Model\LockInfo;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class LockEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct(LockInfo $lock)
+    {
+        $this->lock = $lock;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 55 - 0
app/Exceptions/Handler.php

xqd
@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Exceptions;
+
+use Exception;
+use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
+
+class Handler extends ExceptionHandler
+{
+    /**
+     * A list of the exception types that are not reported.
+     *
+     * @var array
+     */
+    protected $dontReport = [
+        //
+    ];
+
+    /**
+     * A list of the inputs that are never flashed for validation exceptions.
+     *
+     * @var array
+     */
+    protected $dontFlash = [
+        'password',
+        'password_confirmation',
+    ];
+
+    /**
+     * Report or log an exception.
+     *
+     * @param  \Exception  $exception
+     * @return void
+     *
+     * @throws \Exception
+     */
+    public function report(Exception $exception)
+    {
+        parent::report($exception);
+    }
+
+    /**
+     * Render an exception into an HTTP response.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Exception  $exception
+     * @return \Symfony\Component\HttpFoundation\Response
+     *
+     * @throws \Exception
+     */
+    public function render($request, Exception $exception)
+    {
+        return parent::render($request, $exception);
+    }
+}

+ 40 - 0
app/Http/Controllers/Auth/ConfirmPasswordController.php

xqd
@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Http\Controllers\Auth;
+
+use App\Http\Controllers\Controller;
+use App\Providers\RouteServiceProvider;
+use Illuminate\Foundation\Auth\ConfirmsPasswords;
+
+class ConfirmPasswordController extends Controller
+{
+    /*
+    |--------------------------------------------------------------------------
+    | Confirm Password Controller
+    |--------------------------------------------------------------------------
+    |
+    | This controller is responsible for handling password confirmations and
+    | uses a simple trait to include the behavior. You're free to explore
+    | this trait and override any functions that require customization.
+    |
+    */
+
+    use ConfirmsPasswords;
+
+    /**
+     * Where to redirect users when the intended url fails.
+     *
+     * @var string
+     */
+    protected $redirectTo = RouteServiceProvider::HOME;
+
+    /**
+     * Create a new controller instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        $this->middleware('auth');
+    }
+}

+ 22 - 0
app/Http/Controllers/Auth/ForgotPasswordController.php

xqd
@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Http\Controllers\Auth;
+
+use App\Http\Controllers\Controller;
+use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
+
+class ForgotPasswordController extends Controller
+{
+    /*
+    |--------------------------------------------------------------------------
+    | Password Reset Controller
+    |--------------------------------------------------------------------------
+    |
+    | This controller is responsible for handling password reset emails and
+    | includes a trait which assists in sending these notifications from
+    | your application to your users. Feel free to explore this trait.
+    |
+    */
+
+    use SendsPasswordResetEmails;
+}

+ 40 - 0
app/Http/Controllers/Auth/LoginController.php

xqd
@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Http\Controllers\Auth;
+
+use App\Http\Controllers\Controller;
+use App\Providers\RouteServiceProvider;
+use Illuminate\Foundation\Auth\AuthenticatesUsers;
+
+class LoginController extends Controller
+{
+    /*
+    |--------------------------------------------------------------------------
+    | Login Controller
+    |--------------------------------------------------------------------------
+    |
+    | This controller handles authenticating users for the application and
+    | redirecting them to your home screen. The controller uses a trait
+    | to conveniently provide its functionality to your applications.
+    |
+    */
+
+    use AuthenticatesUsers;
+
+    /**
+     * Where to redirect users after login.
+     *
+     * @var string
+     */
+    protected $redirectTo = RouteServiceProvider::HOME;
+
+    /**
+     * Create a new controller instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        $this->middleware('guest')->except('logout');
+    }
+}

+ 73 - 0
app/Http/Controllers/Auth/RegisterController.php

xqd
@@ -0,0 +1,73 @@
+<?php
+
+namespace App\Http\Controllers\Auth;
+
+use App\Http\Controllers\Controller;
+use App\Providers\RouteServiceProvider;
+use App\User;
+use Illuminate\Foundation\Auth\RegistersUsers;
+use Illuminate\Support\Facades\Hash;
+use Illuminate\Support\Facades\Validator;
+
+class RegisterController extends Controller
+{
+    /*
+    |--------------------------------------------------------------------------
+    | Register Controller
+    |--------------------------------------------------------------------------
+    |
+    | This controller handles the registration of new users as well as their
+    | validation and creation. By default this controller uses a trait to
+    | provide this functionality without requiring any additional code.
+    |
+    */
+
+    use RegistersUsers;
+
+    /**
+     * Where to redirect users after registration.
+     *
+     * @var string
+     */
+    protected $redirectTo = RouteServiceProvider::HOME;
+
+    /**
+     * Create a new controller instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        $this->middleware('guest');
+    }
+
+    /**
+     * Get a validator for an incoming registration request.
+     *
+     * @param  array  $data
+     * @return \Illuminate\Contracts\Validation\Validator
+     */
+    protected function validator(array $data)
+    {
+        return Validator::make($data, [
+            'name' => ['required', 'string', 'max:255'],
+            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
+            'password' => ['required', 'string', 'min:8', 'confirmed'],
+        ]);
+    }
+
+    /**
+     * Create a new user instance after a valid registration.
+     *
+     * @param  array  $data
+     * @return \App\User
+     */
+    protected function create(array $data)
+    {
+        return User::create([
+            'name' => $data['name'],
+            'email' => $data['email'],
+            'password' => Hash::make($data['password']),
+        ]);
+    }
+}

+ 30 - 0
app/Http/Controllers/Auth/ResetPasswordController.php

xqd
@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Http\Controllers\Auth;
+
+use App\Http\Controllers\Controller;
+use App\Providers\RouteServiceProvider;
+use Illuminate\Foundation\Auth\ResetsPasswords;
+
+class ResetPasswordController extends Controller
+{
+    /*
+    |--------------------------------------------------------------------------
+    | Password Reset Controller
+    |--------------------------------------------------------------------------
+    |
+    | This controller is responsible for handling password reset requests
+    | and uses a simple trait to include this behavior. You're free to
+    | explore this trait and override any methods you wish to tweak.
+    |
+    */
+
+    use ResetsPasswords;
+
+    /**
+     * Where to redirect users after resetting their password.
+     *
+     * @var string
+     */
+    protected $redirectTo = RouteServiceProvider::HOME;
+}

+ 42 - 0
app/Http/Controllers/Auth/VerificationController.php

xqd
@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Http\Controllers\Auth;
+
+use App\Http\Controllers\Controller;
+use App\Providers\RouteServiceProvider;
+use Illuminate\Foundation\Auth\VerifiesEmails;
+
+class VerificationController extends Controller
+{
+    /*
+    |--------------------------------------------------------------------------
+    | Email Verification Controller
+    |--------------------------------------------------------------------------
+    |
+    | This controller is responsible for handling email verification for any
+    | user that recently registered with the application. Emails may also
+    | be re-sent if the user didn't receive the original email message.
+    |
+    */
+
+    use VerifiesEmails;
+
+    /**
+     * Where to redirect users after verification.
+     *
+     * @var string
+     */
+    protected $redirectTo = RouteServiceProvider::HOME;
+
+    /**
+     * Create a new controller instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        $this->middleware('auth');
+        $this->middleware('signed')->only('verify');
+        $this->middleware('throttle:6,1')->only('verify', 'resend');
+    }
+}

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

xqd
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
+use Illuminate\Foundation\Bus\DispatchesJobs;
+use Illuminate\Foundation\Validation\ValidatesRequests;
+use Illuminate\Routing\Controller as BaseController;
+
+class Controller extends BaseController
+{
+    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
+}

+ 45 - 0
app/Http/Controllers/IndexController.php

xqd
@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Model\Communite;
+use Illuminate\Http\Request;
+use QL\QueryList;
+
+class IndexController extends Controller
+{
+    public function index()
+    {
+//$domain = 'https://cd.lianjia.com/xiaoqu';
+        set_time_limit(1800);
+        for($i=1;$i<100;$i++){
+            $areas = QueryList::get('https://cd.lianjia.com/xiaoqu'.$i,null,[
+                'headers' => [
+                    'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
+                    'Accept-Encoding' => 'gzip, deflate, br',
+                ]
+            ])->find('.position a')->attrs('href');
+            dd($areas);
+            foreach ($areas as $area){
+                Communite::insert(['links'=>$area]);
+            }
+        }
+dd($area);
+        $link = QueryList::get('https://cd.lianjia.com/xiaoqu/1611043165264', null, [
+            'headers' => [
+                'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
+                'Accept-Encoding' => 'gzip, deflate, br',
+            ]
+        ])->getHtml();
+        if($link)
+        dd($link->getHtml());
+        $info = QueryList::get('https://cd.lianjia.com/xiaoqu/1611043165264', null, [
+            'headers' => [
+                'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
+                'Accept-Encoding' => 'gzip, deflate, br',
+            ]
+        ])->find('.xiaoquDescribe')->htmls();
+
+        dd($info);
+    }
+}

+ 82 - 0
app/Http/Kernel.php

xqd
@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Http;
+
+use Illuminate\Foundation\Http\Kernel as HttpKernel;
+
+class Kernel extends HttpKernel
+{
+    /**
+     * The application's global HTTP middleware stack.
+     *
+     * These middleware are run during every request to your application.
+     *
+     * @var array
+     */
+    protected $middleware = [
+        \App\Http\Middleware\TrustProxies::class,
+        \App\Http\Middleware\CheckForMaintenanceMode::class,
+        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
+        \App\Http\Middleware\TrimStrings::class,
+        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
+    ];
+
+    /**
+     * The application's route middleware groups.
+     *
+     * @var array
+     */
+    protected $middlewareGroups = [
+        'web' => [
+            \App\Http\Middleware\EncryptCookies::class,
+            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
+            \Illuminate\Session\Middleware\StartSession::class,
+            // \Illuminate\Session\Middleware\AuthenticateSession::class,
+            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
+            \App\Http\Middleware\VerifyCsrfToken::class,
+            \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        ],
+
+        'api' => [
+            'throttle:60,1',
+            \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        ],
+    ];
+
+    /**
+     * The application's route middleware.
+     *
+     * These middleware may be assigned to groups or used individually.
+     *
+     * @var array
+     */
+    protected $routeMiddleware = [
+        'auth' => \App\Http\Middleware\Authenticate::class,
+        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
+        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
+        'can' => \Illuminate\Auth\Middleware\Authorize::class,
+        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
+        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
+        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
+        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
+        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
+    ];
+
+    /**
+     * The priority-sorted list of middleware.
+     *
+     * This forces non-global middleware to always be in the given order.
+     *
+     * @var array
+     */
+    protected $middlewarePriority = [
+        \Illuminate\Session\Middleware\StartSession::class,
+        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
+        \App\Http\Middleware\Authenticate::class,
+        \Illuminate\Routing\Middleware\ThrottleRequests::class,
+        \Illuminate\Session\Middleware\AuthenticateSession::class,
+        \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        \Illuminate\Auth\Middleware\Authorize::class,
+    ];
+}

+ 21 - 0
app/Http/Middleware/Authenticate.php

xqd
@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Auth\Middleware\Authenticate as Middleware;
+
+class Authenticate extends Middleware
+{
+    /**
+     * Get the path the user should be redirected to when they are not authenticated.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return string|null
+     */
+    protected function redirectTo($request)
+    {
+        if (! $request->expectsJson()) {
+            return route('login');
+        }
+    }
+}

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

xqd
@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
+
+class CheckForMaintenanceMode extends Middleware
+{
+    /**
+     * The URIs that should be reachable while maintenance mode is enabled.
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

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

xqd
@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
+
+class EncryptCookies extends Middleware
+{
+    /**
+     * The names of the cookies that should not be encrypted.
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

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

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

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

xqd
@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
+
+class TrimStrings extends Middleware
+{
+    /**
+     * The names of the attributes that should not be trimmed.
+     *
+     * @var array
+     */
+    protected $except = [
+        'password',
+        'password_confirmation',
+    ];
+}

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

xqd
@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Fideloper\Proxy\TrustProxies as Middleware;
+use Illuminate\Http\Request;
+
+class TrustProxies extends Middleware
+{
+    /**
+     * The trusted proxies for this application.
+     *
+     * @var array|string
+     */
+    protected $proxies;
+
+    /**
+     * The headers that should be used to detect proxies.
+     *
+     * @var int
+     */
+    protected $headers = Request::HEADER_X_FORWARDED_ALL;
+}

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

xqd
@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
+
+class VerifyCsrfToken extends Middleware
+{
+    /**
+     * Indicates whether the XSRF-TOKEN cookie should be set on the response.
+     *
+     * @var bool
+     */
+    protected $addHttpCookie = true;
+
+    /**
+     * The URIs that should be excluded from CSRF verification.
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

+ 34 - 0
app/Jobs/ProcessTestRule.php

xqd
@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Jobs;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+class ProcessTestRule implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    /**
+     * Create a new job instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        //
+    }
+}

+ 10 - 0
app/Links.php

xqd
@@ -0,0 +1,10 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Links extends Model
+{
+    //
+}

+ 86 - 0
app/Listeners/DeviceEventListener.php

xqd
@@ -0,0 +1,86 @@
+<?php
+
+namespace App\Listeners;
+
+use App\Model\DeviceBox;
+use App\Model\DeviceType;
+use App\Model\DeviceTypeBox;
+use App\Model\LockInfo;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+use App\Events\DeviceEvent;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+
+
+class DeviceEventListener
+{
+    /**
+     * Create the event listener.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Handle the event.
+     *
+     * @param  object  $event
+     * @return void
+     */
+    public function handle(DeviceEvent $event)
+    {
+        $device = $event->device;
+        if(!empty($device->device_type)){
+            $this->addBox($device);
+            Log::info('有数据'.$device->device_type);
+        } else {
+            Log::info('没数据'.$device->device_type);
+        }
+
+        return true;
+    }
+
+    public function  addBox($device){
+        $boxmodel = DeviceTypeBox::where(['type'=>intval($device->device_type)])->get(['volume','name','id']);
+        if(!empty($boxModel)){
+           Log::info('有盒子'.count($boxmodel).'个');
+       } else {
+           Log::info('没有盒子 设备类型'.intval($device->device_type));
+       }
+        $data['device_id'] = $device->id;
+        $data['created_at'] = Carbon::now();
+        $data['updated_at'] = Carbon::now();
+        DB::beginTransaction();
+        try {
+            $shou_name = array_column($boxmodel->toArray(),'name');
+            $box_names = DeviceBox::where(['device_id'=>$device->id])->whereNotIn('name',$shou_name)->pluck('name','id')->toArray();
+            //删除盒子与锁
+            if(!empty($box_names)){
+                foreach ($box_names as $id =>$name){
+                    DeviceBox::where(['name'=>$name,'device_id'=>$device->id])->delete();
+                    LockInfo::where(['box_id'=>$id])->delete();
+                    //更新锁命令
+                }
+            }
+
+            foreach ($boxmodel as $val){
+                $data['name'] = $val->name;
+                $data['volume'] = $val->volume;
+                if($old = DeviceBox::where(['name'=>$val->name,'device_id'=>$device->id])->first()){
+                    DeviceBox::where(['id'=>$old->id])->update($data);
+                    continue;
+                }
+                DeviceBox::insert($data);
+            }
+            DB::commit();
+        } catch (\Exception $e){
+            Log::info('错误信息'.$e->getMessage().PHP_EOL);
+            DB::rollBack();
+        }
+    }
+}

+ 59 - 0
app/Listeners/LockEventListener.php

xqd
@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Listeners;
+
+use App\Events\LockEvent;
+use App\Model\DeviceBox;
+use App\Model\LockInfo;
+use App\Server\DeviceServer;
+use Doctrine\DBAL\Driver\IBMDB2\DB2Driver;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Support\Facades\Log;
+
+class LockEventListener
+{
+
+
+    /**
+     * Handle the event.
+     *
+     * @param  object  $event
+     * @return void
+     */
+    public function handle(LockEvent $lock)
+    {
+
+        $lock = $lock->lock ;
+        $box_id = $lock->boxs->id;
+        $device_name = $lock->boxs->devices->device_name;
+
+
+        if(empty($box_id) || empty($device_name)){
+            return fasle;
+        }
+        echo $box_id.'设备名称'.$device_name;
+        $lock_info = LockInfo::where(['box_id'=>$box_id,'status'=>1])->get();
+
+        $rule = [];
+        foreach ($lock_info as $val){
+            $rule[$lock->boxs->name][] =  [
+                'open'=>$val->open_time,
+                'close'=>$val->close_time,
+                'start'=>$val->start_time,
+                'type'=>$val->type,
+                'value'=>$val->value,
+            ];
+        }
+        if(!empty($rule)){
+            $rule['query'] = 1200;
+            //发送命令
+//            (new DeviceServer())->sendMsg($device_name,json_encode($rule));
+
+            Log::info('设备'.$device_name.'盒子'.$lock->boxs->name.'更新规则'.PHP_EOL);
+        } else {
+            Log::info('设备'.$device_name.'盒子'.$lock->boxs->name.'无规则'.PHP_EOL);
+        }
+
+    }
+}

+ 11 - 0
app/Model/BuildInfo.php

xqd
@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+class BuildInfo extends Model
+{
+    protected $table = 'build_info';
+    public $timestamps = false;
+}

+ 11 - 0
app/Model/Communite.php

xqd
@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Communite extends Model
+{
+    protected $table = 'communites';
+    public $timestamps = false;
+}

+ 29 - 0
app/Model/DeviceBox.php

xqd
@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+class DeviceBox extends Model
+{
+    protected $table = 'device_box';
+
+    const DISABLE = 0;
+    const SUCCESS = 1;
+
+    public static $_status=[
+       self::DISABLE=>'禁用',
+       self::SUCCESS=>'启用'
+    ];
+
+    public static function getStatus()
+    {
+        return self::$_status;
+    }
+
+    public function devices()
+    {
+        return $this->hasOne(DeviceInfo::class,'id','device_id');
+    }
+
+}

+ 71 - 0
app/Model/DeviceInfo.php

xqd
@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Model;
+
+use App\Events\DeviceEvent;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Contracts\Events\Dispatcher;
+
+class DeviceInfo extends Model
+{
+    use SoftDeletes;
+    //public $dispatcher;
+
+    const ONLINE = 0, OFFLINE = 1, DISABLE = 2, UNACTIVE = 3;  //在营 离线 禁用 未激活  运行状态 (status)
+    const OK = 0, ERROR = 1; // 正常 故障 设备状态 (runningStatus)
+    const LOCK = 1, UNLOCK = 0;
+    protected $table = "device_info";
+    protected $guarded = [];
+//['在营','离线','禁用','未激活']
+    /*
+     *运行状态
+     */
+    private static $_status =[
+        self::ONLINE=>'在营',
+        self::OFFLINE=>'离线',
+        self::DISABLE=>'禁用',
+        self::UNACTIVE=>'未激活',
+    ];
+    protected static function getStatus(){
+        return self::$_status;
+    }
+    /*
+     *是否故障
+     */
+
+    private static $_brakdown =[
+        self::OK=>'正常',
+        self::ERROR=>'故障',
+    ];
+    protected static function getBrakdown(){
+        return self::$_status;
+    }
+
+    /*
+     *是否关锁
+     */
+    private static $_islock = [
+        self::UNLOCK=>'否',
+        self::LOCK=>'是',
+    ];
+    protected static function getLock(){
+        return self::$_islock;
+    }
+
+    protected $dispatchesEvents = [
+        'updated'=>DeviceEvent::class
+    ];
+
+    public static function getRestRatio($list){
+        $capacitySecurity = SystemConfig::get('system_config', 'capacitySecurity', '800');
+        $list['max_rest'] = $list['max_rest'] == 0 ? 1800 : $list['max_rest'];
+        if (($list['max_rest'] - $list['rest_capacity'] - $capacitySecurity) == 0) {
+            $value =  0;
+        } else {
+            $value = ($list['max_rest'] - $list['rest_capacity'] - $capacitySecurity) / ($list['max_rest'] - $capacitySecurity) * 100;
+        }
+        return $value;
+    }
+
+}

+ 15 - 0
app/Model/DeviceType.php

xqd
@@ -0,0 +1,15 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+class DeviceType extends Model
+{
+    protected $table = 'device_type';
+
+    public static function getType()
+    {
+        return self::pluck('name','id');
+    }
+}

+ 10 - 0
app/Model/DeviceTypeBox.php

xqd
@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+class DeviceTypeBox extends Model
+{
+    protected $table = 'device_type_box';
+}

+ 13 - 0
app/Model/Last.php

xqd
@@ -0,0 +1,13 @@
+<?php
+
+
+namespace App\Model;
+
+
+use Illuminate\Database\Eloquent\Model;
+
+class Last extends Model
+{
+    protected $table = 'last_info';
+    public $timestamps = false;
+}

+ 11 - 0
app/Model/Links.php

xqd
@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Links extends Model
+{
+    protected $table = 'links';
+    public $timestamps = false;
+}

+ 72 - 0
app/Model/LockInfo.php

xqd
@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+use App\Events\LockEvent;
+class LockInfo extends Model
+{
+    protected $table = 'device_lock_info';
+
+    //锁类型 1 不重复 2每天 3每周
+    const ONCE = 1;
+    const EVERYDAY = 2;
+    const EVERYWEEK = 3;
+
+    public static $_lock_type = [
+        self::ONCE=>'不重复',
+        self::EVERYDAY=>'每天',
+        self::EVERYWEEK=>'每周',
+    ];
+
+    public static function get_type()
+    {
+        return self::$_lock_type;
+    }
+
+    public static function week_day()
+    {
+        $array = [
+            1=>'星期一',
+            2=>'星期二',
+            3=>'星期三',
+            4=>'星期四',
+            5=>'星期五',
+            6=>'星期六',
+            7=>'星期天'
+        ];
+        return $array;
+    }
+
+    public static function month_day()
+    {
+         $array = [
+            '1'=>'1号', '2'=>'2号', '3'=>'3号', '4'=>'4号', '5'=>'5号', '6'=>'6号', '7'=>'7号', '8'=>'8号', '9'=>'9号', '10'=>'10号',
+            '11'=>'11号', '12'=>'12号', '13'=>'13号', '14'=>'14号', '15'=>'15号', '16'=>'16号', '17'=>'17号', '18'=>'18号', '19'=>'19号', '20'=>'20号',
+            '21'=>'21号', '22'=>'22号', '23'=>'23号', '24'=>'24号', '25'=>'25号', '26'=>'26号', '27'=>'27号', '28'=>'28号', '29'=>'29号', '30'=>'30号',
+            '31'=>'31号',
+         ];
+        return $array;
+    }
+
+
+    public function getValueAttribute($value)
+    {
+        return explode(',', $value);
+    }
+
+    public function setValueAttribute($value)
+    {
+        $this->attributes['value'] = implode(',', $value);
+    }
+
+//    protected $dispatchesEvents = [
+//        'updated'=>LockEvent::class
+//    ];
+
+    public function boxs()
+    {
+        return $this->hasOne(DeviceBox::class,'id','box_id')->with('devices');
+    }
+
+}

+ 76 - 0
app/Model/SystemConfig.php

xqd
@@ -0,0 +1,76 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * Class System_Config
+ * @package App
+ */
+
+class SystemConfig extends Model
+{
+    //
+    protected $table = "system_config";
+    protected $guarded = [];
+    static $groups = ['ali_config'=>'阿里云',
+        'wechat_config'=>'微信',
+        'system_config'=>'系统设置',
+        'put_config'=>'投放设置',
+        'fetch_config'=>'清运设置',
+        'cash_config'=>'提现设置',
+        'assistant_setting'=>'协管员提现设置',
+    ];
+    const Field_textarea = 0,Filed_richText = 1,Field_Json = 2,
+        Field_Switch = 3,Field_Time = 4,Field_File = 5,
+        Field_Checkbox = 6,Field_Json_Array = 7;
+
+    private static $_fieldType = [
+        self::Field_textarea =>'纯文本',
+        self::Filed_richText =>'富文本',
+        self::Field_Json =>'JSON',
+        self::Field_Switch =>'开关',
+        self::Field_Time =>'时间',
+        self::Field_File =>'文件',
+        self::Field_Checkbox =>'选择框',
+        self::Field_Json_Array =>'数组JSON',
+    ];
+
+    protected static function getType(){
+        return self::$_fieldType;
+    }
+
+    /**
+     * @param String $group
+     * @param String $key
+     * @param String $default
+     * @return array|String
+     */
+    public static function get(string $group, string $key = '', string $default = "")
+    {
+        $query = self::where('group', $group);
+        if ($key) {
+            $res = $query->where('key', $key)->first(['value'])->value ?? $default;
+            return $res;
+        } else {
+            $res =  $query->get(['key', 'value']);
+            $arr = [];
+            foreach ($res as $index => $item) {
+                $arr[$item['key']] = $item['value'];
+            }
+            return $arr;
+        }
+    }
+
+    /**
+     * @param String $group
+     * @param String $key
+     * @param String $value
+     * @return int
+     */
+    public static function set(string $group, string $key, string $value)
+    {
+        return self::where([['group', $group], ['key', $key]])->update(['value' => $value]);
+    }
+}

+ 28 - 0
app/Providers/AppServiceProvider.php

xqd
@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Support\ServiceProvider;
+use Illuminate\Support\Facades\Schema;
+class AppServiceProvider extends ServiceProvider
+{
+    /**
+     * Register any application services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        //
+    }
+
+    /**
+     * Bootstrap any application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        Schema::defaultStringLength(191);
+    }
+}

+ 30 - 0
app/Providers/AuthServiceProvider.php

xqd
@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
+use Illuminate\Support\Facades\Gate;
+
+class AuthServiceProvider extends ServiceProvider
+{
+    /**
+     * The policy mappings for the application.
+     *
+     * @var array
+     */
+    protected $policies = [
+        // 'App\Model' => 'App\Policies\ModelPolicy',
+    ];
+
+    /**
+     * Register any authentication / authorization services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        $this->registerPolicies();
+
+        //
+    }
+}

+ 21 - 0
app/Providers/BroadcastServiceProvider.php

xqd
@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Support\Facades\Broadcast;
+use Illuminate\Support\ServiceProvider;
+
+class BroadcastServiceProvider extends ServiceProvider
+{
+    /**
+     * Bootstrap any application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        Broadcast::routes();
+
+        require base_path('routes/channels.php');
+    }
+}

+ 40 - 0
app/Providers/EventServiceProvider.php

xqd
@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Auth\Events\Registered;
+use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
+use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
+use Illuminate\Support\Facades\Event;
+
+class EventServiceProvider extends ServiceProvider
+{
+    /**
+     * The event listener mappings for the application.
+     *
+     * @var array
+     */
+    protected $listen = [
+        Registered::class => [
+            SendEmailVerificationNotification::class,
+        ],
+        'App\Events\DeviceEvent'=>[
+            'App\Listeners\DeviceEventListener',
+        ],
+        'App\Events\LockEvent'=>[
+            'App\Listeners\LockEventListener',
+        ],
+    ];
+
+    /**
+     * Register any events for your application.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        parent::boot();
+
+        //
+    }
+}

+ 80 - 0
app/Providers/RouteServiceProvider.php

xqd
@@ -0,0 +1,80 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
+use Illuminate\Support\Facades\Route;
+
+class RouteServiceProvider extends ServiceProvider
+{
+    /**
+     * This namespace is applied to your controller routes.
+     *
+     * In addition, it is set as the URL generator's root namespace.
+     *
+     * @var string
+     */
+    protected $namespace = 'App\Http\Controllers';
+
+    /**
+     * The path to the "home" route for your application.
+     *
+     * @var string
+     */
+    public const HOME = '/home';
+
+    /**
+     * Define your route model bindings, pattern filters, etc.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        //
+
+        parent::boot();
+    }
+
+    /**
+     * Define the routes for the application.
+     *
+     * @return void
+     */
+    public function map()
+    {
+        $this->mapApiRoutes();
+
+        $this->mapWebRoutes();
+
+        //
+    }
+
+    /**
+     * Define the "web" routes for the application.
+     *
+     * These routes all receive session state, CSRF protection, etc.
+     *
+     * @return void
+     */
+    protected function mapWebRoutes()
+    {
+        Route::middleware('web')
+             ->namespace($this->namespace)
+             ->group(base_path('routes/web.php'));
+    }
+
+    /**
+     * Define the "api" routes for the application.
+     *
+     * These routes are typically stateless.
+     *
+     * @return void
+     */
+    protected function mapApiRoutes()
+    {
+        Route::prefix('api')
+             ->middleware('api')
+             ->namespace($this->namespace)
+             ->group(base_path('routes/api.php'));
+    }
+}

+ 237 - 0
app/Server/AliYunIotServer.php

xqd
@@ -0,0 +1,237 @@
+<?php
+
+namespace App\Server;
+
+use AlibabaCloud\Client\AlibabaCloud;
+use AlibabaCloud\Client\Exception\ClientException;
+use AlibabaCloud\Client\Exception\ServerException;
+use Illuminate\Support\Facades\Log;
+
+class AliYunIotServer
+{
+
+    protected $errMsg;
+    private $appKey;
+    private $appSecret;
+    private $regionId;
+
+    const DISABLE = 0;
+    const ENABLE = 1;
+
+    /**
+     * AliYunIotServer constructor.
+     * @param string $appKey
+     * @param string $appSecret
+     * @param string $regionId
+     */
+    public function __construct(string $appKey, string $appSecret, string $regionId = 'cn-hangzhou')
+    {
+        $this->appKey = $appKey;
+        $this->appSecret = $appSecret;
+        $this->regionId = $regionId;
+    }
+
+    /**
+     * 获取服务列表
+     * @param int $pageSize
+     * @param int $currentPage
+     * @return array|string
+     */
+    public function getProductList(int $pageSize = 5, int $currentPage = 1)
+    {
+        $params = [
+            'RegionId' => $this->regionId,
+            'PageSize' => "$pageSize",
+            'CurrentPage' => "$currentPage",
+        ];
+        return $this->AliCurl("post", "QueryProductList", $params);
+    }
+
+    /**
+     * 获取设备列表
+     * @param string $productKey
+     * @param int $pageSize
+     * @param int $currentPage
+     * @return array|string
+     */
+    public function getDeviceList(string $productKey, int $pageSize = 5, int $currentPage = 1)
+    {
+        $params = [
+            'RegionId' => $this->regionId,
+            'PageSize' => "$pageSize",
+            'ProductKey' => "$productKey",
+            'CurrentPage' => "$currentPage",
+        ];
+        return $this->AliCurl("post", "QueryDevice", $params);
+    }
+
+    /**
+     * 获取设备属性
+     * @param string $iotId
+     * @param string $iotInstanceId
+     * @return array|string
+     */
+    public function getDeviceProperty(string $iotId, string $iotInstanceId = '')
+    {
+        $params['IotId'] = $iotId;
+        $params['RegionId'] = $this->regionId;
+        /*foreach ($identifier as $key => $val) {
+            $params['Identifier.' . ($key + 1)] = $val;
+        }*/
+        if ($iotInstanceId) {
+            $params['IotInstanceId'] = $iotInstanceId;
+        }
+        return $this->AliCurl("post", "QueryDevicePropertyStatus", $params);
+    }
+
+    /**
+     * 获取设备状态
+     * @param string $iotId
+     * @param string $iotInstanceId
+     * @return array|string
+     */
+    public function getDeviceStatus(string $iotId, string $iotInstanceId = '')
+    {
+        $params['IotId'] = $iotId;
+        $params['RegionId'] = $this->regionId;
+        /*foreach ($identifier as $key => $val) {
+            $params['Identifier.' . ($key + 1)] = $val;
+        }*/
+        if ($iotInstanceId) {
+            $params['IotInstanceId'] = $iotInstanceId;
+        }
+        return $this->AliCurl("post", "GetDeviceStatus", $params);
+    }
+
+    /**
+     * 设置设备属性
+     * @param string $iotId
+     * @param array $property
+     * @param string $iotInstanceId
+     * @return array|string
+     */
+    public function setDeviceProperty(string $iotId, array $property, string $iotInstanceId = '')
+    {
+        /*if ($this->checkProperty($property)) {
+            return $this->errMsg;
+        }*/
+        $params['Items'] = json_encode($property);
+        //dd($params);
+        Log::info("手动上报设备属性" . $params['Items']);
+        $params['IotId'] = $iotId;
+        if ($iotInstanceId) {
+            $params['IotInstanceId'] = $iotInstanceId;
+        }
+        //dd($params);
+        return $this->AliCurl("post", "SetDeviceProperty", $params);
+    }
+
+    /**
+     * 调用设备服务
+     * @param string $iotId
+     * @param string $identifier
+     * @param object $args
+     * @param string $iotInstanceId
+     * @return array|string
+     */
+    public function invokeThingService(string $iotId, string $identifier, object $args, string $iotInstanceId = '')
+    {
+        $params['IotId'] = $iotId;
+        $params['Identifier'] = $identifier;
+        $params['Args'] = json_encode($args);
+        if ($iotInstanceId) {
+            $params['IotInstanceId'] = $iotInstanceId;
+        }
+        return $this->AliCurl("post", "InvokeThingService", $params);
+    }
+
+    /**
+     * 禁用&解禁设备
+     * @param int $status
+     * @param string $iotId
+     * @param string $iotInstanceId
+     * @return array|string
+     */
+    public function switchDevice(int $status, string $iotId, string $iotInstanceId = '')
+    {
+        $params['IotId'] = $iotId;
+        if ($iotInstanceId) {
+            $params['IotInstanceId'] = $iotInstanceId;
+        }
+        if ($status == self::DISABLE) {
+            return $this->AliCurl("post", "DisableThing", $params);
+        } else if ($status == self::ENABLE) {
+            return $this->AliCurl("post", "EnableThing", $params);
+        }
+    }
+
+    /**
+     *调用自定义topic
+     *
+     */
+
+    public function RRpc( array $params, string $iotInstanceId=''){
+        if ($iotInstanceId) {
+            $params['IotInstanceId'] = $iotInstanceId;
+        }
+        //  /a15yVIP0Onl/${deviceName}/user/update topic
+//        dd($params);
+        //要发送的消息内容经过Base64编码得到的字符串格式数据
+        return $this->AliCurl("post", "Pub", $params);
+    }
+
+    /**
+     * @param string $method
+     * @param string $action
+     * @param array $params
+     * @return array|string
+     */
+    private function AliCurl(string $method, string $action, array $params = [])
+    {
+        try {
+            AlibabaCloud::accessKeyClient($this->appKey, $this->appSecret)
+                ->regionId($this->regionId)
+                ->asDefaultClient();
+            $result = AlibabaCloud::rpc()
+                ->product('Iot')
+                // ->scheme('https') // https | http
+                ->version('2018-01-20')
+                ->action($action)
+                ->method(strtoupper($method))
+                ->host('iot.cn-shanghai.aliyuncs.com')
+                ->options([
+                    'query' => $params,
+                ])
+                ->request();
+            return $result->toarray();
+        } catch (ClientException $e) {
+            return $e->getErrorMessage() . PHP_EOL;
+        } catch (ServerException $e) {
+            return $e->getErrorMessage() . PHP_EOL;
+        }
+    }
+
+    /**
+     * @param array $params
+     * @return bool
+     */
+    protected function checkProperty(array $params)
+    {
+        $initialProperty = ['LockSwitch' => 'is_bool'];
+        foreach ($params as $key => $val) {
+            if (!isset($initialProperty[$key])) {
+                $this->errMsg = '该属性未定义';
+                return false;
+            }
+            if ($initialProperty[$key]($val)) {
+                $this->errMsg = '该属性数据类型异常';
+                return false;
+            }
+            if ($val == '' || $val == [] || $val == null) {
+                $this->errMsg = '属性不能为空';
+                return false;
+            }
+        }
+        return true;
+    }
+}

+ 638 - 0
app/Server/DeviceServer.php

xqd
@@ -0,0 +1,638 @@
+<?php
+
+
+namespace App\Server;
+
+use AlibabaCloud\Iot\V20180120\RRpc;
+use App\Model\DeliverInfo;
+use App\Model\DeviceInfo;
+use App\Model\SystemConfig;
+use App\Model\WaringMessage;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Cache;
+
+class DeviceServer
+{
+    private $conf;
+    private $property;
+    private $blueProperty;
+
+    const CLOSE = 0;
+    const OPEN = 1;
+    const AGENTOPEN = 2;
+    const AGENTCLOSE = 3;
+
+    public function __construct()
+    {
+        $this->property = [
+            'CurrentTemperature' => 'device_tem',
+            'IMEI' => 'imei',
+           // 'GeoLocation' => 'location',
+            'MagDoorSwitch' => 'lock_switch',
+            'RodSwitch' => 'deliver_lock_switch',
+            'RunningState' => 'runningStatus',
+            'Weight' => 'device_weight',
+            'RestCapacity' => 'rest_capacity',
+        ];
+        $this->blueProperty = [
+            'CurrentTemperature' => 'device_tem',
+            'IMEI' => 'imei',
+            //'GeoLocation' => 'location',
+            'MagDoorSwitch' => 'lock_switch',
+            'RodSwitch' => 'deliver_lock_switch',
+            'RunningState' => 'runningStatus',
+            'Weight' => 'device_weight',
+            'RestCapacity' => 'rest_capacity',
+        ];
+        $this->conf = SystemConfig::get('ali_config');
+    }
+
+    /**
+     * 刷新所有设备列表
+     * @return string|bool
+     */
+    public function refreshList()
+    {
+        $conf = $this->conf;
+        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+            return '请先配置阿里云app秘钥';
+        }
+        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+            return '请先配置阿里云appKey';
+        }
+        if (!isset($conf['productKey']) || empty($conf['productKey'])) {
+            return '请先配置阿里云产品识别码';
+        }
+
+        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+        $list = $ali->getDeviceList($conf['productKey'], 100);
+        $deviceList = $list['Data']['DeviceInfo'];
+        if ($list['Page'] < $list['PageCount']) {
+            for ($i = ($list['Page'] + 1); $i <= $list['PageCount']; $i++) {
+                $list = $ali->getDeviceList($conf['productKey'], 100, $i);
+                $deviceList = array_merge($deviceList, $list['Data']['DeviceInfo']);
+            }
+        }
+        foreach ($deviceList as $key => $val) {
+            $check = DeviceInfo::where([['device_name', $val['DeviceName']], ['product_key', $val['ProductKey']]])
+                ->orWhere('iot_id', $val['IotId'])->first(['id', 'status']);
+            $status = 0;
+            switch ($val['DeviceStatus']) {
+                case 'ONLINE':
+                    $status = DeviceInfo::ONLINE;
+                    break;
+                case 'OFFLINE':
+                    $status = DeviceInfo::OFFLINE;
+                    break;
+                case 'UNACTIVE':
+                    $status = DeviceInfo::UNACTIVE;
+                    break;
+                case 'DISABLE':
+                    $status = DeviceInfo::DISABLE;
+                    break;
+            }
+            if ($check) {
+                $check->status = $status;
+                $check->save();
+            } else {
+                $create = [
+                    'status' => $status,
+                    'iot_id' => $val['IotId'],
+                    'product_key' => $val['ProductKey'],
+                    'device_secret' => $val['DeviceSecret'],
+                    'device_name' => $val['DeviceName'],
+                ];
+                if ($status != 3) {
+                    DeviceInfo::insert($create);
+                }
+            }
+            $this->refreshDevice($val['IotId']);
+        }
+        return true;
+    }
+
+    /**
+     * 刷新设备属性
+     * @param String $iot_id
+     * @return bool|string|array
+     */
+    public function refreshDevice(string $iot_id)
+    {
+        $conf = $this->conf;
+        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+            return '请先配置阿里云app秘钥';
+        }
+        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+            return '请先配置阿里云appKey';
+        }
+        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+        $deviceProperty = $ali->getDeviceProperty($iot_id);
+        Log::info("设备数据刷新[1]:" . json_encode($deviceProperty));
+        if (isset($deviceProperty['Success']) && $deviceProperty['Success']) {
+            $data = [];
+            foreach ($deviceProperty['Data']['List']['PropertyStatusInfo'] as $index => $item) {
+                if (isset($this->property[$item['Identifier']])) {
+                    if (isset($item['Value'])) {
+                        $data[$this->property[$item['Identifier']]] = $item['Value'];
+                    } else {
+                        return ['data' => ['ErrorMessage' => "请检查设备属性[{$item['Identifier']}]是否初始化"], 'code' => 4];
+                    }
+                }
+            }
+
+            if (empty($data)) {
+                return ['data' => ['ErrorMessage' => '未获取到设备属性'], 'code' => 3];
+            }
+            //修复
+//            if ($data['deliver_lock_switch'] == 1) {
+//                return ['data' => ['ErrorMessage' => '当前设备已开启,请等待'], 'code' => '2'];
+//            }
+      /*      if (isset($data['location'])) {
+                $location = json_decode($data['location'], true);
+                $data['device_latitude'] = $location['latitude'];
+                $data['device_longitude'] = $location['longitude'];
+                unset($data['location']);
+            }*/
+            /*if ($data['rest_capacity'] == 0) {
+                $data['status'] = DeviceInfo::MAX;
+            } else {
+                $data['status'] = DeviceInfo::WELL;
+            }*/
+            $insert['device_item'] = $data['device_tem'];
+            $insert['imei'] = $data['imei'];
+            if ($data['device_tem'] >= 80) {
+                $id = DeviceInfo::where('iot_id', $iot_id)->first(['id'])->id;
+//                Log::info("设备温度【{$id}】:{$data['device_tem']}" );
+//                WaringMessage::temWaring($id);
+            }
+
+            $res = DeviceInfo::where('iot_id', $iot_id)->update($insert);
+            if (!$res) {
+                Log::info('设备数据刷新[2]:' . json_encode($data));
+            }
+            return ['data' => $data, 'code' => '0'];
+        } else {
+            return ['data' => $deviceProperty, 'code' => 1];
+        }
+    }
+
+    /**
+     * 获取设备属性
+     * @param String $iot_id
+     * @return bool|string|array
+     */
+    public function getProperty(string $iot_id)
+    {
+        $conf = $this->conf;
+        //Todo 全局 两个if合并
+        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+            return '请先配置阿里云app秘钥';
+        }
+        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+            return '请先配置阿里云appKey';
+        }
+        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+        $deviceProperty = $ali->getDeviceProperty($iot_id);
+        dd($deviceProperty);
+        if (isset($deviceProperty['Success']) && $deviceProperty['Success']) {
+            $data = [];
+            foreach ($deviceProperty['Data']['List']['PropertyStatusInfo'] as $index => $item) {
+                if (isset($this->property[$item['Identifier']])) {
+                    if (isset($item['Value'])) {
+                        $data[$this->property[$item['Identifier']]] = $item['Value'];
+                    } else {
+                        return ['data' => ['ErrorMessage' => "请检查设备属性[{$item['Identifier']}]是否初始化"], 'code' => 4];
+                    }
+                }
+            }
+            if (empty($data)) {
+                return ['data' => ['ErrorMessage' => '未获取到设备属性'], 'code' => 3];
+            }
+
+            /*if (isset($data['location'])) {
+                $location = json_decode($data['location'], true);
+                $data['device_latitude'] = $location['latitude'];
+                $data['device_longitude'] = $location['longitude'];
+                unset($data['location']);
+            }*/
+            /*if ($data['rest_capacity'] == 0) {
+                $data['status'] = DeviceInfo::MAX;
+            } else {
+                $data['status'] = DeviceInfo::WELL;
+            }*/
+            return ['data' => $data, 'code' => '0'];
+
+        } else {
+            return ['data' => $deviceProperty, 'code' => 1];
+        }
+    }
+    //蓝牙链接 传输加密数据
+    public function getDecodeProperty(string $base64_data, string $iot_id)
+    {
+        Log::info($base64_data);
+        $conf = $this->conf;
+        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+            return '请先配置阿里云app秘钥';
+        }
+        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+            return '请先配置阿里云appKey';
+        }
+        $dataDecode = ToolServer::decode($base64_data, '1234567890123456');
+        //$dataDecode = json_decode($base64_data, true);
+        Log::info("蓝牙设备数据刷新:" . json_encode($dataDecode));
+        $data = [];
+        if (!$dataDecode["P"]) {
+            return ['message' => '未获取到设备属性', 'code' => 3];
+        }
+        $updateIotData = [];
+        foreach ($dataDecode["P"] as $index => $item) {
+            if (isset($this->property[$item['I']])) {
+                if (isset($item['V'])) {
+                    $data[$this->property[$item['I']]] = $item['V'];
+                    $updateIotData[$item['I']] = $item['V'];
+                } else {
+                    return ['data' => ['ErrorMessage' => "请检查设备属性[{$item['Identifier']}]是否初始化"], 'code' => 4];
+                }
+            }
+        }
+        if (empty($data)) {
+            return ['message' => '未获取到设备属性', 'code' => 3];
+        }
+        $iotService = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+        $resUpload = $iotService->setDeviceProperty($iot_id, $updateIotData);
+        /*if (!$resUpload['Success']) {
+            return ['message' => '设备数据上报物联网失败', 'code' => 4];
+        }*/
+
+        if ($data['device_tem'] >= 80) {
+            $id = DeviceInfo::where('iot_id', $iot_id)->first(['id'])->id;
+            WaringMessage::temWaring($id);
+        }
+
+        $res = DeviceInfo::where('iot_id', $iot_id)->update($data);
+        if (!$res) {
+            Log::info('设备数据刷新[3]:' . json_encode($data));
+        }
+
+        return ['data' => $data, 'code' => '0'];
+    }
+
+    public function getBase64Property(string $base64_data)
+    {
+
+        $dataDecode = json_decode(base64_decode($base64_data), true);
+//        Log::debug($dataDecode);
+        if ( empty($dataDecode)|| !is_array($dataDecode) || !isset($dataDecode['identifier']) ) {
+            return true;
+        }
+        if ($dataDecode['identifier'] == 'errorEvent') {
+            $id = DeviceInfo::where('iot_id', $dataDecode['iotId'])->first(['id'])->id;
+            WaringMessage::normalWarning($id, $dataDecode['value']['errorEvent'], WaringMessage::ALARM);
+            return true;
+        }
+        if ($dataDecode['identifier'] == 'warnEvent') {
+            $device = DeviceInfo::where('iot_id', $dataDecode['iotId'])->first(['id', 'device_comment']);
+            $last = WaringMessage::where([['no', $device->id], ['message', $dataDecode['value']['warnEvent']], ['type', WaringMessage::WARN]])->first(['created_at']);
+            $mobile = SystemConfig::get('system_config', 'admin_mobile', 18981831779);
+            if ($mobile && (!$last || ($last && strtotime($last->created_at) + 1800 <= time()))) {
+                $type = SystemConfig::get('sms_config', 'sms_type', 'AliSmsServer');
+                $template = SystemConfig::get('ali_config', 'sms', '');
+                $template = json_decode($template, true);
+                if ($template['DeviceTmpId'] && $template['sign']) {
+                    $type = '\App\Server\Sms\\' . $type;
+                    $sms = new SmsServer(new $type($mobile, $template['DeviceTmpId'], $template['sign'], ['deviceId' => $device->id, 'deviceName' => $device->device_comment, 'warnInfo' => $dataDecode['value']['warnEvent']]));
+                    $sms->send();
+                }
+            }
+            WaringMessage::normalWarning($device->id, $dataDecode['value']['warnEvent'], WaringMessage::WARN);
+            return true;
+        }
+        if ($dataDecode['identifier'] == 'commoneEvent') {
+            //toDO 开/关门
+            $device = DeviceInfo::where('iot_id', $dataDecode['iotId'])->first(['id']);
+            if(!$device){
+                return true;
+            }
+            $order = DeliverInfo::where('device_id', $device->id)->orderBy('id', 'Desc')->first();
+            //优化关门统一走回调
+            if(!$order || $order->status != DeliverInfo::UNFINISHED){
+                return true;
+            }
+            Log::info('Cache:' . 'device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId']);
+            //处理设备发送重复消息
+            if (Cache::has('device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId'])) {
+                Log::info('关门回调通知重复消息:' .$dataDecode['requestId']);
+                return true;
+            }
+            if($dataDecode['value']['action']=='open') {
+                //开门回调通知
+                Log::info('开门回调通知:' . json_encode($dataDecode));
+                $order->open_weight = $dataDecode['value']['weight'];
+                $order->save();
+                Cache::put('device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId'], $dataDecode['requestId'], 3600);
+                return true;
+            }
+            if($dataDecode['value']['action']=='close'){
+                //关门回调通知
+                Log::info('关门回调通知:' . json_encode($dataDecode));
+                $close_weight = $dataDecode['value']['weight'];
+                $weight = $close_weight - $order->open_weight;
+                $order->close_weight = $close_weight;
+                $order->weight = $weight;
+                $order->finished_at = date('Y-m-d H:i:s');
+                Log::info('关门回调变化重量:'.$weight);
+                Log::info('关门回调关门重量:'.$close_weight);
+                Log::info('关门回调获得金额:'.$order->money);
+                Log::info('关门回调变化重量:'.($weight <= 0));
+                Cache::forget('deviceUse_' . $device->id);
+
+
+                $fetch_price= SystemConfig::get('system_config', 'fetch_per_g', '0.1');
+                $price = SystemConfig::get('system_config', 'put_per_g', '0.06');
+
+                //如果有小区加个就取小区价格
+                $deviceInfo = DeviceInfo::with('communities')->where(['id'=>$order['device_id']])->first();
+                if(!empty($deviceInfo->communities)) {
+                    if(!empty($deviceInfo->communities->put_per_g)) $price = $deviceInfo->communities->put_per_g;
+                    if(!empty($deviceInfo->communities->fetch_per_g)) $fetch_price = $deviceInfo->communities->fetch_per_g;
+                }
+
+                $order->deliver_price  = $price;
+                $order->transport_price  = $fetch_price;
+
+                if ($weight <= 0) {
+                    $order->status=DeliverInfo::LOSS;
+                    $order->income = 0;
+                    if($weight < -5000){
+                        $order->status=DeliverInfo::UNNORMAL;
+                        WaringMessage::deliverWarning($order->no);
+                    }
+                    $order->save();
+                    Log::info('关门回调失效订单:' . json_encode($order));
+                    Cache::put('device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId'], $dataDecode['requestId'], 3600);
+                    return true;
+                }
+                $start = date('Y') . '-' . date('m') . '-' . date('d') . ' 00:00:00';
+                $checkCount = DeliverInfo::where([['user_id', $order->user_id], ['status', DeliverInfo::SUCCESS]])
+                    ->where('created_at', '>', $start)->count();
+                $deliverLimit = SystemConfig::get('system_config', 'deliver_limit', 10);
+                $deliverWeight = SystemConfig::get('system_config', 'deliver_weight', 0);
+
+
+                //To Do 地区价格计算公式
+                Log::info('筛选时间:' . $start);
+                Log::info('投递次数:' . $checkCount);
+                Log::info('投递限制:' . $deliverLimit);
+                Log::info('地区价格:' . $price);
+                if (($deliverWeight != 0 && $weight > $deliverWeight) || $checkCount > $deliverLimit) {
+                    $order->status = DeliverInfo::WAIT_CHECK;
+                } else {
+                    $order->status = DeliverInfo::SUCCESS;
+                }
+                $order->money = $price*$weight;
+                $order->income = ($fetch_price - $price)*$weight;
+                if ($order->save()) {
+                    Cache::put('device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId'], $dataDecode['requestId'], 3600);
+                    return true;
+                } else {
+                    return false;
+                }
+
+            }
+        }
+        if (isset($dataDecode['items'])) {
+            $property = $dataDecode['items'];
+            $data = [];
+            if (!$property) {
+                return ['message' => '未获取到设备属性', 'code' => 3];
+            }
+            foreach ($property as $index => $item) {
+                if (isset($this->property[$index])) {
+                    if (isset($item['value'])) {
+                        $data[$this->property[$index]] = $item['value'];
+                    } else {
+                        return ['data' => ['ErrorMessage' => "请检查设备属性[{$item['Identifier']}]是否初始化"], 'code' => 4];
+                    }
+                }
+            }
+            if (empty($data)) {
+                return ['message' => '未获取到设备属性', 'code' => 3];
+            }
+            if ($data['device_tem'] >= 80) {
+                $id = DeviceInfo::where('iot_id', $dataDecode['iotId'])->first(['id'])->id;
+                WaringMessage::temWaring($id);
+            }
+
+            $res = DeviceInfo::where('iot_id', $dataDecode['iotId'])->update($data);
+            $this->getDeviceStatus($dataDecode['iotId']);
+            if (!$res) {
+                Log::info('设备数据刷新[4]:' . json_encode($data));
+            }
+            Log::info('success');
+            return ['data' => $data, 'code' => '0'];
+        }
+        return true;
+    }
+
+    public function getDeviceStatus($iotId)
+    {
+        $conf = $this->conf;
+        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+            return '请先配置阿里云app秘钥';
+        }
+        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+            return '请先配置阿里云appKey';
+        }
+        if (!isset($conf['productKey']) || empty($conf['productKey'])) {
+            return '请先配置阿里云产品识别码';
+        }
+
+        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+        $res = $ali->GetDeviceStatus($iotId);
+        if ($res['Success'] == true) {
+            $check = DeviceInfo::Where('iot_id', $iotId)->first(['status']);
+            $status = 0;
+            switch ($res['Data']['Status']) {
+                case 'ONLINE':
+                    $status = DeviceInfo::ONLINE;
+                    break;
+                case 'OFFLINE':
+                    $status = DeviceInfo::OFFLINE;
+                    break;
+                case 'UNACTIVE':
+                    $status = DeviceInfo::UNACTIVE;
+                    break;
+                case 'DISABLE':
+                    $status = DeviceInfo::DISABLE;
+                    break;
+            }
+            //////  dd($val);
+            $check->status = $status;
+            $check->save();
+            return $status;
+        } else {
+            return 'fail';
+        }
+    }
+
+    /**
+     * 启用和禁用
+     * @param String $iot_id
+     * @param int $state AliYunIotServer::ENABLE
+     * @return array|string
+     */
+    public function switchDevice(string $iot_id, int $state = AliYunIotServer::ENABLE)
+    {
+        $conf = $this->conf;
+        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+            return '请先配置阿里云app秘钥';
+        }
+        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+            return '请先配置阿里云appKey';
+        }
+        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+
+        $res = $ali->switchDevice($state, $iot_id);
+        if (isset($res['Success']) && $res['Success']) {
+            if ($state == AliYunIotServer::ENABLE) {
+                $state = 0;
+            } else {
+                $state = 2;
+            }
+            DeviceInfo::where('iot_id', $iot_id)->update(['status' => $state]);
+            return 'success';
+        } else {
+            return $res['ErrorMessage'];
+        }
+    }
+
+
+    /** 投递门/收运门 开关
+     * @param string $iot_id
+     * @param int $mode
+     * @return string
+     */
+    public function doorOperation(string $iot_id, int $mode = self::OPEN)
+    {
+        $conf = $this->conf;
+        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+            return '请先配置阿里云app秘钥';
+        }
+        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+            return '请先配置阿里云appKey';
+        }
+        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+        if ($mode == self::OPEN) {
+            $identifier = 'open1';
+        } else if ($mode == self::CLOSE) {
+            $identifier = 'close1';
+        } else if ($mode == self::AGENTOPEN) {
+            $identifier = 'RemoteAgentOpen';
+        } else if ($mode == self::AGENTCLOSE) {
+            $identifier = 'RemoteAgentClose';
+        }
+        $args = (object)[];
+        $res = $ali->invokeThingService($iot_id, $identifier, $args);
+        Log::info('doorOperation 参数:'. $iot_id .' '. $mode .'返回数据:'.json_encode($res));
+        if (isset($res['Success']) && $res['Success']) {
+            DeviceInfo::where('iot_id', $iot_id)->update(['deliver_lock_switch' => $mode]);
+            return 'success';
+        } else {
+            return $res['ErrorMessage'];
+        }
+    }
+
+    /** 下发锁协议
+     * @param string $device_name 设备名称
+     * @param string $rules 下发规则
+     **/
+
+    public  function sendMsg(string $device_name, string $rules)
+    {
+        $conf = $this->conf;
+        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+            return '请先配置阿里云app秘钥';
+        }
+        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+            return '请先配置阿里云appKey';
+        }
+
+        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+        $args['Action'] = "Pub";
+        $args['DeviceName'] =  $device_name;
+        $args['ProductKey'] = 'a15yVIP0Onl';
+        $args['MessageContent'] = base64_encode($rules);
+        $args['TopicFullName'] = "/a15yVIP0Onl/{$device_name}/user/get";
+//        $args['RequestBase64Byte'] = base64_encode($rules);
+//        $args['Timeout'] = 7000;
+//        $args['Topic'] = "/a15yVIP0Onl/{$device_name}/user/get";
+        $data = $ali->RRpc($args);
+        return $data;
+    }
+
+//    /** 投递门
+//     * @param string $iot_id
+//     * @param int $mode
+//     * @return string
+//     */RRpcRequestRRpcRequest
+//    public function doorInOperation(string $iot_id, int $mode = self::OPEN)
+//    {
+//        $conf = $this->conf;
+//
+//        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+//            return '请先配置阿里云app秘钥';
+//        }
+//
+//        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+//            return '请先配置阿里云appKey';
+//        }
+//        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+//        if ($mode == self::CLOSE) {
+//            $identifier = 'RemoteClose';
+//        } else {
+//            $identifier = 'RemoteOpen';
+//        }
+//        $args = (object)[];
+//        $res = $ali->invokeThingService($iot_id, $identifier, $args);
+//        Log::info(json_encode($res));
+//        if (isset($res['Success']) && $res['Success']) {
+//            DeviceInfo::where('iot_id', $iot_id)->update(['deliver_lock_switch' => $mode]);
+//            return 'success';
+//        } else {
+//            return $res['ErrorMessage'];
+//        }
+//    }
+//
+//
+//    /** 收运门
+//     * @param string $iot_id
+//     * @param int $mode
+//     * @return string
+//     */
+//    public function doorOutOperation(string $iot_id, int $mode = self::OPEN)
+//    {
+//        $conf = $this->conf;
+//
+//        if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
+//            return '请先配置阿里云app秘钥';
+//        }
+//
+//        if (!isset($conf['appKey']) || empty($conf['appKey'])) {
+//            return '请先配置阿里云appKey';
+//        }
+//        $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
+//        if ($mode == self::CLOSE) {
+//            $identifier = 'RemoteAgentClose';
+//        } else {
+//            $identifier = 'RemoteAgentOpen';
+//        }
+//        $args = (object)[];
+//        $res = $ali->invokeThingService($iot_id, $identifier, $args);
+//        if (isset($res['Success']) && $res['Success']) {
+//            DeviceInfo::where('iot_id', $iot_id)->update(['lock_switch' => $mode]);
+//            return 'success';
+//        } else {
+//            return $res['ErrorMessage'];
+//        }
+//    }
+}

+ 39 - 0
app/User.php

xqd
@@ -0,0 +1,39 @@
+<?php
+
+namespace App;
+
+use Illuminate\Contracts\Auth\MustVerifyEmail;
+use Illuminate\Foundation\Auth\User as Authenticatable;
+use Illuminate\Notifications\Notifiable;
+
+class User extends Authenticatable
+{
+    use Notifiable;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $fillable = [
+        'name', 'email', 'password',
+    ];
+
+    /**
+     * The attributes that should be hidden for arrays.
+     *
+     * @var array
+     */
+    protected $hidden = [
+        'password', 'remember_token',
+    ];
+
+    /**
+     * The attributes that should be cast to native types.
+     *
+     * @var array
+     */
+    protected $casts = [
+        'email_verified_at' => 'datetime',
+    ];
+}