mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2026-02-18 06:33:49 +00:00
core
This commit is contained in:
parent
02c1436e28
commit
39a8e9ede2
40
niucloud/core/addon/AddonLoader.php
Normal file
40
niucloud/core/addon/AddonLoader.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
use core\loader\Loader;
|
||||
|
||||
/**
|
||||
* @see \core\addon\AddonLoader
|
||||
* @mixin \core\addon\BaseAddon
|
||||
* @method array|null load(array $data)
|
||||
*/
|
||||
class AddonLoader extends Loader
|
||||
{
|
||||
|
||||
/**
|
||||
* 空间名
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = '\\core\\addon\\';
|
||||
|
||||
protected $config_name = 'addon';
|
||||
/**
|
||||
* 默认驱动
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getDefault()
|
||||
{
|
||||
return "Event";
|
||||
}
|
||||
|
||||
}
|
||||
140
niucloud/core/addon/BaseAddon.php
Normal file
140
niucloud/core/addon/BaseAddon.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
use core\loader\DriverConfig;
|
||||
use core\loader\Storage;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* Class BaseAddon
|
||||
* @package
|
||||
*/
|
||||
abstract class BaseAddon extends Storage
|
||||
{
|
||||
//插件整体缓存标识
|
||||
public static $cache_tag_name = 'addon_cash';
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地插件目录(已安装)
|
||||
*/
|
||||
protected function getLocalAddons()
|
||||
{
|
||||
$cache_name = "local_install_addons";
|
||||
return Cache::tag(self::$cache_tag_name)->remember($cache_name, function () {
|
||||
$list = Db::name("addon")->column("key");
|
||||
return $list;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件目录
|
||||
* @param string $addon
|
||||
* @return string
|
||||
*/
|
||||
protected function getAddonPath(string $addon)
|
||||
{
|
||||
return root_path() . 'addon' . DIRECTORY_SEPARATOR. $addon. DIRECTORY_SEPARATOR;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统整体app目录
|
||||
* @return string
|
||||
*/
|
||||
protected function getAppPath()
|
||||
{
|
||||
return root_path(). "app". DIRECTORY_SEPARATOR;
|
||||
}
|
||||
/**
|
||||
* 获取插件对应app目录
|
||||
* @param string $addon
|
||||
* @return string
|
||||
*/
|
||||
protected function getAddonAppPath(string $addon)
|
||||
{
|
||||
return $this->getAddonPath($addon). "app". DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取系统enum path
|
||||
*/
|
||||
protected function getEnumPath()
|
||||
{
|
||||
return root_path(). "app". DIRECTORY_SEPARATOR. "enum". DIRECTORY_SEPARATOR;;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取插件对应的enum目录
|
||||
* @param string $addon
|
||||
*/
|
||||
protected function getAddonEnumPath(string $addon)
|
||||
{
|
||||
return $this->getAddonPath($addon). "app". DIRECTORY_SEPARATOR. "enum". DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取插件对应的config目录
|
||||
* @param string $addon
|
||||
*/
|
||||
protected function getAddonConfigPath(string $addon)
|
||||
{
|
||||
return $this->getAddonPath($addon). "config". DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载文件数据
|
||||
* @param $files
|
||||
* @return array
|
||||
*/
|
||||
protected function loadFiles($files)
|
||||
{
|
||||
$default_sort = 100000;
|
||||
$files_data = [];
|
||||
if (!empty($files)) {
|
||||
foreach ($files as $file) {
|
||||
$config = include $file;
|
||||
if (!empty($config)) {
|
||||
if (isset($config[ 'file_sort' ])) {
|
||||
$sort = $config[ 'file_sort' ];
|
||||
unset($config[ 'file_sort' ]);
|
||||
$sort = $sort * 10;
|
||||
while (array_key_exists($sort, $files_data)) {
|
||||
$sort++;
|
||||
}
|
||||
$files_data[ $sort ] = $config;
|
||||
} else {
|
||||
$files_data[ $default_sort ] = $config;
|
||||
$default_sort++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ksort($files_data);
|
||||
return $files_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function load(array $data);
|
||||
}
|
||||
36
niucloud/core/addon/Event.php
Normal file
36
niucloud/core/addon/Event.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
|
||||
class Event extends BaseAddon
|
||||
{
|
||||
/**
|
||||
* 加载事件
|
||||
* @param array $system_event 系统事件
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function load(array $data)
|
||||
{
|
||||
$addons = $this->getLocalAddons();
|
||||
$event_files = [];
|
||||
|
||||
foreach ($addons as $k => $v)
|
||||
{
|
||||
$event_path = $this->getAddonAppPath($v)."event.php";
|
||||
if(is_file($event_path))
|
||||
{
|
||||
$event_files[] = $event_path;
|
||||
}
|
||||
}
|
||||
$files_data = $this->loadFiles($event_files);
|
||||
|
||||
$files_data[1] = $data;
|
||||
|
||||
$events = [];
|
||||
foreach ($files_data as $file_data) {
|
||||
$events = empty($events) ? $file_data : array_merge2($events, $file_data);
|
||||
}
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
52
niucloud/core/addon/Lang.php
Normal file
52
niucloud/core/addon/Lang.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
|
||||
class Lang extends BaseAddon
|
||||
{
|
||||
/**
|
||||
* 加载事件
|
||||
* @param array $data //传入语言类型
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function load(array $data)
|
||||
{
|
||||
$addons = $this->getLocalAddons();
|
||||
$system_lang_path = $this->getAppPath()."lang". DIRECTORY_SEPARATOR. $data['lang_type']. DIRECTORY_SEPARATOR;
|
||||
$lang_files = [
|
||||
$system_lang_path. "api.php",
|
||||
$system_lang_path. "enum.php",
|
||||
$system_lang_path. "validate.php",
|
||||
];
|
||||
|
||||
|
||||
foreach ($addons as $k => $v)
|
||||
{
|
||||
$lang_path = $this->getAddonAppPath($v)."lang". DIRECTORY_SEPARATOR. $data['lang_type']. DIRECTORY_SEPARATOR;
|
||||
|
||||
$api_path = $lang_path."api.php";
|
||||
$enum_path = $lang_path."enum.php";
|
||||
$validate_path = $lang_path."validate.php";
|
||||
if(is_file($api_path))
|
||||
{
|
||||
$lang_files[] = $api_path;
|
||||
|
||||
}
|
||||
if(is_file($enum_path))
|
||||
{
|
||||
$lang_files[] = $enum_path;
|
||||
}
|
||||
if(is_file($validate_path))
|
||||
{
|
||||
$lang_files[] = $validate_path;
|
||||
}
|
||||
}
|
||||
$files_data = $this->loadFiles($lang_files);
|
||||
$lang = [];
|
||||
foreach ($files_data as $file_data) {
|
||||
$lang = empty($lang) ? $file_data : array_merge($lang, $file_data);
|
||||
}
|
||||
return $lang;
|
||||
}
|
||||
}
|
||||
22
niucloud/core/addon/Menu.php
Normal file
22
niucloud/core/addon/Menu.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
|
||||
class Menu extends BaseAddon
|
||||
{
|
||||
/**
|
||||
* 加载菜单
|
||||
* @param array $data //传入插件,应用类型
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function load(array $data):array
|
||||
{
|
||||
$menu_path = $this->getAddonEnumPath($data['addon'])."menu".DIRECTORY_SEPARATOR. $data['app_type']. ".php";
|
||||
if(is_file($menu_path))
|
||||
{
|
||||
return include $menu_path;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
39
niucloud/core/addon/Notice.php
Normal file
39
niucloud/core/addon/Notice.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
|
||||
class Notice extends BaseAddon
|
||||
{
|
||||
/**
|
||||
* 系统uniapp页面链接
|
||||
* @param array $data //系统
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function load(array $data)
|
||||
{
|
||||
$template_files = [];
|
||||
$system_path = $this->getEnumPath(). "notice". DIRECTORY_SEPARATOR. $data['type']. ".php";
|
||||
if(is_file($system_path))
|
||||
{
|
||||
$template_files[] = $system_path;
|
||||
}
|
||||
$addons = $this->getLocalAddons();
|
||||
foreach ($addons as $k => $v)
|
||||
{
|
||||
$template_path = $this->getAddonEnumPath($v). "notice". DIRECTORY_SEPARATOR. $data['type']. ".php";
|
||||
if(is_file($template_path))
|
||||
{
|
||||
$template_files[] = $template_path;
|
||||
}
|
||||
}
|
||||
$template_files_data = $this->loadFiles($template_files);
|
||||
|
||||
$template_data_array = [];
|
||||
foreach ($template_files_data as $file_data)
|
||||
{
|
||||
$template_data_array = empty($template_data_array) ? $file_data : array_merge($template_data_array, $file_data);
|
||||
}
|
||||
return $template_data_array;
|
||||
}
|
||||
}
|
||||
27
niucloud/core/addon/Route.php
Normal file
27
niucloud/core/addon/Route.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
|
||||
class Route extends BaseAddon
|
||||
{
|
||||
/**
|
||||
* 加载路由
|
||||
* @param array $data 传入路由端口
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function load(array $data)
|
||||
{
|
||||
$addons = $this->getLocalAddons();
|
||||
|
||||
foreach ($addons as $k => $v)
|
||||
{
|
||||
$route_path = $this->getAddonAppPath($v). DIRECTORY_SEPARATOR. $data['app_type']. DIRECTORY_SEPARATOR. "route.php";
|
||||
if(is_file($route_path))
|
||||
{
|
||||
include $route_path;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
33
niucloud/core/addon/UniappComponent.php
Normal file
33
niucloud/core/addon/UniappComponent.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
|
||||
class UniappComponent extends BaseAddon
|
||||
{
|
||||
/**
|
||||
* 系统uniapp组件配置
|
||||
* @param array $data //系统
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function load(array $data)
|
||||
{
|
||||
$addons = $this->getLocalAddons();
|
||||
$components_files = [];
|
||||
foreach ($addons as $k => $v)
|
||||
{
|
||||
$components_path = $this->getAddonEnumPath($v). "diy". DIRECTORY_SEPARATOR. "components.php";
|
||||
if(is_file($components_path))
|
||||
{
|
||||
$components_files[] = $components_path;
|
||||
}
|
||||
}
|
||||
$components_files_data = $this->loadFiles($components_files);
|
||||
$components = $data;
|
||||
foreach ($components_files_data as $file_data)
|
||||
{
|
||||
$components = empty($components) ? $file_data : array_merge2($components, $file_data);
|
||||
}
|
||||
return $components;
|
||||
}
|
||||
}
|
||||
37
niucloud/core/addon/UniappLink.php
Normal file
37
niucloud/core/addon/UniappLink.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
|
||||
class UniappLink extends BaseAddon
|
||||
{
|
||||
/**
|
||||
* 系统uniapp页面链接
|
||||
* @param array $data //系统
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function load(array $data)
|
||||
{
|
||||
$addons = $this->getLocalAddons();
|
||||
$link_files = [];
|
||||
foreach ($addons as $k => $v)
|
||||
{
|
||||
$link_path = $this->getAddonEnumPath($v). "diy". DIRECTORY_SEPARATOR. "links.php";
|
||||
if(is_file($link_path))
|
||||
{
|
||||
$link_files[] = $link_path;
|
||||
}
|
||||
}
|
||||
$link_files_data = $this->loadFiles($link_files);
|
||||
$links = $data;
|
||||
foreach ($link_files_data as $file_data)
|
||||
{
|
||||
if(empty($links))
|
||||
{
|
||||
$links = $file_data;
|
||||
}else
|
||||
$links = array_merge($links, $file_data);
|
||||
}
|
||||
return $links;
|
||||
}
|
||||
}
|
||||
37
niucloud/core/addon/UniappPages.php
Normal file
37
niucloud/core/addon/UniappPages.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace core\addon;
|
||||
|
||||
|
||||
class UniappPages extends BaseAddon
|
||||
{
|
||||
/**
|
||||
* 系统uniapp页面链接
|
||||
* @param array $data //系统
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function load(array $data)
|
||||
{
|
||||
$addons = $this->getLocalAddons();
|
||||
$page_files = [];
|
||||
foreach ($addons as $k => $v)
|
||||
{
|
||||
$page_path = $this->getAddonEnumPath($v). "diy". DIRECTORY_SEPARATOR. "pages.php";
|
||||
if(is_file($page_path))
|
||||
{
|
||||
$page_files[] = $page_path;
|
||||
}
|
||||
}
|
||||
$page_files_data = $this->loadFiles($page_files);
|
||||
$pages = $data;
|
||||
foreach ($page_files_data as $file_data)
|
||||
{
|
||||
if(empty($pages))
|
||||
{
|
||||
$pages = $file_data;
|
||||
}else
|
||||
$pages = array_merge($pages, $file_data);
|
||||
}
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
29
niucloud/core/base/BaseAdminController.php
Normal file
29
niucloud/core/base/BaseAdminController.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace core\base;
|
||||
|
||||
/**
|
||||
* 管理端控制器基类
|
||||
* Class BaseAdminController
|
||||
* @package core\base
|
||||
*/
|
||||
class BaseAdminController extends BaseController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
35
niucloud/core/base/BaseAdminService.php
Normal file
35
niucloud/core/base/BaseAdminService.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\base;
|
||||
|
||||
/**
|
||||
* 后台基础服务层
|
||||
* Class BaseAdminService
|
||||
* @package app\service\admin
|
||||
*/
|
||||
class BaseAdminService extends BaseService
|
||||
{
|
||||
|
||||
protected $site_id;
|
||||
protected $username;
|
||||
protected $uid;
|
||||
|
||||
protected $app_type;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->app_type = $this->request->appType();
|
||||
$this->site_id = $this->request->siteId();
|
||||
$this->username = $this->request->username();
|
||||
$this->uid = $this->request->uid();
|
||||
}
|
||||
}
|
||||
29
niucloud/core/base/BaseApiController.php
Normal file
29
niucloud/core/base/BaseApiController.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace core\base;
|
||||
|
||||
/**
|
||||
* api基础控制器
|
||||
* Class BaseApiController
|
||||
* @package app\api\controller
|
||||
*/
|
||||
class BaseApiController extends BaseController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
33
niucloud/core/base/BaseApiService.php
Normal file
33
niucloud/core/base/BaseApiService.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\base;
|
||||
|
||||
/**
|
||||
* 手机前端基础服务层
|
||||
* Class BaseApiService
|
||||
* @package app\service\api
|
||||
*/
|
||||
class BaseApiService extends BaseService
|
||||
{
|
||||
|
||||
protected $site_id;
|
||||
protected $member_id;
|
||||
protected $channel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->site_id = $this->request->siteId();
|
||||
$this->member_id = $this->request->memberId();
|
||||
$this->channel = $this->request->getChannel();
|
||||
}
|
||||
}
|
||||
97
niucloud/core/base/BaseController.php
Normal file
97
niucloud/core/base/BaseController.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace core\base;
|
||||
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\exception\ValidateException;
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* 控制器基础类
|
||||
*/
|
||||
abstract class BaseController
|
||||
{
|
||||
/**
|
||||
* Request实例
|
||||
* @var Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* 应用实例
|
||||
* @var App
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* 是否批量验证
|
||||
* @var bool
|
||||
*/
|
||||
protected $batchValidate = false;
|
||||
|
||||
/**
|
||||
* 控制器中间件
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware = [];
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* @access public
|
||||
* @param App $app 应用对象
|
||||
*/
|
||||
public function __construct(App $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->request = $this->app->request;
|
||||
// 控制器初始化
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
// 初始化
|
||||
protected function initialize()
|
||||
{}
|
||||
|
||||
/**
|
||||
* 验证数据
|
||||
* @access protected
|
||||
* @param array $data 数据
|
||||
* @param string|array $validate 验证器名或者验证规则数组
|
||||
* @param array $message 提示信息
|
||||
* @param bool $batch 是否批量验证
|
||||
* @return array|string|true
|
||||
* @throws ValidateException
|
||||
*/
|
||||
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
|
||||
{
|
||||
if (is_array($validate)) {
|
||||
$v = new Validate();
|
||||
$v->rule($validate);
|
||||
} else {
|
||||
if (strpos($validate, '.')) {
|
||||
// 支持场景
|
||||
[$validate, $scene] = explode('.', $validate);
|
||||
}
|
||||
$class = str_contains($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
|
||||
$v = new $class();
|
||||
if (!empty($scene)) {
|
||||
$v->scene($scene);
|
||||
}
|
||||
}
|
||||
|
||||
$v->message($message);
|
||||
|
||||
// 是否批量验证
|
||||
if ($batch || $this->batchValidate) {
|
||||
$v->batch(true);
|
||||
}
|
||||
|
||||
return $v->failException(true)->check($data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
27
niucloud/core/base/BaseCoreService.php
Normal file
27
niucloud/core/base/BaseCoreService.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\base;
|
||||
|
||||
/**
|
||||
* 系统基础服务层
|
||||
* Class BaseCoreService
|
||||
* @package app\service\core
|
||||
*/
|
||||
class BaseCoreService extends BaseService
|
||||
{
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
81
niucloud/core/base/BaseJob.php
Normal file
81
niucloud/core/base/BaseJob.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\base;
|
||||
|
||||
use app\model\system\Cron;
|
||||
use core\job\Dispatch;
|
||||
use think\queue\Job;
|
||||
|
||||
/**
|
||||
* 队列异步调用定时任务
|
||||
*/
|
||||
abstract class BaseJob extends Dispatch
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
$this->fire(...$arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行消息队列
|
||||
* @param Job $job
|
||||
* @param $data
|
||||
*/
|
||||
public function fire(Job $job, $data): void
|
||||
{
|
||||
try {
|
||||
$action = $data['do'] ?? 'doJob';//任务名
|
||||
$infoData = $data['data'] ?? [];//数据
|
||||
$errorCount = $data['errorCount'] ?? 0;//执行任务错误的最大重试次数
|
||||
$this->runJob($action, $job, $infoData, $errorCount);
|
||||
} catch (\Throwable $e) {
|
||||
$job->delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 执行队列
|
||||
* @param string $action
|
||||
* @param Job $job
|
||||
* @param array $infoData
|
||||
* @param int $errorCount
|
||||
*/
|
||||
protected function runJob(string $action, Job $job, array $infoData, int $errorCount = 3)
|
||||
{
|
||||
|
||||
$action = method_exists($this, $action) ? $action : 'handle';
|
||||
if (!method_exists($this, $action)) {
|
||||
$job->delete();
|
||||
}
|
||||
|
||||
if ($this->{$action}(...$infoData)) {
|
||||
//删除任务
|
||||
$job->delete();
|
||||
} else {
|
||||
if ($job->attempts() >= $errorCount && $errorCount) {
|
||||
//删除任务
|
||||
$job->delete();
|
||||
} else {
|
||||
//再次放入队列
|
||||
$job->release();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
niucloud/core/base/BaseModel.php
Normal file
25
niucloud/core/base/BaseModel.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\base;
|
||||
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 基础模型
|
||||
* Class BaseModel
|
||||
* @package app\model
|
||||
*/
|
||||
class BaseModel extends Model
|
||||
{
|
||||
|
||||
}
|
||||
133
niucloud/core/base/BaseService.php
Normal file
133
niucloud/core/base/BaseService.php
Normal file
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\base;
|
||||
|
||||
|
||||
use app\validate\sys\Page;
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 基础服务层
|
||||
* Class BaseService
|
||||
* @package app\service
|
||||
*/
|
||||
abstract class BaseService
|
||||
{
|
||||
/**
|
||||
* Model 实例
|
||||
* @var BaseModel
|
||||
*/
|
||||
protected $model;
|
||||
protected $request;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->request = request();
|
||||
}
|
||||
/**
|
||||
* 分页列表参数(页码和每页多少条)
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPageParam(){
|
||||
|
||||
$page = request()->params([
|
||||
['page', 1],
|
||||
['limit', 15]
|
||||
]);
|
||||
validate(Page::class)
|
||||
->check($page);
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页列表
|
||||
* @param array $where
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @param null $with //数组可以是数组 function($query) use ($with){$query->with($with);}
|
||||
* @param null $each //闭包匿名函数 function($item, $key){$item['nickname'] = 'think';return $item;}
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPageList(Model $model, array $where, string $field = '*', string $order = '', array $append = [], $with = null, $each = null){
|
||||
$page_params = $this->getPageParam();
|
||||
$page = $page_params['page'];
|
||||
$limit = $page_params['limit'];
|
||||
|
||||
$list = $model->where($where)->when($append, function($query) use ($append){
|
||||
$query->append($append);
|
||||
})->when($with, function ($query) use($with){
|
||||
$query->with($with);
|
||||
})->field($field)->order($order)->paginate([
|
||||
'list_rows' => $limit,
|
||||
'page' => $page,
|
||||
]);
|
||||
if(!empty($each)){
|
||||
$list = $list->each($each);
|
||||
}
|
||||
return $list->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页数据查询,传入model(查询后结果)
|
||||
* @param $model BaseModel
|
||||
* @param $each
|
||||
* @return mixed
|
||||
*/
|
||||
public function pageQuery($model, $each = null)
|
||||
{
|
||||
$page_params = $this->getPageParam();
|
||||
$page = $page_params['page'];
|
||||
$limit = $page_params['limit'];
|
||||
$list = $model->paginate([
|
||||
'list_rows' => $limit,
|
||||
'page' => $page,
|
||||
]);
|
||||
if(!empty($each)){
|
||||
$list = $list->each($each);
|
||||
}
|
||||
return $list->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页视图列表查询
|
||||
* @param Model $model
|
||||
* @param array $where
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param array $append
|
||||
* @param null $with
|
||||
* @param null $each
|
||||
* @return array
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function getPageViewList(Model $model, array $where, string $field = '*', string $order = '', array $append = [], $with = null, $each = null){
|
||||
$page_params = $this->getPageParam();
|
||||
$page = $page_params['page'];
|
||||
$limit = $page_params['limit'];
|
||||
|
||||
$list = $model->where($where)->when($append, function($query) use ($append){
|
||||
$query->append($append);
|
||||
})->when($with, function ($query) use($with){
|
||||
$query->withJoin($with);
|
||||
})->field($field)->order($order)->paginate([
|
||||
'list_rows' => $limit,
|
||||
'page' => $page,
|
||||
]);
|
||||
if(!empty($each)){
|
||||
$list = $list->each($each);
|
||||
}
|
||||
return $list->toArray();
|
||||
}
|
||||
|
||||
}
|
||||
17
niucloud/core/exception/AddonException.php
Normal file
17
niucloud/core/exception/AddonException.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 插件错误异常处理类
|
||||
*/
|
||||
class AddonException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
17
niucloud/core/exception/AdminException.php
Normal file
17
niucloud/core/exception/AdminException.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 平台管理端错误异常处理类
|
||||
*/
|
||||
class AdminException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
17
niucloud/core/exception/ApiException.php
Normal file
17
niucloud/core/exception/ApiException.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 前端错误异常处理类
|
||||
*/
|
||||
class ApiException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
18
niucloud/core/exception/AuthException.php
Normal file
18
niucloud/core/exception/AuthException.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 授权错误异常处理类
|
||||
*/
|
||||
class AuthException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
17
niucloud/core/exception/CaptchaException.php
Normal file
17
niucloud/core/exception/CaptchaException.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 平台管理端错误异常处理类
|
||||
*/
|
||||
class CaptchaException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
17
niucloud/core/exception/CommonException.php
Normal file
17
niucloud/core/exception/CommonException.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 平台管理端错误异常处理类
|
||||
*/
|
||||
class CommonException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
17
niucloud/core/exception/NoticeException.php
Normal file
17
niucloud/core/exception/NoticeException.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 消息错误异常处理类
|
||||
*/
|
||||
class NoticeException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
17
niucloud/core/exception/PayException.php
Normal file
17
niucloud/core/exception/PayException.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 支付错误异常处理类
|
||||
*/
|
||||
class PayException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
17
niucloud/core/exception/UploadFileException.php
Normal file
17
niucloud/core/exception/UploadFileException.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 附件管理错误异常处理类
|
||||
*/
|
||||
class UploadFileException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
18
niucloud/core/exception/WechatException.php
Normal file
18
niucloud/core/exception/WechatException.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace core\exception;
|
||||
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 微信错误异常处理类
|
||||
*/
|
||||
class WechatException extends RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
63
niucloud/core/job/Dispatch.php
Normal file
63
niucloud/core/job/Dispatch.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\job;
|
||||
|
||||
use core\util\Queue;
|
||||
|
||||
/**
|
||||
* 快捷加入消息队列
|
||||
*/
|
||||
class Dispatch
|
||||
{
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
protected static function queueName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 加入队列
|
||||
* @param $action
|
||||
* @param array $data
|
||||
* @param string|null $queueName
|
||||
* @return mixed
|
||||
*/
|
||||
public static function invoke($action, array $data = [], int $secs = 0, string $queue_name = null, bool $is_open = true)
|
||||
{
|
||||
$class = get_called_class();//调用主调类
|
||||
if ($is_open) {
|
||||
$queue = Queue::instance()->job($class)->secs($secs);
|
||||
if (is_array($action)) {
|
||||
$queue->data(...$action);
|
||||
} else if (is_string($action)) {
|
||||
$queue->do($action)->data(...$data);
|
||||
}
|
||||
if ($queue_name) {
|
||||
$queue->setQueueName($queue_name);
|
||||
} else if (static::queueName()) {
|
||||
$queue->setQueueName(static::queueName());
|
||||
}
|
||||
return $queue->push();
|
||||
} else {
|
||||
$class_name = '\\' . $class;
|
||||
$res = new $class_name();
|
||||
if (is_array($action)) {
|
||||
return $res->doJob(...$action);
|
||||
} else {
|
||||
return $res->$action(...$data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
100
niucloud/core/loader/Loader.php
Normal file
100
niucloud/core/loader/Loader.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace core\loader;
|
||||
|
||||
use think\Facade;
|
||||
use think\helper\Str;
|
||||
|
||||
abstract class Loader extends Facade
|
||||
{
|
||||
protected $config_name = null;//配置文件名
|
||||
|
||||
protected $name = null;
|
||||
protected $namespace = null;
|
||||
|
||||
protected $class = null;
|
||||
protected $config = null;
|
||||
protected $config_file = null;
|
||||
/**
|
||||
* @param string $type
|
||||
* @return object|\think\DbManager
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($name = '', array $config = []){
|
||||
if(is_array($name)){
|
||||
$config = $config;
|
||||
$name = null;
|
||||
}
|
||||
if($name){
|
||||
$this->name = $name;
|
||||
}
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认驱动
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function getDefault();
|
||||
/**
|
||||
* 获取实例
|
||||
* @param string $type
|
||||
* @return object|\think\DbManager
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function create(string $type){
|
||||
$class = $this->getClass($type);
|
||||
return self::createFacade($class, [
|
||||
$this->name,
|
||||
$this->config,
|
||||
$this->config_file
|
||||
], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类
|
||||
* @param string $type
|
||||
* @return mixed|string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getClass(string $type){
|
||||
$class = config($this->config_name.'.drivers.'.$type.'.driver');
|
||||
if (class_exists($class)) {
|
||||
return $class;
|
||||
}else{
|
||||
if ($this->namespace || str_contains($type, '\\')) {
|
||||
$class = str_contains($type, '\\') ? $type : $this->namespace . ucfirst(strtolower($type));
|
||||
if (class_exists($class)) {
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new \Exception("Driver [$type] not supported.");
|
||||
}
|
||||
|
||||
|
||||
public function getLoader(){
|
||||
|
||||
if(empty($this->class)){
|
||||
$this->name = $this->name ?: $this->getDefault();
|
||||
if (!$this->name) {
|
||||
throw new \Exception(sprintf(
|
||||
'could not find driver [%s].', static::class
|
||||
));
|
||||
}
|
||||
$this->class = $this->create($this->name);
|
||||
}
|
||||
return $this->class;
|
||||
}
|
||||
/**
|
||||
* 动态调用
|
||||
* @param $method
|
||||
* @param $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
return $this->getLoader()->{$method}(...$arguments);
|
||||
}
|
||||
|
||||
}
|
||||
67
niucloud/core/loader/Storage.php
Normal file
67
niucloud/core/loader/Storage.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
namespace core\loader;
|
||||
|
||||
|
||||
abstract class Storage
|
||||
{
|
||||
|
||||
/**
|
||||
* 驱动名称
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* 驱动配置文件名
|
||||
* @var string
|
||||
*/
|
||||
protected $config_file;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
* @var string
|
||||
*/
|
||||
protected $error;
|
||||
|
||||
/**
|
||||
* BaseStorage constructor.
|
||||
* @param string $name 驱动名
|
||||
* @param string $config_file 驱动配置名
|
||||
* @param array $config 其他配置
|
||||
*/
|
||||
public function __construct(string $name, array $config = [], string $config_file = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->config_file = $config_file;
|
||||
$this->initialize($config);
|
||||
}
|
||||
/**
|
||||
* 设置错误信息
|
||||
* @param string|null $error
|
||||
* @return bool
|
||||
*/
|
||||
protected function setError(?string $error = null)
|
||||
{
|
||||
$this->error = $error ?: '未知错误';
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取错误信息
|
||||
* @return string
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
$error = $this->error;
|
||||
$this->error = null;
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function initialize(array $config);
|
||||
|
||||
}
|
||||
299
niucloud/core/pay/Alipay.php
Normal file
299
niucloud/core/pay/Alipay.php
Normal file
@ -0,0 +1,299 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2023-02-17
|
||||
* Time: 15:58
|
||||
*/
|
||||
|
||||
namespace core\pay;
|
||||
|
||||
use app\enum\pay\OnlinePayEnum;
|
||||
use core\exception\PayException;
|
||||
use Psr\Http\Message\MessageInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Yansongda\Pay\Exception\ContainerException;
|
||||
use Yansongda\Pay\Exception\InvalidParamsException;
|
||||
use Yansongda\Pay\Exception\ServiceNotFoundException;
|
||||
use Yansongda\Pay\Pay;
|
||||
use Yansongda\Supports\Collection;
|
||||
|
||||
|
||||
/**
|
||||
* 文件管理驱动类
|
||||
* Class FileDriver
|
||||
* @package core\file
|
||||
*/
|
||||
class Alipay extends BasePay
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
$config['app_public_cert_path'] = url_to_path($config['app_public_cert_path'] ?? '');
|
||||
$config['alipay_public_cert_path'] = url_to_path($config['alipay_public_cert_path'] ?? '');
|
||||
$config['alipay_root_cert_path'] = url_to_path($config['alipay_root_cert_path'] ?? '');
|
||||
$this->config = $this->payConfig($config, 'alipay');
|
||||
Pay::config($this->config);
|
||||
}
|
||||
|
||||
public function mp(array $params){
|
||||
|
||||
}
|
||||
/**
|
||||
* 网页支付
|
||||
* @param array $params
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function web(array $params)
|
||||
{
|
||||
return $this->returnUrl(Pay::alipay()->web([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'total_amount' => $params['money'],
|
||||
'subject' => $params['boby'],
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机网页支付
|
||||
* @param array $params
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function wap(array $params)
|
||||
{
|
||||
return $this->returnUrl(Pay::alipay()->wap([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'total_amount' => $params['money'],
|
||||
'subject' => $params['boby'],
|
||||
'quit_url' => $params['quit_url'] ?? '',//用户付款中途退出返回商户网站的地址, 一般是商品详情页或购物车页
|
||||
'_method' => 'get',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* app支付
|
||||
* @param $params
|
||||
* @return mixed|ResponseInterface
|
||||
*/
|
||||
public function app(array $params)
|
||||
{
|
||||
return $this->returnUrl(Pay::alipay()->app([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'total_amount' => $params['money'],
|
||||
'subject' => $params['boby'],//用户付款中途退出返回商户网站的地址, 一般是商品详情页或购物车页
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序支付
|
||||
* @param $params
|
||||
* @return mixed|ResponseInterface
|
||||
*/
|
||||
public function mini(array $params)
|
||||
{
|
||||
return Pay::alipay()->mini([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'total_amount' => $params['money'],
|
||||
'subject' => $params['boby'],
|
||||
'buyer_id' => $params['buyer_id'],//买家支付宝用户ID 注:交易的买家与卖家不能相同。
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 付款码支付
|
||||
* @param $params
|
||||
* @return mixed|Collection
|
||||
*/
|
||||
public function pos(array $params)
|
||||
{
|
||||
return Pay::alipay()->pos([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'auth_code' => $params['auth_code'],//付授权码。 当面付场景传买家的付款码(25~30开头的长度为16~24位的数字,实际字符串长度以开发者获取的付款码长度为准)或者刷脸标识串(fp开头的35位字符串)。
|
||||
'total_amount' => $params['money'],
|
||||
'subject' => $params['boby'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码支付
|
||||
* @param $params
|
||||
* @return mixed|Collection
|
||||
*/
|
||||
public function scan(array $params)
|
||||
{
|
||||
return Pay::alipay()->scan([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'total_amount' => $params['money'],
|
||||
'subject' => $params['boby'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账
|
||||
* @param $params
|
||||
* @return mixed|Collection
|
||||
*/
|
||||
public function transfer(array $params)
|
||||
{
|
||||
|
||||
$result = $this->returnFormat(Pay::alipay()->transfer([
|
||||
'out_biz_no' => $params['transfer_no'],
|
||||
'trans_amount' => $params['money'],
|
||||
'product_code' => $params['product_code'] ?: 'TRANS_ACCOUNT_NO_PWD',//业务产品码,单笔无密转账到支付宝账户固定为 : TRANS_ACCOUNT_NO_PWD; 收发现金红包固定为 : STD_RED_PACKET;
|
||||
'biz_scene' => $params['scene'] ?: 'DIRECT_TRANSFER',//描述特定的业务场景,可传的参数如下:DIRECT_TRANSFER:单笔无密转账到支付宝,B2C现金红包;PERSONAL_COLLECTION:C2C现金红包-领红包
|
||||
'payee_info' => [//收款方信息
|
||||
'identity' => $params['to_no'],//参与方的唯一标识
|
||||
'identity_type' => $params['to_type'] ?: 'ALIPAY_LOGON_ID',//参与方的标识类型,目前支持如下类型:1、ALIPAY_USER_ID 支付宝的会员ID2、ALIPAY_LOGON_ID:支付宝登录号,支持邮箱和手机号格式3、ALIPAY_OPEN_ID:支付宝openid
|
||||
'name' => $params['to_name'],//参与方真实姓名,如果非空,将校验收款支付宝账号姓名一致性。当identity_type=ALIPAY_LOGON_ID时,本字段必填。
|
||||
],
|
||||
]));
|
||||
if(!empty($result['msg']) && $result['msg'] != 'Success'){
|
||||
throw new PayException($result['sub_msg']);
|
||||
|
||||
}else{
|
||||
if($result['status'] == 'SUCCESS'){
|
||||
$result = array(
|
||||
'batch_id' => $result['pay_fund_order_id']
|
||||
);
|
||||
}else if($result['status'] == 'FAIL' && !empty($result['fail_reason'])){
|
||||
throw new PayException($result['fail_reason']);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付关闭
|
||||
* @param $out_trade_no
|
||||
* @return void
|
||||
*/
|
||||
public function close(string|int $out_trade_no){
|
||||
$result = $this->returnFormat(Pay::alipay()->close([
|
||||
'out_trade_no' => $out_trade_no,
|
||||
]));
|
||||
//todo 支付宝关闭异步回调
|
||||
if(!empty($result['msg']) && $result['msg'] == 'Success'){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款
|
||||
* @param $out_trade_no
|
||||
* @param $money
|
||||
* @return array|MessageInterface|Collection|null
|
||||
* @throws ContainerException
|
||||
* @throws InvalidParamsException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
public function refund(array $params){
|
||||
$out_trade_no = $params['out_trade_no'];
|
||||
$money = $params['money'];
|
||||
// $total = $params['total'];
|
||||
// $refund_no = $params['refund_no'];
|
||||
$result = Pay::alipay()->refund([
|
||||
'out_trade_no' => $out_trade_no,
|
||||
'refund_amount' => $money,
|
||||
]);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 支部异步回调
|
||||
* @param $out_trade_no
|
||||
* @return void
|
||||
*/
|
||||
public function notify(Callable $callback){
|
||||
try{
|
||||
$result = Pay::alipay()->callback();
|
||||
//通过返回的值
|
||||
if(!empty($result)){//成功
|
||||
//todo 这儿需要具体设计
|
||||
$temp_data = array(
|
||||
'mchid' => $result['seller_id'],
|
||||
'trade_no' => $result['trade_no'],
|
||||
'result' => $result
|
||||
);
|
||||
$callback_result = $callback($result['out_trade_no'], $temp_data);
|
||||
if(is_bool($callback_result) && $callback_result){
|
||||
return Pay::alipay()->success();
|
||||
}
|
||||
}
|
||||
return $this->fail();
|
||||
} catch (\Throwable $e) {
|
||||
return $this->fail();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询普通支付订单
|
||||
* @param $out_trade_no
|
||||
* @return void
|
||||
*/
|
||||
public function getOrder(array $params = []){
|
||||
$out_trade_no = $params['out_trade_no'];
|
||||
$order = [
|
||||
'out_trade_no' => $out_trade_no,
|
||||
];
|
||||
$result = $this->returnFormat(Pay::alipay()->find($order));
|
||||
if(!empty($result['msg']) && $result['msg'] == 'Success'){
|
||||
return [
|
||||
'status' => OnlinePayEnum::getAliPayStatus($result['trade_status'])
|
||||
];
|
||||
}else{
|
||||
if(!empty($result['sub_code']) && $result['sub_code'] == 'ACQ.ACQ.SYSTEM_ERROR'){
|
||||
throw new PayException($result['msg']);
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退款单据
|
||||
* @param $out_trade_no
|
||||
* @param $refund_no
|
||||
* @return void
|
||||
*/
|
||||
public function getRefund(string $out_trade_no, ?string $refund_no){
|
||||
$order = [
|
||||
'out_trade_no' => $out_trade_no,
|
||||
'out_request_no' => $refund_no,
|
||||
'_type' => 'refund',
|
||||
];
|
||||
|
||||
$result = $this->returnFormat(Pay::alipay()->find($order));
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取转账订单
|
||||
* @param $transfer_no
|
||||
* @return void
|
||||
*/
|
||||
public function getTransfer(string $transfer_no){
|
||||
$order = [
|
||||
'out_biz_no' => $transfer_no,
|
||||
'_type' => 'transfer'
|
||||
];
|
||||
$result = $this->returnFormat(Pay::alipay()->find($order));
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function fail(){
|
||||
return 'fail';
|
||||
}
|
||||
|
||||
public function returnUrl($params){
|
||||
return ['url' => $params->getHeader('Location')[0]];
|
||||
}
|
||||
}
|
||||
169
niucloud/core/pay/BasePay.php
Normal file
169
niucloud/core/pay/BasePay.php
Normal file
@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2023-02-17
|
||||
* Time: 15:58
|
||||
*/
|
||||
|
||||
namespace core\pay;
|
||||
|
||||
use core\loader\Storage;
|
||||
|
||||
/**
|
||||
* 文件管理驱动类
|
||||
* Class BasePay
|
||||
*/
|
||||
abstract class BasePay extends Storage
|
||||
{
|
||||
protected $config;//配置
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 网页支付
|
||||
* @param $save_dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function web(array $params);
|
||||
|
||||
/**
|
||||
* 手机网站支付
|
||||
* @param $dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function wap(array $params);
|
||||
|
||||
/**
|
||||
* app支付
|
||||
* @param $dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function app(array $params);
|
||||
|
||||
/**
|
||||
* 小程序支付
|
||||
* @param $dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function mini(array $params);
|
||||
/**
|
||||
* 付款码支付
|
||||
* @param $dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function pos(array $params);
|
||||
/**
|
||||
* 扫码支付
|
||||
* @param $dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function scan(array $params);
|
||||
/**
|
||||
* 转账
|
||||
* @param $dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function transfer(array $params);
|
||||
/**
|
||||
* 公众号支付
|
||||
* @param $dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function mp(array $params);
|
||||
|
||||
/**
|
||||
* 支付关闭
|
||||
* @param string $out_trade_no
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function close(string $out_trade_no);
|
||||
|
||||
/**
|
||||
* 退款
|
||||
* @param array $params
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function refund(array $params);
|
||||
|
||||
/**
|
||||
* 支付通知
|
||||
* @param callable $callback
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function notify(Callable $callback);
|
||||
|
||||
/**
|
||||
* 查询支付订单
|
||||
* @param array $params
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function getOrder(array $params);
|
||||
|
||||
/**
|
||||
* 查询退款订单
|
||||
* @param string|null $out_trade_no
|
||||
* @param string|null $refund_no
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function getRefund(string $out_trade_no, ?string $refund_no);
|
||||
|
||||
/**
|
||||
* 查询转账订单
|
||||
* @param string $transfer_no
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function getTransfer(string $transfer_no);
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @param string $type
|
||||
* @return mixed
|
||||
*/
|
||||
protected function payConfig(array $config, string $type){
|
||||
return array_merge(
|
||||
[
|
||||
'logger' => [
|
||||
'enable' => true,
|
||||
'file' => runtime_path() . 'paylog'.DIRECTORY_SEPARATOR.date('Ym').DIRECTORY_SEPARATOR.date('d').'.log',
|
||||
'level' => env('app_debug') ? 'debug' : 'info', // 建议生产环境等级调整为 info,开发环境为 debug
|
||||
'type' => 'single', // optional, 可选 daily.
|
||||
'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天
|
||||
],
|
||||
'http' => [ // optional
|
||||
'timeout' => 5.0,
|
||||
]
|
||||
],
|
||||
[
|
||||
$type => [
|
||||
'default' => $config
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
public function returnFormat($param){
|
||||
if($param instanceof \Psr\Http\Message\MessageInterface){
|
||||
return $param->getBody()->getContents();
|
||||
}else if($param instanceof \Yansongda\Supports\Collection){
|
||||
return $param->all();
|
||||
}else{
|
||||
return $param;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
41
niucloud/core/pay/PayLoader.php
Normal file
41
niucloud/core/pay/PayLoader.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\pay;
|
||||
|
||||
use core\loader\Loader;
|
||||
|
||||
/**
|
||||
* @see \core\pay\PayLoader
|
||||
* @package think\facade
|
||||
* @mixin \core\pay\Wechatpay
|
||||
* @method string|null upload(string $dir) 附件上传
|
||||
* @method array fetch(string $url, ?string $key) 抓取远程附件
|
||||
* @method mixed delete(string $file_name) 附件删除
|
||||
*/
|
||||
class PayLoader extends Loader
|
||||
{
|
||||
/**
|
||||
* 空间名
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = '\\core\\pay\\';
|
||||
|
||||
protected $config_name = 'pay';
|
||||
/**
|
||||
* 默认驱动
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getDefault()
|
||||
{
|
||||
return config('pay.default');
|
||||
}
|
||||
}
|
||||
374
niucloud/core/pay/Wechatpay.php
Normal file
374
niucloud/core/pay/Wechatpay.php
Normal file
@ -0,0 +1,374 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2023-02-17
|
||||
* Time: 15:58
|
||||
*/
|
||||
|
||||
namespace core\pay;
|
||||
|
||||
use app\enum\pay\OnlinePayEnum;
|
||||
use core\exception\PayException;
|
||||
use EasyWeChat\Factory;
|
||||
use Psr\Http\Message\MessageInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Yansongda\Pay\Exception\ContainerException;
|
||||
use Yansongda\Pay\Exception\InvalidParamsException;
|
||||
use Yansongda\Pay\Exception\ServiceNotFoundException;
|
||||
use Yansongda\Pay\Pay;
|
||||
use Yansongda\Pay\Plugin\Wechat\Fund\Transfer\QueryOutBatchNoPlugin;
|
||||
use Yansongda\Supports\Collection;
|
||||
|
||||
|
||||
/**
|
||||
* 微信支付管理驱动类 todo 注意:暂时不考虑合单类业务
|
||||
* Class FileDriver
|
||||
* @package core\file
|
||||
*/
|
||||
class Wechatpay extends BasePay
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
$this->config = $config;
|
||||
$config['mch_secret_cert'] = url_to_path($config['mch_secret_cert'] ?? '');
|
||||
$config['mch_public_cert_path'] = url_to_path($config['mch_public_cert_path'] ?? '');
|
||||
Pay::config($this->payConfig($config, 'wechat'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 公众号支付
|
||||
* @param array $params
|
||||
* @return mixed|Collection
|
||||
*/
|
||||
public function mp(array $params){
|
||||
return $this->returnFormat(Pay::wechat()->mp([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'description' => $params['boby'],
|
||||
'amount' => [
|
||||
'total' => $params['money'],
|
||||
],
|
||||
'payer' => [
|
||||
'openid' => $params['openid'],
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 手机网页支付
|
||||
* @param $params
|
||||
* @return mixed
|
||||
*/
|
||||
public function wap(array $params)
|
||||
{
|
||||
$order = [
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'description' => $params['boby'],
|
||||
'amount' => [
|
||||
'total' => $params['money'],
|
||||
],
|
||||
'scene_info' => [
|
||||
'payer_client_ip' => request()->ip(),
|
||||
'h5_info' => [
|
||||
'type' => 'Wap',
|
||||
]
|
||||
],
|
||||
];
|
||||
//这儿有些特殊, 默认情况下,H5 支付所使用的 appid 是微信公众号的 appid,即配置文件中的 mp_app_id 参数,如果想使用关联的小程序的 appid,则只需要在调用参数中增加 ['_type' => 'mini'] 即可
|
||||
if(!empty($order['type'])){
|
||||
$order['_type'] = 'mini'; // 注意这一行
|
||||
}
|
||||
return $this->returnFormat(Pay::wechat()->wap($order));
|
||||
}
|
||||
|
||||
public function web(array $params){
|
||||
|
||||
}
|
||||
/**
|
||||
* app支付
|
||||
* @param $params
|
||||
* @return mixed|ResponseInterface
|
||||
*/
|
||||
public function app(array $params)
|
||||
{
|
||||
return $this->returnFormat(Pay::wechat()->app([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'description' => $params['boby'],
|
||||
'amount' => [
|
||||
'total' => $params['money'],
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序支付
|
||||
* @param $params
|
||||
* @return mixed|ResponseInterface
|
||||
*/
|
||||
public function mini(array $params)
|
||||
{
|
||||
return $this->returnFormat(Pay::wechat()->mini([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'description' => $params['boby'],
|
||||
'amount' => [
|
||||
'total' => $params['money'],
|
||||
'currency' => 'CNY',//一般是人民币
|
||||
],
|
||||
'payer' => [
|
||||
'openid' => $params['openid'],
|
||||
]
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 付款码支付
|
||||
* @param $params
|
||||
* @return mixed|Collection
|
||||
*/
|
||||
public function pos(array $params)
|
||||
{
|
||||
//todo 需要自定义通过plugin来侧载开发
|
||||
$app = Factory::payment([
|
||||
'app_id' => $this->config['appid'], //应用id
|
||||
'mch_id' => $this->config["mch_id"] ?? '', //商户号
|
||||
'key' => $this->config["pay_v2_signkey"] ?? '', // API 密钥 todo 注意: 是v2密钥 是v2密钥 是v2密钥
|
||||
'response_type' => 'array',
|
||||
'log' => [
|
||||
'level' => 'debug',
|
||||
'permission' => 0777,
|
||||
'file' => 'runtime/log/wechat/easywechat.logs',
|
||||
],
|
||||
'sandbox' => false, // 设置为 false 或注释则关闭沙箱模式
|
||||
]);
|
||||
$data = [
|
||||
'body' => $params['boby'],
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'total_fee' => $params['money'],
|
||||
'auth_code' => $params["auth_code"],//传入的付款码
|
||||
];
|
||||
$result = $app->base->pay($data);//没有注释路由,调用没有问题
|
||||
return $this->returnFormat($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码支付
|
||||
* @param $params
|
||||
* @return mixed|Collection
|
||||
*/
|
||||
public function scan(array $params)
|
||||
{
|
||||
return $this->returnFormat(Pay::wechat()->scan([
|
||||
'out_trade_no' => $params['out_trade_no'],
|
||||
'description' => $params['boby'],
|
||||
'amount' => [
|
||||
'total' => $params['money'],
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账(微信的转账是很多笔的)
|
||||
* @param $params
|
||||
* @return mixed|Collection
|
||||
*/
|
||||
public function transfer(array $params)
|
||||
{
|
||||
//这儿的批次信息可能是这儿生成的,但依然需要记录
|
||||
$order = [
|
||||
'out_batch_no' => time().'',//
|
||||
'batch_name' => $params['remark'],
|
||||
'batch_remark' => $params['remark'],
|
||||
];
|
||||
$transfer_list = $params['transfer_list'];
|
||||
//单笔转账
|
||||
if(empty($transfer_list)){
|
||||
$transfer_list = array(
|
||||
[
|
||||
'transfer_no' => $params['transfer_no'].'1',
|
||||
'money' => (int)$params['money'],
|
||||
'remark' => $params['remark'],
|
||||
'openid' => $params['to_no']
|
||||
]
|
||||
);
|
||||
}
|
||||
$total_amount = 0;
|
||||
$total_num = 0;
|
||||
|
||||
foreach($transfer_list as $v){
|
||||
$item_transfer = [
|
||||
'out_detail_no' => time().'1',
|
||||
'transfer_amount' => (int)$v['money'],
|
||||
'transfer_remark' => $v['remark'],
|
||||
'openid' => $v['openid'],
|
||||
];
|
||||
$total_amount += (int)$v['money'];
|
||||
$total_num++;
|
||||
if(!empty($v['user_name'])){
|
||||
$item_transfer['user_name'] = $v['user_name'];// 明文传参即可,sdk 会自动加密
|
||||
}
|
||||
$order['transfer_detail_list'][] = $item_transfer;
|
||||
}
|
||||
$order['total_amount'] = (int)$total_amount;
|
||||
$order['total_num'] = (int)$total_num;
|
||||
$result = $this->returnFormat(Pay::wechat()->transfer($order));
|
||||
|
||||
if(!empty($result['code'])){
|
||||
// if($result['code'] == 'PARAM_ERROR'){
|
||||
// throw new PayException();
|
||||
// }else if($result['code'] == 'INVALID_REQUEST'){
|
||||
// throw new PayException();
|
||||
// }
|
||||
if($result['code'] == 'INVALID_REQUEST'){
|
||||
throw new PayException(700010);
|
||||
}
|
||||
throw new PayException($result['message']);
|
||||
}
|
||||
return ['batch_id' => $result['batch_id'], 'out_batch_no' => $result['out_batch_no']];
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付关闭
|
||||
* @param $out_trade_no
|
||||
* @return void
|
||||
*/
|
||||
public function close(string|int $out_trade_no){
|
||||
$result = Pay::wechat()->close([
|
||||
'out_trade_no' => $out_trade_no,
|
||||
]);
|
||||
return $this->returnFormat($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款
|
||||
* @param $out_trade_no
|
||||
* @param $money
|
||||
* @return array|MessageInterface|Collection|null
|
||||
* @throws ContainerException
|
||||
* @throws InvalidParamsException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
public function refund(array $params){
|
||||
$out_trade_no = $params['out_trade_no'];
|
||||
$money = $params['money'];
|
||||
$total = $params['total'];
|
||||
$refund_no = $params['refund_no'];
|
||||
$result = Pay::wechat()->refund([
|
||||
'out_trade_no' => $out_trade_no,
|
||||
'out_refund_no' => $refund_no,
|
||||
'amount' => [
|
||||
'refund' => $money,
|
||||
'total' => $total,
|
||||
'currency' => 'CNY',
|
||||
],
|
||||
]);
|
||||
return $this->returnFormat($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 异步回调
|
||||
* @param $out_trade_no
|
||||
* @return void
|
||||
*/
|
||||
public function notify(Callable $callback){
|
||||
try{
|
||||
$result = $this->returnFormat(Pay::wechat()->callback());
|
||||
if($result['event_type'] == 'TRANSACTION.SUCCESS'){
|
||||
$pay_trade_data = $result['resource']['ciphertext'];
|
||||
$temp_params = [
|
||||
'trade_no' => $pay_trade_data['transaction_id'],
|
||||
'mch_id' => $pay_trade_data['mchid']
|
||||
];
|
||||
$callback_result = $callback($pay_trade_data['out_trade_no'], $temp_params);
|
||||
if(is_bool($callback_result) && $callback_result){
|
||||
return Pay::wechat()->success();
|
||||
}
|
||||
}
|
||||
return $this->fail();
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
// throw new PayException($e->getMessage());
|
||||
return $this->fail($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询普通支付订单
|
||||
* @param string $out_trade_no
|
||||
* @param string $transaction_id
|
||||
* @return array|MessageInterface|Collection|null
|
||||
* @throws ContainerException
|
||||
* @throws InvalidParamsException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
public function getOrder(array $params = []){
|
||||
|
||||
$out_trade_no = $params['out_trade_no'];
|
||||
$transaction_id = $params['transaction_id'];
|
||||
$order = [
|
||||
|
||||
];
|
||||
if(!empty($out_trade_no)){
|
||||
$order['out_trade_no'] = $out_trade_no;
|
||||
}
|
||||
if(!empty($transaction_id)){
|
||||
$order['transaction_id'] = $transaction_id;
|
||||
}
|
||||
$result = Pay::wechat()->find($order);
|
||||
if(empty($result))
|
||||
return $result;
|
||||
$result = $this->returnFormat($result);
|
||||
return [
|
||||
'status' => OnlinePayEnum::getWechatPayStatus($result['trade_state']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退款单据
|
||||
* @param $out_trade_no
|
||||
* @param $refund_no
|
||||
* @return void
|
||||
*/
|
||||
public function getRefund(?string $out_trade_no, ?string $refund_no = ''){
|
||||
$order = [
|
||||
'_type' => 'refund',
|
||||
'out_refund_no' => $refund_no
|
||||
];
|
||||
$result = Pay::wechat()->find($order);
|
||||
return $this->returnFormat($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取转账订单(todo 切勿调用)
|
||||
* @param $transfer_no
|
||||
* @return void
|
||||
*/
|
||||
public function getTransfer(string $transfer_no){
|
||||
|
||||
|
||||
$params = [
|
||||
'out_batch_no' => $transfer_no,
|
||||
];
|
||||
|
||||
$allPlugins = Pay::wechat()->mergeCommonPlugins([QueryOutBatchNoPlugin::class]);
|
||||
|
||||
$result = Pay::wechat()->pay($allPlugins, $params);
|
||||
return $this->returnFormat($result);
|
||||
}
|
||||
|
||||
|
||||
public function fail($message = ''){
|
||||
$response = [
|
||||
'code' => 'FAIL',
|
||||
'message' => $message ?: '失败',
|
||||
];
|
||||
return response($response, 400, [], 'json');
|
||||
}
|
||||
}
|
||||
98
niucloud/core/sms/Aliyun.php
Normal file
98
niucloud/core/sms/Aliyun.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace core\sms;
|
||||
|
||||
use AlibabaCloud\Client\AlibabaCloud;
|
||||
use core\exception\NoticeException;
|
||||
use Exception;
|
||||
|
||||
|
||||
class Aliyun extends BaseSms
|
||||
{
|
||||
|
||||
protected $app_key = '';
|
||||
protected $secret_key = '';
|
||||
protected $sign = '';
|
||||
/**
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
$this->app_key = $config['app_key'] ?? '';
|
||||
$this->secret_key = $config['secret_key'] ?? '';
|
||||
$this->sign = $config['sign'] ?? '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送短信
|
||||
* @param string $mobile
|
||||
* @param string $template_id
|
||||
* @param array $data
|
||||
* @return array|false
|
||||
*/
|
||||
public function send(string $mobile, string $template_id, array $data = [])
|
||||
{
|
||||
try {
|
||||
AlibabaCloud::accessKeyClient($this->app_key, $this->secret_key)
|
||||
->regionId('cn-hangzhou')
|
||||
->asDefaultClient();
|
||||
|
||||
$result = AlibabaCloud::rpcRequest()
|
||||
->product('Dysmsapi')
|
||||
->host('dysmsapi.aliyuncs.com')
|
||||
->version('2017-05-25')
|
||||
->action('SendSms')
|
||||
->method('POST')
|
||||
->debug(false)
|
||||
->options([
|
||||
'query' => [
|
||||
'PhoneNumbers' => $mobile,
|
||||
'SignName' => $this->sign,
|
||||
'TemplateCode' => $template_id,
|
||||
'TemplateParam' => $data,
|
||||
],
|
||||
])
|
||||
->request();
|
||||
|
||||
$res = $result->toArray();
|
||||
if (isset($res['Code']) && $res['Code'] == 'OK') {
|
||||
return $res;
|
||||
}
|
||||
$message = $res['Message'] ?? $res;
|
||||
throw new NoticeException($message);
|
||||
} catch( Exception $e) {
|
||||
throw new NoticeException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function open()
|
||||
{
|
||||
}
|
||||
|
||||
public function modify(string $sign = null, string $phone, string $code)
|
||||
{
|
||||
}
|
||||
|
||||
public function info()
|
||||
{
|
||||
}
|
||||
|
||||
public function temps(int $page = 0, int $limit = 10, int $type = 1)
|
||||
{
|
||||
}
|
||||
|
||||
public function apply(string $title, string $content, int $type)
|
||||
{
|
||||
}
|
||||
|
||||
public function applys(int $tempType, int $page, int $limit)
|
||||
{
|
||||
}
|
||||
|
||||
public function record($record_id)
|
||||
{
|
||||
}
|
||||
}
|
||||
88
niucloud/core/sms/BaseSms.php
Normal file
88
niucloud/core/sms/BaseSms.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\sms;
|
||||
|
||||
use core\loader\DriverConfig;
|
||||
use core\loader\Storage;
|
||||
|
||||
/**
|
||||
* Class BaseSms
|
||||
* @package
|
||||
*/
|
||||
abstract class BaseSms extends Storage
|
||||
{
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 开通服务
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function open();
|
||||
|
||||
/**修改签名
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function modify(string $sign = null, string $phone, string $code);
|
||||
|
||||
/**用户信息
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function info();
|
||||
|
||||
/**发送短信
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function send(string $phone, string $templateId, array $data);
|
||||
|
||||
/**
|
||||
* 短信模板
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @param int $type
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function temps(int $page, int $limit, int $type);
|
||||
|
||||
|
||||
/**
|
||||
* 申请模板
|
||||
* @param string $title
|
||||
* @param string $content
|
||||
* @param int $type
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function apply(string $title, string $content, int $type);
|
||||
|
||||
/**
|
||||
* 模板记录
|
||||
* @param int $tempType
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function applys(int $tempType, int $page, int $limit);
|
||||
|
||||
/**发送记录
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function record($record_id);
|
||||
|
||||
|
||||
}
|
||||
46
niucloud/core/sms/SmsLoader.php
Normal file
46
niucloud/core/sms/SmsLoader.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\sms;
|
||||
|
||||
use core\loader\Loader;
|
||||
|
||||
/**
|
||||
* @see \core\sms\SmsLoader
|
||||
* @package think\facade
|
||||
* @mixin \core\sms\BaseSms
|
||||
* @method string|null send(string $phone, string $templateId, array $data) 发送短信
|
||||
* @method mixed open(null|string $name = null, mixed $default = null) 开启服务
|
||||
* @method mixed apply(string $title, string $content, int $type) 申请模板
|
||||
* @method mixed applys(int $tempType, int $page, int $limit) 模板记录
|
||||
*/
|
||||
class SmsLoader extends Loader
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* 空间名
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = '\\core\\sms\\';
|
||||
|
||||
protected $config_name = 'sms';
|
||||
/**
|
||||
* 默认驱动
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getDefault()
|
||||
{
|
||||
return config('sms.default');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
107
niucloud/core/sms/Tencent.php
Normal file
107
niucloud/core/sms/Tencent.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace core\sms;
|
||||
|
||||
use core\exception\CommonException;
|
||||
use core\exception\NoticeException;
|
||||
use Exception;
|
||||
use TencentCloud\Common\Credential;
|
||||
use TencentCloud\Common\Profile\ClientProfile;
|
||||
use TencentCloud\Common\Profile\HttpProfile;
|
||||
use TencentCloud\Sms\V20190711\Models\SendSmsRequest;
|
||||
use TencentCloud\Sms\V20190711\SmsClient;
|
||||
|
||||
/**
|
||||
* 腾讯云短信
|
||||
* Class Tencent
|
||||
* @package app\core\sms\driver
|
||||
*/
|
||||
class Tencent extends BaseSms
|
||||
{
|
||||
|
||||
|
||||
protected $secret_id = '';
|
||||
protected $secret_key = '';
|
||||
protected $sign = '';
|
||||
protected $app_id = '';
|
||||
/**
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
$this->secret_id = $config['secret_id'] ?? '';
|
||||
$this->secret_key = $config['secret_key'] ?? '';
|
||||
$this->sign = $config['sign'] ?? '';
|
||||
$this->app_id = $config['app_id'] ?? '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 发送短信
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function send(string $mobile, string $template_id, array $data = [])
|
||||
{
|
||||
try {
|
||||
$cred = new Credential($this->secret_id, $this->secret_key);
|
||||
$httpProfile = new HttpProfile();
|
||||
$httpProfile->setEndpoint("sms.tencentcloudapi.com");
|
||||
|
||||
$clientProfile = new ClientProfile();
|
||||
$clientProfile->setHttpProfile($httpProfile);
|
||||
|
||||
$client = new SmsClient($cred, 'ap-guangzhou', $clientProfile);
|
||||
$params = [
|
||||
'PhoneNumberSet' => ['+86' . $mobile],
|
||||
'TemplateID' => $template_id,
|
||||
'Sign' => $this->sign,
|
||||
'TemplateParamSet' => $data,
|
||||
'SmsSdkAppid' => $this->app_id,
|
||||
];
|
||||
$req = new SendSmsRequest();
|
||||
$req->fromJsonString(json_encode($params));
|
||||
$resp = json_decode($client->SendSms($req)->toJsonString(), true);
|
||||
if (isset($resp['SendStatusSet']) && $resp['SendStatusSet'][0]['Code'] == 'Ok') {
|
||||
return $resp;
|
||||
} else {
|
||||
$message = $res['SendStatusSet'][0]['Message'] ?? json_encode($resp);
|
||||
throw new CommonException( $message);
|
||||
}
|
||||
} catch( Exception $e) {
|
||||
throw new NoticeException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function open()
|
||||
{
|
||||
}
|
||||
|
||||
public function modify(string $sign = null, string $phone, string $code)
|
||||
{
|
||||
}
|
||||
|
||||
public function info()
|
||||
{
|
||||
}
|
||||
|
||||
public function temps(int $page = 0, int $limit = 10, int $type = 1)
|
||||
{
|
||||
}
|
||||
|
||||
public function apply(string $title, string $content, int $type)
|
||||
{
|
||||
}
|
||||
|
||||
public function applys(int $tempType, int $page, int $limit)
|
||||
{
|
||||
}
|
||||
|
||||
public function record($record_id)
|
||||
{
|
||||
}
|
||||
}
|
||||
62
niucloud/core/template/BaseTemplate.php
Normal file
62
niucloud/core/template/BaseTemplate.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\template;
|
||||
|
||||
use core\loader\DriverConfig;
|
||||
use core\loader\Storage;
|
||||
|
||||
/**
|
||||
* Class BaseTemplate
|
||||
* @package
|
||||
*/
|
||||
abstract class BaseTemplate extends Storage
|
||||
{
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 发送模板消息
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function send(array $data);
|
||||
|
||||
/**
|
||||
* 增加模板消息
|
||||
* @param string $shortId
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function add(array $data);
|
||||
|
||||
/**
|
||||
* 删除消息模板
|
||||
* @param string $templateId
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function delete(array $data);
|
||||
|
||||
/**
|
||||
* 获取消息模板列表
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function get();
|
||||
|
||||
|
||||
}
|
||||
46
niucloud/core/template/TemplateLoader.php
Normal file
46
niucloud/core/template/TemplateLoader.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\template;
|
||||
|
||||
use core\loader\Loader;
|
||||
|
||||
/**
|
||||
* @see \core\template\TemplateLoader
|
||||
* @package think\facade
|
||||
* @mixin \core\template\Wechat
|
||||
* @method string|null send(string $phone, string $templateId, array $data) 发送短信
|
||||
* @method mixed open(null|string $name = null, mixed $default = null) 开启服务
|
||||
* @method mixed apply(string $title, string $content, int $type) 申请模板
|
||||
* @method mixed applys(int $tempType, int $page, int $limit) 模板记录
|
||||
*/
|
||||
class TemplateLoader extends Loader
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* 空间名
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = '\\core\\template\\';
|
||||
|
||||
protected $config_name = 'template';
|
||||
/**
|
||||
* 默认驱动
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getDefault()
|
||||
{
|
||||
return config('template.default');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
75
niucloud/core/template/Weapp.php
Normal file
75
niucloud/core/template/Weapp.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace core\template;
|
||||
|
||||
use AlibabaCloud\Client\AlibabaCloud;
|
||||
use app\service\core\weapp\CoreWeappService;
|
||||
use app\service\core\wechat\CoreWechatService;
|
||||
use core\exception\NoticeException;
|
||||
use core\sms\BaseSms;
|
||||
use Exception;
|
||||
|
||||
|
||||
class Weapp extends BaseTemplate
|
||||
{
|
||||
|
||||
protected $site_id;
|
||||
/**
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
$this->site_id = $config['site_id'] ?? '';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化订阅消息业务
|
||||
* @return \EasyWeChat\MiniProgram\SubscribeMessage\Client
|
||||
*/
|
||||
public function template(){
|
||||
return CoreWeappService::app($this->site_id)->subscribe_message;
|
||||
}
|
||||
/**
|
||||
* 消息发送
|
||||
* @param string $templateId
|
||||
* @param array $data
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function send(array $data){
|
||||
return $this->template()->send([
|
||||
'template_id' => $data['template_id'],
|
||||
'touser' => $data['openid'],
|
||||
'page' => $data['page'],
|
||||
'data' => $data['data'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加模板消息
|
||||
* @param array $data
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function add(array $data){
|
||||
return $this->template()->addTemplate($data['tid'], $data['kidList'], $data['sceneDesc']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param array $data
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function delete(array $data){
|
||||
return $this->template()->deleteTemplate($data['template_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function get(){
|
||||
|
||||
}
|
||||
}
|
||||
86
niucloud/core/template/Wechat.php
Normal file
86
niucloud/core/template/Wechat.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace core\template;
|
||||
|
||||
use AlibabaCloud\Client\AlibabaCloud;
|
||||
use app\service\core\wechat\CoreWechatService;
|
||||
use core\exception\NoticeException;
|
||||
use core\sms\BaseSms;
|
||||
use Exception;
|
||||
|
||||
|
||||
class Wechat extends BaseTemplate
|
||||
{
|
||||
|
||||
protected $site_id;
|
||||
/**
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
$this->site_id = $config['site_id'] ?? '';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化模板消息业务
|
||||
* @return \EasyWeChat\OfficialAccount\TemplateMessage\Client
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function template(){
|
||||
return CoreWechatService::app($this->site_id)->template_message;
|
||||
}
|
||||
/**
|
||||
* 消息发送
|
||||
* @param string $templateId
|
||||
* @param array $data
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function send(array $data){
|
||||
$openid = $data['openid'];
|
||||
$template_id = $data['template_id'];
|
||||
$template_data = $data['data'];
|
||||
$first = $data['first'];
|
||||
$remark = $data['remark'];
|
||||
$url = $data['url'];
|
||||
$miniprogram = $data['miniprogram'];
|
||||
|
||||
if(!empty($first)) $template_data['first'] = $first;
|
||||
if(!empty($remark)) $template_data['remark'] = $remark;
|
||||
return $this->template()->send([
|
||||
'touser' => $openid,
|
||||
'template_id' => $template_id,
|
||||
'url' => $url,
|
||||
'miniprogram' => $miniprogram,
|
||||
'data' => $template_data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加模板消息
|
||||
* @param string $shortId
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function add(array $data){
|
||||
return $this->template()->addTemplate($data['shortId']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param string $templateId
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function delete(array $data){
|
||||
return $this->template()->deletePrivateTemplate($data['templateId']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function get(){
|
||||
|
||||
}
|
||||
}
|
||||
94
niucloud/core/upload/Aliyun.php
Normal file
94
niucloud/core/upload/Aliyun.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
namespace core\upload;
|
||||
|
||||
use core\exception\UploadFileException;
|
||||
use OSS\Core\OssException;
|
||||
use OSS\OssClient;
|
||||
|
||||
/**
|
||||
* 阿里云存储引擎 (OSS)
|
||||
*/
|
||||
class Aliyun extends BaseUpload
|
||||
{
|
||||
|
||||
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
}
|
||||
|
||||
public function client(){
|
||||
// true为开启CNAME。CNAME是指将自定义域名绑定到存储空间上。
|
||||
$is_cname = true;
|
||||
$access_key_id = $this->config['access_key'];
|
||||
$access_key_secret = $this->config['secret_key'];
|
||||
|
||||
$endpoint = $this->config['endpoint'];// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
|
||||
$oss_client = new OssClient($access_key_id, $access_key_secret, $endpoint, $is_cname);
|
||||
return $oss_client;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行上传
|
||||
* @param $save_dir (保存路径)
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function upload(string $dir)
|
||||
{
|
||||
$this->validate();
|
||||
$bucket = $this->config['bucket'];
|
||||
try {
|
||||
$this->client()->uploadFile(
|
||||
$bucket,
|
||||
$this->getFullPath(),
|
||||
$this->getRealPath()
|
||||
);
|
||||
return true;
|
||||
} catch (OssException $e) {
|
||||
throw new UploadFileException($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 抓取远程资源
|
||||
* @param $url
|
||||
* @param null $key
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function fetch(string $url, ?string $key = null)
|
||||
{
|
||||
$bucket = $this->config['bucket'];
|
||||
try {
|
||||
$content = file_get_contents($url);
|
||||
$this->client()->putObject(
|
||||
$bucket,
|
||||
$key,
|
||||
$content
|
||||
);
|
||||
return true;
|
||||
} catch (OssException $e) {
|
||||
throw new UploadFileException($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param $file_name
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function delete(string $file_name)
|
||||
{
|
||||
$bucket = $this->config['bucket'];
|
||||
try {
|
||||
$this->client()->deleteObject($bucket, $file_name);
|
||||
return true;
|
||||
} catch (OssException $e) {
|
||||
throw new UploadFileException($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
234
niucloud/core/upload/BaseUpload.php
Normal file
234
niucloud/core/upload/BaseUpload.php
Normal file
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\upload;
|
||||
|
||||
|
||||
use app\service\core\upload\CoreUploadConfigService;
|
||||
use core\exception\UploadFileException;
|
||||
use core\loader\DriverConfig;
|
||||
use core\loader\Storage;
|
||||
|
||||
/**
|
||||
* Class BaseUpload
|
||||
*/
|
||||
abstract class BaseUpload extends Storage
|
||||
{
|
||||
|
||||
protected $file;//上传的文件对象
|
||||
protected $file_info;//上传的文件属性参数
|
||||
protected $file_name;//新文件名
|
||||
protected $name;
|
||||
protected $full_file;//完整的文件地址
|
||||
protected $full_path;
|
||||
protected $validate;
|
||||
protected $type;
|
||||
|
||||
protected $config = null;
|
||||
//可能还需要一个完整路径
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件上传
|
||||
* @param $save_dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function upload(string $dir);
|
||||
|
||||
/**
|
||||
* 抓取远程附件
|
||||
* @param $url
|
||||
* @param $key
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function fetch(string $url, ?string $key);
|
||||
|
||||
/**
|
||||
* 附件删除
|
||||
* @param $fileName
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function delete(string $file_name);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 读取文件
|
||||
* @param $name
|
||||
*/
|
||||
public function read(string $name, bool $is_rename = true){
|
||||
$this->name = $name;
|
||||
$this->file = request()->file($name);
|
||||
if(empty($this->file))
|
||||
throw new UploadFileException(100012);
|
||||
$this->file_info = [
|
||||
'name' => $this->file->getOriginalName(),//文件原始名称
|
||||
'mime' => $this->file->getOriginalMime(),//上传文件类型信息
|
||||
'real_path' => $this->file->getRealPath(),//上传文件真实路径
|
||||
'ext' => $this->file->getOriginalExtension(),//上传文件后缀
|
||||
'size' => $this->file->getSize(),//上传文件大小
|
||||
];
|
||||
if($is_rename){
|
||||
$this->file_name = $this->createFileName();
|
||||
}else{
|
||||
$this->file_name = $this->file_info['name'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件类型
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function setType(string $type){
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验文件是否合法
|
||||
*/
|
||||
public function check(){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成新的文件名
|
||||
* @return string
|
||||
*/
|
||||
public function createFileName(string $key = '', string $ext = ''){
|
||||
//DIRECTORY_SEPARATOR 常量
|
||||
if(empty($key)){
|
||||
return time().md5($this->file_info['real_path']).'.'.$this->file_info['ext'];
|
||||
}else{
|
||||
return time().md5($key).'.'.$ext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取原始附件信息
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFileInfo(){
|
||||
return $this->file_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传文件的真实完整路径
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRealPath(){
|
||||
return $this->file_info['real_path'];
|
||||
}
|
||||
/**
|
||||
* 获取生成的文件完整地址
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFullPath(string $dir = ''){
|
||||
return $this->full_path ?: $this->concatFullPath($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并路径和文件名
|
||||
*/
|
||||
public function concatFullPath(string $dir = ''){
|
||||
$this->full_path = implode('/', array_filter([$dir, $this->getFileName()]));
|
||||
return $this->full_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFileName()
|
||||
{
|
||||
return $this->file_name;
|
||||
}
|
||||
public function getUrl(string $path = ''){
|
||||
$path = !empty($path) ? $path : $this->getFullPath();
|
||||
$domain = $this->config['domain'] ?? '';
|
||||
$domain = empty($domain) ? '' : $domain.'/';
|
||||
return $domain.$path;
|
||||
}
|
||||
|
||||
|
||||
public function setValidate(array $validate = []){
|
||||
$this->validate = $validate ?: config('upload.rules')[$this->type] ?? [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据上传文件的类型来校验文件是否符合配置
|
||||
* @param int $site_id
|
||||
* @param string $file
|
||||
* @param string $att_type
|
||||
* @return void
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
if (empty($this->file))
|
||||
throw new UploadFileException('UPLOAD_FAIL');
|
||||
|
||||
$config['file_ext'] = $this->validate['ext'] ?? [];
|
||||
$config['file_mime'] = $this->validate['mime'] ?? [];
|
||||
$config['file_size'] = $this->validate['size'] ?? 0;
|
||||
$rule = [];
|
||||
$file_size = $config['file_size'] ?? 0;
|
||||
if ($file_size > 0) {
|
||||
$rule[] = 'fileSize:' . $file_size;
|
||||
}
|
||||
//验证上传文件类型
|
||||
$file_mime = $config['file_mime'] ?? [];
|
||||
$file_ext = $config['file_ext'] ?? [];
|
||||
if (!empty($file_ext)) {
|
||||
$rule[] = 'fileExt:' . implode(',', $file_ext);
|
||||
}
|
||||
// $image_config = $config['image'] ?? [];
|
||||
// if (!empty($image_config)) {
|
||||
// $image_width = $image_config['width'] ?? 0;
|
||||
// $image_height = $image_config['height'] ?? 0;
|
||||
// $image_type = $image_config['type'] ?? [];
|
||||
// $image_rule = '';
|
||||
// if ($image_width > 0 && $image_height > 0) {
|
||||
// $image_rule = 'image:' . $image_width . ',' . $image_height;
|
||||
// }
|
||||
// if (!empty($image_type)) {
|
||||
// if (empty($image_rule)) {
|
||||
// $image_rule = 'image:';
|
||||
// } else {
|
||||
// $image_rule .= ',';
|
||||
// }
|
||||
// $image_rule .= implode(',', $image_type);
|
||||
// }
|
||||
// if (!empty($image_type)) {
|
||||
// $rule[] = $image_rule;
|
||||
// }
|
||||
// }
|
||||
if (!empty($rule)) {
|
||||
if (!in_array($this->file->getOriginalMime(), $file_mime)) {
|
||||
throw new UploadFileException('UPLOAD_TYPE_NOT_SUPPORT');
|
||||
}
|
||||
validate([$this->name => implode('|', $rule)])->check([$this->name => $this->file]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
89
niucloud/core/upload/Local.php
Normal file
89
niucloud/core/upload/Local.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2023-02-17
|
||||
* Time: 15:58
|
||||
*/
|
||||
|
||||
namespace core\upload;
|
||||
|
||||
use core\exception\UploadFileException;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* 文件管理驱动类
|
||||
* Class FileDriver
|
||||
* @package core\file
|
||||
*/
|
||||
class Local extends BaseUpload
|
||||
{
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
|
||||
}
|
||||
|
||||
public function upload(string $dir)
|
||||
{
|
||||
$this->validate();
|
||||
mkdirs($dir);
|
||||
$this->file->move($dir, $this->file_name);
|
||||
//错误一般是已经被抛出了
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 远程获取图片
|
||||
* @param $url
|
||||
* @param $key
|
||||
* @return true
|
||||
*/
|
||||
public function fetch(string $url, ?string $key)
|
||||
{
|
||||
try {
|
||||
mkdirs($key);
|
||||
$content = @file_get_contents($url);
|
||||
if (!empty($content)) {
|
||||
file_put_contents($key, $content);
|
||||
// $fp = fopen($key, "w");
|
||||
// fwrite($fp, $content);
|
||||
// fclose($fp);
|
||||
}else{
|
||||
throw new UploadFileException(203006);
|
||||
}
|
||||
return true;
|
||||
} catch ( Exception $e ) {
|
||||
throw new UploadFileException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* base64转图片
|
||||
* @param string $content
|
||||
* @param string|null $key
|
||||
* @return void
|
||||
*/
|
||||
public function base64(string $content, ?string $key){
|
||||
|
||||
mkdirs($key);
|
||||
file_put_contents(url_to_path($key), base64_decode($content));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除本地附件
|
||||
* @param $file_name
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function delete(string $file_name)
|
||||
{
|
||||
$file_path = url_to_path($file_name);
|
||||
if (!file_exists($file_path)) {
|
||||
return true;
|
||||
// throw new UploadFileException(100013);
|
||||
}
|
||||
return unlink($file_path);
|
||||
}
|
||||
}
|
||||
111
niucloud/core/upload/Qcloud.php
Normal file
111
niucloud/core/upload/Qcloud.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2023-02-17
|
||||
* Time: 15:58
|
||||
*/
|
||||
|
||||
namespace core\upload;
|
||||
|
||||
use core\exception\UploadFileException;
|
||||
use Exception;
|
||||
use Qcloud\Cos\Client;
|
||||
|
||||
/**
|
||||
* 腾讯云存储引擎 (COS)
|
||||
* Class Qiniu
|
||||
* @package app\common\library\storage\engine
|
||||
*/
|
||||
class Qcloud extends BaseUpload
|
||||
{
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
}
|
||||
/**
|
||||
* 获取服务主体
|
||||
* @return Client
|
||||
*/
|
||||
public function client(){
|
||||
$secret_id = $this->config['access_key']; //替换为用户的 secretId,请登录访问管理控制台进行查看和管理,https://console.tencentcloud.com/cam/capi
|
||||
$secret_key = $this->config['secret_key']; //替换为用户的 secretKey,请登录访问管理控制台进行查看和管理,https://console.tencentcloud.com/cam/capi
|
||||
$region = $this->config['region']; //替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.tencentcloud.com/cos5/bucket
|
||||
|
||||
return new Client(
|
||||
array(
|
||||
'region' => $region,
|
||||
// 'schema' => 'https', //协议头部,默认为http
|
||||
'credentials' => array(
|
||||
'secretId' => $secret_id,
|
||||
'secretKey' => $secret_key)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行上传
|
||||
* @param $save_dir (保存路径)
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function upload(string $dir)
|
||||
{
|
||||
$this->validate();
|
||||
$bucket = $this->config['bucket'];
|
||||
try {
|
||||
$result = $this->client()->putObject(array(
|
||||
'Bucket' => $bucket, //存储桶名称,由BucketName-Appid 组成,可以在COS控制台查看 https://console.tencentcloud.com/cos5/bucket
|
||||
'Key' => $this->getFullPath(),
|
||||
'Body' => fopen($this->getRealPath(), 'rb'),
|
||||
));
|
||||
// 请求成功
|
||||
return true;
|
||||
} catch ( Exception $e ) {
|
||||
throw new UploadFileException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* notes: 抓取远程资源(最大支持上传5G文件)
|
||||
* @param $url
|
||||
* @param null $key
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function fetch(string $url, ?string $key = null)
|
||||
{
|
||||
|
||||
$bucket = $this->config['bucket'];
|
||||
try {
|
||||
$result = $this->client()->putObject(array(
|
||||
'Bucket' => $bucket, //存储桶名称,由BucketName-Appid 组成,可以在COS控制台查看 https://console.tencentcloud.com/cos5/bucket
|
||||
'Key' => $key,
|
||||
'Body' => fopen($url, 'rb'),
|
||||
));
|
||||
// 请求成功
|
||||
return true;
|
||||
} catch ( Exception $e ) {
|
||||
throw new UploadFileException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个简单对象
|
||||
* @param $file_name
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function delete(string $file_name)
|
||||
{
|
||||
$bucket = $this->config['bucket'];
|
||||
try {
|
||||
$this->client()->deleteObject(array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $file_name
|
||||
));
|
||||
return true;
|
||||
} catch ( Exception $e ) {
|
||||
throw new UploadFileException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
96
niucloud/core/upload/Qiniu.php
Normal file
96
niucloud/core/upload/Qiniu.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2023-02-17
|
||||
* Time: 15:58
|
||||
*/
|
||||
|
||||
namespace core\upload;
|
||||
|
||||
use core\exception\UploadFileException;
|
||||
use Exception;
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Config;
|
||||
use Qiniu\Storage\BucketManager;
|
||||
use Qiniu\Storage\UploadManager;
|
||||
use function core\upload\storage\str_contains;
|
||||
|
||||
/**
|
||||
* 文件管理驱动类
|
||||
* Class FileDriver
|
||||
* @package core\file
|
||||
*/
|
||||
class Qiniu extends BaseUpload
|
||||
{
|
||||
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
}
|
||||
/**
|
||||
* 获取一个鉴权对象
|
||||
* @return Auth
|
||||
*/
|
||||
public function auth(){
|
||||
$access_key = $this->config['access_key'];
|
||||
$secret_key = $this->config['secret_key'];
|
||||
return new Auth($access_key, $secret_key);
|
||||
}
|
||||
public function upload(string $dir)
|
||||
{
|
||||
$this->validate();
|
||||
$bucket = $this->config['bucket'];
|
||||
//todo 这儿可以定义凭证的过期时间
|
||||
$up_token = $this->auth()->uploadToken($bucket);
|
||||
// 初始化 UploadManager 对象并进行文件的上传。
|
||||
$upload_mgr = new UploadManager();
|
||||
list($ret, $err) = $upload_mgr->putFile($up_token, $this->getFullPath(), $this->getRealPath());
|
||||
if ($err !== null)
|
||||
throw new UploadFileException($err->message());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 抓取网络资源到空间
|
||||
* @param $url
|
||||
* @param $key
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetch(string $url, ?string $key = null)
|
||||
{
|
||||
$bucket = $this->config['bucket'];
|
||||
$auth = $this->auth();
|
||||
if(!str_contains($url, 'http://') && !str_contains($url, 'https://')){
|
||||
$token = $auth->uploadToken($bucket);
|
||||
$upload_mgr = new UploadManager();
|
||||
list($ret, $err) = $upload_mgr->putFile($token, $key, $url);
|
||||
}else{
|
||||
//抓取网络资源到空间
|
||||
$bucket_manager = new BucketManager($auth);
|
||||
list($ret, $err) = $bucket_manager->fetch($url, $bucket, $key);//不指定key时,以文件内容的hash作为文件名
|
||||
}
|
||||
|
||||
if ($err !== null)
|
||||
throw new UploadFileException($err->message());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除空间中的文件
|
||||
* @param $file_name
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function delete(string $file_name)
|
||||
{
|
||||
$bucket = $this->config['bucket'];
|
||||
$auth = $this->auth();
|
||||
$config = new Config();
|
||||
$bucket_manager = new BucketManager($auth, $config);
|
||||
$err = $bucket_manager->delete($bucket, $file_name);
|
||||
if ($err !== null)
|
||||
throw new UploadFileException($err->message());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
41
niucloud/core/upload/UploadLoader.php
Normal file
41
niucloud/core/upload/UploadLoader.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\upload;
|
||||
|
||||
use core\loader\Loader;
|
||||
|
||||
/**
|
||||
* @see \core\upload\UploadLoader
|
||||
* @package think\facade
|
||||
* @mixin \core\upload\BaseUpload
|
||||
* @method string|null upload(string $dir) 附件上传
|
||||
* @method array fetch(string $url, ?string $key) 抓取远程附件
|
||||
* @method mixed delete(string $file_name) 附件删除
|
||||
*/
|
||||
class UploadLoader extends Loader
|
||||
{
|
||||
/**
|
||||
* 空间名
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = '\\core\\upload\\';
|
||||
|
||||
protected $config_name = 'upload';
|
||||
/**
|
||||
* 默认驱动
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getDefault()
|
||||
{
|
||||
return config('upload.default');
|
||||
}
|
||||
}
|
||||
124
niucloud/core/util/ConfigUtil.php
Normal file
124
niucloud/core/util/ConfigUtil.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\util;
|
||||
|
||||
/**
|
||||
* 系统配置文件加载(event,lang)等
|
||||
* Class ConfigUtil
|
||||
* @package core\util
|
||||
*/
|
||||
class ConfigUtil
|
||||
{
|
||||
/**
|
||||
* config参数
|
||||
* @var array
|
||||
*/
|
||||
public $config = [];
|
||||
|
||||
public $files = [];
|
||||
|
||||
//是否保留唯一key
|
||||
public $unique_key;
|
||||
|
||||
/**
|
||||
* 配置文件目录
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* ConfigUtil constructor.
|
||||
* @param $path
|
||||
* @param $init
|
||||
*/
|
||||
public function __construct(string $path, array $init = [], bool $unique_key = false)
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->config = $init;
|
||||
$this->unique_key = $unique_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载配置文件(多种格式)
|
||||
* @access public
|
||||
* @param string $file 配置文件名
|
||||
* @param string $name 一级配置名
|
||||
* @return array
|
||||
*/
|
||||
public function loadConfig() : array
|
||||
{
|
||||
$files_data = $this->loadFiles();
|
||||
if (!empty($files_data)) {
|
||||
foreach ($files_data as $data) {
|
||||
if ($this->unique_key) {
|
||||
$this->config = $this->config + $data;
|
||||
} else {
|
||||
$this->config = array_merge($this->config, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载返回所有文件数据
|
||||
*/
|
||||
public function loadFiles()
|
||||
{
|
||||
$this->parseFiles($this->path);
|
||||
$default_sort = 100000;
|
||||
$files_data = [];
|
||||
if (!empty($this->files)) {
|
||||
foreach ($this->files as $file) {
|
||||
$config = include $file;
|
||||
if (!empty($config)) {
|
||||
if (isset($config[ 'file_sort' ])) {
|
||||
$sort = $config[ 'file_sort' ];
|
||||
unset($config[ 'file_sort' ]);
|
||||
$sort = $sort * 10;
|
||||
while (array_key_exists($sort, $files_data)) {
|
||||
$sort++;
|
||||
}
|
||||
$files_data[ $sort ] = $config;
|
||||
} else {
|
||||
$files_data[ $default_sort ] = $config;
|
||||
$default_sort++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ksort($files_data);
|
||||
return $files_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 整理所有文件
|
||||
* @param string $path
|
||||
*/
|
||||
protected function parseFiles(string $path)
|
||||
{
|
||||
$files = scandir($path);
|
||||
//先加载系统(system),然后加载非插件,最后按照插件安装顺序进行加载
|
||||
foreach ($files as $file) {
|
||||
if ($file != '.' && $file != '..') {
|
||||
if (is_dir($path . DIRECTORY_SEPARATOR . $file)) {
|
||||
$this->parseFiles($path . DIRECTORY_SEPARATOR . $file);
|
||||
} else {
|
||||
$this->files[] = $path . DIRECTORY_SEPARATOR . $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
230
niucloud/core/util/Queue.php
Normal file
230
niucloud/core/util/Queue.php
Normal file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\util;
|
||||
|
||||
use think\facade\Config;
|
||||
use think\facade\Queue as ThinkQueue;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* Class Queue
|
||||
* @package core\util
|
||||
* @method $this do(string $do) 设置任务执行方法
|
||||
* @method $this job(string $job) 设置任务执行类名
|
||||
* @method $this errorCount(int $errorCount) 执行失败次数
|
||||
* @method $this data(...$data) 执行数据
|
||||
* @method $this secs(int $secs) 延迟执行秒数
|
||||
* @method $this log($log) 记录日志
|
||||
*/
|
||||
class Queue
|
||||
{
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
* @var string
|
||||
*/
|
||||
protected $error;
|
||||
|
||||
/**
|
||||
* 设置错误信息
|
||||
* @param string|null $error
|
||||
* @return bool
|
||||
*/
|
||||
protected function setError(?string $error = null)
|
||||
{
|
||||
$this->error = $error ?: '未知错误';
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取错误信息
|
||||
* @return string
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
$error = $this->error;
|
||||
$this->error = null;
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务执行
|
||||
* @var string
|
||||
*/
|
||||
protected $do = 'doJob';
|
||||
|
||||
/**
|
||||
* 默认任务执行方法名
|
||||
* @var string
|
||||
*/
|
||||
protected $defaultDo;
|
||||
|
||||
/**
|
||||
* 任务类名
|
||||
* @var string
|
||||
*/
|
||||
protected $job;
|
||||
|
||||
/**
|
||||
* 错误次数
|
||||
* @var int
|
||||
*/
|
||||
protected $errorCount = 3;
|
||||
|
||||
/**
|
||||
* 数据
|
||||
* @var array|string
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* 队列名
|
||||
* @var null
|
||||
*/
|
||||
protected $queueName = null;
|
||||
|
||||
/**
|
||||
* 延迟执行秒数
|
||||
* @var int
|
||||
*/
|
||||
protected $secs = 0;
|
||||
|
||||
/**
|
||||
* 记录日志
|
||||
* @var string|callable|array
|
||||
*/
|
||||
protected $log;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $rules = ['do', 'data', 'errorCount', 'job', 'secs', 'log'];
|
||||
|
||||
/**
|
||||
* @var static
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Queue constructor.
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
$this->defaultDo = $this->do;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
if (is_null(self::$instance)) {
|
||||
self::$instance = new static();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $queueName
|
||||
* @return $this
|
||||
*/
|
||||
public function setQueueName(string $queueName)
|
||||
{
|
||||
$this->queueName = $queueName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 放入消息队列
|
||||
* @param array|null $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function push(?array $data = null)
|
||||
{
|
||||
if (!$this->job) {
|
||||
return $this->setError('需要执行的队列类必须存在');
|
||||
}
|
||||
$jodValue = $this->getValues($data);
|
||||
//todo 队列扩展策略调度,
|
||||
$res = ThinkQueue::{$this->action()}(...$jodValue);
|
||||
if (!$res) {
|
||||
$res = ThinkQueue::{$this->action()}(...$jodValue);
|
||||
if (!$res) {
|
||||
Log::error('加入队列失败,参数:' . json_encode($this->getValues($data)));
|
||||
}
|
||||
}
|
||||
$this->clean();
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除数据
|
||||
*/
|
||||
public function clean()
|
||||
{
|
||||
$this->secs = 0;
|
||||
$this->data = [];
|
||||
$this->log = null;
|
||||
$this->queueName = null;
|
||||
$this->errorCount = 3;
|
||||
$this->do = $this->defaultDo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务方式
|
||||
* @return string
|
||||
*/
|
||||
protected function action()
|
||||
{
|
||||
return $this->secs ? 'later' : 'push';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
protected function getValues($data)
|
||||
{
|
||||
$jobData['data'] = $data ?: $this->data;
|
||||
$jobData['do'] = $this->do;
|
||||
$jobData['errorCount'] = $this->errorCount;
|
||||
$jobData['log'] = $this->log;
|
||||
if ($this->do != $this->defaultDo) {
|
||||
$this->job .= '@' . Config::get('queue.prefix', 'eb_') . $this->do;
|
||||
}
|
||||
if ($this->secs) {
|
||||
return [$this->secs, $this->job, $jobData, $this->queueName];
|
||||
} else {
|
||||
return [$this->job, $jobData, $this->queueName];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (in_array($name, $this->rules)) {
|
||||
if ($name === 'data') {
|
||||
$this->{$name} = $arguments;
|
||||
} else {
|
||||
$this->{$name} = $arguments[0] ?? null;
|
||||
}
|
||||
return $this;
|
||||
} else {
|
||||
throw new \RuntimeException('Method does not exist' . __CLASS__ . '->' . $name . '()');
|
||||
}
|
||||
}
|
||||
}
|
||||
101
niucloud/core/util/SqlUtil.php
Normal file
101
niucloud/core/util/SqlUtil.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\util;
|
||||
|
||||
use think\db\exception\PDOException;
|
||||
use think\facade\Config;
|
||||
use think\facade\Db;
|
||||
use think\facade\Env;
|
||||
|
||||
/**
|
||||
* 数据库工具类
|
||||
* Class SqlUtil
|
||||
* @package core\util
|
||||
*/
|
||||
class SqlUtil
|
||||
{
|
||||
|
||||
|
||||
public function executeSql(string $sql_file): bool
|
||||
{
|
||||
$dbprefix = Config::get('database.connections.mysql.prefix');
|
||||
$sql_data = file_get_contents($sql_file);
|
||||
|
||||
$sql_query = $this->getSqlQuery($sql_data);
|
||||
$query_count = count($sql_query);
|
||||
for ($i = 0; $i < $query_count; $i++) {
|
||||
$sql = trim($sql_query[ $i ]);
|
||||
$is_write = false;
|
||||
if (strstr($sql, 'CREATE TABLE')) {
|
||||
$match_item = preg_match('/CREATE TABLE [`]?(\\w+)[`]?/is', $sql, $match_data);
|
||||
$is_write = true;
|
||||
} elseif (strstr($sql, 'ALTER TABLE')) {
|
||||
$match_item = preg_match('/ALTER TABLE [`]?(\\w+)[`]?/is', $sql, $match_data);
|
||||
|
||||
} elseif (strstr($sql, 'INSERT INTO')) {
|
||||
$match_item = preg_match('/INSERT INTO [`]?(\\w+)[`]?/is', $sql, $match_data);
|
||||
} else {
|
||||
$match_item = 0;
|
||||
}
|
||||
if ($match_item > 0) {
|
||||
try {
|
||||
$table_name = $match_data[ 1 ];
|
||||
$new_table_name = $dbprefix . $table_name;
|
||||
$sql_item = $this->strReplaceFirst($table_name, $new_table_name, $sql);
|
||||
Db::execute($sql_item);
|
||||
} catch (\Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql_data
|
||||
* @return array
|
||||
*/
|
||||
public function getSqlQuery($sql_data)
|
||||
{
|
||||
$sql_data = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=utf8", $sql_data);
|
||||
|
||||
$sql_data = str_replace("\r", "\n", $sql_data);
|
||||
$sql_query = [];
|
||||
$num = 0;
|
||||
$sql_array = explode(";\n", trim($sql_data));
|
||||
unset($sql);
|
||||
foreach ($sql_array as $sql) {
|
||||
$sql_query[ $num ] = '';
|
||||
$sqls = explode("\n", trim($sql));
|
||||
$sqls = array_filter($sqls);
|
||||
foreach ($sqls as $query) {
|
||||
$str1 = substr($query, 0, 1);
|
||||
if ($str1 != '#' && $str1 != '-')
|
||||
$sql_query[ $num ] .= $query;
|
||||
}
|
||||
$num++;
|
||||
}
|
||||
return $sql_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* 代码切换
|
||||
* @param $search
|
||||
* @param $replace
|
||||
* @param $subject
|
||||
* @return string
|
||||
*/
|
||||
public function strReplaceFirst($search, $replace, $subject)
|
||||
{
|
||||
return implode($replace, explode($search, $subject, 2));
|
||||
}
|
||||
|
||||
}
|
||||
66
niucloud/core/util/Terminal.php
Normal file
66
niucloud/core/util/Terminal.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace core\util;
|
||||
|
||||
class Terminal
|
||||
{
|
||||
|
||||
private $out_file;
|
||||
// private $
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->error_path = runtime_path() . 'terminal'.DIRECTORY_SEPARATOR.date('Ym').DIRECTORY_SEPARATOR.date('d').'.log';
|
||||
}
|
||||
public function execute(){
|
||||
// $command = [];
|
||||
//可以使自定义指令也可以是
|
||||
$command = $this->command();
|
||||
|
||||
$cwd = $command['cwd'];//程序运行的目录
|
||||
|
||||
// proc_open($command['command'], $descriptorspec, $pipes, $cwd);
|
||||
//通道消息不及时
|
||||
$descriptorspec = array(
|
||||
0 => array('pipe', 'r'), // 标准输入,子进程从此管道中读取数据
|
||||
1 => array('pipe', 'w'), // 标准输出,子进程向此管道中写入数据
|
||||
2 => array('file', $this->out_file, 'a') // 标准错误,写入到一个文件
|
||||
);
|
||||
//放在文件中是同步的,放在管道中可能是不及时的
|
||||
// $descriptorspec = [
|
||||
// 0 => ['pipe', 'r'],
|
||||
// 1 => ['file', $this->out_file, 'w'],
|
||||
// 2 => ['file', $this->out_file, 'w']];
|
||||
// $env_vars = array('some_option' => 'aeiou');//可以不启用其他的环境变量,使用和系统一致的环境变量
|
||||
$env_vars = null;
|
||||
$process = proc_open($command['command'], $descriptorspec, $pipes, $cwd, $env_vars);
|
||||
|
||||
if (is_resource($process)) {
|
||||
// $pipes 现在看起来是这样的:
|
||||
// 0 => 可以向子进程标准输入写入的句柄
|
||||
// 1 => 可以从子进程标准输出读取的句柄
|
||||
// 错误输出将被追加到文件 /tmp/error-output.txt
|
||||
|
||||
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
|
||||
fclose($pipes[0]);
|
||||
|
||||
echo stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
|
||||
|
||||
// 切记:在调用 proc_close 之前关闭所有的管道以避免死锁。
|
||||
$return_value = proc_close($process);
|
||||
|
||||
echo "command returned $return_value\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function command($key){
|
||||
//通过健名获取详细的命令字典
|
||||
|
||||
return [
|
||||
'command' => '',
|
||||
'cwd' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
107
niucloud/core/util/TokenAuth.php
Normal file
107
niucloud/core/util/TokenAuth.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的saas管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud-admin.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace core\util;
|
||||
|
||||
use Firebase\JWT\JWT;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Env;
|
||||
|
||||
|
||||
/**
|
||||
* token工具类
|
||||
* Class TokenAuth
|
||||
* @package core\util
|
||||
*/
|
||||
class TokenAuth
|
||||
{
|
||||
private $token;
|
||||
|
||||
/**
|
||||
*创建token
|
||||
* @param int $id 编码 一般传入用户id
|
||||
* @param string $type 类型(admin,site,home)
|
||||
* @param array $params 参数 传入id, name
|
||||
* @param int $expire_time 有效期
|
||||
* @return array
|
||||
*/
|
||||
public static function createToken(int $id, string $type, array $params = [], int $expire_time = 0): array
|
||||
{
|
||||
$host = app()->request->host();
|
||||
$time = time();
|
||||
$params += [
|
||||
'iss' => $host,
|
||||
'aud' => $host,
|
||||
'iat' => $time,
|
||||
'nbf' => $time,
|
||||
'exp' => $time + $expire_time,
|
||||
];
|
||||
|
||||
$params['jti'] = $id . "_" . $type;
|
||||
$token = JWT::encode($params, Env::get('app.app_key', 'niushop456$%^'));
|
||||
$cache_token = Cache::get("token_" . $params['jti']);
|
||||
$cache_token_arr = $cache_token ?: [];
|
||||
// if(!empty($cache_token))
|
||||
// {
|
||||
//
|
||||
// $cache_token_arr[] = $token;
|
||||
// }
|
||||
$cache_token_arr[] = $token;
|
||||
Cache::tag("token")->set("token_" . $params['jti'], $cache_token_arr);
|
||||
return compact('token', 'params');
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析token
|
||||
* @param string $token
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
public static function parseToken(string $token, string $type): array
|
||||
{
|
||||
$payload = JWT::decode($token, Env::get('app.app_key', 'niushop456$%^'), ['HS256']);
|
||||
if (!empty($payload)) {
|
||||
$token_info = json_decode(json_encode($payload), true);
|
||||
|
||||
if (explode("_", $token_info['jti'])[1] != $type) {
|
||||
return [];
|
||||
}
|
||||
if (!empty($token_info) && !in_array($token, Cache::get('token_' . $token_info['jti'], []))) {
|
||||
return [];
|
||||
}
|
||||
return $token_info;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理token
|
||||
* @param int $id
|
||||
* @param string $type
|
||||
*/
|
||||
public static function clearToken(int $id, string $type, ?string $token = '')
|
||||
{
|
||||
if (!empty($token)) {
|
||||
$token_cache = Cache::get("token_" . $id . "_" . $type, []);
|
||||
//todo 也可以通过修改过期时间来实现
|
||||
if (!empty($token_cache)) {
|
||||
if (($key = array_search($token, $token_cache)) !== false) {
|
||||
array_splice($token_cache, $key, 1);
|
||||
}
|
||||
Cache::set("token_" . $id . "_" . $type, $token_cache);
|
||||
}
|
||||
} else {
|
||||
Cache::set("token_" . $id . "_" . $type, []);
|
||||
}
|
||||
return success();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user