chore: 添加静态资源文件和版本配置文件
添加大量图片、字体、音频等静态资源文件,包括用户界面图片、模板文件和安装界面素材 添加系统版本配置文件(.version)和常量定义文件(.constant) 更新供应商依赖文件,包括Symfony VarDumper组件和相关许可证文件 添加验证码配置文件(captcha.php)和.gitignore规则
This commit is contained in:
35
crmeb/basic/BaseAi.php
Normal file
35
crmeb/basic/BaseAi.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\services\AccessTokenServeService;
|
||||
|
||||
abstract class BaseAi extends BaseStorage
|
||||
{
|
||||
/**
|
||||
* access_token
|
||||
* @var null
|
||||
*/
|
||||
protected $accessToken = NULL;
|
||||
|
||||
/**
|
||||
* BaseProduct constructor.
|
||||
* @param string $name
|
||||
* @param AccessTokenServeService $accessTokenServeService
|
||||
* @param string $configFile
|
||||
*/
|
||||
public function __construct(string $name, AccessTokenServeService $accessTokenServeService, string $configFile)
|
||||
{
|
||||
parent::__construct($name, [], $configFile);
|
||||
$this->accessToken = $accessTokenServeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
}
|
||||
}
|
||||
BIN
crmeb/basic/BaseAuth.php
Executable file
BIN
crmeb/basic/BaseAuth.php
Executable file
Binary file not shown.
BIN
crmeb/basic/BaseController.php
Executable file
BIN
crmeb/basic/BaseController.php
Executable file
Binary file not shown.
104
crmeb/basic/BaseDelivery.php
Normal file
104
crmeb/basic/BaseDelivery.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
|
||||
/**
|
||||
* Class BaseDelivery
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BaseDelivery extends BaseStorage
|
||||
{
|
||||
|
||||
/**
|
||||
* 回调地址
|
||||
* @var null
|
||||
*/
|
||||
protected $callback_url = null;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config)
|
||||
{
|
||||
$this->callback_url = rtrim(sys_config('site_url'), '/') . '/api/city_delivery/notify';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function addMerchant($data); //注册商户
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function addShop($data); //创建门店
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function updateShop($data); //更新门店
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function addOrder($data); //发布订单
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function getOrderPrice($data); //计算订单价格
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function getOrderDetail($data); //获取订单详情
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function cancelOrder($data); //取消订单
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function getRecharge($data); //获取充值地址
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function getBalance($data); //获取余额
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function addTip($data); //支付小费
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function getCity($data); //获取城市信息
|
||||
|
||||
}
|
||||
50
crmeb/basic/BaseErp.php
Normal file
50
crmeb/basic/BaseErp.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\services\erp\AccessToken;
|
||||
|
||||
|
||||
abstract class BaseErp extends BaseStorage
|
||||
{
|
||||
/**
|
||||
* token句柄
|
||||
* @var AccessToken
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* 驱动类型
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* 配置文件名
|
||||
* @var string
|
||||
*/
|
||||
protected $configFile;
|
||||
|
||||
/**
|
||||
* BaseErp constructor.
|
||||
* @param string $name
|
||||
* @param AccessToken $accessToken
|
||||
* @param string $configFile
|
||||
*/
|
||||
public function __construct(string $name, AccessToken $accessToken, string $configFile)
|
||||
{
|
||||
parent::__construct($name, [], $configFile);
|
||||
$this->accessToken = $accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
// parent::initialize($config);
|
||||
}
|
||||
}
|
||||
76
crmeb/basic/BaseExpress.php
Normal file
76
crmeb/basic/BaseExpress.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\services\AccessTokenServeService;
|
||||
use crmeb\services\HttpService;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Config;
|
||||
use crmeb\services\CacheService;
|
||||
|
||||
/**
|
||||
* Class BaseExpress
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BaseExpress extends BaseStorage
|
||||
{
|
||||
|
||||
/**
|
||||
* access_token
|
||||
* @var null
|
||||
*/
|
||||
protected $accessToken = NULL;
|
||||
|
||||
|
||||
public function __construct(string $name, AccessTokenServeService $accessTokenServeService, string $configFile)
|
||||
{
|
||||
parent::__construct($name, [], $configFile);
|
||||
$this->accessToken = $accessTokenServeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
// parent::initialize($config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 开通服务
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function open();
|
||||
|
||||
/**物流追踪
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function query(string $num, string $com = '');
|
||||
|
||||
/**电子面单
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function dump($data);
|
||||
|
||||
/**快递公司
|
||||
* @return mixed
|
||||
*/
|
||||
//abstract public function express($type, $page, $limit);
|
||||
|
||||
/**面单模板
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function temp(string $com);
|
||||
}
|
||||
77
crmeb/basic/BaseJobs.php
Normal file
77
crmeb/basic/BaseJobs.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\interfaces\JobInterface;
|
||||
use think\queue\Job;
|
||||
|
||||
/**
|
||||
* 消息队列基类
|
||||
* Class BaseJobs
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
class BaseJobs implements JobInterface
|
||||
{
|
||||
/**
|
||||
* 运行消息队列
|
||||
* @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)
|
||||
{
|
||||
if (!class_exists(get_class($this))) {
|
||||
$job->delete();
|
||||
} else {
|
||||
$action = method_exists($this, $action) ? $action : 'handle';
|
||||
if (!method_exists($this, $action)) {
|
||||
$job->delete();
|
||||
} else {
|
||||
if ($this->{$action}(...$infoData)) {
|
||||
//删除任务
|
||||
$job->delete();
|
||||
} else {
|
||||
if ($job->attempts() >= $errorCount && $errorCount) {
|
||||
//删除任务
|
||||
$job->delete();
|
||||
} else {
|
||||
//从新放入队列
|
||||
$job->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function failed($data)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
219
crmeb/basic/BaseManager.php
Normal file
219
crmeb/basic/BaseManager.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use think\facade\Config;
|
||||
use think\helper\Str;
|
||||
use think\Container;
|
||||
|
||||
/**
|
||||
* 驱动基类
|
||||
* Class BaseManager
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BaseManager
|
||||
{
|
||||
/**
|
||||
* 驱动的命名空间
|
||||
* @var null
|
||||
*/
|
||||
protected string $namespace;
|
||||
|
||||
/**
|
||||
* 配置
|
||||
* @var null
|
||||
*/
|
||||
protected $configFile = null;
|
||||
|
||||
/**
|
||||
* 配置
|
||||
* @var array
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* 驱动
|
||||
* @var array
|
||||
*/
|
||||
protected $drivers = [];
|
||||
|
||||
/**
|
||||
* 驱动类型
|
||||
* @var null
|
||||
*/
|
||||
protected $name = null;
|
||||
|
||||
/**
|
||||
* BaseManager constructor.
|
||||
* @param string|array|int $name驱动名称
|
||||
* @param array $config 配置
|
||||
*/
|
||||
public function __construct($name = null, array $config = [])
|
||||
{
|
||||
$type = null;
|
||||
if (is_array($name)) {
|
||||
$config = $name;
|
||||
$name = null;
|
||||
}
|
||||
|
||||
if (is_int($name)) {
|
||||
$type = $name;
|
||||
$name = null;
|
||||
}
|
||||
|
||||
if ($name)
|
||||
$this->name = $name;
|
||||
if ($type && is_null($this->name)) {
|
||||
$this->setHandleType((int)$type - 1);
|
||||
}
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取配置文件名
|
||||
* @return $this
|
||||
*/
|
||||
protected function getConfigFile()
|
||||
{
|
||||
if (is_null($this->configFile)) {
|
||||
$this->configFile = strtolower((new \ReflectionClass($this))->getShortName());
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件句柄
|
||||
* @param int $type
|
||||
*/
|
||||
protected function setHandleType(int $type)
|
||||
{
|
||||
$this->getConfigFile();
|
||||
$stores = array_keys(Config::get($this->configFile . '.stores', []));
|
||||
$name = $stores[$type] ?? null;
|
||||
if (!$name) {
|
||||
throw new \RuntimeException($this->configFile . ' type is not used');
|
||||
}
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认句柄
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function getDefaultDriver();
|
||||
|
||||
/**
|
||||
* 动态调用
|
||||
* @param $method
|
||||
* @param $arguments
|
||||
*/
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
return $this->driver()->{$method}(...$arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取驱动实例
|
||||
* @param null|string $name
|
||||
* @return mixed
|
||||
*/
|
||||
protected function driver(string $name = null)
|
||||
{
|
||||
$name = $name ?: $this->name;
|
||||
$name = $name ?: $this->getDefaultDriver();
|
||||
|
||||
if (is_null($name)) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Unable to resolve NULL driver for [%s].', static::class
|
||||
));
|
||||
}
|
||||
|
||||
return $this->drivers[$name] = $this->getDriver($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取驱动实例
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getDriver(string $name)
|
||||
{
|
||||
return $this->drivers[$name] ?? $this->createDriver($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取驱动类型
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
protected function resolveType(string $name)
|
||||
{
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建驱动
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
protected function createDriver(string $name)
|
||||
{
|
||||
$type = $this->resolveType($name);
|
||||
|
||||
$method = 'create' . Str::studly($type) . 'Driver';
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->$method($name);
|
||||
}
|
||||
|
||||
$class = $this->resolveClass($type);
|
||||
$this->name = $type;
|
||||
return $this->invokeClass($class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取驱动类
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveClass(string $type): string
|
||||
{
|
||||
if ($this->namespace || false !== strpos($type, '\\')) {
|
||||
$class = false !== strpos($type, '\\') ? $type : $this->namespace . Str::studly($type);
|
||||
if (class_exists($class)) {
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException("Driver [$type] not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化类
|
||||
* @param $class
|
||||
* @return mixed
|
||||
*/
|
||||
protected function invokeClass($class)
|
||||
{
|
||||
if (!class_exists($class)) {
|
||||
throw new \RuntimeException('class not exists: ' . $class);
|
||||
}
|
||||
$this->getConfigFile();
|
||||
$handle = Container::getInstance()->invokeClass($class, [$this->name, $this->config, $this->configFile]);
|
||||
$this->config = [];
|
||||
return $handle;
|
||||
}
|
||||
|
||||
}
|
||||
152
crmeb/basic/BaseMessage.php
Normal file
152
crmeb/basic/BaseMessage.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use think\facade\Config;
|
||||
|
||||
abstract class BaseMessage extends BaseStorage
|
||||
{
|
||||
/**
|
||||
* 模板id
|
||||
* @var array
|
||||
*/
|
||||
protected $templateIds = [];
|
||||
|
||||
/**
|
||||
* openId
|
||||
* @var string
|
||||
*/
|
||||
protected $openId;
|
||||
|
||||
/**
|
||||
* 跳转链接
|
||||
* @var string
|
||||
*/
|
||||
protected $toUrl;
|
||||
|
||||
/**
|
||||
* 颜色
|
||||
* @var string
|
||||
*/
|
||||
protected $color;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config)
|
||||
{
|
||||
$this->templateIds = Config::get($this->configFile . '.stores.' . $this->name . '.template_id', []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否记录日志
|
||||
* @return mixed
|
||||
*/
|
||||
public function isLog()
|
||||
{
|
||||
$isLog = Config::get($this->configFile . 'isLog', false);
|
||||
return Config::get($this->configFile . '.stores.' . $this->name . '.isLog', $isLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板id
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateId()
|
||||
{
|
||||
return $this->templateIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* openid
|
||||
* @param string $openId
|
||||
* @return $this
|
||||
*/
|
||||
public function to(string $openId)
|
||||
{
|
||||
$this->openId = $openId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转路径
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url)
|
||||
{
|
||||
$this->toUrl = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置背景颜色
|
||||
* @param string $color
|
||||
* @return $this
|
||||
*/
|
||||
public function color(?string $color)
|
||||
{
|
||||
$this->color = $color;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取模板code
|
||||
* @param string $templateId
|
||||
* @return null
|
||||
*/
|
||||
protected function getTemplateCode(string $templateId)
|
||||
{
|
||||
return $this->templateIds[$templateId] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复默认值
|
||||
*/
|
||||
protected function clear()
|
||||
{
|
||||
$this->openId = null;
|
||||
$this->toUrl = null;
|
||||
$this->color = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
* @param string $templateId
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function send(string $templateId, array $data = []);
|
||||
|
||||
/**
|
||||
* 添加模板
|
||||
* @param string $shortId
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function add(string $shortId);
|
||||
|
||||
/**
|
||||
* 删除模板
|
||||
* @param string $templateId
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function delete(string $templateId);
|
||||
|
||||
/**
|
||||
* 获取所有模板
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function list();
|
||||
|
||||
}
|
||||
54
crmeb/basic/BaseModel.php
Normal file
54
crmeb/basic/BaseModel.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\traits\ModelTrait;
|
||||
use think\db\Query;
|
||||
use think\Model;
|
||||
use crmeb\topthink\HasManyThrough;
|
||||
|
||||
/**
|
||||
* Class BaseModel
|
||||
* @package crmeb\basic
|
||||
* @mixin ModelTrait
|
||||
* @mixin Query
|
||||
*/
|
||||
class BaseModel extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* 重写一对多关联
|
||||
* @param string $model
|
||||
* @param string $through
|
||||
* @param string $foreignKey
|
||||
* @param string $throughKey
|
||||
* @param string $localKey
|
||||
* @param string $throughPk
|
||||
* @return HasManyThrough
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/10/11
|
||||
*/
|
||||
public function hasManyThrough(string $model, string $through, string $foreignKey = '', string $throughKey = '', string $localKey = '', string $throughPk = ''): HasManyThrough
|
||||
{
|
||||
// 记录当前关联信息
|
||||
$model = $this->parseModel($model);
|
||||
$through = $this->parseModel($through);
|
||||
$localKey = $localKey ?: $this->getPk();
|
||||
$foreignKey = $foreignKey ?: $this->getForeignKey($this->name);
|
||||
$throughKey = $throughKey ?: $this->getForeignKey((new $through())->getName());
|
||||
$throughPk = $throughPk ?: (new $through())->getPk();
|
||||
|
||||
return new HasManyThrough($this, $model, $through, $foreignKey, $throughKey, $localKey, $throughPk);
|
||||
}
|
||||
|
||||
}
|
||||
50
crmeb/basic/BasePay.php
Normal file
50
crmeb/basic/BasePay.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace crmeb\basic;
|
||||
|
||||
/**
|
||||
* Class BasePay
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BasePay extends BaseStorage
|
||||
{
|
||||
|
||||
/**
|
||||
* 支付参数配置
|
||||
* @var array
|
||||
*/
|
||||
protected $configPay = [];
|
||||
|
||||
/**
|
||||
* 发起支付
|
||||
* @param array|null $configPay
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function pay(?array $configPay = []);
|
||||
|
||||
/**
|
||||
* 退款
|
||||
* @param array|null $configPay
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function refund(?array $configPay = []);
|
||||
|
||||
/**
|
||||
* 设置支付参数
|
||||
* @param array $configPay
|
||||
* @return $this
|
||||
*/
|
||||
public function setConfigPay(array $configPay)
|
||||
{
|
||||
$this->configPay = $configPay;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
61
crmeb/basic/BasePrinter.php
Normal file
61
crmeb/basic/BasePrinter.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\services\printer\AccessToken;
|
||||
|
||||
/**
|
||||
* Class BasePrinter
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BasePrinter extends BaseStorage
|
||||
{
|
||||
|
||||
/**
|
||||
* token句柄
|
||||
* @var AccessToken
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* 打印内容
|
||||
* @var string
|
||||
*/
|
||||
protected $printerContent;
|
||||
|
||||
/**
|
||||
* BasePrinter constructor.
|
||||
* @param string $name
|
||||
* @param AccessToken $accessToken
|
||||
* @param string $configFile
|
||||
*/
|
||||
public function __construct(string $name, AccessToken $accessToken, string $configFile)
|
||||
{
|
||||
parent::__construct($name, [], $configFile);
|
||||
$this->accessToken = $accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始打印
|
||||
* @param array|null $systemConfig
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function startPrinter();
|
||||
|
||||
/**
|
||||
* 设置打印内容
|
||||
* @param array $config
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function setPrinterContent(array $config);
|
||||
|
||||
}
|
||||
61
crmeb/basic/BaseProduct.php
Normal file
61
crmeb/basic/BaseProduct.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\services\AccessTokenServeService;
|
||||
|
||||
/**
|
||||
* Class BaseProduct
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BaseProduct extends BaseStorage
|
||||
{
|
||||
|
||||
/**
|
||||
* access_token
|
||||
* @var null
|
||||
*/
|
||||
protected $accessToken = NULL;
|
||||
|
||||
/**
|
||||
* BaseProduct constructor.
|
||||
* @param string $name
|
||||
* @param AccessTokenServeService $accessTokenServeService
|
||||
* @param string $configFile
|
||||
*/
|
||||
public function __construct(string $name, AccessTokenServeService $accessTokenServeService, string $configFile)
|
||||
{
|
||||
parent::__construct($name, [], $configFile);
|
||||
$this->accessToken = $accessTokenServeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed|void
|
||||
*/
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
// parent::initialize($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开通服务
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function open();
|
||||
|
||||
/**复制商品
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function goods(string $url);
|
||||
}
|
||||
107
crmeb/basic/BaseSmss.php
Normal file
107
crmeb/basic/BaseSmss.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\services\AccessTokenServeService;
|
||||
|
||||
/**
|
||||
* Class BaseSmss
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BaseSmss extends BaseStorage
|
||||
{
|
||||
|
||||
/**
|
||||
* access_token
|
||||
* @var null
|
||||
*/
|
||||
protected $accessToken = NULL;
|
||||
|
||||
/**
|
||||
* BaseSmss constructor.
|
||||
* @param string $name
|
||||
* @param AccessTokenServeService $accessTokenServeService
|
||||
* @param string $configFile
|
||||
*/
|
||||
public function __construct(string $name, AccessTokenServeService $accessTokenServeService, string $configFile, array $config = [])
|
||||
{
|
||||
$this->accessToken = $accessTokenServeService;
|
||||
$this->name = $name;
|
||||
$this->configFile = $configFile;
|
||||
$this->initialize($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @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);
|
||||
}
|
||||
56
crmeb/basic/BaseStorage.php
Normal file
56
crmeb/basic/BaseStorage.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
|
||||
/**
|
||||
* 容器基类
|
||||
* Class BaseStorage
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BaseStorage
|
||||
{
|
||||
use \crmeb\traits\ErrorTrait;
|
||||
|
||||
/**
|
||||
* 驱动名称
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* 驱动配置文件名
|
||||
* @var string
|
||||
*/
|
||||
protected $configFile;
|
||||
|
||||
/**
|
||||
* BaseStorage constructor.
|
||||
* @param string $name 驱动名
|
||||
* @param string $configFile 驱动配置名
|
||||
* @param array $config 其他配置
|
||||
*/
|
||||
public function __construct(string $name, array $config = [], string $configFile = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->configFile = $configFile;
|
||||
$this->initialize($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param array $config
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function initialize(array $config);
|
||||
|
||||
}
|
||||
459
crmeb/basic/BaseUpload.php
Normal file
459
crmeb/basic/BaseUpload.php
Normal file
@@ -0,0 +1,459 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\basic;
|
||||
|
||||
use crmeb\exceptions\UploadException;
|
||||
use think\facade\Config;
|
||||
|
||||
/**
|
||||
* Class BaseUpload
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
abstract class BaseUpload extends BaseStorage
|
||||
{
|
||||
/**
|
||||
* 缩略图
|
||||
* @var string[]
|
||||
*/
|
||||
protected array $thumb = ['big', 'mid', 'small'];
|
||||
|
||||
/**
|
||||
* 缩略图配置
|
||||
* @var array
|
||||
*/
|
||||
protected array $thumbConfig = [
|
||||
'thumb_big_height' => 700,
|
||||
'thumb_big_width' => 700,
|
||||
'thumb_mid_height' => 400,
|
||||
'thumb_mid_width' => 400,
|
||||
'thumb_small_height' => 100,
|
||||
'thumb_small_width' => 100,
|
||||
];
|
||||
/**
|
||||
* 水印配置
|
||||
* @var array
|
||||
*/
|
||||
protected array $waterConfig = [
|
||||
'image_watermark_status' => 0,
|
||||
'watermark_type' => 1,
|
||||
'watermark_image' => '',
|
||||
'watermark_opacity' => 0,
|
||||
'watermark_position' => 1,
|
||||
'watermark_rotate' => 0,
|
||||
'watermark_text' => '',
|
||||
'watermark_text_angle' => "",
|
||||
'watermark_text_color' => '#000000',
|
||||
'watermark_text_size' => '5',
|
||||
'watermark_text_font' => '',
|
||||
'watermark_x' => 0,
|
||||
'watermark_y' => 0
|
||||
];
|
||||
/**
|
||||
* 图片信息
|
||||
* @var array
|
||||
*/
|
||||
protected $fileInfo;
|
||||
/**
|
||||
* 下载图片信息
|
||||
*/
|
||||
protected $downFileInfo;
|
||||
|
||||
/**
|
||||
* 要生成缩略图、水印的图片地址
|
||||
* @var string
|
||||
*/
|
||||
protected string $filePath;
|
||||
|
||||
/**
|
||||
* 验证配置
|
||||
* @var string
|
||||
*/
|
||||
protected string $validate;
|
||||
|
||||
/**
|
||||
* 保存路径
|
||||
* @var string
|
||||
*/
|
||||
protected string $path = '';
|
||||
|
||||
/**
|
||||
* 是否自动裁剪
|
||||
* @var bool
|
||||
*/
|
||||
protected bool $authThumb = false;
|
||||
|
||||
protected function initialize(array $config)
|
||||
{
|
||||
$this->fileInfo = $this->downFileInfo = new \StdClass();
|
||||
$this->thumbConfig = array_merge($this->thumbConfig, $config['thumb'] ?? []);
|
||||
$this->waterConfig = array_merge($this->waterConfig, $config['water'] ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置处理缩略图、水印图片路径
|
||||
* @param string $filePath
|
||||
* @return $this
|
||||
*/
|
||||
public function setFilepath(string $filePath)
|
||||
{
|
||||
$this->filePath = substr($filePath, 0, 1) === '.' ? substr($filePath, 1) : $filePath;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否自动裁剪
|
||||
* @param bool $auth
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuthThumb(bool $auth)
|
||||
{
|
||||
$this->authThumb = $auth;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件路径
|
||||
* @param string $path
|
||||
* @return $this
|
||||
*/
|
||||
public function to(string $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件信息
|
||||
* @return array
|
||||
*/
|
||||
public function getFileInfo()
|
||||
{
|
||||
return $this->fileInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否是图片
|
||||
* @param $filePath
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkImage($filePath)
|
||||
{
|
||||
//获取图像信息
|
||||
$info = @getimagesize($filePath);
|
||||
//检测图像合法性
|
||||
if (false === $info || IMAGETYPE_GIF === $info[2] || empty($info['bits'])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证合法上传域名
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
protected function checkUploadUrl(string $url)
|
||||
{
|
||||
if ($url && strstr($url, 'http') === false) {
|
||||
$url = 'http://' . $url;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getConfig()
|
||||
{
|
||||
$config = Config::get($this->configFile . '.stores.' . $this->name, []);
|
||||
if (empty($config)) {
|
||||
$config['filesize'] = Config::get($this->configFile . '.filesize', []);
|
||||
$config['fileExt'] = Config::get($this->configFile . '.fileExt', []);
|
||||
$config['fileMime'] = Config::get($this->configFile . '.fileMime', []);
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置验证规则
|
||||
* @param array|null $validate
|
||||
* @return $this
|
||||
*/
|
||||
public function validate(?array $validate = null)
|
||||
{
|
||||
if (is_null($validate)) {
|
||||
$validate = $this->getConfig();
|
||||
}
|
||||
$this->extractValidate($validate);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证目录是否正确
|
||||
* @param string $key
|
||||
* @return false|string
|
||||
*/
|
||||
protected function getUploadPath(string $key)
|
||||
{
|
||||
$path = ($this->path ? $this->path . '/' : '') . $key;
|
||||
if ($path && $path[0] === '/') {
|
||||
$path = substr($path, 1);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取上传验证
|
||||
*/
|
||||
protected function extractValidate(array $validateArray)
|
||||
{
|
||||
$validate = [];
|
||||
foreach ($validateArray as $key => $value) {
|
||||
$validate[] = $key . ':' . (is_array($value) ? implode(',', $value) : $value);
|
||||
}
|
||||
$this->validate = implode('|', $validate);
|
||||
unset($validate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取文件名
|
||||
* @param string $path
|
||||
* @param string $ext
|
||||
* @return string
|
||||
*/
|
||||
protected function saveFileName(string $path = null, string $ext = 'jpg')
|
||||
{
|
||||
mt_srand();
|
||||
return ($path ? substr(md5($path), 0, 5) : '') . date('YmdHis') . rand(0, 9999) . '.' . $ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取文件后缀以及之前部分
|
||||
* @param string $path
|
||||
* @return false|string[]
|
||||
*/
|
||||
protected function getFileName(string $path)
|
||||
{
|
||||
$_empty = ['', ''];
|
||||
if (!$path) return $_empty;
|
||||
if (strpos($path, '?')) {
|
||||
$_tarr = explode('?', $path);
|
||||
$path = trim($_tarr[0]);
|
||||
}
|
||||
$arr = explode('.', $path);
|
||||
if (!is_array($arr) || count($arr) <= 1) return $_empty;
|
||||
$ext_name = trim($arr[count($arr) - 1]);
|
||||
$ext_name = !$ext_name ? 'jpg' : $ext_name;
|
||||
return [explode('.' . $ext_name, $path)[0], $ext_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片地址
|
||||
* @param string $filePath
|
||||
* @param bool $is_parse_url
|
||||
* @return string
|
||||
*/
|
||||
protected function getFilePath(string $filePath = '', bool $is_parse_url = false)
|
||||
{
|
||||
$path = $filePath ? $filePath : $this->filePath;
|
||||
if ($is_parse_url) {
|
||||
$data = parse_url($path);
|
||||
//远程地址处理
|
||||
if (isset($data['host']) && isset($data['path'])) {
|
||||
if (file_exists(app()->getRootPath() . 'public' . $data['path'])) {
|
||||
$path = $data['path'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件是否在本地
|
||||
* @param string $filePath
|
||||
* @return bool
|
||||
*/
|
||||
protected function isLocal(string $filePath)
|
||||
{
|
||||
$isLocal = false;
|
||||
$path = $filePath;
|
||||
$data = parse_url($path);
|
||||
//远程地址处理
|
||||
if (isset($data['host']) && isset($data['path'])) {
|
||||
if (file_exists(app()->getRootPath() . 'public' . $data['path'])) {
|
||||
$isLocal = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $isLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型和大小
|
||||
* @param string $url
|
||||
* @param bool $isData
|
||||
* @return array
|
||||
*/
|
||||
protected function getFileHeaders(string $url, $isData = true)
|
||||
{
|
||||
stream_context_set_default(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]);
|
||||
$header['size'] = 0;
|
||||
$header['type'] = 'image/jpeg';
|
||||
if (!$isData) {
|
||||
return $header;
|
||||
}
|
||||
try {
|
||||
$headerArray = get_headers(str_replace('\\', '/', $url), true);
|
||||
if (!isset($headerArray['Content-Length'])) {
|
||||
$header['size'] = 0;
|
||||
} else {
|
||||
if (is_array($headerArray['Content-Length']) && count($headerArray['Content-Length']) == 2) {
|
||||
$header['size'] = $headerArray['Content-Length'][1];
|
||||
} else {
|
||||
$header['size'] = $headerArray['Content-Length'] ?? 0;
|
||||
}
|
||||
}
|
||||
if (!isset($headerArray['Content-Type'])) {
|
||||
$header['type'] = 'image/jpeg';
|
||||
} else {
|
||||
if (is_array($headerArray['Content-Type']) && count($headerArray['Content-Type']) == 2) {
|
||||
$header['type'] = $headerArray['Content-Type'][1];
|
||||
} else {
|
||||
$header['type'] = $headerArray['Content-Type'] ?? 'image/jpeg';
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传信息
|
||||
* @return array
|
||||
*/
|
||||
public function getUploadInfo()
|
||||
{
|
||||
if (isset($this->fileInfo->filePath)) {
|
||||
if (strstr($this->fileInfo->filePath, 'http') === false) {
|
||||
$url = request()->domain() . $this->fileInfo->filePath;
|
||||
} else {
|
||||
$url = $this->fileInfo->filePath;
|
||||
}
|
||||
$headers = $this->getFileHeaders($url);
|
||||
return [
|
||||
'name' => $this->fileInfo->fileName,
|
||||
'real_name' => $this->fileInfo->realName ?? '',
|
||||
'size' => $headers['size'] ?? 0,
|
||||
'type' => $headers['type'] ?? 'image/jpeg',
|
||||
'dir' => $this->fileInfo->filePath,
|
||||
'thumb_path' => $this->fileInfo->filePath,
|
||||
'thumb_path_big' => $this->fileInfo->filePathBig ?? '',
|
||||
'thumb_path_mid' => $this->fileInfo->filePathMid ?? '',
|
||||
'thumb_path_small' => $this->fileInfo->filePathSmall ?? '',
|
||||
'thumb_path_water' => $this->fileInfo->filePathWater ?? '',
|
||||
'time' => time(),
|
||||
];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载信息
|
||||
* @return array
|
||||
*/
|
||||
public function getDownloadInfo()
|
||||
{
|
||||
if (isset($this->downFileInfo->downloadFilePath)) {
|
||||
if (strstr($this->downFileInfo->downloadFilePath, 'http') === false) {
|
||||
$url = request()->domain() . $this->downFileInfo->downloadFilePath;
|
||||
} else {
|
||||
$url = $this->downFileInfo->downloadFilePath;
|
||||
}
|
||||
$headers = $this->getFileHeaders($url);
|
||||
return [
|
||||
'name' => $this->downFileInfo->downloadFileName,
|
||||
'real_name' => $this->downFileInfo->downloadRealName ?? '',
|
||||
'size' => $headers['size'] ?? 0,
|
||||
'type' => $headers['type'] ?? 'image/jpeg',
|
||||
'dir' => $this->downFileInfo->downloadFilePath ?? '',
|
||||
'thumb_path' => $this->downFileInfo->downloadFilePath ?? '',
|
||||
'time' => time(),
|
||||
];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证文件后缀是否为非法文件
|
||||
* @param string $key
|
||||
* @return void
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/10/9
|
||||
*/
|
||||
public function verifyExtension(string $key)
|
||||
{
|
||||
$parseUrl = parse_url($key);
|
||||
$path = $parseUrl['path'] ?? '';
|
||||
$extension = pathinfo($path)['extension'] ?? '';
|
||||
$fileExt = app()->config->get('upload.fileExt');
|
||||
if (!in_array($extension, $fileExt)) {
|
||||
throw new UploadException('文件类型错误,支持:' . implode('、', $fileExt));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function move(string $file = 'file');
|
||||
|
||||
/**
|
||||
* 文件流上传
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function stream(string $fileContent, string $key = null);
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function delete(string $filePath);
|
||||
|
||||
/**
|
||||
* 实例化上传
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function app();
|
||||
|
||||
/**
|
||||
* 获取上传密钥
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function getTempKeys();
|
||||
|
||||
/**
|
||||
* 获取缩略图
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function thumb(string $filePath = '');
|
||||
|
||||
/**
|
||||
* 添加水印
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function water(string $filePath = '');
|
||||
|
||||
}
|
||||
46
crmeb/command/Dao.php
Normal file
46
crmeb/command/Dao.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace crmeb\command;
|
||||
|
||||
use think\console\command\Make;
|
||||
|
||||
/**
|
||||
* Class Business
|
||||
* @package crmeb\command
|
||||
*/
|
||||
class Dao extends Make
|
||||
{
|
||||
protected $type = "Dao";
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setName('make:dao')
|
||||
->setDescription('Create a new service class');
|
||||
}
|
||||
|
||||
protected function getStub(): string
|
||||
{
|
||||
return __DIR__ . DIRECTORY_SEPARATOR. 'stubs' . DIRECTORY_SEPARATOR . 'dao.stub';
|
||||
}
|
||||
|
||||
protected function getNamespace(string $app): string
|
||||
{
|
||||
return parent::getNamespace($app) . '\\dao';
|
||||
}
|
||||
|
||||
protected function getPathName(string $name): string
|
||||
{
|
||||
$name = str_replace('app\\', '', $name);
|
||||
|
||||
return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . 'Dao.php';
|
||||
}
|
||||
}
|
||||
430
crmeb/command/Install.php
Normal file
430
crmeb/command/Install.php
Normal file
@@ -0,0 +1,430 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\command;
|
||||
|
||||
use app\services\system\admin\SystemAdminServices;
|
||||
use app\services\system\config\SystemConfigServices;
|
||||
use crmeb\services\MysqlBackupService;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\console\Table;
|
||||
|
||||
class Install extends Command
|
||||
{
|
||||
|
||||
protected $host;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('install')
|
||||
->addArgument('status', Argument::OPTIONAL, 'start/remove')
|
||||
->addOption('h', null, Option::VALUE_REQUIRED, '网站域名')
|
||||
->addOption('db', null, Option::VALUE_NONE, '是否卸载数据库')
|
||||
->setDescription('命令行一键安装/卸载');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$status = $input->getArgument('status') ?: 'start';
|
||||
|
||||
$database = env('database.database');
|
||||
if (in_array($status, ['start', 'remove'])) {
|
||||
if (!env('database.hostname') ||
|
||||
!$database ||
|
||||
!env('database.username') ||
|
||||
!env('database.password') ||
|
||||
!env('database.hostport')
|
||||
) {
|
||||
$output->error('请先配置数据库,确保数据库能正常连接!');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($input->hasOption('h')) {
|
||||
$this->host = $input->getOption('h');
|
||||
}
|
||||
if (!$status || !in_array($status, ['start', 'remove'])) {
|
||||
$question = $output->choice($input, ' 请选择执行指令数字 ', ['start' => '1', 'remove' => '-1', 'exit' => 0]);
|
||||
if ($question === 'exit') {
|
||||
$output->info('您已退出命令');
|
||||
return;
|
||||
} else {
|
||||
$status = $question;
|
||||
}
|
||||
}
|
||||
if ($status === 'remove') {
|
||||
$this->remove($input, $output);
|
||||
} elseif ($status === 'start') {
|
||||
$this->start($input, $output);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始安装
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @throws \think\db\exception\BindParamException
|
||||
*/
|
||||
protected function start(Input $input, Output $output)
|
||||
{
|
||||
$installLockDir = root_path('public') . 'install/install.lock';
|
||||
if (file_exists($installLockDir)) {
|
||||
$crmeb = get_crmeb_version();
|
||||
$question = $output->confirm($input, '您已经安装' . $crmeb . '版本是否重新安装,重新安装会清除掉之前的数据请谨慎操作?', false);
|
||||
if ($question) {
|
||||
$res = $this->authBackups();
|
||||
if (!$res) {
|
||||
$output->info('已退出安装程序');
|
||||
}
|
||||
$database = env('database.database');
|
||||
$this->dropTable($database);
|
||||
|
||||
unlink($installLockDir);
|
||||
} else {
|
||||
$output->info('已退出安装程序');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$installSql = file_get_contents(root_path('public' . DIRECTORY_SEPARATOR . 'install') . 'crmeb.sql');
|
||||
if (!$installSql) {
|
||||
$output->error('读取安装sql失败,请检查安装sql文件权限,再次尝试安装!');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->query($installSql);
|
||||
|
||||
$this->cleanTable();
|
||||
|
||||
$this->output->writeln('+---------------------------- [创建管理员] ---------------------------------+');
|
||||
$this->output->newLine();
|
||||
[$account, $password] = $this->createAdmin();
|
||||
|
||||
file_put_contents($installLockDir, time());
|
||||
|
||||
$output->info('安装完成!!请妥善保管您的账号密码!');
|
||||
$output->info('账号:' . $account);
|
||||
$output->info('密码:' . $password);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建账号
|
||||
*/
|
||||
protected function createAdmin()
|
||||
{
|
||||
$account = $this->adminAccount();
|
||||
$password = $this->adminPassword();
|
||||
/** @var SystemAdminServices $service */
|
||||
$service = app()->make(SystemAdminServices::class);
|
||||
$tablepre = env('database.prefix');
|
||||
$this->app->db->query('truncate table ' . $tablepre . 'system_admin');
|
||||
try {
|
||||
$service->create(['conf_pwd' => $password, 'roles' => [1], 'pwd' => $password, 'account' => $account, 'level' => 0, 'status' => 1]);
|
||||
} catch (\Throwable $e) {
|
||||
$this->output->writeln($e->getMessage());
|
||||
$this->output->newLine();
|
||||
[$account, $password] = $this->createAdmin();
|
||||
}
|
||||
|
||||
if ($this->host) {
|
||||
/** @var SystemConfigServices $configService */
|
||||
$configService = app()->make(SystemConfigServices::class);
|
||||
$configService->update('site_url', ['value' => json_encode($this->host)], 'menu_name');
|
||||
}
|
||||
|
||||
return [$account, $password];
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载程序
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @throws \think\db\exception\BindParamException
|
||||
*/
|
||||
protected function remove(Input $input, Output $output)
|
||||
{
|
||||
$installLockDir = root_path('public') . 'install/install.lock';
|
||||
if (!file_exists($installLockDir)) {
|
||||
$this->output->info('你尚未安装本程序');
|
||||
return;
|
||||
}
|
||||
$database = env('database.database');
|
||||
$output->info(' 正在进行卸载中...');
|
||||
|
||||
$this->authBackups();
|
||||
|
||||
if ($input->hasOption('db')) {
|
||||
$question = $output->confirm($input, '您确定要清除掉[' . $database . ']数据吗?', false);
|
||||
if ($question) {
|
||||
$this->dropTable($database);
|
||||
}
|
||||
}
|
||||
|
||||
unlink($installLockDir);
|
||||
|
||||
$this->output->info('卸载完成');
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有表数据
|
||||
* @param string $database
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\BindParamException
|
||||
*/
|
||||
protected function dropTable(string $database)
|
||||
{
|
||||
$this->output->writeln('+---------------------------- [清理表数据] ---------------------------------+');
|
||||
$this->output->newLine();
|
||||
$this->output->write("\r 正在清理表数据");
|
||||
|
||||
/** @var MysqlBackupService $service */
|
||||
$service = app()->make(MysqlBackupService::class, [[
|
||||
//数据库备份卷大小
|
||||
'compress' => 1,
|
||||
//数据库备份文件是否启用压缩 0不压缩 1 压缩
|
||||
'level' => 5,
|
||||
]]);
|
||||
$dataList = $service->dataList();
|
||||
$tableName = array_column($dataList, 'name');
|
||||
$count = count($tableName);
|
||||
if ($count) {
|
||||
$res = $this->app->db->transaction(function () use ($database, $tableName) {
|
||||
foreach ($tableName as $name) {
|
||||
$this->app->db->query('DROP TABLE ' . $name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$this->output->write("\r 已清理完毕");
|
||||
$this->output->newLine(2);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行安装sql
|
||||
* @param string $installSql
|
||||
*/
|
||||
protected function query(string $installSql)
|
||||
{
|
||||
$tablepre = env('database.prefix');
|
||||
$sqlArray = $this->sqlSplit($installSql, $tablepre);
|
||||
$table = new Table();
|
||||
$this->output->writeln('+----------------------------- [SQL安装] -----------------------------------+');
|
||||
$this->output->newLine();
|
||||
$header = ['表名', '执行结果', '错误原因', '时间'];
|
||||
$table->setHeader($header);
|
||||
foreach ($sqlArray as $sql) {
|
||||
$sql = trim($sql);
|
||||
if (strstr($sql, 'CREATE TABLE')) {
|
||||
preg_match('/CREATE TABLE (IF NOT EXISTS)? `eb_([^ ]*)`/is', $sql, $matches);
|
||||
$tableName = $tablepre . ($matches[2] ?? '');
|
||||
} else {
|
||||
$tableName = '';
|
||||
}
|
||||
try {
|
||||
$this->app->db->transaction(function () use ($tablepre, $sql, $tableName) {
|
||||
|
||||
$sql = str_replace('`eb_', '`' . $tablepre, $sql);//替换表前缀
|
||||
$this->app->db->query($sql);
|
||||
|
||||
});
|
||||
|
||||
$tableName && $table->addRow([$tableName, 'ok', '无错误', date('Y-m-d H:i:s')]);
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
$tableName && $table->addRow([$tableName, 'x', $e->getMessage(), date('Y-m-d H:i:s')]);
|
||||
}
|
||||
}
|
||||
$this->output->writeln($table->render());
|
||||
$this->output->newLine(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 账号
|
||||
* @return bool|mixed|string
|
||||
*/
|
||||
protected function adminAccount()
|
||||
{
|
||||
$account = $this->output->ask($this->input, '请输入后台登陆账号,最少4个字符', null, function ($value) {
|
||||
if (strlen($value) < 4) {
|
||||
return false;
|
||||
}
|
||||
return $value;
|
||||
});
|
||||
if (!$account) {
|
||||
$this->output->error('账号至少4个字符');
|
||||
$this->output->newLine();
|
||||
$account = $this->adminAccount();
|
||||
}
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码
|
||||
* @return bool|mixed|string|null
|
||||
*/
|
||||
protected function adminPassword()
|
||||
{
|
||||
$password = $this->output->ask($this->input, '请输入登陆密码,密码为数字加字母/字母加符号/数字加字符的组合不能少于6位');
|
||||
if (!preg_match('/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^<>&*]+$)[a-zA-Z\d!@#$%^&<>*]{6,16}$/', $password)) {
|
||||
$this->output->error('请输入符合要求的密码');
|
||||
$this->output->newLine();
|
||||
$password = $this->adminPassword();
|
||||
}
|
||||
return $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清楚多余数据
|
||||
*/
|
||||
protected function cleanTable()
|
||||
{
|
||||
$tablepre = env('database.prefix');
|
||||
$database = env('database.database');
|
||||
$blTable = ['eb_system_admin', 'eb_system_role', 'eb_system_config', 'eb_system_config_tab',
|
||||
'eb_system_menus', 'eb_system_file', 'eb_express', 'eb_system_group', 'eb_system_group_data',
|
||||
'eb_template_message', 'eb_shipping_templates', "eb_shipping_templates_region",
|
||||
"eb_shipping_templates_free", 'eb_system_city', 'eb_diy', 'eb_member_ship', 'eb_member_right',
|
||||
'eb_agreement', 'eb_store_service_speechcraft', 'eb_system_user_level', 'eb_cache'];
|
||||
if ($tablepre !== 'eb_') {
|
||||
$blTable = array_map(function ($name) use ($tablepre) {
|
||||
return str_replace('eb_', $tablepre, $name);
|
||||
}, $blTable);
|
||||
}
|
||||
$tableList = $this->app->db->query("select table_name from information_schema.tables where table_schema='$database'");
|
||||
$tableList = array_column($tableList, 'table_name');
|
||||
foreach ($tableList as $table) {
|
||||
if (!in_array($table, $blTable)) {
|
||||
$this->app->db->query('truncate table ' . $table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 切割sql
|
||||
* @param $sql
|
||||
* @return array
|
||||
*/
|
||||
protected function sqlSplit(string $sql, string $tablepre)
|
||||
{
|
||||
if ($tablepre != "tp_")
|
||||
$sql = str_replace("tp_", $tablepre, $sql);
|
||||
|
||||
$sql = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=utf8", $sql);
|
||||
|
||||
$sql = str_replace("\r", "\n", $sql);
|
||||
$ret = [];
|
||||
$num = 0;
|
||||
$queriesarray = explode(";\n", trim($sql));
|
||||
unset($sql);
|
||||
foreach ($queriesarray as $query) {
|
||||
$ret[$num] = '';
|
||||
$queries = explode("\n", trim($query));
|
||||
$queries = array_filter($queries);
|
||||
foreach ($queries as $query) {
|
||||
$str1 = substr($query, 0, 1);
|
||||
if ($str1 != '#' && $str1 != '-')
|
||||
$ret[$num] .= $query;
|
||||
}
|
||||
$num++;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动备份表
|
||||
* @return bool|mixed|string|null
|
||||
* @throws \think\db\exception\BindParamException
|
||||
*/
|
||||
protected function authBackups(bool $g = false)
|
||||
{
|
||||
/** @var MysqlBackupService $service */
|
||||
$service = app()->make(MysqlBackupService::class, [[
|
||||
//数据库备份卷大小
|
||||
'compress' => 1,
|
||||
//数据库备份文件是否启用压缩 0不压缩 1 压缩
|
||||
'level' => 5,
|
||||
]]);
|
||||
$dataList = $service->dataList();
|
||||
$tableName = array_column($dataList, 'name');
|
||||
$count = count($tableName);
|
||||
if ($count) {
|
||||
$this->output->writeln('+----------------------------- [自动备份] ----------------------------------+');
|
||||
$this->output->newLine();
|
||||
$this->output->newLine();
|
||||
$this->output->writeln(' 正在自动备份[start]');
|
||||
|
||||
$data = [];
|
||||
foreach ($tableName as $i => $t) {
|
||||
|
||||
// $equalStr = str_repeat("=", $i);
|
||||
// $space = str_repeat(" ", $count - $i);
|
||||
// $this->output->write("\r [$equalStr>$space]($i/$count%)");
|
||||
$this->output->writeln(' 已备份:' . $t . ' 完成:(' . ($i + 1) . '/' . $count . ')');
|
||||
|
||||
$res = $service->backup($t, 0);
|
||||
if ($res == false && $res != 0) {
|
||||
$data [] = $t;
|
||||
}
|
||||
}
|
||||
|
||||
$this->output->writeln("\r\n 备份结束[end]");
|
||||
|
||||
if ($data && $g) {
|
||||
return $this->output->confirm($this->input, '自动备份表失败,失败数据库表:' . implode('|', $data) . ';是否继续执行?');
|
||||
}
|
||||
$this->output->newLine();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建进度条
|
||||
* @param $percent
|
||||
* @return string
|
||||
*/
|
||||
protected function buildLine($percent)
|
||||
{
|
||||
$repeatTimes = 100;
|
||||
if ($percent > 0) {
|
||||
$hasColor = str_repeat('■', $percent);
|
||||
} else {
|
||||
$hasColor = '';
|
||||
}
|
||||
|
||||
if ($repeatTimes - $percent > 0) {
|
||||
$noColor = str_repeat(' ', $repeatTimes - $percent);
|
||||
} else {
|
||||
$noColor = '';
|
||||
}
|
||||
|
||||
$buffer = sprintf("[{$hasColor}{$noColor}]");
|
||||
if ($percent !== 100) {
|
||||
$percentString = sprintf("[ %-6s]", $percent . '%');
|
||||
} else {
|
||||
$percentString = sprintf("[ %-5s]", 'OK');
|
||||
}
|
||||
|
||||
return $percentString . $buffer . "\r";
|
||||
}
|
||||
}
|
||||
46
crmeb/command/Service.php
Normal file
46
crmeb/command/Service.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace crmeb\command;
|
||||
|
||||
use think\console\command\Make;
|
||||
|
||||
/**
|
||||
* Class Business
|
||||
* @package crmeb\command
|
||||
*/
|
||||
class Service extends Make
|
||||
{
|
||||
protected $type = "Service";
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setName('make:service')
|
||||
->setDescription('Create a new service class');
|
||||
}
|
||||
|
||||
protected function getStub(): string
|
||||
{
|
||||
return __DIR__ . DIRECTORY_SEPARATOR. 'stubs' . DIRECTORY_SEPARATOR . 'service.stub';
|
||||
}
|
||||
|
||||
protected function getNamespace(string $app): string
|
||||
{
|
||||
return parent::getNamespace($app) . '\\services';
|
||||
}
|
||||
|
||||
protected function getPathName(string $name): string
|
||||
{
|
||||
$name = str_replace('app\\', '', $name);
|
||||
|
||||
return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . 'Services.php';
|
||||
}
|
||||
}
|
||||
35
crmeb/command/stubs/dao.stub
Normal file
35
crmeb/command/stubs/dao.stub
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace {%namespace%};
|
||||
|
||||
use app\dao\BaseDao;
|
||||
use app\model\***\{%className%};
|
||||
|
||||
/**
|
||||
*
|
||||
* Class {%className%}Dao
|
||||
* @package {%namespace%}
|
||||
*/
|
||||
class {%className%}Dao extends BaseDao
|
||||
{
|
||||
|
||||
/**
|
||||
* 设置模型
|
||||
* @return string
|
||||
*/
|
||||
protected function setModel(): string
|
||||
{
|
||||
return {%className%}::class;
|
||||
}
|
||||
|
||||
}
|
||||
35
crmeb/command/stubs/service.stub
Normal file
35
crmeb/command/stubs/service.stub
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace {%namespace%};
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\dao\***\{%className%}Dao;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class {%className%}Services
|
||||
* @package {%namespace%}
|
||||
*/
|
||||
class {%className%}Services extends BaseServices
|
||||
{
|
||||
|
||||
/**
|
||||
* {%className%}Services constructor.
|
||||
* @param {%className%}Dao $dao
|
||||
*/
|
||||
public function __construct({%className%}Dao $dao)
|
||||
{
|
||||
$this->dao = $dao;
|
||||
}
|
||||
|
||||
}
|
||||
35
crmeb/exceptions/AdminException.php
Normal file
35
crmeb/exceptions/AdminException.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class AuthException
|
||||
* @package crmeb\exceptions
|
||||
*/
|
||||
class AdminException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message, $code = 0, Throwable $previous = null)
|
||||
{
|
||||
if(is_array($message)){
|
||||
$errInfo = $message;
|
||||
$message = $errInfo[1] ?? '未知错误';
|
||||
if ($code === 0) {
|
||||
$code = $errInfo[0] ?? 400;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
33
crmeb/exceptions/ApiException.php
Normal file
33
crmeb/exceptions/ApiException.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
/**
|
||||
* API应用错误信息
|
||||
* Class ApiException
|
||||
* @package crmeb\exceptions
|
||||
*/
|
||||
class ApiException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message, $code = 0, \Throwable $previous = null)
|
||||
{
|
||||
if (is_array($message)) {
|
||||
$errInfo = $message;
|
||||
$message = $errInfo[1] ?? '未知错误';
|
||||
if ($code === 0) {
|
||||
$code = $errInfo[0] ?? 400;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
35
crmeb/exceptions/AuthException.php
Normal file
35
crmeb/exceptions/AuthException.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class AuthException
|
||||
* @package crmeb\exceptions
|
||||
*/
|
||||
class AuthException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
if (is_array($message)) {
|
||||
$errInfo = $message;
|
||||
$message = $errInfo[1] ?? '未知错误';
|
||||
if ($code === 0) {
|
||||
$code = $errInfo[0] ?? 400;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
20
crmeb/exceptions/BadMethodCallException.php
Normal file
20
crmeb/exceptions/BadMethodCallException.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
|
||||
class BadMethodCallException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
||||
16
crmeb/exceptions/ErpException.php
Normal file
16
crmeb/exceptions/ErpException.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
|
||||
use Throwable;
|
||||
|
||||
class ErpException extends \RuntimeException
|
||||
{
|
||||
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
32
crmeb/exceptions/PayException.php
Normal file
32
crmeb/exceptions/PayException.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
/**
|
||||
* Class PayException
|
||||
* @package crmeb\exceptions
|
||||
*/
|
||||
class PayException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
if (is_array($message)) {
|
||||
$errInfo = $message;
|
||||
$message = $errInfo[1] ?? '未知错误';
|
||||
if ($code === 0) {
|
||||
$code = $errInfo[0] ?? 400;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
35
crmeb/exceptions/SmsException.php
Normal file
35
crmeb/exceptions/SmsException.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class AuthException
|
||||
* @package crmeb\exceptions
|
||||
*/
|
||||
class SmsException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
if (is_array($message)) {
|
||||
$errInfo = $message;
|
||||
$message = $errInfo[1] ?? '未知错误';
|
||||
if ($code === 0) {
|
||||
$code = $errInfo[0] ?? 400;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
35
crmeb/exceptions/TemplateException.php
Normal file
35
crmeb/exceptions/TemplateException.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class TemplateException
|
||||
* @package crmeb\exceptions
|
||||
*/
|
||||
class TemplateException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
if (is_array($message)) {
|
||||
$errInfo = $message;
|
||||
$message = $errInfo[1] ?? '未知错误';
|
||||
if ($code === 0) {
|
||||
$code = $errInfo[0] ?? 400;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
35
crmeb/exceptions/UploadException.php
Normal file
35
crmeb/exceptions/UploadException.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class AuthException
|
||||
* @package crmeb\exceptions
|
||||
*/
|
||||
class UploadException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
if (is_array($message)) {
|
||||
$errInfo = $message;
|
||||
$message = $errInfo[1] ?? '未知错误';
|
||||
if ($code === 0) {
|
||||
$code = $errInfo[0] ?? 400;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
35
crmeb/exceptions/WechatReplyException.php
Normal file
35
crmeb/exceptions/WechatReplyException.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\exceptions;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 微信消息回复错误
|
||||
* Class WechatReplyException
|
||||
* @package crmeb\exceptions
|
||||
*/
|
||||
class WechatReplyException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
if (is_array($message)) {
|
||||
$errInfo = $message;
|
||||
$message = $errInfo[1] ?? '未知错误';
|
||||
if ($code === 0) {
|
||||
$code = $errInfo[0] ?? 400;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
121
crmeb/form/BaseComponent.php
Normal file
121
crmeb/form/BaseComponent.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form;
|
||||
|
||||
/**
|
||||
* 基础组件集成
|
||||
* Class BaseComponent
|
||||
* @package crmeb\form
|
||||
*/
|
||||
abstract class BaseComponent
|
||||
{
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $init = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [];
|
||||
|
||||
/**
|
||||
* 数据库验证
|
||||
* @var array
|
||||
*/
|
||||
protected $validate = [];
|
||||
|
||||
/**
|
||||
* @var CommonRule
|
||||
*/
|
||||
protected $validataRule;
|
||||
|
||||
/**
|
||||
* 是否实例化
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
if (!$this->init) {
|
||||
$this->validataRule = new CommonRule;
|
||||
$this->init = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 多个验证规则
|
||||
* @param array $validate
|
||||
* @return $this
|
||||
*/
|
||||
public function validates(array $validate)
|
||||
{
|
||||
$this->validate = $validate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个验证规则
|
||||
* @param CommonRule $validate
|
||||
* @return $this
|
||||
*/
|
||||
public function validate(CommonRule $validate)
|
||||
{
|
||||
$this->validate[] = $validate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否必填
|
||||
* @return $this
|
||||
*/
|
||||
public function required()
|
||||
{
|
||||
$this->init();
|
||||
$this->validataRule->required();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置提示消息
|
||||
* @param string $message
|
||||
* @return $this
|
||||
*/
|
||||
public function message(string $message)
|
||||
{
|
||||
$this->init();
|
||||
$this->validataRule->message($message);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据写入
|
||||
*/
|
||||
protected function before()
|
||||
{
|
||||
if (!$this->validate && $this->validataRule instanceof CommonRule) {
|
||||
if (!$this->validataRule->getMessage() && $this->rule['title']) {
|
||||
$this->validataRule->message('请输入' . $this->rule['title']);
|
||||
}
|
||||
$this->validate[] = $this->validataRule->toArray();
|
||||
}
|
||||
$validate = [];
|
||||
foreach ($this->validate as $item) {
|
||||
if ($item instanceof CommonRule) {
|
||||
$validate[] = $item->toArray();
|
||||
} else {
|
||||
$validate[] = $item;
|
||||
}
|
||||
}
|
||||
$this->rule['validate'] = $validate;
|
||||
}
|
||||
}
|
||||
262
crmeb/form/Build.php
Normal file
262
crmeb/form/Build.php
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form;
|
||||
|
||||
|
||||
use crmeb\form\components\Address;
|
||||
use crmeb\form\components\Alert;
|
||||
use crmeb\form\components\Card;
|
||||
use crmeb\form\components\CheckBox;use crmeb\form\components\DiyTable;
|
||||
use crmeb\form\components\Input;
|
||||
use crmeb\form\components\InputNumber;
|
||||
use crmeb\form\components\Map;
|
||||
use crmeb\form\components\Radio;
|
||||
use crmeb\form\components\Select;
|
||||
use crmeb\form\components\Switchs;
|
||||
use crmeb\form\components\Tabs;
|
||||
use crmeb\form\components\Time;
|
||||
use crmeb\form\components\UploadFrame;
|
||||
use crmeb\form\components\UploadImage;
|
||||
|
||||
/**
|
||||
* Class Build
|
||||
* @package crmeb\form
|
||||
* @method Input input(string $field, string $title, $value = null)
|
||||
* @method Tabs tabs(array $options = [])
|
||||
* @method Card card(string $title)
|
||||
* @method InputNumber inputNum(string $field, string $title, $value = null)
|
||||
* @method Select select(string $field, string $title, $value = null)
|
||||
* @method UploadFrame uploadFrame(string $field, string $title, $value = null)
|
||||
* @method UploadImage uploadImage(string $field, string $title, $value = null)
|
||||
* @method Radio radio(string $field, string $title, $value = null)
|
||||
* @method CheckBox checkbox(string $field, string $title, $value = null)
|
||||
* @method Switchs switch (string $field, string $title, $value = null)
|
||||
* @method Alert alert (string $title, string $type = '', bool $closable = false, bool $showIcon = false)
|
||||
* @method DiyTable diyTable(string $field, string $title, array $value = [], array $options = [])
|
||||
* @method Map map(string $field, string $title, $value = null)
|
||||
* @method Address address(string $field, string $title, $value = null)
|
||||
* @method Time time(string $field, string $title, $value = null)
|
||||
*/
|
||||
class Build
|
||||
{
|
||||
|
||||
/**
|
||||
* 挂载组件
|
||||
* @var string[]
|
||||
*/
|
||||
protected static array $components = [
|
||||
'input' => Input::class,
|
||||
'tabs' => Tabs::class,
|
||||
'card' => Card::class,
|
||||
'inputNum' => InputNumber::class,
|
||||
'select' => Select::class,
|
||||
'uploadFrame' => UploadFrame::class,
|
||||
'uploadImage' => UploadImage::class,
|
||||
'radio' => Radio::class,
|
||||
'switch' => Switchs::class,
|
||||
'alert' => Alert::class,
|
||||
'diyTable' => DiyTable::class,
|
||||
'address' => Address::class,
|
||||
'map' => Map::class,
|
||||
'time' => Time::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected array $rule = [];
|
||||
|
||||
/**
|
||||
* 请求地址
|
||||
* @var
|
||||
*/
|
||||
protected ?string $url;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $method = 'POST';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected array $data = [];
|
||||
|
||||
/**
|
||||
* Build constructor.
|
||||
* @param string|null $url
|
||||
* @param array $rule
|
||||
* @param string|null $method
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(string $url = null, array $rule = [], string $method = null, array $data = [])
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->rule = $rule;
|
||||
$this->method = $method ?: 'POST';
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $rule
|
||||
* @return $this
|
||||
*/
|
||||
public function rule(array $rule = [])
|
||||
{
|
||||
$this->rule = $rule;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return $this
|
||||
*/
|
||||
public function method(string $method)
|
||||
{
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Build
|
||||
*/
|
||||
public function data(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置数据
|
||||
* @param $rule
|
||||
* @return mixed
|
||||
*/
|
||||
public function setValue($rule)
|
||||
{
|
||||
if (!$this->data) {
|
||||
return $rule;
|
||||
}
|
||||
foreach ($rule as &$value) {
|
||||
if (isset($value['value']) && $value['value'] !== '' && isset($value['field'])) {
|
||||
$value['value'] = $this->data[$value['field']];
|
||||
}
|
||||
if (isset($value['options']) && $value['options']) {
|
||||
foreach ($value['options'] as $i => $option) {
|
||||
if (isset($option['componentsModel']) && $option['componentsModel']) {
|
||||
$value['options'][$i] = $this->setValue($option['componentsModel']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($value['control']) && $value['control']) {
|
||||
foreach ($value['control'] as $ii => $control) {
|
||||
if (isset($control['componentsModel']) && $control['componentsModel']) {
|
||||
$value['control'][$ii] = $this->setValue($control['componentsModel']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($value['componentsModel']) && $value['componentsModel']) {
|
||||
$value['componentsModel'] = $this->setValue($value['componentsModel']);
|
||||
}
|
||||
}
|
||||
return $rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取验证值
|
||||
* @param $rule
|
||||
* @return array
|
||||
*/
|
||||
protected function getValidate($rule)
|
||||
{
|
||||
$validate = [];
|
||||
foreach ($rule as $value) {
|
||||
if (isset($value['field']) && isset($value['validate']) && $value['validate']) {
|
||||
$validate[$value['field']] = $value['validate'];
|
||||
}
|
||||
if (isset($value['options']) && $value['options']) {
|
||||
foreach ($value['options'] as $option) {
|
||||
if (isset($option['componentsModel']) && $option['componentsModel']) {
|
||||
$validate = array_merge($validate, $this->getValidate($option['componentsModel']));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($value['control']) && $value['control']) {
|
||||
foreach ($value['control'] as $control) {
|
||||
if (isset($control['componentsModel']) && $control['componentsModel']) {
|
||||
$validate = array_merge($validate, $this->getValidate($control['componentsModel']));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($value['componentsModel']) && $value['componentsModel']) {
|
||||
$validate = array_merge($validate, $this->getValidate($value['componentsModel']));
|
||||
}
|
||||
}
|
||||
return $validate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$rule = [];
|
||||
foreach ($this->rule as $item) {
|
||||
if ($item instanceof BuildInterface) {
|
||||
$rule[] = $item->toArray();
|
||||
}
|
||||
}
|
||||
$data = [
|
||||
'rules' => $this->setValue($rule),
|
||||
'validate' => $this->getValidate($rule),
|
||||
'url' => $this->url,
|
||||
'method' => $this->method
|
||||
];
|
||||
$data['validate'] = $data['validate'] ?: (object)[];
|
||||
$this->url = null;
|
||||
$this->rule = [];
|
||||
$this->method = 'POST';
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return json_encode($this->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
$compKeys = array_keys(self::$components);
|
||||
if (in_array($name, $compKeys)) {
|
||||
return new self::$components[$name](...$arguments);
|
||||
}
|
||||
throw new BuildException('Method does not exist');
|
||||
}
|
||||
}
|
||||
27
crmeb/form/BuildException.php
Normal file
27
crmeb/form/BuildException.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form;
|
||||
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class BuildException
|
||||
* @package crmeb\form
|
||||
*/
|
||||
class BuildException extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
24
crmeb/form/BuildInterface.php
Normal file
24
crmeb/form/BuildInterface.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form;
|
||||
|
||||
|
||||
/**
|
||||
* Interface BuildInterface
|
||||
* @package crmeb\form
|
||||
*/
|
||||
interface BuildInterface
|
||||
{
|
||||
|
||||
public function toArray(): array;
|
||||
|
||||
}
|
||||
180
crmeb/form/CommonRule.php
Normal file
180
crmeb/form/CommonRule.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form;
|
||||
|
||||
/**
|
||||
* Class CommonRule
|
||||
* @package crmeb\form
|
||||
*/
|
||||
class CommonRule implements BuildInterface
|
||||
{
|
||||
/**
|
||||
* 验证类型
|
||||
*/
|
||||
const VALIDATE_TYPE = ['string', 'number', 'boolean', 'method', 'regexp', 'integer', 'float', 'array', 'object', 'enum', 'date', 'url', 'hex', 'email'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $required = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $pattern = '';
|
||||
|
||||
/**
|
||||
* 枚举值
|
||||
* @var array
|
||||
*/
|
||||
protected $enum = [];
|
||||
|
||||
/**
|
||||
* 提示语
|
||||
* @var string
|
||||
*/
|
||||
protected $message = '';
|
||||
|
||||
/**
|
||||
* 深度验证对象
|
||||
* @var array
|
||||
*/
|
||||
protected $fields = [];
|
||||
|
||||
/**
|
||||
* 验证触发方式
|
||||
* @var string
|
||||
*/
|
||||
protected $trigger = 'blur';
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function type(string $type)
|
||||
{
|
||||
$this->type = in_array($type, self::VALIDATE_TYPE) ? $type : null;
|
||||
if (!$this->type) {
|
||||
throw new FormValidate('验证类型错误');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否必填
|
||||
* @return $this
|
||||
*/
|
||||
public function required()
|
||||
{
|
||||
$this->required = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置错误提示
|
||||
* @param string $message
|
||||
* @return $this
|
||||
*/
|
||||
public function message(string $message)
|
||||
{
|
||||
$this->message = $message;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提示语
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* 枚举数据
|
||||
* @param array $enum
|
||||
* @return $this
|
||||
*/
|
||||
public function enum(array $enum)
|
||||
{
|
||||
$this->enum = $enum;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 正则表达式
|
||||
* @param string $pattern
|
||||
* @return $this
|
||||
*/
|
||||
public function pattern(string $pattern)
|
||||
{
|
||||
$this->pattern = $pattern;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证规则
|
||||
* @param string|array|BuildInterface $field
|
||||
* @param array $rule
|
||||
* @return $this
|
||||
*/
|
||||
public function field($field, array $rule = [])
|
||||
{
|
||||
if (!in_array($this->type, ['array', 'object'])) {
|
||||
throw new BuildException('无效规则,类型只能在array或者object情况下才可设置');
|
||||
}
|
||||
if ($this->type === 'array') {
|
||||
$rules = [];
|
||||
if ($field instanceof BuildInterface) {
|
||||
$rules = $field->toArray();
|
||||
}
|
||||
$this->fields[] = $rules;
|
||||
} else {
|
||||
$rules = [];
|
||||
foreach ($rule as $item) {
|
||||
if ($item instanceof BuildInterface) {
|
||||
$rules[] = $item->toArray();
|
||||
}
|
||||
}
|
||||
$this->fields[$field] = $rules;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据转换
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$data = [
|
||||
'required' => $this->required,
|
||||
'message' => $this->message,
|
||||
'trigger' => $this->trigger,
|
||||
'pattern' => $this->pattern,
|
||||
'enum' => $this->enum,
|
||||
'type' => $this->type
|
||||
];
|
||||
$res = [];
|
||||
foreach ($data as $key => $value) {
|
||||
if (is_bool($value) || $value) {
|
||||
$res[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
25
crmeb/form/FormValidate.php
Normal file
25
crmeb/form/FormValidate.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form;
|
||||
|
||||
|
||||
/**
|
||||
* Class FormValidate
|
||||
* @package crmeb\form
|
||||
*/
|
||||
class FormValidate extends \RuntimeException
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
70
crmeb/form/components/Address.php
Normal file
70
crmeb/form/components/Address.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 选择地址
|
||||
* Class Addres
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class Address extends BaseComponent implements BuildInterface
|
||||
{
|
||||
|
||||
const NAME = 'address';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'field' => '',
|
||||
'value' => '',
|
||||
'info' => '',
|
||||
];
|
||||
|
||||
/**
|
||||
* Map constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param array $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, array $value = null)
|
||||
{
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['value'] = empty($value) ? '' : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string[]
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
102
crmeb/form/components/Alert.php
Normal file
102
crmeb/form/components/Alert.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 警告框
|
||||
* Class Alert
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class Alert implements BuildInterface
|
||||
{
|
||||
|
||||
//组件名
|
||||
const NAME = 'alert';
|
||||
//提示类型
|
||||
const INFO = 'info';
|
||||
//成功类型
|
||||
const SUCCESS = 'success';
|
||||
//警告类型
|
||||
const WARNING = 'warning';
|
||||
//错误类型
|
||||
const ERROR = 'error';
|
||||
//组件类型
|
||||
const TYPE = [self::INFO, self::SUCCESS, self::WARNING, self::ERROR];
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'type' => '',
|
||||
'closable' => false,
|
||||
'showIcon' => false
|
||||
];
|
||||
|
||||
/**
|
||||
* Alert constructor.
|
||||
* @param string $title
|
||||
* @param string $type
|
||||
* @param bool $closable
|
||||
* @param bool $showIcon
|
||||
*/
|
||||
public function __construct(string $title, string $type = '', bool $closable = false, bool $showIcon = false)
|
||||
{
|
||||
$this->rule['type'] = in_array($type, self::TYPE) ? $type : '';
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['closable'] = $closable;
|
||||
$this->rule['showIcon'] = $showIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置类型
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function type(string $type)
|
||||
{
|
||||
$this->rule['type'] = in_array($type, self::TYPE) ? $type : '';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否可关闭
|
||||
* @param bool $closable
|
||||
* @return $this
|
||||
*/
|
||||
public function closable(bool $closable = false)
|
||||
{
|
||||
$this->rule['closable'] = $closable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否展示图标
|
||||
* @param bool $showIcon
|
||||
* @return $this
|
||||
*/
|
||||
public function showIcon(bool $showIcon = false)
|
||||
{
|
||||
$this->rule['showIcon'] = $showIcon;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
74
crmeb/form/components/Card.php
Normal file
74
crmeb/form/components/Card.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 卡片组件
|
||||
* Class Card
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class Card implements BuildInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
const NAME = 'card';
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'componentsModel' => [],
|
||||
'title' => '',
|
||||
];
|
||||
|
||||
/**
|
||||
* Card constructor.
|
||||
* @param string $title
|
||||
*/
|
||||
public function __construct(string $title)
|
||||
{
|
||||
$this->rule['title'] = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加组件群
|
||||
* @param array $components
|
||||
* @return $this
|
||||
*/
|
||||
public function components(array $components = [])
|
||||
{
|
||||
$this->rule['componentsModel'] = $components;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$componentsModel = [];
|
||||
foreach ($this->rule['componentsModel'] as $item) {
|
||||
if ($item instanceof BuildInterface) {
|
||||
$componentsModel[] = $item->toArray();
|
||||
}
|
||||
}
|
||||
$this->rule['componentsModel'] = $componentsModel;
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
90
crmeb/form/components/CheckBox.php
Normal file
90
crmeb/form/components/CheckBox.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 多选组件
|
||||
* Class CheckBox
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class CheckBox extends BaseComponent implements BuildInterface
|
||||
{
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
const NAME = 'checkbox';
|
||||
|
||||
/**
|
||||
* 组件规则
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'field' => '',
|
||||
'value' => [],
|
||||
'info' => '',
|
||||
'options' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Radio constructor.
|
||||
* @param string $title
|
||||
* @param string $field
|
||||
* @param null $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, array $value = null)
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['value'] = !is_null($value) ? $value : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* options数据 ['label'=>'确定','value'=>1]
|
||||
* @param array $options
|
||||
* @return $this
|
||||
*/
|
||||
public function options(array $options = [])
|
||||
{
|
||||
$this->rule['options'] = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置提示语
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据转换
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
91
crmeb/form/components/DiyTable.php
Normal file
91
crmeb/form/components/DiyTable.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 自定义表格
|
||||
* Class DiyTable
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class DiyTable extends BaseComponent implements BuildInterface
|
||||
{
|
||||
/**
|
||||
* 组件名称
|
||||
*/
|
||||
const NAME = 'diyTable';
|
||||
|
||||
//内部表格自定义类型
|
||||
const TYPE = ['input', 'select', 'inputNumber', 'switch'];
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'value' => [],
|
||||
'type' => '',
|
||||
'field' => '',
|
||||
'options' => [],
|
||||
'info' => '',
|
||||
];
|
||||
|
||||
/**
|
||||
* DiyTable constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param array $value
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(string $field, string $title, array $value = [], array $options = [])
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['options'] = $options;
|
||||
$this->rule['value'] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置列
|
||||
* @param string $name
|
||||
* @param string $key
|
||||
* @param string $type
|
||||
* @param array $props
|
||||
* @return $this
|
||||
*/
|
||||
public function column(string $name, string $key, string $type = 'input', array $props = [])
|
||||
{
|
||||
$this->rule['options'][] = ['name' => $name, 'key' => $key, 'type' => $type, 'props' => $props];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
132
crmeb/form/components/Input.php
Normal file
132
crmeb/form/components/Input.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 输入框组件
|
||||
* Class Input
|
||||
* @package crmeb\form\components
|
||||
* @method Input info(string $info) 设置info
|
||||
* @method Input placeholder(string $placeholder) 设置placeholder
|
||||
* @method Input suffix(string $suffix) 输入框头部图标
|
||||
* @method Input prefix(string $prefix) 输入框尾部图标
|
||||
* @method Input value($value) 设置value
|
||||
* @method Input rows(int $rows) 设置rows
|
||||
* @method Input type(string $type) 设置type
|
||||
* @method Input maxlength(int $maxlength) 设置maxlength
|
||||
*/
|
||||
class Input extends BaseComponent implements BuildInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* 组件名称
|
||||
*/
|
||||
const NAME = 'input';
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'value' => '',
|
||||
'type' => '',
|
||||
'field' => '',
|
||||
'info' => '',
|
||||
'disabled' => false,
|
||||
'placeholder' => '',
|
||||
'suffix' => '',
|
||||
'prefix' => '',
|
||||
'rows' => 2,
|
||||
'copy' => false,
|
||||
'copyText' => '',
|
||||
'randToken' => 0,
|
||||
'maxlength' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Input constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param null $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, $value = null)
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['value'] = empty($value) ? '' : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否禁用
|
||||
* @param bool $disabled
|
||||
* @return $this
|
||||
*/
|
||||
public function disabled(bool $disabled = true)
|
||||
{
|
||||
$this->rule['disabled'] = $disabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机token
|
||||
* @return $this
|
||||
*/
|
||||
public function randToken()
|
||||
{
|
||||
$this->rule['randToken'] = 1;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机encodingAESKeyGen
|
||||
* @return $this
|
||||
*/
|
||||
public function randAESK()
|
||||
{
|
||||
$this->rule['randToken'] = 2;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制按钮
|
||||
* @param string $copyText
|
||||
* @return $this
|
||||
*/
|
||||
public function copy(string $copyText = '复制')
|
||||
{
|
||||
$this->rule['copy'] = true;
|
||||
$this->rule['copyText'] = $copyText;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (in_array($name, ['title', 'field', 'disabled', 'copyText'])) {
|
||||
return $this;
|
||||
}
|
||||
$keys = array_keys($this->rule);
|
||||
if (in_array($name, $keys)) {
|
||||
$this->rule[$name] = $arguments[0] ?? null;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
118
crmeb/form/components/InputNumber.php
Normal file
118
crmeb/form/components/InputNumber.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 数字输入框
|
||||
* Class InputNumber
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class InputNumber extends BaseComponent implements BuildInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
const NAME = 'inputNumber';
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'value' => '',
|
||||
'type' => '',
|
||||
'field' => '',
|
||||
'prefix' => '',
|
||||
'suffix' => '',
|
||||
'info' => '',
|
||||
'min' => null,
|
||||
'max' => 99999999
|
||||
];
|
||||
|
||||
/**
|
||||
* InputNumber constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param null $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, $value = null)
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['value'] = floatval($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提示语
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最小值
|
||||
* @param int $min
|
||||
* @return $this
|
||||
*/
|
||||
public function min(int $min)
|
||||
{
|
||||
$this->rule['min'] = $min;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最大值
|
||||
* @param int $max
|
||||
* @return $this
|
||||
*/
|
||||
public function max(int $max)
|
||||
{
|
||||
$this->rule['max'] = $max;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string[]
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (in_array($name, ['title', 'field'])) {
|
||||
return $this;
|
||||
}
|
||||
$keys = array_keys($this->rule);
|
||||
if (in_array($name, $keys)) {
|
||||
$this->rule[$name] = $arguments[0] ?? null;
|
||||
}
|
||||
}
|
||||
}
|
||||
70
crmeb/form/components/Map.php
Normal file
70
crmeb/form/components/Map.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 地图组件
|
||||
* Class Map
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class Map extends BaseComponent implements BuildInterface
|
||||
{
|
||||
|
||||
const NAME = 'map';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'field' => '',
|
||||
'value' => '',
|
||||
'info' => '',
|
||||
];
|
||||
|
||||
/**
|
||||
* Map constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param string $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, string $value = null)
|
||||
{
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['value'] = empty($value) ? '' : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string[]
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
134
crmeb/form/components/Radio.php
Normal file
134
crmeb/form/components/Radio.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 单选框组件
|
||||
* Class Radio
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class Radio extends BaseComponent implements BuildInterface
|
||||
{
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
const NAME = 'radio';
|
||||
|
||||
/**
|
||||
* 组件规则
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'field' => '',
|
||||
'value' => 0,
|
||||
'info' => '',
|
||||
'vertical' => false,
|
||||
'control' => [],
|
||||
'options' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Radio constructor.
|
||||
* @param string $title
|
||||
* @param string $field
|
||||
* @param null $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, $value = null)
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['value'] = !is_null($value) ? $value : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多个组件联动
|
||||
* @param array $controls
|
||||
* @return $this
|
||||
*/
|
||||
public function controls(array $controls = [])
|
||||
{
|
||||
$this->rule['control'] = $controls;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* options数据 ['label'=>'确定','value'=>1]
|
||||
* @param array $options
|
||||
* @return $this
|
||||
*/
|
||||
public function options(array $options = [])
|
||||
{
|
||||
$this->rule['options'] = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件联动
|
||||
* @param $value
|
||||
* @param array $components
|
||||
* @return $this
|
||||
*/
|
||||
public function control($value, array $components = [])
|
||||
{
|
||||
$this->rule['control'][] = ['value' => $value, 'componentsModel' => $components];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置提示语
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否垂直展示
|
||||
* @param bool $vertical
|
||||
* @return $this
|
||||
*/
|
||||
public function vertical(bool $vertical)
|
||||
{
|
||||
$this->rule['vertical'] = $vertical;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据转换
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$control = [];
|
||||
foreach ($this->rule['control'] as $item) {
|
||||
$data = ['value' => $item['value'], 'componentsModel' => []];
|
||||
foreach ($item['componentsModel'] as $value) {
|
||||
if ($value instanceof BuildInterface) {
|
||||
$data['componentsModel'][] = $value->toArray();
|
||||
}
|
||||
}
|
||||
$control[] = $data;
|
||||
}
|
||||
$this->rule['control'] = $control;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
90
crmeb/form/components/Select.php
Normal file
90
crmeb/form/components/Select.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 多选组件
|
||||
* Class Select
|
||||
* @package crmeb\form\components
|
||||
* @method placeholder(string $placeholder)
|
||||
* @method options(array $options = [])
|
||||
* @method info(string $info)
|
||||
*/
|
||||
class Select extends BaseComponent implements BuildInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
const NAME = 'select';
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'value' => '',
|
||||
'type' => '',
|
||||
'field' => '',
|
||||
'info' => '',
|
||||
'placeholder' => '',
|
||||
'options' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Radio constructor.
|
||||
* @param string $title
|
||||
* @param string $field
|
||||
* @param null $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, $value = null)
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['value'] = !is_null($value) ? $value : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换数据
|
||||
* @return array|string[]
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (in_array($name, ['title', 'field'])) {
|
||||
return $this;
|
||||
}
|
||||
$keys = array_keys($this->rule);
|
||||
if (in_array($name, $keys)) {
|
||||
$this->rule[$name] = $arguments[0] ?? null;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
135
crmeb/form/components/Switchs.php
Normal file
135
crmeb/form/components/Switchs.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 开关组件
|
||||
* Class Switchs
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class Switchs extends BaseComponent implements BuildInterface
|
||||
{
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
const NAME = 'switch';
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'field' => '',
|
||||
'value' => '',
|
||||
'info' => '',
|
||||
'control' => [],
|
||||
'options' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Switchs constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param int $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, int $value = null)
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['value'] = !is_null($value) ? intval($value) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多组件群添加
|
||||
* @param array $controls
|
||||
* @return $this
|
||||
*/
|
||||
public function controls(array $controls = [])
|
||||
{
|
||||
$this->rule['control'] = $controls;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件联动添加
|
||||
* @param $value
|
||||
* @param array $components
|
||||
* @return $this
|
||||
*/
|
||||
public function control(int $value, array $components = [])
|
||||
{
|
||||
$this->rule['control'][] = ['value' => $value, 'componentsModel' => $components];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启值和名称设置
|
||||
* @param string $label
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function trueValue(string $label, int $value)
|
||||
{
|
||||
$this->rule['options'][] = ['trueValue' => $value, 'label' => $label];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭值和名称设置
|
||||
* @param string $label
|
||||
* @param int $value
|
||||
* @return $this
|
||||
*/
|
||||
public function falseValue(string $label, int $value)
|
||||
{
|
||||
$this->rule['options'][] = ['falseValue' => $value, 'label' => $label];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置提示信息
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据转换
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$control = [];
|
||||
foreach ($this->rule['control'] as $item) {
|
||||
$data = ['value' => $item['value'], 'componentsModel' => []];
|
||||
foreach ($item['componentsModel'] as $value) {
|
||||
if ($value instanceof BuildInterface) {
|
||||
$data['componentsModel'][] = $value->toArray();
|
||||
}
|
||||
}
|
||||
$control[] = $data;
|
||||
}
|
||||
$this->rule['control'] = $control;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
76
crmeb/form/components/Tabs.php
Normal file
76
crmeb/form/components/Tabs.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* Tabs 组件
|
||||
* Class Tabs
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class Tabs implements BuildInterface
|
||||
{
|
||||
|
||||
//组件名
|
||||
const NAME = 'tabs';
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var array[]
|
||||
*/
|
||||
protected $rule = [
|
||||
'options' => []
|
||||
];
|
||||
|
||||
/**
|
||||
* Tabs constructor.
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
$this->rule['options'] = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加单个选项卡组件群
|
||||
* @param string $label
|
||||
* @param array $components
|
||||
* @return $this
|
||||
*/
|
||||
public function option(string $label, array $components = [])
|
||||
{
|
||||
$this->rule['options'][] = ['label' => $label, 'componentsModel' => $components];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|array[]
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$options = [];
|
||||
foreach ($this->rule['options'] as $option) {
|
||||
$data = ['label' => $option['label'], 'componentsModel' => []];
|
||||
foreach ($option['componentsModel'] as $item) {
|
||||
if ($item instanceof BuildInterface) {
|
||||
$data['componentsModel'][] = $item->toArray();
|
||||
}
|
||||
}
|
||||
$options[] = $data;
|
||||
}
|
||||
$this->rule['options'] = $options;
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
85
crmeb/form/components/Time.php
Normal file
85
crmeb/form/components/Time.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 时间组件
|
||||
* Class Time
|
||||
* @package crmeb\form\components
|
||||
* @method Time info(string $info) 设置info
|
||||
* @method Time value($value) 设置value
|
||||
* @method Time type(string $type) 设置type
|
||||
* @method Time placeholder(string $placeholder) 设置placeholder
|
||||
*/
|
||||
class Time extends BaseComponent implements BuildInterface
|
||||
{
|
||||
|
||||
const NAME = 'time';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rule = [
|
||||
'title' => '',
|
||||
'value' => '',
|
||||
'field' => '',
|
||||
'info' => '',
|
||||
'placeholder' => '',
|
||||
'format' => 'HH:mm:ss',
|
||||
'type' => 'timerange'
|
||||
];
|
||||
|
||||
/**
|
||||
* Time constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param array|null $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, array $value = null)
|
||||
{
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['value'] = empty($value) ? '' : $value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return array|string[]
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (in_array($name, ['title', 'field', 'disabled', 'copyText'])) {
|
||||
return $this;
|
||||
}
|
||||
$keys = array_keys($this->rule);
|
||||
if (in_array($name, $keys)) {
|
||||
$this->rule[$name] = $arguments[0] ?? null;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
140
crmeb/form/components/UploadFrame.php
Normal file
140
crmeb/form/components/UploadFrame.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 图片选择组件
|
||||
* Class UploadFrame
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class UploadFrame extends BaseComponent implements BuildInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
const NAME = 'uploadFrame';
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'upload' => [
|
||||
'url' => '',
|
||||
'width' => '960px',
|
||||
'height' => '505px',
|
||||
'field' => 'att_dir',
|
||||
'maxNum' => 1,
|
||||
],
|
||||
'field' => '',
|
||||
'title' => '',
|
||||
'value' => '',
|
||||
'info' => '',
|
||||
];
|
||||
|
||||
/**
|
||||
* UploadFrame constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param null $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, $value = null)
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['value'] = !is_null($value) ? $value : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置iframe跳转地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url)
|
||||
{
|
||||
$this->rule['upload']['url'] = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置iframe宽
|
||||
* @param string $width
|
||||
* @return $this
|
||||
*/
|
||||
public function width(string $width = '960px')
|
||||
{
|
||||
$this->rule['upload']['width'] = $width;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置iframe高
|
||||
* @param string $height
|
||||
* @return $this
|
||||
*/
|
||||
public function height(string $height = '505px')
|
||||
{
|
||||
$this->rule['upload']['height'] = $height;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置提取字段
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function field(string $field)
|
||||
{
|
||||
$this->rule['upload']['field'] = $field;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多图单图选择
|
||||
* @param int $maxNum
|
||||
* @return $this
|
||||
*/
|
||||
public function maxNum(int $maxNum = 1)
|
||||
{
|
||||
$this->rule['upload']['maxNum'] = $maxNum;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置提示
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
if ($this->rule['upload']['maxNum'] > 1 && $this->rule['value'] && !is_array($this->rule['value'])) {
|
||||
$this->rule['value'] = [];
|
||||
}
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
156
crmeb/form/components/UploadImage.php
Normal file
156
crmeb/form/components/UploadImage.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\components;
|
||||
|
||||
|
||||
use crmeb\form\BaseComponent;
|
||||
use crmeb\form\BuildInterface;
|
||||
|
||||
/**
|
||||
* 文件上传组件
|
||||
* Class UploadImage
|
||||
* @package crmeb\form\components
|
||||
*/
|
||||
class UploadImage extends BaseComponent implements BuildInterface
|
||||
{
|
||||
|
||||
// 组件名
|
||||
const NAME = 'uploadImage';
|
||||
//图片类型
|
||||
const IMAGE = 'image';
|
||||
//文件类型
|
||||
const FILE = 'file';
|
||||
//上传支持类型
|
||||
const TYPE = [self::IMAGE, self::FILE];
|
||||
|
||||
/**
|
||||
* 规则
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [
|
||||
'upload' => [
|
||||
'url' => '',
|
||||
'size' => 2097152,
|
||||
'format' => [],
|
||||
'headers' => [],
|
||||
'maxNum' => 1,
|
||||
],
|
||||
'field' => '',
|
||||
'type' => '',
|
||||
'title' => '',
|
||||
'icon' => '',
|
||||
'info' => '',
|
||||
'value' => ''
|
||||
];
|
||||
|
||||
/**
|
||||
* UploadImage constructor.
|
||||
* @param string $field
|
||||
* @param string $title
|
||||
* @param null $value
|
||||
*/
|
||||
public function __construct(string $field, string $title, $value = null)
|
||||
{
|
||||
$this->rule['title'] = $title . ':';
|
||||
$this->rule['field'] = $field;
|
||||
$this->rule['value'] = !is_null($value) ? $value : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url)
|
||||
{
|
||||
$this->rule['upload']['url'] = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传类型
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function type(string $type)
|
||||
{
|
||||
$this->rule['type'] = in_array($type, self::TYPE) ? $type : '';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传展示icon
|
||||
* @param string $icon
|
||||
* @return $this
|
||||
*/
|
||||
public function icon(string $icon)
|
||||
{
|
||||
$this->rule['icon'] = $icon;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件headers
|
||||
* @param array $headers
|
||||
* @return $this
|
||||
*/
|
||||
public function headers(array $headers = [])
|
||||
{
|
||||
$this->rule['upload']['headers'] = (object)$headers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件大小
|
||||
* @param string $size
|
||||
* @return $this
|
||||
*/
|
||||
public function size(string $size)
|
||||
{
|
||||
$this->rule['upload']['size'] = $size;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件类型
|
||||
* @param array $format
|
||||
* @return $this
|
||||
*/
|
||||
public function format(array $format = [])
|
||||
{
|
||||
$this->rule['upload']['format'] = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件提示
|
||||
* @param string $info
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info)
|
||||
{
|
||||
$this->rule['info'] = $info;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->rule['name'] = self::NAME;
|
||||
$this->before();
|
||||
return $this->rule;
|
||||
}
|
||||
}
|
||||
30
crmeb/form/validate/ArrRules.php
Normal file
30
crmeb/form/validate/ArrRules.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
|
||||
/**
|
||||
* 数组
|
||||
* Class ArrRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class ArrRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'array';
|
||||
}
|
||||
}
|
||||
72
crmeb/form/validate/BaseRules.php
Normal file
72
crmeb/form/validate/BaseRules.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
|
||||
use crmeb\form\CommonRule;
|
||||
|
||||
/**
|
||||
* Class BaseRules
|
||||
* @package crmeb\form\validate
|
||||
* @method CommonRule required() 是否必填
|
||||
* @method CommonRule message(string $message) 设置错误提示
|
||||
* @method CommonRule enum(array $enum) 枚举
|
||||
* @method CommonRule pattern(string $pattern) 正则表达式
|
||||
* @method CommonRule field($field, array $rule = []) 验证规则
|
||||
*/
|
||||
abstract class BaseRules
|
||||
{
|
||||
/**
|
||||
* 是否初始化
|
||||
* @var bool
|
||||
*/
|
||||
protected static $init = false;
|
||||
|
||||
/**
|
||||
* @var CommonRule
|
||||
*/
|
||||
protected static $rule;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
if (!self::$init) {
|
||||
self::$rule = new CommonRule();
|
||||
self::$rule->type(static::getType());
|
||||
self::$init = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
self::init();
|
||||
if (method_exists(self::$rule, $name)) {
|
||||
return self::$rule->{$name}(...$arguments);
|
||||
}
|
||||
throw new FormValidate(__CLASS__ . ' Method does not exist' . $name . '()');
|
||||
}
|
||||
}
|
||||
29
crmeb/form/validate/BoolRules.php
Normal file
29
crmeb/form/validate/BoolRules.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* 布尔
|
||||
* Class BoolRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class BoolRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'boolean';
|
||||
}
|
||||
}
|
||||
29
crmeb/form/validate/DateRules.php
Normal file
29
crmeb/form/validate/DateRules.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* 日期
|
||||
* Class DateRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class DateRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'date';
|
||||
}
|
||||
}
|
||||
29
crmeb/form/validate/EmailRules.php
Normal file
29
crmeb/form/validate/EmailRules.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
* Class EmailRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class EmailRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'email';
|
||||
}
|
||||
}
|
||||
29
crmeb/form/validate/EnumRules.php
Normal file
29
crmeb/form/validate/EnumRules.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* 枚举
|
||||
* Class EnumRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class EnumRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'enum';
|
||||
}
|
||||
}
|
||||
29
crmeb/form/validate/FloatRules.php
Normal file
29
crmeb/form/validate/FloatRules.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* 浮点
|
||||
* Class FloatRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class FloatRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'float';
|
||||
}
|
||||
}
|
||||
28
crmeb/form/validate/FunRules.php
Normal file
28
crmeb/form/validate/FunRules.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class FunRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class FunRules extends BaseRules
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'method';
|
||||
}
|
||||
}
|
||||
29
crmeb/form/validate/HexRules.php
Normal file
29
crmeb/form/validate/HexRules.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* 16进制
|
||||
* Class HexRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class HexRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'hex';
|
||||
}
|
||||
}
|
||||
28
crmeb/form/validate/IntRules.php
Normal file
28
crmeb/form/validate/IntRules.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* Class IntRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class IntRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'integer';
|
||||
}
|
||||
}
|
||||
28
crmeb/form/validate/NumRules.php
Normal file
28
crmeb/form/validate/NumRules.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* Class NumRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class NumRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'number';
|
||||
}
|
||||
}
|
||||
27
crmeb/form/validate/ObjRules.php
Normal file
27
crmeb/form/validate/ObjRules.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* Class ObjRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class ObjRules extends BaseRules
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'object';
|
||||
}
|
||||
}
|
||||
27
crmeb/form/validate/RegRules.php
Normal file
27
crmeb/form/validate/RegRules.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* Class RegRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class RegRules extends BaseRules
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'regexp';
|
||||
}
|
||||
}
|
||||
37
crmeb/form/validate/StrRules.php
Normal file
37
crmeb/form/validate/StrRules.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
use crmeb\form\FormValidate;
|
||||
|
||||
/**
|
||||
* Class StrRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class StrRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* 手机号正则
|
||||
*/
|
||||
const PHONE_NUMBER = '/((\d{3,4}-)?[0-9]{7,8}$)|(^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])[0-9]{8}$)/';
|
||||
|
||||
/**
|
||||
* 设置类型
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'string';
|
||||
}
|
||||
|
||||
}
|
||||
28
crmeb/form/validate/UrlRules.php
Normal file
28
crmeb/form/validate/UrlRules.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\form\validate;
|
||||
|
||||
/**
|
||||
* Class UrlRules
|
||||
* @package crmeb\form\validate
|
||||
*/
|
||||
class UrlRules extends BaseRules
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string
|
||||
{
|
||||
return 'url';
|
||||
}
|
||||
}
|
||||
42
crmeb/interfaces/HandlerInterface.php
Normal file
42
crmeb/interfaces/HandlerInterface.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\interfaces;
|
||||
|
||||
use Swoole\Websocket\Frame;
|
||||
use think\Request;
|
||||
|
||||
interface HandlerInterface
|
||||
{
|
||||
/**
|
||||
* "onOpen" listener.
|
||||
*
|
||||
* @param int $fd
|
||||
* @param Request $request
|
||||
*/
|
||||
public function onOpen($fd, Request $request);
|
||||
|
||||
/**
|
||||
* "onMessage" listener.
|
||||
* only triggered when event handler not found
|
||||
*
|
||||
* @param Frame $frame
|
||||
*/
|
||||
public function onMessage(Frame $frame);
|
||||
|
||||
/**
|
||||
* "onClose" listener.
|
||||
*
|
||||
* @param int $fd
|
||||
* @param int $reactorId
|
||||
*/
|
||||
public function onClose($fd, $reactorId);
|
||||
}
|
||||
20
crmeb/interfaces/JobInterface.php
Normal file
20
crmeb/interfaces/JobInterface.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\interfaces;
|
||||
|
||||
|
||||
use think\queue\Job;
|
||||
|
||||
interface JobInterface
|
||||
{
|
||||
public function fire(Job $job, $data): void;
|
||||
}
|
||||
18
crmeb/interfaces/ListenerInterface.php
Normal file
18
crmeb/interfaces/ListenerInterface.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\interfaces;
|
||||
|
||||
|
||||
interface ListenerInterface
|
||||
{
|
||||
public function handle($event): void;
|
||||
}
|
||||
20
crmeb/interfaces/MiddlewareInterface.php
Normal file
20
crmeb/interfaces/MiddlewareInterface.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\interfaces;
|
||||
|
||||
|
||||
use app\Request;
|
||||
|
||||
interface MiddlewareInterface
|
||||
{
|
||||
public function handle(Request $request, \Closure $next);
|
||||
}
|
||||
19
crmeb/interfaces/ProviderInterface.php
Normal file
19
crmeb/interfaces/ProviderInterface.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\interfaces;
|
||||
|
||||
|
||||
interface ProviderInterface
|
||||
{
|
||||
public function register($config);
|
||||
}
|
||||
|
||||
50
crmeb/listeners/InitSwooleLockListen.php
Normal file
50
crmeb/listeners/InitSwooleLockListen.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace crmeb\listeners;
|
||||
|
||||
|
||||
use app\listener\system\AutoConfig;
|
||||
use crmeb\interfaces\ListenerInterface;
|
||||
use crmeb\utils\Start;
|
||||
use think\facade\Event;
|
||||
use think\swoole\Manager;
|
||||
use Swoole\Process\Pool;
|
||||
|
||||
/**
|
||||
* swoole 初始化
|
||||
*/
|
||||
class InitSwooleLockListen implements ListenerInterface
|
||||
{
|
||||
|
||||
public function handle($event): void
|
||||
{
|
||||
//注入事件
|
||||
Event::listen('get.config', AutoConfig::class);
|
||||
//启动时输出内容
|
||||
app()->make(Start::class)->show();
|
||||
//增加定时任务进程
|
||||
app()->make(Manager::class)->addBatchWorker(1, [$this, 'createCronServer'], 'cron server');
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建定时任务服务 - 单独启动一个进程做为定时任务执行进程
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/10/7
|
||||
*/
|
||||
public function createCronServer(Pool $pool, $workerId)
|
||||
{
|
||||
event('crontab', $workerId);
|
||||
}
|
||||
}
|
||||
34
crmeb/listeners/SwooleCronListen.php
Normal file
34
crmeb/listeners/SwooleCronListen.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace crmeb\listeners;
|
||||
|
||||
use crmeb\interfaces\ListenerInterface;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* swoole 定时任务
|
||||
*/
|
||||
class SwooleCronListen implements ListenerInterface
|
||||
{
|
||||
|
||||
public function handle($event): void
|
||||
{
|
||||
try {
|
||||
event('crontab');//app/event.php 里面配置事件
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('监听定时器报错: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
28
crmeb/listeners/SwooleShutdownListen.php
Normal file
28
crmeb/listeners/SwooleShutdownListen.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\listeners;
|
||||
|
||||
|
||||
use crmeb\interfaces\ListenerInterface;
|
||||
use Swoole\Timer;
|
||||
|
||||
/**
|
||||
* swoole 停止
|
||||
*/
|
||||
class SwooleShutdownListen implements ListenerInterface
|
||||
{
|
||||
|
||||
public function handle($event): void
|
||||
{
|
||||
Timer::clearAll();
|
||||
}
|
||||
}
|
||||
33
crmeb/listeners/SwooleStartListen.php
Normal file
33
crmeb/listeners/SwooleStartListen.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\listeners;
|
||||
|
||||
|
||||
use crmeb\interfaces\ListenerInterface;
|
||||
|
||||
/**
|
||||
* swoole启动监听
|
||||
* Class SwooleStartListen
|
||||
* @package crmeb\listeners
|
||||
*/
|
||||
class SwooleStartListen implements ListenerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* 事件执行
|
||||
* @param $event
|
||||
*/
|
||||
public function handle($event): void
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
167
crmeb/services/AccessTokenServeService.php
Normal file
167
crmeb/services/AccessTokenServeService.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
|
||||
use crmeb\exceptions\ApiException;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* Class AccessTokenServeService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class AccessTokenServeService extends HttpService
|
||||
{
|
||||
/**
|
||||
* 配置
|
||||
* @var string
|
||||
*/
|
||||
protected string $account;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $secret;
|
||||
|
||||
/**
|
||||
* @var Cache|null
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $cacheTokenPrefix = "_crmeb_plat";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $apiHost = 'http://sms.crmeb.net/api/';
|
||||
|
||||
/**
|
||||
* 登录接口
|
||||
*/
|
||||
const USER_LOGIN = "v2/user/login";
|
||||
|
||||
|
||||
/**
|
||||
* AccessTokenServeService constructor.
|
||||
* @param string $account
|
||||
* @param string $secret
|
||||
* @param null $cache
|
||||
*/
|
||||
public function __construct(string $account, string $secret, $cache = null)
|
||||
{
|
||||
if (!$cache) {
|
||||
/** @var CacheService $cache */
|
||||
$cache = app()->make(CacheService::class);
|
||||
}
|
||||
$this->account = $account;
|
||||
$this->secret = $secret;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
* @return array
|
||||
*/
|
||||
public function getConfig(): array
|
||||
{
|
||||
return [
|
||||
'access_key' => $this->account,
|
||||
'secret_key' => $this->secret
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存token
|
||||
* @return mixed
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
$accessTokenKey = md5($this->account . '_' . $this->secret . $this->cacheTokenPrefix);
|
||||
$cacheToken = $this->cache->get($accessTokenKey);
|
||||
if (!$cacheToken) {
|
||||
$getToken = $this->getTokenFromServer();
|
||||
$this->cache->set($accessTokenKey, $getToken['access_token'], 300);
|
||||
$cacheToken = $getToken['access_token'];
|
||||
}
|
||||
return $cacheToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从服务器获取token
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTokenFromServer()
|
||||
{
|
||||
$params = [
|
||||
'access_key' => $this->account,
|
||||
'secret_key' => $this->secret,
|
||||
];
|
||||
if (!$this->account || !$this->secret) {
|
||||
throw new ApiException('请先登录一号通平台!');
|
||||
}
|
||||
$response = $this->postRequest($this->get(self::USER_LOGIN), $params);
|
||||
$response = json_decode($response, true);
|
||||
if (!$response) {
|
||||
throw new ApiException('获取token失败');
|
||||
}
|
||||
if ($response['status'] === 200) {
|
||||
return $response['data'];
|
||||
} else {
|
||||
throw new ApiException($response['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
* @param string $method
|
||||
* @param bool $isHeader
|
||||
* @param array $header
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function httpRequest(string $url, array $data = [], string $method = 'POST', bool $isHeader = true, array $header = [])
|
||||
{
|
||||
if ($isHeader) {
|
||||
$accessToken = $this->getToken();
|
||||
if (!$accessToken) {
|
||||
throw new ApiException('配置已更改或token已失效');
|
||||
}
|
||||
$header = array_merge($header, ['Authorization:Bearer-' . $accessToken]);
|
||||
}
|
||||
Log::info('请求接口:' . $url . ' 请求参数:' . json_encode($data, JSON_UNESCAPED_UNICODE));
|
||||
$res = $this->request($this->get($url), $method, $data, $header);
|
||||
if (!$res) {
|
||||
throw new ApiException('平台错误:发生异常,请稍后重试');
|
||||
|
||||
}
|
||||
$result = json_decode($res, true) ?: false;
|
||||
if (!isset($result['status']) || $result['status'] != 200) {
|
||||
throw new ApiException(isset($result['msg']) ? '平台错误:' . $result['msg'] : '平台错误:发生异常,请稍后重试');
|
||||
}
|
||||
Log::info('接口返回:' . json_encode($result, JSON_UNESCAPED_UNICODE));
|
||||
return $result['data'] ?? [];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $apiUrl
|
||||
* @return string
|
||||
*/
|
||||
public function get(string $apiUrl = '')
|
||||
{
|
||||
return $this->apiHost . $apiUrl;
|
||||
}
|
||||
}
|
||||
374
crmeb/services/AliPayService.php
Normal file
374
crmeb/services/AliPayService.php
Normal file
@@ -0,0 +1,374 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use Alipay\EasySDK\Payment\Common\Models\AlipayTradeFastpayRefundQueryResponse;
|
||||
use Alipay\EasySDK\Payment\Common\Models\AlipayTradeRefundResponse;
|
||||
use Alipay\EasySDK\Payment\Wap\Models\AlipayTradeWapPayResponse;
|
||||
use crmeb\utils\Hook;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use think\facade\Log;
|
||||
use think\facade\Route as Url;
|
||||
use Alipay\EasySDK\Kernel\Config;
|
||||
use Alipay\EasySDK\Kernel\Factory;
|
||||
use crmeb\exceptions\PayException;
|
||||
use app\services\pay\PayNotifyServices;
|
||||
use Alipay\EasySDK\Kernel\Util\ResponseChecker;
|
||||
use AlibabaCloud\Tea\Tea;
|
||||
|
||||
/**
|
||||
* Class AliPayService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class AliPayService
|
||||
{
|
||||
|
||||
/**
|
||||
* 配置
|
||||
* @var array
|
||||
*/
|
||||
protected array $config = [
|
||||
'appId' => '',
|
||||
'merchantPrivateKey' => '',//应用私钥
|
||||
'alipayPublicKey' => '',//支付宝公钥
|
||||
'notifyUrl' => '',//可设置异步通知接收服务地址
|
||||
'encryptKey' => '',//可设置AES密钥,调用AES加解密相关接口时需要(可选)
|
||||
];
|
||||
|
||||
/**
|
||||
* @var ResponseChecker
|
||||
*/
|
||||
protected ResponseChecker $response;
|
||||
|
||||
/**
|
||||
* 付款码
|
||||
* @var string
|
||||
*/
|
||||
protected string $authCode;
|
||||
|
||||
/**
|
||||
* @var static
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* AliPayService constructor.
|
||||
* @param array $config
|
||||
*/
|
||||
protected function __construct(array $config = [])
|
||||
{
|
||||
if (!$config) {
|
||||
$alipay = SystemConfigService::more(['ali_pay_appid', 'alipay_merchant_private_key', 'alipay_public_key', 'site_url']);
|
||||
$config = [
|
||||
'appId' => $alipay['ali_pay_appid'] ?? '',
|
||||
'merchantPrivateKey' => $alipay['alipay_merchant_private_key'] ?? '',
|
||||
'alipayPublicKey' => $alipay['alipay_public_key'] ?? '',
|
||||
'notifyUrl' => ($alipay['site_url'] ?? '') . Url::buildUrl('/api/pay/notify/alipay'),
|
||||
];
|
||||
}
|
||||
$this->config = array_merge($this->config, $config);
|
||||
Factory::setOptions($this->getOptions());
|
||||
$this->response = new ResponseChecker();
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化
|
||||
* @param array $config
|
||||
* @return static
|
||||
*/
|
||||
public static function instance(array $config = []): self
|
||||
{
|
||||
if (is_null(self::$instance)) {
|
||||
self::$instance = new static($config);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是支付宝付款码
|
||||
* @param string $authCode
|
||||
* @return bool
|
||||
*/
|
||||
public static function isAliPayAuthCode(string $authCode): bool
|
||||
{
|
||||
return preg_match('/^[0-9]{16,24}$/', $authCode) && in_array(substr($authCode, 0, 2), ['25', '26', '27', '28', '29', '30']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
Factory::setOptions($this->getOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置配置
|
||||
* @return Config
|
||||
*/
|
||||
protected function getOptions(): Config
|
||||
{
|
||||
$options = new Config();
|
||||
$options->protocol = 'https';
|
||||
$options->gatewayHost = 'openapi.alipay.com';
|
||||
$options->signType = 'RSA2';
|
||||
|
||||
$options->appId = $this->config['appId'];
|
||||
// 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中
|
||||
$options->merchantPrivateKey = $this->config['merchantPrivateKey'];
|
||||
//注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可
|
||||
$options->alipayPublicKey = $this->config['alipayPublicKey'];
|
||||
//可设置异步通知接收服务地址(可选)
|
||||
$options->notifyUrl = $this->config['notifyUrl'];
|
||||
//可设置AES密钥,调用AES加解密相关接口时需要(可选)
|
||||
if ($this->config['encryptKey']) {
|
||||
$options->encryptKey = $this->config['encryptKey'];
|
||||
}
|
||||
Tea::config(['verify' => false]);
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 付款码付款
|
||||
* @param string $authCode
|
||||
* @param string $title
|
||||
* @param string $orderId
|
||||
* @param string $totalAmount
|
||||
* @param string $passbackParams
|
||||
* @return array
|
||||
*/
|
||||
#[ArrayShape([
|
||||
'paid' => "int",
|
||||
'message' => "mixed|string",
|
||||
'payInfo' => "array"
|
||||
])]
|
||||
public function microPay(string $authCode, string $title, string $orderId, string $totalAmount, string $passbackParams): array
|
||||
{
|
||||
$title = trim($title);
|
||||
try {
|
||||
$result = Factory::payment()->faceToFace()->optional('passback_params', $passbackParams)->pay($title, $orderId, $totalAmount, $authCode);
|
||||
if ($this->response->success($result)) {
|
||||
$response = $result->toMap();
|
||||
return [
|
||||
'paid' => $response['code'] === '10000' ? 1 : 0,
|
||||
'message' => $response['sub_msg'] ?? '支付成功',
|
||||
'payInfo' => $response
|
||||
];
|
||||
} else {
|
||||
throw new PayException('失败原因:' . $result->msg . ',' . $result->subMsg);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new PayException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建订单
|
||||
* @param string $title 商品名称
|
||||
* @param string $orderId 订单号
|
||||
* @param string $totalAmount 支付金额
|
||||
* @param string $passbackParams 备注
|
||||
* @param string $quitUrl 同步跳转地址
|
||||
* @param string $siteUrl
|
||||
* @param bool $isCode
|
||||
*/
|
||||
public function create(string $title, string $orderId, string $totalAmount, string $passbackParams, string $quitUrl = '', string $siteUrl = '', bool $isCode = false)
|
||||
{
|
||||
$title = trim($title);
|
||||
try {
|
||||
if ($isCode) {
|
||||
//二维码支付
|
||||
$result = Factory::payment()->faceToFace()->optional('passback_params', $passbackParams)->precreate($title, $orderId, $totalAmount);
|
||||
} else if (request()->isApp()) {
|
||||
//app支付
|
||||
$result = Factory::payment()->app()->optional('passback_params', $passbackParams)->pay($title, $orderId, $totalAmount);
|
||||
} else {
|
||||
//h5支付
|
||||
$result = Factory::payment()->wap()->optional('passback_params', $passbackParams)->pay($title, $orderId, $totalAmount, $quitUrl, $siteUrl);
|
||||
}
|
||||
if ($this->response->success($result)) {
|
||||
return $result->body ?? $result;
|
||||
} else {
|
||||
throw new PayException('失败原因:' . $result->msg . ',' . $result->subMsg);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new PayException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单退款
|
||||
* @param string $outTradeNo 订单号
|
||||
* @param string $totalAmount 退款金额
|
||||
* @param string $refund_id 退款单号
|
||||
* @return AlipayTradeRefundResponse
|
||||
*/
|
||||
public function refund(string $outTradeNo, string $totalAmount, string $refund_id): AlipayTradeRefundResponse
|
||||
{
|
||||
try {
|
||||
$result = Factory::payment()->common()->refund($outTradeNo, $totalAmount, $refund_id);
|
||||
if ($this->response->success($result)) {
|
||||
return $result;
|
||||
} else {
|
||||
throw new PayException('失败原因:' . $result->msg . ',' . $result->subMsg);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new PayException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询交易退款单号信息
|
||||
* @param string $outTradeNo
|
||||
* @param string $outRequestNo
|
||||
* @return AlipayTradeFastpayRefundQueryResponse
|
||||
*/
|
||||
public function queryRefund(string $outTradeNo, string $outRequestNo): AlipayTradeFastpayRefundQueryResponse
|
||||
{
|
||||
try {
|
||||
$result = Factory::payment()->common()->queryRefund($outTradeNo, $outRequestNo);
|
||||
if ($this->response->success($result)) {
|
||||
return $result;
|
||||
} else {
|
||||
throw new PayException('失败原因:' . $result->msg . ',' . $result->subMsg);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new PayException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付异步回调
|
||||
* @return string
|
||||
*/
|
||||
public static function handleNotify()
|
||||
{
|
||||
return self::instance()->notify(function ($notify) {
|
||||
if (isset($notify->out_trade_no)) {
|
||||
if (isset($notify->attach) && $notify->attach) {
|
||||
if (($count = strpos($notify->out_trade_no, '_')) !== false) {
|
||||
$notify->trade_no = $notify->out_trade_no;
|
||||
$notify->out_trade_no = substr($notify->out_trade_no, $count + 1);
|
||||
}
|
||||
return (new Hook(PayNotifyServices::class, 'aliyun'))->listen($notify->attach, $notify->out_trade_no, $notify->trade_no);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步回调
|
||||
* @param callable $notifyFn
|
||||
* @return string
|
||||
*/
|
||||
public function notify(callable $notifyFn)
|
||||
{
|
||||
// app()->request->filter(['trim']);
|
||||
// $paramInfo = app()->request->postMore([
|
||||
// ['gmt_create', ''],
|
||||
// ['charset', ''],
|
||||
// ['seller_email', ''],
|
||||
// ['subject', ''],
|
||||
// ['sign', ''],
|
||||
//// ['buyer_id', ''],
|
||||
// ['invoice_amount', ''],
|
||||
// ['notify_id', ''],
|
||||
// ['fund_bill_list', ''],
|
||||
// ['notify_type', ''],
|
||||
// ['trade_status', ''],
|
||||
// ['receipt_amount', ''],
|
||||
// ['buyer_pay_amount', ''],
|
||||
// ['app_id', ''],
|
||||
// ['seller_id', ''],
|
||||
// ['sign_type', ''],
|
||||
// ['gmt_payment', ''],
|
||||
// ['notify_time', ''],
|
||||
// ['passback_params', ''],
|
||||
// ['version', ''],
|
||||
// ['out_trade_no', ''],
|
||||
// ['total_amount', ''],
|
||||
// ['trade_no', ''],
|
||||
// ['auth_app_id', ''],
|
||||
// ['buyer_logon_id', ''],
|
||||
// ['point_amount', ''],
|
||||
// ], false, false);
|
||||
$paramInfo = app()->request->param();
|
||||
unset($paramInfo['type']);
|
||||
//卡劵红包类
|
||||
// $voucher_detail_list = app()->request->param('voucher_detail_list');
|
||||
// if ($voucher_detail_list) {
|
||||
// $paramInfo['voucher_detail_list'] = $voucher_detail_list;
|
||||
// }
|
||||
//商户订单号
|
||||
$postOrder['out_trade_no'] = $paramInfo['out_trade_no'] ?? '';
|
||||
//支付宝交易号
|
||||
$postOrder['trade_no'] = $paramInfo['trade_no'] ?? '';
|
||||
//交易状态
|
||||
$postOrder['trade_status'] = $paramInfo['trade_status'] ?? '';
|
||||
//备注
|
||||
$postOrder['attach'] = isset($paramInfo['passback_params']) ? urldecode($paramInfo['passback_params']) : '';
|
||||
|
||||
if (in_array($postOrder['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED']) && $this->verifyNotify($paramInfo)) {
|
||||
try {
|
||||
if ($notifyFn((object)$postOrder)) {
|
||||
return 'success';
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('支付宝异步会回调成功,执行函数错误。错误单号:' . $postOrder['out_trade_no']);
|
||||
}
|
||||
}
|
||||
return 'fail';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 验签
|
||||
* @param array $param
|
||||
* @return bool
|
||||
*/
|
||||
protected function verifyNotify(array $param): bool
|
||||
{
|
||||
try {
|
||||
return Factory::payment()->common()->verifyNotify($param);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('支付宝回调成功,验签发生错误,错误原因:' . $e->getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家支付接口
|
||||
* @param array $bizParams
|
||||
* @return \Alipay\EasySDK\Util\Generic\Models\AlipayOpenApiGenericResponse|false
|
||||
* User: liusl
|
||||
* DateTime: 2024/10/21 12:01
|
||||
*/
|
||||
public function merchantPay(array $bizParams)
|
||||
{
|
||||
try {
|
||||
// 调用工厂类的通用方法执行支付宝转账操作
|
||||
$result = Factory::util()->generic()->execute('alipay.fund.trans.toaccount.transfer', [], $bizParams);
|
||||
// 判断支付是否成功
|
||||
if ($this->response->success($result)) {
|
||||
return $result;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// 记录日志并返回false
|
||||
Log::error('支付宝转账失败,失败原因:' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
436
crmeb/services/CacheService.php
Normal file
436
crmeb/services/CacheService.php
Normal file
@@ -0,0 +1,436 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use think\facade\Cache as CacheStatic;
|
||||
|
||||
/**
|
||||
* crmeb 缓存类
|
||||
* Class CacheService
|
||||
* @package crmeb\services
|
||||
* @mixin \Redis
|
||||
*/
|
||||
class CacheService
|
||||
{
|
||||
|
||||
const CACHE_EXPIRE_NAME = 'cache_expire';
|
||||
|
||||
//副屏相关
|
||||
const CASHIER_AUX_SCREEN_TAG = 'auxScreen';
|
||||
|
||||
/**
|
||||
* 标签名
|
||||
* @var string
|
||||
*/
|
||||
protected static $globalCacheName = '_cached_1515146130';
|
||||
|
||||
/**
|
||||
* 缓存队列key
|
||||
* @var string[]
|
||||
*/
|
||||
protected static $redisQueueKey = [
|
||||
0 => 'product',
|
||||
1 => 'seckill',
|
||||
2 => 'bargain',
|
||||
3 => 'combination',
|
||||
4 => 'integral',
|
||||
5 => 'discounts',
|
||||
6 => 'lottery'
|
||||
];
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
* @var int
|
||||
*/
|
||||
protected static $expire;
|
||||
|
||||
/**
|
||||
* 获取缓存过期时间
|
||||
* @param int|null $expire
|
||||
* @return int
|
||||
*/
|
||||
protected static function getExpire(int $expire = null): int
|
||||
{
|
||||
if (self::$expire) {
|
||||
return (int)self::$expire;
|
||||
}
|
||||
$expire = !is_null($expire) ? $expire : CacheStatic::store('redis')->get(self::CACHE_EXPIRE_NAME, 360);
|
||||
if (!is_int($expire))
|
||||
$expire = (int)$expire;
|
||||
return self::$expire = $expire;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断缓存是否存在
|
||||
* @param string $name
|
||||
* @return bool
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public static function has(string $name): bool
|
||||
{
|
||||
try {
|
||||
return CacheStatic::has($name);
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入缓存
|
||||
* @param string $name 缓存名称
|
||||
* @param mixed $value 缓存值
|
||||
* @param int $expire 缓存时间,为0读取系统缓存时间
|
||||
* @return bool
|
||||
*/
|
||||
public static function set(string $name, $value, int $expire = null): bool
|
||||
{
|
||||
try {
|
||||
return self::handler()->set($name, $value, $expire ?? self::getExpire($expire));
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果不存在则写入缓存
|
||||
* @param string $name
|
||||
* @param bool $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get(string $name, $default = false, int $expire = null)
|
||||
{
|
||||
try {
|
||||
return self::handler()->remember($name, $default, $expire ?? self::getExpire($expire));
|
||||
} catch (\Throwable $e) {
|
||||
try {
|
||||
if (is_callable($default)) {
|
||||
return $default();
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果不存在则写入缓存
|
||||
* @param string $name
|
||||
* @param bool $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function remember(string $name, $default = false, int $expire = null)
|
||||
{
|
||||
try {
|
||||
return self::handler()->remember($name, $default, $expire ?? self::getExpire($expire));
|
||||
} catch (\Throwable $e) {
|
||||
try {
|
||||
if (is_callable($default)) {
|
||||
return $default();
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
* @param string $name
|
||||
* @return bool
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public static function delete(string $name)
|
||||
{
|
||||
return CacheStatic::delete($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存句柄
|
||||
*
|
||||
* @return \think\cache\TagSet|CacheStatic
|
||||
*/
|
||||
public static function handler(?string $cacheName = null)
|
||||
{
|
||||
return CacheStatic::tag($cacheName ?: self::$globalCacheName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存池
|
||||
* @return bool
|
||||
*/
|
||||
public static function clear()
|
||||
{
|
||||
return self::handler()->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redis缓存句柄
|
||||
*
|
||||
* @return \think\cache\TagSet|CacheStatic
|
||||
*/
|
||||
public static function redisHandler($type = null)
|
||||
{
|
||||
if ($type) {
|
||||
return CacheStatic::store('redis')->tag($type);
|
||||
} else {
|
||||
return CacheStatic::store('redis');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 放入令牌桶
|
||||
* @param string $key
|
||||
* @param array $value
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
public static function setTokenBucket(string $key, $value, $expire = null, string $type = 'admin')
|
||||
{
|
||||
try {
|
||||
$redisCahce = self::redisHandler($type);
|
||||
return $redisCahce->set($key, $value, $expire);
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有令牌桶
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
public static function clearTokenAll(string $type = 'admin')
|
||||
{
|
||||
try {
|
||||
return self::redisHandler($type)->clear();
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除令牌桶
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
public static function clearToken(string $key)
|
||||
{
|
||||
try {
|
||||
return self::redisHandler()->delete($key);
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看令牌是否存在
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasToken(string $key)
|
||||
{
|
||||
try {
|
||||
return self::redisHandler()->has($key);
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token令牌桶
|
||||
* @param string $key
|
||||
* @return mixed|null
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public static function getTokenBucket(string $key)
|
||||
{
|
||||
try {
|
||||
return self::redisHandler()->get($key, null);
|
||||
} catch (\Throwable $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定分数区间的成员
|
||||
* @param $key
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
* @param array $options
|
||||
* @return mixed
|
||||
*/
|
||||
public static function zRangeByScore($key, $start = '-inf', $end = '+inf', array $options = [])
|
||||
{
|
||||
return self::redisHandler()->zRangeByScore($key, $start, $end, $options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置redis入库队列
|
||||
* @param string $unique
|
||||
* @param int $number
|
||||
* @param int $type
|
||||
* @param bool $isPush true :重置 false:累加
|
||||
* @return bool
|
||||
*/
|
||||
public static function setStock(string $unique, int $number, int $type = 1, bool $isPush = true)
|
||||
{
|
||||
if (!$unique || !$number) return false;
|
||||
$name = (self::$redisQueueKey[$type] ?? '') . '_' . $type . '_' . $unique;
|
||||
/** @var self $cache */
|
||||
$cache = self::redisHandler();
|
||||
$res = true;
|
||||
if ($isPush) {
|
||||
$cache->del($name);
|
||||
}
|
||||
$data = [];
|
||||
for ($i = 1; $i <= $number; $i++) {
|
||||
$data[] = $i;
|
||||
}
|
||||
$res = $res && $cache->lPush($name, ...$data);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出redis队列中的库存条数
|
||||
* @param string $unique
|
||||
* @param int $number
|
||||
* @param int $type
|
||||
* @return bool
|
||||
*/
|
||||
public static function popStock(string $unique, int $number, int $type = 1)
|
||||
{
|
||||
if (!$unique || !$number) return false;
|
||||
$name = (self::$redisQueueKey[$type] ?? '') . '_' . $type . '_' . $unique;
|
||||
/** @var self $cache */
|
||||
$cache = self::redisHandler();
|
||||
$res = true;
|
||||
if ($number > $cache->lLen($name)) {
|
||||
return false;
|
||||
}
|
||||
for ($i = 1; $i <= $number; $i++) {
|
||||
$res = $res && $cache->lPop($name);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有库存|返回库存
|
||||
* @param string $unique
|
||||
* @param int $number
|
||||
* @param int $type
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkStock(string $unique, int $number = 0, int $type = 1)
|
||||
{
|
||||
$name = (self::$redisQueueKey[$type] ?? '') . '_' . $type . '_' . $unique;
|
||||
if ($number) {
|
||||
return self::redisHandler()->lLen($name) >= $number;
|
||||
} else {
|
||||
return self::redisHandler()->lLen($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查锁
|
||||
* @param int $uid
|
||||
* @param int $timeout
|
||||
* @return bool
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2022/11/22
|
||||
*/
|
||||
public static function setMutex(string $key, int $timeout = 10)
|
||||
{
|
||||
$curTime = time();
|
||||
$readMutexKey = "redis:mutex:{$key}";
|
||||
$mutexRes = self::redisHandler()->handler()->setnx($readMutexKey, $curTime + $timeout);
|
||||
if ($mutexRes) {
|
||||
return true;
|
||||
}
|
||||
//就算意外退出,下次进来也会检查key,防止死锁
|
||||
$time = self::redisHandler()->handler()->get($readMutexKey);
|
||||
if ($curTime > $time) {
|
||||
self::redisHandler()->handler()->del($readMutexKey);
|
||||
return self::redisHandler()->handler()->setnx($readMutexKey, $curTime + $timeout);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除锁
|
||||
* @param $uid
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2022/11/22
|
||||
*/
|
||||
public static function delMutex(string $key)
|
||||
{
|
||||
$readMutexKey = "redis:mutex:{$key}";
|
||||
self::redisHandler()->handler()->del($readMutexKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库锁
|
||||
* @param $key
|
||||
* @param $fn
|
||||
* @param int $ex
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public static function lock($key, $fn = [], int $ex = 10)
|
||||
{
|
||||
$service = app()->make(LockService::class);
|
||||
if ($fn instanceof \Closure) {
|
||||
return $service->exec($key, $fn, $ex);
|
||||
} else {
|
||||
return $service->lock($key, 1, $ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁锁
|
||||
* @param $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function unLock($key)
|
||||
{
|
||||
return app()->make(LockService::class)->unlock($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 魔术方法
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
return self::redisHandler()->{$name}(...$arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 魔术方法
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
return self::redisHandler()->{$name}(...$arguments);
|
||||
}
|
||||
|
||||
}
|
||||
596
crmeb/services/CopyProductService.php
Normal file
596
crmeb/services/CopyProductService.php
Normal file
@@ -0,0 +1,596 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
/**
|
||||
* 复制主流商城商品
|
||||
* Class CopyProductService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class CopyProductService
|
||||
{
|
||||
//接口地址
|
||||
protected static $api = [
|
||||
'taobao' => 'https://api03.6bqb.com/taobao/detail', //https://api03.6bqb.com/app/taobao/detail
|
||||
'tmall' => 'https://api03.6bqb.com/tmall/detail',
|
||||
'jd' => 'https://api03.6bqb.com/jd/detail',
|
||||
'pdd' => 'https://api03.6bqb.com/pdd/detail',
|
||||
'suning' => 'https://api03.6bqb.com/suning/detail',
|
||||
'1688' => 'https://api03.6bqb.com/alibaba/detail'
|
||||
];
|
||||
protected static $apiKey = '';//996EF05B079F8706345938A0CD7339BB
|
||||
//商品默认字段
|
||||
protected static $productInfo = [
|
||||
'cate_id' => '',
|
||||
'store_name' => '',
|
||||
'store_info' => '',
|
||||
'unit_name' => '件',
|
||||
'price' => 0,
|
||||
'keyword' => '',
|
||||
'ficti' => 0,
|
||||
'ot_price' => 0,
|
||||
'give_integral' => 0,
|
||||
'postage' => 0,
|
||||
'cost' => 0,
|
||||
'image' => '',
|
||||
'slider_image' => '',
|
||||
'video_link' => '',
|
||||
'add_time' => 0,
|
||||
'stock' => 0,
|
||||
'description' => '',
|
||||
'description_images' => [],
|
||||
'soure_link' => '',
|
||||
'temp_id' => '',
|
||||
'items' => [],
|
||||
'attrs' => [],
|
||||
'info' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* 整合
|
||||
* @param $url
|
||||
* @param $method
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public static function makeUrl(string $url, string $method, array $data)
|
||||
{
|
||||
$param = '';
|
||||
if (strtolower($method) == 'get' && $data) {
|
||||
foreach ($data as $key => $value) {
|
||||
$param .= '&' . $key . '=' . $value;
|
||||
}
|
||||
}
|
||||
return $url . '?apikey=' . self::$apiKey . $param;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $status
|
||||
* @param string $msg
|
||||
* @param array $data
|
||||
*/
|
||||
public static function setReturn(bool $status = true, string $msg = 'SUCCESS', array $data = [])
|
||||
{
|
||||
return ['status' => $status, 'msg' => $msg, 'data' => $data];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public static function getInfo(string $type = 'taobao', array $data = [], string $apikey = '')
|
||||
{
|
||||
if (!$apikey) {
|
||||
return self::setReturn(false, '请先去设置复制商品apiKey');
|
||||
}
|
||||
$url = self::$api[$type] ?? '';
|
||||
$type = $type == '1688' ? 'alibaba' : $type;
|
||||
$action = $type . 'Info';
|
||||
$deal_action = $type . 'Deal';
|
||||
$method = 'get';
|
||||
self::$apiKey = $apikey;
|
||||
if (!$data || !$url || !is_callable(self::class, $action) || !is_callable(self::class, $deal_action)) {
|
||||
return self::setReturn(false, '暂不支持该平台商品复制');
|
||||
}
|
||||
switch ($type) {
|
||||
case 'taobao':
|
||||
case 'tmall':
|
||||
case 'jd':
|
||||
case 'pdd':
|
||||
case 'alibaba':
|
||||
$method = 'get';
|
||||
if (!isset($data['itemid']) || !$data['itemid'])
|
||||
return self::setReturn(false, '缺少商品ID');
|
||||
break;
|
||||
case 'suning':
|
||||
$method = 'get';
|
||||
if (!isset($data['itemid']) || !$data['itemid'])
|
||||
return self::setReturn(false, '缺少商品ID');
|
||||
if (!isset($data['shopid']) || !$data['shopid'])
|
||||
return self::setReturn(false, '缺少商户ID');
|
||||
break;
|
||||
}
|
||||
$url = self::makeUrl($url, $method, $data);
|
||||
if ($cache_info = CacheService::get(md5($url))) {
|
||||
return self::setReturn(true, 'SUCCESS', $cache_info);
|
||||
}
|
||||
$info = self::$action($url, $data);
|
||||
if (!$info) return self::setReturn(false, '获取商品失败');
|
||||
$info = json_decode($info, true);
|
||||
if (!$info || (!in_array($info['retcode'], ['0000']))) {
|
||||
return self::setReturn(false, $info['message'] ?? '获取商品失败', $info);
|
||||
}
|
||||
$result = $info['data'];
|
||||
//可能存在下一页 但是api中没有分页参数 暂留
|
||||
// if (isset($info['hasNext']) && $info['hasNext']) {
|
||||
// $data['page'] = $info['page'] + 1;
|
||||
// }
|
||||
$result = self::$deal_action($result);
|
||||
//过滤采集到的规格 删除其中的空值
|
||||
if ($result['items']) {
|
||||
foreach ($result['items'] as $k => $item) {
|
||||
if (isset($item['value'])) {
|
||||
if ($item['value'] == '') unset($result['items'][$k]);
|
||||
if (!$item['detail'] || !isset($item['detail'][0]) || $item['detail'][0] == '') unset($result['items'][$k]);
|
||||
} else {
|
||||
unset($result['items'][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$result['items']) {
|
||||
$result['items'] = [
|
||||
[
|
||||
'value' => '默认',
|
||||
'detail' => [
|
||||
'默认'
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
$result['info'] = self::formatAttr(array_values($result['items']));
|
||||
if (!$result['image'] && $result['slider_image'])
|
||||
$result['image'] = $result['slider_image'][0] ?? '';
|
||||
if ($result['description']) {
|
||||
$result['description'] = str_replace('data-lazyload', 'src', $result['description']);
|
||||
}
|
||||
CacheService::set(md5($url), $result, 3600 * 24);
|
||||
return self::setReturn(true, 'SUCCESS', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取淘宝商品
|
||||
* @param $url
|
||||
* @param $data
|
||||
* @param string $method
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function taobaoInfo(string $url, array $data, string $method = 'get')
|
||||
{
|
||||
$info = HttpService::request($url, $method, $data);
|
||||
$result = false;
|
||||
if ($info) {
|
||||
$result = $info;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理获取淘宝的商品
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public static function taobaoDeal(array $data)
|
||||
{
|
||||
$info = $data['item'] ?? [];
|
||||
$result = self::$productInfo;
|
||||
if ($info) {
|
||||
$result['store_name'] = $info['title'] ?? '';
|
||||
$result['store_info'] = $info['subTitle'] ?? '';
|
||||
$result['slider_image'] = $info['images'] ?? '';
|
||||
$result['description'] = $info['desc'] ?? '';
|
||||
$result['description_images'] = $info['descImgs'] ?? [];
|
||||
$items = [];
|
||||
if (isset($info['props']) && $info['props']) {
|
||||
foreach ($info['props'] as $key => $prop) {
|
||||
$item['value'] = $prop['name'];
|
||||
$item['detail'] = [];
|
||||
foreach ($prop['values'] as $name) {
|
||||
$item['detail'][] = $name['name'];
|
||||
}
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
$result['items'] = $items;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取天猫商品
|
||||
* @param $url
|
||||
* @param $data
|
||||
* @param string $method
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function tmallInfo(string $url, array $data, string $method = 'get')
|
||||
{
|
||||
$info = HttpService::request($url, $method, $data);
|
||||
$result = false;
|
||||
if ($info) {
|
||||
$result = $info;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理天猫商品
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public static function tmallDeal(array $data)
|
||||
{
|
||||
$info = $data['item'] ?? [];
|
||||
$result = self::$productInfo;
|
||||
if ($info) {
|
||||
$result['store_name'] = $info['title'] ?? '';
|
||||
$result['store_info'] = $info['subTitle'] ?? '';
|
||||
$result['slider_image'] = self::lingByHttp($info['images'] ?? '');
|
||||
$result['description_images'] = self::lingByHttp($info['descImgs'] ?? []);
|
||||
$description = '';
|
||||
foreach ($result['description_images'] as $item) {
|
||||
$description .= '<img src="' . $item . '">';
|
||||
}
|
||||
unset($item);
|
||||
$result['description'] = $description;
|
||||
$items = [];
|
||||
if (isset($info['props']) && $info['props']) {
|
||||
foreach ($info['props'] as $key => $prop) {
|
||||
$item['value'] = $prop['name'];
|
||||
$item['detail'] = [];
|
||||
foreach ($prop['values'] as $name) {
|
||||
$item['detail'][] = $name['name'];
|
||||
}
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
$result['items'] = $items;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取京东商品
|
||||
* @param $url
|
||||
* @param $data
|
||||
* @param string $method
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function jdInfo(string $url, array $data, string $method = 'get')
|
||||
{
|
||||
$info = HttpService::request($url, $method, $data);
|
||||
$result = false;
|
||||
if ($info) {
|
||||
$result = $info;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理京东商品
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public static function jdDeal(array $data)
|
||||
{
|
||||
$info = $data['item'] ?? [];
|
||||
$result = self::$productInfo;
|
||||
if ($info) {
|
||||
$result['store_name'] = $info['name'] ?? '';
|
||||
$result['store_info'] = $result['store_name'];
|
||||
$result['price'] = $info['price'] ?? 0;
|
||||
$result['ot_price'] = $info['originalPrice'] ?? 0;
|
||||
$result['slider_image'] = $info['images'] ?? [];
|
||||
$result['description'] = $info['desc'] ?? '';
|
||||
$result['description_images'] = $info['descImgs'] ?? [];
|
||||
$result['description_images'] = array_map(function ($item) {
|
||||
if (strstr($item, 'http') === false) {
|
||||
$item = 'http:' . $item;
|
||||
}
|
||||
return $item;
|
||||
}, $result['description_images']);
|
||||
if (strstr($result['description'], '<style>') !== false && strstr($result['description'], '<img') === false) {
|
||||
$content = '';
|
||||
foreach ($result['description_images'] as $item) {
|
||||
$content .= '<p><img src="' . $item . '"></p>';
|
||||
}
|
||||
$result['description'] = $content;
|
||||
}
|
||||
|
||||
$items = [];
|
||||
if (isset($info['skuProps']) && $info['skuProps']) {
|
||||
foreach ($info['skuProps'] as $key => $prop) {
|
||||
$item = [];
|
||||
$item['value'] = $info['saleProp'][$key] ?? '';
|
||||
$item['detail'] = $prop;
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
$result['items'] = $items;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array|string
|
||||
*/
|
||||
public static function lingByHttp($data)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
foreach ($data as &$item) {
|
||||
if (strstr($item, 'http://') === false && strstr($item, 'https://') === false) {
|
||||
$item = 'http:' . $item;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
} else {
|
||||
if (strstr($data, 'http://') === false && strstr($data, 'https://') === false) {
|
||||
$data = 'http:' . $data;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拼多多商品
|
||||
* @param $url
|
||||
* @param $data
|
||||
* @param string $method
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function pddInfo(string $url, array $data, string $method = 'get')
|
||||
{
|
||||
$info = HttpService::request($url, $method, $data);
|
||||
$result = false;
|
||||
if ($info) {
|
||||
$result = $info;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理拼多多商品
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public static function pddDeal(array $data)
|
||||
{
|
||||
$info = $data['item'] ?? [];
|
||||
$result = self::$productInfo;
|
||||
if ($info) {
|
||||
$result['store_name'] = $info['goodsName'] ?? '';
|
||||
$result['store_info'] = $info['goodsDesc'] ?? '';
|
||||
$result['image'] = $info['thumbUrl'] ?? '';
|
||||
$result['slider_image'] = $info['banner'] ?? [];
|
||||
$image = [];
|
||||
foreach ($result['slider_image'] as &$item) {
|
||||
if (is_array($item) && isset($item['url'])) {
|
||||
$image[] = $item['url'];
|
||||
}
|
||||
}
|
||||
if ($image) {
|
||||
$result['slider_image'] = $image;
|
||||
}
|
||||
$result['video_link'] = $info['video']['videoUrl'] ?? '';
|
||||
$result['price'] = $info['maxNormalPrice'] ?? 0;
|
||||
$result['ot_price'] = $info['marketPrice'] ?? 0;
|
||||
$descImgs = [];
|
||||
if (isset($info['detail']) && $info['detail']) {
|
||||
foreach ($info['detail'] as $img) {
|
||||
if (isset($img['url']) && $img['url']) $descImgs[] = $img['url'];
|
||||
}
|
||||
}
|
||||
$result['description_images'] = $descImgs;
|
||||
|
||||
$desc = '<p>';
|
||||
foreach ($descImgs as $item) {
|
||||
$desc .= '<img src="' . $item . '"/>';
|
||||
}
|
||||
$desc .= '</p>';
|
||||
$result['description'] = $desc;
|
||||
|
||||
$items = [];
|
||||
if (isset($info['skus']) && $info['skus']) {
|
||||
$i = 0;
|
||||
foreach ($info['skus'] as $sku) {
|
||||
foreach ($sku['specs'] as $key => $spec) {
|
||||
if ($i == 0) $items[$key]['value'] = $spec['spec_key'];
|
||||
$items[$key]['detail'][] = $spec['spec_value'];
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
foreach ($items as $k => $item) {
|
||||
$items[$k]['detail'] = array_unique($item['detail']);
|
||||
}
|
||||
$result['items'] = $items;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取苏宁商品
|
||||
* @param $url
|
||||
* @param $data
|
||||
* @param string $method
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function suningInfo(string $url, array $data, string $method = 'get')
|
||||
{
|
||||
$info = HttpService::request($url, $method, $data);
|
||||
$result = false;
|
||||
if ($info) {
|
||||
$result = $info;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
* @param string $method
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function alibabaInfo(string $url, array $data, string $method = 'get')
|
||||
{
|
||||
$info = HttpService::request($url, $method, $data);
|
||||
$result = false;
|
||||
if ($info) {
|
||||
$result = $info;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public static function alibabaDeal(array $data)
|
||||
{
|
||||
$result = self::$productInfo;
|
||||
if ($data) {
|
||||
$result['store_name'] = $data['title'] ?? '';
|
||||
$result['store_info'] = $result['store_name'];
|
||||
$result['slider_image'] = $data['images'] ?? [];
|
||||
$result['price'] = $data['price'] ?? 0;
|
||||
$result['description'] = $data['desc'] ?? '';
|
||||
$items = [];
|
||||
if (isset($data['skuProps']) && $data['skuProps']) {
|
||||
$i = 0;
|
||||
foreach ($data['skuProps'] as $passSUb) {
|
||||
$items[$i]['value'] = $passSUb['prop'];
|
||||
$items[$i]['detail'] = array_column($passSUb['value'], 'name');
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
foreach ($items as $k => $item) {
|
||||
$items[$k]['detail'] = array_unique($item['detail']);
|
||||
}
|
||||
$result['items'] = $items;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理苏宁商品
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public static function suningDeal(array $data)
|
||||
{
|
||||
$result = self::$productInfo;
|
||||
if ($data) {
|
||||
$result['store_name'] = $data['title'] ?? '';
|
||||
$result['store_info'] = $result['store_name'];
|
||||
$result['slider_image'] = $data['images'] ?? [];
|
||||
$result['price'] = $data['price'] ?? 0;
|
||||
$result['description'] = $data['desc'] ?? '';
|
||||
$items = [];
|
||||
if (isset($data['passSubList']) && $data['passSubList']) {
|
||||
$i = 0;
|
||||
foreach ($data['passSubList'] as $passSUb) {
|
||||
$j = 0;
|
||||
foreach ($passSUb as $key => $sub) {
|
||||
if ($i == 0) $items[$j]['value'] = $key;
|
||||
foreach ($sub as $value) {
|
||||
if (isset($value['characterValueDisplayName']) && $value['characterValueDisplayName'])
|
||||
$items[$j]['detail'][] = $value['characterValueDisplayName'];
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
foreach ($items as $k => $item) {
|
||||
$items[$k]['detail'] = array_unique($item['detail']);
|
||||
}
|
||||
$result['items'] = $items;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化规格
|
||||
* @param $attr
|
||||
* @return array
|
||||
*/
|
||||
public static function formatAttr(array $attr)
|
||||
{
|
||||
$value = attr_format($attr)[1];
|
||||
$valueNew = [];
|
||||
$count = 0;
|
||||
foreach ($value as $key => $item) {
|
||||
$detail = $item['detail'];
|
||||
// sort($item['detail'], SORT_STRING);
|
||||
$suk = implode(',', $item['detail']);
|
||||
$sukValue[$suk]['pic'] = '';
|
||||
$sukValue[$suk]['price'] = 0;
|
||||
$sukValue[$suk]['cost'] = 0;
|
||||
$sukValue[$suk]['ot_price'] = 0;
|
||||
$sukValue[$suk]['stock'] = 0;
|
||||
$sukValue[$suk]['bar_code'] = '';
|
||||
$sukValue[$suk]['weight'] = 0;
|
||||
$sukValue[$suk]['volume'] = 0;
|
||||
$sukValue[$suk]['brokerage'] = 0;
|
||||
$sukValue[$suk]['brokerage_two'] = 0;
|
||||
|
||||
foreach (array_keys($detail) as $k => $title) {
|
||||
if ($title == '') continue;
|
||||
$header[$k]['title'] = $title;
|
||||
$header[$k]['align'] = 'center';
|
||||
$header[$k]['minWidth'] = 120;
|
||||
}
|
||||
foreach (array_values($detail) as $k => $v) {
|
||||
if ($v == '') continue;
|
||||
$valueNew[$count]['value' . ($k + 1)] = $v;
|
||||
$header[$k]['key'] = 'value' . ($k + 1);
|
||||
}
|
||||
$valueNew[$count]['detail'] = $detail;
|
||||
$valueNew[$count]['pic'] = $sukValue[$suk]['pic'] ?? '';
|
||||
$valueNew[$count]['price'] = $sukValue[$suk]['price'] ? floatval($sukValue[$suk]['price']) : 0;
|
||||
$valueNew[$count]['cost'] = $sukValue[$suk]['cost'] ? floatval($sukValue[$suk]['cost']) : 0;
|
||||
$valueNew[$count]['ot_price'] = isset($sukValue[$suk]['ot_price']) ? floatval($sukValue[$suk]['ot_price']) : 0;
|
||||
$valueNew[$count]['vip_price'] = isset($sukValue[$suk]['vip_price']) ? floatval($sukValue[$suk]['vip_price']) : 0;
|
||||
$valueNew[$count]['stock'] = $sukValue[$suk]['stock'] ? intval($sukValue[$suk]['stock']) : 0;
|
||||
$valueNew[$count]['bar_code'] = $sukValue[$suk]['bar_code'] ?? '';
|
||||
$valueNew[$count]['weight'] = $sukValue[$suk]['weight'] ? floatval($sukValue[$suk]['weight']) : 0;
|
||||
$valueNew[$count]['volume'] = $sukValue[$suk]['volume'] ? floatval($sukValue[$suk]['volume']) : 0;
|
||||
$valueNew[$count]['brokerage'] = $sukValue[$suk]['brokerage'] ? floatval($sukValue[$suk]['brokerage']) : 0;
|
||||
$valueNew[$count]['brokerage_two'] = $sukValue[$suk]['brokerage_two'] ? floatval($sukValue[$suk]['brokerage_two']) : 0;
|
||||
$count++;
|
||||
}
|
||||
$header[] = ['title' => '图片', 'slot' => 'pic', 'align' => 'center', 'minWidth' => 80];
|
||||
$header[] = ['title' => '售价', 'slot' => 'price', 'align' => 'center', 'minWidth' => 95];
|
||||
$header[] = ['title' => '成本价', 'slot' => 'cost', 'align' => 'center', 'minWidth' => 95];
|
||||
$header[] = ['title' => '划线价', 'slot' => 'ot_price', 'align' => 'center', 'minWidth' => 95];
|
||||
$header[] = ['title' => '会员价', 'slot' => 'vip_price', 'align' => 'center', 'minWidth' => 140];
|
||||
$header[] = ['title' => '库存', 'slot' => 'stock', 'align' => 'center', 'minWidth' => 95];
|
||||
$header[] = ['title' => '商品编号', 'slot' => 'bar_code', 'align' => 'center', 'minWidth' => 120];
|
||||
$header[] = ['title' => '重量(KG)', 'slot' => 'weight', 'align' => 'center', 'minWidth' => 95];
|
||||
$header[] = ['title' => '体积(m³)', 'slot' => 'volume', 'align' => 'center', 'minWidth' => 95];
|
||||
$header[] = ['title' => '操作', 'slot' => 'action', 'align' => 'center', 'minWidth' => 70];
|
||||
$info = ['attr' => $attr, 'value' => $valueNew, 'header' => $header];
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
62
crmeb/services/DeliverySevices.php
Normal file
62
crmeb/services/DeliverySevices.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use crmeb\interfaces\DeliveryInterface;
|
||||
use crmeb\services\delivery\Delivery;
|
||||
use crmeb\services\delivery\storage\Dada;
|
||||
use crmeb\services\delivery\store\Uupt;
|
||||
|
||||
/**
|
||||
* Class BaseExpress
|
||||
* @package crmeb\basic
|
||||
*/
|
||||
class DeliverySevices
|
||||
{
|
||||
protected static $delivery = [];
|
||||
|
||||
const DELIVERY_TYPE_DADA = 1;
|
||||
const DELIVERY_TYPE_UU = 2;
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
* @param bool $is_cache
|
||||
* @return Delivery|mixed
|
||||
*/
|
||||
public static function init(int $type = self::DELIVERY_TYPE_DADA, bool $is_cache = false)
|
||||
{
|
||||
$type = (int)$type;
|
||||
|
||||
if ($is_cache && isset(self::$delivery['delivery_' . $type]) && self::$delivery['delivery_' . $type]) {
|
||||
return self::$delivery['delivery_' . $type];
|
||||
}
|
||||
$config = [];
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$config = [
|
||||
'app_key' => sys_config('dada_app_key'),
|
||||
'app_secret' => sys_config('dada_app_sercret'),
|
||||
'source_id' => sys_config('dada_source_id'),
|
||||
];
|
||||
break;
|
||||
case 2:
|
||||
$config = [
|
||||
'app_key' => sys_config('uupt_appkey'),
|
||||
'app_id' => sys_config('uupt_app_id'),
|
||||
'open_id' => sys_config('uupt_open_id'),
|
||||
];
|
||||
break;
|
||||
}
|
||||
return self::$delivery['delivery_' . $type] = new Delivery($type, $config);
|
||||
}
|
||||
|
||||
}
|
||||
217
crmeb/services/DownloadImageService.php
Normal file
217
crmeb/services/DownloadImageService.php
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
|
||||
use crmeb\exceptions\AdminException;
|
||||
use think\exception\ValidateException;
|
||||
use think\Image;
|
||||
|
||||
class DownloadImageService
|
||||
{
|
||||
//是否生成缩略图
|
||||
protected $thumb = false;
|
||||
//缩略图宽度
|
||||
protected $thumbWidth = 300;
|
||||
//缩略图高度
|
||||
protected $thumHeight = 300;
|
||||
//存储位置
|
||||
protected $path = 'attach';
|
||||
|
||||
protected $rules = ['thumb', 'thumbWidth', 'thumHeight', 'path'];
|
||||
|
||||
/**
|
||||
* 获取即将要下载的图片扩展名
|
||||
* @param string $url
|
||||
* @param string $ex
|
||||
* @return array|string[]
|
||||
*/
|
||||
public function getImageExtname($url = '', $ex = 'jpg')
|
||||
{
|
||||
$_empty = ['file_name' => '', 'ext_name' => $ex];
|
||||
if (!$url) return $_empty;
|
||||
if (strpos($url, '?')) {
|
||||
$_tarr = explode('?', $url);
|
||||
$url = trim($_tarr[0]);
|
||||
}
|
||||
$arr = explode('.', $url);
|
||||
if (!is_array($arr) || count($arr) <= 1) return $_empty;
|
||||
$ext_name = trim($arr[count($arr) - 1]);
|
||||
$ext_name = !$ext_name ? $ex : $ext_name;
|
||||
return ['file_name' => md5($url) . '.' . $ext_name, 'ext_name' => $ext_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载图片
|
||||
* @param string $url
|
||||
* @param string $name
|
||||
* @param int $upload_type
|
||||
* @return mixed
|
||||
*/
|
||||
public function downloadImage(string $url, $name = '')
|
||||
{
|
||||
if (!$name) {
|
||||
// 获取要下载的文件名称
|
||||
$downloadImageInfo = $this->getImageExtname($url);
|
||||
$ext = $downloadImageInfo['ext_name'];
|
||||
$name = $downloadImageInfo['file_name'];
|
||||
if (!$name) throw new ValidateException('上传图片不存在');
|
||||
} else {
|
||||
$ext = $this->getImageExtname($name)['ext_name'];
|
||||
}
|
||||
if (!in_array($ext, ['png', 'jpg', 'jpeg', 'gif'])) {
|
||||
throw new ValidateException('格式错误,文件后缀不允许');
|
||||
}
|
||||
if (strstr($url, 'http://') === false && strstr($url, 'https://') === false) {
|
||||
$url = 'http:' . $url;
|
||||
}
|
||||
$url = str_replace('https://', 'http://', $url);
|
||||
if ($this->path == 'attach') {
|
||||
$date_dir = date('Y') . DIRECTORY_SEPARATOR . date('m') . DIRECTORY_SEPARATOR . date('d');
|
||||
$to_path = $this->path . '/' . $date_dir;
|
||||
} else {
|
||||
$to_path = $this->path;
|
||||
}
|
||||
$upload = UploadService::init(1);
|
||||
if (!file_exists($upload->uploadDir($to_path) . '/' . $name)) {
|
||||
ob_start();
|
||||
readfile($url);
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$size = strlen(trim($content));
|
||||
if (!$content || $size <= 2) throw new ValidateException('图片流获取失败');
|
||||
if ($upload->to($to_path)->down($content, $name) === false) {
|
||||
throw new ValidateException('图片下载失败');
|
||||
}
|
||||
$imageInfo = $upload->getDownloadInfo();
|
||||
$path = $imageInfo['dir'];
|
||||
if ($this->thumb) {
|
||||
Image::open(root_path() . 'public' . $path)->thumb($this->thumbWidth, $this->thumHeight)->save(root_path() . 'public' . $path);
|
||||
$this->thumb = false;
|
||||
}
|
||||
} else {
|
||||
$path = '/uploads/' . $to_path . '/' . $name;
|
||||
$imageInfo['name'] = $name;
|
||||
}
|
||||
$date['path'] = $path;
|
||||
$date['name'] = $imageInfo['name'];
|
||||
$date['size'] = $imageInfo['size'] ?? '';
|
||||
$date['mime'] = $imageInfo['type'] ?? '';
|
||||
$date['image_type'] = 1;
|
||||
$date['is_exists'] = false;
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络图片下载
|
||||
* @param $url
|
||||
* @param $name
|
||||
* @param $type
|
||||
* @param $timeout
|
||||
* @param $w
|
||||
* @param $h
|
||||
* @return array|string
|
||||
*/
|
||||
public function downloadOnlineImage($url = '', $name = '', $type = 0, $timeout = 30, $w = 0, $h = 0)
|
||||
{
|
||||
if (!strlen(trim($url))) return '';
|
||||
if (!strlen(trim($name))) {
|
||||
//TODO 获取要下载的文件名称
|
||||
$downloadImageInfo = $this->getImageExtname($url);
|
||||
$ext = $downloadImageInfo['ext_name'];
|
||||
$name = $downloadImageInfo['file_name'];
|
||||
if (!strlen(trim($name))) throw new ValidateException('上传图片不存在');
|
||||
} else {
|
||||
$ext = $this->getImageExtname($name)['ext_name'];
|
||||
}
|
||||
if (!in_array($ext, ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bpm', 'tif', 'pcx', 'tga', 'exif', 'fpx', 'svg', 'apng'])) {
|
||||
$headerArray = get_headers(str_replace('\\', '/', $url), true);
|
||||
if (is_array($headerArray['Content-Type']) && count($headerArray['Content-Type']) == 2) {
|
||||
$contentType = $headerArray['Content-Type'][1];
|
||||
} else {
|
||||
$contentType = $headerArray['Content-Type'];
|
||||
}
|
||||
if(!$contentType) throw new ValidateException('格式错误,文件后缀不允许');
|
||||
$img = explode('/',$contentType);
|
||||
if($img[0]!= 'image') throw new ValidateException('格式错误,文件后缀不允许');
|
||||
}
|
||||
if (strstr($url, 'http://') === false && strstr($url, 'https://') === false) {
|
||||
$url = 'http:' . $url;
|
||||
}
|
||||
$url = str_replace('https://', 'http://', $url);
|
||||
if ($this->path == 'attach') {
|
||||
$date_dir = date('Y') . DIRECTORY_SEPARATOR . date('m') . DIRECTORY_SEPARATOR . date('d');
|
||||
$to_path = $this->path . '/' . $date_dir;
|
||||
} else {
|
||||
$to_path = $this->path;
|
||||
}
|
||||
//TODO 获取远程文件所采用的方法
|
||||
if ($type) {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //TODO 跳过证书检查
|
||||
if (stripos($url, "https://") !== FALSE) curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //TODO 从证书中检查SSL加密算法是否存在
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('user-agent:' . $_SERVER['HTTP_USER_AGENT']));
|
||||
if (ini_get('open_basedir') == '' && ini_get('safe_mode') == 'Off') curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);//TODO 是否采集301、302之后的页面
|
||||
$content = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
} else {
|
||||
try {
|
||||
ob_start();
|
||||
if (substr($url, 0, 2) == '//') {
|
||||
$url = "https:" . $url;
|
||||
}
|
||||
readfile($url);
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
} catch (\Exception $e) {
|
||||
throw new ValidateException($e->getMessage());
|
||||
}
|
||||
}
|
||||
$size = strlen(trim($content));
|
||||
if (!$content || $size <= 2) throw new ValidateException('图片流获取失败');
|
||||
$upload_type = sys_config('upload_type', 1);
|
||||
$upload = UploadService::init($upload_type);
|
||||
if ($upload->to($to_path)->validate()->setAuthThumb(false)->stream($content, $name) === false) {
|
||||
throw new ValidateException($upload->getError());
|
||||
}
|
||||
$imageInfo = $upload->getUploadInfo();
|
||||
$date['path'] = $imageInfo['dir'];
|
||||
$date['name'] = $imageInfo['name'];
|
||||
$date['size'] = $imageInfo['size'];
|
||||
$date['mime'] = $imageInfo['type'];
|
||||
$date['image_type'] = $upload_type;
|
||||
$date['is_exists'] = false;
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (in_array($name, $this->rules)) {
|
||||
if ($name === 'path') {
|
||||
$this->{$name} = $arguments[0] ?? 'attach';
|
||||
} else {
|
||||
$this->{$name} = $arguments[0] ?? null;
|
||||
}
|
||||
return $this;
|
||||
} else {
|
||||
throw new \RuntimeException('Method does not exist' . __CLASS__ . '->' . $name . '()');
|
||||
}
|
||||
}
|
||||
}
|
||||
29
crmeb/services/ExpressService.php
Normal file
29
crmeb/services/ExpressService.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
class ExpressService
|
||||
{
|
||||
protected static $api = [
|
||||
'query' => 'https://wuliu.market.alicloudapi.com/kdi'
|
||||
];
|
||||
|
||||
public static function query($no, $type = '')
|
||||
{
|
||||
$appCode = sys_config('system_express_app_code');
|
||||
if (!$appCode) return false;
|
||||
$res = HttpService::getRequest(self::$api['query'], compact('no', 'type'), ['Authorization:APPCODE ' . $appCode]);
|
||||
$result = json_decode($res, true) ?: false;
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
1242
crmeb/services/FileService.php
Normal file
1242
crmeb/services/FileService.php
Normal file
File diff suppressed because it is too large
Load Diff
49
crmeb/services/FormBuilder.php
Normal file
49
crmeb/services/FormBuilder.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use FormBuilder\Factory\Iview as Form;
|
||||
use FormBuilder\UI\Iview\Components\InputNumber;
|
||||
|
||||
/**
|
||||
* Form Builder
|
||||
* Class FormBuilder
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class FormBuilder extends Form
|
||||
{
|
||||
|
||||
public static function setOptions($call)
|
||||
{
|
||||
if (is_array($call)) {
|
||||
return $call;
|
||||
} else {
|
||||
return $call();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function number($field,$title,$value = null){
|
||||
$number = new InputNumber($field, $title, $value);
|
||||
if (!$number->getProp('max')) {
|
||||
if ($field == 'sort') {
|
||||
$number->max(99999);
|
||||
if (!$number->getProp('min')) {
|
||||
$number->min(0);
|
||||
}
|
||||
} else {
|
||||
$number->max(9999999999);
|
||||
}
|
||||
}
|
||||
return $number;
|
||||
}
|
||||
}
|
||||
133
crmeb/services/GroupDataService.php
Normal file
133
crmeb/services/GroupDataService.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use app\services\system\config\SystemGroupDataServices;use think\facade\Config;
|
||||
|
||||
/**
|
||||
* 获取组合数据配置
|
||||
* Class GroupDataService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class GroupDataService
|
||||
{
|
||||
|
||||
/**
|
||||
* 缓存前缀字符
|
||||
*/
|
||||
const CACHE_SYSTEM = 'system_group_data';
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
const EXPIRE_TIME = 30 * 24 * 3600;
|
||||
|
||||
/**
|
||||
* 获取配置缓存前缀
|
||||
* @return string
|
||||
*/
|
||||
public static function getTag()
|
||||
{
|
||||
return Config::get('cache.stores.redis.tag_prefix') . 'cache_' . self::CACHE_SYSTEM;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取单个值
|
||||
* @param string $config_name 配置名称
|
||||
* @param int $limit 截取多少条
|
||||
* @param bool $isCaChe 是否读取缓存
|
||||
* @return array
|
||||
*/
|
||||
public static function getData(string $config_name, int $limit = 0, bool $isCaChe = false): array
|
||||
{
|
||||
$callable = function () use ($config_name, $limit) {
|
||||
event('get.config');
|
||||
try {
|
||||
/** @var SystemGroupDataServices $service */
|
||||
$service = app()->make(SystemGroupDataServices::class);
|
||||
return $service->getConfigNameValue($config_name, $limit);
|
||||
} catch (\Exception) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
try {
|
||||
$cacheName = $limit ? "data_{$config_name}_{$limit}" : "data_{$config_name}";
|
||||
|
||||
if ($isCaChe)
|
||||
return $callable();
|
||||
|
||||
return CacheService::redisHandler(self::getTag())->remember($cacheName, $callable, self::EXPIRE_TIME);
|
||||
|
||||
} catch (\Throwable) {
|
||||
|
||||
try {
|
||||
return $callable();
|
||||
} catch (\Throwable) {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id 获取单个值
|
||||
* @param int $id
|
||||
* @param bool $isCaChe 是否读取缓存
|
||||
* @return array
|
||||
*/
|
||||
public static function getDataNumber(int $id, bool $isCaChe = false): array
|
||||
{
|
||||
$callable = function () use ($id) {
|
||||
try {
|
||||
|
||||
/** @var SystemGroupDataServices $service */
|
||||
$service = app()->make(SystemGroupDataServices::class);
|
||||
$data = $service->getDateValue($id);
|
||||
if (is_object($data))
|
||||
$data = $data->toArray();
|
||||
return $data;
|
||||
} catch (\Exception) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
try {
|
||||
$cacheName = "data_number_{$id}";
|
||||
|
||||
if ($isCaChe)
|
||||
return $callable();
|
||||
|
||||
return CacheService::redisHandler(self::getTag())->remember($cacheName, $callable, self::EXPIRE_TIME);
|
||||
|
||||
} catch (\Throwable) {
|
||||
|
||||
try {
|
||||
return $callable();
|
||||
} catch (\Throwable) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空配置缓存
|
||||
* @return bool|void
|
||||
*/
|
||||
public static function clear()
|
||||
{
|
||||
try {
|
||||
return CacheService::redisHandler(self::getTag())->clear();
|
||||
} catch (\Throwable $e) {
|
||||
\think\facade\Log::error('清空配置缓存失败:原因:' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
156
crmeb/services/HttpService.php
Normal file
156
crmeb/services/HttpService.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
/**
|
||||
* Class HttpService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class HttpService
|
||||
{
|
||||
/**
|
||||
* 错误信息
|
||||
* @var string|null
|
||||
*/
|
||||
private static string|null $curlError;
|
||||
|
||||
/**
|
||||
* header头信息
|
||||
* @var string|null
|
||||
*/
|
||||
private static string|null $headerStr;
|
||||
|
||||
/**
|
||||
* 请求状态
|
||||
* @var int
|
||||
*/
|
||||
private static $status;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getCurlError()
|
||||
{
|
||||
return self::$curlError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getStatus()
|
||||
{
|
||||
return self::$status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟GET发起请求
|
||||
* @param $url
|
||||
* @param array $data
|
||||
* @param bool $header
|
||||
* @param int $timeout
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function getRequest($url, $data = array(), $header = false, $timeout = 10)
|
||||
{
|
||||
if (!empty($data)) {
|
||||
$url .= (stripos($url, '?') === false ? '?' : '&');
|
||||
$url .= (is_array($data) ? http_build_query($data) : $data);
|
||||
}
|
||||
|
||||
return self::request($url, 'get', array(), $header, $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* curl 请求
|
||||
* @param $url
|
||||
* @param string $method
|
||||
* @param array $data
|
||||
* @param bool $header
|
||||
* @param int $timeout
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function request($url, $method = 'get', $data = array(), $header = false, $timeout = 15)
|
||||
{
|
||||
self::$status = null;
|
||||
self::$curlError = null;
|
||||
self::$headerStr = null;
|
||||
|
||||
$curl = curl_init($url);
|
||||
$method = strtoupper($method);
|
||||
//请求方式
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
|
||||
//post请求
|
||||
if ($method == 'POST') {
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, is_array($data) ? http_build_query($data) : $data);
|
||||
} elseif ($method == 'GET' && count($data)) {
|
||||
$url .= '?' . http_build_query($data);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
}
|
||||
//超时时间
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 300);
|
||||
//设置header头
|
||||
if ($header !== false) curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
|
||||
|
||||
curl_setopt($curl, CURLOPT_FAILONERROR, false);
|
||||
//返回抓取数据
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
//输出header头信息
|
||||
curl_setopt($curl, CURLOPT_HEADER, true);
|
||||
//TRUE 时追踪句柄的请求字符串,从 PHP 5.1.3 开始可用。这个很关键,就是允许你查看请求header
|
||||
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
|
||||
//https请求
|
||||
if (1 == strpos("$" . $url, "https://")) {
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
}
|
||||
self::$curlError = curl_error($curl);
|
||||
|
||||
[$content, $status] = [curl_exec($curl), curl_getinfo($curl), curl_close($curl)];
|
||||
self::$status = $status;
|
||||
self::$headerStr = trim(substr($content, 0, $status['header_size']));
|
||||
$content = trim(substr($content, $status['header_size']));
|
||||
return (intval($status["http_code"]) === 200) ? $content : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟POST发起请求
|
||||
* @param $url
|
||||
* @param array $data
|
||||
* @param bool $header
|
||||
* @param int $timeout
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function postRequest($url, $data = [], $header = false, $timeout = 10)
|
||||
{
|
||||
return self::request($url, 'post', $data, $header, $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取header头字符串类型
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getHeaderStr()
|
||||
{
|
||||
return self::$headerStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取header头数组类型
|
||||
* @return array
|
||||
*/
|
||||
public static function getHeader()
|
||||
{
|
||||
$headArr = explode("\r\n", self::$headerStr);
|
||||
return $headArr;
|
||||
}
|
||||
|
||||
}
|
||||
55
crmeb/services/LockService.php
Normal file
55
crmeb/services/LockService.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Cache;
|
||||
|
||||
class LockService
|
||||
{
|
||||
/**
|
||||
* @param $key
|
||||
* @param $fn
|
||||
* @param int $ex
|
||||
* @return mixed
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/03/01
|
||||
*/
|
||||
public function exec($key, $fn, int $ex = 6)
|
||||
{
|
||||
try {
|
||||
if ($this->lock($key, $key, $ex))
|
||||
return $fn();
|
||||
else throw new ValidateException('请求太过频繁,请稍后再试');
|
||||
} finally {
|
||||
$this->unlock($key, $key);
|
||||
}
|
||||
}
|
||||
|
||||
public function tryLock($key, $value = '1', $ex = 6)
|
||||
{
|
||||
return Cache::store('redis')->handler()->set('lock_' . $key, $value, ["NX", "EX" => $ex]);
|
||||
}
|
||||
|
||||
public function lock($key, $value = '1', $ex = 6)
|
||||
{
|
||||
if ($this->tryLock($key, $value, $ex)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function unlock($key, $value = '1')
|
||||
{
|
||||
$script = <<< EOF
|
||||
if (redis.call("get", "lock_" .. KEYS[1]) == ARGV[1]) then
|
||||
return redis.call("del", "lock_" .. KEYS[1])
|
||||
else
|
||||
return 0
|
||||
end
|
||||
EOF;
|
||||
return Cache::store('redis')->handler()->eval($script, [$key, $value], 1) > 0;
|
||||
}
|
||||
}
|
||||
526
crmeb/services/MysqlBackupService.php
Normal file
526
crmeb/services/MysqlBackupService.php
Normal file
@@ -0,0 +1,526 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace crmeb\services;
|
||||
|
||||
use think\facade\Db;
|
||||
|
||||
class MysqlBackupService
|
||||
{
|
||||
/**
|
||||
* 文件指针
|
||||
* @var resource
|
||||
*/
|
||||
private $fp;
|
||||
/**
|
||||
* 备份文件信息 part - 卷号,name - 文件名
|
||||
* @var array
|
||||
*/
|
||||
private $file;
|
||||
/**
|
||||
* 当前打开文件大小
|
||||
* @var integer
|
||||
*/
|
||||
private $size = 0;
|
||||
|
||||
/**
|
||||
* 数据库配置
|
||||
* @var integer
|
||||
*/
|
||||
private $dbconfig = array();
|
||||
/**
|
||||
* 备份配置
|
||||
* @var integer
|
||||
*/
|
||||
private $config = array(
|
||||
'path' => './Data/',
|
||||
//数据库备份路径
|
||||
'part' => 20971520,
|
||||
//数据库备份卷大小
|
||||
'compress' => 0,
|
||||
//数据库备份文件是否启用压缩 0不压缩 1 压缩
|
||||
'level' => 9,
|
||||
);
|
||||
|
||||
/**
|
||||
* 数据库备份构造方法
|
||||
*
|
||||
* @param array $file 备份或还原的文件信息
|
||||
* @param array $config 备份配置信息
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
$this->config['path'] = app()->getRootPath() . 'backup/';
|
||||
$this->config = array_merge($this->config, $config);
|
||||
//初始化文件名
|
||||
$this->setFile();
|
||||
//初始化数据库连接参数
|
||||
$this->setDbConn();
|
||||
//检查文件是否可写
|
||||
if (!$this->checkPath($this->config['path'])) {
|
||||
throw new \Exception("The current directory is not writable");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置脚本运行超时时间
|
||||
* 0表示不限制,支持连贯操作
|
||||
*/
|
||||
public function setTimeout($time = null)
|
||||
{
|
||||
if (!is_null($time)) {
|
||||
set_time_limit($time) || ini_set("max_execution_time", $time);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据库连接必备参数
|
||||
*
|
||||
* @param array $dbconfig 数据库连接配置信息
|
||||
* @return $this
|
||||
*/
|
||||
public function setDbConn($dbconfig = [])
|
||||
{
|
||||
if (empty($dbconfig)) {
|
||||
$this->dbconfig = config('database.connections.' . config('database.default'));
|
||||
//$this->dbconfig = Config::get('database');
|
||||
} else {
|
||||
$this->dbconfig = $dbconfig;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置备份文件名
|
||||
*
|
||||
* @param null $file
|
||||
* @return $this
|
||||
*/
|
||||
public function setFile($file = null)
|
||||
{
|
||||
if (is_null($file)) {
|
||||
$this->file = ['name' => date('Ymd-His'), 'part' => 1];
|
||||
} else {
|
||||
if (!array_key_exists("name", $file) && !array_key_exists("part", $file)) {
|
||||
$this->file = $file['1'];
|
||||
} else {
|
||||
$this->file = $file;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
//数据类连接
|
||||
public static function connect()
|
||||
{
|
||||
return Db::connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库表列表
|
||||
*
|
||||
* @param null $table
|
||||
* @param int $type
|
||||
* @return array
|
||||
* @throws \think\db\exception\BindParamException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function dataList(?string $table = null, int $type = 1)
|
||||
{
|
||||
$key = 'mysql_backup_' . $table . '_' . $type;
|
||||
$data = CacheService::get($key);
|
||||
if (!$data) {
|
||||
$db = self::connect();
|
||||
if (is_null($table)) {
|
||||
$list = $db->query("SHOW TABLE STATUS");
|
||||
} else {
|
||||
if ($type) {
|
||||
$list = $db->query("SHOW FULL COLUMNS FROM {$table}");
|
||||
} else {
|
||||
$list = $db->query("show columns from {$table}");
|
||||
}
|
||||
}
|
||||
$data = array_map('array_change_key_case', $list);
|
||||
CacheService::set($key, $data, 7200);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库备份文件列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fileList()
|
||||
{
|
||||
$list = [];
|
||||
if (!is_dir($this->config['path'])) {
|
||||
mkdir($this->config['path'], 0755, true);
|
||||
return $list;
|
||||
}
|
||||
$path = realpath($this->config['path']);
|
||||
$flag = \FilesystemIterator::KEY_AS_FILENAME;
|
||||
$glob = new \FilesystemIterator($path, $flag);
|
||||
foreach ($glob as $name => $file) {
|
||||
if (preg_match('/^\\d{8,8}-\\d{6,6}-\\d+\\.sql(?:\\.gz)?$/', $name)) {
|
||||
$info['filename'] = $name;
|
||||
$name = sscanf($name, '%4s%2s%2s-%2s%2s%2s-%d');
|
||||
$date = $name[0] . '-' . $name[1] . '-' . $name[2];
|
||||
$time = $name[3] . ':' . $name[4] . ':' . $name[5];
|
||||
$part = $name[6];
|
||||
if (isset($list[$date . $time])) {
|
||||
$info = $list[$date . $time];
|
||||
$info['part'] = max($info['part'], $part);
|
||||
$info['size'] = $info['size'] + $file->getSize();
|
||||
} else {
|
||||
$info['part'] = $part;
|
||||
$info['size'] = $file->getSize();
|
||||
}
|
||||
$extension = strtoupper(pathinfo($file->getFilename(), PATHINFO_EXTENSION));
|
||||
$info['compress'] = $extension === 'SQL' ? '-' : $extension;
|
||||
$info['time'] = strtotime($date . $time);
|
||||
$list[$date . $time] = $info;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param int $time
|
||||
* @return array|false|string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getFile($type = '', $time = 0)
|
||||
{
|
||||
//
|
||||
if (!is_numeric($time)) {
|
||||
throw new \Exception("{$time} Illegal data type");
|
||||
}
|
||||
switch ($type) {
|
||||
case 'time':
|
||||
$name = date('Ymd-His', $time) . '-*.sql*';
|
||||
$path = realpath($this->config['path']) . DIRECTORY_SEPARATOR . $name;
|
||||
return glob($path);
|
||||
break;
|
||||
case 'timeverif':
|
||||
$name = date('Ymd-His', $time) . '-*.sql*';
|
||||
$path = realpath($this->config['path']) . DIRECTORY_SEPARATOR . $name;
|
||||
$files = glob($path);
|
||||
$list = array();
|
||||
foreach ($files as $name) {
|
||||
$basename = basename($name);
|
||||
$match = sscanf($basename, '%4s%2s%2s-%2s%2s%2s-%d');
|
||||
$gz = preg_match('/^\\d{8,8}-\\d{6,6}-\\d+\\.sql.gz$/', $basename);
|
||||
$list[$match[6]] = array($match[6], $name, $gz);
|
||||
}
|
||||
$last = end($list);
|
||||
if (count($list) === $last[0]) {
|
||||
return $list;
|
||||
} else {
|
||||
throw new \Exception("File {$files['0']} may be damaged, please check again");
|
||||
}
|
||||
break;
|
||||
case 'pathname':
|
||||
return "{$this->config['path']}{$this->file['name']}-{$this->file['part']}.sql";
|
||||
break;
|
||||
case 'filename':
|
||||
return "{$this->file['name']}-{$this->file['part']}.sql";
|
||||
break;
|
||||
case 'filepath':
|
||||
return $this->config['path'];
|
||||
break;
|
||||
default:
|
||||
$arr = array('pathname' => "{$this->config['path']}{$this->file['name']}-{$this->file['part']}.sql", 'filename' => "{$this->file['name']}-{$this->file['part']}.sql", 'filepath' => $this->config['path'], 'file' => $this->file);
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除备份文件
|
||||
* @param $time
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delFile($time)
|
||||
{
|
||||
if ($time) {
|
||||
$file = $this->getFile('time', $time);
|
||||
array_map("unlink", $this->getFile('time', $time));
|
||||
if (count($this->getFile('time', $time))) {
|
||||
throw new \Exception("File {$time} deleted failed");
|
||||
} else {
|
||||
return $time;
|
||||
}
|
||||
} else {
|
||||
throw new \Exception("{$time} Time parameter is incorrect");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载备份
|
||||
*
|
||||
* @param $time
|
||||
* @param int $part
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function downloadFile($time, int $part = 0, bool $isFile = false)
|
||||
{
|
||||
$file = $this->getFile('time', $time);
|
||||
$fileName = $file[$part];
|
||||
if (file_exists($fileName)) {
|
||||
if ($isFile) {
|
||||
$key = password_hash(time() . $fileName, PASSWORD_DEFAULT);
|
||||
CacheService::set($key, ['path' => $fileName, 'fileName' => substr(strstr($fileName, 'backup'), 7)], 300);
|
||||
return $key;
|
||||
}
|
||||
ob_end_clean();
|
||||
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
||||
header('Content-Description: File Transfer');
|
||||
header('Access-Control-Allow-Origin: ' . request()->domain());
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Length: ' . filesize($fileName));
|
||||
header('Content-Disposition: attachment; filename=' . basename($fileName));
|
||||
return readfile($fileName);
|
||||
} else {
|
||||
throw new \Exception("{$time} File is abnormal");
|
||||
}
|
||||
}
|
||||
|
||||
public function import($start)
|
||||
{
|
||||
//还原数据
|
||||
$db = self::connect();
|
||||
if ($this->config['compress']) {
|
||||
$gz = gzopen($this->file[1], 'r');
|
||||
$size = 0;
|
||||
} else {
|
||||
$size = filesize($this->file[1]);
|
||||
$gz = fopen($this->file[1], 'r');
|
||||
}
|
||||
$sql = '';
|
||||
if ($start) {
|
||||
$this->config['compress'] ? gzseek($gz, $start) : fseek($gz, $start);
|
||||
}
|
||||
for ($i = 0; $i < 1000; $i++) {
|
||||
$sql .= $this->config['compress'] ? gzgets($gz) : fgets($gz);
|
||||
if (preg_match('/.*;$/', trim($sql))) {
|
||||
if (false !== $db->execute($sql)) {
|
||||
$start += strlen($sql);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
$sql = '';
|
||||
} elseif ($this->config['compress'] ? gzeof($gz) : feof($gz)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return array($start, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入初始数据
|
||||
*
|
||||
* @return boolean true - 写入成功,false - 写入失败
|
||||
*/
|
||||
public function Backup_Init()
|
||||
{
|
||||
$sql = "-- -----------------------------\n";
|
||||
$sql .= "-- Think MySQL Data Transfer \n";
|
||||
$sql .= "-- \n";
|
||||
$sql .= "-- Host : " . $this->dbconfig['hostname'] . "\n";
|
||||
$sql .= "-- Port : " . $this->dbconfig['hostport'] . "\n";
|
||||
$sql .= "-- Database : " . $this->dbconfig['database'] . "\n";
|
||||
$sql .= "-- \n";
|
||||
$sql .= "-- Part : #{$this->file['part']}\n";
|
||||
$sql .= "-- Date : " . date("Y-m-d H:i:s") . "\n";
|
||||
$sql .= "-- -----------------------------\n\n";
|
||||
$sql .= "SET FOREIGN_KEY_CHECKS = 0;\n\n";
|
||||
return $this->write($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份表结构
|
||||
*
|
||||
* @param string $table
|
||||
* @param int $start
|
||||
* @return bool|int
|
||||
* @throws \think\db\exception\BindParamException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function backup(string $table, int $start, $sql = '')
|
||||
{
|
||||
$db = self::connect();
|
||||
// 备份表结构
|
||||
if (0 == $start) {
|
||||
$result = $db->query("SHOW CREATE TABLE `{$table}`");
|
||||
$sql .= "\n";
|
||||
$sql .= "-- -----------------------------\n";
|
||||
$sql .= "-- Table structure for `{$table}`\n";
|
||||
$sql .= "-- -----------------------------\n";
|
||||
$sql .= "DROP TABLE IF EXISTS `{$table}`;\n";
|
||||
$sql .= trim($result[0]['Create Table']) . ";\n\n";
|
||||
}
|
||||
//数据总数
|
||||
$result = $db->query("SELECT COUNT(*) AS count FROM `{$table}`");
|
||||
$count = $result['0']['count'];
|
||||
//备份表数据
|
||||
if ($count) {
|
||||
//写入数据注释
|
||||
if (0 == $start) {
|
||||
$sql .= "-- -----------------------------\n";
|
||||
$sql .= "-- Records of `{$table}`\n";
|
||||
$sql .= "-- -----------------------------\n";
|
||||
}
|
||||
//备份数据记录
|
||||
$result = $db->query("SELECT * FROM `{$table}` LIMIT :MIN, 1000", ['MIN' => intval($start)]);
|
||||
foreach ($result as $row) {
|
||||
$row = array_map('addslashes', $row);
|
||||
$sql .= "INSERT INTO `{$table}` VALUES ('" . str_replace(array("\r", "\n"), array('\\r', '\\n'), implode("', '", $row)) . "');\n";
|
||||
}
|
||||
if (false === $this->write($sql)) {
|
||||
return false;
|
||||
}
|
||||
//还有更多数据
|
||||
if ($count > $start + 1000) {
|
||||
//return array($start + 1000, $count);
|
||||
return $this->backup($table, $start + 1000);
|
||||
}
|
||||
}
|
||||
//备份下一表
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化表
|
||||
*
|
||||
* @param array|string $tables
|
||||
* @throws \think\db\exception\BindParamException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function optimize($tables)
|
||||
{
|
||||
if ($tables) {
|
||||
$db = self::connect();
|
||||
if (is_array($tables)) {
|
||||
$tables = implode('`,`', $tables);
|
||||
$list = $db->query("OPTIMIZE TABLE `{$tables}`");
|
||||
} else {
|
||||
$list = $db->query("OPTIMIZE TABLE {$tables}");
|
||||
}
|
||||
if (!$list) {
|
||||
throw new \Exception("data sheet'{$tables}'Repair mistakes please try again!");
|
||||
}
|
||||
return $list;
|
||||
} else {
|
||||
throw new \Exception("Please specify the table to be repaired!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修复表
|
||||
*
|
||||
* @param string|null $tables
|
||||
* @return array
|
||||
* @throws \think\db\exception\BindParamException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function repair(?string $tables = null)
|
||||
{
|
||||
if ($tables) {
|
||||
$db = self::connect();
|
||||
if (is_array($tables)) {
|
||||
$tables = implode('`,`', $tables);
|
||||
$list = $db->query("REPAIR TABLE `{$tables}`");
|
||||
} else {
|
||||
$list = $db->query("REPAIR TABLE {$tables}");
|
||||
}
|
||||
if ($list) {
|
||||
return $list;
|
||||
} else {
|
||||
throw new \Exception("data sheet'{$tables}'Repair mistakes please try again!");
|
||||
}
|
||||
} else {
|
||||
throw new \Exception("Please specify the table to be repaired!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入SQL语句
|
||||
*
|
||||
* @param string $sql 要写入的SQL语句
|
||||
* @return boolean true - 写入成功,false - 写入失败!
|
||||
*/
|
||||
private function write(string $sql)
|
||||
{
|
||||
$size = strlen($sql);
|
||||
//由于压缩原因,无法计算出压缩后的长度,这里假设压缩率为50%,
|
||||
//一般情况压缩率都会高于50%;
|
||||
$size = $this->config['compress'] ? $size / 2 : $size;
|
||||
$this->open($size);
|
||||
return $this->config['compress'] ? @gzwrite($this->fp, $sql) : @fwrite($this->fp, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开一个卷,用于写入数据
|
||||
*
|
||||
* @param integer $size 写入数据的大小
|
||||
*/
|
||||
private function open(int $size)
|
||||
{
|
||||
if ($this->fp) {
|
||||
$this->size += $size;
|
||||
if ($this->size > $this->config['part']) {
|
||||
$this->config['compress'] ? @gzclose($this->fp) : @fclose($this->fp);
|
||||
$this->fp = null;
|
||||
$this->file['part']++;
|
||||
session('backup_file', $this->file);
|
||||
$this->Backup_Init();
|
||||
}
|
||||
} else {
|
||||
$backuppath = $this->config['path'];
|
||||
$filename = "{$backuppath}{$this->file['name']}-{$this->file['part']}.sql";
|
||||
if ($this->config['compress']) {
|
||||
$filename = "{$filename}.gz";
|
||||
$this->fp = @gzopen($filename, "a{$this->config['level']}");
|
||||
} else {
|
||||
$this->fp = @fopen($filename, 'a');
|
||||
}
|
||||
$this->size = filesize($filename) + $size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查目录是否可写
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkPath(string $path)
|
||||
{
|
||||
if (is_dir($path)) {
|
||||
return true;
|
||||
}
|
||||
if (mkdir($path, 0755, true)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 析构方法,用于关闭文件资源
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->config['compress'] ? @gzclose($this->fp) : @fclose($this->fp);
|
||||
}
|
||||
}
|
||||
120
crmeb/services/QrcodeService.php
Normal file
120
crmeb/services/QrcodeService.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace crmeb\services;
|
||||
|
||||
use app\services\system\attachment\SystemAttachmentServices;
|
||||
use crmeb\services\wechat\MiniProgram;
|
||||
use GuzzleHttp\Psr7\Utils;
|
||||
|
||||
/**
|
||||
* Class QrcodeService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class QrcodeService
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取二维码完整路径,不存在则自动生成
|
||||
* @param string $name 路径名
|
||||
* @param string $link 需要生成二维码的跳转路径
|
||||
* @param int $type https 1 = http , 0 = https
|
||||
* @param bool $force 是否返回false
|
||||
* @return bool|mixed|string
|
||||
*/
|
||||
public static function getWechatQrcodePath(string $name, string $link, bool $force = false)
|
||||
{
|
||||
/** @var SystemAttachmentServices $systemAttchment */
|
||||
$systemAttchment = app()->make(SystemAttachmentServices::class);
|
||||
try {
|
||||
$imageInfo = $systemAttchment->getInfo(['name' => $name]);
|
||||
$siteUrl = sys_config('site_url');
|
||||
if (!$imageInfo) {
|
||||
$codeUrl = UtilService::setHttpType($siteUrl . $link, request()->isSsl() ? 0 : 1);//二维码链接
|
||||
$imageInfo = UtilService::getQRCodePath($codeUrl, $name);
|
||||
if (is_string($imageInfo) && $force)
|
||||
return false;
|
||||
if (is_array($imageInfo)) {
|
||||
$systemAttchment->attachmentAdd($imageInfo['name'], $imageInfo['size'], $imageInfo['type'], $imageInfo['dir'], $imageInfo['thumb_path'], 1, $imageInfo['image_type'], $imageInfo['time'], 2);
|
||||
$url = $imageInfo['dir'];
|
||||
} else {
|
||||
$url = '';
|
||||
$imageInfo = ['image_type' => 0];
|
||||
}
|
||||
} else $url = $imageInfo['att_dir'];
|
||||
if ($imageInfo['image_type'] == 1 && $url) $url = $siteUrl . $url;
|
||||
return $url;
|
||||
} catch (\Throwable $e) {
|
||||
if ($force)
|
||||
return false;
|
||||
else
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序分享二维码
|
||||
* @param int $id
|
||||
* @param int $uid
|
||||
* @param int $type 1 = 拼团,2 = 秒杀
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function getRoutineQrcodePath(int $id, int $uid, int $type, array $parame = [])
|
||||
{
|
||||
$page = '';
|
||||
$namePath = '';
|
||||
$data = 'id=' . $id . '&pid=' . $uid;
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$page = '/pages/activity/goods_details/index?type=3';
|
||||
$namePath = 'combination_' . $id . '_' . $uid . '.jpg';
|
||||
break;
|
||||
case 2:
|
||||
$page = '/pages/activity/goods_details/index?type=1';
|
||||
$namePath = 'seckill_' . $id . '_' . $uid . '.jpg';
|
||||
if (isset($parame['stop_time']) && $parame['stop_time']) {
|
||||
$data .= '&time=' . $parame['stop_time'];
|
||||
$namePath = $parame['stop_time'] . $namePath;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$page || !$namePath) {
|
||||
return false;
|
||||
}
|
||||
/** @var SystemAttachmentServices $systemAttchment */
|
||||
$systemAttchment = app()->make(SystemAttachmentServices::class);
|
||||
try {
|
||||
$imageInfo = $systemAttchment->getInfo($namePath, 'name');
|
||||
$siteUrl = sys_config('site_url');
|
||||
if (!$imageInfo) {
|
||||
$res = MiniProgram::appCodeUnlimit($page, $data, 280);
|
||||
if (!$res) return false;
|
||||
$uploadType = (int)sys_config('upload_type', 1);
|
||||
$upload = UploadService::init($uploadType);
|
||||
$res = (string)Utils::streamFor($res);
|
||||
$res = $upload->to('routine/product')->validate()->stream($res, $namePath);
|
||||
if ($res === false) {
|
||||
return false;
|
||||
}
|
||||
$imageInfo = $upload->getUploadInfo();
|
||||
$imageInfo['image_type'] = $uploadType;
|
||||
if ($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl . $imageInfo['dir']);
|
||||
else $remoteImage = UtilService::remoteImage($imageInfo['dir']);
|
||||
if (!$remoteImage['status']) return false;
|
||||
$systemAttchment->attachmentAdd($imageInfo['name'], $imageInfo['size'], $imageInfo['type'], $imageInfo['dir'], $imageInfo['thumb_path'], 1, $imageInfo['image_type'], $imageInfo['time'], 2);
|
||||
$url = $imageInfo['dir'];
|
||||
} else $url = $imageInfo['att_dir'];
|
||||
if ($imageInfo['image_type'] == 1) $url = $siteUrl . $url;
|
||||
return $url;
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
166
crmeb/services/RedisService.php
Normal file
166
crmeb/services/RedisService.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
|
||||
use think\facade\Config;
|
||||
use Swoole\Coroutine\Channel;
|
||||
use Swoole\Coroutine\Redis;
|
||||
|
||||
/**
|
||||
* Class RedisService
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2022/10/29
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class RedisService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* 获取进程池最大时间
|
||||
* @var int
|
||||
*/
|
||||
protected $maxWaitTime = 3;
|
||||
|
||||
/**
|
||||
* 最大连接池数量
|
||||
* @var int
|
||||
*/
|
||||
protected $maxActive;
|
||||
|
||||
/**
|
||||
* @var Channel
|
||||
*/
|
||||
protected $pool;
|
||||
|
||||
/**
|
||||
* RedisService constructor.
|
||||
* @param array $config
|
||||
* @param array $pool
|
||||
*/
|
||||
public function __construct(array $config = [], array $pool = [])
|
||||
{
|
||||
$this->config = $config ?: Config::get('cache.stores.redis');
|
||||
$this->maxActive = $pool['maxActive'] ?? Config::get('swoole.pool.redis.cache.max_active', 50);
|
||||
$this->maxWaitTime = $pool['maxWaitTime'] ?? Config::get('swoole.pool.redis.cache.max_wait_time', 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化连接池
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2022/10/29
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->pool = new Channel($this->maxActive);
|
||||
|
||||
go(function () {
|
||||
for ($i = 0; $i < $this->maxActive; $i++) {
|
||||
$redis = $this->createConnect($this->config);
|
||||
$this->pool->push($redis);
|
||||
}
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建连接
|
||||
* @param array $config
|
||||
* @return mixed
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2022/10/29
|
||||
*/
|
||||
public function createConnect(array $config)
|
||||
{
|
||||
$connection = new Redis();
|
||||
$res = $connection->connect($config['host'], $config['port'], \Redis::SERIALIZER_PHP);
|
||||
if ($config['password']) {
|
||||
$connection->auth($config['password']);
|
||||
}
|
||||
|
||||
$connection->select($config['select']);
|
||||
|
||||
if ($res === false) {
|
||||
throw new \RuntimeException("Failed to connect redis server");
|
||||
}
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁连接
|
||||
* @param $connection
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2022/10/29
|
||||
*/
|
||||
public function removeConnect($connection)
|
||||
{
|
||||
\Swoole\Coroutine\defer(function () use ($connection) { //释放
|
||||
$connection->close();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取redis连接句柄
|
||||
* @return Redis
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2022/10/29
|
||||
*/
|
||||
public function getRedis()
|
||||
{
|
||||
|
||||
if ($this->pool->isEmpty()) {
|
||||
$redis = $this->createConnect($this->config);
|
||||
$this->removeConnect($redis);
|
||||
return $redis;
|
||||
}
|
||||
|
||||
$redis = $this->pool->pop($this->maxWaitTime);
|
||||
|
||||
if (false === $redis) {
|
||||
$redis = $this->createConnect($this->config);
|
||||
$this->removeConnect($redis);
|
||||
} else {
|
||||
\Swoole\Coroutine\defer(function () use ($redis) { //释放
|
||||
$this->pool->push($redis);
|
||||
});
|
||||
}
|
||||
|
||||
return $redis;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return Redis
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2022/10/29
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
return call_user_func_array([$this->getRedis(), $name], $arguments);
|
||||
}
|
||||
}
|
||||
344
crmeb/services/SpreadsheetExcelService.php
Normal file
344
crmeb/services/SpreadsheetExcelService.php
Normal file
@@ -0,0 +1,344 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace crmeb\services;
|
||||
|
||||
use crmeb\utils\Arr;
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
|
||||
class SpreadsheetExcelService
|
||||
{
|
||||
//
|
||||
private static $instance = null;
|
||||
//PHPSpreadsheet实例化对象
|
||||
private static $spreadsheet = null;
|
||||
//sheet实例化对象
|
||||
private static $sheet = null;
|
||||
//表头计数
|
||||
protected static $count;
|
||||
//表头占行数
|
||||
protected static $topNumber = 3;
|
||||
//表能占据表行的字母对应self::$cellkey
|
||||
protected static $cells;
|
||||
//表头数据
|
||||
protected static $data = [];
|
||||
//文件名
|
||||
protected static $title = '订单导出';
|
||||
//行宽
|
||||
protected static $width = 20;
|
||||
//行高
|
||||
protected static $height = 50;
|
||||
//保存文件目录
|
||||
protected static $path = '/phpExcel/';
|
||||
//设置style
|
||||
private static $styleArray = [
|
||||
// 'borders' => [
|
||||
// 'allBorders' => [
|
||||
// // PHPExcel_Style_Border里面有很多属性,想要其他的自己去看
|
||||
// // 'style' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK,//边框是粗的
|
||||
// // 'style' => \PHPExcel_Style_Border::BORDER_DOUBLE,//双重的
|
||||
// // 'style' => \PHPExcel_Style_Border::BORDER_HAIR,//虚线
|
||||
// // 'style' => \PHPExcel_Style_Border::BORDER_MEDIUM,//实粗线
|
||||
// // 'style' => \PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT,//虚粗线
|
||||
// // 'style' => \PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT,//点虚粗线
|
||||
// 'style' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,//细边框
|
||||
// // 'color' => ['argb' => 'FFFF0000'],
|
||||
// ],
|
||||
// ],
|
||||
'font' => [
|
||||
'bold' => true
|
||||
],
|
||||
'alignment' => [
|
||||
'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
|
||||
'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER
|
||||
]
|
||||
];
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
private function __clone()
|
||||
{
|
||||
}
|
||||
|
||||
public static function instance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
self::$spreadsheet = $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
|
||||
self::$sheet = $spreadsheet->getActiveSheet();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字符串字符集
|
||||
* @param string $str 需要设置字符集的字符串
|
||||
* @return string
|
||||
*/
|
||||
public function utf8String($str)
|
||||
{
|
||||
$str = is_object($str) ? $str->__toString() : $str;
|
||||
$encode = mb_detect_encoding($str, ["ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5', 'CP936']);
|
||||
if (strtoupper($encode) != 'UTF-8') $str = mb_convert_encoding($str, 'utf-8', $encode);
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建保存excel目录
|
||||
* return string
|
||||
*/
|
||||
public static function savePath()
|
||||
{
|
||||
if (!is_dir(self::$path)) {
|
||||
if (mkdir(self::$path, 0700) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//年月一级目录
|
||||
$mont_path = self::$path . date('Ym');
|
||||
if (!is_dir($mont_path)) {
|
||||
if (mkdir($mont_path, 0700) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//日二级目录
|
||||
$day_path = $mont_path . '/' . date('d');
|
||||
if (!is_dir($day_path)) {
|
||||
if (mkdir($day_path, 0700) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $day_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题
|
||||
* @param $title string || array ['title'=>'','name'=>'','info'=>[]]
|
||||
* @param $Name string
|
||||
* @param $info string || array;
|
||||
* @param $funName function($style,$A,$A2) 自定义设置头部样式
|
||||
* @return $this
|
||||
*/
|
||||
public function setExcelTile($title = '', $Name = '', $info = [], $funName = null)
|
||||
{
|
||||
//设置参数
|
||||
if (is_array($title)) {
|
||||
if (isset($title['title'])) $title = $title['title'];
|
||||
if (isset($title['name'])) $Name = $title['name'];
|
||||
if (isset($title['info'])) $info = $title['info'];
|
||||
}
|
||||
if (empty($title))
|
||||
$title = self::$title;
|
||||
else
|
||||
self::$title = $title;
|
||||
|
||||
if (empty($Name)) $Name = time();
|
||||
//设置Excel属性
|
||||
self::$spreadsheet->getProperties()
|
||||
->setCreator("Neo")
|
||||
->setLastModifiedBy("Neo")
|
||||
->setTitle($this->utf8String($title))
|
||||
->setSubject($Name)
|
||||
->setDescription("")
|
||||
->setKeywords($Name)
|
||||
->setCategory("");
|
||||
self::$sheet->setTitle($Name);
|
||||
self::$sheet->setCellValue('A1', $title);
|
||||
self::$sheet->setCellValue('A2', self::setCellInfo($info));
|
||||
//文字居中
|
||||
self::$sheet->getStyle('A1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||
self::$sheet->getStyle('A2')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||
|
||||
//合并表头单元格
|
||||
self::$sheet->mergeCells('A1:' . self::$cells . '1');
|
||||
self::$sheet->mergeCells('A2:' . self::$cells . '2');
|
||||
|
||||
self::$sheet->getRowDimension(1)->setRowHeight(40);
|
||||
self::$sheet->getRowDimension(2)->setRowHeight(20);
|
||||
|
||||
//设置表头字体
|
||||
self::$sheet->getStyle('A1')->getFont()->setName('黑体');
|
||||
self::$sheet->getStyle('A1')->getFont()->setSize(20);
|
||||
self::$sheet->getStyle('A1')->getFont()->setBold(true);
|
||||
self::$sheet->getStyle('A2')->getFont()->setName('宋体');
|
||||
self::$sheet->getStyle('A2')->getFont()->setSize(14);
|
||||
self::$sheet->getStyle('A2')->getFont()->setBold(true);
|
||||
|
||||
self::$sheet->getStyle('A3:' . self::$cells . '3')->getFont()->setBold(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置第二行标题内容
|
||||
* @param $info array (['name'=>'','site'=>'','phone'=>123] || ['我是表名','我是地址','我是手机号码'] ) || string 自定义
|
||||
* @return string
|
||||
*/
|
||||
private static function setCellInfo($info)
|
||||
{
|
||||
$content = ['操作者:', '导出日期:' . date('Y-m-d', time()), '地址:', '电话:'];
|
||||
if (is_array($info) && !empty($info)) {
|
||||
if (isset($info['name'])) {
|
||||
$content[0] .= $info['name'];
|
||||
} else {
|
||||
$content[0] .= isset($info[0]) ? $info[0] : '';
|
||||
}
|
||||
if (isset($info['site'])) {
|
||||
$content[2] .= $info['site'];
|
||||
} else {
|
||||
$content[2] .= isset($info[1]) ? $info[1] : '';
|
||||
}
|
||||
if (isset($info['phone'])) {
|
||||
$content[3] .= $info['phone'];
|
||||
} else {
|
||||
$content[3] .= isset($info[2]) ? $info[2] : '';
|
||||
}
|
||||
return implode(' ', $content);
|
||||
} else if (is_string($info)) {
|
||||
return empty($info) ? implode(' ', $content) : $info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置头部信息
|
||||
* @param $data array
|
||||
* @return $this
|
||||
*/
|
||||
public function setExcelHeader($data)
|
||||
{
|
||||
$span = 'A';
|
||||
foreach ($data as $key => $value) {
|
||||
self::$sheet->getColumnDimension($span)->setWidth(self::$width);
|
||||
self::$sheet->setCellValue($span . self::$topNumber, $value);
|
||||
$span++;
|
||||
}
|
||||
self::$sheet->getRowDimension(3)->setRowHeight(self::$height);
|
||||
self::$cells = $span;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取表格内的文件数据
|
||||
* @param string $filePath
|
||||
* @param array $cellsData
|
||||
* @param callable $closure
|
||||
* @param int $startLine
|
||||
* @return array
|
||||
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
||||
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
|
||||
*/
|
||||
public static function getExcelData(string $filePath, array $cellsData = [], callable $closure = null, int $startLine = 2)
|
||||
{
|
||||
if (!file_exists($filePath)) {
|
||||
throw new \RuntimeException('文件不存在');
|
||||
}
|
||||
$extension = ucwords(pathinfo($filePath, PATHINFO_EXTENSION));
|
||||
$io = IOFactory::createreader($extension);
|
||||
$spreadsheet = $io->load($filePath);
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$highestRow = $worksheet->getHighestRow();
|
||||
$data = [];
|
||||
|
||||
if ($closure) {
|
||||
$closure($worksheet);
|
||||
}
|
||||
|
||||
for ($j = $startLine; $j <= (int)$highestRow; $j++) {
|
||||
$value = [];
|
||||
foreach ($cellsData as $key => $val) {
|
||||
if ($v = $worksheet->getCell($val . $j)->getValue()) {
|
||||
$value[$key] = $v;
|
||||
}
|
||||
}
|
||||
if ($value) {
|
||||
$data[] = $value;
|
||||
}
|
||||
}
|
||||
return Arr::filterValue($data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* execl数据导出
|
||||
* @param $data 需要导出的数据 格式和以前的可是一样
|
||||
*
|
||||
* 特殊处理:合并单元格需要先对数据进行处理
|
||||
*/
|
||||
public function setExcelContent($data = [])
|
||||
{
|
||||
if (!empty($data) && is_array($data)) {
|
||||
$column = self::$topNumber + 1;
|
||||
// 行写入
|
||||
foreach ($data as $key => $rows) {
|
||||
$span = 'A';
|
||||
// 列写入
|
||||
foreach ($rows as $keyName => $value) {
|
||||
self::$sheet->setCellValue($span . $column, $this->utf8String($value));
|
||||
$span++;
|
||||
}
|
||||
$column++;
|
||||
}
|
||||
self::$sheet->getDefaultRowDimension()->setRowHeight(self::$height);
|
||||
//设置内容字体样式
|
||||
self::$sheet->getStyle('A1:' . $span . $column)->applyFromArray(self::$styleArray);
|
||||
//设置边框
|
||||
self::$sheet->getStyle('A1:' . $span . ($column - 1))->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
|
||||
//设置自动换行
|
||||
self::$sheet->getStyle('A4:' . $span . $column)->getAlignment()->setWrapText(true);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存表格数据,直接下载
|
||||
* @param $filename 文件名称
|
||||
* @param $suffix 文件后缀名
|
||||
* @param $is_save 是否保存文件
|
||||
* @return 保存文件:return string
|
||||
*/
|
||||
public function excelSave($fileName = '', $suffix = 'xlsx', $is_save = false)
|
||||
{
|
||||
if (empty($fileName)) {
|
||||
$fileName = date('YmdHis') . time();
|
||||
}
|
||||
if (empty($suffix)) {
|
||||
$suffix = 'xlsx';
|
||||
}
|
||||
// 重命名表(UTF8编码不需要这一步)
|
||||
if (mb_detect_encoding($fileName) != "UTF-8") {
|
||||
$fileName = iconv("utf-8", "gbk//IGNORE", $fileName);
|
||||
}
|
||||
$spreadsheet = self::$spreadsheet;
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
|
||||
if (!$is_save) {//直接下载
|
||||
|
||||
header('Content-Disposition: attachment;filename="' . $fileName . '.' . $suffix . '"');
|
||||
header('Cache-Control: max-age=0');
|
||||
$writer->save('php://output');
|
||||
// 删除清空 释放内存
|
||||
// $spreadsheet->disconnectWorksheets();
|
||||
unset($spreadsheet);
|
||||
} else {//保存文件
|
||||
|
||||
$root_path = app()->getRootPath() . 'public/phpExcel';
|
||||
if (!is_dir($root_path)) mkdir($root_path, 0700, true);
|
||||
$path = $root_path . '/' . $fileName . '.' . $suffix;
|
||||
//$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
|
||||
//$writer->save($path);
|
||||
$writer->save($path);
|
||||
// 删除清空 释放内存
|
||||
// $spreadsheet->disconnectWorksheets();
|
||||
unset($spreadsheet);
|
||||
return '/phpExcel/' . $fileName . '.' . $suffix;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
146
crmeb/services/SystemConfigService.php
Normal file
146
crmeb/services/SystemConfigService.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use app\services\system\config\SystemConfigServices;
|
||||
use crmeb\utils\Arr;
|
||||
use think\facade\Config;
|
||||
use think\facade\Db;
|
||||
|
||||
/** 获取系统配置服务类
|
||||
* Class SystemConfigService
|
||||
* @package service
|
||||
*/
|
||||
class SystemConfigService
|
||||
{
|
||||
/**
|
||||
* 缓存前缀字符
|
||||
*/
|
||||
const CACHE_SYSTEM = 'system_config';
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
const EXPIRE_TIME = 30 * 24 * 3600;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $relationId = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $type = 0;
|
||||
|
||||
/**
|
||||
* 获取配置缓存前缀
|
||||
* @return string
|
||||
*/
|
||||
public static function getTag()
|
||||
{
|
||||
return Config::get('cache.stores.redis.tag_prefix') . 'cache_' . self::CACHE_SYSTEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $storeId
|
||||
*/
|
||||
public static function setStore(int $storeId)
|
||||
{
|
||||
self::$relationId = $storeId;
|
||||
self::$type = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $supplier
|
||||
*/
|
||||
public static function setSupplier(int $supplier)
|
||||
{
|
||||
self::$relationId = $supplier;
|
||||
self::$type = 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个配置效率更高
|
||||
* @param $key
|
||||
* @param string $default
|
||||
* @param bool $isCaChe 是否获取缓存配置
|
||||
* @return bool|mixed|string
|
||||
*/
|
||||
public static function get(string $key, $default = '', bool $isCaChe = false)
|
||||
{
|
||||
$cacheName = self::CACHE_SYSTEM . ':' . $key . (self::$type ? '_' . self::$type : '') . (self::$relationId ? '_' . self::$relationId : '');
|
||||
$type = self::$type;
|
||||
$relationId = self::$relationId;
|
||||
$callable = function () use ($key, $type, $relationId) {
|
||||
event('get.config');
|
||||
/** @var SystemConfigServices $service */
|
||||
$service = app()->make(SystemConfigServices::class);
|
||||
return $service->getConfigValue($key, $type, $relationId);
|
||||
};
|
||||
|
||||
try {
|
||||
if ($isCaChe) {
|
||||
return $callable();
|
||||
}
|
||||
$value = CacheService::redisHandler(self::getTag())->remember($cacheName, $callable, self::EXPIRE_TIME);
|
||||
self::$relationId = 0;
|
||||
self::$type = 0;
|
||||
return $value;
|
||||
} catch (\Throwable $e) {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多个配置
|
||||
* @param array $keys 示例 [['appid','1'],'appkey']
|
||||
* @param bool $isCaChe 是否获取缓存配置
|
||||
* @return array
|
||||
*/
|
||||
public static function more(array $keys, bool $isCaChe = false)
|
||||
{
|
||||
$cacheName = self::CACHE_SYSTEM . ':' . md5(implode(',', $keys) . (self::$type ? '_' . self::$type : '') . (self::$relationId ? '_' . self::$relationId : ''));
|
||||
$type = self::$type;
|
||||
$relationId = self::$relationId;
|
||||
$callable = function () use ($keys, $type, $relationId) {
|
||||
/** @var SystemConfigServices $service */
|
||||
$service = app()->make(SystemConfigServices::class);
|
||||
return Arr::getDefaultValue($keys, $service->getConfigAll($keys, $type, $relationId));
|
||||
};
|
||||
try {
|
||||
if ($isCaChe)
|
||||
return $callable();
|
||||
|
||||
$value = CacheService::redisHandler(self::getTag())->remember($cacheName, $callable, self::EXPIRE_TIME);
|
||||
self::$relationId = 0;
|
||||
self::$type = 0;
|
||||
return $value;
|
||||
} catch (\Throwable $e) {
|
||||
return Arr::getDefaultValue($keys);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空配置缓存
|
||||
* @return bool|void
|
||||
*/
|
||||
public static function clear()
|
||||
{
|
||||
try {
|
||||
return CacheService::redisHandler(self::getTag())->clear();
|
||||
} catch (\Throwable $e) {
|
||||
\think\facade\Log::error('清空配置缓存失败:原因:' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
148
crmeb/services/UploadService.php
Normal file
148
crmeb/services/UploadService.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use app\services\system\config\SystemStorageServices;
|
||||
use crmeb\services\upload\Upload;
|
||||
|
||||
/**
|
||||
* Class UploadService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class UploadService
|
||||
{
|
||||
|
||||
protected static $upload = [];
|
||||
|
||||
/**
|
||||
* @param null $type
|
||||
* @return Upload|mixed
|
||||
*/
|
||||
public static function init($type = null, $is_cache = false)
|
||||
{
|
||||
if (is_null($type)) {
|
||||
$type = (int)sys_config('upload_type', 1);
|
||||
}
|
||||
if ($is_cache && isset(self::$upload['upload_' . $type]) && self::$upload['upload_' . $type]) {
|
||||
return self::$upload['upload_' . $type];
|
||||
}
|
||||
$type = (int)$type;
|
||||
$config = [];
|
||||
switch ($type) {
|
||||
case 2://七牛
|
||||
$config = [
|
||||
'accessKey' => sys_config('qiniu_accessKey'),
|
||||
'secretKey' => sys_config('qiniu_secretKey'),
|
||||
];
|
||||
break;
|
||||
case 3:// oss 阿里云
|
||||
$config = [
|
||||
'accessKey' => sys_config('accessKey'),
|
||||
'secretKey' => sys_config('secretKey'),
|
||||
];
|
||||
break;
|
||||
case 4:// cos 腾讯云
|
||||
$config = [
|
||||
'accessKey' => sys_config('tengxun_accessKey'),
|
||||
'secretKey' => sys_config('tengxun_secretKey'),
|
||||
'appid' => sys_config('tengxun_appid'),
|
||||
];
|
||||
break;
|
||||
case 5://京东云
|
||||
$config = [
|
||||
'accessKey' => sys_config('jd_accessKey'),
|
||||
'secretKey' => sys_config('jd_secretKey'),
|
||||
'storageRegion' => sys_config('jd_storage_region'),
|
||||
];
|
||||
break;
|
||||
case 6://华为云
|
||||
$config = [
|
||||
'accessKey' => sys_config('hw_accessKey'),
|
||||
'secretKey' => sys_config('hw_secretKey'),
|
||||
];
|
||||
break;
|
||||
case 7://天翼云
|
||||
$config = [
|
||||
'accessKey' => sys_config('ty_accessKey'),
|
||||
'secretKey' => sys_config('ty_secretKey'),
|
||||
];
|
||||
break;
|
||||
}
|
||||
$thumb = SystemConfigService::more(['thumb_big_height', 'thumb_big_width', 'thumb_mid_height', 'thumb_mid_width', 'thumb_small_height', 'thumb_small_width',]);
|
||||
$water = SystemConfigService::more([
|
||||
'image_watermark_status',
|
||||
'watermark_type',
|
||||
'watermark_image',
|
||||
'watermark_opacity',
|
||||
'watermark_position',
|
||||
'watermark_rotate',
|
||||
'watermark_text',
|
||||
'watermark_text_angle',
|
||||
'watermark_text_color',
|
||||
'watermark_text_size',
|
||||
'watermark_x',
|
||||
'watermark_y']);
|
||||
$config = array_merge($config, ['thumb' => $thumb], ['water' => $water]);
|
||||
|
||||
//除了本地存储其他都去获取配置信息
|
||||
if (1 !== $type) {
|
||||
/** @var SystemStorageServices $make */
|
||||
$make = app()->make(SystemStorageServices::class);
|
||||
$res = $make->getConfig($type);
|
||||
$config['uploadUrl'] = $res['domain'];
|
||||
$config['storageName'] = $res['name'];
|
||||
if ($type != 5) $config['storageRegion'] = $res['region'];
|
||||
}
|
||||
|
||||
return self::$upload['upload_' . $type] = new Upload($type, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生辰缩略图水印实例化
|
||||
* @param string $filePath
|
||||
* @param bool $is_remote_down
|
||||
* @return Upload
|
||||
*/
|
||||
public static function getOssInit(string $filePath, bool $is_remote_down = false)
|
||||
{
|
||||
//本地
|
||||
$uploadUrl = sys_config('site_url');
|
||||
if ($uploadUrl && strpos($filePath, $uploadUrl) !== false) {
|
||||
$filePath = explode($uploadUrl, $filePath)[1] ?? '';
|
||||
return self::init(1)->setFilepath($filePath);
|
||||
}
|
||||
$fileArr = parse_url($filePath);
|
||||
$fileHost = ($fileArr['scheme'] ?? '') . '://' . ($fileArr['host'] ?? '');
|
||||
/** @var SystemStorageServices $storageServices */
|
||||
$storageServices = app()->make(SystemStorageServices::class);
|
||||
$storageArr = $storageServices->cacheTag()->remember('storage_list', function () use ($storageServices) {
|
||||
return $storageServices->getStorageList([], ['domain','type']);
|
||||
});
|
||||
foreach ($storageArr as $item) {
|
||||
if ($fileHost == $item['domain']) {
|
||||
return self::init($item['type'])->setFilepath($filePath);
|
||||
}
|
||||
}
|
||||
//远程图片 下载到本地处理
|
||||
if ($is_remote_down) {
|
||||
try {
|
||||
/** @var DownloadImageService $down */
|
||||
$down = app()->make(DownloadImageService::class);
|
||||
$data = $down->path('thumb_water')->downloadImage($filePath);
|
||||
$filePath = $data['path'] ?? '';
|
||||
} catch (\Throwable $e) {
|
||||
//下载失败 传入原地址
|
||||
}
|
||||
}
|
||||
return self::init(1)->setFilepath($filePath);
|
||||
}
|
||||
}
|
||||
124
crmeb/services/UtilService.php
Normal file
124
crmeb/services/UtilService.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
use think\facade\Config;
|
||||
use Endroid\QrCode\Color\Color;
|
||||
use Endroid\QrCode\Encoding\Encoding;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelLow;
|
||||
use Endroid\QrCode\QrCode;
|
||||
use Endroid\QrCode\Label\Label;
|
||||
use Endroid\QrCode\Logo\Logo;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
|
||||
use Endroid\QrCode\Writer\PngWriter;
|
||||
|
||||
/**
|
||||
* Class UtilService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class UtilService
|
||||
{
|
||||
/**
|
||||
* 获取小程序二维码是否生成
|
||||
* @param $url
|
||||
* @return array
|
||||
*/
|
||||
public static function remoteImage($url)
|
||||
{
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
$result = curl_exec($curl);
|
||||
$result = json_decode($result, true);
|
||||
if (is_array($result)) return ['status' => false, 'msg' => $result['errcode'] . '---' . $result['errmsg']];
|
||||
return ['status' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改 https 和 http 移动到common
|
||||
* @param $url $url 域名
|
||||
* @param int $type 0 返回https 1 返回 http
|
||||
* @return string
|
||||
*/
|
||||
public static function setHttpType($url, $type = 0)
|
||||
{
|
||||
$domainTop = substr($url, 0, 5);
|
||||
if ($type) {
|
||||
if ($domainTop == 'https') $url = 'http' . substr($url, 5, strlen($url));
|
||||
} else {
|
||||
if ($domainTop != 'https') $url = 'https:' . substr($url, 5, strlen($url));
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取二维码
|
||||
* @param $url
|
||||
* @param $name
|
||||
* @return array|bool|string
|
||||
*/
|
||||
public static function getQRCodePath(string $url, string $name, string $savePath = 'wechat')
|
||||
{
|
||||
if (!strlen(trim($url)) || !strlen(trim($name))) return false;
|
||||
try {
|
||||
$uploadType = sys_config('upload_type');
|
||||
// 没有选择默认使用本地上传
|
||||
if (!$uploadType) $uploadType = 1;
|
||||
$uploadType = (int)$uploadType;
|
||||
$siteUrl = sys_config('site_url');
|
||||
if (!$siteUrl) return '请前往后台设置->系统设置->网站域名 填写您的域名格式为:http://域名';
|
||||
$info = [];
|
||||
$outfiles = Config::get('qrcode.cache_dir') . '/' . $savePath;
|
||||
$root_outfile = root_path('public/' . $outfiles);
|
||||
if (!is_dir($root_outfile))
|
||||
mkdir($root_outfile, 0777, true);
|
||||
|
||||
// Create QR code
|
||||
$writer = new PngWriter();
|
||||
$qrCode = QrCode::create($url)
|
||||
->setEncoding(new Encoding('UTF-8'))
|
||||
->setErrorCorrectionLevel(new ErrorCorrectionLevelLow())
|
||||
->setSize(300)
|
||||
->setMargin(10)
|
||||
->setRoundBlockSizeMode(new RoundBlockSizeModeMargin())
|
||||
->setForegroundColor(new Color(0, 0, 0))
|
||||
->setBackgroundColor(new Color(255, 255, 255));
|
||||
$writer->write($qrCode)->saveToFile($root_outfile . $name);
|
||||
|
||||
if ($uploadType === 1) {
|
||||
$info["code"] = 200;
|
||||
$info["name"] = $name;
|
||||
$info["dir"] = '/' . $outfiles . '/' . $name;
|
||||
$info["time"] = time();
|
||||
$info['size'] = 0;
|
||||
$info['type'] = 'image/png';
|
||||
$info["image_type"] = 1;
|
||||
$info['thumb_path'] = '/' . $outfiles . '/' . $name;
|
||||
return $info;
|
||||
} else {
|
||||
$upload = UploadService::init($uploadType);
|
||||
$content = file_get_contents($root_outfile . $name);
|
||||
|
||||
$res = $upload->to($outfiles)->validate()->stream($content, $name);
|
||||
if ($res === false) {
|
||||
return $upload->getError();
|
||||
}
|
||||
$info = $upload->getUploadInfo();
|
||||
$info['image_type'] = $uploadType;
|
||||
return $info;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
92
crmeb/services/VicWordService.php
Normal file
92
crmeb/services/VicWordService.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace crmeb\services;
|
||||
|
||||
|
||||
use PullWord\PullWord;
|
||||
|
||||
/**
|
||||
* 分词搜索类
|
||||
* Class VicWordService
|
||||
* @package crmeb\services
|
||||
*/
|
||||
class VicWordService
|
||||
{
|
||||
|
||||
/**
|
||||
* 请求地址
|
||||
* @var string
|
||||
*/
|
||||
protected $url = 'https://sms.crmeb.net/api/v2/open/keyword';
|
||||
|
||||
// protected $url = 'http://test-api.crmeb.com/api/v2/open/keyword';
|
||||
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
private function __clone()
|
||||
{
|
||||
}
|
||||
|
||||
public static function instance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function getWord($str)
|
||||
{
|
||||
try {
|
||||
$res = HttpService::getRequest($this->url ,['keyword' => $str]);
|
||||
$data = json_decode($res, true) ?: [];
|
||||
$data = array_column($data['data'] ?? [], 0);
|
||||
} catch (\Throwable $e) {
|
||||
$data = [];
|
||||
}
|
||||
//没有获取分词时,加上原始的词
|
||||
if (!count($data)) {
|
||||
$data[] = $str;
|
||||
}
|
||||
if ($data) {
|
||||
foreach ($data as $key => &$item) {
|
||||
$item = trim($item);
|
||||
if (!$item) unset($data[$key]);
|
||||
}
|
||||
}
|
||||
return array_merge($data);
|
||||
}
|
||||
|
||||
public function getWordV1($str)
|
||||
{
|
||||
try {
|
||||
$pullWord = new PullWord($str);
|
||||
$result = $pullWord->pull()->toJson()->get();
|
||||
$result = json_decode($result, true);
|
||||
$data = is_array($result) ? array_column($result, 't') : [];
|
||||
} catch (\Throwable $e) {
|
||||
$data = [];
|
||||
}
|
||||
//没有获取分词时,加上原始的词
|
||||
if (!count($data)) {
|
||||
$data[] = $str;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
39
crmeb/services/ai/Ai.php
Normal file
39
crmeb/services/ai/Ai.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace crmeb\services\ai;
|
||||
|
||||
use crmeb\basic\BaseManager;
|
||||
use crmeb\services\AccessTokenServeService;
|
||||
use think\Container;
|
||||
use think\facade\Config;
|
||||
|
||||
class Ai extends BaseManager
|
||||
{
|
||||
/**
|
||||
* 空间名
|
||||
* @var string
|
||||
*/
|
||||
protected string $namespace = '\\crmeb\\services\\ai\\storage\\';
|
||||
|
||||
protected function getDefaultDriver()
|
||||
{
|
||||
return Config::get('ai.default', 'ai');
|
||||
}
|
||||
|
||||
protected function invokeClass($class)
|
||||
{
|
||||
if (!class_exists($class)) {
|
||||
throw new \RuntimeException('class not exists: ' . $class);
|
||||
}
|
||||
|
||||
$this->getConfigFile();
|
||||
|
||||
if (!$this->config) {
|
||||
$this->config = Config::get($this->configFile . '.stores.' . $this->name, []);
|
||||
}
|
||||
$handleAccessToken = new AccessTokenServeService($this->config['access_key'] ?? '', $this->config['secret_key'] ?? '');
|
||||
$handle = Container::getInstance()->invokeClass($class, [$this->name, $handleAccessToken, $this->configFile]);
|
||||
$this->config = [];
|
||||
return $handle;
|
||||
}
|
||||
}
|
||||
38
crmeb/services/ai/storage/Ai.php
Normal file
38
crmeb/services/ai/storage/Ai.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace crmeb\services\ai\storage;
|
||||
|
||||
use crmeb\basic\BaseAi;
|
||||
|
||||
class Ai extends BaseAi
|
||||
{
|
||||
const CONVERSATION = 'v2/chat/conversation';
|
||||
const CHAT = 'v2/chat/chat';
|
||||
|
||||
protected function initialize(array $config = [])
|
||||
{
|
||||
parent::initialize($config);
|
||||
}
|
||||
|
||||
public function chat(string $systemContent, string $userContent)
|
||||
{
|
||||
$param['messages'] = [
|
||||
[
|
||||
'role' => 'system',
|
||||
'content' => $systemContent
|
||||
],
|
||||
[
|
||||
'role' => 'user',
|
||||
'content' => $userContent
|
||||
]
|
||||
];
|
||||
$param['max_tokens'] = '4096';
|
||||
$param['temperature'] = '1';
|
||||
$param['frequency_penalty'] = '0';
|
||||
$param['presence_penalty'] = '0';
|
||||
$param['model'] = 'deepseek-chat';
|
||||
$param['response_format'] = '{ "type": "json_object" }';
|
||||
$result = $this->accessToken->httpRequest(self::CHAT, $param);
|
||||
return str_replace(['```json', '```'], '', $result['data']['choices'][0]['message']['content']);
|
||||
}
|
||||
}
|
||||
40
crmeb/services/delivery/Delivery.php
Normal file
40
crmeb/services/delivery/Delivery.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace crmeb\services\delivery;
|
||||
|
||||
use crmeb\basic\BaseManager;
|
||||
use think\facade\Config;
|
||||
|
||||
/**
|
||||
* Class Delivery
|
||||
* @package crmeb\services\delivery
|
||||
* @mixin \crmeb\services\delivery\storage\Dada
|
||||
* @mixin \crmeb\services\delivery\storage\Uupt
|
||||
*/
|
||||
class Delivery extends BaseManager
|
||||
{
|
||||
/**
|
||||
* 空间名
|
||||
* @var string
|
||||
*/
|
||||
protected string $namespace = '\\crmeb\\services\\delivery\\storage\\';
|
||||
|
||||
/**
|
||||
* 设置默认
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getDefaultDriver()
|
||||
{
|
||||
return Config::get('delivery.default', 'dada');
|
||||
}
|
||||
}
|
||||
380
crmeb/services/delivery/storage/Dada.php
Normal file
380
crmeb/services/delivery/storage/Dada.php
Normal file
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------\
|
||||
namespace crmeb\services\delivery\storage;
|
||||
|
||||
use crmeb\basic\BaseDelivery;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
class Dada extends BaseDelivery
|
||||
{
|
||||
const BASE_URL = 'https://newopen.imdada.cn';
|
||||
|
||||
const ADD_MERCHANT = '/merchantApi/merchant/add';
|
||||
|
||||
const ADD_SHOP = '/api/shop/add';
|
||||
|
||||
const UPDATE_SHOP = '/api/shop/update';
|
||||
|
||||
const GET_CITY_CODE = '/api/cityCode/list';
|
||||
|
||||
const GET_SHOP_DETAIL = '/api/shop/detail';
|
||||
|
||||
const GET_ORDER_PRICE = '/api/order/queryDeliverFee';
|
||||
|
||||
const ADD_ORDER_AFTER_QUERY = '/api/order/addAfterQuery';
|
||||
|
||||
const ADD_ORDER_STSATUS_QUERY = '/api/order/status/query';
|
||||
|
||||
const GET_REASONS = '/api/order/cancel/reasons';
|
||||
|
||||
const CANCEL_ORDER = '/api/order/formalCancel';
|
||||
|
||||
const GET_BALANCE = '/api/balance/query';
|
||||
|
||||
const GET_RECHARGE = '/api/recharge';
|
||||
|
||||
public $config;
|
||||
|
||||
protected array $status = [
|
||||
1 => '待接单',
|
||||
2 => '待取货',
|
||||
3 => '配送中',
|
||||
4 => '已完成',
|
||||
5 => '已取消',
|
||||
8 => '指派单',
|
||||
9 => '妥投异常之物品返回中',
|
||||
10 => '妥投异常之物品返回完成',
|
||||
100 => '骑士到店',
|
||||
1000 => '创建达达运单失败'
|
||||
];
|
||||
public function initialize(array $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
parent::initialize($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建商户
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function addMerchant($data)
|
||||
{
|
||||
return $this->sendRequest(self::ADD_MERCHANT, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建门店
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function addShop($data)
|
||||
{
|
||||
$parmas[] = $data;
|
||||
return $this->sendRequest(self::ADD_SHOP, $parmas);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新门店
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function updateShop($data)
|
||||
{
|
||||
$params['origin_shop_id'] = $data['origin_shop_id'];
|
||||
if (isset($data['new_shop_id'])) $params['new_shop_id'] = $data['new_shop_id'];
|
||||
if (isset($data['station_name'])) $params['station_name'] = $data['station_name'];
|
||||
if (isset($data['business'])) $params['business'] = $data['business'];
|
||||
if (isset($data['station_address'])) $params['station_address'] = $data['station_address'];
|
||||
if (isset($data['lng'])) $params['lng'] = $data['lng'];
|
||||
if (isset($data['lat'])) $params['lat'] = $data['lat'];
|
||||
if (isset($data['contact_name'])) $params['contact_name'] = $data['contact_name'];
|
||||
if (isset($data['phone'])) $params['phone'] = $data['phone'];
|
||||
if (isset($data['status'])) $params['status'] = $data['status'];
|
||||
return $this->sendRequest(self::UPDATE_SHOP, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预发布订单
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function addOrder($data)
|
||||
{
|
||||
$params = [
|
||||
'deliveryNo' => $data['deliveryNo'],
|
||||
];
|
||||
return $this->sendRequest(self::ADD_ORDER_AFTER_QUERY, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算订单价格
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOrderPrice($data)
|
||||
{
|
||||
$params = [
|
||||
'shop_no' => $data['shop_no'],
|
||||
'origin_id' => $data['origin_id'],
|
||||
'city_code' => $data['city_code'],
|
||||
'cargo_price' => $data['cargo_price'],
|
||||
'is_prepay' => $data['is_prepay'],
|
||||
'receiver_name' => $data['receiver_name'],
|
||||
'receiver_address'=> $data['receiver_address'],
|
||||
'callback' => $this->callback_url,
|
||||
'cargo_weight' => $data['cargo_weight'],
|
||||
'receiver_phone' => $data['receiver_phone'],
|
||||
'is_finish_code_needed'=> $data['is_finish_code_needed'],
|
||||
];
|
||||
return $this->sendRequest(self::GET_ORDER_PRICE, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单详情
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOrderDetail($data)
|
||||
{
|
||||
$params['order_id'] = $data['origin_id'];
|
||||
$res = $this->sendRequest(self::ADD_ORDER_STSATUS_QUERY, $params);
|
||||
if($res){
|
||||
$res['status_name'] = $this->status[$res['statusCode']] ?? '';
|
||||
$res['porter_name'] = $this->status[$res['transporterName']] ?? '';
|
||||
$res['porter_phone'] = $this->status[$res['transporterPhone']] ?? '';
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function cancelOrder($data)
|
||||
{
|
||||
$params['order_id'] = $data['origin_id'];
|
||||
$params['cancel_reason'] = $data['cancel_reason'] ?? '无';
|
||||
$params['cancel_reason_id'] = $data['reason'];
|
||||
return $this->sendRequest(self::CANCEL_ORDER, $params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取充值地址
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRecharge($data =[])
|
||||
{
|
||||
$params = [
|
||||
'amount' => $data['amount'] ?? 100,
|
||||
'category'=> $data['category'] ?? 'PC',
|
||||
];
|
||||
return $this->sendRequest(self::GET_RECHARGE, $params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取余额
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBalance($data)
|
||||
{
|
||||
$params['category'] = $data['category'] ?? 3;
|
||||
$res = $this->sendRequest(self::GET_BALANCE, $params);
|
||||
return [
|
||||
'deliverBalance' => $res['deliverBalance']
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 支付小费
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function addTip($data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取消原因
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function reasons($data = '')
|
||||
{
|
||||
$options = $this->sendRequest(self::GET_REASONS, $data);
|
||||
foreach ($options as $option) {
|
||||
$value = $option['id'];
|
||||
$label = $option['reason'];
|
||||
$res[] = compact('value','label');
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取城市信息
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCity($data = '')
|
||||
{
|
||||
$res = $this->sendRequest(self::GET_CITY_CODE, $data);
|
||||
foreach ($res as $item) {
|
||||
$data[] = [
|
||||
'key' => $item['cityName'],
|
||||
'label' => $item['cityName'],
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店信息
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function getShopDetail($id)
|
||||
{
|
||||
$data = ['origin_shop_id' => $id];
|
||||
return $this->sendRequest(self::GET_SHOP_DETAIL, $data);
|
||||
}
|
||||
|
||||
public function getBusiness()
|
||||
{
|
||||
return [
|
||||
['key' => 1 , 'label' => '食品小吃'],
|
||||
['key' => 2 , 'label' => '饮料'],
|
||||
['key' => 3 , 'label' => '鲜花绿植'],
|
||||
['key' => 5 , 'label' => '其他'],
|
||||
['key' => 8 , 'label' => '文印票务'],
|
||||
['key' => 9 , 'label' => '便利店'],
|
||||
['key' => 13 , 'label' => '水果生鲜'],
|
||||
['key' => 19 , 'label' => '同城电商'],
|
||||
['key' => 20 , 'label' => '医药'],
|
||||
['key' => 21 , 'label' => '蛋糕'],
|
||||
['key' => 24 , 'label' => '酒品'],
|
||||
['key' => 25 , 'label' => '小商品市场'],
|
||||
['key' => 26 , 'label' => '服装'],
|
||||
['key' => 27 , 'label' => '汽修零配'],
|
||||
['key' => 28 , 'label' => '数码家电'],
|
||||
['key' => 29 , 'label' => '小龙虾/烧烤'],
|
||||
['key' => 31 , 'label' => '超市'],
|
||||
['key' => 51 , 'label' => '火锅'],
|
||||
['key' => 53 , 'label' => '个护美妆'],
|
||||
['key' => 55 , 'label' => '母婴'],
|
||||
['key' => 57 , 'label' => '家居家纺'],
|
||||
['key' => 59 , 'label' => '手机'],
|
||||
['key' => 61 , 'label' => '家装'],
|
||||
['key' => 63 , 'label' => '成人用品'],
|
||||
];
|
||||
}
|
||||
|
||||
public function sendRequest($api, $params)
|
||||
{
|
||||
$url = self::BASE_URL . $api;
|
||||
$params = $this->bulidRequestParams($params);
|
||||
$response = $this->httpRequestWithPost($url, $params);
|
||||
$data = $this->getMessage($response);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造请求数据
|
||||
* data:业务参数,json字符串
|
||||
*/
|
||||
public function bulidRequestParams($params)
|
||||
{
|
||||
$requestParams = array();
|
||||
$requestParams['app_key'] = $this->config['app_key'];
|
||||
$requestParams['body'] = json_encode($params);
|
||||
$requestParams['format'] = 'json';
|
||||
$requestParams['v'] = '1.0';
|
||||
$requestParams['source_id'] = $this->config['source_id'];
|
||||
$requestParams['timestamp'] = time();
|
||||
$requestParams['signature'] = $this->_sign($requestParams);
|
||||
return json_encode($requestParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名生成signature
|
||||
*/
|
||||
public function _sign($data)
|
||||
{
|
||||
//1.升序排序
|
||||
ksort($data);
|
||||
//2.字符串拼接
|
||||
$args = "";
|
||||
foreach ($data as $key => $value) {
|
||||
$args .= $key . $value;
|
||||
}
|
||||
$args = $this->config['app_secret'] . $args . $this->config['app_secret'];
|
||||
//3.MD5签名,转为大写
|
||||
$sign = strtoupper(md5($args));
|
||||
return $sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求,POST
|
||||
* @param $url 指定URL完整路径地址
|
||||
* @param $data 请求的数据
|
||||
*/
|
||||
public function httpRequestWithPost($url, $data, $headers = [])
|
||||
{
|
||||
$headers = array(
|
||||
'Content-Type: application/json',
|
||||
);
|
||||
$curl = curl_init($url);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HEADER, false);
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 3);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
$resp = curl_exec($curl);
|
||||
$info = curl_getinfo($curl);
|
||||
curl_close($curl);
|
||||
if (isset($info['http_code']) && $info['http_code'] == 200) {
|
||||
return $resp;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
protected function getMessage($json, $message = '未知错误!')
|
||||
{
|
||||
$data = json_decode($json, true);
|
||||
//code=2551 订单创建中
|
||||
if (!in_array($data['code'], [0, 2551])) {
|
||||
isset($data['msg']) && $message = $data['msg'];
|
||||
if ($data['errorCode'] == 7718) {
|
||||
foreach ($data['result']['failedList'] as $datum) {
|
||||
$message .= ':'.$datum['shopName'].'/'. $datum['msg'].';';
|
||||
}
|
||||
}
|
||||
throw new ValidateException('【达达错误提示】:'.$message);
|
||||
} else {
|
||||
if ($data['status'] == 'success') return $data['result'] ?? $data;
|
||||
return $data;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user