Initial
commit
6beac12c64
@ -0,0 +1,21 @@
|
|||||||
|
APP_NAME=service
|
||||||
|
APP_ENV=dev
|
||||||
|
|
||||||
|
DB_DRIVER=mysql
|
||||||
|
DB_HOST=
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=
|
||||||
|
DB_USERNAME=root
|
||||||
|
DB_PASSWORD=
|
||||||
|
DB_CHARSET=utf8mb4
|
||||||
|
DB_COLLATION=utf8mb4_unicode_ci
|
||||||
|
DB_PREFIX=
|
||||||
|
|
||||||
|
REDIS_HOST=172.17.0.2
|
||||||
|
REDIS_AUTH=(null)
|
||||||
|
REDIS_PORT=6379
|
||||||
|
REDIS_DB=0
|
||||||
|
|
||||||
|
LOG_PATH=/data/project/service/runtime/logs
|
||||||
|
|
||||||
|
LANHUO_URL=https://c.uaeee.com
|
@ -0,0 +1,13 @@
|
|||||||
|
.buildpath
|
||||||
|
.settings/
|
||||||
|
.project
|
||||||
|
*.patch
|
||||||
|
.idea/
|
||||||
|
.git/
|
||||||
|
runtime/
|
||||||
|
vendor/
|
||||||
|
.phpintel/
|
||||||
|
.env
|
||||||
|
.DS_Store
|
||||||
|
.phpunit*
|
||||||
|
*.cache
|
@ -0,0 +1,57 @@
|
|||||||
|
# usermod -aG docker gitlab-runner
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
variables:
|
||||||
|
PROJECT_NAME: hyperf
|
||||||
|
REGISTRY_URL: registry-docker.org
|
||||||
|
|
||||||
|
build_test_docker:
|
||||||
|
stage: build
|
||||||
|
before_script:
|
||||||
|
# - git submodule sync --recursive
|
||||||
|
# - git submodule update --init --recursive
|
||||||
|
script:
|
||||||
|
- docker build . -t $PROJECT_NAME
|
||||||
|
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:test
|
||||||
|
- docker push $REGISTRY_URL/$PROJECT_NAME:test
|
||||||
|
only:
|
||||||
|
- test
|
||||||
|
tags:
|
||||||
|
- builder
|
||||||
|
|
||||||
|
deploy_test_docker:
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- docker stack deploy -c deploy.test.yml --with-registry-auth $PROJECT_NAME
|
||||||
|
only:
|
||||||
|
- test
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
|
||||||
|
build_docker:
|
||||||
|
stage: build
|
||||||
|
before_script:
|
||||||
|
# - git submodule sync --recursive
|
||||||
|
# - git submodule update --init --recursive
|
||||||
|
script:
|
||||||
|
- docker build . -t $PROJECT_NAME
|
||||||
|
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME
|
||||||
|
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:latest
|
||||||
|
- docker push $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME
|
||||||
|
- docker push $REGISTRY_URL/$PROJECT_NAME:latest
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
|
tags:
|
||||||
|
- builder
|
||||||
|
|
||||||
|
deploy_docker:
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- echo SUCCESS
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
|
tags:
|
||||||
|
- builder
|
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$header = <<<'EOF'
|
||||||
|
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
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
return (new PhpCsFixer\Config())
|
||||||
|
->setRiskyAllowed(true)
|
||||||
|
->setRules([
|
||||||
|
'@PSR2' => true,
|
||||||
|
'@Symfony' => true,
|
||||||
|
'@DoctrineAnnotation' => true,
|
||||||
|
'@PhpCsFixer' => true,
|
||||||
|
'header_comment' => [
|
||||||
|
'comment_type' => 'PHPDoc',
|
||||||
|
'header' => $header,
|
||||||
|
'separate' => 'none',
|
||||||
|
'location' => 'after_declare_strict',
|
||||||
|
],
|
||||||
|
'array_syntax' => [
|
||||||
|
'syntax' => 'short'
|
||||||
|
],
|
||||||
|
'list_syntax' => [
|
||||||
|
'syntax' => 'short'
|
||||||
|
],
|
||||||
|
'concat_space' => [
|
||||||
|
'spacing' => 'one'
|
||||||
|
],
|
||||||
|
'blank_line_before_statement' => [
|
||||||
|
'statements' => [
|
||||||
|
'declare',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'general_phpdoc_annotation_remove' => [
|
||||||
|
'annotations' => [
|
||||||
|
'author'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'ordered_imports' => [
|
||||||
|
'imports_order' => [
|
||||||
|
'class', 'function', 'const',
|
||||||
|
],
|
||||||
|
'sort_algorithm' => 'alpha',
|
||||||
|
],
|
||||||
|
'single_line_comment_style' => [
|
||||||
|
'comment_types' => [
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'yoda_style' => [
|
||||||
|
'always_move_variable' => false,
|
||||||
|
'equal' => false,
|
||||||
|
'identical' => false,
|
||||||
|
],
|
||||||
|
'phpdoc_align' => [
|
||||||
|
'align' => 'left',
|
||||||
|
],
|
||||||
|
'multiline_whitespace_before_semicolons' => [
|
||||||
|
'strategy' => 'no_multi_line',
|
||||||
|
],
|
||||||
|
'constant_case' => [
|
||||||
|
'case' => 'lower',
|
||||||
|
],
|
||||||
|
'class_attributes_separation' => true,
|
||||||
|
'combine_consecutive_unsets' => true,
|
||||||
|
'declare_strict_types' => true,
|
||||||
|
'linebreak_after_opening_tag' => true,
|
||||||
|
'lowercase_static_reference' => true,
|
||||||
|
'no_useless_else' => true,
|
||||||
|
'no_unused_imports' => true,
|
||||||
|
'not_operator_with_successor_space' => true,
|
||||||
|
'not_operator_with_space' => false,
|
||||||
|
'ordered_class_elements' => true,
|
||||||
|
'php_unit_strict' => false,
|
||||||
|
'phpdoc_separation' => false,
|
||||||
|
'single_quote' => true,
|
||||||
|
'standardize_not_equals' => true,
|
||||||
|
'multiline_comment_opening_closing' => true,
|
||||||
|
])
|
||||||
|
->setFinder(
|
||||||
|
PhpCsFixer\Finder::create()
|
||||||
|
->exclude('public')
|
||||||
|
->exclude('runtime')
|
||||||
|
->exclude('vendor')
|
||||||
|
->in(__DIR__)
|
||||||
|
)
|
||||||
|
->setUsingCache(false);
|
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPSTORM_META {
|
||||||
|
|
||||||
|
// Reflect
|
||||||
|
override(\Psr\Container\ContainerInterface::get(0), map('@'));
|
||||||
|
override(\Hyperf\Utils\Context::get(0), map('@'));
|
||||||
|
override(\make(0), map('@'));
|
||||||
|
override(\di(0), map('@'));
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
# Default Dockerfile
|
||||||
|
#
|
||||||
|
# @link https://www.hyperf.io
|
||||||
|
# @document https://hyperf.wiki
|
||||||
|
# @contact group@hyperf.io
|
||||||
|
# @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
|
|
||||||
|
FROM hyperf/hyperf:8.0-alpine-v3.12-swoole
|
||||||
|
LABEL maintainer="Hyperf Developers <group@hyperf.io>" version="1.0" license="MIT" app.name="Hyperf"
|
||||||
|
|
||||||
|
##
|
||||||
|
# ---------- env settings ----------
|
||||||
|
##
|
||||||
|
# --build-arg timezone=Asia/Shanghai
|
||||||
|
ARG timezone
|
||||||
|
|
||||||
|
ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \
|
||||||
|
APP_ENV=prod \
|
||||||
|
SCAN_CACHEABLE=(true)
|
||||||
|
|
||||||
|
# update
|
||||||
|
RUN set -ex \
|
||||||
|
# show php version and extensions
|
||||||
|
&& php -v \
|
||||||
|
&& php -m \
|
||||||
|
&& php --ri swoole \
|
||||||
|
# ---------- some config ----------
|
||||||
|
&& cd /etc/php8 \
|
||||||
|
# - config PHP
|
||||||
|
&& { \
|
||||||
|
echo "upload_max_filesize=128M"; \
|
||||||
|
echo "post_max_size=128M"; \
|
||||||
|
echo "memory_limit=1G"; \
|
||||||
|
echo "date.timezone=${TIMEZONE}"; \
|
||||||
|
} | tee conf.d/99_overrides.ini \
|
||||||
|
# - config timezone
|
||||||
|
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
|
||||||
|
&& echo "${TIMEZONE}" > /etc/timezone \
|
||||||
|
# ---------- clear works ----------
|
||||||
|
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
|
||||||
|
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
|
||||||
|
|
||||||
|
WORKDIR /opt/www
|
||||||
|
|
||||||
|
# Composer Cache
|
||||||
|
# COPY ./composer.* /opt/www/
|
||||||
|
# RUN composer install --no-dev --no-scripts
|
||||||
|
|
||||||
|
COPY . /opt/www
|
||||||
|
RUN composer install --no-dev -o && php bin/hyperf.php
|
||||||
|
|
||||||
|
EXPOSE 9501
|
||||||
|
|
||||||
|
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]
|
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Command;
|
||||||
|
|
||||||
|
use App\Helper\Signer;
|
||||||
|
use App\Service\AppService;
|
||||||
|
use App\Service\MerchantService;
|
||||||
|
use Hyperf\Command\Command as HyperfCommand;
|
||||||
|
use Hyperf\Command\Annotation\Command;
|
||||||
|
use Hyperf\Contract\ContainerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Command
|
||||||
|
*/
|
||||||
|
class JinlingCommand extends HyperfCommand
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ContainerInterface
|
||||||
|
*/
|
||||||
|
protected $container;
|
||||||
|
|
||||||
|
protected $admin;
|
||||||
|
|
||||||
|
public function __construct(ContainerInterface $container)
|
||||||
|
{
|
||||||
|
$this->container = $container;
|
||||||
|
|
||||||
|
parent::__construct('jinling');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configure()
|
||||||
|
{
|
||||||
|
parent::configure();
|
||||||
|
$this->setDescription('廖金灵测试');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->buildPayPrams();
|
||||||
|
return;
|
||||||
|
/**
|
||||||
|
* @var MerchantService
|
||||||
|
*/
|
||||||
|
$merchantService = $this->container->make(MerchantService::class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var AppService
|
||||||
|
*/
|
||||||
|
$appService = $this->container->make(AppService::class);
|
||||||
|
$merchant = $merchantService->createMerchant([
|
||||||
|
'username' => 'elf',
|
||||||
|
'password' => '123456',
|
||||||
|
'email' => '360197197@qq.com',
|
||||||
|
'mobile' => '18760419185',
|
||||||
|
'ip' => '127.0.0.1'
|
||||||
|
]);
|
||||||
|
$appService->createApp($merchant);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildPayPrams() {
|
||||||
|
$params = [
|
||||||
|
'app_id' => '202304270000004',
|
||||||
|
'timestamp' => time(),
|
||||||
|
'nonce_str' => 'lSHKbuFngCXHN8Ue1s8QHAAzPvOL3u9O',
|
||||||
|
];
|
||||||
|
$data = [
|
||||||
|
'order_name' => '测试订单',
|
||||||
|
'currency' => 'CNY',
|
||||||
|
'amount' => '20',
|
||||||
|
'notify_url' => 'http://www.baidu.com',
|
||||||
|
'redirect_url' => 'http://www.google.com',
|
||||||
|
'out_order_no' => '1122',
|
||||||
|
'direct_pay' => 0,
|
||||||
|
'show_pc_pay_url' => 0,
|
||||||
|
];
|
||||||
|
$params['data'] = json_encode($data);
|
||||||
|
$sign = Signer::sign($params, 'lSHKbuFngCXHN8Ue1s8QHAAzPvOL3u9O');
|
||||||
|
$params['sign'] = $sign;
|
||||||
|
var_dump(json_encode($params));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
<?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 App\Constants;
|
||||||
|
|
||||||
|
use Hyperf\Constants\AbstractConstants;
|
||||||
|
use Hyperf\Constants\Annotation\Constants;
|
||||||
|
|
||||||
|
#[Constants]
|
||||||
|
class ResultCode extends AbstractConstants
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Message("成功")
|
||||||
|
*/
|
||||||
|
const SUCCESS = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("错误")
|
||||||
|
*/
|
||||||
|
const DEFAULT_ERROR = 2000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("Server Error")
|
||||||
|
*/
|
||||||
|
const SERVER_ERROR = 2001;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("message.param_error")
|
||||||
|
*/
|
||||||
|
const SYSTEM_INVALID = 2002;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("Params %s is invalid.")
|
||||||
|
*/
|
||||||
|
const PARAMS_INVALID = 2003;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("message.record_not_exist")
|
||||||
|
*/
|
||||||
|
const RECORD_NOT_FOUND = 2004;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("message.not_logged")
|
||||||
|
*/
|
||||||
|
const UNAUTHORIZED = 2005;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("无权限")
|
||||||
|
*/
|
||||||
|
const FORBIDDEN = 2006;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("message.too_frequent")
|
||||||
|
*/
|
||||||
|
const TOO_FREQUENT = 2007;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Message("Not Found")
|
||||||
|
*/
|
||||||
|
const NOT_FOUND = 2008;
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Contract;
|
||||||
|
|
||||||
|
interface SmsSender {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信验证码
|
||||||
|
*
|
||||||
|
* @param string $mobile 手机号
|
||||||
|
* @param string $code 验证码
|
||||||
|
* @param int $activeMinute 验证码有效期
|
||||||
|
*/
|
||||||
|
public function sendCode($mobile, $code, $activeMinute = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
*
|
||||||
|
* @param string $mobile 手机号
|
||||||
|
* @param string $content 短信内容
|
||||||
|
*/
|
||||||
|
public function send($mobile, $content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量发送短信
|
||||||
|
*
|
||||||
|
* @param array $mobiles 手机号
|
||||||
|
* @param string $content 短信内容
|
||||||
|
*/
|
||||||
|
public function sendBatch(array $mobiles, $content);
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Controller\Payment;
|
||||||
|
|
||||||
|
use App\Constants\ResultCode;
|
||||||
|
use App\Helper\Result;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||||
|
use Hyperf\HttpServer\Contract\ResponseInterface;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
abstract class AbstractController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var ContainerInterface
|
||||||
|
*/
|
||||||
|
protected ContainerInterface $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var RequestInterface
|
||||||
|
*/
|
||||||
|
protected RequestInterface $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Inject
|
||||||
|
* @var ResponseInterface
|
||||||
|
*/
|
||||||
|
protected ResponseInterface $response;
|
||||||
|
|
||||||
|
protected function success(array $data = [], string $message = '成功'): Result
|
||||||
|
{
|
||||||
|
return new Result(ResultCode::SUCCESS, $message, $data);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Controller\Payment;
|
||||||
|
|
||||||
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||||
|
use App\Service\PaymentService;
|
||||||
|
|
||||||
|
class NotifyController extends AbstractController
|
||||||
|
{
|
||||||
|
private PaymentService $paymentService;
|
||||||
|
|
||||||
|
public function __construct(PaymentService $paymentService)
|
||||||
|
{
|
||||||
|
$this->paymentService = $paymentService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(RequestInterface $request)
|
||||||
|
{
|
||||||
|
$params = $request->all();
|
||||||
|
return $this->paymentService->notify($params);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Controller\Payment;
|
||||||
|
|
||||||
|
use App\Model\Order;
|
||||||
|
use Hyperf\HttpServer\Contract\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface;
|
||||||
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||||
|
|
||||||
|
class PageController extends AbstractController
|
||||||
|
{
|
||||||
|
public function index(RequestInterface $request, ResponseInterface $response): Psr7ResponseInterface
|
||||||
|
{
|
||||||
|
$orderNo = $request->input('order_no', '');
|
||||||
|
if (!$orderNo) {
|
||||||
|
return '订单号错误';
|
||||||
|
}
|
||||||
|
$order = Order::where('order_no', $orderNo)->first();
|
||||||
|
if (!$order) {
|
||||||
|
return '订单号错误';
|
||||||
|
}
|
||||||
|
return $response->redirect($order->redirect_url);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Controller\Payment;
|
||||||
|
|
||||||
|
use App\Request\JsapiPayRequest;
|
||||||
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||||
|
use App\Service\PaymentService;
|
||||||
|
|
||||||
|
class PayController extends AbstractController
|
||||||
|
{
|
||||||
|
private PaymentService $paymentService;
|
||||||
|
|
||||||
|
public function __construct(PaymentService $paymentService)
|
||||||
|
{
|
||||||
|
$this->paymentService = $paymentService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsapi(RequestInterface $request)
|
||||||
|
{
|
||||||
|
$form = new JsapiPayRequest($request->all());
|
||||||
|
$order = $this->paymentService->jsapiPay($form->getApp(), $form->getData());
|
||||||
|
return $this->success([
|
||||||
|
'pay_url' => $order->pay_url,
|
||||||
|
'order_no' => $order->order_no,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Exception;
|
||||||
|
|
||||||
|
use App\Constants\ResultCode;
|
||||||
|
use Hyperf\Server\Exception\ServerException;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
abstract class BasicException extends ServerException
|
||||||
|
{
|
||||||
|
protected $code = ResultCode::DEFAULT_ERROR;
|
||||||
|
|
||||||
|
public function __construct(string $message = null, Throwable $previous = null)
|
||||||
|
{
|
||||||
|
if (is_null($message)) {
|
||||||
|
$message = ResultCode::getMessage($this->code);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($message, $this->code, $previous);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?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 App\Exception;
|
||||||
|
|
||||||
|
use App\Constants\ResultCode;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class BusinessException extends BasicException
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Exception\Handler;
|
||||||
|
|
||||||
|
use App\Constants\ResultCode;
|
||||||
|
use App\Exception\BasicException;
|
||||||
|
use App\Helper\Result;
|
||||||
|
use Hyperf\Contract\StdoutLoggerInterface;
|
||||||
|
use Hyperf\ExceptionHandler\ExceptionHandler;
|
||||||
|
use Hyperf\HttpMessage\Stream\SwooleStream;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Throwable;
|
||||||
|
use Hyperf\Database\Model\ModelNotFoundException;
|
||||||
|
|
||||||
|
class AppExceptionHandler extends ExceptionHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var StdoutLoggerInterface
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
public function __construct(StdoutLoggerInterface $logger)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle(Throwable $throwable, ResponseInterface $response)
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
$code = ResultCode::SERVER_ERROR;
|
||||||
|
$message = '';
|
||||||
|
$httpCode = 200;
|
||||||
|
if ($throwable instanceof BasicException) {
|
||||||
|
$this->stopPropagation();
|
||||||
|
$code = $throwable->getCode();
|
||||||
|
$message = $throwable->getMessage();
|
||||||
|
} elseif ($throwable instanceof ModelNotFoundException) {
|
||||||
|
$this->stopPropagation();
|
||||||
|
$code = ResultCode::RECORD_NOT_FOUND;
|
||||||
|
$message = ResultCode::getMessage($code);
|
||||||
|
} else {
|
||||||
|
if (config('app_env') == 'dev') {
|
||||||
|
$message = $throwable->getMessage();
|
||||||
|
$data = [
|
||||||
|
'line' => $throwable->getLine(),
|
||||||
|
'file' => $throwable->getFile(),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$message = ResultCode::getMessage($code);
|
||||||
|
}
|
||||||
|
$this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
|
||||||
|
$this->logger->error($throwable->getTraceAsString());
|
||||||
|
}
|
||||||
|
$result = new Result($code, $message, $data);
|
||||||
|
return $response
|
||||||
|
->withAddedHeader('content-type', 'application/json; charset=utf-8')
|
||||||
|
->withStatus($httpCode)
|
||||||
|
->withBody(new SwooleStream(strval($result)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isValid(Throwable $throwable): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Exception;
|
||||||
|
|
||||||
|
use App\Constants\ResultCode;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class ValidationException extends BasicException
|
||||||
|
{
|
||||||
|
protected $code = ResultCode::PARAMS_INVALID;
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Factory;
|
||||||
|
|
||||||
|
use App\Helper\SmsSender\JhSmsSender;
|
||||||
|
use App\Helper\SmsSender\XgSmsSender;
|
||||||
|
use App\Helper\SmsSender\ZwSmsSender;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
use App\Model\Tool;
|
||||||
|
|
||||||
|
class SmsSenderFactory
|
||||||
|
{
|
||||||
|
protected $senders = [
|
||||||
|
'sms_set' => XgSmsSender::class,
|
||||||
|
'zhongwang' => ZwSmsSender::class,
|
||||||
|
'juhedata' => JhSmsSender::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __invoke(ContainerInterface $container)
|
||||||
|
{
|
||||||
|
$tool = Tool::getActiveByGroup('sms');
|
||||||
|
if (!$tool) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$senderClass = $this->getSenderClass($tool);
|
||||||
|
if ($senderClass) {
|
||||||
|
return make($senderClass, compact('tool'));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSenderClass(Tool $tool)
|
||||||
|
{
|
||||||
|
return $this->senders[$tool->name] ?? null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
use Hyperf\Di\Annotation\AnnotationCollector;
|
||||||
|
|
||||||
|
class Annotation
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 只支持系统默认收集器
|
||||||
|
*/
|
||||||
|
public static function getMethodsByAnnotationAndClass(string $annotation, string $class): array
|
||||||
|
{
|
||||||
|
$items = AnnotationCollector::getMethodsByAnnotation($annotation);
|
||||||
|
$methods = [];
|
||||||
|
foreach ($items as $item) {
|
||||||
|
if ($item['class'] == $class) {
|
||||||
|
$methods[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 只支持系统默认收集器
|
||||||
|
*/
|
||||||
|
public static function getPropertiesByAnnotationAndClass(string $annotation, string $class): array
|
||||||
|
{
|
||||||
|
$items = AnnotationCollector::getPropertiesByAnnotation($annotation);
|
||||||
|
$properties = [];
|
||||||
|
foreach ($items as $item) {
|
||||||
|
if ($item['class'] == $class) {
|
||||||
|
$properties[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $properties;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
use App\Exception\BusinessException;
|
||||||
|
use Hyperf\Utils\ApplicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存辅助类
|
||||||
|
* @method static mixed get(string $key, mixed $default = null)
|
||||||
|
* @method static bool set(string $key, mixed $value, null|int|\DateInterval $ttl = null)
|
||||||
|
* @method static bool delete(string $key)
|
||||||
|
* @method static bool clear()
|
||||||
|
* @method static bool deleteMultiple(iterable $keys)
|
||||||
|
* @method static iterable getMultiple(iterable $keys, mixed $default = null)
|
||||||
|
* @method static bool setMultiple(iterable $values, null|int|\DateInterval $ttl = null)
|
||||||
|
* @method static bool has(string $key)
|
||||||
|
*/
|
||||||
|
class Cache
|
||||||
|
{
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
private static $cacheKeys = [
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function getKey($name, array $params = []): string
|
||||||
|
{
|
||||||
|
$cacheKey = self::$cacheKeys[$name] ?? null;
|
||||||
|
if (is_null($cacheKey)) {
|
||||||
|
throw new BusinessException('缓存不存在');
|
||||||
|
}
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
$cacheKey = str_replace('{' . $key . '}', $value, $cacheKey);
|
||||||
|
}
|
||||||
|
return $cacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInstance()
|
||||||
|
{
|
||||||
|
if (is_null(self::$instance)) {
|
||||||
|
self::$instance = ApplicationContext::getContainer()->get(\Psr\SimpleCache\CacheInterface::class);
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function __callStatic($method, $args)
|
||||||
|
{
|
||||||
|
return call_user_func_array([self::getInstance(), $method], $args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||||
|
use Hyperf\HttpServer\Router\Router;
|
||||||
|
|
||||||
|
if (!function_exists('loadRoutes')) {
|
||||||
|
/**
|
||||||
|
* 加载路由.
|
||||||
|
*/
|
||||||
|
function loadRoutes($path)
|
||||||
|
{
|
||||||
|
$files = scandir($path);
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if ($file == '.' || $file == '..') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$filePath = $path . '/' . $file;
|
||||||
|
if (is_dir($filePath)) {
|
||||||
|
$prefix = '/' . $file;
|
||||||
|
$options = [];
|
||||||
|
if (file_exists($filePath . '/_init.php')) {
|
||||||
|
$config = require($filePath . '/_init.php');
|
||||||
|
$prefix = $config['prefix'] ?? $prefix;
|
||||||
|
$options = $config['options'] ?? $options;
|
||||||
|
}
|
||||||
|
Router::addGroup($prefix, function () use ($filePath) {
|
||||||
|
loadRoutes($filePath);
|
||||||
|
}, $options);
|
||||||
|
} elseif (is_file($filePath)) {
|
||||||
|
if ($file == '_init.php') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
require_once $filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('getClientIp')) {
|
||||||
|
function getClientIp(RequestInterface $request)
|
||||||
|
{
|
||||||
|
$headers = $request->getHeaders();
|
||||||
|
if(isset($headers['x-forwarded-for'][0]) && !empty($headers['x-forwarded-for'][0])) {
|
||||||
|
$ips = explode(',', $headers['x-forwarded-for'][0]);
|
||||||
|
return trim($ips[0]);
|
||||||
|
} elseif (isset($headers['x-real-ip'][0]) && !empty($headers['x-real-ip'][0])) {
|
||||||
|
return $headers['x-real-ip'][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$serverParams = $request->getServerParams();
|
||||||
|
return $serverParams['remote_addr'] ?? '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('getRoutePrefix')) {
|
||||||
|
function getRoutePrefix()
|
||||||
|
{
|
||||||
|
return env('ROUTE_PREFIX', '/newSns');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
use Hyperf\Logger\LoggerFactory;
|
||||||
|
use Hyperf\Utils\ApplicationContext;
|
||||||
|
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
public static function get(string $name = 'app')
|
||||||
|
{
|
||||||
|
return ApplicationContext::getContainer()->get(LoggerFactory::class)->get($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function __callStatic($method, $args)
|
||||||
|
{
|
||||||
|
$name = 'app';
|
||||||
|
if (isset($args[2])) {
|
||||||
|
$name = $args[2];
|
||||||
|
unset($args[2]);
|
||||||
|
}
|
||||||
|
return call_user_func_array([self::get($name), $method], $args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,224 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\Macro;
|
||||||
|
|
||||||
|
use App\Helper\Str;
|
||||||
|
use Hyperf\Database\Model\Builder;
|
||||||
|
use Hyperf\Database\Model\Relations;
|
||||||
|
|
||||||
|
class WhereHasIn
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Builder
|
||||||
|
*/
|
||||||
|
protected $builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $relation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $nextRelation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Closure
|
||||||
|
*/
|
||||||
|
protected $callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $method = 'whereIn';
|
||||||
|
|
||||||
|
public function __construct(Builder $builder, $relation, $callback)
|
||||||
|
{
|
||||||
|
$this->builder = $builder;
|
||||||
|
$this->relation = $relation;
|
||||||
|
$this->callback = $callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Builder
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function execute()
|
||||||
|
{
|
||||||
|
if (! $this->relation) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->where(
|
||||||
|
$this->formatRelation()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Relations\Relation $relation
|
||||||
|
*
|
||||||
|
* @return Builder
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
protected function where($relation)
|
||||||
|
{
|
||||||
|
if ($relation instanceof Relations\MorphTo) {
|
||||||
|
throw new \Exception('Please use whereHasMorphIn() for MorphTo relationships.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$relationQuery = $this->getRelationQuery($relation);
|
||||||
|
$method = $this->method;
|
||||||
|
|
||||||
|
if (
|
||||||
|
$relation instanceof Relations\MorphOne
|
||||||
|
|| $relation instanceof Relations\MorphMany
|
||||||
|
) {
|
||||||
|
return $this->builder->{$method}(
|
||||||
|
$relation->getQualifiedParentKeyName(),
|
||||||
|
$this->withRelationQueryCallback(
|
||||||
|
$relationQuery
|
||||||
|
->select($relation->getQualifiedForeignKeyName())
|
||||||
|
->whereColumn($relation->getQualifiedParentKeyName(), $relation->getQualifiedForeignKeyName())
|
||||||
|
->where($relation->getQualifiedMorphType(), $relation->getMorphClass())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($relation instanceof Relations\MorphToMany) {
|
||||||
|
return $this->builder->{$method}(
|
||||||
|
$relation->getQualifiedParentKeyName(),
|
||||||
|
$this->withRelationQueryCallback(
|
||||||
|
$relationQuery
|
||||||
|
->select($relation->getQualifiedForeignPivotKeyName())
|
||||||
|
->whereColumn($relation->getQualifiedParentKeyName(), $relation->getQualifiedForeignPivotKeyName())
|
||||||
|
->where($relation->getTable().'.'.$relation->getMorphType(), $relation->getMorphClass())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BelongsTo
|
||||||
|
if ($relation instanceof Relations\BelongsTo) {
|
||||||
|
return $this->builder->{$method}(
|
||||||
|
$this->getRelationQualifiedForeignKeyName($relation),
|
||||||
|
$this->withRelationQueryCallback(
|
||||||
|
$relationQuery
|
||||||
|
->select($relation->getQualifiedOwnerKeyName())
|
||||||
|
->whereColumn($this->getRelationQualifiedForeignKeyName($relation), $relation->getQualifiedOwnerKeyName())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$relation instanceof Relations\HasOne
|
||||||
|
|| $relation instanceof Relations\HasMany
|
||||||
|
) {
|
||||||
|
return $this->builder->{$method}(
|
||||||
|
$relation->getQualifiedParentKeyName(),
|
||||||
|
$this->withRelationQueryCallback(
|
||||||
|
$relationQuery
|
||||||
|
->select($relation->getQualifiedForeignKeyName())
|
||||||
|
->whereColumn($relation->getQualifiedParentKeyName(), $relation->getQualifiedForeignKeyName())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BelongsToMany
|
||||||
|
if ($relation instanceof Relations\BelongsToMany) {
|
||||||
|
return $this->builder->{$method}(
|
||||||
|
$relation->getQualifiedParentKeyName(),
|
||||||
|
$this->withRelationQueryCallback(
|
||||||
|
$relationQuery
|
||||||
|
->select($relation->getQualifiedForeignPivotKeyName())
|
||||||
|
->whereColumn($relation->getQualifiedParentKeyName(), $relation->getQualifiedForeignPivotKeyName())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$relation instanceof Relations\HasOneThrough
|
||||||
|
|| $relation instanceof Relations\HasManyThrough
|
||||||
|
) {
|
||||||
|
return $this->builder->{$method}(
|
||||||
|
$relation->getQualifiedLocalKeyName(),
|
||||||
|
$this->withRelationQueryCallback(
|
||||||
|
$relationQuery
|
||||||
|
->select($relation->getQualifiedFirstKeyName())
|
||||||
|
->whereColumn($relation->getQualifiedLocalKeyName(), $relation->getQualifiedFirstKeyName())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \Exception(sprintf('%s does not support "whereHasIn".', get_class($relation)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Relations\Relation $relation
|
||||||
|
*
|
||||||
|
* @return Builder
|
||||||
|
*/
|
||||||
|
protected function getRelationQuery($relation)
|
||||||
|
{
|
||||||
|
$q = $relation->getQuery();
|
||||||
|
|
||||||
|
if ($this->builder->getModel()->getConnectionName() !== $q->getModel()->getConnectionName()) {
|
||||||
|
$databaseName = $this->getRelationDatabaseName($q);
|
||||||
|
$table = $q->getModel()->getTable();
|
||||||
|
|
||||||
|
if (! Str::contains($table, ["`$databaseName`.", "{$databaseName}."])) {
|
||||||
|
$q->from("{$databaseName}.{$table}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $q;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getRelationDatabaseName($q)
|
||||||
|
{
|
||||||
|
return config('database.connections.'.$q->getModel()->getConnectionName().'.database');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getRelationQualifiedForeignKeyName($relation)
|
||||||
|
{
|
||||||
|
if (method_exists($relation, 'getQualifiedForeignKeyName')) {
|
||||||
|
return $relation->getQualifiedForeignKeyName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $relation->getQualifiedForeignKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Relations\Relation
|
||||||
|
*/
|
||||||
|
protected function formatRelation()
|
||||||
|
{
|
||||||
|
if (is_object($this->relation)) {
|
||||||
|
$relation = $this->relation;
|
||||||
|
} else {
|
||||||
|
$relationNames = explode('.', $this->relation);
|
||||||
|
$this->nextRelation = implode('.', array_slice($relationNames, 1));
|
||||||
|
|
||||||
|
$method = $relationNames[0];
|
||||||
|
|
||||||
|
$relation = Relations\Relation::noConstraints(function () use ($method) {
|
||||||
|
return $this->builder->getModel()->$method();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $relation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Builder $relation
|
||||||
|
*
|
||||||
|
* @return Builder
|
||||||
|
*/
|
||||||
|
protected function withRelationQueryCallback($relationQuery)
|
||||||
|
{
|
||||||
|
return call_user_func($this->callback, $this->nextRelation, $relationQuery);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\Macro;
|
||||||
|
|
||||||
|
use Hyperf\Database\Model\Relations\Relation;
|
||||||
|
|
||||||
|
class WhereHasMorphIn
|
||||||
|
{
|
||||||
|
public static function make()
|
||||||
|
{
|
||||||
|
return function ($relation, $types, $callback = null, $boolean = 'and') {
|
||||||
|
$relation = $this->getRelationWithoutConstraints($relation);
|
||||||
|
|
||||||
|
$types = (array) $types;
|
||||||
|
|
||||||
|
if ($types === ['*']) {
|
||||||
|
$types = $this->model->newModelQuery()->distinct()->pluck($relation->getMorphType())->all();
|
||||||
|
|
||||||
|
foreach ($types as &$type) {
|
||||||
|
$type = Relation::getMorphedModel($type) ?? $type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->where(function ($query) use ($relation, $callback, $types) {
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$query->orWhere(function ($query) use ($relation, $callback, $type) {
|
||||||
|
$belongsTo = $this->getBelongsToRelation($relation, $type);
|
||||||
|
|
||||||
|
if ($callback) {
|
||||||
|
$callback = function ($query) use ($callback, $type) {
|
||||||
|
return $callback($query, $type);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$query->where($relation->getRelated()->getTable().'.'.$relation->getMorphType(), '=', (new $type)->getMorphClass())
|
||||||
|
->whereHasIn($belongsTo, $callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, null, null, $boolean);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\Macro;
|
||||||
|
|
||||||
|
class WhereHasNotIn extends WhereHasIn
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $method = 'whereNotIn';
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
use App\Exception\BusinessException;
|
||||||
|
use Hyperf\Database\Model\Relations\Relation;
|
||||||
|
|
||||||
|
class Morph
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 只支持多态关联实体的关联键为id
|
||||||
|
*
|
||||||
|
* @param int $morphId
|
||||||
|
* @param string $morphType
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function getMorph(int $morphId, string $morphType)
|
||||||
|
{
|
||||||
|
$class = self::getMorphClass($morphType);
|
||||||
|
if (is_null($class)) {
|
||||||
|
throw new BusinessException('Morph type error!');
|
||||||
|
}
|
||||||
|
return $class::where('id', $morphId)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMorphClass(string $morphType): ?string
|
||||||
|
{
|
||||||
|
return Relation::$morphMap[$morphType] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证评论类型是否存在
|
||||||
|
*
|
||||||
|
* @param string $morphType
|
||||||
|
* @return void
|
||||||
|
* @throws BusinessException
|
||||||
|
*/
|
||||||
|
public static function checkMorphType(string $morphType)
|
||||||
|
{
|
||||||
|
if (is_null(self::getMorphClass($morphType))) {
|
||||||
|
throw new BusinessException('Morph type error!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function instanceOf(string $morphType, $instance): bool
|
||||||
|
{
|
||||||
|
return get_class($instance) === self::getMorphClass($morphType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMorphTypeOfInstance(object $instance): string
|
||||||
|
{
|
||||||
|
return self::getMorphType(get_class($instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMorphType(string $class): string
|
||||||
|
{
|
||||||
|
$morphMap = Relation::$morphMap;
|
||||||
|
$morphMap = array_flip($morphMap);
|
||||||
|
return $morphMap[$class] ?? '';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay;
|
||||||
|
|
||||||
|
use App\Helper\OmiPay\Request\AbstractRequest;
|
||||||
|
use App\Helper\StringHelper;
|
||||||
|
use App\Helper\TimeHelper;
|
||||||
|
use Exception;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use Hyperf\Guzzle\CoroutineHandler;
|
||||||
|
use GuzzleHttp\HandlerStack;
|
||||||
|
|
||||||
|
abstract class AbstractApi
|
||||||
|
{
|
||||||
|
protected static $client;
|
||||||
|
|
||||||
|
protected static function getCommonParams() {
|
||||||
|
$params = [
|
||||||
|
'm_number' => Config::get('app_id'),
|
||||||
|
'timestamp' => TimeHelper::getMillisecond(),
|
||||||
|
'nonce_str' => StringHelper::getRandomString(32),
|
||||||
|
];
|
||||||
|
$params['sign'] = Signer::sign($params);
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function request(AbstractRequest $request) {
|
||||||
|
$params = self::getCommonParams();
|
||||||
|
$params = array_merge($params, $request->getParams());
|
||||||
|
try {
|
||||||
|
$response = self::getClient()->post($request->getUrl(), [
|
||||||
|
'query' => $params
|
||||||
|
]);
|
||||||
|
$body = (string)$response->getBody();
|
||||||
|
$result = json_decode($body, true);
|
||||||
|
if (empty($result)) {
|
||||||
|
$result = [
|
||||||
|
'return_code' => 'FAIL',
|
||||||
|
'error_code' => 'RESPONSE_ERROR',
|
||||||
|
'error_msg' => '返回数据异常',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return new Result($result);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return new Result([
|
||||||
|
'return_code' => 'FAIL',
|
||||||
|
'error_code' => 'NETWORK_ERROR',
|
||||||
|
'error_msg' => '网络错误',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function getClient(): Client {
|
||||||
|
if (!self::$client) {
|
||||||
|
self::$client = new Client([
|
||||||
|
'base_uri' => Config::get('base_url'),
|
||||||
|
'handler' => HandlerStack::create(new CoroutineHandler()),
|
||||||
|
'headers' => [
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
],
|
||||||
|
'timeout' => 5,
|
||||||
|
'swoole' => [
|
||||||
|
'timeout' => 10,
|
||||||
|
'socket_buffer_size' => 1024 * 1024 * 2,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return self::$client;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay;
|
||||||
|
|
||||||
|
use App\Helper\OmiPay\Request\GetExchangeRateRequest;
|
||||||
|
use App\Helper\OmiPay\Request\MakeJSAPIOrderRequest;
|
||||||
|
use App\Helper\OmiPay\Request\QueryRefundRequest;
|
||||||
|
use App\Helper\OmiPay\Request\RefundRequest;
|
||||||
|
|
||||||
|
class Api extends AbstractApi
|
||||||
|
{
|
||||||
|
public static function getExchangeRate($currency, $baseCurrency, $platform = 'WECHATPAY', $language = 'CHS') {
|
||||||
|
$request = new GetExchangeRateRequest();
|
||||||
|
$request->setCurrency($currency);
|
||||||
|
$request->setBaseCurrency($baseCurrency);
|
||||||
|
$request->setPlatform($platform);
|
||||||
|
$request->setLanguage($language);
|
||||||
|
return self::request($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function makeJSAPIOrder($orderName, $outOrderNo, $currency, $amount, $notifyUrl, $redirectUrl) {
|
||||||
|
$request = new MakeJSAPIOrderRequest();
|
||||||
|
$request->setOrderName($orderName);
|
||||||
|
$request->setCurrency($currency);
|
||||||
|
$request->setOutOrderNo($outOrderNo);
|
||||||
|
$request->setAmount($amount);
|
||||||
|
$request->setNotifyUrl($notifyUrl);
|
||||||
|
$request->setRedirectUrl($redirectUrl);
|
||||||
|
$request->setDirectPay(0);
|
||||||
|
$request->setShowPcPayUrl(0);
|
||||||
|
return self::request($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function refund($orderNo, $outRefundNo, $amount) {
|
||||||
|
$request = new RefundRequest();
|
||||||
|
$request->setOrderNo($orderNo);
|
||||||
|
$request->setOutRefundNo($outRefundNo);
|
||||||
|
$request->setAmount($amount);
|
||||||
|
return self::request($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function queryRefund($refundNo) {
|
||||||
|
$request = new QueryRefundRequest();
|
||||||
|
$request->setRefundNo($refundNo);
|
||||||
|
return self::request($request);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay;
|
||||||
|
|
||||||
|
use App\Helper\StringHelper;
|
||||||
|
use App\Helper\TimeHelper;
|
||||||
|
|
||||||
|
class Config
|
||||||
|
{
|
||||||
|
private static $params = [
|
||||||
|
'app_id' => '30042195760',
|
||||||
|
'secret_key' => 'cea6f34bea8640dea91fd8b7a926a9a5',
|
||||||
|
'base_url' => 'https://www.omipay.com.cn',
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function get($key) {
|
||||||
|
return self::$params[$key] ?: null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay\Request;
|
||||||
|
|
||||||
|
use App\Helper\OmiPay\Config;
|
||||||
|
|
||||||
|
abstract class AbstractRequest
|
||||||
|
{
|
||||||
|
protected $uri;
|
||||||
|
|
||||||
|
protected $method;
|
||||||
|
|
||||||
|
protected $_params = [];
|
||||||
|
|
||||||
|
public function getUrl() {
|
||||||
|
return Config::get('base_url') . $this->uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParams() {
|
||||||
|
return $this->_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
return $this->_params[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($name, $value)
|
||||||
|
{
|
||||||
|
$this->_params[$name] = $value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay\Request;
|
||||||
|
|
||||||
|
class GetExchangeRateRequest extends AbstractRequest
|
||||||
|
{
|
||||||
|
protected $uri = '/omipay/api/v2/GetExchangeRate';
|
||||||
|
|
||||||
|
public function setCurrency($currency) {
|
||||||
|
$this->currency = $currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBaseCurrency($baseCurrency) {
|
||||||
|
$this->base_currency = $baseCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPlatform($platform) {
|
||||||
|
$this->platform = $platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLanguage($language) {
|
||||||
|
$this->language = $language;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay\Request;
|
||||||
|
|
||||||
|
class MakeJSAPIOrderRequest extends AbstractRequest
|
||||||
|
{
|
||||||
|
protected $uri = '/omipay/api/v2/MakeJSAPIOrder';
|
||||||
|
|
||||||
|
public function setOrderName($orderName) {
|
||||||
|
$this->order_name = $orderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOutOrderNo($outOrderNo) {
|
||||||
|
$this->out_order_no = $outOrderNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCurrency($currency) {
|
||||||
|
$this->currency = $currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAmount($amount) {
|
||||||
|
$this->amount = $amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNotifyUrl($notifyUrl) {
|
||||||
|
$this->notify_url = $notifyUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRedirectUrl($redirectUrl) {
|
||||||
|
$this->redirect_url = $redirectUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDirectPay($directPay) {
|
||||||
|
$this->direct_pay = $directPay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setShowPcPayUrl($showPcPayUrl) {
|
||||||
|
$this->show_pc_pay_url = $showPcPayUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setONumber($oNumber) {
|
||||||
|
$this->o_number = $oNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPosNo($posNo) {
|
||||||
|
$this->pos_no = $posNo;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay\Request;
|
||||||
|
|
||||||
|
class QueryOrderRequest extends AbstractRequest
|
||||||
|
{
|
||||||
|
protected $uri = '/omipay/api/v2/QueryOrder';
|
||||||
|
|
||||||
|
public function setOrderNo($orderNo) {
|
||||||
|
$this->order_no = $orderNo;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay\Request;
|
||||||
|
|
||||||
|
class QueryRefundRequest extends AbstractRequest
|
||||||
|
{
|
||||||
|
protected $uri = '/omipay/api/v2/QueryRefund';
|
||||||
|
|
||||||
|
public function setRefundNo($refundNo) {
|
||||||
|
$this->refund_no = $refundNo;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay\Request;
|
||||||
|
|
||||||
|
class RefundRequest extends AbstractRequest
|
||||||
|
{
|
||||||
|
protected $uri = '/omipay/api/v2/Refund';
|
||||||
|
|
||||||
|
public function setOrderNo($orderNo) {
|
||||||
|
$this->order_no = $orderNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOutRefundNo($outRefundNo) {
|
||||||
|
$this->out_refund_no = $outRefundNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAmount($amount) {
|
||||||
|
$this->amount = $amount;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay;
|
||||||
|
|
||||||
|
class Result
|
||||||
|
{
|
||||||
|
private $data;
|
||||||
|
|
||||||
|
public function __construct($data)
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSuccess() {
|
||||||
|
return $this->data['return_code'] == 'SUCCESS';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get($key) {
|
||||||
|
return $this->data[$key] ?? null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper\OmiPay;
|
||||||
|
|
||||||
|
class Signer
|
||||||
|
{
|
||||||
|
public static function sign($params) {
|
||||||
|
$signString = $params['m_number'] . '&'
|
||||||
|
. $params['timestamp'] . '&'
|
||||||
|
. $params['nonce_str'] . '&'
|
||||||
|
. Config::get('secret_key');
|
||||||
|
return strtoupper(md5($signString));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function verify($params) {
|
||||||
|
$sign = $params['sign'] ?? '';
|
||||||
|
return $sign == self::sign($params);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
use Hyperf\AsyncQueue\Driver\DriverFactory;
|
||||||
|
use Hyperf\Utils\ApplicationContext;
|
||||||
|
|
||||||
|
class Queue
|
||||||
|
{
|
||||||
|
private static $factory;
|
||||||
|
|
||||||
|
private static function getFactory()
|
||||||
|
{
|
||||||
|
if (is_null(self::$factory)) {
|
||||||
|
self::$factory = ApplicationContext::getContainer()->get(DriverFactory::class);
|
||||||
|
}
|
||||||
|
return self::$factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function push($jobClass, $params, int $delay = 0): bool
|
||||||
|
{
|
||||||
|
$job = new $jobClass($params);
|
||||||
|
return self::getFactory()->get($job->getQueueName())->push($job, $delay);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
use Hyperf\Redis\RedisFactory;
|
||||||
|
use Hyperf\Redis\RedisProxy;
|
||||||
|
use Hyperf\Utils\ApplicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis辅助类
|
||||||
|
*/
|
||||||
|
class Redis
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var RedisFactory
|
||||||
|
*/
|
||||||
|
private static $factory;
|
||||||
|
|
||||||
|
private static function getFactory(): RedisFactory
|
||||||
|
{
|
||||||
|
if (is_null(self::$factory)) {
|
||||||
|
self::$factory = ApplicationContext::getContainer()->get(RedisFactory::class);
|
||||||
|
}
|
||||||
|
return self::$factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInstance($poolName = 'default'): RedisProxy
|
||||||
|
{
|
||||||
|
return self::getFactory()->get($poolName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function __callStatic($method, $args)
|
||||||
|
{
|
||||||
|
return call_user_func_array([self::getInstance(), $method], $args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
class RedisKey
|
||||||
|
{
|
||||||
|
public static function getGenerateAppIdKey($timestamp) {
|
||||||
|
return 'gennerate_app_id:' . date('Ymd', $timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getGenerateOrderNoKey($timestamp) {
|
||||||
|
return 'gennerate_order_no:' . date('YmdHi', $timestamp);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
use App\Constants\ResultCode;
|
||||||
|
use Hyperf\Utils\Contracts\Arrayable;
|
||||||
|
|
||||||
|
class Result implements Arrayable
|
||||||
|
{
|
||||||
|
private $code;
|
||||||
|
private $message;
|
||||||
|
private $data = [];
|
||||||
|
|
||||||
|
public function __construct(int $code = ResultCode::SUCCESS, string $message = '', array $data = [])
|
||||||
|
{
|
||||||
|
$this->code = $code;
|
||||||
|
$this->message = empty($message) ? ResultCode::getMessage($code) : $message;
|
||||||
|
$this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode(): int
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCode(int $code)
|
||||||
|
{
|
||||||
|
return $this->code = $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMessage(): string
|
||||||
|
{
|
||||||
|
return $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMessage(string $message)
|
||||||
|
{
|
||||||
|
return $this->message = empty($message) ? ResultCode::getMessage($this->code) : $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData(): array
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setData(array $data)
|
||||||
|
{
|
||||||
|
return $this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'code' => $this->code,
|
||||||
|
'message' => $this->message,
|
||||||
|
'data' => new \ArrayObject($this->data),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return json_encode($this->toArray(), JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
class Signer
|
||||||
|
{
|
||||||
|
public static function sign($params, $secretKey) {
|
||||||
|
$signString = $params['app_id'] . '&'
|
||||||
|
. $params['timestamp'] . '&'
|
||||||
|
. $params['nonce_str'] . '&'
|
||||||
|
. $params['data'] . '&'
|
||||||
|
. $secretKey;
|
||||||
|
return md5($signString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function verify($params, $secretKey) {
|
||||||
|
$sign = self::sign($params, $secretKey);
|
||||||
|
return $sign == $params['sign'];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
class StringHelper
|
||||||
|
{
|
||||||
|
public static function getRandomString($length, $withSpecialChar = false)
|
||||||
|
{
|
||||||
|
$chars = array(
|
||||||
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
|
||||||
|
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||||
|
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
|
||||||
|
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2',
|
||||||
|
'3', '4', '5', '6', '7', '8', '9'
|
||||||
|
);
|
||||||
|
|
||||||
|
if($withSpecialChar){
|
||||||
|
$chars = array_merge($chars, array(
|
||||||
|
'!', '@', '#', '$', '?', '|', '{', '/', ':', ';',
|
||||||
|
'%', '^', '&', '*', '(', ')', '-', '_', '[', ']',
|
||||||
|
'}', '<', '>', '~', '+', '=', ',', '.'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$charsLen = count($chars) - 1;
|
||||||
|
shuffle($chars);
|
||||||
|
|
||||||
|
$password = '';
|
||||||
|
for($i=0; $i<$length; $i++){
|
||||||
|
$password .= $chars[mt_rand(0, $charsLen)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $password;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Helper;
|
||||||
|
|
||||||
|
class TimeHelper
|
||||||
|
{
|
||||||
|
public static function getMillisecond(){
|
||||||
|
return (intval(round(microtime(true) * 1000)));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Job;
|
||||||
|
|
||||||
|
use App\Service\UserService;
|
||||||
|
|
||||||
|
class AfterLoginJob extends Job
|
||||||
|
{
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var UserService $userService
|
||||||
|
*/
|
||||||
|
$userService = make(UserService::class);
|
||||||
|
$userService->afterLogin($this->params);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Job;
|
||||||
|
|
||||||
|
use App\Service\UserService;
|
||||||
|
|
||||||
|
class AfterRegisterJob extends Job
|
||||||
|
{
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$userId = $this->params['user_id'] ?? '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var UserService $userService
|
||||||
|
*/
|
||||||
|
$userService = make(UserService::class);
|
||||||
|
$userService->afterRegister($userId);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Job;
|
||||||
|
|
||||||
|
use App\Service\PlayerRoleService;
|
||||||
|
|
||||||
|
class AfterSaveRoleJob extends Job
|
||||||
|
{
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PlayerRoleService $playerRoleService
|
||||||
|
*/
|
||||||
|
$playerRoleService = make(PlayerRoleService::class);
|
||||||
|
$playerRoleService->save($this->params);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Job;
|
||||||
|
|
||||||
|
use App\Service\SpendService;
|
||||||
|
|
||||||
|
class AfterSpendJob extends Job
|
||||||
|
{
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$payOrderNumber = $this->params['pay_order_number'] ?? '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SpendService $spendService
|
||||||
|
*/
|
||||||
|
$spendService = make(SpendService::class);
|
||||||
|
$spendService->afterSpend($payOrderNumber);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Job;
|
||||||
|
|
||||||
|
use Hyperf\AsyncQueue\Job as BaseJob;
|
||||||
|
|
||||||
|
class Job extends BaseJob
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $params;
|
||||||
|
|
||||||
|
protected $queueName = 'default';
|
||||||
|
|
||||||
|
public function __construct(array $params)
|
||||||
|
{
|
||||||
|
$this->params = $this->prepare($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepare(array $params): array
|
||||||
|
{
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getJobName()
|
||||||
|
{
|
||||||
|
return get_called_class();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueueName()
|
||||||
|
{
|
||||||
|
return $this->queueName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Job;
|
||||||
|
|
||||||
|
use App\Exception\BusinessException;
|
||||||
|
use App\Service\SmsService;
|
||||||
|
|
||||||
|
class SmsJob extends Job
|
||||||
|
{
|
||||||
|
public $params;
|
||||||
|
|
||||||
|
protected $queueName = 'sms';
|
||||||
|
|
||||||
|
public function __construct($params)
|
||||||
|
{
|
||||||
|
$this->params = $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$mobile = $this->params['mobile'] ?? null;
|
||||||
|
$options = $this->params['options'] ?? [];
|
||||||
|
$type = $options['type'] ?? '';
|
||||||
|
if (!$mobile) {
|
||||||
|
throw new BusinessException('缺少手机号');
|
||||||
|
}
|
||||||
|
if (!$type) {
|
||||||
|
throw new BusinessException('缺少类型');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SmsService $smsService
|
||||||
|
*/
|
||||||
|
$smsService = make(SmsService::class);
|
||||||
|
if ($type == 'content') {
|
||||||
|
$content = $options['content'] ?? '';
|
||||||
|
$smsService->send($mobile, $content);
|
||||||
|
} elseif ($type == 'code') {
|
||||||
|
$clientIp = $options['client_ip'] ?? '';
|
||||||
|
$smsService->sendCode($mobile, ['client_ip' => $clientIp]);
|
||||||
|
} elseif ($type == 'batch') {
|
||||||
|
if (!is_array($mobile)) {
|
||||||
|
$mobile = [$mobile];
|
||||||
|
}
|
||||||
|
$content = $options['content'] ?? '';
|
||||||
|
$smsService->sendBatch($mobile, $content);
|
||||||
|
} else {
|
||||||
|
throw new BusinessException('类型错误');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
<?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 App\Listener;
|
||||||
|
|
||||||
|
use Hyperf\Database\Events\QueryExecuted;
|
||||||
|
use Hyperf\Event\Annotation\Listener;
|
||||||
|
use Hyperf\Event\Contract\ListenerInterface;
|
||||||
|
use Hyperf\Logger\LoggerFactory;
|
||||||
|
use Hyperf\Utils\Arr;
|
||||||
|
use Hyperf\Utils\Str;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Listener
|
||||||
|
*/
|
||||||
|
class DbQueryExecutedListener implements ListenerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
public function __construct(ContainerInterface $container)
|
||||||
|
{
|
||||||
|
$this->logger = $container->get(LoggerFactory::class)->get('sql');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listen(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
QueryExecuted::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param QueryExecuted $event
|
||||||
|
*/
|
||||||
|
public function process(object $event)
|
||||||
|
{
|
||||||
|
if ($event instanceof QueryExecuted) {
|
||||||
|
$sql = $event->sql;
|
||||||
|
if (! Arr::isAssoc($event->bindings)) {
|
||||||
|
foreach ($event->bindings as $key => $value) {
|
||||||
|
$sql = Str::replaceFirst('?', "'{$value}'", $sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->info(sprintf('[%s] %s', $event->time, $sql));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Listener;
|
||||||
|
|
||||||
|
use App\Helper\Macro\WhereHasIn;
|
||||||
|
use App\Helper\Macro\WhereHasMorphIn;
|
||||||
|
use App\Helper\Macro\WhereHasNotIn;
|
||||||
|
use Hyperf\Database\Model\Builder;
|
||||||
|
use Hyperf\Database\Model\Relations\Relation;
|
||||||
|
use Hyperf\Event\Annotation\Listener;
|
||||||
|
use Hyperf\Event\Contract\ListenerInterface;
|
||||||
|
use Hyperf\Framework\Event\BootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Listener
|
||||||
|
*/
|
||||||
|
class ModelPrepareListener implements ListenerInterface
|
||||||
|
{
|
||||||
|
public function listen(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
BootApplication::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(object $event)
|
||||||
|
{
|
||||||
|
$this->morphMapRelation();
|
||||||
|
$this->macroWhereHasIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function morphMapRelation()
|
||||||
|
{
|
||||||
|
Relation::morphMap([
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function macroWhereHasIn()
|
||||||
|
{
|
||||||
|
Builder::macro('whereHasIn', function ($relationName, $callable = null) {
|
||||||
|
return (new WhereHasIn($this, $relationName, function ($nextRelation, $builder) use ($callable) {
|
||||||
|
if ($nextRelation) {
|
||||||
|
return $builder->whereHasIn($nextRelation, $callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($callable) {
|
||||||
|
return $builder->callScope($callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $builder;
|
||||||
|
}))->execute();
|
||||||
|
});
|
||||||
|
Builder::macro('orWhereHasIn', function ($relationName, $callable = null) {
|
||||||
|
return $this->orWhere(function ($query) use ($relationName, $callable) {
|
||||||
|
return $query->whereHasIn($relationName, $callable);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Builder::macro('whereHasNotIn', function ($relationName, $callable = null) {
|
||||||
|
return (new WhereHasNotIn($this, $relationName, function ($nextRelation, $builder) use ($callable) {
|
||||||
|
if ($nextRelation) {
|
||||||
|
return $builder->whereHasNotIn($nextRelation, $callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($callable) {
|
||||||
|
return $builder->callScope($callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $builder;
|
||||||
|
}))->execute();
|
||||||
|
});
|
||||||
|
Builder::macro('orWhereHasNotIn', function ($relationName, $callable = null) {
|
||||||
|
return $this->orWhere(function ($query) use ($relationName, $callable) {
|
||||||
|
return $query->whereHasNotIn($relationName, $callable);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Builder::macro('whereHasMorphIn', WhereHasMorphIn::make());
|
||||||
|
Builder::macro('orWhereHasMorphIn', function ($relation, $types, $callback = null) {
|
||||||
|
return $this->whereHasMorphIn($relation, $types, $callback, 'or');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
<?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 App\Listener;
|
||||||
|
|
||||||
|
use Hyperf\AsyncQueue\AnnotationJob;
|
||||||
|
use Hyperf\AsyncQueue\Event\AfterHandle;
|
||||||
|
use Hyperf\AsyncQueue\Event\BeforeHandle;
|
||||||
|
use Hyperf\AsyncQueue\Event\Event;
|
||||||
|
use Hyperf\AsyncQueue\Event\FailedHandle;
|
||||||
|
use Hyperf\AsyncQueue\Event\RetryHandle;
|
||||||
|
use Hyperf\Event\Annotation\Listener;
|
||||||
|
use Hyperf\Event\Contract\ListenerInterface;
|
||||||
|
use Hyperf\ExceptionHandler\Formatter\FormatterInterface;
|
||||||
|
use Hyperf\Logger\LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Listener
|
||||||
|
*/
|
||||||
|
class QueueHandleListener implements ListenerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Psr\Log\LoggerInterface
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FormatterInterface
|
||||||
|
*/
|
||||||
|
protected $formatter;
|
||||||
|
|
||||||
|
public function __construct(LoggerFactory $loggerFactory, FormatterInterface $formatter)
|
||||||
|
{
|
||||||
|
$this->logger = $loggerFactory->get('queue');
|
||||||
|
$this->formatter = $formatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listen(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterHandle::class,
|
||||||
|
BeforeHandle::class,
|
||||||
|
FailedHandle::class,
|
||||||
|
RetryHandle::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(object $event)
|
||||||
|
{
|
||||||
|
if ($event instanceof Event && $event->message->job()) {
|
||||||
|
$job = $event->message->job();
|
||||||
|
$jobClass = get_class($job);
|
||||||
|
if ($job instanceof AnnotationJob) {
|
||||||
|
$jobClass = sprintf('Job[%s@%s]', $job->class, $job->method);
|
||||||
|
}
|
||||||
|
$date = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case $event instanceof BeforeHandle:
|
||||||
|
$this->logger->info(sprintf('[%s] Processing %s.', $date, $jobClass));
|
||||||
|
break;
|
||||||
|
case $event instanceof AfterHandle:
|
||||||
|
$this->logger->info(sprintf('[%s] Processed %s.', $date, $jobClass));
|
||||||
|
break;
|
||||||
|
case $event instanceof FailedHandle:
|
||||||
|
$this->logger->error(sprintf('[%s] Failed %s.', $date, $jobClass));
|
||||||
|
$this->logger->error($this->formatter->format($event->getThrowable()));
|
||||||
|
break;
|
||||||
|
case $event instanceof RetryHandle:
|
||||||
|
$this->logger->warning(sprintf('[%s] Retried %s.', $date, $jobClass));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
class App extends Model
|
||||||
|
{
|
||||||
|
public const STATUS_ACTIVE = 1;
|
||||||
|
|
||||||
|
protected $table = 'apps';
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
class Merchant extends Model
|
||||||
|
{
|
||||||
|
public const STATUS_ACTIVE = 1;
|
||||||
|
|
||||||
|
protected $table = 'merchants';
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
use Hyperf\DbConnection\Model\Model as BaseModel;
|
||||||
|
|
||||||
|
abstract class Model extends BaseModel
|
||||||
|
{
|
||||||
|
public static function alias($alias = null)
|
||||||
|
{
|
||||||
|
$name = with(new static)->getTable();
|
||||||
|
if ($alias) {
|
||||||
|
$name .= ' as ' . $alias;
|
||||||
|
}
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromAlias($alias)
|
||||||
|
{
|
||||||
|
return static::from(static::alias($alias));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRawAttribute($key)
|
||||||
|
{
|
||||||
|
if (! $key) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $this->attributes[$key] ?? null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
class Order extends Model
|
||||||
|
{
|
||||||
|
public const STATUS_PREPARE = 1;
|
||||||
|
public const STATUS_WAIT_PAY = 2;
|
||||||
|
public const STATUS_PAYED = 6;
|
||||||
|
public const STATUS_FAILED = 9;
|
||||||
|
|
||||||
|
protected $table = 'orders';
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<?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 App\Process;
|
||||||
|
|
||||||
|
use Hyperf\AsyncQueue\Process\ConsumerProcess;
|
||||||
|
use Hyperf\Process\Annotation\Process;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Process
|
||||||
|
*/
|
||||||
|
class AsyncQueueConsumer extends ConsumerProcess
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Process;
|
||||||
|
|
||||||
|
use Hyperf\AsyncQueue\Process\ConsumerProcess;
|
||||||
|
use Hyperf\Process\Annotation\Process;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Process()
|
||||||
|
*/
|
||||||
|
class SmsQueueConsumer extends ConsumerProcess
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $queue = 'sms';
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Model\Promote;
|
||||||
|
|
||||||
|
class PromoteRepository
|
||||||
|
{
|
||||||
|
public function getLevelPromotesById($id, $columns = ['*']) {
|
||||||
|
$promote = Promote::query()->where('id', $id)->first(Promote::$levelColumns);
|
||||||
|
$levelIds = [];
|
||||||
|
foreach (Promote::$levelColumns as $column) {
|
||||||
|
if ($promote->{$column} > 0) {
|
||||||
|
$levelIds[] = $promote->{$column};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promote::query()->whereIn('id', $levelIds)->get($columns);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Request;
|
||||||
|
|
||||||
|
use App\Exception\BusinessException;
|
||||||
|
use App\Helper\Signer;
|
||||||
|
use App\Model\App;
|
||||||
|
|
||||||
|
class ApiRequest extends Request
|
||||||
|
{
|
||||||
|
protected App $app;
|
||||||
|
|
||||||
|
public function __construct(array $params = [])
|
||||||
|
{
|
||||||
|
$this->checkApp($params['app_id'] ?? null);
|
||||||
|
$this->checkSign($params);
|
||||||
|
|
||||||
|
$data = json_decode($params['data'], true);
|
||||||
|
foreach ($this->defaults() as $key => $value) {
|
||||||
|
if (isset($data[$key])) {
|
||||||
|
if (empty($value) && empty($data[$key])) {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->_data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function checkSign($params) {
|
||||||
|
/* if ($params['timestamp'] < time() - 600) {
|
||||||
|
throw new BusinessException('请求已过期');
|
||||||
|
} */
|
||||||
|
if (!Signer::verify($params, $this->app->app_key)) {
|
||||||
|
throw new BusinessException('验签错误');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function checkApp($appId) {
|
||||||
|
if (is_null($appId)) {
|
||||||
|
throw new BusinessException('[app_id]错误');
|
||||||
|
}
|
||||||
|
$app = App::query()->where('app_id', $appId)->first();
|
||||||
|
if (is_null($app)) {
|
||||||
|
throw new BusinessException('APP错误');
|
||||||
|
}
|
||||||
|
$this->app = $app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApp() {
|
||||||
|
return $this->app;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Request;
|
||||||
|
|
||||||
|
use Hyperf\Validation\Rule;
|
||||||
|
|
||||||
|
class JsapiPayRequest extends ApiRequest
|
||||||
|
{
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'order_name' => ['required', 'max:64'],
|
||||||
|
'out_order_no' => ['required', 'max:32'],
|
||||||
|
'amount' => ['required', Rule::in([5,10,20,30,50,80,98,198,298,398,498,598,698,798,898,998])],
|
||||||
|
'currency' => ['required', Rule::in(['CNY'])],
|
||||||
|
'show_pc_pay_url' => ['integer', Rule::in([1, 2])],
|
||||||
|
'direct_pay' => ['integer', Rule::in([1, 2])],
|
||||||
|
'notify_url' => ['required', 'url'],
|
||||||
|
'redirect_url' => ['required', 'url'],
|
||||||
|
'o_number' => ['max:32'],
|
||||||
|
'pos_no' => ['max:32'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,212 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Request;
|
||||||
|
|
||||||
|
use App\Annotation\Validation\After;
|
||||||
|
use App\Exception\BusinessException;
|
||||||
|
use App\Exception\ValidationException;
|
||||||
|
use App\Helper\Annotation;
|
||||||
|
use Hyperf\Contract\ValidatorInterface;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Hyperf\Utils\Contracts\MessageBag;
|
||||||
|
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
|
||||||
|
|
||||||
|
class Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Inject()
|
||||||
|
* @var ValidatorFactoryInterface
|
||||||
|
*/
|
||||||
|
protected ValidatorFactoryInterface $validationFactory;
|
||||||
|
|
||||||
|
protected $_data = [];
|
||||||
|
|
||||||
|
protected $scene;
|
||||||
|
|
||||||
|
protected $isCheckScene;
|
||||||
|
|
||||||
|
protected $scenes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ValidatorInterface $validator
|
||||||
|
*/
|
||||||
|
protected $validator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data 表单数据
|
||||||
|
*/
|
||||||
|
public function __construct(array $data = [])
|
||||||
|
{
|
||||||
|
foreach ($this->defaults() as $key => $value) {
|
||||||
|
if (isset($data[$key])) {
|
||||||
|
if (empty($value) && empty($data[$key])) {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->_data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置表单参数默认值,暂不支持多维数组
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function defaults(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function before()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final function handleBefore()
|
||||||
|
{
|
||||||
|
$this->before();
|
||||||
|
$this->checkScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getRules()
|
||||||
|
{
|
||||||
|
$rules = $this->rules();
|
||||||
|
$scene = $this->getScene();
|
||||||
|
if ($scene && isset($this->scenes[$scene]) && is_array($this->scenes[$scene])) {
|
||||||
|
$newRules = [];
|
||||||
|
foreach ($this->scenes[$scene] as $field) {
|
||||||
|
if (array_key_exists($field, $rules)) {
|
||||||
|
$newRules[$field] = $rules[$field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $newRules;
|
||||||
|
}
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final function validate($throwException = true)
|
||||||
|
{
|
||||||
|
$this->handleBefore();
|
||||||
|
$this->validator = $this->validationFactory->make($this->_data, $this->getRules(), $this->messages(), $this->attributes());
|
||||||
|
$this->handleAfter();
|
||||||
|
|
||||||
|
$fails = $this->validator->fails();
|
||||||
|
if ($throwException && $fails) {
|
||||||
|
throw new ValidationException($this->getErrorMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return !$fails;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function after()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final function handleAfter()
|
||||||
|
{
|
||||||
|
$this->validator->after(function ($validator) {
|
||||||
|
$items = Annotation::getMethodsByAnnotationAndClass(After::class, static::class);
|
||||||
|
foreach ($items as $item) {
|
||||||
|
if (empty($item['annotation']->scenes) || in_array($this->scene, $item['annotation']->scenes)) {
|
||||||
|
$this->{$item['method']}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->after();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addError($field, $message)
|
||||||
|
{
|
||||||
|
$this->validator->errors()->add($field, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function errors(): MessageBag
|
||||||
|
{
|
||||||
|
return $this->validator->errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrorMessage($isAll = false): string
|
||||||
|
{
|
||||||
|
if ($this->errors()->count() > 0) {
|
||||||
|
$messages = $this->errors()->all();
|
||||||
|
return $isAll ? implode('', $messages) : $messages[0];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public final function getData()
|
||||||
|
{
|
||||||
|
return $this->_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final function getSceneData()
|
||||||
|
{
|
||||||
|
$scene = $this->getScene();
|
||||||
|
if ($scene && isset($this->scenes[$scene]) && is_array($this->scenes[$scene])) {
|
||||||
|
$newData = [];
|
||||||
|
foreach ($this->scenes[$scene] as $field) {
|
||||||
|
if (array_key_exists($field, $this->_data)) {
|
||||||
|
$newData[$field] = $this->_data[$field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $newData;
|
||||||
|
}
|
||||||
|
return $this->_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $scene 场景名称
|
||||||
|
* @param bool $isCheckScene 是否检查场景是否存在
|
||||||
|
*/
|
||||||
|
public final function setScene(string $scene, bool $isCheckScene = true): void
|
||||||
|
{
|
||||||
|
$this->scene = $scene;
|
||||||
|
$this->isCheckScene = $isCheckScene;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final function checkScene()
|
||||||
|
{
|
||||||
|
if ($this->getScene() && $this->isCheckScene && !isset($this->scenes[$this->scene])) {
|
||||||
|
throw new BusinessException('Scene undefined!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final function getScene()
|
||||||
|
{
|
||||||
|
return $this->scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get($key)
|
||||||
|
{
|
||||||
|
return isset($this->_data[$key]) ? $this->_data[$key] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($key, $value)
|
||||||
|
{
|
||||||
|
$this->_data[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __isset($key)
|
||||||
|
{
|
||||||
|
return $this->__get($key);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
trait CommonPromoteScopes
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 查询属于某个推广员的玩家
|
||||||
|
* @param $query
|
||||||
|
* @param $promote 推广员
|
||||||
|
* @param $containSubPromotes 是否包含所有下级
|
||||||
|
*/
|
||||||
|
public function scopeOfPromote($query, $promote, $containSubPromotes = true)
|
||||||
|
{
|
||||||
|
if ($containSubPromotes) {
|
||||||
|
$query->whereHas('promote', function ($query) use ($promote) {
|
||||||
|
$query->ofParent($promote)->orWhere('promote_id', $promote->id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$query->where('promote_id', $promote->id);
|
||||||
|
}
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
use App\Helper\Time;
|
||||||
|
|
||||||
|
trait CommonTimeScopes
|
||||||
|
{
|
||||||
|
public function scopeRangeTime($query, $column, $timeRange, $withTime = true)
|
||||||
|
{
|
||||||
|
if (!$timeRange) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
$timeRange = Time::dateTimeRange($timeRange, $withTime);
|
||||||
|
return $query->whereBetween($column, [strtotime($timeRange[0]), strtotime($timeRange[1])]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeOfMonth($query, $column, $month, $withTime = true)
|
||||||
|
{
|
||||||
|
if (!$month) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
$firstDate = $month . '-01';
|
||||||
|
$lastDate = Time::getMonthLastDate($month);
|
||||||
|
$timeRange = Time::dateTimeRange([$firstDate, $lastDate], $withTime);
|
||||||
|
return $query->whereBetween($column, [strtotime($timeRange[0]), strtotime($timeRange[1])]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeTimeOverlay($query, $rangeColumns, $timeRange)
|
||||||
|
{
|
||||||
|
return $query->whereNot(function ($q) use ($rangeColumns, $timeRange) {
|
||||||
|
$q->where($rangeColumns[1], '<', $timeRange[0])->orWhere($rangeColumns[0], '<', $timeRange[1]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
trait GameScopes
|
||||||
|
{
|
||||||
|
public function scopeOfConditions($query, $params)
|
||||||
|
{
|
||||||
|
if (!empty($params['relation_game_id'])) {
|
||||||
|
$query->where('relation_game_id', $params['relation_game_id']);
|
||||||
|
}
|
||||||
|
if (!empty($params['base_game_id'])) {
|
||||||
|
$query->where('base_game_id', $params['base_game_id']);
|
||||||
|
}
|
||||||
|
if (!empty($params['sdk_version'])) {
|
||||||
|
$query->where('sdk_version', $params['sdk_version']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
trait PlayerRoleScopes
|
||||||
|
{
|
||||||
|
public function scopeOfConditions($query, $params)
|
||||||
|
{
|
||||||
|
if (!empty($params['server_id'])) {
|
||||||
|
$query->where('server_id', $params['server_id']);
|
||||||
|
}
|
||||||
|
if (!empty($params['sdk_version'])) {
|
||||||
|
$query->where('sdk_version', $params['sdk_version']);
|
||||||
|
}
|
||||||
|
if (!empty($params['game_id'])) {
|
||||||
|
$query->where('game_id', $params['game_id']);
|
||||||
|
}
|
||||||
|
if (!empty($params['role_name'])) {
|
||||||
|
$query->where('role_name', $params['role_name']);
|
||||||
|
}
|
||||||
|
if (!empty($params['server_name'])) {
|
||||||
|
$query->where('server_name', $params['server_name']);
|
||||||
|
}
|
||||||
|
if (!empty($params['user_account'])) {
|
||||||
|
$query->where('user_account', $params['user_account']);
|
||||||
|
}
|
||||||
|
if (!empty($params['role_id'])) {
|
||||||
|
$query->where('role_id', $params['role_id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeRangeRoleLevel($query, ?array $roleLevelRange)
|
||||||
|
{
|
||||||
|
if (is_null($roleLevelRange)) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
$min = $roleLevelRange[0] ?? null;
|
||||||
|
$min == '' ? null : $min;
|
||||||
|
|
||||||
|
$max = $roleLevelRange[1] ?? null;
|
||||||
|
$max == '' ? null : $max;
|
||||||
|
|
||||||
|
if (!is_null($min)) {
|
||||||
|
$query->where('role_level', '>=', $min);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($max)) {
|
||||||
|
$query->where('role_level', '<=', $max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
trait PlayerScopes
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
trait PromoteScopes
|
||||||
|
{
|
||||||
|
public function scopeOfConditions($query, $params)
|
||||||
|
{
|
||||||
|
if (!empty($params['level'])) {
|
||||||
|
$query->where('level', $params['level']);
|
||||||
|
}
|
||||||
|
if (!empty($params['parent_id'])) {
|
||||||
|
$query->where('parent_id', $params['parent_id']);
|
||||||
|
}
|
||||||
|
if (!empty($params['account'])) {
|
||||||
|
$query->where('account', 'like', '%' . $params['account'] . '%');
|
||||||
|
}
|
||||||
|
if (!empty($params['mobile'])) {
|
||||||
|
$query->where('mobile_phone', 'like', '%' . $params['mobile'] . '%');
|
||||||
|
}
|
||||||
|
if (!empty($params['idcard'])) {
|
||||||
|
$query->where('idcard', 'like', '%' . $params['idcard'] . '%');
|
||||||
|
}
|
||||||
|
if (!empty($params['realname'])) {
|
||||||
|
$query->where('real_name', 'like', '%' . $params['realname'] . '%');
|
||||||
|
}
|
||||||
|
if (isset($params['status']) && $params['status'] != -1) {
|
||||||
|
$query->where('status', $params['status']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找子推广账号
|
||||||
|
*/
|
||||||
|
public function scopeOfParent($query, $promote)
|
||||||
|
{
|
||||||
|
return $query->where('chain', 'like', $promote->chain . $promote->id . '/%');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
use App\Model\Promote;
|
||||||
|
|
||||||
|
trait SpendScopes
|
||||||
|
{
|
||||||
|
public function scopeOfConditions($query, $params)
|
||||||
|
{
|
||||||
|
if (!empty($params['server_id'])) {
|
||||||
|
$query->where('server_id', $params['server_id']);
|
||||||
|
}
|
||||||
|
if (!empty($params['server_name'])) {
|
||||||
|
$query->where('server_name', $params['server_name']);
|
||||||
|
}
|
||||||
|
if (!empty($params['game_id'])) {
|
||||||
|
$query->where('game_id', $params['game_id']);
|
||||||
|
}
|
||||||
|
if (!empty($params['game_name'])) {
|
||||||
|
$query->where('game_name', $params['game_name']);
|
||||||
|
}
|
||||||
|
if (isset($params['pay_status']) && $params['pay_status'] != -1) {
|
||||||
|
$query->where('pay_status', $params['pay_status']);
|
||||||
|
}
|
||||||
|
if (isset($params['pay_way']) && $params['pay_way'] != -99) {
|
||||||
|
$query->where('pay_way', $params['pay_way']);
|
||||||
|
}
|
||||||
|
if (!empty($params['pay_order_number'])) {
|
||||||
|
$query->where('pay_order_number', $params['pay_order_number']);
|
||||||
|
}
|
||||||
|
if (!empty($params['user_account'])) {
|
||||||
|
$query->where('user_account', $params['user_account']);
|
||||||
|
}
|
||||||
|
if (!empty($params['role_name'])) {
|
||||||
|
$query->where('game_player_name', $params['game_player_name']);
|
||||||
|
}
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeSettleOrder($query, string $tableAlias = null)
|
||||||
|
{
|
||||||
|
$column = 'is_check';
|
||||||
|
if ($tableAlias) {
|
||||||
|
$column = $tableAlias . '.' . $column;
|
||||||
|
}
|
||||||
|
return $query->where($column, 1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
trait UserScopes
|
||||||
|
{
|
||||||
|
public function scopeOfConditions($query, $params)
|
||||||
|
{
|
||||||
|
if (!empty($params['account'])) {
|
||||||
|
$query->where('account', $params['account']);
|
||||||
|
}
|
||||||
|
if (!empty($params['id'])) {
|
||||||
|
$query->where('id', $params['id']);
|
||||||
|
}
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
abstract class AbstractService
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
use App\Helper\Redis;
|
||||||
|
use App\Helper\RedisKey;
|
||||||
|
use App\Helper\StringHelper;
|
||||||
|
use App\Model\App;
|
||||||
|
use App\Model\Merchant;
|
||||||
|
|
||||||
|
class AppService extends AbstractService
|
||||||
|
{
|
||||||
|
public function createApp(Merchant $merchant) {
|
||||||
|
$app = new App();
|
||||||
|
$app->merchant_id = $merchant->id;
|
||||||
|
$app->app_id = $this->generateAppId();
|
||||||
|
$app->app_key = StringHelper::getRandomString(32);
|
||||||
|
$app->status = App::STATUS_ACTIVE;
|
||||||
|
$app->save();
|
||||||
|
return $app;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateAppId() {
|
||||||
|
$now = time();
|
||||||
|
$key = RedisKey::getGenerateAppIdKey($now);
|
||||||
|
$expireAt = strtotime(date('Y-m-d 23:59:59', $now)) + 1;
|
||||||
|
$incrId = Redis::incr($key);
|
||||||
|
$incrId = '' . $incrId;
|
||||||
|
Redis::expireAt($key, $expireAt);
|
||||||
|
$padLength = 8 - strlen($incrId);
|
||||||
|
$incrId = str_pad($incrId, $padLength, '0', STR_PAD_LEFT);
|
||||||
|
return date('Ymd', $now) . $incrId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
use App\Model\Merchant;
|
||||||
|
|
||||||
|
class MerchantService extends AbstractService
|
||||||
|
{
|
||||||
|
public function createMerchant($params) {
|
||||||
|
$merchant = new Merchant();
|
||||||
|
$merchant->username = $params['username'];
|
||||||
|
$merchant->password = $params['password'];
|
||||||
|
$merchant->email = $params['email'] ?: '';
|
||||||
|
$merchant->mobile = $params['mobile'] ?: '';
|
||||||
|
$merchant->register_at = date('Y-m-d H:i:s');
|
||||||
|
$merchant->register_ip = $params['ip'] ?: '';
|
||||||
|
$merchant->status = Merchant::STATUS_ACTIVE;
|
||||||
|
$merchant->save();
|
||||||
|
return $merchant;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
use App\Exception\BusinessException;
|
||||||
|
use App\Helper\OmiPay\Api;
|
||||||
|
use App\Helper\OmiPay\Result;
|
||||||
|
use App\Helper\OmiPay\Signer;
|
||||||
|
use App\Helper\Redis;
|
||||||
|
use App\Helper\RedisKey;
|
||||||
|
use App\Model\App;
|
||||||
|
use App\Model\Order;
|
||||||
|
|
||||||
|
class PaymentService extends AbstractService
|
||||||
|
{
|
||||||
|
public function createOrder(App $app, array $params) {
|
||||||
|
$order = new Order();
|
||||||
|
$order->merchant_id = $app->merchant_id;
|
||||||
|
$order->app_id = $app->app_id;
|
||||||
|
$order->order_no = $this->generateOrderNo();
|
||||||
|
$order->out_order_no = $params['out_order_no'];
|
||||||
|
$order->amount = $params['amount'];
|
||||||
|
$order->currency = $params['currency'];
|
||||||
|
$order->redirect_url = $params['redirect_url'];
|
||||||
|
$order->notify_url = $params['notify_url'];
|
||||||
|
$order->direct_pay = $params['direct_pay'] ?? 0;
|
||||||
|
$order->show_pc_pay_url = $params['show_pc_pay_url'] ?? 0;
|
||||||
|
$order->o_number = $params['o_number'] ?? '';
|
||||||
|
$order->pos_no = $params['pos_no'] ?? '';
|
||||||
|
$order->status = Order::STATUS_PREPARE;
|
||||||
|
$order->save();
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateOrderNo() {
|
||||||
|
$now = time();
|
||||||
|
$key = RedisKey::getGenerateOrderNoKey($now);
|
||||||
|
$incrId = Redis::incr($key);
|
||||||
|
$incrId = '' . $incrId;
|
||||||
|
Redis::expire($key, 5*60);
|
||||||
|
$padLength = 6 - strlen($incrId);
|
||||||
|
$incrId = str_pad($incrId, $padLength, '0', STR_PAD_LEFT);
|
||||||
|
return date('YmdHis', $now) . $incrId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateOrderResult(Order $order, Result $result) {
|
||||||
|
if ($result->isSuccess()) {
|
||||||
|
$order->pay_order_no = $result->get('order_no');
|
||||||
|
$order->pay_url = $result->get('pay_url');
|
||||||
|
$order->status = Order::STATUS_WAIT_PAY;
|
||||||
|
} else {
|
||||||
|
$order->error_code = $result->get('error_code');
|
||||||
|
$order->error_msg = $result->get('error_msg');
|
||||||
|
$order->status = Order::STATUS_FAILED;
|
||||||
|
}
|
||||||
|
$order->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsapiPay(App $app, array $params) {
|
||||||
|
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $params['out_order_no'])->first();
|
||||||
|
if ($order) {
|
||||||
|
throw new BusinessException('订单重复');
|
||||||
|
}
|
||||||
|
$order = $this->createOrder($app, $params);
|
||||||
|
$result = Api::makeJSAPIOrder(
|
||||||
|
$order->order_name,
|
||||||
|
$order->order_no,
|
||||||
|
$order->currency,
|
||||||
|
$order->amount,
|
||||||
|
'http://146.70.113.165:9501/payment/notify',
|
||||||
|
'http://146.70.113.165:9501/payment/page?order_no=' . $order->order_no
|
||||||
|
);
|
||||||
|
$this->updateOrderResult($order, $result);
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function notify($params) {
|
||||||
|
if (Signer::verify($params)) {
|
||||||
|
return 'SIGN FAIL';
|
||||||
|
}
|
||||||
|
if ($params['return_code'] != 'SUCCESS') {
|
||||||
|
return 'STATUS FAIL';
|
||||||
|
}
|
||||||
|
$order = Order::where('order_no', $params['out_order_no'])->where('status', Order::STATUS_WAIT_PAY)->first();
|
||||||
|
$order->status = Order::STATUS_PAYED;
|
||||||
|
$order->payed_at = date('Y-m-d');
|
||||||
|
$order->exchange_rate = $params['exchange_rate'];
|
||||||
|
$order->cny_amount = $params['cny_amount'];
|
||||||
|
$order->save();
|
||||||
|
if ($order->save()) {
|
||||||
|
return 'SUCCESS';
|
||||||
|
}
|
||||||
|
return 'UPDATE FAIL';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
ini_set('display_errors', 'on');
|
||||||
|
ini_set('display_startup_errors', 'on');
|
||||||
|
ini_set('memory_limit', '1G');
|
||||||
|
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
date_default_timezone_set('Asia/Shanghai');
|
||||||
|
|
||||||
|
! defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
|
||||||
|
! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);
|
||||||
|
|
||||||
|
require BASE_PATH . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
// Self-called anonymous function that creates its own scope and keep the global namespace clean.
|
||||||
|
(function () {
|
||||||
|
Hyperf\Di\ClassLoader::init();
|
||||||
|
/** @var Psr\Container\ContainerInterface $container */
|
||||||
|
$container = require BASE_PATH . '/config/container.php';
|
||||||
|
|
||||||
|
$application = $container->get(Hyperf\Contract\ApplicationInterface::class);
|
||||||
|
$application->run();
|
||||||
|
})();
|
@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"name": "hyperf/hyperf-skeleton",
|
||||||
|
"type": "project",
|
||||||
|
"keywords": [
|
||||||
|
"php",
|
||||||
|
"swoole",
|
||||||
|
"framework",
|
||||||
|
"hyperf",
|
||||||
|
"microservice",
|
||||||
|
"middleware"
|
||||||
|
],
|
||||||
|
"description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.3",
|
||||||
|
"hyperf/async-queue": "~2.2.0",
|
||||||
|
"hyperf/cache": "~2.2.0",
|
||||||
|
"hyperf/command": "~2.2.0",
|
||||||
|
"hyperf/config": "~2.2.0",
|
||||||
|
"hyperf/constants": "~2.2.0",
|
||||||
|
"hyperf/database": "~2.2.0",
|
||||||
|
"hyperf/db-connection": "~2.2.0",
|
||||||
|
"hyperf/framework": "~2.2.0",
|
||||||
|
"hyperf/guzzle": "~2.2.0",
|
||||||
|
"hyperf/http-server": "~2.2.0",
|
||||||
|
"hyperf/json-rpc": "~2.2.0",
|
||||||
|
"hyperf/logger": "~2.2.0",
|
||||||
|
"hyperf/memory": "~2.2.0",
|
||||||
|
"hyperf/model-cache": "~2.2.0",
|
||||||
|
"hyperf/process": "~2.2.0",
|
||||||
|
"hyperf/redis": "~2.2.0",
|
||||||
|
"hyperf/rpc": "~2.2.0",
|
||||||
|
"hyperf/rpc-client": "~2.2.0",
|
||||||
|
"hyperf/rpc-server": "~2.2.0",
|
||||||
|
"hyperf/validation": "^2.2",
|
||||||
|
"phpoffice/phpspreadsheet": "^1.24"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.0",
|
||||||
|
"hyperf/devtool": "~2.2.0",
|
||||||
|
"hyperf/ide-helper": "~2.2.0",
|
||||||
|
"hyperf/testing": "~2.2.0",
|
||||||
|
"mockery/mockery": "^1.0",
|
||||||
|
"phpstan/phpstan": "^0.12",
|
||||||
|
"swoole/ide-helper": "^4.5"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-openssl": "Required to use HTTPS.",
|
||||||
|
"ext-json": "Required to use JSON.",
|
||||||
|
"ext-pdo": "Required to use MySQL Client.",
|
||||||
|
"ext-pdo_mysql": "Required to use MySQL Client.",
|
||||||
|
"ext-redis": "Required to use Redis Client."
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\": "app/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"app/Helper/Functions.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"HyperfTest\\": "./test/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"prefer-stable": true,
|
||||||
|
"config": {
|
||||||
|
"optimize-autoloader": true,
|
||||||
|
"sort-packages": true
|
||||||
|
},
|
||||||
|
"extra": [],
|
||||||
|
"scripts": {
|
||||||
|
"post-root-package-install": [
|
||||||
|
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||||
|
],
|
||||||
|
"post-autoload-dump": [
|
||||||
|
"rm -rf runtime/container"
|
||||||
|
],
|
||||||
|
"test": "co-phpunit --prepend test/bootstrap.php -c phpunit.xml --colors=always",
|
||||||
|
"cs-fix": "php-cs-fixer fix $1",
|
||||||
|
"analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config",
|
||||||
|
"start": [
|
||||||
|
"Composer\\Config::disableProcessTimeout",
|
||||||
|
"php ./bin/hyperf.php start"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -0,0 +1,21 @@
|
|||||||
|
<?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 [
|
||||||
|
'scan' => [
|
||||||
|
'paths' => [
|
||||||
|
BASE_PATH . '/app',
|
||||||
|
],
|
||||||
|
'ignore_annotations' => [
|
||||||
|
'mixin',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,13 @@
|
|||||||
|
<?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 [
|
||||||
|
];
|
@ -0,0 +1,38 @@
|
|||||||
|
<?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 [
|
||||||
|
'default' => [
|
||||||
|
'driver' => Hyperf\AsyncQueue\Driver\RedisDriver::class,
|
||||||
|
'redis' => [
|
||||||
|
'pool' => 'default',
|
||||||
|
],
|
||||||
|
'channel' => '{queue}',
|
||||||
|
'timeout' => 2,
|
||||||
|
'retry_seconds' => 5,
|
||||||
|
'handle_timeout' => 10,
|
||||||
|
'processes' => 1,
|
||||||
|
'concurrent' => [
|
||||||
|
'limit' => 10,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sms' => [
|
||||||
|
'driver' => Hyperf\AsyncQueue\Driver\RedisDriver::class,
|
||||||
|
'channel' => '{sms.queue}',
|
||||||
|
'timeout' => 2,
|
||||||
|
'retry_seconds' => 5,
|
||||||
|
'handle_timeout' => 10,
|
||||||
|
'processes' => 1,
|
||||||
|
'concurrent' => [
|
||||||
|
'limit' => 5,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,18 @@
|
|||||||
|
<?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 [
|
||||||
|
'default' => [
|
||||||
|
'driver' => Hyperf\Cache\Driver\RedisDriver::class,
|
||||||
|
'packer' => Hyperf\Utils\Packer\PhpSerializerPacker::class,
|
||||||
|
'prefix' => 'c:',
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'lanhuo' => [
|
||||||
|
'base_url' => env('LANHUO_URL', 'https://c.lshygame.com'),
|
||||||
|
'app_id' => 'LLWF71700000001644',
|
||||||
|
'app_key' => '31h8a',
|
||||||
|
'app_secret' => '9b0c2130ea023243ff76bf7bc724cfc2',
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,13 @@
|
|||||||
|
<?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 [
|
||||||
|
];
|
@ -0,0 +1,49 @@
|
|||||||
|
<?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 [
|
||||||
|
'default' => [
|
||||||
|
'driver' => env('DB_DRIVER', 'mysql'),
|
||||||
|
'host' => env('DB_HOST', 'localhost'),
|
||||||
|
'port' => env('DB_PORT', 3306),
|
||||||
|
'database' => env('DB_DATABASE', 'hyperf'),
|
||||||
|
'username' => env('DB_USERNAME', 'root'),
|
||||||
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
'charset' => env('DB_CHARSET', 'utf8mb4'),
|
||||||
|
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
|
||||||
|
'prefix' => env('DB_PREFIX', ''),
|
||||||
|
'pool' => [
|
||||||
|
'min_connections' => 1,
|
||||||
|
'max_connections' => 10,
|
||||||
|
'connect_timeout' => 10.0,
|
||||||
|
'wait_timeout' => 3.0,
|
||||||
|
'heartbeat' => -1,
|
||||||
|
'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60),
|
||||||
|
],
|
||||||
|
'cache' => [
|
||||||
|
'handler' => Hyperf\ModelCache\Handler\RedisHandler::class,
|
||||||
|
'cache_key' => '{mc:%s:m:%s}:%s:%s',
|
||||||
|
'prefix' => 'default',
|
||||||
|
'ttl' => 3600 * 24,
|
||||||
|
'empty_model_ttl' => 600,
|
||||||
|
'load_script' => true,
|
||||||
|
],
|
||||||
|
'commands' => [
|
||||||
|
'gen:model' => [
|
||||||
|
'path' => 'app/Model',
|
||||||
|
'force_casts' => true,
|
||||||
|
'inheritance' => 'Model',
|
||||||
|
'uses' => '',
|
||||||
|
'table_mapping' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,14 @@
|
|||||||
|
<?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 [
|
||||||
|
\App\Contract\SmsSender::class => \App\Factory\SmsSenderFactory::class
|
||||||
|
];
|
@ -0,0 +1,44 @@
|
|||||||
|
<?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 [
|
||||||
|
'generator' => [
|
||||||
|
'amqp' => [
|
||||||
|
'consumer' => [
|
||||||
|
'namespace' => 'App\\Amqp\\Consumer',
|
||||||
|
],
|
||||||
|
'producer' => [
|
||||||
|
'namespace' => 'App\\Amqp\\Producer',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'aspect' => [
|
||||||
|
'namespace' => 'App\\Aspect',
|
||||||
|
],
|
||||||
|
'command' => [
|
||||||
|
'namespace' => 'App\\Command',
|
||||||
|
],
|
||||||
|
'controller' => [
|
||||||
|
'namespace' => 'App\\Controller',
|
||||||
|
],
|
||||||
|
'job' => [
|
||||||
|
'namespace' => 'App\\Job',
|
||||||
|
],
|
||||||
|
'listener' => [
|
||||||
|
'namespace' => 'App\\Listener',
|
||||||
|
],
|
||||||
|
'middleware' => [
|
||||||
|
'namespace' => 'App\\Middleware',
|
||||||
|
],
|
||||||
|
'Process' => [
|
||||||
|
'namespace' => 'App\\Processes',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,19 @@
|
|||||||
|
<?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 [
|
||||||
|
'handler' => [
|
||||||
|
'http' => [
|
||||||
|
Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
|
||||||
|
App\Exception\Handler\AppExceptionHandler::class,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,13 @@
|
|||||||
|
<?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 [
|
||||||
|
];
|
@ -0,0 +1,56 @@
|
|||||||
|
<?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
|
||||||
|
*/
|
||||||
|
|
||||||
|
$logPath = rtrim(env('LOG_PATH', '@runtime'), '/');
|
||||||
|
$logPath = $logPath === '@runtime' ? BASE_PATH . '/runtime/logs/' : $logPath;
|
||||||
|
$logFileName = $logPath . '/' . env('LOG_FILE_NAME', env('APP_NAME', 'hyperf') . '.log');
|
||||||
|
|
||||||
|
/* return [
|
||||||
|
'default' => [
|
||||||
|
'handler' => [
|
||||||
|
'class' => \Monolog\Handler\StreamHandler::class,
|
||||||
|
'constructor' => [
|
||||||
|
'stream' => $logFileName,
|
||||||
|
'level' => \Monolog\Logger::DEBUG,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'formatter' => [
|
||||||
|
'class' => \Monolog\Formatter\LineFormatter::class,
|
||||||
|
'constructor' => [
|
||||||
|
'format' => null,
|
||||||
|
'dateFormat' => null,
|
||||||
|
'allowInlineLineBreaks' => true,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]; */
|
||||||
|
|
||||||
|
return [
|
||||||
|
'default' => [
|
||||||
|
'handler' => [
|
||||||
|
'class' => Monolog\Handler\RotatingFileHandler::class,
|
||||||
|
'constructor' => [
|
||||||
|
'filename' => $logFileName,
|
||||||
|
'maxFiles' => env('LOG_MAX_FILES', 7),
|
||||||
|
'level' => Monolog\Logger::DEBUG,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'formatter' => [
|
||||||
|
'class' => Monolog\Formatter\LineFormatter::class,
|
||||||
|
'constructor' => [
|
||||||
|
'format' => null,
|
||||||
|
'dateFormat' => 'Y-m-d H:i:s',
|
||||||
|
'allowInlineLineBreaks' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,15 @@
|
|||||||
|
<?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 [
|
||||||
|
'http' => [
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,13 @@
|
|||||||
|
<?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 [
|
||||||
|
];
|
@ -0,0 +1,27 @@
|
|||||||
|
<?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 [
|
||||||
|
'default' => [
|
||||||
|
'host' => env('REDIS_HOST', 'localhost'),
|
||||||
|
'auth' => env('REDIS_AUTH', null),
|
||||||
|
'port' => (int) env('REDIS_PORT', 6379),
|
||||||
|
'db' => (int) env('REDIS_DB', 0),
|
||||||
|
'pool' => [
|
||||||
|
'min_connections' => 1,
|
||||||
|
'max_connections' => 10,
|
||||||
|
'connect_timeout' => 10.0,
|
||||||
|
'wait_timeout' => 3.0,
|
||||||
|
'heartbeat' => -1,
|
||||||
|
'max_idle_time' => (float) env('REDIS_MAX_IDLE_TIME', 60),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,46 @@
|
|||||||
|
<?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
|
||||||
|
*/
|
||||||
|
use Hyperf\Server\Event;
|
||||||
|
use Hyperf\Server\Server;
|
||||||
|
use Swoole\Constant;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'mode' => SWOOLE_PROCESS,
|
||||||
|
'servers' => [
|
||||||
|
[
|
||||||
|
'name' => 'http',
|
||||||
|
'type' => Server::SERVER_HTTP,
|
||||||
|
'host' => '0.0.0.0',
|
||||||
|
'port' => 9501,
|
||||||
|
'sock_type' => SWOOLE_SOCK_TCP,
|
||||||
|
'callbacks' => [
|
||||||
|
Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'settings' => [
|
||||||
|
Constant::OPTION_ENABLE_COROUTINE => true,
|
||||||
|
Constant::OPTION_WORKER_NUM => swoole_cpu_num(),
|
||||||
|
Constant::OPTION_PID_FILE => BASE_PATH . '/runtime/hyperf.pid',
|
||||||
|
Constant::OPTION_OPEN_TCP_NODELAY => true,
|
||||||
|
Constant::OPTION_MAX_COROUTINE => 100000,
|
||||||
|
Constant::OPTION_OPEN_HTTP2_PROTOCOL => true,
|
||||||
|
Constant::OPTION_MAX_REQUEST => 100000,
|
||||||
|
Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024,
|
||||||
|
Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024,
|
||||||
|
],
|
||||||
|
'callbacks' => [
|
||||||
|
Event::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
|
||||||
|
Event::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
|
||||||
|
Event::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,29 @@
|
|||||||
|
<?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 [
|
||||||
|
'consumers' => [
|
||||||
|
[
|
||||||
|
// The service name, this name should as same as with the name of service provider.
|
||||||
|
'name' => 'YourServiceName',
|
||||||
|
// The service registry, if `nodes` is missing below, then you should provide this configs.
|
||||||
|
'registry' => [
|
||||||
|
'protocol' => 'consul',
|
||||||
|
'address' => 'Enter the address of service registry',
|
||||||
|
],
|
||||||
|
// If `registry` is missing, then you should provide the nodes configs.
|
||||||
|
'nodes' => [
|
||||||
|
// Provide the host and port of the service provider.
|
||||||
|
// ['host' => 'The host of the service provider', 'port' => 9502]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -0,0 +1,31 @@
|
|||||||
|
<?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
|
||||||
|
*/
|
||||||
|
use Hyperf\Contract\StdoutLoggerInterface;
|
||||||
|
use Psr\Log\LogLevel;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'app_name' => env('APP_NAME', 'skeleton'),
|
||||||
|
'app_env' => env('APP_ENV', 'dev'),
|
||||||
|
'scan_cacheable' => env('SCAN_CACHEABLE', false),
|
||||||
|
StdoutLoggerInterface::class => [
|
||||||
|
'log_level' => [
|
||||||
|
LogLevel::ALERT,
|
||||||
|
LogLevel::CRITICAL,
|
||||||
|
LogLevel::DEBUG,
|
||||||
|
LogLevel::EMERGENCY,
|
||||||
|
LogLevel::ERROR,
|
||||||
|
LogLevel::INFO,
|
||||||
|
LogLevel::NOTICE,
|
||||||
|
LogLevel::WARNING,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue