xielin 6 年之前
当前提交
f55ed65333
共有 46 个文件被更改,包括 2113 次插入0 次删除
  1. 二进制
      .DS_Store
  2. 15 0
      .editorconfig
  3. 24 0
      .env.example
  4. 7 0
      .gitignore
  5. 0 0
      app/Console/Commands/.gitkeep
  6. 29 0
      app/Console/Kernel.php
  7. 10 0
      app/Events/Event.php
  8. 16 0
      app/Events/ExampleEvent.php
  9. 50 0
      app/Exceptions/Handler.php
  10. 47 0
      app/Helper/helper.php
  11. 10 0
      app/Http/Controllers/Controller.php
  12. 56 0
      app/Http/Controllers/V1/Controller.php
  13. 49 0
      app/Http/Middleware/Authenticate.php
  14. 20 0
      app/Http/Middleware/ExampleMiddleware.php
  15. 46 0
      app/Http/Middleware/JwtAuthMiddleware.php
  16. 37 0
      app/Http/Middleware/SignAuthMiddleware.php
  17. 26 0
      app/Jobs/ExampleJob.php
  18. 24 0
      app/Jobs/Job.php
  19. 31 0
      app/Listeners/ExampleListener.php
  20. 21 0
      app/Providers/AppServiceProvider.php
  21. 39 0
      app/Providers/AuthServiceProvider.php
  22. 35 0
      artisan
  23. 26 0
      bin/fswatch
  24. 11 0
      bin/laravels
  25. 114 0
      bootstrap/app.php
  26. 55 0
      composer.json
  27. 232 0
      config/api.php
  28. 90 0
      config/auth.php
  29. 5 0
      config/customer.php
  30. 197 0
      config/elasticsearch.php
  31. 304 0
      config/jwt.php
  32. 79 0
      config/laravels.php
  33. 19 0
      database/factories/ModelFactory.php
  34. 0 0
      database/migrations/.gitkeep
  35. 16 0
      database/seeds/DatabaseSeeder.php
  36. 26 0
      phpunit.xml
  37. 21 0
      public/.htaccess
  38. 二进制
      public/caihongxinqiu_debug.apk
  39. 28 0
      public/index.php
  40. 1 0
      readme.md
  41. 155 0
      resources/lang/zh-CN/validation.php
  42. 0 0
      resources/views/.gitkeep
  43. 86 0
      routes/api.php
  44. 21 0
      routes/web.php
  45. 21 0
      tests/ExampleTest.php
  46. 14 0
      tests/TestCase.php

二进制
.DS_Store


+ 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

+ 24 - 0
.env.example

@@ -0,0 +1,24 @@
+APP_NAME=cms-service
+APP_ENV=local
+APP_KEY=
+APP_DEBUG=true
+APP_URL=http://localhost
+APP_TIMEZONE=UTC
+
+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
+
+ELASTICSEARCH_HOST=localhost
+ELASTICSEARCH_PORT=9200
+ELASTICSEARCH_USER=
+ELASTICSEARCH_PASS=

+ 7 - 0
.gitignore

@@ -0,0 +1,7 @@
+/vendor
+/.idea
+Homestead.json
+Homestead.yaml
+.env
+/storage/*
+composer.lock

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


+ 29 - 0
app/Console/Kernel.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Console;
+
+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 = [
+        //
+    ];
+
+    /**
+     * Define the application's command schedule.
+     *
+     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
+     * @return void
+     */
+    protected function schedule(Schedule $schedule)
+    {
+        //
+    }
+}

+ 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);
+    }
+}

+ 47 - 0
app/Helper/helper.php

@@ -0,0 +1,47 @@
+<?php
+/**
+ * 添加自定义辅助函数
+ */
+
+/**
+ * 参数签名校验
+ * @param array $params
+ * @return string
+ */
+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));
+}
+
+/**
+ * 验证签名
+ * @param $sign
+ * @param $params
+ * @return bool
+ */
+function verifySign($sign, $params, $secret_key)
+{
+    if ($sign == generateSign($params, $secret_key)) {
+        return true;
+    } else {
+        return false;
+    };
+
+}

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

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

+ 56 - 0
app/Http/Controllers/V1/Controller.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace App\Http\Controllers\V1;
+
+
+use Dingo\Api\Routing\Helpers;
+use App\Http\Controllers\Controller as BaseController;
+
+class Controller extends BaseController
+{
+    use Helpers;
+
+    public function jsonSuccess($data = [], $msg = "成功")
+    {
+        $response = array(
+            'code' => 0,
+            'msg' => $msg,
+            'data' => []
+        );
+        if ($data) {
+            if (is_array($data)) {
+                //带有分页格式转换
+                if (isset($data['meta'])) {
+                    // 更改元数据格式,全部包含在data下
+                    $temp = array(
+                        'data' => array(
+                            'data' => $data['data'],
+                            'pagination' => $data['meta']['pagination']
+                        )
+                    );
+                    $response = array_merge($response, $temp);
+                } elseif(isset($data['data'])) {
+                    $response = array_merge($response, $data);
+                }else{
+                    $temp = array(
+                        'data' => $data
+                    );
+                    $response = array_merge($response, $temp);
+                }
+            } else {
+                $response['data'] = $data;
+            }
+        }
+        return $response;
+    }
+
+    public function jsonError($msg)
+    {
+        $response = array(
+            'code' => 1,
+            'msg' => $msg,
+            'data' => ""
+        );
+        return $response;
+    }
+}

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

@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Contracts\Auth\Factory as Auth;
+use Illuminate\Support\Facades\Log;
+
+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)->setStatusCode(401);
+        }
+        $user = $this->auth->user();
+        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);
+    }
+}

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

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Tymon\JWTAuth\Exceptions\JWTException;
+use Tymon\JWTAuth\Exceptions\TokenExpiredException;
+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 {
+            $user = JWTAuth::parseToken()->authenticate();
+        } catch (TokenExpiredException $e) {
+            $error = [
+                'message' => 'Token is Expired',
+                'code' => 401,
+            ];
+            return response()->json($error)->setStatusCode(401);
+        } catch (TokenInvalidException $e) {
+            $error = [
+                'message' => $e->getMessage(),
+                'code' => 401,
+            ];
+            return response()->json($error)->setStatusCode(401);
+        } catch (JWTException $e) {
+            $error = [
+                'message' => $e->getMessage(),
+                'code' => 401,
+            ];
+            return response()->json($error)->setStatusCode(401);
+        }
+        return $next($request);
+    }
+}

+ 37 - 0
app/Http/Middleware/SignAuthMiddleware.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+
+class SignAuthMiddleware
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+
+        try {
+            if (!verifySign($request->get('sign'), $request->all(), config('customer.app_secret'))) {
+                $error = [
+                    'message' => '数据验签失败',
+                    'code' => 401,
+                ];
+                return response()->json($error)->setStatusCode(401);
+            }
+
+        } catch (\Exception $e) {
+            $error = [
+                'message' => $e->getMessage(),
+                'code' => 401,
+            ];
+            return response()->json($error)->setStatusCode(401);
+        }
+        return $next($request);
+    }
+}

+ 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)
+    {
+        //
+    }
+}

+ 21 - 0
app/Providers/AppServiceProvider.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Support\ServiceProvider;
+
+class AppServiceProvider extends ServiceProvider
+{
+    /**
+     * Register any application services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        Validator::extend('mobile', function ($attribute, $value, $parameters) {
+            return preg_match('/^1[3456789]{1}\d{9}$/', $value);
+        });
+    }
+}

+ 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();
+            }
+        });
+    }
+}

+ 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));

+ 26 - 0
bin/fswatch

@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+WORK_DIR=$1
+if [ ! -n "${WORK_DIR}" ] ;then
+    WORK_DIR="."
+fi
+
+echo "Restarting LaravelS..."
+./bin/laravels restart -d -i
+
+echo "Starting fswatch..."
+LOCKING=0
+fswatch -r -e ".*" -i "\\.php$" ${WORK_DIR} | while read file
+do
+    if [[ ! ${file} =~ .php$ ]] ;then
+        continue
+    fi
+    if [ ${LOCKING} -eq 1 ] ;then
+        echo "Reloading, skipped."
+        continue
+    fi
+    echo "File ${file} has been modified."
+    LOCKING=1
+    ./bin/laravels reload
+    LOCKING=0
+done
+exit 0

+ 11 - 0
bin/laravels

@@ -0,0 +1,11 @@
+#!/usr/bin/env php
+<?php
+$basePath = realpath(__DIR__ . '/../');
+include $basePath . '/vendor/autoload.php';
+
+$command = new Hhxsv5\LaravelS\Console\Portal($basePath);
+$input = new Symfony\Component\Console\Input\ArgvInput();
+$output = new Symfony\Component\Console\Output\ConsoleOutput();
+
+$code = $command->run($input, $output);
+exit($code);

+ 114 - 0
bootstrap/app.php

@@ -0,0 +1,114 @@
+<?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('auth');
+$app->configure('jwt');
+$app->configure('customer');
+$app->configure('elasticsearch');
+/*
+|--------------------------------------------------------------------------
+| 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->routeMiddleware([
+    'auth' => App\Http\Middleware\Authenticate::class,
+    'chxq_jwt_auth' => App\Http\Middleware\JwtAuthMiddleware::class,
+    'chxq_sign' => App\Http\Middleware\SignAuthMiddleware::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(\Cviebrock\LaravelElasticsearch\ServiceProvider::class);
+$app->register(\Illuminate\Redis\RedisServiceProvider::class);
+
+class_alias('\Cviebrock\LaravelElasticsearch\Facade','Elasticsearch');
+/*
+|--------------------------------------------------------------------------
+| 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';
+});
+
+
+$app->register(Hhxsv5\LaravelS\Illuminate\LaravelSServiceProvider::class);
+
+$app->register(Yansongda\LaravelPay\PayServiceProvider::class);
+
+return $app;

+ 55 - 0
composer.json

@@ -0,0 +1,55 @@
+{
+    "name": "laravel/lumen",
+    "description": "The Laravel Lumen Framework.",
+    "keywords": ["framework", "laravel", "lumen"],
+    "license": "MIT",
+    "type": "project",
+    "require": {
+        "php": ">=7.1.3",
+        "cviebrock/laravel-elasticsearch": "^3.5",
+        "dingo/api": "^2.2",
+        "guzzlehttp/guzzle": "^6.3",
+        "hhxsv5/laravel-s": "~3.4.0",
+        "illuminate/redis": "^5.8",
+        "laravel/lumen-framework": "5.8.*",
+        "league/fractal": "^0.17.0",
+        "predis/predis": "^1.1",
+        "tymon/jwt-auth": "1.0.0-rc.4.1",
+        "vlucas/phpdotenv": "^3.3",
+        "yansongda/laravel-pay": "^2.0"
+    },
+    "require-dev": {
+        "fzaninotto/faker": "^1.4",
+        "phpunit/phpunit": "^7.0",
+        "mockery/mockery": "^1.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),
+        ],
+
+    ],
+
+];

+ 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\Member::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' => [
+        //
+    ],
+
+];

+ 5 - 0
config/customer.php

@@ -0,0 +1,5 @@
+<?php
+//此文件为apollo配置文件模板,禁止修改移动
+return [
+    'app_secret' => 'aaaaaaaaaaa'
+];

+ 197 - 0
config/elasticsearch.php

@@ -0,0 +1,197 @@
+<?php
+
+return [
+
+    /**
+     * You can specify one of several different connections when building an
+     * Elasticsearch client.
+     *
+     * Here you may specify which of the connections below you wish to use
+     * as your default connection when building an client. Of course you may
+     * use create several clients at once, each with different configurations.
+     */
+
+    'defaultConnection' => 'default',
+
+    /**
+     * These are the connection parameters used when building a client.
+     */
+
+    'connections' => [
+
+        'default' => [
+
+            /**
+             * Hosts
+             *
+             * This is an array of hosts that the client will connect to. It can be a
+             * single host, or an array if you are running a cluster of Elasticsearch
+             * instances.
+             *
+             * This is the only configuration value that is mandatory.
+             *
+             * Presently using "extended" host configuration method
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_extended_host_configuration
+             *
+             * There is also the shorter "inline" configuration method available
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_inline_host_configuration
+             */
+
+            'hosts' => [
+                [
+                    'host'       => env('ELASTICSEARCH_HOST', 'localhost'),
+                    'port'       => env('ELASTICSEARCH_PORT', 9200),
+                    'scheme'     => env('ELASTICSEARCH_SCHEME', null),
+                    'user'       => env('ELASTICSEARCH_USER', null),
+                    'pass'       => env('ELASTICSEARCH_PASS', null),
+
+                    // If you are connecting to an Elasticsearch instance on AWS, you will need these values as well
+                    'aws'        => env('AWS_ELASTICSEARCH_ENABLED', false),
+                    'aws_region' => env('AWS_REGION', ''),
+                    'aws_key'    => env('AWS_ACCESS_KEY_ID', ''),
+                    'aws_secret' => env('AWS_SECRET_ACCESS_KEY', '')
+                ],
+            ],
+
+            /**
+             * SSL
+             *
+             * If your Elasticsearch instance uses an out-dated or self-signed SSL
+             * certificate, you will need to pass in the certificate bundle.  This can
+             * either be the path to the certificate file (for self-signed certs), or a
+             * package like https://github.com/Kdyby/CurlCaBundle.  See the documentation
+             * below for all the details.
+             *
+             * If you are using SSL instances, and the certificates are up-to-date and
+             * signed by a public certificate authority, then you can leave this null and
+             * just use "https" in the host path(s) above and you should be fine.
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_security.html#_ssl_encryption_2
+             */
+
+            'sslVerification' => null,
+
+            /**
+             * Logging
+             *
+             * Logging is handled by passing in an instance of Monolog\Logger (which
+             * coincidentally is what Laravel's default logger is).
+             *
+             * If logging is enabled, you either need to set the path and log level
+             * (some defaults are given for you below), or you can use a custom logger by
+             * setting 'logObject' to an instance of Psr\Log\LoggerInterface.  In fact,
+             * if you just want to use the default Laravel logger, then set 'logObject'
+             * to \Log::getMonolog().
+             *
+             * Note: 'logObject' takes precedent over 'logPath'/'logLevel', so set
+             * 'logObject' null if you just want file-based logging to a custom path.
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#enabling_logger
+             */
+
+            'logging' => false,
+
+            // If you have an existing instance of Monolog you can use it here.
+            // 'logObject' => \Log::getMonolog(),
+
+            'logPath' => storage_path('logs/elasticsearch.log'),
+
+            'logLevel' => Monolog\Logger::INFO,
+
+            /**
+             * Retries
+             *
+             * By default, the client will retry n times, where n = number of nodes in
+             * your cluster. If you would like to disable retries, or change the number,
+             * you can do so here.
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_set_retries
+             */
+
+            'retries' => null,
+
+            /**
+             * The remainder of the configuration options can almost always be left
+             * as-is unless you have specific reasons to change them.  Refer to the
+             * appropriate sections in the Elasticsearch documentation for what each option
+             * does and what values it expects.
+             */
+
+            /**
+             * Sniff On Start
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html
+             */
+
+            'sniffOnStart' => false,
+
+            /**
+             * HTTP Handler
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_configure_the_http_handler
+             * @see http://ringphp.readthedocs.org/en/latest/client_handlers.html
+             */
+
+            'httpHandler' => null,
+
+            /**
+             * Connection Pool
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_connection_pool
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_connection_pool.html
+             */
+
+            'connectionPool' => null,
+
+            /**
+             * Connection Selector
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_connection_selector
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_selectors.html
+             */
+
+            'connectionSelector' => null,
+
+            /**
+             * Serializer
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_serializer
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_serializers.html
+             */
+
+            'serializer' => null,
+
+            /**
+             * Connection Factory
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_a_custom_connectionfactory
+             */
+
+            'connectionFactory' => null,
+
+            /**
+             * Endpoint
+             *
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/6.0/_configuration.html#_set_the_endpoint_closure
+             */
+
+            'endpoint' => null,
+
+
+            /**
+             * Register additional namespaces
+             *
+             * An array of additional namespaces to register.
+             *
+             * @example 'namespaces' => [XPack::Security(), XPack::Watcher()]
+             * @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/ElasticsearchPHP_Endpoints.html#Elasticsearch_ClientBuilderregisterNamespace_registerNamespace
+             */
+            'namespaces' => []
+
+        ],
+
+    ],
+
+];

+ 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'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | 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 * 24 * 7),
+
+    /*
+    |--------------------------------------------------------------------------
+    | 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,
+
+    ],
+
+];

+ 79 - 0
config/laravels.php

@@ -0,0 +1,79 @@
+<?php
+/**
+ * @see https://github.com/hhxsv5/laravel-s/blob/master/Settings-CN.md  Chinese
+ * @see https://github.com/hhxsv5/laravel-s/blob/master/Settings.md  English
+ */
+return [
+    'listen_ip'                => env('LARAVELS_LISTEN_IP', '0.0.0.0'),
+    'listen_port'              => env('LARAVELS_LISTEN_PORT', 18211),
+    'socket_type'              => defined('SWOOLE_SOCK_TCP') ? SWOOLE_SOCK_TCP : 1,
+    'enable_coroutine_runtime' => false,
+    'server'                   => env('LARAVELS_SERVER', 'cms-service'),
+    'handle_static'            => env('LARAVELS_HANDLE_STATIC', false),
+    'laravel_base_path'        => env('LARAVEL_BASE_PATH', base_path()),
+    'inotify_reload'           => [
+        'enable'        => env('LARAVELS_INOTIFY_RELOAD', false),
+        'watch_path'    => base_path(),
+        'file_types'    => ['.php'],
+        'excluded_dirs' => [],
+        'log'           => true,
+    ],
+    'event_handlers'           => [],
+    'websocket'                => [
+        'enable' => false,
+        //'handler' => XxxWebSocketHandler::class,
+    ],
+    'sockets'                  => [],
+    'processes'                => [],
+    'timer'                    => [
+        'enable'        => false,
+        'jobs'          => [
+            // Enable LaravelScheduleJob to run `php artisan schedule:run` every 1 minute, replace Linux Crontab
+            //\Hhxsv5\LaravelS\Illuminate\LaravelScheduleJob::class,
+            // Two ways to configure parameters:
+            // [\App\Jobs\XxxCronJob::class, [1000, true]], // Pass in parameters when registering
+            // \App\Jobs\XxxCronJob::class, // Override the corresponding method to return the configuration
+        ],
+        'pid_file'      => storage_path('laravels-timer.pid'),
+        'max_wait_time' => 5,
+    ],
+    'events'                   => [],
+    'swoole_tables'            => [],
+    'register_providers'       => [],
+    'cleaners'                 => [
+        //Hhxsv5\LaravelS\Illuminate\Cleaners\SessionCleaner::class, // If you use the session/authentication in your project, please uncomment this line
+        //Hhxsv5\LaravelS\Illuminate\Cleaners\AuthCleaner::class,    // If you use the authentication/passport in your project, please uncomment this line
+        Hhxsv5\LaravelS\Illuminate\Cleaners\JWTCleaner::class,     // If you use the package "tymon/jwt-auth" in your project, please uncomment this line
+        // ...
+    ],
+    'swoole'                   => [
+        'daemonize'          => env('LARAVELS_DAEMONIZE', false),
+        'dispatch_mode'      => 2,
+        'reactor_num'        => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 4,
+        'worker_num'         => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 8,
+        //'task_worker_num'    => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 8,
+        'task_ipc_mode'      => 1,
+        'task_max_request'   => 8000,
+        'task_tmpdir'        => @is_writable('/dev/shm/') ? '/dev/shm' : '/tmp',
+        'max_request'        => 8000,
+        'open_tcp_nodelay'   => true,
+        'pid_file'           => storage_path('laravels.pid'),
+        'log_file'           => storage_path(sprintf('logs/swoole-%s.log', date('Y-m'))),
+        'log_level'          => 4,
+        'document_root'      => base_path('public'),
+        'buffer_output_size' => 2 * 1024 * 1024,
+        'socket_buffer_size' => 128 * 1024 * 1024,
+        'package_max_length' => 4 * 1024 * 1024,
+        'reload_async'       => true,
+        'max_wait_time'      => 60,
+        'enable_reuse_port'  => true,
+        'enable_coroutine'   => false,
+        'http_compression'   => false,
+
+        /**
+         * More settings of Swoole
+         * @see https://wiki.swoole.com/wiki/page/274.html  Chinese
+         * @see https://www.swoole.co.uk/docs/modules/swoole-server/configuration  English
+         */
+    ],
+];

+ 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


+ 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');
+    }
+}

+ 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>

二进制
public/caihongxinqiu_debug.apk


+ 28 - 0
public/index.php

@@ -0,0 +1,28 @@
+<?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.
+|
+*/
+
+$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();

+ 1 - 0
readme.md

@@ -0,0 +1 @@
+# 平台APP客户端接口

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

@@ -0,0 +1,155 @@
+<?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 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' => [
+        'name' => '名称',
+        'username' => '用户名',
+        'email' => '邮箱',
+        'first_name' => '名',
+        'last_name' => '姓',
+        'password' => '密码',
+        'password_confirmation' => '确认密码',
+        'city' => '城市',
+        'country' => '国家',
+        'address' => '地址',
+        'phone' => '电话',
+        'mobile' => '手机',
+        'age' => '年龄',
+        'sex' => '性别',
+        'gender' => '性别',
+        'day' => '天',
+        'month' => '月',
+        'year' => '年',
+        'hour' => '时',
+        'minute' => '分',
+        'second' => '秒',
+        'title' => '标题',
+        'content' => '内容',
+        'description' => '描述',
+        'excerpt' => '摘要',
+        'date' => '日期',
+        'time' => '时间',
+        'available' => '可用的',
+        'size' => '大小',
+        'sms_code' => '手机短信',
+        'vendor' => '手机厂商',
+        'client_name' => '客户端名称',
+
+    ],
+
+    'mobile'    => '手机号码格式不正确。',
+];

+ 0 - 0
resources/views/.gitkeep


+ 86 - 0
routes/api.php

@@ -0,0 +1,86 @@
+<?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\V1',
+], function ($api) {
+    //登录
+    $api->post('login', 'AuthController@authenticate');
+    //测试签名
+    $api->post('sign', 'IndexController@index4');
+    //测试支付宝 支付
+    $api->post('alipay', 'AlipayController@index');
+    //回调
+    $api->post('return', 'AlipayController@return');
+    //异步回调
+    $api->post('notify', 'AlipayController@notify');
+    //测试微信支付
+    $api->post('weixin', 'WeixinPayController@index');
+    //微信回调
+    $api->post('wxin_notify', 'WeixinPayController@notify');
+    //测试短信验证码
+    $api->post('send_sms', 'SendSmsController@index');
+    //手机号码注册
+    $api->post('mobileRegister', 'AuthController@mobileRegister');
+    //微信注册
+    $api->post('weixinRegister', 'AuthController@weixinRegister');
+    //手机号码,密码登录
+    $api->post('mobileLogin', 'AuthController@mobileLogin');
+    //手机号码短信登陆
+    $api->post('mobileSmsLogin', 'AuthController@mobileSmsLogin');
+    //微信登录
+    $api->post('weixinLogin', 'AuthController@weixinLogin');
+    //测试reids
+    $api->post('loginCount', 'AuthController@loginCount');
+
+
+    $api->group(['middleware' => 'auth:api'], function ($api) {
+
+    });
+
+    //登录+验签
+    $api->group(['middleware' => ['chxq_jwt_auth','chxq_sign']], function ($api) {
+        //登出
+        $api->post('logout', 'AuthController@logout');
+        //刷新身份令牌
+        $api->post('refresh', 'AuthController@refresh');
+        //绑定微信
+        $api->post('bindWeixin', 'AuthController@bindWeixin');
+        //绑定手机
+        $api->post('bindMobile', 'AuthController@bindMobile');
+        //设置密码
+        $api->post('setPassword', 'AuthController@setPassword');
+        //修改密码
+        $api->post('updatePassword', 'AuthController@updatePassword');
+        //解绑温馨
+        $api->post('unbindWeixin', 'AuthController@unbindWeixin');
+        //检查微信号是否绑定
+        $api->post('isBindWeixin', 'AuthController@isBindWeixin');
+        //新增快递地址
+        $api->post('addExpressAddress', 'MemberExpressAddressController@addExpressAddress');
+        //新增自提地址
+        $api->post('addSelfAddress', 'MemberExpressAddressController@addSelfAddress');
+        //用户自提地址
+        $api->post('selfAddressList', 'MemberExpressAddressController@selfAddressList');
+        //删除地址
+        $api->post('addressDelete', 'MemberExpressAddressController@delete');
+        //设置默认地址
+        $api->post('addressIsDefault', 'MemberExpressAddressController@isDefault');
+    });
+    //仅验签
+    $api->group(['middleware' => 'chxq_sign'], function ($api) {
+
+    });
+});

+ 21 - 0
routes/web.php

@@ -0,0 +1,21 @@
+<?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->app->version();
+});
+
+
+$router->get('/test', function () use ($router) {
+    return 'test';
+});

+ 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';
+    }
+}