Commit 0343a4e1 authored by 王源's avatar 王源 🎧

分割rpc文件

parent bb7cfa5a
# 导出Excel csv工具使用说明
1、导出Excel,不使用模板的情况
```$xslt
$exporter = new Exporter(Exporter::EXPORTER_TYPE_XLSX,'导出产品信息');#不用模板的情况
//填充表头
$title = ['产品','颜色','尺码','sku']
$list = Product::with(["color","size"])->get()->toArray();
$exporter->append($title)
->append($list,['name','color.name','size.name|未设定尺码','sku'])//填充数据
->setUnprotectRange("A1:B".$exporter->getCurrentRowIndex())//设置保护
->download(Exporter::DOWNLOAD_TYPE_STREAM,"产品数据");//下载数据
```
2、导出Excel,使用模板的情况
```$xslt
//根据模板导出器
$exporter = new Exporter(Exporter::EXPORTER_TYPE_XLSX, 'template/xxx.xlsx', '导出产品信息');#使用模板来生成
//新增sheet并使用它
$exporter->addSheet('颜色参考表', true);
//填充表头
$title = ['颜色id','中文颜色名','英文颜色名']
$exporter->append($title)
->append(Color::get(["id", "cn_name", "en_name"]))
->setUnprotectRange();//全表保护
//设置保护
//使用别的sheet表
$exporter->setSheetByIndex(0)->setBeginRowIndex(2)->setBeginColumnChar("C");//从第三列开始填充数据
//填充数据
$list = Product::with(["color","size"])->get()->toArray();
$exporter->append($list,['name','color.name','size.name|未设定尺码','sku']);
$file= $exporter->download(Exporter::DOWNLOAD_TYPE_RETURN_FILE_PATH,"产品数据");
echo $file;
```
<?php
declare(strict_types=1);
namespace Meibuyu\Micro\Amqp\Producer;
use Exception;
use Hyperf\Amqp\Annotation\Producer;
use Hyperf\Amqp\Message\ProducerMessage;
use Meibuyu\Micro\Exceptions\HttpResponseException;
use Meibuyu\Micro\Model\Auth;
/**
* @Producer(exchange="micro", routingKey="exception-log")
*/
class ExceptionLogProducer extends ProducerMessage
{
public function __construct($data)
{
try {
$data['operator'] = Auth::user()['name'];
} catch (HttpResponseException $e) {
put_log('获取操作人失败; ' . $e->getMessage(), 'ExceptionLogProducer.log');
}
// 获取trace中真实文件和行数
if (!empty($data['trace'])) {
preg_match('/(\/var\/www\/app\/.+?\.php)(?=\()/', $data['trace'], $matchFiles);
if (!empty($matchFiles[0])) {
$data['file'] = $matchFiles[0];
$file = str_replace('/', '\/', $matchFiles[0]);
$file = str_replace('.', '\.', $file);
$pattern = '/(?<=' . $file . '\()[0-9]+(?=\))/';
preg_match($pattern, $data['trace'], $matchLines);
if (!empty($matchLines[0])) {
$data['line'] = $matchLines[0];
}
}
}
if (!empty($data['file'])) {
// 只对项目app文件夹下的错误获取编码人
preg_match('/(\/var\/www\/app\/)/', $data['file'], $matchPaths);
if (!empty($matchPaths[0])) {
try {
exec("cd {$matchPaths[0]} && git blame -L {$data['line']},{$data['line']} {$data['file']}", $output);
if (!empty($output[0]) && is_string($output[0])) {
preg_match('/(?<=\()[^ ]+/', $output[0], $matchCoders);
if (!empty($matchCoders[0])) {
$data['coder'] = $matchCoders[0];
}
}
} catch (Exception $e) {
put_log('获取编码人失败; ' . $e->getMessage(), 'ExceptionLogProducer.log');
}
}
}
$this->payload = $data;
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/4/9
* Time: 14:59
*/
namespace Meibuyu\Micro\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target({"CLASS"})
*/
class AutoPerm extends AbstractAnnotation
{
/**
* @var string
*/
public $prefix = '';
/**
* @var array
*/
public $exclude = [];
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/4/8
* Time: 13:59
*/
namespace Meibuyu\Micro\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target({"METHOD"})
*/
class Perm extends AbstractAnnotation
{
/**
* @var string
*/
public $name = '';
public function __construct($value = null)
{
$this->bindMainProperty('name', $value);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/4/8
* Time: 14:48
*/
namespace Meibuyu\Micro\Aspect;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Utils\Str;
use Meibuyu\Micro\Annotation\AutoPerm;
use Meibuyu\Micro\Annotation\Perm;
use Meibuyu\Micro\Exceptions\HttpResponseException;
use Meibuyu\Micro\Handler\PermHandler;
/**
* @Aspect()
*/
class PermAnnotationAspect extends AbstractAspect
{
/**
* @Inject()
* @var PermHandler
*/
private $permHandler;
/**
* @Inject
* @var ConfigInterface
*/
protected $config;
public $annotations = [
Perm::class,
AutoPerm::class,
];
/**
* @param ProceedingJoinPoint $proceedingJoinPoint
* @return mixed
* @throws HttpResponseException
* @throws \Hyperf\Di\Exception\Exception
*/
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
$perm = $this->genPermName($proceedingJoinPoint);
if ($perm) {
if ($this->permHandler->check($perm)) {
return $proceedingJoinPoint->process();
} else {
throw new HttpResponseException('当前用户没有此操作权限');
}
}
return $proceedingJoinPoint->process();
}
// 生成权限名
public function genPermName(ProceedingJoinPoint $proceedingJoinPoint)
{
/** @var AutoPerm $autoPerm */
/** @var Perm $perm */
[$autoPerm, $perm] = $this->getAnnotations($proceedingJoinPoint);
$className = $proceedingJoinPoint->className;
$methodName = $proceedingJoinPoint->methodName;
if ($autoPerm && in_array($methodName, $autoPerm->exclude)) {
return false; // 跳过不需要鉴权的方法
}
$prefix = $autoPerm && $autoPerm->prefix ? $autoPerm->prefix : $this->genPrefix($className);
$name = $perm && $perm->name ? $perm->name : $this->genName($methodName);
return $this->parsePermName($prefix, $name);
}
// 拼接权限名
protected function parsePermName($prefix, $name)
{
// 注意每个应用的app_name的唯一性
$appName = trim($this->config->get('app_name'), '_');
$prefix = trim($prefix, '_');
$name = trim($name, '_');
return $appName . '_' . $prefix . '_' . $name;
}
// 生成前缀
protected function genPrefix(string $className): string
{
$handledNamespace = Str::replaceFirst('Controller', '', Str::after($className, '\\Controller\\'));
$namespaceLength = strrpos($handledNamespace, '\\');
$prefix = $namespaceLength ? substr($handledNamespace, $namespaceLength + 1) : $handledNamespace;
$prefix = Str::snake($prefix);
$prefix = str_replace('__', '_', $prefix);
return $prefix;
}
// 生成名称
protected function genName(string $methodName): string
{
$methodName = Str::snake($methodName);
$methodName = str_replace('__', '_', $methodName);
return $methodName;
}
// 获取注解
public function getAnnotations(ProceedingJoinPoint $proceedingJoinPoint)
{
$metadata = $proceedingJoinPoint->getAnnotationMetadata();
return [
$metadata->class[AutoPerm::class] ?? null,
$metadata->method[Perm::class] ?? null
];
}
}
\ No newline at end of file
This diff is collapsed.
<?php
/**
* Created by PhpStorm.
* User: %user%
* Date: %date%
* Time: %time%
* Description:
*/
namespace App\Controller;
use App\Repository\Interfaces\%ModelClass%Repository;
use Hyperf\Di\Annotation\Inject;
use Meibuyu\Micro\Annotation\AutoPerm;
use Meibuyu\Micro\Annotation\Perm;
/**
* @AutoPerm()
* Class %ModelClass%Controller
* @package App\Controller
*/
class %ModelClass%Controller extends AbstractController
{
/**
* @Inject()
* @var %ModelClass%Repository
*/
private $repository;
/**
* 获取列表数据
* @return mixed
*/
public function index()
{
$list = $this->repository->list();
return success('获取成功', $list);
}
/**
* 获取列表数据
* @Perm("index")
* @param int $id id编号
* @return mixed
*/
public function show($id)
{
$data = $this->repository->show($id);
return success('获取成功', $data);
}
/**
* 添加记录
* @return mixed
*/
public function create()
{
$data = $this->repository->create($this->request->all());
return success('创建成功', $data);
}
/**
* 更新数据
* @param int $id id编号
* @return mixed
*/
public function update($id)
{
$data = $this->repository->update($this->request->all(), $id);
return success('更新成功', $data);
}
/**
* 删除单条数据
* @param int $id id编号
* @return mixed
*/
public function delete($id)
{
$deleted = $this->repository->delete($id);
return success('删除成功', $deleted);
}
%rs%
}
<?php
declare(strict_types=1);
use Hyperf\Database\Seeders\Seeder;
use Hyperf\DbConnection\Db;
class DataBaseSeeder extends Seeder
{
/**
* Run the database seeds.
* @return void
*/
public function run()
{
/**
* var $seeders 可执行的seeder填充类
**/
$seeders = [
];
Db::statement('SET FOREIGN_KEY_CHECKS = 0');
foreach($seeders as $item){
require BASE_PATH . "/seeders/seeders/" . \Hyperf\Utils\Str::snake(str_replace("::class", "", $item)) . ".php";
$instance = new $item;
$instance->run();
}
Db::statement('SET FOREIGN_KEY_CHECKS = 1');
}
}
<?php
/**
* Created by PhpStorm.
* User: %user%
* Date: %date%
* Time: %time%
* Description:
*/
use Hyperf\Database\Migrations\Migration;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Schema\Schema;
use Hyperf\DbConnection\Db;
class %ClassName% extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::disableForeignKeyConstraints();
Schema::create('%tableName%', function (Blueprint $table) {
%attributes%
});
%tableComment%
Schema::enableForeignKeyConstraints();
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::disableForeignKeyConstraints();
Schema::dropIfExists('%tableName%');
Schema::enableForeignKeyConstraints();
}
}
<?php
/**
* Created by PhpStorm.
* User: %user%
* Date: %date%
* Time: %time%
* Description:
*/
declare (strict_types=1);
namespace App\Model;
%namespace%
/**
* 模型类 %ClassName%
* @package App\Model
%properties%
*/
class %ClassName% extends Model
{
%SoftDelete%
/**
* 是否使用时间戳管理
* @var bool
*/
public $timestamps = %timestamps%;
/**
* 可写入数据的字段.
* @var array
*/
protected $fillable = [
%fillAble%
];
%relations%
}
<?php
/**
* Created by PhpStorm.
* User: %user%
* Date: %date%
* Time: %time%
* Description:
*/
declare(strict_types=1);
namespace App\Repository\Eloquent;
use App\Model\%ModelClass%;
use App\Repository\Interfaces\%ModelClass%Repository;
use App\Validators\%ModelClass%Validator;
use Hyperf\DbConnection\Db;
use Meibuyu\Micro\Exceptions\HttpResponseException;
use Meibuyu\Micro\Repository\Eloquent\BaseRepository;
/**
* Class %ModelClass%RepositoryEloquent
* @package App\Repository\Eloquent;
*/
class %ModelClass%RepositoryEloquent extends BaseRepository implements %ModelClass%Repository
{
public function model()
{
return %ModelClass%::class;
}
public function validator()
{
return %ModelClass%Validator::class;
}
/**
* 获取数据列表
* @return array
*/
public function list()
{
$pageSize = (int)$this->request->input('page_size', DEFAULT_PAGE_SIZE);
%list%
}
/**
* 获取单条数据
* @param $id
* @return array
*/
public function show($id)
{
%show%
}
/**
* 添加记录
* @param array $attributes
* @return bool
*/
public function create(array $attributes)
{
Db::transaction(function () use ($attributes) {
%create%
});
return true;
}
/**
* 更新数据
* @param array $attributes
* @param $id
* @return bool
*/
public function update(array $attributes, $id)
{
Db::transaction(function () use ($attributes, $id) {
%update%
});
return true;
}
/**
* 删除单条数据
* @param $id
* @return bool
* @throws HttpResponseException
*/
public function delete($id)
{
return parent::delete($id); // TODO: Change the autogenerated stub
}
%rs%
}
<?php
/**
* Created by PhpStorm.
* User: %user%
* Date: %date%
* Time: %time%
* Description:
*/
declare(strict_types=1);
namespace App\Repository\Interfaces;
use Meibuyu\Micro\Repository\Contracts\RepositoryInterface;
/**
* Interface %ClassName%
* @package App\Repository\Interfaces
*/
interface %ClassName% extends RepositoryInterface
{
}
<?php
declare(strict_types=1);
use App\Model\%modelClass%;%otherModel%
use Faker\Factory;
use Hyperf\Database\Seeders\Seeder;
use Hyperf\DbConnection\Db;
class %className% extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$faker = Factory::create('zh-CN');
%modelClass%::query()->truncate();
$n = %generateCount%;
for ($i = 0; $i < $n; $i++) {
$instance = %modelClass%::create([
%fields%
]);
%otherProcess%
}
}
}
<?php
/**
* Created by PhpStorm.
* User: %user%
* Date: %date%
* Time: %time%
* Description:
*/
declare(strict_types=1);
namespace App\Validators;
use Meibuyu\Micro\Validator\Contracts\ValidatorInterface;
use Meibuyu\Micro\Validator\HyperfValidator;
class %ModelClass%Validator extends HyperfValidator
{
protected $rules = [
ValidatorInterface::RULE_CREATE => [
%createRules%
],
ValidatorInterface::RULE_UPDATE => [
%updateRules%
],
];
protected $attributes = [
%attributes%
];
}
<?php
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/2/11
* Time: 11:49
*/
namespace Meibuyu\Micro;
class ConfigProvider
{
public function __invoke(): array
{
return [
'exceptions' => [
/**
* 以下异常处理器会合并到项目的config/autoload/exceptions.php文件配置数组的前面;
* 请勿在此使用顶级异常捕获处理器,防止项目中异常处理器无效;
*/
'handler' => [
'http' => [
\Meibuyu\Micro\Exceptions\Handler\MicroExceptionHandler::class,
\Meibuyu\Micro\Exceptions\Handler\QueryExceptionHandler::class,
\Meibuyu\Micro\Exceptions\Handler\PhpSpreadsheetExceptionHandler::class,
],
],
],
'dependencies' => [
\Hyperf\ServiceGovernance\Listener\RegisterServiceListener::class => \Meibuyu\Micro\Listener\RegisterServiceListener::class,
],
'commands' => [
\Meibuyu\Micro\Command\MakeModelCommand::class,
],
'annotations' => [
'scan' => [
'paths' => [
__DIR__,
],
],
],
];
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Time: 2020/10/27 9:21
*/
namespace Meibuyu\Micro\Constants;
class Department
{
const WAREHOUSE_LOGISTICS = 5; // 仓储物流部
const WAREHOUSE = 6; // 仓储部
const LOGISTICS = 7; // 物流部
const FINANCE = 10; //财务部
const HR = 18; // 行政人事部
const TECH = 34; // 技术部
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/3/23
* Time: 17:45
*/
namespace Meibuyu\Micro\Constants;
class MaterialCategory
{
const FU_LIAO = 1; // 辅料
const MIAN_LIAO = 2; // 面料
const LI_BU = 3; // 里布
const HAO_CAI = 4; // 耗材
const FU_LIAO_WAREHOUSE = 33;
const MIAN_LIAO_WAREHOUSE = 36;
/**
* 通过原料类型获取对应仓库id
* @param $categoryId
* @return int
* @throws \Exception
*/
public static function getWarehouseId($categoryId)
{
switch ($categoryId) {
case self::FU_LIAO:
case self::HAO_CAI:
return self::FU_LIAO_WAREHOUSE;
case self::MIAN_LIAO:
case self::LI_BU:
return self::MIAN_LIAO_WAREHOUSE;
default:
throw new \Exception("原料类型不存在");
}
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/6/18
* Time: 8:32
*/
namespace Meibuyu\Micro\Constants;
class SpecialUserId
{
const BOSS = 38; // 王大抗
const ZHANG_TING_TING = 83; // 张婷婷
const MA_BAO_TONG = 84; // 马宝同
const CAI_YA_XIANG = 85; // 蔡亚祥
const CAI_HONG_SHAN = 86; // 蔡红山
const ZHAN_YONG_YONG = 87; // 詹永勇
const LI_DONG = 292; // 李东
const BAO_SHI_FANG= 322; // 鲍诗芳
}
<?php
declare(strict_types=1);
namespace Meibuyu\Micro\Exceptions\Handler;
use Exception;
use Hyperf\Amqp\Producer;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Logger\LoggerFactory;
use Meibuyu\Micro\Amqp\Producer\ExceptionLogProducer;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class AppExceptionHandler extends ExceptionHandler
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var StdoutLoggerInterface
*/
protected $stdoutLogger;
/**
* @var LoggerInterface
*/
protected $logger;
/**
* @var ConfigInterface
*/
protected $config;
/**
* @var RequestInterface
*/
protected $request;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->stdoutLogger = $container->get(StdoutLoggerInterface::class);
$this->logger = $container->get(LoggerFactory::class)->get('Uncaught Exception');
$this->config = $container->get(ConfigInterface::class);
$this->request = $container->get(RequestInterface::class);
}
public function handle(Throwable $throwable, ResponseInterface $response)
{
// 捕获所有未捕获的异常
$this->stopPropagation();
$api = sprintf('%s(%s)', $this->request->getUri(), $this->request->getMethod());
$exceptionClass = get_class($throwable);
$message = $throwable->getMessage();
$line = $throwable->getLine();
$file = $throwable->getFile();
$code = $throwable->getCode();
$trace = $throwable->getTraceAsString();
$data = [
'api' => $api,
'server' => $this->config->get('app_name'),
'file' => $file,
'line' => $line,
'message' => $message,
'trace' => $trace,
'code' => $code,
'created_at' => now(),
];
try {
$exceptionLogProducer = new ExceptionLogProducer($data);
$producer = $this->container->get(Producer::class);
$producer->produce($exceptionLogProducer);
} catch (Exception $e) {
put_log('异常日志失败; ' . $e->getMessage(), 'ExceptionLogProducer.log');
}
$msg = sprintf('%s: %s(%s) in %s:%s', $exceptionClass, $message, $code, $file, $line);
$error = sprintf("API: %s\n%s\nStack trace:\n%s", $api, $msg, $trace);
$this->logger->error($error);
$this->stdoutLogger->error($error);
return $response->withStatus(500)->withBody(new SwooleStream($msg));
}
public function isValid(Throwable $throwable): bool
{
return true;
}
}
<?php
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/2/7
* Time: 16:39
*/
namespace Meibuyu\Micro\Exceptions\Handler;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Meibuyu\Micro\Exceptions\HttpResponseException;
use Meibuyu\Micro\Exceptions\ValidatorException;
use Psr\Http\Message\ResponseInterface;
use Throwable;
class MicroExceptionHandler extends ExceptionHandler
{
public function handle(Throwable $throwable, ResponseInterface $response)
{
// 判断被捕获到的异常是希望被捕获的异常
if ($throwable instanceof HttpResponseException) {
// 格式化输出
$data = json_encode([
'code' => $throwable->getCode() ?: 400,
'msg' => $throwable->getMessage(),
], JSON_UNESCAPED_UNICODE);
// 阻止异常冒泡
$this->stopPropagation();
return $response
->withAddedHeader('content-type', 'application/json')
->withBody(new SwooleStream($data));
} else if ($throwable instanceof ValidatorException) {
$this->stopPropagation(); // 阻止异常冒泡
/** @var ValidatorException $throwable */
$data = json_encode([
'code' => $throwable->getCode() ?: 401,
'msg' => $throwable->first(),
], JSON_UNESCAPED_UNICODE);
return $response
->withAddedHeader('content-type', 'application/json')
->withBody(new SwooleStream($data));
}
return $response; // 交给下一个异常处理器
}
public function isValid(Throwable $throwable): bool
{
return true;
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/24
* Time: 18:05
*/
namespace Meibuyu\Micro\Exceptions\Handler;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
use Psr\Http\Message\ResponseInterface;
use Throwable;
class PhpSpreadsheetExceptionHandler extends ExceptionHandler
{
public function handle(Throwable $throwable, ResponseInterface $response)
{
$error = $throwable->getMessage();
if ($throwable instanceof PhpSpreadsheetException) {
if (strpos($error, 'Formula Error') !== false) {
$msg = '表格公式错误, 请检查是否引用其它表格数据';
return $this->jsonResponse($msg, $response);
}
} else if (strpos($error, 'PhpOffice\PhpSpreadsheet\Writer\Xls::writeSummaryProp()') !== false) {
$msg = '表格格式兼容错误,请上传 xlsx 结尾的excel';
return $this->jsonResponse($msg, $response);
}
return $response;
}
public function jsonResponse($msg, ResponseInterface $response)
{
// 阻止异常冒泡
$this->stopPropagation();
// 格式化输出
$data = json_encode([
'code' => 400,
'msg' => $msg,
], JSON_UNESCAPED_UNICODE);
return $response->withAddedHeader('content-type', 'application/json')->withBody(new SwooleStream($data));
}
public function isValid(Throwable $throwable): bool
{
return true;
}
}
<?php
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/5/12
* Time: 16:11
*/
namespace Meibuyu\Micro\Exceptions\Handler;
use Hyperf\Database\Exception\QueryException;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;
class QueryExceptionHandler extends ExceptionHandler
{
public function handle(Throwable $throwable, ResponseInterface $response)
{
$code = $throwable->getCode();
$msg = $throwable->getMessage();
if ($code == 23000 && strpos($msg, 'foreign key') !== false) {
// 格式化输出
$data = json_encode([
'code' => 400,
'msg' => '此数据下有关联的数据,不可进行操作',
], JSON_UNESCAPED_UNICODE);
// 阻止异常冒泡
$this->stopPropagation();
return $response
->withAddedHeader('content-type', 'application/json')
->withBody(new SwooleStream($data));
}
return $response; // 交给下一个异常处理器
}
public function isValid(Throwable $throwable): bool
{
return $throwable instanceof QueryException;
}
}
<?php
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/2/7
* Time: 16:18
*/
namespace Meibuyu\Micro\Exceptions;
class HttpResponseException extends \Exception
{
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/3/17
*/
namespace Meibuyu\Micro\Exceptions;
use Throwable;
class ObjectNotExistException extends \Exception
{
public function __construct($message, $code = 0, Throwable $previous = null)
{
parent::__construct($message . ' Not Exist!', $code, $previous);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/2/7
* Time: 15:24
*/
namespace Meibuyu\Micro\Exceptions;
class RepositoryException extends \Exception
{
}
\ No newline at end of file
<?php
namespace Meibuyu\Micro\Exceptions;
use Hyperf\Utils\Contracts\MessageBag;
class ValidatorException extends \Exception
{
/**
* @var MessageBag
*/
protected $messageBag;
/**
* @param MessageBag $messageBag
*/
public function __construct(MessageBag $messageBag)
{
parent::__construct('The given data was invalid.');
$this->messageBag = $messageBag;
}
/**
* @return MessageBag
*/
public function errors()
{
return $this->messageBag;
}
/**
* @return string
*/
public function first()
{
return $this->messageBag->first();
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray(): array
{
return [
'error' => 'validation_exception',
'error_description' => $this->errors()
];
}
/**
* Convert the object to its JSON representation.
*
* @param int $options
* @return string
*/
public function toJson($options = 0)
{
return json_encode($this->toArray(), $options);
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/7/3
* Time: 14:27
*/
namespace Meibuyu\Micro\Handler;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Di\Annotation\Inject;
use Meibuyu\Micro\Exceptions\HttpResponseException;
use Meibuyu\Micro\Model\Auth;
use Meibuyu\Micro\Service\Interfaces\MessageServiceInterface;
class MessageHandler
{
/**
* @Inject()
* @var MessageServiceInterface
*/
private $messageService;
/**
* @Inject
* @var ConfigInterface
*/
protected $config;
/**
* 发送模板消息
* @param $receiverIds
* @param $templateId
* @param array $replace
* @throws HttpResponseException
*/
public function sendTemp($receiverIds, $templateId, $replace = [])
{
$application = $this->config->get('app_name');
if (!$application) {
throw new HttpResponseException("请设置应用名app_name");
}
$receiverIds = is_array($receiverIds) ? $receiverIds : [$receiverIds];
$sendUserId = Auth::id();
$this->messageService->send($receiverIds, $application, $templateId, $sendUserId, $replace);
}
/**
* 发送文本消息
* @param $receiverIds
* @param $content
* @throws HttpResponseException
*/
public function sendText($receiverIds, $content)
{
$application = $this->config->get('app_name');
if (!$application) {
throw new HttpResponseException("请设置应用名app_name");
}
$receiverIds = is_array($receiverIds) ? $receiverIds : [$receiverIds];
$sendUserId = Auth::id();
$this->messageService->send($receiverIds, $application, 0, $sendUserId, [], $content);
}
/**
* 自动发送模板消息
* @param $receiverIds
* @param $templateId
* @param array $replace
* @throws HttpResponseException
*/
public function sendAutoTemp($receiverIds, $templateId, $replace = [])
{
$application = $this->config->get('app_name');
if (!$application) {
throw new HttpResponseException("请设置应用名app_name");
}
$receiverIds = is_array($receiverIds) ? $receiverIds : [$receiverIds];
$this->messageService->send($receiverIds, $application, $templateId, 0, $replace);
}
/**
* 自动发送文本消息
* @param $receiverIds
* @param $content
* @throws \Exception
*/
public function sendAutoText($receiverIds, $content)
{
$application = $this->config->get('app_name');
if (!$application) {
throw new \Exception("请设置应用名app_name");
}
$receiverIds = is_array($receiverIds) ? $receiverIds : [$receiverIds];
$this->messageService->send($receiverIds, $application, 0, 0, [], $content);
}
/**
* 定时任务专用 发送文本消息
* @param $receiverIds
* @param $content
* @throws HttpResponseException
*/
public function sendCrontabText($receiverIds, $content)
{
$application = $this->config->get('app_name');
if (!$application) {
throw new HttpResponseException("请设置应用名app_name");
}
$receiverIds = is_array($receiverIds) ? $receiverIds : [$receiverIds];
$this->messageService->send($receiverIds, $application, 0, 0, [], $content);
}
/**
* 发送markdown 文本消息
* @param $receiverIds
* @param $content
* @param $title
* @throws HttpResponseException
*/
public function sendMarkDownText($receiverIds, $content, $title)
{
$application = $this->config->get('app_name');
if (!$application) {
throw new HttpResponseException("请设置应用名app_name");
}
$receiverIds = is_array($receiverIds) ? $receiverIds : [$receiverIds];
$sendUserId = Auth::id();
$this->messageService->SendMarkDownMessage($receiverIds, $application, 0, $sendUserId, [], $content, $title);
}
/**
* 自动发送markdown 文本消息
* @param $receiverIds
* @param $content
* @param $title
* @throws HttpResponseException
*/
public function sendAutoMarkDownText($receiverIds, $content, $title)
{
$application = $this->config->get('app_name');
if (!$application) {
throw new HttpResponseException("请设置应用名app_name");
}
$receiverIds = is_array($receiverIds) ? $receiverIds : [$receiverIds];
$this->messageService->SendMarkDownMessage($receiverIds, $application, 0, 0, [], $content, $title);
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/4/8
* Time: 16:12
*/
namespace Meibuyu\Micro\Handler;
use Hyperf\Di\Annotation\Inject;
use Meibuyu\Micro\Model\Auth;
use Meibuyu\Micro\Service\Interfaces\UserServiceInterface;
class PermHandler
{
/**
* @Inject()
* @var UserServiceInterface
*/
protected $userServer;
public function check($perm)
{
return $this->userServer->checkPerm(Auth::id(), $perm);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: 梁俊杰
* Date: 2019/12/03
* Time: 16:08
* Description:
*/
namespace Meibuyu\Micro;
class Helper
{
/**
* 获取唯一编号
* @param string $prefix
* @return string
*/
public static function uid($prefix = '')
{
return uniqid($prefix);
}
/**
* 返回成功消息
* @param array|string $data 返回数据 默认空
* @param string $msg 消息,默认 Success
* @param int $code 成功代码,默认200
* @return array
*/
public static function success($data = '', $msg = 'success', $code = 200)
{
return self::response($data, $msg, $code);
}
/**
* 返回失败消息
* @param array|string $data 返回数据 默认空
* @param string $msg 消息,默认 Error
* @param int $code 失败代码,默认400
* @return array
*/
public static function fail($data = '', $msg = 'fail', $code = 400)
{
return self::response($data, $msg, $code);
}
/**
* 返回操作消息
* @param array|string $data 返回数据 默认空
* @param string $msg 消息,默认空
* @param int $code 操作代码,默认200
* @return array
*/
public static function response($data = '', $msg = '', $code = 200)
{
return ['data' => $data, 'msg' => $msg, 'code' => $code];
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/5/6
* Time: 8:54
*/
namespace Meibuyu\Micro\Listener;
use Hyperf\ServiceGovernance\Listener\RegisterServiceListener as BaseRegisterServiceListener;
class RegisterServiceListener extends BaseRegisterServiceListener
{
protected function getServers(): array
{
$result = [];
$servers = $this->config->get('server.servers', []);
foreach ($servers as $server) {
if (!isset($server['name'], $server['host'], $server['port'])) {
continue;
}
if (!$server['name']) {
throw new \InvalidArgumentException('Invalid server name');
}
/**
* 若在docker中运行,会获取到docker环境中的ip
* 这里对配置文件中local_ip判断,如果有,直接使用
*/
$host = isset($server['local_ip']) ? $server['local_ip'] : $server['host'];
if (in_array($host, ['0.0.0.0', 'localhost'])) {
$host = $this->getInternalIp();
}
if (!filter_var($host, FILTER_VALIDATE_IP)) {
throw new \InvalidArgumentException(sprintf('Invalid host %s', $host));
}
$port = $server['port'];
if (!is_numeric($port) || ($port < 0 || $port > 65535)) {
throw new \InvalidArgumentException(sprintf('Invalid port %s', $port));
}
$port = (int)$port;
$result[$server['name']] = [$host, $port];
}
return $result;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/3/30
* Time: 9:56
*/
declare(strict_types=1);
namespace Meibuyu\Micro\Manager;
use Hyperf\HttpMessage\Upload\UploadedFile;
use Meibuyu\Micro\Exceptions\HttpResponseException;
class UploadManager
{
public static $pathPrefix = '/upload/';
public static $options = [
'path' => 'default', // 默认保存路径
'maxSize' => 10 * 1024 * 1024, // 文件大小,10M
'temp' => false, // 是否为临时文件
'mime' => ['jpeg', 'png', 'gif', 'jpg', 'svg', 'txt', 'pdf', 'xlsx', 'xls', 'doc', 'docx', 'rar', 'zip', 'csv'], // 允许上传的文件类型
];
/**
* 图片上传方法
* @param $image
* @param array $options
* @return string
* @throws HttpResponseException
*/
public static function uploadImage($image, $options = [])
{
$imgOptions = [
'path' => 'images',
'mime' => ['jpeg', 'png', 'gif', 'jpg', 'svg']
];
$options = array_merge($imgOptions, $options);
return self::uploadFile($image, $options);
}
/**
* 表格上传方法
* @param $excel
* @param array $options
* @return string
* @throws HttpResponseException
*/
public static function uploadExcel($excel, $options = [])
{
$excelOptions = [
'path' => 'excel',
'mime' => ['xlsx', 'xls', 'csv']
];
$options = array_merge($excelOptions, $options);
return self::uploadFile($excel, $options);
}
/**
* 表格上传方法获取真实地址
* @param $excel
* @param array $options
* @return string
* @throws HttpResponseException
*/
public static function uploadExcelGetRealPath($excel, $options = [])
{
$excelOptions = [
'path' => 'excel',
'mime' => ['xlsx', 'xls', 'csv']
];
$options = array_merge($excelOptions, $options);
return self::uploadFile($excel, $options, true);
}
/**
* 文件上传方法
* @param UploadedFile $file 上传的文件
* @param array $options 配置参数
* @param bool $realPath
* @return string
* @throws HttpResponseException
*/
public static function uploadFile($file, $options = [], $realPath = false)
{
$documentRoot = config('server.settings.document_root');
if (!$documentRoot) {
throw new \RuntimeException('未配置静态资源');
}
$options = self::parseOptions($options);
if ($file->isValid()) {
$extension = strtolower($file->getExtension());
// 通过扩展名判断类型
if (!in_array($extension, $options['mime'])) {
throw new HttpResponseException('文件类型不支持,目前只支持' . implode(',', $options['mime']));
}
// 判断文件大小
if ($file->getSize() > $options['maxSize']) {
throw new HttpResponseException('文件超出系统规定的大小,最大不能超过' . num_2_file_size($options['maxSize']));
}
// 文件重命名,由当前日期时间 + 唯一ID + 扩展名
$fileName = date('YmdHis') . uniqid() . '.' . $extension;
$savePath = self::parsePath($options, $documentRoot) . $fileName;
$file->moveTo($savePath);
if ($file->isMoved()) {
if ($realPath) {
return $savePath;
} else {
return str_replace($documentRoot, '', $savePath);
}
} else {
throw new HttpResponseException('文件保存失败');
}
} else {
throw new HttpResponseException('文件无效');
}
}
/**
* 文件上传方法(micro-api-flow)
* @param UploadedFile $file 上传的文件
* @param array $options 配置参数
* @param bool $realPath
* @return string
* @throws HttpResponseException
*/
public static function uploadFileGetName($file, $options = [], $realPath = false)
{
$documentRoot = config('server.settings.document_root');
if (!$documentRoot) {
throw new \RuntimeException('未配置静态资源');
}
$options = self::parseOptions($options);
if ($file->isValid()) {
$extension = strtolower($file->getExtension());
// 通过扩展名判断类型
if (!in_array($extension, $options['mime'])) {
throw new HttpResponseException('文件类型不支持,目前只支持' . implode(',', $options['mime']));
}
// 判断文件大小
if ($file->getSize() > $options['maxSize']) {
throw new HttpResponseException('文件超出系统规定的大小,最大不能超过' . num_2_file_size($options['maxSize']));
}
// 文件重命名,由当前日期时间 + 唯一ID + 扩展名
$fileName = date('YmdHis') . uniqid() . '.' . $extension;
$name = $file->toArray()['name'];
$savePath = self::parsePath($options, $documentRoot) . $fileName;
$file->moveTo($savePath);
if ($file->isMoved()) {
if ($realPath) {
return $savePath . '?' . $name;
} else {
return str_replace($documentRoot, '', $savePath . '?' . $name);
}
} else {
throw new HttpResponseException('文件保存失败');
}
} else {
throw new HttpResponseException('文件无效');
}
}
/**
* 生成头像
* @return string|string[]
*/
public static function createAvatar()
{
$documentRoot = config('server.settings.document_root');
if (!$documentRoot) {
throw new \RuntimeException('未配置静态资源');
}
$img = imagecreatetruecolor(180, 180);
$bgColor = imagecolorallocate($img, 240, 240, 240);
imagefill($img, 0, 0, $bgColor);
$color = imagecolorallocate($img, rand(90, 230), rand(90, 230), rand(90, 230));
for ($i = 0; $i < 90; $i++) {
for ($y = 0; $y < 180; $y++) {
$ad = rand(10, 50); //随机
if ($ad % 3 == 0) {
for ($xx = $i; $xx < $i + 15; $xx++) {
for ($yy = $y; $yy < $y + 30; $yy++) {
imagesetpixel($img, $xx, $yy, $color);
}
}
$is = ((90 - $i) + 90) - 15; //计算偏移
for ($xx = $is; $xx < $is + 15; $xx++) {
for ($yy = $y; $yy < $y + 30; $yy++) {
imagesetpixel($img, $xx, $yy, $color);
}
}
}
$y += 14;
}
$i += 14;
}
$path = $documentRoot . self::$pathPrefix . 'avatar/default/';
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
$fileName = $path . date('YmdHis') . uniqid() . '.png';
imagepng($img, $fileName);
imagedestroy($img);//释放内存
return str_replace($documentRoot, '', $fileName);
}
/**
* 处理保存路径
* @param $options
* @param $documentRoot
* @return string
*/
public static function parsePath($options, $documentRoot)
{
if (isset($options['temp']) && $options['temp']) {
// 如果是临时文件,修改保存路径为临时路径
$options['path'] = 'temp';
}
$path = $documentRoot . self::$pathPrefix . $options['path'] . '/' . date('Y-m-d');
if (!is_dir($path)) {
// 判断路径是否存在,不存在,则创建
mkdir($path, 0777, true);
}
return $path . '/';
}
/**
* 处理配置参数
* @param array $options
* @return array
*/
public static function parseOptions($options = [])
{
if ($options == []) {
return self::$options;
} else {
return array_merge(self::$options, $options);
}
}
public static function deleteFile($path)
{
$documentRoot = config('server.settings.document_root');
if (!$documentRoot) {
throw new \RuntimeException('未配置静态资源');
}
$path = str_replace(config('app_domain'), '', $path);
$path = $documentRoot . $path;
if (file_exists($path)) {
unlink($path);
}
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/24
* Time: 9:33
*/
namespace Meibuyu\Micro\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class CheckWebhookMiddleware implements MiddlewareInterface
{
/**
* @inheritDoc
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$domain = $request->getHeader('x-shopify-shop-domain')[0] ?? null;
$topic = $request->getHeader('x-shopify-topic')[0] ?? null;
if ($domain && $topic) {
return $handler->handle($request);
} else {
return response()->withStatus(500);
}
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/4/3
* Time: 10:17
*/
declare(strict_types=1);
namespace Meibuyu\Micro\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class TokenExistMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (token()) {
return $handler->handle($request);
} else {
return response()->json([
'code' => 403,
'msg' => 'token不存在'
]);
}
}
}
<?php
namespace Meibuyu\Micro\Model;
use Hyperf\Utils\Context;
use Meibuyu\Micro\Exceptions\HttpResponseException;
class Auth
{
/**
* @return bool|mixed|string|null
* @throws HttpResponseException
*/
private static function init()
{
if (Context::has('auth')) {
return Context::get('auth');
} else {
$token = token();
if (!$token) throw new HttpResponseException('Token不存在');
$auth = redis()->get($token);
if ($auth) {
$auth = json_decode($auth, true);
Context::set('auth', $auth);
return $auth;
} else {
throw new HttpResponseException('用户不存在');
}
}
}
/**
* @return object
* @throws HttpResponseException
*/
public static function user()
{
return self::init();
}
/**
* @return integer
* @throws HttpResponseException
*/
public static function id()
{
return self::init()['id'];
}
}
<?php
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/2/7
* Time: 13:42
*/
namespace Meibuyu\Micro\Repository\Contracts;
interface RepositoryInterface
{
public function list();
public function show($id);
/**
* @param array $columns
* @return mixed
*/
public function all($columns = array('*'));
public function paginate($perPage = 10, $columns = array('*'));
public function create(array $attributes);
public function update(array $attributes, $id);
public function delete($id);
public function find($id, $columns = array('*'));
public function findBy($field, $value, $columns = array('*'));
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/2/7
* Time: 13:47
*/
namespace Meibuyu\Micro\Repository\Eloquent;
use Hyperf\Database\Exception\QueryException;
use Hyperf\Database\Model\Builder;
use Hyperf\DbConnection\Model\Model;
use Hyperf\HttpServer\Contract\RequestInterface;
use Meibuyu\Micro\Exceptions\HttpResponseException;
use Meibuyu\Micro\Exceptions\RepositoryException;
use Meibuyu\Micro\Exceptions\ValidatorException;
use Meibuyu\Micro\Repository\Contracts\RepositoryInterface;
use Meibuyu\Micro\Validator\Contracts\ValidatorInterface;
use Psr\Container\ContainerInterface;
abstract class BaseRepository implements RepositoryInterface
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var RequestInterface
*/
protected $request;
/**
* @var Model|Builder
*/
protected $model;
/**
* @var ValidatorInterface
*/
protected $validator;
/**
* BaseRepository constructor.
* @param ContainerInterface $container
* @param RequestInterface $request
* @throws RepositoryException
*/
public function __construct(ContainerInterface $container, RequestInterface $request)
{
$this->container = $container;
$this->request = $request;
$this->makeModel();
$this->makeValidator();
}
/**
* Specify Model class name
* @return mixed
*/
abstract public function model();
/**
* Specify Validator class name
* @return null|mixed
*/
public function validator()
{
return null;
}
/**
* @return Model
* @throws RepositoryException
*/
public function makeModel()
{
$model = $this->container->make($this->model());
if (!$model instanceof Model) {
throw new RepositoryException("Class {$this->model()} must be an instance of Hyperf\\DbConnection\\Model\\Model");
}
return $this->model = $model;
}
/**
* @param null $validator
*
* @return null|ValidatorInterface
* @throws RepositoryException
*/
public function makeValidator($validator = null)
{
$validator = !is_null($validator) ? $validator : $this->validator();
if (!is_null($validator)) {
$this->validator = $this->container->make($validator);
if (!$this->validator instanceof ValidatorInterface) {
throw new RepositoryException("Class {$validator} must be an instance of Meibuyu\\Micro\\Validator\\Contracts\\ValidatorInterface");
}
return $this->validator;
}
return null;
}
/**
* @param $id
* @param array $columns
* @return mixed|Model
* @throws HttpResponseException
*/
public function find($id, $columns = ['*'])
{
$model = $this->model->find($id, $columns);
if (!$model) {
throw new HttpResponseException('数据不存在');
}
return $model;
}
/**
* @param array $columns
* @return mixed
*/
public function all($columns = ['*'])
{
return $this->model->get($columns);
}
public function list()
{
return $this->all();
}
/**
* @param $id
* @return Model|mixed
* @throws HttpResponseException
*/
public function show($id)
{
return $this->find($id);
}
public function paginate($perPage = 10, $columns = ['*'])
{
return $this->model->paginate($perPage, $columns);
}
/**
* @param array $attributes
* @return Model
* @throws ValidatorException
*/
public function create(array $attributes)
{
if (!is_null($this->validator)) {
$this->validator->with($attributes)->passesOrFail(ValidatorInterface::RULE_CREATE);
}
$model = $this->model->newInstance($attributes);
$model->save();
return $model;
}
/**
* @param array $attributes
* @param $id
* @return Model | mixed
* @throws HttpResponseException
* @throws ValidatorException
*/
public function update(array $attributes, $id)
{
if (!is_null($this->validator)) {
$this->validator->with($attributes)->setId($id)->passesOrFail(ValidatorInterface::RULE_UPDATE);
}
$model = $this->find($id);
$model->fill($attributes);
$model->save();
return $model;
}
/**
* @param $id
* @return bool|mixed
* @throws HttpResponseException
*/
public function delete($id)
{
$model = $this->find($id);
try {
$delete = $model->delete();
} catch (QueryException $e) {
$msg = $e->getMessage();
if ($e->getCode() == 23000 && strpos($msg, 'foreign key') !== false) {
throw new HttpResponseException('此数据下有关联的数据,不可进行操作');
} else {
throw new HttpResponseException($msg);
}
} catch (\Exception $e) {
throw new HttpResponseException($e->getMessage());
}
if ($delete !== false) {
return $delete;
} else {
throw new HttpResponseException('删除失败,请刷新重试');
}
}
public function findBy($field, $value, $columns = ['*'])
{
return $this->model->where($field, '=', $value)->first($columns);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: 王源
* Date: 2020/1/9
* Time: 15:08
*/
namespace Meibuyu\Micro\Service;
use Exception;
use Hyperf\DbConnection\Model\Model;
use Meibuyu\Micro\Helper;
class BaseService
{
/**
* @var Model
*/
protected $model;
/**
* 查找一个数据
* @param $id
* @return Model | array
*/
protected function find($id)
{
$model = $this->model->find($id);
return $model;
}
public function all(array $columns = ['*'], array $relations = []): array
{
return $this->model->with($relations)->get($columns)->toArray();
}
/**
* 获取一条数据
* @param int $id
* @param array $columns
* @param array $relations
* @return mixed
*/
public function get(int $id, array $columns = ['*'], array $relations = [])
{
return $this->model->with($relations)->find($id, $columns);
}
/**
* 插入一条数据
* @param array $params
* @return array
*/
public function insert($params)
{
try {
$res = $this->model->insert($params);
return Helper::success($res);
} catch (Exception $e) {
return Helper::fail('', $e->getMessage());
}
}
/**
* 新增一条数据
* @param array $params
* @return array
*/
public function create($params)
{
try {
$model = $this->model->newInstance($params);
$model->save();
return Helper::success($model);
} catch (Exception $e) {
return Helper::fail('', $e->getMessage());
}
}
/**
* 更新数据
* @param $id
* @param array $params
* @return array
*/
public function update($id, $params)
{
try {
$model = $this->find($id);
$model->fill($params);
$model->save();
return Helper::success($model);
} catch (Exception $e) {
return Helper::fail('', $e->getMessage());
}
}
/**
* 删除数据
* @param $id
* @return array
*/
public function delete($id)
{
try {
$model = $this->find($id);
$res = $model->delete();
if ($res) {
return Helper::success($res, '删除成功');
} else {
return Helper::fail($res, '删除失败');
}
} catch (Exception $e) {
return Helper::fail('', $e->getMessage());
}
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/18
* Time: 8:13
*/
namespace Meibuyu\Micro\Shopify;
use Exception;
use Meibuyu\Micro\Shopify\lib\AbstractShopify;
use Meibuyu\Micro\Shopify\lib\Collect;
use Meibuyu\Micro\Shopify\lib\Collection;
use Meibuyu\Micro\Shopify\lib\CustomCollection;
use Meibuyu\Micro\Shopify\lib\Event;
use Meibuyu\Micro\Shopify\lib\Fulfillment;
use Meibuyu\Micro\Shopify\lib\FulfillmentOrder;
use Meibuyu\Micro\Shopify\lib\FulfillmentService;
use Meibuyu\Micro\Shopify\lib\GraphQL;
use Meibuyu\Micro\Shopify\lib\InventoryItem;
use Meibuyu\Micro\Shopify\lib\InventoryLevel;
use Meibuyu\Micro\Shopify\lib\Location;
use Meibuyu\Micro\Shopify\lib\Metafield;
use Meibuyu\Micro\Shopify\lib\Order;
use Meibuyu\Micro\Shopify\lib\Product;
use Meibuyu\Micro\Shopify\lib\ProductVariant;
use Meibuyu\Micro\Shopify\lib\SmartCollection;
use Meibuyu\Micro\Shopify\lib\Webhook;
/**
* Class ShopifyApp
* @package Meibuyu\Shopify
*
* @property-read Webhook $Webhook
* @property-read Collect $Collect
* @property-read Collection $Collection
* @property-read CustomCollection $CustomCollection
* @property-read SmartCollection $SmartCollection
* @property-read Metafield $Metafield
* @property-read Product $Product
* @property-read ProductVariant $ProductVariant
* @property-read InventoryItem $InventoryItem
* @property-read InventoryLevel $InventoryLevel
* @property-read Location $Location
* @property-read Order $Order
* @property-read Event $Event
* @property-read Fulfillment $Fulfillment
* @property-read FulfillmentService $FulfillmentService
* @property-read GraphQL $GraphQL
*
* @method Webhook Webhook(integer $id = null)
* @method Collection Collection(integer $id = null)
* @method CustomCollection CustomCollection(integer $id = null)
* @method SmartCollection SmartCollection(integer $id = null)
* @method Metafield Metafield(integer $id = null)
* @method Product Product(integer $id = null)
* @method ProductVariant ProductVariant(integer $id = null)
* @method InventoryItem InventoryItem(integer $id = null)
* @method InventoryLevel InventoryLevel(integer $id = null)
* @method Location Location(integer $id = null)
* @method Order Order(integer $id = null)
* @method Event Event(integer $id = null)
* @method Fulfillment Fulfillment(integer $id = null)
* @method FulfillmentOrder FulfillmentOrder()
* @method FulfillmentService FulfillmentService(integer $id = null)
* @method GraphQL GraphQL()
*
*/
class ShopifyApp
{
protected $resources = [
'Webhook',
'Collect',
'Collection',
'CustomCollection',
'SmartCollection',
'Metafield',
'Product',
'ProductVariant',
'InventoryItem',
'InventoryLevel',
'Location',
'Order',
'Event',
'Fulfillment',
'FulfillmentOrder',
'FulfillmentService',
'GraphQL',
];
protected $childResources = array(
'Fulfillment' => 'Order',
'FulfillmentEvent' => 'Fulfillment',
'FulfillmentOrder' => 'Order',
'OrderRisk' => 'Order',
'ProductImage' => 'Product',
'ProductVariant' => 'Product',
'DiscountCode' => 'PriceRule',
'Refund' => 'Order',
'Transaction' => 'Order',
);
public $config = [];
public $defaultApiVersion = '2021-07';
/**
* ShopifyApp constructor.
* @param array $config
*/
public function __construct($config)
{
$this->config = [
'api_version' => $this->defaultApiVersion
];
foreach ($config as $key => $value) {
$this->config[$key] = $value;
}
if (isset($config['shop_url'])) {
$this->setApiUrl();
}
}
/**
* 返回AbstractShopify实例
* @param string $className 实现的类名
* @return AbstractShopify
* @throws Exception
*/
public function __get($className)
{
return $this->$className();
}
/**
* 返回AbstractShopify实例
* @param string $className 实现的类名
* @param $arguments
* @return AbstractShopify
* @throws Exception
*/
public function __call($className, $arguments)
{
if (!in_array($className, $this->resources)) {
if (isset($this->childResources[$className])) {
$message = "$className 是属于 {$this->childResources[$className]} 的子集, 无法直接访问";
} else {
$message = "未知类 $className";
}
throw new Exception($message);
}
$resourceID = !empty($arguments) ? $arguments[0] : null;
$resourceClassName = __NAMESPACE__ . "\\lib\\$className";
return new $resourceClassName($this->config, $resourceID);
}
public function setApiUrl()
{
$shopUrl = $this->config['shop_url'];
$shopUrl = preg_replace('#^https?://|/$#', '', $shopUrl);
$apiVersion = $this->config['api_version'];
$this->config['api_url'] = "https://$shopUrl/admin/api/$apiVersion/";
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/19
* Time: 9:25
*/
namespace Meibuyu\Micro\Shopify;
use Hyperf\Contract\ContainerInterface;
class ShopifyFactory
{
/**
* @var ContainerInterface
*/
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function create(array $config = []): ShopifyApp
{
if (method_exists($this->container, 'make')) {
// Create by DI for AOP.
return $this->container->make(ShopifyApp::class, ['config' => $config]);
}
return new ShopifyApp($config);
}
}
This diff is collapsed.
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/24
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
class Collect extends AbstractShopify
{
protected $resourceKey = 'collect';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/24
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class Collection
* @package Meibuyu\Micro\Shopify\lib
*
* @property-read Metafield $Metafield
*
* @method Metafield Metafield(integer $id = null)
*/
class Collection extends AbstractShopify
{
protected $resourceKey = 'collection';
protected $childResource = [
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/22
* Time: 16:14
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class CustomCollection
* @package Meibuyu\Micro\Shopify\lib
*
* @property-read Metafield $Metafield
*
* @method Metafield Metafield(integer $id = null)
*/
class CustomCollection extends AbstractShopify
{
protected $resourceKey = 'custom_collection';
protected $childResource = [
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class Event
* @package Meibuyu\Micro\Shopify\lib
*/
class Event extends AbstractShopify
{
protected $resourceKey = 'event';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class Fulfillment
* @package Meibuyu\Micro\Shopify\lib
*
* @property-read Event $Event
*
* @method Event Event(integer $id = null)
*
* @method array update_tracking($info) Update Tracking
* @method array complete() Complete a fulfillment
* @method array open() Open a pending fulfillment
* @method array cancel() Cancel a fulfillment
*/
class Fulfillment extends AbstractShopify
{
protected $resourceKey = 'fulfillment';
protected $childResource = [
'FulfillmentEvent' => 'Event',
];
protected $customPostActions = [
'update_tracking',
'complete',
'open',
'cancel',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class FulfillmentEvent
* @package Meibuyu\Micro\Shopify\lib
*/
class FulfillmentEvent extends AbstractShopify
{
protected $resourceKey = 'event';
}
<?php
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class FulfillmentOrder
* @package Meibuyu\Micro\Shopify\lib
*
* @property-read Event $Event
*
* @method array cancel() Cancel a fulfillment order
* @method array close() Marks a fulfillment order as incomplete
* @method array move() Moves a fulfillment order to a new location
*/
class FulfillmentOrder extends AbstractShopify
{
protected $resourceKey = 'fulfillment_order';
protected $customPostActions = [
'cancel',
'close',
'move',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class FulfillmentService
* @package Meibuyu\Micro\Shopify\lib
*/
class FulfillmentService extends AbstractShopify
{
protected $resourceKey = 'fulfillment_service';
public $countEnabled = false;
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2021/01/08
* Time: 09:34:30
*/
namespace Meibuyu\Micro\Shopify\lib;
use Exception;
use Meibuyu\Micro\Shopify\tools\HttpRequestGraphQL;
/**
* Class GraphQL
* @package Meibuyu\Micro\Shopify\lib
*/
class GraphQL extends AbstractShopify
{
protected $resourceKey = 'graphql';
protected $pluralizeKey = 'graphql';
public function post($graphQL, $url = null, $wrapData = false, $variables = null)
{
if (!$url) $url = $this->generateUrl();
$response = HttpRequestGraphQL::post($url, $graphQL, $this->httpHeaders, $variables);
return $this->processResponse($response);
}
public function get($urlParams = array(), $url = null, $dataKey = null)
{
throw new Exception("GraphQL 只支持 POST 请求!");
}
public function put($id, $dataArray, $url = null, $wrapData = true)
{
throw new Exception("GraphQL 只支持 POST 请求!");
}
public function delete($id = null, $urlParams = [], $url = null)
{
throw new Exception("GraphQL 只支持 POST 请求!");
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/23
* Time: 8:58
*/
namespace Meibuyu\Micro\Shopify\lib;
class InventoryItem extends AbstractShopify
{
protected $resourceKey = 'inventory_item';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/23
* Time: 8:58
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class InventoryLevel
* @package Meibuyu\Micro\Shopify\lib
*
* @method array adjust($data) Adjust inventory level.
* @method array connect($data) Connect an inventory item to a location.
* @method array set($data) Sets an inventory level for a single inventory item within a location.
*/
class InventoryLevel extends AbstractShopify
{
protected $resourceKey = 'inventory_level';
protected $customPostActions = [
'adjust',
'connect',
'set',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/23
* Time: 8:58
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class Location
* @package Meibuyu\Micro\Shopify\lib
*/
class Location extends AbstractShopify
{
protected $resourceKey = 'location';
protected $childResource = [
'InventoryLevel',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/26
* Time: 15:50
*/
namespace Meibuyu\Micro\Shopify\lib;
class Metafield extends AbstractShopify
{
protected $resourceKey = 'metafield';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class Order
* @package Meibuyu\Micro\Shopify\lib
*
* @property-read Fulfillment $Fulfillment
* @property-read Event $Event
*
* @method Fulfillment Fulfillment(integer $id = null)
* @method FulfillmentOrder FulfillmentOrder()
* @method Event Event(integer $id = null)
*
* @method array close() Close an Order
* @method array open() Re-open a closed Order
* @method array cancel(array $data) Cancel an Order
*/
class Order extends AbstractShopify
{
protected $resourceKey = 'order';
protected $childResource = [
'Fulfillment',
'FulfillmentOrder',
'Event',
];
protected $customPostActions = [
'close',
'open',
'cancel',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class Product
* @package Meibuyu\Micro\Shopify\lib
*
* @property-read ProductImage $Image
* @property-read ProductVariant $Variant
* @property-read Metafield $Metafield
*
* @method ProductImage Image(integer $id = null)
* @method ProductVariant Variant(integer $id = null)
* @method Metafield Metafield(integer $id = null)
*/
class Product extends AbstractShopify
{
protected $resourceKey = 'product';
protected $childResource = [
'ProductImage' => 'Image',
'ProductVariant' => 'Variant',
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
class ProductImage extends AbstractShopify
{
protected $resourceKey = 'image';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**
* Class ProductVariant
* @package Meibuyu\Micro\Shopify\lib
*
* @property-read Metafield $Metafield
*
* @method Metafield Metafield(integer $id = null)
*/
class ProductVariant extends AbstractShopify
{
protected $resourceKey = 'variant';
protected $childResource = [
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/24
* Time: 16:50
*/
namespace Meibuyu\Micro\Shopify\lib;
/**\
* Class SmartCollection
* @package Meibuyu\Micro\Shopify\lib
*
* @property-read Metafield $Metafield
*
* @method Metafield Metafield(integer $id = null)
*/
class SmartCollection extends AbstractShopify
{
protected $resourceKey = 'smart_collection';
protected $childResource = [
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/18
* Time: 8:13
*/
namespace Meibuyu\Micro\Shopify\lib;
class Webhook extends AbstractShopify
{
protected $resourceKey = 'webhook';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/19
* Time: 9:06
*/
namespace Meibuyu\Micro\Shopify\tools;
use Exception;
/**
* Curl的json格式请求
* Class HttpRequestJson
* @package Meibuyu\Micro\Tools
*/
class CurlHttpRequestJson
{
protected function prepareRequest($headers, $data = [])
{
$data = json_encode($data);
if (!empty($data)) {
$headers['Content-type'] = 'application/json';
$headers['Content-Length'] = strlen($data);
}
return [$headers, $data];
}
/**
* @param $url
* @param array $headers
* @return array
* @throws Exception
* @author zero
*/
public function get($url, $headers = [])
{
return CurlRequest::get($url, $headers);
}
/**
* post请求
* @param $url
* @param $data
* @param array $headers
* @return array
* @throws Exception
* @author zero
*/
public function post($url, $data, $headers = [])
{
[$headers, $data] = self::prepareRequest($headers, $data);
return CurlRequest::post($url, $data, $headers);
}
/**
* put请求
* @param $url
* @param $data
* @param array $headers
* @return array
* @throws Exception
* @author zero
*/
public function put($url, $data, $headers = [])
{
[$headers, $data] = self::prepareRequest($headers, $data);
return CurlRequest::put($url, $data, $headers);
}
/**
* delete请求
* @param $url
* @param array $headers
* @return array
* @throws Exception
* @author zero
*/
public function delete($url, $headers = [])
{
return CurlRequest::delete($url, $headers);
}
}
<?php
namespace Meibuyu\Micro\Shopify\tools;
use Exception;
class CurlRequest
{
protected static function init($url, $httpHeaders = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100); // 设置超时限制防止死循环
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'PHPClassic/PHPShopify');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名
$headers = [];
foreach ($httpHeaders as $key => $value) {
$headers[] = "$key: $value";
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
return $ch;
}
/**
* @param $url
* @param array $httpHeaders
* @return array
* @throws Exception
* @author zero
*/
public static function get($url, $httpHeaders = [])
{
$ch = self::init($url, $httpHeaders);
return self::processRequest($ch);
}
/**
* @param $url
* @param $data
* @param array $httpHeaders
* @return array
* @throws Exception
* @author zero
*/
public static function post($url, $data, $httpHeaders = [])
{
$ch = self::init($url, $httpHeaders);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
return self::processRequest($ch);
}
/**
* @param $url
* @param $data
* @param array $httpHeaders
* @return array
* @throws Exception
* @author zero
*/
public static function put($url, $data, $httpHeaders = [])
{
$ch = self::init($url, $httpHeaders);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
return self::processRequest($ch);
}
/**
* @param $url
* @param array $httpHeaders
* @return array
* @throws Exception
* @author zero
*/
public static function delete($url, $httpHeaders = [])
{
$ch = self::init($url, $httpHeaders);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
return self::processRequest($ch);
}
/**
* @param $ch
* @return array
* @throws Exception
* @author zero
*/
protected static function processRequest($ch)
{
$output = curl_exec($ch);
$response = new CurlResponse($output);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// if ($httpCode == 429) {
// $limitHeader = explode('/', $response->getHeader('X-Shopify-Shop-Api-Call-Limit')[0], 2);
// if (isset($limitHeader[1]) && $limitHeader[0] < $limitHeader[1]) {
// throw new Exception($response->getBody());
// }
// }
if (curl_errno($ch)) {
throw new Exception(curl_errno($ch) . ' : ' . curl_error($ch));
}
curl_close($ch);
return [$httpCode, $response->getHeaders(), $response->getBody()];
}
}
<?php
namespace Meibuyu\Micro\Shopify\tools;
class CurlResponse
{
/** @var array */
private $headers = [];
/** @var string */
private $body;
public function __construct($response)
{
$this->parse($response);
}
/**
* @param string $response
*/
private function parse($response)
{
$response = explode("\r\n\r\n", $response);
if (count($response) > 1) {
// We want the last two parts
$response = array_slice($response, -2, 2);
list($headers, $body) = $response;
foreach (explode("\r\n", $headers) as $header) {
$pair = explode(': ', $header, 2);
if (isset($pair[1])) {
$headerKey = strtolower($pair[0]);
$this->headers[$headerKey][] = $pair[1];
}
}
} else {
$body = $response[0];
}
$this->body = $body;
}
/**
* @return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* @param string $key
*
* @return string
*/
public function getHeader($key)
{
return isset($this->headers[$key]) ? $this->headers[$key] : null;
}
/**
* @return string
*/
public function getBody()
{
return $this->body;
}
public function __toString()
{
$body = $this->getBody();
$body = $body ?: '';
return $body;
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Time: 2021/1/14 9:16
*/
namespace Meibuyu\Micro\Shopify\tools;
class GraphQL
{
public static function parseDeliveryProfileId($gid)
{
if ($gid && stripos($gid, 'gid://shopify/DeliveryProfile/') !== false) {
$gid = str_replace('gid://shopify/DeliveryProfile/', '', $gid);
}
return (int)$gid;
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Time: 2021/1/11 10:10
*/
namespace Meibuyu\Micro\Shopify\tools;
use Exception;
class HttpRequestGraphQL
{
/**
* @param array $headers
* @param array $data
* @param null $variables
* @return array
* @throws Exception
* @author zero
*/
protected static function prepareRequest($headers = [], $data = [], $variables = null)
{
if (is_string($data)) {
$postDataGraphQL = $data;
} else {
throw new Exception("Only GraphQL string is allowed!");
}
if (is_array($variables)) {
$postDataGraphQL = json_encode(['query' => $data, 'variables' => $variables]);
$headers['Content-type'] = 'application/json';
} else {
$headers['Content-type'] = 'application/graphql';
}
return [$headers, $postDataGraphQL];
}
/**
* @param $url
* @param $data
* @param array $headers
* @param null $variables
* @return array
* @throws Exception
* @author zero
*/
public static function post($url, $data, $headers = [], $variables = null)
{
[$headers, $postDataGraphQL] = self::prepareRequest($headers, $data, $variables);
return CurlRequest::post($url, $postDataGraphQL, $headers);
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/19
* Time: 9:06
*/
namespace Meibuyu\Micro\Shopify\tools;
use GuzzleHttp\HandlerStack;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\Guzzle\HandlerStackFactory;
use Psr\Http\Message\ResponseInterface;
/**
* json格式请求
* Class HttpRequestJson
* @package Meibuyu\Micro\Tools
*/
class HttpRequestJson
{
/**
* @var ClientFactory
*/
private $clientFactory;
/**
* @var HandlerStack
*/
private $stack;
public function __construct(ClientFactory $clientFactory)
{
$this->clientFactory = $clientFactory;
$factory = new HandlerStackFactory();
$this->stack = $factory->create();
}
/**
* get请求
* @param $url
* @param array $httpHeaders
* @return ResponseInterface
*/
public function get($url, $httpHeaders = [])
{
$client = $this->clientFactory->create(['timeout' => 60, 'handler' => $this->stack,]);
$res = $client->get($url, ['headers' => $httpHeaders]);
return $this->processResponse($res);
}
/**
* post请求
* @param $url
* @param $data
* @param array $httpHeaders
* @return ResponseInterface
*/
public function post($url, $data, $httpHeaders = [])
{
$client = $this->clientFactory->create(['timeout' => 60, 'handler' => $this->stack,]);
$res = $client->post($url, ['headers' => $httpHeaders, 'json' => $data]);
return $this->processResponse($res);
}
/**
* put请求
* @param $url
* @param $data
* @param array $httpHeaders
* @return ResponseInterface
*/
public function put($url, $data, $httpHeaders = [])
{
$client = $this->clientFactory->create(['timeout' => 60, 'handler' => $this->stack,]);
$res = $client->put($url, ['headers' => $httpHeaders, 'json' => $data]);
return $this->processResponse($res);
}
/**
* delete请求
* @param $url
* @param array $httpHeaders
* @return ResponseInterface
*/
public function delete($url, $httpHeaders = [])
{
$client = $this->clientFactory->create(['timeout' => 60, 'handler' => $this->stack,]);
$res = $client->delete($url, ['headers' => $httpHeaders]);
return $this->processResponse($res);
}
/**
* 处理响应
* @param ResponseInterface $response
* @return mixed
*/
public function processResponse($response)
{
$code = $response->getStatusCode();
$headers = $response->getHeaders();
$content = $response->getBody()->getContents();
return [$code, $headers, $content];
}
}
<?php
namespace Meibuyu\Micro\Tools;
use Psr\SimpleCache\CacheInterface;
/**
* Class Cache
* @package Meibuyu\Micro\Tools
* @method static get($key, $default = null)
* @method static set($key, $value, $ttl = null)
* @method static delete($key)
* @method static clear()
* @method static getMultiple($keys, $default = null)
* @method static setMultiple($values, $ttl = null)
* @method static deleteMultiple($keys)
* @method static has($key)
*/
class Cacher
{
/**
* @var CacheInterface
*/
protected static $driver;
/**
* @return CacheInterface
*/
public static function driver()
{
if (!self::$driver) {
self::$driver = container(CacheInterface::class);
}
return self::$driver;
}
public static function __callStatic($name, $arguments)
{
return static::driver()->{$name}(...$arguments);
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/17
* Time: 8:40
*/
namespace Meibuyu\Micro\Tools;
use Exception;
/**
* 图片工具类
* Class Imager
* @package Meibuyu\Micro\Tools
*/
class Imager
{
/**
* 图片转base64,暂不支持外部地址图片
* @param $path
* @param bool $noPrefix 不需要前缀
* @return string
* @throws Exception
*/
public static function img2Base64($path, $noPrefix = false)
{
$path = self::parsePath($path);
if (file_exists($path)) {
$fp = fopen($path, "r"); // 图片是否可读权限
if ($fp) {
$imgInfo = getimagesize($path); // 取得图片的大小,类型等
$content = fread($fp, filesize($path));
$content = chunk_split(base64_encode($content)); // base64编码
if ($noPrefix) {
$base64 = $content;
} else {
$base64 = 'data:' . $imgInfo['mime'] . ';base64,' . $content; // 合成图片的base64编码
}
fclose($fp);
return $base64;
} else {
throw new Exception('图片读取失败');
}
} else {
throw new Exception('图片不存在');
}
}
/**
* @param $path
* @return string
* @throws Exception
*/
public static function parsePath($path)
{
if (strstr($path, 'http')) {
$appDomain = config('app_domain');
if (strstr($path, $appDomain)) {
$path = str_replace($appDomain, '', $path);
} else {
throw new Exception('暂不支持外部地址图片');
}
}
$documentRoot = config('server.settings.document_root');
if (!strstr($path, $documentRoot)) {
$path = trim(trim($path), '/');
$path = $documentRoot . '/' . $path;
}
return $path;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment