初始化-安装依赖
This commit is contained in:
100
server/plugin/saiadmin/service/EmailService.php
Normal file
100
server/plugin/saiadmin/service/EmailService.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | saiadmin [ saiadmin快速开发框架 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: sai <1430792918@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace plugin\saiadmin\service;
|
||||
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use plugin\saiadmin\app\logic\system\SystemConfigLogic;
|
||||
use plugin\saiadmin\exception\ApiException;
|
||||
use plugin\saiadmin\utils\Arr;
|
||||
|
||||
/**
|
||||
* 邮件服务类
|
||||
*/
|
||||
class EmailService
|
||||
{
|
||||
/**
|
||||
* 读取配置
|
||||
* @return array
|
||||
*/
|
||||
public static function getConfig(): array
|
||||
{
|
||||
$logic = new SystemConfigLogic();
|
||||
$config = $logic->getGroup('email_config');
|
||||
if (!$config) {
|
||||
throw new ApiException('未设置邮件配置');
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Mailer
|
||||
* @return PHPMailer
|
||||
*/
|
||||
public static function getMailer(): PHPMailer
|
||||
{
|
||||
if (!class_exists(PHPMailer::class)) {
|
||||
throw new ApiException('请执行 composer require phpmailer/phpmailer 并重启');
|
||||
}
|
||||
$config = static::getConfig();
|
||||
$mailer = new PHPMailer();
|
||||
$mailer->SMTPDebug = intval(Arr::getConfigValue($config,'SMTPDebug'));
|
||||
$mailer->isSMTP();
|
||||
$mailer->Host = Arr::getConfigValue($config,'Host');
|
||||
$mailer->SMTPAuth = true;
|
||||
$mailer->CharSet = Arr::getConfigValue($config,'CharSet');
|
||||
$mailer->Username = Arr::getConfigValue($config,'Username');
|
||||
$mailer->Password = Arr::getConfigValue($config,'Password');
|
||||
$mailer->SMTPSecure = Arr::getConfigValue($config,'SMTPSecure');
|
||||
$mailer->Port = Arr::getConfigValue($config,'Port');
|
||||
return $mailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @param $subject
|
||||
* @param $content
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function send($from, $to, $subject, $content): string
|
||||
{
|
||||
$mailer = static::getMailer();
|
||||
call_user_func_array([$mailer, 'setFrom'], (array)$from);
|
||||
call_user_func_array([$mailer, 'addAddress'], (array)$to);
|
||||
$mailer->Subject = $subject;
|
||||
$mailer->isHTML(true);
|
||||
$mailer->Body = $content;
|
||||
$mailer->send();
|
||||
return $mailer->ErrorInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照模版发送
|
||||
* @param string|array $to
|
||||
* @param $subject
|
||||
* @param $content
|
||||
* @param array $templateData
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function sendByTemplate($to, $subject, $content, array $templateData = []): string
|
||||
{
|
||||
if ($templateData) {
|
||||
$search = [];
|
||||
foreach ($templateData as $key => $value) {
|
||||
$search[] = '{' . $key . '}';
|
||||
}
|
||||
$content = str_replace($search, array_values($templateData), $content);
|
||||
}
|
||||
$config = static::getConfig();
|
||||
return static::send([Arr::getConfigValue($config,'From'), Arr::getConfigValue($config,'FromName')], $to, $subject, $content);
|
||||
}
|
||||
|
||||
}
|
||||
136
server/plugin/saiadmin/service/OpenSpoutWriter.php
Normal file
136
server/plugin/saiadmin/service/OpenSpoutWriter.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
namespace plugin\saiadmin\service;
|
||||
|
||||
use OpenSpout\Common\Entity\Style\Border;
|
||||
use OpenSpout\Common\Entity\Style\BorderPart;
|
||||
use OpenSpout\Writer\XLSX\Writer;
|
||||
use OpenSpout\Common\Entity\Row;
|
||||
use OpenSpout\Common\Entity\Style\Style;
|
||||
|
||||
/**
|
||||
* Excel写入类
|
||||
* OpenSpout
|
||||
*/
|
||||
class OpenSpoutWriter
|
||||
{
|
||||
/**
|
||||
* 操作实例
|
||||
* @var Writer
|
||||
*/
|
||||
protected $instance;
|
||||
|
||||
/**
|
||||
* 文件路径
|
||||
* @var string
|
||||
*/
|
||||
protected $filepath;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param string $fileName 文件名称
|
||||
*/
|
||||
public function __construct(string $fileName)
|
||||
{
|
||||
$this->filepath = $this->getFileName($fileName);
|
||||
$this->instance = new Writer();
|
||||
$this->instance->openToFile($this->filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整的文件路径
|
||||
* @param string $fileName
|
||||
* @return string
|
||||
*/
|
||||
public function getFileName(string $fileName): string
|
||||
{
|
||||
$path = config('plugin.saiadmin.saithink.export_path',base_path() . '/plugin/saiadmin/public/export/');
|
||||
@mkdir($path, 0777, true);
|
||||
return $path . $fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置表格宽度
|
||||
* @param array $width 宽度数组
|
||||
* @return void
|
||||
*/
|
||||
public function setWidth(array $width = [])
|
||||
{
|
||||
if (empty($width)) {
|
||||
return;
|
||||
}
|
||||
$sheet = $this->instance->getCurrentSheet();
|
||||
foreach ($width as $key => $value) {
|
||||
$sheet->setColumnWidth($value, $key + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置表头
|
||||
* @param array $header 表头数组
|
||||
* @param $style
|
||||
* @return void
|
||||
*/
|
||||
public function setHeader(array $header = [], $style = null): void
|
||||
{
|
||||
if (empty($style)) {
|
||||
$border = new Border(
|
||||
new BorderPart("top", "black", "thin"),
|
||||
new BorderPart("right", "black", "thin"),
|
||||
new BorderPart("bottom", "black", "thin"),
|
||||
new BorderPart("left", "black", "thin"),
|
||||
);
|
||||
$style = new Style();
|
||||
$style->setFontBold();
|
||||
$style->setCellAlignment("center");
|
||||
$style->setBorder($border);
|
||||
}
|
||||
$rowFromValues = Row::fromValues($header, $style);
|
||||
$this->instance->addRow($rowFromValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据
|
||||
* @param array $data 数据数组
|
||||
* @param $style
|
||||
* @return void
|
||||
*/
|
||||
public function setData(array $data = [], $style = null, array $filter = []): void
|
||||
{
|
||||
if (empty($style)) {
|
||||
$border = new Border(
|
||||
new BorderPart("top", "black", "thin"),
|
||||
new BorderPart("right", "black", "thin"),
|
||||
new BorderPart("bottom", "black", "thin"),
|
||||
new BorderPart("left", "black", "thin"),
|
||||
);
|
||||
$style = new Style();
|
||||
$style->setCellAlignment("center");
|
||||
$style->setBorder($border);
|
||||
}
|
||||
foreach($data as $row) {
|
||||
if (!empty($filter)) {
|
||||
foreach ($filter as $key => $value) {
|
||||
foreach ($value as $item) {
|
||||
if ($item['value'] == $row[$key]) {
|
||||
$row[$key] = $item['label'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$rowFromValues = Row::fromValues($row, $style);
|
||||
$this->instance->addRow($rowFromValues);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件
|
||||
* @return string
|
||||
*/
|
||||
public function returnFile(): string
|
||||
{
|
||||
$this->instance->close();
|
||||
return $this->filepath;
|
||||
}
|
||||
|
||||
}
|
||||
51
server/plugin/saiadmin/service/Permission.php
Normal file
51
server/plugin/saiadmin/service/Permission.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\saiadmin\service;
|
||||
|
||||
/**
|
||||
* 权限注解
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
|
||||
class Permission
|
||||
{
|
||||
/**
|
||||
* 权限标题/名称
|
||||
*/
|
||||
public string $title;
|
||||
|
||||
/**
|
||||
* 权限标识(唯一,格式如:module:controller:action)
|
||||
*/
|
||||
public ?string $slug = null;
|
||||
|
||||
/**
|
||||
* 构造函数 #[Permission(title:'标题', slug:'标识')]
|
||||
* @param string|null $title
|
||||
* @param string|null $slug
|
||||
*/
|
||||
public function __construct(
|
||||
?string $title = null,
|
||||
?string $slug = null,
|
||||
)
|
||||
{
|
||||
$this->title = $title ?? '';
|
||||
$this->slug = $slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取权限标题
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取权限标识
|
||||
*/
|
||||
public function getSlug(): ?string
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
}
|
||||
137
server/plugin/saiadmin/service/storage/ChunkUploadService.php
Normal file
137
server/plugin/saiadmin/service/storage/ChunkUploadService.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
namespace plugin\saiadmin\service\storage;
|
||||
|
||||
use plugin\saiadmin\app\logic\system\SystemConfigLogic;
|
||||
use plugin\saiadmin\app\model\system\SystemAttachment;
|
||||
use plugin\saiadmin\exception\ApiException;
|
||||
use plugin\saiadmin\utils\Arr;
|
||||
|
||||
/**
|
||||
* 切片上传服务
|
||||
*/
|
||||
class ChunkUploadService
|
||||
{
|
||||
/**
|
||||
* 基础配置
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
protected $path;
|
||||
|
||||
protected $folder = "chunk";
|
||||
|
||||
/**
|
||||
* 初始化切片上传服务
|
||||
*/
|
||||
public function __construct($folder = "chunk")
|
||||
{
|
||||
$logic = new SystemConfigLogic();
|
||||
$this->folder = $folder;
|
||||
$this->config = $logic->getGroup('upload_config');
|
||||
$this->path = $this->checkPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并创建上传路径
|
||||
* @return string
|
||||
*/
|
||||
public function checkPath(): string
|
||||
{
|
||||
$root = Arr::getConfigValue($this->config, 'local_root');
|
||||
$path = base_path() . DIRECTORY_SEPARATOR . $root . $this->folder . DIRECTORY_SEPARATOR;
|
||||
if (!is_dir($path)) {
|
||||
mkdir($path, 0777, true);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查切片文件上传状态
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function checkChunk($data): array
|
||||
{
|
||||
$allow_file = Arr::getConfigValue($this->config, 'upload_allow_file');
|
||||
if (!in_array($data['ext'], explode(',', $allow_file))) {
|
||||
throw new ApiException('不支持该格式的文件上传');
|
||||
}
|
||||
// 检查已经上传的分片文件
|
||||
for ($i = 0; $i < $data['total']; ++$i) {
|
||||
$chunkFile = $this->path . "{$data['hash']}_{$data['total']}_{$i}.chunk";
|
||||
if (!file_exists($chunkFile)) {
|
||||
if ($i == 0) {
|
||||
return $this->uploadChunk($data);
|
||||
} else {
|
||||
return ['chunk' => $i, 'status' => 'resume'];
|
||||
}
|
||||
}
|
||||
}
|
||||
// 分片文件已经全部上传
|
||||
return ['chunk' => $i, 'status' => 'success'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传切片
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function uploadChunk($data): array
|
||||
{
|
||||
$allow_file = Arr::getConfigValue($this->config, 'upload_allow_file');
|
||||
if (!in_array($data['ext'], explode(',', $allow_file))) {
|
||||
throw new ApiException('不支持该格式的文件上传');
|
||||
}
|
||||
$request = request();
|
||||
if (!$request) {
|
||||
throw new ApiException('切片上传服务必须在 HTTP 请求环境下调用');
|
||||
}
|
||||
$uploadFile = current($request->file());
|
||||
$chunkName = $this->path . "{$data['hash']}_{$data['total']}_{$data['index']}.chunk";
|
||||
$uploadFile->move($chunkName);
|
||||
if (($data['index'] + 1) == $data['total']) {
|
||||
return $this->mergeChunk($data);
|
||||
}
|
||||
return ['chunk' => $data['index'], 'status' => 'success'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并切片文件
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function mergeChunk($data): array
|
||||
{
|
||||
$filePath = $this->path . $data['hash'] . '.' . $data['ext'];
|
||||
$fileHandle = fopen($filePath, 'w');
|
||||
for ($i = 0; $i < $data['total']; ++$i) {
|
||||
$chunkFile = $this->path . "{$data['hash']}_{$data['total']}_{$i}.chunk";
|
||||
if (!file_exists($chunkFile)) {
|
||||
throw new ApiException('切片文件查找失败,请重新上传');
|
||||
}
|
||||
fwrite($fileHandle, file_get_contents($chunkFile));
|
||||
unlink($chunkFile);
|
||||
}
|
||||
|
||||
$domain = Arr::getConfigValue($this->config, 'local_domain');
|
||||
$uri = Arr::getConfigValue($this->config, 'local_uri');
|
||||
$baseUrl = $domain . $uri . $this->folder . '/';
|
||||
|
||||
$save_path = Arr::getConfigValue($this->config, 'local_root') . $this->folder . '/';
|
||||
$object_name = $data['hash'] . '.' . $data['ext'];
|
||||
|
||||
$info['storage_mode'] = 1;
|
||||
$info['category_id'] = 1;
|
||||
$info['origin_name'] = $data['name'];
|
||||
$info['object_name'] = $object_name;
|
||||
$info['hash'] = $data['hash'];
|
||||
$info['mime_type'] = $data['type'];
|
||||
$info['storage_path'] = $save_path . $object_name;
|
||||
$info['suffix'] = $data['ext'];
|
||||
$info['size_byte'] = $data['size'];
|
||||
$info['size_info'] = formatBytes($data['size']);
|
||||
$info['url'] = $baseUrl . $object_name;
|
||||
SystemAttachment::create($info);
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
136
server/plugin/saiadmin/service/storage/UploadService.php
Normal file
136
server/plugin/saiadmin/service/storage/UploadService.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | saiadmin [ saiadmin快速开发框架 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: sai <1430792918@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace plugin\saiadmin\service\storage;
|
||||
|
||||
use plugin\saiadmin\app\logic\system\SystemConfigLogic;
|
||||
use plugin\saiadmin\exception\ApiException;
|
||||
use plugin\saiadmin\utils\Arr;
|
||||
|
||||
/**
|
||||
* 文件上传服务
|
||||
* @method static array uploadFile(array $config = []) 上传文件
|
||||
* @method static array uploadBase64(string $base64, string $extension = 'png') 上传Base64文件
|
||||
* @method static array uploadServerFile(string $file_path) 上传服务端文件
|
||||
*/
|
||||
class UploadService
|
||||
{
|
||||
/**
|
||||
* @desc 存储磁盘
|
||||
* @param int $type
|
||||
* @param string $upload
|
||||
* @param bool $_is_file_upload
|
||||
* @return mixed
|
||||
*/
|
||||
public static function disk(int $type = 1, string $upload = 'image', bool $_is_file_upload = true)
|
||||
{
|
||||
$logic = new SystemConfigLogic();
|
||||
$uploadConfig = $logic->getGroup('upload_config');
|
||||
|
||||
$file = current(request()->file());
|
||||
$ext = $file->getUploadExtension() ?: null;
|
||||
$file_size = $file->getSize();
|
||||
if ($file_size > Arr::getConfigValue($uploadConfig, 'upload_size')) {
|
||||
throw new ApiException('文件大小超过限制');
|
||||
}
|
||||
$allow_file = Arr::getConfigValue($uploadConfig, 'upload_allow_file');
|
||||
$allow_image = Arr::getConfigValue($uploadConfig, 'upload_allow_image');
|
||||
if ($upload == 'image') {
|
||||
if (!in_array($ext, explode(',', $allow_image))) {
|
||||
throw new ApiException('不支持该格式的文件上传');
|
||||
}
|
||||
} else {
|
||||
if (!in_array($ext, explode(',', $allow_file))) {
|
||||
throw new ApiException('不支持该格式的文件上传');
|
||||
}
|
||||
}
|
||||
switch ($type) {
|
||||
case 1:
|
||||
// 本地
|
||||
$config = [
|
||||
'adapter' => \Tinywan\Storage\Adapter\LocalAdapter::class,
|
||||
'root' => Arr::getConfigValue($uploadConfig, 'local_root'),
|
||||
'dirname' => function () {
|
||||
return date('Ymd');
|
||||
},
|
||||
'domain' => Arr::getConfigValue($uploadConfig, 'local_domain'),
|
||||
'uri' => Arr::getConfigValue($uploadConfig, 'local_uri'),
|
||||
'algo' => 'sha1',
|
||||
];
|
||||
break;
|
||||
case 2:
|
||||
// 阿里云
|
||||
$config = [
|
||||
'adapter' => \Tinywan\Storage\Adapter\OssAdapter::class,
|
||||
'accessKeyId' => Arr::getConfigValue($uploadConfig, 'oss_accessKeyId'),
|
||||
'accessKeySecret' => Arr::getConfigValue($uploadConfig, 'oss_accessKeySecret'),
|
||||
'bucket' => Arr::getConfigValue($uploadConfig, 'oss_bucket'),
|
||||
'dirname' => Arr::getConfigValue($uploadConfig, 'oss_dirname'),
|
||||
'domain' => Arr::getConfigValue($uploadConfig, 'oss_domain'),
|
||||
'endpoint' => Arr::getConfigValue($uploadConfig, 'oss_endpoint'),
|
||||
'algo' => 'sha1',
|
||||
];
|
||||
break;
|
||||
case 3:
|
||||
// 七牛
|
||||
$config = [
|
||||
'adapter' => \Tinywan\Storage\Adapter\QiniuAdapter::class,
|
||||
'accessKey' => Arr::getConfigValue($uploadConfig, 'qiniu_accessKey'),
|
||||
'secretKey' => Arr::getConfigValue($uploadConfig, 'qiniu_secretKey'),
|
||||
'bucket' => Arr::getConfigValue($uploadConfig, 'qiniu_bucket'),
|
||||
'dirname' => Arr::getConfigValue($uploadConfig, 'qiniu_dirname'),
|
||||
'domain' => Arr::getConfigValue($uploadConfig, 'qiniu_domain'),
|
||||
];
|
||||
break;
|
||||
case 4:
|
||||
// 腾讯云
|
||||
$config = [
|
||||
'adapter' => \Tinywan\Storage\Adapter\CosAdapter::class,
|
||||
'secretId' => Arr::getConfigValue($uploadConfig, 'cos_secretId'),
|
||||
'secretKey' => Arr::getConfigValue($uploadConfig, 'cos_secretKey'),
|
||||
'bucket' => Arr::getConfigValue($uploadConfig, 'cos_bucket'),
|
||||
'dirname' => Arr::getConfigValue($uploadConfig, 'cos_dirname'),
|
||||
'domain' => Arr::getConfigValue($uploadConfig, 'cos_domain'),
|
||||
'region' => Arr::getConfigValue($uploadConfig, 'cos_region'),
|
||||
];
|
||||
break;
|
||||
case 5:
|
||||
// s3 亚马逊
|
||||
$config = [
|
||||
'adapter' => \Tinywan\Storage\Adapter\S3Adapter::class,
|
||||
'key' => Arr::getConfigValue($uploadConfig, 's3_key'),
|
||||
'secret' => Arr::getConfigValue($uploadConfig, 's3_secret'),
|
||||
'bucket' => Arr::getConfigValue($uploadConfig, 's3_bucket'),
|
||||
'dirname' => Arr::getConfigValue($uploadConfig, 's3_dirname'),
|
||||
'domain' => Arr::getConfigValue($uploadConfig, 's3_domain'),
|
||||
'region' => Arr::getConfigValue($uploadConfig, 's3_region'),
|
||||
'version' => Arr::getConfigValue($uploadConfig, 's3_version'),
|
||||
// 'use_path_style_endpoint' => Arr::getConfigValue($uploadConfig,'s3_use_path_style_endpoint'),
|
||||
'use_path_style_endpoint' => filter_var(Arr::getConfigValue($uploadConfig, 's3_use_path_style_endpoint'), FILTER_VALIDATE_BOOLEAN),
|
||||
'endpoint' => Arr::getConfigValue($uploadConfig, 's3_endpoint'),
|
||||
'acl' => Arr::getConfigValue($uploadConfig, 's3_acl'),
|
||||
];
|
||||
break;
|
||||
default:
|
||||
throw new ApiException('该上传模式不存在');
|
||||
}
|
||||
return new $config['adapter'](array_merge(
|
||||
$config,
|
||||
['_is_file_upload' => $_is_file_upload]
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return mixed
|
||||
* @author Tinywan(ShaoBo Wan)
|
||||
*/
|
||||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
return static::disk()->{$name}(...$arguments);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user