diff --git a/app/Admin/Controllers/ActivityController.php b/app/Admin/Controllers/ActivityController.php index 4253328..962f254 100644 --- a/app/Admin/Controllers/ActivityController.php +++ b/app/Admin/Controllers/ActivityController.php @@ -88,7 +88,7 @@ class ActivityController extends AdminController amis()->TextControl('name', __('admin.activities.name'))->required(true), Components::make()->cropImageControl('cover', __('admin.activities.cover'), 1.5)->required(true), amis()->DateRangeControl('start_at', __('admin.activities.activity_at'))->extraName('end_at')->clearable(false)->format('YYYY-MM-DD HH:mm:ss')->required(true), - amis()->TextareaControl('rules', __('admin.activities.rules')) + amis()->TextareaControl('rules', __('admin.activities.rules'))->minRows(30) ]); } @@ -240,7 +240,7 @@ class ActivityController extends AdminController amis()->TextControl('gift_name', __('admin.activity_gifts.name'))->required(true), Components::make()->cropImageControl('logo', __('admin.activity_gifts.logo')), Components::make()->sortControl('rank', __('admin.activity_gifts.rank'))->required(true), - amis()->TextareaControl('explain', __('admin.activity_gifts.explain')) + amis()->TextareaControl('explain', __('admin.activity_gifts.explain'))->minRows(6) ]) ])->size('lg') ) @@ -262,7 +262,7 @@ class ActivityController extends AdminController amis()->TextControl('name', __('admin.activity_gifts.name'))->required(true), Components::make()->cropImageControl('logo', __('admin.activity_gifts.logo')), Components::make()->sortControl('rank', __('admin.activity_gifts.rank'))->required(true), - amis()->TextareaControl('explain', __('admin.activity_gifts.explain')) + amis()->TextareaControl('explain', __('admin.activity_gifts.explain'))->minRows(6) ]) ])->size('lg')), amisMake()->AjaxAction()->label('删除')->level('link') diff --git a/app/Admin/Controllers/ArticleController.php b/app/Admin/Controllers/ArticleController.php index 387ffc1..0364f57 100644 --- a/app/Admin/Controllers/ArticleController.php +++ b/app/Admin/Controllers/ArticleController.php @@ -87,7 +87,7 @@ class ArticleController extends AdminController amis()->Wrapper()->body([ amis()->TextControl('title', __('admin.articles.title'))->required(true), Components::make()->parentControl(admin_url('api/keywords/tree-list?parent_name=article_category&has_owner=0'), 'category', __('admin.articles.category'), 'name', 'key'), - Components::make()->keywordsTagControl('t_ids', __('admin.articles.tags'), 'article_tag'), + // Components::make()->keywordsTagControl('t_ids', __('admin.articles.tags'), 'article_tag'), Components::make()->cropImageControl('cover', __('admin.articles.cover')), amis()->TextControl('source', __('admin.articles.source')), Components::make()->sortControl('sort', __('admin.articles.sort')), diff --git a/app/Http/Controllers/Api/ApiController.php b/app/Http/Controllers/Api/ApiController.php new file mode 100644 index 0000000..83b9141 --- /dev/null +++ b/app/Http/Controllers/Api/ApiController.php @@ -0,0 +1,37 @@ +service = $this->serviceName::make(); + } + } + + public function json($data, $code = Response::HTTP_OK, $message = '') + { + $result = ['data' => $data, 'code' => $code, 'message' => $message]; + return response()->json($result); + } + + public function success($data = [], $message = '') + { + return $this->json($data, Response::HTTP_OK, $message); + } + + public function error($message = '', $code = Response::HTTP_BAD_REQUEST, $data = []) + { + return $this->json($data, $code, $message); + } +} diff --git a/app/Http/Controllers/Api/AuthController.php b/app/Http/Controllers/Api/AuthController.php index 1730717..de1414d 100644 --- a/app/Http/Controllers/Api/AuthController.php +++ b/app/Http/Controllers/Api/AuthController.php @@ -1,7 +1,46 @@ service->register($openid); + + $apiToken = $this->service->login($user); + + return $this->success([ + 'user' => UserResource::make($user)->resolve(), + 'api_token' => $apiToken, + 'expire_in' => Carbon::parse()->addDay()->toDateTimeString() + ]); + } + /** + * + */ + public function refreshToken(Request $request) + { + $user = auth('api')->user(); + //撤销当前令牌 + $request->user()->currentAccessToken()->delete(); + //颁发新令牌 + return $this->success([ + 'api_token' => $user->createToken( + name: 'api', + expiresAt: now()->addDay(), + )->plainTextToken, + 'expire_in' => Carbon::parse()->addDay()->toDateTimeString() + ]); + } } \ No newline at end of file diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 494c050..4bf5612 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -39,6 +39,7 @@ class Kernel extends HttpKernel ], 'api' => [ + \App\Http\Middleware\AcceptHeader::class, // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, diff --git a/app/Http/Middleware/AcceptHeader.php b/app/Http/Middleware/AcceptHeader.php new file mode 100644 index 0000000..e009236 --- /dev/null +++ b/app/Http/Middleware/AcceptHeader.php @@ -0,0 +1,22 @@ +headers->set('Accept', 'application/json'); + return $next($request); + } +} diff --git a/app/Http/Middleware/HasBindPhone.php b/app/Http/Middleware/HasBindPhone.php new file mode 100644 index 0000000..c7bd82b --- /dev/null +++ b/app/Http/Middleware/HasBindPhone.php @@ -0,0 +1,26 @@ +user(); + if(!($user && $user->phone)){ + return response()->json(['data'=>[], 'code'=>Response::HTTP_FORBIDDEN, 'message'=>'请先登录']); + } + return $next($request); + } +} diff --git a/app/Http/Resources/Api/UserResource.php b/app/Http/Resources/Api/UserResource.php new file mode 100644 index 0000000..86faa47 --- /dev/null +++ b/app/Http/Resources/Api/UserResource.php @@ -0,0 +1,28 @@ + $this->nick_name ??'', + 'avatar' => $this->avatar ??'', + 'phone' => $this->phone ??'', + ]; + } + + public function with($request) + { + return ['code' => Response::HTTP_OK, 'message' => '']; + } +} \ No newline at end of file diff --git a/app/Services/Api/UserService.php b/app/Services/Api/UserService.php new file mode 100644 index 0000000..aee57f9 --- /dev/null +++ b/app/Services/Api/UserService.php @@ -0,0 +1,46 @@ +first()){ + $user = new User(); + $user->mini_openid = $miniOpenid; + $user->save(); + } + + return $user; + } + + public function login(User $user) + { + //记录当前登录时间、IP + $ip = request()->getClientIp(); + $user->last_login_ip = ip2long($ip); + $user->last_login_at = now(); + $user->save(); + + //撤销当前所有令牌; + $user->tokens()->delete(); + + return $user->createToken( + name: 'api', + expiresAt: now()->addDay(), + )->plainTextToken; + } + +} \ No newline at end of file diff --git a/composer.json b/composer.json index 6548345..1cb19ae 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "laravel/framework": "^10.10", "laravel/sanctum": "^3.3", "laravel/tinker": "^2.8", + "overtrue/laravel-wechat": "^7.2", "rap2hpoutre/fast-excel": "^5.4", "slowlyo/owl-admin": "^3.5", "tucker-eric/eloquentfilter": "^3.2" diff --git a/composer.lock b/composer.lock index 2772f00..258c530 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6ce90738fadc40a447dfead6b131ec62", + "content-hash": "309e17fdf6a179f27ef0418b52084800", "packages": [ { "name": "aliyuncs/oss-sdk-php", @@ -2004,6 +2004,150 @@ ], "time": "2023-02-08T01:06:31+00:00" }, + { + "name": "nyholm/psr7", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.1" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-11-13T09:31:12+00:00" + }, + { + "name": "nyholm/psr7-server", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7-server.git", + "reference": "4335801d851f554ca43fa6e7d2602141538854dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7-server/zipball/4335801d851f554ca43fa6e7d2602141538854dc", + "reference": "4335801d851f554ca43fa6e7d2602141538854dc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "nyholm/nsa": "^1.1", + "nyholm/psr7": "^1.3", + "phpunit/phpunit": "^7.0 || ^8.5 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nyholm\\Psr7Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "Helper classes to handle PSR-7 server requests", + "homepage": "http://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7-server/issues", + "source": "https://github.com/Nyholm/psr7-server/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-11-08T09:30:43+00:00" + }, { "name": "openspout/openspout", "version": "v4.23.0", @@ -2077,6 +2221,152 @@ ], "time": "2024-01-09T09:30:37+00:00" }, + { + "name": "overtrue/laravel-wechat", + "version": "7.3.0", + "source": { + "type": "git", + "url": "https://github.com/overtrue/laravel-wechat.git", + "reference": "b3e89dddc45da4eb3d5322a10dee9dc65e619579" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/overtrue/laravel-wechat/zipball/b3e89dddc45da4eb3d5322a10dee9dc65e619579", + "reference": "b3e89dddc45da4eb3d5322a10dee9dc65e619579", + "shasum": "" + }, + "require": { + "illuminate/container": "^9.0|^10.0|^11.0", + "w7corp/easywechat": "^6.0.0" + }, + "require-dev": { + "brainmaestro/composer-git-hooks": "dev-master", + "jetbrains/phpstorm-attributes": "^1.0", + "laravel/framework": "^10.0", + "laravel/pint": "^1.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Overtrue\\LaravelWeChat\\ServiceProvider" + ] + }, + "hooks": { + "pre-commit": [ + "composer check-style" + ], + "pre-push": [ + "composer check-style" + ] + } + }, + "autoload": { + "psr-4": { + "Overtrue\\LaravelWeChat\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "微信 SDK for Laravel", + "keywords": [ + "laravel", + "sdk", + "wechat", + "weixin" + ], + "support": { + "issues": "https://github.com/overtrue/laravel-wechat/issues", + "source": "https://github.com/overtrue/laravel-wechat/tree/7.3.0" + }, + "funding": [ + { + "url": "https://github.com/overtrue", + "type": "github" + } + ], + "time": "2024-03-13T02:06:36+00:00" + }, + { + "name": "overtrue/socialite", + "version": "4.10.1", + "source": { + "type": "git", + "url": "https://github.com/overtrue/socialite.git", + "reference": "457b48f31414dc00d3fb445d6ab9355595067afe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/overtrue/socialite/zipball/457b48f31414dc00d3fb445d6ab9355595067afe", + "reference": "457b48f31414dc00d3fb445d6ab9355595067afe", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^7.0", + "php": ">=8.0.2", + "symfony/psr-http-message-bridge": "^2.1|^6.0" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.0", + "laravel/pint": "^1.2", + "mockery/mockery": "^1.3", + "phpstan/phpstan": "^1.7", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Contracts/FactoryInterface.php", + "src/Contracts/UserInterface.php", + "src/Contracts/ProviderInterface.php" + ], + "psr-4": { + "Overtrue\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "A collection of OAuth 2 packages.", + "keywords": [ + "Feishu", + "login", + "oauth", + "qcloud", + "qq", + "social", + "wechat", + "weibo" + ], + "support": { + "issues": "https://github.com/overtrue/socialite/issues", + "source": "https://github.com/overtrue/socialite/tree/4.10.1" + }, + "funding": [ + { + "url": "https://github.com/overtrue", + "type": "github" + } + ], + "time": "2024-03-08T06:41:54+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.2", @@ -2132,6 +2422,55 @@ ], "time": "2023-11-12T21:59:55+00:00" }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, { "name": "psr/clock", "version": "1.0.0", @@ -2864,6 +3203,178 @@ ], "time": "2024-04-02T06:12:27+00:00" }, + { + "name": "symfony/cache", + "version": "v6.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "b9e9b93c9817ec6c789c7943f5e54b57a041c16a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/b9e9b93c9817ec6c789c7943f5e54b57a041c16a", + "reference": "b9e9b93c9817ec6c789c7943f5e54b57a041c16a", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.3.6|^7.0" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/var-dumper": "<5.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "classmap": [ + "Traits/ValueWrapper.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v6.4.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:22:46+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/df6a1a44c890faded49a5fca33c2d5c5fd3c2197", + "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/console", "version": "v6.4.1", @@ -3224,6 +3735,177 @@ "homepage": "https://symfony.com", "time": "2023-10-31T17:30:12+00:00" }, + { + "name": "symfony/http-client", + "version": "v6.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "3683d8107cf1efdd24795cc5f7482be1eded34ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/3683d8107cf1efdd24795cc5f7482be1eded34ac", + "reference": "3683d8107cf1efdd24795cc5f7482be1eded34ac", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3.4.1", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v6.4.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:22:46+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "20414d96f391677bf80078aa55baece78b82647d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/http-foundation", "version": "v6.4.0", @@ -3901,6 +4583,82 @@ ], "time": "2023-01-26T09:26:14+00:00" }, + { + "name": "symfony/polyfill-php81", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", + "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, { "name": "symfony/polyfill-php83", "version": "v1.28.0", @@ -4055,6 +4813,89 @@ "homepage": "https://symfony.com", "time": "2023-11-17T21:06:49+00:00" }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v6.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "e8adf6b1b46d9115f5d9247fa74bbefc459680c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/e8adf6b1b46d9115f5d9247fa74bbefc459680c0", + "reference": "e8adf6b1b46d9115f5d9247fa74bbefc459680c0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/http-message": "^1.0|^2.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-kernel": "<6.2" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "php-http/discovery": "^1.15", + "psr/log": "^1.1.4|^2|^3", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^6.2|^7.0", + "symfony/http-kernel": "^6.2|^7.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "https://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v6.4.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:22:46+00:00" + }, { "name": "symfony/routing", "version": "v6.4.1", @@ -4477,6 +5318,134 @@ ], "time": "2023-11-09T08:28:32+00:00" }, + { + "name": "symfony/var-exporter", + "version": "v6.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "825f9b00c37bbe1c1691cc1aff9b5451fc9b4405" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/825f9b00c37bbe1c1691cc1aff9b5451fc9b4405", + "reference": "825f9b00c37bbe1c1691cc1aff9b5451fc9b4405", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v6.4.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:22:46+00:00" + }, + { + "name": "thenorthmemory/xml", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/TheNorthMemory/xml.git", + "reference": "6f50c63450a0b098772423f8bdc3c4ad2c4c30bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TheNorthMemory/xml/zipball/6f50c63450a0b098772423f8bdc3c4ad2c4c30bb", + "reference": "6f50c63450a0b098772423f8bdc3c4ad2c4c30bb", + "shasum": "" + }, + "require": { + "ext-libxml": "*", + "ext-simplexml": "*", + "php": ">=7.1.2" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.89 || ^1.0", + "phpunit/phpunit": "^7.5 || ^8.5.16 || ^9.3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "TheNorthMemory\\Xml\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "James ZHANG", + "homepage": "https://github.com/TheNorthMemory" + } + ], + "description": "A wrapper of the XML parser and builder", + "homepage": "https://github.com/TheNorthMemory/xml", + "keywords": [ + "xml-builder", + "xml-parser" + ], + "support": { + "issues": "https://github.com/TheNorthMemory/xml/issues", + "source": "https://github.com/TheNorthMemory/xml/tree/1.1.1" + }, + "time": "2023-01-15T06:01:13+00:00" + }, { "name": "tijsverkoyen/css-to-inline-styles", "version": "2.2.6", @@ -4681,6 +5650,105 @@ ], "time": "2022-03-08T17:03:00+00:00" }, + { + "name": "w7corp/easywechat", + "version": "6.15.1", + "source": { + "type": "git", + "url": "https://github.com/w7corp/easywechat.git", + "reference": "8902917ceeaa20354301e533ff3725f0044c04ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/w7corp/easywechat/zipball/8902917ceeaa20354301e533ff3725f0044c04ca", + "reference": "8902917ceeaa20354301e533ff3725f0044c04ca", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-fileinfo": "*", + "ext-libxml": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "ext-sodium": "*", + "nyholm/psr7": "^1.5", + "nyholm/psr7-server": "^1.0", + "overtrue/socialite": "^3.5.4|^4.0.1", + "php": ">=8.0.2", + "psr/http-client": "^1.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/polyfill-php81": "^1.25", + "symfony/psr-http-message-bridge": "^2.1.2|^6.4.0", + "thenorthmemory/xml": "^1.0" + }, + "require-dev": { + "brainmaestro/composer-git-hooks": "^2.8", + "jetbrains/phpstorm-attributes": "^1.0", + "laravel/pint": "^1.2", + "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.4.4", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/var-dumper": "^5.2" + }, + "type": "library", + "extra": { + "hooks": { + "pre-commit": [ + "composer check-style", + "composer phpstan", + "composer test" + ], + "pre-push": [ + "composer check-style" + ], + "config": { + "stop-on-failure": [ + "pre-commit", + "pre-push" + ] + } + } + }, + "autoload": { + "psr-4": { + "EasyWeChat\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "微信SDK", + "keywords": [ + "easywechat", + "sdk", + "wechat", + "weixin", + "weixin-sdk" + ], + "support": { + "issues": "https://github.com/w7corp/easywechat/issues", + "source": "https://github.com/w7corp/easywechat/tree/6.15.1" + }, + "funding": [ + { + "url": "https://github.com/overtrue", + "type": "github" + } + ], + "time": "2024-03-29T12:23:19+00:00" + }, { "name": "webmozart/assert", "version": "1.11.0", diff --git a/config/auth.php b/config/auth.php index 9548c15..1acfc20 100644 --- a/config/auth.php +++ b/config/auth.php @@ -40,6 +40,11 @@ return [ 'driver' => 'session', 'provider' => 'users', ], + + 'api' => [ + 'driver' => 'sanctum', + 'provider' => 'users', + ], ], /* diff --git a/config/easywechat.php b/config/easywechat.php new file mode 100644 index 0000000..1d6281a --- /dev/null +++ b/config/easywechat.php @@ -0,0 +1,168 @@ + [ + 'http' => [ + 'timeout' => 5.0, + ], + ], + + /* + * 公众号 + */ + // 'official_account' => [ + // 'default' => [ + // 'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', ''), // AppID + // 'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', ''), // AppSecret + // 'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', ''), // Token + // 'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', ''), // EncodingAESKey + + /* + * OAuth 配置 + * + * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login + * callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。) + * enforce_https:是否强制使用 HTTPS 跳转 + */ + // 'oauth' => [ + // 'scopes' => array_map('trim', explode(',', env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES', 'snsapi_userinfo'))), + // 'callback' => env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK', '/examples/oauth_callback.php'), + // 'enforce_https' => true, + // ], + + /** + * 接口请求相关配置,超时时间等,具体可用参数请参考: + * https://github.com/symfony/symfony/blob/6.0/src/Symfony/Contracts/HttpClient/HttpClientInterface.php#L26 + */ + //'http' => [ + // 'timeout' => 5.0, + // // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri + // 'base_uri' => 'https://api.weixin.qq.com/', + //], + // ], + // ], + + /* + * 开放平台第三方平台 + */ + // 'open_platform' => [ + // 'default' => [ + // 'app_id' => env('WECHAT_OPEN_PLATFORM_APPID', ''), + // 'secret' => env('WECHAT_OPEN_PLATFORM_SECRET', ''), + // 'token' => env('WECHAT_OPEN_PLATFORM_TOKEN', ''), + // 'aes_key' => env('WECHAT_OPEN_PLATFORM_AES_KEY', ''), + +/** + * 接口请求相关配置,超时时间等,具体可用参数请参考: + * https://github.com/symfony/symfony/blob/6.0/src/Symfony/Contracts/HttpClient/HttpClientInterface.php#L26 + */ + // 'http' => [ + // 'timeout' => 5.0, + // // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri + // 'base_uri' => 'https://api.weixin.qq.com/', + // ], + // ], + // ], + + /* + * 小程序 + */ + 'mini_app' => [ + 'default' => [ + 'app_id' => env('WECHAT_MINI_APP_APPID', ''), + 'secret' => env('WECHAT_MINI_APP_SECRET', ''), + 'token' => env('WECHAT_MINI_APP_TOKEN', ''), + 'aes_key' => env('WECHAT_MINI_APP_AES_KEY', ''), + +/** + * 接口请求相关配置,超时时间等,具体可用参数请参考: + * https://github.com/symfony/symfony/blob/6.0/src/Symfony/Contracts/HttpClient/HttpClientInterface.php#L26 + */ + 'http' => [ + 'timeout' => 5.0, + // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri + 'base_uri' => 'https://api.weixin.qq.com/', + ], + ], + ], + + /* + * 微信支付 + */ + // 'pay' => [ + // 'default' => [ + // 'app_id' => env('WECHAT_PAY_APPID', ''), + // 'mch_id' => env('WECHAT_PAY_MCH_ID', 'your-mch-id'), + // 'private_key' => '/data/private/certs/apiclient_key.pem', + // 'certificate' => '/data/private/certs/apiclient_cert.pem', + // 'notify_url' => 'http://example.com/payments/wechat-notify', // 默认支付结果通知地址 + // /** + // * 证书序列号,可通过命令从证书获取: + // * `openssl x509 -in application_cert.pem -noout -serial` + // */ + // 'certificate_serial_no' => '6F2BADBE1738B07EE45C6A85C5F86EE343CAABC3', + // + // 'http' => [ + // 'base_uri' => 'https://api.mch.weixin.qq.com/', + // ], + // + // // v2 API 秘钥 + // //'v2_secret_key' => '26db3e15cfedb44abfbb5fe94fxxxxx', + // + // // v3 API 秘钥 + // //'secret_key' => '43A03299A3C3FED3D8CE7B820Fxxxxx', + // + // // 注意 此处为微信支付平台证书 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/wechatpay5_1.shtml + // 'platform_certs' => [ + // '/data/private/certs/platform_key.pem', + // ], + // ], + // ], + + /* + * 企业微信 + */ + // 'work' => [ + // 'default' => [ + // 'corp_id' => env('WECHAT_WORK_CORP_ID', ''), + // 'secret' => env('WECHAT_WORK_SECRET', ''), + // 'token' => env('WECHAT_WORK_TOKEN', ''), + // 'aes_key' => env('WECHAT_WORK_AES_KEY', ''), + +/** + * 接口请求相关配置,超时时间等,具体可用参数请参考: + * https://github.com/symfony/symfony/blob/6.0/src/Symfony/Contracts/HttpClient/HttpClientInterface.php#L26 + */ + // 'http' => [ + // 'timeout' => 5.0, + // // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri + // 'base_uri' => 'https://api.weixin.qq.com/', + // ], + // ], + // ], + + /* + * 企业微信开放平台 + */ + // 'open_work' => [ + // 'default' => [ + // 'corp_id' => env('WECHAT_OPEN_WORK_CORP_ID', ''), + // 'provider_secret' => env('WECHAT_OPEN_WORK_SECRET', ''), + // 'token' => env('WECHAT_OPEN_WORK_TOKEN', ''), + // 'aes_key' => env('WECHAT_OPEN_WORK_AES_KEY', ''), + +/** + * 接口请求相关配置,超时时间等,具体可用参数请参考: + * https://github.com/symfony/symfony/blob/6.0/src/Symfony/Contracts/HttpClient/HttpClientInterface.php#L26 + */ + // 'http' => [ + // 'timeout' => 5.0, + // // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri + // 'base_uri' => 'https://api.weixin.qq.com/', + // ], + // ], + // ], +]; diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 1869c43..6eec5c2 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -13,16 +13,19 @@ return new class extends Migration { Schema::create('users', function (Blueprint $table) { $table->id(); - $table->string('mini_openid')->comment('小程序openid'); - $table->string('union_id')->nullable()->default('')->comment('微信唯一标识'); + $table->string('mini_openid')->unique()->comment('小程序openid'); + $table->string('union_id')->nullable()->comment('微信唯一标识'); $table->string('nick_name')->nullable()->default('')->comment('微信昵称'); $table->string('avatar')->nullable()->default('')->comment('微信头像'); $table->string('phone')->nullable()->default('')->comment('手机号'); + $table->timestamp('bind_phone_at')->nullable()->comment('绑定手机号时间'); + $table->timestamp('last_login_at')->nullable()->comment('上次登录时间'); - $table->timestamp('last_login_ip')->nullable()->comment('上次登录ip'); + $table->bigInteger('last_login_ip')->nullable()->comment('上次登录ip'); $table->rememberToken(); $table->timestamps(); + }); } diff --git a/routes/api.php b/routes/api.php index 889937e..c8e08b6 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,6 +2,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; +use App\Http\Middleware\HasBindPhone; /* |-------------------------------------------------------------------------- @@ -13,7 +14,16 @@ use Illuminate\Support\Facades\Route; | be assigned to the "api" middleware group. Make something great! | */ +Route::group(['prefix' => 'miniprogram', 'namespace' => 'Api\Miniprogram'], function () { + // code2session + Route::post('code-to-session', [App\Http\Controllers\Api\AuthController::class, 'codeToSession']); -Route::middleware('auth:sanctum')->get('/user', function (Request $request) { - return $request->user(); + Route::middleware('auth:sanctum')->group(function(){ + // 令牌刷新 + Route::post('refresh-token', [App\Http\Controllers\Api\AuthController::class, 'refreshToken']); + // 已授权绑定手机号 + Route::middleware([HasBindPhone::class])->group(function(){ + + }); + }); });