xielin пре 5 година
комит
c5aad3b374
76 измењених фајлова са 3461 додато и 0 уклоњено
  1. BIN
      .DS_Store
  2. 15 0
      .editorconfig
  3. 32 0
      .env.example
  4. 9 0
      .gitignore
  5. 102 0
      .rocketeer/config.php
  6. 40 0
      .rocketeer/hooks.php
  7. 24 0
      .rocketeer/paths.php
  8. 80 0
      .rocketeer/remote.php
  9. 35 0
      .rocketeer/scm.php
  10. 19 0
      .rocketeer/stages.php
  11. 61 0
      .rocketeer/strategies.php
  12. 0 0
      app/Console/Commands/.gitkeep
  13. 137 0
      app/Console/Commands/Trace.php
  14. 86 0
      app/Console/Commands/apollo.php
  15. 48 0
      app/Console/Kernel.php
  16. 10 0
      app/Events/Event.php
  17. 16 0
      app/Events/ExampleEvent.php
  18. 50 0
      app/Exceptions/Handler.php
  19. 87 0
      app/Helper/helper.php
  20. 50 0
      app/Http/Controllers/AuthController.php
  21. 11 0
      app/Http/Controllers/Controller.php
  22. 39 0
      app/Http/Controllers/IndexController.php
  23. 74 0
      app/Http/Controllers/MetaController.php
  24. 34 0
      app/Http/Controllers/TestController.php
  25. 48 0
      app/Http/Middleware/Authenticate.php
  26. 20 0
      app/Http/Middleware/ExampleMiddleware.php
  27. 68 0
      app/Http/Middleware/JwtAuthMiddleware.php
  28. 38 0
      app/Http/Middleware/SqlMiddleware.php
  29. 26 0
      app/Jobs/ExampleJob.php
  30. 24 0
      app/Jobs/Job.php
  31. 31 0
      app/Listeners/ExampleListener.php
  32. 17 0
      app/Models/Meta.php
  33. 18 0
      app/Providers/AppServiceProvider.php
  34. 39 0
      app/Providers/AuthServiceProvider.php
  35. 19 0
      app/Providers/EventServiceProvider.php
  36. 87 0
      app/Repositories/MetaRepository.php
  37. 19 0
      app/Transformers/LoginTransformer.php
  38. 38 0
      app/Transformers/MetaTransformer.php
  39. 45 0
      app/User.php
  40. 35 0
      artisan
  41. 118 0
      bootstrap/app.php
  42. 57 0
      composer.json
  43. 232 0
      config/api.php
  44. 10 0
      config/apollo.php
  45. 90 0
      config/auth.php
  46. 10 0
      config/customer.tpl
  47. 131 0
      config/database.php
  48. 82 0
      config/filesystems.php
  49. 304 0
      config/jwt.php
  50. 19 0
      database/factories/ModelFactory.php
  51. 0 0
      database/migrations/.gitkeep
  52. 34 0
      database/migrations/2019_04_09_065115_create_user_table.php
  53. 49 0
      database/migrations/2019_11_26_092044_create_meta_table.php
  54. 16 0
      database/seeds/DatabaseSeeder.php
  55. 20 0
      deploy/nginx/conf.d/app.beta.conf
  56. 20 0
      deploy/nginx/conf.d/app.dev.conf
  57. 2 0
      deploy/php/local.ini
  58. 32 0
      docker-compose-beta.yml
  59. 31 0
      docker-compose-dev.yml
  60. 26 0
      phpunit.xml
  61. 21 0
      public/.htaccess
  62. 29 0
      public/index.php
  63. 21 0
      readme.md
  64. 19 0
      resources/lang/en/auth.php
  65. 19 0
      resources/lang/en/pagination.php
  66. 22 0
      resources/lang/en/passwords.php
  67. 146 0
      resources/lang/en/validation.php
  68. 17 0
      resources/lang/zh-CN/auth.php
  69. 17 0
      resources/lang/zh-CN/pagination.php
  70. 20 0
      resources/lang/zh-CN/passwords.php
  71. 126 0
      resources/lang/zh-CN/validation.php
  72. 0 0
      resources/views/.gitkeep
  73. 35 0
      routes/api.php
  74. 20 0
      routes/web.php
  75. 21 0
      tests/ExampleTest.php
  76. 14 0
      tests/TestCase.php

+ 15 - 0
.editorconfig

@@ -0,0 +1,15 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.yml]
+indent_size = 2

+ 32 - 0
.env.example

@@ -0,0 +1,32 @@
+APP_NAME=community-manage
+APP_ENV=local
+APP_KEY=
+APP_DEBUG=true
+APP_URL=http://localhost
+APP_TIMEZONE=Asia/Shanghai
+APP_LOCALE=zh-CN
+
+LOG_CHANNEL=stack
+LOG_SLACK_WEBHOOK_URL=
+
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=homestead
+DB_USERNAME=homestead
+DB_PASSWORD=secret
+
+CACHE_DRIVER=file
+QUEUE_CONNECTION=sync
+
+JWT_SECRET=chxqyhnjuikm67wshaed8ij3hyf2ndh3
+
+PER_PAGE=20
+
+APP_ID=chxq-platform-manage
+CLUSTER=default
+APOLLO_NAMESPACES="application,community-manage"
+APOLLO_CONFIG_SERVER=http://127.0.0.1:18080
+
+RPC_NODE_URL=https://127.0.0.1:8888
+RPC_KEOSD_URL=http://127.0.0.1:8900

+ 9 - 0
.gitignore

@@ -0,0 +1,9 @@
+/vendor
+.idea*
+Homestead.json
+Homestead.yaml
+.env
+composer.lock
+/storage/*
+/config/customer.php
+/public/export/*

+ 102 - 0
.rocketeer/config.php

@@ -0,0 +1,102 @@
+<?php
+
+use Rocketeer\Services\Connections\ConnectionsHandler;
+
+return [
+
+    // The name of the application to deploy
+    // This will create a folder of the same name in the root directory
+    // configured above, so be careful about the characters used
+    'application_name' => 'trace-manage',
+
+    // Plugins
+    ////////////////////////////////////////////////////////////////////
+
+    // The plugins to load
+    'plugins'          => [// 'Rocketeer\Plugins\Slack\RocketeerSlack',
+    ],
+
+    // Logging
+    ////////////////////////////////////////////////////////////////////
+
+    // The schema to use to name log files
+    'logs'             => function (ConnectionsHandler $connections) {
+        return sprintf('%s-%s-%s.log', $connections->getConnection(), $connections->getStage(), date('Ymd'));
+    },
+
+    // Remote access
+    //
+    // You can either use a single connection or an array of connections
+    ////////////////////////////////////////////////////////////////////
+
+    // The default remote connection(s) to execute tasks on
+    'default'          => ['beta'],
+
+    // The various connections you defined
+    // You can leave all of this empty or remove it entirely if you don't want
+    // to track files with credentials : Rocketeer will prompt you for your credentials
+    // and store them locally
+    'connections'      => [
+        'beta'  => [
+            'host'      => '47.92.174.125:2345',
+            'username'  => 'root',
+            'password'  => '',
+            'key'       => '/root/.ssh/id_rsa',
+            'keyphrase' => '',
+            'agent'     => '',
+            'db_role'   => true,
+        ],
+        'production' => [
+            'host'      => '47.92.121.231:2345',
+            'username'  => 'root',
+            'password'  => '',
+            'key'       => '/root/.ssh/id_rsa',
+            'keyphrase' => '',
+            'agent'     => '',
+            'db_role'   => true,
+        ],
+    ],
+
+    /*
+     * In most multiserver scenarios, migrations must be run in an exclusive server.
+     * In the event of not having a separate database server (in which case it can
+     * be handled through connections), you can assign a 'db_role' => true to the
+     * server's configuration and it will only run the migrations in that specific
+     * server at the time of deployment.
+     */
+    'use_roles'        => false,
+
+    // Contextual options
+    //
+    // In this section you can fine-tune the above configuration according
+    // to the stage or connection currently in use.
+    // Per example :
+    // 'stages' => array(
+    // 	'staging' => array(
+    // 		'scm' => array('branch' => 'staging'),
+    // 	),
+    //  'production' => array(
+    //    'scm' => array('branch' => 'master'),
+    //  ),
+    // ),
+    ////////////////////////////////////////////////////////////////////
+
+    'on'               => [
+
+        // Stages configurations
+        'stages'      => [],
+        // Connections configuration
+        'connections' => [
+            'production'    => [
+                'remote'    => [
+                    'root_directory'    => '/data/wwwroot/uptoyo/api'
+                ],
+                'scm'   => [
+                    'branch'    => 'release'
+                ]
+            ]
+        ],
+
+    ],
+
+];

+ 40 - 0
.rocketeer/hooks.php

@@ -0,0 +1,40 @@
+<?php
+
+return [
+
+    // Tasks
+    //
+    // Here you can define in the `before` and `after` array, Tasks to execute
+    // before or after the core Rocketeer Tasks. You can either put a simple command,
+    // a closure which receives a $task object, or the name of a class extending
+    // the Rocketeer\Abstracts\AbstractTask class
+    //
+    // In the `custom` array you can list custom Tasks classes to be added
+    // to Rocketeer. Those will then be available in the command line
+    // with all the other tasks
+    //////////////////////////////////////////////////////////////////////
+
+    // Tasks to execute before the core Rocketeer Tasks
+    'before' => [
+        'setup'   => [],
+        'deploy'  => [],
+        'cleanup' => [],
+    ],
+
+    // Tasks to execute after the core Rocketeer Tasks
+    'after'  => [
+        'setup'   => [],
+        'deploy'  => [
+            'composer dumpautoload',
+            'chmod -R 777 bootstrap',
+            'chmod -R 777 storage',
+            'chmod -R 777 public',
+            'service php-fpm reload'
+        ],
+        'cleanup' => [],
+    ],
+
+    // Custom Tasks to register with Rocketeer
+    'custom' => [],
+
+];

+ 24 - 0
.rocketeer/paths.php

@@ -0,0 +1,24 @@
+<?php
+
+return [
+
+    // Configurable paths
+    //
+    // Here you can manually set paths to some commands Rocketeer
+    // might try to use, if you leave those empty it will try to find them
+    // manually or assume they're in the root folder
+    //
+    // You can also add in this file custom paths for any command or binary
+    // Rocketeer might go looking for
+    ////////////////////////////////////////////////////////////////////
+
+    // Path to the PHP binary
+    'php'      => '/usr/local/php/bin/php',
+
+    // Path to Composer
+    'composer' => '/usr/local/bin/composer',
+
+    // Path to the Artisan CLI
+    'artisan'  => 'artisan',
+
+];

+ 80 - 0
.rocketeer/remote.php

@@ -0,0 +1,80 @@
+<?php
+
+return [
+
+    // Remote server
+    //////////////////////////////////////////////////////////////////////
+
+    // Variables about the servers. Those can be guessed but in
+    // case of problem it's best to input those manually
+    'variables'      => [
+        'directory_separator' => '/',
+        'line_endings'        => "\n",
+    ],
+
+    // The number of releases to keep at all times
+    'keep_releases'  => 4,
+
+    // Folders
+    ////////////////////////////////////////////////////////////////////
+
+    // The root directory where your applications will be deployed
+    // This path *needs* to start at the root, ie. start with a /
+    'root_directory' => '/data/wwwroot/beta',
+
+    // The folder the application will be cloned in
+    // Leave empty to use `application_name` as your folder name
+    'app_directory'  => '',
+
+    // A list of folders/file to be shared between releases
+    // Use this to list folders that need to keep their state, like
+    // user uploaded data, file-based databases, etc.
+    'shared'         => [
+        'storage',
+        'vendor',
+        '.env',
+    ],
+
+    // Execution
+    //////////////////////////////////////////////////////////////////////
+
+    // If enabled will force a shell to be created
+    // which is required for some tools like RVM or NVM
+    'shell'          => false,
+
+    // An array of commands to run under shell
+    'shelled'        => ['which', 'ruby', 'npm', 'bower', 'bundle', 'grunt'],
+
+    // Enable use of sudo for some commands
+    // You can specify a sudo user by doing
+    // 'sudo' => 'the_user'
+    'sudo' => false,
+
+    // An array of commands to run under sudo
+    'sudoed' => [],
+
+    // Permissions$
+    ////////////////////////////////////////////////////////////////////
+
+    'permissions'    => [
+
+        // The folders and files to set as web writable
+        'files'    => [
+            'bootstrap/cache',
+            'storage',
+        ],
+
+        // Here you can configure what actions will be executed to set
+        // permissions on the folder above. The Closure can return
+        // a single command as a string or an array of commands
+        'callback' => function ($task, $file) {
+            return [
+                sprintf('chmod -R 777 %s', $file),
+                sprintf('chmod -R g+s %s', $file),
+                sprintf('chown -R www:www %s', $file),
+            ];
+        },
+
+    ],
+
+];

+ 35 - 0
.rocketeer/scm.php

@@ -0,0 +1,35 @@
+<?php
+
+return [
+
+    // SCM repository
+    //////////////////////////////////////////////////////////////////////
+
+    // The SCM used (supported: "git", "svn")
+    'scm'        => 'git',
+
+    // The SSH/HTTPS address to your repository
+    // Example: https://github.com/vendor/website.git
+    'repository' => 'http://caihongxingqiu:Ch20151002@git.caihongxingqiu.net/rainbow/community-manage.git',
+
+    // The repository credentials : you can leave those empty
+    // if you're using SSH or if your repository is public
+    // In other cases you can leave this empty too, and you will
+    // be prompted for the credentials on deploy. If you don't want
+    // to be prompted (public repo, etc) set the values to null
+    'username'   => 'null',
+    'password'   => 'null',
+
+    // The branch to deploy
+    'branch'     => 'master',
+
+    // Whether your SCM should do a "shallow" clone of the repository
+    // or not – this means a clone with just the latest state of your
+    // application (no history)
+    // If you're having problems cloning, try setting this to false
+    'shallow'    => true,
+
+    // Recursively pull in submodules. Works only with GIT.
+    'submodules' => true,
+
+];

+ 19 - 0
.rocketeer/stages.php

@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+    // Stages
+    //
+    // The multiples stages of your application
+    // if you don't know what this does, then you don't need it
+    //////////////////////////////////////////////////////////////////////
+
+    // Adding entries to this array will split the remote folder in stages
+    // Like /var/www/yourapp/staging and /var/www/yourapp/production
+    'stages'  => [],
+
+    // The default stage to execute tasks on when --stage is not provided
+    // Falsey means all of them
+    'default' => '',
+
+];

+ 61 - 0
.rocketeer/strategies.php

@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of Rocketeer
+ *
+ * (c) Maxime Fabre <ehtnam6@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Rocketeer\Binaries\PackageManagers\Composer;
+use Rocketeer\Tasks\Subtasks\Primer;
+
+return [
+
+    // Task strategies
+    //
+    // Here you can configure in a modular way which tasks to use to
+    // execute various core parts of your deployment's flow
+    //////////////////////////////////////////////////////////////////////
+
+    // Which strategy to use to check the server
+    'check'        => 'Php',
+
+    // Which strategy to use to create a new release
+    'deploy'       => 'Clone',
+
+    // Which strategy to use to test your application
+    'test'         => 'Phpunit',
+
+    // Which strategy to use to migrate your database
+    'migrate'      => 'Artisan',
+
+    // Which strategy to use to install your application's dependencies
+    'dependencies' => 'Composer',
+
+    // Execution hooks
+    //////////////////////////////////////////////////////////////////////
+
+    'composer'     => [
+        'install' => function (Composer $composer, $task) {
+            return $composer->install([], ['--no-interaction' => null, '--prefer-dist' => null]);
+        },
+        'update'  => function (Composer $composer) {
+            return $composer->update();
+        },
+    ],
+
+    // Here you can configure the Primer tasks
+    // which will run a set of commands on the local
+    // machine, determining whether the deploy can proceed
+    // or not
+    'primer'       => function (Primer $task) {
+        return [
+            // $task->executeTask('Test'),
+            // $task->binary('grunt')->execute('lint'),
+        ];
+    },
+
+];

+ 0 - 0
app/Console/Commands/.gitkeep


+ 137 - 0
app/Console/Commands/Trace.php

@@ -0,0 +1,137 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Models\Meta;
+use BlockMatrix\EosRpc\ChainFactory;
+use BlockMatrix\EosRpc\EosRpc;
+use BlockMatrix\EosRpc\WalletFactory;
+use GuzzleHttp\Client;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Storage;
+use Org\Multilinguals\Apollo\Client\ApolloClient;
+use ZanySoft\Zip\Zip;
+
+class Trace extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'trace';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '自动打zip包,并进行上链操作';
+
+    protected $save_dir = '';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->save_dir = '';
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->line('-----------traceing---------');
+        $metas = Meta::where('status',0)->get();
+        foreach($metas as $meta){
+            $this->save_dir = storage_path($meta['patch_num']);
+            if(!is_dir($this->save_dir)){
+                mkdir($this->save_dir);
+            }
+            $files = [];
+            //1.生成txt
+            $myfile = fopen($this->save_dir."/批次信息.txt", "w");
+            $txt  = "批次号:{$meta['patch_num']}\n";
+            $txt .= "鸡种:{$meta['variety']}\n";
+            $txt .= "年龄:{$meta['age']}\n";
+            $txt .= "口粮:{$meta['food']}\n";
+            $txt .= "水源:{$meta['water']}\n";
+            fwrite($myfile, $txt);
+            fclose($myfile);
+            array_push($files,$this->save_dir."/批次信息.txt");
+            //2.生成质检信息
+            $myfile = fopen($this->save_dir."/质检信息.html", "w");
+            $txt  = $meta['report'];
+            fwrite($myfile, $txt);
+            fclose($myfile);
+            array_push($files,$this->save_dir."/质检信息.html");
+            $varietyImg = $this->downloadImg($this->save_dir,$meta['variety_img'],'鸡种');
+            array_push($files,$varietyImg);
+            $foodImg = $this->downloadImg($this->save_dir,$meta['food_img'],'口粮');
+            array_push($files,$foodImg);
+            $waterImg = $this->downloadImg($this->save_dir,$meta['water_img'],'水源');
+            array_push($files,$waterImg);
+            $farms = \GuzzleHttp\json_decode($meta['farm'],true);
+            foreach ($farms as $k=>$v){
+                $farmImg = $this->downloadImg($this->save_dir,$v,'农场'.($k+1));
+                array_push($files,$farmImg);
+            }
+            //生成zip包
+            $zipPath = storage_path().'/'.$meta['patch_num'].".zip";
+            $zip = Zip::create($zipPath);
+            $zip->add($this->save_dir,true);
+            $zip->close();
+            $md5 = md5_file($zipPath);
+            $this->line($zipPath.'ZIP包MD5码:'.$md5);
+
+            $zipUrl = Storage::put('/trace/'.date('Ym'), file_get_contents($zipPath));
+            //Meta::where('patch_num',$meta['patch_num'])->update(['md5'=>$md5,'zip'=>$zipUrl]);
+            $row = $this->transcation($md5);
+            var_dump($row);
+        }
+    }
+    //下载远程图片到服务器
+    protected function downloadImg($path,$img,$name=''){
+        $client = new Client(['verify' => false]);  //忽略SSL错误
+        if($name){
+            $path = $path .'/'. $name . '.jpg';
+        }else{
+            $path = $path .'/'. md5(time()) . '.jpg';
+        }
+
+        $response = $client->get($img, ['save_to' => $path]);  //保存远程url到文件
+        if ($response->getStatusCode() == 200) {
+            return $path;
+        }
+        Log::debug('下载'.$img.'失败');
+        return false;
+    }
+
+    protected function transcation($md5){
+        $api = (new ChainFactory())->api(base_path());
+        $walapi = (new WalletFactory())->api(base_path());
+        $eos = (new EosRpc($api, $walapi));
+        $walletPassword = "PW5KFL5mQSWauhwnYTMFU3v9ALhkTCuCkfvVJgzJTpRKZysygTJZe";
+        $eos->setWalletInfo("default", $walletPassword);
+        $trans = $eos->transfer("alice", "bob", "1.0000 SYS", $md5);
+        $aliceBalance = $api->getCurrencyBalance('eosio.token', 'alice', 'SYS');
+        $bobBalance = $api->getCurrencyBalance('eosio.token', 'bob', 'SYS');
+        $row = $api->getBlockHeaderState($trans);
+
+        return response()->json([
+            'trans' => $trans,
+            'alice' => $aliceBalance,
+            'bob' => $bobBalance,
+            'row' => $row,
+        ]);
+    }
+}

+ 86 - 0
app/Console/Commands/apollo.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+use Org\Multilinguals\Apollo\Client\ApolloClient;
+
+class Apollo extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'apollo';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Apollo配置服务';
+
+
+    private $apollo;
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->save_dir = storage_path('apollo');
+        $this->config_tpl = config_path() . '/customer.tpl';
+        $this->config_file = config_path() . '/customer.php';
+
+        $this->apollo = new ApolloClient(
+            config('apollo.config_server'),
+            config('apollo.app_id'),
+            config('apollo.namespaces')
+        );
+        $this->apollo->save_dir = $this->save_dir;
+        if(!is_dir($this->save_dir)){
+            mkdir($this->save_dir);
+        }
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->line('apollo配置服务开启');
+        $restart = true; //失败自动重启
+        do {
+            $error = $this->apollo->start(function () {
+                $list = glob($this->save_dir . DIRECTORY_SEPARATOR . 'apolloConfig.*');
+                $apollo = [];
+                foreach ($list as $l) {
+                    $config = require $l;
+                    if (is_array($config) && isset($config['configurations'])) {
+                        $apollo = array_merge($apollo, $config['configurations']);
+                    }
+                }
+                if (!$apollo) {
+                    Log::error('Load Apollo Config Failed, no config available');
+                }
+                $tpl = file_get_contents($this->config_tpl);
+                foreach ($apollo as $key =>$value){
+                    $tpl = str_replace('{'.$key.'}',$value,$tpl);
+                }
+                file_put_contents($this->config_file,$tpl);
+            }); //此处传入回调
+            if ($error) {
+                Log::info("Apollo Hand error :" . $error);
+            }
+            sleep(60);
+        } while ($error && $restart);
+    }
+}

+ 48 - 0
app/Console/Kernel.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Console;
+
+use App\Console\Commands\Apollo;
+use App\Console\Commands\CommunityMemberStatistics;
+use App\Console\Commands\Downloads;
+use App\Console\Commands\MusicImport;
+use App\Console\Commands\PostCollectBean;
+use App\Console\Commands\PostCreateBean;
+use App\Console\Commands\PostStatistics;
+use App\Console\Commands\PostYesterday;
+use App\Console\Commands\TopicUseCount;
+use App\Console\Commands\Trace;
+use App\Console\Commands\UpdatePostInfo;
+use App\Console\Commands\UpdatePostStatus;
+use App\Console\Commands\UpdateReplyCount;
+use App\Console\Commands\UpdateTopicData;
+use App\Console\Commands\UpdateTopicUseCount;
+use App\Console\Commands\VirusAdd;
+use App\Console\Commands\YesterdayGreatPost;
+use Illuminate\Console\Scheduling\Schedule;
+use Laravel\Lumen\Console\Kernel as ConsoleKernel;
+
+class Kernel extends ConsoleKernel
+{
+    /**
+     * The Artisan commands provided by your application.
+     *
+     * @var array
+     */
+    protected $commands = [
+        Apollo::class,
+        Trace::class,
+    ];
+
+    /**
+     * Define the application's command schedule.
+     *
+     * @param  \Illuminate\Console\Scheduling\Schedule $schedule
+     * @return void
+     */
+    protected function schedule(Schedule $schedule)
+    {
+        $path = storage_path('logs/' . date('Y-m-d') . '-schedule.log');
+
+    }
+}

+ 10 - 0
app/Events/Event.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Events;
+
+use Illuminate\Queue\SerializesModels;
+
+abstract class Event
+{
+    use SerializesModels;
+}

+ 16 - 0
app/Events/ExampleEvent.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Events;
+
+class ExampleEvent extends Event
+{
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+}

+ 50 - 0
app/Exceptions/Handler.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace App\Exceptions;
+
+use Exception;
+use Illuminate\Validation\ValidationException;
+use Illuminate\Auth\Access\AuthorizationException;
+use Illuminate\Database\Eloquent\ModelNotFoundException;
+use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+
+class Handler extends ExceptionHandler
+{
+    /**
+     * A list of the exception types that should not be reported.
+     *
+     * @var array
+     */
+    protected $dontReport = [
+        AuthorizationException::class,
+        HttpException::class,
+        ModelNotFoundException::class,
+        ValidationException::class,
+    ];
+
+    /**
+     * Report or log an exception.
+     *
+     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
+     *
+     * @param  \Exception  $exception
+     * @return void
+     */
+    public function report(Exception $exception)
+    {
+        parent::report($exception);
+    }
+
+    /**
+     * Render an exception into an HTTP response.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Exception  $exception
+     * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
+     */
+    public function render($request, Exception $exception)
+    {
+        return parent::render($request, $exception);
+    }
+}

+ 87 - 0
app/Helper/helper.php

@@ -0,0 +1,87 @@
+<?php
+/**
+ * 添加自定义辅助函数
+ */
+
+if ( ! function_exists('config_path'))
+{
+    /**
+     * Get the configuration path.
+     *
+     * @param string $path
+     * @return string
+     */
+    function config_path($path = '')
+    {
+        return app()->basePath() . '/config' . ($path ? '/' . $path : $path);
+    }
+}
+
+if (! function_exists('public_path')) {
+    /**
+     * Get the path to the public folder.
+     *
+     * @param  string  $path
+     * @return string
+     */
+    function public_path($path = '')
+    {
+        return app()->basePath() . '/public' . ($path ? '/' . $path : $path);
+    }
+}
+
+function subtext($text, $length)
+{
+    if(mb_strlen($text, 'utf8') > $length) {
+        return mb_substr($text, 0, $length, 'utf8').'...';
+    } else {
+        return $text;
+    }
+}
+
+
+function http($url, $param, $isCheck = true, $method = 'post')
+{
+    try {
+        $client = new \GuzzleHttp\Client();
+        $response = $client->request($method, $url, $param);
+        $result = json_decode($response->getBody()->getContents(), true);
+        \Illuminate\Support\Facades\Log::debug('url:'.$url.'param:'.json_encode($param).'response:'.json_encode($result));
+        if ($isCheck == true) {
+            if ($result['code'] == 0) {
+                return $result['data'];
+            } else {
+                return [];
+            }
+        } else {
+            return $result;
+        }
+
+    } catch (\Exception $exception) {
+        \Illuminate\Support\Facades\Log::debug('http-exception:'.$exception->getMessage());
+        return [];
+    }
+}
+
+
+function generateSign(array $params, $secret_key)
+{
+    unset($params['sign']);
+    // 将删除参数组中所有等值为FALSE的参数(包括:NULL, 空字符串,0, false)
+    $params = array_filter($params);
+
+    // 按照键名对参数数组进行升序排序
+    ksort($params);
+
+    // 给参数数组追加密钥,键名为 key, 值为签名配置中配置的 secret_key 的值
+    $params['chxq_key'] = $secret_key;
+    \Illuminate\Support\Facades\Log::debug($params);
+    // 生成 URL-encode 之后的请求字符串
+    $str = http_build_query($params);
+    $str = urldecode($str);
+    \Illuminate\Support\Facades\Log::debug($str);
+    //$str = "address=计算机啊手机壳阿看见手机卡&address_type=1&area_id=2&area_name=西安市&city_id=2&city_name=西安市&contact_mobile
+    //=18458881890&contact_name=刘德华&province_id=1&province_name=陕西省&uid=0&zipcode=1000000";
+    // 将请求字符串使用MD5加密后,再转换成大写,并返回
+    return strtoupper(MD5($str));
+}

+ 50 - 0
app/Http/Controllers/AuthController.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Transformers\LoginTransformer;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Hash;
+use Illuminate\Support\Facades\Validator;
+use Tymon\JWTAuth\Facades\JWTAuth;
+class AuthController extends Controller
+{
+
+    /**
+     * Create a new controller instance.
+     *
+     * @return void
+     */
+    public function __construct(JWTAuth $jwt)
+    {
+    }
+
+//    /**
+//     * 登录
+//     * @param Request $request
+//     * @return mixed
+//     * @deprecated
+//     */
+    public function authenticate(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'username' => 'required',
+            'password' => 'required',
+        ]);
+        if ($validator->fails()) {
+            return $this->response->error($validator->errors()->first(), 500);
+        }
+//        echo Hash::make('123456');
+        $credentials = $request->only(['username', 'password']);
+        if (!$token = Auth::attempt($credentials)) {
+            return $this->response->error('登录失败,请重试', 401);
+        }
+
+        $users = Auth::user();
+        $users->token = $token;
+
+        return $this->response->item($users, new LoginTransformer());
+    }
+
+}

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

@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Routing\Controller as BaseController;
+use Dingo\Api\Routing\Helpers;
+
+class Controller extends BaseController
+{
+    use Helpers;
+}

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

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/3
+ * Time: 14:36
+ */
+
+namespace App\Http\Controllers;
+
+
+use App\Repositories\MetaRepository;
+use App\Transformers\MetaTransformer;
+use Illuminate\Http\Request;
+use League\Fractal\Manager;
+use League\Fractal\Resource\Collection;
+use League\Fractal\Pagination\IlluminatePaginatorAdapter;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\Rule;
+
+class IndexController extends Controller
+{
+    public function __construct(MetaRepository $metaRepository)
+    {
+        $this->metaRepository = $metaRepository;
+    }
+
+    public function index(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'patch_num' => 'required'
+        ]);
+        if ($validator->fails()) {
+            return $this->response->error($validator->errors()->first(), 500);
+        }
+        $meta = $this->metaRepository->view($request->all());
+        return $this->response->item($meta, new MetaTransformer());
+    }
+}

+ 74 - 0
app/Http/Controllers/MetaController.php

@@ -0,0 +1,74 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/3
+ * Time: 14:36
+ */
+
+namespace App\Http\Controllers;
+
+
+use App\Repositories\MetaRepository;
+use App\Transformers\MetaTransformer;
+use Illuminate\Http\Request;
+use League\Fractal\Manager;
+use League\Fractal\Resource\Collection;
+use League\Fractal\Pagination\IlluminatePaginatorAdapter;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\Rule;
+
+class MetaController extends Controller
+{
+    public function __construct(MetaRepository $metaRepository)
+    {
+        $this->metaRepository = $metaRepository;
+    }
+
+    public function index(Request $request)
+    {
+        $productList = $this->metaRepository->index($request->all());
+        $fractal = new Manager();
+        $resource = new Collection($productList, new MetaTransformer());
+        $resource->setPaginator(new IlluminatePaginatorAdapter($productList));
+        $data = $fractal->createData($resource)->toArray();
+        $data['extra'] = [
+            'filters' => [
+                'patch_num',
+            ],
+            'columns' => [
+                'patch_num',
+                'md5',
+                'zip',
+                'status',
+                'trans_id',
+                'created_at',
+                'updated_at',
+            ]
+        ];
+        return $data;
+    }
+
+    /**
+     * 发布信息
+     */
+    public function create(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'patch_num' => 'required|max:16',
+            'variety' => 'required|max:4',
+            'variety_img' => 'required|url',
+            'age' => 'required|max:4',
+            'food' => 'required|max:5',
+            'food_img' => 'required|url',
+            'water' => 'required|max:5',
+            'water_img' => 'required|url',
+            'farm.*' => 'required|url',
+            'report' => 'required'
+        ]);
+        if ($validator->fails()) {
+            return $this->response->error($validator->errors()->first(), 500);
+        }
+        return  $this->metaRepository->create($request->all());
+    }
+}

+ 34 - 0
app/Http/Controllers/TestController.php

@@ -0,0 +1,34 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/3
+ * Time: 14:36
+ */
+
+namespace App\Http\Controllers;
+
+
+use BlockMatrix\EosRpc\ChainFactory;
+use BlockMatrix\EosRpc\EosRpc;
+use BlockMatrix\EosRpc\WalletFactory;
+
+class TestController extends Controller
+{
+    public function index()
+    {
+        $api = (new ChainFactory())->api(base_path());
+        $walapi = (new WalletFactory())->api(base_path());
+        $eos = (new EosRpc($api, $walapi));
+        $walletPassword = "PW5KFL5mQSWauhwnYTMFU3v9ALhkTCuCkfvVJgzJTpRKZysygTJZe";
+        $eos->setWalletInfo("default", $walletPassword);
+        $trans = $eos->transfer("alice", "bob", "1.0000 SYS", "开始交易" . md5(time()));
+        $aliceBalance = $api->getCurrencyBalance('eosio.token', 'alice', 'SYS');
+        $bobBalance = $api->getCurrencyBalance('eosio.token', 'bob', 'SYS');
+        return response()->json([
+            'trans' => $trans,
+            'alice' => $aliceBalance,
+            'bob' => $bobBalance,
+        ]);
+    }
+}

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

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Contracts\Auth\Factory as Auth;
+
+class Authenticate
+{
+    /**
+     * The authentication guard factory instance.
+     *
+     * @var \Illuminate\Contracts\Auth\Factory
+     */
+    protected $auth;
+
+    /**
+     * Create a new middleware instance.
+     *
+     * @param  \Illuminate\Contracts\Auth\Factory  $auth
+     * @return void
+     */
+    public function __construct(Auth $auth)
+    {
+        $this->auth = $auth;
+    }
+
+    /**
+     * 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 ($this->auth->guard($guard)->guest()) {
+            $error = [
+                'message' => '请重新登录',
+                'code' => 401,
+            ];
+            return response()->json($error);
+        }
+
+        return $next($request);
+    }
+}

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

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+
+class ExampleMiddleware
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        return $next($request);
+    }
+}

+ 68 - 0
app/Http/Middleware/JwtAuthMiddleware.php

@@ -0,0 +1,68 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\Log;
+use Tymon\JWTAuth\Exceptions\JWTException;
+use Tymon\JWTAuth\Exceptions\TokenExpiredException;
+use Tymon\JWTAuth\Exceptions\TokenInvalidException;
+use Tymon\JWTAuth\Facades\JWTAuth;
+use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
+
+class JwtAuthMiddleware
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+
+        try {
+            $token = JWTAuth::getToken();
+            if(empty($token)){
+                $error = [
+                    'message' => 'token is required',
+                    'code' => 401,
+                ];
+                return response()->json($error);
+            }
+//            $data = JWTAuth::decode($token)->authenticate();
+            $data = JWTAuth::decode($token);
+            Log::debug('parse-token='.json_encode($data));
+        } catch (TokenExpiredException $e) {
+            $error = [
+                'message' => 'Token is Expired',
+                'code' => 401,
+            ];
+            Log::debug('parse-token='.$e->getMessage());
+            return response()->json($error);
+        } catch (TokenInvalidException $e) {
+            $error = [
+                'message' => $e->getMessage(),
+                'code' => 401,
+            ];
+            Log::debug('parse-token='.$e->getMessage());
+            return response()->json($error);
+        } catch (JWTException $e) {
+            $error = [
+                'message' => $e->getMessage(),
+                'code' => 401,
+            ];
+            Log::debug('parse-token='.$e->getMessage());
+            return response()->json($error);
+        }catch (\Exception $e){
+            $error = [
+                'message' => $e->getMessage(),
+                'code' => 401,
+            ];
+            Log::debug('parse-token='.$e->getMessage());
+            return response()->json($error);
+        }
+        return $next($request);
+    }
+}

+ 38 - 0
app/Http/Middleware/SqlMiddleware.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\DB;
+
+class SqlMiddleware
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        if ($request->sql_debug==1) {
+            DB::connection()->enableQueryLog();
+        }
+
+        $response = $next($request);
+        if ($request->get('sql_debug')) {
+            $queries = DB::getQueryLog();
+
+            if (!empty($queries)) {
+                foreach ($queries as &$query) {
+                    $query['full_query'] = vsprintf(str_replace('?', '%s', $query['query']), $query['bindings']);
+                }
+            }
+
+            dd($queries);exit;
+        }
+
+        return $response;
+    }
+}

+ 26 - 0
app/Jobs/ExampleJob.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Jobs;
+
+class ExampleJob extends Job
+{
+    /**
+     * Create a new job instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        //
+    }
+}

+ 24 - 0
app/Jobs/Job.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Jobs;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Contracts\Queue\ShouldQueue;
+
+abstract class Job implements ShouldQueue
+{
+    /*
+    |--------------------------------------------------------------------------
+    | Queueable Jobs
+    |--------------------------------------------------------------------------
+    |
+    | This job base class provides a central location to place any logic that
+    | is shared across all of your jobs. The trait included with the class
+    | provides access to the "queueOn" and "delay" queue helper methods.
+    |
+    */
+
+    use InteractsWithQueue, Queueable, SerializesModels;
+}

+ 31 - 0
app/Listeners/ExampleListener.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Listeners;
+
+use App\Events\ExampleEvent;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Contracts\Queue\ShouldQueue;
+
+class ExampleListener
+{
+    /**
+     * Create the event listener.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Handle the event.
+     *
+     * @param  ExampleEvent  $event
+     * @return void
+     */
+    public function handle(ExampleEvent $event)
+    {
+        //
+    }
+}

+ 17 - 0
app/Models/Meta.php

@@ -0,0 +1,17 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 15:32
+ */
+namespace App\Models;
+use Illuminate\Database\Eloquent\Model;
+
+class Meta extends Model
+{
+    //
+    protected $table = 'meta';
+    protected $guarded = [];
+
+}

+ 18 - 0
app/Providers/AppServiceProvider.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Support\ServiceProvider;
+
+class AppServiceProvider extends ServiceProvider
+{
+    /**
+     * Register any application services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        //
+    }
+}

+ 39 - 0
app/Providers/AuthServiceProvider.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Providers;
+
+use App\User;
+use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\ServiceProvider;
+
+class AuthServiceProvider extends ServiceProvider
+{
+    /**
+     * Register any application services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        //
+    }
+
+    /**
+     * Boot the authentication services for the application.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        // Here you may define how you wish users to be authenticated for your Lumen
+        // application. The callback which receives the incoming request instance
+        // should return either a User instance or null. You're free to obtain
+        // the User instance via an API token or any other method necessary.
+
+        $this->app['auth']->viaRequest('api', function ($request) {
+            if ($request->input('api_token')) {
+                return User::where('api_token', $request->input('api_token'))->first();
+            }
+        });
+    }
+}

+ 19 - 0
app/Providers/EventServiceProvider.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Providers;
+
+use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;
+
+class EventServiceProvider extends ServiceProvider
+{
+    /**
+     * The event listener mappings for the application.
+     *
+     * @var array
+     */
+    protected $listen = [
+        'App\Events\ExampleEvent' => [
+            'App\Listeners\ExampleListener',
+        ],
+    ];
+}

+ 87 - 0
app/Repositories/MetaRepository.php

@@ -0,0 +1,87 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019-06-10
+ * Time: 17:40
+ */
+namespace App\Repositories;
+
+use App\Models\Meta;
+use Dingo\Api\Http\Response;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Database\QueryException;
+use Illuminate\Support\Facades\Log;
+
+class MetaRepository {
+    public function __construct(Meta $meta){
+        $this->meta = $meta;
+    }
+    //列表
+    public function index($request){
+        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
+        $where = [];
+        return $this->meta->where($where)->orderBy('id', 'desc')->paginate($perPage);
+    }
+    //详情
+    public function view($request){
+        return $this->meta->where(['patch_num'=>$request['patch_num']])->first();
+    }
+    //创建
+    public function create($request){
+        $category = $this->meta->where(['patch_num'=>$request['patch_num']])->first();
+        if($category){
+            return Response::create([
+                'message'  => '该批次已存在',
+                'status_code'   => 500
+            ]);
+        }
+        if(count($request['farm'])>10){
+            return Response::create([
+                'message'  => '农场图片不能超过10张',
+                'status_code'   => 500
+            ]);
+        }
+        $data = [
+            'patch_num' => $request['patch_num'],
+            'variety' => $request['variety'],
+            'variety_img' => $request['variety_img'],
+            'age' => $request['age'],
+            'food' => $request['food'],
+            'food_img' => $request['food_img'],
+            'water' => $request['water'],
+            'water_img' => $request['water_img'],
+            'logistical' => $request['logistical']??'',
+            'farm' => \GuzzleHttp\json_encode($request['farm']),
+            'report' => $request['report'],
+        ];
+
+        DB::beginTransaction();
+        try{
+            $meta = $this->meta->create($data);
+
+            DB::commit();
+            return Response::create();
+        }catch (QueryException $exception){
+            DB::rollBack();
+            Log::debug('新增元数据失败:'.$exception->getMessage());
+            return Response::create([
+                'message'  => '新增元数据失败,请重试',
+                'error' => $exception->getMessage(),
+                'status_code'   => 500
+            ]);
+        }
+    }
+    //修改
+    public function update($request){
+        $category = $this->meta->where('id', $request['id'])->first();
+        if(isset($request['is_suggest']) && $request['is_suggest'] !== null){
+            $category->is_suggest = $request['is_suggest'];
+        }
+        $res = $category->save();
+        if($res){
+            return Response::create();
+        }
+    }
+}

+ 19 - 0
app/Transformers/LoginTransformer.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Transformers;
+
+use App\User;
+use League\Fractal\TransformerAbstract;
+
+class LoginTransformer extends TransformerAbstract
+{
+
+    public function transform(User $user)
+    {
+        return [
+            'user_id'  => $user['id'],
+            'username'  => $user['username'],
+            'token'  => "Bearer {$user['token']}",
+        ];
+    }
+}

+ 38 - 0
app/Transformers/MetaTransformer.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019-06-10
+ * Time: 18:47
+ */
+
+namespace App\Transformers;
+
+use App\Models\Category;
+use App\Models\Meta;
+use League\Fractal\TransformerAbstract;
+use Illuminate\Support\Carbon;
+
+class MetaTransformer extends TransformerAbstract
+{
+    public function transform(Meta $meta)
+    {
+
+        return [
+            "patch_num" => $meta['patch_num'],
+            "variety" => $meta['variety'],
+            "variety_img" => $meta['variety_img'],
+            "age" => $meta['age'],
+            "food" => $meta['food'],
+            "food_img" => $meta['food_img'],
+            "water" => $meta['water'],
+            "water_img" => $meta['water_img'],
+            "status" => $meta['status'],
+            "trans_id" => $meta['trans_id'],
+            "zip" => $meta['zip'],
+            "md5" => $meta['md5'],
+            "created_at" => Carbon::parse($meta['created_at'])->toDateTimeString(),
+            "updated_at" => Carbon::parse($meta['updated_at'])->toDateTimeString(),
+        ];
+    }
+}

+ 45 - 0
app/User.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App;
+
+use Illuminate\Auth\Authenticatable;
+use Laravel\Lumen\Auth\Authorizable;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
+use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
+use Tymon\JWTAuth\Contracts\JWTSubject;
+
+class User extends Model implements JWTSubject,AuthenticatableContract, AuthorizableContract
+{
+    use Authenticatable, Authorizable;
+
+    public $table='user';
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $fillable = [
+        'username', 'password',
+    ];
+
+    /**
+     * The attributes excluded from the model's JSON form.
+     *
+     * @var array
+     */
+    protected $hidden = [
+        'password',
+    ];
+
+    public function getJWTIdentifier()
+    {
+        return $this->getKey();
+    }
+
+    public function getJWTCustomClaims()
+    {
+        return [];
+    }
+
+}

+ 35 - 0
artisan

@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+<?php
+
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Output\ConsoleOutput;
+
+/*
+|--------------------------------------------------------------------------
+| Create The Application
+|--------------------------------------------------------------------------
+|
+| First we need to get an application instance. This creates an instance
+| of the application / container and bootstraps the application so it
+| is ready to receive HTTP / Console requests from the environment.
+|
+*/
+
+$app = require __DIR__.'/bootstrap/app.php';
+
+/*
+|--------------------------------------------------------------------------
+| Run The Artisan Application
+|--------------------------------------------------------------------------
+|
+| When we run the console application, the current CLI command will be
+| executed in this console and the response sent back to a terminal
+| or another output device for the developers. Here goes nothing!
+|
+*/
+
+$kernel = $app->make(
+    'Illuminate\Contracts\Console\Kernel'
+);
+
+exit($kernel->handle(new ArgvInput, new ConsoleOutput));

+ 118 - 0
bootstrap/app.php

@@ -0,0 +1,118 @@
+<?php
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
+    dirname(__DIR__)
+))->bootstrap();
+
+/*
+|--------------------------------------------------------------------------
+| Create The Application
+|--------------------------------------------------------------------------
+|
+| Here we will load the environment and create the application instance
+| that serves as the central piece of this framework. We'll use this
+| application as an "IoC" container and router for this framework.
+|
+*/
+
+$app = new Laravel\Lumen\Application(
+    dirname(__DIR__)
+);
+
+$app->withFacades();
+
+$app->withEloquent();
+$app->configure('api');
+$app->configure('apollo');
+$app->configure('auth');
+$app->configure('jwt');
+$app->configure('customer');
+$app->configure('database');
+$app->configure('constants');
+$app->configure('aliyunvod');
+
+/*
+|--------------------------------------------------------------------------
+| Register Container Bindings
+|--------------------------------------------------------------------------
+|
+| Now we will register a few bindings in the service container. We will
+| register the exception handler and the console kernel. You may add
+| your own bindings here if you like or you can make another file.
+|
+*/
+
+$app->singleton(
+    Illuminate\Contracts\Debug\ExceptionHandler::class,
+    App\Exceptions\Handler::class
+);
+
+$app->singleton(
+    Illuminate\Contracts\Console\Kernel::class,
+    App\Console\Kernel::class
+);
+
+/*
+|--------------------------------------------------------------------------
+| Register Middleware
+|--------------------------------------------------------------------------
+|
+| Next, we will register the middleware with the application. These can
+| be global middleware that run before and after each request into a
+| route or middleware that'll be assigned to some specific routes.
+|
+*/
+
+// $app->middleware([
+//     App\Http\Middleware\ExampleMiddleware::class
+// ]);
+
+$app->middleware([
+    App\Http\Middleware\SqlMiddleware::class
+]);
+
+$app->routeMiddleware([
+    'auth' => App\Http\Middleware\Authenticate::class,
+    'jwt.chxq_auth' => App\Http\Middleware\JwtAuthMiddleware::class,
+]);
+
+/*
+|--------------------------------------------------------------------------
+| Register Service Providers
+|--------------------------------------------------------------------------
+|
+| Here we will register all of the application's service providers which
+| are used to bind services into the container. Service providers are
+| totally optional, so you are not required to uncomment this line.
+|
+*/
+
+$app->register(App\Providers\AppServiceProvider::class);
+$app->register(App\Providers\AuthServiceProvider::class);
+
+$app->register(Dingo\Api\Provider\LumenServiceProvider::class);
+$app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);
+$app->register(\Illuminate\Redis\RedisServiceProvider::class);
+$app->register(\Junliuxian\AliOSS\AliOssServiceProvider::class);
+$app->register(\ZanySoft\Zip\ZipServiceProvider::class);
+/*
+|--------------------------------------------------------------------------
+| Load The Application Routes
+|--------------------------------------------------------------------------
+|
+| Next we will include the routes file so that they can all be added to
+| the application. This will provide all of the URLs the application
+| can respond to, as well as the controllers that may handle them.
+|
+*/
+
+$app->router->group([
+    'namespace' => 'App\Http\Controllers',
+], function ($router) {
+    require __DIR__.'/../routes/api.php';
+    require __DIR__.'/../routes/web.php';
+});
+
+return $app;

+ 57 - 0
composer.json

@@ -0,0 +1,57 @@
+{
+    "name": "laravel/lumen",
+    "description": "The Laravel Lumen Framework.",
+    "keywords": ["framework", "laravel", "lumen"],
+    "license": "MIT",
+    "type": "project",
+    "require": {
+        "php": ">=7.1.3",
+        "dingo/api": "^2.2",
+        "doctrine/dbal": "^2.9",
+        "guzzlehttp/guzzle": "^6.3",
+        "illuminate/redis": "^5.8",
+        "junliuxian/ali-oss-storage": "~2.0",
+        "laravel/lumen-framework": "5.8.*",
+        "league/csv": "^9.1",
+        "linland/php-eos-rpc-sdk": "dev-master",
+        "multilinguals/apollo-client": "^0.1.2",
+        "predis/predis": "^1.1",
+        "tymon/jwt-auth": "1.0.0-rc.4.1",
+        "vlucas/phpdotenv": "^3.3",
+        "zanysoft/laravel-zip": "^1.0"
+    },
+    "require-dev": {
+        "fzaninotto/faker": "^1.4",
+        "mockery/mockery": "^1.0",
+        "phpunit/phpunit": "^7.0"
+    },
+    "autoload": {
+        "classmap": [
+            "database/seeds",
+            "database/factories"
+        ],
+        "psr-4": {
+            "App\\": "app/"
+        },
+        "files": [
+            "app/Helper/helper.php"
+        ]
+    },
+    "autoload-dev": {
+        "classmap": [
+            "tests/"
+        ]
+    },
+    "scripts": {
+        "post-root-package-install": [
+            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
+        ]
+    },
+    "config": {
+        "preferred-install": "dist",
+        "sort-packages": true,
+        "optimize-autoloader": true
+    },
+    "minimum-stability": "dev",
+    "prefer-stable": true
+}

+ 232 - 0
config/api.php

@@ -0,0 +1,232 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Standards Tree
+    |--------------------------------------------------------------------------
+    |
+    | Versioning an API with Dingo revolves around content negotiation and
+    | custom MIME types. A custom type will belong to one of three
+    | standards trees, the Vendor tree (vnd), the Personal tree
+    | (prs), and the Unregistered tree (x).
+    |
+    | By default the Unregistered tree (x) is used, however, should you wish
+    | to you can register your type with the IANA. For more details:
+    | https://tools.ietf.org/html/rfc6838
+    |
+    */
+
+    'standardsTree' => env('API_STANDARDS_TREE', 'x'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | API Subtype
+    |--------------------------------------------------------------------------
+    |
+    | Your subtype will follow the standards tree you use when used in the
+    | "Accept" header to negotiate the content type and version.
+    |
+    | For example: Accept: application/x.SUBTYPE.v1+json
+    |
+    */
+
+    'subtype' => env('API_SUBTYPE', ''),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Default API Version
+    |--------------------------------------------------------------------------
+    |
+    | This is the default version when strict mode is disabled and your API
+    | is accessed via a web browser. It's also used as the default version
+    | when generating your APIs documentation.
+    |
+    */
+
+    'version' => env('API_VERSION', 'v1'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Default API Prefix
+    |--------------------------------------------------------------------------
+    |
+    | A default prefix to use for your API routes so you don't have to
+    | specify it for each group.
+    |
+    */
+
+    'prefix' => env('API_PREFIX', '/'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Default API Domain
+    |--------------------------------------------------------------------------
+    |
+    | A default domain to use for your API routes so you don't have to
+    | specify it for each group.
+    |
+    */
+
+    'domain' => env('API_DOMAIN', null),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Name
+    |--------------------------------------------------------------------------
+    |
+    | When documenting your API using the API Blueprint syntax you can
+    | configure a default name to avoid having to manually specify
+    | one when using the command.
+    |
+    */
+
+    'name' => env('API_NAME', null),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Conditional Requests
+    |--------------------------------------------------------------------------
+    |
+    | Globally enable conditional requests so that an ETag header is added to
+    | any successful response. Subsequent requests will perform a check and
+    | will return a 304 Not Modified. This can also be enabled or disabled
+    | on certain groups or routes.
+    |
+    */
+
+    'conditionalRequest' => env('API_CONDITIONAL_REQUEST', true),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Strict Mode
+    |--------------------------------------------------------------------------
+    |
+    | Enabling strict mode will require clients to send a valid Accept header
+    | with every request. This also voids the default API version, meaning
+    | your API will not be browsable via a web browser.
+    |
+    */
+
+    'strict' => env('API_STRICT', false),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Debug Mode
+    |--------------------------------------------------------------------------
+    |
+    | Enabling debug mode will result in error responses caused by thrown
+    | exceptions to have a "debug" key that will be populated with
+    | more detailed information on the exception.
+    |
+    */
+
+    'debug' => env('API_DEBUG', true),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Generic Error Format
+    |--------------------------------------------------------------------------
+    |
+    | When some HTTP exceptions are not caught and dealt with the API will
+    | generate a generic error response in the format provided. Any
+    | keys that aren't replaced with corresponding values will be
+    | removed from the final response.
+    |
+    */
+
+    'errorFormat' => [
+        'message' => ':message',
+        'errors' => ':errors',
+        'code' => ':code',
+        'status_code' => ':status_code',
+        'debug' => ':debug',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | API Middleware
+    |--------------------------------------------------------------------------
+    |
+    | Middleware that will be applied globally to all API requests.
+    |
+    */
+
+    'middleware' => [
+
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Providers
+    |--------------------------------------------------------------------------
+    |
+    | The authentication providers that should be used when attempting to
+    | authenticate an incoming API request.
+    |
+    */
+
+    'auth' => [
+        'jwt' => 'Dingo\Api\Auth\Provider\JWT',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Throttling / Rate Limiting
+    |--------------------------------------------------------------------------
+    |
+    | Consumers of your API can be limited to the amount of requests they can
+    | make. You can create your own throttles or simply change the default
+    | throttles.
+    |
+    */
+
+    'throttling' => [
+
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Response Transformer
+    |--------------------------------------------------------------------------
+    |
+    | Responses can be transformed so that they are easier to format. By
+    | default a Fractal transformer will be used to transform any
+    | responses prior to formatting. You can easily replace
+    | this with your own transformer.
+    |
+    */
+
+    'transformer' => env('API_TRANSFORMER', Dingo\Api\Transformer\Adapter\Fractal::class),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Response Formats
+    |--------------------------------------------------------------------------
+    |
+    | Responses can be returned in multiple formats by registering different
+    | response formatters. You can also customize an existing response
+    | formatter with a number of options to configure its output.
+    |
+    */
+
+    'defaultFormat' => env('API_DEFAULT_FORMAT', 'json'),
+
+    'formats' => [
+
+        'json' => Dingo\Api\Http\Response\Format\Json::class,
+
+    ],
+
+    'formatsOptions' => [
+
+        'json' => [
+            'pretty_print' => env('API_JSON_FORMAT_PRETTY_PRINT_ENABLED', false),
+            'indent_style' => env('API_JSON_FORMAT_INDENT_STYLE', 'space'),
+            'indent_size' => env('API_JSON_FORMAT_INDENT_SIZE', 2),
+        ],
+
+    ],
+
+];

+ 10 - 0
config/apollo.php

@@ -0,0 +1,10 @@
+<?php
+
+return [
+    'namespaces' => explode(',', env('APOLLO_NAMESPACES')),
+    'cluster' => env('APOLLO_CLUSTER'),
+    'save_dir' => storage_path('apollo'),
+    'config_server' => env('APOLLO_CONFIG_SERVER'),
+    'app_id' => env('APP_ID'),
+    'timeout_interval' => 70
+];

+ 90 - 0
config/auth.php

@@ -0,0 +1,90 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Defaults
+    |--------------------------------------------------------------------------
+    |
+    | This option controls the default authentication "guard" and password
+    | reset options for your application. You may change these defaults
+    | as required, but they're a perfect start for most applications.
+    |
+    */
+
+    'defaults' => [
+        'guard' => env('AUTH_GUARD', 'api'),
+        'passwords'=>'users',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Guards
+    |--------------------------------------------------------------------------
+    |
+    | Next, you may define every authentication guard for your application.
+    | Of course, a great default configuration has been defined for you
+    | here which uses session storage and the Eloquent user provider.
+    |
+    | All authentication drivers have a user provider. This defines how the
+    | users are actually retrieved out of your database or other storage
+    | mechanisms used by this application to persist your user's data.
+    |
+    | Supported: "token"
+    |
+    */
+
+    'guards' => [
+        'api' => ['driver' => 'jwt','provider' => 'users',],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | User Providers
+    |--------------------------------------------------------------------------
+    |
+    | All authentication drivers have a user provider. This defines how the
+    | users are actually retrieved out of your database or other storage
+    | mechanisms used by this application to persist your user's data.
+    |
+    | If you have multiple user tables or models you may configure multiple
+    | sources which represent each model / table. These sources may then
+    | be assigned to any extra authentication guards you have defined.
+    |
+    | Supported: "database", "eloquent"
+    |
+    */
+
+    'providers' => [
+        //
+        'users' => [
+            'driver' => 'eloquent',
+            'model' => App\User::class,
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Resetting Passwords
+    |--------------------------------------------------------------------------
+    |
+    | Here you may set the options for resetting passwords including the view
+    | that is your password reset e-mail. You may also set the name of the
+    | table that maintains all of the reset tokens for your application.
+    |
+    | You may specify multiple password reset configurations if you have more
+    | than one user table or model in the application and you want to have
+    | separate password reset settings based on the specific user types.
+    |
+    | The expire time is the number of minutes that the reset token should be
+    | considered valid. This security feature keeps tokens short-lived so
+    | they have less time to be guessed. You may change this as needed.
+    |
+    */
+
+    'passwords' => [
+        //
+    ],
+
+];

+ 10 - 0
config/customer.tpl

@@ -0,0 +1,10 @@
+<?php
+//此文件为apollo配置文件模板,禁止修改移动
+return [
+    'jwt_secret' => '{jwt_secret}',
+    'manage_service_url' => '{manage_service_url}',
+    'VIRUS_URL' => '{VIRUS_URL}',
+    'VIRUS_APP_ID' => '{VIRUS_APP_ID}',
+    'VIRUS_APP_SECRET' => '{VIRUS_APP_SECRET}',
+    'chxq_oss_url' => '{chxq_oss_url}',
+];

+ 131 - 0
config/database.php

@@ -0,0 +1,131 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Default Database Connection Name
+    |--------------------------------------------------------------------------
+    |
+    | Here you may specify which of the database connections below you wish
+    | to use as your default connection for all database work. Of course
+    | you may use many connections at once using the Database library.
+    |
+    */
+
+    'default' => env('DB_CONNECTION', 'mysql'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Database Connections
+    |--------------------------------------------------------------------------
+    |
+    | Here are each of the database connections setup for your application.
+    | Of course, examples of configuring each database platform that is
+    | supported by Laravel is shown below to make development simple.
+    |
+    |
+    | All database work in Laravel is done through the PHP PDO facilities
+    | so make sure you have the driver for your particular database of
+    | choice installed on your machine before you begin development.
+    |
+    */
+
+    'connections' => [
+
+        'sqlite' => [
+            'driver' => 'sqlite',
+            'database' => env('DB_DATABASE', database_path('database.sqlite')),
+            'prefix' => env('DB_PREFIX', ''),
+        ],
+
+        'mysql' => [
+            'driver' => 'mysql',
+            'host' => env('DB_HOST', '127.0.0.1'),
+            'port' => env('DB_PORT', 3306),
+            'database' => env('DB_DATABASE', 'forge'),
+            'username' => env('DB_USERNAME', 'forge'),
+            'password' => env('DB_PASSWORD', ''),
+            'unix_socket' => env('DB_SOCKET', ''),
+            'charset' => env('DB_CHARSET', 'utf8mb4'),
+            'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
+            'prefix' => env('DB_PREFIX', ''),
+            'strict' => env('DB_STRICT_MODE', true),
+            'engine' => env('DB_ENGINE', null),
+            'timezone' => env('DB_TIMEZONE', '+08:00'),
+        ],
+
+        'pgsql' => [
+            'driver' => 'pgsql',
+            'host' => env('DB_HOST', '127.0.0.1'),
+            'port' => env('DB_PORT', 5432),
+            'database' => env('DB_DATABASE', 'forge'),
+            'username' => env('DB_USERNAME', 'forge'),
+            'password' => env('DB_PASSWORD', ''),
+            'charset' => env('DB_CHARSET', 'utf8'),
+            'prefix' => env('DB_PREFIX', ''),
+            'schema' => env('DB_SCHEMA', 'public'),
+            'sslmode' => env('DB_SSL_MODE', 'prefer'),
+        ],
+
+        'sqlsrv' => [
+            'driver' => 'sqlsrv',
+            'host' => env('DB_HOST', 'localhost'),
+            'port' => env('DB_PORT', 1433),
+            'database' => env('DB_DATABASE', 'forge'),
+            'username' => env('DB_USERNAME', 'forge'),
+            'password' => env('DB_PASSWORD', ''),
+            'charset' => env('DB_CHARSET', 'utf8'),
+            'prefix' => env('DB_PREFIX', ''),
+        ],
+
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Migration Repository Table
+    |--------------------------------------------------------------------------
+    |
+    | This table keeps track of all the migrations that have already run for
+    | your application. Using this information, we can determine which of
+    | the migrations on disk haven't actually been run in the database.
+    |
+    */
+
+    'migrations' => 'migrations',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Redis Databases
+    |--------------------------------------------------------------------------
+    |
+    | Redis is an open source, fast, and advanced key-value store that also
+    | provides a richer set of commands than a typical key-value systems
+    | such as APC or Memcached. Laravel makes it easy to dig right in.
+    |
+    */
+
+    'redis' => [
+
+        'client' => 'predis',
+
+        'cluster' => env('REDIS_CLUSTER', false),
+
+        'default' => [
+            'host' => env('REDIS_HOST', '127.0.0.1'),
+            'password' => env('REDIS_PASSWORD', null),
+            'port' => env('REDIS_PORT', 6379),
+            'database' => env('REDIS_DB', 0),
+            'read_write_timeout' => 0,
+        ],
+
+        'cache' => [
+            'host' => env('REDIS_HOST', '127.0.0.1'),
+            'password' => env('REDIS_PASSWORD', null),
+            'port' => env('REDIS_PORT', 6379),
+            'database' => env('REDIS_CACHE_DB', 1),
+        ],
+
+    ],
+
+];

+ 82 - 0
config/filesystems.php

@@ -0,0 +1,82 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Default Filesystem Disk
+    |--------------------------------------------------------------------------
+    |
+    | Here you may specify the default filesystem disk that should be used
+    | by the framework. The "local" disk, as well as a variety of cloud
+    | based disks are available to your application. Just store away!
+    |
+    */
+
+    'default' => env('FILESYSTEM_DRIVER', 'oss'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Default Cloud Filesystem Disk
+    |--------------------------------------------------------------------------
+    |
+    | Many applications store files both locally and in the cloud. For this
+    | reason, you may specify a default "cloud" driver here. This driver
+    | will be bound as the Cloud disk implementation in the container.
+    |
+    */
+
+    'cloud' => env('FILESYSTEM_CLOUD', 's3'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Filesystem Disks
+    |--------------------------------------------------------------------------
+    |
+    | Here you may configure as many filesystem "disks" as you wish, and you
+    | may even configure multiple disks of the same driver. Defaults have
+    | been setup for each driver as an example of the required options.
+    |
+    | Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
+    |
+    */
+
+    'disks' => [
+
+        'local' => [
+            'driver' => 'local',
+            'root' => storage_path('app'),
+        ],
+
+        'public' => [
+            'driver' => 'local',
+            'root' => storage_path('app/public'),
+            'url' => env('APP_URL') . '/storage',
+            'visibility' => 'public',
+        ],
+
+        's3' => [
+            'driver' => 's3',
+            'key' => env('AWS_ACCESS_KEY_ID'),
+            'secret' => env('AWS_SECRET_ACCESS_KEY'),
+            'region' => env('AWS_DEFAULT_REGION'),
+            'bucket' => env('AWS_BUCKET'),
+            'url' => env('AWS_URL'),
+        ],
+
+        'oss' => [
+            'driver' => 'oss',
+            'access_id' => 'LTAIGTDKUOVQf2Ln',
+            'access_key' => 'HzY9r2gDPbURQ0Vp69A7THV0RmxMkb',
+            'bucket' => 'rainbowstar',
+            'endpoint' => 'oss-cn-zhangjiakou.aliyuncs.com', // OSS 外网节点或自定义外部域名
+//            'endpoint_internal' => '<internal endpoint [OSS内网节点] 如:oss-cn-shenzhen-internal.aliyuncs.com>', // v2.0.4 新增配置属性,如果为空,则默认使用 endpoint 配置(由于内网上传有点小问题未解决,请大家暂时不要使用内网节点上传,正在与阿里技术沟通中)
+            'cdnDomain' => '', // 如果isCName为true, getUrl会判断cdnDomain是否设定来决定返回的url,如果cdnDomain未设置,则使用endpoint来生成url,否则使用cdn
+            'ssl' => false, // true to use 'https://' and false to use 'http://'. default is false,
+            'isCName' => false, // 是否使用自定义域名,true: 则Storage.url()会使用自定义的cdn或域名生成文件url, false: 则使用外部节点生成url
+            'debug' => true,
+        ],
+
+    ],
+
+];

+ 304 - 0
config/jwt.php

@@ -0,0 +1,304 @@
+<?php
+
+/*
+ * This file is part of jwt-auth.
+ *
+ * (c) Sean Tymon <tymon148@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | JWT Authentication Secret
+    |--------------------------------------------------------------------------
+    |
+    | Don't forget to set this in your .env file, as it will be used to sign
+    | your tokens. A helper command is provided for this:
+    | `php artisan jwt:secret`
+    |
+    | Note: This will be used for Symmetric algorithms only (HMAC),
+    | since RSA and ECDSA use a private/public key combo (See below).
+    |
+    */
+
+    'secret' => env('JWT_SECRET',config('customer.jwt_secret')),
+
+    /*
+    |--------------------------------------------------------------------------
+    | JWT Authentication Keys
+    |--------------------------------------------------------------------------
+    |
+    | The algorithm you are using, will determine whether your tokens are
+    | signed with a random string (defined in `JWT_SECRET`) or using the
+    | following public & private keys.
+    |
+    | Symmetric Algorithms:
+    | HS256, HS384 & HS512 will use `JWT_SECRET`.
+    |
+    | Asymmetric Algorithms:
+    | RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below.
+    |
+    */
+
+    'keys' => [
+
+        /*
+        |--------------------------------------------------------------------------
+        | Public Key
+        |--------------------------------------------------------------------------
+        |
+        | A path or resource to your public key.
+        |
+        | E.g. 'file://path/to/public/key'
+        |
+        */
+
+        'public' => env('JWT_PUBLIC_KEY'),
+
+        /*
+        |--------------------------------------------------------------------------
+        | Private Key
+        |--------------------------------------------------------------------------
+        |
+        | A path or resource to your private key.
+        |
+        | E.g. 'file://path/to/private/key'
+        |
+        */
+
+        'private' => env('JWT_PRIVATE_KEY'),
+
+        /*
+        |--------------------------------------------------------------------------
+        | Passphrase
+        |--------------------------------------------------------------------------
+        |
+        | The passphrase for your private key. Can be null if none set.
+        |
+        */
+
+        'passphrase' => env('JWT_PASSPHRASE'),
+
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | JWT time to live
+    |--------------------------------------------------------------------------
+    |
+    | Specify the length of time (in minutes) that the token will be valid for.
+    | Defaults to 1 hour.
+    |
+    | You can also set this to null, to yield a never expiring token.
+    | Some people may want this behaviour for e.g. a mobile app.
+    | This is not particularly recommended, so make sure you have appropriate
+    | systems in place to revoke the token if necessary.
+    | Notice: If you set this to null you should remove 'exp' element from 'required_claims' list.
+    |
+    */
+
+    'ttl' => env('JWT_TTL', 60),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Refresh time to live
+    |--------------------------------------------------------------------------
+    |
+    | Specify the length of time (in minutes) that the token can be refreshed
+    | within. I.E. The user can refresh their token within a 2 week window of
+    | the original token being created until they must re-authenticate.
+    | Defaults to 2 weeks.
+    |
+    | You can also set this to null, to yield an infinite refresh time.
+    | Some may want this instead of never expiring tokens for e.g. a mobile app.
+    | This is not particularly recommended, so make sure you have appropriate
+    | systems in place to revoke the token if necessary.
+    |
+    */
+
+    'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
+
+    /*
+    |--------------------------------------------------------------------------
+    | JWT hashing algorithm
+    |--------------------------------------------------------------------------
+    |
+    | Specify the hashing algorithm that will be used to sign the token.
+    |
+    | See here: https://github.com/namshi/jose/tree/master/src/Namshi/JOSE/Signer/OpenSSL
+    | for possible values.
+    |
+    */
+
+    'algo' => env('JWT_ALGO', 'HS256'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Required Claims
+    |--------------------------------------------------------------------------
+    |
+    | Specify the required claims that must exist in any token.
+    | A TokenInvalidException will be thrown if any of these claims are not
+    | present in the payload.
+    |
+    */
+
+    'required_claims' => [
+        'iss',
+        'iat',
+        'exp',
+        'nbf',
+        'sub',
+        'jti',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Persistent Claims
+    |--------------------------------------------------------------------------
+    |
+    | Specify the claim keys to be persisted when refreshing a token.
+    | `sub` and `iat` will automatically be persisted, in
+    | addition to the these claims.
+    |
+    | Note: If a claim does not exist then it will be ignored.
+    |
+    */
+
+    'persistent_claims' => [
+        // 'foo',
+        // 'bar',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Lock Subject
+    |--------------------------------------------------------------------------
+    |
+    | This will determine whether a `prv` claim is automatically added to
+    | the token. The purpose of this is to ensure that if you have multiple
+    | authentication models e.g. `App\User` & `App\OtherPerson`, then we
+    | should prevent one authentication request from impersonating another,
+    | if 2 tokens happen to have the same id across the 2 different models.
+    |
+    | Under specific circumstances, you may want to disable this behaviour
+    | e.g. if you only have one authentication model, then you would save
+    | a little on token size.
+    |
+    */
+
+    'lock_subject' => true,
+
+    /*
+    |--------------------------------------------------------------------------
+    | Leeway
+    |--------------------------------------------------------------------------
+    |
+    | This property gives the jwt timestamp claims some "leeway".
+    | Meaning that if you have any unavoidable slight clock skew on
+    | any of your servers then this will afford you some level of cushioning.
+    |
+    | This applies to the claims `iat`, `nbf` and `exp`.
+    |
+    | Specify in seconds - only if you know you need it.
+    |
+    */
+
+    'leeway' => env('JWT_LEEWAY', 0),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Blacklist Enabled
+    |--------------------------------------------------------------------------
+    |
+    | In order to invalidate tokens, you must have the blacklist enabled.
+    | If you do not want or need this functionality, then set this to false.
+    |
+    */
+
+    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
+
+    /*
+    | -------------------------------------------------------------------------
+    | Blacklist Grace Period
+    | -------------------------------------------------------------------------
+    |
+    | When multiple concurrent requests are made with the same JWT,
+    | it is possible that some of them fail, due to token regeneration
+    | on every request.
+    |
+    | Set grace period in seconds to prevent parallel request failure.
+    |
+    */
+
+    'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Cookies encryption
+    |--------------------------------------------------------------------------
+    |
+    | By default Laravel encrypt cookies for security reason.
+    | If you decide to not decrypt cookies, you will have to configure Laravel
+    | to not encrypt your cookie token by adding its name into the $except
+    | array available in the middleware "EncryptCookies" provided by Laravel.
+    | see https://laravel.com/docs/master/responses#cookies-and-encryption
+    | for details.
+    |
+    | Set it to true if you want to decrypt cookies.
+    |
+    */
+
+    'decrypt_cookies' => false,
+
+    /*
+    |--------------------------------------------------------------------------
+    | Providers
+    |--------------------------------------------------------------------------
+    |
+    | Specify the various providers used throughout the package.
+    |
+    */
+
+    'providers' => [
+
+        /*
+        |--------------------------------------------------------------------------
+        | JWT Provider
+        |--------------------------------------------------------------------------
+        |
+        | Specify the provider that is used to create and decode the tokens.
+        |
+        */
+
+        'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,
+
+        /*
+        |--------------------------------------------------------------------------
+        | Authentication Provider
+        |--------------------------------------------------------------------------
+        |
+        | Specify the provider that is used to authenticate users.
+        |
+        */
+
+        'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
+
+        /*
+        |--------------------------------------------------------------------------
+        | Storage Provider
+        |--------------------------------------------------------------------------
+        |
+        | Specify the provider that is used to store tokens in the blacklist.
+        |
+        */
+
+        'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
+
+    ],
+
+];

+ 19 - 0
database/factories/ModelFactory.php

@@ -0,0 +1,19 @@
+<?php
+
+/*
+|--------------------------------------------------------------------------
+| Model Factories
+|--------------------------------------------------------------------------
+|
+| Here you may define all of your model factories. Model factories give
+| you a convenient way to create models for testing and seeding your
+| database. Just tell the factory how a default model should look.
+|
+*/
+
+$factory->define(App\User::class, function (Faker\Generator $faker) {
+    return [
+        'name' => $faker->name,
+        'email' => $faker->email,
+    ];
+});

+ 0 - 0
database/migrations/.gitkeep


+ 34 - 0
database/migrations/2019_04_09_065115_create_user_table.php

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateUserTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('user', function (Blueprint $table) {
+            $table->bigIncrements('id');
+            $table->string('username',32)->comment('用户名');
+            $table->string('password')->nullable()->default('')->comment('密码');
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('user');
+    }
+}

+ 49 - 0
database/migrations/2019_11_26_092044_create_meta_table.php

@@ -0,0 +1,49 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateMetaTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('meta', function (Blueprint $table) {
+            $table->bigIncrements('id');
+            $table->string('patch_num')->default('')->comment('批次号');
+            $table->string('variety')->default('')->comment('鸡种');
+            $table->string('variety_img')->default('')->comment('鸡种图片');
+            $table->string('age')->default('')->comment('鸡龄');
+            $table->string('food')->default('')->comment('口粮');
+            $table->string('food_img')->default('')->comment('口粮图片');
+            $table->string('water')->default('')->comment('水源');
+            $table->string('water_img')->default('')->comment('水源图片');
+            $table->string('logistical')->default('')->comment('物流追踪');
+            $table->text('farm')->comment('农场');
+            $table->text('report')->comment('检测报告');
+            $table->string('zip')->default('')->comment('zip包地址');
+
+            $table->string('trans_id')->default('')->comment('交易ID');
+            $table->string('block_height')->default(0)->comment('区块高度');
+            $table->string('block_time')->default('')->comment('上链时间');
+            $table->string('md5')->default('')->comment('meta信息md5码');
+            $table->tinyInteger('status')->default(0)->comment('上链状态 0准备上链 1上链成功 2上链失败');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('meta');
+    }
+}

+ 16 - 0
database/seeds/DatabaseSeeder.php

@@ -0,0 +1,16 @@
+<?php
+
+use Illuminate\Database\Seeder;
+
+class DatabaseSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        // $this->call('UsersTableSeeder');
+    }
+}

+ 20 - 0
deploy/nginx/conf.d/app.beta.conf

@@ -0,0 +1,20 @@
+server {
+    listen 80;
+    index index.php index.html;
+    error_log  /var/log/nginx/error.log;
+    access_log /var/log/nginx/access.log;
+    root /var/www/public;
+    location ~ \.php$ {
+        try_files $uri =404;
+        fastcgi_split_path_info ^(.+\.php)(/.+)$;
+        fastcgi_pass app_trace_manage_beta:9000;
+        fastcgi_index index.php;
+        include fastcgi_params;
+        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+        fastcgi_param PATH_INFO $fastcgi_path_info;
+    }
+    location / {
+        try_files $uri $uri/ /index.php?$query_string;
+        gzip_static on;
+    }
+}

+ 20 - 0
deploy/nginx/conf.d/app.dev.conf

@@ -0,0 +1,20 @@
+server {
+    listen 80;
+    index index.php index.html;
+    error_log  /var/log/nginx/error.log;
+    access_log /var/log/nginx/access.log;
+    root /var/www/public;
+    location ~ \.php$ {
+        try_files $uri =404;
+        fastcgi_split_path_info ^(.+\.php)(/.+)$;
+        fastcgi_pass app_trace_manage_dev:9000;
+        fastcgi_index index.php;
+        include fastcgi_params;
+        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+        fastcgi_param PATH_INFO $fastcgi_path_info;
+    }
+    location / {
+        try_files $uri $uri/ /index.php?$query_string;
+        gzip_static on;
+    }
+}

+ 2 - 0
deploy/php/local.ini

@@ -0,0 +1,2 @@
+upload_max_filesize=40M
+post_max_size=40M

+ 32 - 0
docker-compose-beta.yml

@@ -0,0 +1,32 @@
+version: '3'
+
+services:
+  app_trace_manage_beta:
+    image: harbor.caihongxingqiu.com:9401/library/php:latest
+    tty: true
+    working_dir: /var/www
+    volumes:
+      - ./:/var/www
+      - ./deploy/php/local.ini:/usr/local/etc/php/conf.d/local.ini
+      - /data/wwwroot/beta/community-manage:/data/wwwroot/beta/community-manage
+    networks:
+      - chxq
+
+  server_trace_manage_beta:
+    image: harbor.caihongxingqiu.com:9401/library/nginx:latest
+    tty: true
+    depends_on:
+      - app_trace_manage_beta
+    ports:
+      - "28219:80"
+    volumes:
+      - ./:/var/www
+      - ./deploy/nginx/conf.d/app.beta.conf:/etc/nginx/conf.d/app.beta.conf
+    networks:
+      - chxq
+
+#docker networks
+#docker network create --driver overlay chxq
+networks:
+  chxq:
+    external: true

+ 31 - 0
docker-compose-dev.yml

@@ -0,0 +1,31 @@
+version: '3'
+
+services:
+  app_trace_manage_dev:
+    image: harbor.caihongxingqiu.com:9401/library/php:latest
+    tty: true
+    working_dir: /var/www
+    volumes:
+      - ./:/var/www
+      - ./deploy/php/local.ini:/usr/local/etc/php/conf.d/local.ini
+    networks:
+      - chxq
+
+  server_trace_manage_dev:
+    image: harbor.caihongxingqiu.com:9401/library/nginx:latest
+    tty: true
+    depends_on:
+      - app_trace_manage_dev
+    ports:
+      - "18219:80"
+    volumes:
+      - ./:/var/www
+      - ./deploy/nginx/conf.d/app.dev.conf:/etc/nginx/conf.d/app.dev.conf
+    networks:
+      - chxq
+
+#docker networks
+#docker network create --driver overlay chxq
+networks:
+  chxq:
+    external: true

+ 26 - 0
phpunit.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         bootstrap="bootstrap/app.php"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false">
+    <testsuites>
+        <testsuite name="Application Test Suite">
+            <directory suffix="Test.php">./tests</directory>
+        </testsuite>
+    </testsuites>
+    <filter>
+        <whitelist processUncoveredFilesFromWhitelist="true">
+            <directory suffix=".php">./app</directory>
+        </whitelist>
+    </filter>
+    <php>
+        <env name="APP_ENV" value="testing"/>
+        <env name="CACHE_DRIVER" value="array"/>
+        <env name="QUEUE_CONNECTION" value="sync"/>
+    </php>
+</phpunit>

+ 21 - 0
public/.htaccess

@@ -0,0 +1,21 @@
+<IfModule mod_rewrite.c>
+    <IfModule mod_negotiation.c>
+        Options -MultiViews -Indexes
+    </IfModule>
+
+    RewriteEngine On
+
+    # Handle Authorization Header
+    RewriteCond %{HTTP:Authorization} .
+    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+
+    # Redirect Trailing Slashes If Not A Folder...
+    RewriteCond %{REQUEST_FILENAME} !-d
+    RewriteCond %{REQUEST_URI} (.+)/$
+    RewriteRule ^ %1 [L,R=301]
+
+    # Handle Front Controller...
+    RewriteCond %{REQUEST_FILENAME} !-d
+    RewriteCond %{REQUEST_FILENAME} !-f
+    RewriteRule ^ index.php [L]
+</IfModule>

+ 29 - 0
public/index.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+|--------------------------------------------------------------------------
+| Create The Application
+|--------------------------------------------------------------------------
+|
+| First we need to get an application instance. This creates an instance
+| of the application / container and bootstraps the application so it
+| is ready to receive HTTP / Console requests from the environment.
+|
+*/
+
+ini_set('molten.service_name', 'community-manage');
+$app = require __DIR__.'/../bootstrap/app.php';
+
+/*
+|--------------------------------------------------------------------------
+| Run The Application
+|--------------------------------------------------------------------------
+|
+| Once we have the application, we can handle the incoming request
+| through the kernel, and send the associated response back to
+| the client's browser allowing them to enjoy the creative
+| and wonderful application we have prepared for them.
+|
+*/
+
+$app->run();

+ 21 - 0
readme.md

@@ -0,0 +1,21 @@
+# Lumen PHP Framework
+
+[![Build Status](https://travis-ci.org/laravel/lumen-framework.svg)](https://travis-ci.org/laravel/lumen-framework)
+[![Total Downloads](https://poser.pugx.org/laravel/lumen-framework/d/total.svg)](https://packagist.org/packages/laravel/lumen-framework)
+[![Latest Stable Version](https://poser.pugx.org/laravel/lumen-framework/v/stable.svg)](https://packagist.org/packages/laravel/lumen-framework)
+[![Latest Unstable Version](https://poser.pugx.org/laravel/lumen-framework/v/unstable.svg)](https://packagist.org/packages/laravel/lumen-framework)
+[![License](https://poser.pugx.org/laravel/lumen-framework/license.svg)](https://packagist.org/packages/laravel/lumen-framework)
+
+Laravel Lumen is a stunningly fast PHP micro-framework for building web applications with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Lumen attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as routing, database abstraction, queueing, and caching.
+
+## Official Documentation
+
+Documentation for the framework can be found on the [Lumen website](https://lumen.laravel.com/docs).
+
+## Security Vulnerabilities
+
+If you discover a security vulnerability within Lumen, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed.
+
+## License
+
+The Lumen framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

+ 19 - 0
resources/lang/en/auth.php

@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used during authentication for various
+    | messages that we need to display to the user. You are free to modify
+    | these language lines according to your application's requirements.
+    |
+    */
+
+    'failed' => 'These credentials do not match our records.',
+    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+
+];

+ 19 - 0
resources/lang/en/pagination.php

@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Pagination Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used by the paginator library to build
+    | the simple pagination links. You are free to change them to anything
+    | you want to customize your views to better match your application.
+    |
+    */
+
+    'previous' => '&laquo; Previous',
+    'next' => 'Next &raquo;',
+
+];

+ 22 - 0
resources/lang/en/passwords.php

@@ -0,0 +1,22 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Password Reset Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are the default lines which match reasons
+    | that are given by the password broker for a password update attempt
+    | has failed, such as for an invalid token or invalid new password.
+    |
+    */
+
+    'password' => 'Passwords must be at least six characters and match the confirmation.',
+    'reset' => 'Your password has been reset!',
+    'sent' => 'We have e-mailed your password reset link!',
+    'token' => 'This password reset token is invalid.',
+    'user' => "We can't find a user with that e-mail address.",
+
+];

+ 146 - 0
resources/lang/en/validation.php

@@ -0,0 +1,146 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines contain the default error messages used by
+    | the validator class. Some of these rules have multiple versions such
+    | as the size rules. Feel free to tweak each of these messages here.
+    |
+    */
+
+    'accepted'             => 'The :attribute must be accepted.',
+    'active_url'           => 'The :attribute is not a valid URL.',
+    'after'                => 'The :attribute must be a date after :date.',
+    'after_or_equal'       => 'The :attribute must be a date after or equal to :date.',
+    'alpha'                => 'The :attribute may only contain letters.',
+    'alpha_dash'           => 'The :attribute may only contain letters, numbers, dashes and underscores.',
+    'alpha_num'            => 'The :attribute may only contain letters and numbers.',
+    'array'                => 'The :attribute must be an array.',
+    'before'               => 'The :attribute must be a date before :date.',
+    'before_or_equal'      => 'The :attribute must be a date before or equal to :date.',
+    'between'              => [
+        'numeric' => 'The :attribute must be between :min and :max.',
+        'file'    => 'The :attribute must be between :min and :max kilobytes.',
+        'string'  => 'The :attribute must be between :min and :max characters.',
+        'array'   => 'The :attribute must have between :min and :max items.',
+    ],
+    'boolean'              => 'The :attribute field must be true or false.',
+    'confirmed'            => 'The :attribute confirmation does not match.',
+    'date'                 => 'The :attribute is not a valid date.',
+    'date_format'          => 'The :attribute does not match the format :format.',
+    'different'            => 'The :attribute and :other must be different.',
+    'digits'               => 'The :attribute must be :digits digits.',
+    'digits_between'       => 'The :attribute must be between :min and :max digits.',
+    'dimensions'           => 'The :attribute has invalid image dimensions.',
+    'distinct'             => 'The :attribute field has a duplicate value.',
+    'email'                => 'The :attribute must be a valid email address.',
+    'exists'               => 'The selected :attribute is invalid.',
+    'file'                 => 'The :attribute must be a file.',
+    'filled'               => 'The :attribute field must have a value.',
+    'gt'                   => [
+        'numeric' => 'The :attribute must be greater than :value.',
+        'file'    => 'The :attribute must be greater than :value kilobytes.',
+        'string'  => 'The :attribute must be greater than :value characters.',
+        'array'   => 'The :attribute must have more than :value items.',
+    ],
+    'gte'                  => [
+        'numeric' => 'The :attribute must be greater than or equal :value.',
+        'file'    => 'The :attribute must be greater than or equal :value kilobytes.',
+        'string'  => 'The :attribute must be greater than or equal :value characters.',
+        'array'   => 'The :attribute must have :value items or more.',
+    ],
+    'image'                => 'The :attribute must be an image.',
+    'in'                   => 'The selected :attribute is invalid.',
+    'in_array'             => 'The :attribute field does not exist in :other.',
+    'integer'              => 'The :attribute must be an integer.',
+    'ip'                   => 'The :attribute must be a valid IP address.',
+    'ipv4'                 => 'The :attribute must be a valid IPv4 address.',
+    'ipv6'                 => 'The :attribute must be a valid IPv6 address.',
+    'json'                 => 'The :attribute must be a valid JSON string.',
+    'lt'                   => [
+        'numeric' => 'The :attribute must be less than :value.',
+        'file'    => 'The :attribute must be less than :value kilobytes.',
+        'string'  => 'The :attribute must be less than :value characters.',
+        'array'   => 'The :attribute must have less than :value items.',
+    ],
+    'lte'                  => [
+        'numeric' => 'The :attribute must be less than or equal :value.',
+        'file'    => 'The :attribute must be less than or equal :value kilobytes.',
+        'string'  => 'The :attribute must be less than or equal :value characters.',
+        'array'   => 'The :attribute must not have more than :value items.',
+    ],
+    'max'                  => [
+        'numeric' => 'The :attribute may not be greater than :max.',
+        'file'    => 'The :attribute may not be greater than :max kilobytes.',
+        'string'  => 'The :attribute may not be greater than :max characters.',
+        'array'   => 'The :attribute may not have more than :max items.',
+    ],
+    'mimes'                => 'The :attribute must be a file of type: :values.',
+    'mimetypes'            => 'The :attribute must be a file of type: :values.',
+    'min'                  => [
+        'numeric' => 'The :attribute must be at least :min.',
+        'file'    => 'The :attribute must be at least :min kilobytes.',
+        'string'  => 'The :attribute must be at least :min characters.',
+        'array'   => 'The :attribute must have at least :min items.',
+    ],
+    'not_in'               => 'The selected :attribute is invalid.',
+    'not_regex'            => 'The :attribute format is invalid.',
+    'numeric'              => 'The :attribute must be a number.',
+    'present'              => 'The :attribute field must be present.',
+    'regex'                => 'The :attribute format is invalid.',
+    'required'             => 'The :attribute field is required.',
+    'required_if'          => 'The :attribute field is required when :other is :value.',
+    'required_unless'      => 'The :attribute field is required unless :other is in :values.',
+    'required_with'        => 'The :attribute field is required when :values is present.',
+    'required_with_all'    => 'The :attribute field is required when :values is present.',
+    'required_without'     => 'The :attribute field is required when :values is not present.',
+    'required_without_all' => 'The :attribute field is required when none of :values are present.',
+    'same'                 => 'The :attribute and :other must match.',
+    'size'                 => [
+        'numeric' => 'The :attribute must be :size.',
+        'file'    => 'The :attribute must be :size kilobytes.',
+        'string'  => 'The :attribute must be :size characters.',
+        'array'   => 'The :attribute must contain :size items.',
+    ],
+    'string'               => 'The :attribute must be a string.',
+    'timezone'             => 'The :attribute must be a valid zone.',
+    'unique'               => 'The :attribute has already been taken.',
+    'uploaded'             => 'The :attribute failed to upload.',
+    'url'                  => 'The :attribute format is invalid.',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | Here you may specify custom validation messages for attributes using the
+    | convention "attribute.rule" to name the lines. This makes it quick to
+    | specify a specific custom language line for a given attribute rule.
+    |
+    */
+
+    'custom' => [
+        'attribute-name' => [
+            'rule-name' => 'custom-message',
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Attributes
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used to swap attribute place-holders
+    | with something more reader friendly such as E-Mail Address instead
+    | of "email". This simply helps us make messages a little cleaner.
+    |
+    */
+
+    'attributes' => [],
+
+];

+ 17 - 0
resources/lang/zh-CN/auth.php

@@ -0,0 +1,17 @@
+<?php
+
+return [
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used during authentication for various
+    | messages that we need to display to the user. You are free to modify
+    | these language lines according to your application's requirements.
+    |
+    */
+
+    'failed' => '用户名或密码错误。',
+    'throttle' => '您的尝试登录次数过多,请 :seconds 秒后再试。',
+];

+ 17 - 0
resources/lang/zh-CN/pagination.php

@@ -0,0 +1,17 @@
+<?php
+
+return [
+    /*
+    |--------------------------------------------------------------------------
+    | Pagination Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used by the paginator library to build
+    | the simple pagination links. You are free to change them to anything
+    | you want to customize your views to better match your application.
+    |
+    */
+
+    'previous' => '&laquo; 上一页',
+    'next' => '下一页 &raquo;',
+];

+ 20 - 0
resources/lang/zh-CN/passwords.php

@@ -0,0 +1,20 @@
+<?php
+
+return [
+    /*
+    |--------------------------------------------------------------------------
+    | Password Reminder Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are the default lines which match reasons
+    | that are given by the password broker for a password update attempt
+    | has failed, such as for an invalid token or invalid new password.
+    |
+    */
+
+    'password' => '密码至少是六位字符并且匹配。',
+    'reset' => '密码重置成功!',
+    'sent' => '密码重置邮件已发送!',
+    'token' => '密码重置令牌无效。',
+    'user' => '找不到该邮箱对应的用户。',
+];

+ 126 - 0
resources/lang/zh-CN/validation.php

@@ -0,0 +1,126 @@
+<?php
+
+return [
+    /*
+    |--------------------------------------------------------------------------
+    | Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines contain the default error messages used by
+    | the validator class. Some of these rules have multiple versions such
+    | as the size rules. Feel free to tweak each of these messages.
+    |
+    */
+
+    'accepted' => ':attribute 必须接受。',
+    'active_url' => ':attribute 不是一个有效的网址。',
+    'after' => ':attribute 必须要晚于 :date。',
+    'after_or_equal' => ':attribute 必须要等于 :date 或更晚。',
+    'alpha' => ':attribute 只能由字母组成。',
+    'alpha_dash' => ':attribute 只能由字母、数字和斜杠组成。',
+    'alpha_num' => ':attribute 只能由字母和数字组成。',
+    'array' => ':attribute 必须是一个数组。',
+    'before' => ':attribute 必须要早于 :date。',
+    'before_or_equal' => ':attribute 必须要等于 :date 或更早。',
+    'between' => [
+        'numeric' => ':attribute 必须介于 :min - :max 之间。',
+        'file' => ':attribute 必须介于 :min - :max kb 之间。',
+        'string' => ':attribute 必须介于 :min - :max 个字符之间。',
+        'array' => ':attribute 必须只有 :min - :max 个单元。',
+    ],
+    'boolean' => ':attribute 必须为布尔值。',
+    'confirmed' => ':attribute 两次输入不一致。',
+    'date' => ':attribute 不是一个有效的日期。',
+    'date_format' => ':attribute 的格式必须为 :format。',
+    'different' => ':attribute 和 :other 必须不同。',
+    'digits' => ':attribute 必须是 :digits 位的数字。',
+    'digits_between' => ':attribute 必须是介于 :min 和 :max 位的数字。',
+    'dimensions' => ':attribute 图片尺寸不正确。',
+    'distinct' => ':attribute 已经存在。',
+    'email' => ':attribute 不是一个合法的邮箱。',
+    'exists' => ':attribute 不存在。',
+    'file' => ':attribute 必须是文件。',
+    'filled' => ':attribute 不能为空。',
+    'image' => ':attribute 必须是图片。',
+    'in' => '已选的属性 :attribute 非法。',
+    'in_array' => ':attribute 没有在 :other 中。',
+    'integer' => ':attribute 必须是整数。',
+    'ip' => ':attribute 必须是有效的 IP 地址。',
+    'ipv4' => ':attribute 必须是有效的 IPv4 地址。',
+    'ipv6' => ':attribute 必须是有效的 IPv6 地址。',
+    'json' => ':attribute 必须是正确的 JSON 格式。',
+    'max' => [
+        'numeric' => ':attribute 不能大于 :max。',
+        'file' => ':attribute 不能大于 :max kb。',
+        'string' => ':attribute 不能大于 :max 个字符。',
+        'array' => ':attribute 最多只有 :max 个单元。',
+    ],
+    'mimes' => ':attribute 必须是一个 :values 类型的文件。',
+    'mimetypes' => ':attribute 必须是一个 :values 类型的文件。',
+    'min' => [
+        'numeric' => ':attribute 必须大于等于 :min。',
+        'file' => ':attribute 大小不能小于 :min kb。',
+        'string' => ':attribute 至少为 :min 个字符。',
+        'array' => ':attribute 至少有 :min 个单元。',
+    ],
+    'not_in' => '已选的属性 :attribute 非法。',
+    'numeric' => ':attribute 必须是一个数字。',
+    'present' => ':attribute 必须存在。',
+    'regex' => ':attribute 格式不正确。',
+    'required' => ':attribute 不能为空。',
+    'required_if' => '当 :other 为 :value 时 :attribute 不能为空。',
+    'required_unless' => '当 :other 不为 :value 时 :attribute 不能为空。',
+    'required_with' => '当 :values 存在时 :attribute 不能为空。',
+    'required_with_all' => '当 :values 存在时 :attribute 不能为空。',
+    'required_without' => '当 :values 不存在时 :attribute 不能为空。',
+    'required_without_all' => '当 :values 都不存在时 :attribute 不能为空。',
+    'same' => ':attribute 和 :other 必须相同。',
+    'size' => [
+        'numeric' => ':attribute 大小必须为 :size。',
+        'file' => ':attribute 大小必须为 :size kb。',
+        'string' => ':attribute 必须是 :size 个字符。',
+        'array' => ':attribute 必须为 :size 个单元。',
+    ],
+    'string' => ':attribute 必须是一个字符串。',
+    'timezone' => ':attribute 必须是一个合法的时区值。',
+    'unique' => ':attribute 已经存在。',
+    'uploaded' => ':attribute 上传失败。',
+    'url' => ':attribute 格式不正确。',
+
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Attributes
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used to swap attribute place-holders
+    | with something more reader friendly such as E-Mail Address instead
+    | of 'email'. This simply helps us make messages a little cleaner.
+    |
+    */
+
+    'attributes' => [
+        'post_id' => '内容id',
+        'uid' => '用户uid',
+        'type' => '类型',
+        'is_suggest' => '是否推荐',
+        'img' => '图片',
+        'video' => '视频',
+        'video_id' => '视频id',
+        'topic_ids' => '话题id',
+        'title' => '标题',
+        'content' => '内容',
+        'location' => '位置',
+        'imgs' => '图组',
+        'imgs.*' => '图集',
+        'add_pv' => '增加浏览量',
+        'add_praise_count' => '增加点赞数',
+        'add_collect_count' => '增加收藏数',
+        'add_share_count' => '增加分享数',
+        'download_type' => '下载类型',
+        'download_status' => '下载状态',
+        'category_ids' => '话题分类id',
+        'category_ids.*' => '话题分类子id',
+    ],
+
+];

+ 0 - 0
resources/views/.gitkeep


+ 35 - 0
routes/api.php

@@ -0,0 +1,35 @@
+<?php
+
+/*
+|--------------------------------------------------------------------------
+| Application Routes
+|--------------------------------------------------------------------------
+|
+| Here is where you can register all of the routes for an application.
+| It is a breeze. Simply tell Lumen the URIs it should respond to
+| and give it the Closure to call when that URI is requested.
+|
+*/
+
+$api = app('Dingo\Api\Routing\Router');
+
+$api->version('v1', [
+    'namespace' => 'App\Http\Controllers',
+], function ($api) {
+
+    //前台
+    $api->get('egg', 'IndexController@index');
+
+
+
+
+    //后台
+    //登录
+    $api->post('login', 'AuthController@authenticate');
+    $api->get('metas', 'MetaController@index');
+    $api->post('meta', 'MetaController@create');
+    $api->group(['middleware' => 'jwt.chxq_auth'], function ($api) {
+
+    });
+
+});

+ 20 - 0
routes/web.php

@@ -0,0 +1,20 @@
+<?php
+
+/*
+|--------------------------------------------------------------------------
+| Application Routes
+|--------------------------------------------------------------------------
+|
+| Here is where you can register all of the routes for an application.
+| It is a breeze. Simply tell Lumen the URIs it should respond to
+| and give it the Closure to call when that URI is requested.
+|
+*/
+
+$router->get('/', function () use ($router) {
+    return '欢迎来到由你';
+});
+
+$router->get('/test', function () use ($router) {
+    return 'test-manage';
+});

+ 21 - 0
tests/ExampleTest.php

@@ -0,0 +1,21 @@
+<?php
+
+use Laravel\Lumen\Testing\DatabaseMigrations;
+use Laravel\Lumen\Testing\DatabaseTransactions;
+
+class ExampleTest extends TestCase
+{
+    /**
+     * A basic test example.
+     *
+     * @return void
+     */
+    public function testExample()
+    {
+        $this->get('/');
+
+        $this->assertEquals(
+            $this->app->version(), $this->response->getContent()
+        );
+    }
+}

+ 14 - 0
tests/TestCase.php

@@ -0,0 +1,14 @@
+<?php
+
+abstract class TestCase extends Laravel\Lumen\Testing\TestCase
+{
+    /**
+     * Creates the application.
+     *
+     * @return \Laravel\Lumen\Application
+     */
+    public function createApplication()
+    {
+        return require __DIR__.'/../bootstrap/app.php';
+    }
+}