mirror of
http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore.git
synced 2026-01-15 03:45:06 +08:00
init(core): 初始化代码
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
vendor/
|
||||||
131
.idea/HDK-Core.iml
generated
131
.idea/HDK-Core.iml
generated
@@ -3,9 +3,134 @@
|
|||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="Singularity\HDK\" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="Singularity\HDK\Core\" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Singularity\HDK\Test\\Core\" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/tests/Example" isTestSource="true" packagePrefix="Tests\Example\" />
|
<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" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/tea-xml" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/darabonba-openapi" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/openapi-util" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/tea" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/tea-utils" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/gateway-spi" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/endpoint-util" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/dysmsapi-20170525" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/alibabacloud/credentials" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/justinrainbow/json-schema" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/graham-campbell/result-type" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/fig/http-message-util" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/lmc/http-constants" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/cache" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-server-handler" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-server-middleware" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/seld/phar-utils" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/seld/jsonlint" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/seld/signal-handler" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/fast-route" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/react/promise" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/roave/dont" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/database" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/contract" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/di" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/context" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/logger" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/http-server" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/translation" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/framework" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/config" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/redis" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/constants" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/dispatcher" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/server" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/utils" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/http-message" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/exception-handler" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/macroable" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/resource" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/paginator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/engine" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/pool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/event" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/validation" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hyperf/session" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/php-di/phpdoc-reader" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/teapot/status-code" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/vlucas/phpdotenv" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/adbario/php-dot-notation" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-mime" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-stdlib" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/php-enum" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php81" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mailer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/filesystem" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/annotations" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/ergebnis/http-method" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/firebase/php-jwt" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/jetbrains/phpstorm-attributes" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/lizhichao/one-sm" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
||||||
|
<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" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|||||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="PhpPropertyOnlyWrittenInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
130
.idea/php.xml
generated
130
.idea/php.xml
generated
@@ -9,6 +9,136 @@
|
|||||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="PhpIncludePathManager">
|
||||||
|
<include_path>
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/tea-xml" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/darabonba-openapi" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/openapi-util" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/tea" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/tea-utils" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/gateway-spi" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/endpoint-util" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/dysmsapi-20170525" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/alibabacloud/credentials" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/justinrainbow/json-schema" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/graham-campbell/result-type" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/composer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/fig/http-message-util" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/lmc/http-constants" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/cache" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/http-server-handler" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/http-server-middleware" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/container" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/http-client" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/seld/phar-utils" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/seld/jsonlint" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/seld/signal-handler" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/nikic/fast-route" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/react/promise" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/roave/dont" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/database" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/contract" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/di" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/context" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/logger" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/http-server" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/translation" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/framework" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/config" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/redis" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/constants" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/dispatcher" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/server" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/utils" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/http-message" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/exception-handler" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/macroable" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/resource" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/paginator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/engine" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/pool" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/event" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/validation" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/hyperf/session" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/nesbot/carbon" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/php-di/phpdoc-reader" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/teapot/status-code" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/adbario/php-dot-notation" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/laminas/laminas-mime" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/laminas/laminas-stdlib" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/myclabs/php-enum" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php81" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/mailer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/string" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/process" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/console" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/doctrine/annotations" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/ergebnis/http-method" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/firebase/php-jwt" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/jetbrains/phpstorm-attributes" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/lizhichao/one-sm" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpoption/phpoption" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
|
||||||
|
<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" />
|
||||||
|
</include_path>
|
||||||
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.0" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.0" />
|
||||||
<component name="PhpStanOptionsConfiguration">
|
<component name="PhpStanOptionsConfiguration">
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
|
|||||||
@@ -1,44 +1,94 @@
|
|||||||
{
|
{
|
||||||
"name": "singularity/php-package-boilperplate",
|
"name": "singularity/hdk-core",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"description": "PHP 通用包模板",
|
"description": "Common Hyperf Development Kit",
|
||||||
|
"extra": {
|
||||||
|
"hyperf": {
|
||||||
|
"config": "Singularity\\HDK\\ConfigProvider"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "~8.0",
|
||||||
|
"ext-redis": "^5.3",
|
||||||
|
"ext-swoole": "*",
|
||||||
|
"composer/composer": ">=2.0",
|
||||||
|
"ergebnis/http-method": "^2.2",
|
||||||
|
"hyperf/config": "^2.2",
|
||||||
|
"hyperf/constants": "^2.2",
|
||||||
|
"hyperf/context": "^2.2",
|
||||||
|
"hyperf/database": "^2.2",
|
||||||
|
"hyperf/di": "^2.2",
|
||||||
|
"hyperf/framework": "^2.2",
|
||||||
|
"hyperf/http-server": "^2.2",
|
||||||
|
"hyperf/logger": "^2.2",
|
||||||
|
"hyperf/redis": "^2.2",
|
||||||
|
"hyperf/resource": "^2.2",
|
||||||
|
"hyperf/translation": "^2.2",
|
||||||
|
"jetbrains/phpstorm-attributes": "^1.0",
|
||||||
|
"lmc/http-constants": "^1.2",
|
||||||
|
"myclabs/php-enum": "^1.8",
|
||||||
|
"roave/dont": "^1.5",
|
||||||
|
"symfony/polyfill-php81": "^1.26",
|
||||||
|
"teapot/status-code": "^1.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"swoole/ide-helper": "*",
|
||||||
|
"guzzlehttp/guzzle": "^7.4",
|
||||||
|
"firebase/php-jwt": "^6.1",
|
||||||
|
"hyperf/session": "^2.2",
|
||||||
|
"hyperf/validation": "^2.2",
|
||||||
|
"symfony/mailer": "^6.0",
|
||||||
|
"phpunit/phpunit": "^9.5",
|
||||||
|
"roave/security-advisories": "dev-latest",
|
||||||
|
"alibabacloud/dysmsapi-20170525": "^2.0.9"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"firebase/php-jwt": "JWT 鉴权必需",
|
||||||
|
"hyperf/session": "Session 鉴权必需",
|
||||||
|
"symfony/mailer": "用于发送电子邮件",
|
||||||
|
"guzzlehttp/guzzle": "需要发起 http 请求时必需",
|
||||||
|
"alibabacloud/dysmsapi-20170525": "阿里云短信服务必需"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"optimize-autoloader": true,
|
||||||
|
"sort-packages": true,
|
||||||
|
"secure-http": false
|
||||||
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Singularity\\HDK\\": "src/"
|
"Singularity\\HDK\\Core\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Tests\\Example\\": "tests/"
|
"Singularity\\HDK\\Test\\\\Core\\": "tests/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require": {
|
|
||||||
"php": "^8.0",
|
|
||||||
"composer/composer": "~2.0.14"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^9.5"
|
|
||||||
},
|
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"config": {
|
|
||||||
"optimize-autoloader": true,
|
|
||||||
"sort-packages": true
|
|
||||||
},
|
|
||||||
"extra": [],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"post-root-package-install": [
|
"post-root-package-install": [],
|
||||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
|
||||||
],
|
|
||||||
"test": "vendor/bin/phpunit --prepend test/bootstrap.php -c phpunit.xml --colors=always",
|
"test": "vendor/bin/phpunit --prepend test/bootstrap.php -c phpunit.xml --colors=always",
|
||||||
"cs-fix": "php-cs-fixer fix $1",
|
"cs-fix": "php-cs-fixer fix $1",
|
||||||
"analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config"
|
"analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config"
|
||||||
},
|
},
|
||||||
"repositories": {
|
"repositories": {
|
||||||
|
"lux-map": {
|
||||||
|
"type": "composer",
|
||||||
|
"url": "https://satis.luxcreo.cn/"
|
||||||
|
},
|
||||||
"packagist": {
|
"packagist": {
|
||||||
"type": "composer",
|
"type": "composer",
|
||||||
"url": "https://mirrors.aliyun.com/composer"
|
"url": "https://mirrors.aliyun.com/composer/"
|
||||||
|
},
|
||||||
|
"packagist-tx": {
|
||||||
|
"type": "composer",
|
||||||
|
"url": "https://mirrors.cloud.tencent.com/composer/"
|
||||||
|
},
|
||||||
|
"packagist-hw": {
|
||||||
|
"type": "composer",
|
||||||
|
"url": "https://repo.huaweicloud.com/repository/php/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6661
composer.lock
generated
6661
composer.lock
generated
File diff suppressed because it is too large
Load Diff
82
publish/common.php
Normal file
82
publish/common.php
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* common.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/27
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 响应
|
||||||
|
'response' => [
|
||||||
|
'restful' => false, // 若禁用,则状态码永远只为 200
|
||||||
|
'code_name' => 'code', // 错误码名称
|
||||||
|
'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 的过期时间
|
||||||
|
'forbidden_key' => 'user:last_invalidate_time', // redis 中储存时的 key 名(此时间之前登录的用户都会被 T 掉)
|
||||||
|
],
|
||||||
|
'app' => [
|
||||||
|
'expire_time' => 30 * 24 * 60 * 60,
|
||||||
|
'prefix_key' => 'token:',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
// redis 补充配置
|
||||||
|
'redis' => [
|
||||||
|
'prefix' => sprintf(
|
||||||
|
"%s:%s:",
|
||||||
|
env('APP_NAME'),
|
||||||
|
env('APP_ENV', 'product')
|
||||||
|
), // 强烈建议按此格式划分
|
||||||
|
],
|
||||||
|
|
||||||
|
// account http请求配置
|
||||||
|
'http_request' => [
|
||||||
|
'account' => [
|
||||||
|
'api_base_uri' => env('API_BASE_URI', ''),
|
||||||
|
'rpc_base_uri' => env('RPC_BASE_URI', ''),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
// 第三方服务
|
||||||
|
'third_party' => [
|
||||||
|
'email' => [
|
||||||
|
'dsn' => 'smtp://account@luxcreo.ai:Qfsd8866@smtp.qiye.aliyun.com:465',
|
||||||
|
'mailer_sender' => 'account@luxcreo.ai', // 发件邮箱
|
||||||
|
'mailer_sender_name' => 'LuxCreo', // 发件人名称
|
||||||
|
],
|
||||||
|
'sms' => [
|
||||||
|
'aliyun' => [
|
||||||
|
'access_key_id' => env('ACCESS_KEY_ID', ''),
|
||||||
|
'access_key_secret' => env('ACCESS_KEY_SECRET', ''),
|
||||||
|
'sign' => '', // 短信签名名称
|
||||||
|
'template_code' => '', // 短信模板CODE
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'storage' => [
|
||||||
|
'oss' => [
|
||||||
|
'access_key_id' => env('ACCESS_KEY_ID', ''),
|
||||||
|
'access_key_secret' => env('ACCESS_KEY_SECRET', ''),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
166
publish/languages/en/common_error.php
Normal file
166
publish/languages/en/common_error.php
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* This file is part of Hyperf.
|
||||||
|
*
|
||||||
|
* @link https://www.hyperf.io
|
||||||
|
* @document https://hyperf.wiki
|
||||||
|
* @contact group@hyperf.io
|
||||||
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
// 系统错误或未预期的错误
|
||||||
|
'server_error' => 'An internal error is occurred, try again later',
|
||||||
|
'program' => [
|
||||||
|
'default' => 'An internal error is occurred, try again later',
|
||||||
|
'syntax' => [
|
||||||
|
'default' => 'An internal error is occurred, try again later',
|
||||||
|
],
|
||||||
|
'sql' => [
|
||||||
|
'default' => 'An internal error is occurred, try again later',
|
||||||
|
'column_not_found' => 'An internal error is occurred, try again later',
|
||||||
|
'insert' => 'An internal error is occurred, try again later',
|
||||||
|
'update' => 'An internal error is occurred, try again later',
|
||||||
|
'delete' => 'An internal error is occurred, try again later',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
// 参数校验
|
||||||
|
'params' => [
|
||||||
|
'method' => [
|
||||||
|
'default' => 'Reject request',
|
||||||
|
],
|
||||||
|
// 参数非法
|
||||||
|
'format_error' => 'Format error :param',
|
||||||
|
|
||||||
|
// 数据错误
|
||||||
|
'error' => [
|
||||||
|
'default' => 'Failed verification',
|
||||||
|
'user' => [
|
||||||
|
'default' => 'Format error, :reason',
|
||||||
|
'sec_email' => [
|
||||||
|
'unique' => 'Oops! This email address is already used',
|
||||||
|
'required' => '请传入安全邮箱',
|
||||||
|
'undefined' => '请先绑定',
|
||||||
|
],
|
||||||
|
'sec_phone' => [
|
||||||
|
'unique' => 'Oops! This phone is already used',
|
||||||
|
'required' => '请传入安全手机号码',
|
||||||
|
'undefined' => '请先绑定',
|
||||||
|
],
|
||||||
|
'username' => [
|
||||||
|
'unique' => 'Oops! This username is already used',
|
||||||
|
],
|
||||||
|
'sign_up' => [
|
||||||
|
'default' => 'An account with this email or phone already exists.',
|
||||||
|
],
|
||||||
|
'action' => [
|
||||||
|
'error' => 'This type of verification code is unexpected',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'code' => [
|
||||||
|
'error' => 'This verification code is incorrect or expired',
|
||||||
|
'timeout' => 'This verification code is incorrect or expired',
|
||||||
|
'limit' => [
|
||||||
|
'default' => 'SMS verification code has reached the upper limit today, please come back tomorrow. Any problem, please contact our customer service.',
|
||||||
|
'day' => 'SMS verification code has reached the upper limit today, please come back tomorrow. Any problem, please contact our customer service.',
|
||||||
|
'hour' => 'SMS verification code has reached the upper limit today, please come back tomorrow. Any problem, please contact our customer service.',
|
||||||
|
'minute' => 'Try again later',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'target' => [
|
||||||
|
'format' => 'Invalid Target URL',
|
||||||
|
'missing' => 'Missing Target URL',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
// 鉴权
|
||||||
|
'auth' => [
|
||||||
|
'default' => 'Please login',
|
||||||
|
'jwt' => [
|
||||||
|
'default' => 'Please login',
|
||||||
|
'iat' => 'Processing, try again later',
|
||||||
|
'nbf' => 'Processing, try again later',
|
||||||
|
'exp' => 'Please login',
|
||||||
|
'iss' => 'Please login',
|
||||||
|
'uid' => 'Please login',
|
||||||
|
],
|
||||||
|
'session' => [
|
||||||
|
'default' => 'Please login',
|
||||||
|
'uid' => 'Please login',
|
||||||
|
'created_at' => 'Please login',
|
||||||
|
],
|
||||||
|
'forbidden' => [
|
||||||
|
'default' => 'You don\'t have permission to manipulate this content',
|
||||||
|
'read' => [
|
||||||
|
'default' => 'You don\'t have permission to manipulate this content',
|
||||||
|
],
|
||||||
|
'update' => [
|
||||||
|
'default' => 'You don\'t have permission to manipulate this content',
|
||||||
|
'address' => [
|
||||||
|
'unique' => 'You need at least one default shipping address',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'create' => [
|
||||||
|
'default' => 'You don\'t have permission to manipulate this content',
|
||||||
|
'wechat' => [
|
||||||
|
'redundant' => 'Oops! This WeChat is already used',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'delete' => [
|
||||||
|
'default' => 'You don\'t have permission to manipulate this content',
|
||||||
|
'wechat' => [
|
||||||
|
'only' => 'You need to add phone or email before unbind WeChat.',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'app' => [
|
||||||
|
'default' => 'Please login',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
// 服务出错
|
||||||
|
'server' => [
|
||||||
|
'cache' => [
|
||||||
|
'redis' => [
|
||||||
|
'default' => 'Oops!Something went wrong and it was probably our fault. Please try again, or report the problem to us.',
|
||||||
|
'refused' => 'Oops!Something went wrong and it was probably our fault. Please try again, or report the problem to us.',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'dependency' => [
|
||||||
|
'sms' => [
|
||||||
|
'default' => 'Oops!Something went wrong and it was probably our fault. Please try again, or report the problem to us.',
|
||||||
|
],
|
||||||
|
'wechat' => [
|
||||||
|
'default' => 'Please refresh the QR code and scan the code again',
|
||||||
|
'code' => 'An internal error is occurred, try again later',
|
||||||
|
'timeout' => 'An internal error is occurred, try again later',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'message' => [
|
||||||
|
'email' => [
|
||||||
|
'default' => 'Email send error.',
|
||||||
|
'not_found' => 'Incorrect Email',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'not_found' => [
|
||||||
|
'route' => [
|
||||||
|
'default' => 'The route does not exist',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// 模型
|
||||||
|
'model' => [
|
||||||
|
'not_found' => 'Resource Error',
|
||||||
|
'user' => [
|
||||||
|
'default' => 'Invalid User',
|
||||||
|
'not_valid' => 'The username or password is incorrect',
|
||||||
|
],
|
||||||
|
'document' => [
|
||||||
|
'default' => 'DOC deleted',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
175
publish/languages/zh_CN/common_error.php
Normal file
175
publish/languages/zh_CN/common_error.php
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* This file is part of Hyperf.
|
||||||
|
*
|
||||||
|
* @link https://www.hyperf.io
|
||||||
|
* @document https://hyperf.wiki
|
||||||
|
* @contact group@hyperf.io
|
||||||
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
// 系统错误或未预期的错误
|
||||||
|
'server_error' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
'program' => [
|
||||||
|
'default' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
'syntax' => [
|
||||||
|
'default' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
],
|
||||||
|
'sql' => [
|
||||||
|
'default' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
'column_not_found' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
'insert' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
'update' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
'delete' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
// 参数校验
|
||||||
|
'params' => [
|
||||||
|
'method' => [
|
||||||
|
'default' => '请求方式错误!支持的请求类型为::METHODS',
|
||||||
|
],
|
||||||
|
// 参数非法
|
||||||
|
'format_error' => '参数 :param 格式错误',
|
||||||
|
|
||||||
|
// 数据错误
|
||||||
|
'error' => [
|
||||||
|
'default' => '校验失败',
|
||||||
|
'user' => [
|
||||||
|
'default' => '验证失败,:reason',
|
||||||
|
'username' => [
|
||||||
|
'unique' => '用户名已存在',
|
||||||
|
],
|
||||||
|
'sec_email' => [
|
||||||
|
'unique' => '此邮箱已被绑定',
|
||||||
|
'required' => '请传入安全邮箱',
|
||||||
|
'undefined' => '请先绑定',
|
||||||
|
'error_format' => '请传入正确的邮箱地址',
|
||||||
|
],
|
||||||
|
'sec_phone' => [
|
||||||
|
'unique' => '此手机号已被绑定',
|
||||||
|
'required' => '请传入安全手机号码',
|
||||||
|
'undefined' => '请先绑定',
|
||||||
|
'error_format' => '请传入正确的手机号码',
|
||||||
|
],
|
||||||
|
'sign_up' => [
|
||||||
|
'default' => '此账号已注册',
|
||||||
|
],
|
||||||
|
'action' => [
|
||||||
|
'error' => '验证码类型错误',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'code' => [
|
||||||
|
'error' => '验证码错误或已过期',
|
||||||
|
'timeout' => '验证码错误或已过期',
|
||||||
|
'limit' => [
|
||||||
|
'default' => '今日短信验证码已达上限,请明日再试。如有紧急情况,请联系人工客服',
|
||||||
|
'day' => '今日短信验证码已达上限,请明日再试。如有紧急情况,请联系人工客服',
|
||||||
|
'hour' => '今日短信验证码已达上限,请明日再试。如有紧急情况,请联系人工客服',
|
||||||
|
'minute' => '你点的太快啦,稍后再试',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'target' => [
|
||||||
|
'format' => '跳转目标错误',
|
||||||
|
'missing' => '要跳转的目标缺失',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
// 鉴权
|
||||||
|
'auth' => [
|
||||||
|
'default' => '请先登录',
|
||||||
|
'jwt' => [
|
||||||
|
'default' => '登录失效,请重新登录',
|
||||||
|
'iat' => '账户生效中,请稍后再试',
|
||||||
|
'nbf' => '账户生效中,请稍后再试',
|
||||||
|
'exp' => '登录失效,请重新登录',
|
||||||
|
'iss' => '登录失效,请重新登录',
|
||||||
|
'uid' => '登录失效,请重新登录',
|
||||||
|
],
|
||||||
|
'session' => [
|
||||||
|
'default' => '登录失效,请重新登录',
|
||||||
|
'uid' => '登录失效,请重新登录',
|
||||||
|
'created_at' => '登录失效,请重新登录',
|
||||||
|
],
|
||||||
|
'saml' => [
|
||||||
|
'default' => 'SAML 检验失败',
|
||||||
|
'params' => [
|
||||||
|
'default' => 'SAML 参数校验失败',
|
||||||
|
'saml_request' => 'SAMLRequest 参数不能为空',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'forbidden' => [
|
||||||
|
'default' => '您无权操作此内容',
|
||||||
|
'read' => [
|
||||||
|
'default' => '您无权操作此内容',
|
||||||
|
],
|
||||||
|
'update' => [
|
||||||
|
'default' => '您无权操作此内容',
|
||||||
|
'address' => [
|
||||||
|
'unique' => '您至少需要一个默认收货地址',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'create' => [
|
||||||
|
'default' => '您无权操作此内容',
|
||||||
|
'wechat' => [
|
||||||
|
'redundant' => '此微信已绑定其他账户',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'delete' => [
|
||||||
|
'default' => '您无权操作此内容',
|
||||||
|
'wechat' => [
|
||||||
|
'only' => '你还未关联安全手机号或安全邮箱,解绑后将无法登录',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'app' => [
|
||||||
|
'default' => '登录失效,请重新登录',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
// 服务出错
|
||||||
|
'server' => [
|
||||||
|
'cache' => [
|
||||||
|
'redis' => [
|
||||||
|
'default' => '服务出了点问题,请稍后再试',
|
||||||
|
'refused' => '服务出了点问题,请稍后再试',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'dependency' => [
|
||||||
|
'sms' => [
|
||||||
|
'default' => '服务出了点问题,请稍后再试',
|
||||||
|
],
|
||||||
|
'wechat' => [
|
||||||
|
'default' => '请刷新二维码,重新扫码',
|
||||||
|
'code' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
'timeout' => '服务器开小差了,稍后再来试试吧',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'message' => [
|
||||||
|
'email' => [
|
||||||
|
'default' => '邮件发送失败',
|
||||||
|
'not_found' => '邮箱格式不正确',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'not_found' => [
|
||||||
|
'route' => [
|
||||||
|
'default' => '当前路由不存在',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// 模型
|
||||||
|
'model' => [
|
||||||
|
'not_found' => '当前:resource不存在',
|
||||||
|
'user' => [
|
||||||
|
'default' => '用户不存在',
|
||||||
|
'not_valid' => '用户名或密码错误',
|
||||||
|
],
|
||||||
|
'document' => [
|
||||||
|
'default' => '文档已删除',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
13
publish/scripts/docker-env.sh
Executable file
13
publish/scripts/docker-env.sh
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# todo 修改下面 --name 指定的容器名
|
||||||
|
# todo 修改下面 -p 绑定的第一个端口号
|
||||||
|
docker run \
|
||||||
|
--pull always \
|
||||||
|
-ti --rm --name "hyperf-development-kit" \
|
||||||
|
--privileged -u root \
|
||||||
|
-w "/srv/www" \
|
||||||
|
-v "$(pwd)":/srv/www \
|
||||||
|
-v ~/.ssh:/root/.ssh \
|
||||||
|
-p 9501:9501 \
|
||||||
|
harbor.luxcreo.cn/library/hyperf:8.0-swoole /bin/ash
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
export name
|
|
||||||
export email
|
|
||||||
|
|
||||||
git config --global user.email "${email}"
|
|
||||||
git config --global user.name "${name}"
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
alias ll='ls $LS_OPTIONS -l --color=auto' 2>/dev/null
|
|
||||||
alias l.='ls $LS_OPTIONS -d .* --color=auto' 2>/dev/null
|
|
||||||
alias ls='ls $LS_OPTIONS --color=auto' 2>/dev/null
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
chmod -R 700 ~/.ssh
|
|
||||||
#chmod 600 ~/.ssh/authorized_keys
|
|
||||||
|
|
||||||
#chown -R git:git ~/.ssh
|
|
||||||
9
scripts/docker-env.sh
Executable file
9
scripts/docker-env.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
docker run \
|
||||||
|
--pull always \
|
||||||
|
-ti --rm --name "hyperf-development-kit" \
|
||||||
|
-w "/srv/www" \
|
||||||
|
-v "$(pwd)":/srv/www \
|
||||||
|
-v ~/.ssh:/root/.ssh \
|
||||||
|
harbor.luxcreo.cn/library/hyperf:8.0-swoole /bin/ash
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
docker run \
|
|
||||||
-ti --rm --name "composer-template" \
|
|
||||||
-w "/srv/www" \
|
|
||||||
-v "$(pwd)":/srv/www \
|
|
||||||
-v ~/.ssh:/root/.ssh \
|
|
||||||
-p 8866:80 \
|
|
||||||
php:cli-alpine /bin/ash
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
docker login harbor.luxcreo.cn -u admin -p Mao+690629
|
|
||||||
|
|
||||||
set image_name=composer-template
|
|
||||||
docker build --force-rm=true --target cd --tag %image_name% --target dev --tag %image_name%-dev .
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
for /F %%i in ('chdir') do ( set current_dir=%%i)
|
|
||||||
|
|
||||||
docker run ^
|
|
||||||
-ti --rm --name "composer-template" ^
|
|
||||||
-v "%current_dir%":"/srv/www" ^
|
|
||||||
-v "%USERPROFILE%\.ssh":"/root/.ssh" ^
|
|
||||||
-p 8866:80 ^
|
|
||||||
--env-file=.env ^
|
|
||||||
php:cli-alpine /bin/ash
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
if "%*"=="" (echo <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>/<2F>ļ<EFBFBD><C4BC><EFBFBD> & exit 1) else .\vendor\bin\phpcs.bat %* || echo. & echo <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣬<EFBFBD><E2A3AC><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ctrl-c ȡ<><C8A1> & pause &.\vendor\bin\phpcbf %* && echo <20><>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
::@echo off ::<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7>ھ<EFBFBD><DABE>ᱨ<D7BB><E1B1A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪<EFBFBD><D6AA>ɶԭ<C9B6><D4AD>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# Windows 系统常用脚本
|
|
||||||
|
|
||||||
## 格式化
|
|
||||||
```bat
|
|
||||||
.\scripts\win\prettier.bat .\application\alpha.php
|
|
||||||
```
|
|
||||||
69
src/ConfigProvider.php
Normal file
69
src/ConfigProvider.php
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* This file is part of Hyperf.
|
||||||
|
*
|
||||||
|
* @link https://www.hyperf.io
|
||||||
|
* @document https://doc.hyperf.io
|
||||||
|
* @contact group@hyperf.io
|
||||||
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK;
|
||||||
|
|
||||||
|
use Hyperf\Contract\StdoutLoggerInterface;
|
||||||
|
use Hyperf\Framework\Logger\StdoutLogger;
|
||||||
|
|
||||||
|
class ConfigProvider
|
||||||
|
{
|
||||||
|
public function __invoke(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// 合并到 config/autoload/dependencies.php 文件
|
||||||
|
'dependencies' => [
|
||||||
|
StdoutLoggerInterface::class => StdoutLogger::class,
|
||||||
|
],
|
||||||
|
// 合并到 config/autoload/annotations.php 文件
|
||||||
|
'annotations' => [
|
||||||
|
'scan' => [
|
||||||
|
'paths' => [
|
||||||
|
__DIR__,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// 默认 Command 的定义,合并到 Hyperf\Contract\ConfigInterface 内,换个方式理解也就是与 config/autoload/commands.php 对应
|
||||||
|
'commands' => [
|
||||||
|
],
|
||||||
|
// 与 commands 类似
|
||||||
|
'listeners' => [],
|
||||||
|
// 组件默认配置文件,即执行命令后会把 source 的对应的文件复制为 destination 对应的的文件
|
||||||
|
'publish' => [
|
||||||
|
[
|
||||||
|
'id' => 'config',
|
||||||
|
'description' => 'The common config for HDK',
|
||||||
|
'source' => __DIR__ . '/../publish/common.php',
|
||||||
|
'destination' => BASE_PATH . '/config/autoload/common.php',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => 'script',
|
||||||
|
'description' => 'The common script for HDK',
|
||||||
|
'source' => __DIR__ . '/../publish/scripts/docker-env.sh',
|
||||||
|
'destination' => BASE_PATH . '/scripts/docker-env.sh',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => 'languages_cn',
|
||||||
|
'description' => 'The common error message for Chinese',
|
||||||
|
'source' => __DIR__ . '/../publish/languages/zh_CN/common_error.php',
|
||||||
|
'destination' => BASE_PATH . '/storage/languages/zh_CN/common_error.php',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => 'languages_en',
|
||||||
|
'description' => 'The common error message for English',
|
||||||
|
'source' => __DIR__ . '/../publish/languages/en/common_error.php',
|
||||||
|
'destination' => BASE_PATH . '/storage/languages/en/common_error.php',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
396
src/Constants/CommonErrorCode.php
Normal file
396
src/Constants/CommonErrorCode.php
Normal file
@@ -0,0 +1,396 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* CommonErrorCode.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/25
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Constants;
|
||||||
|
|
||||||
|
use Hyperf\Constants\AbstractConstants;
|
||||||
|
use Hyperf\Constants\Annotation\Constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Constants
|
||||||
|
* Singularity\HyperfDevelopmentKit\Utils\Constants\CommonErrorCode@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/25
|
||||||
|
*/
|
||||||
|
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")
|
||||||
|
*/
|
||||||
|
public const FORBIDDEN_DELETE_ONLY_USERNAME_WITH_WECHAT = 2040411;
|
||||||
|
|
||||||
|
// 205 App 鉴权
|
||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
69
src/Controller/AbstractController.php
Normal file
69
src/Controller/AbstractController.php
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AbstractController.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/25
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Controller;
|
||||||
|
|
||||||
|
use Dont\DontCall;
|
||||||
|
use Dont\DontCallStatic;
|
||||||
|
use Dont\DontClone;
|
||||||
|
use Dont\DontDeserialise;
|
||||||
|
use Dont\DontGet;
|
||||||
|
use Dont\DontSerialise;
|
||||||
|
use Dont\DontSet;
|
||||||
|
use Dont\DontToString;
|
||||||
|
use Hyperf\Contract\ContainerInterface;
|
||||||
|
use Hyperf\Contract\StdoutLoggerInterface;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||||
|
use Hyperf\HttpServer\Contract\ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽象控制器基类
|
||||||
|
* Singularity\HyperfDevelopmentKit\Utils\Controller\AbstractController@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/25
|
||||||
|
*/
|
||||||
|
abstract class AbstractController
|
||||||
|
{
|
||||||
|
use DontGet;
|
||||||
|
use DontSet;
|
||||||
|
use DontCall;
|
||||||
|
use DontCallStatic;
|
||||||
|
use DontClone;
|
||||||
|
use DontSerialise;
|
||||||
|
use DontDeserialise;
|
||||||
|
use DontToString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var ContainerInterface
|
||||||
|
*/
|
||||||
|
protected ContainerInterface $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var RequestInterface
|
||||||
|
*/
|
||||||
|
protected RequestInterface $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var ResponseInterface
|
||||||
|
*/
|
||||||
|
protected ResponseInterface $response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var \Hyperf\Contract\StdoutLoggerInterface
|
||||||
|
*/
|
||||||
|
protected StdoutLoggerInterface $stdoutLogger;
|
||||||
|
|
||||||
|
}
|
||||||
40
src/Enumerations/Http/Header/Authentication.php
Normal file
40
src/Enumerations/Http/Header/Authentication.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Authentication.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header;
|
||||||
|
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\Extend\SM3;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC4559 as Negotiate;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC6750 as Bearer;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC7486 as HOBA;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC7616 as DIGEST;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC7617 as Basic;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC7804 as SCRAM_SHA_256;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC8120 as Mutual;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC8292 as vapid;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\Vendor\AWS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP 认证相关的值
|
||||||
|
*
|
||||||
|
* @link https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication
|
||||||
|
*/
|
||||||
|
interface Authentication extends
|
||||||
|
Basic,
|
||||||
|
Bearer,
|
||||||
|
DIGEST,
|
||||||
|
HOBA,
|
||||||
|
Mutual,
|
||||||
|
Negotiate,
|
||||||
|
vapid,
|
||||||
|
SCRAM_SHA_256,
|
||||||
|
AWS,
|
||||||
|
SM3
|
||||||
|
{
|
||||||
|
}
|
||||||
28
src/Enumerations/Http/Header/Extend/SM3.php
Normal file
28
src/Enumerations/Http/Header/Extend/SM3.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* SM3.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\Extend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HDK\Utils\Enumerations\Http\Header\Authentication\Extend\SM3@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface SM3
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 国密 SM3
|
||||||
|
*
|
||||||
|
* @see https://sm3.doylee.cn
|
||||||
|
* @link http://www.sca.gov.cn/sca/xwdt/2010-12/17/1002389/files/302a3ada057c4a73830536d03e683110.pdf SM3密码杂凑算法
|
||||||
|
*/
|
||||||
|
public const SCRAM_SM3 = 'SCRAM-SM3';
|
||||||
|
}
|
||||||
26
src/Enumerations/Http/Header/RFCs/RFC4559.php
Normal file
26
src/Enumerations/Http/Header/RFCs/RFC4559.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RFC4559.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\RFCs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HyperfDevelopmentKit\Utils\Enumerations\Http\RFCs\RFC4559@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface RFC4559
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @link https://www.ietf.org/rfc/rfc4559.txt RFC 4559
|
||||||
|
*/
|
||||||
|
public const NEGOTIATE_NTLM = 'Negotiate';
|
||||||
|
|
||||||
|
}
|
||||||
29
src/Enumerations/Http/Header/RFCs/RFC6750.php
Normal file
29
src/Enumerations/Http/Header/RFCs/RFC6750.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RFC6750.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\RFCs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HyperfDevelopmentKit\Utils\Enumerations\Http\RFCs\RFC6750@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface RFC6750
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* bearer tokens to access OAuth 2.0-protected resources
|
||||||
|
*
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc6750 RFC 6750
|
||||||
|
* @codingStandardsIgnoreEnd
|
||||||
|
*/
|
||||||
|
public const Bearer = 'Bearer';
|
||||||
|
}
|
||||||
29
src/Enumerations/Http/Header/RFCs/RFC7486.php
Normal file
29
src/Enumerations/Http/Header/RFCs/RFC7486.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RFC7486.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\RFCs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HyperfDevelopmentKit\Utils\Enumerations\Http\RFCs\RFC7486@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface RFC7486
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* HTTP Origin-Bound Authentication, digital-signature-based
|
||||||
|
*
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc7486#section-3 RFC 7486, Section 3
|
||||||
|
* @codingStandardsIgnoreEnd
|
||||||
|
*/
|
||||||
|
public const HOBA = 'HOBA';
|
||||||
|
}
|
||||||
35
src/Enumerations/Http/Header/RFCs/RFC7616.php
Normal file
35
src/Enumerations/Http/Header/RFCs/RFC7616.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RFC7616.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\RFCs;
|
||||||
|
|
||||||
|
use Lmc\HttpConstants\Header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HyperfDevelopmentKit\Utils\Enumerations\Http\RFCs\RFC7616@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface RFC7616
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* HTTP Digest Access Authentication
|
||||||
|
*
|
||||||
|
* Firefox 93 and later support SHA-256 encryption.
|
||||||
|
* Previous versions only support MD5 hashing (not recommended).
|
||||||
|
*
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc7616 RFC 7616
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
*/
|
||||||
|
public const DIGEST = Header::DIGEST;
|
||||||
|
|
||||||
|
}
|
||||||
29
src/Enumerations/Http/Header/RFCs/RFC7617.php
Normal file
29
src/Enumerations/Http/Header/RFCs/RFC7617.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RFC7617.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\RFCs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HyperfDevelopmentKit\Utils\Enumerations\Http\RFCs\RFC7617@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface RFC7617
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* base64-encoded credentials.
|
||||||
|
*
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc7617 RFC-7617
|
||||||
|
* @codingStandardsIgnoreEnd
|
||||||
|
*/
|
||||||
|
public const BASIC = 'Basic';
|
||||||
|
}
|
||||||
27
src/Enumerations/Http/Header/RFCs/RFC7804.php
Normal file
27
src/Enumerations/Http/Header/RFCs/RFC7804.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RFC7804.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\RFCs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HDK\Utils\Enumerations\Http\Header\Authentication\RFCs\RFC7804@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface RFC7804
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Salted Challenge Response HTTP Authentication Mechanism
|
||||||
|
*
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc7804 RFC 7804
|
||||||
|
*/
|
||||||
|
public const SCRAM_SHA_256 = 'SCRAM-SHA-256';
|
||||||
|
}
|
||||||
25
src/Enumerations/Http/Header/RFCs/RFC8120.php
Normal file
25
src/Enumerations/Http/Header/RFCs/RFC8120.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RFC8120.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\RFCs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HyperfDevelopmentKit\Utils\Enumerations\Http\RFCs\RFC8120@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface RFC8120
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc8120 RFC 8120
|
||||||
|
*/
|
||||||
|
public const MUTUAL = 'Mutual';
|
||||||
|
}
|
||||||
27
src/Enumerations/Http/Header/RFCs/RFC8292.php
Normal file
27
src/Enumerations/Http/Header/RFCs/RFC8292.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RFC8292.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\RFCs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HDK\Utils\Enumerations\Http\Header\Authentication\RFCs\RFC8292@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface RFC8292
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Voluntary Application Server Identification (VAPID) for Web Push
|
||||||
|
*
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc8292 RFC 8292
|
||||||
|
*/
|
||||||
|
public const VAPID = 'vapid';
|
||||||
|
}
|
||||||
27
src/Enumerations/Http/Header/Vendor/AWS.php
vendored
Normal file
27
src/Enumerations/Http/Header/Vendor/AWS.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AWS.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Enumerations\Http\Header\Vendor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HDK\Utils\Enumerations\Http\Vendor\AWS@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
interface AWS
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This scheme is used for AWS3 server authentication.
|
||||||
|
*
|
||||||
|
* @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';
|
||||||
|
}
|
||||||
32
src/Exceptions/DbException.php
Normal file
32
src/Exceptions/DbException.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Exceptions;
|
||||||
|
|
||||||
|
use Hyperf\HttpMessage\Exception\HttpException;
|
||||||
|
use Singularity\HDK\Core\Constants\CommonErrorCode;
|
||||||
|
use Teapot\StatusCode\RFC\RFC7231;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 902 数据库错误
|
||||||
|
*/
|
||||||
|
class DbException extends HttpException
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
int $code = CommonErrorCode::PROGRAM_SQL_ERROR,
|
||||||
|
?string $message = null,
|
||||||
|
public string $sql = '',
|
||||||
|
Throwable $previous = null
|
||||||
|
) {
|
||||||
|
if ($code == CommonErrorCode::FORBIDDEN) {
|
||||||
|
$previous_code = $previous?->getCode();
|
||||||
|
$code = empty($previous_code) ? $code : $previous_code;
|
||||||
|
}
|
||||||
|
parent::__construct(
|
||||||
|
RFC7231::INTERNAL_SERVER_ERROR,
|
||||||
|
$message ?? CommonErrorCode::getMessage($code),
|
||||||
|
$code,
|
||||||
|
$previous
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/Exceptions/Forbidden.php
Normal file
31
src/Exceptions/Forbidden.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Exceptions;
|
||||||
|
|
||||||
|
use Hyperf\HttpMessage\Exception\HttpException;
|
||||||
|
use Singularity\HDK\Core\Constants\CommonErrorCode;
|
||||||
|
use Teapot\StatusCode\RFC\RFC7231;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户无权访问
|
||||||
|
*/
|
||||||
|
class Forbidden extends HttpException
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
int $code = CommonErrorCode::FORBIDDEN,
|
||||||
|
?string $message = null,
|
||||||
|
Throwable $previous = null
|
||||||
|
) {
|
||||||
|
if ($code == CommonErrorCode::FORBIDDEN) {
|
||||||
|
$previous_code = $previous?->getCode();
|
||||||
|
$code = empty($previous_code) ? $code : $previous_code;
|
||||||
|
}
|
||||||
|
parent::__construct(
|
||||||
|
config('common.response.restful') ? RFC7231::FORBIDDEN : 200,
|
||||||
|
$message ?? CommonErrorCode::getMessage($code),
|
||||||
|
$code,
|
||||||
|
$previous
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
307
src/Exceptions/Handler/CommonHandler.php
Normal file
307
src/Exceptions/Handler/CommonHandler.php
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* This file is part of Hyperf.
|
||||||
|
*
|
||||||
|
* @link https://www.hyperf.io
|
||||||
|
* @document https://hyperf.wiki
|
||||||
|
* @contact group@hyperf.io
|
||||||
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Exceptions\Handler;
|
||||||
|
|
||||||
|
use Hyperf\Database\Exception\QueryException;
|
||||||
|
use Hyperf\Database\Model\ModelNotFoundException;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Hyperf\ExceptionHandler\ExceptionHandler;
|
||||||
|
use Hyperf\Framework\Logger\StdoutLogger;
|
||||||
|
use Hyperf\HttpMessage\Exception\BadRequestHttpException;
|
||||||
|
use Hyperf\HttpMessage\Exception\HttpException;
|
||||||
|
use Hyperf\HttpMessage\Exception\MethodNotAllowedHttpException;
|
||||||
|
use Hyperf\HttpMessage\Exception\NotFoundHttpException;
|
||||||
|
use Hyperf\HttpMessage\Stream\SwooleStream;
|
||||||
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||||
|
use Hyperf\Utils\Codec\Json;
|
||||||
|
use Hyperf\Validation\ValidationException;
|
||||||
|
use Lmc\HttpConstants\Header;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use RedisException;
|
||||||
|
use Singularity\HDK\Core\Constants\CommonErrorCode;
|
||||||
|
use Singularity\HDK\Core\Exceptions\ValidateException;
|
||||||
|
use Symfony\Component\Mailer\Exception\TransportException;
|
||||||
|
use Teapot\StatusCode\RFC\RFC7231;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用异常处理
|
||||||
|
* Singularity\HDK\Utils\Exceptions\Handler\CommonHandler@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/28
|
||||||
|
*/
|
||||||
|
class CommonHandler extends ExceptionHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Inject(required=false)
|
||||||
|
*
|
||||||
|
* @var RequestInterface|null
|
||||||
|
*/
|
||||||
|
private ?RequestInterface $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var StdoutLogger
|
||||||
|
*/
|
||||||
|
private StdoutLogger $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function handle(
|
||||||
|
Throwable $throwable,
|
||||||
|
ResponseInterface $response
|
||||||
|
): ResponseInterface {
|
||||||
|
// 阻止异常冒泡
|
||||||
|
$this->stopPropagation();
|
||||||
|
|
||||||
|
$restful = config('common.response.restful');
|
||||||
|
$code_name = config('common.response.code_name');
|
||||||
|
$message_name = config('common.response.message_name');
|
||||||
|
|
||||||
|
$is_testing = config('app_status') === true;
|
||||||
|
$this->request?->url();
|
||||||
|
|
||||||
|
$is_debug = $this->request?->hasHeader('Postman-Token')
|
||||||
|
|| str_starts_with($this->request?->header('User-Agent'), 'apifox');
|
||||||
|
|
||||||
|
$error_type = $throwable::class;
|
||||||
|
$request_time = date('Y-m-d H:i:s');
|
||||||
|
$request_data = Json::encode($this->request?->getParsedBody());
|
||||||
|
$request_headers = Json::encode($this->request?->getHeaders());
|
||||||
|
|
||||||
|
// 901 程序语法错误
|
||||||
|
|
||||||
|
// 902 SQL 语法错误
|
||||||
|
if ($throwable instanceof QueryException) {
|
||||||
|
$code = match ($throwable->getCode()) {
|
||||||
|
'42S22' => CommonErrorCode::PROGRAM_SQL_COLUMN_NOT_FOUND,
|
||||||
|
default => CommonErrorCode::PROGRAM_SQL_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
$code_name => $code,
|
||||||
|
$message_name => CommonErrorCode::getMessage(
|
||||||
|
$is_testing
|
||||||
|
? $code
|
||||||
|
: CommonErrorCode::PROGRAM_SQL_ERROR
|
||||||
|
),
|
||||||
|
];
|
||||||
|
if ($is_testing) {
|
||||||
|
$data['details'] = [
|
||||||
|
'sql' => $throwable->getSql(),
|
||||||
|
'error' => $throwable->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 101 请求方式错误
|
||||||
|
if ($throwable instanceof MethodNotAllowedHttpException) {
|
||||||
|
$message = explode(': ', $throwable->getMessage());
|
||||||
|
$allow_method = explode(', ', $message[1]);
|
||||||
|
$code = CommonErrorCode::REQUEST_METHOD_ERROR;
|
||||||
|
$data = [
|
||||||
|
$code_name => $code,
|
||||||
|
$message_name => CommonErrorCode::getMessage($code, [
|
||||||
|
'methods' => join(', ', $allow_method),
|
||||||
|
]),
|
||||||
|
'currentMethod' => $this->request?->getMethod(),
|
||||||
|
'allowedMethod' => $allow_method,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证失败
|
||||||
|
if ($throwable instanceof BadRequestHttpException) {
|
||||||
|
$data = [
|
||||||
|
$code_name => CommonErrorCode::REQUEST_PARAMS_ERROR,
|
||||||
|
$message_name => $is_testing
|
||||||
|
? $throwable->getMessage()
|
||||||
|
: CommonErrorCode::getMessage(CommonErrorCode::SERVER_ERROR),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($throwable instanceof ValidationException) {
|
||||||
|
$data = $throwable->validator->errors()->first();
|
||||||
|
|
||||||
|
if (is_numeric($data)) {
|
||||||
|
$code = (int)$data;
|
||||||
|
$data = CommonErrorCode::getMessage($data);
|
||||||
|
}
|
||||||
|
$data = [
|
||||||
|
$code_name => $code ?? CommonErrorCode::REQUEST_PARAMS_ERROR,
|
||||||
|
$message_name => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if ($throwable instanceof ValidateException) {
|
||||||
|
$code = $throwable->getCode();
|
||||||
|
$message = $throwable->getMessage();
|
||||||
|
$data = [
|
||||||
|
$code_name => $code,
|
||||||
|
$message_name => $message ?? CommonErrorCode::getMessage($code, [
|
||||||
|
'param' => $throwable->getFieldName(),
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
if ($is_debug) {
|
||||||
|
$data['currentValue'] = $throwable->getCurrentValue();
|
||||||
|
$data['availableValue'] = $throwable->getAvailableValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路由不存在
|
||||||
|
if ($throwable instanceof NotFoundHttpException) {
|
||||||
|
$code = CommonErrorCode::ROUTE_NOT_FOUND;
|
||||||
|
$data = [
|
||||||
|
$code_name => $code,
|
||||||
|
$message_name => CommonErrorCode::getMessage($code),
|
||||||
|
];
|
||||||
|
$status_code = 404;
|
||||||
|
}
|
||||||
|
// 模型不存在
|
||||||
|
if ($throwable instanceof ModelNotFoundException) {
|
||||||
|
$code = empty($throwable->getCode()) ? CommonErrorCode::MODEL_NOT_FOUND : $throwable->getCode();
|
||||||
|
$message = empty($throwable->getCode()) ? CommonErrorCode::getMessage($code, [
|
||||||
|
'resource' => '资源',
|
||||||
|
]) : $throwable->getMessage();
|
||||||
|
$data = [
|
||||||
|
$code_name => $code,
|
||||||
|
$message_name => $message,
|
||||||
|
];
|
||||||
|
$status_code = 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 300 服务出错
|
||||||
|
// 303 缓存异常
|
||||||
|
if ($throwable instanceof RedisException) {
|
||||||
|
$code = CommonErrorCode::SERVER_CACHE_REDIS_ERROR;
|
||||||
|
if ($throwable->getMessage() === 'Connection refused') {
|
||||||
|
$code = CommonErrorCode::SERVER_CACHE_REDIS_REFUSED_ERROR;
|
||||||
|
}
|
||||||
|
$data = [
|
||||||
|
$code_name => $code,
|
||||||
|
$message_name => CommonErrorCode::getMessage(
|
||||||
|
$is_testing
|
||||||
|
? $code
|
||||||
|
: CommonErrorCode::SERVER_CACHE_REDIS_ERROR
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 306 消息异常
|
||||||
|
// 30601 邮箱发件异常
|
||||||
|
if ($throwable instanceof TransportException) {
|
||||||
|
$code = CommonErrorCode::SERVER_MESSAGE_EMAIL_ERROR;
|
||||||
|
if (strpos($throwable->getMessage(), '500 Error: bad syntax')) {
|
||||||
|
$code = CommonErrorCode::SERVER_MESSAGE_EMAIL_NOT_FOUND;
|
||||||
|
}
|
||||||
|
$data = [
|
||||||
|
$code_name => $code,
|
||||||
|
$message_name => CommonErrorCode::getMessage(
|
||||||
|
$is_testing
|
||||||
|
? $code
|
||||||
|
: CommonErrorCode::SERVER_MESSAGE_EMAIL_ERROR
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($data)) {
|
||||||
|
// 其他情况
|
||||||
|
$data = [
|
||||||
|
$code_name => $is_testing
|
||||||
|
? ($throwable->getCode() == 0
|
||||||
|
? CommonErrorCode::SERVER_ERROR
|
||||||
|
: $throwable->getCode())
|
||||||
|
: CommonErrorCode::SERVER_ERROR,
|
||||||
|
$message_name => $is_testing ? $throwable->getMessage() : __(
|
||||||
|
CommonErrorCode::getMessage(CommonErrorCode::SERVER_ERROR)
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
// 其他错误
|
||||||
|
if ($throwable instanceof HttpException) {
|
||||||
|
$data = [
|
||||||
|
$code_name => $throwable->getCode() ?? $throwable->getStatusCode(),
|
||||||
|
$message_name => $throwable->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $response->withHeader(
|
||||||
|
Header::CONTENT_TYPE,
|
||||||
|
'application/json; charset=utf-8'
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($is_debug && $is_testing) {
|
||||||
|
$data['trace'] = [
|
||||||
|
'errorType' => $error_type,
|
||||||
|
'errorTrack' => $throwable->getTrace(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$cookies = json_encode($this->request->getCookieParams(), JSON_UNESCAPED_UNICODE);
|
||||||
|
$this->logger->error(
|
||||||
|
<<<ERROR_LOG
|
||||||
|
TYPE: $error_type
|
||||||
|
[$data[$code_name]] $data[$message_name]
|
||||||
|
{$throwable->getMessage()}
|
||||||
|
-------------------------------
|
||||||
|
REQUEST_TIME: $request_time
|
||||||
|
-------------------------------
|
||||||
|
REQUEST_HEADERS:
|
||||||
|
$request_headers
|
||||||
|
-------------------------------
|
||||||
|
REQUEST_COOKIES:
|
||||||
|
$cookies
|
||||||
|
-------------------------------
|
||||||
|
REQUEST_METHOD:
|
||||||
|
{$this->request?->getMethod()}
|
||||||
|
-------------------------------
|
||||||
|
REQUEST_URL:
|
||||||
|
{$this->request?->getUri()}
|
||||||
|
-------------------------------
|
||||||
|
REQUEST_QUERY:
|
||||||
|
{$this->request?->getQueryString()}
|
||||||
|
-------------------------------
|
||||||
|
REQUEST_DATA:
|
||||||
|
$request_data
|
||||||
|
-------------------------------
|
||||||
|
TRACE:
|
||||||
|
{$throwable->getTraceAsString()}
|
||||||
|
===============================
|
||||||
|
|
||||||
|
ERROR_LOG
|
||||||
|
);
|
||||||
|
$data = Json::encode($data);
|
||||||
|
|
||||||
|
if ($restful) {
|
||||||
|
$response = $response->withStatus(
|
||||||
|
$status_code ??
|
||||||
|
$throwable->status ??
|
||||||
|
$throwable->statusCode ??
|
||||||
|
RFC7231::INTERNAL_SERVER_ERROR
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $response
|
||||||
|
->withBody(
|
||||||
|
new SwooleStream($data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断该异常处理器是否要对该异常进行处理.
|
||||||
|
*/
|
||||||
|
public function isValid(Throwable $throwable): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/Exceptions/ThirdPartyException.php
Normal file
10
src/Exceptions/ThirdPartyException.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Exceptions;
|
||||||
|
|
||||||
|
use Hyperf\Server\Exception\ServerException;
|
||||||
|
|
||||||
|
class ThirdPartyException extends ServerException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
38
src/Exceptions/Unauthorized.php
Normal file
38
src/Exceptions/Unauthorized.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Exceptions;
|
||||||
|
|
||||||
|
use Hyperf\HttpMessage\Exception\HttpException;
|
||||||
|
use Singularity\HDK\Core\Constants\CommonErrorCode;
|
||||||
|
use Singularity\HDK\Utils\Enumerations\Http\Header\RFCs\RFC7616;
|
||||||
|
use Teapot\StatusCode\RFC\RFC7235;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证未通过
|
||||||
|
*/
|
||||||
|
class Unauthorized extends HttpException
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
int $code = CommonErrorCode::UNAUTHORIZED,
|
||||||
|
Throwable $previous = null,
|
||||||
|
private string $authenticationType = RFC7616::DIGEST
|
||||||
|
) {
|
||||||
|
if ($code == CommonErrorCode::UNAUTHORIZED) {
|
||||||
|
$previous_code = $previous?->getCode();
|
||||||
|
$code = empty($previous_code) ? $code : $previous_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct(
|
||||||
|
RFC7235::UNAUTHORIZED,
|
||||||
|
CommonErrorCode::getMessage($code),
|
||||||
|
$code,
|
||||||
|
$previous
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAuthenticationType(): string
|
||||||
|
{
|
||||||
|
return $this->authenticationType;
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/Exceptions/ValidateException.php
Normal file
61
src/Exceptions/ValidateException.php
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Exceptions;
|
||||||
|
|
||||||
|
use Hyperf\HttpMessage\Exception\HttpException;
|
||||||
|
use Singularity\HDK\Core\Constants\CommonErrorCode;
|
||||||
|
use Teapot\StatusCode\RFC\RFC4918;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证失败的异常
|
||||||
|
*/
|
||||||
|
class ValidateException extends HttpException
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
int $code = CommonErrorCode::FORMATTER_ERROR,
|
||||||
|
?string $message = null,
|
||||||
|
private string $field = '',
|
||||||
|
private mixed $currentValue = null,
|
||||||
|
private array $availableValue = [],
|
||||||
|
Throwable $previous = null
|
||||||
|
) {
|
||||||
|
if ($code == CommonErrorCode::FORMATTER_ERROR) {
|
||||||
|
$previous_code = $previous?->getCode();
|
||||||
|
$code = empty($previous_code) ? $code : $previous_code;
|
||||||
|
}
|
||||||
|
parent::__construct(
|
||||||
|
RFC4918::UNPROCESSABLE_ENTITY,
|
||||||
|
$message ??
|
||||||
|
CommonErrorCode::getMessage(
|
||||||
|
$code,
|
||||||
|
[
|
||||||
|
'param' => $this->getFieldName(),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
$code,
|
||||||
|
$previous
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFieldName(): string
|
||||||
|
{
|
||||||
|
return $this->field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getCurrentValue(): mixed
|
||||||
|
{
|
||||||
|
return $this->currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAvailableValue(): array
|
||||||
|
{
|
||||||
|
return $this->availableValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
119
src/Middleware/ClassicCoreMiddleware.php
Normal file
119
src/Middleware/ClassicCoreMiddleware.php
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ClassicCoreMiddleware.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/29
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Middleware;
|
||||||
|
|
||||||
|
use Hyperf\Contract\LengthAwarePaginatorInterface;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Hyperf\HttpMessage\Stream\SwooleStream;
|
||||||
|
use Hyperf\HttpServer\CoreMiddleware;
|
||||||
|
use Hyperf\Utils\Codec\Json;
|
||||||
|
use Hyperf\Utils\Contracts\Arrayable;
|
||||||
|
use Hyperf\Utils\Contracts\Jsonable;
|
||||||
|
use Lmc\HttpConstants\Header;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Singularity\HDK\Core\Service\UtilsService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HDK\Utils\Middleware\ClassicCoreMiddleware@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/4/29
|
||||||
|
*/
|
||||||
|
class ClassicCoreMiddleware extends CoreMiddleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Inject()
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
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->utilsService->extendLinkToHeader($fact_response, $paginator->nextPageUrl(), 'next');
|
||||||
|
$fact_response = $this->utilsService->extendLinkToHeader(
|
||||||
|
$fact_response,
|
||||||
|
$paginator->url($paginator->lastPage()),
|
||||||
|
'last'
|
||||||
|
);
|
||||||
|
$fact_response = $this->utilsService->extendLinkToHeader($fact_response, $paginator->url(1), 'first');
|
||||||
|
$fact_response = $this->utilsService->extendLinkToHeader(
|
||||||
|
$fact_response,
|
||||||
|
$paginator->previousPageUrl(),
|
||||||
|
'prev'
|
||||||
|
);
|
||||||
|
return $fact_response
|
||||||
|
->withAddedHeader(Header::CONTENT_TYPE, 'application/json')
|
||||||
|
->withBody(
|
||||||
|
new SwooleStream(
|
||||||
|
Json::encode([
|
||||||
|
$code_name => 200,
|
||||||
|
$message_name => 'ok',
|
||||||
|
$data_name => $response->items(),
|
||||||
|
'meta' => [
|
||||||
|
'currentPage' => $paginator->currentPage(),
|
||||||
|
'lastPage' => $paginator->lastPage(),
|
||||||
|
'perPage' => $paginator->perPage(),
|
||||||
|
'total' => $paginator->total(),
|
||||||
|
],
|
||||||
|
])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// 可 Json 化的数据结构
|
||||||
|
if ($response instanceof Jsonable) {
|
||||||
|
$response = [
|
||||||
|
$code_name => 200,
|
||||||
|
$message_name => 'ok',
|
||||||
|
$data_name => $response->toArray(),
|
||||||
|
];
|
||||||
|
return $this->response()
|
||||||
|
->withAddedHeader(Header::CONTENT_TYPE, 'application/json')
|
||||||
|
->withBody(new SwooleStream(Json::encode($response)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 普通数组
|
||||||
|
if (is_array($response) || $response instanceof Arrayable) {
|
||||||
|
$response = [
|
||||||
|
$code_name => 200,
|
||||||
|
$message_name => 'ok',
|
||||||
|
$data_name => $response,
|
||||||
|
];
|
||||||
|
return $this->response()
|
||||||
|
->withAddedHeader(Header::CONTENT_TYPE, 'application/json')
|
||||||
|
->withBody(new SwooleStream(Json::encode($response)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他默认按字符串处理
|
||||||
|
return $this->response()
|
||||||
|
->withAddedHeader(Header::CONTENT_TYPE, 'text/plain')
|
||||||
|
->withBody(
|
||||||
|
new SwooleStream((string)$response)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
86
src/Middleware/CorsMiddleware.php
Normal file
86
src/Middleware/CorsMiddleware.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CorsMiddleware.php@HDK
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/5/18
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Middleware;
|
||||||
|
|
||||||
|
use Ergebnis\Http\Method;
|
||||||
|
use Hyperf\Context\Context;
|
||||||
|
use Lmc\HttpConstants\Header;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跨域中间件
|
||||||
|
* Singularity\HDK\Utils\Middleware\CorsMiddleware@HDK
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/5/18
|
||||||
|
*/
|
||||||
|
class CorsMiddleware implements MiddlewareInterface, Method
|
||||||
|
{
|
||||||
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
|
{
|
||||||
|
$response = Context::get(ResponseInterface::class);
|
||||||
|
$response = $response
|
||||||
|
->withHeader(
|
||||||
|
Header::ACCESS_CONTROL_ALLOW_ORIGIN,
|
||||||
|
$request->getHeaderLine('Origin') ?? '',
|
||||||
|
)
|
||||||
|
->withHeader(Header::ACCESS_CONTROL_ALLOW_CREDENTIALS, 'true')
|
||||||
|
->withHeader(
|
||||||
|
Header::ACCESS_CONTROL_ALLOW_METHODS,
|
||||||
|
join(', ', [
|
||||||
|
self::HEAD,
|
||||||
|
self::GET,
|
||||||
|
self::POST,
|
||||||
|
self::PUT,
|
||||||
|
self::DELETE,
|
||||||
|
self::PATCH,
|
||||||
|
self::OPTIONS,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
->withHeader(
|
||||||
|
Header::ACCESS_CONTROL_ALLOW_HEADERS,
|
||||||
|
join(', ', [
|
||||||
|
Header::DNT,
|
||||||
|
Header::KEEP_ALIVE,
|
||||||
|
Header::USER_AGENT,
|
||||||
|
Header::CACHE_CONTROL,
|
||||||
|
Header::CONTENT_TYPE,
|
||||||
|
Header::AUTHORIZATION,
|
||||||
|
Header::ACCEPT_LANGUAGE,
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
->withHeader(
|
||||||
|
'Access-Control-Expose-Headers',
|
||||||
|
join(', ', [
|
||||||
|
'Per-Page',
|
||||||
|
'Total',
|
||||||
|
'Current-Page',
|
||||||
|
'Total-Pages',
|
||||||
|
Header::CONTENT_LANGUAGE,
|
||||||
|
Header::LINK,
|
||||||
|
Header::WWW_AUTHENTICATE,
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
Context::set(ResponseInterface::class, $response);
|
||||||
|
|
||||||
|
if ($request->getMethod() == self::OPTIONS) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $handler->handle($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/Middleware/ExtendsMiddleware.php
Normal file
34
src/Middleware/ExtendsMiddleware.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Middleware;
|
||||||
|
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
use Singularity\HDK\Core\Service\ExtendService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展资源中间件
|
||||||
|
*/
|
||||||
|
class ExtendsMiddleware implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var \Singularity\HDK\Core\Service\ExtendService
|
||||||
|
*/
|
||||||
|
private ExtendService $service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function process(
|
||||||
|
ServerRequestInterface $request,
|
||||||
|
RequestHandlerInterface $handler
|
||||||
|
): ResponseInterface {
|
||||||
|
$this->service->parse($request);
|
||||||
|
|
||||||
|
return $handler->handle($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/Middleware/InternationalizationMiddleware.php
Normal file
51
src/Middleware/InternationalizationMiddleware.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Middleware;
|
||||||
|
|
||||||
|
use Hyperf\Context\Context;
|
||||||
|
use Hyperf\Contract\TranslatorInterface;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HDK\Utils\Middleware\InternationalizationMiddleware@HDK
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/5/18
|
||||||
|
*/
|
||||||
|
class InternationalizationMiddleware implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var TranslatorInterface
|
||||||
|
*/
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
|
{
|
||||||
|
$response = Context::get(ResponseInterface::class);
|
||||||
|
$language = $request->getHeaderLine('Accept-Language');
|
||||||
|
if (!empty($language)) {
|
||||||
|
$language = match (strtolower($language)) {
|
||||||
|
'en', 'en_us', 'en-us', 'en-uk', 'en_uk' => 'en',
|
||||||
|
'zh', 'zh_cn', 'zh-cn' => 'zh_CN',
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/Resource/ClassicResponse.php
Normal file
29
src/Resource/ClassicResponse.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ClassicResponse.php@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/5/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用经典方式响应
|
||||||
|
* Singularity\HDK\Utils\Resource\ClassicResponse@hyperf-development-kit
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/5/6
|
||||||
|
*/
|
||||||
|
trait ClassicResponse
|
||||||
|
{
|
||||||
|
public function with(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'code' => 200,
|
||||||
|
'message' => 'ok',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/Service/Base64Wrapper.php
Normal file
23
src/Service/Base64Wrapper.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64处理器
|
||||||
|
*/
|
||||||
|
class Base64Wrapper
|
||||||
|
{
|
||||||
|
public function encode(string $base64String): string
|
||||||
|
{
|
||||||
|
$base64String = strtr($base64String, '==', '');
|
||||||
|
$base64String = trim($base64String, '=');
|
||||||
|
$base64String = strtr($base64String, '+', '-');
|
||||||
|
return strtr($base64String, '/', '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decode(string $decoder): string
|
||||||
|
{
|
||||||
|
$origin_string = strtr($decoder, '_', '/');
|
||||||
|
return strtr($origin_string, '-', '+');
|
||||||
|
}
|
||||||
|
}
|
||||||
118
src/Service/EmailService.php
Normal file
118
src/Service/EmailService.php
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* This file is part of LuxAccountX.
|
||||||
|
*
|
||||||
|
* @link http://124.126.16.154:8888/WebService/LuxAccountX
|
||||||
|
* @document https://lux-software.yuque.com/htnx76/vcm2oc
|
||||||
|
* @contact dongyun.li@luxcreo.ai
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Service;
|
||||||
|
|
||||||
|
use JetBrains\PhpStorm\Deprecated;
|
||||||
|
use Symfony\Component\Mailer\Mailer;
|
||||||
|
use Symfony\Component\Mailer\Transport;
|
||||||
|
use Symfony\Component\Mime\Address;
|
||||||
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邮箱验证码
|
||||||
|
*/
|
||||||
|
class EmailService
|
||||||
|
{
|
||||||
|
private Mailer $mailer;
|
||||||
|
|
||||||
|
private string $from;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$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')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送邮件
|
||||||
|
*
|
||||||
|
* @param string $target
|
||||||
|
* @param string $subject
|
||||||
|
* @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()
|
||||||
|
*/
|
||||||
|
#[Deprecated]
|
||||||
|
public function sendCode(
|
||||||
|
string $target,
|
||||||
|
string $subject,
|
||||||
|
string $text
|
||||||
|
): bool {
|
||||||
|
return $this->sendText($target, $subject, $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|array $target
|
||||||
|
* @param string $subject
|
||||||
|
* @param string $text
|
||||||
|
* @param array $cc
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
|
||||||
|
*/
|
||||||
|
public function sendText(
|
||||||
|
string|array $target,
|
||||||
|
string $subject,
|
||||||
|
string $text,
|
||||||
|
array $cc = []
|
||||||
|
): bool {
|
||||||
|
$email = (new Email())
|
||||||
|
->from(Address::create($this->from))
|
||||||
|
->to(...(is_array($target) ? $target : [$target]))
|
||||||
|
->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
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
|
||||||
|
*/
|
||||||
|
public function sendHtml(
|
||||||
|
string|array $target,
|
||||||
|
string $subject,
|
||||||
|
string $html,
|
||||||
|
array $cc = []
|
||||||
|
): bool {
|
||||||
|
$email = (new Email())
|
||||||
|
->from(Address::create($this->from))
|
||||||
|
->to(...(is_array($target) ? $target : [$target]))
|
||||||
|
->cc(...$cc)
|
||||||
|
->subject($subject)
|
||||||
|
->html($html);
|
||||||
|
|
||||||
|
$this->mailer->send($email);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/Service/ExtendService.php
Normal file
49
src/Service/ExtendService.php
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Service;
|
||||||
|
|
||||||
|
use Hyperf\Context\Context;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源扩展
|
||||||
|
*/
|
||||||
|
class ExtendService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function parse(ServerRequestInterface $request): 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
|
||||||
|
*/
|
||||||
|
public function getExtends(): array
|
||||||
|
{
|
||||||
|
return Context::get(self::class) ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否传入了此扩展
|
||||||
|
*
|
||||||
|
* @param string $field
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasExtends(string $field): bool
|
||||||
|
{
|
||||||
|
return Context::has(self::class) && isset(array_flip(Context::get(self::class))[$field]);
|
||||||
|
}
|
||||||
|
}
|
||||||
86
src/Service/HttpRequestService.php
Normal file
86
src/Service/HttpRequestService.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\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);
|
||||||
|
}
|
||||||
|
}
|
||||||
131
src/Service/OssService.php
Normal file
131
src/Service/OssService.php
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* OssService.php@LuxStudio
|
||||||
|
*
|
||||||
|
* @author 李东云<dongyun.li@luxcreo.cn>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2022/5/11
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Utils\Service;
|
||||||
|
|
||||||
|
use Hyperf\Utils\Codec\Json;
|
||||||
|
|
||||||
|
class OssService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @const 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');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成签证
|
||||||
|
*
|
||||||
|
* @param string|null $dir
|
||||||
|
* @param bool $isImage
|
||||||
|
* @param int $maxFileSize 最大文件大小(单位:b)
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function generatePolicy(
|
||||||
|
string $dir = null,
|
||||||
|
bool $isImage = false,
|
||||||
|
int $maxFileSize = 1048576000
|
||||||
|
): array {
|
||||||
|
$expire_time = time() + self::EXPIRE;
|
||||||
|
$expiration = $this->gmtIso8601($expire_time);
|
||||||
|
|
||||||
|
//最大文件大小.用户可以自己设置
|
||||||
|
$condition = [
|
||||||
|
0 => 'Content-Length-Range',
|
||||||
|
1 => 0,
|
||||||
|
2 => $maxFileSize,
|
||||||
|
];
|
||||||
|
$conditions[] = $condition;
|
||||||
|
|
||||||
|
// 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。
|
||||||
|
if ($dir) {
|
||||||
|
$start = [
|
||||||
|
0 => 'starts-with',
|
||||||
|
1 => '$key',
|
||||||
|
2 => $dir,
|
||||||
|
];
|
||||||
|
$conditions[] = $start;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$policy = Json::encode([
|
||||||
|
'expiration' => $expiration,
|
||||||
|
'conditions' => $conditions,
|
||||||
|
]);
|
||||||
|
$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'),
|
||||||
|
'callbackBody' => $isImage ? <<<'callbackBody'
|
||||||
|
{
|
||||||
|
"bucket": ${bucket},
|
||||||
|
"object": ${object},
|
||||||
|
"etag": ${etag},
|
||||||
|
"size": ${size},
|
||||||
|
"mimeType": ${mimeType},
|
||||||
|
"imageInfo": {
|
||||||
|
"height": ${imageInfo.height},
|
||||||
|
"width": ${imageInfo.width},
|
||||||
|
"format": ${imageInfo.format}
|
||||||
|
},
|
||||||
|
"uid": ${x:uid},
|
||||||
|
"name": ${x:name},
|
||||||
|
"hash": ${x:hash}
|
||||||
|
}
|
||||||
|
callbackBody: <<<'callbackBody'
|
||||||
|
{
|
||||||
|
"bucket": ${bucket},
|
||||||
|
"object": ${object},
|
||||||
|
"etag": ${etag},
|
||||||
|
"size": ${size},
|
||||||
|
"mimeType": ${mimeType},
|
||||||
|
"uid": ${x:uid},
|
||||||
|
"name": ${x:name},
|
||||||
|
"hash": ${x:hash}
|
||||||
|
}
|
||||||
|
callbackBody,
|
||||||
|
'callbackBodyType' => 'application/json',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'accessid' => $this->accessKeyId,
|
||||||
|
'host' => $this->host,
|
||||||
|
'policy' => $base64_policy,
|
||||||
|
'signature' => $signature,
|
||||||
|
'expire' => $expire_time,
|
||||||
|
'dir' => $dir,
|
||||||
|
'callback' => base64_encode($callback),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将时间戳转化为 ISO8601 格式
|
||||||
|
*
|
||||||
|
* @param int $time
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function gmtIso8601(int $time): string
|
||||||
|
{
|
||||||
|
return str_replace('+00:00', '.000Z', gmdate('c', $time));
|
||||||
|
}
|
||||||
|
}
|
||||||
114
src/Service/SmsService.php
Normal file
114
src/Service/SmsService.php
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Service;
|
||||||
|
|
||||||
|
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
|
||||||
|
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
|
||||||
|
use AlibabaCloud\Tea\Exception\TeaError;
|
||||||
|
use Darabonba\OpenApi\Models\Config;
|
||||||
|
use Hyperf\HttpMessage\Exception\HttpException;
|
||||||
|
use Hyperf\Utils\Codec\Json;
|
||||||
|
use Singularity\HDK\Core\Constants\CommonErrorCode;
|
||||||
|
use Singularity\HDK\Core\Exceptions\ValidateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信服务
|
||||||
|
*/
|
||||||
|
class SmsService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi
|
||||||
|
*/
|
||||||
|
private Dysmsapi $client;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->client = $this->createClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化实例
|
||||||
|
*
|
||||||
|
* @return \AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi
|
||||||
|
*/
|
||||||
|
private function createClient(): Dysmsapi
|
||||||
|
{
|
||||||
|
$config = new Config();
|
||||||
|
// 访问的域名
|
||||||
|
$config->endpoint = "dysmsapi.aliyuncs.com";
|
||||||
|
$config->accessKeyId = config('common.third_party.sms.aliyun.access_key_id');
|
||||||
|
$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 string|null $signName 短信签名名称
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @link https://help.aliyun.com/document_detail/419273.htm
|
||||||
|
*/
|
||||||
|
public function sendSmsCountryside(
|
||||||
|
string $phone,
|
||||||
|
?string $templateCode = null,
|
||||||
|
?array $templateParam = null,
|
||||||
|
?string $signName = null,
|
||||||
|
): bool {
|
||||||
|
if (is_array($templateParam) && count($templateParam) <= 0) {
|
||||||
|
throw new \UnexpectedValueException('不支持空数组,请用 null 代替或不传', CommonErrorCode::FORMATTER_ERROR);
|
||||||
|
}
|
||||||
|
$phone_number = strtr($phone, ['#' => '']);
|
||||||
|
|
||||||
|
$sendSmsRequest = new SendSmsRequest(
|
||||||
|
[
|
||||||
|
"signName" => $signName ?? config('common.third_party.sms.aliyun.sign_name'),
|
||||||
|
"phoneNumbers" => $phone_number,
|
||||||
|
"templateCode" => $templateCode ?? config('common.third_party.sms.aliyun.template_code'),
|
||||||
|
"templateParam" => Json::encode($templateParam),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $this->client->sendSms($sendSmsRequest);
|
||||||
|
|
||||||
|
$response_code = $response->body->code;
|
||||||
|
$message = $response->body->message;
|
||||||
|
if ($response_code !== 'OK') {
|
||||||
|
throw new TeaError($response->toMap(), $message);
|
||||||
|
}
|
||||||
|
} 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)) {
|
||||||
|
'天级' => CommonErrorCode::REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_DAY,
|
||||||
|
'小时' => CommonErrorCode::REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_HOUR,
|
||||||
|
'分钟' => CommonErrorCode::REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_MINUTE,
|
||||||
|
default => null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isset($error_code)) {
|
||||||
|
throw new ValidateException($error_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new HttpException(
|
||||||
|
500,
|
||||||
|
$message,
|
||||||
|
CommonErrorCode::SERVER_DEPENDENCY_SMS_ERROR,
|
||||||
|
$error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
299
src/Service/UtilsService.php
Normal file
299
src/Service/UtilsService.php
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
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\Pure;
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public function generateSecureCode(int $length = 4): string
|
||||||
|
{
|
||||||
|
$code = '';
|
||||||
|
for ($times = 0; $times < $length; $times++) {
|
||||||
|
$code .= rand(1, 9);
|
||||||
|
}
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRealIpAddress(): 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';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在响应头中添加 Link 字段
|
||||||
|
*
|
||||||
|
* @param \Psr\Http\Message\ResponseInterface $response
|
||||||
|
* @param string|null $urlReference
|
||||||
|
* @param string $rel
|
||||||
|
* @param array $params
|
||||||
|
* @param bool $trimQuote
|
||||||
|
*
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function extendLinkToHeader(
|
||||||
|
ResponseInterface $response,
|
||||||
|
?string $urlReference,
|
||||||
|
string $rel = '',
|
||||||
|
array $params = [],
|
||||||
|
bool $trimQuote = true
|
||||||
|
): ResponseInterface {
|
||||||
|
if (is_null($urlReference)) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params['rel'] = $rel;
|
||||||
|
if (!$trimQuote) {
|
||||||
|
foreach ($params as &$value) {
|
||||||
|
$value = '"' . trim($value, '"') . '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$link_list = [];
|
||||||
|
if ($response->hasHeader('Link')) {
|
||||||
|
$link = $response->getHeaderLine('Link');
|
||||||
|
$link_list = explode(',', $link);
|
||||||
|
$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
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function buildUrl(string $url, array $params = []): string
|
||||||
|
{
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以迭代器的形式响应
|
||||||
|
*
|
||||||
|
* @param string $fullName
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
while ($data = fgetcsv($file)) { //每次读取CSV里面的一行内容
|
||||||
|
$row_number++;
|
||||||
|
$data = empty($headers) ? $data : array_combine($headers, $data);
|
||||||
|
$data = array_map(function ($row) {
|
||||||
|
return is_string($row) ? trim($row) : $row;
|
||||||
|
}, $data);
|
||||||
|
if (!is_null($batchNumber)) {
|
||||||
|
$result[intval($row_number / $batchNumber)][] = $data;
|
||||||
|
} else {
|
||||||
|
$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
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function unlimitedSubCategoriesQuicklyWithLevel(
|
||||||
|
array &$list,
|
||||||
|
int $level = 1,
|
||||||
|
string $parentIdName = 'parent_id',
|
||||||
|
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,来将本身存进去
|
||||||
|
if (isset($list[$item[$parentIdName]])) {
|
||||||
|
$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)
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
#[
|
||||||
|
ArrayShape(['size' => 'float', 'unit' => 'string']),
|
||||||
|
Pure
|
||||||
|
]
|
||||||
|
public function convertStorageSize(
|
||||||
|
float|int|string $size,
|
||||||
|
bool $unitToUpper = false,
|
||||||
|
int $precision = 2
|
||||||
|
): array {
|
||||||
|
$unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];
|
||||||
|
if ($size > 0) {
|
||||||
|
$i = floor(log($size, 1024));
|
||||||
|
$size = round($size / pow(1024, $i), $precision);
|
||||||
|
} else {
|
||||||
|
$i = 0;
|
||||||
|
$size = 0;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'size' => $size,
|
||||||
|
'unit' => $unitToUpper ? strtoupper($unit[$i]) : $unit[$i],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将时长转换为带单位时间
|
||||||
|
*
|
||||||
|
* @param int|float $duration 时长(单位:ms)
|
||||||
|
* @param bool $unitToUpper
|
||||||
|
* @param bool $format
|
||||||
|
* @param integer $precision
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
#[
|
||||||
|
ArrayShape([
|
||||||
|
'duration' => 'float',
|
||||||
|
'unit' => 'string',
|
||||||
|
])
|
||||||
|
]
|
||||||
|
public function convertDuration(
|
||||||
|
int|float $duration,
|
||||||
|
bool $unitToUpper = false,
|
||||||
|
bool $format = true,
|
||||||
|
int $precision = 3
|
||||||
|
): array {
|
||||||
|
$unit = ['ms', 's'];
|
||||||
|
|
||||||
|
if ($duration > 1) {
|
||||||
|
$i = floor(log($duration, 1000));
|
||||||
|
$duration = round($duration / pow(1000, $i), $precision);
|
||||||
|
} elseif ($duration < 1) {
|
||||||
|
$i = 0;
|
||||||
|
} else {
|
||||||
|
$i = 0;
|
||||||
|
$duration = 0;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'duration' => $format ? number_format($duration, $precision) : $duration,
|
||||||
|
'unit' => $unitToUpper ? strtoupper($unit[$i]) : $unit[$i],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user