Phase1 后端核心:
- 新增 fsgx_v1.sql 迁移脚本(is_queue_goods/frozen_points/available_points/no_assess)
- SystemConfigServices 返佣设置扩展(周期人数/分档比例/范围/时机)
- StoreOrderCreateServices 周期循环佣金计算
- StoreOrderTakeServices 佣金发放后同步冻结积分
- StoreProductServices/StoreProduct 保存 is_queue_goods
Phase2 后端接口:
- GET /api/hjf/brokerage/progress 佣金周期进度
- GET /api/hjf/assets/overview 资产总览
- HjfPointsServices 每日 frozen_points 0.4‰ 释放定时任务
- PUT /adminapi/hjf/member/{uid}/no_assess 不考核接口
- GET /adminapi/hjf/points/release_log 积分日志接口
Phase3 前端清理:
- hjfCustom.js 路由精简(仅保留 points/log)
- hjfQueue.js/hjfMember.js API 清理/重定向至 CRMEB 原生接口
- pages.json 公排→推荐佣金/佣金记录/佣金规则
Phase4-5 前端改造:
- queue/status.vue 推荐佣金进度页整体重写
- 商品详情/订单确认/支付结果页文案与逻辑改造
- 个人中心/资产页/引导页/规则页文案改造
- HjfQueueProgress/HjfRefundNotice/HjfAssetCard 组件改造
- 推广中心嵌入佣金进度摘要
- hjfMockData.js 全量更新(公排字段→佣金字段)
Phase6 Admin 增强:
- 用户列表新增 frozen_points/available_points 列及不考核操作按钮
- hjfPoints.js USE_MOCK=false 对接真实积分日志接口
Phase7 配置文档:
- docs/fsgx-phase7-config-checklist.md 后台配置与全链路验收清单
Made-with: Cursor
249 lines
8.3 KiB
PHP
249 lines
8.3 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Symfony\Component\HttpClient;
|
|
|
|
use Http\Discovery\Exception\NotFoundException;
|
|
use Http\Discovery\Psr17FactoryDiscovery;
|
|
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
use Nyholm\Psr7\Request;
|
|
use Nyholm\Psr7\Uri;
|
|
use Psr\Http\Client\ClientInterface;
|
|
use Psr\Http\Client\NetworkExceptionInterface;
|
|
use Psr\Http\Client\RequestExceptionInterface;
|
|
use Psr\Http\Message\RequestFactoryInterface;
|
|
use Psr\Http\Message\RequestInterface;
|
|
use Psr\Http\Message\ResponseFactoryInterface;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Psr\Http\Message\StreamFactoryInterface;
|
|
use Psr\Http\Message\StreamInterface;
|
|
use Psr\Http\Message\UriFactoryInterface;
|
|
use Psr\Http\Message\UriInterface;
|
|
use Symfony\Component\HttpClient\Response\StreamableInterface;
|
|
use Symfony\Component\HttpClient\Response\StreamWrapper;
|
|
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|
use Symfony\Contracts\Service\ResetInterface;
|
|
|
|
if (!interface_exists(RequestFactoryInterface::class)) {
|
|
throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as the "psr/http-factory" package is not installed. Try running "composer require nyholm/psr7".');
|
|
}
|
|
|
|
if (!interface_exists(ClientInterface::class)) {
|
|
throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as the "psr/http-client" package is not installed. Try running "composer require psr/http-client".');
|
|
}
|
|
|
|
/**
|
|
* An adapter to turn a Symfony HttpClientInterface into a PSR-18 ClientInterface.
|
|
*
|
|
* Run "composer require psr/http-client" to install the base ClientInterface. Run
|
|
* "composer require nyholm/psr7" to install an efficient implementation of response
|
|
* and stream factories with flex-provided autowiring aliases.
|
|
*
|
|
* @author Nicolas Grekas <p@tchwork.com>
|
|
*/
|
|
final class Psr18Client implements ClientInterface, RequestFactoryInterface, StreamFactoryInterface, UriFactoryInterface, ResetInterface
|
|
{
|
|
private $client;
|
|
private $responseFactory;
|
|
private $streamFactory;
|
|
|
|
public function __construct(HttpClientInterface $client = null, ResponseFactoryInterface $responseFactory = null, StreamFactoryInterface $streamFactory = null)
|
|
{
|
|
$this->client = $client ?? HttpClient::create();
|
|
$streamFactory ??= $responseFactory instanceof StreamFactoryInterface ? $responseFactory : null;
|
|
|
|
if (null === $responseFactory || null === $streamFactory) {
|
|
if (!class_exists(Psr17Factory::class) && !class_exists(Psr17FactoryDiscovery::class)) {
|
|
throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as no PSR-17 factories have been provided. Try running "composer require nyholm/psr7".');
|
|
}
|
|
|
|
try {
|
|
$psr17Factory = class_exists(Psr17Factory::class, false) ? new Psr17Factory() : null;
|
|
$responseFactory ??= $psr17Factory ?? Psr17FactoryDiscovery::findResponseFactory();
|
|
$streamFactory ??= $psr17Factory ?? Psr17FactoryDiscovery::findStreamFactory();
|
|
} catch (NotFoundException $e) {
|
|
throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been found. Try running "composer require nyholm/psr7".', 0, $e);
|
|
}
|
|
}
|
|
|
|
$this->responseFactory = $responseFactory;
|
|
$this->streamFactory = $streamFactory;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function sendRequest(RequestInterface $request): ResponseInterface
|
|
{
|
|
try {
|
|
$body = $request->getBody();
|
|
|
|
if ($body->isSeekable()) {
|
|
$body->seek(0);
|
|
}
|
|
|
|
$options = [
|
|
'headers' => $request->getHeaders(),
|
|
'body' => $body->getContents(),
|
|
];
|
|
|
|
if ('1.0' === $request->getProtocolVersion()) {
|
|
$options['http_version'] = '1.0';
|
|
}
|
|
|
|
$response = $this->client->request($request->getMethod(), (string) $request->getUri(), $options);
|
|
|
|
$psrResponse = $this->responseFactory->createResponse($response->getStatusCode());
|
|
|
|
foreach ($response->getHeaders(false) as $name => $values) {
|
|
foreach ($values as $value) {
|
|
try {
|
|
$psrResponse = $psrResponse->withAddedHeader($name, $value);
|
|
} catch (\InvalidArgumentException $e) {
|
|
// ignore invalid header
|
|
}
|
|
}
|
|
}
|
|
|
|
$body = $response instanceof StreamableInterface ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client);
|
|
$body = $this->streamFactory->createStreamFromResource($body);
|
|
|
|
if ($body->isSeekable()) {
|
|
$body->seek(0);
|
|
}
|
|
|
|
return $psrResponse->withBody($body);
|
|
} catch (TransportExceptionInterface $e) {
|
|
if ($e instanceof \InvalidArgumentException) {
|
|
throw new Psr18RequestException($e, $request);
|
|
}
|
|
|
|
throw new Psr18NetworkException($e, $request);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function createRequest(string $method, $uri): RequestInterface
|
|
{
|
|
if ($this->responseFactory instanceof RequestFactoryInterface) {
|
|
return $this->responseFactory->createRequest($method, $uri);
|
|
}
|
|
|
|
if (class_exists(Request::class)) {
|
|
return new Request($method, $uri);
|
|
}
|
|
|
|
if (class_exists(Psr17FactoryDiscovery::class)) {
|
|
return Psr17FactoryDiscovery::findRequestFactory()->createRequest($method, $uri);
|
|
}
|
|
|
|
throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function createStream(string $content = ''): StreamInterface
|
|
{
|
|
$stream = $this->streamFactory->createStream($content);
|
|
|
|
if ($stream->isSeekable()) {
|
|
$stream->seek(0);
|
|
}
|
|
|
|
return $stream;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
|
|
{
|
|
return $this->streamFactory->createStreamFromFile($filename, $mode);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function createStreamFromResource($resource): StreamInterface
|
|
{
|
|
return $this->streamFactory->createStreamFromResource($resource);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function createUri(string $uri = ''): UriInterface
|
|
{
|
|
if ($this->responseFactory instanceof UriFactoryInterface) {
|
|
return $this->responseFactory->createUri($uri);
|
|
}
|
|
|
|
if (class_exists(Uri::class)) {
|
|
return new Uri($uri);
|
|
}
|
|
|
|
if (class_exists(Psr17FactoryDiscovery::class)) {
|
|
return Psr17FactoryDiscovery::findUrlFactory()->createUri($uri);
|
|
}
|
|
|
|
throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__));
|
|
}
|
|
|
|
public function reset()
|
|
{
|
|
if ($this->client instanceof ResetInterface) {
|
|
$this->client->reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
class Psr18NetworkException extends \RuntimeException implements NetworkExceptionInterface
|
|
{
|
|
private $request;
|
|
|
|
public function __construct(TransportExceptionInterface $e, RequestInterface $request)
|
|
{
|
|
parent::__construct($e->getMessage(), 0, $e);
|
|
$this->request = $request;
|
|
}
|
|
|
|
public function getRequest(): RequestInterface
|
|
{
|
|
return $this->request;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
class Psr18RequestException extends \InvalidArgumentException implements RequestExceptionInterface
|
|
{
|
|
private $request;
|
|
|
|
public function __construct(TransportExceptionInterface $e, RequestInterface $request)
|
|
{
|
|
parent::__construct($e->getMessage(), 0, $e);
|
|
$this->request = $request;
|
|
}
|
|
|
|
public function getRequest(): RequestInterface
|
|
{
|
|
return $this->request;
|
|
}
|
|
}
|