mirror of
http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore.git
synced 2026-01-15 05:35:09 +08:00
Merge branch 'feature/pest' into 'main'
单元测试PEST的引入 See merge request !1
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
vendor/
|
||||
vendor/
|
||||
.phpunit.result.cache
|
||||
.php-cs-fixer.cache
|
||||
13
.idea/HDK-Core.iml
generated
13
.idea/HDK-Core.iml
generated
@@ -4,7 +4,7 @@
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="Singularity\HDK\Core\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Singularity\HDK\Test\\Core\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Singularity\HDK\Test\Core\" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/lines-of-code" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
|
||||
@@ -131,6 +131,17 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/swoole/ide-helper" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/pestphp/pest" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/pestphp/pest-plugin" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nunomaduro/collision" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/test-time" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/pest-plugin-test-time" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/friendsofphp/php-cs-fixer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/options-resolver" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpstan/phpstan" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
||||
1
.idea/inspectionProfiles/Project_Default.xml
generated
1
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -2,5 +2,6 @@
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PhpPropertyOnlyWrittenInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="PhpStanGlobal" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
14
.idea/php-test-framework.xml
generated
Normal file
14
.idea/php-test-framework.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PhpTestFrameworkSettings">
|
||||
<test_tools>
|
||||
<tool tool_name="Pest">
|
||||
<settings>
|
||||
<configurations>
|
||||
<local_configuration configuration_file_path="$PROJECT_DIR$/phpunit.xml" executable_path="$PROJECT_DIR$/vendor/pestphp/pest/bin/pest" use_configuration_file="true" />
|
||||
</configurations>
|
||||
</settings>
|
||||
</tool>
|
||||
</test_tools>
|
||||
</component>
|
||||
</project>
|
||||
26
.idea/php.xml
generated
26
.idea/php.xml
generated
@@ -4,11 +4,20 @@
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCSFixerOptionsConfiguration">
|
||||
<option name="allowRiskyRules" value="true" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpCSFixer">
|
||||
<phpcsfixer_settings>
|
||||
<PhpCSFixerConfiguration standards="PSR1;PSR2;Symfony;DoctrineAnnotation;PHP70Migration;PHP71Migration" tool_path="$PROJECT_DIR$/vendor/friendsofphp/php-cs-fixer/php-cs-fixer" />
|
||||
</phpcsfixer_settings>
|
||||
</component>
|
||||
<component name="PhpExternalFormatter">
|
||||
<option name="externalFormatter" value="PHP_CBF" />
|
||||
</component>
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
|
||||
@@ -137,10 +146,27 @@
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
|
||||
<path value="$PROJECT_DIR$/vendor/swoole/ide-helper" />
|
||||
<path value="$PROJECT_DIR$/vendor/pestphp/pest" />
|
||||
<path value="$PROJECT_DIR$/vendor/pestphp/pest-plugin" />
|
||||
<path value="$PROJECT_DIR$/vendor/filp/whoops" />
|
||||
<path value="$PROJECT_DIR$/vendor/nunomaduro/collision" />
|
||||
<path value="$PROJECT_DIR$/vendor/facade/ignition-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/spatie/test-time" />
|
||||
<path value="$PROJECT_DIR$/vendor/spatie/pest-plugin-test-time" />
|
||||
<path value="$PROJECT_DIR$/vendor/friendsofphp/php-cs-fixer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/options-resolver" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.0" />
|
||||
<component name="PhpStan">
|
||||
<PhpStan_settings>
|
||||
<PhpStanConfiguration tool_path="$PROJECT_DIR$/vendor/bin/phpstan" />
|
||||
</PhpStan_settings>
|
||||
</component>
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="memoryLimit" value="300M" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpUnit">
|
||||
|
||||
23
.php-cs-fixer.dist.php
Normal file
23
.php-cs-fixer.dist.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* .php-cs-fixer.dist.php@HDK-Core
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/1/9
|
||||
*/
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()->in([
|
||||
__DIR__ . '/publish',
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
]);
|
||||
|
||||
$config = new PhpCsFixer\Config();
|
||||
return $config->setRules([
|
||||
'@PSR12' => true,
|
||||
'strict_param' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
])
|
||||
->setUsingCache(false)
|
||||
->setFinder($finder);
|
||||
@@ -39,15 +39,19 @@
|
||||
"teapot/status-code": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"swoole/ide-helper": "*",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"alibabacloud/dysmsapi-20170525": "^2.0",
|
||||
"firebase/php-jwt": "^6.1",
|
||||
"friendsofphp/php-cs-fixer": "^3.13",
|
||||
"guzzlehttp/guzzle": "^7.5",
|
||||
"hyperf/session": "^2.2",
|
||||
"hyperf/validation": "^2.2",
|
||||
"symfony/mailer": "^6.0",
|
||||
"pestphp/pest": "^1.22",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"alibabacloud/dysmsapi-20170525": "^2.0.9"
|
||||
"spatie/pest-plugin-test-time": "^1.1",
|
||||
"swoole/ide-helper": "*",
|
||||
"symfony/mailer": "^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"firebase/php-jwt": "JWT 鉴权必需",
|
||||
@@ -68,16 +72,22 @@
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Singularity\\HDK\\Test\\\\Core\\": "tests/"
|
||||
"Singularity\\HDK\\Test\\Core\\": "tests/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"scripts": {
|
||||
"post-root-package-install": [],
|
||||
"test": "vendor/bin/phpunit --prepend test/bootstrap.php -c phpunit.xml --colors=always",
|
||||
"cs-fix": "php-cs-fixer fix $1",
|
||||
"analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config"
|
||||
"test": "vendor/bin/pest $1",
|
||||
"cs-fix": "vendor/bin/php-cs-fixer fix $1 --rules=@PSR12 --allow-risky=yes",
|
||||
"analyse": "vendor/bin/phpstan analyse $1",
|
||||
"ci": [
|
||||
"@analyse publish/ src/ tests/",
|
||||
"@cs-fix",
|
||||
"@test --ci",
|
||||
"echo CI Success"
|
||||
]
|
||||
},
|
||||
"repositories": {
|
||||
"lux-map": {
|
||||
|
||||
600
composer.lock
generated
600
composer.lock
generated
@@ -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": "539f315413216a83cfb505b9a06fe2c1",
|
||||
"content-hash": "8725cce0321e7f830ec9ac4994183116",
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/ca-bundle",
|
||||
@@ -439,11 +439,11 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"version": "1.14.1",
|
||||
"version": "1.14.2",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/doctrine/annotations/1.14.1/doctrine-annotations-1.14.1.zip",
|
||||
"reference": "9e034d7a70032d422169f27d8759e8d84abb4f51",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/doctrine/annotations/1.14.2/doctrine-annotations-1.14.2.zip",
|
||||
"reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -501,7 +501,7 @@
|
||||
"docblock",
|
||||
"parser"
|
||||
],
|
||||
"time": "2022-12-12T12:46:12+00:00"
|
||||
"time": "2022-12-15T06:48:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
@@ -4369,12 +4369,110 @@
|
||||
"time": "2022-06-18T20:57:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.3.1",
|
||||
"name": "facade/ignition-contracts",
|
||||
"version": "1.0.2",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/firebase/php-jwt/v6.3.1/firebase-php-jwt-v6.3.1.zip",
|
||||
"reference": "ddfaddcb520488b42bca3a75e17e9dd53c3667da",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/facade/ignition-contracts/1.0.2/facade-ignition-contracts-1.0.2.zip",
|
||||
"reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^v2.15.8",
|
||||
"phpunit/phpunit": "^9.3.11",
|
||||
"vimeo/psalm": "^3.17.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facade\\IgnitionContracts\\": "src"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://flareapp.io",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Solution contracts for Ignition",
|
||||
"homepage": "https://github.com/facade/ignition-contracts",
|
||||
"keywords": [
|
||||
"contracts",
|
||||
"flare",
|
||||
"ignition"
|
||||
],
|
||||
"time": "2020-10-16T08:27:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.14.6",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/filp/whoops/2.14.6/filp-whoops-2.14.6.zip",
|
||||
"reference": "f7948baaa0330277c729714910336383286305da",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9 || ^7.0 || ^8.0",
|
||||
"psr/log": "^1.0.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9 || ^1.0",
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3",
|
||||
"symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
|
||||
"whoops/soap": "Formats errors as SOAP responses"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Whoops\\": "src/Whoops/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Filipe Dobreira",
|
||||
"homepage": "https://github.com/filp",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "php error handling for cool kids",
|
||||
"homepage": "https://filp.github.io/whoops/",
|
||||
"keywords": [
|
||||
"error",
|
||||
"exception",
|
||||
"handling",
|
||||
"library",
|
||||
"throwable",
|
||||
"whoops"
|
||||
],
|
||||
"time": "2022-11-02T16:23:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.3.2",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/firebase/php-jwt/v6.3.2/firebase-php-jwt-v6.3.2.zip",
|
||||
"reference": "ea7dda77098b96e666c5ef382452f94841e439cd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4418,7 +4516,80 @@
|
||||
"jwt",
|
||||
"php"
|
||||
],
|
||||
"time": "2022-11-01T21:20:08+00:00"
|
||||
"time": "2022-12-19T17:10:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.13.2",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/friendsofphp/php-cs-fixer/v3.13.2/friendsofphp-php-cs-fixer-v3.13.2.zip",
|
||||
"reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/semver": "^3.2",
|
||||
"composer/xdebug-handler": "^3.0.3",
|
||||
"doctrine/annotations": "^1.13",
|
||||
"ext-json": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"sebastian/diff": "^4.0",
|
||||
"symfony/console": "^5.4 || ^6.0",
|
||||
"symfony/event-dispatcher": "^5.4 || ^6.0",
|
||||
"symfony/filesystem": "^5.4 || ^6.0",
|
||||
"symfony/finder": "^5.4 || ^6.0",
|
||||
"symfony/options-resolver": "^5.4 || ^6.0",
|
||||
"symfony/polyfill-mbstring": "^1.23",
|
||||
"symfony/polyfill-php80": "^1.25",
|
||||
"symfony/polyfill-php81": "^1.25",
|
||||
"symfony/process": "^5.4 || ^6.0",
|
||||
"symfony/stopwatch": "^5.4 || ^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"justinrainbow/json-schema": "^5.2",
|
||||
"keradus/cli-executor": "^2.0",
|
||||
"mikey179/vfsstream": "^1.6.10",
|
||||
"php-coveralls/php-coveralls": "^2.5.2",
|
||||
"php-cs-fixer/accessible-object": "^1.1",
|
||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2",
|
||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1",
|
||||
"phpspec/prophecy": "^1.15",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"phpunitgoodpractices/polyfill": "^1.6",
|
||||
"phpunitgoodpractices/traits": "^1.9.2",
|
||||
"symfony/phpunit-bridge": "^6.0",
|
||||
"symfony/yaml": "^5.4 || ^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "For handling output formats in XML",
|
||||
"ext-mbstring": "For handling non-UTF8 characters."
|
||||
},
|
||||
"bin": [
|
||||
"php-cs-fixer"
|
||||
],
|
||||
"type": "application",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpCsFixer\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Dariusz Rumiński",
|
||||
"email": "dariusz.ruminski@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A tool to automatically fix PHP code style",
|
||||
"time": "2023-01-02T23:53:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
@@ -4848,6 +5019,191 @@
|
||||
],
|
||||
"time": "2022-03-03T13:19:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
"version": "v5.11.0",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/nunomaduro/collision/v5.11.0/nunomaduro-collision-v5.11.0.zip",
|
||||
"reference": "8b610eef8582ccdc05d8f2ab23305e2d37049461",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"facade/ignition-contracts": "^1.0",
|
||||
"filp/whoops": "^2.14.3",
|
||||
"php": "^7.3 || ^8.0",
|
||||
"symfony/console": "^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"brianium/paratest": "^6.1",
|
||||
"fideloper/proxy": "^4.4.1",
|
||||
"fruitcake/laravel-cors": "^2.0.3",
|
||||
"laravel/framework": "8.x-dev",
|
||||
"nunomaduro/larastan": "^0.6.2",
|
||||
"nunomaduro/mock-final-classes": "^1.0",
|
||||
"orchestra/testbench": "^6.0",
|
||||
"phpstan/phpstan": "^0.12.64",
|
||||
"phpunit/phpunit": "^9.5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"NunoMaduro\\Collision\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nuno Maduro",
|
||||
"email": "enunomaduro@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Cli error handling for console/command-line PHP applications.",
|
||||
"keywords": [
|
||||
"artisan",
|
||||
"cli",
|
||||
"command-line",
|
||||
"console",
|
||||
"error",
|
||||
"handling",
|
||||
"laravel",
|
||||
"laravel-zero",
|
||||
"php",
|
||||
"symfony"
|
||||
],
|
||||
"time": "2022-01-10T16:22:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pestphp/pest",
|
||||
"version": "v1.22.3",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/pestphp/pest/v1.22.3/pestphp-pest-v1.22.3.zip",
|
||||
"reference": "b58a020423e9ad16c8bb8781927d516adae00da4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"nunomaduro/collision": "^5.11.0|^6.3.0",
|
||||
"pestphp/pest-plugin": "^1.1.0",
|
||||
"php": "^7.3 || ^8.0",
|
||||
"phpunit/phpunit": "^9.5.26"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/console": "^8.83.26",
|
||||
"illuminate/support": "^8.83.26",
|
||||
"laravel/dusk": "^6.25.2",
|
||||
"pestphp/pest-dev-tools": "^1.0.0",
|
||||
"pestphp/pest-plugin-parallel": "^1.2"
|
||||
},
|
||||
"bin": [
|
||||
"bin/pest"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-1.x": "1.x-dev"
|
||||
},
|
||||
"pest": {
|
||||
"plugins": [
|
||||
"Pest\\Plugins\\Coverage",
|
||||
"Pest\\Plugins\\Init",
|
||||
"Pest\\Plugins\\Version",
|
||||
"Pest\\Plugins\\Environment"
|
||||
]
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Pest\\Laravel\\PestServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Functions.php",
|
||||
"src/Pest.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Pest\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nuno Maduro",
|
||||
"email": "enunomaduro@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "An elegant PHP Testing Framework.",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"pest",
|
||||
"php",
|
||||
"test",
|
||||
"testing",
|
||||
"unit"
|
||||
],
|
||||
"time": "2022-12-07T14:31:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pestphp/pest-plugin",
|
||||
"version": "v1.1.0",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/pestphp/pest-plugin/v1.1.0/pestphp-pest-plugin-v1.1.0.zip",
|
||||
"reference": "606c5f79c6a339b49838ffbee0151ca519efe378",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.1.0 || ^2.0.0",
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"pestphp/pest": "<1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^2.4.2",
|
||||
"pestphp/pest": "^1.22.1",
|
||||
"pestphp/pest-dev-tools": "^1.0.0"
|
||||
},
|
||||
"type": "composer-plugin",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
},
|
||||
"class": "Pest\\Plugin\\Manager"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Pest\\Plugin\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "The Pest plugin manager",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"manager",
|
||||
"pest",
|
||||
"php",
|
||||
"plugin",
|
||||
"test",
|
||||
"testing",
|
||||
"unit"
|
||||
],
|
||||
"time": "2022-09-18T13:18:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
"version": "2.0.3",
|
||||
@@ -4939,6 +5295,41 @@
|
||||
"description": "Library for handling version information and constraints",
|
||||
"time": "2022-02-21T01:04:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.9.8",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/phpstan/phpstan/1.9.8/phpstan-phpstan-1.9.8.zip",
|
||||
"reference": "45411d15bf85a33b4a8ee9b75a6e82998c9adb97",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2|^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan-shim": "*"
|
||||
},
|
||||
"bin": [
|
||||
"phpstan",
|
||||
"phpstan.phar"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHPStan - PHP Static Analysis Tool",
|
||||
"keywords": [
|
||||
"dev",
|
||||
"static analysis"
|
||||
],
|
||||
"time": "2023-01-08T21:26:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.22",
|
||||
@@ -5384,7 +5775,7 @@
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/roave/security-advisories/dev-latest/roave-security-advisories-dev-latest.zip",
|
||||
"reference": "326a87e33bf91da7161ad24a6f7ab5d2bb63077a",
|
||||
"reference": "ef9dca6c49faa06e7203bbed30411e26e474a8fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"conflict": {
|
||||
@@ -5439,7 +5830,7 @@
|
||||
"cesnet/simplesamlphp-module-proxystatistics": "<3.1",
|
||||
"codeception/codeception": "<3.1.3|>=4,<4.1.22",
|
||||
"codeigniter/framework": "<=3.0.6",
|
||||
"codeigniter4/framework": "<4.2.7",
|
||||
"codeigniter4/framework": "<4.2.11",
|
||||
"codeigniter4/shield": "= 1.0.0-beta",
|
||||
"codiad/codiad": "<=2.8.4",
|
||||
"composer/composer": "<1.10.26|>=2-alpha.1,<2.2.12|>=2.3,<2.3.5",
|
||||
@@ -5523,7 +5914,7 @@
|
||||
"friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
|
||||
"friendsoftypo3/mediace": ">=7.6.2,<7.6.5",
|
||||
"froala/wysiwyg-editor": "<3.2.7",
|
||||
"froxlor/froxlor": "<0.10.39",
|
||||
"froxlor/froxlor": "<0.10.39|>=2-beta.0,<2-beta.1",
|
||||
"fuel/core": "<1.8.1",
|
||||
"gaoming13/wechat-php-sdk": "<=1.10.2",
|
||||
"genix/cms": "<=1.1.11",
|
||||
@@ -5611,6 +6002,7 @@
|
||||
"melisplatform/melis-cms": "<5.0.1",
|
||||
"melisplatform/melis-front": "<5.0.1",
|
||||
"mezzio/mezzio-swoole": "<3.7|>=4,<4.3",
|
||||
"mgallegos/laravel-jqgrid": "<=1.3",
|
||||
"microweber/microweber": "<=1.3.1",
|
||||
"miniorange/miniorange-saml": "<1.4.3",
|
||||
"mittwald/typo3_forum": "<1.2.1",
|
||||
@@ -5742,7 +6134,7 @@
|
||||
"simplito/elliptic-php": "<1.0.6",
|
||||
"slim/slim": "<2.6",
|
||||
"smarty/smarty": "<3.1.47|>=4,<4.2.1",
|
||||
"snipe/snipe-it": "<6.0.11|>= 6.0.0-RC-1, <= 6.0.0-RC-5",
|
||||
"snipe/snipe-it": "<=6.0.14|>= 6.0.0-RC-1, <= 6.0.0-RC-5",
|
||||
"socalnick/scn-social-auth": "<1.15.2",
|
||||
"socialiteproviders/steam": "<1.1",
|
||||
"spatie/browsershot": "<3.57.4",
|
||||
@@ -5807,13 +6199,13 @@
|
||||
"tinymce/tinymce": "<5.10.7|>=6,<6.3.1",
|
||||
"titon/framework": ">=0,<9.9.99",
|
||||
"tobiasbg/tablepress": "<= 2.0-RC1",
|
||||
"topthink/framework": "<=6.0.13",
|
||||
"topthink/framework": "<6.0.14",
|
||||
"topthink/think": "<=6.0.9",
|
||||
"topthink/thinkphp": "<=3.2.3",
|
||||
"tribalsystems/zenario": "<=9.3.57595",
|
||||
"truckersmp/phpwhois": "<=4.3.1",
|
||||
"twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3",
|
||||
"typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.33|>=11,<11.5.20|>=12,<12.1.1",
|
||||
"typo3/cms": "<2.0.5|>=3,<3.0.3|>=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.33|>=11,<11.5.20|>=12,<12.1.1",
|
||||
"typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
||||
"typo3/cms-core": "<8.7.49|>=9,<9.5.38|>=10,<10.4.33|>=11,<11.5.20|>=12,<12.1.1",
|
||||
"typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
||||
@@ -5851,7 +6243,7 @@
|
||||
"yiisoft/yii2-bootstrap": "<2.0.4",
|
||||
"yiisoft/yii2-dev": "<2.0.43",
|
||||
"yiisoft/yii2-elasticsearch": "<2.0.5",
|
||||
"yiisoft/yii2-gii": "<2.0.4",
|
||||
"yiisoft/yii2-gii": "<=2.2.4",
|
||||
"yiisoft/yii2-jui": "<2.0.4",
|
||||
"yiisoft/yii2-redis": "<2.0.8",
|
||||
"yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6",
|
||||
@@ -5902,7 +6294,7 @@
|
||||
}
|
||||
],
|
||||
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
|
||||
"time": "2022-12-19T08:05:12+00:00"
|
||||
"time": "2023-01-04T14:04:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
@@ -6612,6 +7004,95 @@
|
||||
"homepage": "https://github.com/sebastianbergmann/version",
|
||||
"time": "2020-09-28T06:39:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/pest-plugin-test-time",
|
||||
"version": "1.1.1",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/spatie/pest-plugin-test-time/1.1.1/spatie-pest-plugin-test-time-1.1.1.zip",
|
||||
"reference": "1ca56762948ceded0225ecd5b90bfc4bb48a0229",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"nesbot/carbon": "^2.50",
|
||||
"pestphp/pest": "^1.10",
|
||||
"php": "^8.0",
|
||||
"spatie/test-time": "^1.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Spatie\\PestPluginTestTime\\": "src"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A Pest plugin to control the flow of time",
|
||||
"homepage": "https://github.com/spatie/pest-plugin-test-time",
|
||||
"keywords": [
|
||||
"pest-plugin-test-time",
|
||||
"spatie"
|
||||
],
|
||||
"time": "2022-06-05T13:57:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/test-time",
|
||||
"version": "1.3.0",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/spatie/test-time/1.3.0/spatie-test-time-1.3.0.zip",
|
||||
"reference": "5738d4bff591d896d443785c6d787eb8cfa20e27",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"nesbot/carbon": "^2.54",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5.10"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\TestTime\\": "src"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Alex Vanderbist",
|
||||
"email": "alex@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A small package to control the flow time",
|
||||
"homepage": "https://github.com/spatie/test-time",
|
||||
"keywords": [
|
||||
"spatie",
|
||||
"test-time"
|
||||
],
|
||||
"time": "2022-02-04T08:55:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swoole/ide-helper",
|
||||
"version": "5.0.1",
|
||||
@@ -6860,6 +7341,50 @@
|
||||
],
|
||||
"time": "2022-11-28T12:25:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v6.0.3",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/symfony/options-resolver/v6.0.3/symfony-options-resolver-v6.0.3.zip",
|
||||
"reference": "51f7006670febe4cbcbae177cbffe93ff833250d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"symfony/deprecation-contracts": "^2.1|^3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\OptionsResolver\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides an improved replacement for the array_replace PHP function",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"config",
|
||||
"configuration",
|
||||
"options"
|
||||
],
|
||||
"time": "2022-01-02T09:55:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.27.0",
|
||||
@@ -6977,6 +7502,45 @@
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v6.0.13",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/symfony/stopwatch/v6.0.13/symfony-stopwatch-v6.0.13.zip",
|
||||
"reference": "7554fde6848af5ef1178f8ccbdbdb8ae1092c70a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"symfony/service-contracts": "^1|^2|^3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Stopwatch\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides a way to profile code",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2022-09-28T15:52:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
"version": "1.2.1",
|
||||
|
||||
9
phpstan.dist.neon
Normal file
9
phpstan.dist.neon
Normal file
@@ -0,0 +1,9 @@
|
||||
parameters:
|
||||
level: 6
|
||||
paths:
|
||||
- publish
|
||||
- src
|
||||
- tests
|
||||
ignoreErrors:
|
||||
- '#Constant BASE_PATH not found#'
|
||||
- '#Property [a-zA-Z0-9\\_]+::\$[a-zA-Z0-9]+ is never written, only read.#'
|
||||
15
phpunit.xml
15
phpunit.xml
@@ -1,9 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd">
|
||||
<coverage/>
|
||||
<testsuites>
|
||||
<testsuite name="Example">
|
||||
<directory>./tests/Example/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php"
|
||||
colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd">
|
||||
<coverage/>
|
||||
<testsuites>
|
||||
<testsuite name="Unit">
|
||||
<directory>./tests/Unit/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
|
||||
@@ -17,18 +17,18 @@ return [
|
||||
'message_name' => 'message', // 错误信息名称
|
||||
'data_name' => 'data', // 响应数据字段名称
|
||||
],
|
||||
|
||||
|
||||
// 鉴权相关
|
||||
'token' => [
|
||||
// jwt 必需,否则无效
|
||||
'jwt' => [
|
||||
// 过期时间
|
||||
'expire_time' => 30 * 24 * 60 * 60,
|
||||
|
||||
|
||||
'private_key' => '', // 用于加密 jwt
|
||||
'public_key' => '', // 用于解密 jwt
|
||||
],
|
||||
|
||||
|
||||
// session 必需,否则无效
|
||||
'session' => [
|
||||
// 'expire_time' => null, // 始终为 session 的过期时间
|
||||
@@ -39,7 +39,7 @@ return [
|
||||
'prefix_key' => 'token:',
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
// redis 补充配置
|
||||
'redis' => [
|
||||
'prefix' => sprintf(
|
||||
@@ -48,7 +48,7 @@ return [
|
||||
env('APP_ENV', 'product')
|
||||
), // 强烈建议按此格式划分
|
||||
],
|
||||
|
||||
|
||||
// account http请求配置
|
||||
'http_request' => [
|
||||
'account' => [
|
||||
@@ -56,7 +56,7 @@ return [
|
||||
'rpc_base_uri' => env('RPC_BASE_URI', ''),
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
// 第三方服务
|
||||
'third_party' => [
|
||||
'email' => [
|
||||
@@ -79,4 +79,4 @@ return [
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
];
|
||||
|
||||
@@ -25,7 +25,7 @@ return [
|
||||
'delete' => 'An internal error is occurred, try again later',
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
// 参数校验
|
||||
'params' => [
|
||||
'method' => [
|
||||
@@ -33,7 +33,7 @@ return [
|
||||
],
|
||||
// 参数非法
|
||||
'format_error' => 'Format error :param',
|
||||
|
||||
|
||||
// 数据错误
|
||||
'error' => [
|
||||
'default' => 'Failed verification',
|
||||
@@ -75,7 +75,7 @@ return [
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
// 鉴权
|
||||
'auth' => [
|
||||
'default' => 'Please login',
|
||||
@@ -120,7 +120,7 @@ return [
|
||||
'default' => 'Please login',
|
||||
]
|
||||
],
|
||||
|
||||
|
||||
// 服务出错
|
||||
'server' => [
|
||||
'cache' => [
|
||||
@@ -146,7 +146,7 @@ return [
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
'not_found' => [
|
||||
'route' => [
|
||||
'default' => 'The route does not exist',
|
||||
|
||||
@@ -25,7 +25,7 @@ return [
|
||||
'delete' => '服务器开小差了,稍后再来试试吧',
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
// 参数校验
|
||||
'params' => [
|
||||
'method' => [
|
||||
@@ -33,7 +33,7 @@ return [
|
||||
],
|
||||
// 参数非法
|
||||
'format_error' => '参数 :param 格式错误',
|
||||
|
||||
|
||||
// 数据错误
|
||||
'error' => [
|
||||
'default' => '校验失败',
|
||||
@@ -77,7 +77,7 @@ return [
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
// 鉴权
|
||||
'auth' => [
|
||||
'default' => '请先登录',
|
||||
@@ -129,7 +129,7 @@ return [
|
||||
'default' => '登录失效,请重新登录',
|
||||
]
|
||||
],
|
||||
|
||||
|
||||
// 服务出错
|
||||
'server' => [
|
||||
'cache' => [
|
||||
@@ -155,7 +155,7 @@ return [
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
'not_found' => [
|
||||
'route' => [
|
||||
'default' => '当前路由不存在',
|
||||
|
||||
@@ -17,8 +17,10 @@ use Hyperf\Framework\Logger\StdoutLogger;
|
||||
|
||||
class ConfigProvider
|
||||
{
|
||||
/** @phpstan-ignore-next-line */
|
||||
public function __invoke(): array
|
||||
{
|
||||
/** @noinspection PhpUndefinedConstantInspection */
|
||||
return [
|
||||
// 合并到 config/autoload/dependencies.php 文件
|
||||
'dependencies' => [
|
||||
|
||||
@@ -23,288 +23,288 @@ use Hyperf\Constants\Annotation\Constants;
|
||||
class CommonErrorCode extends AbstractConstants
|
||||
{
|
||||
// =============== 9 服务器异常 =================
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.server_common_error")
|
||||
*/
|
||||
public const SERVER_ERROR = 9000000;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.program.default")
|
||||
*/
|
||||
public const PROGRAM_ERROR = 9000000;
|
||||
|
||||
|
||||
// 901 逻辑错误
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.program.syntax.default")
|
||||
*/
|
||||
public const PROGRAM_SYNTAX_ERROR = 9010001;
|
||||
|
||||
|
||||
// 902 SQL 错误
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.program.sql.default")
|
||||
*/
|
||||
public const PROGRAM_SQL_ERROR = 9020001;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.program.sql.update")
|
||||
*/
|
||||
public const PROGRAM_SQL_UPDATE_ERROR = 9020101;
|
||||
|
||||
|
||||
// 90201 字段不存在
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.program.sql.column_not_found")
|
||||
*/
|
||||
public const PROGRAM_SQL_COLUMN_NOT_FOUND = 9020101;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.program.sql.insert")
|
||||
*/
|
||||
public const PROGRAM_SQL_INSERT_ERROR = 9020201;
|
||||
|
||||
|
||||
// =============== 1 请求错误 =================
|
||||
// 101 请求方式有误
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.method.default")
|
||||
*/
|
||||
public const REQUEST_METHOD_ERROR = 1010001;
|
||||
|
||||
|
||||
// 102 参数非法
|
||||
|
||||
|
||||
/**
|
||||
* 参数非法.
|
||||
* @Message("common_error.params.format_error")
|
||||
*/
|
||||
public const FORMATTER_ERROR = 1020001;
|
||||
|
||||
|
||||
/**
|
||||
* 缺少参数.
|
||||
* @Message("common_error.params.error.default")
|
||||
*/
|
||||
public const REQUEST_PARAMS_MISS = 1020002;
|
||||
|
||||
|
||||
/**
|
||||
* 签名非法.
|
||||
* @Message("common_error.params.error.default")
|
||||
*/
|
||||
public const REQUEST_SIGN_ERROR = 1020003;
|
||||
|
||||
|
||||
|
||||
|
||||
// 103 参数错误
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.default")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR = 1030001;
|
||||
|
||||
|
||||
// 10301 用户信息错误
|
||||
/**
|
||||
* @Message("common_error.params.error.user.default")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER = 1030101;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.sign_up.default")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_REGISTERED = 1030102;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.username.unique")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_USERNAME_UNIQUE = 1030111;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.sec_phone.unique")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_SEC_PHONE_UNIQUE = 1030121;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.sec_phone.required")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_SEC_PHONE_REQUIRED = 1030122;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.sec_phone.undefined")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_SEC_PHONE_UNDEFINED = 1030123;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.sec_email.unique")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_SEC_EMAIL_UNIQUE = 1030131;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.sec_email.required")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_SEC_EMAIL_REQUIRED = 1030132;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.sec_email.undefined")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_SEC_EMAIL_UNDEFINED = 1030133;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.user.action.error")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_USER_ACTION_ERROR = 1030141;
|
||||
|
||||
|
||||
// 10302 验证码错误
|
||||
/**
|
||||
* @Message("common_error.params.error.code.error")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_CODE_ERROR = 1030201;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.code.timeout")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_CODE_TIMEOUT = 1030202;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.code.limit.minute")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_MINUTE = 1030301;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.code.limit.hour")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_HOUR = 1030302;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.code.limit.day")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_DAY = 1030303;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.target.format")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_TARGET_FORMAT = 1030401;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.params.error.target.missing")
|
||||
*/
|
||||
public const REQUEST_PARAMS_ERROR_TARGET_MISSING = 1030402;
|
||||
|
||||
|
||||
// =============== 2 鉴权问题 =================
|
||||
// 201 JWT 鉴权失败
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.default")
|
||||
*/
|
||||
public const UNAUTHORIZED = 200000;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.jwt.default")
|
||||
*/
|
||||
public const AUTH_JWT_ERROR = 201000;
|
||||
|
||||
|
||||
// 20101 验证
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.jwt.iat")
|
||||
*/
|
||||
public const AUTH_JWT_IAT_ERROR = 2010101;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.jwt.nbf")
|
||||
*/
|
||||
public const AUTH_JWT_NBF_ERROR = 2010102;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.jwt.exp")
|
||||
*/
|
||||
public const AUTH_JWT_EXP_TIMEOUT = 2010103;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.jwt.iss")
|
||||
*/
|
||||
public const AUTH_JWT_ISS_ERROR = 2010104;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.jwt.uid")
|
||||
*/
|
||||
public const AUTH_JWT_UID_ERROR = 2010105;
|
||||
|
||||
|
||||
// 202 Session 鉴权
|
||||
/**
|
||||
* @Message("common_error.auth.session.default")
|
||||
*/
|
||||
public const AUTH_SESSION_ERROR = 202000;
|
||||
|
||||
|
||||
// 20201 验证
|
||||
/**
|
||||
* @Message("common_error.auth.session.uid")
|
||||
*/
|
||||
public const AUTH_SESSION_UID_ERROR = 2020101;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.session.created_at")
|
||||
*/
|
||||
public const AUTH_SESSION_CREATED_AT_ERROR = 2020102;
|
||||
|
||||
|
||||
|
||||
|
||||
// 203 SAML 鉴权
|
||||
/**
|
||||
* @Message("common_error.auth.saml.default")
|
||||
*/
|
||||
public const AUTH_SAML_ERROR = 203000;
|
||||
|
||||
|
||||
// 20301 验证
|
||||
/**
|
||||
* @Message("common_error.auth.saml.params.default")
|
||||
*/
|
||||
public const AUTH_SAML_REQUEST_PARAMS_ERROR = 2030100;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.saml.params.saml_request")
|
||||
*/
|
||||
public const AUTH_SAML_REQUEST_PARAMS_SAML_REQUEST = 2030101;
|
||||
|
||||
|
||||
|
||||
|
||||
// 204 无权访问
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.forbidden.default")
|
||||
*/
|
||||
public const FORBIDDEN = 204000;
|
||||
|
||||
|
||||
// 20401 无权访问
|
||||
/**
|
||||
* @Message("common_error.auth.forbidden.read.default")
|
||||
*/
|
||||
public const FORBIDDEN_READ_ERROR = 2040101;
|
||||
|
||||
|
||||
// 20402 无权修改
|
||||
/**
|
||||
* @Message("common_error.auth.forbidden.update.default")
|
||||
*/
|
||||
public const FORBIDDEN_UPDATE_ERROR = 2040201;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.forbidden.update.address.unique")
|
||||
*/
|
||||
public const FORBIDDEN_UPDATE_ADDRESS_DEFAULT_UNIQUE_ERROR = 2040211;
|
||||
|
||||
|
||||
// 20403 无权创建
|
||||
/**
|
||||
* @Message("common_error.auth.forbidden.create.default")
|
||||
*/
|
||||
public const FORBIDDEN_CREATE_ERROR = 2040301;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.forbidden.create.wechat.redundant")
|
||||
*/
|
||||
public const FORBIDDEN_CREATE_WECHAT_REDUNDANT_ERROR = 2040311;
|
||||
|
||||
|
||||
// 20404 无权删除
|
||||
/**
|
||||
* @Message("common_error.auth.forbidden.delete.default")
|
||||
*/
|
||||
public const FORBIDDEN_DELETE_ERROR = 2040401;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.auth.forbidden.delete.wechat.only")
|
||||
*/
|
||||
@@ -315,82 +315,82 @@ class CommonErrorCode extends AbstractConstants
|
||||
* @Message("common_error.auth.app.default")
|
||||
*/
|
||||
public const AUTH_APP_ERROR = 205000;
|
||||
|
||||
|
||||
// ============== 3 依赖服务出错 ===============
|
||||
// 303 缓存异常
|
||||
// 30301 Redis 异常
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.server.cache.redis.default")
|
||||
*/
|
||||
public const SERVER_CACHE_REDIS_ERROR = 3030101;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.server.cache.redis.refused")
|
||||
*/
|
||||
public const SERVER_CACHE_REDIS_REFUSED_ERROR = 3030110;
|
||||
|
||||
|
||||
// 30302 SMS 异常
|
||||
/**
|
||||
* @Message("common_error.server.dependency_sms_common_error")
|
||||
*/
|
||||
public const SERVER_DEPENDENCY_SMS_ERROR = 3030201;
|
||||
|
||||
|
||||
// 30303 微信错误
|
||||
/**
|
||||
* @Message("common_error.server.dependency.wechat.default")
|
||||
*/
|
||||
public const SERVER_DEPENDENCY_WECHAT_ERROR = 3030301;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.server.dependency.wechat.code")
|
||||
*/
|
||||
public const SERVER_DEPENDENCY_WECHAT_CODE_ERROR = 3030302;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.server.dependency.wechat.timeout")
|
||||
*/
|
||||
public const SERVER_DEPENDENCY_WECHAT_CODE_TIMEOUT_ERROR = 3030311;
|
||||
|
||||
|
||||
// 306 消息异常
|
||||
// 30601 自建邮箱发件服务异常
|
||||
/**
|
||||
* @Message("common_error.server.message.email.default")
|
||||
*/
|
||||
public const SERVER_MESSAGE_EMAIL_ERROR = 3060101;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.server.message.email.not_found")
|
||||
*/
|
||||
public const SERVER_MESSAGE_EMAIL_NOT_FOUND = 3060102;
|
||||
|
||||
|
||||
// =============== 4 资源不存在 ================
|
||||
// 401 路由不存在
|
||||
/**
|
||||
* @Message("common_error.not_found.route.default")
|
||||
*/
|
||||
public const ROUTE_NOT_FOUND = 4010001;
|
||||
|
||||
|
||||
// 402 模型不存在
|
||||
/**
|
||||
* @Message("common_error.model.not_found")
|
||||
*/
|
||||
public const MODEL_NOT_FOUND = 4020001;
|
||||
|
||||
|
||||
// 40201 用户不存在
|
||||
/**
|
||||
* @Message("common_error.model.user.default")
|
||||
* @note !!!这个码一定不要改,前端根据这个做判断了!!!!
|
||||
*/
|
||||
public const USER_NOT_FOUND = 4020101;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.model.user.not_valid")
|
||||
*/
|
||||
public const USER_NOT_VALID = 4020102;
|
||||
|
||||
|
||||
/**
|
||||
* @Message("common_error.model.document.default")
|
||||
*/
|
||||
public const DOCUMENT_NOT_EXISTS = 4020201;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ abstract class AbstractController
|
||||
use DontSerialise;
|
||||
use DontDeserialise;
|
||||
use DontToString;
|
||||
|
||||
|
||||
/**
|
||||
* @Inject
|
||||
* @var ContainerInterface
|
||||
@@ -53,17 +53,16 @@ abstract class AbstractController
|
||||
* @var RequestInterface
|
||||
*/
|
||||
protected RequestInterface $request;
|
||||
|
||||
|
||||
/**
|
||||
* @Inject
|
||||
* @var ResponseInterface
|
||||
*/
|
||||
protected ResponseInterface $response;
|
||||
|
||||
|
||||
/**
|
||||
* @Inject
|
||||
* @var \Hyperf\Contract\StdoutLoggerInterface
|
||||
*/
|
||||
protected StdoutLoggerInterface $stdoutLogger;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,4 @@ interface Authentication extends
|
||||
AWS,
|
||||
SM3
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,4 +25,4 @@ interface SM3
|
||||
* @link http://www.sca.gov.cn/sca/xwdt/2010-12/17/1002389/files/302a3ada057c4a73830536d03e683110.pdf SM3密码杂凑算法
|
||||
*/
|
||||
public const SCRAM_SM3 = 'SCRAM-SM3';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,5 +22,4 @@ interface RFC4559
|
||||
* @link https://www.ietf.org/rfc/rfc4559.txt RFC 4559
|
||||
*/
|
||||
public const NEGOTIATE_NTLM = 'Negotiate';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,4 @@ interface RFC6750
|
||||
* @codingStandardsIgnoreEnd
|
||||
*/
|
||||
public const Bearer = 'Bearer';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,4 @@ interface RFC7486
|
||||
* @codingStandardsIgnoreEnd
|
||||
*/
|
||||
public const HOBA = 'HOBA';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,5 +31,4 @@ interface RFC7616
|
||||
* @codingStandardsIgnoreStart
|
||||
*/
|
||||
public const DIGEST = Header::DIGEST;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,4 @@ interface RFC7617
|
||||
* @codingStandardsIgnoreEnd
|
||||
*/
|
||||
public const BASIC = 'Basic';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ interface RFC7804
|
||||
* @link https://datatracker.ietf.org/doc/html/rfc7804 RFC 7804
|
||||
*/
|
||||
public const SCRAM_SHA_256 = 'SCRAM-SHA-256';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,4 @@ interface RFC8120
|
||||
* @link https://datatracker.ietf.org/doc/html/rfc8120 RFC 8120
|
||||
*/
|
||||
public const MUTUAL = 'Mutual';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ interface RFC8292
|
||||
* @link https://datatracker.ietf.org/doc/html/rfc8292 RFC 8292
|
||||
*/
|
||||
public const VAPID = 'vapid';
|
||||
}
|
||||
}
|
||||
|
||||
2
src/Enumerations/Http/Header/Vendor/AWS.php
vendored
2
src/Enumerations/Http/Header/Vendor/AWS.php
vendored
@@ -24,4 +24,4 @@ interface AWS
|
||||
* @link https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html AWS Doc
|
||||
*/
|
||||
public const AWS4_HMAC_SHA256 = 'AWS4-HMAC-SHA256';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,4 +29,4 @@ class DbException extends HttpException
|
||||
$previous
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,4 +28,4 @@ class Forbidden extends HttpException
|
||||
$previous
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ class CommonHandler extends ExceptionHandler
|
||||
|
||||
if (is_numeric($data)) {
|
||||
$code = (int)$data;
|
||||
$data = CommonErrorCode::getMessage($data);
|
||||
$data = CommonErrorCode::getMessage($code);
|
||||
}
|
||||
$data = [
|
||||
$code_name => $code ?? CommonErrorCode::REQUEST_PARAMS_ERROR,
|
||||
@@ -149,9 +149,9 @@ class CommonHandler extends ExceptionHandler
|
||||
$message = $throwable->getMessage();
|
||||
$data = [
|
||||
$code_name => $code,
|
||||
$message_name => $message ?? CommonErrorCode::getMessage($code, [
|
||||
'param' => $throwable->getFieldName(),
|
||||
]),
|
||||
$message_name => empty($message) ? CommonErrorCode::getMessage($code, [
|
||||
'param' => $throwable->getFieldName(),
|
||||
]) : $message,
|
||||
];
|
||||
if ($is_debug) {
|
||||
$data['currentValue'] = $throwable->getCurrentValue();
|
||||
@@ -231,7 +231,7 @@ class CommonHandler extends ExceptionHandler
|
||||
// 其他错误
|
||||
if ($throwable instanceof HttpException) {
|
||||
$data = [
|
||||
$code_name => $throwable->getCode() ?? $throwable->getStatusCode(),
|
||||
$code_name => $throwable->getCode() ?: $throwable->getStatusCode(),
|
||||
$message_name => $throwable->getMessage(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -6,5 +6,4 @@ use Hyperf\Server\Exception\ServerException;
|
||||
|
||||
class ThirdPartyException extends ServerException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class Unauthorized extends HttpException
|
||||
$previous_code = $previous?->getCode();
|
||||
$code = empty($previous_code) ? $code : $previous_code;
|
||||
}
|
||||
|
||||
|
||||
parent::__construct(
|
||||
RFC7235::UNAUTHORIZED,
|
||||
CommonErrorCode::getMessage($code),
|
||||
@@ -30,9 +30,9 @@ class Unauthorized extends HttpException
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function getAuthenticationType(): string
|
||||
{
|
||||
return $this->authenticationType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,14 @@ use Throwable;
|
||||
*/
|
||||
class ValidateException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param int $code
|
||||
* @param string|null $message
|
||||
* @param string $field
|
||||
* @param mixed|null $currentValue
|
||||
* @param array<int, mixed> $availableValue
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(
|
||||
int $code = CommonErrorCode::FORMATTER_ERROR,
|
||||
?string $message = null,
|
||||
@@ -37,12 +45,12 @@ class ValidateException extends HttpException
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function getFieldName(): string
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -50,12 +58,12 @@ class ValidateException extends HttpException
|
||||
{
|
||||
return $this->currentValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public function getAvailableValue(): array
|
||||
{
|
||||
return $this->availableValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,26 +35,26 @@ class ClassicCoreMiddleware extends CoreMiddleware
|
||||
* @var \Singularity\HDK\Core\Service\UtilsService
|
||||
*/
|
||||
private UtilsService $utilsService;
|
||||
|
||||
|
||||
/**
|
||||
* Transfer the non-standard response content to a standard response object.
|
||||
*
|
||||
* @param null|array|Arrayable|Jsonable|string $response
|
||||
* @param null|array<string, mixed>|Arrayable<string, mixed>|Jsonable|string $response
|
||||
*/
|
||||
protected function transferToResponse($response, ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$code_name = config('common.response.code_name');
|
||||
$message_name = config('common.response.message_name');
|
||||
$data_name = config('common.response.data_name');
|
||||
|
||||
|
||||
// 分页数据
|
||||
if ($response instanceof LengthAwarePaginatorInterface) {
|
||||
$paginator = $response;
|
||||
$fact_response = $this->response()->withHeader('Per-Page', $paginator->perPage())
|
||||
->withHeader('Total', $paginator->total())
|
||||
->withHeader('Current-Page', $paginator->currentPage())
|
||||
->withHeader('Total-Pages', $paginator->hasPages());
|
||||
|
||||
$fact_response = $this->response()->withHeader('Per-Page', (string)$paginator->perPage())
|
||||
->withHeader('Total', (string)$paginator->total())
|
||||
->withHeader('Current-Page', (string)$paginator->currentPage())
|
||||
->withHeader('Total-Pages', (string)$paginator->hasPages());
|
||||
|
||||
$fact_response = $this->utilsService->extendLinkToHeader($fact_response, $paginator->nextPageUrl(), 'next');
|
||||
$fact_response = $this->utilsService->extendLinkToHeader(
|
||||
$fact_response,
|
||||
@@ -86,7 +86,7 @@ class ClassicCoreMiddleware extends CoreMiddleware
|
||||
);
|
||||
}
|
||||
// 可 Json 化的数据结构
|
||||
if ($response instanceof Jsonable) {
|
||||
if ($response instanceof Jsonable && $response instanceof Arrayable) {
|
||||
$response = [
|
||||
$code_name => 200,
|
||||
$message_name => 'ok',
|
||||
@@ -96,7 +96,7 @@ class ClassicCoreMiddleware extends CoreMiddleware
|
||||
->withAddedHeader(Header::CONTENT_TYPE, 'application/json')
|
||||
->withBody(new SwooleStream(Json::encode($response)));
|
||||
}
|
||||
|
||||
|
||||
// 普通数组
|
||||
if (is_array($response) || $response instanceof Arrayable) {
|
||||
$response = [
|
||||
@@ -108,7 +108,7 @@ class ClassicCoreMiddleware extends CoreMiddleware
|
||||
->withAddedHeader(Header::CONTENT_TYPE, 'application/json')
|
||||
->withBody(new SwooleStream(Json::encode($response)));
|
||||
}
|
||||
|
||||
|
||||
// 其他默认按字符串处理
|
||||
return $this->response()
|
||||
->withAddedHeader(Header::CONTENT_TYPE, 'text/plain')
|
||||
@@ -116,4 +116,4 @@ class ClassicCoreMiddleware extends CoreMiddleware
|
||||
new SwooleStream((string)$response)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class CorsMiddleware implements MiddlewareInterface, Method
|
||||
$response = $response
|
||||
->withHeader(
|
||||
Header::ACCESS_CONTROL_ALLOW_ORIGIN,
|
||||
$request->getHeaderLine('Origin') ?? '',
|
||||
$request->getHeaderLine('Origin'),
|
||||
)
|
||||
->withHeader(Header::ACCESS_CONTROL_ALLOW_CREDENTIALS, 'true')
|
||||
->withHeader(
|
||||
@@ -74,13 +74,13 @@ class CorsMiddleware implements MiddlewareInterface, Method
|
||||
Header::WWW_AUTHENTICATE,
|
||||
])
|
||||
);
|
||||
|
||||
|
||||
Context::set(ResponseInterface::class, $response);
|
||||
|
||||
|
||||
if ($request->getMethod() == self::OPTIONS) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class ExtendsMiddleware implements MiddlewareInterface
|
||||
* @var \Singularity\HDK\Core\Service\ExtendService
|
||||
*/
|
||||
private ExtendService $service;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -28,7 +28,7 @@ class ExtendsMiddleware implements MiddlewareInterface
|
||||
RequestHandlerInterface $handler
|
||||
): ResponseInterface {
|
||||
$this->service->parse($request);
|
||||
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class InternationalizationMiddleware implements MiddlewareInterface
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -41,11 +41,11 @@ class InternationalizationMiddleware implements MiddlewareInterface
|
||||
default => config('translation.locale')
|
||||
};
|
||||
$this->translator->setLocale($language);
|
||||
|
||||
|
||||
$response = $response->withAddedHeader('Content-Language', strtr($this->translator->getLocale(), '_', '-'));
|
||||
Context::set(ResponseInterface::class, $response);
|
||||
}
|
||||
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,4 @@ trait ClassicResponse
|
||||
'message' => 'ok',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,10 @@ class Base64Wrapper
|
||||
$base64String = strtr($base64String, '+', '-');
|
||||
return strtr($base64String, '/', '_');
|
||||
}
|
||||
|
||||
|
||||
public function decode(string $decoder): string
|
||||
{
|
||||
$origin_string = strtr($decoder, '_', '/');
|
||||
return strtr($origin_string, '-', '+');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Singularity\HDK\Core\Service;
|
||||
|
||||
use JetBrains\PhpStorm\Deprecated;
|
||||
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
|
||||
use Symfony\Component\Mailer\Mailer;
|
||||
use Symfony\Component\Mailer\Transport;
|
||||
use Symfony\Component\Mime\Address;
|
||||
@@ -23,22 +24,25 @@ use Symfony\Component\Mime\Email;
|
||||
class EmailService
|
||||
{
|
||||
private Mailer $mailer;
|
||||
|
||||
|
||||
private string $from;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$dsn = config('common.third_party.email.dsn');
|
||||
|
||||
public function __construct(
|
||||
?string $dsn = null,
|
||||
?string $mailSenderName = null,
|
||||
?string $mailSender = null
|
||||
) {
|
||||
$dsn ??= config('common.third_party.email.dsn');
|
||||
$transport = Transport::fromDsn($dsn);
|
||||
$this->mailer = new Mailer($transport);
|
||||
|
||||
|
||||
$this->from = sprintf(
|
||||
"%s <%s>",
|
||||
config('common.third_party.email.mailer_sender_name'),
|
||||
config('common.third_party.email.mailer_sender')
|
||||
$mailSenderName ?? config('common.third_party.email.mailer_sender_name'),
|
||||
$mailSender ?? config('common.third_party.email.mailer_sender')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送邮件
|
||||
*
|
||||
@@ -47,9 +51,9 @@ class EmailService
|
||||
* @param string $text
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
|
||||
* @see \Singularity\HDK\Core\Service\EmailService::sendText()
|
||||
* @see \Singularity\HDK\Core\Service\EmailService::sendHtml()
|
||||
* @throws TransportExceptionInterface
|
||||
* @see EmailService::sendText
|
||||
* @see EmailService::sendHtml
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function sendCode(
|
||||
@@ -59,15 +63,15 @@ class EmailService
|
||||
): bool {
|
||||
return $this->sendText($target, $subject, $text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|array $target
|
||||
* @param string $subject
|
||||
* @param string $text
|
||||
* @param array $cc
|
||||
* @param string|array<string> $target
|
||||
* @param string $subject
|
||||
* @param string $text
|
||||
* @param array<string> $cc
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
*/
|
||||
public function sendText(
|
||||
string|array $target,
|
||||
@@ -81,22 +85,22 @@ class EmailService
|
||||
->cc(...$cc)
|
||||
->subject($subject)
|
||||
->text($text);
|
||||
|
||||
|
||||
$this->mailer->send($email);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 以 HTML 格式发送邮件
|
||||
*
|
||||
* @param string|array $target
|
||||
* @param string $subject
|
||||
* @param string $html
|
||||
* @param array $cc
|
||||
* @param string|array<string> $target
|
||||
* @param string $subject
|
||||
* @param string $html
|
||||
* @param array<string> $cc
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
*/
|
||||
public function sendHtml(
|
||||
string|array $target,
|
||||
@@ -110,9 +114,9 @@ class EmailService
|
||||
->cc(...$cc)
|
||||
->subject($subject)
|
||||
->html($html);
|
||||
|
||||
|
||||
$this->mailer->send($email);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,30 +11,32 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||
class ExtendService
|
||||
{
|
||||
/**
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
*
|
||||
* @param ServerRequestInterface|null $request
|
||||
* @param array<string, string>|null $params
|
||||
* @return string[]
|
||||
*/
|
||||
public function parse(ServerRequestInterface $request): array
|
||||
{
|
||||
$params = $request->getQueryParams();
|
||||
public function parse(
|
||||
?ServerRequestInterface $request,
|
||||
?array $params = null
|
||||
): array {
|
||||
$params ??= $request->getQueryParams();
|
||||
$extends = $params['extends'] ?? null;
|
||||
if (!empty($extends)) {
|
||||
$extends = explode(',', $extends);
|
||||
return Context::set(self::class, array_map('trim', $extends));
|
||||
}
|
||||
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getExtends(): array
|
||||
{
|
||||
return Context::get(self::class) ?? [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断是否传入了此扩展
|
||||
*
|
||||
@@ -46,4 +48,4 @@ class ExtendService
|
||||
{
|
||||
return Context::has(self::class) && isset(array_flip(Context::get(self::class))[$field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Singularity\HDK\Core\Service;
|
||||
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
|
||||
/**
|
||||
* 发起 Http 请求的类
|
||||
*/
|
||||
class HttpRequestService
|
||||
{
|
||||
/**
|
||||
* @var \GuzzleHttp\Client
|
||||
*/
|
||||
protected Client $client;
|
||||
|
||||
protected function __construct(array $headers = [], string $base_uri = '', array $cookie = [])
|
||||
{
|
||||
$options = [
|
||||
'timeout' => 20,
|
||||
'headers' => $headers
|
||||
];
|
||||
if (!empty($base_uri)) {
|
||||
$options['base_uri'] = $base_uri;
|
||||
}
|
||||
if (!empty($cookie)) {
|
||||
$options['cookies'] = CookieJar::fromArray(
|
||||
[
|
||||
$this->cookie['key'] => $this->cookie['value']
|
||||
],
|
||||
parse_url($base_uri)['host']
|
||||
);
|
||||
}
|
||||
|
||||
$this->client = new Client($options);
|
||||
}
|
||||
|
||||
protected function get($uri, $params = [])
|
||||
{
|
||||
return $this->bar($uri, $params);
|
||||
}
|
||||
|
||||
protected function post($uri, $params = [])
|
||||
{
|
||||
return $this->bar($uri, $params, 'post');
|
||||
}
|
||||
|
||||
protected function put($uri, $params = [])
|
||||
{
|
||||
return $this->bar($uri, $params, 'put');
|
||||
}
|
||||
|
||||
protected function delete($uri, $params = [])
|
||||
{
|
||||
return $this->bar($uri, $params, 'delete');
|
||||
}
|
||||
|
||||
protected function patch($uri, $params = [])
|
||||
{
|
||||
return $this->bar($uri, $params, 'patch');
|
||||
}
|
||||
|
||||
private function bar($uri, $params = [], $method = 'get')
|
||||
{
|
||||
|
||||
try {
|
||||
$http = $this->client->{$method}($uri, ['json' => $params]);
|
||||
$result = $this->jsonToArray($http);
|
||||
} catch (ClientException|ServerException $e) {
|
||||
$response = $e->getResponse();
|
||||
$result = $this->jsonToArray($response);
|
||||
$result['httpCode'] = $response->getStatusCode();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function jsonToArray($http)
|
||||
{
|
||||
return json_decode($http->getBody()->getContents(), true);
|
||||
}
|
||||
}
|
||||
@@ -14,38 +14,49 @@ use Hyperf\Utils\Codec\Json;
|
||||
class OssService
|
||||
{
|
||||
/**
|
||||
* @const 30s 过期
|
||||
* @param string|null $accessKeyId 不传则取配置文件
|
||||
* @param string|null $accessKeySecret 不传则取配置文件
|
||||
* @param string|null $host 不传则取配置文件
|
||||
* @param int|null $expiration 过期时间,默认30s
|
||||
*/
|
||||
public const EXPIRE = 30;
|
||||
|
||||
protected string $accessKeyId;
|
||||
protected string $accessKeySecret;
|
||||
protected string $host;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->accessKeyId = config('common.third_party.storage.oss.access_key_id');
|
||||
$this->accessKeySecret = config('common.third_party.storage.oss.access_key_secret');
|
||||
$this->host = config('common.third_party.storage.oss.oss_host');
|
||||
public function __construct(
|
||||
public ?string $accessKeyId = null,
|
||||
public ?string $accessKeySecret = null,
|
||||
public ?string $host = null,
|
||||
public ?string $callbackUrl = null,
|
||||
public ?int $expiration = 30
|
||||
) {
|
||||
$this->accessKeyId ??= config('common.third_party.storage.oss.access_key_id');
|
||||
$this->accessKeySecret ??= config('common.third_party.storage.oss.access_key_secret');
|
||||
$this->host ??= config('common.third_party.storage.oss.oss_host');
|
||||
$this->callbackUrl ??= config('oss_callback');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成签证
|
||||
*
|
||||
* @param string|null $dir
|
||||
* @param bool $isImage
|
||||
* @param int $maxFileSize 最大文件大小(单位:b)
|
||||
* @param bool $isImage
|
||||
* @param int $maxFileSize 最大文件大小(单位:b)
|
||||
*
|
||||
* @return array
|
||||
* @return array{
|
||||
* 'accessid' : string,
|
||||
* 'host' : string,
|
||||
* 'policy': string,
|
||||
* 'signature': string,
|
||||
* 'expire' : int,
|
||||
* 'dir' : string,
|
||||
* 'callback':string
|
||||
* }
|
||||
*/
|
||||
public function generatePolicy(
|
||||
string $dir = null,
|
||||
bool $isImage = false,
|
||||
int $maxFileSize = 1048576000
|
||||
): array {
|
||||
$expire_time = time() + self::EXPIRE;
|
||||
$expire_time = time() + $this->expiration;
|
||||
$expiration = $this->gmtIso8601($expire_time);
|
||||
|
||||
|
||||
//最大文件大小.用户可以自己设置
|
||||
$condition = [
|
||||
0 => 'Content-Length-Range',
|
||||
@@ -53,7 +64,7 @@ class OssService
|
||||
2 => $maxFileSize,
|
||||
];
|
||||
$conditions[] = $condition;
|
||||
|
||||
|
||||
// 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。
|
||||
if ($dir) {
|
||||
$start = [
|
||||
@@ -63,8 +74,8 @@ class OssService
|
||||
];
|
||||
$conditions[] = $start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$policy = Json::encode([
|
||||
'expiration' => $expiration,
|
||||
'conditions' => $conditions,
|
||||
@@ -72,9 +83,9 @@ class OssService
|
||||
$base64_policy = base64_encode($policy);
|
||||
$string_to_sign = $base64_policy;
|
||||
$signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true));
|
||||
|
||||
|
||||
$callback = Json::encode([
|
||||
'callbackUrl' => config('oss_callback'),
|
||||
'callbackUrl' => $this->callbackUrl,
|
||||
'callbackBody' => $isImage ? <<<'callbackBody'
|
||||
{
|
||||
"bucket": ${bucket},
|
||||
@@ -91,7 +102,7 @@ class OssService
|
||||
"name": ${x:name},
|
||||
"hash": ${x:hash}
|
||||
}
|
||||
callbackBody: <<<'callbackBody'
|
||||
callbackBody : <<<'callbackBody'
|
||||
{
|
||||
"bucket": ${bucket},
|
||||
"object": ${object},
|
||||
@@ -105,7 +116,7 @@ callbackBody: <<<'callbackBody'
|
||||
callbackBody,
|
||||
'callbackBodyType' => 'application/json',
|
||||
]);
|
||||
|
||||
|
||||
return [
|
||||
'accessid' => $this->accessKeyId,
|
||||
'host' => $this->host,
|
||||
@@ -116,7 +127,7 @@ callbackBody,
|
||||
'callback' => base64_encode($callback),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将时间戳转化为 ISO8601 格式
|
||||
*
|
||||
@@ -128,4 +139,4 @@ callbackBody,
|
||||
{
|
||||
return str_replace('+00:00', '.000Z', gmdate('c', $time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ class SmsService
|
||||
* @var \AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi
|
||||
*/
|
||||
private Dysmsapi $client;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->client = $this->createClient();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化实例
|
||||
*
|
||||
@@ -40,13 +40,13 @@ class SmsService
|
||||
$config->accessKeySecret = config('common.third_party.sms.aliyun.access_key_secret');
|
||||
return new Dysmsapi($config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 国内短信
|
||||
*
|
||||
* @param string $phone 接收短信的手机号码
|
||||
* @param string|null $templateCode 短信模板CODE
|
||||
* @param array|null $templateParam 短信模板变量对应的实际值(不支持空数组)
|
||||
* @param array<string, string>|null $templateParam 短信模板变量对应的实际值(不支持空数组)
|
||||
* @param string|null $signName 短信签名名称
|
||||
*
|
||||
* @return bool
|
||||
@@ -62,7 +62,7 @@ class SmsService
|
||||
throw new \UnexpectedValueException('不支持空数组,请用 null 代替或不传', CommonErrorCode::FORMATTER_ERROR);
|
||||
}
|
||||
$phone_number = strtr($phone, ['#' => '']);
|
||||
|
||||
|
||||
$sendSmsRequest = new SendSmsRequest(
|
||||
[
|
||||
"signName" => $signName ?? config('common.third_party.sms.aliyun.sign_name'),
|
||||
@@ -71,10 +71,10 @@ class SmsService
|
||||
"templateParam" => Json::encode($templateParam),
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
try {
|
||||
$response = $this->client->sendSms($sendSmsRequest);
|
||||
|
||||
|
||||
$response_code = $response->body->code;
|
||||
$message = $response->body->message;
|
||||
if ($response_code !== 'OK') {
|
||||
@@ -83,10 +83,10 @@ class SmsService
|
||||
} catch (TeaError $error) {
|
||||
$data = $error->getErrorInfo();
|
||||
$data = $data['data'] ?? $data['body'];
|
||||
|
||||
|
||||
$code = $data['Code'];
|
||||
$message = $data['Message'];
|
||||
|
||||
|
||||
// 频率太高
|
||||
if ($code === 'isv.BUSINESS_LIMIT_CONTROL') {
|
||||
$error_code = match (mb_substr($message, 2, 2)) {
|
||||
@@ -95,12 +95,12 @@ class SmsService
|
||||
'分钟' => CommonErrorCode::REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_MINUTE,
|
||||
default => null
|
||||
};
|
||||
|
||||
|
||||
if (isset($error_code)) {
|
||||
throw new ValidateException($error_code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new HttpException(
|
||||
500,
|
||||
$message,
|
||||
@@ -108,7 +108,7 @@ class SmsService
|
||||
$error
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,8 @@ namespace Singularity\HDK\Core\Service;
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Generator;
|
||||
use Hyperf\Contract\StdoutLoggerInterface;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
@@ -19,59 +17,50 @@ use Psr\Http\Message\ResponseInterface;
|
||||
*/
|
||||
class UtilsService
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
* @var \Hyperf\HttpServer\Contract\RequestInterface
|
||||
*/
|
||||
private RequestInterface $request;
|
||||
|
||||
/**
|
||||
* @Inject()
|
||||
* @var \Hyperf\Contract\StdoutLoggerInterface
|
||||
*/
|
||||
private StdoutLoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
*
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
#[Pure]
|
||||
public function generateSecureCode(int $length = 4): string
|
||||
{
|
||||
$code = '';
|
||||
for ($times = 0; $times < $length; $times++) {
|
||||
$code .= rand(1, 9);
|
||||
$code .= random_int(1, 9);
|
||||
}
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function getRealIpAddress(): string
|
||||
|
||||
/**
|
||||
* 获取真实IP
|
||||
* @param RequestInterface $request
|
||||
* @return string
|
||||
*/
|
||||
public function getRealIpAddress(RequestInterface $request): string
|
||||
{
|
||||
$ip = $this->request->server('remote_addr');
|
||||
if (empty($ip) or in_array(
|
||||
$ip,
|
||||
[
|
||||
'localhost',
|
||||
'127.0.0.1',
|
||||
]
|
||||
)) {
|
||||
$ip = $this->request->header('x-real-ip');
|
||||
}
|
||||
return $ip ?? 'unknown';
|
||||
$x_real_ip = $request->header('x-real-ip');
|
||||
var_dump(__METHOD__ . 'x-real-ip: ' . $x_real_ip);
|
||||
$remote_addr = $request->server('remote_addr');
|
||||
var_dump(__METHOD__ . 'remote_addr: ' . $remote_addr);
|
||||
return $x_real_ip
|
||||
?? $remote_addr
|
||||
?? 'unknown';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在响应头中添加 Link 字段
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
* @param string|null $urlReference
|
||||
* @param string $rel
|
||||
* @param array $params
|
||||
* @param bool $trimQuote
|
||||
* @param ResponseInterface $response
|
||||
* @param string|null $urlReference
|
||||
* @param string $rel
|
||||
* @param array<string, string> $params
|
||||
* @param bool $trimQuote
|
||||
*
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function extendLinkToHeader(
|
||||
ResponseInterface $response,
|
||||
@@ -83,14 +72,14 @@ class UtilsService
|
||||
if (is_null($urlReference)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
$params['rel'] = $rel;
|
||||
if (!$trimQuote) {
|
||||
foreach ($params as &$value) {
|
||||
$value = '"' . trim($value, '"') . '"';
|
||||
$value = sprintf("\"%s\"", trim($value, '"'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$link_list = [];
|
||||
if ($response->hasHeader('Link')) {
|
||||
$link = $response->getHeaderLine('Link');
|
||||
@@ -98,64 +87,124 @@ class UtilsService
|
||||
$link_list = array_map('trim', $link_list);
|
||||
}
|
||||
$link_list[] = "<$urlReference>; " . http_build_query($params, '', '; ');
|
||||
|
||||
|
||||
return $response->withHeader(
|
||||
'Link',
|
||||
join(',', $link_list)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建 URL
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
*
|
||||
* @param array<string, string> $moreQueries 要附加的 query 参数
|
||||
* @param bool $anchorQuery 开启后,query 参数将被尽量组合到锚点中,以支持 spa 路由
|
||||
* @return string
|
||||
*/
|
||||
public function buildUrl(string $url, array $params = []): string
|
||||
#[Pure]
|
||||
public function buildUrl(string $url, array $moreQueries = [], bool $anchorQuery = false): string
|
||||
{
|
||||
if (count($moreQueries) === 0) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$url_info = parse_url($url);
|
||||
$base_url = str_replace(('?' . $url_info['query'] ?? ''), '', $url);
|
||||
parse_str($url_info['query'], $origin_params);
|
||||
$origin_params += $params;
|
||||
|
||||
return $base_url . '?' . http_build_query($origin_params);
|
||||
|
||||
$result = '';
|
||||
// 协议
|
||||
if (isset($url_info['scheme'])) {
|
||||
$result .= $url_info['scheme'];
|
||||
}
|
||||
// 域名
|
||||
if (isset($url_info['host'])) {
|
||||
if (!empty($result)) {
|
||||
$result .= ':';
|
||||
}
|
||||
$result .= '//';
|
||||
// 用户名
|
||||
if (isset($url_info['user'])) {
|
||||
$result .= $url_info['user'];
|
||||
// 密码
|
||||
if (isset($url_info['pass'])) {
|
||||
$result .= ':' . $url_info['pass'];
|
||||
}
|
||||
$result .= '@';
|
||||
}
|
||||
$result .= $url_info['host'];
|
||||
}
|
||||
// 端口
|
||||
if (isset($url_info['port'])) {
|
||||
$result .= ':' . $url_info['port'];
|
||||
}
|
||||
// 路径
|
||||
$result .= $url_info['path'];
|
||||
// 查询参数
|
||||
if (!empty($url_info['query'])) {
|
||||
$query_params = $url_info['query'];
|
||||
parse_str($query_params, $origin_params);
|
||||
if (!$anchorQuery) {
|
||||
$origin_params += $moreQueries;
|
||||
}
|
||||
$result .= '?' . http_build_query($origin_params);
|
||||
} else {
|
||||
if (!$anchorQuery) {
|
||||
$result .= '?' . http_build_query($moreQueries);
|
||||
}
|
||||
}
|
||||
// 锚点
|
||||
if (!empty($url_info['fragment'])) {
|
||||
$fragment = $url_info['fragment'];
|
||||
if ($anchorQuery) {
|
||||
$fragment_data = parse_url($url_info['fragment']);
|
||||
parse_str($fragment_data['query'] ?? '', $hash_queries);
|
||||
$hash_queries += $moreQueries;
|
||||
|
||||
$fragment = $fragment_data['path'] . '?' . http_build_query($hash_queries);
|
||||
}
|
||||
$result .= '#' . $fragment;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 以迭代器的形式响应
|
||||
*
|
||||
* @param string $fullName
|
||||
*
|
||||
* @return \Generator
|
||||
* @throws \Exception
|
||||
* @return Generator
|
||||
* @throws Exception
|
||||
*/
|
||||
public function csvReaderGenerator(string $fullName): Generator
|
||||
{
|
||||
if (!is_file($fullName)) {
|
||||
throw new Exception('指定的 csv 文件不存在');
|
||||
}
|
||||
|
||||
|
||||
$file = fopen($fullName, 'r');
|
||||
while ($data = fgetcsv($file)) { //每次读取CSV里面的一行内容
|
||||
yield $data;
|
||||
}
|
||||
|
||||
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 以数组形式响应
|
||||
*
|
||||
* @throws \Exception
|
||||
* @param string $fullName
|
||||
* @param array<string> $headers
|
||||
* @param int|null $batchNumber
|
||||
* @return array<int, mixed>
|
||||
* @throws Exception
|
||||
*/
|
||||
public function csvReader(string $fullName, array $headers = [], ?int $batchNumber = null): array
|
||||
{
|
||||
if (!is_file($fullName)) {
|
||||
throw new Exception($fullName . ' 不存在');
|
||||
}
|
||||
|
||||
|
||||
$file = fopen($fullName, 'r');
|
||||
$result = [];
|
||||
$row_number = 0;
|
||||
@@ -171,23 +220,24 @@ class UtilsService
|
||||
$result[] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fclose($file);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (level倒序)快速无极分类(时间复杂度 O(n),空间复杂度 O(1))
|
||||
* 条件:数组索引是数据parent_id对应的id,只支持level倒序
|
||||
*
|
||||
* @param array $list
|
||||
* @param int $level
|
||||
* @param string $parentIdName
|
||||
* @param string $childrenName
|
||||
* @param \Closure|null $filterCallback
|
||||
* @param array<int, mixed> $list
|
||||
* @param int $level
|
||||
* @param string $parentIdName
|
||||
* @param string $childrenName
|
||||
* @param Closure|null $filterCallback
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[NoReturn]
|
||||
public function unlimitedSubCategoriesQuicklyWithLevel(
|
||||
array &$list,
|
||||
int $level = 1,
|
||||
@@ -195,15 +245,11 @@ class UtilsService
|
||||
string $childrenName = 'children',
|
||||
?Closure $filterCallback = null
|
||||
): void {
|
||||
$start_time = microtime(true);
|
||||
$max_times = count($list);
|
||||
$current_times = 0;
|
||||
foreach ($list as $i => &$item) {
|
||||
$current_times++;
|
||||
if (!isset($item[$parentIdName])) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
unset($list[$i]);
|
||||
$item = isset($filterCallback) ? $filterCallback($item) : $item;
|
||||
//判定非顶级的pid是否存在,如果存在,则再pid所在的数组下面加入一个字段items,来将本身存进去
|
||||
@@ -211,34 +257,26 @@ class UtilsService
|
||||
$list[$item[$parentIdName]][$childrenName][] = $item;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//取出顶级
|
||||
if ($item['level'] === $level) {
|
||||
$list[$childrenName][] = $item;
|
||||
}
|
||||
}
|
||||
$list = $list[$childrenName];
|
||||
$end_time = microtime(true);
|
||||
$this->logger->debug("快速无极分类循环{$current_times}次,数组元素数量$max_times");
|
||||
|
||||
$cost_time = ($end_time - $start_time) * 1000;
|
||||
$this->logger->debug("快速无极分类用时{$cost_time}ms");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 将内存/硬盘大小转化为带单位大小
|
||||
*
|
||||
* @param float|int|string $size 空间大小(单位:Byte)
|
||||
* @param bool $unitToUpper 单位转换为大写(默认 false)
|
||||
* @param int $precision 小数点后保留的位数(默认 2)
|
||||
* @param float|int|string $size 空间大小(单位:Byte)
|
||||
* @param bool $unitToUpper 单位转换为大写(默认 false)
|
||||
* @param int $precision 小数点后保留的位数(默认 2)
|
||||
*
|
||||
* @return array
|
||||
* @return array{'size': float, 'unit': string}
|
||||
*/
|
||||
#[
|
||||
ArrayShape(['size' => 'float', 'unit' => 'string']),
|
||||
Pure
|
||||
]
|
||||
#[Pure]
|
||||
public function convertStorageSize(
|
||||
float|int|string $size,
|
||||
bool $unitToUpper = false,
|
||||
@@ -257,23 +295,18 @@ class UtilsService
|
||||
'unit' => $unitToUpper ? strtoupper($unit[$i]) : $unit[$i],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将时长转换为带单位时间
|
||||
*
|
||||
* @param int|float $duration 时长(单位:ms)
|
||||
* @param bool $unitToUpper
|
||||
* @param bool $format
|
||||
* @param integer $precision
|
||||
* @param bool $unitToUpper
|
||||
* @param bool $format
|
||||
* @param integer $precision
|
||||
*
|
||||
* @return array
|
||||
* @return array{'duration': float, 'unit': string}
|
||||
*/
|
||||
#[
|
||||
ArrayShape([
|
||||
'duration' => 'float',
|
||||
'unit' => 'string',
|
||||
])
|
||||
]
|
||||
#[Pure]
|
||||
public function convertDuration(
|
||||
int|float $duration,
|
||||
bool $unitToUpper = false,
|
||||
@@ -281,7 +314,7 @@ class UtilsService
|
||||
int $precision = 3
|
||||
): array {
|
||||
$unit = ['ms', 's'];
|
||||
|
||||
|
||||
if ($duration > 1) {
|
||||
$i = floor(log($duration, 1000));
|
||||
$duration = round($duration / pow(1000, $i), $precision);
|
||||
@@ -296,4 +329,4 @@ class UtilsService
|
||||
'unit' => $unitToUpper ? strtoupper($unit[$i]) : $unit[$i],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
tests/Pest.php
Normal file
30
tests/Pest.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Test Case
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The closure you provide to your test functions is always bound to a specific PHPUnit test
|
||||
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
|
||||
| need to change it using the "uses()" function to bind a different classes or traits.
|
||||
|
|
||||
*/
|
||||
|
||||
// uses(Tests\TestCase::class)->in('Feature');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Functions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
|
||||
| project that you don't want to repeat in every file. Here you can also expose helpers as
|
||||
| global functions to help you to reduce the number of lines of code in your test files.
|
||||
|
|
||||
*/
|
||||
|
||||
/*function something()
|
||||
{
|
||||
// ..
|
||||
}*/
|
||||
32
tests/Unit/Base64WrapperTest.php
Normal file
32
tests/Unit/Base64WrapperTest.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Base64WrapperTest.php@HDK-Core
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2022/12/20
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Test\Core\Unit;
|
||||
|
||||
use Singularity\HDK\Core\Service\Base64Wrapper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
it('assertions base64 wrapper ENCODE', function (string $source, string $expected) {
|
||||
$encoded = (new Base64Wrapper())->encode($source);
|
||||
|
||||
expect($expected)->toBe($encoded);
|
||||
})->with([
|
||||
['abc==', 'abc'],
|
||||
['=ccc=', 'ccc'],
|
||||
['YWJ/+j', 'YWJ_-j']
|
||||
]);
|
||||
|
||||
it('assertions base64 wrapper DECODE', function (string $source, string $expected) {
|
||||
$decoded = (new Base64Wrapper())->decode($source);
|
||||
|
||||
expect($expected)->toBe($decoded);
|
||||
})->with([
|
||||
['abc', 'abc'],
|
||||
['YWJ_-j', 'YWJ/+j']
|
||||
]);
|
||||
65
tests/Unit/EmailServiceTest.php
Normal file
65
tests/Unit/EmailServiceTest.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* EmailServiceTest.php@HDK-Core
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2022/12/20
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Test\Core\Service;
|
||||
|
||||
use Singularity\HDK\Core\Service\EmailService;
|
||||
use Symfony\Component\Mailer\Exception\TransportException;
|
||||
|
||||
$dsn = 'smtp://account@luxcreo.ai:Qfsd8866@smtp.qiye.aliyun.com:465';
|
||||
$mail_sender_name = 'LuxCreo';
|
||||
$mail_sender = 'account@luxcreo.ai';
|
||||
$email = new EmailService($dsn, $mail_sender_name, $mail_sender);
|
||||
|
||||
it('assertions that send HTML is available', function () use ($email) {
|
||||
$result = $email->sendHtml(
|
||||
'dongyun.li@luxcreo.ai',
|
||||
'HDK Unit Test HTML',
|
||||
<<<HTML
|
||||
<h1>Hello, World!</h1>
|
||||
HTML
|
||||
);
|
||||
expect($result)->toBeTrue();
|
||||
});
|
||||
|
||||
it('assertions that send Text is available', function () use ($email) {
|
||||
$result = $email->sendText(
|
||||
'dongyun.li@luxcreo.ai',
|
||||
'HDK Unit Test Text',
|
||||
<<<Text
|
||||
<h1>Hello, World!</h1>
|
||||
Text
|
||||
);
|
||||
expect($result)->toBeTrue();
|
||||
});
|
||||
|
||||
it('assertions Error Receiver can be catch', function () use ($email) {
|
||||
try {
|
||||
$email->sendHtml(
|
||||
'unknown@luxcreo.ai',
|
||||
'HDK Unit Test',
|
||||
<<<HTML
|
||||
<h1>Hello, World!</h1>
|
||||
HTML
|
||||
);
|
||||
} catch (TransportException $t) {
|
||||
expect($t->getCode())->toBe(554);
|
||||
}
|
||||
try {
|
||||
$email->sendText(
|
||||
'unknown@luxcreo.ai',
|
||||
'HDK Unit Test',
|
||||
<<<Text
|
||||
<h1>Hello, World!</h1>
|
||||
Text
|
||||
);
|
||||
} catch (TransportException $t) {
|
||||
expect($t->getCode())->toBe(554);
|
||||
}
|
||||
});
|
||||
38
tests/Unit/ExtendServiceTest.php
Normal file
38
tests/Unit/ExtendServiceTest.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* ExtendServiceTest.php@HDK-Core
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2022/12/20
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Test\Core\Unit;
|
||||
|
||||
use Singularity\HDK\Core\Service\ExtendService;
|
||||
|
||||
$service = new ExtendService();
|
||||
|
||||
it('asserts query parameters can be parsed.', function () use ($service) {
|
||||
$result = $service->parse(
|
||||
null,
|
||||
params: [
|
||||
'id' => 5,
|
||||
'extends' => 'a,b',
|
||||
]
|
||||
);
|
||||
expect($result)->toBeArray()->toHaveCount(2)->toBe(['a', 'b']);
|
||||
});
|
||||
it('asserts has extends', function () use ($service) {
|
||||
expect($service->hasExtends('a'))->toBeTrue()
|
||||
->and($service->hasExtends('b'))->toBeTrue()
|
||||
->and($service->hasExtends('c'))->toBeFalse();
|
||||
})->depends('it asserts query parameters can be parsed.');
|
||||
|
||||
it('asserts parsed extends', function () use ($service) {
|
||||
$extends = $service->getExtends();
|
||||
expect($extends)->toBeArray()->toMatchArray([
|
||||
'a',
|
||||
'b',
|
||||
]);
|
||||
})->depends('it asserts query parameters can be parsed.');
|
||||
50
tests/Unit/OssServiceTest.php
Normal file
50
tests/Unit/OssServiceTest.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* OssServiceTest.php@HDK-Core
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/1/9
|
||||
*/
|
||||
|
||||
use Hyperf\Utils\Codec\Json;
|
||||
use Singularity\HDK\Core\Service\OssService;
|
||||
|
||||
use function Spatie\PestPluginTestTime\testTime;
|
||||
|
||||
it('asserts oss policy can be generated', function ($setDir, $isImage, $maxSize) {
|
||||
testTime()->freeze();
|
||||
$oss = new OssService(
|
||||
'{MOCK_ACCESS_KEY_ID}',
|
||||
'{MOCK_ACCESS_KEY_SECRET}',
|
||||
'{MOCK_HOST}',
|
||||
'{MOCK_CALLBACK_URL}',
|
||||
30,
|
||||
);
|
||||
|
||||
[
|
||||
'accessid' => $accessId,
|
||||
'host' => $host,
|
||||
'policy' => $policy,
|
||||
'signature' => $signature,
|
||||
'expire' => $expire,
|
||||
'dir' => $dir,
|
||||
'callback' => $callback,
|
||||
] = $oss->generatePolicy($setDir, $isImage, $maxSize);
|
||||
|
||||
$sign = base64_encode(hash_hmac('sha1', $policy, '{MOCK_ACCESS_KEY_SECRET}', true));
|
||||
$policy = Json::decode(base64_decode($policy));
|
||||
$callback = Json::decode(base64_decode($callback));
|
||||
|
||||
expect($accessId)->toBe('{MOCK_ACCESS_KEY_ID}')
|
||||
->and($host)->toBe('{MOCK_HOST}')
|
||||
->and($dir)->toBe($setDir)
|
||||
->and($setDir)->toBe($policy['conditions'][1][2])
|
||||
->and($expire)->toBe(testTime()->addSeconds(30)->unix())
|
||||
->and($policy['expiration'])->toBe(testTime()->setMilli(0)->toIso8601ZuluString('m'))
|
||||
->and($maxSize)->toBe($policy['conditions'][0][2])
|
||||
->and($callback['callbackUrl'])->toBe('{MOCK_CALLBACK_URL}')
|
||||
->and($signature)->toBe($sign);
|
||||
})->with([
|
||||
['uploaded', true, 1048576000],
|
||||
]);
|
||||
62
tests/Unit/UtilsServiceTest.php
Normal file
62
tests/Unit/UtilsServiceTest.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* UtilsServiceTest.php@HDK-Core
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/1/12
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Core\Service\UtilsService;
|
||||
|
||||
$utils = new UtilsService();
|
||||
|
||||
$length_data = [];
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
try {
|
||||
$length_data[] = random_int(1, 9);
|
||||
} catch (Exception $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
test('断言验证码可以正常生成指定长度', function (int $length) use ($utils) {
|
||||
try {
|
||||
$code = $utils->generateSecureCode($length);
|
||||
expect($code)->toHaveLength($length);
|
||||
} catch (Exception $e) {
|
||||
expect($e)->toBeNull();
|
||||
}
|
||||
})->with($length_data)->group('pure', 'utils');
|
||||
|
||||
test('断言可以根据参数构建 URL', function (string $url, array $params, bool $anchorQuery, string $expect) use ($utils) {
|
||||
$url = $utils->buildUrl(url: $url, moreQueries: $params, anchorQuery: $anchorQuery);
|
||||
expect($url)->toBe($expect);
|
||||
})->with([
|
||||
['baidu.com/list', ['a' => 'b'], false, 'baidu.com/list?a=b'],
|
||||
['/api/v1/doc/categories/1?order=id', ['sort' => 'desc'], false, '/api/v1/doc/categories/1?order=id&sort=desc'],
|
||||
['//google.com/search?c=d', ['a' => 'b'], false, '//google.com/search?c=d&a=b'],
|
||||
[
|
||||
'https://support.luxcreo.com/#/support?id=123',
|
||||
['category' => 'abc'],
|
||||
true,
|
||||
'https://support.luxcreo.com/#/support?id=123&category=abc',
|
||||
],
|
||||
[
|
||||
'https://support.luxcreo.com/#/support',
|
||||
['category' => 'abc'],
|
||||
true,
|
||||
'https://support.luxcreo.com/#/support?category=abc',
|
||||
],
|
||||
[
|
||||
'ssh://username:password@127.0.0.1/git/resp?id=1#/page?a=b',
|
||||
['c' => 'd'],
|
||||
false,
|
||||
'ssh://username:password@127.0.0.1/git/resp?id=1&c=d#/page?a=b',
|
||||
],
|
||||
[
|
||||
'http://username:password@127.0.0.1/git/resp?id=1#/page?a=b',
|
||||
['c' => 'd'],
|
||||
true,
|
||||
'http://username:password@127.0.0.1/git/resp?id=1#/page?a=b&c=d',
|
||||
]
|
||||
])->group('pure', 'utils');
|
||||
Reference in New Issue
Block a user